pax_global_header00006660000000000000000000000064144057130730014516gustar00rootroot0000000000000052 comment=697e89b1290bcb244b3c17feb1a9420f707132ad leocad-23.03/000077500000000000000000000000001440571307300127545ustar00rootroot00000000000000leocad-23.03/.gitattributes000066400000000000000000000004771440571307300156570ustar00rootroot00000000000000# Set the default behavior, in case people don't have core.autocrlf set. * text=auto # Explicitly declare text files you want to always be normalized and converted # to native line endings on checkout. *.cpp text *.h text # Denote all files that are truly binary and should not be modified. *.png binary *.jpg binary leocad-23.03/.github/000077500000000000000000000000001440571307300143145ustar00rootroot00000000000000leocad-23.03/.github/ISSUE_TEMPLATE/000077500000000000000000000000001440571307300164775ustar00rootroot00000000000000leocad-23.03/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000016421440571307300211740ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve title: '' labels: bug assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Version (please complete the following information):** - OS: [e.g. Windows 10, Ubuntu, macOS] - LeoCAD Version [e.g. 19.07 or continuous] **Crash information:** Some versions of LeoCAD will show a message that they saved a minidump file when they crash, if you see this message please attach the file. **Additional context** Add any other context about the problem here. If you're seeing a graphical issue, adding a screenshot of the About Dialog may help. leocad-23.03/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000011231440571307300222210ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for this project title: '' labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. leocad-23.03/.github/workflows/000077500000000000000000000000001440571307300163515ustar00rootroot00000000000000leocad-23.03/.github/workflows/continuous.yml000066400000000000000000000037031440571307300213050ustar00rootroot00000000000000name: LeoCAD CI on: push: branches: [ "master" ] jobs: build-ubuntu: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install Qt uses: jurplel/install-qt-action@v3 with: cache: 'true' - name: Get number of CPU cores uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores - name: Generate Makefile run: qmake PREFIX=/usr - name: Build run: make -j ${{ steps.cpu-cores.outputs.count }} build-macos: runs-on: macos-latest steps: - uses: actions/checkout@v3 - name: Install Qt uses: jurplel/install-qt-action@v3 with: cache: 'true' - name: Cache Library uses: actions/cache@v3 id: cache-library with: path: library.bin key: library-20.03 - name: Download Library if: steps.cache-library.outputs.cache-hit != 'true' run: | wget https://github.com/leozide/leocad/releases/download/v19.07.1/Library-20.03.zip -O library.zip unzip library.zip - name: Cache POV-Ray uses: actions/cache@v3 id: cache-povray with: path: povray key: povray-20.03 - name: Download POV-Ray if: steps.cache-povray.outputs.cache-hit != 'true' run: | wget https://github.com/leozide/povray/releases/download/continuous/povray chmod +x povray curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/leozide/leocad/commits/master -o repo.txt echo < repo.txt echo export REMOTE=$(grep -Po '(?<=: \")(([a-z0-9])\w+)(?=\")' -m 1 repo.txt) export REMOTE=$(grep -Po '(?<=: \")(([a-z0-9])\w+)(?=\")' -m 1 repo.txt) echo $REMOTE - name: Get number of CPU cores uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores - name: Generate Makefile run: qmake PREFIX=/usr - name: Build run: make -j ${{ steps.cpu-cores.outputs.count }} leocad-23.03/.gitignore000066400000000000000000000005611440571307300147460ustar00rootroot00000000000000*.suo *.sln *.vcxproj *.filters *.user *.pdb *.db *.psess *.opendb *.opensdf *.sdf *.suo *.vspx *.xcodeproj *.qm *.ldr *.dat *.mpd !/resources/*.ldr *.dae *.3ds *.obj .vs build debug release ipch Debug* .DS_Store .qmake.stash Makefile library.bin leocad_plugin_import.cpp leocad_resource.* povray uic_wrapper.bat /tools/setup/*.exe appdir LeoCAD-Windows*.exe *.snap leocad-23.03/PKGBUILD000066400000000000000000000036761440571307300141140ustar00rootroot00000000000000# Maintainer: Peter Bartfai pkgname=leocad pkgver=18.02 pkgrel=1 pkgdesc="LeoCAD is a CAD program for creating virtual LEGO models." url="http://leocad.org" arch=('x86_64' 'i686') license=('GPL') #Qt4.x depends=('qt4' 'libpng' 'libjpeg-turbo' 'mesa-libgl') #Qt5.x #depends=('qt5-base' 'qt5-tools' 'qt5-gamepad' 'libpng' 'libjpeg-turbo' 'mesa-libgl') makedepends=('glu' 'ca-certificates') conflicts=() replaces=() backup=() source=("leocad-git.tar.gz") md5sums=(SKIP) build() { cd ${srcdir}/leocad-git if test "$CARCH" == x86_64; then PLATFORM=linux-g++-64 else PLATFORM=linux-g++-32 fi if [ -x /usr/bin/qmake ] ; then qmake -spec $PLATFORM DISABLE_UPDATE_CHECK=1 LDRAW_LIBRARY_PATH=/usr/share/ldraw ; lrelease leocad.pro ; elif [ -x /usr/bin/qmake-qt4 ] ; then qmake-qt4 -spec $PLATFORM DISABLE_UPDATE_CHECK=1 LDRAW_LIBRARY_PATH=/usr/share/ldraw ; lrelease-qt4 leocad.pro ; elif [ -x /usr/bin/qmake-qt5 ] ; then qmake-qt5 -spec $PLATFORM DISABLE_UPDATE_CHECK=1 LDRAW_LIBRARY_PATH=/usr/share/ldraw ; lrelease-qt5 leocad.pro ; fi make } package() { cd "${srcdir}/leocad-git" mkdir -p ${pkgdir}/usr/bin mkdir -p ${pkgdir}/usr/share/leocad install -m 755 build/release/leocad ${pkgdir}/usr/bin install -m 644 docs/README.md ${pkgdir}/usr/share/leocad/README.md install -m 644 docs/CREDITS.txt ${pkgdir}/usr/share/leocad/CREDITS.txt install -m 644 docs/COPYING.txt ${pkgdir}/usr/share/leocad/COPYING.txt mkdir -p ${pkgdir}/usr/share/mime/packages/ mkdir -p ${pkgdir}/usr/share/applications/ mkdir -p ${pkgdir}/usr/share/icons/hicolor/scalable/mimetypes install -m 644 qt/leocad.xml \ ${pkgdir}/usr/share/mime/packages/leocad.xml install -m 644 qt/leocad.desktop \ ${pkgdir}/usr/share/applications/leocad.desktop install -m 644 resources/application-vnd.leocad.svg \ ${pkgdir}/usr/share/icons/hicolor/scalable/mimetypes/application-vnd.leocad.svg make INSTALL_ROOT="${pkgdir}" install } leocad-23.03/appveyor.yml000066400000000000000000000122401440571307300153430ustar00rootroot00000000000000version: '{branch}.{build}' image: - Ubuntu1604 - macos - Visual Studio 2019 configuration: Release platform: x64 environment: GITHUB_TOKEN: secure: ZaApxtWM3JA1AdJqs2pv+BCE5XIUrrVKXNy05q8f6f4zRZ7H/lMEJ6gZ1o2yp6NT for: - matrix: only: - image: Visual Studio 2019 before_build: - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" - set PATH=C:\Qt\5.15\msvc2019_64\bin;%PATH% - git rev-parse --short HEAD > version.txt - set /p VERSION= < version.txt - qmake -v - qmake -tp vc build: project: leocad.vcxproj verbosity: minimal after_build: - 7z a symbols.zip build/release/leocad.exe build/release/leocad.pdb - mkdir appdir - copy build\release\leocad.exe appdir - copy docs\readme.md appdir\readme.txt - appveyor DownloadFile https://github.com/leozide/leocad/releases/download/v21.06/Library-23.01.zip -FileName library.zip - 7z e library.zip - copy library.bin appdir\\library.bin - appveyor DownloadFile https://github.com/leozide/povray/releases/download/continuous/povconsole32-sse2.exe -FileName appdir\povconsole32-sse2.exe - windeployqt appdir\leocad.exe - copy tools\setup\leocad.nsi . - copy tools\setup\setup.ico . - 'copy "%VCToolsRedistDir%\vcredist_x64.exe" appdir' - '"C:\Program Files (x86)\NSIS\makensis.exe" /V4 /DX64 "/XOutFile LeoCAD-Windows-%VERSION%.exe" leocad.nsi' - set TRAVIS_TAG=%APPVEYOR_REPO_TAG_NAME% - set TRAVIS_REPO_SLUG=%APPVEYOR_REPO_NAME% - set TRAVIS_COMMIT=%APPVEYOR_REPO_COMMIT% - appveyor DownloadFile https://github.com/probonopd/uploadtool/raw/master/upload.sh - if not defined APPVEYOR_PULL_REQUEST_NUMBER (bash upload.sh LeoCAD*.exe) artifacts: - path: symbols.zip name: symbols - path: LeoCAD-Windows-$(VERSION).exe name: leocad - matrix: only: - image: Ubuntu1604 install: - sudo apt-get -y install libqt5opengl5-dev libxcb-xinerama0 before_build: - export PATH=$HOME/Qt/5.15/gcc_64/bin:$PATH - export TRAVIS_TAG=$APPVEYOR_REPO_TAG_NAME - export TRAVIS_REPO_SLUG=$APPVEYOR_REPO_NAME - export TRAVIS_COMMIT=$APPVEYOR_REPO_COMMIT build_script: - qmake PREFIX=/usr - make after_build: - make install INSTALL_ROOT=AppDir - appveyor DownloadFile https://github.com/leozide/leocad/releases/download/v21.06/Library-23.01.zip -FileName library.zip - unzip library.zip - mkdir -p AppDir/usr/share/leocad - mv library.bin AppDir/usr/share/leocad/library.bin - cp qt/leocad.desktop AppDir/leocad.desktop - cp tools/icon/256x256/apps/leocad.png AppDir/leocad.png - appveyor DownloadFile https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage - chmod a+x linuxdeployqt*.AppImage - unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH - export VERSION=$(git rev-parse --short HEAD) - ./linuxdeployqt*.AppImage ./AppDir/usr/share/applications/*.desktop -bundle-non-qt-libs - ./linuxdeployqt*.AppImage --appimage-extract - export PATH=$(readlink -f ./squashfs-root/usr/bin/):$PATH - ./squashfs-root/usr/bin/appimagetool AppDir/ - mv ./LeoCAD-$VERSION-x86_64.AppImage ./LeoCAD-Linux-$VERSION-x86_64.AppImage - 'curl -s -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/leozide/leocad/commits/master -o repo.txt' - 'export REMOTE=$(grep -Po ''(?<=: \")(([a-z0-9])\w+)(?=\")'' -m 1 repo.txt)' - export LOCAL=$(git rev-parse HEAD) - if [[ "$REMOTE" != "$LOCAL" ]]; then echo "Build no longer current. $REMOTE vs $LOCAL - aborting upload."; exit 0; fi; - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh - bash upload.sh LeoCAD*.AppImage* - matrix: only: - image: macos install: - brew install grep before_build: - export PATH=$HOME/Qt/5.15/clang_64/bin:$PATH - export TRAVIS_TAG=$APPVEYOR_REPO_TAG_NAME - export TRAVIS_REPO_SLUG=$APPVEYOR_REPO_NAME - export TRAVIS_COMMIT=$APPVEYOR_REPO_COMMIT - appveyor DownloadFile https://github.com/leozide/povray/releases/download/continuous/povray - chmod +x povray - appveyor DownloadFile https://github.com/leozide/leocad/releases/download/v21.06/Library-23.01.zip -FileName library.zip - unzip library.zip build_script: - qmake PREFIX=/usr - make after_build: - cd build/release - macdeployqt LeoCAD.app -dmg - mv LeoCAD.dmg LeoCAD-macOS-$(git rev-parse --short HEAD).dmg - 'curl -s -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/leozide/leocad/commits/master -o repo.txt' - 'export REMOTE=$(ggrep -Po ''(?<=: \")(([a-z0-9])\w+)(?=\")'' -m 1 repo.txt)' - export LOCAL=$(git rev-parse HEAD) - if [[ "$REMOTE" != "$LOCAL" ]]; then echo "Build no longer current. $REMOTE vs $LOCAL - aborting upload."; exit 0; fi; - appveyor DownloadFile https://github.com/probonopd/uploadtool/raw/master/upload.sh - bash upload.sh LeoCAD*.dmg* leocad-23.03/common/000077500000000000000000000000001440571307300142445ustar00rootroot00000000000000leocad-23.03/common/camera.cpp000066400000000000000000000763611440571307300162150ustar00rootroot00000000000000#include "lc_global.h" #include "lc_math.h" #include "lc_colors.h" #include #include #include #include #include "lc_file.h" #include "camera.h" #include "lc_application.h" #include "lc_context.h" #define LC_CAMERA_POSITION_EDGE 7.5f #define LC_CAMERA_TARGET_EDGE 7.5f #define LC_CAMERA_SAVE_VERSION 7 // LeoCAD 0.80 lcCamera::lcCamera(bool Simple) : lcObject(lcObjectType::Camera) { Initialize(); if (Simple) mState |= LC_CAMERA_SIMPLE; else { mPosition = lcVector3(-250.0f, -250.0f, 75.0f); mTargetPosition = lcVector3(0.0f, 0.0f, 0.0f); mUpVector = lcVector3(-0.2357f, -0.2357f, 0.94281f); mPositionKeys.ChangeKey(mPosition, 1, true); mTargetPositionKeys.ChangeKey(mTargetPosition, 1, true); mUpVectorKeys.ChangeKey(mUpVector, 1, true); UpdatePosition(1); } } lcCamera::lcCamera(float ex, float ey, float ez, float tx, float ty, float tz) : lcObject(lcObjectType::Camera) { // Fix the up vector lcVector3 UpVector(0, 0, 1), FrontVector(ex - tx, ey - ty, ez - tz), SideVector; FrontVector.Normalize(); if (FrontVector == UpVector) SideVector = lcVector3(1, 0, 0); else SideVector = lcCross(FrontVector, UpVector); UpVector = lcCross(SideVector, FrontVector); UpVector.Normalize(); Initialize(); mPositionKeys.ChangeKey(lcVector3(ex, ey, ez), 1, true); mTargetPositionKeys.ChangeKey(lcVector3(tx, ty, tz), 1, true); mUpVectorKeys.ChangeKey(UpVector, 1, true); UpdatePosition(1); } lcCamera::~lcCamera() { } lcViewpoint lcCamera::GetViewpoint(const QString& ViewpointName) { const QLatin1String ViewpointNames[] = { QLatin1String("front"), QLatin1String("back"), QLatin1String("top"), QLatin1String("bottom"), QLatin1String("left"), QLatin1String("right"), QLatin1String("home") }; LC_ARRAY_SIZE_CHECK(ViewpointNames, lcViewpoint::Count); for (int ViewpointIndex = 0; ViewpointIndex < static_cast(lcViewpoint::Count); ViewpointIndex++) if (ViewpointNames[ViewpointIndex] == ViewpointName) return static_cast(ViewpointIndex); return lcViewpoint::Count; } void lcCamera::Initialize() { m_fovy = 30.0f; m_zNear = 25.0f; m_zFar = 50000.0f; mState = 0; } void lcCamera::SetName(const QString& Name) { mName = Name; } void lcCamera::CreateName(const lcArray& Cameras) { if (!mName.isEmpty()) { bool Found = false; for (const lcCamera* Camera : Cameras) { if (Camera->GetName() == mName) { Found = true; break; } } if (!Found) return; } int MaxCameraNumber = 0; const QLatin1String Prefix("Camera "); for (const lcCamera* Camera : Cameras) { QString CameraName = Camera->GetName(); if (CameraName.startsWith(Prefix)) { bool Ok = false; int CameraNumber = CameraName.mid(Prefix.size()).toInt(&Ok); if (Ok && CameraNumber > MaxCameraNumber) MaxCameraNumber = CameraNumber; } } mName = Prefix + QString::number(MaxCameraNumber + 1); } void lcCamera::SaveLDraw(QTextStream& Stream) const { const QLatin1String LineEnding("\r\n"); Stream << QLatin1String("0 !LEOCAD CAMERA FOV ") << m_fovy << QLatin1String(" ZNEAR ") << m_zNear << QLatin1String(" ZFAR ") << m_zFar << LineEnding; if (mPositionKeys.GetSize() > 1) mPositionKeys.SaveKeysLDraw(Stream, "CAMERA POSITION_KEY "); else Stream << QLatin1String("0 !LEOCAD CAMERA POSITION ") << mPosition[0] << ' ' << mPosition[1] << ' ' << mPosition[2] << LineEnding; if (mTargetPositionKeys.GetSize() > 1) mTargetPositionKeys.SaveKeysLDraw(Stream, "CAMERA TARGET_POSITION_KEY "); else Stream << QLatin1String("0 !LEOCAD CAMERA TARGET_POSITION ") << mTargetPosition[0] << ' ' << mTargetPosition[1] << ' ' << mTargetPosition[2] << LineEnding; if (mUpVectorKeys.GetSize() > 1) mUpVectorKeys.SaveKeysLDraw(Stream, "CAMERA UP_VECTOR_KEY "); else Stream << QLatin1String("0 !LEOCAD CAMERA UP_VECTOR ") << mUpVector[0] << ' ' << mUpVector[1] << ' ' << mUpVector[2] << LineEnding; Stream << QLatin1String("0 !LEOCAD CAMERA "); if (IsHidden()) Stream << QLatin1String("HIDDEN"); if (IsOrtho()) Stream << QLatin1String("ORTHOGRAPHIC "); Stream << QLatin1String("NAME ") << mName << LineEnding; } bool lcCamera::ParseLDrawLine(QTextStream& Stream) { while (!Stream.atEnd()) { QString Token; Stream >> Token; if (Token == QLatin1String("HIDDEN")) SetHidden(true); else if (Token == QLatin1String("ORTHOGRAPHIC")) SetOrtho(true); else if (Token == QLatin1String("FOV")) Stream >> m_fovy; else if (Token == QLatin1String("ZNEAR")) Stream >> m_zNear; else if (Token == QLatin1String("ZFAR")) Stream >> m_zFar; else if (Token == QLatin1String("POSITION")) { Stream >> mPosition[0] >> mPosition[1] >> mPosition[2]; mPositionKeys.ChangeKey(mPosition, 1, true); } else if (Token == QLatin1String("TARGET_POSITION")) { Stream >> mTargetPosition[0] >> mTargetPosition[1] >> mTargetPosition[2]; mTargetPositionKeys.ChangeKey(mTargetPosition, 1, true); } else if (Token == QLatin1String("UP_VECTOR")) { Stream >> mUpVector[0] >> mUpVector[1] >> mUpVector[2]; mUpVectorKeys.ChangeKey(mUpVector, 1, true); } else if (Token == QLatin1String("POSITION_KEY")) mPositionKeys.LoadKeysLDraw(Stream); else if (Token == QLatin1String("TARGET_POSITION_KEY")) mTargetPositionKeys.LoadKeysLDraw(Stream); else if (Token == QLatin1String("UP_VECTOR_KEY")) mUpVectorKeys.LoadKeysLDraw(Stream); else if (Token == QLatin1String("NAME")) { mName = Stream.readAll().trimmed(); return true; } } return false; } ///////////////////////////////////////////////////////////////////////////// // Camera save/load bool lcCamera::FileLoad(lcFile& file) { quint8 version, ch; version = file.ReadU8(); if (version > LC_CAMERA_SAVE_VERSION) return false; if (version > 5) { if (file.ReadU8() != 1) return false; quint16 time; float param[4]; quint8 type; quint32 n; file.ReadU32(&n, 1); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 4); file.ReadU8(&type, 1); } file.ReadU32(&n, 1); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 4); file.ReadU8(&type, 1); } } if (version == 4) { char Name[81]; file.ReadBuffer(Name, 80); } else { ch = file.ReadU8(); if (ch == 0xFF) return false; char Name[81]; file.ReadBuffer(Name, ch); } if (version < 3) { double d[3]; file.ReadDoubles(d, 3); file.ReadDoubles(d, 3); file.ReadDoubles(d, 3); } if (version == 3) { ch = file.ReadU8(); while (ch--) { quint8 step; double eye[3], target[3], up[3]; file.ReadDoubles(eye, 3); file.ReadDoubles(target, 3); file.ReadDoubles(up, 3); file.ReadU8(&step, 1); file.ReadS32(); // snapshot file.ReadS32(); // cam } } if (version < 4) { file.ReadDouble(); // m_fovy file.ReadDouble(); // m_zFar file.ReadDouble(); // m_zNear } else { qint32 n; if (version < 6) { quint16 time; float param[4]; quint8 type; n = file.ReadS32(); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 3); file.ReadU8(&type, 1); } n = file.ReadS32(); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 3); file.ReadU8(&type, 1); } } float f; file.ReadFloats(&f, 1); // m_fovy file.ReadFloats(&f, 1); // m_zFar file.ReadFloats(&f, 1); // m_zNear if (version < 5) { n = file.ReadS32(); } else { ch = file.ReadU8(); file.ReadU8(); } } if ((version > 1) && (version < 4)) { quint32 show; qint32 user; file.ReadU32(&show, 1); // if (version > 2) file.ReadS32(&user, 1); } return true; } void lcCamera::CompareBoundingBox(lcVector3& Min, lcVector3& Max) { const lcVector3 Points[2] = { mPosition, mTargetPosition }; for (int i = 0; i < 2; i++) { const lcVector3& Point = Points[i]; // TODO: this should check the entire mesh Min = lcMin(Point, Min); Max = lcMax(Point, Max); } } void lcCamera::MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance) { if (IsSimple()) AddKey = false; if (IsSelected(LC_CAMERA_SECTION_POSITION)) { mPosition += Distance; mPositionKeys.ChangeKey(mPosition, Step, AddKey); } if (IsSelected(LC_CAMERA_SECTION_TARGET)) { mTargetPosition += Distance; mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey); } else if (IsSelected(LC_CAMERA_SECTION_UPVECTOR)) { mUpVector += Distance; mUpVector.Normalize(); mUpVectorKeys.ChangeKey(mUpVector, Step, AddKey); } const lcVector3 FrontVector(mTargetPosition - mPosition); lcVector3 SideVector = lcCross(FrontVector, mUpVector); if (fabsf(lcDot(mUpVector, SideVector)) > 0.99f) SideVector = lcVector3(1, 0, 0); mUpVector = lcCross(SideVector, FrontVector); mUpVector.Normalize(); } void lcCamera::MoveRelative(const lcVector3& Distance, lcStep Step, bool AddKey) { if (IsSimple()) AddKey = false; const lcVector3 Relative = lcMul30(Distance, lcMatrix44Transpose(mWorldView)) * 5.0f; mPosition += Relative; mPositionKeys.ChangeKey(mPosition, Step, AddKey); mTargetPosition += Relative; mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey); UpdatePosition(Step); } void lcCamera::UpdatePosition(lcStep Step) { if (!IsSimple()) { mPosition = mPositionKeys.CalculateKey(Step); mTargetPosition = mTargetPositionKeys.CalculateKey(Step); mUpVector = mUpVectorKeys.CalculateKey(Step); } const lcVector3 FrontVector(mPosition - mTargetPosition); const lcVector3 SideVector = lcCross(FrontVector, mUpVector); mUpVector = lcNormalize(lcCross(SideVector, FrontVector)); mWorldView = lcMatrix44LookAt(mPosition, mTargetPosition, mUpVector); } void lcCamera::CopyPosition(const lcCamera* Camera) { m_fovy = Camera->m_fovy; m_zNear = Camera->m_zNear; m_zFar = Camera->m_zFar; mWorldView = Camera->mWorldView; mPosition = Camera->mPosition; mTargetPosition = Camera->mTargetPosition; mUpVector = Camera->mUpVector; mState |= (Camera->mState & LC_CAMERA_ORTHO); } void lcCamera::CopySettings(const lcCamera* camera) { m_fovy = camera->m_fovy; m_zNear = camera->m_zNear; m_zFar = camera->m_zFar; mState |= (camera->mState & LC_CAMERA_ORTHO); } void lcCamera::DrawInterface(lcContext* Context, const lcScene& Scene) const { Q_UNUSED(Scene); Context->SetMaterial(lcMaterialType::UnlitColor); lcMatrix44 ViewWorldMatrix = lcMatrix44AffineInverse(mWorldView); ViewWorldMatrix.SetTranslation(lcVector3(0, 0, 0)); const lcMatrix44 CameraViewMatrix = lcMul(ViewWorldMatrix, lcMatrix44Translation(mPosition)); Context->SetWorldMatrix(CameraViewMatrix); float Verts[(12 + 8 + 8 + 3 + 4) * 3]; float* CurVert = Verts; float Length = lcLength(mPosition - mTargetPosition); *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE * 2; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE * 2; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE * 2; *CurVert++ = LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE; *CurVert++ = -LC_CAMERA_POSITION_EDGE * 2; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE - Length; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE - Length; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE - Length; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE - Length; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE - Length; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE - Length; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE - Length; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE - Length; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE + 25.0f; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE + 25.0f; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE + 25.0f; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE + 25.0f; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE + 25.0f; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE + 25.0f; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE + 25.0f; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = LC_CAMERA_TARGET_EDGE; *CurVert++ = -LC_CAMERA_TARGET_EDGE + 25.0f; *CurVert++ = -LC_CAMERA_TARGET_EDGE; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = -Length; *CurVert++ = 0.0f; *CurVert++ = 25.0f; *CurVert++ = 0.0f; const GLushort Indices[40 + 24 + 24 + 4 + 16] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7, 8, 9, 9, 10, 10, 11, 11, 8, 8, 28, 9, 28, 10, 28, 11, 28, 12, 13, 13, 14, 14, 15, 15, 12, 16, 17, 17, 18, 18, 19, 19, 16, 12, 16, 13, 17, 14, 18, 15, 19, 20, 21, 21, 22, 22, 23, 23, 20, 24, 25, 25, 26, 26, 27, 27, 24, 20, 24, 21, 25, 22, 26, 23, 27, 28, 29, 28, 30, 31, 32, 32, 33, 33, 34, 34, 31, 28, 31, 28, 32, 28, 33, 28, 34 }; Context->SetVertexBufferPointer(Verts); Context->SetVertexFormatPosition(3); Context->SetIndexBufferPointer(Indices); const lcPreferences& Preferences = lcGetPreferences(); const float LineWidth = Preferences.mLineWidth; const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor); const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor); const lcVector4 CameraColor = lcVector4FromColor(Preferences.mCameraColor); if (!IsSelected()) { Context->SetLineWidth(LineWidth); Context->SetColor(CameraColor); Context->DrawIndexedPrimitives(GL_LINES, 40 + 24 + 24 + 4, GL_UNSIGNED_SHORT, 0); } else { if (IsSelected(LC_CAMERA_SECTION_POSITION)) { Context->SetLineWidth(2.0f * LineWidth); if (IsFocused(LC_CAMERA_SECTION_POSITION)) Context->SetColor(FocusedColor); else Context->SetColor(SelectedColor); } else { Context->SetLineWidth(LineWidth); Context->SetColor(CameraColor); } Context->DrawIndexedPrimitives(GL_LINES, 40, GL_UNSIGNED_SHORT, 0); if (IsSelected(LC_CAMERA_SECTION_TARGET)) { Context->SetLineWidth(2.0f * LineWidth); if (IsFocused(LC_CAMERA_SECTION_TARGET)) Context->SetColor(FocusedColor); else Context->SetColor(SelectedColor); } else { Context->SetLineWidth(LineWidth); Context->SetColor(CameraColor); } Context->DrawIndexedPrimitives(GL_LINES, 24, GL_UNSIGNED_SHORT, 40 * 2); if (IsSelected(LC_CAMERA_SECTION_UPVECTOR)) { Context->SetLineWidth(2.0f * LineWidth); if (IsFocused(LC_CAMERA_SECTION_UPVECTOR)) Context->SetColor(FocusedColor); else Context->SetColor(SelectedColor); } else { Context->SetLineWidth(LineWidth); Context->SetColor(CameraColor); } Context->DrawIndexedPrimitives(GL_LINES, 24, GL_UNSIGNED_SHORT, (40 + 24) * 2); Context->SetColor(CameraColor); Context->SetLineWidth(LineWidth); float SizeY = tanf(LC_DTOR * m_fovy / 2) * Length; float SizeX = SizeY * 1.333f; *CurVert++ = SizeX; *CurVert++ = SizeY; *CurVert++ = -Length; *CurVert++ = -SizeX; *CurVert++ = SizeY; *CurVert++ = -Length; *CurVert++ = -SizeX; *CurVert++ = -SizeY; *CurVert++ = -Length; *CurVert++ = SizeX; *CurVert++ = -SizeY; *CurVert++ = -Length; Context->DrawIndexedPrimitives(GL_LINES, 4 + 16, GL_UNSIGNED_SHORT, (40 + 24 + 24) * 2); } } void lcCamera::RemoveKeyFrames() { mPositionKeys.RemoveAll(); mPositionKeys.ChangeKey(mPosition, 1, true); mTargetPositionKeys.RemoveAll(); mTargetPositionKeys.ChangeKey(mTargetPosition, 1, true); mUpVectorKeys.RemoveAll(); mUpVectorKeys.ChangeKey(mUpVector, 1, true); } void lcCamera::RayTest(lcObjectRayTest& ObjectRayTest) const { lcVector3 Min = lcVector3(-LC_CAMERA_POSITION_EDGE, -LC_CAMERA_POSITION_EDGE, -LC_CAMERA_POSITION_EDGE); lcVector3 Max = lcVector3(LC_CAMERA_POSITION_EDGE, LC_CAMERA_POSITION_EDGE, LC_CAMERA_POSITION_EDGE); lcVector3 Start = lcMul31(ObjectRayTest.Start, mWorldView); lcVector3 End = lcMul31(ObjectRayTest.End, mWorldView); float Distance; lcVector3 Plane; if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, nullptr, &Plane) && (Distance < ObjectRayTest.Distance)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_POSITION; ObjectRayTest.Distance = Distance; ObjectRayTest.PieceInfoRayTest.Plane = Plane; } Min = lcVector3(-LC_CAMERA_TARGET_EDGE, -LC_CAMERA_TARGET_EDGE, -LC_CAMERA_TARGET_EDGE); Max = lcVector3(LC_CAMERA_TARGET_EDGE, LC_CAMERA_TARGET_EDGE, LC_CAMERA_TARGET_EDGE); lcMatrix44 WorldView = mWorldView; WorldView.SetTranslation(lcMul30(-mTargetPosition, WorldView)); Start = lcMul31(ObjectRayTest.Start, WorldView); End = lcMul31(ObjectRayTest.End, WorldView); if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, nullptr, &Plane) && (Distance < ObjectRayTest.Distance)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_TARGET; ObjectRayTest.Distance = Distance; ObjectRayTest.PieceInfoRayTest.Plane = Plane; } const lcMatrix44 ViewWorld = lcMatrix44AffineInverse(mWorldView); const lcVector3 UpVectorPosition = lcMul31(lcVector3(0, 25, 0), ViewWorld); WorldView = mWorldView; WorldView.SetTranslation(lcMul30(-UpVectorPosition, WorldView)); Start = lcMul31(ObjectRayTest.Start, WorldView); End = lcMul31(ObjectRayTest.End, WorldView); if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, nullptr, &Plane) && (Distance < ObjectRayTest.Distance)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_UPVECTOR; ObjectRayTest.Distance = Distance; ObjectRayTest.PieceInfoRayTest.Plane = Plane; } } void lcCamera::BoxTest(lcObjectBoxTest& ObjectBoxTest) const { lcVector3 Min(-LC_CAMERA_POSITION_EDGE, -LC_CAMERA_POSITION_EDGE, -LC_CAMERA_POSITION_EDGE); lcVector3 Max(LC_CAMERA_POSITION_EDGE, LC_CAMERA_POSITION_EDGE, LC_CAMERA_POSITION_EDGE); lcVector4 LocalPlanes[6]; for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) { const lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], mWorldView); LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(mWorldView[3], Normal)); } if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes)) { ObjectBoxTest.Objects.Add(const_cast(this)); return; } Min = lcVector3(-LC_CAMERA_TARGET_EDGE, -LC_CAMERA_TARGET_EDGE, -LC_CAMERA_TARGET_EDGE); Max = lcVector3(LC_CAMERA_TARGET_EDGE, LC_CAMERA_TARGET_EDGE, LC_CAMERA_TARGET_EDGE); lcMatrix44 WorldView = mWorldView; WorldView.SetTranslation(lcMul30(-mTargetPosition, WorldView)); for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) { const lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], WorldView); LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(WorldView[3], Normal)); } if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes)) { ObjectBoxTest.Objects.Add(const_cast(this)); return; } const lcMatrix44 ViewWorld = lcMatrix44AffineInverse(mWorldView); const lcVector3 UpVectorPosition = lcMul31(lcVector3(0, 25, 0), ViewWorld); WorldView = mWorldView; WorldView.SetTranslation(lcMul30(-UpVectorPosition, WorldView)); for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) { const lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], WorldView); LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(WorldView[3], Normal)); } if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes)) { ObjectBoxTest.Objects.Add(const_cast(this)); return; } } void lcCamera::InsertTime(lcStep Start, lcStep Time) { mPositionKeys.InsertTime(Start, Time); mTargetPositionKeys.InsertTime(Start, Time); mUpVectorKeys.InsertTime(Start, Time); } void lcCamera::RemoveTime(lcStep Start, lcStep Time) { mPositionKeys.RemoveTime(Start, Time); mTargetPositionKeys.RemoveTime(Start, Time); mUpVectorKeys.RemoveTime(Start, Time); } void lcCamera::ZoomExtents(float AspectRatio, const lcVector3& Center, const std::vector& Points, lcStep Step, bool AddKey) { if (IsOrtho()) { float MinX = FLT_MAX, MaxX = -FLT_MAX, MinY = FLT_MAX, MaxY = -FLT_MAX; for (lcVector3 Point : Points) { Point = lcMul30(Point, mWorldView); MinX = lcMin(MinX, Point.x); MinY = lcMin(MinY, Point.y); MaxX = lcMax(MaxX, Point.x); MaxY = lcMax(MaxY, Point.y); } const lcVector3 ViewCenter = lcMul30(Center, mWorldView); float Width = qMax(fabsf(MaxX - ViewCenter.x), fabsf(ViewCenter.x - MinX)) * 2; float Height = qMax(fabsf(MaxY - ViewCenter.y), fabsf(ViewCenter.y - MinY)) * 2; if (Width > Height * AspectRatio) Height = Width / AspectRatio; const float f = Height / (m_fovy * (LC_PI / 180.0f)); const lcVector3 FrontVector(mTargetPosition - mPosition); mPosition = Center - lcNormalize(FrontVector) * f; mTargetPosition = Center; } else { const lcVector3 Position(mPosition + Center - mTargetPosition); const lcMatrix44 ProjectionMatrix = lcMatrix44Perspective(m_fovy, AspectRatio, m_zNear, m_zFar); std::tie(mPosition, std::ignore) = lcZoomExtents(Position, mWorldView, ProjectionMatrix, Points.data(), Points.size()); mTargetPosition = Center; } if (IsSimple()) AddKey = false; mPositionKeys.ChangeKey(mPosition, Step, AddKey); mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey); UpdatePosition(Step); } void lcCamera::ZoomRegion(float AspectRatio, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners, lcStep Step, bool AddKey) { if (IsOrtho()) { float MinX = FLT_MAX, MaxX = -FLT_MAX, MinY = FLT_MAX, MaxY = -FLT_MAX; for (int PointIdx = 0; PointIdx < 2; PointIdx++) { const lcVector3 Point = lcMul30(Corners[PointIdx], mWorldView); MinX = lcMin(MinX, Point.x); MinY = lcMin(MinY, Point.y); MaxX = lcMax(MaxX, Point.x); MaxY = lcMax(MaxY, Point.y); } float Width = MaxX - MinX; float Height = MaxY - MinY; if (Width > Height * AspectRatio) Height = Width / AspectRatio; const float f = Height / (m_fovy * (LC_PI / 180.0f)); const lcVector3 FrontVector(mTargetPosition - mPosition); mPosition = TargetPosition - lcNormalize(FrontVector) * f; mTargetPosition = TargetPosition; } else { const lcMatrix44 WorldView = lcMatrix44LookAt(Position, TargetPosition, mUpVector); const lcMatrix44 ProjectionMatrix = lcMatrix44Perspective(m_fovy, AspectRatio, m_zNear, m_zFar); std::tie(mPosition, std::ignore) = lcZoomExtents(Position, WorldView, ProjectionMatrix, Corners, 2); mTargetPosition = TargetPosition; } if (IsSimple()) AddKey = false; mPositionKeys.ChangeKey(mPosition, Step, AddKey); mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey); UpdatePosition(Step); } void lcCamera::Zoom(float Distance, lcStep Step, bool AddKey) { lcVector3 FrontVector(mPosition - mTargetPosition); FrontVector.Normalize(); FrontVector *= -5.0f * Distance; // Don't zoom ortho in if it would cross the ortho focal plane. if (IsOrtho()) { if ((Distance > 0) && (lcDot(mPosition + FrontVector - mTargetPosition, mPosition - mTargetPosition) <= 0)) return; mPosition += FrontVector; } else { mPosition += FrontVector; mTargetPosition += FrontVector; } if (IsSimple()) AddKey = false; mPositionKeys.ChangeKey(mPosition, Step, AddKey); mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey); UpdatePosition(Step); } void lcCamera::Pan(const lcVector3& Distance, lcStep Step, bool AddKey) { mPosition += Distance; mTargetPosition += Distance; if (IsSimple()) AddKey = false; mPositionKeys.ChangeKey(mPosition, Step, AddKey); mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey); UpdatePosition(Step); } void lcCamera::Orbit(float DistanceX, float DistanceY, const lcVector3& CenterPosition, lcStep Step, bool AddKey) { lcVector3 FrontVector(mPosition - mTargetPosition); lcVector3 Z(lcNormalize(lcVector3(FrontVector[0], FrontVector[1], 0))); if (qIsNaN(Z[0]) || qIsNaN(Z[1])) Z = lcNormalize(lcVector3(mUpVector[0], mUpVector[1], 0)); if (mUpVector[2] < 0) { Z[0] = -Z[0]; Z[1] = -Z[1]; } const lcMatrix44 YRot(lcVector4(Z[0], Z[1], 0.0f, 0.0f), lcVector4(-Z[1], Z[0], 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f)); const lcMatrix44 transform = lcMul(lcMul(lcMul(lcMatrix44AffineInverse(YRot), lcMatrix44RotationY(DistanceY)), YRot), lcMatrix44RotationZ(-DistanceX)); mPosition = lcMul31(mPosition - CenterPosition, transform) + CenterPosition; mTargetPosition = lcMul31(mTargetPosition - CenterPosition, transform) + CenterPosition; mUpVector = lcMul31(mUpVector, transform); if (IsSimple()) AddKey = false; mPositionKeys.ChangeKey(mPosition, Step, AddKey); mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey); mUpVectorKeys.ChangeKey(mUpVector, Step, AddKey); UpdatePosition(Step); } void lcCamera::Roll(float Distance, lcStep Step, bool AddKey) { const lcVector3 FrontVector(mPosition - mTargetPosition); const lcMatrix44 Rotation = lcMatrix44FromAxisAngle(FrontVector, Distance); mUpVector = lcMul30(mUpVector, Rotation); if (IsSimple()) AddKey = false; mUpVectorKeys.ChangeKey(mUpVector, Step, AddKey); UpdatePosition(Step); } void lcCamera::Center(const lcVector3& NewCenter, lcStep Step, bool AddKey) { const lcMatrix44 Inverse = lcMatrix44AffineInverse(mWorldView); const lcVector3 Direction = -lcVector3(Inverse[2]); // float Yaw, Pitch, Roll; float Roll; if (fabsf(Direction.z) < 0.9999f) { // Yaw = atan2f(Direction.y, Direction.x); // Pitch = asinf(Direction.z); Roll = atan2f(Inverse[0][2], Inverse[1][2]); } else { // Yaw = 0.0f; // Pitch = asinf(Direction.z); Roll = atan2f(Inverse[0][1], Inverse[1][1]); } mTargetPosition = NewCenter; lcVector3 FrontVector(mPosition - mTargetPosition); const lcMatrix44 Rotation = lcMatrix44FromAxisAngle(FrontVector, Roll); lcVector3 UpVector(0, 0, 1), SideVector; FrontVector.Normalize(); if (fabsf(lcDot(UpVector, FrontVector)) > 0.99f) SideVector = lcVector3(-1, 0, 0); else SideVector = lcCross(FrontVector, UpVector); UpVector = lcCross(SideVector, FrontVector); UpVector.Normalize(); mUpVector = lcMul30(UpVector, Rotation); if (IsSimple()) AddKey = false; mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey); mUpVectorKeys.ChangeKey(mUpVector, Step, AddKey); UpdatePosition(Step); } void lcCamera::SetViewpoint(lcViewpoint Viewpoint) { lcVector3 Positions[] = { lcVector3( 0.0f, -1250.0f, 0.0f), // lcViewpoint::Front lcVector3( 0.0f, 1250.0f, 0.0f), // lcViewpoint::Back lcVector3( 0.0f, 0.0f, 1250.0f), // lcViewpoint::Top lcVector3( 0.0f, 0.0f, -1250.0f), // lcViewpoint::Bottom lcVector3( 1250.0f, 0.0f, 0.0f), // lcViewpoint::Left lcVector3(-1250.0f, 0.0f, 0.0f), // lcViewpoint::Right lcVector3( 375.0f, -375.0f, 187.5f) // lcViewpoint::Home }; lcVector3 Ups[] = { lcVector3(0.0f, 0.0f, 1.0f), lcVector3(0.0f, 0.0f, 1.0f), lcVector3(0.0f, 1.0f, 0.0f), lcVector3(0.0f,-1.0f, 0.0f), lcVector3(0.0f, 0.0f, 1.0f), lcVector3(0.0f, 0.0f, 1.0f), lcVector3(0.2357f, -0.2357f, 0.94281f) }; mPosition = Positions[static_cast(Viewpoint)]; mTargetPosition = lcVector3(0, 0, 0); mUpVector = Ups[static_cast(Viewpoint)]; mPositionKeys.ChangeKey(mPosition, 1, false); mTargetPositionKeys.ChangeKey(mTargetPosition, 1, false); mUpVectorKeys.ChangeKey(mUpVector, 1, false); UpdatePosition(1); } void lcCamera::SetViewpoint(const lcVector3& Position) { mPosition = Position; mTargetPosition = lcVector3(0, 0, 0); lcVector3 UpVector(0, 0, 1), FrontVector(Position), SideVector; FrontVector.Normalize(); if (fabsf(lcDot(UpVector, FrontVector)) > 0.99f) SideVector = lcVector3(-1, 0, 0); else SideVector = lcCross(FrontVector, UpVector); UpVector = lcCross(SideVector, FrontVector); UpVector.Normalize(); mUpVector = UpVector; mPositionKeys.ChangeKey(mPosition, 1, false); mTargetPositionKeys.ChangeKey(mTargetPosition, 1, false); mUpVectorKeys.ChangeKey(mUpVector, 1, false); UpdatePosition(1); } void lcCamera::SetViewpoint(const lcVector3& Position, const lcVector3& Target, const lcVector3& Up) { mPosition = Position; mTargetPosition = Target; const lcVector3 Direction = Target - Position; lcVector3 UpVector, SideVector; SideVector = lcCross(Direction, Up); UpVector = lcCross(SideVector, Direction); UpVector.Normalize(); mUpVector = UpVector; mPositionKeys.ChangeKey(mPosition, 1, false); mTargetPositionKeys.ChangeKey(mTargetPosition, 1, false); mUpVectorKeys.ChangeKey(mUpVector, 1, false); UpdatePosition(1); } void lcCamera::SetAngles(float Latitude, float Longitude, float Distance) { mPosition = lcVector3(0, -1, 0); mTargetPosition = lcVector3(0, 0, 0); mUpVector = lcVector3(0, 0, 1); const lcMatrix33 LongitudeMatrix = lcMatrix33RotationZ(LC_DTOR * Longitude); mPosition = lcMul(mPosition, LongitudeMatrix); const lcVector3 SideVector = lcMul(lcVector3(-1, 0, 0), LongitudeMatrix); const lcMatrix33 LatitudeMatrix = lcMatrix33FromAxisAngle(SideVector, LC_DTOR * Latitude); mPosition = lcMul(mPosition, LatitudeMatrix) * Distance; mUpVector = lcMul(mUpVector, LatitudeMatrix); mPositionKeys.ChangeKey(mPosition, 1, false); mTargetPositionKeys.ChangeKey(mTargetPosition, 1, false); mUpVectorKeys.ChangeKey(mUpVector, 1, false); UpdatePosition(1); } void lcCamera::GetAngles(float& Latitude, float& Longitude, float& Distance) const { lcVector3 FrontVector(mPosition - mTargetPosition); const lcVector3 X(1, 0, 0); const lcVector3 Y(0, 1, 0); const lcVector3 Z(0, 0, 1); FrontVector.Normalize(); Latitude = acos(lcDot(-FrontVector, Z)) * LC_RTOD - 90.0f; const lcVector3 CameraXY = -lcNormalize(lcVector3(FrontVector.x, FrontVector.y, 0.0f)); Longitude = acos(lcDot(CameraXY, Y)) * LC_RTOD; if (lcDot(CameraXY, X) > 0) Longitude = -Longitude; Distance = lcLength(mPosition); } leocad-23.03/common/camera.h000066400000000000000000000176641440571307300156630ustar00rootroot00000000000000#pragma once #include "object.h" #include "lc_math.h" #include "lc_array.h" #define LC_CAMERA_HIDDEN 0x0001 #define LC_CAMERA_SIMPLE 0x0002 #define LC_CAMERA_ORTHO 0x0004 #define LC_CAMERA_POSITION_SELECTED 0x0010 #define LC_CAMERA_POSITION_FOCUSED 0x0020 #define LC_CAMERA_TARGET_SELECTED 0x0040 #define LC_CAMERA_TARGET_FOCUSED 0x0080 #define LC_CAMERA_UPVECTOR_SELECTED 0x0100 #define LC_CAMERA_UPVECTOR_FOCUSED 0x0200 #define LC_CAMERA_SELECTION_MASK (LC_CAMERA_POSITION_SELECTED | LC_CAMERA_TARGET_SELECTED | LC_CAMERA_UPVECTOR_SELECTED) #define LC_CAMERA_FOCUS_MASK (LC_CAMERA_POSITION_FOCUSED | LC_CAMERA_TARGET_FOCUSED | LC_CAMERA_UPVECTOR_FOCUSED) enum class lcViewpoint { Front, Back, Top, Bottom, Left, Right, Home, Count }; enum lcCameraSection { LC_CAMERA_SECTION_POSITION, LC_CAMERA_SECTION_TARGET, LC_CAMERA_SECTION_UPVECTOR }; class lcCamera : public lcObject { public: lcCamera(bool Simple); lcCamera(float ex, float ey, float ez, float tx, float ty, float tz); ~lcCamera(); lcCamera(const lcCamera&) = delete; lcCamera(lcCamera&&) = delete; lcCamera& operator=(const lcCamera&) = delete; lcCamera& operator=(lcCamera&&) = delete; static lcViewpoint GetViewpoint(const QString& ViewpointName); QString GetName() const override { return mName; } void SetName(const QString& Name); void CreateName(const lcArray& Cameras); bool IsSimple() const { return (mState & LC_CAMERA_SIMPLE) != 0; } bool IsOrtho() const { return (mState & LC_CAMERA_ORTHO) != 0; } void SetOrtho(bool Ortho) { if (Ortho) mState |= LC_CAMERA_ORTHO; else mState &= ~LC_CAMERA_ORTHO; } bool IsSelected() const override { return (mState & LC_CAMERA_SELECTION_MASK) != 0; } bool IsSelected(quint32 Section) const override { switch (Section) { case LC_CAMERA_SECTION_POSITION: return (mState & LC_CAMERA_POSITION_SELECTED) != 0; break; case LC_CAMERA_SECTION_TARGET: return (mState & LC_CAMERA_TARGET_SELECTED) != 0; break; case LC_CAMERA_SECTION_UPVECTOR: return (mState & LC_CAMERA_UPVECTOR_SELECTED) != 0; break; } return false; } void SetSelected(bool Selected) override { if (Selected) mState |= LC_CAMERA_SELECTION_MASK; else mState &= ~(LC_CAMERA_SELECTION_MASK | LC_CAMERA_FOCUS_MASK); } void SetSelected(quint32 Section, bool Selected) override { switch (Section) { case LC_CAMERA_SECTION_POSITION: if (Selected) mState |= LC_CAMERA_POSITION_SELECTED; else mState &= ~(LC_CAMERA_POSITION_SELECTED | LC_CAMERA_POSITION_FOCUSED); break; case LC_CAMERA_SECTION_TARGET: if (Selected) mState |= LC_CAMERA_TARGET_SELECTED; else mState &= ~(LC_CAMERA_TARGET_SELECTED | LC_CAMERA_TARGET_FOCUSED); break; case LC_CAMERA_SECTION_UPVECTOR: if (Selected) mState |= LC_CAMERA_UPVECTOR_SELECTED; else mState &= ~(LC_CAMERA_UPVECTOR_SELECTED | LC_CAMERA_UPVECTOR_FOCUSED); break; } } bool IsFocused() const override { return (mState & LC_CAMERA_FOCUS_MASK) != 0; } bool IsFocused(quint32 Section) const override { switch (Section) { case LC_CAMERA_SECTION_POSITION: return (mState & LC_CAMERA_POSITION_FOCUSED) != 0; break; case LC_CAMERA_SECTION_TARGET: return (mState & LC_CAMERA_TARGET_FOCUSED) != 0; break; case LC_CAMERA_SECTION_UPVECTOR: return (mState & LC_CAMERA_UPVECTOR_FOCUSED) != 0; break; } return false; } void SetFocused(quint32 Section, bool Focus) override { switch (Section) { case LC_CAMERA_SECTION_POSITION: if (Focus) mState |= LC_CAMERA_POSITION_SELECTED | LC_CAMERA_POSITION_FOCUSED; else mState &= ~(LC_CAMERA_POSITION_SELECTED | LC_CAMERA_POSITION_FOCUSED); break; case LC_CAMERA_SECTION_TARGET: if (Focus) mState |= LC_CAMERA_TARGET_SELECTED | LC_CAMERA_TARGET_FOCUSED; else mState &= ~(LC_CAMERA_TARGET_SELECTED | LC_CAMERA_TARGET_FOCUSED); break; case LC_CAMERA_SECTION_UPVECTOR: if (Focus) mState |= LC_CAMERA_UPVECTOR_SELECTED | LC_CAMERA_UPVECTOR_FOCUSED; else mState &= ~(LC_CAMERA_UPVECTOR_SELECTED | LC_CAMERA_UPVECTOR_FOCUSED); break; } } quint32 GetFocusSection() const override { if (mState & LC_CAMERA_POSITION_FOCUSED) return LC_CAMERA_SECTION_POSITION; if (mState & LC_CAMERA_TARGET_FOCUSED) return LC_CAMERA_SECTION_TARGET; if (mState & LC_CAMERA_UPVECTOR_FOCUSED) return LC_CAMERA_SECTION_UPVECTOR; return ~0U; } quint32 GetAllowedTransforms() const override { return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z; } lcVector3 GetSectionPosition(quint32 Section) const override { switch (Section) { case LC_CAMERA_SECTION_POSITION: return mPosition; case LC_CAMERA_SECTION_TARGET: return mTargetPosition; case LC_CAMERA_SECTION_UPVECTOR: return lcMul31(lcVector3(0, 25, 0), lcMatrix44AffineInverse(mWorldView)); } return lcVector3(0.0f, 0.0f, 0.0f); } void SaveLDraw(QTextStream& Stream) const; bool ParseLDrawLine(QTextStream& Stream); public: bool IsVisible() const { return (mState & LC_CAMERA_HIDDEN) == 0; } bool IsHidden() const { return (mState & LC_CAMERA_HIDDEN) != 0; } void SetHidden(bool Hidden) { if (Hidden) mState |= LC_CAMERA_HIDDEN; else mState &= ~LC_CAMERA_HIDDEN; } void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey) { mPositionKeys.ChangeKey(Position, Step, AddKey); } void SetTargetPosition(const lcVector3& TargetPosition, lcStep Step, bool AddKey) { mTargetPositionKeys.ChangeKey(TargetPosition, Step, AddKey); } void SetUpVector(const lcVector3& UpVector, lcStep Step, bool AddKey) { mPositionKeys.ChangeKey(UpVector, Step, AddKey); } float GetOrthoHeight() const { // Compute the FOV/plane intersection radius. // d d // a = 2 atan(------) => ~ a = --- => d = af // 2f f const float f = (mPosition - mTargetPosition).Length(); return (m_fovy * f) * (LC_PI / 180.0f); } public: void RayTest(lcObjectRayTest& ObjectRayTest) const override; void BoxTest(lcObjectBoxTest& ObjectBoxTest) const override; void DrawInterface(lcContext* Context, const lcScene& Scene) const override; void RemoveKeyFrames() override; void InsertTime(lcStep Start, lcStep Time); void RemoveTime(lcStep Start, lcStep Time); static bool FileLoad(lcFile& file); void CompareBoundingBox(lcVector3& Min, lcVector3& Max); void UpdatePosition(lcStep Step); void CopyPosition(const lcCamera* Camera); void CopySettings(const lcCamera* Camera); void ZoomExtents(float AspectRatio, const lcVector3& Center, const std::vector& Points, lcStep Step, bool AddKey); void ZoomRegion(float AspectRatio, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners, lcStep Step, bool AddKey); void Zoom(float Distance, lcStep Step, bool AddKey); void Pan(const lcVector3& Distance, lcStep Step, bool AddKey); void Orbit(float DistanceX, float DistanceY, const lcVector3& CenterPosition, lcStep Step, bool AddKey); void Roll(float Distance, lcStep Step, bool AddKey); void Center(const lcVector3& NewCenter, lcStep Step, bool AddKey); void MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance); void MoveRelative(const lcVector3& Distance, lcStep Step, bool AddKey); void SetViewpoint(lcViewpoint Viewpoint); void SetViewpoint(const lcVector3& Position); void SetViewpoint(const lcVector3& Position, const lcVector3& Target, const lcVector3& Up); void GetAngles(float& Latitude, float& Longitude, float& Distance) const; void SetAngles(float Latitude, float Longitude, float Distance); float m_fovy; float m_zNear; float m_zFar; lcMatrix44 mWorldView; lcVector3 mPosition; lcVector3 mTargetPosition; lcVector3 mUpVector; protected: lcObjectKeyArray mPositionKeys; lcObjectKeyArray mTargetPositionKeys; lcObjectKeyArray mUpVectorKeys; void Initialize(); QString mName; quint32 mState; }; leocad-23.03/common/group.cpp000066400000000000000000000020541440571307300161050ustar00rootroot00000000000000#include "lc_global.h" #include #include "group.h" #include "lc_file.h" lcGroup::lcGroup() { mGroup = nullptr; } void lcGroup::FileLoad(lcFile* File) { qint32 GroupIndex; char Name[LC_MAX_GROUP_NAME + 1]; File->ReadU8(); File->ReadBuffer(Name, sizeof(Name)); mName = QString::fromUtf8(Name); File->ReadVector3(); File->ReadS32(&GroupIndex, 1); mGroup = (lcGroup*)(quintptr)GroupIndex; } void lcGroup::CreateName(const lcArray& Groups) { if (!mName.isEmpty()) { bool Found = false; for (const lcGroup* const Group : Groups) { if (Group->mName == mName) { Found = true; break; } } if (!Found) return; } int Max = 0; QString Prefix = QApplication::tr("Group #"); const int Length = Prefix.length(); for (const lcGroup* const Group : Groups) { const QString& Name = Group->mName; if (Name.startsWith(Prefix)) { bool Ok = false; int GroupNumber = Name.mid(Length).toInt(&Ok); if (Ok && GroupNumber > Max) Max = GroupNumber; } } mName = Prefix + QString::number(Max + 1); } leocad-23.03/common/group.h000066400000000000000000000004571440571307300155570ustar00rootroot00000000000000#pragma once #include "lc_array.h" #define LC_MAX_GROUP_NAME 64 class lcGroup { public: lcGroup(); lcGroup* GetTopGroup() { return mGroup ? mGroup->GetTopGroup() : this; } void FileLoad(lcFile* File); void CreateName(const lcArray& Groups); lcGroup* mGroup; QString mName; }; leocad-23.03/common/image.cpp000066400000000000000000000065751440571307300160470ustar00rootroot00000000000000#include "lc_global.h" #include "image.h" #include "lc_file.h" static void CopyFromQImage(const QImage& Src, Image& Dest) { const bool Alpha = Src.hasAlphaChannel(); Dest.Allocate(Src.width(), Src.height(), Alpha ? lcPixelFormat::R8G8B8A8 : lcPixelFormat::R8G8B8); quint8* Bytes = (quint8*)Dest.mData; for (int y = 0; y < Dest.mHeight; y++) { for (int x = 0; x < Dest.mWidth; x++) { QRgb Pixel = Src.pixel(x, y); *Bytes++ = qRed(Pixel); *Bytes++ = qGreen(Pixel); *Bytes++ = qBlue(Pixel); if (Alpha) *Bytes++ = qAlpha(Pixel); } } } Image::Image() { mData = nullptr; mWidth = 0; mHeight = 0; mFormat = lcPixelFormat::Invalid; } Image::Image(Image&& Other) { mData = Other.mData; mWidth = Other.mWidth; mHeight = Other.mHeight; mFormat = Other.mFormat; Other.mData = nullptr; Other.mWidth = 0; Other.mHeight = 0; Other.mFormat = lcPixelFormat::Invalid; } Image::~Image() { FreeData(); } int Image::GetBPP() const { switch (mFormat) { case lcPixelFormat::Invalid: return 0; case lcPixelFormat::A8: return 1; case lcPixelFormat::L8A8: return 2; case lcPixelFormat::R8G8B8: return 3; case lcPixelFormat::R8G8B8A8: return 4; } return 0; } bool Image::HasAlpha() const { switch (mFormat) { case lcPixelFormat::Invalid: return false; case lcPixelFormat::A8: return true; case lcPixelFormat::L8A8: return true; case lcPixelFormat::R8G8B8: return false; case lcPixelFormat::R8G8B8A8: return true; } return 0; } void Image::FreeData() { free(mData); mData = nullptr; mWidth = 0; mHeight = 0; mFormat = lcPixelFormat::Invalid; } void Image::Allocate(int Width, int Height, lcPixelFormat Format) { FreeData(); mWidth = Width; mHeight = Height; mFormat = Format; mData = (unsigned char*)malloc(mWidth * mHeight * GetBPP()); } void Image::ResizePow2() { int i, shifted_x, shifted_y; shifted_x = mWidth; for (i = 0; ((i < 16) && (shifted_x != 0)); i++) shifted_x = shifted_x >> 1; shifted_x = (i != 0) ? 1 << (i-1) : 1; shifted_y = mHeight; for (i = 0; ((i < 16) && (shifted_y != 0)); i++) shifted_y = shifted_y >> 1; shifted_y = (i != 0) ? 1 << (i-1) : 1; if ((shifted_x != mWidth) || (shifted_y != mHeight)) Resize (shifted_x, shifted_y); } void Image::Resize(int width, int height) { int i, j, k, components, stx, sty; float accumx, accumy; unsigned char* bits = nullptr; components = GetBPP(); const int BufferSize = width * height * components; if (BufferSize) { bits = (unsigned char*)malloc(BufferSize); if (bits) { for (j = 0; j < mHeight; j++) { accumy = (float)height*j / (float)mHeight; sty = (int)floor(accumy); for (i = 0; i < mWidth; i++) { accumx = (float)width*i / (float)mWidth; stx = (int)floor(accumx); for (k = 0; k < components; k++) bits[(stx + sty*width)*components + k] = mData[(i + j * mWidth) * components + k]; } } } } free(mData); mData = bits; mWidth = width; mHeight = height; } bool Image::FileLoad(lcMemFile& File) { QImage Image; const unsigned char* Buffer = File.mBuffer + File.mPosition; const size_t BufferLength = File.mFileSize - File.mPosition; if (!Image.loadFromData(Buffer, (int)BufferLength)) return false; CopyFromQImage(Image, *this); return true; } bool Image::FileLoad(const QString& FileName) { QImage Image; if (!Image.load(FileName)) return false; CopyFromQImage(Image, *this); return true; } leocad-23.03/common/image.h000066400000000000000000000012561440571307300155030ustar00rootroot00000000000000#pragma once // Image Options #define LC_IMAGE_TRANSPARENT 0x2000 //#define LC_IMAGE_MASK 0x7000 enum class lcPixelFormat { Invalid, A8, L8A8, R8G8B8, R8G8B8A8 }; class Image { public: Image(); Image(Image&& Other); ~Image(); Image(const Image&) = delete; Image& operator=(const Image&) = delete; Image& operator=(Image&&) = delete; int GetBPP() const; bool HasAlpha() const; bool FileLoad(lcMemFile& File); bool FileLoad(const QString& FileName); void Resize(int Width, int Height); void ResizePow2(); void Allocate(int Width, int Height, lcPixelFormat Format); void FreeData(); int mWidth; int mHeight; lcPixelFormat mFormat; unsigned char* mData; }; leocad-23.03/common/lc_application.cpp000066400000000000000000001400451440571307300177350ustar00rootroot00000000000000#include "lc_global.h" #include #include "lc_application.h" #include "lc_library.h" #include "lc_profile.h" #include "project.h" #include "lc_mainwindow.h" #include "lc_qpreferencesdialog.h" #include "lc_partselectionwidget.h" #include "lc_shortcuts.h" #include "lc_view.h" #include "camera.h" #include "lc_previewwidget.h" #ifdef Q_OS_WIN #include #endif lcApplication* gApplication; void lcPreferences::LoadDefaults() { mFixedAxes = lcGetProfileInt(LC_PROFILE_FIXED_AXES); mMouseSensitivity = lcGetProfileInt(LC_PROFILE_MOUSE_SENSITIVITY); mShadingMode = static_cast(lcGetProfileInt(LC_PROFILE_SHADING_MODE)); mBackgroundGradient = lcGetProfileInt(LC_PROFILE_BACKGROUND_GRADIENT); mBackgroundSolidColor = lcGetProfileInt(LC_PROFILE_BACKGROUND_COLOR); mBackgroundGradientColorTop = lcGetProfileInt(LC_PROFILE_GRADIENT_COLOR_TOP); mBackgroundGradientColorBottom = lcGetProfileInt(LC_PROFILE_GRADIENT_COLOR_BOTTOM); mDrawAxes = lcGetProfileInt(LC_PROFILE_DRAW_AXES); mAxisIconLocation = static_cast(lcGetProfileInt(LC_PROFILE_DRAW_AXES_LOCATION)); mAxesColor = lcGetProfileInt(LC_PROFILE_AXES_COLOR); mTextColor = lcGetProfileInt(LC_PROFILE_TEXT_COLOR); mMarqueeBorderColor = lcGetProfileInt(LC_PROFILE_MARQUEE_BORDER_COLOR); mMarqueeFillColor = lcGetProfileInt(LC_PROFILE_MARQUEE_FILL_COLOR); mOverlayColor = lcGetProfileInt(LC_PROFILE_OVERLAY_COLOR); mActiveViewColor = lcGetProfileInt(LC_PROFILE_ACTIVE_VIEW_COLOR); mInactiveViewColor = lcGetProfileInt(LC_PROFILE_INACTIVE_VIEW_COLOR); mDrawEdgeLines = lcGetProfileInt(LC_PROFILE_DRAW_EDGE_LINES); mDrawConditionalLines = lcGetProfileInt(LC_PROFILE_DRAW_CONDITIONAL_LINES); mLineWidth = lcGetProfileFloat(LC_PROFILE_LINE_WIDTH); mAllowLOD = lcGetProfileInt(LC_PROFILE_ALLOW_LOD); mMeshLODDistance = lcGetProfileFloat(LC_PROFILE_LOD_DISTANCE); mFadeSteps = lcGetProfileInt(LC_PROFILE_FADE_STEPS); mFadeStepsColor = lcGetProfileInt(LC_PROFILE_FADE_STEPS_COLOR); mHighlightNewParts = lcGetProfileInt(LC_PROFILE_HIGHLIGHT_NEW_PARTS); mHighlightNewPartsColor = lcGetProfileInt(LC_PROFILE_HIGHLIGHT_NEW_PARTS_COLOR); mDrawGridStuds = lcGetProfileInt(LC_PROFILE_GRID_STUDS); mGridStudColor = lcGetProfileInt(LC_PROFILE_GRID_STUD_COLOR); mDrawGridLines = lcGetProfileInt(LC_PROFILE_GRID_LINES); mGridLineSpacing = lcGetProfileInt(LC_PROFILE_GRID_LINE_SPACING); mGridLineColor = lcGetProfileInt(LC_PROFILE_GRID_LINE_COLOR); mDrawGridOrigin = lcGetProfileInt(LC_PROFILE_GRID_ORIGIN); mViewSphereEnabled = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_ENABLED); mViewSphereLocation = static_cast(lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_LOCATION)); mViewSphereSize = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_SIZE); mViewSphereColor = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_COLOR); mViewSphereTextColor = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_TEXT_COLOR); mViewSphereHighlightColor = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_HIGHLIGHT_COLOR); mAutoLoadMostRecent = lcGetProfileInt(LC_PROFILE_AUTOLOAD_MOSTRECENT); mRestoreTabLayout = lcGetProfileInt(LC_PROFILE_RESTORE_TAB_LAYOUT); mColorTheme = static_cast(lcGetProfileInt(LC_PROFILE_COLOR_THEME)); mPreviewViewSphereEnabled = lcGetProfileInt(LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED); mPreviewViewSphereSize = lcGetProfileInt(LC_PROFILE_PREVIEW_VIEW_SPHERE_SIZE); mPreviewViewSphereLocation = static_cast(lcGetProfileInt(LC_PROFILE_PREVIEW_VIEW_SPHERE_LOCATION)); mDrawPreviewAxis = lcGetProfileInt(LC_PROFILE_PREVIEW_DRAW_AXES); mStudCylinderColor = lcGetProfileInt(LC_PROFILE_STUD_CYLINDER_COLOR); mPartEdgeColor = lcGetProfileInt(LC_PROFILE_PART_EDGE_COLOR); mBlackEdgeColor = lcGetProfileInt(LC_PROFILE_BLACK_EDGE_COLOR); mDarkEdgeColor = lcGetProfileInt(LC_PROFILE_DARK_EDGE_COLOR); mPartEdgeContrast = lcGetProfileFloat(LC_PROFILE_PART_EDGE_CONTRAST); mPartColorValueLDIndex = lcGetProfileFloat(LC_PROFILE_PART_COLOR_VALUE_LD_INDEX); mAutomateEdgeColor = lcGetProfileInt(LC_PROFILE_AUTOMATE_EDGE_COLOR); mObjectSelectedColor = lcGetProfileUInt(LC_PROFILE_OBJECT_SELECTED_COLOR); mObjectFocusedColor = lcGetProfileUInt(LC_PROFILE_OBJECT_FOCUSED_COLOR); mCameraColor = lcGetProfileUInt(LC_PROFILE_CAMERA_COLOR); mLightColor = lcGetProfileUInt(LC_PROFILE_LIGHT_COLOR); mControlPointColor = lcGetProfileUInt(LC_PROFILE_CONTROL_POINT_COLOR); mControlPointFocusedColor = lcGetProfileUInt(LC_PROFILE_CONTROL_POINT_FOCUSED_COLOR); } void lcPreferences::SaveDefaults() { lcSetProfileInt(LC_PROFILE_FIXED_AXES, mFixedAxes); lcSetProfileInt(LC_PROFILE_MOUSE_SENSITIVITY, mMouseSensitivity); lcSetProfileInt(LC_PROFILE_SHADING_MODE, static_cast(mShadingMode)); lcSetProfileInt(LC_PROFILE_DRAW_AXES, mDrawAxes); lcSetProfileInt(LC_PROFILE_DRAW_AXES_LOCATION, static_cast(mAxisIconLocation)); lcSetProfileInt(LC_PROFILE_AXES_COLOR, mAxesColor); lcSetProfileInt(LC_PROFILE_TEXT_COLOR, mTextColor); lcSetProfileInt(LC_PROFILE_BACKGROUND_GRADIENT, mBackgroundGradient); lcSetProfileInt(LC_PROFILE_BACKGROUND_COLOR, mBackgroundSolidColor); lcSetProfileInt(LC_PROFILE_GRADIENT_COLOR_TOP, mBackgroundGradientColorTop); lcSetProfileInt(LC_PROFILE_GRADIENT_COLOR_BOTTOM, mBackgroundGradientColorBottom); lcSetProfileInt(LC_PROFILE_MARQUEE_BORDER_COLOR, mMarqueeBorderColor); lcSetProfileInt(LC_PROFILE_MARQUEE_FILL_COLOR, mMarqueeFillColor); lcSetProfileInt(LC_PROFILE_OVERLAY_COLOR, mOverlayColor); lcSetProfileInt(LC_PROFILE_ACTIVE_VIEW_COLOR, mActiveViewColor); lcSetProfileInt(LC_PROFILE_INACTIVE_VIEW_COLOR, mInactiveViewColor); lcSetProfileInt(LC_PROFILE_DRAW_EDGE_LINES, mDrawEdgeLines); lcSetProfileInt(LC_PROFILE_DRAW_CONDITIONAL_LINES, mDrawConditionalLines); lcSetProfileFloat(LC_PROFILE_LINE_WIDTH, mLineWidth); lcSetProfileInt(LC_PROFILE_ALLOW_LOD, mAllowLOD); lcSetProfileFloat(LC_PROFILE_LOD_DISTANCE, mMeshLODDistance); lcSetProfileInt(LC_PROFILE_FADE_STEPS, mFadeSteps); lcSetProfileInt(LC_PROFILE_FADE_STEPS_COLOR, mFadeStepsColor); lcSetProfileInt(LC_PROFILE_HIGHLIGHT_NEW_PARTS, mHighlightNewParts); lcSetProfileInt(LC_PROFILE_HIGHLIGHT_NEW_PARTS_COLOR, mHighlightNewPartsColor); lcSetProfileInt(LC_PROFILE_GRID_STUDS, mDrawGridStuds); lcSetProfileInt(LC_PROFILE_GRID_STUD_COLOR, mGridStudColor); lcSetProfileInt(LC_PROFILE_GRID_LINES, mDrawGridLines); lcSetProfileInt(LC_PROFILE_GRID_LINE_SPACING, mGridLineSpacing); lcSetProfileInt(LC_PROFILE_GRID_LINE_COLOR, mGridLineColor); lcSetProfileInt(LC_PROFILE_GRID_ORIGIN, mDrawGridOrigin); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_ENABLED, mViewSphereSize ? 1 : 0); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_LOCATION, static_cast(mViewSphereLocation)); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_SIZE, mViewSphereSize); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_COLOR, mViewSphereColor); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_TEXT_COLOR, mViewSphereTextColor); lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_HIGHLIGHT_COLOR, mViewSphereHighlightColor); lcSetProfileInt(LC_PROFILE_AUTOLOAD_MOSTRECENT, mAutoLoadMostRecent); lcSetProfileInt(LC_PROFILE_RESTORE_TAB_LAYOUT, mRestoreTabLayout); lcSetProfileInt(LC_PROFILE_COLOR_THEME, static_cast(mColorTheme)); lcSetProfileInt(LC_PROFILE_PREVIEW_VIEW_SPHERE_SIZE, mPreviewViewSphereSize); lcSetProfileInt(LC_PROFILE_PREVIEW_VIEW_SPHERE_LOCATION, static_cast(mPreviewViewSphereLocation)); lcSetProfileInt(LC_PROFILE_PREVIEW_DRAW_AXES, mDrawPreviewAxis); lcSetProfileInt(LC_PROFILE_STUD_CYLINDER_COLOR, mStudCylinderColor); lcSetProfileInt(LC_PROFILE_PART_EDGE_COLOR, mPartEdgeColor); lcSetProfileInt(LC_PROFILE_BLACK_EDGE_COLOR, mBlackEdgeColor); lcSetProfileInt(LC_PROFILE_DARK_EDGE_COLOR, mDarkEdgeColor); lcSetProfileFloat(LC_PROFILE_PART_EDGE_CONTRAST, mPartEdgeContrast); lcSetProfileFloat(LC_PROFILE_PART_COLOR_VALUE_LD_INDEX, mPartColorValueLDIndex); lcSetProfileInt(LC_PROFILE_AUTOMATE_EDGE_COLOR, mAutomateEdgeColor); lcSetProfileUInt(LC_PROFILE_OBJECT_SELECTED_COLOR, mObjectSelectedColor); lcSetProfileUInt(LC_PROFILE_OBJECT_FOCUSED_COLOR, mObjectFocusedColor); lcSetProfileUInt(LC_PROFILE_CAMERA_COLOR, mCameraColor); lcSetProfileUInt(LC_PROFILE_LIGHT_COLOR, mLightColor); lcSetProfileUInt(LC_PROFILE_CONTROL_POINT_COLOR, mControlPointColor); lcSetProfileUInt(LC_PROFILE_CONTROL_POINT_FOCUSED_COLOR, mControlPointFocusedColor); } void lcPreferences::SetInterfaceColors(lcColorTheme ColorTheme) { if (ColorTheme == lcColorTheme::Dark) { mAxesColor = LC_RGBA(160, 160, 160, 255); mTextColor = LC_RGBA(160, 160, 160, 255); mBackgroundSolidColor = LC_RGB(49, 52, 55); mBackgroundGradientColorTop = LC_RGB(0, 0, 191); mBackgroundGradientColorBottom = LC_RGB(255, 255, 255); mOverlayColor = lcGetProfileInt(LC_PROFILE_OVERLAY_COLOR); mActiveViewColor = LC_RGBA(41, 128, 185, 255); mGridStudColor = LC_RGBA(24, 24, 24, 192); mGridLineColor = LC_RGBA(24, 24, 24, 255); mViewSphereColor = LC_RGBA(35, 38, 41, 255); mViewSphereTextColor = LC_RGBA(224, 224, 224, 255); mViewSphereHighlightColor = LC_RGBA(41, 128, 185, 255); } else { mAxesColor = LC_RGBA(0, 0, 0, 255); mTextColor = LC_RGBA(0, 0, 0, 255); mBackgroundSolidColor = LC_RGB(255, 255, 255); mBackgroundGradientColorTop = LC_RGB(54, 72, 95); mBackgroundGradientColorBottom = LC_RGB(49, 52, 55); mOverlayColor = LC_RGBA(0, 0, 0, 255); mActiveViewColor = LC_RGBA(255, 0, 0, 255); mGridStudColor = LC_RGBA(64, 64, 64, 192); mGridLineColor = LC_RGBA(0, 0, 0, 255); mViewSphereColor = LC_RGBA(255, 255, 255, 255); mViewSphereTextColor = LC_RGBA(0, 0, 0, 255); mViewSphereHighlightColor = LC_RGBA(255, 0, 0, 255); } } lcApplication::lcApplication(int& Argc, char** Argv) : QApplication(Argc, Argv) { setApplicationDisplayName(QLatin1String("LeoCAD")); gApplication = this; mDefaultStyle = style()->objectName(); mPreferences.LoadDefaults(); } lcApplication::~lcApplication() { gApplication = nullptr; } void lcApplication::UpdateStyle() { if (mPreferences.mColorTheme == lcColorTheme::Dark) { if (!QApplication::setStyle("fusion")) return; QPalette Palette = QApplication::palette(); Palette.setColor(QPalette::Window, QColor(49, 52, 55)); Palette.setColor(QPalette::WindowText, QColor(240, 240, 240)); Palette.setColor(QPalette::Base, QColor(35, 38, 41)); Palette.setColor(QPalette::AlternateBase, QColor(44, 47, 50)); Palette.setColor(QPalette::ToolTipBase, QColor(224, 224, 244)); Palette.setColor(QPalette::ToolTipText, QColor(58, 58, 58)); #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) Palette.setColor(QPalette::PlaceholderText, QColor(100, 100, 100)); #endif Palette.setColor(QPalette::Text, QColor(224, 224, 224)); Palette.setColor(QPalette::Button, QColor(45, 48, 51)); Palette.setColor(QPalette::ButtonText, QColor(224, 224, 244)); Palette.setColor(QPalette::Light, QColor(65, 65, 65)); Palette.setColor(QPalette::Midlight, QColor(62, 62, 62)); Palette.setColor(QPalette::Dark, QColor(35, 35, 35)); Palette.setColor(QPalette::Mid, QColor(50, 50, 50)); Palette.setColor(QPalette::Shadow, QColor(20, 20, 20)); // Palette.setColor(QPalette::Highlight, QColor(46, 108, 219)); Palette.setColor(QPalette::Highlight, QColor(41, 128, 185)); Palette.setColor(QPalette::HighlightedText, QColor(232, 232, 232)); Palette.setColor(QPalette::Link, QColor(41, 128, 185)); Palette.setColor(QPalette::Disabled, QPalette::Text, QColor(128, 128, 128)); Palette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(128, 128, 128)); Palette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(128, 128, 128)); QApplication::setPalette(Palette); QFile StylesheetFile(QLatin1String(":/stylesheet/stylesheet.qss")); if (StylesheetFile.open(QIODevice::ReadOnly)) { QString Stylesheet = QString::fromLatin1(StylesheetFile.readAll()); qApp->setStyleSheet(Stylesheet); } } else { QApplication::setStyle(mDefaultStyle); QApplication::setPalette(qApp->style()->standardPalette()); qApp->setStyleSheet(QString()); } } void lcApplication::SaveTabLayout() const { if (!mProject || mProject->GetFileName().isEmpty()) return; QSettings Settings; QByteArray TabLayout = gMainWindow->GetTabLayout(); Settings.setValue(GetTabLayoutKey(), TabLayout); } QString lcApplication::GetTabLayoutKey() const { if (mProject) { QString FileName = mProject->GetFileName(); if (!FileName.isEmpty()) { FileName.replace('\\', '?'); FileName.replace('/', '?'); return QString("TabLayouts/%1").arg(FileName); } } return QString(); } void lcApplication::SetProject(Project* Project) { SaveTabLayout(); if (gMainWindow) { gMainWindow->RemoveAllModelTabs(); if (gMainWindow->GetPreviewWidget()) gMainWindow->GetPreviewWidget()->ClearPreview(); } delete mProject; mProject = Project; Project->SetActiveModel(0); lcGetPiecesLibrary()->RemoveTemporaryPieces(); if (mProject && !mProject->GetFileName().isEmpty() && mPreferences.mRestoreTabLayout) { QSettings Settings; QByteArray TabLayout = Settings.value(GetTabLayoutKey()).toByteArray(); if (gMainWindow) gMainWindow->RestoreTabLayout(TabLayout); } } void lcApplication::SetClipboard(const QByteArray& Clipboard) { mClipboard = Clipboard; gMainWindow->UpdatePaste(!mClipboard.isEmpty()); } void lcApplication::ExportClipboard(const QByteArray& Clipboard) { QMimeData* MimeData = new QMimeData(); MimeData->setData("application/vnd.leocad-clipboard", Clipboard); QApplication::clipboard()->setMimeData(MimeData); SetClipboard(Clipboard); } bool lcApplication::LoadPartsLibrary(const QList>& LibraryPaths, bool OnlyUsePaths) { if (mLibrary == nullptr) mLibrary = new lcPiecesLibrary(); const bool ShowProgress = gMainWindow != nullptr; if (!OnlyUsePaths) { char* EnvPath = getenv("LEOCAD_LIB"); if (EnvPath && EnvPath[0]) return mLibrary->Load(EnvPath, ShowProgress); QString CustomPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY); if (!CustomPath.isEmpty()) return mLibrary->Load(CustomPath, ShowProgress); } for (const QPair& LibraryPathEntry : LibraryPaths) { if (mLibrary->Load(LibraryPathEntry.first, ShowProgress)) { if (LibraryPathEntry.second) mLibrary->SetOfficialPieces(); return true; } } return false; } lcCommandLineOptions lcApplication::ParseCommandLineOptions() { lcPreferences Preferences; Preferences.LoadDefaults(); lcCommandLineOptions Options; Options.FadeSteps = Preferences.mFadeSteps; Options.ImageHighlight = Preferences.mHighlightNewParts; Options.ImageWidth = lcGetProfileInt(LC_PROFILE_IMAGE_WIDTH); Options.ImageHeight = lcGetProfileInt(LC_PROFILE_IMAGE_HEIGHT); Options.ShadingMode = Preferences.mShadingMode; Options.LineWidth = Preferences.mLineWidth; Options.AASamples = lcGetProfileInt(LC_PROFILE_ANTIALIASING_SAMPLES); Options.StudStyle = static_cast(lcGetProfileInt(LC_PROFILE_STUD_STYLE)); Options.ImageStart = 0; Options.ImageEnd = 0; Options.CameraPosition[0] = lcVector3(0.0f, 0.0f, 0.0f); Options.CameraPosition[1] = lcVector3(0.0f, 0.0f, 0.0f); Options.CameraPosition[2] = lcVector3(0.0f, 0.0f, 0.0f); Options.CameraLatLon = lcVector2(0.0f, 0.0f); Options.FoV = 0.0f; Options.ZPlanes = lcVector2(0.0f, 0.0f); Options.Viewpoint = lcViewpoint::Count; Options.FadeStepsColor = Preferences.mFadeStepsColor; Options.HighlightColor = Preferences.mHighlightNewPartsColor; Options.StudCylinderColor = Preferences.mStudCylinderColor; Options.PartEdgeColor = Preferences.mPartEdgeColor; Options.BlackEdgeColor = Preferences.mBlackEdgeColor; Options.DarkEdgeColor = Preferences.mDarkEdgeColor; Options.PartEdgeContrast = Preferences.mPartEdgeContrast; Options.PartColorValueLDIndex = Preferences.mPartColorValueLDIndex; Options.AutomateEdgeColor = Preferences.mAutomateEdgeColor; QStringList Arguments = arguments(); if (Arguments.isEmpty()) return Options; Arguments.removeFirst(); while (!Arguments.isEmpty()) { QString Option = Arguments.takeFirst(); if (Option.isEmpty()) continue; auto ParseString = [&Option, &Arguments, &Options](QString& Value, bool Required) { if (!Arguments.isEmpty() && Arguments.front()[0] != '-') { QString Parameter = Arguments.takeFirst(); Value = Parameter; } else if (Required) { Options.StdErr += tr("Not enough parameters for the '%1' option.\n").arg(Option); Options.ParseOK = false; return false; } return true; }; auto ParseInteger = [&Option, &Arguments, &Options](int& Value, int Min, int Max) { if (!Arguments.isEmpty() && Arguments.front()[0] != '-') { bool Ok = false; QString Parameter = Arguments.takeFirst(); int NewValue = Parameter.toInt(&Ok); if (Ok && NewValue >= Min && NewValue <= Max) { Value = NewValue; return true; } else Options.StdErr += tr("Invalid parameter value specified for the '%1' option: '%2'.\n").arg(Option, Parameter); } else Options.StdErr += tr("Not enough parameters for the '%1' option.\n").arg(Option); Options.ParseOK = false; return false; }; auto ParseUnsigned = [&Option, &Arguments, &Options](uint& Value, uint Min, uint Max) { if (!Arguments.isEmpty() && Arguments.front()[0] != '-') { bool Ok = false; QString Parameter = Arguments.takeFirst(); uint NewValue = Parameter.toUInt(&Ok); if (Ok && NewValue >= Min && NewValue <= Max) { Value = NewValue; return true; } else Options.StdErr += tr("Invalid parameter value specified for the '%1' option: '%2'.\n").arg(Option, Parameter); } else Options.StdErr += tr("Not enough parameters for the '%1' option.\n").arg(Option); Options.ParseOK = false; return false; }; auto ParseFloat = [&Option, &Arguments, &Options](float& Value, float Min, float Max) { if (!Arguments.isEmpty() && Arguments.front()[0] != '-') { bool Ok = false; QString Parameter = Arguments.takeFirst(); float NewValue = Parameter.toFloat(&Ok); if (Ok && NewValue >= Min && NewValue <= Max) { Value = NewValue; return true; } else Options.StdErr += tr("Invalid parameter value specified for the '%1' option: '%2'.\n").arg(Option, Parameter); } else Options.StdErr += tr("Not enough parameters for the '%1' option.\n").arg(Option); Options.ParseOK = false; return false; }; auto ParseFloatArray = [&Option, &Arguments, &Options](int Count, float* ValueArray, bool NegativesValid) { if (Arguments.size() < Count) { Options.StdErr += tr("Not enough parameters for the '%1' option.\n").arg(Option); Arguments.clear(); Options.ParseOK = false; return false; } for (int ParseIndex = 0; ParseIndex < Count; ParseIndex++) { if (NegativesValid || Arguments.front()[0] != '-') { bool Ok = false; QString Parameter = Arguments.takeFirst(); float NewValue = Parameter.toFloat(&Ok); if (Ok) { *(ValueArray++) = NewValue; continue; } Options.StdErr += tr("Invalid parameter value specified for the '%1' option: '%2'.\n").arg(Option, Parameter); } else Options.StdErr += tr("Not enough parameters for the '%1' option.\n").arg(Option); Options.ParseOK = false; return false; } return true; }; auto ParseColor = [&Option, &Arguments, &Options](quint32& Color) { if (!Arguments.isEmpty() && Arguments.front()[0] != '-') { QString Parameter = Arguments.takeFirst(); QColor ParsedColor = QColor(Parameter); if (ParsedColor.isValid()) { Color = LC_RGBA(ParsedColor.red(), ParsedColor.green(), ParsedColor.blue(), ParsedColor.alpha()); return true; } else Options.StdErr += tr("Invalid parameter value specified for the '%1' option: '%2'.\n").arg(Option, Parameter); } else Options.StdErr += tr("Not enough parameters for the '%1' option.\n").arg(Option); Options.ParseOK = false; return false; }; if (Option[0] != '-') { if (QFileInfo(Option).isReadable()) Options.ProjectName = Option; else Options.StdErr += tr("The file '%1' is not readable.\n").arg(Option); continue; } if (Option == QLatin1String("-l") || Option == QLatin1String("--libpath")) { QString LibPath; if (ParseString(LibPath, true)) Options.LibraryPaths += QPair(LibPath, false); } else if (Option == QLatin1String("-i") || Option == QLatin1String("--image")) { Options.SaveImage = true; ParseString(Options.ImageName, false); } else if (Option == QLatin1String("-w") || Option == QLatin1String("--width")) ParseInteger(Options.ImageWidth, 1, INT_MAX); else if (Option == QLatin1String("-h") || Option == QLatin1String("--height")) ParseInteger(Options.ImageHeight, 1, INT_MAX); else if (Option == QLatin1String("-f") || Option == QLatin1String("--from")) ParseUnsigned(Options.ImageStart, 1, LC_STEP_MAX); else if (Option == QLatin1String("-t") || Option == QLatin1String("--to")) ParseUnsigned(Options.ImageEnd, 1, LC_STEP_MAX); else if (Option == QLatin1String("-s") || Option == QLatin1String("--submodel")) ParseString(Options.ModelName, true); else if (Option == QLatin1String("-c") || Option == QLatin1String("--camera")) ParseString(Options.CameraName, true); else if (Option == QLatin1String("--viewpoint")) { QString ViewpointName; if (ParseString(ViewpointName, true)) { Options.Viewpoint = lcCamera::GetViewpoint(ViewpointName); if (Options.Viewpoint == lcViewpoint::Count) { Options.StdErr += tr("Invalid parameter value specified for the '%1' option: '%2'.\n").arg(Option, ViewpointName); Options.ParseOK = false; } } } else if (Option == QLatin1String("--camera-angles")) { if ((Options.SetCameraAngles = ParseFloatArray(2, Options.CameraLatLon, true)) && (fabsf(Options.CameraLatLon[0]) > 360.0f || fabsf(Options.CameraLatLon[1]) > 360.0f)) { Options.StdErr += tr("Invalid parameter value(s) specified for the '%1' option: limits are +/- 360.\n").arg(Option); Options.ParseOK = false; } } else if (Option == QLatin1String("--camera-position") || Option == QLatin1String("--camera-position-ldraw")) { if ((Options.SetCameraPosition = ParseFloatArray(9, Options.CameraPosition[0], true))) { lcVector3 Front = Options.CameraPosition[1] - Options.CameraPosition[0]; if (Front.LengthSquared() < 1.0f || Options.CameraPosition[2].LengthSquared() < 1.0f || fabsf(lcDot(lcNormalize(Front), lcNormalize(Options.CameraPosition[2]))) > 0.99f) { Options.StdErr += tr("Invalid parameter value(s) specified for the '%1' option.\n").arg(Option); Options.ParseOK = false; } else if (Option == QLatin1String("--camera-position-ldraw")) { Options.CameraPosition[0] = lcVector3LDrawToLeoCAD(Options.CameraPosition[0]); Options.CameraPosition[1] = lcVector3LDrawToLeoCAD(Options.CameraPosition[1]); Options.CameraPosition[2] = lcVector3LDrawToLeoCAD(Options.CameraPosition[2]); } } } else if (Option == QLatin1String("--orthographic")) Options.Orthographic = true; else if (Option == QLatin1String("--fov")) Options.SetFoV = ParseFloat(Options.FoV, 1.0f, 180.0f); else if (Option == QLatin1String("--zplanes")) { if ((Options.SetZPlanes = ParseFloatArray(2, Options.ZPlanes, false)) && (Options.ZPlanes[0] < 1.0 || Options.ZPlanes[0] >= Options.ZPlanes[1])) { Options.StdErr += tr("Invalid parameter value(s) specified for the '%1' option: requirements are: 1 <= < .\n").arg(Option); Options.ParseOK = false; } } else if (Option == QLatin1String("-scc") || Option == QLatin1String("--stud-cylinder-color")) { if (ParseColor(Options.StudCylinderColor)) { if (!lcIsHighContrast(Options.StudStyle)) { Options.StdErr += tr("High contrast stud style is required for the '%1' option but is not enabled.\n").arg(Option); Options.ParseOK = false; } } } else if (Option == QLatin1String("-ec") || Option == QLatin1String("--edge-color")) { if (ParseColor(Options.PartEdgeColor)) { if (!lcIsHighContrast(Options.StudStyle)) { Options.StdErr += tr("High contrast stud style is required for the '%1' option but is not enabled.\n").arg(Option); Options.ParseOK = false; } } } else if (Option == QLatin1String("-bec") || Option == QLatin1String("--black-edge-color")) { if (ParseColor(Options.BlackEdgeColor)) { if (!lcIsHighContrast(Options.StudStyle)) { Options.StdErr += tr("High contrast stud style is required for the '%1' option but is not enabled.\n").arg(Option); Options.ParseOK = false; } } } else if (Option == QLatin1String("-dec") || Option == QLatin1String("--dark-edge-color")) { if (ParseColor(Options.DarkEdgeColor)) { if (!lcIsHighContrast(Options.StudStyle)) { Options.StdErr += tr("High contrast stud style is required for the '%1' option but is not enabled.\n").arg(Option); Options.ParseOK = false; } } } else if (Option == QLatin1String("-aec") || Option == QLatin1String("--automate-edge-color")) { Options.AutomateEdgeColor = true; } else if (Option == QLatin1String("-cc") || Option == QLatin1String("--color-contrast")) { if (ParseFloat(Options.PartEdgeContrast, 0.0f, 1.0f)) { if (!Options.AutomateEdgeColor) { Options.StdErr += tr("Automate edge color is required for the '%1' option but is not enabled.\n").arg(Option); Options.ParseOK = false; } } } else if (Option == QLatin1String("-ldv") || Option == QLatin1String("--light-dark-value")) { if (ParseFloat(Options.PartColorValueLDIndex, 0.0f, 1.0f)) { if (!Options.AutomateEdgeColor) { Options.StdErr += tr("Automate edge color is required for the '%1' option but is not enabled.\n").arg(Option); Options.ParseOK = false; } } } else if (Option == QLatin1String("--fade-steps")) Options.FadeSteps = true; else if (Option == QLatin1String("--no-fade-steps")) Options.FadeSteps = false; else if (Option == QLatin1String("--fade-steps-color")) { if (ParseColor(Options.FadeStepsColor)) { Options.SetFadeStepsColor = true; Options.FadeSteps = true; } } else if (Option == QLatin1String("--highlight")) Options.ImageHighlight = true; else if (Option == QLatin1String("--no-highlight")) Options.ImageHighlight = false; else if (Option == QLatin1String("--highlight-color")) { if (ParseColor(Options.HighlightColor)) { Options.SetHighlightColor = true; Options.ImageHighlight = true; } } else if (Option == QLatin1String("--shading")) { QString ShadingString; if (ParseString(ShadingString, true)) { if (ShadingString == QLatin1String("wireframe")) Options.ShadingMode = lcShadingMode::Wireframe; else if (ShadingString == QLatin1String("flat")) Options.ShadingMode = lcShadingMode::Flat; else if (ShadingString == QLatin1String("default")) Options.ShadingMode = lcShadingMode::DefaultLights; else if (ShadingString == QLatin1String("full")) Options.ShadingMode = lcShadingMode::Full; else { Options.StdErr += tr("Invalid parameter value specified for the '%1' option: '%2'.\n").arg(Option, ShadingString); Options.ParseOK = false; } } } else if (Option == QLatin1String("--line-width")) ParseFloat(Options.LineWidth, 0.0f, 10.0f); else if (Option == QLatin1String("--aa-samples")) { if (ParseInteger(Options.AASamples, 1, 8) && Options.AASamples != 1 && Options.AASamples != 2 && Options.AASamples != 4 && Options.AASamples != 8) { Options.StdErr += tr("Invalid parameter value specified for the '%1' option: '%2'.\n").arg(Option, QString::number(Options.AASamples)); Options.ParseOK = false; } } else if (Option == QLatin1String("-ss") || Option == QLatin1String("--stud-style")) { int StudStyle; if (ParseInteger(StudStyle, 0, static_cast(lcStudStyle::Count) - 1)) Options.StudStyle = static_cast(StudStyle); } else if (Option == QLatin1String("-obj") || Option == QLatin1String("--export-wavefront")) { Options.SaveWavefront = true; ParseString(Options.SaveWavefrontName, false); } else if (Option == QLatin1String("-3ds") || Option == QLatin1String("--export-3ds")) { Options.Save3DS = true; ParseString(Options.Save3DSName, false); } else if (Option == QLatin1String("-dae") || Option == QLatin1String("--export-collada")) { Options.SaveCOLLADA = true; ParseString(Options.SaveCOLLADAName, false); } else if (Option == QLatin1String("-csv") || Option == QLatin1String("--export-csv")) { Options.SaveCSV = true; ParseString(Options.SaveCSVName, false); } else if (Option == QLatin1String("-html") || Option == QLatin1String("--export-html")) { Options.SaveHTML = true; ParseString(Options.SaveHTMLName, false); } else if (Option == QLatin1String("-v") || Option == QLatin1String("--version")) { #ifdef LC_CONTINUOUS_BUILD Options.StdOut += tr("LeoCAD Continuous Build %1\n").arg(QT_STRINGIFY(LC_CONTINUOUS_BUILD)); #else Options.StdOut += tr("LeoCAD Version %1\n").arg(LC_VERSION_TEXT); #endif Options.StdOut += tr("Compiled %1\n").arg(__DATE__); Options.Exit = true; } else if (Option == QLatin1String("-?") || Option == QLatin1String("--help")) { Options.StdOut += tr("Usage: leocad [options] [file]\n"); Options.StdOut += tr(" [options] can be:\n"); Options.StdOut += tr(" -l, --libpath : Set the Parts Library location to path.\n"); Options.StdOut += tr(" -i, --image : Save a picture in the format specified by ext and exit.\n"); Options.StdOut += tr(" -w, --width : Set the picture width.\n"); Options.StdOut += tr(" -h, --height : Set the picture height.\n"); Options.StdOut += tr(" -f, --from : Set the first step to save pictures.\n"); Options.StdOut += tr(" -t, --to : Set the last step to save pictures.\n"); Options.StdOut += tr(" -s, --submodel : Set the active submodel.\n"); Options.StdOut += tr(" -c, --camera : Set the active camera.\n"); Options.StdOut += tr(" -ss, --stud-style : Set the stud style 0=No style, 1=LDraw single wire, 2=LDraw double wire, 3=LDraw raised floating, 4=LDraw raised rounded, 5=LDraw subtle rounded, 6=LEGO no logo, 7=LEGO single wire.\n"); Options.StdOut += tr(" --viewpoint : Set the viewpoint.\n"); Options.StdOut += tr(" --camera-angles : Set the camera angles in degrees around the model.\n"); Options.StdOut += tr(" --camera-position : Set the camera position, target and up vector.\n"); Options.StdOut += tr(" --camera-position-ldraw : Set the camera position, target and up vector using LDraw coordinates.\n"); Options.StdOut += tr(" --orthographic: Render images using an orthographic projection.\n"); Options.StdOut += tr(" --fov : Set the vertical field of view used to render images (< 180).\n"); Options.StdOut += tr(" --zplanes : Set the near and far clipping planes used to render images (1 <= < ).\n"); Options.StdOut += tr(" --fade-steps: Render parts from prior steps faded.\n"); Options.StdOut += tr(" --no-fade-steps: Do not render parts from prior steps faded.\n"); Options.StdOut += tr(" --fade-steps-color : Renderinng color for prior step parts (#AARRGGBB).\n"); Options.StdOut += tr(" --highlight: Highlight parts in the steps they appear.\n"); Options.StdOut += tr(" --no-highlight: Do not highlight parts in the steps they appear.\n"); Options.StdOut += tr(" --highlight-color: Renderinng color for highlighted parts (#AARRGGBB).\n"); Options.StdOut += tr(" --shading : Select shading mode for rendering.\n"); Options.StdOut += tr(" --line-width : Set the width of the edge lines.\n"); Options.StdOut += tr(" --aa-samples : AntiAliasing sample size (1, 2, 4, or 8).\n"); Options.StdOut += tr(" -scc, --stud-cylinder-color <#AARRGGBB>: High contrast stud cylinder color.\n"); Options.StdOut += tr(" -ec, --edge-color <#AARRGGBB>: High contrast edge color.\n"); Options.StdOut += tr(" -bec, --black-edge-color <#AARRGGBB>: High contrast edge color for black parts.\n"); Options.StdOut += tr(" -dec, --dark-edge-color <#AARRGGBB>: High contrast edge color for dark color parts.\n"); Options.StdOut += tr(" -aec, --automate-edge-color: Enable automatically adjusted edge colors.\n"); Options.StdOut += tr(" -cc, --color-contrast : Color contrast value between 0.0 and 1.0.\n"); Options.StdOut += tr(" -ldv, --light-dark-value : Light/Dark color value between 0.0 and 1.0.\n"); Options.StdOut += tr(" -obj, --export-wavefront : Export the model to Wavefront OBJ format.\n"); Options.StdOut += tr(" -3ds, --export-3ds : Export the model to 3D Studio 3DS format.\n"); Options.StdOut += tr(" -dae, --export-collada : Export the model to COLLADA DAE format.\n"); Options.StdOut += tr(" -csv, --export-csv : Export the list of parts used in csv format.\n"); Options.StdOut += tr(" -html, --export-html : Create an HTML page for the model.\n"); Options.StdOut += tr(" -v, --version: Output version information and exit.\n"); Options.StdOut += tr(" -?, --help: Display this help message and exit.\n"); Options.StdOut += QLatin1String("\n"); Options.Exit = true; } else { Options.StdErr += tr("Unknown option: '%1'.\n").arg(Option); Options.ParseOK = false; } } if (Options.AutomateEdgeColor && lcIsHighContrast(Options.StudStyle)) { Options.StdErr += tr("High contrast stud and edge color settings are ignored when -aec or --automate-edge-color is set.\n"); } if (!Options.CameraName.isEmpty()) { if (Options.Viewpoint != lcViewpoint::Count) Options.StdErr += tr("--viewpoint is ignored when --camera is set.\n"); if (Options.Orthographic) Options.StdErr += tr("--orthographic is ignored when --camera is set.\n"); if (Options.SetCameraAngles) Options.StdErr += tr("--camera-angles is ignored when --camera is set.\n"); if (Options.SetCameraPosition) Options.StdErr += tr("--camera-position is ignored when --camera is set.\n"); } else if (Options.Viewpoint != lcViewpoint::Count) { if (Options.SetCameraAngles) Options.StdErr += tr("--camera-angles is ignored when --viewpoint is set.\n"); if (Options.SetCameraPosition) Options.StdErr += tr("--camera-position is ignored when --viewpoint is set.\n"); } else if (Options.SetCameraAngles) { if (Options.SetCameraPosition) Options.StdErr += tr("--camera-position is ignored when --camera-angles is set.\n"); } const bool SaveAndExit = (Options.SaveImage || Options.SaveWavefront || Options.Save3DS || Options.SaveCOLLADA || Options.SaveCSV || Options.SaveHTML); if (SaveAndExit && Options.ProjectName.isEmpty()) { Options.StdErr += tr("No file name specified.\n"); Options.ParseOK = false; } return Options; } lcStartupMode lcApplication::Initialize(const QList>& LibraryPaths) { lcCommandLineOptions Options = ParseCommandLineOptions(); QTextStream StdErr(stderr, QIODevice::WriteOnly); QTextStream StdOut(stdout, QIODevice::WriteOnly); if (!Options.StdErr.isEmpty()) { StdErr << Options.StdErr; StdErr.flush(); } if (!Options.StdOut.isEmpty()) { StdOut << Options.StdOut; StdOut.flush(); } if (!Options.ParseOK) return lcStartupMode::Error; if (Options.Exit) return lcStartupMode::Success; if (!lcContext::InitializeRenderer()) { StdErr << tr("Error creating OpenGL context.\n"); return lcStartupMode::Error; } const bool SaveAndExit = (Options.SaveImage || Options.SaveWavefront || Options.Save3DS || Options.SaveCOLLADA || Options.SaveCSV || Options.SaveHTML); if (!SaveAndExit) { UpdateStyle(); gMainWindow = new lcMainWindow(); lcLoadDefaultKeyboardShortcuts(); lcLoadDefaultMouseShortcuts(); } if (!LoadPartsLibrary(Options.LibraryPaths.isEmpty() ? LibraryPaths : Options.LibraryPaths, !Options.LibraryPaths.isEmpty())) { QString Message; if (mLibrary->LoadBuiltinPieces()) Message = tr("LeoCAD could not find a compatible Parts Library so only a small number of parts will be available.\n\nPlease visit https://www.leocad.org for information on how to download and install a library."); else Message = tr("LeoCAD could not load Parts Library.\n\nPlease visit https://www.leocad.org for information on how to download and install a library."); if (gMainWindow) QMessageBox::information(gMainWindow, tr("LeoCAD"), Message); else { StdErr << Message << "\n"; StdErr.flush(); } } mPreferences.mShadingMode = Options.ShadingMode; mPreferences.mLineWidth = Options.LineWidth; mPreferences.mStudCylinderColor = Options.StudCylinderColor; mPreferences.mPartEdgeColor = Options.PartEdgeColor; mPreferences.mBlackEdgeColor = Options.BlackEdgeColor; mPreferences.mDarkEdgeColor = Options.DarkEdgeColor; mPreferences.mPartEdgeContrast = Options.PartEdgeContrast; mPreferences.mPartColorValueLDIndex = Options.PartColorValueLDIndex; mPreferences.mAutomateEdgeColor = Options.AutomateEdgeColor; lcGetPiecesLibrary()->SetStudStyle(Options.StudStyle, false); if (!SaveAndExit) gMainWindow->CreateWidgets(); Project* NewProject = new Project(); SetProject(NewProject); if (!SaveAndExit && Options.ProjectName.isEmpty() && lcGetProfileInt(LC_PROFILE_AUTOLOAD_MOSTRECENT)) Options.ProjectName = lcGetProfileString(LC_PROFILE_RECENT_FILE1); bool ProjectLoaded = false; if (!Options.ProjectName.isEmpty()) { if (gMainWindow) gMainWindow->OpenProject(Options.ProjectName); else { Project* LoadedProject = new Project(); if (LoadedProject->Load(Options.ProjectName, false)) { SetProject(LoadedProject); ProjectLoaded = true; } else { delete LoadedProject; } } } if (ProjectLoaded) { if (!Options.ModelName.isEmpty()) mProject->SetActiveModel(Options.ModelName); std::unique_ptr ActiveView; if (Options.SaveImage) { lcModel* Model; if (!Options.ModelName.isEmpty()) { Model = mProject->GetModel(Options.ModelName); if (!Model) { StdErr << tr("Error: model '%1' does not exist.\n").arg(Options.ModelName); return lcStartupMode::Error; } } else Model = mProject->GetMainModel(); ActiveView = std::unique_ptr(new lcView(lcViewType::View, Model)); ActiveView->SetOffscreenContext(); ActiveView->MakeCurrent(); } if (Options.SaveImage) ActiveView->SetSize(Options.ImageWidth, Options.ImageHeight); if (ActiveView) { if (!Options.CameraName.isEmpty()) ActiveView->SetCamera(Options.CameraName); else { ActiveView->SetProjection(Options.Orthographic); if (Options.SetFoV) ActiveView->GetCamera()->m_fovy = Options.FoV; if (Options.SetZPlanes) { lcCamera* Camera = ActiveView->GetCamera(); Camera->m_zNear = Options.ZPlanes[0]; Camera->m_zFar = Options.ZPlanes[1]; } if (Options.Viewpoint != lcViewpoint::Count) ActiveView->SetViewpoint(Options.Viewpoint); else if (Options.SetCameraAngles) ActiveView->SetCameraAngles(Options.CameraLatLon[0], Options.CameraLatLon[1]); else if (Options.SetCameraPosition) ActiveView->SetViewpoint(Options.CameraPosition[0], Options.CameraPosition[1], Options.CameraPosition[2]); } } if (Options.SaveImage) { lcModel* ActiveModel = ActiveView->GetModel(); if (Options.ImageName.isEmpty()) Options.ImageName = mProject->GetImageFileName(true); if (Options.ImageEnd < Options.ImageStart) Options.ImageEnd = Options.ImageStart; else if (Options.ImageStart > Options.ImageEnd) Options.ImageStart = Options.ImageEnd; if ((Options.ImageStart == 0) && (Options.ImageEnd == 0)) Options.ImageStart = Options.ImageEnd = ActiveModel->GetCurrentStep(); else if ((Options.ImageStart == 0) && (Options.ImageEnd != 0)) Options.ImageStart = Options.ImageEnd; else if ((Options.ImageStart != 0) && (Options.ImageEnd == 0)) Options.ImageEnd = Options.ImageStart; if (Options.ImageStart > 255) Options.ImageStart = 255; if (Options.ImageEnd > 255) Options.ImageEnd = 255; QString Frame; if (Options.ImageStart != Options.ImageEnd) { QString Extension = QFileInfo(Options.ImageName).suffix(); Frame = Options.ImageName.left(Options.ImageName.length() - Extension.length() - 1) + QLatin1String("%1.") + Extension; } else Frame = Options.ImageName; mPreferences.mFadeSteps = Options.FadeSteps; if (Options.SetFadeStepsColor) mPreferences.mFadeStepsColor = Options.FadeStepsColor; mPreferences.mHighlightNewParts = Options.ImageHighlight; if (Options.SetHighlightColor) mPreferences.mHighlightNewPartsColor = Options.HighlightColor; if (Options.CameraName.isEmpty() && !Options.SetCameraPosition) ActiveView->ZoomExtents(); auto ProgressCallback = [&StdOut](const QString& FileName) { StdOut << tr("Saved '%1'.\n").arg(FileName); }; ActiveView->SaveStepImages(Frame, Options.ImageStart != Options.ImageEnd, Options.ImageStart, Options.ImageEnd, ProgressCallback); } if (Options.SaveWavefront) { QString FileName; if (!Options.SaveWavefrontName.isEmpty()) FileName = Options.SaveWavefrontName; else FileName = Options.ProjectName; QString Extension = QFileInfo(FileName).suffix().toLower(); if (Extension.isEmpty()) { FileName += ".obj"; } else if (Extension != "obj") { FileName = FileName.left(FileName.length() - Extension.length() - 1); FileName += ".obj"; } if (mProject->ExportWavefront(FileName)) StdOut << tr("Saved '%1'.\n").arg(FileName); } if (Options.Save3DS) { QString FileName; if (!Options.Save3DSName.isEmpty()) FileName = Options.Save3DSName; else FileName = Options.ProjectName; QString Extension = QFileInfo(FileName).suffix().toLower(); if (Extension.isEmpty()) { FileName += ".3ds"; } else if (Extension != "3ds") { FileName = FileName.left(FileName.length() - Extension.length() - 1); FileName += ".3ds"; } if (mProject->Export3DStudio(FileName)) StdOut << tr("Saved '%1'.\n").arg(FileName); } if (Options.SaveCOLLADA) { QString FileName; if (!Options.SaveCOLLADAName.isEmpty()) FileName = Options.SaveCOLLADAName; else FileName = Options.ProjectName; QString Extension = QFileInfo(FileName).suffix().toLower(); if (Extension.isEmpty()) { FileName += ".dae"; } else if (Extension != "dae") { FileName = FileName.left(FileName.length() - Extension.length() - 1); FileName += ".dae"; } if (mProject->ExportCOLLADA(FileName)) StdOut << tr("Saved '%1'.\n").arg(FileName); } if (Options.SaveCSV) { QString FileName; if (!Options.SaveCSVName.isEmpty()) FileName = Options.SaveCSVName; else FileName = Options.ProjectName; QString Extension = QFileInfo(FileName).suffix().toLower(); if (Extension.isEmpty()) { FileName += ".csv"; } else if (Extension != "csv") { FileName = FileName.left(FileName.length() - Extension.length() - 1); FileName += ".csv"; } if (mProject->ExportCSV(FileName)) StdOut << tr("Saved '%1'.\n").arg(FileName); } if (Options.SaveHTML) { lcHTMLExportOptions HTMLOptions(mProject); if (!Options.SaveHTMLName.isEmpty()) HTMLOptions.PathName = Options.SaveHTMLName; mProject->ExportHTML(HTMLOptions); } } if (!SaveAndExit) { gMainWindow->SetColorIndex(lcGetColorIndex(7)); gMainWindow->GetPartSelectionWidget()->SetDefaultPart(); gMainWindow->UpdateRecentFiles(); gMainWindow->show(); #ifdef Q_OS_WIN QWindowsWindowFunctions::setHasBorderInFullScreen(gMainWindow->windowHandle(), true); #endif } return SaveAndExit ? lcStartupMode::Success : lcStartupMode::ShowWindow; } void lcApplication::Shutdown() { delete gMainWindow; gMainWindow = nullptr; delete mProject; mProject = nullptr; delete mLibrary; mLibrary = nullptr; lcContext::ShutdownRenderer(); } void lcApplication::ShowPreferencesDialog() { lcPreferencesDialogOptions Options; int CurrentAASamples = lcGetProfileInt(LC_PROFILE_ANTIALIASING_SAMPLES); lcStudStyle CurrentStudStyle = lcGetPiecesLibrary()->GetStudStyle(); Options.Preferences = mPreferences; Options.LibraryPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY); Options.MinifigSettingsPath = lcGetProfileString(LC_PROFILE_MINIFIG_SETTINGS); Options.ColorConfigPath = lcGetProfileString(LC_PROFILE_COLOR_CONFIG); Options.POVRayPath = lcGetProfileString(LC_PROFILE_POVRAY_PATH); Options.LGEOPath = lcGetProfileString(LC_PROFILE_POVRAY_LGEO_PATH); Options.DefaultAuthor = lcGetProfileString(LC_PROFILE_DEFAULT_AUTHOR_NAME); Options.Language = lcGetProfileString(LC_PROFILE_LANGUAGE); Options.CheckForUpdates = lcGetProfileInt(LC_PROFILE_CHECK_UPDATES); Options.AASamples = CurrentAASamples; Options.StudStyle = CurrentStudStyle; Options.Categories = gCategories; Options.CategoriesModified = false; Options.CategoriesDefault = false; Options.KeyboardShortcuts = gKeyboardShortcuts; Options.KeyboardShortcutsModified = false; Options.KeyboardShortcutsDefault = false; Options.MouseShortcuts = gMouseShortcuts; Options.MouseShortcutsModified = false; Options.MouseShortcutsDefault = false; lcQPreferencesDialog Dialog(gMainWindow, &Options); if (Dialog.exec() != QDialog::Accepted) return; bool LanguageChanged = Options.Language != lcGetProfileString(LC_PROFILE_LANGUAGE); bool LibraryChanged = Options.LibraryPath != lcGetProfileString(LC_PROFILE_PARTS_LIBRARY); bool ColorsChanged = Options.ColorConfigPath != lcGetProfileString(LC_PROFILE_COLOR_CONFIG); bool AAChanged = CurrentAASamples != Options.AASamples; bool StudStyleChanged = CurrentStudStyle != Options.StudStyle; bool AutomateEdgeColorChanged = Options.Preferences.mAutomateEdgeColor != mPreferences.mAutomateEdgeColor; AutomateEdgeColorChanged |= Options.Preferences.mStudCylinderColor != mPreferences.mStudCylinderColor; AutomateEdgeColorChanged |= Options.Preferences.mPartEdgeColor != mPreferences.mPartEdgeColor; AutomateEdgeColorChanged |= Options.Preferences.mBlackEdgeColor != mPreferences.mBlackEdgeColor; AutomateEdgeColorChanged |= Options.Preferences.mDarkEdgeColor != mPreferences.mDarkEdgeColor; AutomateEdgeColorChanged |= Options.Preferences.mPartEdgeContrast != mPreferences.mPartEdgeContrast; AutomateEdgeColorChanged |= Options.Preferences.mPartColorValueLDIndex != mPreferences.mPartColorValueLDIndex; mPreferences = Options.Preferences; mPreferences.SaveDefaults(); UpdateStyle(); lcSetProfileString(LC_PROFILE_DEFAULT_AUTHOR_NAME, Options.DefaultAuthor); lcSetProfileString(LC_PROFILE_PARTS_LIBRARY, Options.LibraryPath); lcSetProfileString(LC_PROFILE_MINIFIG_SETTINGS, Options.MinifigSettingsPath); lcSetProfileString(LC_PROFILE_POVRAY_PATH, Options.POVRayPath); lcSetProfileString(LC_PROFILE_POVRAY_LGEO_PATH, Options.LGEOPath); lcSetProfileString(LC_PROFILE_LANGUAGE, Options.Language); lcSetProfileInt(LC_PROFILE_CHECK_UPDATES, Options.CheckForUpdates); lcSetProfileInt(LC_PROFILE_ANTIALIASING_SAMPLES, Options.AASamples); lcSetProfileInt(LC_PROFILE_STUD_STYLE, static_cast(Options.StudStyle)); if (LanguageChanged || LibraryChanged || AAChanged) QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Some changes will only take effect the next time you start LeoCAD.")); if (Options.CategoriesModified) { if (Options.CategoriesDefault) lcResetDefaultCategories(); else { gCategories = Options.Categories; lcSaveDefaultCategories(); } gMainWindow->UpdateCategories(); } if (Options.KeyboardShortcutsModified) { if (Options.KeyboardShortcutsDefault) lcResetDefaultKeyboardShortcuts(); else { gKeyboardShortcuts = Options.KeyboardShortcuts; lcSaveDefaultKeyboardShortcuts(); } gMainWindow->UpdateShortcuts(); } if (Options.MouseShortcutsModified) { if (Options.MouseShortcutsDefault) lcResetDefaultMouseShortcuts(); else { gMouseShortcuts = Options.MouseShortcuts; lcSaveDefaultMouseShortcuts(); } } if (StudStyleChanged) { lcSetProfileInt(LC_PROFILE_STUD_STYLE, static_cast(Options.StudStyle)); lcGetPiecesLibrary()->SetStudStyle(Options.StudStyle, true); } else if (ColorsChanged || AutomateEdgeColorChanged) { if (ColorsChanged) lcSetProfileString(LC_PROFILE_COLOR_CONFIG, Options.ColorConfigPath); lcGetPiecesLibrary()->LoadColors(); } gMainWindow->SetShadingMode(Options.Preferences.mShadingMode); lcView::UpdateAllViews(); } leocad-23.03/common/lc_application.h000066400000000000000000000110451440571307300173770ustar00rootroot00000000000000#pragma once #include "lc_array.h" #include "lc_math.h" class Project; class lcPiecesLibrary; enum class lcViewSphereLocation; enum class lcShadingMode { Wireframe, Flat, DefaultLights, Full }; enum class lcColorTheme { Dark, System }; enum class lcAxisIconLocation { TopLeft, TopRight, BottomLeft, BottomRight }; class lcPreferences { public: void LoadDefaults(); void SaveDefaults(); void SetInterfaceColors(lcColorTheme ColorTheme); int mMouseSensitivity; lcShadingMode mShadingMode; bool mBackgroundGradient; quint32 mBackgroundSolidColor; quint32 mBackgroundGradientColorTop; quint32 mBackgroundGradientColorBottom; bool mDrawAxes; lcAxisIconLocation mAxisIconLocation; quint32 mAxesColor; quint32 mTextColor; quint32 mMarqueeBorderColor; quint32 mMarqueeFillColor; quint32 mOverlayColor; quint32 mActiveViewColor; quint32 mInactiveViewColor; bool mDrawEdgeLines; bool mDrawConditionalLines; float mLineWidth; bool mAllowLOD; float mMeshLODDistance; bool mFadeSteps; quint32 mFadeStepsColor; bool mHighlightNewParts; quint32 mHighlightNewPartsColor; bool mGridEnabled = true; bool mDrawGridStuds; quint32 mGridStudColor; bool mDrawGridLines; int mGridLineSpacing; quint32 mGridLineColor; bool mDrawGridOrigin; bool mFixedAxes; bool mViewSphereEnabled; lcViewSphereLocation mViewSphereLocation; int mViewSphereSize; quint32 mViewSphereColor; quint32 mViewSphereTextColor; quint32 mViewSphereHighlightColor; bool mAutoLoadMostRecent; bool mRestoreTabLayout; lcColorTheme mColorTheme; quint32 mObjectSelectedColor; quint32 mObjectFocusedColor; quint32 mCameraColor; quint32 mLightColor; quint32 mControlPointColor; quint32 mControlPointFocusedColor; int mPreviewViewSphereEnabled; int mPreviewViewSphereSize; lcViewSphereLocation mPreviewViewSphereLocation; int mDrawPreviewAxis; quint32 mStudCylinderColor; quint32 mPartEdgeColor; quint32 mBlackEdgeColor; quint32 mDarkEdgeColor; float mPartEdgeContrast; float mPartColorValueLDIndex; bool mAutomateEdgeColor; }; struct lcCommandLineOptions { bool ParseOK = true; bool Exit = false; bool SaveImage = false; bool SaveWavefront = false; bool Save3DS = false; bool SaveCOLLADA = false; bool SaveCSV = false; bool SaveHTML = false; bool SetCameraAngles = false; bool SetCameraPosition = false; bool Orthographic = false; bool SetFoV = false; bool SetZPlanes = false; bool SetFadeStepsColor = false; bool SetHighlightColor = false; bool FadeSteps = false; bool ImageHighlight = false; bool AutomateEdgeColor = false; int ImageWidth; int ImageHeight; int AASamples; lcShadingMode ShadingMode; float LineWidth; lcStudStyle StudStyle; lcStep ImageStart; lcStep ImageEnd; lcVector3 CameraPosition[3]; lcVector2 CameraLatLon; float FoV; float PartEdgeContrast; float PartColorValueLDIndex; lcVector2 ZPlanes; lcViewpoint Viewpoint; quint32 StudCylinderColor; quint32 PartEdgeColor; quint32 BlackEdgeColor; quint32 DarkEdgeColor; quint32 FadeStepsColor; quint32 HighlightColor; QString ImageName; QString ModelName; QString CameraName; QString ProjectName; QString SaveWavefrontName; QString Save3DSName; QString SaveCOLLADAName; QString SaveCSVName; QString SaveHTMLName; QList> LibraryPaths; QString StdOut; QString StdErr; }; enum class lcStartupMode { ShowWindow, Success, Error }; class lcApplication : public QApplication { Q_OBJECT public: lcApplication(int& Argc, char** Argv); ~lcApplication(); lcApplication(const lcApplication&) = delete; lcApplication(lcApplication&&) = delete; lcApplication& operator=(const lcApplication&) = delete; lcApplication& operator=(lcApplication&&) = delete; void SetProject(Project* Project); static lcCommandLineOptions ParseCommandLineOptions(); lcStartupMode Initialize(const QList>& LibraryPaths); void Shutdown(); void ShowPreferencesDialog(); void SaveTabLayout() const; bool LoadPartsLibrary(const QList>& LibraryPaths, bool OnlyUsePaths); void SetClipboard(const QByteArray& Clipboard); void ExportClipboard(const QByteArray& Clipboard); Project* mProject = nullptr; lcPiecesLibrary* mLibrary = nullptr; lcPreferences mPreferences; QByteArray mClipboard; protected: void UpdateStyle(); QString GetTabLayoutKey() const; QString mDefaultStyle; }; extern lcApplication* gApplication; inline lcPiecesLibrary* lcGetPiecesLibrary() { return gApplication->mLibrary; } inline Project* lcGetActiveProject() { return gApplication->mProject; } inline lcPreferences& lcGetPreferences() { return gApplication->mPreferences; } leocad-23.03/common/lc_array.h000066400000000000000000000063301440571307300162130ustar00rootroot00000000000000#pragma once template class lcArray { public: lcArray(int Size = 0, int Grow = 16) { mData = nullptr; mLength = 0; mAlloc = 0; mGrow = Grow; if (Size != 0) AllocGrow(Size); } lcArray(const lcArray& Array) { mData = nullptr; *this = Array; } ~lcArray() { delete[] mData; } lcArray& operator=(const lcArray& Array) { mLength = Array.mLength; mAlloc = Array.mAlloc; mGrow = Array.mGrow; delete[] mData; mData = new T[mAlloc]; for (int i = 0; i < mLength; i++) mData[i] = Array.mData[i]; return *this; } lcArray(lcArray&& Array) { mData = nullptr; *this = std::move(Array); } lcArray& operator=(lcArray&& Array) { delete[] mData; mData = Array.mData; Array.mData = nullptr; mLength = Array.mLength; Array.mLength = 0; mAlloc = Array.mAlloc; Array.mAlloc = 0; mGrow = Array.mGrow; Array.mGrow = 16; return *this; } const T& operator[](int Index) const { return mData[Index]; } T& operator[](int Index) { return mData[Index]; } bool operator==(const lcArray& Array) const { if (mLength != Array.mLength) return false; for (int i = 0; i < mLength; i++) if (mData[i] != Array.mData[i]) return false; return true; } T* begin() { return &mData[0]; } T* end() { return &mData[0] + mLength; } const T* begin() const { return &mData[0]; } const T* end() const { return &mData[0] + mLength; } bool IsEmpty() const { return mLength == 0; } int GetSize() const { return mLength; } void SetSize(size_t NewSize) { if (NewSize > mAlloc) AllocGrow(NewSize - mLength); mLength = (int)NewSize; } void SetGrow(int Grow) { if (Grow) mGrow = Grow; } void AllocGrow(size_t Grow) { if ((mLength + Grow) > mAlloc) { const size_t NewSize = ((mLength + Grow + mGrow - 1) / mGrow) * mGrow; T* NewData = new T[NewSize]; for (int i = 0; i < mLength; i++) NewData[i] = mData[i]; delete[] mData; mData = NewData; mAlloc = NewSize; } } void Add(const T& NewItem) { AllocGrow(1); mData[mLength++] = NewItem; } T& Add() { AllocGrow(1); mData[mLength++] = T(); return mData[mLength - 1]; } T& InsertAt(int Index) { if (Index >= mLength) AllocGrow(Index - mLength + 1); else AllocGrow(1); mLength++; for (int i = mLength - 1; i > Index; i--) mData[i] = mData[i - 1]; return mData[Index]; } void InsertAt(int Index, const T& NewItem) { if (Index >= mLength) AllocGrow(Index - mLength + 1); else AllocGrow(1); mLength++; for (int i = mLength - 1; i > Index; i--) mData[i] = mData[i - 1]; mData[Index] = NewItem; } void RemoveIndex(int Index) { mLength--; for (int i = Index; i < mLength; i++) mData[i] = mData[i + 1]; } void Remove(const T& Item) { for (int i = 0; i < mLength; i++) { if (mData[i] == Item) { RemoveIndex(i); return; } } } void RemoveAll() { mLength = 0; } void DeleteAll() { for (int i = 0; i < mLength; i++) delete mData[i]; mLength = 0; } int FindIndex(const T& Item) const { for (int i = 0; i < mLength; i++) if (mData[i] == Item) return i; return -1; } protected: T* mData; int mLength; size_t mAlloc; int mGrow; }; leocad-23.03/common/lc_bricklink.cpp000066400000000000000000000063661440571307300174110ustar00rootroot00000000000000#include "lc_global.h" #include "lc_file.h" #include "lc_library.h" #include "lc_mainwindow.h" #include "pieceinf.h" static QJsonDocument lcLoadBrickLinkMapping() { std::map Remapping; QFile File(lcGetPiecesLibrary()->mLibraryDir.absoluteFilePath(QLatin1String("ldraw2bl.txt"))); QByteArray Data; if (File.open(QIODevice::ReadOnly)) Data = File.readAll(); else { QFile DefaultFile(":/resources/ldraw2bl.txt"); if (DefaultFile.open(QIODevice::ReadOnly)) Data = DefaultFile.readAll(); } return QJsonDocument::fromJson(Data); } static std::string lcGetBrickLinkPart(const QJsonObject& PartMapping, const QString& LDrawPart) { QJsonObject::const_iterator PartIt = PartMapping.find(LDrawPart); return (PartIt != PartMapping.end()) ? PartIt.value().toString().toStdString() : LDrawPart.toStdString(); } static int lcGetBrickLinkColor(const QJsonObject& ColorMapping, int ColorIndex) { int ColorCode = gColorList[ColorIndex].Code; QJsonObject::const_iterator ColorIt = ColorMapping.find(QString::number(ColorCode)); return (ColorIt != ColorMapping.end()) ? ColorIt.value().toString().toInt() : 0; } class lcBrickLinkItem { public: lcBrickLinkItem(const std::string& id, int color, int count) : mId(id), mColor(color), mCount(count) { } void AddToCount(int count) { mCount += count; } std::string mId; int mColor; int mCount; }; void lcExportBrickLink(const QString& SaveFileName, const lcPartsList& PartsList) { QJsonDocument Document = lcLoadBrickLinkMapping(); QJsonObject Root = Document.object(); QJsonObject PartMapping = Root["Parts"].toObject(); QJsonObject ColorMapping = Root["Colors"].toObject(); lcDiskFile BrickLinkFile(SaveFileName); char Line[1024]; if (!BrickLinkFile.Open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, QObject::tr("LeoCAD"), QObject::tr("Could not open file '%1' for writing.").arg(SaveFileName)); return; } std::map Inventory; BrickLinkFile.WriteLine("\n"); for (const auto& PartIt : PartsList) { const PieceInfo* Info = PartIt.first; for (const auto& ColorIt : PartIt.second) { char FileName[LC_PIECE_NAME_LEN]; strcpy(FileName, Info->mFileName); char* Ext = strchr(FileName, '.'); if (Ext) *Ext = 0; std::string Remapped = lcGetBrickLinkPart(PartMapping, FileName); int Color = lcGetBrickLinkColor(ColorMapping, ColorIt.first); std::string key(Remapped); key += "-" + std::to_string(Color); auto iter = Inventory.find(key); if (iter == Inventory.end()) { Inventory.emplace(std::make_pair(key, lcBrickLinkItem(Remapped, Color, ColorIt.second))); } else { iter->second.AddToCount(ColorIt.second); } } } for (const auto& Item : Inventory) { BrickLinkFile.WriteLine(" \n"); BrickLinkFile.WriteLine(" P\n"); sprintf(Line, " %s\n", Item.second.mId.c_str()); BrickLinkFile.WriteLine(Line); sprintf(Line, " %d\n", Item.second.mCount); BrickLinkFile.WriteLine(Line); if (Item.second.mColor) { sprintf(Line, " %d\n", Item.second.mColor); BrickLinkFile.WriteLine(Line); } BrickLinkFile.WriteLine(" \n"); } BrickLinkFile.WriteLine("\n"); } leocad-23.03/common/lc_bricklink.h000066400000000000000000000001351440571307300170420ustar00rootroot00000000000000#pragma once void lcExportBrickLink(const QString& FileName, const lcPartsList& PartsList); leocad-23.03/common/lc_category.cpp000066400000000000000000000154371440571307300172550ustar00rootroot00000000000000#include "lc_global.h" #include "lc_category.h" #include "lc_file.h" #include "lc_profile.h" std::vector gCategories; void lcResetDefaultCategories() { lcResetCategories(gCategories); lcRemoveProfileKey(LC_PROFILE_CATEGORIES); } void lcLoadDefaultCategories(bool BuiltInLibrary) { QByteArray Buffer = lcGetProfileBuffer(LC_PROFILE_CATEGORIES); if (Buffer.isEmpty() || !lcLoadCategories(Buffer, gCategories)) lcResetCategories(gCategories, BuiltInLibrary); } void lcSaveDefaultCategories() { QByteArray ByteArray; QTextStream Stream(&ByteArray, QIODevice::WriteOnly); lcSaveCategories(Stream, gCategories); lcSetProfileBuffer(LC_PROFILE_CATEGORIES, ByteArray); } void lcResetCategories(std::vector& Categories, bool BuiltInLibrary) { const char DefaultCategories[] = { "Animal=^%Animal | ^%Bone\n" "Antenna=^%Antenna\n" "Arch=^%Arch\n" "Bar=^%Bar\n" "Baseplate=^%Baseplate | ^%Platform\n" "Boat=^%Boat | ^%Sail\n" "Brick=^%Brick\n" "Container=^%Container | ^%Box | ^Chest | ^%Storage | ^Mailbox\n" "Door and Window=^%Door | ^%Window | ^%Glass | ^%Freestyle | ^%Gate | ^%Garage | ^%Roller\n" "Electric=^%Battery | ^%Electric\n" "Hinge and Bracket=^%Hinge | ^%Bracket | ^%Turntable\n" "Hose=^%Hose | ^%Rubber | ^%String\n" "Minifig=^%Minifig\n" "Miscellaneous=^%Arm | ^%Barrel | ^%Brush | ^%Bucket | ^%Cardboard | ^%Claw | ^%Cockpit | ^%Cocoon | ^%Conveyor | ^%Crane | ^%Cupboard | ^%Fence | ^%Gold | ^%Handle | ^%Hook | ^%Jack | ^%Key | ^%Ladder | ^%Medical | ^%Motor | ^%Rock | ^%Rope | ^%Slide | ^%Sheet | ^%Snow | ^%Sports | ^%Spring | ^%Staircase | ^%Stretcher | ^%Tap | ^%Tipper | ^%Trailer | ^%Umbrella | ^%Winch\n" "Other=^%Ball | ^%Belville | ^%BigFig | ^%Die | ^%Duplo | ^%Fabuland | ^%Figure | ^%Homemaker | ^%Maxifig | ^%Microfig | ^%Mursten | ^%Quatro | ^%Scala | ^%Znap\n" "Panel=^%Panel | ^%Castle Wall | ^%Castle Turret\n" "Plant=^%Plant\n" "Plate=^%Plate\n" "Round=^%Cylinder | ^%Cone | ^%Dish | ^%Dome | ^%Hemisphere | ^%Round\n" "Sign and Flag=^%Flag | ^%Roadsign | ^%Streetlight | ^%Flagpost | ^%Lamppost | ^%Signpost\n" "Slope=^%Slope | ^%Roof\n" "Sticker=^%Sticker\n" "Support=^%Support\n" "Technic=^%Technic | ^%Rack\n" "Tile=^%Tile\n" "Train=^%Train | ^%Monorail | ^%Magnet\n" "Tyre and Wheel=^%Tyre | %^Wheel | %^Wheels | ^%Castle Wagon | ^%Axle\n" "Vehicle=^%Bike | ^%Canvas | ^%Car | ^%Excavator | ^%Exhaust | ^%Forklift | ^%Grab Jaw | ^%Jet | ^%Landing | ^%Motorcycle | ^%Plane | ^%Propellor | ^%Tail | ^%Tractor | ^%Vehicle | ^%Wheelbarrow\n" "Windscreen=^%Windscreen\n" "Wedge=^%Wedge\n" "Wing=^%Wing\n" }; const char BuiltInCategories[] = { "Baseplate=^%Baseplate\n" "Brick=^%Brick\n" "Plate=^%Plate\n" "Slope=^%Slope\n" "Tile=^%Tile\n" }; QByteArray Buffer; if (BuiltInLibrary) Buffer.append(BuiltInCategories, sizeof(BuiltInCategories)); else Buffer.append(DefaultCategories, sizeof(DefaultCategories)); lcLoadCategories(Buffer, Categories); } bool lcLoadCategories(const QString& FileName, std::vector& Categories) { QFile File(FileName); if (!File.open(QIODevice::ReadOnly)) return false; QByteArray FileData = File.readAll(); return lcLoadCategories(FileData, Categories); } bool lcLoadCategories(const QByteArray& Buffer, std::vector& Categories) { Categories.clear(); QTextStream Stream(Buffer); for (QString Line = Stream.readLine(); !Line.isNull(); Line = Stream.readLine()) { int Equals = Line.indexOf('='); if (Equals == -1) continue; QString Name = Line.left(Equals); QString Keywords = Line.mid(Equals + 1); lcLibraryCategory Category; Category.Name = Name; Category.Keywords = Keywords.toLatin1(); Categories.emplace_back(std::move(Category)); } return true; } bool lcSaveCategories(const QString& FileName, const std::vector& Categories) { QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) return false; QTextStream Stream(&File); return lcSaveCategories(Stream, Categories); } bool lcSaveCategories(QTextStream& Stream, const std::vector& Categories) { QString Format("%1=%2\r\n"); for (const lcLibraryCategory& Category : Categories) Stream << Format.arg(Category.Name, QString::fromLatin1(Category.Keywords)); Stream.flush(); return true; } bool lcMatchCategory(const char* PieceName, const char* Expression) { // Check if we need to split the test expression. const char* p = Expression; while (*p) { if (*p == '!') { return !lcMatchCategory(PieceName, p + 1); } else if (*p == '(') { // const char* Start = p; int c = 0; // Skip what's inside the parenthesis. do { if (*p == '(') c++; else if (*p == ')') c--; else if (*p == 0) return false; // Mismatched parenthesis. p++; } while (c); if (*p == 0) break; } else if ((*p == '|') || (*p == '&')) { std::string LeftStr(Expression, (p - Expression) - 1); std::string RightStr(p + 1); if (*p == '|') return lcMatchCategory(PieceName, LeftStr.c_str()) || lcMatchCategory(PieceName, RightStr.c_str()); else return lcMatchCategory(PieceName, LeftStr.c_str()) && lcMatchCategory(PieceName, RightStr.c_str()); } p++; } if (strchr(Expression, '(')) { p = Expression; while (*p) { if (*p == '(') { const char* Start = p; int c = 0; // Extract what's inside the parenthesis. do { if (*p == '(') c++; else if (*p == ')') c--; else if (*p == 0) return false; // Mismatched parenthesis. p++; } while (c); std::string SubExpression(Start + 1, p - Start - 2); return lcMatchCategory(PieceName, SubExpression.c_str()); } p++; } } const char* SearchStart = Expression; while (isspace(*SearchStart)) SearchStart++; const char* SearchEnd = SearchStart + strlen(SearchStart) - 1; while (SearchEnd >= SearchStart && isspace(*SearchEnd)) SearchEnd--; // Testing a simple case. std::string Search; if (SearchStart != SearchEnd) Search = std::string(SearchStart, SearchEnd - SearchStart + 1); const char* Word = Search.c_str(); // Check for modifiers. bool WholeWord = 0; bool Begin = 0; for (;;) { if (Word[0] == '^') WholeWord = true; else if (Word[0] == '%') Begin = true; else break; Word++; } const char* Result = strcasestr(PieceName, Word); if (!Result) return false; if (Begin && (Result != PieceName)) { if ((Result != PieceName + 1) || ((Result[-1] != '_') && (Result[-1] != '~'))) return false; } if (WholeWord) { char End = Result[strlen(Word)]; if ((End != 0) && (End != ' ')) return false; if ((Result != PieceName) && ((Result[-1] == '_') || (Result[-1] == '~'))) Result--; if ((Result != PieceName) && (Result[-1] != ' ')) return false; } return true; } leocad-23.03/common/lc_category.h000066400000000000000000000014431440571307300167120ustar00rootroot00000000000000#pragma once struct lcLibraryCategory { QString Name; QByteArray Keywords; }; extern std::vector gCategories; void lcResetDefaultCategories(); void lcLoadDefaultCategories(bool BuiltInLibrary = false); void lcSaveDefaultCategories(); void lcResetCategories(std::vector& Categories, bool BuiltInLibrary = false); bool lcLoadCategories(const QString& FileName, std::vector& Categories); bool lcLoadCategories(const QByteArray& Buffer, std::vector& Categories); bool lcSaveCategories(const QString& FileName, const std::vector& Categories); bool lcSaveCategories(QTextStream& Stream, const std::vector& Categories); bool lcMatchCategory(const char* PieceName, const char* Expression); leocad-23.03/common/lc_collapsiblewidget.cpp000066400000000000000000000041161440571307300211250ustar00rootroot00000000000000#include "lc_global.h" #include "lc_collapsiblewidget.h" QImage lcCollapsibleWidget::mExpandedIcon; QImage lcCollapsibleWidget::mCollapsedIcon; lcCollapsibleWidget::lcCollapsibleWidget(const QString& Title, QWidget* Parent) : QWidget(Parent) { QVBoxLayout* Layout = new QVBoxLayout(this); // Layout->setSpacing(0); Layout->setContentsMargins(0, 0, 0, 0); QHBoxLayout* TitleLayout = new QHBoxLayout(); TitleLayout->setContentsMargins(0, 0, 0, 0); Layout->addLayout(TitleLayout); mTitleButton = new QToolButton(this); mTitleButton->setText(Title); mTitleButton->setAutoRaise(true); mTitleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mTitleButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum); TitleLayout->addWidget(mTitleButton); connect(mTitleButton, SIGNAL(clicked()), this, SLOT(TitleClicked())); mChildWidget = new QWidget(this); Layout->addWidget(mChildWidget); UpdateIcon(); } void lcCollapsibleWidget::TitleClicked() { mExpanded = !mExpanded; mChildWidget->setVisible(mExpanded); UpdateIcon(); } void lcCollapsibleWidget::Collapse() { if (mExpanded) TitleClicked(); } void lcCollapsibleWidget::SetChildLayout(QLayout* Layout) { Layout->setContentsMargins(12, 0, 0, 0); mChildWidget->setLayout(Layout); } void lcCollapsibleWidget::UpdateIcon() { if (mExpanded) { if (mExpandedIcon.isNull()) { QImage Image(16, 16, QImage::Format::Format_ARGB32); Image.fill(QColor(0, 0, 0, 0)); uint Color = palette().color(QPalette::Text).rgba(); for (int y = 0; y < 8; y++) for (int x = y; x < 8 - y; x++) Image.setPixel(x + 4, y + 6, Color); mExpandedIcon = Image; } mTitleButton->setIcon(QPixmap::fromImage(mExpandedIcon)); } else { if (mCollapsedIcon.isNull()) { QImage Image(16, 16, QImage::Format::Format_ARGB32); Image.fill(QColor(0, 0, 0, 0)); uint Color = palette().color(QPalette::Text).rgba(); for (int y = 0; y < 8; y++) for (int x = y; x < 8 - y; x++) Image.setPixel(y + 6, x + 4, Color); mCollapsedIcon = Image; } mTitleButton->setIcon(QPixmap::fromImage(mCollapsedIcon)); } } leocad-23.03/common/lc_collapsiblewidget.h000066400000000000000000000006751440571307300206000ustar00rootroot00000000000000#pragma once class lcCollapsibleWidget : public QWidget { Q_OBJECT public: lcCollapsibleWidget(const QString& RootTitle, QWidget* Parent = nullptr); void Collapse(); void SetChildLayout(QLayout* Layout); protected slots: void TitleClicked(); protected: void UpdateIcon(); QToolButton* mTitleButton = nullptr; QWidget* mChildWidget = nullptr; bool mExpanded = true; static QImage mExpandedIcon; static QImage mCollapsedIcon; }; leocad-23.03/common/lc_colors.cpp000066400000000000000000000226721440571307300167400ustar00rootroot00000000000000#include "lc_global.h" #include "lc_colors.h" #include "lc_file.h" #include "lc_library.h" #include "lc_application.h" #include std::vector gColorList; lcColorGroup gColorGroups[LC_NUM_COLORGROUPS]; int gEdgeColor; int gDefaultColor; static void GetToken(char*& Ptr, char* Token) { while (*Ptr && *Ptr <= 32) Ptr++; while (*Ptr > 32) *Token++ = *Ptr++; *Token = 0; } static void lcAdjustStudStyleColors(std::vector& Colors, lcStudStyle StudStyle) { const lcPreferences& Preferences = lcGetPreferences(); if (!Preferences.mAutomateEdgeColor && !lcIsHighContrast(StudStyle)) return; const lcVector4 Edge = lcVector4FromColor(Preferences.mPartEdgeColor); const lcVector4 DarkEdge = lcVector4FromColor(Preferences.mDarkEdgeColor); const lcVector4 BlackEdge = lcVector4FromColor(Preferences.mBlackEdgeColor); const float ContrastControl = Preferences.mPartEdgeContrast; const float LightDarkControl = Preferences.mAutomateEdgeColor ? Preferences.mPartColorValueLDIndex : LC_SRGB_TO_LINEAR(Preferences.mPartColorValueLDIndex); for (lcColor& Color : Colors) { const lcVector3 LinearColor = lcSRGBToLinear(lcVector3(Color.Value)); const float ValueLuminescence = lcLuminescence(LinearColor); if (Preferences.mAutomateEdgeColor) { if (Color.Adjusted) continue; const float EdgeLuminescence = lcLuminescence(lcSRGBToLinear(lcVector3(Color.Edge))); Color.Edge = lcAlgorithmicEdgeColor(LinearColor, ValueLuminescence, EdgeLuminescence, ContrastControl, LightDarkControl); Color.Adjusted = true; } else { if (Color.Code == 4242) continue; else if (Color.Code == 0) Color.Edge = BlackEdge; else if (ValueLuminescence < LightDarkControl) Color.Edge = DarkEdge; else Color.Edge = Edge; } } } static std::vector lcParseColorFile(lcFile& File) { char Line[1024], Token[1024]; std::vector Colors; lcColor Color; while (File.ReadLine(Line, sizeof(Line))) { char* Ptr = Line; GetToken(Ptr, Token); if (strcmp(Token, "0")) continue; GetToken(Ptr, Token); strupr(Token); if (strcmp(Token, "!COLOUR")) continue; Color.Code = ~0U; Color.Translucent = false; Color.Group = LC_COLORGROUP_SOLID; Color.Value[0] = FLT_MAX; Color.Value[1] = FLT_MAX; Color.Value[2] = FLT_MAX; Color.Value[3] = 1.0f; Color.Edge[0] = FLT_MAX; Color.Edge[1] = FLT_MAX; Color.Edge[2] = FLT_MAX; Color.Edge[3] = 1.0f; GetToken(Ptr, Token); strncpy(Color.Name, Token, sizeof(Color.Name)); Color.Name[LC_MAX_COLOR_NAME - 1] = 0; strncpy(Color.SafeName, Color.Name, sizeof(Color.SafeName)); for (char* Underscore = strchr((char*)Color.Name, '_'); Underscore; Underscore = strchr(Underscore, '_')) *Underscore = ' '; for (GetToken(Ptr, Token); Token[0]; GetToken(Ptr, Token)) { strupr(Token); if (!strcmp(Token, "CODE")) { GetToken(Ptr, Token); Color.Code = atoi(Token); } else if (!strcmp(Token, "VALUE")) { GetToken(Ptr, Token); if (Token[0] == '#') Token[0] = ' '; int Value; if (sscanf(Token, "%x", &Value) != 1) Value = 0; Color.Value[2] = (float)(Value & 0xff) / 255.0f; Value >>= 8; Color.Value[1] = (float)(Value & 0xff) / 255.0f; Value >>= 8; Color.Value[0] = (float)(Value & 0xff) / 255.0f; } else if (!strcmp(Token, "EDGE")) { GetToken(Ptr, Token); if (Token[0] == '#') Token[0] = ' '; int Value; if (sscanf(Token, "%x", &Value) != 1) Value = 0; Color.Edge[2] = (float)(Value & 0xff) / 255.0f; Value >>= 8; Color.Edge[1] = (float)(Value & 0xff) / 255.0f; Value >>= 8; Color.Edge[0] = (float)(Value & 0xff) / 255.0f; } else if (!strcmp(Token, "ALPHA")) { GetToken(Ptr, Token); int Value = atoi(Token); Color.Value[3] = (float)(Value & 0xff) / 255.0f; if (Value != 255) Color.Translucent = true; if (Value == 128) Color.Group = LC_COLORGROUP_TRANSLUCENT; else if (Value != 0) Color.Group = LC_COLORGROUP_SPECIAL; } else if (!strcmp(Token, "CHROME") || !strcmp(Token, "PEARLESCENT") || !strcmp(Token, "RUBBER") || !strcmp(Token, "MATTE_METALIC") || !strcmp(Token, "METAL") || !strcmp(Token, "LUMINANCE")) { Color.Group = LC_COLORGROUP_SPECIAL; } else if (!strcmp(Token, "MATERIAL")) { Color.Group = LC_COLORGROUP_SPECIAL; break; // Material is always last so ignore it and the rest of the line. } } if (Color.Code == ~0U || Color.Value[0] == FLT_MAX) continue; if (Color.Edge[0] == FLT_MAX) { Color.Edge[0] = 33.0f / 255.0f; Color.Edge[1] = 33.0f / 255.0f; Color.Edge[2] = 33.0f / 255.0f; } bool Duplicate = false; for (lcColor& ExistingColor : Colors) { if (ExistingColor.Code == Color.Code) { ExistingColor = Color; Duplicate = true; break; } } if (!Duplicate) Colors.push_back(Color); } return Colors; } bool lcLoadColorFile(lcFile& File, lcStudStyle StudStyle) { std::vector Colors = lcParseColorFile(File); const bool Valid = !Colors.empty(); if (Valid) lcAdjustStudStyleColors(Colors, StudStyle); bool FoundMain = false, FoundEdge = false, FoundStud = false, FoundNoColor = false; for (const lcColor& Color : Colors) { switch (Color.Code) { case 16: FoundMain = true; break; case 24: FoundEdge = true; break; case 4242: FoundStud = true; break; case LC_COLOR_NOCOLOR: FoundNoColor = true; break; } } if (!FoundMain) { lcColor MainColor; MainColor.Code = 16; MainColor.Translucent = false; MainColor.Group = LC_COLORGROUP_SOLID; MainColor.Value[0] = 1.0f; MainColor.Value[1] = 1.0f; MainColor.Value[2] = 0.5f; MainColor.Value[3] = 1.0f; MainColor.Edge[0] = 0.2f; MainColor.Edge[1] = 0.2f; MainColor.Edge[2] = 0.2f; MainColor.Edge[3] = 1.0f; strcpy(MainColor.Name, "Main Color"); strcpy(MainColor.SafeName, "Main_Color"); Colors.push_back(MainColor); } if (!FoundEdge) { lcColor EdgeColor; EdgeColor.Code = 24; EdgeColor.Translucent = false; EdgeColor.Group = LC_NUM_COLORGROUPS; EdgeColor.Value[0] = 0.5f; EdgeColor.Value[1] = 0.5f; EdgeColor.Value[2] = 0.5f; EdgeColor.Value[3] = 1.0f; EdgeColor.Edge[0] = 0.2f; EdgeColor.Edge[1] = 0.2f; EdgeColor.Edge[2] = 0.2f; EdgeColor.Edge[3] = 1.0f; strcpy(EdgeColor.Name, "Edge Color"); strcpy(EdgeColor.SafeName, "Edge_Color"); Colors.push_back(EdgeColor); } if (!FoundStud) { const lcPreferences& Preferences = lcGetPreferences(); lcColor StudCylinderColor; StudCylinderColor.Code = 4242; StudCylinderColor.Translucent = false; StudCylinderColor.Group = LC_NUM_COLORGROUPS; StudCylinderColor.Value = lcVector4FromColor(Preferences.mStudCylinderColor); StudCylinderColor.Edge = lcVector4FromColor(Preferences.mPartEdgeColor); strcpy(StudCylinderColor.Name, "Stud Cylinder Color"); strcpy(StudCylinderColor.SafeName, "Stud_Cylinder_Color"); Colors.push_back(StudCylinderColor); } if (!FoundNoColor) { lcColor NoColor; NoColor.Code = LC_COLOR_NOCOLOR; NoColor.Translucent = false; NoColor.Group = LC_NUM_COLORGROUPS; NoColor.Value[0] = 0.5f; NoColor.Value[1] = 0.5f; NoColor.Value[2] = 0.5f; NoColor.Value[3] = 1.0f; NoColor.Edge[0] = 0.2f; NoColor.Edge[1] = 0.2f; NoColor.Edge[2] = 0.2f; NoColor.Edge[3] = 1.0f; strcpy(NoColor.Name, "No Color"); strcpy(NoColor.SafeName, "No_Color"); Colors.push_back(NoColor); } for (lcColor& Color : gColorList) Color.Group = LC_NUM_COLORGROUPS; for (int GroupIdx = 0; GroupIdx < LC_NUM_COLORGROUPS; GroupIdx++) gColorGroups[GroupIdx].Colors.clear(); gColorGroups[0].Name = QApplication::tr("Solid", "Colors"); gColorGroups[1].Name = QApplication::tr("Translucent", "Colors"); gColorGroups[2].Name = QApplication::tr("Special", "Colors"); for (lcColor& Color : Colors) { int ColorIndex; for (ColorIndex = 0; ColorIndex < static_cast(gColorList.size()); ColorIndex++) if (gColorList[ColorIndex].Code == Color.Code) break; if (ColorIndex == static_cast(gColorList.size())) gColorList.push_back(Color); else gColorList[ColorIndex] = Color; if (Color.Group != LC_NUM_COLORGROUPS) gColorGroups[Color.Group].Colors.push_back(ColorIndex); if (Color.Code == 16) gDefaultColor = ColorIndex; else if (Color.Code == 24) gEdgeColor = ColorIndex; } return Valid; } void lcLoadDefaultColors(lcStudStyle StudStyle) { lcDiskFile ConfigFile(":/resources/ldconfig.ldr"); if (ConfigFile.Open(QIODevice::ReadOnly)) lcLoadColorFile(ConfigFile, StudStyle); } int lcGetColorIndex(quint32 ColorCode) { for (size_t ColorIdx = 0; ColorIdx < gColorList.size(); ColorIdx++) if (gColorList[ColorIdx].Code == ColorCode) return (int)ColorIdx; lcColor Color; Color.Code = ColorCode; Color.Translucent = false; Color.Edge[0] = 0.2f; Color.Edge[1] = 0.2f; Color.Edge[2] = 0.2f; Color.Edge[3] = 1.0f; if (ColorCode & LC_COLOR_DIRECT) { Color.Value[0] = (float)((ColorCode & 0xff0000) >> 16) / 255.0f; Color.Value[1] = (float)((ColorCode & 0x00ff00) >> 8) / 255.0f; Color.Value[2] = (float)((ColorCode & 0x0000ff) >> 0) / 255.0f; Color.Value[3] = 1.0f; sprintf(Color.Name, "Color %06X", ColorCode & 0xffffff); sprintf(Color.SafeName, "Color_%06X", ColorCode & 0xffffff); } else { Color.Value[0] = 0.5f; Color.Value[1] = 0.5f; Color.Value[2] = 0.5f; Color.Value[3] = 1.0f; sprintf(Color.Name, "Color %03d", ColorCode); sprintf(Color.SafeName, "Color_%03d", ColorCode); } gColorList.push_back(Color); return (int)gColorList.size() - 1; } leocad-23.03/common/lc_colors.h000066400000000000000000000027221440571307300163770ustar00rootroot00000000000000#pragma once #include "lc_array.h" #include "lc_math.h" #define LC_MAX_COLOR_NAME 64 #define LC_COLOR_DIRECT 0x80000000 #define LC_COLOR_NOCOLOR 0xffffffff struct lcColor { quint32 Code; int Group; bool Translucent = false; bool Adjusted = false; lcVector4 Value; lcVector4 Edge; char Name[LC_MAX_COLOR_NAME]; char SafeName[LC_MAX_COLOR_NAME]; }; enum { LC_COLORGROUP_SOLID, LC_COLORGROUP_TRANSLUCENT, LC_COLORGROUP_SPECIAL, LC_NUM_COLORGROUPS }; struct lcColorGroup { std::vector Colors; QString Name; }; extern std::vector gColorList; extern lcColorGroup gColorGroups[LC_NUM_COLORGROUPS]; extern int gEdgeColor; extern int gDefaultColor; void lcLoadDefaultColors(lcStudStyle StudStyle); bool lcLoadColorFile(lcFile& File, lcStudStyle StudStyle); int lcGetColorIndex(quint32 ColorCode); inline quint32 lcGetColorCodeFromExtendedColor(int Color) { const quint32 ConversionTable[] = { 4, 12, 2, 10, 1, 9, 14, 15, 8, 0, 6, 13, 13, 334, 36, 44, 34, 42, 33, 41, 46, 47, 7, 382, 6, 13, 11, 383 }; return ConversionTable[Color]; } inline quint32 lcGetColorCodeFromOriginalColor(int Color) { const quint32 ConversionTable[] = { 0, 2, 4, 9, 7, 6, 22, 8, 10, 11, 14, 16, 18, 9, 21, 20, 22, 8, 10, 11 }; return lcGetColorCodeFromExtendedColor(ConversionTable[Color]); } inline quint32 lcGetColorCode(int ColorIndex) { return gColorList[ColorIndex].Code; } inline bool lcIsColorTranslucent(size_t ColorIndex) { return gColorList[ColorIndex].Translucent; } leocad-23.03/common/lc_commands.cpp000066400000000000000000001500571440571307300172370ustar00rootroot00000000000000#include "lc_global.h" #include "lc_commands.h" const lcCommand gCommands[] = { // LC_FILE_NEW { QT_TRANSLATE_NOOP("Action", "File.New"), QT_TRANSLATE_NOOP("Menu", "&New"), QT_TRANSLATE_NOOP("Status", "Create a new model"), "Ctrl+N" }, // LC_FILE_OPEN { QT_TRANSLATE_NOOP("Action", "File.Open"), QT_TRANSLATE_NOOP("Menu", "&Open..."), QT_TRANSLATE_NOOP("Status", "Open an existing model"), "Ctrl+O" }, // LC_FILE_MERGE { QT_TRANSLATE_NOOP("Action", "File.Merge"), QT_TRANSLATE_NOOP("Menu", "&Merge..."), QT_TRANSLATE_NOOP("Status", "Merge the contents of another file with the current one"), "" }, // LC_FILE_SAVE { QT_TRANSLATE_NOOP("Action", "File.Save"), QT_TRANSLATE_NOOP("Menu", "&Save"), QT_TRANSLATE_NOOP("Status", "Save the current model"), "Ctrl+S" }, // LC_FILE_SAVEAS { QT_TRANSLATE_NOOP("Action", "File.SaveAs"), QT_TRANSLATE_NOOP("Menu", "Save &As..."), QT_TRANSLATE_NOOP("Status", "Save the current model with a new name"), "" }, // LC_FILE_SAVE_IMAGE { QT_TRANSLATE_NOOP("Action", "File.SaveImage"), QT_TRANSLATE_NOOP("Menu", "Save &Image..."), QT_TRANSLATE_NOOP("Status", "Save a picture of the current view"), "" }, // LC_FILE_IMPORT_LDD { QT_TRANSLATE_NOOP("Action", "File.Import.LDD"), QT_TRANSLATE_NOOP("Menu", "&LEGO Digital Designer..."), QT_TRANSLATE_NOOP("Status", "Import a file in LEGO Digital Designer LXF format"), "" }, // LC_FILE_IMPORT_INVENTORY { QT_TRANSLATE_NOOP("Action", "File.Import.Inventory"), QT_TRANSLATE_NOOP("Menu", "Set &Inventory..."), QT_TRANSLATE_NOOP("Status", "Import all parts from an official set"), "" }, // LC_FILE_EXPORT_3DS { QT_TRANSLATE_NOOP("Action", "File.Export.3DS"), QT_TRANSLATE_NOOP("Menu", "3D &Studio..."), QT_TRANSLATE_NOOP("Status", "Export the current model in 3D Studio 3DS format"), "" }, // LC_FILE_EXPORT_COLLADA { QT_TRANSLATE_NOOP("Action", "File.Export.COLLADA"), QT_TRANSLATE_NOOP("Menu", "&COLLADA..."), QT_TRANSLATE_NOOP("Status", "Export the current model in COLLADA DAE format"), "" }, // LC_FILE_EXPORT_HTML { QT_TRANSLATE_NOOP("Action", "File.Export.HTML"), QT_TRANSLATE_NOOP("Menu", "&HTML..."), QT_TRANSLATE_NOOP("Status", "Create an HTML page for the current model"), "" }, // LC_FILE_EXPORT_BRICKLINK { QT_TRANSLATE_NOOP("Action", "File.Export.BrickLink"), QT_TRANSLATE_NOOP("Menu", "&BrickLink..."), QT_TRANSLATE_NOOP("Status", "Export a list of parts used in BrickLink XML format"), "" }, // LC_FILE_EXPORT_CSV { QT_TRANSLATE_NOOP("Action", "File.Export.CSV"), QT_TRANSLATE_NOOP("Menu", "&CSV..."), QT_TRANSLATE_NOOP("Status", "Export a list of parts used in comma delimited file format"), "" }, // LC_FILE_EXPORT_POVRAY { QT_TRANSLATE_NOOP("Action", "File.Export.POVRay"), QT_TRANSLATE_NOOP("Menu", "&POV-Ray..."), QT_TRANSLATE_NOOP("Status", "Export the current model in POV-Ray format"), "" }, // LC_FILE_EXPORT_WAVEFRONT { QT_TRANSLATE_NOOP("Action", "File.Export.Wavefront"), QT_TRANSLATE_NOOP("Menu", "&Wavefront..."), QT_TRANSLATE_NOOP("Status", "Export the current model in Wavefront OBJ format"), "" }, // LC_FILE_RENDER { QT_TRANSLATE_NOOP("Action", "File.Render"), QT_TRANSLATE_NOOP("Menu", "&Render..."), QT_TRANSLATE_NOOP("Status", "Render the current model using POV-Ray"), "" }, // LC_FILE_INSTRUCTIONS { QT_TRANSLATE_NOOP("Action", "File.Instructions"), QT_TRANSLATE_NOOP("Menu", "&Instructions..."), QT_TRANSLATE_NOOP("Status", "Configure instructions layout"), "" }, // LC_FILE_PRINT { QT_TRANSLATE_NOOP("Action", "File.Print"), QT_TRANSLATE_NOOP("Menu", "&Print..."), QT_TRANSLATE_NOOP("Status", "Print the current model"), "" }, // LC_FILE_PRINT_PREVIEW { QT_TRANSLATE_NOOP("Action", "File.PrintPreview"), QT_TRANSLATE_NOOP("Menu", "Print Pre&view..."), QT_TRANSLATE_NOOP("Status", "Display how the model would look if printed"), "" }, // LC_FILE_RECENT1 { QT_TRANSLATE_NOOP("Action", "File.Recent1"), QT_TRANSLATE_NOOP("Menu", "&Recent 1"), QT_TRANSLATE_NOOP("Status", "Open this model"), "" }, // LC_FILE_RECENT2 { QT_TRANSLATE_NOOP("Action", "File.Recent2"), QT_TRANSLATE_NOOP("Menu", "&Recent 2"), QT_TRANSLATE_NOOP("Status", "Open this model"), "" }, // LC_FILE_RECENT3 { QT_TRANSLATE_NOOP("Action", "File.Recent3"), QT_TRANSLATE_NOOP("Menu", "&Recent 3"), QT_TRANSLATE_NOOP("Status", "Open this model"), "" }, // LC_FILE_RECENT4 { QT_TRANSLATE_NOOP("Action", "File.Recent4"), QT_TRANSLATE_NOOP("Menu", "&Recent 4"), QT_TRANSLATE_NOOP("Status", "Open this model"), "" }, // LC_FILE_EXIT { QT_TRANSLATE_NOOP("Action", "File.Exit"), QT_TRANSLATE_NOOP("Menu", "E&xit"), QT_TRANSLATE_NOOP("Status", "Quit the application; prompts to save model"), "" }, // LC_EDIT_UNDO { QT_TRANSLATE_NOOP("Action", "Edit.Undo"), QT_TRANSLATE_NOOP("Menu", "&Undo"), QT_TRANSLATE_NOOP("Status", "Undo the last action"), "Ctrl+Z" }, // LC_EDIT_REDO { QT_TRANSLATE_NOOP("Action", "Edit.Redo"), QT_TRANSLATE_NOOP("Menu", "&Redo"), QT_TRANSLATE_NOOP("Status", "Redo the previously undone action"), "Ctrl+Y" }, // LC_EDIT_CUT { QT_TRANSLATE_NOOP("Action", "Edit.Cut"), QT_TRANSLATE_NOOP("Menu", "Cu&t"), QT_TRANSLATE_NOOP("Status", "Cut the selection and put it on the Clipboard"), "Ctrl+X" }, // LC_EDIT_COPY { QT_TRANSLATE_NOOP("Action", "Edit.Copy"), QT_TRANSLATE_NOOP("Menu", "&Copy"), QT_TRANSLATE_NOOP("Status", "Copy the selection and put it on the Clipboard"), "Ctrl+C" }, // LC_EDIT_PASTE { QT_TRANSLATE_NOOP("Action", "Edit.Paste"), QT_TRANSLATE_NOOP("Menu", "&Paste"), QT_TRANSLATE_NOOP("Status", "Insert Clipboard contents in the current step"), "Ctrl+V" }, // LC_EDIT_PASTE_STEPS { QT_TRANSLATE_NOOP("Action", "Edit.PasteSteps"), QT_TRANSLATE_NOOP("Menu", "Paste with Steps"), QT_TRANSLATE_NOOP("Status", "Insert Clipboard contents in their original steps"), "" }, // LC_EDIT_FIND { QT_TRANSLATE_NOOP("Action", "Edit.Find"), QT_TRANSLATE_NOOP("Menu", "&Find"), QT_TRANSLATE_NOOP("Status", "Find piece"), "Ctrl+F" }, // LC_EDIT_FIND_NEXT { QT_TRANSLATE_NOOP("Action", "Edit.FindNext"), QT_TRANSLATE_NOOP("Menu", "Find Ne&xt"), QT_TRANSLATE_NOOP("Status", "Find next piece"), "F3" }, // LC_EDIT_FIND_PREVIOUS { QT_TRANSLATE_NOOP("Action", "Edit.FindPrevious"), QT_TRANSLATE_NOOP("Menu", "Find Pre&vious"), QT_TRANSLATE_NOOP("Status", "Find previous piece"), "Shift+F3" }, // LC_EDIT_FIND_ALL { QT_TRANSLATE_NOOP("Action", "Edit.FindAll"), QT_TRANSLATE_NOOP("Menu", "Find All"), QT_TRANSLATE_NOOP("Status", "Find all pieces that match the search criteria"), "" }, // LC_EDIT_REPLACE { QT_TRANSLATE_NOOP("Action", "Edit.Replace"), QT_TRANSLATE_NOOP("Menu", "&Replace"), QT_TRANSLATE_NOOP("Status", "Replace piece"), "" }, // LC_EDIT_REPLACE_NEXT { QT_TRANSLATE_NOOP("Action", "Edit.ReplaceNext"), QT_TRANSLATE_NOOP("Menu", "Replace Next"), QT_TRANSLATE_NOOP("Status", "Replace next piece"), "" }, // LC_EDIT_REPLACE_ALL { QT_TRANSLATE_NOOP("Action", "Edit.ReplaceAll"), QT_TRANSLATE_NOOP("Menu", "Replace All"), QT_TRANSLATE_NOOP("Status", "Replace all pieces that match the search criteria"), "" }, // LC_EDIT_SELECT_ALL { QT_TRANSLATE_NOOP("Action", "Edit.SelectAll"), QT_TRANSLATE_NOOP("Menu", "Select &All"), QT_TRANSLATE_NOOP("Status", "Select all pieces in the model"), "Ctrl+A" }, // LC_EDIT_SELECT_NONE { QT_TRANSLATE_NOOP("Action", "Edit.SelectNone"), QT_TRANSLATE_NOOP("Menu", "Select &None"), QT_TRANSLATE_NOOP("Status", "De-select everything"), "" }, // LC_EDIT_SELECT_INVERT { QT_TRANSLATE_NOOP("Action", "Edit.SelectInvert"), QT_TRANSLATE_NOOP("Menu", "Select &Invert"), QT_TRANSLATE_NOOP("Status", "Invert the current selection set"), "Ctrl+I" }, // LC_EDIT_SELECT_BY_NAME { QT_TRANSLATE_NOOP("Action", "Edit.SelectByName"), QT_TRANSLATE_NOOP("Menu", "Select by Na&me..."), QT_TRANSLATE_NOOP("Status", "Select objects by name"), "" }, // LC_EDIT_SELECT_SINGLE { QT_TRANSLATE_NOOP("Action", "Edit.SelectSingle"), QT_TRANSLATE_NOOP("Menu", "Single Selection"), QT_TRANSLATE_NOOP("Status", "Select one piece at a time"), "" }, // LC_EDIT_SELECT_PIECE { QT_TRANSLATE_NOOP("Action", "Edit.SelectPiece"), QT_TRANSLATE_NOOP("Menu", "Piece Selection"), QT_TRANSLATE_NOOP("Status", "Select all pieces of the same type"), "" }, // LC_EDIT_SELECT_COLOR { QT_TRANSLATE_NOOP("Action", "Edit.SelectColor"), QT_TRANSLATE_NOOP("Menu", "Color Selection"), QT_TRANSLATE_NOOP("Status", "Select all pieces of the same color"), "" }, // LC_EDIT_SELECT_PIECE_COLOR { QT_TRANSLATE_NOOP("Action", "Edit.SelectPieceColor"), QT_TRANSLATE_NOOP("Menu", "Piece and Color Selection"), QT_TRANSLATE_NOOP("Status", "Select all pieces of the same type and color"), "" }, // LC_EDIT_TRANSFORM_RELATIVE { QT_TRANSLATE_NOOP("Action", "Edit.TransformRelative"), QT_TRANSLATE_NOOP("Menu", "Relative Transforms"), QT_TRANSLATE_NOOP("Status", "Move and rotate objects relative to the one that has focus"), "" }, // LC_EDIT_TRANSFORM_ABSOLUTE { QT_TRANSLATE_NOOP("Action", "Edit.TransformAbsolute"), QT_TRANSLATE_NOOP("Menu", "Absolute Transforms"), QT_TRANSLATE_NOOP("Status", "Move and rotate objects in absolute coordinates"), "" }, // LC_EDIT_TRANSFORM_TOGGLE_RELATIVE { QT_TRANSLATE_NOOP("Action", "Edit.TransformToggleRelative"), QT_TRANSLATE_NOOP("Menu", "Toggle Relative Transforms"), QT_TRANSLATE_NOOP("Status", "Toggle moving and rotating objects relative to the one that has focus"), "" }, // LC_EDIT_TRANSFORM_SEPARATELY { QT_TRANSLATE_NOOP("Action", "Edit.TransformSeparately"), QT_TRANSLATE_NOOP("Menu", "Rotate Separately"), QT_TRANSLATE_NOOP("Status", "Rotate selected pieces separately"), "" }, // LC_EDIT_TRANSFORM_TOGETHER { QT_TRANSLATE_NOOP("Action", "Edit.TransformTogether"), QT_TRANSLATE_NOOP("Menu", "Rotate Together"), QT_TRANSLATE_NOOP("Status", "Rotate selected pieces together"), "" }, // LC_EDIT_TRANSFORM_TOGGLE_SEPARATE { QT_TRANSLATE_NOOP("Action", "Edit.TransformToggleSeparate"), QT_TRANSLATE_NOOP("Menu", "Toggle Separate Transforms"), QT_TRANSLATE_NOOP("Status", "Toggle rotating selected pieces separately"), "" }, // LC_EDIT_SNAP_MOVE_TOGGLE { QT_TRANSLATE_NOOP("Action", "Edit.Snap.Toggle"), QT_TRANSLATE_NOOP("Menu", "Move Snap Enabled"), QT_TRANSLATE_NOOP("Status", "Toggle snap axes"), "" }, // LC_EDIT_SNAP_MOVE_XY0 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.XY0"), QT_TRANSLATE_NOOP("Menu", "None"), QT_TRANSLATE_NOOP("Status", "Do not snap movement along the XY plane"), "0" }, // LC_EDIT_SNAP_MOVE_XY1 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.XY1"), QT_TRANSLATE_NOOP("Menu", "1/20 Stud"), QT_TRANSLATE_NOOP("Status", "Snap movement along the XY plane to 1/20 stud"), "1" }, // LC_EDIT_SNAP_MOVE_XY2 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.XY2"), QT_TRANSLATE_NOOP("Menu", "1/4 Stud"), QT_TRANSLATE_NOOP("Status", "Snap movement along the XY plane to 1/4 stud"), "2" }, // LC_EDIT_SNAP_MOVE_XY3 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.XY3"), QT_TRANSLATE_NOOP("Menu", "1 Flat"), QT_TRANSLATE_NOOP("Status", "Snap movement along the XY plane to 1 flat"), "3" }, // LC_EDIT_SNAP_MOVE_XY4 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.XY4"), QT_TRANSLATE_NOOP("Menu", "1/2 Stud"), QT_TRANSLATE_NOOP("Status", "Snap movement along the XY plane to 1/2 stud"), "4" }, // LC_EDIT_SNAP_MOVE_XY5 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.XY5"), QT_TRANSLATE_NOOP("Menu", "1 Stud"), QT_TRANSLATE_NOOP("Status", "Snap movement along the XY plane to 1 stud"), "5" }, // LC_EDIT_SNAP_MOVE_XY6 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.XY6"), QT_TRANSLATE_NOOP("Menu", "2 Studs"), QT_TRANSLATE_NOOP("Status", "Snap movement along the XY plane to 2 studs"), "6" }, // LC_EDIT_SNAP_MOVE_XY7 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.XY7"), QT_TRANSLATE_NOOP("Menu", "3 Studs"), QT_TRANSLATE_NOOP("Status", "Snap movement along the XY plane to 3 studs"), "7" }, // LC_EDIT_SNAP_MOVE_XY8 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.XY8"), QT_TRANSLATE_NOOP("Menu", "4 Studs"), QT_TRANSLATE_NOOP("Status", "Snap movement along the XY plane to 4 studs"), "8" }, // LC_EDIT_SNAP_MOVE_XY9 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.XY9"), QT_TRANSLATE_NOOP("Menu", "8 Studs"), QT_TRANSLATE_NOOP("Status", "Snap movement along the XY plane to 8 studs"), "9" }, // LC_EDIT_SNAP_MOVE_Z0 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.Z0"), QT_TRANSLATE_NOOP("Menu", "None"), QT_TRANSLATE_NOOP("Status", "Do not snap movement along the Z axis"), "Ctrl+Shift+0" }, // LC_EDIT_SNAP_MOVE_Z1 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.Z1"), QT_TRANSLATE_NOOP("Menu", "1/20 Stud"), QT_TRANSLATE_NOOP("Status", "Snap movement along the Z axis to 1/20 stud"), "Ctrl+Shift+1" }, // LC_EDIT_SNAP_MOVE_Z2 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.Z2"), QT_TRANSLATE_NOOP("Menu", "1/4 Stud"), QT_TRANSLATE_NOOP("Status", "Snap movement along the Z axis to 1/4 stud"), "Ctrl+Shift+2" }, // LC_EDIT_SNAP_MOVE_Z3 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.Z3"), QT_TRANSLATE_NOOP("Menu", "1 Flat"), QT_TRANSLATE_NOOP("Status", "Snap movement along the Z axis to 1 flat"), "Ctrl+Shift+3" }, // LC_EDIT_SNAP_MOVE_Z4 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.Z4"), QT_TRANSLATE_NOOP("Menu", "1/2 Stud"), QT_TRANSLATE_NOOP("Status", "Snap movement along the Z axis to 1/2 stud"), "Ctrl+Shift+4" }, // LC_EDIT_SNAP_MOVE_Z5 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.Z5"), QT_TRANSLATE_NOOP("Menu", "1 Stud"), QT_TRANSLATE_NOOP("Status", "Snap movement along the Z axis to 1 stud"), "Ctrl+Shift+5" }, // LC_EDIT_SNAP_MOVE_Z6 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.Z6"), QT_TRANSLATE_NOOP("Menu", "1 Brick"), QT_TRANSLATE_NOOP("Status", "Snap movement along the Z axis to 1 brick"), "Ctrl+Shift+6" }, // LC_EDIT_SNAP_MOVE_Z7 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.Z7"), QT_TRANSLATE_NOOP("Menu", "2 Bricks"), QT_TRANSLATE_NOOP("Status", "Snap movement along the Z axis to 2 bricks"), "Ctrl+Shift+7" }, // LC_EDIT_SNAP_MOVE_Z8 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.Z8"), QT_TRANSLATE_NOOP("Menu", "4 Bricks"), QT_TRANSLATE_NOOP("Status", "Snap movement along the Z axis to 4 bricks"), "Ctrl+Shift+8" }, // LC_EDIT_SNAP_MOVE_Z9 { QT_TRANSLATE_NOOP("Action", "Edit.SnapMove.Z9"), QT_TRANSLATE_NOOP("Menu", "8 Bricks"), QT_TRANSLATE_NOOP("Status", "Snap movement along the Z axis to 8 bricks"), "Ctrl+Shift+9" }, // LC_EDIT_SNAP_ANGLE_TOGGLE { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Toggle"), QT_TRANSLATE_NOOP("Menu", "Rotation Snap Enabled"), QT_TRANSLATE_NOOP("Status", "Snap rotations to fixed intervals"), "" }, // LC_EDIT_SNAP_ANGLE0 { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Angle0"), QT_TRANSLATE_NOOP("Menu", "None"), QT_TRANSLATE_NOOP("Status", "Do not snap rotations"), "Shift+0" }, // LC_EDIT_SNAP_ANGLE1 { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Angle1"), QT_TRANSLATE_NOOP("Menu", "1 Degree"), QT_TRANSLATE_NOOP("Status", "Snap rotations to 1 degree"), "Shift+1" }, // LC_EDIT_SNAP_ANGLE2 { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Angle2"), QT_TRANSLATE_NOOP("Menu", "5 Degrees"), QT_TRANSLATE_NOOP("Status", "Snap rotations to 5 degrees"), "Shift+2" }, // LC_EDIT_SNAP_ANGLE3 { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Angle3"), QT_TRANSLATE_NOOP("Menu", "15 Degrees"), QT_TRANSLATE_NOOP("Status", "Snap rotations to 15 degrees"), "Shift+3" }, // LC_EDIT_SNAP_ANGLE4 { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Angle4"), QT_TRANSLATE_NOOP("Menu", "22.5 Degrees"), QT_TRANSLATE_NOOP("Status", "Snap rotations to 22.5 degrees"), "Shift+4" }, // LC_EDIT_SNAP_ANGLE5 { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Angle5"), QT_TRANSLATE_NOOP("Menu", "30 Degrees"), QT_TRANSLATE_NOOP("Status", "Snap rotations to 30 degrees"), "Shift+5" }, // LC_EDIT_SNAP_ANGLE6 { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Angle6"), QT_TRANSLATE_NOOP("Menu", "45 Degrees"), QT_TRANSLATE_NOOP("Status", "Snap rotations to 45 degrees"), "Shift+6" }, // LC_EDIT_SNAP_ANGLE7 { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Angle7"), QT_TRANSLATE_NOOP("Menu", "60 Degrees"), QT_TRANSLATE_NOOP("Status", "Snap rotations to 60 degrees"), "Shift+7" }, // LC_EDIT_SNAP_ANGLE8 { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Angle8"), QT_TRANSLATE_NOOP("Menu", "90 Degrees"), QT_TRANSLATE_NOOP("Status", "Snap rotations to 90 degrees"), "Shift+8" }, // LC_EDIT_SNAP_ANGLE9 { QT_TRANSLATE_NOOP("Action", "Edit.SnapAngle.Angle9"), QT_TRANSLATE_NOOP("Menu", "180 Degrees"), QT_TRANSLATE_NOOP("Status", "Snap rotations to 180 degrees"), "Shift+9" }, // LC_EDIT_TRANSFORM { QT_TRANSLATE_NOOP("Action", "Edit.Transform"), QT_TRANSLATE_NOOP("Menu", "Transform"), QT_TRANSLATE_NOOP("Status", "Apply transform to selected objects"), "" }, // LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION { QT_TRANSLATE_NOOP("Action", "Edit.TransformAbsoluteTranslation"), QT_TRANSLATE_NOOP("Menu", "Absolute Translation"), QT_TRANSLATE_NOOP("Status", "Switch to absolute translation mode when applying transforms"), "" }, // LC_EDIT_TRANSFORM_RELATIVE_TRANSLATION { QT_TRANSLATE_NOOP("Action", "Edit.TransformRelativeTranslation"), QT_TRANSLATE_NOOP("Menu", "Relative Translation"), QT_TRANSLATE_NOOP("Status", "Switch to relative translation mode when applying transforms"), "" }, // LC_EDIT_TRANSFORM_ABSOLUTE_ROTATION { QT_TRANSLATE_NOOP("Action", "Edit.TransformAbsoluteRotation"), QT_TRANSLATE_NOOP("Menu", "Absolute Rotation"), QT_TRANSLATE_NOOP("Status", "Switch to absolute rotation mode when applying transforms"), "" }, // LC_EDIT_TRANSFORM_RELATIVE_ROTATION { QT_TRANSLATE_NOOP("Action", "Edit.TransformRelativeRotation"), QT_TRANSLATE_NOOP("Menu", "Relative Rotation"), QT_TRANSLATE_NOOP("Status", "Switch to relative rotation mode when applying transforms"), "" }, // LC_EDIT_ACTION_INSERT { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Insert"), QT_TRANSLATE_NOOP("Menu", "Insert"), QT_TRANSLATE_NOOP("Status", "Add new pieces to the model"), "" }, // LC_EDIT_ACTION_LIGHT { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Light"), QT_TRANSLATE_NOOP("Menu", "Light"), QT_TRANSLATE_NOOP("Status", "Add new omni light sources to the model"), "" }, // LC_EDIT_ACTION_SPOTLIGHT { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Spotlight"), QT_TRANSLATE_NOOP("Menu", "Spotlight"), QT_TRANSLATE_NOOP("Status", "Add new spotlights to the model"), "" }, // LC_EDIT_ACTION_CAMERA { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Camera"), QT_TRANSLATE_NOOP("Menu", "Camera"), QT_TRANSLATE_NOOP("Status", "Create a new camera"), "" }, // LC_EDIT_ACTION_SELECT { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Select"), QT_TRANSLATE_NOOP("Menu", "Select"), QT_TRANSLATE_NOOP("Status", "Select objects (hold the CTRL key down or drag the mouse to select multiple objects)"), "" }, // LC_EDIT_ACTION_MOVE { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Move"), QT_TRANSLATE_NOOP("Menu", "Move"), QT_TRANSLATE_NOOP("Status", "Move selected objects"), "" }, // LC_EDIT_ACTION_ROTATE { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Rotate"), QT_TRANSLATE_NOOP("Menu", "Rotate"), QT_TRANSLATE_NOOP("Status", "Rotate selected pieces"), "" }, // LC_EDIT_ACTION_DELETE { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Delete"), QT_TRANSLATE_NOOP("Menu", "Delete"), QT_TRANSLATE_NOOP("Status", "Delete objects"), "" }, // LC_EDIT_ACTION_PAINT { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Paint"), QT_TRANSLATE_NOOP("Menu", "Paint"), QT_TRANSLATE_NOOP("Status", "Change piece color"), "" }, // LC_EDIT_ACTION_COLOR_PICKER { QT_TRANSLATE_NOOP("Action", "Edit.Tool.ColorPicker"), QT_TRANSLATE_NOOP("Menu", "Color Picker"), QT_TRANSLATE_NOOP("Status", "Get piece color"), "" }, // LC_EDIT_ACTION_ZOOM { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Zoom"), QT_TRANSLATE_NOOP("Menu", "Zoom"), QT_TRANSLATE_NOOP("Status", "Zoom in or out"), "" }, // LC_EDIT_ACTION_PAN { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Pan"), QT_TRANSLATE_NOOP("Menu", "Pan"), QT_TRANSLATE_NOOP("Status", "Pan the current view"), "" }, // LC_EDIT_ACTION_ROTATE_VIEW { QT_TRANSLATE_NOOP("Action", "Edit.Tool.RotateView"), QT_TRANSLATE_NOOP("Menu", "Rotate View"), QT_TRANSLATE_NOOP("Status", "Rotate the current view"), "" }, // LC_EDIT_ACTION_ROLL { QT_TRANSLATE_NOOP("Action", "Edit.Tool.Roll"), QT_TRANSLATE_NOOP("Menu", "Roll"), QT_TRANSLATE_NOOP("Status", "Roll the current view"), "" }, // LC_EDIT_ACTION_ZOOM_REGION { QT_TRANSLATE_NOOP("Action", "Edit.Tool.ZoomRegion"), QT_TRANSLATE_NOOP("Menu", "Zoom Region"), QT_TRANSLATE_NOOP("Status", "Zoom into a region of the screen"), "" }, // LC_EDIT_CANCEL { QT_TRANSLATE_NOOP("Action", "Edit.Cancel"), QT_TRANSLATE_NOOP("Menu", "Cancel Action"), QT_TRANSLATE_NOOP("Status", "Cancel current mouse action"), "Esc" }, // LC_VIEW_PREFERENCES { QT_TRANSLATE_NOOP("Action", "View.Preferences"), QT_TRANSLATE_NOOP("Menu", "P&references..."), QT_TRANSLATE_NOOP("Status", "Change program settings"), "" }, // LC_VIEW_ZOOM_IN { QT_TRANSLATE_NOOP("Action", "View.ZoomIn"), QT_TRANSLATE_NOOP("Menu", "Zoom In"), QT_TRANSLATE_NOOP("Status", "Zoom in"), "+" }, // LC_VIEW_ZOOM_OUT { QT_TRANSLATE_NOOP("Action", "View.ZoomOut"), QT_TRANSLATE_NOOP("Menu", "Zoom Out"), QT_TRANSLATE_NOOP("Status", "Zoom out"), "-" }, // LC_VIEW_ZOOM_EXTENTS { QT_TRANSLATE_NOOP("Action", "View.ZoomExtents"), QT_TRANSLATE_NOOP("Menu", "Zoom E&xtents"), QT_TRANSLATE_NOOP("Status", "Fit all pieces in current the view (hold the CTRL key down to zoom all views)"), "" }, // LC_VIEW_LOOK_AT { QT_TRANSLATE_NOOP("Action", "View.LookAt"), QT_TRANSLATE_NOOP("Menu", "Look At"), QT_TRANSLATE_NOOP("Status", "Rotate view so selected pieces are at center"), "" }, // LC_VIEW_MOVE_FORWARD { QT_TRANSLATE_NOOP("Action", "View.MoveForward"), QT_TRANSLATE_NOOP("Menu", "Move Forward"), QT_TRANSLATE_NOOP("Status", "Move the current view forward"), "" }, // LC_VIEW_MOVE_BACKWARD { QT_TRANSLATE_NOOP("Action", "View.MoveBackward"), QT_TRANSLATE_NOOP("Menu", "Move Backward"), QT_TRANSLATE_NOOP("Status", "Move the current view backward"), "" }, // LC_VIEW_MOVE_LEFT { QT_TRANSLATE_NOOP("Action", "View.MoveLeft"), QT_TRANSLATE_NOOP("Menu", "Move Left"), QT_TRANSLATE_NOOP("Status", "Move the current view to the left"), "" }, // LC_VIEW_MOVE_RIGHT { QT_TRANSLATE_NOOP("Action", "View.MoveRight"), QT_TRANSLATE_NOOP("Menu", "Move Right"), QT_TRANSLATE_NOOP("Status", "Move the current view to the right"), "" }, // LC_VIEW_MOVE_UP { QT_TRANSLATE_NOOP("Action", "View.MoveUp"), QT_TRANSLATE_NOOP("Menu", "Move Up"), QT_TRANSLATE_NOOP("Status", "Move the current view up"), "" }, // LC_VIEW_MOVE_DOWN { QT_TRANSLATE_NOOP("Action", "View.MoveDown"), QT_TRANSLATE_NOOP("Menu", "Move Down"), QT_TRANSLATE_NOOP("Status", "Move the current view down"), "" }, // LC_VIEW_VIEWPOINT_FRONT { QT_TRANSLATE_NOOP("Action", "View.Viewpoint.Front"), QT_TRANSLATE_NOOP("Menu", "&Front"), QT_TRANSLATE_NOOP("Status", "View model from the front"), "F" }, // LC_VIEW_VIEWPOINT_BACK { QT_TRANSLATE_NOOP("Action", "View.Viewpoint.Back"), QT_TRANSLATE_NOOP("Menu", "&Back"), QT_TRANSLATE_NOOP("Status", "View model from the back"), "B" }, // LC_VIEW_VIEWPOINT_TOP { QT_TRANSLATE_NOOP("Action", "View.Viewpoint.Top"), QT_TRANSLATE_NOOP("Menu", "&Top"), QT_TRANSLATE_NOOP("Status", "View model from the top"), "T" }, // LC_VIEW_VIEWPOINT_BOTTOM { QT_TRANSLATE_NOOP("Action", "View.Viewpoint.Bottom"), QT_TRANSLATE_NOOP("Menu", "B&ottom"), QT_TRANSLATE_NOOP("Status", "View model from the bottom"), "O" }, // LC_VIEW_VIEWPOINT_LEFT { QT_TRANSLATE_NOOP("Action", "View.Viewpoint.Left"), QT_TRANSLATE_NOOP("Menu", "&Left"), QT_TRANSLATE_NOOP("Status", "View model from the left"), "L" }, // LC_VIEW_VIEWPOINT_RIGHT { QT_TRANSLATE_NOOP("Action", "View.Viewpoint.Right"), QT_TRANSLATE_NOOP("Menu", "&Right"), QT_TRANSLATE_NOOP("Status", "View model from the right"), "R" }, // LC_VIEW_VIEWPOINT_HOME { QT_TRANSLATE_NOOP("Action", "View.Viewpoint.Home"), QT_TRANSLATE_NOOP("Menu", "&Home"), QT_TRANSLATE_NOOP("Status", "View model from the default position"), "H" }, // LC_VIEW_CAMERA_NONE { QT_TRANSLATE_NOOP("Action", "View.Cameras.None"), QT_TRANSLATE_NOOP("Menu", "None"), QT_TRANSLATE_NOOP("Status", "Do not use a camera"), "" }, // LC_VIEW_CAMERA1 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera01"), QT_TRANSLATE_NOOP("Menu", "Camera 1"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA2 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera02"), QT_TRANSLATE_NOOP("Menu", "Camera 2"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA3 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera03"), QT_TRANSLATE_NOOP("Menu", "Camera 3"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA4 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera04"), QT_TRANSLATE_NOOP("Menu", "Camera 4"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA5 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera05"), QT_TRANSLATE_NOOP("Menu", "Camera 5"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA6 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera06"), QT_TRANSLATE_NOOP("Menu", "Camera 6"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA7 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera07"), QT_TRANSLATE_NOOP("Menu", "Camera 7"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA8 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera08"), QT_TRANSLATE_NOOP("Menu", "Camera 8"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA9 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera09"), QT_TRANSLATE_NOOP("Menu", "Camera 9"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA10 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera10"), QT_TRANSLATE_NOOP("Menu", "Camera 10"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA11 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera11"), QT_TRANSLATE_NOOP("Menu", "Camera 11"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA12 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera12"), QT_TRANSLATE_NOOP("Menu", "Camera 12"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA13 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera13"), QT_TRANSLATE_NOOP("Menu", "Camera 13"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA14 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera14"), QT_TRANSLATE_NOOP("Menu", "Camera 14"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA15 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera15"), QT_TRANSLATE_NOOP("Menu", "Camera 15"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_CAMERA16 { QT_TRANSLATE_NOOP("Action", "View.Cameras.Camera16"), QT_TRANSLATE_NOOP("Menu", "Camera 16"), QT_TRANSLATE_NOOP("Status", "Use this camera"), "" }, // LC_VIEW_TIME_FIRST { QT_TRANSLATE_NOOP("Action", "View.Time.First"), QT_TRANSLATE_NOOP("Menu", "First"), QT_TRANSLATE_NOOP("Status", "Go to the first step of the model"), "Alt+Up" }, // LC_VIEW_TIME_PREVIOUS { QT_TRANSLATE_NOOP("Action", "View.Time.Previous"), QT_TRANSLATE_NOOP("Menu", "Previous"), QT_TRANSLATE_NOOP("Status", "Go to the previous step"), "Alt+Left" }, // LC_VIEW_TIME_NEXT { QT_TRANSLATE_NOOP("Action", "View.Time.Next"), QT_TRANSLATE_NOOP("Menu", "Next"), QT_TRANSLATE_NOOP("Status", "Go to the next step"), "Alt+Right" }, // LC_VIEW_TIME_LAST { QT_TRANSLATE_NOOP("Action", "View.Time.Last"), QT_TRANSLATE_NOOP("Menu", "Last"), QT_TRANSLATE_NOOP("Status", "Go to the last step of the model"), "Alt+Down" }, // LC_VIEW_TIME_INSERT_BEFORE { QT_TRANSLATE_NOOP("Action", "View.Time.InsertBefore"), QT_TRANSLATE_NOOP("Menu", "Insert Before"), QT_TRANSLATE_NOOP("Status", "Insert a new step before the current step"), "" }, // LC_VIEW_TIME_INSERT_AFTER { QT_TRANSLATE_NOOP("Action", "View.Time.InsertAfter"), QT_TRANSLATE_NOOP("Menu", "Insert After"), QT_TRANSLATE_NOOP("Status", "Insert a new step after the current step"), "" }, // LC_VIEW_TIME_DELETE { QT_TRANSLATE_NOOP("Action", "View.Time.Delete"), QT_TRANSLATE_NOOP("Menu", "Remove Step"), QT_TRANSLATE_NOOP("Status", "Remove current step"), "" }, // LC_VIEW_TIME_ADD_KEYS { QT_TRANSLATE_NOOP("Action", "View.Time.AddKeys"), QT_TRANSLATE_NOOP("Menu", "Add Keys"), QT_TRANSLATE_NOOP("Status", "Toggle adding new animation keys"), "" }, // LC_VIEW_SPLIT_HORIZONTAL { QT_TRANSLATE_NOOP("Action", "View.SplitHorizontal"), QT_TRANSLATE_NOOP("Menu", "Split &Horizontal"), QT_TRANSLATE_NOOP("Status", "Split the current view horizontally"), "" }, // LC_VIEW_SPLIT_VERTICAL { QT_TRANSLATE_NOOP("Action", "View.SplitVertical"), QT_TRANSLATE_NOOP("Menu", "Split &Vertical"), QT_TRANSLATE_NOOP("Status", "Split the current view vertically"), "" }, // LC_VIEW_REMOVE_VIEW { QT_TRANSLATE_NOOP("Action", "View.RemoveView"), QT_TRANSLATE_NOOP("Menu", "Re&move View"), QT_TRANSLATE_NOOP("Status", "Remove the current view"), "" }, // LC_VIEW_RESET_VIEWS { QT_TRANSLATE_NOOP("Action", "View.ResetViews"), QT_TRANSLATE_NOOP("Menu", "Rese&t Views"), QT_TRANSLATE_NOOP("Status", "Reset all views"), "" }, // LC_VIEW_TOOLBAR_STANDARD { QT_TRANSLATE_NOOP("Action", "View.Toolbars.Standard"), QT_TRANSLATE_NOOP("Menu", "Standard"), QT_TRANSLATE_NOOP("Status", "Toggle the Standard Toolbar"), "" }, // LC_VIEW_TOOLBAR_TOOLS { QT_TRANSLATE_NOOP("Action", "View.Toolbars.Tools"), QT_TRANSLATE_NOOP("Menu", "Tools"), QT_TRANSLATE_NOOP("Status", "Toggle the Tools Toolbar"), "" }, // LC_VIEW_TOOLBAR_TIME { QT_TRANSLATE_NOOP("Action", "View.Toolbars.Time"), QT_TRANSLATE_NOOP("Menu", "Time"), QT_TRANSLATE_NOOP("Status", "Toggle the Time Toolbar"), "" }, // LC_VIEW_TOOLBAR_PARTS { QT_TRANSLATE_NOOP("Action", "View.Toolbars.Parts"), QT_TRANSLATE_NOOP("Menu", "Parts"), QT_TRANSLATE_NOOP("Status", "Toggle the Parts Toolbar"), "" }, // LC_VIEW_TOOLBAR_COLORS { QT_TRANSLATE_NOOP("Action", "View.Toolbars.Colors"), QT_TRANSLATE_NOOP("Menu", "Colors"), QT_TRANSLATE_NOOP("Status", "Toggle the Colors Toolbar"), "" }, // LC_VIEW_TOOLBAR_PROPERTIES { QT_TRANSLATE_NOOP("Action", "View.Toolbars.Properties"), QT_TRANSLATE_NOOP("Menu", "Properties"), QT_TRANSLATE_NOOP("Status", "Toggle the Properties Toolbar"), "" }, // LC_VIEW_TOOLBAR_TIMELINE { QT_TRANSLATE_NOOP("Action", "View.Toolbars.Timeline"), QT_TRANSLATE_NOOP("Menu", "Timeline"), QT_TRANSLATE_NOOP("Status", "Toggle the Timeline Toolbar"), "" }, // LC_VIEW_TOOLBAR_PREVIEW { QT_TRANSLATE_NOOP("Action", "View.Toolbars.Preview"), QT_TRANSLATE_NOOP("Menu", "Preview"), QT_TRANSLATE_NOOP("Status", "Toggle the Preview Toolbar"), "" }, // LC_VIEW_FULLSCREEN { QT_TRANSLATE_NOOP("Action", "View.FullScreen"), QT_TRANSLATE_NOOP("Menu", "&Full Screen"), QT_TRANSLATE_NOOP("Status", "Toggle fullscreen mode"), "" }, // LC_VIEW_CLOSE_CURRENT_TAB { QT_TRANSLATE_NOOP("Action", "View.CloseCurrentTab"), QT_TRANSLATE_NOOP("Menu", "Close &Tab"), QT_TRANSLATE_NOOP("Status", "Close current tab"), "Ctrl+W" }, // LC_VIEW_SHADE_WIREFRAME { QT_TRANSLATE_NOOP("Action", "View.Shade.Wireframe"), QT_TRANSLATE_NOOP("Menu", "&Wireframe"), QT_TRANSLATE_NOOP("Status", "Display the scene as wireframe"), "" }, // LC_VIEW_SHADE_FLAT { QT_TRANSLATE_NOOP("Action", "View.Shade.Flat"), QT_TRANSLATE_NOOP("Menu", "&Flat Shading"), QT_TRANSLATE_NOOP("Status", "Display the scene without any shading or lights"), "" }, // LC_VIEW_SHADE_DEFAULT_LIGHTS { QT_TRANSLATE_NOOP("Action", "View.Shade.DefaultLights"), QT_TRANSLATE_NOOP("Menu", "&Default Lights"), QT_TRANSLATE_NOOP("Status", "Display the scene with the default lights"), "" }, // LC_VIEW_PROJECTION_PERSPECTIVE { QT_TRANSLATE_NOOP("Action", "View.Projection.Perspective"), QT_TRANSLATE_NOOP("Menu", "&Perspective"), QT_TRANSLATE_NOOP("Status", "Set the current camera to use a perspective projection"), "" }, // LC_VIEW_PROJECTION_ORTHO { QT_TRANSLATE_NOOP("Action", "View.Projection.Orthographic"), QT_TRANSLATE_NOOP("Menu", "&Orthographic"), QT_TRANSLATE_NOOP("Status", "Set the current camera to use an orthographic projection"), "" }, // LC_VIEW_TOGGLE_VIEW_SPHERE { QT_TRANSLATE_NOOP("Action", "View.ToggleViewSphere"), QT_TRANSLATE_NOOP("Menu", "View Sphere"), QT_TRANSLATE_NOOP("Status", "Toggle the view sphere"), "" }, // LC_VIEW_TOGGLE_AXIS_ICON { QT_TRANSLATE_NOOP("Action", "View.ToggleAxisIcon"), QT_TRANSLATE_NOOP("Menu", "Axis Icon"), QT_TRANSLATE_NOOP("Status", "Toggle axis icon"), "" }, // LC_VIEW_TOGGLE_GRID { QT_TRANSLATE_NOOP("Action", "View.ToggleGrid"), QT_TRANSLATE_NOOP("Menu", "Base Grid"), QT_TRANSLATE_NOOP("Status", "Toggle grid"), "" }, // LC_VIEW_FADE_PREVIOUS_STEPS { QT_TRANSLATE_NOOP("Action", "View.FadePreviousSteps"), QT_TRANSLATE_NOOP("Menu", "Fade Previous Steps"), QT_TRANSLATE_NOOP("Status", "Toggle fading previous model steps"), "" }, // LC_PIECE_INSERT { QT_TRANSLATE_NOOP("Action", "Piece.Insert"), QT_TRANSLATE_NOOP("Menu", "&Insert"), QT_TRANSLATE_NOOP("Status", "Add a new piece to the model"), "Insert" }, // LC_PIECE_DELETE { QT_TRANSLATE_NOOP("Action", "Piece.Delete"), QT_TRANSLATE_NOOP("Menu", "&Delete"), QT_TRANSLATE_NOOP("Status", "Delete selected objects"), "Delete" }, // LC_PIECE_DUPLICATE { QT_TRANSLATE_NOOP("Action", "Piece.Duplicate"), QT_TRANSLATE_NOOP("Menu", "&Duplicate"), QT_TRANSLATE_NOOP("Status", "Create a copy of the selected pieces"), "Ctrl+D" }, // LC_PIECE_PAINT_SELECTED { QT_TRANSLATE_NOOP("Action", "Piece.PaintSelected"), QT_TRANSLATE_NOOP("Menu", "&Paint Selected"), QT_TRANSLATE_NOOP("Status", "Change the color of the selected pieces"), "" }, // LC_PIECE_RESET_PIVOT_POINT { QT_TRANSLATE_NOOP("Action", "Piece.ResetPivotPoint"), QT_TRANSLATE_NOOP("Menu", "Reset &Pivot Point"), QT_TRANSLATE_NOOP("Status", "Reset the pivot point of the selected pieces to their origin"), "" }, // LC_PIECE_REMOVE_KEY_FRAMES { QT_TRANSLATE_NOOP("Action", "Piece.RemoveKeyFrames"), QT_TRANSLATE_NOOP("Menu", "Remove &Key Frames"), QT_TRANSLATE_NOOP("Status", "Remove all key frames from the selected pieces"), "" }, // LC_PIECE_CONTROL_POINT_INSERT { QT_TRANSLATE_NOOP("Action", "Piece.ControlPoint.Insert"), QT_TRANSLATE_NOOP("Menu", "Insert Control Point"), QT_TRANSLATE_NOOP("Status", "Insert a new control point"), "" }, // LC_PIECE_CONTROL_POINT_REMOVE { QT_TRANSLATE_NOOP("Action", "Piece.ControlPoint.Remove"), QT_TRANSLATE_NOOP("Menu", "Remove Control Point"), QT_TRANSLATE_NOOP("Status", "Remove the selected control point"), "" }, // LC_PIECE_MOVE_PLUSX { QT_TRANSLATE_NOOP("Action", "Piece.Move.PlusX"), QT_TRANSLATE_NOOP("Menu", "Move +X"), QT_TRANSLATE_NOOP("Status", "Move selected objects along the X axis"), "Down" }, // LC_PIECE_MOVE_MINUSX { QT_TRANSLATE_NOOP("Action", "Piece.Move.MinusX"), QT_TRANSLATE_NOOP("Menu", "Move -X"), QT_TRANSLATE_NOOP("Status", "Move selected objects along the X axis"), "Up" }, // LC_PIECE_MOVE_PLUSY { QT_TRANSLATE_NOOP("Action", "Piece.Move.PlusY"), QT_TRANSLATE_NOOP("Menu", "Move +Y"), QT_TRANSLATE_NOOP("Status", "Move selected objects along the Y axis"), "Right" }, // LC_PIECE_MOVE_MINUSY { QT_TRANSLATE_NOOP("Action", "Piece.Move.MinusY"), QT_TRANSLATE_NOOP("Menu", "Move -Y"), QT_TRANSLATE_NOOP("Status", "Move selected objects along the Y axis"), "Left" }, // LC_PIECE_MOVE_PLUSZ { QT_TRANSLATE_NOOP("Action", "Piece.Move.PlusZ"), QT_TRANSLATE_NOOP("Menu", "Move +Z"), QT_TRANSLATE_NOOP("Status", "Move selected objects along the Z axis"), "PgUp" }, // LC_PIECE_MOVE_MINUSZ { QT_TRANSLATE_NOOP("Action", "Piece.Move.MinusZ"), QT_TRANSLATE_NOOP("Menu", "Move -Z"), QT_TRANSLATE_NOOP("Status", "Move selected objects along the Z axis"), "PgDown" }, // LC_PIECE_ROTATE_PLUSX { QT_TRANSLATE_NOOP("Action", "Piece.Rotate.PlusX"), QT_TRANSLATE_NOOP("Menu", "Rotate +X"), QT_TRANSLATE_NOOP("Status", "Rotate selected objects along the X axis"), "Shift+Down" }, // LC_PIECE_ROTATE_MINUSX { QT_TRANSLATE_NOOP("Action", "Piece.Rotate.MinusX"), QT_TRANSLATE_NOOP("Menu", "Rotate -X"), QT_TRANSLATE_NOOP("Status", "Rotate selected objects along the X axis"), "Shift+Up" }, // LC_PIECE_ROTATE_PLUSY { QT_TRANSLATE_NOOP("Action", "Piece.Rotate.PlusY"), QT_TRANSLATE_NOOP("Menu", "Rotate +Y"), QT_TRANSLATE_NOOP("Status", "Rotate selected objects along the Y axis"), "Shift+Right" }, // LC_PIECE_ROTATE_MINUSY { QT_TRANSLATE_NOOP("Action", "Piece.Rotate.MinusY"), QT_TRANSLATE_NOOP("Menu", "Rotate -Y"), QT_TRANSLATE_NOOP("Status", "Rotate selected objects along the Y axis"), "Shift+Left" }, // LC_PIECE_ROTATE_PLUSZ { QT_TRANSLATE_NOOP("Action", "Piece.Rotate.PlusZ"), QT_TRANSLATE_NOOP("Menu", "Rotate +Z"), QT_TRANSLATE_NOOP("Status", "Rotate selected objects along the Z axis"), "Shift+PgUp" }, // LC_PIECE_ROTATE_MINUSZ { QT_TRANSLATE_NOOP("Action", "Piece.Rotate.MinusZ"), QT_TRANSLATE_NOOP("Menu", "Rotate -Z"), QT_TRANSLATE_NOOP("Status", "Rotate selected objects along the Z axis"), "Shift+PgDown" }, // LC_PIECE_MINIFIG_WIZARD { QT_TRANSLATE_NOOP("Action", "Piece.MinifigWizard"), QT_TRANSLATE_NOOP("Menu", "Minifig &Wizard..."), QT_TRANSLATE_NOOP("Status", "Add a new minifig to the model"), "" }, // LC_PIECE_ARRAY { QT_TRANSLATE_NOOP("Action", "Piece.Array"), QT_TRANSLATE_NOOP("Menu", "A&rray..."), QT_TRANSLATE_NOOP("Status", "Make copies of the selected pieces"), "" }, // LC_PIECE_VIEW_SELECTED_MODEL { QT_TRANSLATE_NOOP("Action", "Piece.ViewSelectedModel"), QT_TRANSLATE_NOOP("Menu", "Open Selected Model"), QT_TRANSLATE_NOOP("Status", "Open the model referenced by the selected piece in a new tab"), "" }, // LC_PIECE_MOVE_SELECTION_TO_MODEL { QT_TRANSLATE_NOOP("Action", "Piece.MoveSelectionToModel"), QT_TRANSLATE_NOOP("Menu", "Move to New Model..."), QT_TRANSLATE_NOOP("Status", "Move the selected pieces to a new model and replace them with a reference to the model"), "" }, // LC_PIECE_INLINE_SELECTED_MODELS { QT_TRANSLATE_NOOP("Action", "Piece.InlineSelectedModels"), QT_TRANSLATE_NOOP("Menu", "Inline Selected Models"), QT_TRANSLATE_NOOP("Status", "Insert the contents of the selected model references into the current model"), "" }, // LC_PIECE_EDIT_SELECTED_SUBMODEL { QT_TRANSLATE_NOOP("Action", "Piece.EditSelectedSubmodel"), QT_TRANSLATE_NOOP("Menu", "Edit Selected Submodel"), QT_TRANSLATE_NOOP("Status", "Edit the currently selected submodel in-place"), "" }, // LC_PIECE_EDIT_END_SUBMODEL { QT_TRANSLATE_NOOP("Action", "Piece.EditEndSubmodel"), QT_TRANSLATE_NOOP("Menu", "End Submodel Editing"), QT_TRANSLATE_NOOP("Status", "End in-place submodel editing"), "" }, // LC_PIECE_GROUP { QT_TRANSLATE_NOOP("Action", "Piece.Group"), QT_TRANSLATE_NOOP("Menu", "&Group..."), QT_TRANSLATE_NOOP("Status", "Group selected pieces together"), "Ctrl+G" }, // LC_PIECE_UNGROUP { QT_TRANSLATE_NOOP("Action", "Piece.Ungroup"), QT_TRANSLATE_NOOP("Menu", "&Ungroup"), QT_TRANSLATE_NOOP("Status", "Ungroup selected group"), "Ctrl+U" }, // LC_PIECE_GROUP_ADD { QT_TRANSLATE_NOOP("Action", "Piece.GroupAdd"), QT_TRANSLATE_NOOP("Menu", "&Add to Group"), QT_TRANSLATE_NOOP("Status", "Add focused piece to selected group"), "" }, // LC_PIECE_GROUP_REMOVE { QT_TRANSLATE_NOOP("Action", "Piece.GroupRemove"), QT_TRANSLATE_NOOP("Menu", "Re&move from Group"), QT_TRANSLATE_NOOP("Status", "Remove focused piece from group"), "" }, // LC_PIECE_GROUP_EDIT { QT_TRANSLATE_NOOP("Action", "Piece.GroupEdit"), QT_TRANSLATE_NOOP("Menu", "&Edit Groups..."), QT_TRANSLATE_NOOP("Status", "Edit groups"), "" }, // LC_PIECE_HIDE_SELECTED { QT_TRANSLATE_NOOP("Action", "Piece.HideSelected"), QT_TRANSLATE_NOOP("Menu", "&Hide Selected"), QT_TRANSLATE_NOOP("Status", "Hide selected objects"), "Ctrl+H" }, // LC_PIECE_HIDE_UNSELECTED { QT_TRANSLATE_NOOP("Action", "Piece.HideUnselected"), QT_TRANSLATE_NOOP("Menu", "Hide &Unselected"), QT_TRANSLATE_NOOP("Status", "Hide objects that are not selected"), "" }, // LC_PIECE_UNHIDE_SELECTED { QT_TRANSLATE_NOOP("Action", "Piece.UnhideSelected"), QT_TRANSLATE_NOOP("Menu", "&Unhide Selected"), QT_TRANSLATE_NOOP("Status", "Show hidden objects that are selected"), "" }, // LC_PIECE_UNHIDE_ALL { QT_TRANSLATE_NOOP("Action", "Piece.UnhideAll"), QT_TRANSLATE_NOOP("Menu", "U&nhide All"), QT_TRANSLATE_NOOP("Status", "Show all hidden objects"), "" }, // LC_PIECE_SHOW_EARLIER { QT_TRANSLATE_NOOP("Action", "Piece.ShowEarlier"), QT_TRANSLATE_NOOP("Menu", "Show Earlier"), QT_TRANSLATE_NOOP("Status", "Show selected pieces one step earlier"), "" }, // LC_PIECE_SHOW_LATER { QT_TRANSLATE_NOOP("Action", "Piece.ShowLater"), QT_TRANSLATE_NOOP("Menu", "Show Later"), QT_TRANSLATE_NOOP("Status", "Show selected pieces one step later"), "" }, // LC_MODEL_NEW { QT_TRANSLATE_NOOP("Action", "Model.New"), QT_TRANSLATE_NOOP("Menu", "New Submodel..."), QT_TRANSLATE_NOOP("Status", "Create a new submodel"), "" }, // LC_MODEL_PROPERTIES { QT_TRANSLATE_NOOP("Action", "Model.Properties"), QT_TRANSLATE_NOOP("Menu", "Prope&rties..."), QT_TRANSLATE_NOOP("Status", "Display the properties of the current submodel"), "" }, // LC_MODEL_LIST { QT_TRANSLATE_NOOP("Action", "Model.List"), QT_TRANSLATE_NOOP("Menu", "Submodels..."), QT_TRANSLATE_NOOP("Status", "Show a list of all submodels"), "" }, // LC_MODEL_01 { QT_TRANSLATE_NOOP("Action", "Model.Model01"), QT_TRANSLATE_NOOP("Menu", "Model 1"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_02 { QT_TRANSLATE_NOOP("Action", "Model.Model02"), QT_TRANSLATE_NOOP("Menu", "Model 2"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_03 { QT_TRANSLATE_NOOP("Action", "Model.Model03"), QT_TRANSLATE_NOOP("Menu", "Model 3"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_04 { QT_TRANSLATE_NOOP("Action", "Model.Model04"), QT_TRANSLATE_NOOP("Menu", "Model 4"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_05 { QT_TRANSLATE_NOOP("Action", "Model.Model05"), QT_TRANSLATE_NOOP("Menu", "Model 5"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_06 { QT_TRANSLATE_NOOP("Action", "Model.Model06"), QT_TRANSLATE_NOOP("Menu", "Model 6"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_07 { QT_TRANSLATE_NOOP("Action", "Model.Model07"), QT_TRANSLATE_NOOP("Menu", "Model 7"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_08 { QT_TRANSLATE_NOOP("Action", "Model.Model08"), QT_TRANSLATE_NOOP("Menu", "Model 8"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_09 { QT_TRANSLATE_NOOP("Action", "Model.Model09"), QT_TRANSLATE_NOOP("Menu", "Model 9"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_10 { QT_TRANSLATE_NOOP("Action", "Model.Model10"), QT_TRANSLATE_NOOP("Menu", "Model 10"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_11 { QT_TRANSLATE_NOOP("Action", "Model.Model11"), QT_TRANSLATE_NOOP("Menu", "Model 11"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_12 { QT_TRANSLATE_NOOP("Action", "Model.Model12"), QT_TRANSLATE_NOOP("Menu", "Model 12"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_13 { QT_TRANSLATE_NOOP("Action", "Model.Model13"), QT_TRANSLATE_NOOP("Menu", "Model 13"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_14 { QT_TRANSLATE_NOOP("Action", "Model.Model14"), QT_TRANSLATE_NOOP("Menu", "Model 14"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_15 { QT_TRANSLATE_NOOP("Action", "Model.Model15"), QT_TRANSLATE_NOOP("Menu", "Model 15"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_16 { QT_TRANSLATE_NOOP("Action", "Model.Model16"), QT_TRANSLATE_NOOP("Menu", "Model 16"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_17 { QT_TRANSLATE_NOOP("Action", "Model.Model17"), QT_TRANSLATE_NOOP("Menu", "Model 17"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_18 { QT_TRANSLATE_NOOP("Action", "Model.Model18"), QT_TRANSLATE_NOOP("Menu", "Model 18"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_19 { QT_TRANSLATE_NOOP("Action", "Model.Model19"), QT_TRANSLATE_NOOP("Menu", "Model 19"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_20 { QT_TRANSLATE_NOOP("Action", "Model.Model20"), QT_TRANSLATE_NOOP("Menu", "Model 20"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_21 { QT_TRANSLATE_NOOP("Action", "Model.Model21"), QT_TRANSLATE_NOOP("Menu", "Model 21"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_22 { QT_TRANSLATE_NOOP("Action", "Model.Model22"), QT_TRANSLATE_NOOP("Menu", "Model 22"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_23 { QT_TRANSLATE_NOOP("Action", "Model.Model23"), QT_TRANSLATE_NOOP("Menu", "Model 23"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_24 { QT_TRANSLATE_NOOP("Action", "Model.Model24"), QT_TRANSLATE_NOOP("Menu", "Model 24"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_25 { QT_TRANSLATE_NOOP("Action", "Model.Model25"), QT_TRANSLATE_NOOP("Menu", "Model 25"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_26 { QT_TRANSLATE_NOOP("Action", "Model.Model26"), QT_TRANSLATE_NOOP("Menu", "Model 26"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_27 { QT_TRANSLATE_NOOP("Action", "Model.Model27"), QT_TRANSLATE_NOOP("Menu", "Model 27"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_28 { QT_TRANSLATE_NOOP("Action", "Model.Model28"), QT_TRANSLATE_NOOP("Menu", "Model 28"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_29 { QT_TRANSLATE_NOOP("Action", "Model.Model29"), QT_TRANSLATE_NOOP("Menu", "Model 29"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_30 { QT_TRANSLATE_NOOP("Action", "Model.Model30"), QT_TRANSLATE_NOOP("Menu", "Model 30"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_31 { QT_TRANSLATE_NOOP("Action", "Model.Model31"), QT_TRANSLATE_NOOP("Menu", "Model 31"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_32 { QT_TRANSLATE_NOOP("Action", "Model.Model32"), QT_TRANSLATE_NOOP("Menu", "Model 32"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_33 { QT_TRANSLATE_NOOP("Action", "Model.Model33"), QT_TRANSLATE_NOOP("Menu", "Model 33"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_34 { QT_TRANSLATE_NOOP("Action", "Model.Model34"), QT_TRANSLATE_NOOP("Menu", "Model 34"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_35 { QT_TRANSLATE_NOOP("Action", "Model.Model35"), QT_TRANSLATE_NOOP("Menu", "Model 35"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_36 { QT_TRANSLATE_NOOP("Action", "Model.Model36"), QT_TRANSLATE_NOOP("Menu", "Model 36"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_37 { QT_TRANSLATE_NOOP("Action", "Model.Model37"), QT_TRANSLATE_NOOP("Menu", "Model 37"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_38 { QT_TRANSLATE_NOOP("Action", "Model.Model38"), QT_TRANSLATE_NOOP("Menu", "Model 38"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_39 { QT_TRANSLATE_NOOP("Action", "Model.Model39"), QT_TRANSLATE_NOOP("Menu", "Model 39"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_MODEL_40 { QT_TRANSLATE_NOOP("Action", "Model.Model40"), QT_TRANSLATE_NOOP("Menu", "Model 40"), QT_TRANSLATE_NOOP("Status", "Switch to this submodel"), "" }, // LC_HELP_HOMEPAGE { QT_TRANSLATE_NOOP("Action", "Help.HomePage"), QT_TRANSLATE_NOOP("Menu", "LeoCAD &Home Page"), QT_TRANSLATE_NOOP("Status", "Open LeoCAD's home page on the internet using your default web browser"), "" }, // LC_HELP_BUG_REPORT { QT_TRANSLATE_NOOP("Action", "Help.BugReport"), QT_TRANSLATE_NOOP("Menu", "Report a Bug"), QT_TRANSLATE_NOOP("Status", "Open LeoCAD's bug report form on your default web browser"), "" }, // LC_HELP_UPDATES { QT_TRANSLATE_NOOP("Action", "Help.Updates"), QT_TRANSLATE_NOOP("Menu", "Check for &Updates..."), QT_TRANSLATE_NOOP("Status", "Check if a newer LeoCAD version or parts library has been released"), "" }, // LC_HELP_ABOUT { QT_TRANSLATE_NOOP("Action", "Help.About"), QT_TRANSLATE_NOOP("Menu", "&About..."), QT_TRANSLATE_NOOP("Status", "Display program version number and system information"), "" }, // LC_TIMELINE_INSERT_BEFORE { "", QT_TRANSLATE_NOOP("Menu", "Insert Step Before"), QT_TRANSLATE_NOOP("Status", "Insert a new step before the current step"), "" }, // LC_TIMELINE_INSERT_AFTER { "", QT_TRANSLATE_NOOP("Menu", "Insert Step After"), QT_TRANSLATE_NOOP("Status", "Insert a new step after the current step"), "" }, // LC_TIMELINE_DELETE { "", QT_TRANSLATE_NOOP("Menu", "Remove Step"), QT_TRANSLATE_NOOP("Status", "Remove current step"), "" }, // LC_TIMELINE_MOVE_SELECTION { "", QT_TRANSLATE_NOOP("Menu", "Move Selection Here"), QT_TRANSLATE_NOOP("Status", "Move the selected parts into this step"), "" }, // LC_TIMELINE_MOVE_SELECTION_BEFORE { "", QT_TRANSLATE_NOOP("Menu", "Move Selection Before"), QT_TRANSLATE_NOOP("Status", "Move the selected parts into a new step before this"), "" }, // LC_TIMELINE_MOVE_SELECTION_AFTER { "", QT_TRANSLATE_NOOP("Menu", "Move Selection After"), QT_TRANSLATE_NOOP("Status", "Move the selected parts into a new step after this"), "" }, // LC_TIMELINE_SET_CURRENT { "", QT_TRANSLATE_NOOP("Menu", "Set Current Step"), QT_TRANSLATE_NOOP("Status", "View the model at this point in the timeline"), "" } }; LC_ARRAY_SIZE_CHECK(gCommands, LC_NUM_COMMANDS); const char* gToolNames[] = { QT_TRANSLATE_NOOP("Mouse", "NewPiece"), // lcTool::Insert QT_TRANSLATE_NOOP("Mouse", "NewPointLight"), // lcTool::Light QT_TRANSLATE_NOOP("Mouse", "NewSpotLight"), // lcTool::SpotLight QT_TRANSLATE_NOOP("Mouse", "NewCamera"), // lcTool::Camera QT_TRANSLATE_NOOP("Mouse", "Select"), // lcTool::Select QT_TRANSLATE_NOOP("Mouse", "Move"), // lcTool::Move QT_TRANSLATE_NOOP("Mouse", "Rotate"), // lcTool::Rotate QT_TRANSLATE_NOOP("Mouse", "Delete"), // lcTool::Eraser QT_TRANSLATE_NOOP("Mouse", "Paint"), // lcTool::Paint QT_TRANSLATE_NOOP("Mouse", "ColorPicker"), // lcTool::ColorPicker QT_TRANSLATE_NOOP("Mouse", "Zoom"), // lcTool::Zoom QT_TRANSLATE_NOOP("Mouse", "Pan"), // lcTool::Pan QT_TRANSLATE_NOOP("Mouse", "Orbit"), // lcTool::RotateView QT_TRANSLATE_NOOP("Mouse", "Roll"), // lcTool::Roll QT_TRANSLATE_NOOP("Mouse", "ZoomRegion") // lcTool::ZoomRegion }; LC_ARRAY_SIZE_CHECK(gToolNames, lcTool::Count); leocad-23.03/common/lc_commands.h000066400000000000000000000154411440571307300167010ustar00rootroot00000000000000#pragma once enum lcCommandId { LC_FILE_NEW, LC_FILE_OPEN, LC_FILE_MERGE, LC_FILE_SAVE, LC_FILE_SAVEAS, LC_FILE_SAVE_IMAGE, LC_FILE_IMPORT_LDD, LC_FILE_IMPORT_INVENTORY, LC_FILE_EXPORT_3DS, LC_FILE_EXPORT_COLLADA, LC_FILE_EXPORT_HTML, LC_FILE_EXPORT_BRICKLINK, LC_FILE_EXPORT_CSV, LC_FILE_EXPORT_POVRAY, LC_FILE_EXPORT_WAVEFRONT, LC_FILE_RENDER, LC_FILE_INSTRUCTIONS, LC_FILE_PRINT, LC_FILE_PRINT_PREVIEW, LC_FILE_RECENT_FIRST, LC_FILE_RECENT1 = LC_FILE_RECENT_FIRST, LC_FILE_RECENT2, LC_FILE_RECENT3, LC_FILE_RECENT4, LC_FILE_RECENT_LAST = LC_FILE_RECENT4, LC_FILE_EXIT, LC_EDIT_UNDO, LC_EDIT_REDO, LC_EDIT_CUT, LC_EDIT_COPY, LC_EDIT_PASTE, LC_EDIT_PASTE_STEPS, LC_EDIT_FIND, LC_EDIT_FIND_NEXT, LC_EDIT_FIND_PREVIOUS, LC_EDIT_FIND_ALL, LC_EDIT_REPLACE, LC_EDIT_REPLACE_NEXT, LC_EDIT_REPLACE_ALL, LC_EDIT_SELECT_ALL, LC_EDIT_SELECT_NONE, LC_EDIT_SELECT_INVERT, LC_EDIT_SELECT_BY_NAME, LC_EDIT_SELECTION_MODE_FIRST, LC_EDIT_SELECTION_SINGLE = LC_EDIT_SELECTION_MODE_FIRST, LC_EDIT_SELECTION_PIECE, LC_EDIT_SELECTION_COLOR, LC_EDIT_SELECTION_PIECE_COLOR, LC_EDIT_SELECTION_MODE_LAST = LC_EDIT_SELECTION_PIECE_COLOR, LC_EDIT_TRANSFORM_RELATIVE, LC_EDIT_TRANSFORM_ABSOLUTE, LC_EDIT_TRANSFORM_TOGGLE_RELATIVE, LC_EDIT_TRANSFORM_SEPARATELY, LC_EDIT_TRANSFORM_TOGETHER, LC_EDIT_TRANSFORM_TOGGLE_SEPARATE, LC_EDIT_SNAP_MOVE_TOGGLE, LC_EDIT_SNAP_MOVE_XY0, LC_EDIT_SNAP_MOVE_XY1, LC_EDIT_SNAP_MOVE_XY2, LC_EDIT_SNAP_MOVE_XY3, LC_EDIT_SNAP_MOVE_XY4, LC_EDIT_SNAP_MOVE_XY5, LC_EDIT_SNAP_MOVE_XY6, LC_EDIT_SNAP_MOVE_XY7, LC_EDIT_SNAP_MOVE_XY8, LC_EDIT_SNAP_MOVE_XY9, LC_EDIT_SNAP_MOVE_Z0, LC_EDIT_SNAP_MOVE_Z1, LC_EDIT_SNAP_MOVE_Z2, LC_EDIT_SNAP_MOVE_Z3, LC_EDIT_SNAP_MOVE_Z4, LC_EDIT_SNAP_MOVE_Z5, LC_EDIT_SNAP_MOVE_Z6, LC_EDIT_SNAP_MOVE_Z7, LC_EDIT_SNAP_MOVE_Z8, LC_EDIT_SNAP_MOVE_Z9, LC_EDIT_SNAP_ANGLE_TOGGLE, LC_EDIT_SNAP_ANGLE0, LC_EDIT_SNAP_ANGLE1, LC_EDIT_SNAP_ANGLE2, LC_EDIT_SNAP_ANGLE3, LC_EDIT_SNAP_ANGLE4, LC_EDIT_SNAP_ANGLE5, LC_EDIT_SNAP_ANGLE6, LC_EDIT_SNAP_ANGLE7, LC_EDIT_SNAP_ANGLE8, LC_EDIT_SNAP_ANGLE9, LC_EDIT_TRANSFORM, LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION, LC_EDIT_TRANSFORM_RELATIVE_TRANSLATION, LC_EDIT_TRANSFORM_ABSOLUTE_ROTATION, LC_EDIT_TRANSFORM_RELATIVE_ROTATION, LC_EDIT_ACTION_FIRST, LC_EDIT_ACTION_INSERT = LC_EDIT_ACTION_FIRST, LC_EDIT_ACTION_LIGHT, LC_EDIT_ACTION_SPOTLIGHT, LC_EDIT_ACTION_CAMERA, LC_EDIT_ACTION_SELECT, LC_EDIT_ACTION_MOVE, LC_EDIT_ACTION_ROTATE, LC_EDIT_ACTION_DELETE, LC_EDIT_ACTION_PAINT, LC_EDIT_ACTION_COLOR_PICKER, LC_EDIT_ACTION_ZOOM, LC_EDIT_ACTION_PAN, LC_EDIT_ACTION_ROTATE_VIEW, LC_EDIT_ACTION_ROLL, LC_EDIT_ACTION_ZOOM_REGION, LC_EDIT_ACTION_LAST = LC_EDIT_ACTION_ZOOM_REGION, LC_EDIT_CANCEL, LC_VIEW_PREFERENCES, LC_VIEW_ZOOM_IN, LC_VIEW_ZOOM_OUT, LC_VIEW_ZOOM_EXTENTS, LC_VIEW_LOOK_AT, LC_VIEW_MOVE_FORWARD, LC_VIEW_MOVE_BACKWARD, LC_VIEW_MOVE_LEFT, LC_VIEW_MOVE_RIGHT, LC_VIEW_MOVE_UP, LC_VIEW_MOVE_DOWN, LC_VIEW_VIEWPOINT_FRONT, LC_VIEW_VIEWPOINT_BACK, LC_VIEW_VIEWPOINT_TOP, LC_VIEW_VIEWPOINT_BOTTOM, LC_VIEW_VIEWPOINT_LEFT, LC_VIEW_VIEWPOINT_RIGHT, LC_VIEW_VIEWPOINT_HOME, LC_VIEW_CAMERA_NONE, LC_VIEW_CAMERA_FIRST, LC_VIEW_CAMERA1 = LC_VIEW_CAMERA_FIRST, LC_VIEW_CAMERA2, LC_VIEW_CAMERA3, LC_VIEW_CAMERA4, LC_VIEW_CAMERA5, LC_VIEW_CAMERA6, LC_VIEW_CAMERA7, LC_VIEW_CAMERA8, LC_VIEW_CAMERA9, LC_VIEW_CAMERA10, LC_VIEW_CAMERA11, LC_VIEW_CAMERA12, LC_VIEW_CAMERA13, LC_VIEW_CAMERA14, LC_VIEW_CAMERA15, LC_VIEW_CAMERA16, LC_VIEW_CAMERA_LAST = LC_VIEW_CAMERA16, LC_VIEW_TIME_FIRST, LC_VIEW_TIME_PREVIOUS, LC_VIEW_TIME_NEXT, LC_VIEW_TIME_LAST, LC_VIEW_TIME_INSERT_BEFORE, LC_VIEW_TIME_INSERT_AFTER, LC_VIEW_TIME_DELETE, LC_VIEW_TIME_ADD_KEYS, LC_VIEW_SPLIT_HORIZONTAL, LC_VIEW_SPLIT_VERTICAL, LC_VIEW_REMOVE_VIEW, LC_VIEW_RESET_VIEWS, LC_VIEW_TOOLBAR_STANDARD, LC_VIEW_TOOLBAR_FIRST = LC_VIEW_TOOLBAR_STANDARD, LC_VIEW_TOOLBAR_TOOLS, LC_VIEW_TOOLBAR_TIME, LC_VIEW_TOOLBAR_PARTS, LC_VIEW_TOOLBAR_COLORS, LC_VIEW_TOOLBAR_PROPERTIES, LC_VIEW_TOOLBAR_TIMELINE, LC_VIEW_TOOLBAR_PREVIEW, LC_VIEW_TOOLBAR_LAST = LC_VIEW_TOOLBAR_PREVIEW, LC_VIEW_FULLSCREEN, LC_VIEW_CLOSE_CURRENT_TAB, LC_VIEW_SHADING_FIRST, LC_VIEW_SHADING_WIREFRAME = LC_VIEW_SHADING_FIRST, LC_VIEW_SHADING_FLAT, LC_VIEW_SHADING_DEFAULT_LIGHTS, LC_VIEW_SHADING_LAST = LC_VIEW_SHADING_DEFAULT_LIGHTS, LC_VIEW_PROJECTION_FIRST, LC_VIEW_PROJECTION_PERSPECTIVE = LC_VIEW_PROJECTION_FIRST, LC_VIEW_PROJECTION_ORTHO, LC_VIEW_PROJECTION_LAST = LC_VIEW_PROJECTION_ORTHO, LC_VIEW_TOGGLE_VIEW_SPHERE, LC_VIEW_TOGGLE_AXIS_ICON, LC_VIEW_TOGGLE_GRID, LC_VIEW_FADE_PREVIOUS_STEPS, LC_PIECE_INSERT, LC_PIECE_DELETE, LC_PIECE_DUPLICATE, LC_PIECE_PAINT_SELECTED, LC_PIECE_RESET_PIVOT_POINT, LC_PIECE_REMOVE_KEY_FRAMES, LC_PIECE_CONTROL_POINT_INSERT, LC_PIECE_CONTROL_POINT_REMOVE, LC_PIECE_MOVE_PLUSX, LC_PIECE_MOVE_MINUSX, LC_PIECE_MOVE_PLUSY, LC_PIECE_MOVE_MINUSY, LC_PIECE_MOVE_PLUSZ, LC_PIECE_MOVE_MINUSZ, LC_PIECE_ROTATE_PLUSX, LC_PIECE_ROTATE_MINUSX, LC_PIECE_ROTATE_PLUSY, LC_PIECE_ROTATE_MINUSY, LC_PIECE_ROTATE_PLUSZ, LC_PIECE_ROTATE_MINUSZ, LC_PIECE_MINIFIG_WIZARD, LC_PIECE_ARRAY, LC_PIECE_VIEW_SELECTED_MODEL, LC_PIECE_MOVE_SELECTION_TO_MODEL, LC_PIECE_INLINE_SELECTED_MODELS, LC_PIECE_EDIT_SELECTED_SUBMODEL, LC_PIECE_EDIT_END_SUBMODEL, LC_PIECE_GROUP, LC_PIECE_UNGROUP, LC_PIECE_GROUP_ADD, LC_PIECE_GROUP_REMOVE, LC_PIECE_GROUP_EDIT, LC_PIECE_HIDE_SELECTED, LC_PIECE_HIDE_UNSELECTED, LC_PIECE_UNHIDE_SELECTED, LC_PIECE_UNHIDE_ALL, LC_PIECE_SHOW_EARLIER, LC_PIECE_SHOW_LATER, LC_MODEL_NEW, LC_MODEL_PROPERTIES, LC_MODEL_LIST, LC_MODEL_FIRST, LC_MODEL_01 = LC_MODEL_FIRST, LC_MODEL_02, LC_MODEL_03, LC_MODEL_04, LC_MODEL_05, LC_MODEL_06, LC_MODEL_07, LC_MODEL_08, LC_MODEL_09, LC_MODEL_10, LC_MODEL_11, LC_MODEL_12, LC_MODEL_13, LC_MODEL_14, LC_MODEL_15, LC_MODEL_16, LC_MODEL_17, LC_MODEL_18, LC_MODEL_19, LC_MODEL_20, LC_MODEL_21, LC_MODEL_22, LC_MODEL_23, LC_MODEL_24, LC_MODEL_25, LC_MODEL_26, LC_MODEL_27, LC_MODEL_28, LC_MODEL_29, LC_MODEL_30, LC_MODEL_31, LC_MODEL_32, LC_MODEL_33, LC_MODEL_34, LC_MODEL_35, LC_MODEL_36, LC_MODEL_37, LC_MODEL_38, LC_MODEL_39, LC_MODEL_40, LC_MODEL_LAST = LC_MODEL_40, LC_HELP_HOMEPAGE, LC_HELP_BUG_REPORT, LC_HELP_UPDATES, LC_HELP_ABOUT, LC_TIMELINE_INSERT_BEFORE, LC_TIMELINE_INSERT_AFTER, LC_TIMELINE_DELETE, LC_TIMELINE_MOVE_SELECTION, LC_TIMELINE_MOVE_SELECTION_BEFORE, LC_TIMELINE_MOVE_SELECTION_AFTER, LC_TIMELINE_SET_CURRENT, LC_NUM_COMMANDS }; struct lcCommand { const char* ID; const char* MenuName; const char* StatusText; const char* DefaultShortcut; }; extern const lcCommand gCommands[]; enum class lcTool { Insert, Light, SpotLight, Camera, Select, Move, Rotate, Eraser, Paint, ColorPicker, Zoom, Pan, RotateView, Roll, ZoomRegion, Count }; extern const char* gToolNames[]; leocad-23.03/common/lc_context.cpp000066400000000000000000001077631440571307300171300ustar00rootroot00000000000000#include "lc_global.h" #include "lc_context.h" #include "lc_glextensions.h" #include "lc_mesh.h" #include "lc_texture.h" #include "lc_colors.h" #include "lc_mainwindow.h" #include "lc_library.h" #include "texfont.h" #include "lc_view.h" #include "lc_viewsphere.h" #include "lc_viewmanipulator.h" #include "lc_stringcache.h" #include "lc_partselectionwidget.h" #include #ifdef LC_OPENGLES #define glEnableClientState(...) #define glDisableClientState(...) #define glVertexPointer(...) #define glTexCoordPointer(...) #define glColorPointer(...) #define GL_ARRAY_BUFFER_ARB GL_ARRAY_BUFFER #define GL_ELEMENT_ARRAY_BUFFER_ARB GL_ELEMENT_ARRAY_BUFFER #define GL_STATIC_DRAW_ARB GL_STATIC_DRAW #endif std::unique_ptr lcContext::mOffscreenContext; std::unique_ptr lcContext::mOffscreenSurface; std::unique_ptr lcContext::mGlobalOffscreenContext; lcProgram lcContext::mPrograms[static_cast(lcMaterialType::Count)]; lcContext::lcContext() { mVertexBufferObject = 0; mIndexBufferObject = 0; mVertexBufferPointer = nullptr; mIndexBufferPointer = nullptr; mVertexBufferOffset = (char*)~0; mNormalEnabled = false; mTexCoordEnabled = false; mColorEnabled = false; mTexture2D = 0; mTextureCubeMap = 0; mPolygonOffset = lcPolygonOffset::None; mDepthWrite = true; mDepthFunction = lcDepthFunction::LessEqual; mDepthTest = true; mColorWrite = true; mColorBlend = false; mCullFace = false; mLineWidth = 1.0f; #if LC_FIXED_FUNCTION mMatrixMode = GL_MODELVIEW; mTextureEnabled = false; #endif mColor = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); mWorldMatrix = lcMatrix44Identity(); mViewMatrix = lcMatrix44Identity(); mProjectionMatrix = lcMatrix44Identity(); mViewProjectionMatrix = lcMatrix44Identity(); mHighlightParams[0] = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); mHighlightParams[1] = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); mHighlightParams[2] = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); mHighlightParams[3] = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); mColorDirty = false; mWorldMatrixDirty = false; mViewMatrixDirty = false; mProjectionMatrixDirty = false; mViewProjectionMatrixDirty = false; mHighlightParamsDirty = false; mMaterialType = lcMaterialType::Count; } lcContext::~lcContext() { } bool lcContext::InitializeRenderer() { if (!CreateOffscreenContext()) return false; mGlobalOffscreenContext = std::unique_ptr(new(lcContext)); lcContext* Context = mGlobalOffscreenContext.get(); Context->SetOffscreenContext(); lcInitializeGLExtensions(mOffscreenContext.get()); gStringCache.Initialize(Context); gTexFont.Initialize(Context); Context->CreateResources(); lcView::CreateResources(Context); lcViewManipulator::CreateResources(Context); lcViewSphere::CreateResources(Context); if (!gSupportsShaderObjects && lcGetPreferences().mShadingMode == lcShadingMode::DefaultLights) lcGetPreferences().mShadingMode = lcShadingMode::Flat; if (!gSupportsShaderObjects && lcGetPreferences().mDrawConditionalLines) lcGetPreferences().mDrawConditionalLines = false; if (!gSupportsFramebufferObject) gMainWindow->GetPartSelectionWidget()->DisableIconMode(); return true; } void lcContext::ShutdownRenderer() { if (!mGlobalOffscreenContext) return; mGlobalOffscreenContext->MakeCurrent(); lcContext* Context = mGlobalOffscreenContext.get(); gStringCache.Reset(); gTexFont.Reset(); lcView::DestroyResources(Context); Context->DestroyResources(); lcViewManipulator::DestroyResources(Context); lcViewSphere::DestroyResources(Context); mGlobalOffscreenContext.reset(); lcContext::DestroyOffscreenContext(); } lcContext* lcContext::GetGlobalOffscreenContext() { return mGlobalOffscreenContext.get(); } bool lcContext::CreateOffscreenContext() { std::unique_ptr OffscreenContext(new QOpenGLContext()); if (!OffscreenContext) return false; OffscreenContext->setShareContext(QOpenGLContext::globalShareContext()); if (!OffscreenContext->create() || !OffscreenContext->isValid()) return false; std::unique_ptr OffscreenSurface(new QOffscreenSurface()); if (!OffscreenSurface) return false; OffscreenSurface->create(); if (!OffscreenSurface->isValid()) return false; if (!OffscreenContext->makeCurrent(OffscreenSurface.get())) return false; mOffscreenContext = std::move(OffscreenContext); mOffscreenSurface = std::move(OffscreenSurface); return true; } void lcContext::DestroyOffscreenContext() { mOffscreenSurface.reset(); mOffscreenContext.reset(); } void lcContext::CreateShaderPrograms() { const char* ShaderPrefix = { #ifndef LC_OPENGLES "#version 110\n" "#define mediump\n" "#define LC_VERTEX_INPUT attribute\n" "#define LC_VERTEX_OUTPUT varying\n" "#define LC_PIXEL_INPUT varying\n" "#define LC_PIXEL_OUTPUT\n" "#define LC_SHADER_PRECISION\n" #else "#version 300 es\n" "#define texture2D texture\n" "#define LC_VERTEX_INPUT in\n" "#define LC_VERTEX_OUTPUT out\n" "#define LC_PIXEL_INPUT in mediump\n" "#define gl_FragColor FragColor\n" "#define LC_PIXEL_OUTPUT out mediump vec4 gl_FragColor;\n" "#define LC_SHADER_PRECISION mediump\n" #endif "#define LC_PIXEL_FAKE_LIGHTING \\\n" " LC_SHADER_PRECISION vec3 Normal = normalize(PixelNormal); \\\n" " LC_SHADER_PRECISION vec3 LightDirection = normalize(PixelPosition - LightPosition); \\\n" " LC_SHADER_PRECISION vec3 VertexToEye = normalize(EyePosition - PixelPosition); \\\n" " LC_SHADER_PRECISION vec3 LightReflect = normalize(reflect(-LightDirection, Normal)); \\\n" " LC_SHADER_PRECISION float Specular = abs(dot(VertexToEye, LightReflect)); \\\n" " Specular = min(pow(Specular, 8.0), 1.0) * 0.25; \\\n" " LC_SHADER_PRECISION vec3 SpecularColor = vec3(Specular, Specular, Specular); \\\n" " LC_SHADER_PRECISION float Diffuse = min(abs(dot(Normal, LightDirection)) * 0.6 + 0.65, 1.0);\n" }; const char* const VertexShaders[] = { ":/resources/shaders/unlit_color_vs.glsl", // UnlitColor ":/resources/shaders/unlit_color_conditional_vs.glsl", // UnlitColorConditional ":/resources/shaders/unlit_texture_modulate_vs.glsl", // UnlitTextureModulate ":/resources/shaders/unlit_texture_decal_vs.glsl", // UnlitTextureDecal ":/resources/shaders/unlit_vertex_color_vs.glsl", // UnlitVertexColor ":/resources/shaders/unlit_view_sphere_vs.glsl", // UnlitViewSphere ":/resources/shaders/fakelit_color_vs.glsl", // FakeLitColor ":/resources/shaders/fakelit_texture_decal_vs.glsl" // FakeLitTextureDecal }; LC_ARRAY_SIZE_CHECK(VertexShaders, lcMaterialType::Count); const char* const FragmentShaders[] = { ":/resources/shaders/unlit_color_ps.glsl", // UnlitColor ":/resources/shaders/unlit_color_conditional_ps.glsl", // UnlitColorConditional ":/resources/shaders/unlit_texture_modulate_ps.glsl", // UnlitTextureModulate ":/resources/shaders/unlit_texture_decal_ps.glsl", // UnlitTextureDecal ":/resources/shaders/unlit_vertex_color_ps.glsl", // UnlitVertexColor ":/resources/shaders/unlit_view_sphere_ps.glsl", // UnlitViewSphere ":/resources/shaders/fakelit_color_ps.glsl", // FakeLitColor ":/resources/shaders/fakelit_texture_decal_ps.glsl" // FakeLitTextureDecal }; LC_ARRAY_SIZE_CHECK(FragmentShaders, lcMaterialType::Count); const auto LoadShader = [this, ShaderPrefix](const char* FileName, GLuint ShaderType) -> GLuint { QFile ShaderFile(FileName); if (!ShaderFile.open(QIODevice::ReadOnly)) return 0; QByteArray Data = ShaderPrefix + ShaderFile.readAll(); const char* Source = Data.constData(); const GLuint Shader = glCreateShader(ShaderType); glShaderSource(Shader, 1, &Source, nullptr); glCompileShader(Shader); #ifndef QT_NO_DEBUG GLint ShaderCompiled = 0; glGetShaderiv(Shader, GL_COMPILE_STATUS, &ShaderCompiled); if (ShaderCompiled == GL_FALSE) { GLint Length = 0; glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &Length); QByteArray InfoLog; InfoLog.resize(Length); glGetShaderInfoLog(Shader, Length, &Length, InfoLog.data()); qDebug() << InfoLog; } #endif return Shader; }; for (int MaterialType = 0; MaterialType < static_cast(lcMaterialType::Count); MaterialType++) { const GLuint VertexShader = LoadShader(VertexShaders[MaterialType], GL_VERTEX_SHADER); const GLuint FragmentShader = LoadShader(FragmentShaders[MaterialType], GL_FRAGMENT_SHADER); GLuint Program = glCreateProgram(); glAttachShader(Program, VertexShader); glAttachShader(Program, FragmentShader); glBindAttribLocation(Program, static_cast(lcProgramAttrib::Position), "VertexPosition"); glBindAttribLocation(Program, static_cast(lcProgramAttrib::Normal), "VertexNormal"); glBindAttribLocation(Program, static_cast(lcProgramAttrib::TexCoord), "VertexTexCoord"); glBindAttribLocation(Program, static_cast(lcProgramAttrib::Color), "VertexColor"); glBindAttribLocation(Program, static_cast(lcProgramAttrib::ControlPoint1), "VertexPosition1"); glBindAttribLocation(Program, static_cast(lcProgramAttrib::ControlPoint2), "VertexPosition2"); glBindAttribLocation(Program, static_cast(lcProgramAttrib::ControlPoint3), "VertexPosition3"); glBindAttribLocation(Program, static_cast(lcProgramAttrib::ControlPoint4), "VertexPosition4"); glLinkProgram(Program); glDetachShader(Program, VertexShader); glDetachShader(Program, FragmentShader); glDeleteShader(VertexShader); glDeleteShader(FragmentShader); GLint IsLinked = 0; glGetProgramiv(Program, GL_LINK_STATUS, &IsLinked); if (IsLinked == GL_FALSE) { GLint Length = 0; glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &Length); QByteArray InfoLog; InfoLog.resize(Length); glGetProgramInfoLog(Program, Length, &Length, InfoLog.data()); glDeleteProgram(Program); Program = 0; } mPrograms[MaterialType].Object = Program; mPrograms[MaterialType].WorldViewProjectionMatrixLocation = glGetUniformLocation(Program, "WorldViewProjectionMatrix"); mPrograms[MaterialType].WorldMatrixLocation = glGetUniformLocation(Program, "WorldMatrix"); mPrograms[MaterialType].MaterialColorLocation = glGetUniformLocation(Program, "MaterialColor"); mPrograms[MaterialType].LightPositionLocation = glGetUniformLocation(Program, "LightPosition"); mPrograms[MaterialType].EyePositionLocation = glGetUniformLocation(Program, "EyePosition"); mPrograms[MaterialType].HighlightParamsLocation = glGetUniformLocation(Program, "HighlightParams"); const GLint TextureLocation = glGetUniformLocation(Program, "Texture"); if (TextureLocation != -1) { glUseProgram(Program); glUniform1i(TextureLocation, 0); glUseProgram(0); } } } void lcContext::CreateResources() { if (!gSupportsShaderObjects) return; CreateShaderPrograms(); } void lcContext::DestroyResources() { if (!gSupportsShaderObjects) return; for (int MaterialType = 0; MaterialType < static_cast(lcMaterialType::Count); MaterialType++) { glDeleteProgram(mPrograms[MaterialType].Object); mPrograms[MaterialType].Object = 0; } } void lcContext::MakeCurrent() { if (mWidget) mWidget->makeCurrent(); else mOffscreenContext->makeCurrent(mOffscreenSurface.get()); } void lcContext::SetGLContext(QOpenGLContext* Context, QOpenGLWidget* Widget) { mContext = Context; mWidget = Widget; MakeCurrent(); initializeOpenGLFunctions(); } void lcContext::SetOffscreenContext() { SetGLContext(mOffscreenContext.get(), nullptr); } void lcContext::SetDefaultState() { #ifndef LC_OPENGLES if (QSurfaceFormat::defaultFormat().samples() > 1) glEnable(GL_LINE_SMOOTH); #endif glEnable(GL_DEPTH_TEST); mDepthTest = true; glDepthFunc(GL_LEQUAL); mDepthFunction = lcDepthFunction::LessEqual; mColorWrite = true; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); mColorBlend = false; glDisable(GL_BLEND); if (gSupportsBlendFuncSeparate) glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE); else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (gSupportsVertexBufferObject) { glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } if (gSupportsShaderObjects) { SetVertexAttribPointer(lcProgramAttrib::Position, 3, GL_FLOAT, false, 0, nullptr); EnableVertexAttrib(lcProgramAttrib::Position); DisableVertexAttrib(lcProgramAttrib::Normal); SetVertexAttribPointer(lcProgramAttrib::Normal, 4, GL_BYTE, true, 0, nullptr); DisableVertexAttrib(lcProgramAttrib::TexCoord); SetVertexAttribPointer(lcProgramAttrib::TexCoord, 2, GL_FLOAT, false, 0, nullptr); DisableVertexAttrib(lcProgramAttrib::Color); SetVertexAttribPointer(lcProgramAttrib::Color, 4, GL_FLOAT, false, 0, nullptr); } else { #if LC_FIXED_FUNCTION glEnableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glVertexPointer(3, GL_FLOAT, 0, nullptr); glNormalPointer(GL_BYTE, 0, nullptr); glTexCoordPointer(2, GL_FLOAT, 0, nullptr); glColorPointer(4, GL_FLOAT, 0, nullptr); mNormalEnabled = false; mTexCoordEnabled = false; mColorEnabled = false; #endif } mVertexBufferObject = 0; mIndexBufferObject = 0; mVertexBufferPointer = nullptr; mIndexBufferPointer = nullptr; mVertexBufferOffset = (char*)~0; for (int AttribIndex = 0; AttribIndex < static_cast(lcProgramAttrib::Count); AttribIndex++) mVertexAttribState[AttribIndex] = lcVertexAttribState(); glBindTexture(GL_TEXTURE_2D, 0); mTexture2D = 0; glBindTexture(GL_TEXTURE_CUBE_MAP, 0); mTextureCubeMap = 0; glDisable(GL_POLYGON_OFFSET_FILL); mPolygonOffset = lcPolygonOffset::None; mDepthWrite = true; glDepthMask(GL_TRUE); glDisable(GL_CULL_FACE); mCullFace = false; glLineWidth(1.0f); mLineWidth = 1.0f; if (gSupportsShaderObjects) { glUseProgram(0); mMaterialType = lcMaterialType::Count; } else { #if LC_FIXED_FUNCTION glMatrixMode(GL_MODELVIEW); mMatrixMode = GL_MODELVIEW; glShadeModel(GL_FLAT); glDisable(GL_TEXTURE_2D); mTextureEnabled = false; #endif } } void lcContext::ClearColorAndDepth(const lcVector4& ClearColor) { glClearColor(ClearColor[0], ClearColor[1], ClearColor[2], ClearColor[3]); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void lcContext::ClearDepth() { glClear(GL_DEPTH_BUFFER_BIT); } void lcContext::ClearResources() { ClearVertexBuffer(); ClearIndexBuffer(); ClearTexture2D(); } void lcContext::SetMaterial(lcMaterialType MaterialType) { if (MaterialType == mMaterialType) return; mMaterialType = MaterialType; if (gSupportsShaderObjects) { glUseProgram(mPrograms[static_cast(MaterialType)].Object); mColorDirty = true; mWorldMatrixDirty = true; // todo: change dirty to a bitfield and set the lighting constants dirty here mViewMatrixDirty = true; mHighlightParamsDirty = true; } else { #if LC_FIXED_FUNCTION switch (MaterialType) { case lcMaterialType::UnlitTextureModulate: glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if (!mTextureEnabled) { glEnable(GL_TEXTURE_2D); mTextureEnabled = true; } break; case lcMaterialType::FakeLitTextureDecal: case lcMaterialType::UnlitTextureDecal: glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); if (!mTextureEnabled) { glEnable(GL_TEXTURE_2D); mTextureEnabled = true; } break; case lcMaterialType::UnlitColor: case lcMaterialType::UnlitColorConditional: case lcMaterialType::UnlitVertexColor: case lcMaterialType::FakeLitColor: if (mTextureEnabled) { glDisable(GL_TEXTURE_2D); mTextureEnabled = false; } break; case lcMaterialType::UnlitViewSphere: case lcMaterialType::Count: break; } #endif } } void lcContext::SetViewport(int x, int y, int Width, int Height) { glViewport(x, y, Width, Height); } void lcContext::SetPolygonOffset(lcPolygonOffset PolygonOffset) { if (mPolygonOffset == PolygonOffset) return; switch (PolygonOffset) { case lcPolygonOffset::None: glDisable(GL_POLYGON_OFFSET_FILL); break; case lcPolygonOffset::Opaque: glPolygonOffset(0.5f, 0.1f); glEnable(GL_POLYGON_OFFSET_FILL); break; case lcPolygonOffset::Translucent: glPolygonOffset(0.25f, 0.1f); glEnable(GL_POLYGON_OFFSET_FILL); break; } mPolygonOffset = PolygonOffset; } void lcContext::SetDepthWrite(bool Enable) { if (Enable == mDepthWrite) return; glDepthMask(Enable ? GL_TRUE : GL_FALSE); mDepthWrite = Enable; } void lcContext::SetDepthFunction(lcDepthFunction DepthFunction) { if (DepthFunction == mDepthFunction) return; switch (DepthFunction) { case lcDepthFunction::Always: glDepthFunc(GL_ALWAYS); break; case lcDepthFunction::LessEqual: glDepthFunc(GL_LEQUAL); break; } mDepthFunction = DepthFunction; } void lcContext::EnableDepthTest(bool Enable) { if (Enable == mDepthTest) return; if (Enable) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); mDepthTest = Enable; } void lcContext::EnableColorWrite(bool Enable) { if (Enable == mColorWrite) return; if (Enable) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); else glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); mColorWrite = Enable; } void lcContext::EnableColorBlend(bool Enable) { if (Enable == mColorBlend) return; if (Enable) glEnable(GL_BLEND); else glDisable(GL_BLEND); mColorBlend = Enable; } void lcContext::EnableCullFace(bool Enable) { if (Enable == mCullFace) return; if (Enable) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); mCullFace = Enable; } void lcContext::SetLineWidth(float LineWidth) { if (LineWidth == mLineWidth) return; glLineWidth(LineWidth); mLineWidth = LineWidth; } void lcContext::BindTexture2D(const lcTexture* Texture) { GLuint TextureObject = Texture->mTexture; if (mTexture2D == TextureObject) return; glBindTexture(GL_TEXTURE_2D, TextureObject); mTexture2D = TextureObject; } void lcContext::BindTextureCubeMap(const lcTexture* Texture) { GLuint TextureObject = Texture->mTexture; if (mTextureCubeMap == TextureObject) return; glBindTexture(GL_TEXTURE_CUBE_MAP, TextureObject); mTextureCubeMap = TextureObject; } void lcContext::ClearTexture2D() { if (mTexture2D == 0) return; glBindTexture(GL_TEXTURE_2D, 0); mTexture2D = 0; } void lcContext::ClearTextureCubeMap() { if (mTexture2D == 0) return; glBindTexture(GL_TEXTURE_CUBE_MAP, 0); mTextureCubeMap = 0; } void lcContext::UploadTexture(lcTexture* Texture) { if (!Texture->mTexture) glGenTextures(1, &Texture->mTexture); constexpr int Filters[2][5] = { { GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR }, { GL_NEAREST, GL_LINEAR, GL_LINEAR, GL_LINEAR, GL_LINEAR }, }; const int Flags = Texture->GetFlags(); const int FilterFlags = Flags & LC_TEXTURE_FILTER_MASK; const int FilterIndex = FilterFlags >> LC_TEXTURE_FILTER_SHIFT; const int MipIndex = Flags & LC_TEXTURE_MIPMAPS ? 0 : 1; unsigned int Faces, Target; if ((Flags & LC_TEXTURE_CUBEMAP) == 0) { Faces = 1; Target = GL_TEXTURE_2D; BindTexture2D(Texture); } else { Faces = 6; Target = GL_TEXTURE_CUBE_MAP; BindTextureCubeMap(Texture); } glTexParameteri(Target, GL_TEXTURE_WRAP_S, (Flags & LC_TEXTURE_WRAPU) ? GL_REPEAT : GL_CLAMP_TO_EDGE); glTexParameteri(Target, GL_TEXTURE_WRAP_T, (Flags & LC_TEXTURE_WRAPV) ? GL_REPEAT : GL_CLAMP_TO_EDGE); glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, Filters[MipIndex][FilterIndex]); glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, Filters[1][FilterIndex]); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); if (gSupportsAnisotropic && FilterFlags == LC_TEXTURE_ANISOTROPIC) glTexParameterf(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, lcMin(4.0f, gMaxAnisotropy)); int Format; switch (Texture->GetImage(0).mFormat) { default: case lcPixelFormat::Invalid: Format = 0; break; case lcPixelFormat::A8: Format = GL_ALPHA; break; case lcPixelFormat::L8A8: Format = GL_LUMINANCE_ALPHA; break; case lcPixelFormat::R8G8B8: Format = GL_RGB; break; case lcPixelFormat::R8G8B8A8: Format = GL_RGBA; break; } int CurrentImage = 0; if (Flags & LC_TEXTURE_CUBEMAP) Target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; for (size_t FaceIdx = 0; FaceIdx < Faces; FaceIdx++) { void* Data = Texture->GetImage(CurrentImage).mData; glTexImage2D(Target, 0, Format, Texture->mWidth, Texture->mHeight, 0, Format, GL_UNSIGNED_BYTE, Data); if (Flags & LC_TEXTURE_MIPMAPS || FilterFlags >= LC_TEXTURE_BILINEAR) { int Width = Texture->mWidth; int Height = Texture->mHeight; int Components = Texture->GetImage(CurrentImage).GetBPP(); for (int Level = 1; ((Width != 1) || (Height != 1)); Level++) { int RowStride = Width * Components; Width = lcMax(1, Width >> 1); Height = lcMax(1, Height >> 1); if (Texture->GetImageCount() == Faces) { GLubyte* Out, * In; In = Out = (GLubyte*)Data; for (int y = 0; y < Height; y++, In += RowStride) for (int x = 0; x < Width; x++, Out += Components, In += 2 * Components) for (int c = 0; c < Components; c++) Out[c] = (In[c] + In[c + Components] + In[RowStride] + In[c + RowStride + Components]) / 4; } else Data = Texture->GetImage(++CurrentImage).mData; glTexImage2D(Target, Level, Format, Width, Height, 0, Format, GL_UNSIGNED_BYTE, Data); } if (Texture->GetImageCount() == Faces) CurrentImage++; } else CurrentImage++; Target++; } if ((Flags & LC_TEXTURE_CUBEMAP) == 0) ClearTexture2D(); else ClearTextureCubeMap(); } void lcContext::SetColor(float Red, float Green, float Blue, float Alpha) { SetColor(lcVector4(Red, Green, Blue, Alpha)); } void lcContext::SetColorIndex(int ColorIndex) { SetColor(gColorList[ColorIndex].Value); } void lcContext::SetColorIndexTinted(int ColorIndex, const lcVector4& Tint, float Weight) { const lcVector3 Color(gColorList[ColorIndex].Value * Weight + Tint * (1.0f - Weight)); SetColor(lcVector4(Color, gColorList[ColorIndex].Value.w)); } void lcContext::SetColorIndexTinted(int ColorIndex, const lcVector4& Tint) { SetColor(gColorList[ColorIndex].Value * Tint); } void lcContext::SetEdgeColorIndex(int ColorIndex) { SetColor(gColorList[ColorIndex].Edge); } void lcContext::SetEdgeColorIndexTinted(int ColorIndex, const lcVector4& Tint) { SetColor(gColorList[ColorIndex].Edge * Tint); } lcVertexBuffer lcContext::CreateVertexBuffer(int Size, const void* Data) { lcVertexBuffer VertexBuffer; if (gSupportsVertexBufferObject) { glGenBuffers(1, &VertexBuffer.Object); glBindBuffer(GL_ARRAY_BUFFER_ARB, VertexBuffer.Object); glBufferData(GL_ARRAY_BUFFER_ARB, Size, Data, GL_STATIC_DRAW_ARB); glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); // context remove mVertexBufferObject = 0; } else { VertexBuffer.Pointer = malloc(Size); if (VertexBuffer.Pointer) memcpy(VertexBuffer.Pointer, Data, Size); } return VertexBuffer; } void lcContext::DestroyVertexBuffer(lcVertexBuffer& VertexBuffer) { if (!VertexBuffer.IsValid()) return; if (gSupportsVertexBufferObject) { if (mVertexBufferObject == VertexBuffer.Object) { glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); mVertexBufferObject = 0; } glDeleteBuffers(1, &VertexBuffer.Object); } else { free(VertexBuffer.Pointer); } VertexBuffer.Pointer = nullptr; } lcIndexBuffer lcContext::CreateIndexBuffer(int Size, const void* Data) { lcIndexBuffer IndexBuffer; if (gSupportsVertexBufferObject) { glGenBuffers(1, &IndexBuffer.Object); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, IndexBuffer.Object); glBufferData(GL_ELEMENT_ARRAY_BUFFER_ARB, Size, Data, GL_STATIC_DRAW_ARB); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); // context remove mIndexBufferObject = 0; } else { IndexBuffer.Pointer = malloc(Size); if (IndexBuffer.Pointer) memcpy(IndexBuffer.Pointer, Data, Size); } return IndexBuffer; } void lcContext::DestroyIndexBuffer(lcIndexBuffer& IndexBuffer) { if (!IndexBuffer.IsValid()) return; if (gSupportsVertexBufferObject) { if (mIndexBufferObject == IndexBuffer.Object) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); mIndexBufferObject = 0; } glDeleteBuffers(1, &IndexBuffer.Object); } else { free(IndexBuffer.Pointer); } IndexBuffer.Pointer = nullptr; } void lcContext::ClearVertexBuffer() { mVertexBufferPointer = nullptr; mVertexBufferOffset = (char*)~0; if (mVertexBufferObject) { glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); mVertexBufferObject = 0; } if (gSupportsShaderObjects) { SetVertexAttribPointer(lcProgramAttrib::Position, 3, GL_FLOAT, false, 0, nullptr); DisableVertexAttrib(lcProgramAttrib::Normal); SetVertexAttribPointer(lcProgramAttrib::Normal, 4, GL_BYTE, true, 0, nullptr); DisableVertexAttrib(lcProgramAttrib::TexCoord); SetVertexAttribPointer(lcProgramAttrib::TexCoord, 2, GL_FLOAT, false, 0, nullptr); DisableVertexAttrib(lcProgramAttrib::Color); SetVertexAttribPointer(lcProgramAttrib::Color, 4, GL_FLOAT, false, 0, nullptr); } else { #if LC_FIXED_FUNCTION if (mNormalEnabled) glDisableClientState(GL_NORMAL_ARRAY); if (mTexCoordEnabled) glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (mColorEnabled) glDisableClientState(GL_COLOR_ARRAY); glVertexPointer(3, GL_FLOAT, 0, nullptr); glNormalPointer(GL_BYTE, 0, nullptr); glTexCoordPointer(2, GL_FLOAT, 0, nullptr); glColorPointer(4, GL_FLOAT, 0, nullptr); #endif } } void lcContext::SetVertexBuffer(lcVertexBuffer VertexBuffer) { if (gSupportsVertexBufferObject) { const GLuint VertexBufferObject = VertexBuffer.Object; mVertexBufferPointer = nullptr; if (VertexBufferObject != mVertexBufferObject) { glBindBuffer(GL_ARRAY_BUFFER_ARB, VertexBufferObject); mVertexBufferObject = VertexBufferObject; mVertexBufferOffset = (char*)~0; } } else { mVertexBufferPointer = (char*)VertexBuffer.Pointer; mVertexBufferOffset = (char*)~0; } } void lcContext::SetVertexBufferPointer(const void* VertexBuffer) { if (gSupportsVertexBufferObject && mVertexBufferObject) { glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); mVertexBufferObject = 0; } mVertexBufferPointer = (char*)VertexBuffer; mVertexBufferOffset = (char*)~0; } void lcContext::SetVertexAttribPointer(lcProgramAttrib Attrib, GLint Size, GLenum Type, GLboolean Normalized, GLsizei Stride, const void* Pointer) { const int Index = static_cast(Attrib); lcVertexAttribState& State = mVertexAttribState[Index]; if (State.Size != Size || State.Type != Type || State.Normalized != Normalized || State.Stride != Stride || State.Pointer != Pointer || State.VertexBufferObject != mVertexBufferObject) { glVertexAttribPointer(Index, Size, Type, Normalized, Stride, Pointer); State.Size = Size; State.Type = Type; State.Normalized = Normalized; State.Stride = Stride; State.Pointer = Pointer; State.VertexBufferObject = mVertexBufferObject; } } void lcContext::EnableVertexAttrib(lcProgramAttrib Attrib) { const int Index = static_cast(Attrib); lcVertexAttribState& State = mVertexAttribState[Index]; if (!State.Enabled) { glEnableVertexAttribArray(Index); State.Enabled = true; } } void lcContext::DisableVertexAttrib(lcProgramAttrib Attrib) { const int Index = static_cast(Attrib); lcVertexAttribState& State = mVertexAttribState[Index]; if (State.Enabled) { glDisableVertexAttribArray(Index); State.Enabled = false; } } void lcContext::SetVertexFormatPosition(int PositionSize) { const int VertexSize = PositionSize * sizeof(float); const char* VertexBufferPointer = mVertexBufferPointer; if (gSupportsShaderObjects) { SetVertexAttribPointer(lcProgramAttrib::Position, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer); DisableVertexAttrib(lcProgramAttrib::Normal); DisableVertexAttrib(lcProgramAttrib::TexCoord); DisableVertexAttrib(lcProgramAttrib::Color); } else { #if LC_FIXED_FUNCTION if (mVertexBufferOffset != mVertexBufferPointer) { glVertexPointer(PositionSize, GL_FLOAT, VertexSize, VertexBufferPointer); mVertexBufferOffset = VertexBufferPointer; } if (mNormalEnabled) { glDisableClientState(GL_NORMAL_ARRAY); mNormalEnabled = false; } if (mTexCoordEnabled) { glDisableClientState(GL_TEXTURE_COORD_ARRAY); mTexCoordEnabled = false; } if (mColorEnabled) { glDisableClientState(GL_COLOR_ARRAY); mColorEnabled = false; } #endif } } void lcContext::SetVertexFormatConditional(int BufferOffset) { constexpr int VertexSize = 12 * sizeof(float); const char* VertexBufferPointer = mVertexBufferPointer + BufferOffset; if (gSupportsShaderObjects) { SetVertexAttribPointer(lcProgramAttrib::ControlPoint1, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer); EnableVertexAttrib(lcProgramAttrib::ControlPoint1); SetVertexAttribPointer(lcProgramAttrib::ControlPoint2, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 3 * sizeof(float)); EnableVertexAttrib(lcProgramAttrib::ControlPoint2); SetVertexAttribPointer(lcProgramAttrib::ControlPoint3, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 6 * sizeof(float)); EnableVertexAttrib(lcProgramAttrib::ControlPoint3); SetVertexAttribPointer(lcProgramAttrib::ControlPoint4, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 9 * sizeof(float)); EnableVertexAttrib(lcProgramAttrib::ControlPoint4); } } void lcContext::SetVertexFormat(int BufferOffset, int PositionSize, int NormalSize, int TexCoordSize, int ColorSize, bool EnableNormals) { const int VertexSize = (PositionSize + TexCoordSize) * sizeof(float) + NormalSize * sizeof(quint32) + ColorSize; const char* VertexBufferPointer = mVertexBufferPointer + BufferOffset; if (gSupportsShaderObjects) { int Offset = 0; SetVertexAttribPointer(lcProgramAttrib::Position, PositionSize, GL_FLOAT, false, VertexSize, VertexBufferPointer); EnableVertexAttrib(lcProgramAttrib::Position); Offset += PositionSize * sizeof(float); if (NormalSize && EnableNormals) { SetVertexAttribPointer(lcProgramAttrib::Normal, 4, GL_BYTE, true, VertexSize, VertexBufferPointer + Offset); EnableVertexAttrib(lcProgramAttrib::Normal); } else DisableVertexAttrib(lcProgramAttrib::Normal); Offset += NormalSize * sizeof(quint32); if (TexCoordSize) { SetVertexAttribPointer(lcProgramAttrib::TexCoord, TexCoordSize, GL_FLOAT, false, VertexSize, VertexBufferPointer + Offset); EnableVertexAttrib(lcProgramAttrib::TexCoord); } else DisableVertexAttrib(lcProgramAttrib::TexCoord); Offset += TexCoordSize * sizeof(float); if (ColorSize) { SetVertexAttribPointer(lcProgramAttrib::Color, ColorSize, GL_UNSIGNED_BYTE, true, VertexSize, VertexBufferPointer + Offset); EnableVertexAttrib(lcProgramAttrib::Color); } else DisableVertexAttrib(lcProgramAttrib::Color); } else { #if LC_FIXED_FUNCTION if (mVertexBufferOffset != VertexBufferPointer) { glVertexPointer(PositionSize, GL_FLOAT, VertexSize, VertexBufferPointer); mVertexBufferOffset = VertexBufferPointer; } int Offset = PositionSize * sizeof(float); if (NormalSize && EnableNormals) { glNormalPointer(GL_BYTE, VertexSize, VertexBufferPointer + Offset); if (!mNormalEnabled) { glEnableClientState(GL_NORMAL_ARRAY); mNormalEnabled = true; } } else if (mNormalEnabled) { glDisableClientState(GL_NORMAL_ARRAY); mNormalEnabled = false; } Offset += NormalSize * sizeof(quint32); if (TexCoordSize) { glTexCoordPointer(TexCoordSize, GL_FLOAT, VertexSize, VertexBufferPointer + Offset); if (!mTexCoordEnabled) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); mTexCoordEnabled = true; } Offset += 2 * sizeof(float); } else if (mTexCoordEnabled) { glDisableClientState(GL_TEXTURE_COORD_ARRAY); mTexCoordEnabled = false; } if (ColorSize) { glColorPointer(ColorSize, GL_FLOAT, VertexSize, VertexBufferPointer + Offset); if (!mColorEnabled) { glEnableClientState(GL_COLOR_ARRAY); mColorEnabled = true; } } else if (mColorEnabled) { glDisableClientState(GL_COLOR_ARRAY); mColorEnabled = false; } #endif } } void lcContext::ClearIndexBuffer() { if (mIndexBufferObject) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); mIndexBufferObject = 0; } } void lcContext::SetIndexBuffer(lcIndexBuffer IndexBuffer) { if (gSupportsVertexBufferObject) { const GLuint IndexBufferObject = IndexBuffer.Object; mIndexBufferPointer = nullptr; if (IndexBufferObject != mIndexBufferObject) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, IndexBufferObject); mIndexBufferObject = IndexBufferObject; } } else { mIndexBufferPointer = (char*)IndexBuffer.Pointer; } } void lcContext::SetIndexBufferPointer(const void* IndexBuffer) { if (mIndexBufferObject) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); mIndexBufferObject = 0; } mIndexBufferPointer = (char*)IndexBuffer; } void lcContext::BindMesh(const lcMesh* Mesh) { const lcPiecesLibrary* const Library = lcGetPiecesLibrary(); if (Mesh->mVertexCacheOffset != -1) { const GLuint VertexBufferObject = Library->mVertexBuffer.Object; const GLuint IndexBufferObject = Library->mIndexBuffer.Object; if (VertexBufferObject != mVertexBufferObject) { glBindBuffer(GL_ARRAY_BUFFER_ARB, VertexBufferObject); mVertexBufferObject = VertexBufferObject; mVertexBufferPointer = nullptr; mVertexBufferOffset = (char*)~0; } if (IndexBufferObject != mIndexBufferObject) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, IndexBufferObject); mIndexBufferObject = IndexBufferObject; mIndexBufferPointer = nullptr; } } else { if (mVertexBufferObject) { glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); mVertexBufferObject = 0; } if (mIndexBufferObject) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); mIndexBufferObject = 0; } mVertexBufferPointer = (char*)Mesh->mVertexData; mIndexBufferPointer = (char*)Mesh->mIndexData; mVertexBufferOffset = (char*)~0; } } void lcContext::FlushState() { if (gSupportsShaderObjects) { const lcProgram& Program = mPrograms[static_cast(mMaterialType)]; if (mWorldMatrixDirty || mViewMatrixDirty || mProjectionMatrixDirty) { if (mViewProjectionMatrixDirty) { mViewProjectionMatrix = lcMul(mViewMatrix, mProjectionMatrix); mViewProjectionMatrixDirty = false; } if (mWorldMatrixDirty) { if (Program.WorldMatrixLocation != -1) glUniformMatrix4fv(Program.WorldMatrixLocation, 1, false, mWorldMatrix); } if (mViewMatrixDirty) { const lcMatrix44 InverseViewMatrix = lcMatrix44AffineInverse(mViewMatrix); lcVector3 ViewPosition = lcMul30(-mViewMatrix.GetTranslation(), InverseViewMatrix); if (Program.LightPositionLocation != -1) { lcVector3 LightPosition = ViewPosition + lcMul30(lcVector3(300.0f, 300.0f, 0.0f), InverseViewMatrix); glUniform3fv(Program.LightPositionLocation, 1, LightPosition); } if (Program.EyePositionLocation != -1) glUniform3fv(Program.EyePositionLocation, 1, ViewPosition); } glUniformMatrix4fv(Program.WorldViewProjectionMatrixLocation, 1, false, lcMul(mWorldMatrix, mViewProjectionMatrix)); mWorldMatrixDirty = false; mViewMatrixDirty = false; mProjectionMatrixDirty = false; } if (mColorDirty && Program.MaterialColorLocation != -1) { glUniform4fv(Program.MaterialColorLocation, 1, mColor); mColorDirty = false; } if (mHighlightParamsDirty && Program.HighlightParamsLocation != -1) { glUniform4fv(Program.HighlightParamsLocation, 4, mHighlightParams[0]); mHighlightParamsDirty = false; } } else { #if LC_FIXED_FUNCTION glColor4fv(mColor); if (mWorldMatrixDirty || mViewMatrixDirty) { if (mMatrixMode != GL_MODELVIEW) { glMatrixMode(GL_MODELVIEW); mMatrixMode = GL_MODELVIEW; } glLoadMatrixf(lcMul(mWorldMatrix, mViewMatrix)); mWorldMatrixDirty = false; mViewMatrixDirty = false; } if (mProjectionMatrixDirty) { if (mMatrixMode != GL_PROJECTION) { glMatrixMode(GL_PROJECTION); mMatrixMode = GL_PROJECTION; } glLoadMatrixf(mProjectionMatrix); mProjectionMatrixDirty = false; } #endif } } void lcContext::DrawPrimitives(GLenum Mode, GLint First, GLsizei Count) { FlushState(); glDrawArrays(Mode, First, Count); } void lcContext::DrawIndexedPrimitives(GLenum Mode, GLsizei Count, GLenum Type, int Offset) { FlushState(); glDrawElements(Mode, Count, Type, mIndexBufferPointer + Offset); } leocad-23.03/common/lc_context.h000066400000000000000000000147041440571307300165650ustar00rootroot00000000000000#pragma once #include "lc_array.h" #include "lc_math.h" #include "lc_colors.h" #include "lc_mesh.h" class lcVertexBuffer { public: constexpr lcVertexBuffer() : Pointer(nullptr) { } bool IsValid() const { return Pointer != nullptr; } union { GLuint Object; void* Pointer; }; }; class lcIndexBuffer { public: constexpr lcIndexBuffer() : Pointer(nullptr) { } bool IsValid() const { return Pointer != nullptr; } union { GLuint Object; void* Pointer; }; }; enum class lcMaterialType { UnlitColor, UnlitColorConditional, UnlitTextureModulate, UnlitTextureDecal, UnlitVertexColor, UnlitViewSphere, FakeLitColor, FakeLitTextureDecal, Count }; enum class lcProgramAttrib { Position, Normal, TexCoord, Color, ControlPoint1 = 0, ControlPoint2, ControlPoint3, ControlPoint4, Count }; struct lcProgram { GLuint Object; GLint WorldViewProjectionMatrixLocation; GLint WorldMatrixLocation; GLint MaterialColorLocation; GLint LightPositionLocation; GLint EyePositionLocation; GLint HighlightParamsLocation; }; enum class lcPolygonOffset { None, Opaque, Translucent }; enum class lcDepthFunction { LessEqual, Always }; struct lcVertexAttribState { GLint Size = 0; GLenum Type = 0; GLboolean Normalized = 0; bool Enabled = 0; GLsizei Stride = 0; const void* Pointer = nullptr; GLuint VertexBufferObject = 0; }; class lcContext : protected QOpenGLFunctions { public: lcContext(); ~lcContext(); lcContext(const lcContext&) = delete; lcContext(lcContext&&) = delete; lcContext& operator=(const lcContext&) = delete; lcContext& operator=(lcContext&&) = delete; static bool InitializeRenderer(); static void ShutdownRenderer(); static lcContext* GetGlobalOffscreenContext(); void CreateResources(); void DestroyResources(); void SetDefaultState(); void ClearResources(); void MakeCurrent(); void SetGLContext(QOpenGLContext* GLContext, QOpenGLWidget* Widget); void SetOffscreenContext(); void ClearColorAndDepth(const lcVector4& ClearColor); void ClearDepth(); void SetWorldMatrix(const lcMatrix44& WorldMatrix) { mWorldMatrix = WorldMatrix; mWorldMatrixDirty = true; } void SetViewMatrix(const lcMatrix44& ViewMatrix) { mViewMatrix = ViewMatrix; mViewMatrixDirty = true; mViewProjectionMatrixDirty = true; } void SetProjectionMatrix(const lcMatrix44& ProjectionMatrix) { mProjectionMatrix = ProjectionMatrix; mProjectionMatrixDirty = true; mViewProjectionMatrixDirty = true; } const lcMatrix44& GetProjectionMatrix() { return mProjectionMatrix; } void SetMaterial(lcMaterialType MaterialType); void SetViewport(int x, int y, int Width, int Height); void SetPolygonOffset(lcPolygonOffset PolygonOffset); void SetDepthWrite(bool Enable); void SetDepthFunction(lcDepthFunction DepthFunction); void EnableDepthTest(bool Enable); void EnableColorWrite(bool Enable); void EnableColorBlend(bool Enable); void EnableCullFace(bool Enable); void SetLineWidth(float LineWidth); void BindTexture2D(const lcTexture* Texture); void BindTextureCubeMap(const lcTexture* Texture); void ClearTexture2D(); void ClearTextureCubeMap(); void UploadTexture(lcTexture* Texture); void SetColor(const lcVector4& Color) { mColor = Color; mColorDirty = true; } void SetHighlightParams(const lcVector4& HighlightPosition, const lcVector4& TextColor, const lcVector4& BackgroundColor, const lcVector4& HighlightColor) { mHighlightParams[0] = HighlightPosition; mHighlightParams[1] = TextColor; mHighlightParams[2] = BackgroundColor; mHighlightParams[3] = HighlightColor; mHighlightParamsDirty = true; } void SetColor(float Red, float Green, float Blue, float Alpha); void SetColorIndex(int ColorIndex); void SetColorIndexTinted(int ColorIndex, const lcVector4& Tint, float Weight); void SetColorIndexTinted(int ColorIndex, const lcVector4& Tint); void SetEdgeColorIndex(int ColorIndex); void SetEdgeColorIndexTinted(int ColorIndex, const lcVector4& Tint); lcVertexBuffer CreateVertexBuffer(int Size, const void* Data); void DestroyVertexBuffer(lcVertexBuffer& VertexBuffer); lcIndexBuffer CreateIndexBuffer(int Size, const void* Data); void DestroyIndexBuffer(lcIndexBuffer& IndexBuffer); void ClearVertexBuffer(); void SetVertexBuffer(lcVertexBuffer VertexBuffer); void SetVertexBufferPointer(const void* VertexBuffer); void ClearIndexBuffer(); void SetIndexBuffer(lcIndexBuffer IndexBuffer); void SetIndexBufferPointer(const void* IndexBuffer); void SetVertexFormat(int BufferOffset, int PositionSize, int NormalSize, int TexCoordSize, int ColorSize, bool EnableNormals); void SetVertexFormatPosition(int PositionSize); void SetVertexFormatConditional(int BufferOffset); void DrawPrimitives(GLenum Mode, GLint First, GLsizei Count); void DrawIndexedPrimitives(GLenum Mode, GLsizei Count, GLenum Type, int Offset); void BindMesh(const lcMesh* Mesh); protected: static bool CreateOffscreenContext(); static void DestroyOffscreenContext(); void CreateShaderPrograms(); void FlushState(); void SetVertexAttribPointer(lcProgramAttrib Attrib, GLint Size, GLenum Type, GLboolean Normalized, GLsizei Stride, const void* Pointer); void EnableVertexAttrib(lcProgramAttrib Attrib); void DisableVertexAttrib(lcProgramAttrib Attrib); QOpenGLWidget* mWidget = nullptr; QOpenGLContext* mContext = nullptr; GLuint mVertexBufferObject; GLuint mIndexBufferObject; const char* mVertexBufferPointer; const char* mIndexBufferPointer; const char* mVertexBufferOffset; lcMaterialType mMaterialType; bool mNormalEnabled; bool mTexCoordEnabled; bool mColorEnabled; lcVertexAttribState mVertexAttribState[static_cast(lcProgramAttrib::Count)]; GLuint mTexture2D; GLuint mTextureCubeMap; lcPolygonOffset mPolygonOffset; bool mDepthWrite; lcDepthFunction mDepthFunction; bool mDepthTest; bool mColorWrite; bool mColorBlend; bool mCullFace; float mLineWidth; int mMatrixMode; bool mTextureEnabled; lcVector4 mColor; lcMatrix44 mWorldMatrix; lcMatrix44 mViewMatrix; lcMatrix44 mProjectionMatrix; lcMatrix44 mViewProjectionMatrix; lcVector4 mHighlightParams[4]; bool mColorDirty; bool mWorldMatrixDirty; bool mViewMatrixDirty; bool mProjectionMatrixDirty; bool mViewProjectionMatrixDirty; bool mHighlightParamsDirty; static std::unique_ptr mOffscreenContext; static std::unique_ptr mOffscreenSurface; static std::unique_ptr mGlobalOffscreenContext; static lcProgram mPrograms[static_cast(lcMaterialType::Count)]; Q_DECLARE_TR_FUNCTIONS(lcContext); }; leocad-23.03/common/lc_edgecolordialog.cpp000066400000000000000000000252671440571307300205650ustar00rootroot00000000000000#include "lc_edgecolordialog.h" #include "lc_application.h" lcAutomateEdgeColorDialog::lcAutomateEdgeColorDialog(QWidget* Parent, bool ShowHighContrastDialog) :QDialog(Parent) { const lcPreferences& Preferences = lcGetPreferences(); mStudCylinderColor = Preferences.mStudCylinderColor; mPartEdgeColor = Preferences.mPartEdgeColor; mBlackEdgeColor = Preferences.mBlackEdgeColor; mDarkEdgeColor = Preferences.mDarkEdgeColor; mPartEdgeContrast = Preferences.mPartEdgeContrast; mPartColorValueLDIndex = Preferences.mPartColorValueLDIndex; setWindowTitle(tr("Color Preferences")); QVBoxLayout* MainLayout = new QVBoxLayout(this); QGroupBox* EdgeSettingsBox = new QGroupBox(tr("Edge Colors"), this); MainLayout->addWidget(EdgeSettingsBox); QGridLayout* EdgeSettingsLayout = new QGridLayout(EdgeSettingsBox); EdgeSettingsBox->setLayout(EdgeSettingsLayout); int LDIndexRow = 0; PartEdgeContrast = nullptr; PartEdgeContrastSlider = nullptr; if (!ShowHighContrastDialog) { LDIndexRow = 1; QLabel* PartEdgeContrastLabel = new QLabel(tr("Contrast:"), this); PartEdgeContrast = new QLabel(this); PartEdgeContrastSlider = new QSlider(Qt::Horizontal, this); PartEdgeContrastSlider->setRange(0, 100); PartEdgeContrastSlider->setValue(mPartEdgeContrast * 100); PartEdgeContrastSlider->setToolTip(tr("Set the amount of contrast - 0.50 is midway.")); connect(PartEdgeContrastSlider, SIGNAL(valueChanged(int)), this, SLOT(SliderValueChanged(int))); emit PartEdgeContrastSlider->valueChanged(PartEdgeContrastSlider->value()); ResetPartEdgeContrastButton = new QToolButton(this); ResetPartEdgeContrastButton->setText(tr("Reset")); connect(ResetPartEdgeContrastButton, SIGNAL(clicked()), this, SLOT(ResetSliderButtonClicked())); EdgeSettingsLayout->addWidget(PartEdgeContrastLabel,0,0); EdgeSettingsLayout->addWidget(PartEdgeContrastSlider,0,1); EdgeSettingsLayout->addWidget(PartEdgeContrast,0,2); EdgeSettingsLayout->addWidget(ResetPartEdgeContrastButton,0,3); } QLabel* PartColorValueLDIndexLabel = new QLabel(ShowHighContrastDialog ? tr("Light/Dark Value:") : tr("Saturation:"), this); PartColorValueLDIndex = new QLabel(this); PartColorValueLDIndexSlider = new QSlider(Qt::Horizontal, this); PartColorValueLDIndexSlider->setRange(0, 100); PartColorValueLDIndexSlider->setValue(mPartColorValueLDIndex * 100); PartColorValueLDIndexSlider->setToolTip(ShowHighContrastDialog ? tr("Set to classify where color values are light or dark - e.g. Dark Bluish Gray (72) is light at 0.39.") : tr("Set to specify amount of edge color tint or shade from the saturation adjusted part color")); connect(PartColorValueLDIndexSlider, SIGNAL(valueChanged(int)), this, SLOT(SliderValueChanged(int))); emit PartColorValueLDIndexSlider->valueChanged(PartColorValueLDIndexSlider->value()); ResetPartColorValueLDIndexButton = new QToolButton(this); ResetPartColorValueLDIndexButton->setText(tr("Reset")); connect(ResetPartColorValueLDIndexButton, SIGNAL(clicked()), this, SLOT(ResetSliderButtonClicked())); EdgeSettingsLayout->addWidget(PartColorValueLDIndexLabel,LDIndexRow,0); EdgeSettingsLayout->addWidget(PartColorValueLDIndexSlider,LDIndexRow,1); EdgeSettingsLayout->addWidget(PartColorValueLDIndex,LDIndexRow,2); EdgeSettingsLayout->addWidget(ResetPartColorValueLDIndexButton,LDIndexRow,3); QGroupBox* HighContrastColorBox = new QGroupBox(tr("High Contrast"), this); HighContrastColorBox->setVisible(ShowHighContrastDialog); MainLayout->addWidget(HighContrastColorBox); QGridLayout* HighContrastColorLayout = new QGridLayout(HighContrastColorBox); HighContrastColorBox->setLayout(HighContrastColorLayout); auto SetButtonPixmap = [](quint32 Color, QToolButton* Button) { QPixmap Pixmap(12, 12); QColor ButtonColor(QColor(LC_RGBA_RED(Color), LC_RGBA_GREEN(Color), LC_RGBA_BLUE(Color))); Pixmap.fill(ButtonColor); Button->setIcon(Pixmap); Button->setToolTip(ButtonColor.name().toUpper()); }; QLabel* StudCylinderColorLabel = new QLabel(tr("Stud Cylinder Color:"), this); StudCylinderColorButton = new QToolButton(this); SetButtonPixmap(mStudCylinderColor, StudCylinderColorButton); connect(StudCylinderColorButton, SIGNAL(clicked()), this, SLOT(ColorButtonClicked())); ResetStudCylinderColorButton = new QToolButton(this); ResetStudCylinderColorButton->setText(tr("Reset"));; connect(ResetStudCylinderColorButton, SIGNAL(clicked()), this, SLOT(ResetColorButtonClicked())); HighContrastColorLayout->addWidget(StudCylinderColorLabel,0,0); HighContrastColorLayout->addWidget(StudCylinderColorButton,0,1); HighContrastColorLayout->addWidget(ResetStudCylinderColorButton,0,2); QLabel* PartEdgeColorLabel = new QLabel(tr("Parts Edge Color:"), this); PartEdgeColorButton = new QToolButton(this); SetButtonPixmap(mPartEdgeColor, PartEdgeColorButton); connect(PartEdgeColorButton, SIGNAL(clicked()), this, SLOT(ColorButtonClicked())); ResetPartEdgeColorButton = new QToolButton(this); ResetPartEdgeColorButton->setText(tr("Reset")); connect(ResetPartEdgeColorButton, SIGNAL(clicked()), this, SLOT(ResetColorButtonClicked())); HighContrastColorLayout->addWidget(PartEdgeColorLabel,1,0); HighContrastColorLayout->addWidget(PartEdgeColorButton,1,1); HighContrastColorLayout->addWidget(ResetPartEdgeColorButton,1,2); QLabel* BlackEdgeColorLabel = new QLabel(tr("Black Parts Edge Color:"), this); BlackEdgeColorButton = new QToolButton(this); SetButtonPixmap(mBlackEdgeColor, BlackEdgeColorButton); connect(BlackEdgeColorButton, SIGNAL(clicked()), this, SLOT(ColorButtonClicked())); ResetBlackEdgeColorButton = new QToolButton(this); ResetBlackEdgeColorButton->setText(tr("Reset")); connect(ResetBlackEdgeColorButton, SIGNAL(clicked()), this, SLOT(ResetColorButtonClicked())); HighContrastColorLayout->addWidget(BlackEdgeColorLabel,2,0); HighContrastColorLayout->addWidget(BlackEdgeColorButton,2,1); HighContrastColorLayout->addWidget(ResetBlackEdgeColorButton,2,2); QLabel* DarkEdgeColorLabel = new QLabel(tr("Dark Parts Edge Color:"), this); DarkEdgeColorButton = new QToolButton(this); SetButtonPixmap(mDarkEdgeColor, DarkEdgeColorButton); connect(DarkEdgeColorButton, SIGNAL(clicked()), this, SLOT(ColorButtonClicked())); ResetDarkEdgeColorButton = new QToolButton(this); ResetDarkEdgeColorButton->setText(tr("Reset")); connect(ResetDarkEdgeColorButton, SIGNAL(clicked()), this, SLOT(ResetColorButtonClicked())); HighContrastColorLayout->addWidget(DarkEdgeColorLabel,3,0); HighContrastColorLayout->addWidget(DarkEdgeColorButton,3,1); HighContrastColorLayout->addWidget(ResetDarkEdgeColorButton,3,2); QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); MainLayout->addWidget(buttonBox); QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); setMinimumSize(220,100); } void lcAutomateEdgeColorDialog::SliderValueChanged(int Value) { if (sender() == PartEdgeContrastSlider) { mPartEdgeContrast = Value * 0.01f; PartEdgeContrast->setText(QString::number(mPartEdgeContrast, 'f', 2)); } else if (sender() == PartColorValueLDIndexSlider) { mPartColorValueLDIndex = Value * 0.01f; PartColorValueLDIndex->setText(QString::number(mPartColorValueLDIndex, 'f', 2)); } } void lcAutomateEdgeColorDialog::ColorButtonClicked() { QObject* Button = sender(); QString Title; quint32* Color = nullptr; QColorDialog::ColorDialogOptions DialogOptions; if (Button == StudCylinderColorButton) { Title = tr("Select Stud Cylinder Color"); Color = &mStudCylinderColor; } else if (Button == PartEdgeColorButton) { Title = tr("Select Part Edge Color"); Color = &mPartEdgeColor; } else if (Button == BlackEdgeColorButton) { if (lcGetPreferences().mAutomateEdgeColor) { QMessageBox msgBox; msgBox.setText(tr("Automate edge color appears to be enabled.
Black parts edge color will not be accessible.
Do you want to continue?")); if (msgBox.exec() != QMessageBox::Accepted) return; } Title = tr("Select Black Edge Color"); Color = &mBlackEdgeColor; } else if (Button == DarkEdgeColorButton) { if (lcGetPreferences().mAutomateEdgeColor) { QMessageBox msgBox; msgBox.setText(tr("Automate edge color appears to be enabled.
Dark parts edge color will not be accessible.
Do you want to continue?")); if (msgBox.exec() != QMessageBox::Accepted) return; } Title = tr("Select Dark Edge Color"); Color = &mDarkEdgeColor; } else return; QColor OldColor = QColor(LC_RGBA_RED(*Color), LC_RGBA_GREEN(*Color), LC_RGBA_BLUE(*Color), LC_RGBA_ALPHA(*Color)); QColor NewColor = QColorDialog::getColor(OldColor, this, Title, DialogOptions); if (NewColor == OldColor || !NewColor.isValid()) return; *Color = LC_RGBA(NewColor.red(), NewColor.green(), NewColor.blue(), NewColor.alpha()); QPixmap Pix(12, 12); NewColor.setAlpha(255); Pix.fill(NewColor); ((QToolButton*)Button)->setIcon(Pix); ((QToolButton*)Button)->setToolTip(NewColor.name().toUpper()); } void lcAutomateEdgeColorDialog::ResetSliderButtonClicked() { if (sender() == ResetPartEdgeContrastButton) { PartEdgeContrastSlider->setValue(0.5f * 100); } else if (sender() == ResetPartColorValueLDIndexButton) { PartColorValueLDIndexSlider->setValue(0.5f * 100); } } void lcAutomateEdgeColorDialog::ResetColorButtonClicked() { quint32* Color = nullptr; QPixmap Pix(12, 12); QColor ResetColor; if (sender() == ResetStudCylinderColorButton) { Color = &mStudCylinderColor; *Color = LC_RGBA(27, 42, 52, 255); ResetColor = QColor(LC_RGBA_RED(*Color), LC_RGBA_GREEN(*Color), LC_RGBA_BLUE(*Color), LC_RGBA_ALPHA(*Color)); Pix.fill(ResetColor); StudCylinderColorButton->setIcon(Pix); StudCylinderColorButton->setToolTip(ResetColor.name().toUpper()); } else if (sender() == ResetPartEdgeColorButton) { Color = &mPartEdgeColor; *Color = LC_RGBA(0, 0, 0, 255); ResetColor = QColor(LC_RGBA_RED(*Color), LC_RGBA_GREEN(*Color), LC_RGBA_BLUE(*Color), LC_RGBA_ALPHA(*Color)); Pix.fill(ResetColor); PartEdgeColorButton->setIcon(Pix); PartEdgeColorButton->setToolTip(ResetColor.name().toUpper()); } else if (sender() == ResetBlackEdgeColorButton) { Color = &mBlackEdgeColor; *Color = LC_RGBA(255, 255, 255, 255); ResetColor = QColor(LC_RGBA_RED(*Color), LC_RGBA_GREEN(*Color), LC_RGBA_BLUE(*Color), LC_RGBA_ALPHA(*Color)); Pix.fill(ResetColor); BlackEdgeColorButton->setIcon(Pix); BlackEdgeColorButton->setToolTip(ResetColor.name().toUpper()); } else if (sender() == ResetDarkEdgeColorButton) { Color = &mDarkEdgeColor; *Color = LC_RGBA(27, 42, 52, 255); ResetColor = QColor(LC_RGBA_RED(*Color), LC_RGBA_GREEN(*Color), LC_RGBA_BLUE(*Color), LC_RGBA_ALPHA(*Color)); Pix.fill(ResetColor); DarkEdgeColorButton->setIcon(Pix); DarkEdgeColorButton->setToolTip(ResetColor.name().toUpper()); } } leocad-23.03/common/lc_edgecolordialog.h000066400000000000000000000020161440571307300202150ustar00rootroot00000000000000#pragma once #include class lcAutomateEdgeColorDialog : public QDialog { Q_OBJECT public: lcAutomateEdgeColorDialog(QWidget *Parent, bool ShowHighContrastDialog); quint32 mStudCylinderColor; quint32 mPartEdgeColor; quint32 mDarkEdgeColor; quint32 mBlackEdgeColor; float mPartEdgeContrast; float mPartColorValueLDIndex; protected slots: void SliderValueChanged(int); void ResetSliderButtonClicked(); void ColorButtonClicked(); void ResetColorButtonClicked(); protected: QSlider* PartColorValueLDIndexSlider; QSlider* PartEdgeContrastSlider; QLabel* PartEdgeContrast; QLabel* PartColorValueLDIndex; QToolButton* ResetPartEdgeContrastButton; QToolButton* ResetPartColorValueLDIndexButton; QToolButton* StudCylinderColorButton; QToolButton* PartEdgeColorButton; QToolButton* BlackEdgeColorButton; QToolButton* DarkEdgeColorButton; QToolButton* ResetStudCylinderColorButton; QToolButton* ResetPartEdgeColorButton; QToolButton* ResetBlackEdgeColorButton; QToolButton* ResetDarkEdgeColorButton; }; leocad-23.03/common/lc_file.cpp000066400000000000000000000045171440571307300163540ustar00rootroot00000000000000#include "lc_global.h" #include #include #include #include #include "lc_file.h" lcMemFile::lcMemFile() { mGrowBytes = 1024; mPosition = 0; mBufferSize = 0; mFileSize = 0; mBuffer = nullptr; } lcMemFile::~lcMemFile() { Close(); } void lcMemFile::Seek(qint64 Offset, int From) { if (From == SEEK_SET) mPosition = Offset; else if (From == SEEK_CUR) mPosition += Offset; else if (From == SEEK_END) mPosition = mFileSize + Offset; } long lcMemFile::GetPosition() const { return (long)mPosition; } void lcMemFile::SetLength(size_t NewLength) { if (NewLength > mBufferSize) GrowFile(NewLength); if (NewLength < mPosition) mPosition = NewLength; mFileSize = NewLength; } size_t lcMemFile::GetLength() const { return mFileSize; } void lcMemFile::Close() { if (!mBuffer) return; mPosition = 0; mBufferSize = 0; mFileSize = 0; free(mBuffer); mBuffer = nullptr; } size_t lcMemFile::ReadBuffer(void* Buffer, size_t Bytes) { if (Bytes == 0 || mPosition > mFileSize) return 0; size_t BytesToRead; if (mPosition + Bytes > mFileSize) BytesToRead = mFileSize - mPosition; else BytesToRead = Bytes; memcpy(Buffer, mBuffer + mPosition, BytesToRead); mPosition += BytesToRead; return BytesToRead; } size_t lcMemFile::WriteBuffer(const void* Buffer, size_t Bytes) { if (Bytes == 0) return 0; if (mPosition + Bytes > mBufferSize) GrowFile(mPosition + Bytes); memcpy(mBuffer + mPosition, Buffer, Bytes); mPosition += Bytes; if (mPosition > mFileSize) mFileSize = mPosition; return Bytes; } void lcMemFile::GrowFile(size_t NewLength) { if (NewLength <= mBufferSize) return; NewLength = ((NewLength + mGrowBytes - 1) / mGrowBytes) * mGrowBytes; if (mBuffer) { unsigned char* NewBuffer = (unsigned char*)realloc(mBuffer, NewLength); if (!NewBuffer) return; mBuffer = NewBuffer; } else mBuffer = (unsigned char*)malloc(NewLength); mBufferSize = NewLength; } char* lcMemFile::ReadLine(char* Buffer, size_t BufferSize) { int BytesRead = 0; unsigned char ch; if (BufferSize == 0) return nullptr; if (mPosition >= mFileSize) return nullptr; while ((--BufferSize)) { if (mPosition == mFileSize) break; ch = mBuffer[mPosition]; mPosition++; Buffer[BytesRead++] = ch; if (ch == '\n') break; } Buffer[BytesRead] = 0; return Buffer; } leocad-23.03/common/lc_file.h000066400000000000000000000230301440571307300160100ustar00rootroot00000000000000#pragma once #include #include #include "lc_math.h" #define LC_FOURCC(ch0, ch1, ch2, ch3) (quint32)((quint32)(quint8)(ch0) | ((quint32)(quint8)(ch1) << 8) | \ ((quint32)(quint8)(ch2) << 16) | ((quint32)(quint8)(ch3) << 24 )) class lcFile { public: lcFile() { } virtual ~lcFile() { } lcFile(const lcFile&) = delete; lcFile(lcFile&&) = delete; lcFile& operator=(const lcFile&) = delete; lcFile& operator=(lcFile&&) = delete; virtual long GetPosition() const = 0; virtual void Seek(qint64 Offset, int From) = 0; virtual size_t GetLength() const = 0; virtual void Close() = 0; virtual char* ReadLine(char* Buffer, size_t BufferSize) = 0; void WriteLine(const char* Buffer) { WriteBuffer(Buffer, strlen(Buffer)); } virtual size_t ReadBuffer(void* Buffer, size_t Bytes) = 0; virtual size_t WriteBuffer(const void* Buffer, size_t Bytes) = 0; quint8 ReadU8() { quint8 Value; Read8(&Value, 1); return Value; } size_t ReadU8(quint8* Buffer, size_t Count) { return Read8(Buffer, Count); } qint8 ReadS8() { qint8 Value; Read8(&Value, 1); return Value; } size_t ReadS8(qint8* Buffer, size_t Count) { return Read8(Buffer, Count); } quint16 ReadU16() { quint16 Value; Read16(&Value, 1); return Value; } size_t ReadU16(quint16* Buffer, size_t Count) { return Read16(Buffer, Count); } qint16 ReadS16() { qint16 Value; Read16(&Value, 1); return Value; } size_t ReadS16(qint16* Buffer, size_t Count) { return Read16(Buffer, Count); } quint32 ReadU32() { quint32 Value; Read32(&Value, 1); return Value; } size_t ReadU32(quint32* Buffer, size_t Count) { return Read32(Buffer, Count); } qint32 ReadS32() { qint32 Value; Read32(&Value, 1); return Value; } size_t ReadS32(qint32* Buffer, size_t Count) { return Read32(Buffer, Count); } quint64 ReadU64() { quint64 Value; Read64(&Value, 1); return Value; } size_t ReadU64(quint64* Buffer, size_t Count) { return Read64(Buffer, Count); } qint64 ReadS64() { qint64 Value; Read64(&Value, 1); return Value; } size_t ReadS64(qint64* Buffer, size_t Count) { return Read64(Buffer, Count); } float ReadFloat() { float Value; Read32(&Value, 1); return Value; } size_t ReadFloats(float* Buffer, size_t Count) { return Read32(Buffer, Count); } double ReadDouble() { double Value; Read64(&Value, 1); return Value; } lcVector3 ReadVector3() { lcVector3 Vector; ReadFloats(Vector, 3); return Vector; } size_t ReadDoubles(double* Buffer, size_t Count) { return Read64(Buffer, Count); } QString ReadQString() { const quint32 Size = ReadU32(); char* Buffer = new char[Size]; ReadBuffer(Buffer, Size); QString String = QString::fromUtf8(Buffer, Size); delete[] Buffer; return String; } void WriteU8(const quint8& Value) { Write8(&Value, 1); } size_t WriteU8(const quint8* Buffer, size_t Count) { return Write8(Buffer, Count); } void WriteS8(const qint8& Value) { Write8(&Value, 1); } size_t WriteS8(const qint8* Buffer, size_t Count) { return Write8(Buffer, Count); } void WriteU16(const quint16& Value) { Write16(&Value, 1); } size_t WriteU16(const quint16* Buffer, size_t Count) { return Write16(Buffer, Count); } void WriteS16(const qint16& Value) { Write16(&Value, 1); } size_t WriteS16(const qint16* Buffer, size_t Count) { return Write16(Buffer, Count); } void WriteU32(const quint32& Value) { Write32(&Value, 1); } size_t WriteU32(const quint32* Buffer, size_t Count) { return Write32(Buffer, Count); } void WriteS32(const qint32& Value) { Write32(&Value, 1); } size_t WriteS32(const qint32* Buffer, size_t Count) { return Write32(Buffer, Count); } void WriteU64(const quint64& Value) { Write64(&Value, 1); } size_t WriteU64(const quint64* Buffer, size_t Count) { return Write64(Buffer, Count); } void WriteS64(const qint64& Value) { Write64(&Value, 1); } size_t WriteS64(const qint64* Buffer, size_t Count) { return Write64(Buffer, Count); } void WriteFloat(const float& Value) { Write32(&Value, 1); } size_t WriteFloats(const float* Buffer, size_t Count) { return Write32(Buffer, Count); } void WriteDouble(const double& Value) { Write64(&Value, 1); } size_t WriteDoubles(const double* Buffer, size_t Count) { return Write64(Buffer, Count); } void WriteVector3(const lcVector3& Vector) { WriteFloats(Vector, 3); } void WriteQString(const QString& String) { QByteArray Data = String.toUtf8(); WriteU32(Data.size()); WriteBuffer(Data, Data.size()); } protected: size_t Read8(void* Buffer, size_t Count) { return ReadBuffer(Buffer, Count); } size_t Read16(void* Buffer, size_t Count) { size_t NumRead; NumRead = ReadBuffer(Buffer, Count * 2) / 2; #if Q_BYTE_ORDER == Q_BIG_ENDIAN quint8 Temp[2]; quint8* Bytes = (quint8*)Buffer; for (size_t Idx = 0; Idx < NumRead; Idx++) { Temp[0] = Bytes[0]; Temp[1] = Bytes[1]; *Bytes++ = Temp[1]; *Bytes++ = Temp[0]; } #endif return NumRead; } size_t Read32(void* Buffer, size_t Count) { size_t NumRead; NumRead = ReadBuffer(Buffer, Count * 4) / 4; #if Q_BYTE_ORDER == Q_BIG_ENDIAN quint8 Temp[4]; quint8* Bytes = (quint8*)Buffer; for (size_t Idx = 0; Idx < NumRead; Idx++) { Temp[0] = Bytes[0]; Temp[1] = Bytes[1]; Temp[2] = Bytes[2]; Temp[3] = Bytes[3]; *Bytes++ = Temp[3]; *Bytes++ = Temp[2]; *Bytes++ = Temp[1]; *Bytes++ = Temp[0]; } #endif return NumRead; } size_t Read64(void* Buffer, size_t Count) { size_t NumRead; NumRead = ReadBuffer(Buffer, Count * 8) / 8; #if Q_BYTE_ORDER == Q_BIG_ENDIAN quint8 Temp[8]; quint8* Bytes = (quint8*)Buffer; for (size_t Idx = 0; Idx < NumRead; Idx++) { Temp[0] = Bytes[0]; Temp[1] = Bytes[1]; Temp[2] = Bytes[2]; Temp[3] = Bytes[3]; Temp[4] = Bytes[4]; Temp[5] = Bytes[5]; Temp[6] = Bytes[6]; Temp[7] = Bytes[7]; *Bytes++ = Temp[7]; *Bytes++ = Temp[6]; *Bytes++ = Temp[5]; *Bytes++ = Temp[4]; *Bytes++ = Temp[3]; *Bytes++ = Temp[2]; *Bytes++ = Temp[1]; *Bytes++ = Temp[0]; } #endif return NumRead; } size_t Write8(const void* Buffer, size_t Count) { return WriteBuffer(Buffer, Count); } size_t Write16(const void* Buffer, size_t Count) { #if Q_BYTE_ORDER == Q_BIG_ENDIAN size_t BytesWritten = 0; quint8 Temp[2]; quint8* Bytes = (quint8*)Buffer; for (size_t Idx = 0; Idx < Count; Idx++) { Temp[1] = *Bytes++; Temp[0] = *Bytes++; BytesWritten += WriteBuffer(Temp, 2); } return BytesWritten / 2; #else return WriteBuffer(Buffer, Count * 2) / 2; #endif } size_t Write32(const void* Buffer, size_t Count) { #if Q_BYTE_ORDER == Q_BIG_ENDIAN size_t BytesWritten = 0; quint8 Temp[4]; quint8* Bytes = (quint8*)Buffer; for (size_t Idx = 0; Idx < Count; Idx++) { Temp[3] = *Bytes++; Temp[2] = *Bytes++; Temp[1] = *Bytes++; Temp[0] = *Bytes++; BytesWritten += WriteBuffer(Temp, 4); } return BytesWritten / 4; #else return WriteBuffer(Buffer, Count * 4); #endif } size_t Write64(const void* Buffer, size_t Count) { #if Q_BYTE_ORDER == Q_BIG_ENDIAN size_t BytesWritten = 0; quint8 Temp[8]; quint8* Bytes = (quint8*)Buffer; for (size_t Idx = 0; Idx < Count; Idx++) { Temp[7] = *Bytes++; Temp[6] = *Bytes++; Temp[5] = *Bytes++; Temp[4] = *Bytes++; Temp[3] = *Bytes++; Temp[2] = *Bytes++; Temp[1] = *Bytes++; Temp[0] = *Bytes++; BytesWritten += WriteBuffer(Temp, 8); } return BytesWritten / 8; #else return WriteBuffer(Buffer, Count * 8); #endif } }; class lcMemFile : public lcFile { public: lcMemFile(); ~lcMemFile(); lcMemFile(const lcMemFile&) = delete; lcMemFile(lcMemFile&&) = delete; lcMemFile& operator=(const lcMemFile&) = delete; lcMemFile& operator=(lcMemFile&&) = delete; long GetPosition() const override; void Seek(qint64 Offset, int From) override; void SetLength(size_t NewLength); size_t GetLength() const override; void Close() override; char* ReadLine(char* Buffer, size_t BufferSize) override; size_t ReadBuffer(void* Buffer, size_t Bytes) override; size_t WriteBuffer(const void* Buffer, size_t Bytes) override; void GrowFile(size_t NewLength); size_t mGrowBytes; size_t mPosition; size_t mBufferSize; size_t mFileSize; unsigned char* mBuffer; }; class lcDiskFile : public lcFile { public: lcDiskFile() { } lcDiskFile(const QString& FileName) : mFile(FileName) { } ~lcDiskFile() { Close(); } lcDiskFile(const lcDiskFile&) = delete; lcDiskFile(lcDiskFile&&) = delete; lcDiskFile& operator=(const lcDiskFile&) = delete; lcDiskFile& operator=(lcDiskFile&&) = delete; void SetFileName(const QString& FileName) { mFile.setFileName(FileName); } long GetPosition() const override { return mFile.pos(); } void Seek(qint64 Offset, int From) override { switch (From) { case SEEK_CUR: Offset += mFile.pos(); break; case SEEK_END: Offset += mFile.size(); break; } mFile.seek(Offset); } size_t GetLength() const override { return mFile.size(); } void Close() override { mFile.close(); } char* ReadLine(char* Buffer, size_t BufferSize) override { const qint64 LineLength = mFile.readLine(Buffer, BufferSize); return LineLength != -1 ? Buffer : nullptr; } size_t ReadBuffer(void* Buffer, size_t Bytes) override { return mFile.read((char*)Buffer, Bytes); } size_t WriteBuffer(const void* Buffer, size_t Bytes) override { return mFile.write((const char*)Buffer, Bytes); } bool Open(QIODevice::OpenMode Flags) { return mFile.open(Flags); } protected: QFile mFile; }; leocad-23.03/common/lc_findreplacewidget.cpp000066400000000000000000000131021440571307300211030ustar00rootroot00000000000000#include "lc_global.h" #include "lc_findreplacewidget.h" #include "lc_qcolorpicker.h" #include "lc_library.h" #include "lc_mainwindow.h" #include "pieceinf.h" #include "piece.h" #include "lc_model.h" #include "lc_view.h" lcFindReplaceWidget::lcFindReplaceWidget(QWidget* Parent, lcModel* Model, bool Replace) : QWidget(Parent) { setAutoFillBackground(true); QPalette Palette = palette(); Palette.setColor(QPalette::Window, QApplication::palette().color(QPalette::Button)); setPalette(Palette); QGridLayout* Layout = new QGridLayout(this); Layout->setContentsMargins(5, 5, 5, 5); Layout->addWidget(new QLabel(tr("Find:")), 0, 0); lcQColorPicker* FindColorPicker = new lcQColorPicker(this, true); Layout->addWidget(FindColorPicker, 0, 1); mFindPartComboBox = new QComboBox(this); mFindPartComboBox->setEditable(true); mFindPartComboBox->setInsertPolicy(QComboBox::NoInsert); Layout->addWidget(mFindPartComboBox, 0, 2); QToolButton* FindNextButton = new QToolButton(this); FindNextButton->setAutoRaise(true); FindNextButton->setDefaultAction(gMainWindow->mActions[LC_EDIT_FIND_NEXT]); Layout->addWidget(FindNextButton, 0, 3); QToolButton* FindAllButton = new QToolButton(this); FindAllButton ->setAutoRaise(true); FindAllButton ->setDefaultAction(gMainWindow->mActions[LC_EDIT_FIND_ALL]); Layout->addWidget(FindAllButton, 0, 4); connect(FindColorPicker, &lcQColorPicker::colorChanged, this, &lcFindReplaceWidget::FindColorIndexChanged); connect(mFindPartComboBox->lineEdit(), &QLineEdit::returnPressed, gMainWindow->mActions[LC_EDIT_FIND_NEXT], &QAction::trigger); connect(mFindPartComboBox->lineEdit(), &QLineEdit::textEdited, this, &lcFindReplaceWidget::FindTextEdited); connect(mFindPartComboBox, static_cast(&QComboBox::activated), this, &lcFindReplaceWidget::FindActivated); lcQColorPicker* ReplaceColorPicker = nullptr; if (Replace) { Layout->addWidget(new QLabel(tr("Replace:")), 1, 0); ReplaceColorPicker = new lcQColorPicker(this, true); Layout->addWidget(ReplaceColorPicker, 1, 1); mReplacePartComboBox = new QComboBox(this); Layout->addWidget(mReplacePartComboBox, 1, 2); QToolButton* ReplaceNextButton = new QToolButton(this); ReplaceNextButton->setAutoRaise(true); ReplaceNextButton->setDefaultAction(gMainWindow->mActions[LC_EDIT_REPLACE_NEXT]); Layout->addWidget(ReplaceNextButton, 1, 3); QToolButton* ReplaceAllButton = new QToolButton(this); ReplaceAllButton->setAutoRaise(true); ReplaceAllButton->setDefaultAction(gMainWindow->mActions[LC_EDIT_REPLACE_ALL]); Layout->addWidget(ReplaceAllButton, 1, 4); connect(ReplaceColorPicker, &lcQColorPicker::colorChanged, this, &lcFindReplaceWidget::ReplaceColorIndexChanged); connect(mReplacePartComboBox, static_cast(&QComboBox::activated), this, &lcFindReplaceWidget::ReplaceActivated); mReplacePartComboBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); mReplacePartComboBox->setMinimumContentsLength(1); lcPiecesLibrary* Library = lcGetPiecesLibrary(); std::vector SortedPieces; SortedPieces.reserve(Library->mPieces.size()); for (const auto& PartIt : Library->mPieces) SortedPieces.push_back(PartIt.second); auto PieceCompare = [](PieceInfo* Info1, PieceInfo* Info2) { return strcmp(Info1->m_strDescription, Info2->m_strDescription) < 0; }; std::sort(SortedPieces.begin(), SortedPieces.end(), PieceCompare); mReplacePartComboBox->addItem(QString(), QVariant::fromValue((void*)nullptr)); for (PieceInfo* Info : SortedPieces) mReplacePartComboBox->addItem(QString::fromLatin1(Info->m_strDescription), QVariant::fromValue((void*)Info)); ReplaceColorPicker->setCurrentColor(lcGetColorIndex(LC_COLOR_NOCOLOR)); mReplacePartComboBox->setCurrentIndex(0); } lcPartsList PartsList; Model->GetPartsList(gDefaultColor, false, true, PartsList); for (const auto& PartIt : PartsList) mFindPartComboBox->addItem(QString::fromLatin1(PartIt.first->m_strDescription), QVariant::fromValue((void*)PartIt.first)); mFindPartComboBox->model()->sort(0); lcPiece* Focus = dynamic_cast(Model->GetFocusObject()); if (Focus) { lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); Params.FindInfo = Focus->mPieceInfo; Params.FindColorIndex = Focus->GetColorIndex(); FindColorPicker->setCurrentColor(Params.FindColorIndex); mFindPartComboBox->setCurrentIndex(mFindPartComboBox->findData(QVariant::fromValue((void*)Params.FindInfo))); } else { FindColorPicker->setCurrentColor(lcGetColorIndex(LC_COLOR_NOCOLOR)); mFindPartComboBox->setEditText(QString()); } mFindPartComboBox->setFocus(); adjustSize(); move(1, 1); show(); } void lcFindReplaceWidget::FindColorIndexChanged(int ColorIndex) { lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); Params.FindColorIndex = ColorIndex; } void lcFindReplaceWidget::FindTextEdited(const QString& Text) { lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); Params.FindString = Text; Params.FindInfo = nullptr; } void lcFindReplaceWidget::FindActivated(int Index) { lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); Params.FindString.clear(); Params.FindInfo = (PieceInfo*)mFindPartComboBox->itemData(Index).value(); } void lcFindReplaceWidget::ReplaceColorIndexChanged(int ColorIndex) { lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); Params.ReplaceColorIndex = ColorIndex; } void lcFindReplaceWidget::ReplaceActivated(int Index) { lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); Params.ReplacePieceInfo = (PieceInfo*)mReplacePartComboBox->itemData(Index).value(); } leocad-23.03/common/lc_findreplacewidget.h000066400000000000000000000007241440571307300205560ustar00rootroot00000000000000#pragma once class lcFindReplaceWidget : public QWidget { Q_OBJECT public: lcFindReplaceWidget(QWidget* Parent, lcModel* Model, bool Replace); protected slots: void FindColorIndexChanged(int ColorIndex); void FindTextEdited(const QString& Text); void FindActivated(int Index); void ReplaceColorIndexChanged(int ColorIndex); void ReplaceActivated(int Index); protected: QComboBox* mFindPartComboBox = nullptr; QComboBox* mReplacePartComboBox = nullptr; }; leocad-23.03/common/lc_glextensions.cpp000066400000000000000000000033751440571307300201600ustar00rootroot00000000000000#include "lc_global.h" #include "lc_glextensions.h" #include bool gSupportsShaderObjects; bool gSupportsVertexBufferObject; bool gSupportsFramebufferObject; bool gSupportsBlendFuncSeparate; bool gSupportsAnisotropic; GLfloat gMaxAnisotropy; #if !defined(QT_NO_DEBUG) && defined(GL_ARB_debug_output) static void APIENTRY lcGLDebugCallback(GLenum Source, GLenum Type, GLuint Id, GLenum Severity, GLsizei Length, const GLchar* Message, GLvoid* UserParam) { Q_UNUSED(Source); Q_UNUSED(Type); Q_UNUSED(Id); Q_UNUSED(Severity); Q_UNUSED(Length); Q_UNUSED(UserParam); qDebug() << Message; } #endif void lcInitializeGLExtensions(const QOpenGLContext* Context) { const QOpenGLFunctions* Functions = Context->functions(); #if !defined(QT_NO_DEBUG) && defined(GL_ARB_debug_output) if (Context->hasExtension("GL_KHR_debug")) { PFNGLDEBUGMESSAGECALLBACKARBPROC DebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKARBPROC)Context->getProcAddress("glDebugMessageCallback"); #ifndef GL_DEBUG_OUTPUT #define GL_DEBUG_OUTPUT 0x92E0 #endif if (DebugMessageCallback) { DebugMessageCallback((GLDEBUGPROCARB)&lcGLDebugCallback, nullptr); glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } } #endif if (Context->hasExtension("GL_EXT_texture_filter_anisotropic")) { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gMaxAnisotropy); gSupportsAnisotropic = true; } gSupportsVertexBufferObject = Functions->hasOpenGLFeature(QOpenGLFunctions::Buffers); gSupportsFramebufferObject = Functions->hasOpenGLFeature(QOpenGLFunctions::Framebuffers); gSupportsBlendFuncSeparate = Functions->hasOpenGLFeature(QOpenGLFunctions::BlendFuncSeparate); gSupportsShaderObjects = Functions->hasOpenGLFeature(QOpenGLFunctions::Shaders); } leocad-23.03/common/lc_glextensions.h000066400000000000000000000004531440571307300176170ustar00rootroot00000000000000#pragma once void lcInitializeGLExtensions(const QOpenGLContext* Context); extern bool gSupportsShaderObjects; extern bool gSupportsVertexBufferObject; extern bool gSupportsFramebufferObject; extern bool gSupportsBlendFuncSeparate; extern bool gSupportsAnisotropic; extern GLfloat gMaxAnisotropy; leocad-23.03/common/lc_global.cpp000066400000000000000000000000361440571307300166650ustar00rootroot00000000000000#include "common/lc_global.h" leocad-23.03/common/lc_global.h000066400000000000000000000053221440571307300163350ustar00rootroot00000000000000#ifndef LC_GLOBAL_H #define LC_GLOBAL_H #ifdef __cplusplus #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if _MSC_VER #pragma warning(default : 4062) // enumerator 'identifier' in switch of enum 'enumeration' is not handled #pragma warning(default : 4388) // 'token' : signed/unsigned mismatch #pragma warning(default : 4389) // 'equality-operator' : signed/unsigned mismatch #pragma warning(default : 5038) // data member 'A::y' will be initialized after data member 'A::x' #endif #ifndef Q_FALLTHROUGH #define Q_FALLTHROUGH(); #endif #ifndef QT_STRINGIFY #define QT_STRINGIFY2(x) #x #define QT_STRINGIFY(x) QT_STRINGIFY2(x) #endif #define LC_ARRAY_COUNT(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) #define LC_ARRAY_SIZE_CHECK(a,s) static_assert(LC_ARRAY_COUNT(a) == static_cast(s), QT_STRINGIFY(a) " size mismatch.") #if !defined(EGL_VERSION_1_0) && !defined(GL_ES_VERSION_2_0) && !defined(GL_ES_VERSION_3_0) && !defined(QT_OPENGL_ES) #ifdef Q_OS_MACOS #define LC_FIXED_FUNCTION 0 #else #define LC_FIXED_FUNCTION 1 #endif #else #define LC_OPENGLES 1 #define LC_FIXED_FUNCTION 0 #endif // Old defines and declarations. #define LC_MAXPATH 1024 #define LC_MAXNAME 1000 typedef quint32 lcStep; #define LC_STEP_MAX 0xffffffff #ifdef Q_OS_WIN char* strcasestr(const char *s, const char *find); #else char* strupr(char* string); #endif // Version number. #define LC_VERSION_MAJOR 23 #define LC_VERSION_MINOR 03 #define LC_VERSION_PATCH 0 #define LC_VERSION_TEXT "23.03" // Forward declarations. class Project; class lcModel; class lcObject; class lcPiece; class lcCamera; class lcLight; class lcGroup; class PieceInfo; typedef std::map> lcPartsList; struct lcModelPartsEntry; struct lcMinifig; enum class lcViewpoint; enum class lcShadingMode; enum class lcStudStyle; class lcInstructions; struct lcInstructionsPageSetup; struct lcObjectRayTest; struct lcObjectBoxTest; class lcVector2; class lcVector3; class lcVector4; class lcMatrix33; class lcMatrix44; class lcFindReplaceWidget; struct lcFindReplaceParams; class lcCollapsibleWidget; class lcViewWidget; class lcView; class lcContext; class lcMesh; struct lcMeshSection; struct lcRenderMesh; struct lcObjectSection; struct lcPieceInfoRayTest; class lcTexture; class lcScene; class lcViewManipulator; class lcViewSphere; enum class lcRenderMeshState : int; enum class lcTrackTool; enum class lcTrackButton; class lcFile; class lcMemFile; class lcDiskFile; #endif #endif // LC_GLOBAL_H leocad-23.03/common/lc_http.cpp000066400000000000000000000032311440571307300164040ustar00rootroot00000000000000#include "lc_global.h" #include "lc_http.h" #ifdef Q_OS_WIN #include lcHttpReply::lcHttpReply(QObject* Parent, const QString& URL) : QThread(Parent) { mError = true; mAbort = false; mURL = URL; } void lcHttpReply::run() { HINTERNET Session = nullptr; HINTERNET Request = nullptr; static_assert(sizeof(wchar_t) == sizeof(QChar), "Character size mismatch"); Session = InternetOpen(L"LeoCAD", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (!Session) return; Request = InternetOpenUrl(Session, (WCHAR*)mURL.data(), NULL, 0, 0, 0); if (!Request) { InternetCloseHandle(Session); return; } for (;;) { char Buffer[1024]; DWORD BytesRead; if (mAbort) break; if (!InternetReadFile(Request, Buffer, sizeof(Buffer), &BytesRead)) break; if (BytesRead) mBuffer.append(Buffer, BytesRead); else { mError = false; break; } Sleep(0); } InternetCloseHandle(Request); InternetCloseHandle(Session); } lcHttpManager::lcHttpManager(QObject* Owner) : QObject(Owner) { } lcHttpReply* lcHttpManager::DownloadFile(const QString& Url) { lcHttpReply* Reply = new lcHttpReply(this, Url); connect(Reply, &QThread::finished, [this, Reply] { emit DownloadFinished(Reply); }); Reply->start(); return Reply; } #else lcHttpManager::lcHttpManager(QObject* Owner) : QNetworkAccessManager(Owner) { connect(this, SIGNAL(finished(QNetworkReply*)), this, SLOT(Finished(QNetworkReply*))); } lcHttpReply* lcHttpManager::lcHttpManager::DownloadFile(const QString& Url) { return (lcHttpReply*)get(QNetworkRequest(QUrl(Url))); } void lcHttpManager::Finished(QNetworkReply* Reply) { emit DownloadFinished((lcHttpReply*)Reply); } #endif leocad-23.03/common/lc_http.h000066400000000000000000000020271440571307300160530ustar00rootroot00000000000000#pragma once #include #include #ifdef Q_OS_WIN class lcHttpReply : public QThread { Q_OBJECT public: lcHttpReply(QObject* Parent, const QString& URL); void run() override; bool error() const { return mError; } void abort() { mAbort = true; } QByteArray readAll() const { return mBuffer; } protected: bool mError; bool mAbort; QByteArray mBuffer; QString mURL; }; class lcHttpManager : public QObject { Q_OBJECT public: lcHttpManager(QObject* Owner = nullptr); lcHttpReply* DownloadFile(const QString& Url); signals: void DownloadFinished(lcHttpReply* Reply); }; #else class lcHttpReply : public QNetworkReply { Q_OBJECT lcHttpReply(QObject* Parent) : QNetworkReply(Parent) { } }; class lcHttpManager : public QNetworkAccessManager { Q_OBJECT public: lcHttpManager(QObject* Owner = nullptr); lcHttpReply* DownloadFile(const QString& Url); signals: void DownloadFinished(lcHttpReply* Reply); protected slots: void Finished(QNetworkReply* Reply); }; #endif leocad-23.03/common/lc_instructions.cpp000066400000000000000000000163471440571307300202050ustar00rootroot00000000000000#include "lc_global.h" #include "lc_instructions.h" #include "project.h" #include "lc_model.h" #include "piece.h" #include "pieceinf.h" const float lcInstructions::mDisplayDPI = 72.0f; lcInstructions::lcInstructions(Project* Project) : mProject(Project) { mPageSetup.Width = 8.5f * mDisplayDPI; mPageSetup.Height = 11.0f * mDisplayDPI; mPageSetup.MarginLeft = 0.5 * mDisplayDPI; mPageSetup.MarginRight = 0.5 * mDisplayDPI; mPageSetup.MarginTop = 0.5 * mDisplayDPI; mPageSetup.MarginBottom = 0.5 * mDisplayDPI; mPageSettings.Rows = 1; mPageSettings.Columns = 1; mPageSettings.Direction = lcInstructionsDirection::Horizontal; mStepProperties[static_cast(lcInstructionsPropertyType::ShowStepNumber)].Value = true; mStepProperties[static_cast(lcInstructionsPropertyType::ShowStepPLI)].Value = true; mStepProperties[static_cast(lcInstructionsPropertyType::StepNumberFont)].Value = QFont("Arial", 72).toString(); mStepProperties[static_cast(lcInstructionsPropertyType::StepNumberColor)].Value = LC_RGBA(0, 0, 0, 255); mStepProperties[static_cast(lcInstructionsPropertyType::StepBackgroundColor)].Value = LC_RGBA(255, 255, 255, 0); mStepProperties[static_cast(lcInstructionsPropertyType::PLIBackgroundColor)].Value = LC_RGBA(255, 255, 255, 255); mStepProperties[static_cast(lcInstructionsPropertyType::PLIFont)].Value = QFont("Arial", 16, QFont::Bold).toString(); mStepProperties[static_cast(lcInstructionsPropertyType::PLITextColor)].Value = LC_RGBA(0, 0, 0, 255); mStepProperties[static_cast(lcInstructionsPropertyType::PLIBorderColor)].Value = LC_RGBA(0, 0, 0, 255); // mStepProperties[static_cast(lcInstructionsPropertyType::PLIBorderWidth)].Value = 2.0f; // mStepProperties[static_cast(lcInstructionsPropertyType::PLIBorderRound)].Value = true; static_assert(static_cast(lcInstructionsPropertyType::Count) == 9, "Missing default property"); CreatePages(); } QString lcInstructions::GetPropertyLabel(lcInstructionsPropertyType Type) { switch (Type) { case lcInstructionsPropertyType::ShowStepNumber: return tr("Show Step Number"); case lcInstructionsPropertyType::ShowStepPLI: return tr("Show Parts List"); case lcInstructionsPropertyType::StepNumberFont: return tr("Font:"); case lcInstructionsPropertyType::StepNumberColor: return tr("Text Color:"); case lcInstructionsPropertyType::StepBackgroundColor: return tr("Background Color:"); case lcInstructionsPropertyType::PLIBackgroundColor: return tr("Background Color:"); case lcInstructionsPropertyType::PLIFont: return tr("Font:"); case lcInstructionsPropertyType::PLITextColor: return tr("Text Color:"); case lcInstructionsPropertyType::PLIBorderColor: return tr("Border Color:"); case lcInstructionsPropertyType::Count: break; } return QString(); } void lcInstructions::SetDefaultPageSettings(const lcInstructionsPageSettings& PageSettings) { mPageSettings = PageSettings; CreatePages(); } bool lcInstructions::GetBoolProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const { QVariant Value = GetProperty(Type, Model, Step); return Value.toBool(); } QColor lcInstructions::GetColorProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const { QVariant Value = GetProperty(Type, Model, Step); return lcQColorFromRGBA(Value.toUInt()); } QFont lcInstructions::GetFontProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const { QVariant Value = GetProperty(Type, Model, Step); QFont Font; Font.fromString(Value.toString()); return Font; } QVariant lcInstructions::GetProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const { QVariant Value = mStepProperties[static_cast(Type)].Value; std::map::const_iterator ModelIt = mModels.find(Model); if (ModelIt == mModels.end()) return Value; const lcInstructionsModel& InstructionModel = ModelIt->second; for (lcStep StepIndex = 0; StepIndex <= Step; StepIndex++) { const lcInstructionsProperties& Properties = InstructionModel.StepProperties[StepIndex]; const lcInstructionsProperty& Property = Properties[static_cast(Type)]; if (Property.Mode == lcInstructionsPropertyMode::NotSet || (Property.Mode == lcInstructionsPropertyMode::StepOnly && StepIndex != Step)) continue; Value = Property.Value; } return Value; } void lcInstructions::SetDefaultBool(lcInstructionsPropertyType Type, bool Enabled) { SetDefaultProperty(Type, Enabled); } void lcInstructions::SetDefaultColor(lcInstructionsPropertyType Type, const QColor& Color) { SetDefaultProperty(Type, lcRGBAFromQColor(Color)); } void lcInstructions::SetDefaultFont(lcInstructionsPropertyType Type, const QFont& Font) { SetDefaultProperty(Type, Font.toString()); } void lcInstructions::SetDefaultProperty(lcInstructionsPropertyType Type, const QVariant& Value) { lcInstructionsProperty& Property = mStepProperties[static_cast(Type)]; if (Property.Value == Value) return; Property.Value = Value; emit StepSettingsChanged(nullptr, 0); } void lcInstructions::CreatePages() { mPages.clear(); if (mProject) { std::vector AddedModels; lcModel* Model = mProject->GetMainModel(); if (Model) AddDefaultPages(Model, AddedModels); } } void lcInstructions::AddDefaultPages(lcModel* Model, std::vector& AddedModels) { if (std::find(AddedModels.begin(), AddedModels.end(), Model) != AddedModels.end()) return; AddedModels.push_back(Model); const lcStep LastStep = Model->GetLastStep(); lcInstructionsPage Page; int Row = 0, Column = 0; lcInstructionsModel InstructionModel; InstructionModel.StepProperties.resize(LastStep + 1); mModels.emplace(Model, std::move(InstructionModel)); for (lcStep Step = 1; Step <= LastStep; Step++) { std::set StepSubModels; for (lcPiece* Piece : Model->GetPieces()) { if (!Piece->IsHidden() && Piece->GetStepShow() == Step && Piece->mPieceInfo->IsModel()) { lcModel* SubModel = Piece->mPieceInfo->GetModel(); if (std::find(AddedModels.begin(), AddedModels.end(), SubModel) == AddedModels.end()) StepSubModels.insert(SubModel); } } if (!StepSubModels.empty()) { if (!Page.Steps.empty()) { mPages.emplace_back(std::move(Page)); Row = 0; Column = 0; } for (lcModel* SubModel : StepSubModels) AddDefaultPages(SubModel, AddedModels); } lcInstructionsStep InstructionsStep; InstructionsStep.Model = Model; InstructionsStep.Step = Step; const double Width = 1.0 / (double)mPageSettings.Columns; const double Height = 1.0 / (double)mPageSettings.Rows; InstructionsStep.Rect = QRectF(Column * Width, Row * Height, Width, Height); Page.Steps.push_back(std::move(InstructionsStep)); if (mPageSettings.Direction == lcInstructionsDirection::Horizontal) { Column++; if (Column == mPageSettings.Columns) { Row++; Column = 0; } if (Row == mPageSettings.Rows) { mPages.emplace_back(std::move(Page)); Row = 0; Column = 0; } } else { Row++; if (Row == mPageSettings.Rows) { Row = 0; Column++; } if (Column == mPageSettings.Columns) { mPages.emplace_back(std::move(Page)); Row = 0; Column = 0; } } } if (!Page.Steps.empty()) mPages.emplace_back(std::move(Page)); } leocad-23.03/common/lc_instructions.h000066400000000000000000000052011440571307300176350ustar00rootroot00000000000000#pragma once #include "lc_math.h" struct lcInstructionsPageSetup { float Width; float Height; float MarginLeft; float MarginRight; float MarginTop; float MarginBottom; }; enum class lcInstructionsDirection { Horizontal, Vertical }; struct lcInstructionsPageSettings { int Rows; int Columns; lcInstructionsDirection Direction; }; enum class lcInstructionsPropertyMode { NotSet, Default, Model, StepForward, StepOnly }; enum class lcInstructionsPropertyType { ShowStepNumber, ShowStepPLI, StepNumberFont, StepNumberColor, StepBackgroundColor, PLIBackgroundColor, PLIFont, PLITextColor, PLIBorderColor, // PLIBorderWidth, // PLIBorderRound, // pli: spacing and margins, text alignment Count }; struct lcInstructionsProperty { lcInstructionsPropertyMode Mode = lcInstructionsPropertyMode::NotSet; QVariant Value; }; using lcInstructionsProperties = std::array(lcInstructionsPropertyType::Count)>; struct lcInstructionsStep { QRectF Rect; lcModel* Model; lcStep Step; lcInstructionsProperties Properties; }; struct lcInstructionsPage { // lcInstructionsPageSettings Settings; std::vector Steps; }; struct lcInstructionsModel { std::vector StepProperties; }; class lcInstructions : public QObject { Q_OBJECT public: lcInstructions(Project* Project = nullptr); static QString GetPropertyLabel(lcInstructionsPropertyType Type); void SetDefaultPageSettings(const lcInstructionsPageSettings& PageSettings); bool GetBoolProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const; QColor GetColorProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const; QFont GetFontProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const; void SetDefaultBool(lcInstructionsPropertyType Type, bool Enabled); void SetDefaultColor(lcInstructionsPropertyType Type, const QColor& Color); void SetDefaultFont(lcInstructionsPropertyType Type, const QFont& Font); //protected: std::vector mPages; lcInstructionsPageSettings mPageSettings; lcInstructionsPageSetup mPageSetup; lcInstructionsProperties mStepProperties; std::map mModels; signals: void StepSettingsChanged(lcModel* Model, lcStep Step); protected: void CreatePages(); void AddDefaultPages(lcModel* Model, std::vector& AddedModels); QVariant GetProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const; void SetDefaultProperty(lcInstructionsPropertyType Type, const QVariant& Value); Project* mProject = nullptr; static const float mDisplayDPI; }; leocad-23.03/common/lc_instructionsdialog.cpp000066400000000000000000000555401440571307300213630ustar00rootroot00000000000000#include "lc_global.h" #include "lc_instructionsdialog.h" #include "lc_pagesetupdialog.h" #include "project.h" #include "lc_model.h" #include "lc_view.h" #include "lc_collapsiblewidget.h" lcInstructionsStepImageItem::lcInstructionsStepImageItem(QGraphicsItem* Parent, lcInstructions* Instructions, lcModel* Model, lcStep Step) : QGraphicsPixmapItem(Parent), mInstructions(Instructions), mModel(Model), mStep(Step) { setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); } void lcInstructionsStepImageItem::Update() { lcView View(lcViewType::View, mModel); View.SetOffscreenContext(); View.MakeCurrent(); View.SetBackgroundColorOverride(lcRGBAFromQColor(mInstructions->GetColorProperty(lcInstructionsPropertyType::StepBackgroundColor, mModel, mStep))); View.SetSize(mWidth, mHeight); std::vector Images = View.GetStepImages(mStep, mStep); if (!Images.empty()) setPixmap(QPixmap::fromImage(Images.front())); } lcInstructionsStepNumberItem::lcInstructionsStepNumberItem(QGraphicsItem* Parent, lcInstructions* Instructions, lcModel* Model, lcStep Step) : QGraphicsSimpleTextItem(Parent), mInstructions(Instructions), mModel(Model), mStep(Step) { setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); } void lcInstructionsStepNumberItem::Update() { bool Visible = mInstructions->GetBoolProperty(lcInstructionsPropertyType::ShowStepNumber, mModel, mStep); setVisible(Visible); QFont StepNumberFont = mInstructions->GetFontProperty(lcInstructionsPropertyType::StepNumberFont, mModel, mStep); setFont(StepNumberFont); setBrush(QBrush(mInstructions->GetColorProperty(lcInstructionsPropertyType::StepNumberColor, mModel, mStep))); setText(QString::number(mStep)); } lcInstructionsPartsListItem::lcInstructionsPartsListItem(QGraphicsItem* Parent, lcInstructions* Instructions, lcModel* Model, lcStep Step) : QGraphicsPixmapItem(Parent), mInstructions(Instructions), mModel(Model), mStep(Step) { setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); } void lcInstructionsPartsListItem::Update() { bool Visible = mInstructions->GetBoolProperty(lcInstructionsPropertyType::ShowStepPLI, mModel, mStep); setVisible(Visible); if (!Visible) return; QColor BackgroundColor = mInstructions->GetColorProperty(lcInstructionsPropertyType::PLIBackgroundColor, mModel, mStep); QFont Font = mInstructions->GetFontProperty(lcInstructionsPropertyType::PLIFont, mModel, mStep); QColor TextColor = mInstructions->GetColorProperty(lcInstructionsPropertyType::PLITextColor, mModel, mStep); QImage PartsImage = mModel->GetPartsListImage(300, mStep, lcRGBAFromQColor(BackgroundColor), Font, TextColor); setPixmap(QPixmap::fromImage(PartsImage)); } lcInstructionsPageWidget::lcInstructionsPageWidget(QWidget* Parent, lcInstructions* Instructions, lcInstructionsPropertiesWidget* PropertiesWidget) : QGraphicsView(Parent), mInstructions(Instructions), mPropertiesWidget(PropertiesWidget) { QGraphicsScene* Scene = new QGraphicsScene(); setScene(Scene); connect(mInstructions, &lcInstructions::StepSettingsChanged, this, &lcInstructionsPageWidget::StepSettingsChanged); connect(Scene, &QGraphicsScene::selectionChanged, this, &lcInstructionsPageWidget::SelectionChanged); } void lcInstructionsPageWidget::StepSettingsChanged(lcModel* Model, lcStep Step) { QGraphicsScene* Scene = scene(); QList Items = Scene->items(); for (QGraphicsItem* Item : Items) { lcInstructionsStepImageItem* ImageItem = dynamic_cast(Item); if (ImageItem) { if (!Model || (ImageItem->GetModel() == Model && ImageItem->GetStep() == Step)) ImageItem->Update(); continue; } lcInstructionsStepNumberItem* NumberItem = dynamic_cast(Item); if (NumberItem) { if (!Model || (NumberItem->GetModel() == Model && NumberItem->GetStep() == Step)) NumberItem->Update(); continue; } lcInstructionsPartsListItem* PartsItem = dynamic_cast(Item); if (PartsItem) { if (!Model || (PartsItem->GetModel() == Model && PartsItem->GetStep() == Step)) PartsItem->Update(); continue; } } } void lcInstructionsPageWidget::SelectionChanged() { QGraphicsScene* Scene = qobject_cast(sender()); QGraphicsItem* Focus = nullptr; if (Scene) { QList SelectedItems = Scene->selectedItems(); if (!SelectedItems.isEmpty()) Focus = SelectedItems.first(); } mPropertiesWidget->SelectionChanged(Focus); } static void lcUpdateInstructionsPageScene(lcInstructions* Instructions, const lcInstructionsPage* Page, QGraphicsScene* Scene) { Scene->clear(); if (!Page) return; const lcInstructionsPageSetup& PageSetup = Instructions->mPageSetup; // Scene->setSceneRect(0, 0, mInstructions->mPageSetup.Width, mInstructions->mPageSetup.Height); QGraphicsRectItem* PageItem = Scene->addRect(QRectF(0.0f, 0.0f, PageSetup.Width, PageSetup.Height), QPen(Qt::black), QBrush(Qt::white)); PageItem->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true); QRectF MarginsRect(PageSetup.MarginLeft, PageSetup.MarginTop, PageSetup.Width - PageSetup.MarginLeft - PageSetup.MarginRight, PageSetup.Height - PageSetup.MarginTop - PageSetup.MarginBottom); for (const lcInstructionsStep& Step : Page->Steps) { lcInstructionsStepImageItem* StepImageItem = new lcInstructionsStepImageItem(PageItem, Instructions, Step.Model, Step.Step); StepImageItem->setPos(MarginsRect.left() + MarginsRect.width() * Step.Rect.x(), MarginsRect.top() + MarginsRect.height() * Step.Rect.y()); StepImageItem->SetImageSize(MarginsRect.width() * Step.Rect.width(), MarginsRect.height() * Step.Rect.height()); StepImageItem->Update(); lcInstructionsStepNumberItem* StepNumberItem = new lcInstructionsStepNumberItem(StepImageItem, Instructions, Step.Model, Step.Step); StepNumberItem->Update(); lcInstructionsPartsListItem* PartsImageItem = new lcInstructionsPartsListItem(StepImageItem, Instructions, Step.Model, Step.Step); PartsImageItem->setPos(StepNumberItem->boundingRect().topRight()); PartsImageItem->Update(); } } void lcInstructionsPageWidget::SetCurrentPage(const lcInstructionsPage* Page) { QGraphicsScene* Scene = scene(); lcUpdateInstructionsPageScene(mInstructions, Page, Scene); } lcInstructionsPageListWidget::lcInstructionsPageListWidget(QWidget* Parent, lcInstructions* Instructions) : QDockWidget(Parent), mInstructions(Instructions) { QWidget* CentralWidget = new QWidget(this); setWidget(CentralWidget); setWindowTitle(tr("Pages")); QVBoxLayout* Layout = new QVBoxLayout(CentralWidget); Layout->setContentsMargins(0, 0, 0, 0); QHBoxLayout* ButtonsLayout = new QHBoxLayout(); ButtonsLayout->setContentsMargins(0, 0, 0, 0); Layout->addLayout(ButtonsLayout); QToolButton* PageSetupButton = new QToolButton(); PageSetupButton->setText(tr("Page Setup")); ButtonsLayout->addWidget(PageSetupButton); connect(PageSetupButton, SIGNAL(clicked()), this, SLOT(ShowPageSetupDialog())); ButtonsLayout->addStretch(1); /* lcCollapsibleWidget* SetupWidget = new lcCollapsibleWidget(tr("Page Setup"), CentralWidget); Layout->addWidget(SetupWidget); // QVBoxLayout* SetupLayout = new QVBoxLayout(); // SetupWidget->SetChildLayout(SetupLayout); QGridLayout* SetupLayout = new QGridLayout(); SetupWidget->SetChildLayout(SetupLayout); // lcCollapsibleWidget* SizeWidget = new lcCollapsibleWidget(tr("Size")); QGroupBox* SizeWidget = new QGroupBox(tr("Size")); SetupLayout->addWidget(SizeWidget); QGridLayout* SizeLayout = new QGridLayout(); // SizeWidget->SetChildLayout(SizeLayout); SizeWidget->setLayout(SizeLayout); mWidthEdit = new lcSmallLineEdit(); SizeLayout->addWidget(new QLabel(tr("Width:")), 1, 0); SizeLayout->addWidget(mWidthEdit, 1, 1); mHeightEdit = new lcSmallLineEdit(); SizeLayout->addWidget(new QLabel(tr("Height:")), 1, 2); SizeLayout->addWidget(mHeightEdit, 1, 3); mUnitsComboBox = new QComboBox(); mUnitsComboBox->addItems(QStringList() << tr("Pixels") << tr("Centimeters") << tr("Inches")); SizeLayout->addWidget(new QLabel(tr("Units:")), 4, 0); SizeLayout->addWidget(mUnitsComboBox, 4, 1, 1, -1); mSizeComboBox = new QComboBox(); SizeLayout->addWidget(new QLabel(tr("Preset:")), 5, 0); SizeLayout->addWidget(mSizeComboBox, 5, 1, 1, -1); // lcCollapsibleWidget* OrientationWidget = new lcCollapsibleWidget(tr("Orientation")); // SetupLayout->addWidget(OrientationWidget); // // QVBoxLayout* OrientationLayout = new QVBoxLayout(); // OrientationWidget->SetChildLayout(OrientationLayout); // // mPortraitButton = new QRadioButton(tr("Portrait")); // OrientationLayout->addWidget(mPortraitButton); // mLandscapeButton = new QRadioButton(tr("Landscape")); // OrientationLayout->addWidget(mLandscapeButton); QGroupBox* MarginsWidget = new QGroupBox(tr("Margins")); // lcCollapsibleWidget* MarginsWidget = new lcCollapsibleWidget(tr("Margins")); SetupLayout->addWidget(MarginsWidget); QGridLayout* MarginsLayout = new QGridLayout(); // MarginsWidget->SetChildLayout(MarginsLayout); MarginsWidget->setLayout(MarginsLayout); mLeftMarginEdit = new lcSmallLineEdit(); MarginsLayout->addWidget(new QLabel(tr("Left:")), 2, 0); MarginsLayout->addWidget(mLeftMarginEdit, 2, 1); mRightMarginEdit = new lcSmallLineEdit(); MarginsLayout->addWidget(new QLabel(tr("Right:")), 2, 2); MarginsLayout->addWidget(mRightMarginEdit, 2, 3); mTopMarginEdit = new lcSmallLineEdit(); MarginsLayout->addWidget(new QLabel(tr("Top:")), 3, 0); MarginsLayout->addWidget(mTopMarginEdit, 3, 1); mBottomMarginEdit = new lcSmallLineEdit(); MarginsLayout->addWidget(new QLabel(tr("Bottom:")), 3, 2); MarginsLayout->addWidget(mBottomMarginEdit, 3, 3); // lcCollapsibleWidget* UnitsWidget = new lcCollapsibleWidget(tr("Units")); // SetupLayout->addWidget(UnitsWidget); // // QVBoxLayout* UnitsLayout = new QVBoxLayout(); // UnitsWidget->SetChildLayout(UnitsLayout); // SetupWidget->Collapse(); */ mThumbnailsWidget = new QListWidget(CentralWidget); Layout->addWidget(mThumbnailsWidget); } void lcInstructionsPageListWidget::ShowPageSetupDialog() { lcPageSetupDialog Dialog(this, &mInstructions->mPageSetup); if (Dialog.exec() != QDialog::Accepted) return; } lcInstructionsPropertiesWidget::lcInstructionsPropertiesWidget(QWidget* Parent, lcInstructions* Instructions) : QDockWidget(Parent), mInstructions(Instructions) { QWidget* CentralWidget = new QWidget(this); setWidget(CentralWidget); setWindowTitle(tr("Properties")); QGridLayout* Layout = new QGridLayout(CentralWidget); Layout->setContentsMargins(0, 0, 0, 0); QComboBox* ScopeComboBox = new QComboBox(CentralWidget); ScopeComboBox->addItems(QStringList() << tr("Default") << tr("Current Model") << tr("Current Step Only") << tr("Current Step Forward")); Layout->addWidget(new QLabel(tr("Scope:")), 0, 0); Layout->addWidget(ScopeComboBox, 0, 1); QComboBox* PresetComboBox = new QComboBox(CentralWidget); Layout->addWidget(new QLabel(tr("Preset:")), 1, 0); Layout->addWidget(PresetComboBox, 1, 1); Layout->setRowStretch(3, 1); } void lcInstructionsPropertiesWidget::AddBoolProperty(lcInstructionsPropertyType Type) { const QString Label = mInstructions->GetPropertyLabel(Type); const int Row = mPropertiesLayout->rowCount(); QCheckBox* CheckBox = new QCheckBox(Label); mPropertiesLayout->addWidget(CheckBox, Row, 0, 1, -1); bool Enabled = mInstructions->GetBoolProperty(Type, mModel, mStep); CheckBox->setChecked(Enabled); connect(CheckBox, &QToolButton::toggled, [this, Type](bool Checked) { mInstructions->SetDefaultBool(Type, Checked); } ); } void lcInstructionsPropertiesWidget::AddColorProperty(lcInstructionsPropertyType Type) { const QString Label = mInstructions->GetPropertyLabel(Type); const int Row = mPropertiesLayout->rowCount(); mPropertiesLayout->addWidget(new QLabel(Label), Row, 0); QToolButton* ColorButton = new QToolButton(); mPropertiesLayout->addWidget(ColorButton, Row, 1); auto UpdateButton = [this, Type, ColorButton]() { QPixmap Pixmap(12, 12); QColor Color = mInstructions->GetColorProperty(Type, mModel, mStep); Pixmap.fill(Color); ColorButton->setIcon(Pixmap); }; UpdateButton(); connect(ColorButton, &QToolButton::clicked, [this, Type, UpdateButton]() { QString Title; switch (Type) { case lcInstructionsPropertyType::StepNumberColor: Title = tr("Select Step Number Color"); break; case lcInstructionsPropertyType::StepBackgroundColor: Title = tr("Select Step Background Color"); break; case lcInstructionsPropertyType::PLIBackgroundColor: Title = tr("Select Parts List Background Color"); break; case lcInstructionsPropertyType::PLIBorderColor: Title = tr("Select Parts List Border Color"); break; case lcInstructionsPropertyType::PLITextColor: Title = tr("Select Parts List Text Color"); break; case lcInstructionsPropertyType::ShowStepNumber: case lcInstructionsPropertyType::ShowStepPLI: case lcInstructionsPropertyType::StepNumberFont: case lcInstructionsPropertyType::PLIFont: // case lcInstructionsPropertyType::StepPLIBorderWidth: // case lcInstructionsPropertyType::StepPLIBorderRound: case lcInstructionsPropertyType::Count: break; } QColor Color = mInstructions->GetColorProperty(Type, mModel, mStep); Color = QColorDialog::getColor(Color, this, Title); if (Color.isValid()) { mInstructions->SetDefaultColor(Type, Color); UpdateButton(); } }); } void lcInstructionsPropertiesWidget::AddFontProperty(lcInstructionsPropertyType Type) { const QString Label = mInstructions->GetPropertyLabel(Type); const int Row = mPropertiesLayout->rowCount(); mPropertiesLayout->addWidget(new QLabel(Label), Row, 0); QToolButton* FontButton = new QToolButton(); mPropertiesLayout->addWidget(FontButton, Row, 1); auto UpdateButton = [this, Type, FontButton]() { QFont Font = mInstructions->GetFontProperty(Type, mModel, mStep); QString FontName = QString("%1 %2").arg(Font.family(), QString::number(Font.pointSize())); FontButton->setText(FontName); }; UpdateButton(); connect(FontButton, &QToolButton::clicked, [this, Type, UpdateButton]() { QString Title; switch (Type) { case lcInstructionsPropertyType::StepNumberFont: Title = tr("Select Step Number Font"); break; case lcInstructionsPropertyType::PLIFont: Title = tr("Select Parts List Font"); break; case lcInstructionsPropertyType::ShowStepNumber: case lcInstructionsPropertyType::ShowStepPLI: case lcInstructionsPropertyType::StepNumberColor: case lcInstructionsPropertyType::StepBackgroundColor: case lcInstructionsPropertyType::PLIBackgroundColor: case lcInstructionsPropertyType::PLITextColor: case lcInstructionsPropertyType::PLIBorderColor: case lcInstructionsPropertyType::Count: break; } bool Ok = false; QFont Font = mInstructions->GetFontProperty(Type, mModel, mStep); Font = QFontDialog::getFont(&Ok, Font, this, tr("Select Step Number Font")); if (Ok) { UpdateButton(); mInstructions->SetDefaultFont(Type, Font); } }); } void lcInstructionsPropertiesWidget::SelectionChanged(QGraphicsItem* FocusItem) { if (mFocusItem == FocusItem) return; delete mWidget; mWidget = nullptr; mFocusItem = FocusItem; mModel = nullptr; mStep = 1; if (!FocusItem) return; auto CreatePropertyWidget = [this](const QString& Title) { mWidget = new lcCollapsibleWidget(Title); // todo: disable collapse QGridLayout* WidgetLayout = qobject_cast(widget()->layout()); WidgetLayout->addWidget(mWidget, 2, 0, 1, -1); mPropertiesLayout = new QGridLayout(); mWidget->SetChildLayout(mPropertiesLayout); }; lcInstructionsStepImageItem* ImageItem = dynamic_cast(FocusItem); if (ImageItem) { CreatePropertyWidget(tr("Step Properties")); mModel = ImageItem->GetModel(); mStep = ImageItem->GetStep(); AddBoolProperty(lcInstructionsPropertyType::ShowStepNumber); AddBoolProperty(lcInstructionsPropertyType::ShowStepPLI); AddColorProperty(lcInstructionsPropertyType::StepBackgroundColor); return; } lcInstructionsStepNumberItem* NumberItem = dynamic_cast(FocusItem); if (NumberItem) { CreatePropertyWidget(tr("Step Number Properties")); mModel = NumberItem->GetModel(); mStep = NumberItem->GetStep(); AddFontProperty(lcInstructionsPropertyType::StepNumberFont); AddColorProperty(lcInstructionsPropertyType::StepNumberColor); return; } lcInstructionsPartsListItem* PartsItem = dynamic_cast(FocusItem); if (PartsItem) { CreatePropertyWidget(tr("Parts List Properties")); mModel = PartsItem->GetModel(); mStep = PartsItem->GetStep(); AddColorProperty(lcInstructionsPropertyType::PLIBackgroundColor); AddFontProperty(lcInstructionsPropertyType::PLIFont); AddColorProperty(lcInstructionsPropertyType::PLITextColor); AddColorProperty(lcInstructionsPropertyType::PLIBorderColor); // PLIBorderWidth, // PLIBorderRound, return; } } lcInstructionsDialog::lcInstructionsDialog(QWidget* Parent, Project* Project) : QMainWindow(Parent), mProject(Project) { setWindowTitle(tr("Instructions")); mInstructions = mProject->GetInstructions(); mPropertiesWidget = new lcInstructionsPropertiesWidget(this, mInstructions); mPropertiesWidget->setObjectName("InstructionsProperties"); addDockWidget(Qt::RightDockWidgetArea, mPropertiesWidget); mPageWidget = new lcInstructionsPageWidget(this, mInstructions, mPropertiesWidget); setCentralWidget(mPageWidget); mPageListWidget = new lcInstructionsPageListWidget(this, mInstructions); mPageListWidget->setObjectName("InstructionsPageList"); addDockWidget(Qt::LeftDockWidgetArea, mPageListWidget); mPageSettingsToolBar = addToolBar(tr("Page Settings")); mPageSettingsToolBar->setObjectName("PageSettings"); mPageSettingsToolBar->setFloatable(false); mPageSettingsToolBar->setMovable(false); mPrintAction = mPageSettingsToolBar->addAction(tr("Print")); mVerticalPageAction = mPageSettingsToolBar->addAction(tr("Vertical")); mVerticalPageAction->setCheckable(true); mHorizontalPageAction = mPageSettingsToolBar->addAction(tr("Horizontal")); mHorizontalPageAction->setCheckable(true); mRowsSpinBox = new QSpinBox(mPageSettingsToolBar); mPageSettingsToolBar->addWidget(mRowsSpinBox); mColumnsSpinBox = new QSpinBox(mPageSettingsToolBar); mPageSettingsToolBar->addWidget(mColumnsSpinBox); QActionGroup* PageDirectionGroup = new QActionGroup(mPageSettingsToolBar); PageDirectionGroup->addAction(mVerticalPageAction); PageDirectionGroup->addAction(mHorizontalPageAction); for (size_t PageNumber = 0; PageNumber < mInstructions->mPages.size(); PageNumber++) mPageListWidget->mThumbnailsWidget->addItem(QString(tr("Page %1")).arg(PageNumber + 1)); connect(mPageListWidget->mThumbnailsWidget, SIGNAL(currentRowChanged(int)), this, SLOT(CurrentThumbnailChanged(int))); mPageListWidget->mThumbnailsWidget->setCurrentRow(0); connect(mPrintAction, &QAction::triggered, this, &lcInstructionsDialog::ShowPrintDialog); connect(mVerticalPageAction, SIGNAL(toggled(bool)), this, SLOT(UpdatePageSettings())); connect(mHorizontalPageAction, SIGNAL(toggled(bool)), this, SLOT(UpdatePageSettings())); connect(mRowsSpinBox, SIGNAL(valueChanged(int)), this, SLOT(UpdatePageSettings())); connect(mColumnsSpinBox, SIGNAL(valueChanged(int)), this, SLOT(UpdatePageSettings())); } void lcInstructionsDialog::ShowPrintDialog() { #ifndef QT_NO_PRINTER int PageCount = static_cast(mInstructions->mPages.size()); QPrinter Printer(QPrinter::HighResolution); Printer.setFromTo(1, PageCount + 1); QPrintDialog PrintDialog(&Printer, this); if (PrintDialog.exec() == QDialog::Accepted) Print(&Printer); #endif } void lcInstructionsDialog::Print(QPrinter* Printer) { #ifndef QT_NO_PRINTER int DocCopies; int PageCopies; const int PageCount = static_cast(mInstructions->mPages.size()); if (Printer->collateCopies()) { DocCopies = 1; PageCopies = Printer->supportsMultipleCopies() ? 1 : Printer->copyCount(); } else { DocCopies = Printer->supportsMultipleCopies() ? 1 : Printer->copyCount(); PageCopies = 1; } int FromPage = Printer->fromPage(); int ToPage = Printer->toPage(); bool Ascending = true; if (FromPage == 0 && ToPage == 0) { FromPage = 1; ToPage = PageCount; } FromPage = qMax(1, FromPage); ToPage = qMin(PageCount, ToPage); if (ToPage < FromPage) return; if (Printer->pageOrder() == QPrinter::LastPageFirst) { std::swap(FromPage, ToPage); Ascending = false; } QGraphicsScene* Scene = new QGraphicsScene(); QPainter Painter(Printer); bool FirstPage = true; for (int DocCopy = 0; DocCopy < DocCopies; DocCopy++) { int Page = FromPage; for (;;) { for (int PageCopy = 0; PageCopy < PageCopies; PageCopy++) { if (Printer->printerState() == QPrinter::Aborted || Printer->printerState() == QPrinter::Error) return; if (!FirstPage) Printer->newPage(); else FirstPage = false; const lcInstructionsPage* InstructionsPage = &mInstructions->mPages[Page - 1]; lcUpdateInstructionsPageScene(mInstructions, InstructionsPage, Scene); Scene->render(&Painter); } if (Page == ToPage) break; if (Ascending) Page++; else Page--; } } delete Scene; #endif } void lcInstructionsDialog::UpdatePageSettings() { lcInstructionsPageSettings PageSettings; PageSettings.Rows = mRowsSpinBox->value(); PageSettings.Columns = mColumnsSpinBox->value(); if (mHorizontalPageAction->isChecked()) PageSettings.Direction = lcInstructionsDirection::Horizontal; else PageSettings.Direction = lcInstructionsDirection::Vertical; mInstructions->SetDefaultPageSettings(PageSettings); // lcInstructionsPage* Page = &mInstructions.mPages[mThumbnailsWidget->currentIndex().row()]; mPageListWidget->mThumbnailsWidget->clear(); for (size_t PageNumber = 0; PageNumber < mInstructions->mPages.size(); PageNumber++) mPageListWidget->mThumbnailsWidget->addItem(QString("Page %1").arg(PageNumber + 1)); // mThumbnailsWidget->setCurrentRow(0); // mPageWidget->SetCurrentPage(Page); } void lcInstructionsDialog::CurrentThumbnailChanged(int Index) { if (Index < 0 || Index >= static_cast(mInstructions->mPages.size())) { mPageWidget->SetCurrentPage(nullptr); return; } const lcInstructionsPage* Page = &mInstructions->mPages[Index]; // const lcInstructionsPageSettings& PageSettings = Page->Settings; const lcInstructionsPageSettings& PageSettings = mInstructions->mPageSettings; mPageWidget->SetCurrentPage(Page); if (PageSettings.Direction == lcInstructionsDirection::Horizontal) { mHorizontalPageAction->blockSignals(true); mHorizontalPageAction->setChecked(true); mHorizontalPageAction->blockSignals(false); } else { mVerticalPageAction->blockSignals(true); mVerticalPageAction->setChecked(true); mVerticalPageAction->blockSignals(false); } mRowsSpinBox->blockSignals(true); mRowsSpinBox->setValue(PageSettings.Rows); mRowsSpinBox->blockSignals(false); mColumnsSpinBox->blockSignals(true); mColumnsSpinBox->setValue(PageSettings.Columns); mColumnsSpinBox->blockSignals(false); } leocad-23.03/common/lc_instructionsdialog.h000066400000000000000000000076411440571307300210270ustar00rootroot00000000000000#pragma once #include "lc_instructions.h" class lcInstructionsPropertiesWidget; class lcInstructionsStepImageItem : public QGraphicsPixmapItem { public: lcInstructionsStepImageItem(QGraphicsItem* Parent, lcInstructions* Instructions, lcModel* Model, lcStep Step); lcModel* GetModel() const { return mModel; } lcStep GetStep() const { return mStep; } void SetImageSize(int Width, int Height) { mWidth = Width; mHeight = Height; } void Update(); protected: lcInstructions* mInstructions = nullptr; lcModel* mModel = nullptr; lcStep mStep = 1; int mWidth = 1; int mHeight = 1; }; class lcInstructionsStepNumberItem : public QGraphicsSimpleTextItem { public: lcInstructionsStepNumberItem(QGraphicsItem* Parent, lcInstructions* Instructions, lcModel* Model, lcStep Step); lcModel* GetModel() const { return mModel; } lcStep GetStep() const { return mStep; } void Update(); protected: lcInstructions* mInstructions = nullptr; lcModel* mModel = nullptr; lcStep mStep = 1; }; class lcInstructionsPartsListItem : public QGraphicsPixmapItem { public: lcInstructionsPartsListItem(QGraphicsItem* Parent, lcInstructions* Instructions, lcModel* Model, lcStep Step); lcModel* GetModel() const { return mModel; } lcStep GetStep() const { return mStep; } void Update(); protected: lcInstructions* mInstructions = nullptr; lcModel* mModel = nullptr; lcStep mStep = 1; }; class lcInstructionsPageWidget : public QGraphicsView { Q_OBJECT public: lcInstructionsPageWidget(QWidget* Parent, lcInstructions* Instructions, lcInstructionsPropertiesWidget* PropertiesWidget); void SetCurrentPage(const lcInstructionsPage* Page); protected slots: void StepSettingsChanged(lcModel* Model, lcStep Step); void SelectionChanged(); protected: lcInstructions* mInstructions; lcInstructionsPropertiesWidget* mPropertiesWidget; }; class lcInstructionsPageListWidget : public QDockWidget { Q_OBJECT public: lcInstructionsPageListWidget(QWidget* Parent, lcInstructions* Instructions); protected slots: void ShowPageSetupDialog(); public: //protected: // QComboBox* mSizeComboBox = nullptr; // QLineEdit* mWidthEdit = nullptr; // QLineEdit* mHeightEdit = nullptr; // // QRadioButton* mPortraitButton = nullptr; // QRadioButton* mLandscapeButton = nullptr; // // QLineEdit* mLeftMarginEdit = nullptr; // QLineEdit* mRightMarginEdit = nullptr; // QLineEdit* mTopMarginEdit = nullptr; // QLineEdit* mBottomMarginEdit = nullptr; // // QComboBox* mUnitsComboBox = nullptr; QListWidget* mThumbnailsWidget = nullptr; protected: lcInstructions* mInstructions; }; class lcInstructionsPropertiesWidget : public QDockWidget { Q_OBJECT public: lcInstructionsPropertiesWidget(QWidget* Parent, lcInstructions* Instructions); void SelectionChanged(QGraphicsItem* FocusItem); protected: void AddBoolProperty(lcInstructionsPropertyType Type); void AddColorProperty(lcInstructionsPropertyType Type); void AddFontProperty(lcInstructionsPropertyType Type); lcCollapsibleWidget* mWidget = nullptr; QGridLayout* mPropertiesLayout = nullptr; lcInstructions* mInstructions = nullptr; QGraphicsItem* mFocusItem = nullptr; lcModel* mModel = nullptr; lcStep mStep = 1; }; class lcInstructionsDialog : public QMainWindow { Q_OBJECT public: lcInstructionsDialog(QWidget* Parent, Project* Project); protected slots: void ShowPrintDialog(); void UpdatePageSettings(); void CurrentThumbnailChanged(int Index); protected: void Print(QPrinter* Printer); Project* mProject = nullptr; int mCurrentPageNumber; lcInstructions* mInstructions; lcInstructionsPageWidget* mPageWidget = nullptr; lcInstructionsPageListWidget* mPageListWidget = nullptr; lcInstructionsPropertiesWidget* mPropertiesWidget = nullptr; QToolBar* mPageSettingsToolBar = nullptr; QAction* mPrintAction = nullptr; QAction* mVerticalPageAction = nullptr; QAction* mHorizontalPageAction = nullptr; QSpinBox* mRowsSpinBox = nullptr; QSpinBox* mColumnsSpinBox = nullptr; }; leocad-23.03/common/lc_library.cpp000066400000000000000000001356501440571307300171040ustar00rootroot00000000000000#include "lc_global.h" #include "lc_library.h" #include "lc_zipfile.h" #include "lc_file.h" #include "pieceinf.h" #include "lc_colors.h" #include "lc_texture.h" #include "lc_category.h" #include "lc_application.h" #include "lc_context.h" #include "lc_glextensions.h" #include "lc_synth.h" #include "project.h" #include "lc_profile.h" #include "lc_meshloader.h" #include #include #include #include #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif #define LC_LIBRARY_CACHE_VERSION 0x0109 #define LC_LIBRARY_CACHE_ARCHIVE 0x0001 #define LC_LIBRARY_CACHE_DIRECTORY 0x0002 lcPiecesLibrary::lcPiecesLibrary() #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) : mLoadMutex(QMutex::Recursive) #endif { QStringList cachePathList = QStandardPaths::standardLocations(QStandardPaths::CacheLocation); mCachePath = cachePathList.first(); QDir Dir; Dir.mkpath(mCachePath); mNumOfficialPieces = 0; mBuffersDirty = false; mHasUnofficial = false; mCancelLoading = false; mStudStyle = static_cast(lcGetProfileInt(LC_PROFILE_STUD_STYLE)); } lcPiecesLibrary::~lcPiecesLibrary() { mLoadMutex.lock(); mLoadQueue.clear(); mLoadMutex.unlock(); mCancelLoading = true; WaitForLoadQueue(); Unload(); ReleaseBuffers(); } void lcPiecesLibrary::Unload() { for (const auto& PieceIt : mPieces) delete PieceIt.second; mPieces.clear(); mSources.clear(); for (lcTexture* Texture : mTextures) delete Texture; mTextures.clear(); mNumOfficialPieces = 0; for (std::unique_ptr& ZipFile : mZipFiles) ZipFile.reset(); } void lcPiecesLibrary::RemoveTemporaryPieces() { QMutexLocker LoadLock(&mLoadMutex); for (auto PieceIt = mPieces.begin(); PieceIt != mPieces.end();) { PieceInfo* Info = PieceIt->second; if (Info->IsTemporary() && Info->GetRefCount() == 0) { PieceIt = mPieces.erase(PieceIt); delete Info; } else PieceIt++; } } void lcPiecesLibrary::RemovePiece(PieceInfo* Info) { for (auto PieceIt = mPieces.begin(); PieceIt != mPieces.end(); PieceIt++) { if (PieceIt->second == Info) { mPieces.erase(PieceIt); break; } } delete Info; } void lcPiecesLibrary::RenamePiece(PieceInfo* Info, const char* NewName) { for (auto PieceIt = mPieces.begin(); PieceIt != mPieces.end(); PieceIt++) { if (PieceIt->second == Info) { mPieces.erase(PieceIt); break; } } strncpy(Info->mFileName, NewName, sizeof(Info->mFileName)); Info->mFileName[sizeof(Info->mFileName) - 1] = 0; strncpy(Info->m_strDescription, NewName, sizeof(Info->m_strDescription)); Info->m_strDescription[sizeof(Info->m_strDescription) - 1] = 0; char PieceName[LC_PIECE_NAME_LEN]; strcpy(PieceName, Info->mFileName); strupr(PieceName); mPieces[PieceName] = Info; } PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, Project* CurrentProject, bool CreatePlaceholder, bool SearchProjectFolder) { QString ProjectPath; if (SearchProjectFolder) { QString FileName = CurrentProject->GetFileName(); if (!FileName.isEmpty()) ProjectPath = QFileInfo(FileName).absolutePath(); } char CleanName[LC_PIECE_NAME_LEN]; const char* Src = PieceName; char* Dst = CleanName; while (*Src && Dst - CleanName != sizeof(CleanName)) { if (*Src == '\\') *Dst = '/'; else if (*Src >= 'a' && *Src <= 'z') *Dst = *Src + 'A' - 'a'; else *Dst = *Src; Src++; Dst++; } *Dst = 0; const auto PieceIt = mPieces.find(CleanName); if (PieceIt != mPieces.end()) { PieceInfo* Info = PieceIt->second; if ((!CurrentProject || !Info->IsModel() || CurrentProject->GetModels().FindIndex(Info->GetModel()) != -1) && (!ProjectPath.isEmpty() || !Info->IsProject() || Info->IsProjectPiece())) return Info; } if (!ProjectPath.isEmpty()) { QFileInfo ProjectFile = QFileInfo(ProjectPath + QDir::separator() + PieceName); if (ProjectFile.isFile()) { Project* NewProject = new Project(); if (NewProject->Load(ProjectFile.absoluteFilePath(), false)) { PieceInfo* Info = new PieceInfo(); Info->CreateProject(NewProject, PieceName); mPieces[CleanName] = Info; return Info; } else delete NewProject; } } if (CreatePlaceholder) { PieceInfo* Info = new PieceInfo(); Info->CreatePlaceholder(PieceName); mPieces[CleanName] = Info; return Info; } return nullptr; } lcTexture* lcPiecesLibrary::FindTexture(const char* TextureName, Project* CurrentProject, bool SearchProjectFolder) { for (lcTexture* Texture : mTextures) if (!strcmp(TextureName, Texture->mName)) return Texture; QString ProjectPath; if (SearchProjectFolder) { QString FileName = CurrentProject->GetFileName(); if (!FileName.isEmpty()) ProjectPath = QFileInfo(FileName).absolutePath(); } if (!ProjectPath.isEmpty()) { QFileInfo TextureFile = QFileInfo(ProjectPath + QDir::separator() + TextureName + ".png"); if (TextureFile.isFile()) { lcTexture* Texture = lcLoadTexture(TextureFile.absoluteFilePath(), LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV); if (Texture) { mTextures.push_back(Texture); return Texture; } } } return nullptr; } bool lcPiecesLibrary::Load(const QString& LibraryPath, bool ShowProgress) { Unload(); if (OpenArchive(LibraryPath, lcZipFileType::Official)) { LoadColors(); mLibraryDir = QFileInfo(LibraryPath).absoluteDir(); QString UnofficialFileName = mLibraryDir.absoluteFilePath(QLatin1String("ldrawunf.zip")); if (!OpenArchive(UnofficialFileName, lcZipFileType::Unofficial)) UnofficialFileName.clear(); ReadArchiveDescriptions(LibraryPath, UnofficialFileName); } else { mLibraryDir.setPath(LibraryPath); if (OpenDirectory(mLibraryDir, ShowProgress)) LoadColors(); else return false; } UpdateStudStyleSource(); lcLoadDefaultCategories(); lcSynthInit(); return true; } void lcPiecesLibrary::LoadColors() { QString CustomColorsPath = lcGetProfileString(LC_PROFILE_COLOR_CONFIG); if (!CustomColorsPath.isEmpty()) { lcDiskFile ColorFile(CustomColorsPath); if (ColorFile.Open(QIODevice::ReadOnly) && lcLoadColorFile(ColorFile, mStudStyle)) { emit ColorsLoaded(); return; } } if (mZipFiles[static_cast(lcZipFileType::Official)]) { lcMemFile ColorFile; if (!mZipFiles[static_cast(lcZipFileType::Official)]->ExtractFile("ldraw/ldconfig.ldr", ColorFile) || !lcLoadColorFile(ColorFile, mStudStyle)) lcLoadDefaultColors(mStudStyle); } else { lcDiskFile ColorFile(mLibraryDir.absoluteFilePath(QLatin1String("ldconfig.ldr"))); if (!ColorFile.Open(QIODevice::ReadOnly) || !lcLoadColorFile(ColorFile, mStudStyle)) { ColorFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String("LDConfig.ldr"))); if (!ColorFile.Open(QIODevice::ReadOnly) || !lcLoadColorFile(ColorFile, mStudStyle)) lcLoadDefaultColors(mStudStyle); } } emit ColorsLoaded(); } bool lcPiecesLibrary::IsStudPrimitive(const char* FileName) { return memcmp(FileName, "STU", 3) == 0; } bool lcPiecesLibrary::IsStudStylePrimitive(const char* FileName) { constexpr std::array StudStylePrimitives = { "2-4STUD4.DAT", "STUD.DAT", "STUD2.DAT", "STUD2A.DAT", "STUD3.DAT", "STUD4.DAT", "STUD4A.DAT", "STUD4H.DAT", "8/STUD.DAT", "8/STUD2.DAT", "8/STUD2A.DAT", "8/STUD3.DAT", "8/STUD4.DAT", "8/STUD4A.DAT", "8/STUD4H.DAT" }; for (const char* StudStylePrimitive : StudStylePrimitives) if (!strcmp(StudStylePrimitive, FileName)) return true; return false; } void lcPiecesLibrary::UpdateStudStyleSource() { if (!mSources.empty() && mSources.front()->Type == lcLibrarySourceType::StudStyle) mSources.erase(mSources.begin()); mZipFiles[static_cast(lcZipFileType::StudStyle)].reset(); if (mStudStyle == lcStudStyle::Plain) return; const QLatin1String FileNames[] = { QLatin1String(""), // Plain QLatin1String(":/resources/studlogo1.zip"), // ThinLinesLogo QLatin1String(":/resources/studlogo2.zip"), // OutlineLogo QLatin1String(":/resources/studlogo3.zip"), // SharpTopLogo QLatin1String(":/resources/studlogo4.zip"), // RoundedTopLogo QLatin1String(":/resources/studlogo5.zip"), // FlattenedLogo QLatin1String(":/resources/studslegostyle1.zip"), // HighContrast QLatin1String(":/resources/studslegostyle2.zip") // HighContrastLogo }; LC_ARRAY_SIZE_CHECK(FileNames, lcStudStyle::Count); std::unique_ptr StudStyleFile(new lcDiskFile(FileNames[static_cast(mStudStyle)])); if (StudStyleFile->Open(QIODevice::ReadOnly)) OpenArchive(std::move(StudStyleFile), lcZipFileType::StudStyle); } bool lcPiecesLibrary::OpenArchive(const QString& FileName, lcZipFileType ZipFileType) { std::unique_ptr File(new lcDiskFile(FileName)); if (!File->Open(QIODevice::ReadOnly)) return false; return OpenArchive(std::move(File), ZipFileType); } bool lcPiecesLibrary::OpenArchive(std::unique_ptr File, lcZipFileType ZipFileType) { std::unique_ptr ZipFile(new lcZipFile()); if (!ZipFile->OpenRead(std::move(File))) return false; std::unique_ptr Source(new lcLibrarySource); Source->Type = ZipFileType != lcZipFileType::StudStyle ? lcLibrarySourceType::Library : lcLibrarySourceType::StudStyle; for (int FileIdx = 0; FileIdx < ZipFile->mFiles.GetSize(); FileIdx++) { lcZipFileInfo& FileInfo = ZipFile->mFiles[FileIdx]; char NameBuffer[LC_PIECE_NAME_LEN]; char* Name = NameBuffer; const char* Src = FileInfo.file_name; char* Dst = Name; while (*Src && Dst - Name < LC_PIECE_NAME_LEN) { if (*Src >= 'a' && *Src <= 'z') *Dst = *Src + 'A' - 'a'; else if (*Src == '\\') *Dst = '/'; else *Dst = *Src; Src++; Dst++; } if (Dst - Name <= 4) continue; *Dst = 0; Dst -= 4; if (memcmp(Dst, ".DAT", 4)) { if (!memcmp(Dst, ".PNG", 4)) { if ((ZipFileType == lcZipFileType::Official && !memcmp(Name, "LDRAW/PARTS/TEXTURES/", 21)) || (ZipFileType == lcZipFileType::Unofficial && !memcmp(Name, "PARTS/TEXTURES/", 15))) { lcTexture* Texture = new lcTexture(); mTextures.push_back(Texture); *Dst = 0; strncpy(Texture->mName, Name + (ZipFileType == lcZipFileType::Official ? 21 : 15), sizeof(Texture->mName)-1); Texture->mName[sizeof(Texture->mName) - 1] = 0; } } continue; } if (ZipFileType == lcZipFileType::Official) { if (memcmp(Name, "LDRAW/", 6)) continue; Name += 6; } if (!memcmp(Name, "PARTS/", 6)) { Name += 6; if (memcmp(Name, "S/", 2)) { PieceInfo* Info = FindPiece(Name, nullptr, false, false); if (!Info) { Info = new PieceInfo(); strncpy(Info->mFileName, FileInfo.file_name + (Name - NameBuffer), sizeof(Info->mFileName)-1); Info->mFileName[sizeof(Info->mFileName) - 1] = 0; mPieces[Name] = Info; } Info->SetZipFile(ZipFileType, FileIdx); } else Source->Primitives[Name] = new lcLibraryPrimitive(QString(), FileInfo.file_name + (Name - NameBuffer), ZipFileType, FileIdx, false, false, true); } else if (!memcmp(Name, "P/", 2)) { Name += 2; Source->Primitives[Name] = new lcLibraryPrimitive(QString(), FileInfo.file_name + (Name - NameBuffer), ZipFileType, FileIdx, IsStudPrimitive(Name), IsStudStylePrimitive(Name), false); } } mZipFiles[static_cast(ZipFileType)] = std::move(ZipFile); if (ZipFileType != lcZipFileType::StudStyle) mSources.emplace_back(std::move(Source)); else mSources.insert(mSources.begin(), std::move(Source)); return true; } void lcPiecesLibrary::ReadArchiveDescriptions(const QString& OfficialFileName, const QString& UnofficialFileName) { QFileInfo OfficialInfo(OfficialFileName); QFileInfo UnofficialInfo(UnofficialFileName); mArchiveCheckSum[0] = OfficialInfo.size(); mArchiveCheckSum[1] = OfficialInfo.lastModified().toMSecsSinceEpoch(); if (!UnofficialFileName.isEmpty()) { mArchiveCheckSum[2] = UnofficialInfo.size(); mArchiveCheckSum[3] = UnofficialInfo.lastModified().toMSecsSinceEpoch(); } else { mArchiveCheckSum[2] = 0; mArchiveCheckSum[3] = 0; } QString IndexFileName = QFileInfo(QDir(mCachePath), QLatin1String("index")).absoluteFilePath(); if (!LoadCacheIndex(IndexFileName)) { lcMemFile PieceFile; for (const auto& PieceIt : mPieces) { PieceInfo* Info = PieceIt.second; mZipFiles[static_cast(Info->mZipFileType)]->ExtractFile(Info->mZipFileIndex, PieceFile, 256); PieceFile.Seek(0, SEEK_END); PieceFile.WriteU8(0); char* Src = (char*)PieceFile.mBuffer + 2; char* Dst = Info->m_strDescription; for (;;) { if (*Src != '\r' && *Src != '\n' && *Src && Dst - Info->m_strDescription < (int)sizeof(Info->m_strDescription) - 1) { *Dst++ = *Src++; continue; } *Dst = 0; break; } } SaveArchiveCacheIndex(IndexFileName); } } bool lcPiecesLibrary::OpenDirectory(const QDir& LibraryDir, bool ShowProgress) { const QLatin1String BaseFolders[] = { QLatin1String(""), QLatin1String("unofficial/") }; constexpr int NumBaseFolders = LC_ARRAY_COUNT(BaseFolders); QFileInfoList FileLists[NumBaseFolders]; for (unsigned int BaseFolderIdx = 0; BaseFolderIdx < NumBaseFolders; BaseFolderIdx++) { QString ParstPath = QDir(LibraryDir.absoluteFilePath(BaseFolders[BaseFolderIdx])).absoluteFilePath(QLatin1String("parts/")); QDir Dir = QDir(ParstPath, QLatin1String("*.dat"), QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable); FileLists[BaseFolderIdx] = Dir.entryInfoList(); } if (FileLists[static_cast(lcLibraryFolderType::Official)].isEmpty()) return false; mHasUnofficial = !FileLists[static_cast(lcLibraryFolderType::Unofficial)].isEmpty(); ReadDirectoryDescriptions(FileLists, ShowProgress); for (unsigned int BaseFolderIdx = 0; BaseFolderIdx < LC_ARRAY_COUNT(BaseFolders); BaseFolderIdx++) { std::unique_ptr Source(new lcLibrarySource); Source->Type = lcLibrarySourceType::Library; const char* PrimitiveDirectories[] = { "p/", "parts/s/" }; bool SubFileDirectories[] = { false, false, true }; QDir BaseDir(LibraryDir.absoluteFilePath(QLatin1String(BaseFolders[BaseFolderIdx]))); for (int DirectoryIdx = 0; DirectoryIdx < (int)(LC_ARRAY_COUNT(PrimitiveDirectories)); DirectoryIdx++) { QString ChildPath = BaseDir.absoluteFilePath(QLatin1String(PrimitiveDirectories[DirectoryIdx])); QDirIterator DirIterator(ChildPath, QStringList() << QLatin1String("*.dat"), QDir::Files | QDir::Hidden | QDir::Readable, QDirIterator::Subdirectories); while (DirIterator.hasNext()) { char Name[LC_PIECE_NAME_LEN]; QString FileName = DirIterator.next(); QByteArray FileString = BaseDir.relativeFilePath(FileName).toLatin1(); const char* Src = strchr(FileString, '/') + 1; char* Dst = Name; while (*Src && Dst - Name < (int)sizeof(Name)) { if (*Src >= 'a' && *Src <= 'z') *Dst = *Src + 'A' - 'a'; else if (*Src == '\\') *Dst = '/'; else *Dst = *Src; Src++; Dst++; } *Dst = 0; if (Dst - Name <= 4) continue; Dst -= 4; if (memcmp(Dst, ".DAT", 4)) continue; if (BaseFolderIdx > 0 && IsPrimitive(Name)) continue; if (BaseFolderIdx == static_cast(lcLibraryFolderType::Unofficial)) mHasUnofficial = true; const bool SubFile = SubFileDirectories[DirectoryIdx]; Source->Primitives[Name] = new lcLibraryPrimitive(std::move(FileName), strchr(FileString, '/') + 1, lcZipFileType::Count, 0, !SubFile && IsStudPrimitive(Name), IsStudStylePrimitive(Name), SubFile); } } mSources.emplace_back(std::move(Source)); } for (unsigned int BaseFolderIdx = 0; BaseFolderIdx < LC_ARRAY_COUNT(BaseFolders); BaseFolderIdx++) { QDir BaseDir(LibraryDir.absoluteFilePath(QLatin1String(BaseFolders[BaseFolderIdx]))); QDir Dir(BaseDir.absoluteFilePath(QLatin1String("parts/textures/")), QLatin1String("*.png"), QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable); QStringList FileList = Dir.entryList(); mTextures.reserve(mTextures.size() + FileList.size()); for (int FileIdx = 0; FileIdx < FileList.size(); FileIdx++) { char Name[LC_MAXPATH]; QByteArray FileString = FileList[FileIdx].toLatin1(); const char* Src = FileString; char* Dst = Name; while (*Src && Dst - Name < (int)sizeof(Name)) { if (*Src >= 'a' && *Src <= 'z') *Dst = *Src + 'A' - 'a'; else if (*Src == '\\') *Dst = '/'; else *Dst = *Src; Src++; Dst++; } if (Dst - Name <= 4) continue; Dst -= 4; if (memcmp(Dst, ".PNG", 4)) continue; *Dst = 0; lcTexture* Texture = new lcTexture(); mTextures.push_back(Texture); strncpy(Texture->mName, Name, sizeof(Texture->mName)); Texture->mName[sizeof(Texture->mName) - 1] = 0; Texture->mFileName = Dir.absoluteFilePath(FileList[FileIdx]); } } return true; } void lcPiecesLibrary::ReadDirectoryDescriptions(const QFileInfoList (&FileLists)[static_cast(lcLibraryFolderType::Count)], bool ShowProgress) { QString IndexFileName = QFileInfo(QDir(mCachePath), QLatin1String("index")).absoluteFilePath(); lcMemFile IndexFile; std::vector CachedDescriptions; if (ReadDirectoryCacheFile(IndexFileName, IndexFile)) { QString LibraryPath = IndexFile.ReadQString(); if (LibraryPath == mLibraryDir.absolutePath()) { int NumDescriptions = IndexFile.ReadU32(); CachedDescriptions.reserve(NumDescriptions); while (NumDescriptions--) { const char* FileName = (const char*)IndexFile.mBuffer + IndexFile.GetPosition(); CachedDescriptions.push_back(FileName); IndexFile.Seek(strlen(FileName) + 1, SEEK_CUR); const char* Description = (const char*)IndexFile.mBuffer + IndexFile.GetPosition(); IndexFile.Seek(strlen(Description) + 1, SEEK_CUR); IndexFile.Seek(4 + 1 + 8, SEEK_CUR); } } } for (int FolderIdx = 0; FolderIdx < static_cast(lcLibraryFolderType::Count); FolderIdx++) { const QFileInfoList& FileList = FileLists[FolderIdx]; for (int FileIdx = 0; FileIdx < FileList.size(); FileIdx++) { char Name[LC_PIECE_NAME_LEN]; QByteArray FileString = FileList[FileIdx].fileName().toLatin1(); const char* Src = FileString; char* Dst = Name; while (*Src && Dst - Name < (int)sizeof(Name)) { if (*Src >= 'a' && *Src <= 'z') *Dst = *Src + 'A' - 'a'; else if (*Src == '\\') *Dst = '/'; else *Dst = *Src; Src++; Dst++; } *Dst = 0; if (FolderIdx > 0 && mPieces.find(Name) != mPieces.end()) continue; PieceInfo* Info = new PieceInfo(); strncpy(Info->mFileName, FileString, sizeof(Info->mFileName)); Info->mFileName[sizeof(Info->mFileName) - 1] = 0; Info->mFolderType = FolderIdx; Info->mFolderIndex = FileIdx; mPieces[Name] = Info; } } QAtomicInt FilesLoaded; bool Modified = false; auto ReadDescriptions = [&FileLists, &CachedDescriptions, &FilesLoaded, &Modified](const std::pair& Entry) { PieceInfo* Info = Entry.second; FilesLoaded.ref(); lcDiskFile PieceFile(FileLists[Info->mFolderType][Info->mFolderIndex].absoluteFilePath()); char Line[1024]; if (!CachedDescriptions.empty()) { auto DescriptionCompare = [](const void* Key, const void* Element) { return strcmp((const char*)Key, *(const char**)Element); }; void* CachedDescription = bsearch(Info->mFileName, &CachedDescriptions.front(), CachedDescriptions.size(), sizeof(char*), DescriptionCompare); if (CachedDescription) { const char* FileName = *(const char**)CachedDescription; const char* Description = FileName + strlen(FileName) + 1; const uint64_t CachedFileTime = *(uint64_t*)(Description + strlen(Description) + 1 + 4 + 1); quint64 FileTime = FileLists[Info->mFolderType][Info->mFolderIndex].lastModified().toMSecsSinceEpoch(); if (FileTime == CachedFileTime) { strcpy(Info->m_strDescription, Description); return; } } } if (!PieceFile.Open(QIODevice::ReadOnly) || !PieceFile.ReadLine(Line, sizeof(Line))) { strcpy(Info->m_strDescription, "Unknown"); return; } const char* Src = Line + 2; char* Dst = Info->m_strDescription; for (;;) { if (*Src != '\r' && *Src != '\n' && *Src && Dst - Info->m_strDescription < (int)sizeof(Info->m_strDescription) - 1) { *Dst++ = *Src++; continue; } *Dst = 0; break; } Modified = true; }; QProgressDialog* ProgressDialog = new QProgressDialog(nullptr); ProgressDialog->setWindowFlags(ProgressDialog->windowFlags() & ~Qt::WindowCloseButtonHint); ProgressDialog->setWindowTitle(tr("Initializing")); ProgressDialog->setLabelText(tr("Loading Parts Library")); ProgressDialog->setMaximum((int)mPieces.size()); ProgressDialog->setMinimum(0); ProgressDialog->setValue(0); ProgressDialog->setCancelButton(nullptr); ProgressDialog->setAutoReset(false); if (ShowProgress) ProgressDialog->show(); QFuture LoadFuture = QtConcurrent::map(mPieces, ReadDescriptions); while (!LoadFuture.isFinished()) { ProgressDialog->setValue(FilesLoaded); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); } ProgressDialog->setValue(FilesLoaded); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); ProgressDialog->deleteLater(); if (Modified) { lcMemFile NewIndexFile; NewIndexFile.WriteQString(mLibraryDir.absolutePath()); NewIndexFile.WriteU32((quint32)mPieces.size()); std::vector SortedPieces; SortedPieces.reserve(mPieces.size()); for (const auto& PieceIt : mPieces) SortedPieces.push_back(PieceIt.second); auto PieceInfoCompare = [](PieceInfo* Info1, PieceInfo* Info2) { return strcmp(Info1->mFileName, Info2->mFileName) < 0; }; std::sort(SortedPieces.begin(), SortedPieces.end(), PieceInfoCompare); for (const PieceInfo* Info : SortedPieces) { if (NewIndexFile.WriteBuffer(Info->mFileName, strlen(Info->mFileName) + 1) == 0) return; if (NewIndexFile.WriteBuffer(Info->m_strDescription, strlen(Info->m_strDescription) + 1) == 0) return; NewIndexFile.WriteU8(static_cast(Info->mFolderType)); quint64 FileTime = FileLists[Info->mFolderType][Info->mFolderIndex].lastModified().toMSecsSinceEpoch(); NewIndexFile.WriteU64(FileTime); } WriteDirectoryCacheFile(IndexFileName, NewIndexFile); } } bool lcPiecesLibrary::ReadArchiveCacheFile(const QString& FileName, lcMemFile& CacheFile) { QFile File(FileName); if (!File.open(QIODevice::ReadOnly)) return false; quint32 CacheVersion, CacheFlags; if (File.read((char*)&CacheVersion, sizeof(CacheVersion)) == -1 || CacheVersion != LC_LIBRARY_CACHE_VERSION) return false; if (File.read((char*)&CacheFlags, sizeof(CacheFlags)) == -1 || CacheFlags != LC_LIBRARY_CACHE_ARCHIVE) return false; qint64 CacheCheckSum[4]; if (File.read((char*)&CacheCheckSum, sizeof(CacheCheckSum)) == -1 || memcmp(CacheCheckSum, mArchiveCheckSum, sizeof(CacheCheckSum))) return false; quint32 UncompressedSize; if (File.read((char*)&UncompressedSize, sizeof(UncompressedSize)) == -1) return false; QByteArray CompressedData = File.readAll(); CacheFile.SetLength(UncompressedSize); CacheFile.Seek(0, SEEK_SET); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) constexpr qsizetype CHUNK = 16384; #else constexpr int CHUNK = 16384; #endif int ret; unsigned have; z_stream strm; unsigned char in[CHUNK]; unsigned char out[CHUNK]; int pos; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; pos = 0; ret = inflateInit2(&strm, -MAX_WBITS); if (ret != Z_OK) return ret; do { strm.avail_in = lcMin(CompressedData.size() - pos, CHUNK); strm.next_in = in; if (strm.avail_in == 0) break; memcpy(in, CompressedData.constData() + pos, strm.avail_in); pos += strm.avail_in; do { strm.avail_out = CHUNK; strm.next_out = out; ret = inflate(&strm, Z_NO_FLUSH); switch (ret) { case Z_NEED_DICT: ret = Z_DATA_ERROR; Q_FALLTHROUGH(); case Z_DATA_ERROR: Q_FALLTHROUGH(); case Z_MEM_ERROR: (void)inflateEnd(&strm); return ret; } have = CHUNK - strm.avail_out; CacheFile.WriteBuffer(out, have); } while (strm.avail_out == 0); } while (ret != Z_STREAM_END); (void)inflateEnd(&strm); CacheFile.Seek(0, SEEK_SET); return ret == Z_STREAM_END; } bool lcPiecesLibrary::WriteArchiveCacheFile(const QString& FileName, lcMemFile& CacheFile) { QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) return false; constexpr quint32 CacheVersion = LC_LIBRARY_CACHE_VERSION; constexpr quint32 CacheFlags = LC_LIBRARY_CACHE_ARCHIVE; if (File.write((char*)&CacheVersion, sizeof(CacheVersion)) == -1) return false; if (File.write((char*)&CacheFlags, sizeof(CacheFlags)) == -1) return false; if (File.write((char*)&mArchiveCheckSum, sizeof(mArchiveCheckSum)) == -1) return false; const quint32 UncompressedSize = (quint32)CacheFile.GetLength(); if (File.write((char*)&UncompressedSize, sizeof(UncompressedSize)) == -1) return false; constexpr size_t BufferSize = 16384; char WriteBuffer[BufferSize]; z_stream Stream; quint32 Crc32 = 0; CacheFile.Seek(0, SEEK_SET); Stream.zalloc = nullptr; Stream.zfree = nullptr; Stream.opaque = nullptr; if (deflateInit2(&Stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) return false; Bytef* BufferIn = CacheFile.mBuffer; int FlushMode; do { uInt Read = (uInt)lcMin(CacheFile.GetLength() - (BufferIn - CacheFile.mBuffer), BufferSize); Stream.avail_in = Read; Stream.next_in = BufferIn; Crc32 = crc32(Crc32, BufferIn, Read); BufferIn += Read; FlushMode = (BufferIn >= CacheFile.mBuffer + CacheFile.GetLength()) ? Z_FINISH : Z_NO_FLUSH; do { Stream.avail_out = BufferSize; Stream.next_out = (Bytef*)WriteBuffer; deflate(&Stream, FlushMode); File.write(WriteBuffer, BufferSize - Stream.avail_out); } while (Stream.avail_out == 0); } while (FlushMode != Z_FINISH); deflateEnd(&Stream); return true; } bool lcPiecesLibrary::ReadDirectoryCacheFile(const QString& FileName, lcMemFile& CacheFile) { QFile File(FileName); if (!File.open(QIODevice::ReadOnly)) return false; quint32 CacheVersion, CacheFlags; if (File.read((char*)&CacheVersion, sizeof(CacheVersion)) == -1 || CacheVersion != LC_LIBRARY_CACHE_VERSION) return false; if (File.read((char*)&CacheFlags, sizeof(CacheFlags)) == -1 || CacheFlags != LC_LIBRARY_CACHE_DIRECTORY) return false; quint32 UncompressedSize; if (File.read((char*)&UncompressedSize, sizeof(UncompressedSize)) == -1) return false; QByteArray Data = qUncompress(File.readAll()); if (Data.isEmpty()) return false; CacheFile.SetLength(Data.size()); CacheFile.Seek(0, SEEK_SET); CacheFile.WriteBuffer(Data.constData(), Data.size()); CacheFile.Seek(0, SEEK_SET); return true; } bool lcPiecesLibrary::WriteDirectoryCacheFile(const QString& FileName, lcMemFile& CacheFile) { QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) return false; constexpr quint32 CacheVersion = LC_LIBRARY_CACHE_VERSION; if (File.write((char*)&CacheVersion, sizeof(CacheVersion)) == -1) return false; constexpr quint32 CacheFlags = LC_LIBRARY_CACHE_DIRECTORY; if (File.write((char*)&CacheFlags, sizeof(CacheFlags)) == -1) return false; const quint32 UncompressedSize = (quint32)CacheFile.GetLength(); if (File.write((char*)&UncompressedSize, sizeof(UncompressedSize)) == -1) return false; File.write(qCompress(CacheFile.mBuffer, (int)CacheFile.GetLength())); return true; } bool lcPiecesLibrary::LoadCacheIndex(const QString& FileName) { lcMemFile IndexFile; if (!ReadArchiveCacheFile(FileName, IndexFile)) return false; quint32 NumFiles; if (IndexFile.ReadBuffer((char*)&NumFiles, sizeof(NumFiles)) == 0 || NumFiles != mPieces.size()) return false; for (const auto& PieceIt : mPieces) { PieceInfo* Info = PieceIt.second; quint8 Length; if (IndexFile.ReadBuffer((char*)&Length, sizeof(Length)) == 0 || Length >= sizeof(Info->m_strDescription)) return false; if (IndexFile.ReadBuffer((char*)Info->m_strDescription, Length) == 0) return false; Info->m_strDescription[Length] = 0; } return true; } bool lcPiecesLibrary::SaveArchiveCacheIndex(const QString& FileName) { lcMemFile IndexFile; const quint32 NumFiles = (quint32)mPieces.size(); if (IndexFile.WriteBuffer((char*)&NumFiles, sizeof(NumFiles)) == 0) return false; for (const auto& PieceIt : mPieces) { const PieceInfo* Info = PieceIt.second; const quint8 Length = (quint8)strlen(Info->m_strDescription); if (IndexFile.WriteBuffer((char*)&Length, sizeof(Length)) == 0) return false; if (IndexFile.WriteBuffer((char*)Info->m_strDescription, Length) == 0) return false; } return WriteArchiveCacheFile(FileName, IndexFile); } bool lcPiecesLibrary::LoadCachePiece(PieceInfo* Info) { QString FileName = QFileInfo(QDir(mCachePath), QString::fromLatin1(Info->mFileName)).absoluteFilePath(); lcMemFile MeshData; if (!ReadArchiveCacheFile(FileName, MeshData)) return false; qint32 Flags; if (MeshData.ReadBuffer((char*)&Flags, sizeof(Flags)) == 0) return false; if (Flags != static_cast(mStudStyle)) return false; lcMesh* Mesh = new lcMesh; if (Mesh->FileLoad(MeshData)) { Info->SetMesh(Mesh); return true; } else { delete Mesh; return false; } } bool lcPiecesLibrary::SaveCachePiece(PieceInfo* Info) { lcMemFile MeshData; const qint32 Flags = static_cast(mStudStyle); if (MeshData.WriteBuffer((char*)&Flags, sizeof(Flags)) == 0) return false; if (!Info->GetMesh()->FileSave(MeshData)) return false; QString FileName = QFileInfo(QDir(mCachePath), QString::fromLatin1(Info->mFileName)).absoluteFilePath(); return WriteArchiveCacheFile(FileName, MeshData); } class lcSleeper : public QThread { public: static void msleep(unsigned long Msecs) { QThread::msleep(Msecs); } }; void lcPiecesLibrary::LoadPieceInfo(PieceInfo* Info, bool Wait, bool Priority) { QMutexLocker LoadLock(&mLoadMutex); if (Wait) { if (Info->AddRef() == 1) Info->Load(); else { if (Info->mState == lcPieceInfoState::Unloaded) { Info->Load(); emit PartLoaded(Info); } else { LoadLock.unlock(); while (Info->mState != lcPieceInfoState::Loaded) lcSleeper::msleep(10); } } } else { if (Info->AddRef() == 1) { if (Priority) mLoadQueue.prepend(Info); else mLoadQueue.append(Info); mLoadFutures.append(QtConcurrent::run([this]() { LoadQueuedPiece(); })); } } } void lcPiecesLibrary::ReleasePieceInfo(PieceInfo* Info) { QMutexLocker LoadLock(&mLoadMutex); if (Info->GetRefCount() == 0 || Info->Release() == 0) Info->Unload(); } void lcPiecesLibrary::LoadQueuedPiece() { mLoadMutex.lock(); PieceInfo* Info = nullptr; while (!mLoadQueue.isEmpty()) { Info = mLoadQueue.takeFirst(); if (Info->mState == lcPieceInfoState::Unloaded && Info->GetRefCount() > 0) { Info->mState = lcPieceInfoState::Loading; break; } Info = nullptr; } mLoadMutex.unlock(); if (Info) Info->Load(); emit PartLoaded(Info); } void lcPiecesLibrary::WaitForLoadQueue() { for (QFuture& Future : mLoadFutures) Future.waitForFinished(); mLoadFutures.clear(); } bool lcPiecesLibrary::LoadPieceData(PieceInfo* Info) { lcLibraryMeshData MeshData; lcMeshLoader MeshLoader(MeshData, true, nullptr, false); bool Loaded = false; bool SaveCache = false; if (Info->mZipFileType != lcZipFileType::Count && mZipFiles[static_cast(Info->mZipFileType)]) { if (LoadCachePiece(Info)) return true; lcMemFile PieceFile; if (mZipFiles[static_cast(Info->mZipFileType)]->ExtractFile(Info->mZipFileIndex, PieceFile)) Loaded = MeshLoader.LoadMesh(PieceFile, LC_MESHDATA_SHARED); SaveCache = Loaded && (Info->mZipFileType == lcZipFileType::Official); } else { char FileName[LC_MAXPATH]; lcDiskFile PieceFile; sprintf(FileName, "parts/%s", Info->mFileName); PieceFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName))); if (PieceFile.Open(QIODevice::ReadOnly)) Loaded = MeshLoader.LoadMesh(PieceFile, LC_MESHDATA_SHARED); if (mHasUnofficial && !Loaded) { sprintf(FileName, "unofficial/parts/%s", Info->mFileName); PieceFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName))); if (PieceFile.Open(QIODevice::ReadOnly)) Loaded = MeshLoader.LoadMesh(PieceFile, LC_MESHDATA_SHARED); } } if (mCancelLoading) return false; if (Info) { if (Loaded) Info->SetMesh(MeshData.CreateMesh()); else { lcMesh* Mesh = new lcMesh; Mesh->CreateBox(); Info->SetMesh(Mesh); } } if (SaveCache) SaveCachePiece(Info); return Loaded; } void lcPiecesLibrary::GetPrimitiveFile(lcLibraryPrimitive* Primitive, std::function Callback) { if (mZipFiles[static_cast(lcZipFileType::Official)]) { lcMemFile IncludeFile; if (mZipFiles[static_cast(Primitive->mZipFileType)]->ExtractFile(Primitive->mZipFileIndex, IncludeFile)) Callback(IncludeFile); } else { lcDiskFile IncludeFile(Primitive->mFileName); if (IncludeFile.Open(QIODevice::ReadOnly)) Callback(IncludeFile); } } void lcPiecesLibrary::GetPieceFile(const char* PieceName, std::function Callback) { const auto PieceIt = mPieces.find(PieceName); if (PieceIt != mPieces.end()) { PieceInfo* Info = PieceIt->second; if (mZipFiles[static_cast(lcZipFileType::Official)] && Info->mZipFileType != lcZipFileType::Count) { lcMemFile IncludeFile; if (mZipFiles[static_cast(Info->mZipFileType)]->ExtractFile(Info->mZipFileIndex, IncludeFile)) Callback(IncludeFile); } else { lcDiskFile IncludeFile; char FileName[LC_MAXPATH]; bool Found = false; sprintf(FileName, "parts/%s", Info->mFileName); IncludeFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName))); Found = IncludeFile.Open(QIODevice::ReadOnly); if (mHasUnofficial && !Found) { sprintf(FileName, "unofficial/parts/%s", Info->mFileName); IncludeFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName))); Found = IncludeFile.Open(QIODevice::ReadOnly); } if (Found) Callback(IncludeFile); } } else { bool Found = false; if (mZipFiles[static_cast(lcZipFileType::Official)]) { lcMemFile IncludeFile; auto LoadIncludeFile = [&IncludeFile, PieceName, this](const char* Folder, lcZipFileType ZipFileType) { char IncludeFileName[LC_MAXPATH]; sprintf(IncludeFileName, Folder, PieceName); return mZipFiles[static_cast(ZipFileType)]->ExtractFile(IncludeFileName, IncludeFile); }; Found = LoadIncludeFile("ldraw/parts/%s", lcZipFileType::Official); if (!Found) Found = LoadIncludeFile("ldraw/p/%s", lcZipFileType::Official); if (mZipFiles[static_cast(lcZipFileType::Unofficial)] && !Found) { Found = LoadIncludeFile("parts/%s", lcZipFileType::Unofficial); if (!Found) Found = LoadIncludeFile("p/%s", lcZipFileType::Unofficial); } if (Found) Callback(IncludeFile); } else { lcDiskFile IncludeFile; auto LoadIncludeFile = [&IncludeFile, PieceName, this](const QLatin1String& Folder) { const QString IncludeFileName = Folder + PieceName; IncludeFile.SetFileName(mLibraryDir.absoluteFilePath(IncludeFileName)); if (IncludeFile.Open(QIODevice::ReadOnly)) return true; #if defined(Q_OS_MACOS) || defined(Q_OS_LINUX) // todo: search the parts/primitive lists and get the file name from there instead of using toLower IncludeFile.SetFileName(mLibraryDir.absoluteFilePath(IncludeFileName.toLower())); return IncludeFile.Open(QIODevice::ReadOnly); #else return false; #endif }; Found = LoadIncludeFile(QLatin1String("parts/")); if (!Found) Found = LoadIncludeFile(QLatin1String("p/")); if (mHasUnofficial && !Found) { Found = LoadIncludeFile(QLatin1String("unofficial/parts/")); if (!Found) Found = LoadIncludeFile(QLatin1String("unofficial/p/")); } if (Found) Callback(IncludeFile); } } } void lcPiecesLibrary::ReleaseBuffers() { lcContext* Context = lcContext::GetGlobalOffscreenContext(); Context->MakeCurrent(); Context->DestroyVertexBuffer(mVertexBuffer); Context->DestroyIndexBuffer(mIndexBuffer); mBuffersDirty = true; } void lcPiecesLibrary::UpdateBuffers(lcContext* Context) { if (!gSupportsVertexBufferObject || !mBuffersDirty) return; int VertexDataSize = 0; int IndexDataSize = 0; std::vector Meshes; for (const auto& PieceIt : mPieces) { const PieceInfo* const Info = PieceIt.second; lcMesh* Mesh = Info->GetMesh(); if (!Mesh) continue; if (Mesh->mVertexDataSize > 16 * 1024 * 1024 || Mesh->mIndexDataSize > 16 * 1024 * 1024) continue; VertexDataSize += Mesh->mVertexDataSize; IndexDataSize += Mesh->mIndexDataSize; Meshes.push_back(Mesh); } Context->DestroyVertexBuffer(mVertexBuffer); Context->DestroyIndexBuffer(mIndexBuffer); if (!VertexDataSize || !IndexDataSize) return; void* VertexData = malloc(VertexDataSize); void* IndexData = malloc(IndexDataSize); VertexDataSize = 0; IndexDataSize = 0; for (lcMesh* Mesh : Meshes) { Mesh->mVertexCacheOffset = VertexDataSize; Mesh->mIndexCacheOffset = IndexDataSize; memcpy((char*)VertexData + VertexDataSize, Mesh->mVertexData, Mesh->mVertexDataSize); memcpy((char*)IndexData + IndexDataSize, Mesh->mIndexData, Mesh->mIndexDataSize); VertexDataSize += Mesh->mVertexDataSize; IndexDataSize += Mesh->mIndexDataSize; } mVertexBuffer = Context->CreateVertexBuffer(VertexDataSize, VertexData); mIndexBuffer = Context->CreateIndexBuffer(IndexDataSize, IndexData); mBuffersDirty = false; free(VertexData); free(IndexData); } void lcPiecesLibrary::UnloadUnusedParts() { QMutexLocker LoadLock(&mLoadMutex); for (const auto& PieceIt : mPieces) { PieceInfo* Info = PieceIt.second; if (Info->GetRefCount() == 0 && Info->mState != lcPieceInfoState::Unloaded) ReleasePieceInfo(Info); } } bool lcPiecesLibrary::LoadTexture(lcTexture* Texture) { QMutexLocker Lock(&mTextureMutex); char FileName[2*LC_MAXPATH]; if (mZipFiles[static_cast(lcZipFileType::Official)]) { lcMemFile TextureFile; sprintf(FileName, "ldraw/parts/textures/%s.png", Texture->mName); if (!mZipFiles[static_cast(lcZipFileType::Official)]->ExtractFile(FileName, TextureFile)) { sprintf(FileName, "parts/textures/%s.png", Texture->mName); if (!mZipFiles[static_cast(lcZipFileType::Unofficial)] || !mZipFiles[static_cast(lcZipFileType::Unofficial)]->ExtractFile(FileName, TextureFile)) return false; } return Texture->Load(TextureFile); } else return Texture->Load(Texture->mFileName); } void lcPiecesLibrary::ReleaseTexture(lcTexture* Texture) { QMutexLocker LoadLock(&mLoadMutex); if (Texture->Release() == 0 && Texture->IsTemporary()) { std::vector::iterator TextureIt = std::find(mTextures.begin(), mTextures.end(), Texture); if (TextureIt != mTextures.end()) mTextures.erase(TextureIt); delete Texture; } } bool lcPiecesLibrary::SupportsStudStyle() const { return true; } void lcPiecesLibrary::SetStudStyle(lcStudStyle StudStyle, bool Reload) { if (mStudStyle == StudStyle) return; mStudStyle = StudStyle; LoadColors(); UpdateStudStyleSource(); mLoadMutex.lock(); for (const std::unique_ptr& Source : mSources) { for (const auto& PrimitiveIt : Source->Primitives) { lcLibraryPrimitive* Primitive = PrimitiveIt.second; if (Primitive->mStudStyle || Primitive->mMeshData.mHasStyleStud) Primitive->Unload(); } } mLoadMutex.unlock(); if (Reload) { mLoadMutex.lock(); for (const auto& PieceIt : mPieces) { PieceInfo* Info = PieceIt.second; if (Info->mState == lcPieceInfoState::Loaded && Info->GetMesh() && Info->GetMesh()->mFlags & lcMeshFlag::HasStyleStud) { Info->Unload(); mLoadQueue.append(Info); mLoadFutures.append(QtConcurrent::run([this]() { LoadQueuedPiece(); })); } } mLoadMutex.unlock(); WaitForLoadQueue(); } } bool lcPiecesLibrary::IsPrimitive(const char* Name) const { for (const std::unique_ptr& Source : mSources) if (Source->Primitives.find(Name) != Source->Primitives.end()) return true; return false; } lcLibraryPrimitive* lcPiecesLibrary::FindPrimitive(const char* Name) const { for (const std::unique_ptr& Source : mSources) { const auto PrimitiveIt = Source->Primitives.find(Name); if (PrimitiveIt != Source->Primitives.end()) return PrimitiveIt->second; } return nullptr; } bool lcPiecesLibrary::LoadPrimitive(lcLibraryPrimitive* Primitive) { mLoadMutex.lock(); if (Primitive->mState == lcPrimitiveState::NotLoaded) Primitive->mState = lcPrimitiveState::Loading; else { mLoadMutex.unlock(); while (Primitive->mState == lcPrimitiveState::Loading) lcSleeper::msleep(5); return Primitive->mState == lcPrimitiveState::Loaded; } mLoadMutex.unlock(); lcMeshLoader MeshLoader(Primitive->mMeshData, true, nullptr, false); if (mZipFiles[static_cast(lcZipFileType::Official)]) { lcLibraryPrimitive* LowPrimitive = nullptr; lcMemFile PrimFile; if (Primitive->mStud && !Primitive->mStudStyle) { if (strncmp(Primitive->mName, "8/", 2)) // todo: this is currently the only place that uses mName so use mFileName instead. this should also be done for the loose file libraries. { char Name[LC_PIECE_NAME_LEN]; strcpy(Name, "8/"); strcat(Name, Primitive->mName); strupr(Name); LowPrimitive = FindPrimitive(Name); // todo: low primitives don't work with studlogo, because the low stud gets added as shared } } if (!mZipFiles[static_cast(Primitive->mZipFileType)]->ExtractFile(Primitive->mZipFileIndex, PrimFile)) return false; if (!LowPrimitive) { if (!MeshLoader.LoadMesh(PrimFile, LC_MESHDATA_SHARED)) return false; } else { if (!MeshLoader.LoadMesh(PrimFile, LC_MESHDATA_HIGH)) return false; if (!mZipFiles[static_cast(LowPrimitive->mZipFileType)]->ExtractFile(LowPrimitive->mZipFileIndex, PrimFile)) return false; if (!MeshLoader.LoadMesh(PrimFile, LC_MESHDATA_LOW)) return false; } } else { if (Primitive->mZipFileType == lcZipFileType::Count) { lcDiskFile PrimFile(Primitive->mFileName); if (!PrimFile.Open(QIODevice::ReadOnly) || !MeshLoader.LoadMesh(PrimFile, LC_MESHDATA_SHARED)) // todo: LOD like the zip files return false; } else { lcMemFile PrimFile; if (!mZipFiles[static_cast(Primitive->mZipFileType)]->ExtractFile(Primitive->mZipFileIndex, PrimFile)) return false; if (!MeshLoader.LoadMesh(PrimFile, LC_MESHDATA_SHARED)) return false; } } mLoadMutex.lock(); Primitive->mState = lcPrimitiveState::Loaded; mLoadMutex.unlock(); return true; } bool lcPiecesLibrary::PieceInCategory(PieceInfo* Info, const char* CategoryKeywords) const { if (Info->IsTemporary()) return false; const char* PieceName; if (Info->m_strDescription[0] == '~' || Info->m_strDescription[0] == '_') PieceName = Info->m_strDescription + 1; else PieceName = Info->m_strDescription; return lcMatchCategory(PieceName, CategoryKeywords); } void lcPiecesLibrary::GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray& SinglePieces, lcArray& GroupedPieces) { if (CategoryIndex >= 0 && CategoryIndex < static_cast(gCategories.size())) GetCategoryEntries(gCategories[CategoryIndex].Keywords.constData(), GroupPieces, SinglePieces, GroupedPieces); } void lcPiecesLibrary::GetCategoryEntries(const char* CategoryKeywords, bool GroupPieces, lcArray& SinglePieces, lcArray& GroupedPieces) { SinglePieces.RemoveAll(); GroupedPieces.RemoveAll(); for (const auto& PieceIt : mPieces) { PieceInfo* Info = PieceIt.second; if (!PieceInCategory(Info, CategoryKeywords)) continue; if (!GroupPieces) { SinglePieces.Add(Info); continue; } // Check if it's a patterned piece. if (Info->IsPatterned()) { PieceInfo* Parent; // Find the parent of this patterned piece. char ParentName[LC_PIECE_NAME_LEN]; strcpy(ParentName, Info->mFileName); *strchr(ParentName, 'P') = '\0'; strcat(ParentName, ".dat"); Parent = FindPiece(ParentName, nullptr, false, false); if (Parent) { // Check if the parent was added as a single piece. int Index = SinglePieces.FindIndex(Parent); if (Index != -1) SinglePieces.RemoveIndex(Index); Index = GroupedPieces.FindIndex(Parent); if (Index == -1) GroupedPieces.Add(Parent); } else { // Patterned pieces should have a parent but in case they don't just add them anyway. SinglePieces.Add(Info); } } else { // Check if this piece has already been added to this category by one of its children. const int Index = GroupedPieces.FindIndex(Info); if (Index == -1) SinglePieces.Add(Info); } } } void lcPiecesLibrary::GetPatternedPieces(PieceInfo* Parent, lcArray& Pieces) const { char Name[LC_PIECE_NAME_LEN]; strcpy(Name, Parent->mFileName); char* Ext = strchr(Name, '.'); if (Ext) *Ext = 0; strcat(Name, "P"); strupr(Name); Pieces.RemoveAll(); for (const auto& PieceIt : mPieces) if (strncmp(Name, PieceIt.first.c_str(), strlen(Name)) == 0) Pieces.Add(PieceIt.second); // Sometimes pieces with A and B versions don't follow the same convention (for example, 3040Pxx instead of 3040BPxx). if (Pieces.GetSize() == 0) { strcpy(Name, Parent->mFileName); Ext = strchr(Name, '.'); if (Ext) *Ext = 0; size_t Len = strlen(Name); if (Name[Len-1] < '0' || Name[Len-1] > '9') Name[Len-1] = 'P'; for (const auto& PieceIt : mPieces) if (strncmp(Name, PieceIt.first.c_str(), strlen(Name)) == 0) Pieces.Add(PieceIt.second); } } void lcPiecesLibrary::GetParts(lcArray& Parts) const { Parts.SetSize(0); Parts.AllocGrow(mPieces.size()); for (const auto& PartIt : mPieces) Parts.Add(PartIt.second); } std::vector lcPiecesLibrary::GetPartsFromSet(const std::vector& PartIds) const { std::vector Parts; Parts.reserve(PartIds.size()); for (const std::string& PartId : PartIds) { std::map::const_iterator PartIt = mPieces.find(PartId); if (PartIt != mPieces.end()) Parts.push_back(PartIt->second); } return Parts; } std::string lcPiecesLibrary::GetPartId(const PieceInfo* Info) const { std::map::const_iterator PartIt = std::find_if(mPieces.begin(), mPieces.end(), [Info](const std::pair& PartIt) { return PartIt.second == Info; }); if (PartIt != mPieces.end()) return PartIt->first; else return std::string(); } bool lcPiecesLibrary::LoadBuiltinPieces() { std::unique_ptr File(new lcDiskFile(":/resources/library.zip")); if (!File->Open(QIODevice::ReadOnly) || !OpenArchive(std::move(File), lcZipFileType::Official)) return false; lcMemFile PieceFile; for (const auto& PieceIt : mPieces) { PieceInfo* Info = PieceIt.second; mZipFiles[static_cast(Info->mZipFileType)]->ExtractFile(Info->mZipFileIndex, PieceFile, 256); PieceFile.Seek(0, SEEK_END); PieceFile.WriteU8(0); char* Src = (char*)PieceFile.mBuffer + 2; char* Dst = Info->m_strDescription; for (;;) { if (*Src != '\r' && *Src != '\n' && *Src && Dst - Info->m_strDescription < (int)sizeof(Info->m_strDescription) - 1) { *Dst++ = *Src++; continue; } *Dst = 0; break; } } lcLoadDefaultColors(lcStudStyle::Plain); lcLoadDefaultCategories(true); lcSynthInit(); return true; } leocad-23.03/common/lc_library.h000066400000000000000000000144231440571307300165430ustar00rootroot00000000000000#pragma once #include "lc_context.h" #include "lc_mesh.h" #include "lc_math.h" #include "lc_array.h" #include "lc_meshloader.h" class PieceInfo; class lcZipFile; class lcLibraryMeshData; enum class lcStudStyle { Plain, ThinLinesLogo, OutlineLogo, SharpTopLogo, RoundedTopLogo, FlattenedLogo, HighContrast, HighContrastLogo, Count }; constexpr bool lcIsHighContrast(lcStudStyle StudStyle) { return StudStyle == lcStudStyle::HighContrast || StudStyle == lcStudStyle::HighContrastLogo; } enum class lcZipFileType { Official, Unofficial, StudStyle, Count }; enum class lcLibraryFolderType { Official, Unofficial, Count }; enum class lcPrimitiveState { NotLoaded, Loading, Loaded }; class lcLibraryPrimitive { public: explicit lcLibraryPrimitive(QString&& FileName, const char* Name, lcZipFileType ZipFileType, quint32 ZipFileIndex, bool Stud, bool StudStyle, bool SubFile) : mFileName(std::move(FileName)) { strncpy(mName, Name, sizeof(mName)-1); mName[sizeof(mName) - 1] = 0; mZipFileType = ZipFileType; mZipFileIndex = ZipFileIndex; mState = lcPrimitiveState::NotLoaded; mStud = Stud; mStudStyle = StudStyle; mSubFile = SubFile; } void SetZipFile(lcZipFileType ZipFileType, quint32 ZipFileIndex) { mZipFileType = ZipFileType; mZipFileIndex = ZipFileIndex; } void Unload() { mState = lcPrimitiveState::NotLoaded; mMeshData.Clear(); } QString mFileName; char mName[LC_MAXNAME]; lcZipFileType mZipFileType; quint32 mZipFileIndex; lcPrimitiveState mState; bool mStud; bool mStudStyle; bool mSubFile; lcLibraryMeshData mMeshData; }; enum class lcLibrarySourceType { Library, StudStyle }; struct lcLibrarySource { lcLibrarySource() = default; ~lcLibrarySource() { for (const auto& PrimitiveIt : Primitives) delete PrimitiveIt.second; } lcLibrarySource(const lcLibrarySource&) = delete; lcLibrarySource(lcLibrarySource&&) = delete; lcLibrarySource& operator=(const lcLibrarySource&) = delete; lcLibrarySource& operator=(lcLibrarySource&&) = delete; lcLibrarySourceType Type; std::map Primitives; }; class lcPiecesLibrary : public QObject { Q_OBJECT public: lcPiecesLibrary(); ~lcPiecesLibrary(); lcPiecesLibrary(const lcPiecesLibrary&) = delete; lcPiecesLibrary(lcPiecesLibrary&&) = delete; lcPiecesLibrary& operator=(const lcPiecesLibrary&) = delete; lcPiecesLibrary& operator=(lcPiecesLibrary&&) = delete; bool Load(const QString& LibraryPath, bool ShowProgress); void LoadColors(); void Unload(); void RemoveTemporaryPieces(); void RemovePiece(PieceInfo* Info); void RenamePiece(PieceInfo* Info, const char* NewName); PieceInfo* FindPiece(const char* PieceName, Project* Project, bool CreatePlaceholder, bool SearchProjectFolder); void LoadPieceInfo(PieceInfo* Info, bool Wait, bool Priority); void ReleasePieceInfo(PieceInfo* Info); bool LoadBuiltinPieces(); bool LoadPieceData(PieceInfo* Info); void LoadQueuedPiece(); void WaitForLoadQueue(); lcTexture* FindTexture(const char* TextureName, Project* CurrentProject, bool SearchProjectFolder); bool LoadTexture(lcTexture* Texture); void ReleaseTexture(lcTexture* Texture); bool PieceInCategory(PieceInfo* Info, const char* CategoryKeywords) const; void GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray& SinglePieces, lcArray& GroupedPieces); void GetCategoryEntries(const char* CategoryKeywords, bool GroupPieces, lcArray& SinglePieces, lcArray& GroupedPieces); void GetPatternedPieces(PieceInfo* Parent, lcArray& Pieces) const; void GetParts(lcArray& Parts) const; std::vector GetPartsFromSet(const std::vector& PartIds) const; std::string GetPartId(const PieceInfo* Info) const; void GetPrimitiveFile(lcLibraryPrimitive* Primitive, std::function Callback); void GetPieceFile(const char* FileName, std::function Callback); bool IsPrimitive(const char* Name) const; lcLibraryPrimitive* FindPrimitive(const char* Name) const; bool LoadPrimitive(lcLibraryPrimitive* Primitive); bool SupportsStudStyle() const; void SetStudStyle(lcStudStyle StudStyle, bool Reload); lcStudStyle GetStudStyle() const { return mStudStyle; } void SetOfficialPieces() { if (mZipFiles[static_cast(lcZipFileType::Official)]) mNumOfficialPieces = (int)mPieces.size(); } bool ShouldCancelLoading() const { return mCancelLoading; } void UpdateBuffers(lcContext* Context); void UnloadUnusedParts(); std::map mPieces; int mNumOfficialPieces; std::vector mTextures; QDir mLibraryDir; bool mBuffersDirty; lcVertexBuffer mVertexBuffer; lcIndexBuffer mIndexBuffer; signals: void PartLoaded(PieceInfo* Info); void ColorsLoaded(); protected: bool OpenArchive(const QString& FileName, lcZipFileType ZipFileType); bool OpenArchive(std::unique_ptr File, lcZipFileType ZipFileType); bool OpenDirectory(const QDir& LibraryDir, bool ShowProgress); void ReadArchiveDescriptions(const QString& OfficialFileName, const QString& UnofficialFileName); void ReadDirectoryDescriptions(const QFileInfoList (&FileLists)[static_cast(lcLibraryFolderType::Count)], bool ShowProgress); bool ReadArchiveCacheFile(const QString& FileName, lcMemFile& CacheFile); bool WriteArchiveCacheFile(const QString& FileName, lcMemFile& CacheFile); bool LoadCacheIndex(const QString& FileName); bool SaveArchiveCacheIndex(const QString& FileName); bool LoadCachePiece(PieceInfo* Info); bool SaveCachePiece(PieceInfo* Info); bool ReadDirectoryCacheFile(const QString& FileName, lcMemFile& CacheFile); bool WriteDirectoryCacheFile(const QString& FileName, lcMemFile& CacheFile); static bool IsStudPrimitive(const char* FileName); static bool IsStudStylePrimitive(const char* FileName); void UpdateStudStyleSource(); void ReleaseBuffers(); std::vector> mSources; #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QRecursiveMutex mLoadMutex; #else QMutex mLoadMutex; #endif QList> mLoadFutures; QList mLoadQueue; QMutex mTextureMutex; lcStudStyle mStudStyle; QString mCachePath; qint64 mArchiveCheckSum[4]; std::unique_ptr mZipFiles[static_cast(lcZipFileType::Count)]; bool mHasUnofficial; bool mCancelLoading; }; leocad-23.03/common/lc_lxf.cpp000066400000000000000000000156351440571307300162310ustar00rootroot00000000000000#include "lc_global.h" #include "lc_lxf.h" #include "lc_library.h" #include "lc_application.h" #include "lc_mainwindow.h" #include "piece.h" #include "lc_file.h" #include static bool lcLoadLDrawXML(std::map& MaterialTable, std::map& BrickTable, std::map>& TransformTable) { QFile File(lcGetPiecesLibrary()->mLibraryDir.absoluteFilePath(QLatin1String("ldraw.xml"))); QByteArray Data; if (File.open(QIODevice::ReadOnly)) Data = File.readAll(); else { QFile DefaultFile(":/resources/ldraw.xml"); if (DefaultFile.open(QIODevice::ReadOnly)) Data = DefaultFile.readAll(); } if (Data.isEmpty()) return false; QDomDocument Document; Document.setContent(QString::fromUtf8(Data)); QDomElement Root = Document.documentElement(); if (Root.tagName() != QLatin1String("LDrawMapping")) return false; for (QDomNode Node = Root.firstChild(); !Node.isNull(); Node = Node.nextSibling()) { QDomElement Element = Node.toElement(); QString ElementName = Element.tagName(); if (ElementName == QLatin1String("Material")) { int LDrawColor = Element.attribute(QLatin1String("ldraw")).toInt(); int LegoColor = Element.attribute(QLatin1String("lego")).toInt(); MaterialTable[LegoColor] = LDrawColor; } else if (ElementName == QLatin1String("Brick")) { QString LDrawID = Element.attribute(QLatin1String("ldraw")); int LegoID = Element.attribute(QLatin1String("lego")).toInt(); BrickTable.insert(std::make_pair(LegoID, LDrawID.toStdString())); } else if (ElementName == QLatin1String("Transformation")) { QString LDrawID = Element.attribute(QLatin1String("ldraw")); lcVector3 Translation; lcVector4 AxisAngle; Translation[0] = Element.attribute(QLatin1String("tx")).toFloat(); Translation[1] = Element.attribute(QLatin1String("ty")).toFloat(); Translation[2] = Element.attribute(QLatin1String("tz")).toFloat(); AxisAngle[0] = Element.attribute(QLatin1String("ax")).toFloat(); AxisAngle[1] = Element.attribute(QLatin1String("ay")).toFloat(); AxisAngle[2] = Element.attribute(QLatin1String("az")).toFloat(); AxisAngle[3] = Element.attribute(QLatin1String("angle")).toFloat(); TransformTable.insert(std::make_pair(LDrawID.toStdString(), std::make_pair(Translation, AxisAngle))); } } return true; } bool lcImportLXFMLFile(const QString& FileData, std::vector& Pieces, std::vector>& Groups) { std::map MaterialTable; std::map BrickTable; std::map> TransformTable; if (!lcLoadLDrawXML(MaterialTable, BrickTable, TransformTable)) return false; QDomDocument Document; Document.setContent(FileData); QDomElement Root = Document.documentElement(); if (Root.tagName() != QLatin1String("LXFML")) return false; for (QDomNode SectionNode = Root.firstChild(); !SectionNode.isNull(); SectionNode = SectionNode.nextSibling()) { QDomElement SectionElement = SectionNode.toElement(); if (SectionElement.tagName() != QLatin1String("Bricks")) continue; for (QDomNode BrickNode = SectionElement.firstChild(); !BrickNode.isNull(); BrickNode = BrickNode.nextSibling()) { QDomElement BrickElement = BrickNode.toElement(); if (BrickElement.tagName() != QLatin1String("Brick")) continue; int NumBrickPieces = 0; for (QDomNode PartNode = BrickElement.firstChild(); !PartNode.isNull(); PartNode = PartNode.nextSibling()) { QDomElement PartElement = PartNode.toElement(); if (PartElement.tagName() != QLatin1String("Part")) continue; bool BoneFound = false; lcMatrix44 WorldMatrix; for (QDomNode BoneNode = PartElement.firstChild(); !BoneNode.isNull(); BoneNode = BoneNode.nextSibling()) { QDomElement BoneElement = BoneNode.toElement(); if (BoneElement.tagName() != QLatin1String("Bone")) continue; QString BoneTransform = BoneElement.attribute(QLatin1String("transformation")); QStringList BoneElements = BoneTransform.split(','); if (BoneElements.size() != 12) continue; WorldMatrix[0][0] = BoneElements[0].toFloat(); WorldMatrix[0][1] = BoneElements[1].toFloat(); WorldMatrix[0][2] = BoneElements[2].toFloat(); WorldMatrix[0][3] = 0.0f; WorldMatrix[1][0] = BoneElements[3].toFloat(); WorldMatrix[1][1] = BoneElements[4].toFloat(); WorldMatrix[1][2] = BoneElements[5].toFloat(); WorldMatrix[1][3] = 0.0f; WorldMatrix[2][0] = BoneElements[6].toFloat(); WorldMatrix[2][1] = BoneElements[7].toFloat(); WorldMatrix[2][2] = BoneElements[8].toFloat(); WorldMatrix[3][3] = 0.0f; WorldMatrix[3][0] = BoneElements[9].toFloat(); WorldMatrix[3][1] = BoneElements[10].toFloat(); WorldMatrix[3][2] = BoneElements[11].toFloat(); WorldMatrix[3][3] = 1.0f; BoneFound = true; break; } if (!BoneFound) continue; QString LegoID = PartElement.attribute(QLatin1String("designID")); int Material = PartElement.attribute(QLatin1String("materials")).split(',').first().toInt(); PieceInfo* Info = nullptr; const auto BrickIt = BrickTable.find(LegoID.toInt()); if (BrickIt != BrickTable.end()) Info = lcGetPiecesLibrary()->FindPiece(BrickIt->second.c_str(), nullptr, true, false); else Info = lcGetPiecesLibrary()->FindPiece(LegoID.toLatin1() + ".dat", nullptr, true, false); const auto ColorIt = MaterialTable.find(Material); int ColorCode = 16; if (ColorIt != MaterialTable.end()) ColorCode = ColorIt->second; const auto TransformIt = TransformTable.find(BrickIt != BrickTable.end() ? BrickIt->second : (LegoID.toStdString() + ".dat")); if (TransformIt != TransformTable.end()) { const lcVector4& AxisAngle = TransformIt->second.second; const lcVector3& TransformTranslation = TransformIt->second.first; lcMatrix44 Transform = lcMatrix44FromAxisAngle(lcVector3(AxisAngle[0], AxisAngle[1], AxisAngle[2]), -AxisAngle[3]); Transform.SetTranslation(lcMul30(-TransformTranslation, Transform)); WorldMatrix = lcMul(Transform, WorldMatrix); } WorldMatrix = lcMatrix44(lcVector4(WorldMatrix[0][0], -WorldMatrix[0][1], -WorldMatrix[0][2], 0.0f), lcVector4(-WorldMatrix[1][0], WorldMatrix[1][1], WorldMatrix[1][2], 0.0f), lcVector4(-WorldMatrix[2][0], WorldMatrix[2][1], WorldMatrix[2][2], 0.0f), lcVector4(WorldMatrix[3][0] * 25.0f, -WorldMatrix[3][1] * 25.0f, -WorldMatrix[3][2] * 25.0f, 1.0f)); lcPiece* Piece = new lcPiece(nullptr); Piece->SetPieceInfo(Info, QString(), false); Piece->Initialize(lcMatrix44LDrawToLeoCAD(WorldMatrix), 1); Piece->SetColorCode(ColorCode); Pieces.push_back(Piece); NumBrickPieces++; } if (NumBrickPieces > 1) { std::vector Group; for (size_t PieceIdx = Pieces.size() - NumBrickPieces; PieceIdx < Pieces.size(); PieceIdx++) Group.push_back(Pieces[PieceIdx]); Groups.push_back(Group); } } } return true; } leocad-23.03/common/lc_lxf.h000066400000000000000000000002131440571307300156600ustar00rootroot00000000000000#pragma once bool lcImportLXFMLFile(const QString& FileData, std::vector& Pieces, std::vector>& Groups); leocad-23.03/common/lc_mainwindow.cpp000066400000000000000000002742431440571307300176160ustar00rootroot00000000000000#include "lc_global.h" #include "lc_mainwindow.h" #include #include #include "lc_partselectionwidget.h" #include "lc_timelinewidget.h" #include "lc_viewwidget.h" #include "lc_qcolorlist.h" #include "lc_qpropertiestree.h" #include "lc_qutils.h" #include "lc_qupdatedialog.h" #include "lc_qaboutdialog.h" #include "lc_setsdatabasedialog.h" #include "lc_qhtmldialog.h" #include "lc_renderdialog.h" #include "lc_instructionsdialog.h" #include "lc_profile.h" #include "lc_view.h" #include "project.h" #include "piece.h" #include "camera.h" #include "group.h" #include "pieceinf.h" #include "lc_library.h" #include "lc_colors.h" #include "lc_previewwidget.h" #if LC_ENABLE_GAMEPAD #include #endif lcMainWindow* gMainWindow; #define LC_TAB_LAYOUT_VERSION 0x0001 void lcTabBar::mousePressEvent(QMouseEvent* Event) { if (Event->button() == Qt::MiddleButton) mMousePressTab = tabAt(Event->pos()); else QTabBar::mousePressEvent(Event); } void lcTabBar::mouseReleaseEvent(QMouseEvent* Event) { if (Event->button() == Qt::MiddleButton && tabAt(Event->pos()) == mMousePressTab) tabCloseRequested(mMousePressTab); else QTabBar::mouseReleaseEvent(Event); } lcMainWindow::lcMainWindow() { memset(mActions, 0, sizeof(mActions)); mTransformType = lcTransformType::RelativeTranslation; mColorIndex = lcGetColorIndex(7); mTool = lcTool::Select; mAddKeys = false; mMoveSnapEnabled = true; mAngleSnapEnabled = true; mMoveXYSnapIndex = 4; mMoveZSnapIndex = 3; mAngleSnapIndex = 5; mRelativeTransform = true; mLocalTransform = false; mCurrentPieceInfo = nullptr; mSelectionMode = lcSelectionMode::Single; mModelTabWidget = nullptr; mPreviewToolBar = nullptr; mPreviewWidget = nullptr; for (int FileIdx = 0; FileIdx < LC_MAX_RECENT_FILES; FileIdx++) mRecentFiles[FileIdx] = lcGetProfileString((LC_PROFILE_KEY)(LC_PROFILE_RECENT_FILE1 + FileIdx)); #if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) connect(&mGamepadTimer, &QTimer::timeout, this, &lcMainWindow::UpdateGamepads); mLastGamepadUpdate = QDateTime::currentDateTime(); mGamepadTimer.start(33); #endif gMainWindow = this; } lcMainWindow::~lcMainWindow() { if (mCurrentPieceInfo) { lcPiecesLibrary* Library = lcGetPiecesLibrary(); Library->ReleasePieceInfo(mCurrentPieceInfo); mCurrentPieceInfo = nullptr; } for (int FileIdx = 0; FileIdx < LC_MAX_RECENT_FILES; FileIdx++) lcSetProfileString((LC_PROFILE_KEY)(LC_PROFILE_RECENT_FILE1 + FileIdx), mRecentFiles[FileIdx]); gMainWindow = nullptr; } void lcMainWindow::CreateWidgets() { setAcceptDrops(true); setWindowIcon(QIcon(":/resources/leocad.png")); setWindowFilePath(QString()); CreateActions(); CreateToolBars(); CreateMenus(); CreateStatusBar(); mModelTabWidget = new QTabWidget(); mModelTabWidget->tabBar()->setMovable(true); mModelTabWidget->tabBar()->setTabsClosable(true); mModelTabWidget->tabBar()->setContextMenuPolicy(Qt::CustomContextMenu); setCentralWidget(mModelTabWidget); connect(mModelTabWidget->tabBar(), SIGNAL(tabCloseRequested(int)), this, SLOT(ModelTabClosed(int))); connect(mModelTabWidget->tabBar(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ModelTabContextMenuRequested(const QPoint&))); connect(mModelTabWidget, SIGNAL(currentChanged(int)), this, SLOT(ModelTabChanged(int))); connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(ClipboardChanged())); ClipboardChanged(); QSettings Settings; Settings.beginGroup("MainWindow"); resize(QSize(800, 600)); move(QPoint(200, 200)); restoreGeometry(Settings.value("Geometry").toByteArray()); restoreState(Settings.value("State").toByteArray()); mPartSelectionWidget->LoadState(Settings); Settings.endGroup(); } void lcMainWindow::CreateActions() { for (int CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++) { QAction* Action = new QAction(qApp->translate("Menu", gCommands[CommandIdx].MenuName), this); Action->setStatusTip(qApp->translate("Status", gCommands[CommandIdx].StatusText)); connect(Action, SIGNAL(triggered()), this, SLOT(ActionTriggered())); addAction(Action); mActions[CommandIdx] = Action; } mActions[LC_FILE_NEW]->setToolTip(tr("New Model")); mActions[LC_FILE_OPEN]->setToolTip(tr("Open Model")); mActions[LC_FILE_SAVE]->setToolTip(tr("Save Model")); QIcon FileNewIcon; FileNewIcon.addFile(":/resources/file_new.png"); FileNewIcon.addFile(":/resources/file_new_16.png"); mActions[LC_FILE_NEW]->setIcon(FileNewIcon); QIcon FileSaveIcon; FileSaveIcon.addFile(":/resources/file_save.png"); FileSaveIcon.addFile(":/resources/file_save_16.png"); mActions[LC_FILE_SAVE]->setIcon(FileSaveIcon); QIcon FileOpenIcon; FileOpenIcon.addFile(":/resources/file_open.png"); FileOpenIcon.addFile(":/resources/file_open_16.png"); mActions[LC_FILE_OPEN]->setIcon(FileOpenIcon); QIcon FilePrintIcon; FilePrintIcon.addFile(":/resources/file_print.png"); FilePrintIcon.addFile(":/resources/file_print_16.png"); mActions[LC_FILE_PRINT]->setIcon(FilePrintIcon); QIcon FilePrintPreviewIcon; FilePrintPreviewIcon.addFile(":/resources/file_print_preview.png"); FilePrintPreviewIcon.addFile(":/resources/file_print_preview_16.png"); mActions[LC_FILE_PRINT_PREVIEW]->setIcon(FilePrintPreviewIcon); QIcon EditUndoIcon; EditUndoIcon.addFile(":/resources/edit_undo.png"); EditUndoIcon.addFile(":/resources/edit_undo_16.png"); mActions[LC_EDIT_UNDO]->setIcon(EditUndoIcon); QIcon EditRedoIcon; EditRedoIcon.addFile(":/resources/edit_redo.png"); EditRedoIcon.addFile(":/resources/edit_redo_16.png"); mActions[LC_EDIT_REDO]->setIcon(EditRedoIcon); QIcon EditCutIcon; EditCutIcon.addFile(":/resources/edit_cut.png"); EditCutIcon.addFile(":/resources/edit_cut_16.png"); mActions[LC_EDIT_CUT]->setIcon(EditCutIcon); QIcon EditCopyIcon; EditCopyIcon.addFile(":/resources/edit_copy.png"); EditCopyIcon.addFile(":/resources/edit_copy_16.png"); mActions[LC_EDIT_COPY]->setIcon(EditCopyIcon); QIcon EditPasteIcon; EditPasteIcon.addFile(":/resources/edit_paste.png"); EditPasteIcon.addFile(":/resources/edit_paste_16.png"); mActions[LC_EDIT_PASTE]->setIcon(EditPasteIcon); QIcon EditActionInsertIcon; EditActionInsertIcon.addFile(":/resources/action_insert.png"); EditActionInsertIcon.addFile(":/resources/action_insert_16.png"); mActions[LC_EDIT_ACTION_INSERT]->setIcon(EditActionInsertIcon); QIcon EditActionLightIcon; EditActionLightIcon.addFile(":/resources/action_light.png"); EditActionLightIcon.addFile(":/resources/action_light_16.png"); mActions[LC_EDIT_ACTION_LIGHT]->setIcon(EditActionLightIcon); QIcon EditActionSpotLightIcon; EditActionSpotLightIcon.addFile(":/resources/action_spotlight.png"); EditActionSpotLightIcon.addFile(":/resources/action_spotlight_16.png"); mActions[LC_EDIT_ACTION_SPOTLIGHT]->setIcon(EditActionSpotLightIcon); QIcon EditActionSelectIcon; EditActionSelectIcon.addFile(":/resources/action_select.png"); EditActionSelectIcon.addFile(":/resources/action_select_16.png"); mActions[LC_EDIT_ACTION_SELECT]->setIcon(EditActionSelectIcon); QIcon EditActionMoveIcon; EditActionMoveIcon.addFile(":/resources/action_move.png"); EditActionMoveIcon.addFile(":/resources/action_move_16.png"); mActions[LC_EDIT_ACTION_MOVE]->setIcon(EditActionMoveIcon); QIcon EditActionRotateIcon; EditActionRotateIcon.addFile(":/resources/action_rotate.png"); EditActionRotateIcon.addFile(":/resources/action_rotate_16.png"); mActions[LC_EDIT_ACTION_ROTATE]->setIcon(EditActionRotateIcon); QIcon EditActionDeleteIcon; EditActionDeleteIcon.addFile(":/resources/action_delete.png"); EditActionDeleteIcon.addFile(":/resources/action_delete_16.png"); mActions[LC_EDIT_ACTION_DELETE]->setIcon(EditActionDeleteIcon); QIcon EditActionPaintIcon; EditActionPaintIcon.addFile(":/resources/action_paint.png"); EditActionPaintIcon.addFile(":/resources/action_paint_16.png"); mActions[LC_EDIT_ACTION_PAINT]->setIcon(EditActionPaintIcon); QIcon EditActionColorPickerIcon; EditActionColorPickerIcon.addFile(":/resources/action_color_picker.png"); EditActionColorPickerIcon.addFile(":/resources/action_color_picker_16.png"); mActions[LC_EDIT_ACTION_COLOR_PICKER]->setIcon(EditActionColorPickerIcon); QIcon EditActionZoomIcon; EditActionZoomIcon.addFile(":/resources/action_zoom.png"); EditActionZoomIcon.addFile(":/resources/action_zoom_16.png"); mActions[LC_EDIT_ACTION_ZOOM]->setIcon(EditActionZoomIcon); QIcon EditActionPanIcon; EditActionPanIcon.addFile(":/resources/action_pan.png"); EditActionPanIcon.addFile(":/resources/action_pan_16.png"); mActions[LC_EDIT_ACTION_PAN]->setIcon(EditActionPanIcon); mActions[LC_EDIT_ACTION_CAMERA]->setIcon(QIcon(":/resources/action_camera.png")); mActions[LC_EDIT_ACTION_ROTATE_VIEW]->setIcon(QIcon(":/resources/action_rotate_view.png")); mActions[LC_EDIT_ACTION_ROLL]->setIcon(QIcon(":/resources/action_roll.png")); mActions[LC_EDIT_ACTION_ZOOM_REGION]->setIcon(QIcon(":/resources/action_zoom_region.png")); mActions[LC_EDIT_FIND]->setIcon(QIcon(":/resources/edit_find.png")); mActions[LC_EDIT_FIND_NEXT]->setIcon(QIcon(":/resources/edit_find_next.png")); mActions[LC_EDIT_FIND_PREVIOUS]->setIcon(QIcon(":/resources/edit_find_previous.png")); mActions[LC_EDIT_FIND_ALL]->setIcon(QIcon(":/resources/edit_find_all.png")); mActions[LC_EDIT_REPLACE_NEXT]->setIcon(QIcon(":/resources/edit_replace_next.png")); mActions[LC_EDIT_REPLACE_ALL]->setIcon(QIcon(":/resources/edit_replace_all.png")); mActions[LC_PIECE_SHOW_EARLIER]->setIcon(QIcon(":/resources/piece_show_earlier.png")); mActions[LC_PIECE_SHOW_LATER]->setIcon(QIcon(":/resources/piece_show_later.png")); mActions[LC_VIEW_SPLIT_HORIZONTAL]->setIcon(QIcon(":/resources/view_split_horizontal.png")); mActions[LC_VIEW_SPLIT_VERTICAL]->setIcon(QIcon(":/resources/view_split_vertical.png")); mActions[LC_VIEW_ZOOM_IN]->setIcon(QIcon(":/resources/view_zoomin.png")); mActions[LC_VIEW_ZOOM_OUT]->setIcon(QIcon(":/resources/view_zoomout.png")); mActions[LC_VIEW_ZOOM_EXTENTS]->setIcon(QIcon(":/resources/view_zoomextents.png")); mActions[LC_VIEW_TIME_FIRST]->setIcon(QIcon(":/resources/time_first.png")); mActions[LC_VIEW_TIME_PREVIOUS]->setIcon(QIcon(":/resources/time_previous.png")); mActions[LC_VIEW_TIME_NEXT]->setIcon(QIcon(":/resources/time_next.png")); mActions[LC_VIEW_TIME_LAST]->setIcon(QIcon(":/resources/time_last.png")); mActions[LC_VIEW_TIME_ADD_KEYS]->setIcon(QIcon(":/resources/time_add_keys.png")); mActions[LC_HELP_HOMEPAGE]->setIcon(QIcon(":/resources/help_homepage.png")); mActions[LC_EDIT_SNAP_MOVE_TOGGLE]->setCheckable(true); mActions[LC_EDIT_SNAP_ANGLE_TOGGLE]->setCheckable(true); mActions[LC_VIEW_CAMERA_NONE]->setCheckable(true); mActions[LC_VIEW_TIME_ADD_KEYS]->setCheckable(true); for (int ActionIndex = LC_VIEW_TOOLBAR_FIRST; ActionIndex <= LC_VIEW_TOOLBAR_LAST; ActionIndex++) mActions[ActionIndex]->setCheckable(true); QActionGroup* ActionRelativeGroup = new QActionGroup(this); for (int ActionIdx = LC_EDIT_TRANSFORM_RELATIVE; ActionIdx <= LC_EDIT_TRANSFORM_ABSOLUTE; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ActionRelativeGroup->addAction(mActions[ActionIdx]); } QActionGroup* ActionSeparateGroup = new QActionGroup(this); for (int ActionIdx = LC_EDIT_TRANSFORM_SEPARATELY; ActionIdx <= LC_EDIT_TRANSFORM_TOGETHER; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ActionSeparateGroup->addAction(mActions[ActionIdx]); } QActionGroup* ActionSnapXYGroup = new QActionGroup(this); for (int ActionIdx = LC_EDIT_SNAP_MOVE_XY0; ActionIdx <= LC_EDIT_SNAP_MOVE_XY9; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ActionSnapXYGroup->addAction(mActions[ActionIdx]); } QActionGroup* ActionSnapZGroup = new QActionGroup(this); for (int ActionIdx = LC_EDIT_SNAP_MOVE_Z0; ActionIdx <= LC_EDIT_SNAP_MOVE_Z9; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ActionSnapZGroup->addAction(mActions[ActionIdx]); } QActionGroup* ActionSnapAngleGroup = new QActionGroup(this); for (int ActionIdx = LC_EDIT_SNAP_ANGLE0; ActionIdx <= LC_EDIT_SNAP_ANGLE9; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ActionSnapAngleGroup->addAction(mActions[ActionIdx]); } QActionGroup* ActionTransformTypeGroup = new QActionGroup(this); for (int ActionIdx = LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION; ActionIdx <= LC_EDIT_TRANSFORM_RELATIVE_ROTATION; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ActionTransformTypeGroup->addAction(mActions[ActionIdx]); } QActionGroup* ActionToolGroup = new QActionGroup(this); for (int ActionIdx = LC_EDIT_ACTION_FIRST; ActionIdx <= LC_EDIT_ACTION_LAST; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ActionToolGroup->addAction(mActions[ActionIdx]); } QActionGroup* ActionCameraGroup = new QActionGroup(this); ActionCameraGroup->addAction(mActions[LC_VIEW_CAMERA_NONE]); for (int ActionIdx = LC_VIEW_CAMERA_FIRST; ActionIdx <= LC_VIEW_CAMERA_LAST; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ActionCameraGroup->addAction(mActions[ActionIdx]); } QActionGroup* ActionPerspectiveGroup = new QActionGroup(this); for (int ActionIdx = LC_VIEW_PROJECTION_FIRST; ActionIdx <= LC_VIEW_PROJECTION_LAST; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ActionPerspectiveGroup->addAction(mActions[ActionIdx]); } QActionGroup* ActionShadingGroup = new QActionGroup(this); for (int ActionIdx = LC_VIEW_SHADING_FIRST; ActionIdx <= LC_VIEW_SHADING_LAST; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ActionShadingGroup->addAction(mActions[ActionIdx]); } QActionGroup* SelectionModeGroup = new QActionGroup(this); for (int ActionIdx = LC_EDIT_SELECTION_MODE_FIRST; ActionIdx <= LC_EDIT_SELECTION_MODE_LAST; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); SelectionModeGroup->addAction(mActions[ActionIdx]); } QActionGroup* ModelGroup = new QActionGroup(this); for (int ActionIdx = LC_MODEL_FIRST; ActionIdx <= LC_MODEL_LAST; ActionIdx++) { mActions[ActionIdx]->setCheckable(true); ModelGroup->addAction(mActions[ActionIdx]); } UpdateShortcuts(); } void lcMainWindow::CreateMenus() { QMenu* TransformMenu = new QMenu(tr("Transform"), this); TransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_RELATIVE_TRANSLATION]); TransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION]); TransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_RELATIVE_ROTATION]); TransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_ABSOLUTE_ROTATION]); mActions[LC_EDIT_TRANSFORM]->setMenu(TransformMenu); mCameraMenu = new QMenu(tr("C&ameras"), this); mCameraMenu->addAction(mActions[LC_VIEW_CAMERA_NONE]); for (int actionIdx = LC_VIEW_CAMERA_FIRST; actionIdx <= LC_VIEW_CAMERA_LAST; actionIdx++) mCameraMenu->addAction(mActions[actionIdx]); mViewpointMenu = new QMenu(tr("&Viewpoints"), this); mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_FRONT]); mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_BACK]); mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_LEFT]); mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_RIGHT]); mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_TOP]); mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_BOTTOM]); mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_HOME]); mProjectionMenu = new QMenu(tr("Projection"), this); mProjectionMenu->addAction(mActions[LC_VIEW_PROJECTION_PERSPECTIVE]); mProjectionMenu->addAction(mActions[LC_VIEW_PROJECTION_ORTHO]); mShadingMenu = new QMenu(tr("Sh&ading"), this); mShadingMenu->addAction(mActions[LC_VIEW_SHADING_WIREFRAME]); mShadingMenu->addAction(mActions[LC_VIEW_SHADING_FLAT]); mShadingMenu->addAction(mActions[LC_VIEW_SHADING_DEFAULT_LIGHTS]); mToolsMenu = new QMenu(tr("Tools"), this); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_INSERT]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_LIGHT]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_SPOTLIGHT]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_CAMERA]); mToolsMenu->addSeparator(); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_SELECT]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_MOVE]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_ROTATE]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_DELETE]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_PAINT]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_COLOR_PICKER]); mToolsMenu->addSeparator(); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_ZOOM]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_PAN]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_ROTATE_VIEW]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_ROLL]); mToolsMenu->addAction(mActions[LC_EDIT_ACTION_ZOOM_REGION]); QMenu* FileMenu = menuBar()->addMenu(tr("&File")); FileMenu->addAction(mActions[LC_FILE_NEW]); FileMenu->addAction(mActions[LC_FILE_OPEN]); FileMenu->addAction(mActions[LC_FILE_MERGE]); FileMenu->addSeparator(); FileMenu->addAction(mActions[LC_FILE_SAVE]); FileMenu->addAction(mActions[LC_FILE_SAVEAS]); FileMenu->addAction(mActions[LC_FILE_SAVE_IMAGE]); QMenu* ImportMenu = FileMenu->addMenu(tr("&Import")); ImportMenu->addAction(mActions[LC_FILE_IMPORT_LDD]); ImportMenu->addAction(mActions[LC_FILE_IMPORT_INVENTORY]); QMenu* ExportMenu = FileMenu->addMenu(tr("&Export")); ExportMenu->addAction(mActions[LC_FILE_EXPORT_3DS]); ExportMenu->addAction(mActions[LC_FILE_EXPORT_BRICKLINK]); ExportMenu->addAction(mActions[LC_FILE_EXPORT_COLLADA]); ExportMenu->addAction(mActions[LC_FILE_EXPORT_CSV]); ExportMenu->addAction(mActions[LC_FILE_EXPORT_HTML]); ExportMenu->addAction(mActions[LC_FILE_EXPORT_POVRAY]); ExportMenu->addAction(mActions[LC_FILE_EXPORT_WAVEFRONT]); FileMenu->addSeparator(); FileMenu->addAction(mActions[LC_FILE_RENDER]); FileMenu->addAction(mActions[LC_FILE_INSTRUCTIONS]); FileMenu->addAction(mActions[LC_FILE_PRINT]); FileMenu->addAction(mActions[LC_FILE_PRINT_PREVIEW]); FileMenu->addSeparator(); FileMenu->addAction(mActions[LC_FILE_RECENT1]); FileMenu->addAction(mActions[LC_FILE_RECENT2]); FileMenu->addAction(mActions[LC_FILE_RECENT3]); FileMenu->addAction(mActions[LC_FILE_RECENT4]); mActionFileRecentSeparator = FileMenu->addSeparator(); FileMenu->addAction(mActions[LC_FILE_EXIT]); QMenu* EditMenu = menuBar()->addMenu(tr("&Edit")); EditMenu->addAction(mActions[LC_EDIT_UNDO]); EditMenu->addAction(mActions[LC_EDIT_REDO]); EditMenu->addSeparator(); EditMenu->addAction(mActions[LC_EDIT_CUT]); EditMenu->addAction(mActions[LC_EDIT_COPY]); EditMenu->addAction(mActions[LC_EDIT_PASTE]); EditMenu->addAction(mActions[LC_EDIT_PASTE_STEPS]); EditMenu->addSeparator(); EditMenu->addAction(mActions[LC_EDIT_FIND]); EditMenu->addAction(mActions[LC_EDIT_FIND_NEXT]); EditMenu->addAction(mActions[LC_EDIT_FIND_PREVIOUS]); EditMenu->addAction(mActions[LC_EDIT_REPLACE]); EditMenu->addAction(mActions[LC_EDIT_REPLACE_NEXT]); EditMenu->addSeparator(); EditMenu->addAction(mActions[LC_EDIT_SELECT_ALL]); EditMenu->addAction(mActions[LC_EDIT_SELECT_NONE]); EditMenu->addAction(mActions[LC_EDIT_SELECT_INVERT]); EditMenu->addAction(mActions[LC_EDIT_SELECT_BY_NAME]); EditMenu->addMenu(mSelectionModeMenu); EditMenu->addSeparator(); EditMenu->addMenu(mTransformMenu); EditMenu->addMenu(mToolsMenu); QMenu* ViewMenu = menuBar()->addMenu(tr("&View")); ViewMenu->addAction(mActions[LC_VIEW_PREFERENCES]); ViewMenu->addSeparator(); ViewMenu->addAction(mActions[LC_VIEW_ZOOM_EXTENTS]); ViewMenu->addAction(mActions[LC_VIEW_LOOK_AT]); ViewMenu->addMenu(mViewpointMenu); ViewMenu->addMenu(mCameraMenu); ViewMenu->addMenu(mProjectionMenu); ViewMenu->addMenu(mShadingMenu); QMenu* StepMenu = ViewMenu->addMenu(tr("Ste&p")); StepMenu->addAction(mActions[LC_VIEW_TIME_FIRST]); StepMenu->addAction(mActions[LC_VIEW_TIME_PREVIOUS]); StepMenu->addAction(mActions[LC_VIEW_TIME_NEXT]); StepMenu->addAction(mActions[LC_VIEW_TIME_LAST]); StepMenu->addSeparator(); StepMenu->addAction(mActions[LC_VIEW_TIME_INSERT_BEFORE]); StepMenu->addAction(mActions[LC_VIEW_TIME_INSERT_AFTER]); StepMenu->addAction(mActions[LC_VIEW_TIME_DELETE]); ViewMenu->addSeparator(); ViewMenu->addAction(mActions[LC_VIEW_SPLIT_HORIZONTAL]); ViewMenu->addAction(mActions[LC_VIEW_SPLIT_VERTICAL]); ViewMenu->addAction(mActions[LC_VIEW_REMOVE_VIEW]); ViewMenu->addAction(mActions[LC_VIEW_RESET_VIEWS]); ViewMenu->addSeparator(); QMenu* ToolBarsMenu = ViewMenu->addMenu(tr("T&oolbars")); connect(ToolBarsMenu, SIGNAL(aboutToShow()), this, SLOT(UpdateDockWidgetActions())); ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_PARTS]); ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_COLORS]); ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_PROPERTIES]); ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_TIMELINE]); ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_PREVIEW]); ToolBarsMenu->addSeparator(); ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_STANDARD]); ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_TOOLS]); ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_TIME]); ViewMenu->addAction(mActions[LC_VIEW_FULLSCREEN]); QMenu* PieceMenu = menuBar()->addMenu(tr("&Piece")); PieceMenu->addAction(mActions[LC_PIECE_INSERT]); PieceMenu->addAction(mActions[LC_PIECE_DELETE]); PieceMenu->addAction(mActions[LC_PIECE_DUPLICATE]); PieceMenu->addAction(mActions[LC_PIECE_PAINT_SELECTED]); PieceMenu->addAction(mActions[LC_PIECE_ARRAY]); PieceMenu->addAction(mActions[LC_PIECE_MINIFIG_WIZARD]); PieceMenu->addAction(mActions[LC_PIECE_RESET_PIVOT_POINT]); PieceMenu->addAction(mActions[LC_PIECE_REMOVE_KEY_FRAMES]); PieceMenu->addSeparator(); PieceMenu->addAction(mActions[LC_PIECE_EDIT_SELECTED_SUBMODEL]); PieceMenu->addAction(mActions[LC_PIECE_EDIT_END_SUBMODEL]); PieceMenu->addAction(mActions[LC_PIECE_VIEW_SELECTED_MODEL]); PieceMenu->addAction(mActions[LC_PIECE_INLINE_SELECTED_MODELS]); PieceMenu->addAction(mActions[LC_PIECE_MOVE_SELECTION_TO_MODEL]); PieceMenu->addSeparator(); PieceMenu->addAction(mActions[LC_PIECE_GROUP]); PieceMenu->addAction(mActions[LC_PIECE_UNGROUP]); PieceMenu->addAction(mActions[LC_PIECE_GROUP_REMOVE]); PieceMenu->addAction(mActions[LC_PIECE_GROUP_ADD]); PieceMenu->addAction(mActions[LC_PIECE_GROUP_EDIT]); PieceMenu->addSeparator(); PieceMenu->addAction(mActions[LC_PIECE_HIDE_SELECTED]); PieceMenu->addAction(mActions[LC_PIECE_HIDE_UNSELECTED]); PieceMenu->addAction(mActions[LC_PIECE_UNHIDE_SELECTED]); PieceMenu->addAction(mActions[LC_PIECE_UNHIDE_ALL]); QMenu* ModelMenu = menuBar()->addMenu(tr("Sub&model")); ModelMenu->addAction(mActions[LC_MODEL_PROPERTIES]); ModelMenu->addAction(mActions[LC_MODEL_NEW]); ModelMenu->addAction(mActions[LC_MODEL_LIST]); ModelMenu->addSeparator(); for (int ModelIdx = LC_MODEL_FIRST; ModelIdx <= LC_MODEL_LAST; ModelIdx++) ModelMenu->addAction(mActions[ModelIdx]); QMenu* HelpMenu = menuBar()->addMenu(tr("&Help")); HelpMenu->addAction(mActions[LC_HELP_HOMEPAGE]); HelpMenu->addAction(mActions[LC_HELP_BUG_REPORT]); #if !LC_DISABLE_UPDATE_CHECK HelpMenu->addAction(mActions[LC_HELP_UPDATES]); #endif #ifndef Q_OS_MACOS HelpMenu->addSeparator(); #endif HelpMenu->addAction(mActions[LC_HELP_ABOUT]); } void lcMainWindow::CreateToolBars() { mSelectionModeMenu = new QMenu(tr("Selection Mode"), this); for (int ModeIdx = LC_EDIT_SELECTION_MODE_FIRST; ModeIdx <= LC_EDIT_SELECTION_MODE_LAST; ModeIdx++) mSelectionModeMenu->addAction(mActions[ModeIdx]); QAction* SelectionModeAction = new QAction(tr("Selection Mode"), this); SelectionModeAction->setStatusTip(tr("Change selection mode")); SelectionModeAction->setIcon(QIcon(":/resources/action_select.png")); SelectionModeAction->setMenu(mSelectionModeMenu); mTransformMenu = new QMenu(tr("Transform"), this); mTransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_RELATIVE]); mTransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_ABSOLUTE]); mTransformMenu->addSeparator(); mTransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_TOGETHER]); mTransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_SEPARATELY]); QAction* TransformAction = new QAction(tr("Transform"), this); TransformAction->setStatusTip(tr("Transform Options")); TransformAction->setIcon(QIcon(":/resources/edit_transform_relative.png")); TransformAction->setMenu(mTransformMenu); QMenu* SnapXYMenu = new QMenu(tr("Snap XY"), this); for (int actionIdx = LC_EDIT_SNAP_MOVE_XY0; actionIdx <= LC_EDIT_SNAP_MOVE_XY9; actionIdx++) SnapXYMenu->addAction(mActions[actionIdx]); QMenu* SnapZMenu = new QMenu(tr("Snap Z"), this); for (int actionIdx = LC_EDIT_SNAP_MOVE_Z0; actionIdx <= LC_EDIT_SNAP_MOVE_Z9; actionIdx++) SnapZMenu->addAction(mActions[actionIdx]); QMenu* SnapMenu = new QMenu(tr("Snap Menu"), this); SnapMenu->addAction(mActions[LC_EDIT_SNAP_MOVE_TOGGLE]); SnapMenu->addSeparator(); SnapMenu->addMenu(SnapXYMenu); SnapMenu->addMenu(SnapZMenu); QAction* MoveAction = new QAction(tr("Movement Snap"), this); MoveAction->setStatusTip(tr("Snap translations to fixed intervals")); MoveAction->setIcon(QIcon(":/resources/edit_snap_move.png")); MoveAction->setMenu(SnapMenu); QMenu* SnapAngleMenu = new QMenu(tr("Snap Angle Menu"), this); SnapAngleMenu->addAction(mActions[LC_EDIT_SNAP_ANGLE_TOGGLE]); SnapAngleMenu->addSeparator(); for (int actionIdx = LC_EDIT_SNAP_ANGLE0; actionIdx <= LC_EDIT_SNAP_ANGLE9; actionIdx++) SnapAngleMenu->addAction(mActions[actionIdx]); QAction* AngleAction = new QAction(tr("Rotation Snap"), this); AngleAction->setStatusTip(tr("Snap rotations to fixed intervals")); AngleAction->setIcon(QIcon(":/resources/edit_snap_angle.png")); AngleAction->setMenu(SnapAngleMenu); mStandardToolBar = addToolBar(tr("Standard")); mStandardToolBar->setObjectName("StandardToolbar"); mStandardToolBar->addAction(mActions[LC_FILE_NEW]); mStandardToolBar->addAction(mActions[LC_FILE_OPEN]); mStandardToolBar->addAction(mActions[LC_FILE_SAVE]); mStandardToolBar->addSeparator(); mStandardToolBar->addAction(mActions[LC_EDIT_UNDO]); mStandardToolBar->addAction(mActions[LC_EDIT_REDO]); mStandardToolBar->addSeparator(); mStandardToolBar->addAction(SelectionModeAction); mStandardToolBar->addAction(TransformAction); mStandardToolBar->addAction(MoveAction); mStandardToolBar->addAction(AngleAction); ((QToolButton*)mStandardToolBar->widgetForAction(SelectionModeAction))->setPopupMode(QToolButton::InstantPopup); ((QToolButton*)mStandardToolBar->widgetForAction(TransformAction))->setPopupMode(QToolButton::InstantPopup); ((QToolButton*)mStandardToolBar->widgetForAction(MoveAction))->setPopupMode(QToolButton::InstantPopup); ((QToolButton*)mStandardToolBar->widgetForAction(AngleAction))->setPopupMode(QToolButton::InstantPopup); mTimeToolBar = addToolBar(tr("Time")); mTimeToolBar->setObjectName("TimeToolbar"); mTimeToolBar->addAction(mActions[LC_VIEW_TIME_FIRST]); mTimeToolBar->addAction(mActions[LC_VIEW_TIME_PREVIOUS]); mTimeToolBar->addAction(mActions[LC_VIEW_TIME_NEXT]); mTimeToolBar->addAction(mActions[LC_VIEW_TIME_LAST]); mTimeToolBar->addAction(mActions[LC_VIEW_TIME_ADD_KEYS]); mToolsToolBar = addToolBar(tr("Tools")); mToolsToolBar->setObjectName("ToolsToolbar"); insertToolBarBreak(mToolsToolBar); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_INSERT]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_LIGHT]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_SPOTLIGHT]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_CAMERA]); mToolsToolBar->addSeparator(); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_SELECT]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_MOVE]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_ROTATE]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_DELETE]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_PAINT]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_COLOR_PICKER]); mToolsToolBar->addSeparator(); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_ZOOM]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_PAN]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_ROTATE_VIEW]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_ROLL]); mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_ZOOM_REGION]); mToolsToolBar->hide(); mPartsToolBar = new QDockWidget(tr("Parts"), this); mPartsToolBar->setObjectName("PartsToolbar"); mPartSelectionWidget = new lcPartSelectionWidget(mPartsToolBar); mPartsToolBar->setWidget(mPartSelectionWidget); addDockWidget(Qt::RightDockWidgetArea, mPartsToolBar); mColorsToolBar = new QDockWidget(tr("Colors"), this); mColorsToolBar->setObjectName("ColorsToolbar"); mColorsToolBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); mColorList = new lcQColorList(); connect(mColorList, SIGNAL(colorChanged(int)), this, SLOT(ColorChanged(int))); QWidget* ColorWidget = new QWidget(mColorsToolBar); QVBoxLayout* ColorLayout = new QVBoxLayout(ColorWidget); ColorLayout->setContentsMargins(0, 0, 0, 0); QHBoxLayout* ColorButtonLayout = new QHBoxLayout(); ColorButtonLayout->setContentsMargins(0, 0, 0, 0); ColorLayout->addLayout(ColorButtonLayout); mColorButton = new QToolButton(ColorWidget); mColorButton->setAutoRaise(true); mColorButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mColorButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum); ColorButtonLayout->addWidget(mColorButton); connect(mColorButton, SIGNAL(clicked()), this, SLOT(ColorButtonClicked())); ColorLayout->addWidget(mColorList); mColorsToolBar->setWidget(ColorWidget); addDockWidget(Qt::RightDockWidgetArea, mColorsToolBar); mPropertiesToolBar = new QDockWidget(tr("Properties"), this); mPropertiesToolBar->setObjectName("PropertiesToolbar"); QWidget* PropertiesWidget = new QWidget(mPropertiesToolBar); QVBoxLayout* PropertiesLayout = new QVBoxLayout(PropertiesWidget); PropertiesLayout->setContentsMargins(0, 0, 0, 0); mPropertiesWidget = new lcQPropertiesTree(PropertiesWidget); PropertiesLayout->addWidget(mPropertiesWidget); QHBoxLayout* TransformLayout = new QHBoxLayout; QWidget* TransformWidget = new QWidget(); TransformWidget->setLayout(TransformLayout); QToolButton* TransformButton = new QToolButton(TransformWidget); TransformButton->setDefaultAction(mActions[LC_EDIT_TRANSFORM]); TransformButton->setPopupMode(QToolButton::InstantPopup); TransformLayout->addWidget(TransformButton); mTransformXEdit = new lcTransformLineEdit(); TransformLayout->addWidget(mTransformXEdit); mTransformYEdit = new lcTransformLineEdit(); TransformLayout->addWidget(mTransformYEdit); mTransformZEdit = new lcTransformLineEdit(); TransformLayout->addWidget(mTransformZEdit); PropertiesLayout->addWidget(TransformWidget); connect(mTransformXEdit, SIGNAL(returnPressed()), mActions[LC_EDIT_TRANSFORM], SIGNAL(triggered())); connect(mTransformYEdit, SIGNAL(returnPressed()), mActions[LC_EDIT_TRANSFORM], SIGNAL(triggered())); connect(mTransformZEdit, SIGNAL(returnPressed()), mActions[LC_EDIT_TRANSFORM], SIGNAL(triggered())); mPropertiesToolBar->setWidget(PropertiesWidget); addDockWidget(Qt::RightDockWidgetArea, mPropertiesToolBar); mTimelineToolBar = new QDockWidget(tr("Timeline"), this); mTimelineToolBar->setObjectName("TimelineToolbar"); mTimelineToolBar->setAcceptDrops(true); mTimelineWidget = new lcTimelineWidget(mTimelineToolBar); mTimelineToolBar->setWidget(mTimelineWidget); addDockWidget(Qt::RightDockWidgetArea, mTimelineToolBar); CreatePreviewWidget(); tabifyDockWidget(mPartsToolBar, mPropertiesToolBar); tabifyDockWidget(mPropertiesToolBar, mTimelineToolBar); tabifyDockWidget(mTimelineToolBar, mPreviewToolBar); connect(mPropertiesToolBar, SIGNAL(topLevelChanged(bool)), this, SLOT(EnableWindowFlags(bool))); connect(mTimelineToolBar, SIGNAL(topLevelChanged(bool)), this, SLOT(EnableWindowFlags(bool))); connect(mPartsToolBar, SIGNAL(topLevelChanged(bool)), this, SLOT(EnableWindowFlags(bool))); connect(mColorsToolBar, SIGNAL(topLevelChanged(bool)), this, SLOT(EnableWindowFlags(bool))); mPartsToolBar->raise(); } lcView* lcMainWindow::CreateView(lcModel* Model) { lcView* NewView = new lcView(lcViewType::View, Model); connect(NewView, SIGNAL(CameraChanged()), this, SLOT(ViewCameraChanged())); connect(NewView, SIGNAL(FocusReceived()), this, SLOT(ViewFocusReceived())); AddView(NewView); return NewView; } void lcMainWindow::PreviewPiece(const QString& PartId, int ColorCode, bool ShowPreview) { if (ShowPreview) mPreviewToolBar->show(); mPreviewWidget->SetCurrentPiece(PartId, ColorCode); } void lcMainWindow::CreatePreviewWidget() { mPreviewWidget = new lcPreviewDockWidget(); mPreviewToolBar = new QDockWidget(tr("Preview"), this); mPreviewToolBar->setWindowTitle(tr("Preview")); mPreviewToolBar->setObjectName("PreviewToolBar"); mPreviewToolBar->setWidget(mPreviewWidget); addDockWidget(Qt::RightDockWidgetArea, mPreviewToolBar); connect(mPreviewToolBar, SIGNAL(topLevelChanged(bool)), this, SLOT(EnableWindowFlags(bool))); } void lcMainWindow::TogglePreviewWidget(bool Visible) { if (mPreviewToolBar) { if (Visible) mPreviewToolBar->show(); else mPreviewToolBar->hide(); } else if (Visible) { CreatePreviewWidget(); } } void lcMainWindow::EnableWindowFlags(bool Detached) { if (Detached) { QDockWidget* DockWidget = qobject_cast(sender()); DockWidget->setWindowFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint); if (isVisible()) DockWidget->show(); } } class lcElidedLabel : public QFrame { public: explicit lcElidedLabel(QWidget* Parent = nullptr) : QFrame(Parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); } void setText(const QString& Text) { mText = Text; update(); } protected: void paintEvent(QPaintEvent* event) override; QString mText; }; void lcElidedLabel::paintEvent(QPaintEvent* event) { QFrame::paintEvent(event); QPainter Painter(this); QFontMetrics FontMetrics = Painter.fontMetrics(); int LineSpacing = FontMetrics.lineSpacing(); int y = 0; QTextLayout TextLayout(mText, Painter.font()); TextLayout.beginLayout(); for (;;) { QTextLine Line = TextLayout.createLine(); if (!Line.isValid()) break; Line.setLineWidth(width()); int NextLineY = y + LineSpacing; if (height() >= NextLineY + LineSpacing) { Line.draw(&Painter, QPoint(0, y)); y = NextLineY; } else { QString LastLine = mText.mid(Line.textStart()); QString ElidedLastLine = FontMetrics.elidedText(LastLine, Qt::ElideRight, width()); Painter.drawText(QPoint(0, y + FontMetrics.ascent()), ElidedLastLine); Line = TextLayout.createLine(); break; } } TextLayout.endLayout(); } void lcMainWindow::CreateStatusBar() { QStatusBar* StatusBar = new QStatusBar(this); setStatusBar(StatusBar); mStatusBarLabel = new lcElidedLabel(); StatusBar->addWidget(mStatusBarLabel, 1); mStatusPositionLabel = new QLabel(); StatusBar->addPermanentWidget(mStatusPositionLabel); mStatusSnapLabel = new QLabel(); StatusBar->addPermanentWidget(mStatusSnapLabel); mStatusTimeLabel = new QLabel(); StatusBar->addPermanentWidget(mStatusTimeLabel); } void lcMainWindow::closeEvent(QCloseEvent* Event) { if (SaveProjectIfModified()) { Event->accept(); QSettings Settings; Settings.beginGroup("MainWindow"); Settings.setValue("Geometry", saveGeometry()); Settings.setValue("State", saveState()); mPartSelectionWidget->SaveState(Settings); Settings.endGroup(); gApplication->SaveTabLayout(); } else Event->ignore(); } void lcMainWindow::dragEnterEvent(QDragEnterEvent* Event) { if (Event->mimeData()->hasUrls()) Event->acceptProposedAction(); } void lcMainWindow::dropEvent(QDropEvent* Event) { const QMimeData* MimeData = Event->mimeData(); const QList Urls = MimeData->urls(); for (const QUrl& Url : Urls) if (OpenProject(Url.toLocalFile())) break; } QMenu* lcMainWindow::createPopupMenu() { QMenu* Menu = new QMenu(this); UpdateDockWidgetActions(); Menu->addAction(mActions[LC_VIEW_TOOLBAR_PARTS]); Menu->addAction(mActions[LC_VIEW_TOOLBAR_COLORS]); Menu->addAction(mActions[LC_VIEW_TOOLBAR_PROPERTIES]); Menu->addAction(mActions[LC_VIEW_TOOLBAR_TIMELINE]); Menu->addAction(mActions[LC_VIEW_TOOLBAR_PREVIEW]); Menu->addSeparator(); Menu->addAction(mActions[LC_VIEW_TOOLBAR_STANDARD]); Menu->addAction(mActions[LC_VIEW_TOOLBAR_TOOLS]); Menu->addAction(mActions[LC_VIEW_TOOLBAR_TIME]); return Menu; } void lcMainWindow::UpdateDockWidgetActions() { mActions[LC_VIEW_TOOLBAR_PARTS]->setChecked(mPartsToolBar->isVisible()); mActions[LC_VIEW_TOOLBAR_COLORS]->setChecked(mColorsToolBar->isVisible()); mActions[LC_VIEW_TOOLBAR_PROPERTIES]->setChecked(mPropertiesToolBar->isVisible()); mActions[LC_VIEW_TOOLBAR_TIMELINE]->setChecked(mTimelineToolBar->isVisible()); mActions[LC_VIEW_TOOLBAR_STANDARD]->setChecked(mStandardToolBar->isVisible()); mActions[LC_VIEW_TOOLBAR_TOOLS]->setChecked(mToolsToolBar->isVisible()); mActions[LC_VIEW_TOOLBAR_TIME]->setChecked(mTimeToolBar->isVisible()); mActions[LC_VIEW_TOOLBAR_PREVIEW]->setChecked(mPreviewToolBar->isVisible()); } void lcMainWindow::UpdateGamepads() { #if LC_ENABLE_GAMEPAD QDateTime Now = QDateTime::currentDateTime(); quint64 Elapsed = mLastGamepadUpdate.msecsTo(Now); mLastGamepadUpdate = Now; if (!gMainWindow) return; lcView* ActiveView = GetActiveView(); if (!ActiveView) return; const QList Gamepads = QGamepadManager::instance()->connectedGamepads(); if (Gamepads.isEmpty()) return; QGamepad Gamepad(Gamepads[0]); float Scale = (float)Elapsed / 20.0f; lcVector3 Distance(Scale * Gamepad.axisLeftX(), 0.0f, -Scale * Gamepad.axisLeftY()); if (fabsf(Distance.LengthSquared()) > 0.01f) ActiveView->MoveCamera(Distance); #endif } void lcMainWindow::ModelTabContextMenuRequested(const QPoint& Point) { QMenu* Menu = new QMenu; mModelTabWidgetContextMenuIndex = mModelTabWidget->tabBar()->tabAt(Point); if (mModelTabWidget->count() > 1) Menu->addAction(tr("Close Other Tabs"), this, SLOT(ModelTabCloseOtherTabs())); if (mModelTabWidgetContextMenuIndex == mModelTabWidget->currentIndex()) Menu->addAction(mActions[LC_VIEW_RESET_VIEWS]); Menu->exec(QCursor::pos()); delete Menu; } void lcMainWindow::ModelTabCloseOtherTabs() { if (mModelTabWidgetContextMenuIndex == -1) return; while (mModelTabWidget->count() - 1 > mModelTabWidgetContextMenuIndex) delete mModelTabWidget->widget(mModelTabWidgetContextMenuIndex + 1); while (mModelTabWidget->count() > 1) delete mModelTabWidget->widget(0); } void lcMainWindow::ModelTabClosed(int Index) { if (mModelTabWidget->count() != 1) delete mModelTabWidget->widget(Index); else NewProject(); } void lcMainWindow::ModelTabChanged(int Index) { Project* Project = lcGetActiveProject(); lcModelTabWidget* CurrentTab = (lcModelTabWidget*)mModelTabWidget->widget(Index); Project->SetActiveModel(Project->GetModels().FindIndex(CurrentTab ? CurrentTab->GetModel() : nullptr)); } void lcMainWindow::ClipboardChanged() { const QString MimeType = QLatin1String("application/vnd.leocad-clipboard"); const QMimeData* MimeData = QApplication::clipboard()->mimeData(); QByteArray ClipboardData; if (MimeData && MimeData->hasFormat(MimeType)) ClipboardData = MimeData->data(MimeType); gApplication->SetClipboard(ClipboardData); } void lcMainWindow::ActionTriggered() { QObject* Action = sender(); for (int CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++) { if (Action == mActions[CommandIdx]) { HandleCommand((lcCommandId)CommandIdx); break; } } } void lcMainWindow::ColorChanged(int ColorIndex) { SetColorIndex(ColorIndex); } void lcMainWindow::ColorButtonClicked() { lcModel* ActiveModel = GetActiveModel(); if (ActiveModel) ActiveModel->PaintSelectedPieces(); } void lcMainWindow::ProjectFileChanged(const QString& Path) { static bool Ignore; if (Ignore) return; QString Text = tr("The file '%1' has been modified by another application, do you want to reload it?").arg(QDir::toNativeSeparators(Path)); Project* CurrentProject = lcGetActiveProject(); Ignore = true; if (QMessageBox::question(this, tr("File Changed"), Text, QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { Ignore = false; CurrentProject->MarkAsModified(); UpdateTitle(); return; } Ignore = false; QFileInfo FileInfo(Path); if (FileInfo == QFileInfo(CurrentProject->GetFileName())) { Project* NewProject = new Project; if (NewProject->Load(Path, true)) { QByteArray TabLayout = GetTabLayout(); gApplication->SetProject(NewProject); RestoreTabLayout(TabLayout); lcView::UpdateAllViews(); } } else { PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(FileInfo.fileName().toLatin1(), CurrentProject, false, true); if (Info && Info->IsProject()) Info->GetProject()->Load(Path, true); } } void lcMainWindow::Print(QPrinter* Printer) { #ifndef QT_NO_PRINTER int DocCopies; int PageCopies; lcInstructions* Instructions = lcGetActiveProject()->GetInstructions(); const int PageCount = static_cast(Instructions->mPages.size()); if (Printer->collateCopies()) { DocCopies = 1; PageCopies = Printer->supportsMultipleCopies() ? 1 : Printer->copyCount(); } else { DocCopies = Printer->supportsMultipleCopies() ? 1 : Printer->copyCount(); PageCopies = 1; } int FromPage = Printer->fromPage(); int ToPage = Printer->toPage(); bool Ascending = true; if (FromPage == 0 && ToPage == 0) { FromPage = 1; ToPage = PageCount; } FromPage = qMax(1, FromPage); ToPage = qMin(PageCount, ToPage); if (ToPage < FromPage) return; if (Printer->pageOrder() == QPrinter::LastPageFirst) { int Tmp = FromPage; FromPage = ToPage; ToPage = Tmp; Ascending = false; } QRect PageRect = Printer->pageLayout().paintRectPixels(Printer->resolution()); const int Resolution = Printer->resolution(); const int Margin = Resolution / 2; // todo: user setting QRect MarginRect = QRect(PageRect.left() + Margin, PageRect.top() + Margin, PageRect.width() - Margin * 2, PageRect.height() - Margin * 2); QPainter Painter(Printer); bool FirstPage = true; // TODO: option to print background for (int DocCopy = 0; DocCopy < DocCopies; DocCopy++) { int Page = FromPage; for (;;) { for (int PageCopy = 0; PageCopy < PageCopies; PageCopy++) { if (Printer->printerState() == QPrinter::Aborted || Printer->printerState() == QPrinter::Error) return; if (!FirstPage) Printer->newPage(); else FirstPage = false; int StepWidth = MarginRect.width(); int StepHeight = MarginRect.height(); const lcInstructionsPage& PageLayout = Instructions->mPages[Page - 1]; lcModel* Model = PageLayout.Steps[0].Model; lcStep Step = PageLayout.Steps[0].Step; QImage Image = Model->GetStepImage(false, StepWidth, StepHeight, Step); Painter.drawImage(MarginRect.left(), MarginRect.top(), Image); // TODO: add print options somewhere but Qt doesn't allow changes to the page setup dialog // DWORD dwPrint = theApp.GetProfileInt("Settings","Print", PRINT_NUMBERS|PRINT_BORDER); // if (print text) { QFont Font("Helvetica", 96); Painter.setFont(Font); QFontMetrics FontMetrics(Font); int TextMargin = Resolution / 2; QRect TextRect = QRect(MarginRect.left() + TextMargin, MarginRect.top() + TextMargin, MarginRect.width() - TextMargin * 2, MarginRect.height() - TextMargin * 2); Painter.drawText(TextRect, Qt::AlignTop | Qt::AlignLeft, QString::number(Step)); } /* // if (print border) { QPen BlackPen(Qt::black, 2); Painter.setPen(BlackPen); Painter.drawLine(MarginRect.left(), MarginRect.top(), MarginRect.right(), MarginRect.top()); Painter.drawLine(MarginRect.left(), MarginRect.bottom(), MarginRect.right(), MarginRect.bottom()); Painter.drawLine(MarginRect.left(), MarginRect.top(), MarginRect.left(), MarginRect.bottom()); Painter.drawLine(MarginRect.right(), MarginRect.top(), MarginRect.right(), MarginRect.bottom()); } */ // TODO: print header and footer } if (Page == ToPage) break; if (Ascending) Page++; else Page--; } } #endif } void lcMainWindow::ShowUpdatesDialog() { lcQUpdateDialog Dialog(this, false); Dialog.exec(); } void lcMainWindow::ShowAboutDialog() { lcQAboutDialog Dialog(this); Dialog.exec(); } void lcMainWindow::ShowHTMLDialog() { lcHTMLExportOptions Options(lcGetActiveProject()); lcQHTMLDialog Dialog(this, &Options); if (Dialog.exec() != QDialog::Accepted) return; Options.SaveDefaults(); lcGetActiveProject()->ExportHTML(Options); } void lcMainWindow::ShowRenderDialog() { lcRenderDialog Dialog(this); Dialog.exec(); } void lcMainWindow::ShowInstructionsDialog() { lcInstructionsDialog* Dialog = new lcInstructionsDialog(this, lcGetActiveProject()); Dialog->setWindowModality(Qt::ApplicationModal); Dialog->setAttribute(Qt::WA_DeleteOnClose); Dialog->show(); } void lcMainWindow::ShowPrintDialog() { #ifndef QT_NO_PRINTER int PageCount = static_cast(lcGetActiveProject()->GetInstructions()->mPages.size()); QPrinter Printer(QPrinter::HighResolution); Printer.setFromTo(1, PageCount + 1); QPrintDialog PrintDialog(&Printer, this); if (PrintDialog.exec() == QDialog::Accepted) Print(&Printer); #endif } void lcMainWindow::SetShadingMode(lcShadingMode ShadingMode) { lcGetPreferences().mShadingMode = ShadingMode; UpdateShadingMode(); lcView::UpdateAllViews(); if (mPartSelectionWidget) mPartSelectionWidget->Redraw(); } void lcMainWindow::SetSelectionMode(lcSelectionMode SelectionMode) { mSelectionMode = SelectionMode; UpdateSelectionMode(); } void lcMainWindow::ToggleViewSphere() { lcGetPreferences().mViewSphereEnabled = !lcGetPreferences().mViewSphereEnabled; lcView::UpdateAllViews(); } void lcMainWindow::ToggleAxisIcon() { lcGetPreferences().mDrawAxes = !lcGetPreferences().mDrawAxes; lcView::UpdateAllViews(); } void lcMainWindow::ToggleGrid() { lcGetPreferences().mGridEnabled = !lcGetPreferences().mGridEnabled; lcView::UpdateAllViews(); } void lcMainWindow::ToggleFadePreviousSteps() { lcGetPreferences().mFadeSteps = !lcGetPreferences().mFadeSteps; lcView::UpdateAllViews(); } QByteArray lcMainWindow::GetTabLayout() { QByteArray TabLayoutData; QDataStream DataStream(&TabLayoutData, QIODevice::WriteOnly); DataStream << (quint32)LC_TAB_LAYOUT_VERSION; qint32 NumTabs = mModelTabWidget->count(); DataStream << NumTabs; DataStream << ((lcModelTabWidget*)mModelTabWidget->currentWidget())->GetModel()->GetProperties().mFileName; for (int TabIdx = 0; TabIdx < NumTabs; TabIdx++) { lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->widget(TabIdx); DataStream << TabWidget->GetModel()->GetProperties().mFileName; std::function SaveWidget = [&DataStream, &SaveWidget, &TabWidget](QWidget* Widget) { if (Widget->metaObject() == &lcViewWidget::staticMetaObject) { lcView* CurrentView = ((lcViewWidget*)Widget)->GetView(); DataStream << (qint32)0; DataStream << (qint32)(TabWidget->GetActiveView() == CurrentView ? 1 : 0); const lcCamera* Camera = CurrentView->GetCamera(); if (Camera->IsSimple()) { DataStream << (qint32)0; DataStream << Camera->m_fovy; DataStream << Camera->m_zNear; DataStream << Camera->m_zFar; DataStream << Camera->mPosition; DataStream << Camera->mTargetPosition; DataStream << Camera->mUpVector; } else { DataStream << (qint32)1; DataStream << Camera->GetName(); } } else { QSplitter* Splitter = (QSplitter*)Widget; DataStream << (qint32)(Splitter->orientation() == Qt::Horizontal ? 1 : 2); DataStream << Splitter->sizes(); SaveWidget(Splitter->widget(0)); SaveWidget(Splitter->widget(1)); } }; QLayout* TabLayout = TabWidget->layout(); SaveWidget(TabLayout->itemAt(0)->widget()); } return TabLayoutData; } void lcMainWindow::RestoreTabLayout(const QByteArray& TabLayout) { if (TabLayout.isEmpty()) return; QDataStream DataStream(TabLayout); quint32 Version; DataStream >> Version; if (Version != LC_TAB_LAYOUT_VERSION) return; qint32 NumTabs; DataStream >> NumTabs; QString CurrentTabName; DataStream >> CurrentTabName; RemoveAllModelTabs(); for (int TabIdx = 0; TabIdx < NumTabs; TabIdx++) { QString ModelName; DataStream >> ModelName; lcModel* Model = lcGetActiveProject()->GetModel(ModelName); lcModelTabWidget* TabWidget = nullptr; if (Model) { SetCurrentModelTab(Model); TabWidget = (lcModelTabWidget*)mModelTabWidget->widget(mModelTabWidget->count() - 1); } QWidget* ActiveWidget = nullptr; std::function LoadWidget = [&DataStream, &LoadWidget, &ActiveWidget, this](QWidget* ParentWidget) { qint32 WidgetType; DataStream >> WidgetType; if (WidgetType == 0) { qint32 IsActive; DataStream >> IsActive; if (IsActive) ActiveWidget = ParentWidget; qint32 CameraType; DataStream >> CameraType; lcView* CurrentView = nullptr; if (ParentWidget) CurrentView = ((lcViewWidget*)ParentWidget)->GetView(); if (CameraType == 0) { float FoV, ZNear, ZFar; lcVector3 Position, TargetPosition, UpVector; DataStream >> FoV; DataStream >> ZNear; DataStream >> ZFar; DataStream >> Position; DataStream >> TargetPosition; DataStream >> UpVector; if (CurrentView) { lcCamera* Camera = CurrentView->GetCamera(); if (!std::isnan(FoV)) Camera->m_fovy = FoV; if (!std::isnan(ZNear)) Camera->m_zNear = ZNear; if (!std::isnan(ZFar)) Camera->m_zFar = ZFar; if (!Position.IsNan() && !TargetPosition.IsNan() && !UpVector.IsNan()) { Camera->mPosition = Position; Camera->mTargetPosition = TargetPosition; Camera->mUpVector = UpVector; } Camera->UpdatePosition(1); } } else { QByteArray CameraName; DataStream >> CameraName; if (CurrentView) CurrentView->SetCamera(CameraName); } } else { QList Sizes; DataStream >> Sizes; if (ParentWidget) { ParentWidget->setFocus(); if (WidgetType == 1) SplitVertical(); else SplitHorizontal(); QSplitter* Splitter = (QSplitter*)ParentWidget->parentWidget(); Splitter->setSizes(Sizes); LoadWidget(Splitter->widget(0)); LoadWidget(Splitter->widget(1)); } else { LoadWidget(nullptr); LoadWidget(nullptr); } } }; LoadWidget(TabWidget ? TabWidget->layout()->itemAt(0)->widget() : nullptr); if (ActiveWidget && TabWidget) ActiveWidget->setFocus(); } if (!mModelTabWidget->count()) lcGetActiveProject()->SetActiveModel(0); else lcGetActiveProject()->SetActiveModel(CurrentTabName); } void lcMainWindow::RemoveAllModelTabs() { while (mModelTabWidget->count()) delete mModelTabWidget->widget(0); } void lcMainWindow::CloseCurrentModelTab() { if (mModelTabWidget->count() > 1) delete mModelTabWidget->currentWidget(); else NewProject(); } void lcMainWindow::SetCurrentModelTab(lcModel* Model) { for (int TabIdx = 0; TabIdx < mModelTabWidget->count(); TabIdx++) { lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->widget(TabIdx); if (TabWidget->GetModel() == Model) { mModelTabWidget->setCurrentIndex(TabIdx); return; } } lcModelTabWidget* TabWidget = new lcModelTabWidget(Model); mModelTabWidget->addTab(TabWidget, Model->GetProperties().mFileName); QVBoxLayout* CentralLayout = new QVBoxLayout(TabWidget); CentralLayout->setContentsMargins(0, 0, 0, 0); lcView* NewView = CreateView(Model); lcViewWidget* ViewWidget = new lcViewWidget(TabWidget, NewView); CentralLayout->addWidget(ViewWidget); mModelTabWidget->setCurrentWidget(TabWidget); ViewWidget->show(); ViewWidget->setFocus(); NewView->ZoomExtents(); } void lcMainWindow::AddView(lcView* View) { lcModelTabWidget* TabWidget = GetTabWidgetForModel(View->GetModel()); if (!TabWidget) return; if (!TabWidget->GetActiveView()) { TabWidget->SetActiveView(View); UpdatePerspective(); } } void lcMainWindow::RemoveView(lcView* View) { lcModelTabWidget* TabWidget = GetTabForView(View); if (TabWidget) TabWidget->RemoveView(View); } void lcMainWindow::SetActiveView(lcView* ActiveView) { lcModelTabWidget* TabWidget = GetTabForView(ActiveView); if (!TabWidget) return; lcView* CurrentActiveView = TabWidget->GetActiveView(); if (CurrentActiveView == ActiveView) return; if (CurrentActiveView) CurrentActiveView->SetTopSubmodelActive(); TabWidget->SetActiveView(ActiveView); UpdateCameraMenu(); UpdatePerspective(); } void lcMainWindow::SetTool(lcTool Tool) { mTool = Tool; QAction* Action = mActions[LC_EDIT_ACTION_FIRST + static_cast(mTool)]; if (Action) Action->setChecked(true); lcView::UpdateAllViews(); } void lcMainWindow::SetColorIndex(int ColorIndex) { mColorIndex = ColorIndex; if (mPartSelectionWidget) mPartSelectionWidget->SetColorIndex(ColorIndex); UpdateColor(); } void lcMainWindow::SetMoveSnapEnabled(bool Enabled) { mMoveSnapEnabled = Enabled; UpdateSnap(); } void lcMainWindow::SetAngleSnapEnabled(bool Enabled) { mAngleSnapEnabled = Enabled; UpdateSnap(); } void lcMainWindow::SetMoveXYSnapIndex(int Index) { mMoveXYSnapIndex = Index; UpdateSnap(); } void lcMainWindow::SetMoveZSnapIndex(int Index) { mMoveZSnapIndex = Index; UpdateSnap(); } void lcMainWindow::SetAngleSnapIndex(int Index) { mAngleSnapIndex = Index; UpdateSnap(); } void lcMainWindow::SetRelativeTransform(bool RelativeTransform) { mRelativeTransform = RelativeTransform; UpdateLockSnap(); lcView::UpdateAllViews(); } void lcMainWindow::SetSeparateTransform(bool SelectionTransform) { mLocalTransform = SelectionTransform; UpdateLockSnap(); } void lcMainWindow::SetTransformType(lcTransformType TransformType) { if (TransformType < lcTransformType::First || TransformType >= lcTransformType::Count) return; mTransformType = TransformType; constexpr const char* IconNames[] = { ":/resources/edit_transform_absolute_translation.png", ":/resources/edit_transform_relative_translation.png", ":/resources/edit_transform_absolute_rotation.png", ":/resources/edit_transform_relative_rotation.png" }; LC_ARRAY_SIZE_CHECK(IconNames, lcTransformType::Count); int TransformIndex = static_cast(TransformType); mActions[LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION + TransformIndex]->setChecked(true); mActions[LC_EDIT_TRANSFORM]->setIcon(QIcon(IconNames[TransformIndex])); } void lcMainWindow::SetCurrentPieceInfo(PieceInfo* Info) { lcPiecesLibrary* Library = lcGetPiecesLibrary(); if (mCurrentPieceInfo) Library->ReleasePieceInfo(mCurrentPieceInfo); mCurrentPieceInfo = Info; if (mCurrentPieceInfo) Library->LoadPieceInfo(mCurrentPieceInfo, true, true); } lcVector3 lcMainWindow::GetTransformAmount() { lcVector3 Transform; Transform.x = lcParseValueLocalized(mTransformXEdit->text()); Transform.y = lcParseValueLocalized(mTransformYEdit->text()); Transform.z = lcParseValueLocalized(mTransformZEdit->text()); return Transform; } void lcMainWindow::SplitView(Qt::Orientation Orientation) { QWidget* Focus = focusWidget(); if (Focus->metaObject() != &lcViewWidget::staticMetaObject) return; QWidget* Parent = Focus->parentWidget(); QSplitter* Splitter; QList Sizes; if (Parent->metaObject() == &lcModelTabWidget::staticMetaObject) { Splitter = new QSplitter(Orientation, Parent); Parent->layout()->addWidget(Splitter); Splitter->addWidget(Focus); Splitter->addWidget(new lcViewWidget(mModelTabWidget->currentWidget(), CreateView(GetCurrentTabModel()))); } else { QSplitter* ParentSplitter = (QSplitter*)Parent; Sizes = ParentSplitter->sizes(); int FocusIndex = ParentSplitter->indexOf(Focus); Splitter = new QSplitter(Orientation, Parent); ParentSplitter->insertWidget(FocusIndex, Splitter); Splitter->addWidget(Focus); Splitter->addWidget(new lcViewWidget(mModelTabWidget->currentWidget(), CreateView(GetCurrentTabModel()))); ParentSplitter->setSizes(Sizes); } Sizes.clear(); Sizes.append(10); Sizes.append(10); Splitter->setSizes(Sizes); Focus->setFocus(); } void lcMainWindow::SplitHorizontal() { SplitView(Qt::Vertical); } void lcMainWindow::SplitVertical() { SplitView(Qt::Horizontal); } void lcMainWindow::RemoveActiveView() { QWidget* Focus = focusWidget(); if (Focus->metaObject() != &lcViewWidget::staticMetaObject) return; QWidget* Parent = Focus->parentWidget(); if (Parent->metaObject() == &lcModelTabWidget::staticMetaObject) return; QWidget* ParentParentWidget = Parent->parentWidget(); QSplitter* ParentSplitter = (QSplitter*)Parent; int FocusIndex = ParentSplitter->indexOf(Focus); QWidget* OtherWidget = ParentSplitter->widget(!FocusIndex); if (ParentParentWidget->metaObject() == &lcModelTabWidget::staticMetaObject) { QLayout* CentralLayout = ParentParentWidget->layout(); CentralLayout->addWidget(OtherWidget); CentralLayout->removeWidget(Parent); } else { QSplitter* ParentParentSplitter = (QSplitter*)ParentParentWidget; QList Sizes = ParentParentSplitter->sizes(); int ParentIndex = ParentParentSplitter->indexOf(Parent); Parent->setParent(nullptr); ParentParentSplitter->insertWidget(ParentIndex, OtherWidget); ParentParentSplitter->setSizes(Sizes); } Parent->deleteLater(); if (OtherWidget->metaObject() != &lcViewWidget::staticMetaObject) { lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->currentWidget(); if (TabWidget) OtherWidget = TabWidget->GetAnyViewWidget(); } OtherWidget->setFocus(); } void lcMainWindow::ResetViews() { lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->currentWidget(); if (!TabWidget) return; QLayout* TabLayout = TabWidget->layout(); QWidget* TopWidget = TabLayout->itemAt(0)->widget(); TopWidget->deleteLater(); lcView* NewView = CreateView(TabWidget->GetModel()); lcViewWidget* ViewWidget = new lcViewWidget(TabWidget, NewView); TabLayout->addWidget(ViewWidget); ViewWidget->show(); ViewWidget->setFocus(); NewView->ZoomExtents(); } void lcMainWindow::ToggleDockWidget(QWidget* DockWidget) { if (DockWidget->isHidden()) DockWidget->show(); else DockWidget->hide(); } void lcMainWindow::TogglePrintPreview() { #ifndef QT_NO_PRINTER // todo: print preview inside main window int PageCount = static_cast(lcGetActiveProject()->GetInstructions()->mPages.size()); QPrinter Printer(QPrinter::ScreenResolution); Printer.setFromTo(1, PageCount + 1); QPrintPreviewDialog Preview(&Printer, this); connect(&Preview, SIGNAL(paintRequested(QPrinter*)), SLOT(Print(QPrinter*))); Preview.exec(); #endif } void lcMainWindow::ToggleFullScreen() { // todo: hide toolbars and menu // todo: create fullscreen toolbar or support esc key to go back if (isFullScreen()) showNormal(); else showFullScreen(); } void lcMainWindow::AddRecentFile(const QString& FileName) { QString SavedName = FileName; int FileIdx; QFileInfo FileInfo(FileName); for (FileIdx = 0; FileIdx < LC_MAX_RECENT_FILES; FileIdx++) if (QFileInfo(mRecentFiles[FileIdx]) == FileInfo) break; for (FileIdx = lcMin(FileIdx, LC_MAX_RECENT_FILES - 1); FileIdx > 0; FileIdx--) mRecentFiles[FileIdx] = mRecentFiles[FileIdx - 1]; mRecentFiles[0] = SavedName; UpdateRecentFiles(); } void lcMainWindow::RemoveRecentFile(int FileIndex) { for (int FileIdx = FileIndex; FileIdx < LC_MAX_RECENT_FILES - 1; FileIdx++) mRecentFiles[FileIdx] = mRecentFiles[FileIdx + 1]; mRecentFiles[LC_MAX_RECENT_FILES - 1].clear(); UpdateRecentFiles(); } void lcMainWindow::UpdateSelectedObjects(bool SelectionChanged) { int Flags = 0; lcArray Selection; lcObject* Focus = nullptr; lcModel* ActiveModel = GetActiveModel(); if (ActiveModel) ActiveModel->GetSelectionInformation(&Flags, Selection, &Focus); if (SelectionChanged) { mTimelineWidget->UpdateSelection(); mActions[LC_EDIT_CUT]->setEnabled(Flags & LC_SEL_SELECTED); mActions[LC_EDIT_COPY]->setEnabled(Flags & LC_SEL_SELECTED); mActions[LC_EDIT_FIND]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0); mActions[LC_EDIT_FIND_NEXT]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0); mActions[LC_EDIT_FIND_PREVIOUS]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0); mActions[LC_EDIT_FIND_ALL]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0); mActions[LC_EDIT_REPLACE]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0); mActions[LC_EDIT_REPLACE_NEXT]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0); mActions[LC_EDIT_REPLACE_ALL]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0); mActions[LC_EDIT_SELECT_INVERT]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0); mActions[LC_EDIT_SELECT_BY_NAME]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0); mActions[LC_EDIT_SELECT_NONE]->setEnabled(Flags & LC_SEL_SELECTED); mActions[LC_EDIT_SELECT_ALL]->setEnabled(Flags & LC_SEL_UNSELECTED); mActions[LC_PIECE_DELETE]->setEnabled(Flags & LC_SEL_SELECTED); mActions[LC_PIECE_DUPLICATE]->setEnabled(Flags & LC_SEL_SELECTED); mActions[LC_PIECE_PAINT_SELECTED]->setEnabled(Flags & LC_SEL_PIECE); mActions[LC_PIECE_RESET_PIVOT_POINT]->setEnabled(Flags & LC_SEL_SELECTED); mActions[LC_PIECE_REMOVE_KEY_FRAMES]->setEnabled(Flags & LC_SEL_SELECTED); mActions[LC_PIECE_ARRAY]->setEnabled(Flags & LC_SEL_PIECE); mActions[LC_PIECE_CONTROL_POINT_INSERT]->setEnabled(Flags & LC_SEL_CAN_ADD_CONTROL_POINT); mActions[LC_PIECE_CONTROL_POINT_REMOVE]->setEnabled(Flags & LC_SEL_CAN_REMOVE_CONTROL_POINT); mActions[LC_PIECE_HIDE_SELECTED]->setEnabled(Flags & LC_SEL_VISIBLE_SELECTED); mActions[LC_PIECE_HIDE_UNSELECTED]->setEnabled(Flags & LC_SEL_UNSELECTED); mActions[LC_PIECE_UNHIDE_SELECTED]->setEnabled(Flags & LC_SEL_HIDDEN_SELECTED); mActions[LC_PIECE_UNHIDE_ALL]->setEnabled(Flags & LC_SEL_HIDDEN); mActions[LC_PIECE_VIEW_SELECTED_MODEL]->setEnabled(Flags & LC_SEL_MODEL_SELECTED); mActions[LC_PIECE_MOVE_SELECTION_TO_MODEL]->setEnabled(Flags & LC_SEL_PIECE); mActions[LC_PIECE_INLINE_SELECTED_MODELS]->setEnabled(Flags & LC_SEL_MODEL_SELECTED); mActions[LC_PIECE_EDIT_SELECTED_SUBMODEL]->setEnabled(Flags & LC_SEL_MODEL_SELECTED); mActions[LC_PIECE_GROUP]->setEnabled(Flags & LC_SEL_CAN_GROUP); mActions[LC_PIECE_UNGROUP]->setEnabled(Flags & LC_SEL_GROUPED); mActions[LC_PIECE_GROUP_ADD]->setEnabled((Flags & (LC_SEL_GROUPED | LC_SEL_FOCUS_GROUPED)) == LC_SEL_GROUPED); mActions[LC_PIECE_GROUP_REMOVE]->setEnabled(Flags & LC_SEL_FOCUS_GROUPED); mActions[LC_PIECE_GROUP_EDIT]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0); mActions[LC_PIECE_SHOW_EARLIER]->setEnabled(Flags & LC_SEL_PIECE); // FIXME: disable if current step is 1 mActions[LC_PIECE_SHOW_LATER]->setEnabled(Flags & LC_SEL_PIECE); mActions[LC_TIMELINE_MOVE_SELECTION]->setEnabled(Flags & LC_SEL_PIECE); mActions[LC_TIMELINE_MOVE_SELECTION_BEFORE]->setEnabled(Flags & LC_SEL_PIECE); mActions[LC_TIMELINE_MOVE_SELECTION_AFTER]->setEnabled(Flags & LC_SEL_PIECE); mActions[LC_PIECE_EDIT_END_SUBMODEL]->setEnabled(GetCurrentTabModel() != ActiveModel); } mPropertiesWidget->Update(Selection, Focus); QString Message; if ((Selection.GetSize() == 1) && Focus) { if (Focus->IsPiece()) Message = tr("%1 (ID: %2)").arg(Focus->GetName(), ((lcPiece*)Focus)->GetID()); else Message = Focus->GetName(); } else if (Selection.GetSize() > 0) { Message = tr("%n Object(s) selected", "", Selection.GetSize()); if (Focus && Focus->IsPiece()) { Message.append(tr(" - %1 (ID: %2)").arg(Focus->GetName(), ((lcPiece*)Focus)->GetID())); const lcGroup* Group = ((lcPiece*)Focus)->GetGroup(); if (Group && !Group->mName.isEmpty()) Message.append(tr(" in group '%1'").arg(Group->mName)); } } mStatusBarLabel->setText(Message); lcVector3 Position; lcGetActiveModel()->GetFocusPosition(Position); QString Label("X: %1 Y: %2 Z: %3"); Label = Label.arg(QLocale::system().toString(Position[0], 'f', 2), QLocale::system().toString(Position[1], 'f', 2), QLocale::system().toString(Position[2], 'f', 2)); mStatusPositionLabel->setText(Label); } void lcMainWindow::UpdateTimeline(bool Clear, bool UpdateItems) { mTimelineWidget->Update(Clear, UpdateItems); } void lcMainWindow::UpdatePaste(bool Enabled) { if (mActions[LC_EDIT_PASTE]) mActions[LC_EDIT_PASTE]->setEnabled(Enabled); if (mActions[LC_EDIT_PASTE_STEPS]) mActions[LC_EDIT_PASTE_STEPS]->setEnabled(Enabled); } void lcMainWindow::UpdateCurrentStep() { lcModel* Model = lcGetActiveModel(); lcStep CurrentStep = Model->GetCurrentStep(); lcStep LastStep = Model->GetLastStep(); mActions[LC_VIEW_TIME_FIRST]->setEnabled(CurrentStep != 1); mActions[LC_VIEW_TIME_PREVIOUS]->setEnabled(CurrentStep > 1); mActions[LC_VIEW_TIME_NEXT]->setEnabled(CurrentStep < LC_STEP_MAX); mActions[LC_VIEW_TIME_LAST]->setEnabled(CurrentStep != LastStep); mStatusTimeLabel->setText(QString(tr("Step %1")).arg(QString::number(CurrentStep))); } void lcMainWindow::SetAddKeys(bool AddKeys) { QAction* Action = mActions[LC_VIEW_TIME_ADD_KEYS]; if (Action) Action->setChecked(AddKeys); mAddKeys = AddKeys; } void lcMainWindow::UpdateLockSnap() { if (GetRelativeTransform()) mActions[LC_EDIT_TRANSFORM_RELATIVE]->setChecked(true); else mActions[LC_EDIT_TRANSFORM_ABSOLUTE]->setChecked(true); if (GetSeparateTransform()) mActions[LC_EDIT_TRANSFORM_SEPARATELY]->setChecked(true); else mActions[LC_EDIT_TRANSFORM_TOGETHER]->setChecked(true); UpdateSnap(); } void lcMainWindow::UpdateSnap() { mActions[LC_EDIT_SNAP_MOVE_TOGGLE]->setChecked(mMoveSnapEnabled); mActions[LC_EDIT_SNAP_ANGLE_TOGGLE]->setChecked(mAngleSnapEnabled); mActions[LC_EDIT_SNAP_MOVE_XY0 + mMoveXYSnapIndex]->setChecked(true); mActions[LC_EDIT_SNAP_MOVE_Z0 + mMoveZSnapIndex]->setChecked(true); mActions[LC_EDIT_SNAP_ANGLE0 + mAngleSnapIndex]->setChecked(true); QString Relative = mRelativeTransform ? tr("Rel") : tr("Abs"); mStatusSnapLabel->setText(QString(tr(" M: %1 %2 R: %3 %4 ")).arg(GetMoveXYSnapText(), GetMoveZSnapText(), GetAngleSnapText(), Relative)); } void lcMainWindow::UpdateColor() { QPixmap Pixmap(14, 14); Pixmap.fill(QColor::fromRgbF(gColorList[mColorIndex].Value[0], gColorList[mColorIndex].Value[1], gColorList[mColorIndex].Value[2])); mColorButton->setIcon(Pixmap); mColorButton->setText(QString(" ") + gColorList[mColorIndex].Name); mColorList->setCurrentColor(mColorIndex); } void lcMainWindow::UpdateUndoRedo(const QString& UndoText, const QString& RedoText) { QAction* UndoAction = mActions[LC_EDIT_UNDO]; QAction* RedoAction = mActions[LC_EDIT_REDO]; if (!UndoText.isEmpty()) { UndoAction->setEnabled(true); UndoAction->setText(QString(tr("&Undo %1")).arg(UndoText)); } else { UndoAction->setEnabled(false); UndoAction->setText(tr("&Undo")); } if (!RedoText.isEmpty()) { RedoAction->setEnabled(true); RedoAction->setText(QString(tr("&Redo %1")).arg(RedoText)); } else { RedoAction->setEnabled(false); RedoAction->setText(tr("&Redo")); } } void lcMainWindow::ViewFocusReceived() { SetActiveView(qobject_cast(sender())); } void lcMainWindow::ViewCameraChanged() { lcView* View = qobject_cast(sender()); if (!View || !View->IsLastFocused()) return; UpdateCameraMenu(); } void lcMainWindow::UpdateCameraMenu() { const lcArray& Cameras = lcGetActiveModel()->GetCameras(); lcView* ActiveView = GetActiveView(); const lcCamera* CurrentCamera = ActiveView ? ActiveView->GetCamera() : nullptr; bool CurrentSet = false; for (int ActionIdx = LC_VIEW_CAMERA_FIRST; ActionIdx <= LC_VIEW_CAMERA_LAST; ActionIdx++) { QAction* Action = mActions[ActionIdx]; int CameraIdx = ActionIdx - LC_VIEW_CAMERA_FIRST; if (CameraIdx < Cameras.GetSize()) { if (CurrentCamera == Cameras[CameraIdx]) { Action->setChecked(true); CurrentSet = true; } Action->setText(Cameras[CameraIdx]->GetName()); Action->setVisible(true); } else Action->setVisible(false); } if (!CurrentSet) mActions[LC_VIEW_CAMERA_NONE]->setChecked(true); UpdatePerspective(); } void lcMainWindow::UpdatePerspective() { lcView* ActiveView = GetActiveView(); if (ActiveView) { if (ActiveView->GetCamera()->IsOrtho()) mActions[LC_VIEW_PROJECTION_ORTHO]->setChecked(true); else mActions[LC_VIEW_PROJECTION_PERSPECTIVE]->setChecked(true); } } void lcMainWindow::UpdateShadingMode() { mActions[LC_VIEW_SHADING_FIRST + static_cast(lcGetPreferences().mShadingMode)]->setChecked(true); } void lcMainWindow::UpdateSelectionMode() { switch (mSelectionMode) { case lcSelectionMode::Single: mActions[LC_EDIT_SELECTION_SINGLE]->setChecked(true); break; case lcSelectionMode::Piece: mActions[LC_EDIT_SELECTION_PIECE]->setChecked(true); break; case lcSelectionMode::Color: mActions[LC_EDIT_SELECTION_COLOR]->setChecked(true); break; case lcSelectionMode::PieceColor: mActions[LC_EDIT_SELECTION_PIECE_COLOR]->setChecked(true); break; } } void lcMainWindow::UpdateModels() { const lcArray& Models = lcGetActiveProject()->GetModels(); lcModel* CurrentModel = lcGetActiveModel(); for (int ActionIdx = LC_MODEL_FIRST; ActionIdx <= LC_MODEL_LAST; ActionIdx++) { QAction* Action = mActions[ActionIdx]; int ModelIdx = ActionIdx - LC_MODEL_FIRST; if (ModelIdx < Models.GetSize()) { Action->setChecked(CurrentModel == Models[ModelIdx]); Action->setText(QString::fromLatin1("%1%2 %3").arg(ModelIdx < 9 ? QString("&") : QString(), QString::number(ModelIdx + 1), Models[ModelIdx]->GetProperties().mFileName)); Action->setVisible(true); } else Action->setVisible(false); } for (int TabIdx = 0; TabIdx < mModelTabWidget->count(); ) { lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->widget(TabIdx); lcModel* Model = TabWidget->GetModel(); if (!Model) TabIdx++; else if (Models.FindIndex(Model) != -1) { mModelTabWidget->setTabText(TabIdx, Model->GetProperties().mFileName); TabIdx++; } else delete TabWidget; } mPartSelectionWidget->UpdateModels(); if (mCurrentPieceInfo && mCurrentPieceInfo->IsModel()) if (Models.FindIndex(mCurrentPieceInfo->GetModel()) == -1) SetCurrentPieceInfo(nullptr); } void lcMainWindow::UpdateCategories() { mPartSelectionWidget->UpdateCategories(); } void lcMainWindow::UpdateTitle() { setWindowModified(lcGetActiveProject()->IsModified()); setWindowFilePath(lcGetActiveProject()->GetTitle()); } void lcMainWindow::UpdateModified(bool Modified) { setWindowModified(Modified); } void lcMainWindow::UpdateRecentFiles() { for (int ActionIdx = LC_FILE_RECENT_FIRST; ActionIdx <= LC_FILE_RECENT_LAST; ActionIdx++) { int FileIdx = ActionIdx - LC_FILE_RECENT_FIRST; QAction* Action = mActions[ActionIdx]; if (!mRecentFiles[FileIdx].isEmpty()) { Action->setText(QString("&%1 %2").arg(QString::number(FileIdx + 1), QDir::toNativeSeparators(mRecentFiles[FileIdx]))); Action->setVisible(true); } else Action->setVisible(false); } mActionFileRecentSeparator->setVisible(!mRecentFiles[0].isEmpty()); } void lcMainWindow::UpdateShortcuts() { for (int ActionIdx = 0; ActionIdx < LC_NUM_COMMANDS; ActionIdx++) mActions[ActionIdx]->setShortcut(QKeySequence(gKeyboardShortcuts.mShortcuts[ActionIdx])); } void lcMainWindow::NewProject() { if (!SaveProjectIfModified()) return; Project* NewProject = new Project(); gApplication->SetProject(NewProject); lcGetPiecesLibrary()->UnloadUnusedParts(); } bool lcMainWindow::OpenProject(const QString& FileName) { if (!SaveProjectIfModified()) return false; QString LoadFileName = FileName; if (LoadFileName.isEmpty()) { LoadFileName = lcGetActiveProject()->GetFileName(); if (LoadFileName.isEmpty()) LoadFileName = lcGetProfileString(LC_PROFILE_PROJECTS_PATH); LoadFileName = QFileDialog::getOpenFileName(this, tr("Open Model"), LoadFileName, tr("Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*)")); if (LoadFileName.isEmpty()) return false; lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(LoadFileName).absolutePath()); } return OpenProjectFile(LoadFileName); } void lcMainWindow::OpenRecentProject(int RecentFileIndex) { if (!SaveProjectIfModified()) return; if (!OpenProjectFile(mRecentFiles[RecentFileIndex])) RemoveRecentFile(RecentFileIndex); } bool lcMainWindow::OpenProjectFile(const QString& FileName) { Project* NewProject = new Project(); if (NewProject->Load(FileName, true)) { gApplication->SetProject(NewProject); AddRecentFile(FileName); lcView::UpdateProjectViews(NewProject); return true; } delete NewProject; return false; } void lcMainWindow::MergeProject() { QString LoadFileName = lcGetActiveProject()->GetFileName(); if (LoadFileName.isEmpty()) LoadFileName = lcGetProfileString(LC_PROFILE_PROJECTS_PATH); LoadFileName = QFileDialog::getOpenFileName(this, tr("Merge Model"), LoadFileName, tr("Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*)")); if (LoadFileName.isEmpty()) return; lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(LoadFileName).absolutePath()); Project* NewProject = new Project(); if (NewProject->Load(LoadFileName, true)) { int NumModels = NewProject->GetModels().GetSize(); lcGetActiveProject()->Merge(NewProject); if (NumModels == 1) QMessageBox::information(this, tr("LeoCAD"), tr("Merged 1 submodel.")); else QMessageBox::information(this, tr("LeoCAD"), tr("Merged %1 submodels.").arg(NumModels)); UpdateModels(); } delete NewProject; } void lcMainWindow::ImportLDD() { if (!SaveProjectIfModified()) return; QString LoadFileName = QFileDialog::getOpenFileName(this, tr("Import"), QString(), tr("LEGO Diginal Designer Files (*.lxf);;All Files (*.*)")); if (LoadFileName.isEmpty()) return; Project* NewProject = new Project(); if (NewProject->ImportLDD(LoadFileName)) { gApplication->SetProject(NewProject); lcView::UpdateProjectViews(NewProject); } else delete NewProject; } void lcMainWindow::ImportInventory() { if (!SaveProjectIfModified()) return; lcSetsDatabaseDialog Dialog(this); if (Dialog.exec() != QDialog::Accepted) return; Project* NewProject = new Project(); if (NewProject->ImportInventory(Dialog.GetSetInventory(), Dialog.GetSetName(), Dialog.GetSetDescription())) { gApplication->SetProject(NewProject); lcView::UpdateProjectViews(NewProject); } else delete NewProject; } bool lcMainWindow::SaveProject(const QString& FileName) { QString SaveFileName = FileName; Project* Project = lcGetActiveProject(); if (SaveFileName.isEmpty()) { SaveFileName = Project->GetFileName(); if (SaveFileName.isEmpty()) SaveFileName = QFileInfo(QDir(lcGetProfileString(LC_PROFILE_PROJECTS_PATH)), Project->GetTitle()).absoluteFilePath(); QString Filter = (Project->GetModels().GetSize() > 1) ? tr("Supported Files (*.mpd);;All Files (*.*)") : tr("Supported Files (*.ldr *.dat *.mpd);;All Files (*.*)"); SaveFileName = QFileDialog::getSaveFileName(this, tr("Save Model"), SaveFileName, Filter); if (SaveFileName.isEmpty()) return false; lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(SaveFileName).absolutePath()); } if (QFileInfo(SaveFileName).suffix().toLower() == QLatin1String("lcd")) { QMessageBox::warning(this, tr("Error"), tr("Saving files in LCD format is no longer supported, please use the LDR or MPD formats instead.")); return false; } if (!Project->Save(SaveFileName)) return false; AddRecentFile(SaveFileName); UpdateTitle(); return true; } bool lcMainWindow::SaveProjectIfModified() { Project* Project = lcGetActiveProject(); if (!Project->IsModified()) return true; switch (QMessageBox::question(this, tr("Save Model"), tr("Save changes to '%1'?").arg(Project->GetTitle()), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel)) { default: case QMessageBox::Cancel: return false; case QMessageBox::Yes: if (!SaveProject(Project->GetFileName())) return false; break; case QMessageBox::No: break; } return true; } bool lcMainWindow::SetModelFromFocus() { lcObject* FocusObject = GetActiveModel()->GetFocusObject(); if (!FocusObject || !FocusObject->IsPiece()) return false; lcModel* Model = ((lcPiece*)FocusObject)->mPieceInfo->GetModel(); if (Model) { Project* Project = lcGetActiveProject(); Project->SetActiveModel(Project->GetModels().FindIndex(Model)); return true; } return false; } void lcMainWindow::SetModelFromSelection() { if (SetModelFromFocus()) return; lcModel* Model = GetActiveModel()->GetFirstSelectedSubmodel(); if (Model) { Project* Project = lcGetActiveProject(); Project->SetActiveModel(Project->GetModels().FindIndex(Model)); } } lcModel* lcMainWindow::GetActiveModel() const { lcView* ActiveView = GetActiveView(); return ActiveView ? ActiveView->GetActiveModel() : nullptr; } lcModelTabWidget* lcMainWindow::GetTabForView(lcView* View) const { QWidget* Widget = View->GetWidget(); while (Widget) { lcModelTabWidget* TabWidget = qobject_cast(Widget); if (TabWidget) return TabWidget; else Widget = Widget->parentWidget(); } return nullptr; } void lcMainWindow::HandleCommand(lcCommandId CommandId) { lcView* ActiveView = GetActiveView(); lcModel* ActiveModel = ActiveView ? ActiveView->GetActiveModel() : nullptr; switch (CommandId) { case LC_FILE_NEW: NewProject(); break; case LC_FILE_OPEN: OpenProject(QString()); break; case LC_FILE_MERGE: MergeProject(); break; case LC_FILE_SAVE: SaveProject(lcGetActiveProject()->GetFileName()); break; case LC_FILE_SAVEAS: SaveProject(QString()); break; case LC_FILE_SAVE_IMAGE: lcGetActiveProject()->SaveImage(); break; case LC_FILE_IMPORT_LDD: ImportLDD(); break; case LC_FILE_IMPORT_INVENTORY: ImportInventory(); break; case LC_FILE_EXPORT_3DS: lcGetActiveProject()->Export3DStudio(QString()); break; case LC_FILE_EXPORT_COLLADA: lcGetActiveProject()->ExportCOLLADA(QString()); break; case LC_FILE_EXPORT_HTML: ShowHTMLDialog(); break; case LC_FILE_EXPORT_BRICKLINK: lcGetActiveProject()->ExportBrickLink(); break; case LC_FILE_EXPORT_CSV: lcGetActiveProject()->ExportCSV(QString()); break; case LC_FILE_EXPORT_POVRAY: lcGetActiveProject()->ExportPOVRay(QString()); break; case LC_FILE_EXPORT_WAVEFRONT: lcGetActiveProject()->ExportWavefront(QString()); break; case LC_FILE_RENDER: ShowRenderDialog(); break; case LC_FILE_INSTRUCTIONS: ShowInstructionsDialog(); break; case LC_FILE_PRINT_PREVIEW: TogglePrintPreview(); break; case LC_FILE_PRINT: ShowPrintDialog(); break; case LC_FILE_RECENT1: case LC_FILE_RECENT2: case LC_FILE_RECENT3: case LC_FILE_RECENT4: OpenRecentProject(CommandId - LC_FILE_RECENT1); break; case LC_FILE_EXIT: close(); break; case LC_EDIT_UNDO: if (ActiveModel) ActiveModel->UndoAction(); break; case LC_EDIT_REDO: if (ActiveModel) ActiveModel->RedoAction(); break; case LC_EDIT_CUT: if (ActiveModel) ActiveModel->Cut(); break; case LC_EDIT_COPY: if (ActiveModel) ActiveModel->Copy(); break; case LC_EDIT_PASTE: if (ActiveModel) ActiveModel->Paste(true); break; case LC_EDIT_PASTE_STEPS: if (ActiveModel) ActiveModel->Paste(false); break; case LC_EDIT_FIND: if (ActiveView) ActiveView->ShowFindReplaceWidget(false); break; case LC_EDIT_FIND_NEXT: if (ActiveModel) ActiveModel->FindReplacePiece(true, false); break; case LC_EDIT_FIND_PREVIOUS: if (ActiveModel) ActiveModel->FindReplacePiece(false, false); break; case LC_EDIT_FIND_ALL: if (ActiveModel) ActiveModel->FindReplacePiece(true, true); break; case LC_EDIT_REPLACE: if (ActiveView) ActiveView->ShowFindReplaceWidget(true); break; case LC_EDIT_REPLACE_ALL: if (ActiveModel) ActiveModel->FindReplacePiece(true, true); break; case LC_EDIT_REPLACE_NEXT: if (ActiveModel) ActiveModel->FindReplacePiece(true, false); break; case LC_EDIT_SELECT_ALL: if (ActiveModel) ActiveModel->SelectAllPieces(); break; case LC_EDIT_SELECT_NONE: if (ActiveModel) ActiveModel->ClearSelection(true); break; case LC_EDIT_SELECT_INVERT: if (ActiveModel) ActiveModel->InvertSelection(); break; case LC_EDIT_SELECT_BY_NAME: if (ActiveModel) ActiveModel->ShowSelectByNameDialog(); break; case LC_EDIT_SELECTION_SINGLE: SetSelectionMode(lcSelectionMode::Single); break; case LC_EDIT_SELECTION_PIECE: SetSelectionMode(lcSelectionMode::Piece); break; case LC_EDIT_SELECTION_COLOR: SetSelectionMode(lcSelectionMode::Color); break; case LC_EDIT_SELECTION_PIECE_COLOR: SetSelectionMode(lcSelectionMode::PieceColor); break; case LC_VIEW_SPLIT_HORIZONTAL: SplitHorizontal(); break; case LC_VIEW_SPLIT_VERTICAL: SplitVertical(); break; case LC_VIEW_REMOVE_VIEW: RemoveActiveView(); break; case LC_VIEW_RESET_VIEWS: ResetViews(); break; case LC_VIEW_TOOLBAR_STANDARD: ToggleDockWidget(mStandardToolBar); break; case LC_VIEW_TOOLBAR_TOOLS: ToggleDockWidget(mToolsToolBar); break; case LC_VIEW_TOOLBAR_TIME: ToggleDockWidget(mTimeToolBar); break; case LC_VIEW_TOOLBAR_PARTS: ToggleDockWidget(mPartsToolBar); break; case LC_VIEW_TOOLBAR_COLORS: ToggleDockWidget(mColorsToolBar); break; case LC_VIEW_TOOLBAR_PROPERTIES: ToggleDockWidget(mPropertiesToolBar); break; case LC_VIEW_TOOLBAR_TIMELINE: ToggleDockWidget(mTimelineToolBar); break; case LC_VIEW_TOOLBAR_PREVIEW: ToggleDockWidget(mPreviewToolBar); break; case LC_VIEW_FULLSCREEN: ToggleFullScreen(); break; case LC_VIEW_CLOSE_CURRENT_TAB: CloseCurrentModelTab(); break; case LC_VIEW_SHADING_WIREFRAME: SetShadingMode(lcShadingMode::Wireframe); break; case LC_VIEW_SHADING_FLAT: SetShadingMode(lcShadingMode::Flat); break; case LC_VIEW_SHADING_DEFAULT_LIGHTS: SetShadingMode(lcShadingMode::DefaultLights); break; case LC_VIEW_PROJECTION_PERSPECTIVE: if (ActiveView) ActiveView->SetProjection(false); break; case LC_VIEW_PROJECTION_ORTHO: if (ActiveView) ActiveView->SetProjection(true); break; case LC_VIEW_TOGGLE_VIEW_SPHERE: ToggleViewSphere(); break; case LC_VIEW_TOGGLE_AXIS_ICON: ToggleAxisIcon(); break; case LC_VIEW_TOGGLE_GRID: ToggleGrid(); break; case LC_VIEW_FADE_PREVIOUS_STEPS: ToggleFadePreviousSteps(); break; case LC_PIECE_INSERT: if (ActiveModel) ActiveModel->AddPiece(); break; case LC_PIECE_DELETE: if (ActiveModel) ActiveModel->DeleteSelectedObjects(); break; case LC_PIECE_DUPLICATE: if (ActiveModel) ActiveModel->DuplicateSelectedPieces(); break; case LC_PIECE_PAINT_SELECTED: if (ActiveModel) ActiveModel->PaintSelectedPieces(); break; case LC_PIECE_RESET_PIVOT_POINT: if (ActiveModel) ActiveModel->ResetSelectedPiecesPivotPoint(); break; case LC_PIECE_REMOVE_KEY_FRAMES: if (ActiveModel) ActiveModel->RemoveSelectedPiecesKeyFrames(); break; case LC_PIECE_CONTROL_POINT_INSERT: if (ActiveModel) ActiveModel->InsertControlPoint(); break; case LC_PIECE_CONTROL_POINT_REMOVE: if (ActiveModel) ActiveModel->RemoveFocusedControlPoint(); break; case LC_PIECE_MOVE_PLUSX: if (ActiveModel) ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true); break; case LC_PIECE_MOVE_MINUSX: if (ActiveModel) ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(-lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true); break; case LC_PIECE_MOVE_PLUSY: if (ActiveModel) ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true); break; case LC_PIECE_MOVE_MINUSY: if (ActiveModel) ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true); break; case LC_PIECE_MOVE_PLUSZ: if (ActiveModel) ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true); break; case LC_PIECE_MOVE_MINUSZ: if (ActiveModel) ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true); break; case LC_PIECE_ROTATE_PLUSX: if (ActiveModel) ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true); break; case LC_PIECE_ROTATE_MINUSX: if (ActiveModel) ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(-lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true); break; case LC_PIECE_ROTATE_PLUSY: if (ActiveModel) ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true); break; case LC_PIECE_ROTATE_MINUSY: if (ActiveModel) ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true); break; case LC_PIECE_ROTATE_PLUSZ: if (ActiveModel) ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetAngleSnap(), 1.0f))), true, false, true, true); break; case LC_PIECE_ROTATE_MINUSZ: if (ActiveModel) ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetAngleSnap(), 1.0f))), true, false, true, true); break; case LC_PIECE_MINIFIG_WIZARD: if (ActiveModel) ActiveModel->ShowMinifigDialog(); break; case LC_PIECE_ARRAY: if (ActiveModel) ActiveModel->ShowArrayDialog(); break; case LC_PIECE_VIEW_SELECTED_MODEL: SetModelFromSelection(); break; case LC_PIECE_MOVE_SELECTION_TO_MODEL: if (ActiveModel) ActiveModel->MoveSelectionToModel(lcGetActiveProject()->CreateNewModel(false)); break; case LC_PIECE_INLINE_SELECTED_MODELS: if (ActiveModel) ActiveModel->InlineSelectedModels(); break; case LC_PIECE_EDIT_END_SUBMODEL: if (ActiveView) { ActiveView->SetTopSubmodelActive(); if (ActiveModel) { std::vector UpdatedModels; ActiveModel->UpdatePieceInfo(UpdatedModels); } } break; case LC_PIECE_EDIT_SELECTED_SUBMODEL: if (ActiveView) ActiveView->SetSelectedSubmodelActive(); break; case LC_PIECE_GROUP: if (ActiveModel) ActiveModel->GroupSelection(); break; case LC_PIECE_UNGROUP: if (ActiveModel) ActiveModel->UngroupSelection(); break; case LC_PIECE_GROUP_ADD: if (ActiveModel) ActiveModel->AddSelectedPiecesToGroup(); break; case LC_PIECE_GROUP_REMOVE: if (ActiveModel) ActiveModel->RemoveFocusPieceFromGroup(); break; case LC_PIECE_GROUP_EDIT: if (ActiveModel) ActiveModel->ShowEditGroupsDialog(); break; case LC_PIECE_HIDE_SELECTED: if (ActiveModel) ActiveModel->HideSelectedPieces(); break; case LC_PIECE_HIDE_UNSELECTED: if (ActiveModel) ActiveModel->HideUnselectedPieces(); break; case LC_PIECE_UNHIDE_SELECTED: if (ActiveModel) ActiveModel->UnhideSelectedPieces(); break; case LC_PIECE_UNHIDE_ALL: if (ActiveModel) ActiveModel->UnhideAllPieces(); break; case LC_PIECE_SHOW_EARLIER: if (ActiveModel) ActiveModel->ShowSelectedPiecesEarlier(); break; case LC_PIECE_SHOW_LATER: if (ActiveModel) ActiveModel->ShowSelectedPiecesLater(); break; case LC_VIEW_PREFERENCES: gApplication->ShowPreferencesDialog(); break; case LC_VIEW_ZOOM_IN: if (ActiveView) ActiveView->Zoom(10.0f); break; case LC_VIEW_ZOOM_OUT: if (ActiveView) ActiveView->Zoom(-10.0f); break; case LC_VIEW_ZOOM_EXTENTS: if (ActiveView) ActiveView->ZoomExtents(); break; case LC_VIEW_LOOK_AT: if (ActiveView) ActiveView->LookAt(); break; case LC_VIEW_MOVE_FORWARD: if (ActiveView) ActiveView->MoveCamera(lcVector3(0.0f, 0.0f, -1.0f)); break; case LC_VIEW_MOVE_BACKWARD: if (ActiveView) ActiveView->MoveCamera(lcVector3(0.0f, 0.0f, 1.0f)); break; case LC_VIEW_MOVE_LEFT: if (ActiveView) ActiveView->MoveCamera(lcVector3(-1.0f, 0.0f, 0.0f)); break; case LC_VIEW_MOVE_RIGHT: if (ActiveView) ActiveView->MoveCamera(lcVector3(1.0f, 0.0f, 0.0f)); break; case LC_VIEW_MOVE_UP: if (ActiveView) ActiveView->MoveCamera(lcVector3(0.0f, 1.0f, 0.0f)); break; case LC_VIEW_MOVE_DOWN: if (ActiveView) ActiveView->MoveCamera(lcVector3(0.0f, -1.0f, 0.0f)); break; case LC_VIEW_TIME_NEXT: if (ActiveModel) ActiveModel->ShowNextStep(); break; case LC_VIEW_TIME_PREVIOUS: if (ActiveModel) ActiveModel->ShowPreviousStep(); break; case LC_VIEW_TIME_FIRST: if (ActiveModel) ActiveModel->ShowFirstStep(); break; case LC_VIEW_TIME_LAST: if (ActiveModel) ActiveModel->ShowLastStep(); break; case LC_VIEW_TIME_INSERT_BEFORE: lcGetActiveModel()->InsertStep(lcGetActiveModel()->GetCurrentStep()); break; case LC_VIEW_TIME_INSERT_AFTER: lcGetActiveModel()->InsertStep(lcGetActiveModel()->GetCurrentStep() + 1); break; case LC_VIEW_TIME_DELETE: lcGetActiveModel()->RemoveStep(lcGetActiveModel()->GetCurrentStep()); break; case LC_VIEW_VIEWPOINT_FRONT: if (ActiveView) ActiveView->SetViewpoint(lcViewpoint::Front); break; case LC_VIEW_VIEWPOINT_BACK: if (ActiveView) ActiveView->SetViewpoint(lcViewpoint::Back); break; case LC_VIEW_VIEWPOINT_TOP: if (ActiveView) ActiveView->SetViewpoint(lcViewpoint::Top); break; case LC_VIEW_VIEWPOINT_BOTTOM: if (ActiveView) ActiveView->SetViewpoint(lcViewpoint::Bottom); break; case LC_VIEW_VIEWPOINT_LEFT: if (ActiveView) ActiveView->SetViewpoint(lcViewpoint::Left); break; case LC_VIEW_VIEWPOINT_RIGHT: if (ActiveView) ActiveView->SetViewpoint(lcViewpoint::Right); break; case LC_VIEW_VIEWPOINT_HOME: if (ActiveView) ActiveView->SetViewpoint(lcViewpoint::Home); break; case LC_VIEW_CAMERA_NONE: if (ActiveView) ActiveView->RemoveCamera(); break; case LC_VIEW_CAMERA1: case LC_VIEW_CAMERA2: case LC_VIEW_CAMERA3: case LC_VIEW_CAMERA4: case LC_VIEW_CAMERA5: case LC_VIEW_CAMERA6: case LC_VIEW_CAMERA7: case LC_VIEW_CAMERA8: case LC_VIEW_CAMERA9: case LC_VIEW_CAMERA10: case LC_VIEW_CAMERA11: case LC_VIEW_CAMERA12: case LC_VIEW_CAMERA13: case LC_VIEW_CAMERA14: case LC_VIEW_CAMERA15: case LC_VIEW_CAMERA16: if (ActiveView) ActiveView->SetCameraIndex(CommandId - LC_VIEW_CAMERA1); break; case LC_MODEL_NEW: lcGetActiveProject()->CreateNewModel(true); break; case LC_MODEL_PROPERTIES: lcGetActiveModel()->ShowPropertiesDialog(); break; case LC_MODEL_LIST: lcGetActiveProject()->ShowModelListDialog(); break; case LC_MODEL_01: case LC_MODEL_02: case LC_MODEL_03: case LC_MODEL_04: case LC_MODEL_05: case LC_MODEL_06: case LC_MODEL_07: case LC_MODEL_08: case LC_MODEL_09: case LC_MODEL_10: case LC_MODEL_11: case LC_MODEL_12: case LC_MODEL_13: case LC_MODEL_14: case LC_MODEL_15: case LC_MODEL_16: case LC_MODEL_17: case LC_MODEL_18: case LC_MODEL_19: case LC_MODEL_20: case LC_MODEL_21: case LC_MODEL_22: case LC_MODEL_23: case LC_MODEL_24: case LC_MODEL_25: case LC_MODEL_26: case LC_MODEL_27: case LC_MODEL_28: case LC_MODEL_29: case LC_MODEL_30: case LC_MODEL_31: case LC_MODEL_32: case LC_MODEL_33: case LC_MODEL_34: case LC_MODEL_35: case LC_MODEL_36: case LC_MODEL_37: case LC_MODEL_38: case LC_MODEL_39: case LC_MODEL_40: lcGetActiveProject()->SetActiveModel(CommandId - LC_MODEL_01); break; case LC_HELP_HOMEPAGE: QDesktopServices::openUrl(QUrl("https://www.leocad.org/")); break; case LC_HELP_BUG_REPORT: QDesktopServices::openUrl(QUrl("https://github.com/leozide/leocad/issues")); break; case LC_HELP_UPDATES: ShowUpdatesDialog(); break; case LC_HELP_ABOUT: ShowAboutDialog(); break; case LC_VIEW_TIME_ADD_KEYS: SetAddKeys(!GetAddKeys()); break; case LC_EDIT_TRANSFORM_RELATIVE: SetRelativeTransform(true); break; case LC_EDIT_TRANSFORM_ABSOLUTE: SetRelativeTransform(false); break; case LC_EDIT_TRANSFORM_TOGGLE_RELATIVE: SetRelativeTransform(!GetRelativeTransform()); break; case LC_EDIT_TRANSFORM_SEPARATELY: SetSeparateTransform(true); break; case LC_EDIT_TRANSFORM_TOGETHER: SetSeparateTransform(false); break; case LC_EDIT_TRANSFORM_TOGGLE_SEPARATE: SetSeparateTransform(!GetSeparateTransform()); break; case LC_EDIT_SNAP_MOVE_TOGGLE: SetMoveSnapEnabled(!mMoveSnapEnabled); break; case LC_EDIT_SNAP_MOVE_XY0: case LC_EDIT_SNAP_MOVE_XY1: case LC_EDIT_SNAP_MOVE_XY2: case LC_EDIT_SNAP_MOVE_XY3: case LC_EDIT_SNAP_MOVE_XY4: case LC_EDIT_SNAP_MOVE_XY5: case LC_EDIT_SNAP_MOVE_XY6: case LC_EDIT_SNAP_MOVE_XY7: case LC_EDIT_SNAP_MOVE_XY8: case LC_EDIT_SNAP_MOVE_XY9: SetMoveXYSnapIndex(CommandId - LC_EDIT_SNAP_MOVE_XY0); break; case LC_EDIT_SNAP_MOVE_Z0: case LC_EDIT_SNAP_MOVE_Z1: case LC_EDIT_SNAP_MOVE_Z2: case LC_EDIT_SNAP_MOVE_Z3: case LC_EDIT_SNAP_MOVE_Z4: case LC_EDIT_SNAP_MOVE_Z5: case LC_EDIT_SNAP_MOVE_Z6: case LC_EDIT_SNAP_MOVE_Z7: case LC_EDIT_SNAP_MOVE_Z8: case LC_EDIT_SNAP_MOVE_Z9: SetMoveZSnapIndex(CommandId - LC_EDIT_SNAP_MOVE_Z0); break; case LC_EDIT_SNAP_ANGLE_TOGGLE: SetAngleSnapEnabled(!mAngleSnapEnabled); break; case LC_EDIT_SNAP_ANGLE0: case LC_EDIT_SNAP_ANGLE1: case LC_EDIT_SNAP_ANGLE2: case LC_EDIT_SNAP_ANGLE3: case LC_EDIT_SNAP_ANGLE4: case LC_EDIT_SNAP_ANGLE5: case LC_EDIT_SNAP_ANGLE6: case LC_EDIT_SNAP_ANGLE7: case LC_EDIT_SNAP_ANGLE8: case LC_EDIT_SNAP_ANGLE9: SetAngleSnapIndex(CommandId - LC_EDIT_SNAP_ANGLE0); break; case LC_EDIT_TRANSFORM: if (ActiveModel) ActiveModel->TransformSelectedObjects(GetTransformType(), GetTransformAmount()); break; case LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION: SetTransformType(lcTransformType::AbsoluteTranslation); break; case LC_EDIT_TRANSFORM_RELATIVE_TRANSLATION: SetTransformType(lcTransformType::RelativeTranslation); break; case LC_EDIT_TRANSFORM_ABSOLUTE_ROTATION: SetTransformType(lcTransformType::AbsoluteRotation); break; case LC_EDIT_TRANSFORM_RELATIVE_ROTATION: SetTransformType(lcTransformType::RelativeRotation); break; case LC_EDIT_ACTION_SELECT: SetTool(lcTool::Select); break; case LC_EDIT_ACTION_INSERT: SetTool(lcTool::Insert); break; case LC_EDIT_ACTION_LIGHT: SetTool(lcTool::Light); break; case LC_EDIT_ACTION_SPOTLIGHT: SetTool(lcTool::SpotLight); break; case LC_EDIT_ACTION_CAMERA: SetTool(lcTool::Camera); break; case LC_EDIT_ACTION_MOVE: SetTool(lcTool::Move); break; case LC_EDIT_ACTION_ROTATE: SetTool(lcTool::Rotate); break; case LC_EDIT_ACTION_DELETE: SetTool(lcTool::Eraser); break; case LC_EDIT_ACTION_PAINT: SetTool(lcTool::Paint); break; case LC_EDIT_ACTION_COLOR_PICKER: SetTool(lcTool::ColorPicker); break; case LC_EDIT_ACTION_ZOOM: SetTool(lcTool::Zoom); break; case LC_EDIT_ACTION_ZOOM_REGION: SetTool(lcTool::ZoomRegion); break; case LC_EDIT_ACTION_PAN: SetTool(lcTool::Pan); break; case LC_EDIT_ACTION_ROTATE_VIEW: SetTool(lcTool::RotateView); break; case LC_EDIT_ACTION_ROLL: SetTool(lcTool::Roll); break; case LC_EDIT_CANCEL: if (ActiveView && !ActiveView->CloseFindReplaceDialog()) ActiveView->CancelTrackingOrClearSelection(); break; case LC_TIMELINE_INSERT_BEFORE: mTimelineWidget->InsertStepBefore(); break; case LC_TIMELINE_INSERT_AFTER: mTimelineWidget->InsertStepAfter(); break; case LC_TIMELINE_DELETE: mTimelineWidget->RemoveStep(); break; case LC_TIMELINE_MOVE_SELECTION: mTimelineWidget->MoveSelection(); break; case LC_TIMELINE_MOVE_SELECTION_BEFORE: mTimelineWidget->MoveSelectionBefore(); break; case LC_TIMELINE_MOVE_SELECTION_AFTER: mTimelineWidget->MoveSelectionAfter(); break; case LC_TIMELINE_SET_CURRENT: mTimelineWidget->SetCurrentStep(); break; case LC_NUM_COMMANDS: break; } } leocad-23.03/common/lc_mainwindow.h000066400000000000000000000222501440571307300172500ustar00rootroot00000000000000#pragma once #include "lc_application.h" #include "lc_shortcuts.h" #include "lc_array.h" #include "lc_commands.h" #include "lc_model.h" class lcPartSelectionWidget; class lcPreviewDockWidget; class PiecePreview; class lcQPartsTree; class lcQColorList; class lcQPropertiesTree; class lcTimelineWidget; class lcElidedLabel; #ifdef QT_NO_PRINTER class QPrinter; #endif #define LC_MAX_RECENT_FILES 4 class lcTabBar : public QTabBar { public: lcTabBar(QWidget* Parent = nullptr) : QTabBar(Parent), mMousePressTab(-1) { } protected: void mousePressEvent(QMouseEvent* Event) override; void mouseReleaseEvent(QMouseEvent* Event) override; int mMousePressTab; }; class lcModelTabWidget : public QWidget { Q_OBJECT public: lcModelTabWidget(lcModel* Model) { mModel = Model; mActiveView = nullptr; } QWidget* GetAnyViewWidget() { QWidget* Widget = layout()->itemAt(0)->widget(); while (Widget->metaObject() == &QSplitter::staticMetaObject) Widget = ((QSplitter*)Widget)->widget(0); return Widget; } lcView* GetActiveView() const { return mActiveView; } void SetActiveView(lcView* ActiveView) { mActiveView = ActiveView; } void RemoveView(const lcView* View) { if (View == mActiveView) mActiveView = nullptr; } lcModel* GetModel() const { return mModel; } protected: lcModel* mModel; lcView* mActiveView; }; class lcMainWindow : public QMainWindow { Q_OBJECT public: lcMainWindow(); ~lcMainWindow(); void CreateWidgets(); lcTool GetTool() const { return mTool; } lcTransformType GetTransformType() const { return mTransformType; } bool GetAddKeys() const { return mAddKeys; } float GetMoveXYSnap() const { const float SnapXYTable[] = { 0.0f, 1.0f, 5.0f, 8.0f, 10.0f, 20.0f, 40.0f, 60.0f, 80.0f, 160.0f }; return mMoveSnapEnabled ? SnapXYTable[mMoveXYSnapIndex] : 0.0f; } float GetMoveZSnap() const { const float SnapZTable[] = { 0.0f, 1.0f, 5.0f, 8.0f, 10.0f, 20.0f, 24.0f, 48.0f, 96.0f, 192.0f }; return mMoveSnapEnabled ? SnapZTable[mMoveZSnapIndex] : 0.0f; } float GetAngleSnap() const { const float AngleTable[] = { 0.0f, 1.0f, 5.0f, 15.0f, 22.5f, 30.0f, 45.0f, 60.0f, 90.0f, 180.0f }; return mAngleSnapEnabled ? AngleTable[mAngleSnapIndex] : 0.0f; } QString GetMoveXYSnapText() const { QString SnapXYText[] = { tr("0"), tr("1/20S"), tr("1/4S"), tr("1F"), tr("1/2S"), tr("1S"), tr("2S"), tr("3S"), tr("4S"), tr("8S") }; return mMoveSnapEnabled ? SnapXYText[mMoveXYSnapIndex] : tr("None"); } QString GetMoveZSnapText() const { QString SnapZText[] = { tr("0"), tr("1/20S"), tr("1/4S"), tr("1F"), tr("1/2S"), tr("1S"), tr("1B"), tr("2B"), tr("4B"), tr("8B") }; return mMoveSnapEnabled ? SnapZText[mMoveZSnapIndex] : tr("None"); } QString GetAngleSnapText() const { return mAngleSnapEnabled ? QString::number(GetAngleSnap()) : tr("None"); } bool GetRelativeTransform() const { return mRelativeTransform; } bool GetSeparateTransform() const { return mLocalTransform; } lcSelectionMode GetSelectionMode() const { return mSelectionMode; } PieceInfo* GetCurrentPieceInfo() const { return mCurrentPieceInfo; } lcView* GetActiveView() const { const lcModelTabWidget* const CurrentTab = mModelTabWidget ? (lcModelTabWidget*)mModelTabWidget->currentWidget() : nullptr; return CurrentTab ? CurrentTab->GetActiveView() : nullptr; } lcModel* GetActiveModel() const; lcModelTabWidget* GetTabForView(lcView* View) const; lcModel* GetCurrentTabModel() const { const lcModelTabWidget* const CurrentTab = (lcModelTabWidget*)mModelTabWidget->currentWidget(); return CurrentTab ? CurrentTab->GetModel() : nullptr; } lcPartSelectionWidget* GetPartSelectionWidget() const { return mPartSelectionWidget; } lcPreviewDockWidget* GetPreviewWidget() const { return mPreviewWidget; } QMenu* GetToolsMenu() const { return mToolsMenu; } QMenu* GetViewpointMenu() const { return mViewpointMenu; } QMenu* GetCameraMenu() const { return mCameraMenu; } QMenu* GetProjectionMenu() const { return mProjectionMenu; } QMenu* GetShadingMenu() const { return mShadingMenu; } QByteArray GetTabLayout(); void RestoreTabLayout(const QByteArray& TabLayout); void RemoveAllModelTabs(); void CloseCurrentModelTab(); void SetCurrentModelTab(lcModel* Model); void ResetCameras(); void AddView(lcView* View); void RemoveView(lcView* View); void SetTool(lcTool Tool); void SetTransformType(lcTransformType TransformType); void SetColorIndex(int ColorIndex); void SetMoveSnapEnabled(bool Enabled); void SetAngleSnapEnabled(bool Enabled); void SetMoveXYSnapIndex(int Index); void SetMoveZSnapIndex(int Index); void SetAngleSnapIndex(int Index); void SetRelativeTransform(bool RelativeTransform); void SetSeparateTransform(bool SelectionTransform); void SetCurrentPieceInfo(PieceInfo* Info); void SetShadingMode(lcShadingMode ShadingMode); void SetSelectionMode(lcSelectionMode SelectionMode); void ToggleViewSphere(); void ToggleAxisIcon(); void ToggleGrid(); void ToggleFadePreviousSteps(); void NewProject(); bool OpenProject(const QString& FileName); void OpenRecentProject(int RecentFileIndex); void MergeProject(); void ImportLDD(); void ImportInventory(); bool SaveProject(const QString& FileName); bool SaveProjectIfModified(); bool SetModelFromFocus(); void SetModelFromSelection(); void HandleCommand(lcCommandId CommandId); void AddRecentFile(const QString& FileName); void RemoveRecentFile(int FileIndex); void SplitHorizontal(); void SplitVertical(); void RemoveActiveView(); void ResetViews(); void TogglePrintPreview(); void ToggleFullScreen(); void UpdateSelectedObjects(bool SelectionChanged); void UpdateTimeline(bool Clear, bool UpdateItems); void UpdatePaste(bool Enabled); void UpdateCurrentStep(); void SetAddKeys(bool AddKeys); void UpdateLockSnap(); void UpdateSnap(); void UpdateColor(); void UpdateUndoRedo(const QString& UndoText, const QString& RedoText); void UpdatePerspective(); void UpdateCameraMenu(); void UpdateShadingMode(); void UpdateSelectionMode(); void UpdateModels(); void UpdateCategories(); void UpdateTitle(); void UpdateModified(bool Modified); void UpdateRecentFiles(); void UpdateShortcuts(); lcVector3 GetTransformAmount(); QString mRecentFiles[LC_MAX_RECENT_FILES]; int mColorIndex; QAction* mActions[LC_NUM_COMMANDS]; public slots: void ProjectFileChanged(const QString& Path); void PreviewPiece(const QString& PartId, int ColorCode, bool ShowPreview); void TogglePreviewWidget(bool Visible); protected slots: void ViewFocusReceived(); void ViewCameraChanged(); void UpdateDockWidgetActions(); void UpdateGamepads(); void ModelTabContextMenuRequested(const QPoint& Point); void ModelTabCloseOtherTabs(); void ModelTabClosed(int Index); void ModelTabChanged(int Index); void ClipboardChanged(); void ActionTriggered(); void ColorChanged(int ColorIndex); void ColorButtonClicked(); void Print(QPrinter* Printer); void EnableWindowFlags(bool); protected: void closeEvent(QCloseEvent *event) override; void dragEnterEvent(QDragEnterEvent* Event) override; void dropEvent(QDropEvent* Event) override; QMenu* createPopupMenu() override; void CreateActions(); void CreateMenus(); void CreateToolBars(); void CreateStatusBar(); lcView* CreateView(lcModel* Model); void SetActiveView(lcView* ActiveView); void ToggleDockWidget(QWidget* DockWidget); void SplitView(Qt::Orientation Orientation); void ShowUpdatesDialog(); void ShowAboutDialog(); void ShowHTMLDialog(); void ShowRenderDialog(); void ShowInstructionsDialog(); void ShowPrintDialog(); void CreatePreviewWidget(); bool OpenProjectFile(const QString& FileName); lcModelTabWidget* GetTabWidgetForModel(const lcModel* Model) const { for (int TabIdx = 0; TabIdx < mModelTabWidget->count(); TabIdx++) { lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->widget(TabIdx); if (TabWidget->GetModel() == Model) return TabWidget; } return nullptr; } QTimer mGamepadTimer; QDateTime mLastGamepadUpdate; bool mAddKeys; lcTool mTool; lcTransformType mTransformType; bool mMoveSnapEnabled; bool mAngleSnapEnabled; int mMoveXYSnapIndex; int mMoveZSnapIndex; int mAngleSnapIndex; bool mRelativeTransform; bool mLocalTransform; PieceInfo* mCurrentPieceInfo; lcSelectionMode mSelectionMode; int mModelTabWidgetContextMenuIndex; QAction* mActionFileRecentSeparator; QTabWidget* mModelTabWidget; QToolBar* mStandardToolBar; QToolBar* mToolsToolBar; QToolBar* mTimeToolBar; QDockWidget* mPreviewToolBar; QDockWidget* mPartsToolBar; QDockWidget* mColorsToolBar; QDockWidget* mPropertiesToolBar; QDockWidget* mTimelineToolBar; lcPartSelectionWidget* mPartSelectionWidget; lcQColorList* mColorList; QToolButton* mColorButton; lcQPropertiesTree* mPropertiesWidget; lcTimelineWidget* mTimelineWidget; QLineEdit* mTransformXEdit; QLineEdit* mTransformYEdit; QLineEdit* mTransformZEdit; lcPreviewDockWidget* mPreviewWidget; lcElidedLabel* mStatusBarLabel; QLabel* mStatusPositionLabel; QLabel* mStatusSnapLabel; QLabel* mStatusTimeLabel; QMenu* mTransformMenu; QMenu* mToolsMenu; QMenu* mViewpointMenu; QMenu* mCameraMenu; QMenu* mProjectionMenu; QMenu* mShadingMenu; QMenu* mSelectionModeMenu; }; extern class lcMainWindow* gMainWindow; leocad-23.03/common/lc_math.h000066400000000000000000001506051440571307300160330ustar00rootroot00000000000000#pragma once #include #include #define LC_DTOR (static_cast(M_PI / 180)) #define LC_RTOD (static_cast(180 / M_PI)) #define LC_PI (static_cast(M_PI)) #define LC_2PI (static_cast(2 * M_PI)) #define LC_RGB_EPSILON (static_cast(0.5f / 255.0f)) #define LC_RGB(r,g,b) LC_RGBA(r,g,b,255) #define LC_RGBA(r,g,b,a) ((quint32)(((quint8) (r) | ((quint16) (g) << 8)) | (((quint32) (quint8) (b)) << 16) | (((quint32) (quint8) (a)) << 24))) #define LC_RGBA_RED(rgba) ((quint8)(((rgba) >> 0) & 0xff)) #define LC_RGBA_GREEN(rgba) ((quint8)(((rgba) >> 8) & 0xff)) #define LC_RGBA_BLUE(rgba) ((quint8)(((rgba) >> 16) & 0xff)) #define LC_RGBA_ALPHA(rgba) ((quint8)(((rgba) >> 24) & 0xff)) #define LC_SRGB_TO_LINEAR(v) (powf(v, 2.2f)) #define LC_LINEAR_TO_SRGB(v) (powf(v, 1.0f / 2.2f)) inline quint32 lcRGBAFromQColor(const QColor& Color) { return LC_RGBA(Color.red(), Color.green(), Color.blue(), Color.alpha()); } inline QColor lcQColorFromRGBA(quint32 RGBA) { return QColor::fromRgb(LC_RGBA_RED(RGBA), LC_RGBA_GREEN(RGBA), LC_RGBA_BLUE(RGBA), LC_RGBA_ALPHA(RGBA)); } template inline T lcMin(const T& a, const T& b) { return a < b ? a : b; } template inline T lcMax(const T& a, const T& b) { return a > b ? a : b; } template inline T lcClamp(const T& Value, const T& Min, const T& Max) { if (Value > Max) return Max; else if (Value < Min) return Min; else return Value; } class lcVector2 { public: lcVector2() { } constexpr lcVector2(const float _x, const float _y) : x(_x), y(_y) { } operator const float*() const { return (const float*)this; } operator float*() { return (float*)this; } const float& operator[](int i) const { return ((float*)this)[i]; } float& operator[](int i) { return ((float*)this)[i]; } bool IsNan() const { return std::isnan(x) || std::isnan(y); } float x, y; }; class lcVector3 { public: lcVector3() { } constexpr lcVector3(const float _x, const float _y, const float _z) : x(_x), y(_y), z(_z) { } explicit lcVector3(const lcVector4& v); operator const float*() const { return (const float*)this; } operator float*() { return (float*)this; } const float& operator[](int i) const { return ((float*)this)[i]; } float& operator[](int i) { return ((float*)this)[i]; } bool IsNan() const { return std::isnan(x) || std::isnan(y) || std::isnan(z); } void Normalize(); float Length() const; float LengthSquared() const; float x, y, z; }; class lcVector4 { public: lcVector4() { } constexpr lcVector4(const float _x, const float _y, const float _z, const float _w) : x(_x), y(_y), z(_z), w(_w) { } constexpr lcVector4(const lcVector3& _xyz, const float _w) : x(_xyz.x), y(_xyz.y), z(_xyz.z), w(_w) { } operator const float*() const { return (const float*)this; } operator float*() { return (float*)this; } const float& operator[](int i) const { return ((float*)this)[i]; } float& operator[](int i) { return ((float*)this)[i]; } bool IsNan() const { return std::isnan(x) || std::isnan(y) || std::isnan(z) || std::isnan(w); } float x, y, z, w; }; class lcMatrix33 { public: lcMatrix33() { } lcMatrix33(const lcVector3& _x, const lcVector3& _y, const lcVector3& _z) { r[0] = _x; r[1] = _y; r[2] = _z; } explicit lcMatrix33(const lcMatrix44& Matrix); operator const float*() const { return (const float*)this; } operator float*() { return (float*)this; } const lcVector3& operator[](int i) const { return r[i]; } lcVector3& operator[](int i) { return r[i]; } void Orthonormalize(); lcVector3 r[3]; }; class lcMatrix44 { public: lcMatrix44() { } lcMatrix44(const lcVector4& _x, const lcVector4& _y, const lcVector4& _z, const lcVector4& _w) { r[0] = _x; r[1] = _y; r[2] = _z; r[3] = _w; } lcMatrix44(const lcMatrix33& Rotation, const lcVector3& Translation) { r[0] = lcVector4(Rotation[0][0], Rotation[0][1], Rotation[0][2], 0.0f); r[1] = lcVector4(Rotation[1][0], Rotation[1][1], Rotation[1][2], 0.0f); r[2] = lcVector4(Rotation[2][0], Rotation[2][1], Rotation[2][2], 0.0f); r[3] = lcVector4(Translation, 1.0f); } lcVector3 GetTranslation() const { return lcVector3(r[3][0], r[3][1], r[3][2]); } void SetTranslation(const lcVector3& Translation) { r[3] = lcVector4(Translation[0], Translation[1], Translation[2], 1.0f); } operator const float*() const { return (const float*)this; } operator float*() { return (float*)this; } const lcVector4& operator[](int i) const { return r[i]; } lcVector4& operator[](int i) { return r[i]; } float Determinant() const; lcVector4 r[4]; }; inline lcVector3::lcVector3(const lcVector4& v) : x(v.x), y(v.y), z(v.z) { } inline lcVector3 operator+(const lcVector3& a, const lcVector3& b) { return lcVector3(a.x + b.x, a.y + b.y, a.z + b.z); } inline lcVector3 operator-(const lcVector3& a, const lcVector3& b) { return lcVector3(a.x - b.x, a.y - b.y, a.z - b.z); } inline lcVector3 operator*(const lcVector3& a, const lcVector3& b) { return lcVector3(a.x * b.x, a.y * b.y, a.z * b.z); } inline lcVector3 operator/(const lcVector3& a, const lcVector3& b) { return lcVector3(a.x / b.x, a.y / b.y, a.z / b.z); } inline lcVector3 operator*(const lcVector3& a, float b) { return lcVector3(a.x * b, a.y * b, a.z * b); } inline lcVector3 operator/(const lcVector3& a, float b) { return lcVector3(a.x / b, a.y / b, a.z / b); } inline lcVector3 operator*(float a, const lcVector3& b) { return lcVector3(b.x * a, b.y * a, b.z * a); } inline lcVector3 operator/(float a, const lcVector3& b) { return lcVector3(b.x / a, b.y / a, b.z / a); } inline lcVector3 operator-(const lcVector3& a) { return lcVector3(-a.x, -a.y, -a.z); } inline lcVector3& operator+=(lcVector3& a, const lcVector3& b) { a.x += b.x; a.y += b.y; a.z += b.z; return a; } inline lcVector3& operator-=(lcVector3& a, const lcVector3& b) { a.x -= b.x; a.y -= b.y; a.z -= b.z; return a; } inline lcVector3& operator*=(lcVector3& a, const lcVector3& b) { a.x *= b.x; a.y *= b.y; a.z *= b.z; return a; } inline lcVector3& operator/=(lcVector3& a, const lcVector3& b) { a.x /= b.x; a.y /= b.y; a.z /= b.z; return a; } inline lcVector3& operator+=(lcVector3& a, float b) { a.x += b; a.y += b; a.z += b; return a; } inline lcVector3& operator*=(lcVector3& a, float b) { a.x *= b; a.y *= b; a.z *= b; return a; } inline lcVector3& operator/=(lcVector3& a, float b) { a.x /= b; a.y /= b; a.z /= b; return a; } inline bool operator==(const lcVector3& a, const lcVector3& b) { return a.x == b.x && a.y == b.y && a.z == b.z; } inline bool operator!=(const lcVector3& a, const lcVector3& b) { return a.x != b.x || a.y != b.y || a.z != b.z; } #ifndef QT_NO_DEBUG inline QDebug operator<<(QDebug Debug, const lcVector2& v) { QDebugStateSaver Saver(Debug); Debug.nospace() << '(' << v.x << ", " << v.y << ')'; return Debug; } inline QDebug operator<<(QDebug Debug, const lcVector3& v) { QDebugStateSaver Saver(Debug); Debug.nospace() << '(' << v.x << ", " << v.y << ", " << v.z << ')'; return Debug; } inline QDebug operator<<(QDebug Debug, const lcVector4& v) { QDebugStateSaver Saver(Debug); Debug.nospace() << '(' << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ')'; return Debug; } inline QDebug operator<<(QDebug Debug, const lcMatrix33& m) { QDebugStateSaver Saver(Debug); Debug.nospace() << '[' << m[0] << ", " << m[1] << ", " << m[2] << ']'; return Debug; } inline QDebug operator<<(QDebug Debug, const lcMatrix44& m) { QDebugStateSaver Saver(Debug); Debug.nospace() << '[' << m[0] << ", " << m[1] << ", " << m[2] << ", " << m[3] << ']'; return Debug; } #endif inline QDataStream& operator<<(QDataStream& Stream, const lcVector3& v) { Stream << v.x << v.y << v.z; return Stream; } inline QDataStream& operator>>(QDataStream& Stream, lcVector3& v) { Stream >> v.x >> v.y >> v.z; return Stream; } inline QDataStream& operator<<(QDataStream& Stream, const lcVector4& v) { Stream << v.x << v.y << v.z << v.w; return Stream; } inline QDataStream& operator >> (QDataStream& Stream, lcVector4& v) { Stream >> v.x >> v.y >> v.z >> v.w; return Stream; } inline void lcVector3::Normalize() { const float InvLength = 1.0f / Length(); x *= InvLength; y *= InvLength; z *= InvLength; } inline float lcVector3::Length() const { return sqrtf(x * x + y * y + z * z); } inline float lcVector3::LengthSquared() const { return x * x + y * y + z * z; } inline float lcLength(const lcVector3& a) { return a.Length(); } inline float lcLengthSquared(const lcVector3& a) { return a.LengthSquared(); } inline lcVector3 lcNormalize(const lcVector3& a) { lcVector3 Ret(a); Ret.Normalize(); return Ret; } inline float lcDot(const lcVector3& a, const lcVector3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } inline float lcDot3(const lcVector4& a, const lcVector3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } inline float lcDot3(const lcVector3& a, const lcVector4& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } inline float lcDot3(const lcVector4& a, const lcVector4& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } inline float lcDot(const lcVector4& a, const lcVector4& b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } inline lcVector3 lcCross(const lcVector3& a, const lcVector3& b) { return lcVector3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } template<> inline lcVector3 lcMin(const lcVector3& a, const lcVector3& b) { return lcVector3(a.x < b.x ? a.x : b.x, a.y < b.y ? a.y : b.y, a.z < b.z ? a.z : b.z); } template<> inline lcVector3 lcMax(const lcVector3& a, const lcVector3& b) { return lcVector3(a.x > b.x ? a.x : b.x, a.y > b.y ? a.y : b.y, a.z > b.z ? a.z : b.z); } inline lcVector4 operator+(const lcVector4& a, const lcVector4& b) { return lcVector4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); } inline lcVector4 operator-(const lcVector4& a, const lcVector4& b) { return lcVector4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); } inline lcVector4 operator*(const lcVector4& a, float f) { return lcVector4(a.x * f, a.y * f, a.z * f, a.w * f); } inline lcVector4 operator*(const lcVector4& a, const lcVector4& b) { return lcVector4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); } inline lcVector4 operator/(const lcVector4& a, float f) { return lcVector4(a.x / f, a.y / f, a.z / f, a.w / f); } inline lcVector4 operator/(const lcVector4& a, const lcVector4& b) { return lcVector4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); } inline lcVector4& operator+=(lcVector4& a, const lcVector4& b) { a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w; return a; } inline lcVector4& operator-=(lcVector4& a, const lcVector4& b) { a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w; return a; } inline lcVector4& operator*=(lcVector4& a, float b) { a.x *= b; a.y *= b; a.z *= b; a.w *= b; return a; } inline lcVector4& operator/=(lcVector4& a, float b) { a.x /= b; a.y /= b; a.z /= b; a.w /= b; return a; } inline quint32 lcPackNormal(const lcVector3& Normal) { quint32 Packed = 0; Packed |= (((qint8)(Normal.x * 127.0f)) & 0xff) << 0; Packed |= (((qint8)(Normal.y * 127.0f)) & 0xff) << 8; Packed |= (((qint8)(Normal.z * 127.0f)) & 0xff) << 16; return Packed; } inline lcVector3 lcUnpackNormal(quint32 Packed) { lcVector3 Normal; Normal.x = (float)(qint8)((Packed >> 0) & 0xff) / 127.0f; Normal.y = (float)(qint8)((Packed >> 8) & 0xff) / 127.0f; Normal.z = (float)(qint8)((Packed >> 16) & 0xff) / 127.0f; return Normal; } inline lcVector3 lcVector3LDrawToLeoCAD(const lcVector3& Vector) { return lcVector3(Vector[0], Vector[2], -Vector[1]); } inline lcVector3 lcVector3FromColor(quint32 Color) { lcVector3 v(LC_RGBA_RED(Color), LC_RGBA_GREEN(Color), LC_RGBA_BLUE(Color)); v /= 255.0f; return v; } inline lcVector4 lcVector4FromColor(quint32 Color) { lcVector4 v(LC_RGBA_RED(Color), LC_RGBA_GREEN(Color), LC_RGBA_BLUE(Color), LC_RGBA_ALPHA(Color)); v /= 255.0f; return v; } inline quint32 lcColorFromVector3(const lcVector3& Color) { return LC_RGB(roundf(Color[0] * 255), roundf(Color[1] * 255), roundf(Color[2] * 255)); } inline float lcLuminescence(const lcVector3& Color) { return 0.2126f * Color[0] + 0.7152f * Color[1] + 0.0722f * Color[2]; } inline lcVector3 lcSRGBToLinear(const lcVector3& Color) { const float r = LC_SRGB_TO_LINEAR(Color[0]); const float g = LC_SRGB_TO_LINEAR(Color[1]); const float b = LC_SRGB_TO_LINEAR(Color[2]); return lcVector3(r, g, b); } inline lcVector3 lcLinearToSRGB(const lcVector3& Color) { const float r = LC_LINEAR_TO_SRGB(Color[0]); const float g = LC_LINEAR_TO_SRGB(Color[1]); const float b = LC_LINEAR_TO_SRGB(Color[2]); return lcVector3(r, g, b); } inline lcVector3 lcMul(const lcVector3& a, const lcMatrix33& b) { return b.r[0] * a[0] + b.r[1] * a[1] + b.r[2] * a[2]; } inline lcVector3 lcMul31(const lcVector3& a, const lcMatrix44& b) { lcVector4 v = b.r[0] * a[0] + b.r[1] * a[1] + b.r[2] * a[2] + b.r[3]; return lcVector3(v[0], v[1], v[2]); } inline lcVector3 lcMul31(const lcVector4& a, const lcMatrix44& b) { lcVector4 v = b.r[0] * a[0] + b.r[1] * a[1] + b.r[2] * a[2] + b.r[3]; return lcVector3(v[0], v[1], v[2]); } inline lcVector3 lcMul30(const lcVector3& a, const lcMatrix44& b) { lcVector4 v = b.r[0] * a[0] + b.r[1] * a[1] + b.r[2] * a[2]; return lcVector3(v[0], v[1], v[2]); } inline lcVector3 lcMul30(const lcVector4& a, const lcMatrix44& b) { lcVector4 v = b.r[0] * a[0] + b.r[1] * a[1] + b.r[2] * a[2]; return lcVector3(v[0], v[1], v[2]); } inline lcVector4 lcMul4(const lcVector4& a, const lcMatrix44& b) { return b.r[0] * a[0] + b.r[1] * a[1] + b.r[2] * a[2] + b.r[3] * a[3]; } inline lcMatrix33 lcMul(const lcMatrix33& a, const lcMatrix33& b) { const lcVector3 Col0(b.r[0][0], b.r[1][0], b.r[2][0]); const lcVector3 Col1(b.r[0][1], b.r[1][1], b.r[2][1]); const lcVector3 Col2(b.r[0][2], b.r[1][2], b.r[2][2]); const lcVector3 Ret0(lcDot(a.r[0], Col0), lcDot(a.r[0], Col1), lcDot(a.r[0], Col2)); const lcVector3 Ret1(lcDot(a.r[1], Col0), lcDot(a.r[1], Col1), lcDot(a.r[1], Col2)); const lcVector3 Ret2(lcDot(a.r[2], Col0), lcDot(a.r[2], Col1), lcDot(a.r[2], Col2)); return lcMatrix33(Ret0, Ret1, Ret2); } inline lcMatrix44 lcMul(const lcMatrix44& a, const lcMatrix44& b) { lcMatrix44 Result; Result.r[0] = b.r[0] * a[0].x + b.r[1] * a[0].y + b.r[2] * a[0].z + b.r[3] * a[0].w; Result.r[1] = b.r[0] * a[1].x + b.r[1] * a[1].y + b.r[2] * a[1].z + b.r[3] * a[1].w; Result.r[2] = b.r[0] * a[2].x + b.r[1] * a[2].y + b.r[2] * a[2].z + b.r[3] * a[2].w; Result.r[3] = b.r[0] * a[3].x + b.r[1] * a[3].y + b.r[2] * a[3].z + b.r[3] * a[3].w; return Result; } inline lcMatrix33::lcMatrix33(const lcMatrix44& Matrix) { r[0] = lcVector3(Matrix.r[0].x, Matrix.r[0].y, Matrix.r[0].z); r[1] = lcVector3(Matrix.r[1].x, Matrix.r[1].y, Matrix.r[1].z); r[2] = lcVector3(Matrix.r[2].x, Matrix.r[2].y, Matrix.r[2].z); } inline void lcMatrix33::Orthonormalize() { r[0] = lcNormalize(r[0]); r[1] = lcNormalize(r[1] - lcDot(r[1], r[0]) * r[0]); r[2] = r[2] - lcDot(r[2], r[0]) * r[0]; r[2] -= lcDot(r[2], r[1]) * r[1]; r[2] = lcNormalize(r[2]); } inline lcMatrix33 lcMatrix33Identity() { lcMatrix33 m; m.r[0] = lcVector3(1.0f, 0.0f, 0.0f); m.r[1] = lcVector3(0.0f, 1.0f, 0.0f); m.r[2] = lcVector3(0.0f, 0.0f, 1.0f); return m; } inline lcMatrix33 lcMatrix33Scale(const lcVector3& Scale) { lcMatrix33 m; m.r[0] = lcVector3(Scale.x, 0.0f, 0.0f); m.r[1] = lcVector3(0.0f, Scale.y, 0.0f); m.r[2] = lcVector3(0.0f, 0.0f, Scale.z); return m; } inline lcMatrix33 lcMatrix33RotationX(const float Radians) { float s, c; s = sinf(Radians); c = cosf(Radians); lcMatrix33 m; m.r[0] = lcVector3(1.0f, 0.0f, 0.0f); m.r[1] = lcVector3(0.0f, c, s); m.r[2] = lcVector3(0.0f, -s, c); return m; } inline lcMatrix33 lcMatrix33RotationY(const float Radians) { float s, c; s = sinf(Radians); c = cosf(Radians); lcMatrix33 m; m.r[0] = lcVector3( c, 0.0f, -s); m.r[1] = lcVector3(0.0f, 1.0f, 0.0f); m.r[2] = lcVector3( s, 0.0f, c); return m; } inline lcMatrix33 lcMatrix33RotationZ(const float Radians) { float s = sinf(Radians); float c = cosf(Radians); lcMatrix33 m; m.r[0] = lcVector3( c, s, 0.0f); m.r[1] = lcVector3( -s, c, 0.0f); m.r[2] = lcVector3(0.0f, 0.0f, 1.0f); return m; } inline lcMatrix33 lcMatrix33FromAxisAngle(const lcVector3& Axis, const float Radians) { float s = sinf(Radians); float c = cosf(Radians); float mag = Axis.Length(); if (mag == 0.0f) return lcMatrix33Identity(); lcVector3 Normal = Axis * (1.0f / mag); float xx = Normal[0] * Normal[0]; float yy = Normal[1] * Normal[1]; float zz = Normal[2] * Normal[2]; float xy = Normal[0] * Normal[1]; float yz = Normal[1] * Normal[2]; float zx = Normal[2] * Normal[0]; float xs = Normal[0] * s; float ys = Normal[1] * s; float zs = Normal[2] * s; float one_c = 1.0f - c; lcMatrix33 m; m.r[0] = lcVector3((one_c * xx) + c, (one_c * xy) + zs, (one_c * zx) - ys); m.r[1] = lcVector3((one_c * xy) - zs, (one_c * yy) + c, (one_c * yz) + xs); m.r[2] = lcVector3((one_c * zx) + ys, (one_c * yz) - xs, (one_c * zz) + c); return m; } inline lcMatrix33 lcMatrix33Transpose(const lcMatrix33& m) { lcMatrix33 t; t.r[0] = lcVector3(m[0][0], m[1][0], m[2][0]); t.r[1] = lcVector3(m[0][1], m[1][1], m[2][1]); t.r[2] = lcVector3(m[0][2], m[1][2], m[2][2]); return t; } inline lcMatrix33 lcMatrix33AffineInverse(const lcMatrix33& m) { lcMatrix33 Inv; Inv.r[0] = lcVector3(m.r[0][0], m.r[1][0], m.r[2][0]); Inv.r[1] = lcVector3(m.r[0][1], m.r[1][1], m.r[2][1]); Inv.r[2] = lcVector3(m.r[0][2], m.r[1][2], m.r[2][2]); return Inv; } inline lcMatrix33 lcMatrix33FromEulerAngles(const lcVector3& Radians) { float CosYaw, SinYaw, CosPitch, SinPitch, CosRoll, SinRoll; CosRoll = cosf(Radians[0]); SinRoll = sinf(Radians[0]); CosPitch = cosf(Radians[1]); SinPitch = sinf(Radians[1]); CosYaw = cosf(Radians[2]); SinYaw = sinf(Radians[2]); lcMatrix33 m; m.r[0] = lcVector3(CosYaw * CosPitch, SinYaw * CosPitch, -SinPitch); m.r[1] = lcVector3(CosYaw * SinPitch * SinRoll - SinYaw * CosRoll, CosYaw * CosRoll + SinYaw * SinPitch * SinRoll, CosPitch * SinRoll); m.r[2] = lcVector3(CosYaw * SinPitch * CosRoll + SinYaw * SinRoll, SinYaw * SinPitch * CosRoll - CosYaw * SinRoll, CosPitch * CosRoll); return m; } inline lcVector3 lcMatrix33ToEulerAngles(const lcMatrix33& RotMat) { float SinPitch, CosPitch, SinRoll, CosRoll, SinYaw, CosYaw; SinPitch = -RotMat.r[0][2]; CosPitch = sqrtf(1 - SinPitch*SinPitch); if (fabsf(CosPitch) > 0.0005f) { SinRoll = RotMat.r[1][2] / CosPitch; CosRoll = RotMat.r[2][2] / CosPitch; SinYaw = RotMat.r[0][1] / CosPitch; CosYaw = RotMat.r[0][0] / CosPitch; } else { SinRoll = -RotMat.r[2][1]; CosRoll = RotMat.r[1][1]; SinYaw = 0.0f; CosYaw = 1.0f; } lcVector3 Rot(atan2f(SinRoll, CosRoll), atan2f(SinPitch, CosPitch), atan2f(SinYaw, CosYaw)); if (Rot[0] < 0) Rot[0] += LC_2PI; if (Rot[1] < 0) Rot[1] += LC_2PI; if (Rot[2] < 0) Rot[2] += LC_2PI; return Rot; } inline float lcMatrix44::Determinant() const { return r[0][0] * r[1][1] * r[2][2] + r[0][1] * r[1][2] * r[2][0] + r[0][2] * r[1][0] * r[2][1] - r[0][0] * r[1][2] * r[2][1] - r[0][1] * r[1][0] * r[2][2] - r[0][2] * r[1][1] * r[2][0]; } inline lcMatrix44 lcMatrix44Identity() { lcMatrix44 m; m.r[0] = lcVector4(1.0f, 0.0f, 0.0f, 0.0f); m.r[1] = lcVector4(0.0f, 1.0f, 0.0f, 0.0f); m.r[2] = lcVector4(0.0f, 0.0f, 1.0f, 0.0f); m.r[3] = lcVector4(0.0f, 0.0f, 0.0f, 1.0f); return m; } inline lcMatrix44 lcMatrix44Translation(const lcVector3& Translation) { lcMatrix44 m; m.r[0] = lcVector4(1.0f, 0.0f, 0.0f, 0.0f); m.r[1] = lcVector4(0.0f, 1.0f, 0.0f, 0.0f); m.r[2] = lcVector4(0.0f, 0.0f, 1.0f, 0.0f); m.r[3] = lcVector4(Translation[0], Translation[1], Translation[2], 1.0f); return m; } inline lcMatrix44 lcMatrix44RotationX(const float Radians) { float s, c; s = sinf(Radians); c = cosf(Radians); lcMatrix44 m; m.r[0] = lcVector4(1.0f, 0.0f, 0.0f, 0.0f); m.r[1] = lcVector4(0.0f, c, s, 0.0f); m.r[2] = lcVector4(0.0f, -s, c, 0.0f); m.r[3] = lcVector4(0.0f, 0.0f, 0.0f, 1.0f); return m; } inline lcMatrix44 lcMatrix44RotationY(const float Radians) { float s, c; s = sinf(Radians); c = cosf(Radians); lcMatrix44 m; m.r[0] = lcVector4( c, 0.0f, -s, 0.0f); m.r[1] = lcVector4(0.0f, 1.0f, 0.0f, 0.0f); m.r[2] = lcVector4( s, 0.0f, c, 0.0f); m.r[3] = lcVector4(0.0f, 0.0f, 0.0f, 1.0f); return m; } inline lcMatrix44 lcMatrix44RotationZ(const float Radians) { float s, c; s = sinf(Radians); c = cosf(Radians); lcMatrix44 m; m.r[0] = lcVector4( c, s, 0.0f, 0.0f); m.r[1] = lcVector4( -s, c, 0.0f, 0.0f); m.r[2] = lcVector4(0.0f, 0.0f, 1.0f, 0.0f); m.r[3] = lcVector4(0.0f, 0.0f, 0.0f, 1.0f); return m; } inline lcMatrix44 lcMatrix44Scale(const lcVector3& Scale) { lcMatrix44 m; m.r[0] = lcVector4(Scale.x, 0.0f, 0.0f, 0.0f); m.r[1] = lcVector4(0.0f, Scale.y, 0.0f, 0.0f); m.r[2] = lcVector4(0.0f, 0.0f, Scale.z, 0.0f); m.r[3] = lcVector4(0.0f, 0.0f, 0.0f, 1.0f); return m; } inline lcMatrix44 lcMatrix44LookAt(const lcVector3& Eye, const lcVector3& Target, const lcVector3& Up) { lcVector3 x, y, z; z = lcNormalize(Eye - Target); x = lcNormalize(lcCross(Up, z)); y = lcNormalize(lcCross(z, x)); lcMatrix44 m; m.r[0] = lcVector4(x[0], y[0], z[0], 0.0f); m.r[1] = lcVector4(x[1], y[1], z[1], 0.0f); m.r[2] = lcVector4(x[2], y[2], z[2], 0.0f); m.r[3] = m.r[0] * -Eye[0] + m.r[1] * -Eye[1] + m.r[2] * -Eye[2]; m.r[3][3] = 1.0f; return m; } inline lcMatrix44 lcMatrix44Frustum(float Left, float Right, float Bottom, float Top, float Near, float Far) { if ((Near <= 0.0f) || (Far <= 0.0f) || (Near == Far) || (Left == Right) || (Top == Bottom)) return lcMatrix44Identity(); float x, y, a, b, c, d; x = (2.0f * Near) / (Right - Left); y = (2.0f * Near) / (Top - Bottom); a = (Right + Left) / (Right - Left); b = (Top + Bottom) / (Top - Bottom); c = -(Far + Near) / (Far - Near); d = -(2.0f * Far * Near) / (Far - Near); lcMatrix44 m; m.r[0] = lcVector4(x, 0, 0, 0); m.r[1] = lcVector4(0, y, 0, 0); m.r[2] = lcVector4(a, b, c, -1); m.r[3] = lcVector4(0, 0, d, 0); return m; } inline lcMatrix44 lcMatrix44Perspective(float FoVy, float Aspect, float Near, float Far) { float Left, Right, Bottom, Top; Top = Near * (float)tan(FoVy * LC_PI / 360.0f); Bottom = -Top; Left = Bottom * Aspect; Right = Top * Aspect; return lcMatrix44Frustum(Left, Right, Bottom, Top, Near, Far); } inline lcMatrix44 lcMatrix44Ortho(float Left, float Right, float Bottom, float Top, float Near, float Far) { lcMatrix44 m; m.r[0] = lcVector4(2.0f / (Right-Left), 0.0f, 0.0f, 0.0f), m.r[1] = lcVector4(0.0f, 2.0f / (Top-Bottom), 0.0f, 0.0f), m.r[2] = lcVector4(0.0f, 0.0f, -2.0f / (Far-Near), 0.0f), m.r[3] = lcVector4(-(Right+Left) / (Right-Left), -(Top+Bottom) / (Top-Bottom), -(Far+Near) / (Far-Near), 1.0f); return m; } inline lcMatrix44 lcMatrix44FromAxisAngle(const lcVector3& Axis, const float Radians) { float s, c, mag, xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c; s = sinf(Radians); c = cosf(Radians); mag = Axis.Length(); if (mag == 0.0f) return lcMatrix44Identity(); lcVector3 Normal = Axis * (1.0f / mag); xx = Normal[0] * Normal[0]; yy = Normal[1] * Normal[1]; zz = Normal[2] * Normal[2]; xy = Normal[0] * Normal[1]; yz = Normal[1] * Normal[2]; zx = Normal[2] * Normal[0]; xs = Normal[0] * s; ys = Normal[1] * s; zs = Normal[2] * s; one_c = 1.0f - c; lcMatrix44 m; m.r[0] = lcVector4((one_c * xx) + c, (one_c * xy) + zs, (one_c * zx) - ys, 0.0f); m.r[1] = lcVector4((one_c * xy) - zs, (one_c * yy) + c, (one_c * yz) + xs, 0.0f); m.r[2] = lcVector4((one_c * zx) + ys, (one_c * yz) - xs, (one_c * zz) + c, 0.0f); m.r[3] = lcVector4(0.0f, 0.0f, 0.0f, 1.0f); return m; } inline lcVector4 lcMatrix44ToAxisAngle(const lcMatrix44& m) { lcVector3 Rows[3]; Rows[0] = lcNormalize(lcVector3(m.r[0][0], m.r[0][1], m.r[0][2])); Rows[1] = lcNormalize(lcVector3(m.r[1][0], m.r[1][1], m.r[1][2])); Rows[2] = lcNormalize(lcVector3(m.r[2][0], m.r[2][1], m.r[2][2])); if (m.Determinant() < 0.0f) Rows[0] *= -1.0f; const float Trace = Rows[0][0] + Rows[1][1] + Rows[2][2]; const float Cos = 0.5f * (Trace - 1.0f); lcVector4 rot; rot[3] = acosf(lcClamp(Cos, -1.0f, 1.0f)); // in [0,PI] if (rot[3] > 0.01f) { if (fabsf(LC_PI - rot[3]) > 0.01f) { rot[0] = Rows[1][2] - Rows[2][1]; rot[1] = Rows[2][0] - Rows[0][2]; rot[2] = Rows[0][1] - Rows[1][0]; float inv = 1.0f / sqrtf(rot[0]*rot[0] + rot[1]*rot[1] + rot[2]*rot[2]); rot[0] *= inv; rot[1] *= inv; rot[2] *= inv; } else { // angle is PI float HalfInverse; if (Rows[0][0] >= Rows[1][1]) { // r00 >= r11 if (Rows[0][0] >= Rows[2][2]) { // r00 is maximum diagonal term rot[0] = 0.5f * sqrtf(Rows[0][0] - Rows[1][1] - Rows[2][2] + 1.0f); HalfInverse = 0.5f / rot[0]; rot[1] = HalfInverse * Rows[1][0]; rot[2] = HalfInverse * Rows[2][0]; } else { // r22 is maximum diagonal term rot[2] = 0.5f * sqrtf(Rows[2][2] - Rows[0][0] - Rows[1][1] + 1.0f); HalfInverse = 0.5f / rot[2]; rot[0] = HalfInverse * Rows[2][0]; rot[1] = HalfInverse * Rows[2][1]; } } else { // r11 > r00 if (Rows[1][1] >= Rows[2][2]) { // r11 is maximum diagonal term rot[1] = 0.5f * sqrtf(Rows[1][1] - Rows[0][0] - Rows[2][2] + 1.0f); HalfInverse = 0.5f / rot[1]; rot[0] = HalfInverse * Rows[1][0]; rot[2] = HalfInverse * Rows[2][1]; } else { // r22 is maximum diagonal term rot[2] = 0.5f * sqrtf(Rows[2][2] - Rows[0][0] - Rows[1][1] + 1.0f); HalfInverse = 0.5f / rot[2]; rot[0] = HalfInverse * Rows[2][0]; rot[1] = HalfInverse * Rows[2][1]; } } } } else { // The angle is 0 and the matrix is the identity. rot[0] = 0.0f; rot[1] = 0.0f; rot[2] = 1.0f; } return rot; } inline lcMatrix44 lcMatrix44FromEulerAngles(const lcVector3& Radians) { float CosYaw, SinYaw, CosPitch, SinPitch, CosRoll, SinRoll; CosRoll = cosf(Radians[0]); SinRoll = sinf(Radians[0]); CosPitch = cosf(Radians[1]); SinPitch = sinf(Radians[1]); CosYaw = cosf(Radians[2]); SinYaw = sinf(Radians[2]); lcMatrix44 m; m.r[0] = lcVector4(CosYaw * CosPitch, SinYaw * CosPitch, -SinPitch, 0.0f); m.r[1] = lcVector4(CosYaw * SinPitch * SinRoll - SinYaw * CosRoll, CosYaw * CosRoll + SinYaw * SinPitch * SinRoll, CosPitch * SinRoll, 0.0f); m.r[2] = lcVector4(CosYaw * SinPitch * CosRoll + SinYaw * SinRoll, SinYaw * SinPitch * CosRoll - CosYaw * SinRoll, CosPitch * CosRoll, 0.0f); m.r[3] = lcVector4(0.0f, 0.0f, 0.0f, 1.0f); return m; } inline lcVector3 lcMatrix44ToEulerAngles(const lcMatrix44& RotMat) { float SinPitch, CosPitch, SinRoll, CosRoll, SinYaw, CosYaw; SinPitch = -RotMat.r[0][2]; CosPitch = sqrtf(1 - SinPitch*SinPitch); if (fabsf(CosPitch) > 0.0005f) { SinRoll = RotMat.r[1][2] / CosPitch; CosRoll = RotMat.r[2][2] / CosPitch; SinYaw = RotMat.r[0][1] / CosPitch; CosYaw = RotMat.r[0][0] / CosPitch; } else { SinRoll = -RotMat.r[2][1]; CosRoll = RotMat.r[1][1]; SinYaw = 0.0f; CosYaw = 1.0f; } lcVector3 Rot(atan2f(SinRoll, CosRoll), atan2f(SinPitch, CosPitch), atan2f(SinYaw, CosYaw)); if (Rot[0] < 0) Rot[0] += LC_2PI; if (Rot[1] < 0) Rot[1] += LC_2PI; if (Rot[2] < 0) Rot[2] += LC_2PI; return Rot; } inline lcMatrix44 lcMatrix44Transpose(const lcMatrix44& m) { lcMatrix44 t; t.r[0] = lcVector4(m[0][0], m[1][0], m[2][0], m[3][0]); t.r[1] = lcVector4(m[0][1], m[1][1], m[2][1], m[3][1]); t.r[2] = lcVector4(m[0][2], m[1][2], m[2][2], m[3][2]); t.r[3] = lcVector4(m[0][3], m[1][3], m[2][3], m[3][3]); return t; } inline lcMatrix44 lcMatrix44AffineInverse(const lcMatrix44& m) { lcMatrix44 Inv; Inv.r[0] = lcVector4(m.r[0][0], m.r[1][0], m.r[2][0], m.r[0][3]); Inv.r[1] = lcVector4(m.r[0][1], m.r[1][1], m.r[2][1], m.r[1][3]); Inv.r[2] = lcVector4(m.r[0][2], m.r[1][2], m.r[2][2], m.r[2][3]); lcVector3 Trans = -lcMul30(m.r[3], Inv); Inv.r[3] = lcVector4(Trans[0], Trans[1], Trans[2], 1.0f); return Inv; } // Inverse code from the GLU library. inline lcMatrix44 lcMatrix44Inverse(const lcMatrix44& m) { #define SWAP_ROWS(a, b) { float *_tmp = a; (a)=(b); (b)=_tmp; } #define MAT(m,col,row) m.r[row][col] float wtmp[4][8]; float m0, m1, m2, m3, s; float *r0, *r1, *r2, *r3; r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1), r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3), r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1), r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3), r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1), r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3), r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1), r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3), r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; // choose pivot - or die if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2); if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1); if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0); // if (0.0 == r0[0]) return GL_FALSE; // eliminate first variable m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; s = r0[4]; if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } s = r0[5]; if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } s = r0[6]; if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } s = r0[7]; if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } // choose pivot - or die if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2); if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1); // if (0.0 == r1[1]) return GL_FALSE; // eliminate second variable m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1]; r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } // choose pivot - or die if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2); // if (0.0 == r2[2]) return GL_FALSE; // eliminate third variable m3 = r3[2]/r2[2]; r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], r3[7] -= m3 * r2[7]; // last check // if (0.0 == r3[3]) return GL_FALSE; s = 1.0f/r3[3]; // now back substitute row 3 r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; m2 = r2[3]; // now back substitute row 2 s = 1.0f/r2[2]; r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); m1 = r1[3]; r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; m0 = r0[3]; r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; m1 = r1[2]; // now back substitute row 1 s = 1.0f/r1[1]; r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); m0 = r0[2]; r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; m0 = r0[1]; // now back substitute row 0 s = 1.0f/r0[0]; r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); const lcVector4 Row0(r0[4], r1[4], r2[4], r3[4]); const lcVector4 Row1(r0[5], r1[5], r2[5], r3[5]); const lcVector4 Row2(r0[6], r1[6], r2[6], r3[6]); const lcVector4 Row3(r0[7], r1[7], r2[7], r3[7]); lcMatrix44 out(Row0, Row1, Row2, Row3); return out; #undef MAT #undef SWAP_ROWS } inline lcMatrix44 lcMatrix44LeoCADToLDraw(const lcMatrix44& Matrix) { lcMatrix44 m; m.r[0] = lcVector4(Matrix[0][0], -Matrix[2][0], Matrix[1][0], 0.0f); m.r[1] = lcVector4(-Matrix[0][2], Matrix[2][2], -Matrix[1][2], 0.0f); m.r[2] = lcVector4(Matrix[0][1], -Matrix[2][1], Matrix[1][1], 0.0f); m.r[3] = lcVector4(Matrix[3][0], -Matrix[3][2], Matrix[3][1], 1.0f); return m; } inline lcMatrix44 lcMatrix44LDrawToLeoCAD(const lcMatrix44& Matrix) { lcMatrix44 m; m.r[0] = lcVector4(Matrix[0][0], Matrix[0][2], -Matrix[0][1], 0.0f); m.r[1] = lcVector4(Matrix[2][0], Matrix[2][2], -Matrix[2][1], 0.0f); m.r[2] = lcVector4(-Matrix[1][0], -Matrix[1][2], Matrix[1][1], 0.0f); m.r[3] = lcVector4(Matrix[3][0], Matrix[3][2], -Matrix[3][1], 1.0f); return m; } inline lcVector4 lcQuaternionRotationX(float Radians) { return lcVector4(sinf(Radians / 2.0f), 0, 0, cosf(Radians / 2.0f)); } inline lcVector4 lcQuaternionRotationY(float Radians) { return lcVector4(0, sinf(Radians / 2.0f), 0, cosf(Radians / 2.0f)); } inline lcVector4 lcQuaternionRotationZ(float Radians) { return lcVector4(0, 0, sinf(Radians / 2.0f), cosf(Radians / 2.0f)); } inline lcVector4 lcQuaternionFromAxisAngle(const lcVector4& a) { const float s = sinf(a[3] / 2.0f); return lcVector4(a[0] * s, a[1] * s, a[2] * s, cosf(a[3] / 2.0f)); } inline lcVector4 lcQuaternionToAxisAngle(const lcVector4& a) { const float Len = lcDot3(a, a); if (Len > 0.00001f) { const float f = 1.0f / sqrtf(Len); return lcVector4(a[0] * f, a[1] * f, a[2] * f, acosf(a[3]) * 2.0f); } else { return lcVector4(0, 0, 1, 0); } } inline lcVector4 lcQuaternionMultiply(const lcVector4& a, const lcVector4& b) { const float x = a[0] * b[3] + a[1] * b[2] - a[2] * b[1] + a[3] * b[0]; const float y = -a[0] * b[2] + a[1] * b[3] + a[2] * b[0] + a[3] * b[1]; const float z = a[0] * b[1] - a[1] * b[0] + a[2] * b[3] + a[3] * b[2]; const float w = -a[0] * b[0] - a[1] * b[1] - a[2] * b[2] + a[3] * b[3]; return lcVector4(x, y, z, w); } inline lcVector3 lcQuaternionMul(const lcVector3& a, const lcVector4& b) { // Faster to transform to a matrix and multiply. const float Tx = 2.0f*b[0]; const float Ty = 2.0f*b[1]; const float Tz = 2.0f*b[2]; const float Twx = Tx*b[3]; const float Twy = Ty*b[3]; const float Twz = Tz*b[3]; const float Txx = Tx*b[0]; const float Txy = Ty*b[0]; const float Txz = Tz*b[0]; const float Tyy = Ty*b[1]; const float Tyz = Tz*b[1]; const float Tzz = Tz*b[2]; lcVector3 Rows[3]; Rows[0] = lcVector3(1.0f-(Tyy+Tzz), Txy+Twz, Txz-Twy); Rows[1] = lcVector3(Txy-Twz, 1.0f-(Txx+Tzz), Tyz+Twx); Rows[2] = lcVector3(Txz+Twy, Tyz-Twx, 1.0f-(Txx+Tyy)); return lcVector3(Rows[0]*a[0] + Rows[1]*a[1] + Rows[2]*a[2]); } // Convert world coordinates to screen coordinates. inline lcVector3 lcProjectPoint(const lcVector3& Point, const lcMatrix44& ModelView, const lcMatrix44& Projection, const int Viewport[4]) { lcVector4 Tmp; Tmp = lcMul4(lcVector4(Point[0], Point[1], Point[2], 1.0f), ModelView); Tmp = lcMul4(Tmp, Projection); // Normalize. Tmp /= Tmp[3]; // Screen coordinates. return lcVector3(Viewport[0] + (1 + Tmp[0]) * Viewport[2] / 2, Viewport[1] + (1 + Tmp[1]) * Viewport[3] / 2, (1 + Tmp[2]) / 2); } inline lcVector3 lcUnprojectPoint(const lcVector3& Point, const lcMatrix44& ModelView, const lcMatrix44& Projection, const int Viewport[4]) { // Calculate the screen to model transform. const lcMatrix44 Transform = lcMatrix44Inverse(lcMul(ModelView, Projection)); lcVector4 Tmp; // Convert the point to homogeneous coordinates. Tmp[0] = (Point[0] - Viewport[0]) * 2.0f / Viewport[2] - 1.0f; Tmp[1] = (Point[1] - Viewport[1]) * 2.0f / Viewport[3] - 1.0f; Tmp[2] = Point[2] * 2.0f - 1.0f; Tmp[3] = 1.0f; Tmp = lcMul4(Tmp, Transform); if (Tmp[3] != 0.0f) Tmp /= Tmp[3]; return lcVector3(Tmp[0], Tmp[1], Tmp[2]); } inline void lcUnprojectPoints(lcVector3* Points, int NumPoints, const lcMatrix44& ModelView, const lcMatrix44& Projection, const int Viewport[4]) { // Calculate the screen to model transform. const lcMatrix44 Transform = lcMatrix44Inverse(lcMul(ModelView, Projection)); for (int i = 0; i < NumPoints; i++) { lcVector4 Tmp; // Convert the point to homogeneous coordinates. Tmp[0] = (Points[i][0] - Viewport[0]) * 2.0f / Viewport[2] - 1.0f; Tmp[1] = (Points[i][1] - Viewport[1]) * 2.0f / Viewport[3] - 1.0f; Tmp[2] = Points[i][2] * 2.0f - 1.0f; Tmp[3] = 1.0f; Tmp = lcMul4(Tmp, Transform); if (Tmp[3] != 0.0f) Tmp /= Tmp[3]; Points[i] = lcVector3(Tmp[0], Tmp[1], Tmp[2]); } } inline void lcGetFrustumPlanes(const lcMatrix44& WorldView, const lcMatrix44& Projection, lcVector4 Planes[6]) { lcMatrix44 WorldProj = lcMul(WorldView, Projection); Planes[0][0] = (WorldProj[0][0] - WorldProj[0][3]) * -1; Planes[0][1] = (WorldProj[1][0] - WorldProj[1][3]) * -1; Planes[0][2] = (WorldProj[2][0] - WorldProj[2][3]) * -1; Planes[0][3] = (WorldProj[3][0] - WorldProj[3][3]) * -1; Planes[1][0] = WorldProj[0][0] + WorldProj[0][3]; Planes[1][1] = WorldProj[1][0] + WorldProj[1][3]; Planes[1][2] = WorldProj[2][0] + WorldProj[2][3]; Planes[1][3] = WorldProj[3][0] + WorldProj[3][3]; Planes[2][0] = (WorldProj[0][1] - WorldProj[0][3]) * -1; Planes[2][1] = (WorldProj[1][1] - WorldProj[1][3]) * -1; Planes[2][2] = (WorldProj[2][1] - WorldProj[2][3]) * -1; Planes[2][3] = (WorldProj[3][1] - WorldProj[3][3]) * -1; Planes[3][0] = WorldProj[0][1] + WorldProj[0][3]; Planes[3][1] = WorldProj[1][1] + WorldProj[1][3]; Planes[3][2] = WorldProj[2][1] + WorldProj[2][3]; Planes[3][3] = WorldProj[3][1] + WorldProj[3][3]; Planes[4][0] = (WorldProj[0][2] - WorldProj[0][3]) * -1; Planes[4][1] = (WorldProj[1][2] - WorldProj[1][3]) * -1; Planes[4][2] = (WorldProj[2][2] - WorldProj[2][3]) * -1; Planes[4][3] = (WorldProj[3][2] - WorldProj[3][3]) * -1; Planes[5][0] = WorldProj[0][2] + WorldProj[0][3]; Planes[5][1] = WorldProj[1][2] + WorldProj[1][3]; Planes[5][2] = WorldProj[2][2] + WorldProj[2][3]; Planes[5][3] = WorldProj[3][2] + WorldProj[3][3]; for (int i = 0; i < 6; i++) { const lcVector3 Normal(Planes[i][0], Planes[i][1], Planes[i][2]); const float Length = Normal.Length(); Planes[i] /= -Length; } } inline std::tuple lcZoomExtents(const lcVector3& Position, const lcMatrix44& WorldView, const lcMatrix44& Projection, const lcVector3* Points, size_t NumPoints) { if (!NumPoints) return std::make_tuple(Position, 2500.0f); lcVector4 Planes[6]; lcGetFrustumPlanes(WorldView, Projection, Planes); const lcVector3 Front(WorldView[0][2], WorldView[1][2], WorldView[2][2]); float SmallestDistance = FLT_MAX; for (int PlaneIdx = 0; PlaneIdx < 4; PlaneIdx++) { const lcVector3 Plane(Planes[PlaneIdx][0], Planes[PlaneIdx][1], Planes[PlaneIdx][2]); const float ep = lcDot(Position, Plane); const float fp = lcDot(Front, Plane); for (size_t PointIdx = 0; PointIdx < NumPoints; PointIdx++) { const float u = (ep - lcDot(Points[PointIdx], Plane)) / fp; if (u < SmallestDistance) SmallestDistance = u; } } lcVector3 NewPosition = Position - (Front * SmallestDistance); float FarDistance = 2500.0f; for (size_t PointIdx = 0; PointIdx < NumPoints; PointIdx++) { const float Distance = lcDot(Points[PointIdx], Front); if (Distance > FarDistance) FarDistance = Distance; } return std::make_tuple(NewPosition, FarDistance + lcDot(NewPosition, Front)); } inline void lcClosestPointsBetweenLines(const lcVector3& Line1a, const lcVector3& Line1b, const lcVector3& Line2a, const lcVector3& Line2b, lcVector3* Intersection1, lcVector3* Intersection2) { const lcVector3 u1 = Line1b - Line1a; const lcVector3 u2 = Line2b - Line2a; const lcVector3 p21 = Line2a - Line1a; const lcVector3 m = lcCross(u2, u1); const float m2 = lcDot(m, m); if (m2 < 0.00001f) { if (Intersection1) *Intersection1 = Line1a; if (Intersection2) *Intersection2 = Line2a; return; } const lcVector3 r = lcCross(p21, m / m2); if (Intersection1) { const float t1 = lcDot(r, u2); *Intersection1 = Line1a + t1 * u1; } if (Intersection2) { const float t2 = lcDot(r, u1); *Intersection2 = Line2a + t2 * u2; } } inline bool lcLineSegmentPlaneIntersection(lcVector3* Intersection, const lcVector3& Start, const lcVector3& End, const lcVector4& Plane) { const lcVector3 Dir = End - Start; const lcVector3 PlaneNormal(Plane[0], Plane[1], Plane[2]); const float t1 = lcDot(PlaneNormal, Start) + Plane[3]; const float t2 = lcDot(PlaneNormal, Dir); if (t2 == 0.0f) return false; const float t = -t1 / t2; *Intersection = Start + t * Dir; if ((t < 0.0f) || (t > 1.0f)) return false; return true; } inline bool lcLineTriangleMinIntersection(const lcVector3& p1, const lcVector3& p2, const lcVector3& p3, const lcVector3& Start, const lcVector3& End, float* MinDist, lcVector3* Intersection) { // Calculate the polygon plane. const lcVector3 PlaneNormal = lcCross(p1 - p2, p3 - p2); const float PlaneD = -lcDot(PlaneNormal, p1); // Check if the line is parallel to the plane. const lcVector3 Dir = End - Start; const float t1 = lcDot(PlaneNormal, Start) + PlaneD; const float t2 = lcDot(PlaneNormal, Dir); if (t2 == 0) return false; const float t = -(t1 / t2); if (t < 0) return false; // Intersection of the plane and line segment. *Intersection = Start - (t1 / t2) * Dir; float Dist = lcLength(Start - *Intersection); if (Dist > *MinDist) return false; // Check if we're inside the triangle. lcVector3 pa1, pa2, pa3; pa1 = lcNormalize(p1 - *Intersection); pa2 = lcNormalize(p2 - *Intersection); pa3 = lcNormalize(p3 - *Intersection); float a1, a2, a3; a1 = lcDot(pa1, pa2); a2 = lcDot(pa2, pa3); a3 = lcDot(pa3, pa1); const float total = (acosf(a1) + acosf(a2) + acosf(a3)) * LC_RTOD; if (fabs(total - 360) <= 0.001f) { *MinDist = Dist; return true; } return false; } // Sutherland-Hodgman method of clipping a polygon to a plane. inline void lcPolygonPlaneClip(lcVector3* InPoints, int NumInPoints, lcVector3* OutPoints, int* NumOutPoints, const lcVector4& Plane) { lcVector3 *s, *p, i; *NumOutPoints = 0; s = &InPoints[NumInPoints-1]; for (int j = 0; j < NumInPoints; j++) { p = &InPoints[j]; if (lcDot3(*p, Plane) + Plane[3] <= 0) { if (lcDot3(*s, Plane) + Plane[3] <= 0) { // Both points inside. OutPoints[*NumOutPoints] = *p; *NumOutPoints = *NumOutPoints + 1; } else { // Outside, inside. lcLineSegmentPlaneIntersection(&i, *s, *p, Plane); OutPoints[*NumOutPoints] = i; *NumOutPoints = *NumOutPoints + 1; OutPoints[*NumOutPoints] = *p; *NumOutPoints = *NumOutPoints + 1; } } else { if (lcDot3(*s, Plane) + Plane[3] <= 0) { // Inside, outside. lcLineSegmentPlaneIntersection(&i, *s, *p, Plane); OutPoints[*NumOutPoints] = i; *NumOutPoints = *NumOutPoints + 1; } } s = p; } } // Return true if a polygon intersects a set of planes. inline bool lcTriangleIntersectsPlanes(const float* p1, const float* p2, const float* p3, const lcVector4 Planes[6]) { constexpr int NumPlanes = 6; const float* const Points[3] = { p1, p2, p3 }; int Outcodes[3] = { 0, 0, 0 }, i; constexpr int NumPoints = 3; // First do the Cohen-Sutherland out code test for trivial rejects/accepts. for (i = 0; i < NumPoints; i++) { const lcVector3 Pt(Points[i][0], Points[i][1], Points[i][2]); for (int j = 0; j < NumPlanes; j++) { if (lcDot3(Pt, Planes[j]) + Planes[j][3] > 0) Outcodes[i] |= 1 << j; } } // Polygon completely outside a plane. if ((Outcodes[0] & Outcodes[1] & Outcodes[2]) != 0) return false; // If any vertex has an out code of all zeros then we intersect the volume. if (!Outcodes[0] || !Outcodes[1] || !Outcodes[2]) return true; // Buffers for clipping the polygon. lcVector3 ClipPoints[2][8]; int NumClipPoints[2]; int ClipBuffer = 0; NumClipPoints[0] = NumPoints; ClipPoints[0][0] = lcVector3(p1[0], p1[1], p1[2]); ClipPoints[0][1] = lcVector3(p2[0], p2[1], p2[2]); ClipPoints[0][2] = lcVector3(p3[0], p3[1], p3[2]); // Now clip the polygon against the planes. for (i = 0; i < NumPlanes; i++) { lcPolygonPlaneClip(ClipPoints[ClipBuffer], NumClipPoints[ClipBuffer], ClipPoints[ClipBuffer^1], &NumClipPoints[ClipBuffer^1], Planes[i]); ClipBuffer ^= 1; if (!NumClipPoints[ClipBuffer]) return false; } return true; } // Return true if a ray intersects a bounding box, and calculates the distance from the start of the ray (adapted from Graphics Gems). inline bool lcBoundingBoxRayIntersectDistance(const lcVector3& Min, const lcVector3& Max, const lcVector3& Start, const lcVector3& End, float* Dist, lcVector3* Intersection, lcVector3* Plane) { bool MiddleQuadrant[3]; bool Inside = true; float CandidatePlane[3]; float MaxT[3]; int i; // Find candidate planes. for (i = 0; i < 3; i++) { if (Start[i] < Min[i]) { MiddleQuadrant[i] = false; CandidatePlane[i] = Min[i]; Inside = false; } else if (Start[i] > Max[i]) { MiddleQuadrant[i] = false; CandidatePlane[i] = Max[i]; Inside = false; } else { MiddleQuadrant[i] = true; CandidatePlane[i] = 0.0f; } } // Ray origin inside box. if (Inside) { *Dist = 0; if (Intersection) *Intersection = Start; if (Plane) *Plane = Start; return true; } // Calculate T distances to candidate planes. lcVector3 Dir = End - Start; for (i = 0; i < 3; i++) { if (!MiddleQuadrant[i] && Dir[i] != 0.0f) MaxT[i] = (CandidatePlane[i] - Start[i]) / Dir[i]; else MaxT[i] = -1.0f; } // Get largest of the MaxT's for final choice of intersection. int WhichPlane = 0; for (i = 1; i < 3; i++) if (MaxT[WhichPlane] < MaxT[i]) WhichPlane = i; // Check final candidate actually inside box. if (MaxT[WhichPlane] < 0.0f) return false; lcVector3 Point; for (i = 0; i < 3; i++) { if (WhichPlane != i) { Point[i] = Start[i] + MaxT[WhichPlane] * Dir[i]; if (Point[i] < Min[i] || Point[i] > Max[i]) return false; } else Point[i] = CandidatePlane[i]; } *Dist = lcLength(Point - Start); if (Intersection) *Intersection = Point; if (Plane) { *Plane = lcVector3(0.0f, 0.0f, 0.0f); (*Plane)[WhichPlane] = CandidatePlane[WhichPlane]; } return true; } inline bool lcSphereRayIntersection(const lcVector3& Center, float Radius, const lcVector3& Start, const lcVector3& End, lcVector3& Intersection) { const lcVector3 RayDirection = lcNormalize(End - Start); const lcVector3 RayCenter = Center - Start; const float RayCenterSquared = lcDot(RayCenter, RayCenter); const float ClosestApproach = lcDot(RayCenter, RayDirection); if (ClosestApproach < 0) return false; const float HalfCordSquared = (Radius * Radius) - RayCenterSquared + (ClosestApproach * ClosestApproach); if (HalfCordSquared < 0) return false; Intersection = Start + RayDirection * (ClosestApproach - sqrtf(HalfCordSquared)); return true; } inline bool lcSphereRayMinIntersectDistance(const lcVector3& Center, float Radius, const lcVector3& Start, const lcVector3& End, float* Dist) { const lcVector3 Dir = Center - Start; const float LengthSquaredDir = lcLengthSquared(Dir); const float RadiusSquared = Radius * Radius; if (LengthSquaredDir < RadiusSquared) { // Ray origin inside sphere. *Dist = 0; return true; } else { const lcVector3 RayDir = End - Start; float t = lcDot(Dir, RayDir) / lcLengthSquared(RayDir); // Ray points away from sphere. if (t < 0) return false; const float c = (RadiusSquared - LengthSquaredDir) / lcLengthSquared(RayDir) + (t * t); if (c > 0) { *Dist = t - sqrtf(c); return true; } return false; } } inline lcVector3 lcRayPointClosestPoint(const lcVector3& Point, const lcVector3& Start, const lcVector3& End) { const lcVector3 Dir = Point - Start; const lcVector3 RayDir = End - Start; float t = lcDot(Dir, RayDir) / lcLengthSquared(RayDir); t = lcClamp(t, 0.0f, 1.0f); return Start + t * RayDir; } inline float lcRayPointDistance(const lcVector3& Point, const lcVector3& Start, const lcVector3& End) { const lcVector3 Closest = lcRayPointClosestPoint(Point, Start, End); return lcLength(Closest - Point); } // Returns true if the axis aligned box intersects the volume defined by planes. inline bool lcBoundingBoxIntersectsVolume(const lcVector3& Min, const lcVector3& Max, const lcVector4 Planes[6]) { constexpr int NumPlanes = 6; lcVector3 Points[8] = { Points[0] = lcVector3(Min[0], Min[1], Min[2]), Points[1] = lcVector3(Min[0], Max[1], Min[2]), Points[2] = lcVector3(Max[0], Max[1], Min[2]), Points[3] = lcVector3(Max[0], Min[1], Min[2]), Points[4] = lcVector3(Min[0], Min[1], Max[2]), Points[5] = lcVector3(Min[0], Max[1], Max[2]), Points[6] = lcVector3(Max[0], Max[1], Max[2]), Points[7] = lcVector3(Max[0], Min[1], Max[2]) }; // Start by testing trivial reject/accept cases. int Outcodes[8]; int i; for (i = 0; i < 8; i++) { Outcodes[i] = 0; for (int j = 0; j < NumPlanes; j++) { if (lcDot3(Points[i], Planes[j]) + Planes[j][3] > 0) Outcodes[i] |= 1 << j; } } int OutcodesOR = 0, OutcodesAND = 0x3f; for (i = 0; i < 8; i++) { OutcodesAND &= Outcodes[i]; OutcodesOR |= Outcodes[i]; } // All corners outside the same plane. if (OutcodesAND != 0) return false; // All corners inside the volume. if (OutcodesOR == 0) return true; int Indices[36] = { 0, 1, 2, 0, 2, 3, 7, 6, 5, 7, 5, 4, 0, 1, 5, 0, 5, 4, 2, 3, 7, 2, 7, 6, 0, 3, 7, 0, 7, 4, 1, 2, 6, 1, 6, 5 }; for (int Idx = 0; Idx < 36; Idx += 3) if (lcTriangleIntersectsPlanes(Points[Indices[Idx]*3], Points[Indices[Idx+1]*3], Points[Indices[Idx+2]*3], Planes)) return true; return false; } struct lcBoundingBox { lcVector3 Min; lcVector3 Max; }; inline void lcGetBoxCorners(const lcVector3& Min, const lcVector3& Max, lcVector3 Points[8]) { Points[0] = lcVector3(Max.x, Max.y, Min.z); Points[1] = lcVector3(Min.x, Max.y, Min.z); Points[2] = lcVector3(Max.x, Max.y, Max.z); Points[3] = lcVector3(Min.x, Min.y, Min.z); Points[4] = lcVector3(Min.x, Min.y, Max.z); Points[5] = lcVector3(Max.x, Min.y, Max.z); Points[6] = lcVector3(Max.x, Min.y, Min.z); Points[7] = lcVector3(Min.x, Max.y, Max.z); } inline void lcGetBoxCorners(const lcBoundingBox& BoundingBox, lcVector3 Points[8]) { lcGetBoxCorners(BoundingBox.Min, BoundingBox.Max, Points); } /* bool SphereIntersectsVolume(const Vector3& Center, float Radius, const Vector4* Planes, int NumPlanes) { for (int j = 0; j < NumPlanes; j++) if (Dot3(Center, Planes[j]) + Planes[j][3] > Radius) return false; return true; }*/ inline lcVector3 lcRGBToHSL(const lcVector3& rgb) { int Mi; float M, m, C, h, S, L; // h is H/60 Mi = (rgb[0] >= rgb[1]) ? 0 : 1; Mi = (rgb[Mi] >= rgb[2]) ? Mi : 2; M = rgb[Mi]; m = (rgb[0] < rgb[1]) ? rgb[0] : rgb[1]; m = (m < rgb[2]) ? m : rgb[2]; C = M - m; L = (M + m) / 2.0f; if (C < LC_RGB_EPSILON) // C == 0.0 h = 0.0f; else if (Mi == 0) // M == R h = 0.0f + (rgb[1] - rgb[2]) / C; else if (Mi == 1) // M == G h = 2.0f + (rgb[2] - rgb[0]) / C; else // M = B h = 4.0f + (rgb[0] - rgb[1]) / C; h = (h < 0.0) ? h + 6.0f : h; h = (h >= 6.0) ? h - 6.0f : h; S = ((L < (LC_RGB_EPSILON / 2.0f)) || (L > (1.0f -(LC_RGB_EPSILON / 2.0f)))) ? 0.0f : (2.0f * (M - L)) / (1.0f - fabs((2.0f * L) - 1.0f)) ; return lcVector3(h, S, L); } inline lcVector3 lcHSLToRGB(const lcVector3& hSL) { lcVector3 rgb; float h, S, L, C, X, m; h = hSL[0]; S = hSL[1]; L = hSL[2]; C = (1.0f - fabs(2.0f * L - 1.0f)) * S; X = C * (1.0f - fabs(fmodf(h, 2.0f) - 1.0f)); if (h < 1.0f) rgb = lcVector3(C, X, 0.0f); else if (h < 2.0f) rgb = lcVector3(X, C, 0.0f); else if (h < 3.0f) rgb = lcVector3(0.0f, C, X); else if (h < 4.0f) rgb = lcVector3(0.0f, X, C); else if (h < 5.0f) rgb = lcVector3(X, 0.0f, C); else rgb = lcVector3(C, 0.0f, X); m = L - C / 2.0f; rgb += m; return rgb; } inline lcVector4 lcAlgorithmicEdgeColor(const lcVector3& Value, const float ValueLum, const float EdgeLum, const float Contrast, const float Saturation) { float y1, yt; lcVector3 hSL, rgb1, rgbf; // Determine luma target if (EdgeLum < ValueLum) { // Light base color yt = ValueLum - Contrast * ValueLum; } else { // Dark base color yt = ValueLum + Contrast * (1.0f - ValueLum); } // Get base color in hSL hSL = lcRGBToHSL(Value); // Adjust saturation // sat = 4.0f * sat - 2.0f; // if (sat < 0.0f) // { // sat = -sat; // hSL[0] = (hSL[0] < 3.0f) ? hSL[0] + 3.0f : hSL[0] - 3.0f; // } // sat = (sat > 2.0f) ? 2.0f : sat; // if (sat > 1.0f) // { // // Supersaturate // sat -= 1.0f; // hSL[1] += sat * (1.0f - hSL[1]); // } // else // { // Desaturate hSL[1] *= Saturation; // } // Adjusted color to RGB rgb1 = lcHSLToRGB(lcVector3(hSL[0], hSL[1], 0.5f)); // Fix adjusted color luma to target value y1 = lcLuminescence(rgb1); if (yt < y1) { // Make darker via scaling rgbf = (yt/y1) * rgb1; } else { // Make lighter via scaling anti-color rgbf = lcVector3(1.0f, 1.0f, 1.0f) - rgb1; rgbf *= (1.0f - yt) / (1.0f - y1); rgbf = lcVector3(1.0f, 1.0f, 1.0f) - rgbf; } return lcVector4(lcLinearToSRGB(rgbf), 1.0f); } leocad-23.03/common/lc_mesh.cpp000066400000000000000000000421671440571307300163740ustar00rootroot00000000000000#include "lc_global.h" #include "lc_mesh.h" #include "lc_colors.h" #include "lc_texture.h" #include "lc_file.h" #include "lc_math.h" #include "lc_application.h" #include "lc_library.h" #define LC_MESH_FILE_ID LC_FOURCC('M', 'E', 'S', 'H') #define LC_MESH_FILE_VERSION 0x0121 lcMesh* gPlaceholderMesh; lcMesh::lcMesh() { for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { mLods[LodIdx].Sections = nullptr; mLods[LodIdx].NumSections = 0; } mNumVertices = 0; mNumTexturedVertices = 0; mIndexType = 0; mVertexData = nullptr; mVertexDataSize = 0; mIndexData = nullptr; mIndexDataSize = 0; mVertexCacheOffset = -1; mIndexCacheOffset = -1; } lcMesh::~lcMesh() { free(mVertexData); free(mIndexData); for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) delete[] mLods[LodIdx].Sections; } void lcMesh::Create(quint16(&NumSections)[LC_NUM_MESH_LODS], int VertexCount, int TexturedVertexCount, int ConditionalVertexCount, int IndexCount) { for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { if (NumSections[LodIdx]) mLods[LodIdx].Sections = new lcMeshSection[NumSections[LodIdx]]; mLods[LodIdx].NumSections = NumSections[LodIdx]; } mNumVertices = VertexCount; mNumTexturedVertices = TexturedVertexCount; mConditionalVertexCount = ConditionalVertexCount; mVertexDataSize = VertexCount * sizeof(lcVertex) + TexturedVertexCount * sizeof(lcVertexTextured) + ConditionalVertexCount * sizeof(lcVertexConditional); mVertexData = malloc(mVertexDataSize); if (VertexCount < 0x10000 && TexturedVertexCount < 0x10000 && ConditionalVertexCount < 0x10000) { mIndexType = GL_UNSIGNED_SHORT; mIndexDataSize = IndexCount * sizeof(GLushort); } else { mIndexType = GL_UNSIGNED_INT; mIndexDataSize = IndexCount * sizeof(GLuint); } mIndexData = malloc(mIndexDataSize); } void lcMesh::CreateBox() { quint16 NumSections[LC_NUM_MESH_LODS]; memset(NumSections, 0, sizeof(NumSections)); NumSections[LC_MESH_LOD_HIGH] = 2; Create(NumSections, 24, 0, 0, 36 + 24); lcVector3 Min(-10.0f, -10.0f, -24.0f); lcVector3 Max(10.0f, 10.0f, 4.0f); mRadius = lcLength(Max - Min) / 2.0f; mBoundingBox.Min = Min; mBoundingBox.Max = Max; mFlags |= lcMeshFlag::HasDefault | lcMeshFlag::HasLines; lcVertex* Verts = (lcVertex*)mVertexData; quint16* Indices = (quint16*)mIndexData; Verts[0].Position = lcVector3(Min[0], Min[1], Min[2]); Verts[0].Normal = lcPackNormal(lcVector3(0.0f, 0.0f, -1.0f)); Verts[1].Position = lcVector3(Min[0], Max[1], Min[2]); Verts[1].Normal = lcPackNormal(lcVector3(0.0f, 0.0f, -1.0f)); Verts[2].Position = lcVector3(Max[0], Max[1], Min[2]); Verts[2].Normal = lcPackNormal(lcVector3(0.0f, 0.0f, -1.0f)); Verts[3].Position = lcVector3(Max[0], Min[1], Min[2]); Verts[3].Normal = lcPackNormal(lcVector3(0.0f, 0.0f, -1.0f)); Verts[4].Position = lcVector3(Min[0], Min[1], Max[2]); Verts[4].Normal = lcPackNormal(lcVector3(0.0f, 0.0f, 1.0f)); Verts[5].Position = lcVector3(Min[0], Max[1], Max[2]); Verts[5].Normal = lcPackNormal(lcVector3(0.0f, 0.0f, 1.0f)); Verts[6].Position = lcVector3(Max[0], Max[1], Max[2]); Verts[6].Normal = lcPackNormal(lcVector3(0.0f, 0.0f, 1.0f)); Verts[7].Position = lcVector3(Max[0], Min[1], Max[2]); Verts[7].Normal = lcPackNormal(lcVector3(0.0f, 0.0f, 1.0f)); Verts[8].Position = lcVector3(Min[0], Min[1], Min[2]); Verts[8].Normal = lcPackNormal(lcVector3(-1.0f, 0.0f, 0.0f)); Verts[9].Position = lcVector3(Min[0], Min[1], Max[2]); Verts[9].Normal = lcPackNormal(lcVector3(-1.0f, 0.0f, 0.0f)); Verts[10].Position = lcVector3(Min[0], Max[1], Max[2]); Verts[10].Normal = lcPackNormal(lcVector3(-1.0f, 0.0f, 0.0f)); Verts[11].Position = lcVector3(Min[0], Max[1], Min[2]); Verts[11].Normal = lcPackNormal(lcVector3(-1.0f, 0.0f, 0.0f)); Verts[12].Position = lcVector3(Max[0], Min[1], Min[2]); Verts[12].Normal = lcPackNormal(lcVector3(1.0f, 0.0f, 0.0f)); Verts[13].Position = lcVector3(Max[0], Min[1], Max[2]); Verts[13].Normal = lcPackNormal(lcVector3(1.0f, 0.0f, 0.0f)); Verts[14].Position = lcVector3(Max[0], Max[1], Max[2]); Verts[14].Normal = lcPackNormal(lcVector3(1.0f, 0.0f, 0.0f)); Verts[15].Position = lcVector3(Max[0], Max[1], Min[2]); Verts[15].Normal = lcPackNormal(lcVector3(1.0f, 0.0f, 0.0f)); Verts[16].Position = lcVector3(Min[0], Min[1], Min[2]); Verts[16].Normal = lcPackNormal(lcVector3(0.0f, -1.0f, 0.0f)); Verts[17].Position = lcVector3(Min[0], Min[1], Max[2]); Verts[17].Normal = lcPackNormal(lcVector3(0.0f, -1.0f, 0.0f)); Verts[18].Position = lcVector3(Max[0], Min[1], Max[2]); Verts[18].Normal = lcPackNormal(lcVector3(0.0f, -1.0f, 0.0f)); Verts[19].Position = lcVector3(Max[0], Min[1], Min[2]); Verts[19].Normal = lcPackNormal(lcVector3(0.0f, -1.0f, 0.0f)); Verts[20].Position = lcVector3(Min[0], Max[1], Min[2]); Verts[20].Normal = lcPackNormal(lcVector3(0.0f, 1.0f, 0.0f)); Verts[21].Position = lcVector3(Min[0], Max[1], Max[2]); Verts[21].Normal = lcPackNormal(lcVector3(0.0f, 1.0f, 0.0f)); Verts[22].Position = lcVector3(Max[0], Max[1], Max[2]); Verts[22].Normal = lcPackNormal(lcVector3(0.0f, 1.0f, 0.0f)); Verts[23].Position = lcVector3(Max[0], Max[1], Min[2]); Verts[23].Normal = lcPackNormal(lcVector3(0.0f, 1.0f, 0.0f)); lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[0]; Section->ColorIndex = gDefaultColor; Section->IndexOffset = 0; Section->NumIndices = 36; Section->PrimitiveType = LC_MESH_TRIANGLES; Section->Texture = nullptr; Section->BoundingBox = mBoundingBox; Section->Radius = mRadius; *Indices++ = 0; *Indices++ = 1; *Indices++ = 2; *Indices++ = 0; *Indices++ = 2; *Indices++ = 3; *Indices++ = 7; *Indices++ = 6; *Indices++ = 5; *Indices++ = 7; *Indices++ = 5; *Indices++ = 4; *Indices++ = 8; *Indices++ = 9; *Indices++ = 10; *Indices++ = 8; *Indices++ = 10; *Indices++ = 11; *Indices++ = 15; *Indices++ = 14; *Indices++ = 13; *Indices++ = 15; *Indices++ = 13; *Indices++ = 12; *Indices++ = 16; *Indices++ = 17; *Indices++ = 18; *Indices++ = 16; *Indices++ = 18; *Indices++ = 19; *Indices++ = 23; *Indices++ = 22; *Indices++ = 21; *Indices++ = 23; *Indices++ = 21; *Indices++ = 20; Section = &mLods[LC_MESH_LOD_HIGH].Sections[1]; Section->ColorIndex = gEdgeColor; Section->IndexOffset = 36 * 2; Section->NumIndices = 24; Section->PrimitiveType = LC_MESH_LINES; Section->Texture = nullptr; Section->BoundingBox = mBoundingBox; Section->Radius = mRadius; *Indices++ = 0; *Indices++ = 1; *Indices++ = 1; *Indices++ = 2; *Indices++ = 2; *Indices++ = 3; *Indices++ = 3; *Indices++ = 0; *Indices++ = 4; *Indices++ = 5; *Indices++ = 5; *Indices++ = 6; *Indices++ = 6; *Indices++ = 7; *Indices++ = 7; *Indices++ = 4; *Indices++ = 0; *Indices++ = 4; *Indices++ = 1; *Indices++ = 5; *Indices++ = 2; *Indices++ = 6; *Indices++ = 3; *Indices++ = 7; } template bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance, lcVector3& HitPlane) { float Distance; lcVector3 IntersectionPlane; if (!lcBoundingBoxRayIntersectDistance(mBoundingBox.Min, mBoundingBox.Max, Start, End, &Distance, nullptr, &IntersectionPlane) || (Distance >= MinDistance)) return false; const lcVertex* const Verts = (lcVertex*)mVertexData; bool Hit = false; lcVector3 Intersection; for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) { lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) continue; IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType); for (int Idx = 0; Idx < Section->NumIndices; Idx += 3) { const lcVector3& v1 = Verts[Indices[Idx]].Position; const lcVector3& v2 = Verts[Indices[Idx + 1]].Position; const lcVector3& v3 = Verts[Indices[Idx + 2]].Position; if (lcLineTriangleMinIntersection(v1, v2, v3, Start, End, &MinDistance, &Intersection)) Hit = true; } } if (Hit) HitPlane = IntersectionPlane; return Hit; } bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& HitPlane) { if (mIndexType == GL_UNSIGNED_SHORT) return MinIntersectDist(Start, End, MinDist, HitPlane); else return MinIntersectDist(Start, End, MinDist, HitPlane); } template bool lcMesh::IntersectsPlanes(const lcVector4 (&Planes)[6]) { lcVertex* Verts = (lcVertex*)mVertexData; for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) { lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) continue; IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType); for (int Idx = 0; Idx < Section->NumIndices; Idx += 3) if (lcTriangleIntersectsPlanes(Verts[Indices[Idx]].Position, Verts[Indices[Idx+1]].Position, Verts[Indices[Idx+2]].Position, Planes)) return true; } return false; } bool lcMesh::IntersectsPlanes(const lcVector4 (&Planes)[6]) { if (mIndexType == GL_UNSIGNED_SHORT) return IntersectsPlanes(Planes); else return IntersectsPlanes(Planes); } template void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char** ColorTable) { char Line[1024]; int NumSections = 0; for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) { const lcMeshSection* const Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; if (Section->PrimitiveType == LC_MESH_TRIANGLES || Section->PrimitiveType == LC_MESH_TEXTURED_TRIANGLES) NumSections++; } if (NumSections > 1) sprintf(Line, "#declare lc_%s = union {\n", MeshName); else sprintf(Line, "#declare lc_%s = mesh {\n", MeshName); File.WriteLine(Line); const lcVertex* const Verts = (lcVertex*)mVertexData; for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) { lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) continue; IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType); if (NumSections > 1) File.WriteLine(" mesh {\n"); for (int Idx = 0; Idx < Section->NumIndices; Idx += 3) { const lcVector3 v1 = Verts[Indices[Idx]].Position / 25.0f; const lcVector3 v2 = Verts[Indices[Idx + 1]].Position / 25.0f; const lcVector3 v3 = Verts[Indices[Idx + 2]].Position / 25.0f; const lcVector3 n1 = lcUnpackNormal(Verts[Indices[Idx]].Normal); const lcVector3 n2 = lcUnpackNormal(Verts[Indices[Idx + 1]].Normal); const lcVector3 n3 = lcUnpackNormal(Verts[Indices[Idx + 2]].Normal); sprintf(Line, " smooth_triangle { <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f> }\n", -v1.y, -v1.x, v1.z, -n1.y, -n1.x, n1.z, -v2.y, -v2.x, v2.z, -n2.y, -n2.x, n2.z, -v3.y, -v3.x, v3.z, -n3.y, -n3.x, n3.z); File.WriteLine(Line); } if (Section->ColorIndex != gDefaultColor) { sprintf(Line, "material { texture { %s normal { bumps 0.1 scale 2 } } }", ColorTable[Section->ColorIndex]); File.WriteLine(Line); } if (NumSections > 1) File.WriteLine(" }\n"); } File.WriteLine("}\n\n"); } void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char** ColorTable) { if (mIndexType == GL_UNSIGNED_SHORT) ExportPOVRay(File, MeshName, ColorTable); else ExportPOVRay(File, MeshName, ColorTable); } template void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset) { char Line[1024]; for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) { lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) continue; IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType); if (Section->ColorIndex == gDefaultColor) sprintf(Line, "usemtl %s\n", gColorList[DefaultColorIndex].SafeName); else sprintf(Line, "usemtl %s\n", gColorList[Section->ColorIndex].SafeName); File.WriteLine(Line); for (int Idx = 0; Idx < Section->NumIndices; Idx += 3) { const long int idx1 = Indices[Idx + 0] + VertexOffset; const long int idx2 = Indices[Idx + 1] + VertexOffset; const long int idx3 = Indices[Idx + 2] + VertexOffset; if (idx1 != idx2 && idx1 != idx3 && idx2 != idx3) sprintf(Line, "f %ld//%ld %ld//%ld %ld//%ld\n", idx1, idx1, idx2, idx2, idx3, idx3); File.WriteLine(Line); } } File.WriteLine("\n"); } void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset) { if (mIndexType == GL_UNSIGNED_SHORT) ExportWavefrontIndices(File, DefaultColorIndex, VertexOffset); else ExportWavefrontIndices(File, DefaultColorIndex, VertexOffset); } bool lcMesh::FileLoad(lcMemFile& File) { if (File.ReadU32() != LC_MESH_FILE_ID || File.ReadU32() != LC_MESH_FILE_VERSION) return false; mFlags = static_cast(File.ReadU32()); mBoundingBox.Min = File.ReadVector3(); mBoundingBox.Max = File.ReadVector3(); mRadius = File.ReadFloat(); quint32 VertexCount, TexturedVertexCount, ConditionalVertexCount, IndexCount; quint16 NumLods, NumSections[LC_NUM_MESH_LODS]; if (!File.ReadU32(&VertexCount, 1) || !File.ReadU32(&TexturedVertexCount, 1) || !File.ReadU32(&ConditionalVertexCount, 1) || !File.ReadU32(&IndexCount, 1)) return false; if (!File.ReadU16(&NumLods, 1) || NumLods != LC_NUM_MESH_LODS || !File.ReadU16(NumSections, LC_NUM_MESH_LODS)) return false; Create(NumSections, VertexCount, TexturedVertexCount, ConditionalVertexCount, IndexCount); for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { for (int SectionIdx = 0; SectionIdx < mLods[LodIdx].NumSections; SectionIdx++) { lcMeshSection& Section = mLods[LodIdx].Sections[SectionIdx]; quint32 ColorCode, IndexOffset; quint16 PrimtiveType, Length; if (!File.ReadU32(&ColorCode, 1) || !File.ReadU32(&IndexOffset, 1) || !File.ReadU32(&IndexCount, 1) || !File.ReadU16(&PrimtiveType, 1)) return false; Section.ColorIndex = lcGetColorIndex(ColorCode); Section.IndexOffset = IndexOffset; Section.NumIndices = IndexCount; Section.PrimitiveType = (lcMeshPrimitiveType)PrimtiveType; Section.BoundingBox.Min = File.ReadVector3(); Section.BoundingBox.Max = File.ReadVector3(); Section.Radius = File.ReadFloat(); if (!File.ReadU16(&Length, 1)) return false; if (Length) { if (Length >= LC_TEXTURE_NAME_LEN) return false; char FileName[LC_TEXTURE_NAME_LEN]; File.ReadBuffer(FileName, Length); FileName[Length] = 0; Section.Texture = lcGetPiecesLibrary()->FindTexture(FileName, nullptr, false); if (Section.Texture) Section.Texture->AddRef(); } else Section.Texture = nullptr; } } File.ReadBuffer(mVertexData, mNumVertices * sizeof(lcVertex) + mNumTexturedVertices * sizeof(lcVertexTextured) + mConditionalVertexCount * sizeof(lcVertexConditional)); if (mIndexType == GL_UNSIGNED_SHORT) File.ReadU16((quint16*)mIndexData, mIndexDataSize / 2); else File.ReadU32((quint32*)mIndexData, mIndexDataSize / 4); return true; } bool lcMesh::FileSave(lcMemFile& File) { File.WriteU32(LC_MESH_FILE_ID); File.WriteU32(LC_MESH_FILE_VERSION); File.WriteU32(mFlags); File.WriteVector3(mBoundingBox.Min); File.WriteVector3(mBoundingBox.Max); File.WriteFloat(mRadius); File.WriteU32(mNumVertices); File.WriteU32(mNumTexturedVertices); File.WriteU32(mConditionalVertexCount); File.WriteU32(mIndexDataSize / (mIndexType == GL_UNSIGNED_SHORT ? 2 : 4)); File.WriteU16(LC_NUM_MESH_LODS); for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) File.WriteU16(mLods[LodIdx].NumSections); for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { for (int SectionIdx = 0; SectionIdx < mLods[LodIdx].NumSections; SectionIdx++) { const lcMeshSection& Section = mLods[LodIdx].Sections[SectionIdx]; File.WriteU32(lcGetColorCode(Section.ColorIndex)); File.WriteU32(Section.IndexOffset); File.WriteU32(Section.NumIndices); File.WriteU16(Section.PrimitiveType); File.WriteVector3(Section.BoundingBox.Min); File.WriteVector3(Section.BoundingBox.Max); File.WriteFloat(Section.Radius); if (Section.Texture) { const quint16 Length = (quint16)strlen(Section.Texture->mName); File.WriteU16(Length); File.WriteBuffer(Section.Texture->mName, Length); } else File.WriteU16(0); } } File.WriteBuffer(mVertexData, mNumVertices * sizeof(lcVertex) + mNumTexturedVertices * sizeof(lcVertexTextured) + mConditionalVertexCount * sizeof(lcVertexConditional)); if (mIndexType == GL_UNSIGNED_SHORT) File.WriteU16((quint16*)mIndexData, mIndexDataSize / 2); else File.WriteU32((quint32*)mIndexData, mIndexDataSize / 4); return true; } int lcMesh::GetLodIndex(float Distance) const { if (lcGetPiecesLibrary()->GetStudStyle() != lcStudStyle::Plain) // todo: support low lod studs return LC_MESH_LOD_HIGH; if (mLods[LC_MESH_LOD_LOW].NumSections && (Distance > mRadius)) return LC_MESH_LOD_LOW; else return LC_MESH_LOD_HIGH; } leocad-23.03/common/lc_mesh.h000066400000000000000000000064501440571307300160340ustar00rootroot00000000000000#pragma once #include "lc_math.h" enum lcMeshPrimitiveType { LC_MESH_LINES = 0x01, LC_MESH_TRIANGLES = 0x02, LC_MESH_TEXTURED_TRIANGLES = 0x08, LC_MESH_CONDITIONAL_LINES = 0x10, LC_MESH_NUM_PRIMITIVE_TYPES }; struct lcVertex { lcVector3 Position; quint32 Normal; }; struct lcVertexTextured { lcVector3 Position; quint32 Normal; lcVector2 TexCoord; }; struct lcVertexConditional { lcVector3 Position1; lcVector3 Position2; lcVector3 Position3; lcVector3 Position4; }; struct lcMeshSection { int ColorIndex; int IndexOffset; int NumIndices; lcMeshPrimitiveType PrimitiveType; lcTexture* Texture; lcBoundingBox BoundingBox; float Radius; }; struct lcMeshLod { lcMeshSection* Sections; int NumSections; }; enum { LC_MESH_LOD_HIGH, LC_MESH_LOD_LOW, LC_NUM_MESH_LODS }; enum class lcMeshFlag { HasDefault = 0x01, // Mesh has triangles using the default color HasSolid = 0x02, // Mesh has triangles using a solid color HasTranslucent = 0x04, // Mesh has triangles using a translucent color HasLines = 0x08, // Mesh has lines HasTexture = 0x10, // Mesh has sections using textures HasStyleStud = 0x20 // Mesh has a stud that can have a logo applied }; Q_DECLARE_FLAGS(lcMeshFlags, lcMeshFlag) Q_DECLARE_OPERATORS_FOR_FLAGS(lcMeshFlags) class lcMesh { public: lcMesh(); ~lcMesh(); lcMesh(const lcMesh&) = delete; lcMesh(lcMesh&&) = delete; lcMesh& operator=(const lcMesh&) = delete; lcMesh& operator=(lcMesh&&) = delete; void Create(quint16 (&NumSections)[LC_NUM_MESH_LODS], int VertexCount, int TexturedVertexCount, int ConditionalVertexCount, int IndexCount); void CreateBox(); bool FileLoad(lcMemFile& File); bool FileSave(lcMemFile& File); template void ExportPOVRay(lcFile& File, const char* MeshName, const char** ColorTable); void ExportPOVRay(lcFile& File, const char* MeshName, const char** ColorTable); template void ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset); void ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset); template bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& HitPlane); bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& HitPlane); template bool IntersectsPlanes(const lcVector4 (&Planes)[6]); bool IntersectsPlanes(const lcVector4 (&Planes)[6]); int GetLodIndex(float Distance) const; const lcVertex* GetVertexData() const { return static_cast(mVertexData); } const lcVertexTextured* GetTexturedVertexData() const { return reinterpret_cast(static_cast(mVertexData) + mNumVertices * sizeof(lcVertex)); } const lcVertexConditional* GetConditionalVertexData() const { return reinterpret_cast(static_cast(mVertexData) + mNumVertices * sizeof(lcVertex) + mNumTexturedVertices * sizeof(lcVertexTextured)); } lcMeshLod mLods[LC_NUM_MESH_LODS]; lcBoundingBox mBoundingBox; float mRadius; lcMeshFlags mFlags; void* mVertexData; int mVertexDataSize; void* mIndexData; int mIndexDataSize; int mVertexCacheOffset; int mIndexCacheOffset; int mNumVertices; int mNumTexturedVertices; int mConditionalVertexCount; int mIndexType; }; leocad-23.03/common/lc_meshloader.cpp000066400000000000000000001361421440571307300175600ustar00rootroot00000000000000#include "lc_global.h" #include "lc_meshloader.h" #include "lc_file.h" #include "lc_colors.h" #include "lc_library.h" #include "lc_application.h" #include "lc_texture.h" static void lcCheckTexCoordsWrap(const lcVector4& Plane2, const lcVector3 (&Positions)[3], lcVector2 (&TexCoords)[3]) { lcVector2& TexCoords1 = TexCoords[0]; lcVector2& TexCoords2 = TexCoords[1]; lcVector2& TexCoords3 = TexCoords[2]; const float u12 = fabsf(TexCoords1.x - TexCoords2.x); const float u13 = fabsf(TexCoords1.x - TexCoords3.x); const float u23 = fabsf(TexCoords2.x - TexCoords3.x); if (u12 < 0.5f && u13 < 0.5f && u23 < 0.5f) return; const float Dot1 = fabsf(lcDot(Plane2, lcVector4(Positions[0], 1.0f))); const float Dot2 = fabsf(lcDot(Plane2, lcVector4(Positions[1], 1.0f))); const float Dot3 = fabsf(lcDot(Plane2, lcVector4(Positions[2], 1.0f))); if (Dot1 > Dot2) { if (Dot1 > Dot3) { if (u12 > 0.5f) TexCoords2.x += TexCoords2.x < 0.5f ? 1.0f : -1.0f; if (u13 > 0.5f) TexCoords3.x += TexCoords3.x < 0.5f ? 1.0f : -1.0f; } else { if (u13 > 0.5f) TexCoords1.x += TexCoords1.x < 0.5f ? 1.0f : -1.0f; if (u23 > 0.5f) TexCoords2.x += TexCoords2.x < 0.5f ? 1.0f : -1.0f; } } else { if (Dot2 > Dot3) { if (u12 > 0.5f) TexCoords1.x += TexCoords1.x < 0.5f ? 1.0f : -1.0f; if (u23 > 0.5f) TexCoords3.x += TexCoords3.x < 0.5f ? 1.0f : -1.0f; } else { if (u13 > 0.5f) TexCoords1.x += TexCoords1.x < 0.5f ? 1.0f : -1.0f; if (u23 > 0.5f) TexCoords2.x += TexCoords2.x < 0.5f ? 1.0f : -1.0f; } } } static void lcCheckTexCoordsPole(const lcVector4& FrontPlane, const lcVector4& Plane2, const lcVector3(&Positions)[3], lcVector2(&TexCoords)[3]) { int PoleIndex; int EdgeIndex1, EdgeIndex2; if (fabsf(lcDot(lcVector4(Positions[0], 1.0f), FrontPlane)) < 0.01f && fabsf(lcDot(lcVector4(Positions[0], 1.0f), Plane2)) < 0.01f) { PoleIndex = 0; EdgeIndex1 = 1; EdgeIndex2 = 2; } else if (fabsf(lcDot(lcVector4(Positions[1], 1.0f), FrontPlane)) < 0.01f && fabsf(lcDot(lcVector4(Positions[1], 1.0f), Plane2)) < 0.01f) { PoleIndex = 1; EdgeIndex1 = 0; EdgeIndex2 = 2; } else if (fabsf(lcDot(lcVector4(Positions[2], 1.0f), FrontPlane)) < 0.01f && fabsf(lcDot(lcVector4(Positions[2], 1.0f), Plane2)) < 0.01f) { PoleIndex = 2; EdgeIndex1 = 0; EdgeIndex2 = 1; } else return; const lcVector3 OppositeEdge = Positions[EdgeIndex2] - Positions[EdgeIndex1]; const lcVector3 SideEdge = Positions[PoleIndex] - Positions[EdgeIndex1]; const float OppositeLength = lcLength(OppositeEdge); const float Projection = lcDot(OppositeEdge, SideEdge) / (OppositeLength * OppositeLength); TexCoords[PoleIndex].x = TexCoords[EdgeIndex1].x + (TexCoords[EdgeIndex2].x - TexCoords[EdgeIndex1].x) * Projection; } static void lcResequenceQuad(int* Indices, int a, int b, int c, int d) { Indices[0] = a; Indices[1] = b; Indices[2] = c; Indices[3] = d; } static void lcTestQuad(int (&TriangleIndices)[2][3], const lcVector3 (&Vertices)[4]) { const lcVector3 v01 = Vertices[1] - Vertices[0]; const lcVector3 v02 = Vertices[2] - Vertices[0]; const lcVector3 v03 = Vertices[3] - Vertices[0]; const lcVector3 cp1 = lcCross(v01, v02); const lcVector3 cp2 = lcCross(v02, v03); if (lcDot(cp1, cp2) > 0.0f) return; const lcVector3 v12 = Vertices[2] - Vertices[1]; const lcVector3 v13 = Vertices[3] - Vertices[1]; const lcVector3 v23 = Vertices[3] - Vertices[2]; int QuadIndices[4] = { 0, 1, 2, 3 }; if (lcDot(lcCross(v12, v01), lcCross(v01, v13)) > 0.0f) { if (-lcDot(lcCross(v02, v12), lcCross(v12, v23)) > 0.0f) lcResequenceQuad(QuadIndices, 1, 2, 3, 0); else lcResequenceQuad(QuadIndices, 0, 3, 1, 2); } else { if (-lcDot(lcCross(v02, v12), lcCross(v12, v23)) > 0.0f) lcResequenceQuad(QuadIndices, 0, 1, 3, 2); else lcResequenceQuad(QuadIndices, 1, 2, 3, 0); } TriangleIndices[0][0] = QuadIndices[0]; TriangleIndices[0][1] = QuadIndices[1]; TriangleIndices[0][2] = QuadIndices[2]; TriangleIndices[1][0] = QuadIndices[2]; TriangleIndices[1][1] = QuadIndices[3]; TriangleIndices[1][2] = QuadIndices[0]; } constexpr float lcDistanceEpsilon = 0.01f; // Maximum value for 50591.dat static bool lcCompareVertices(const lcVector3& Position1, const lcVector3& Position2) { return fabsf(Position1.x - Position2.x) < lcDistanceEpsilon && fabsf(Position1.y - Position2.y) < lcDistanceEpsilon && fabsf(Position1.z - Position2.z) < lcDistanceEpsilon; } lcMeshLoaderSection* lcMeshLoaderTypeData::AddSection(lcMeshPrimitiveType PrimitiveType, lcMeshLoaderMaterial* Material) { for (const std::unique_ptr& Section : mSections) if (Section->mMaterial == Material && Section->mPrimitiveType == PrimitiveType) return Section.get(); mSections.emplace_back(new lcMeshLoaderSection(PrimitiveType, Material)); return mSections.back().get(); } quint32 lcMeshLoaderTypeData::AddVertex(const lcVector3& Position, bool Optimize) { if (Optimize) { for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--) { const lcMeshLoaderVertex& Vertex = mVertices[VertexIdx]; if (lcCompareVertices(Position, Vertex.Position)) return VertexIdx; } } lcMeshLoaderVertex& Vertex = mVertices.Add(); Vertex.Position = Position; Vertex.Normal = lcVector3(0.0f, 0.0f, 0.0f); Vertex.NormalWeight = 0.0f; return mVertices.GetSize() - 1; } quint32 lcMeshLoaderTypeData::AddVertex(const lcVector3& Position, const lcVector3& Normal, float NormalWeight, bool Optimize) { if (Optimize) { for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--) { lcMeshLoaderVertex& Vertex = mVertices[VertexIdx]; if (lcCompareVertices(Position, Vertex.Position)) { if (Vertex.NormalWeight == 0.0f) { Vertex.Normal = Normal; Vertex.NormalWeight = NormalWeight; return VertexIdx; } else if (lcDot(Normal, Vertex.Normal) > 0.71f) { Vertex.Normal = lcNormalize(Vertex.Normal * Vertex.NormalWeight + Normal * NormalWeight); Vertex.NormalWeight += NormalWeight; return VertexIdx; } } } } lcMeshLoaderVertex& Vertex = mVertices.Add(); Vertex.Position = Position; Vertex.Normal = Normal; Vertex.NormalWeight = 1.0f; return mVertices.GetSize() - 1; } quint32 lcMeshLoaderTypeData::AddConditionalVertex(const lcVector3(&Position)[4]) { lcMeshLoaderConditionalVertex& Vertex = mConditionalVertices.Add(); Vertex.Position[0] = Position[0]; Vertex.Position[1] = Position[1]; Vertex.Position[2] = Position[2]; Vertex.Position[3] = Position[3]; return mConditionalVertices.GetSize() - 1; } void lcMeshLoaderTypeData::ProcessLine(int LineType, lcMeshLoaderMaterial* Material, bool WindingCCW, lcVector3 (&Vertices)[4], bool Optimize) { constexpr lcMeshPrimitiveType PrimitiveTypes[4] = { LC_MESH_LINES, LC_MESH_TRIANGLES, LC_MESH_TRIANGLES, LC_MESH_CONDITIONAL_LINES }; lcMeshPrimitiveType PrimitiveType = PrimitiveTypes[LineType - 2]; if (Material->Type != lcMeshLoaderMaterialType::Solid && PrimitiveType == LC_MESH_TRIANGLES) PrimitiveType = LC_MESH_TEXTURED_TRIANGLES; lcMeshLoaderSection* Section = AddSection(PrimitiveType, Material); if (LineType == 3 || LineType == 4) { int TriangleIndices[2][3] = { { 0, 1, 2 }, { 2, 3, 0 } }; if (LineType == 4) lcTestQuad(TriangleIndices, Vertices); lcVector3 Normal = lcNormalize(lcCross(Vertices[1] - Vertices[0], Vertices[2] - Vertices[0])); if (!WindingCCW) Normal = -Normal; for (int TriangleIndex = 0; TriangleIndex < LineType - 2; TriangleIndex++) { const lcVector3& Vertex1 = Vertices[TriangleIndices[TriangleIndex][0]]; const lcVector3& Vertex2 = Vertices[TriangleIndices[TriangleIndex][1]]; const lcVector3& Vertex3 = Vertices[TriangleIndices[TriangleIndex][2]]; const lcVector3 Edge1 = lcNormalize(Vertex2 - Vertex1); const lcVector3 Edge2 = lcNormalize(Vertex3 - Vertex1); const lcVector3 Edge3 = lcNormalize(Vertex3 - Vertex2); const float Angle1 = acosf(lcDot(Edge1, Edge2)); const float Angle2 = acosf(lcDot(-Edge1, Edge3)); const float Angle3 = LC_PI - Angle1 - Angle2; int Indices[3]; Indices[0] = AddVertex(Vertex1, Normal, Angle1, Optimize); Indices[1] = AddVertex(Vertex2, Normal, Angle2, Optimize); Indices[2] = AddVertex(Vertex3, Normal, Angle3, Optimize); if (Indices[0] != Indices[1] && Indices[0] != Indices[2] && Indices[1] != Indices[2]) { if (WindingCCW) { Section->mIndices.Add(Indices[0]); Section->mIndices.Add(Indices[1]); Section->mIndices.Add(Indices[2]); } else { Section->mIndices.Add(Indices[2]); Section->mIndices.Add(Indices[1]); Section->mIndices.Add(Indices[0]); } } } } else if (LineType == 2) { int Indices[2]; Indices[0] = AddVertex(Vertices[0], Optimize); Indices[1] = AddVertex(Vertices[1], Optimize); if (Indices[0] != Indices[1]) { Section->mIndices.Add(Indices[0]); Section->mIndices.Add(Indices[1]); } } else if (LineType == 5) { int Indices[2]; Indices[0] = AddConditionalVertex(Vertices); Section->mIndices.Add(Indices[0]); std::swap(Vertices[0], Vertices[1]); Indices[1] = AddConditionalVertex(Vertices); Section->mIndices.Add(Indices[1]); } } void lcMeshLoaderTypeData::AddMeshData(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap) { const lcArray& DataVertices = Data.mVertices; lcArray IndexRemap(DataVertices.GetSize()); const lcMatrix33 NormalTransform = lcMatrix33Transpose(lcMatrix33(lcMatrix44Inverse(Transform))); mVertices.AllocGrow(DataVertices.GetSize()); for (const lcMeshLoaderVertex& DataVertex : DataVertices) { const lcVector3 Position = lcMul31(DataVertex.Position, Transform); int Index; if (DataVertex.NormalWeight == 0.0f) Index = AddVertex(Position, true); else { lcVector3 Normal = lcNormalize(lcMul(DataVertex.Normal, NormalTransform)); if (InvertNormals) Normal = -Normal; Index = AddVertex(Position, Normal, DataVertex.NormalWeight, true); } IndexRemap.Add(Index); } mConditionalVertices.AllocGrow(Data.mConditionalVertices.GetSize()); lcArray ConditionalRemap(Data.mConditionalVertices.GetSize()); for (const lcMeshLoaderConditionalVertex& DataVertex : Data.mConditionalVertices) { lcVector3 Position[4]; Position[0] = lcMul31(DataVertex.Position[0], Transform); Position[1] = lcMul31(DataVertex.Position[1], Transform); Position[2] = lcMul31(DataVertex.Position[2], Transform); Position[3] = lcMul31(DataVertex.Position[3], Transform); const int Index = AddConditionalVertex(Position); ConditionalRemap.Add(Index); } for (const std::unique_ptr& SrcSection : Data.mSections) { const quint32 ColorCode = SrcSection->mMaterial->Color == 16 ? CurrentColorCode : SrcSection->mMaterial->Color; lcMeshPrimitiveType PrimitiveType = SrcSection->mPrimitiveType; lcMeshLoaderSection* DstSection; if (SrcSection->mMaterial->Type != lcMeshLoaderMaterialType::Solid) { lcMeshLoaderTextureMap DstTextureMap = *TextureMap; for (lcVector3& Point : DstTextureMap.Points) Point = lcMul31(Point, Transform); DstSection = AddSection(PrimitiveType, mMeshData->GetTexturedMaterial(ColorCode, DstTextureMap)); } else if (TextureMap && SrcSection->mPrimitiveType == LC_MESH_TRIANGLES) { PrimitiveType = LC_MESH_TEXTURED_TRIANGLES; DstSection = AddSection(PrimitiveType, mMeshData->GetTexturedMaterial(ColorCode, *TextureMap)); } else { DstSection = AddSection(PrimitiveType, mMeshData->GetMaterial(ColorCode)); } DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize()); if (PrimitiveType == LC_MESH_CONDITIONAL_LINES) { for (const quint32 Index : SrcSection->mIndices) DstSection->mIndices.Add(ConditionalRemap[Index]); } else if (!InvertWinding || (PrimitiveType == LC_MESH_LINES)) { for (const quint32 Index : SrcSection->mIndices) DstSection->mIndices.Add(IndexRemap[Index]); } else { for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx += 3) { DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx + 2]]); DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx + 1]]); DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx + 0]]); } } } } void lcMeshLoaderTypeData::AddMeshDataNoDuplicateCheck(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap) { const lcArray& DataVertices = Data.mVertices; quint32 BaseIndex; const lcMatrix33 NormalTransform = lcMatrix33Transpose(lcMatrix33(lcMatrix44Inverse(Transform))); BaseIndex = mVertices.GetSize(); mVertices.SetGrow(lcMin(mVertices.GetSize(), 8 * 1024 * 1024)); mVertices.AllocGrow(DataVertices.GetSize()); for (int SrcVertexIdx = 0; SrcVertexIdx < DataVertices.GetSize(); SrcVertexIdx++) { const lcMeshLoaderVertex& SrcVertex = DataVertices[SrcVertexIdx]; lcMeshLoaderVertex& DstVertex = mVertices.Add(); DstVertex.Position = lcMul31(SrcVertex.Position, Transform); DstVertex.Normal = lcNormalize(lcMul(SrcVertex.Normal, NormalTransform)); if (InvertNormals) DstVertex.Normal = -DstVertex.Normal; DstVertex.NormalWeight = SrcVertex.NormalWeight; } mConditionalVertices.AllocGrow(Data.mConditionalVertices.GetSize()); const quint32 BaseConditional = mConditionalVertices.GetSize(); for (const lcMeshLoaderConditionalVertex& DataVertex : Data.mConditionalVertices) { lcMeshLoaderConditionalVertex& Vertex = mConditionalVertices.Add(); Vertex.Position[0] = lcMul31(DataVertex.Position[0], Transform); Vertex.Position[1] = lcMul31(DataVertex.Position[1], Transform); Vertex.Position[2] = lcMul31(DataVertex.Position[2], Transform); Vertex.Position[3] = lcMul31(DataVertex.Position[3], Transform); } for (const std::unique_ptr& SrcSection : Data.mSections) { const quint32 ColorCode = SrcSection->mMaterial->Color == 16 ? CurrentColorCode : SrcSection->mMaterial->Color; lcMeshPrimitiveType PrimitiveType = SrcSection->mPrimitiveType; lcMeshLoaderSection* DstSection; if (SrcSection->mMaterial->Type != lcMeshLoaderMaterialType::Solid) { lcMeshLoaderTextureMap DstTextureMap = *TextureMap; for (lcVector3& Point : DstTextureMap.Points) Point = lcMul31(Point, Transform); DstSection = AddSection(PrimitiveType, mMeshData->GetTexturedMaterial(ColorCode, DstTextureMap)); } else if (TextureMap && SrcSection->mPrimitiveType == LC_MESH_TRIANGLES) { PrimitiveType = LC_MESH_TEXTURED_TRIANGLES; DstSection = AddSection(PrimitiveType, mMeshData->GetTexturedMaterial(ColorCode, *TextureMap)); } else { DstSection = AddSection(PrimitiveType, mMeshData->GetMaterial(ColorCode)); } DstSection->mIndices.SetGrow(lcMin(DstSection->mIndices.GetSize(), 8 * 1024 * 1024)); DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize()); if (PrimitiveType == LC_MESH_CONDITIONAL_LINES) { for (const quint32 Index : SrcSection->mIndices) DstSection->mIndices.Add(BaseConditional + Index); } else if (!InvertWinding || (PrimitiveType == LC_MESH_LINES)) { for (const quint32 Index : SrcSection->mIndices) DstSection->mIndices.Add(BaseIndex + Index); } else { for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx += 3) { DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx + 2]); DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx + 1]); DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx + 0]); } } } } void lcLibraryMeshData::AddVertices(lcMeshDataType MeshDataType, int VertexCount, int* BaseVertex, lcMeshLoaderVertex** VertexBuffer) { lcArray& Vertices = mData[MeshDataType].mVertices; int CurrentSize = Vertices.GetSize(); Vertices.SetSize(CurrentSize + VertexCount); *BaseVertex = CurrentSize; *VertexBuffer = &Vertices[CurrentSize]; } void lcLibraryMeshData::AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, int IndexCount, quint32** IndexBuffer) { lcMeshLoaderSection* Section = mData[MeshDataType].AddSection(PrimitiveType, GetMaterial(ColorCode)); lcArray& Indices = Section->mIndices; const int CurrentSize = Indices.GetSize(); Indices.SetSize(CurrentSize + IndexCount); *IndexBuffer = &Indices[CurrentSize]; } void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex) { for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) { const int DestIndex = OverrideDestIndex == LC_MESHDATA_SHARED ? MeshDataIdx : OverrideDestIndex; mData[DestIndex].AddMeshData(Data.mData[MeshDataIdx], Transform, CurrentColorCode, InvertWinding, InvertNormals, TextureMap); } mHasTextures |= (Data.mHasTextures || TextureMap); } void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex) { for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) { const int DestIndex = OverrideDestIndex == LC_MESHDATA_SHARED ? MeshDataIdx : OverrideDestIndex; mData[DestIndex].AddMeshDataNoDuplicateCheck(Data.mData[MeshDataIdx], Transform, CurrentColorCode, InvertWinding, InvertNormals, TextureMap); } mHasTextures |= (Data.mHasTextures || TextureMap); } lcMeshLoaderMaterial* lcLibraryMeshData::GetMaterial(quint32 ColorCode) { for (const std::unique_ptr& Material : mMaterials) if (Material->Type == lcMeshLoaderMaterialType::Solid && Material->Color == ColorCode) return Material.get(); lcMeshLoaderMaterial* Material = new lcMeshLoaderMaterial(); mMaterials.emplace_back(Material); Material->Type = lcMeshLoaderMaterialType::Solid; Material->Color = ColorCode; return Material; } lcMeshLoaderMaterial* lcLibraryMeshData::GetTexturedMaterial(quint32 ColorCode, const lcMeshLoaderTextureMap& TextureMap) { for (const std::unique_ptr& Material : mMaterials) { if (Material->Type != TextureMap.Type || Material->Color != ColorCode) continue; if (strcmp(Material->Name, TextureMap.Name)) continue; if (Material->Points[0] != TextureMap.Points[0] || Material->Points[1] != TextureMap.Points[1] || Material->Points[2] != TextureMap.Points[2]) continue; if (Material->Type == lcMeshLoaderMaterialType::Cylindrical) { if (Material->Angles[0] != TextureMap.Angles[0]) continue; } else if (Material->Type == lcMeshLoaderMaterialType::Spherical) { if (Material->Angles[0] != TextureMap.Angles[0] || Material->Angles[1] != TextureMap.Angles[1]) continue; } return Material.get(); } lcMeshLoaderMaterial* Material = new lcMeshLoaderMaterial(); mMaterials.emplace_back(Material); Material->Type = TextureMap.Type; Material->Color = ColorCode; Material->Points[0] = TextureMap.Points[0]; Material->Points[1] = TextureMap.Points[1]; Material->Points[2] = TextureMap.Points[2]; Material->Angles[0] = TextureMap.Angles[0]; Material->Angles[1] = TextureMap.Angles[1]; strcpy(Material->Name, TextureMap.Name); return Material; } static bool lcMeshLoaderFinalSectionCompare(const lcMeshLoaderFinalSection& a, const lcMeshLoaderFinalSection& b) { if (a.PrimitiveType != b.PrimitiveType) { const lcMeshPrimitiveType PrimitiveOrder[LC_MESH_NUM_PRIMITIVE_TYPES] = { LC_MESH_TRIANGLES, LC_MESH_TEXTURED_TRIANGLES, LC_MESH_LINES, LC_MESH_CONDITIONAL_LINES }; for (int PrimitiveType = 0; PrimitiveType < LC_MESH_NUM_PRIMITIVE_TYPES; PrimitiveType++) { const lcMeshPrimitiveType Primitive = PrimitiveOrder[PrimitiveType]; if (a.PrimitiveType == Primitive) return true; if (b.PrimitiveType == Primitive) return false; } } const bool TranslucentA = lcIsColorTranslucent(a.Color); const bool TranslucentB = lcIsColorTranslucent(b.Color); if (TranslucentA != TranslucentB) return !TranslucentA; return a.Color > b.Color; } quint32 lcLibraryMeshData::AddTexturedVertex(const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoords) { for (int VertexIndex = mTexturedVertices.GetSize() - 1; VertexIndex >= 0; VertexIndex--) { const lcMeshLoaderTexturedVertex& Vertex = mTexturedVertices[VertexIndex]; if (Vertex.Position == Position && Vertex.Normal == Normal && Vertex.TexCoords == TexCoords) return VertexIndex; } lcMeshLoaderTexturedVertex& Vertex = mTexturedVertices.Add(); Vertex.Position = Position; Vertex.Normal = Normal; Vertex.TexCoords = TexCoords; return mTexturedVertices.GetSize() - 1; } void lcLibraryMeshData::GeneratePlanarTexcoords(lcMeshLoaderSection* Section, const lcMeshLoaderTypeData& Data) { const lcMeshLoaderMaterial* Material = Section->mMaterial; lcVector4 Planes[2]; for (int EdgeIdx = 0; EdgeIdx < 2; EdgeIdx++) { lcVector3 Normal = Material->Points[EdgeIdx + 1] - Material->Points[0]; const float Length = lcLength(Normal); Normal /= Length; Planes[EdgeIdx].x = Normal.x / Length; Planes[EdgeIdx].y = Normal.y / Length; Planes[EdgeIdx].z = Normal.z / Length; Planes[EdgeIdx].w = -lcDot(Normal, Material->Points[0]) / Length; } for (quint32& Index : Section->mIndices) { const lcMeshLoaderVertex& SrcVertex = Data.mVertices[Index]; const lcVector2 TexCoords(lcDot3(SrcVertex.Position, Planes[0]) + Planes[0].w, lcDot3(SrcVertex.Position, Planes[1]) + Planes[1].w); Index = AddTexturedVertex(SrcVertex.Position, SrcVertex.Normal, TexCoords); } } void lcLibraryMeshData::GenerateCylindricalTexcoords(lcMeshLoaderSection* Section, const lcMeshLoaderTypeData& Data) { const lcMeshLoaderMaterial* Material = Section->mMaterial; const lcVector3 Up = Material->Points[0] - Material->Points[1]; const float UpLength = lcLength(Up); const lcVector3 Front = lcNormalize(Material->Points[2] - Material->Points[1]); const lcVector3 Plane1Normal = Up / UpLength; const lcVector3 Plane2Normal = lcNormalize(lcCross(Front, Up)); const lcVector4 FrontPlane = lcVector4(Front, -lcDot(Front, Material->Points[1])); const lcVector4 Plane1 = lcVector4(Plane1Normal, -lcDot(Plane1Normal, Material->Points[1])); const lcVector4 Plane2 = lcVector4(Plane2Normal, -lcDot(Plane2Normal, Material->Points[1])); const float Angle = 360.0f / Material->Angles[0]; for (int TriangleIndex = 0; TriangleIndex < Section->mIndices.GetSize(); TriangleIndex += 3) { const lcVector3 Positions[3] = { Data.mVertices[Section->mIndices[TriangleIndex + 0]].Position, Data.mVertices[Section->mIndices[TriangleIndex + 1]].Position, Data.mVertices[Section->mIndices[TriangleIndex + 2]].Position }; lcVector2 TexCoords[3]; for (int CornerIndex = 0; CornerIndex < 3; CornerIndex++) { const float DotPlane1 = lcDot(lcVector4(Positions[CornerIndex], 1.0f), Plane1); const lcVector3 PointInPlane1 = Positions[CornerIndex] - lcVector3(Plane1) * DotPlane1; const float DotFrontPlane = lcDot(lcVector4(PointInPlane1, 1.0f), FrontPlane); const float DotPlane2 = lcDot(lcVector4(PointInPlane1, 1.0f), Plane2); const float Angle1 = atan2f(DotPlane2, DotFrontPlane) / LC_PI * Angle; TexCoords[CornerIndex].x = lcClamp(0.5f + 0.5f * Angle1, 0.0f, 1.0f); TexCoords[CornerIndex].y = DotPlane1 / UpLength; } lcCheckTexCoordsWrap(Plane2, Positions, TexCoords); for (int CornerIndex = 0; CornerIndex < 3; CornerIndex++) Section->mIndices[TriangleIndex + CornerIndex] = AddTexturedVertex(Positions[CornerIndex], Data.mVertices[Section->mIndices[TriangleIndex + CornerIndex]].Normal, TexCoords[CornerIndex]); } } void lcLibraryMeshData::GenerateSphericalTexcoords(lcMeshLoaderSection* Section, const lcMeshLoaderTypeData& Data) { const lcMeshLoaderMaterial* Material = Section->mMaterial; const lcVector3 Front = lcNormalize(Material->Points[1] - Material->Points[0]); const lcVector3 Plane1Normal = lcNormalize(lcCross(Front, Material->Points[2] - Material->Points[0])); const lcVector3 Plane2Normal = lcNormalize(lcCross(Plane1Normal, Front)); const lcVector4 FrontPlane = lcVector4(Front, -lcDot(Front, Material->Points[0])); const lcVector3 Center = Material->Points[0]; const lcVector4 Plane1 = lcVector4(Plane1Normal, -lcDot(Plane1Normal, Material->Points[0])); const lcVector4 Plane2 = lcVector4(Plane2Normal, -lcDot(Plane2Normal, Material->Points[0])); const float Angle1 = 360.0f / Material->Angles[0]; const float Angle2 = 180.0f / Material->Angles[1]; for (int TriangleIndex = 0; TriangleIndex < Section->mIndices.GetSize(); TriangleIndex += 3) { const lcVector3 Positions[3] = { Data.mVertices[Section->mIndices[TriangleIndex + 0]].Position, Data.mVertices[Section->mIndices[TriangleIndex + 1]].Position, Data.mVertices[Section->mIndices[TriangleIndex + 2]].Position }; lcVector2 TexCoords[3]; for (int CornerIndex = 0; CornerIndex < 3; CornerIndex++) { const lcVector3 VertexDir = Positions[CornerIndex] - Center; const float DotPlane1 = lcDot(lcVector4(Positions[CornerIndex], 1.0f), Plane1); const lcVector3 PointInPlane1 = Positions[CornerIndex] - lcVector3(Plane1) * DotPlane1; const float DotFrontPlane = lcDot(lcVector4(PointInPlane1, 1.0f), FrontPlane); const float DotPlane2 = lcDot(lcVector4(PointInPlane1, 1.0f), Plane2); const float AngleX = atan2f(DotPlane2, DotFrontPlane) / LC_PI * Angle1; TexCoords[CornerIndex].x = 0.5f + 0.5f * AngleX; const float AngleY = asinf(DotPlane1 / lcLength(VertexDir)) / LC_PI * Angle2; TexCoords[CornerIndex].y = 0.5f - AngleY; } lcCheckTexCoordsWrap(Plane2, Positions, TexCoords); lcCheckTexCoordsPole(FrontPlane, Plane2, Positions, TexCoords); for (int CornerIndex = 0; CornerIndex < 3; CornerIndex++) Section->mIndices[TriangleIndex + CornerIndex] = AddTexturedVertex(Positions[CornerIndex], Data.mVertices[Section->mIndices[TriangleIndex + CornerIndex]].Normal, TexCoords[CornerIndex]); } } void lcLibraryMeshData::GenerateTexturedVertices() { for (lcMeshLoaderTypeData& Data : mData) { for (const std::unique_ptr& Section : Data.mSections) { switch (Section->mMaterial->Type) { case lcMeshLoaderMaterialType::Solid: break; case lcMeshLoaderMaterialType::Planar: GeneratePlanarTexcoords(Section.get(), Data); break; case lcMeshLoaderMaterialType::Cylindrical: GenerateCylindricalTexcoords(Section.get(), Data); break; case lcMeshLoaderMaterialType::Spherical: GenerateSphericalTexcoords(Section.get(), Data); break; } } } } lcMesh* lcLibraryMeshData::CreateMesh() { lcMesh* Mesh = new lcMesh(); int BaseVertices[LC_NUM_MESHDATA_TYPES]; int BaseConditionalVertices[LC_NUM_MESHDATA_TYPES]; int NumVertices = 0; int ConditionalVertexCount = 0; for (const std::unique_ptr& Material : mMaterials) Material->Color = lcGetColorIndex(Material->Color); for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) { BaseVertices[MeshDataIdx] = NumVertices; NumVertices += mData[MeshDataIdx].mVertices.GetSize(); BaseConditionalVertices[MeshDataIdx] = ConditionalVertexCount; ConditionalVertexCount += mData[MeshDataIdx].mConditionalVertices.GetSize(); } if (mHasTextures) GenerateTexturedVertices(); quint16 NumSections[LC_NUM_MESH_LODS]; int NumIndices = 0; lcArray FinalSections[LC_NUM_MESH_LODS]; for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { auto AddFinalSection = [](lcMeshLoaderSection* Section, lcArray& FinalSections) { for (const lcMeshLoaderFinalSection& FinalSection : FinalSections) if (FinalSection.PrimitiveType == Section->mPrimitiveType && FinalSection.Color == Section->mMaterial->Color && !strcmp(FinalSection.Name, Section->mMaterial->Name)) return; lcMeshLoaderFinalSection& FinalSection = FinalSections.Add(); FinalSection.PrimitiveType = Section->mPrimitiveType; FinalSection.Color = Section->mMaterial->Color; strcpy(FinalSection.Name, Section->mMaterial->Name); }; for (const std::unique_ptr& Section : mData[LC_MESHDATA_SHARED].mSections) { NumIndices += Section->mIndices.GetSize(); AddFinalSection(Section.get(), FinalSections[LodIdx]); } for (const std::unique_ptr& Section : mData[LodIdx].mSections) { NumIndices += Section->mIndices.GetSize(); AddFinalSection(Section.get(), FinalSections[LodIdx]); } NumSections[LodIdx] = FinalSections[LodIdx].GetSize(); std::sort(FinalSections[LodIdx].begin(), FinalSections[LodIdx].end(), lcMeshLoaderFinalSectionCompare); } Mesh->Create(NumSections, NumVertices, mTexturedVertices.GetSize(), ConditionalVertexCount, NumIndices); lcVertex* DstVerts = (lcVertex*)Mesh->mVertexData; for (const lcMeshLoaderTypeData& Data : mData) { for (const lcMeshLoaderVertex& SrcVertex : Data.mVertices) { lcVertex& DstVertex = *DstVerts++; DstVertex.Position = lcVector3LDrawToLeoCAD(SrcVertex.Position); DstVertex.Normal = lcPackNormal(lcVector3LDrawToLeoCAD(SrcVertex.Normal)); } } lcVertexTextured* DstTexturedVerts = (lcVertexTextured*)DstVerts; if (mHasTextures) { for (const lcMeshLoaderTexturedVertex& SrcVertex : mTexturedVertices) { lcVertexTextured& DstVertex = *DstTexturedVerts++; DstVertex.Position = lcVector3LDrawToLeoCAD(SrcVertex.Position); DstVertex.Normal = lcPackNormal(lcVector3LDrawToLeoCAD(SrcVertex.Normal)); DstVertex.TexCoord = SrcVertex.TexCoords; } } lcVertexConditional* DstConditionalVerts = (lcVertexConditional*)DstTexturedVerts; for (const lcMeshLoaderTypeData& Data : mData) { for (const lcMeshLoaderConditionalVertex& SrcVertex : Data.mConditionalVertices) { lcVertexConditional& DstVertex = *DstConditionalVerts++; DstVertex.Position1 = lcVector3LDrawToLeoCAD(SrcVertex.Position[0]); DstVertex.Position2 = lcVector3LDrawToLeoCAD(SrcVertex.Position[1]); DstVertex.Position3 = lcVector3LDrawToLeoCAD(SrcVertex.Position[2]); DstVertex.Position4 = lcVector3LDrawToLeoCAD(SrcVertex.Position[3]); } } if (Mesh->mIndexType == GL_UNSIGNED_SHORT) WriteSections(Mesh, FinalSections, BaseVertices, BaseConditionalVertices); else WriteSections(Mesh, FinalSections, BaseVertices, BaseConditionalVertices); if (mHasStyleStud) Mesh->mFlags |= lcMeshFlag::HasStyleStud; UpdateMeshBoundingBox(Mesh); return Mesh; } template void lcLibraryMeshData::WriteSections(lcMesh* Mesh, const lcArray (&FinalSections)[LC_NUM_MESH_LODS], int(&BaseVertices)[LC_NUM_MESHDATA_TYPES], int(&BaseConditionalVertices)[LC_NUM_MESHDATA_TYPES]) { int NumIndices = 0; for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { for (int SectionIdx = 0; SectionIdx < FinalSections[LodIdx].GetSize(); SectionIdx++) { const lcMeshLoaderFinalSection& FinalSection = FinalSections[LodIdx][SectionIdx]; lcMeshSection& DstSection = Mesh->mLods[LodIdx].Sections[SectionIdx]; DstSection.ColorIndex = FinalSection.Color; DstSection.PrimitiveType = FinalSection.PrimitiveType; DstSection.NumIndices = 0; if (!FinalSection.Name[0]) DstSection.Texture = nullptr; else { if (mMeshLoader) DstSection.Texture = lcGetPiecesLibrary()->FindTexture(FinalSection.Name, mMeshLoader->mCurrentProject, mMeshLoader->mSearchProjectFolder); else DstSection.Texture = lcGetPiecesLibrary()->FindTexture(FinalSection.Name, nullptr, false); if (DstSection.Texture) DstSection.Texture->AddRef(); } DstSection.IndexOffset = NumIndices * sizeof(IndexType); IndexType* Index = (IndexType*)Mesh->mIndexData + NumIndices; const auto AddSection = [&DstSection, &Index, &BaseVertices, &BaseConditionalVertices](lcMeshLoaderSection* SrcSection, lcMeshDataType SrcDataType) { switch (DstSection.PrimitiveType) { case LC_MESH_LINES: case LC_MESH_TRIANGLES: { const IndexType BaseVertex = BaseVertices[SrcDataType]; for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) *Index++ = BaseVertex + SrcSection->mIndices[IndexIdx]; } break; case LC_MESH_CONDITIONAL_LINES: { const IndexType BaseVertex = BaseConditionalVertices[SrcDataType]; for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) *Index++ = BaseVertex + SrcSection->mIndices[IndexIdx]; } break; case LC_MESH_TEXTURED_TRIANGLES: { for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) *Index++ = SrcSection->mIndices[IndexIdx]; } break; case LC_MESH_NUM_PRIMITIVE_TYPES: break; } DstSection.NumIndices += SrcSection->mIndices.GetSize(); }; for (const std::unique_ptr& Section : mData[LC_MESHDATA_SHARED].mSections) if (FinalSection.PrimitiveType == Section->mPrimitiveType && FinalSection.Color == Section->mMaterial->Color && !strcmp(FinalSection.Name, Section->mMaterial->Name)) AddSection(Section.get(), LC_MESHDATA_SHARED); const lcMeshDataType MeshDataType = (LodIdx == LC_MESH_LOD_LOW) ? LC_MESHDATA_LOW : LC_MESHDATA_HIGH; for (const std::unique_ptr& Section : mData[MeshDataType].mSections) if (FinalSection.PrimitiveType == Section->mPrimitiveType && FinalSection.Color == Section->mMaterial->Color && !strcmp(FinalSection.Name, Section->mMaterial->Name)) AddSection(Section.get(), MeshDataType); if (DstSection.PrimitiveType == LC_MESH_TRIANGLES || DstSection.PrimitiveType == LC_MESH_TEXTURED_TRIANGLES) { if (DstSection.ColorIndex == gDefaultColor) Mesh->mFlags |= lcMeshFlag::HasDefault; else { if (lcIsColorTranslucent(DstSection.ColorIndex)) Mesh->mFlags |= lcMeshFlag::HasTranslucent; else Mesh->mFlags |= lcMeshFlag::HasSolid; } } else Mesh->mFlags |= lcMeshFlag::HasLines; if (DstSection.PrimitiveType == LC_MESH_TEXTURED_TRIANGLES) Mesh->mFlags |= lcMeshFlag::HasTexture; NumIndices += DstSection.NumIndices; } } } void lcLibraryMeshData::UpdateMeshBoundingBox(lcMesh* Mesh) { lcVector3 MeshMin(FLT_MAX, FLT_MAX, FLT_MAX), MeshMax(-FLT_MAX, -FLT_MAX, -FLT_MAX); bool UpdatedBoundingBox = false; for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { lcMeshLod& Lod = Mesh->mLods[LodIdx]; for (int SectionIdx = 0; SectionIdx < Lod.NumSections; SectionIdx++) { lcMeshSection& Section = Lod.Sections[SectionIdx]; lcVector3 SectionMin(FLT_MAX, FLT_MAX, FLT_MAX), SectionMax(-FLT_MAX, -FLT_MAX, -FLT_MAX); if (Mesh->mIndexType == GL_UNSIGNED_SHORT) UpdateMeshSectionBoundingBox(Mesh, Section, SectionMin, SectionMax); else UpdateMeshSectionBoundingBox(Mesh, Section, SectionMin, SectionMax); Section.BoundingBox.Max = SectionMax; Section.BoundingBox.Min = SectionMin; Section.Radius = lcLength((SectionMax - SectionMin) / 2.0f); if (Section.PrimitiveType == LC_MESH_TRIANGLES || Section.PrimitiveType == LC_MESH_TEXTURED_TRIANGLES) { UpdatedBoundingBox = true; MeshMin = lcMin(SectionMin, MeshMin); MeshMax = lcMax(SectionMax, MeshMax); } } } if (!UpdatedBoundingBox) MeshMin = MeshMax = lcVector3(0.0f, 0.0f, 0.0f); Mesh->mBoundingBox.Max = MeshMax; Mesh->mBoundingBox.Min = MeshMin; Mesh->mRadius = lcLength((MeshMax - MeshMin) / 2.0f); } template void lcLibraryMeshData::UpdateMeshSectionBoundingBox(const lcMesh* Mesh, const lcMeshSection& Section, lcVector3& SectionMin, lcVector3& SectionMax) { const IndexType* IndexBuffer = reinterpret_cast(static_cast(Mesh->mIndexData) + Section.IndexOffset); switch (Section.PrimitiveType) { case LC_MESH_LINES: case LC_MESH_TRIANGLES: { const lcVertex* VertexBuffer = Mesh->GetVertexData(); for (int Index = 0; Index < Section.NumIndices; Index++) { const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position; SectionMin = lcMin(SectionMin, Position); SectionMax = lcMax(SectionMax, Position); } } break; case LC_MESH_CONDITIONAL_LINES: { const lcVertexConditional* VertexBuffer = Mesh->GetConditionalVertexData(); for (int Index = 0; Index < Section.NumIndices; Index++) { const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position1; SectionMin = lcMin(SectionMin, Position); SectionMax = lcMax(SectionMax, Position); } } break; case LC_MESH_TEXTURED_TRIANGLES: { const lcVertexTextured* VertexBuffer = Mesh->GetTexturedVertexData(); for (int Index = 0; Index < Section.NumIndices; Index++) { const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position; SectionMin = lcMin(SectionMin, Position); SectionMax = lcMax(SectionMax, Position); } } break; case LC_MESH_NUM_PRIMITIVE_TYPES: break; } } lcMeshLoader::lcMeshLoader(lcLibraryMeshData& MeshData, bool Optimize, Project* CurrentProject, bool SearchProjectFolder) : mCurrentProject(CurrentProject), mSearchProjectFolder(SearchProjectFolder), mMeshData(MeshData), mOptimize(Optimize) { MeshData.SetMeshLoader(this); } bool lcMeshLoader::LoadMesh(lcFile& File, lcMeshDataType MeshDataType) { return ReadMeshData(File, lcMatrix44Identity(), 16, false, MeshDataType); } bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, quint32 CurrentColorCode, bool InvertWinding, lcMeshDataType MeshDataType) { char Buffer[1024]; char* Line; bool InvertNext = false; bool WindingCCW = !InvertWinding; lcPiecesLibrary* Library = lcGetPiecesLibrary(); while (File.ReadLine(Buffer, sizeof(Buffer))) { if (Library->ShouldCancelLoading()) return false; quint32 ColorCode, ColorCodeHex; bool LastToken = false; int LineType; Line = Buffer; if (sscanf(Line, "%d", &LineType) != 1) continue; if (LineType == 0) { char* Token = Line; while (*Token && *Token <= 32) Token++; Token++; while (*Token && *Token <= 32) Token++; char* End = Token; while (*End && *End > 32) End++; LastToken = (*End == 0); *End = 0; if (!strcmp(Token, "!TEXMAP")) { Token += 8; while (*Token && *Token <= 32) Token++; End = Token; while (*End && *End > 32) End++; *End = 0; bool Start = false; bool Next = false; if (!strcmp(Token, "START")) { Token += 6; Start = true; } else if (!strcmp(Token, "NEXT")) { Token += 5; Next = true; } if (Start || Next) { while (*Token && *Token <= 32) Token++; End = Token; while (*End && *End > 32) End++; *End = 0; auto CleanTextureName = [](char* FileName) { char* Ch; for (Ch = FileName; *Ch; Ch++) { if (*Ch >= 'a' && *Ch <= 'z') *Ch = *Ch + 'A' - 'a'; else if (*Ch == '\\') *Ch = '/'; } if (Ch - FileName > 4) { Ch -= 4; if (!memcmp(Ch, ".PNG", 4)) *Ch = 0; } }; if (!strcmp(Token, "PLANAR")) { Token += 7; mTextureStack.emplace_back(); lcMeshLoaderTextureMap& Map = mTextureStack.back(); Map.Type = lcMeshLoaderMaterialType::Planar; lcVector3 (&Points)[3] = Map.Points; sscanf(Token, "%f %f %f %f %f %f %f %f %f %s", &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, Map.Name); Points[0] = lcMul31(Points[0], CurrentTransform); Points[1] = lcMul31(Points[1], CurrentTransform); Points[2] = lcMul31(Points[2], CurrentTransform); CleanTextureName(Map.Name); } else if (!strcmp(Token, "CYLINDRICAL")) { Token += 12; mTextureStack.emplace_back(); lcMeshLoaderTextureMap& Map = mTextureStack.back(); Map.Type = lcMeshLoaderMaterialType::Cylindrical; lcVector3 (&Points)[3] = Map.Points; float& Angle = Map.Angles[0]; sscanf(Token, "%f %f %f %f %f %f %f %f %f %f %s", &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, &Angle, Map.Name); Points[0] = lcMul31(Points[0], CurrentTransform); Points[1] = lcMul31(Points[1], CurrentTransform); Points[2] = lcMul31(Points[2], CurrentTransform); CleanTextureName(Map.Name); } else if (!strcmp(Token, "SPHERICAL")) { Token += 10; mTextureStack.emplace_back(); lcMeshLoaderTextureMap& Map = mTextureStack.back(); Map.Type = lcMeshLoaderMaterialType::Spherical; lcVector3(&Points)[3] = Map.Points; float& Angle1 = Map.Angles[0]; float& Angle2 = Map.Angles[1]; sscanf(Token, "%f %f %f %f %f %f %f %f %f %f %f %s", &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, &Angle1, &Angle2, Map.Name); Points[0] = lcMul31(Points[0], CurrentTransform); Points[1] = lcMul31(Points[1], CurrentTransform); Points[2] = lcMul31(Points[2], CurrentTransform); CleanTextureName(Map.Name); } } else if (!strcmp(Token, "FALLBACK")) { if (!mTextureStack.empty()) mTextureStack.back().Fallback = true; } else if (!strcmp(Token, "END")) { if (!mTextureStack.empty()) mTextureStack.pop_back(); } continue; } else if (!strcmp(Token, "BFC")) { while (!LastToken) { Token = End + 1; while (*Token && *Token <= 32) Token++; End = Token; while (*End && *End > 32) End++; LastToken = (*End == 0); *End = 0; if (!strcmp(Token, "INVERTNEXT")) InvertNext = true; else if (!strcmp(Token, "CCW")) WindingCCW = !InvertWinding; else if (!strcmp(Token, "CW")) WindingCCW = InvertWinding; } } else if (!strcmp(Token, "!:")) { Token += 3; Line = Token; if (mTextureStack.empty()) continue; } else continue; } if (sscanf(Line, "%d %d", &LineType, &ColorCode) != 2) continue; if (LineType < 1 || LineType > 5) continue; if (ColorCode == 0) { sscanf(Line, "%d %i", &LineType, &ColorCodeHex); if (ColorCode != ColorCodeHex) ColorCode = ColorCodeHex | LC_COLOR_DIRECT; } if (ColorCode == 16) ColorCode = CurrentColorCode; lcMeshLoaderTextureMap* TextureMap = nullptr; if (!mTextureStack.empty()) { TextureMap = &mTextureStack.back(); // TODO: think about a way to handle the texture fallback // if (TextureMap->Texture) { if (TextureMap->Fallback) continue; } // else // { // if (!TextureMap->Fallback) // continue; // // TextureMap = nullptr; // } } int Dummy; lcVector3 Points[4]; switch (LineType) { case 1: { char OriginalFileName[LC_MAXPATH]; float fm[12]; sscanf(Line, "%d %i %f %f %f %f %f %f %f %f %f %f %f %f %s", &LineType, &Dummy, &fm[0], &fm[1], &fm[2], &fm[3], &fm[4], &fm[5], &fm[6], &fm[7], &fm[8], &fm[9], &fm[10], &fm[11], OriginalFileName); char FileName[LC_MAXPATH]; strcpy(FileName, OriginalFileName); char* Ch; for (Ch = FileName; *Ch; Ch++) { if (*Ch >= 'a' && *Ch <= 'z') *Ch = *Ch + 'A' - 'a'; else if (*Ch == '\\') *Ch = '/'; } lcLibraryPrimitive* Primitive = !TextureMap ? Library->FindPrimitive(FileName) : nullptr; lcMatrix44 IncludeTransform(lcVector4(fm[3], fm[6], fm[9], 0.0f), lcVector4(fm[4], fm[7], fm[10], 0.0f), lcVector4(fm[5], fm[8], fm[11], 0.0f), lcVector4(fm[0], fm[1], fm[2], 1.0f)); IncludeTransform = lcMul(IncludeTransform, CurrentTransform); bool Mirror = IncludeTransform.Determinant() < 0.0f; const auto FileCallback = [this, &IncludeTransform, &ColorCode, &Mirror, &InvertNext, &MeshDataType](lcFile& File) { ReadMeshData(File, IncludeTransform, ColorCode, Mirror ^ InvertNext, MeshDataType); }; if (Primitive) { if (Primitive->mState != lcPrimitiveState::Loaded && !Library->LoadPrimitive(Primitive)) break; if (Primitive->mStud) mMeshData.AddMeshDataNoDuplicateCheck(Primitive->mMeshData, IncludeTransform, ColorCode, Mirror ^ InvertNext, InvertNext, TextureMap, MeshDataType); else if (!Primitive->mSubFile) { if (mOptimize) mMeshData.AddMeshData(Primitive->mMeshData, IncludeTransform, ColorCode, Mirror ^ InvertNext, InvertNext, TextureMap, MeshDataType); else mMeshData.AddMeshDataNoDuplicateCheck(Primitive->mMeshData, IncludeTransform, ColorCode, Mirror ^ InvertNext, InvertNext, TextureMap, MeshDataType); } else Library->GetPrimitiveFile(Primitive, FileCallback); mMeshData.mHasStyleStud |= Primitive->mStudStyle | Primitive->mMeshData.mHasStyleStud; } else Library->GetPieceFile(FileName, FileCallback); } break; case 2: sscanf(Line, "%d %i %f %f %f %f %f %f", &LineType, &Dummy, &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z); Points[0] = lcMul31(Points[0], CurrentTransform); Points[1] = lcMul31(Points[1], CurrentTransform); mMeshData.mData[MeshDataType].ProcessLine(LineType, mMeshData.GetMaterial(ColorCode), WindingCCW, Points, mOptimize); break; case 3: sscanf(Line, "%d %i %f %f %f %f %f %f %f %f %f", &LineType, &Dummy, &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z); Points[0] = lcMul31(Points[0], CurrentTransform); Points[1] = lcMul31(Points[1], CurrentTransform); Points[2] = lcMul31(Points[2], CurrentTransform); if (!TextureMap) mMeshData.mData[MeshDataType].ProcessLine(LineType, mMeshData.GetMaterial(ColorCode), WindingCCW, Points, mOptimize); else { mMeshData.mHasTextures = true; mMeshData.mData[MeshDataType].ProcessLine(LineType, mMeshData.GetTexturedMaterial(ColorCode, *TextureMap), WindingCCW, Points, mOptimize); if (TextureMap->Next) mTextureStack.pop_back(); } break; case 4: sscanf(Line, "%d %i %f %f %f %f %f %f %f %f %f %f %f %f", &LineType, &Dummy, &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, &Points[3].x, &Points[3].y, &Points[3].z); Points[0] = lcMul31(Points[0], CurrentTransform); Points[1] = lcMul31(Points[1], CurrentTransform); Points[2] = lcMul31(Points[2], CurrentTransform); Points[3] = lcMul31(Points[3], CurrentTransform); if (!TextureMap) mMeshData.mData[MeshDataType].ProcessLine(LineType, mMeshData.GetMaterial(ColorCode), WindingCCW, Points, mOptimize); else { mMeshData.mHasTextures = true; mMeshData.mData[MeshDataType].ProcessLine(LineType, mMeshData.GetTexturedMaterial(ColorCode, *TextureMap), WindingCCW, Points, mOptimize); if (TextureMap->Next) mTextureStack.pop_back(); } break; case 5: sscanf(Line, "%d %i %f %f %f %f %f %f %f %f %f %f %f %f", &LineType, &Dummy, &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, &Points[3].x, &Points[3].y, &Points[3].z); Points[0] = lcMul31(Points[0], CurrentTransform); Points[1] = lcMul31(Points[1], CurrentTransform); Points[2] = lcMul31(Points[2], CurrentTransform); Points[3] = lcMul31(Points[3], CurrentTransform); mMeshData.mData[MeshDataType].ProcessLine(LineType, mMeshData.GetMaterial(ColorCode), WindingCCW, Points, mOptimize); break; } InvertNext = false; } return true; } leocad-23.03/common/lc_meshloader.h000066400000000000000000000142321440571307300172200ustar00rootroot00000000000000#pragma once #include "lc_array.h" #include "lc_math.h" #include "lc_mesh.h" class lcLibraryMeshData; class lcMeshLoader; enum lcMeshDataType { LC_MESHDATA_HIGH, LC_MESHDATA_LOW, LC_MESHDATA_SHARED, LC_NUM_MESHDATA_TYPES }; struct lcMeshLoaderVertex { lcVector3 Position; lcVector3 Normal; float NormalWeight; }; struct lcMeshLoaderTexturedVertex { lcVector3 Position; lcVector3 Normal; lcVector2 TexCoords; }; struct lcMeshLoaderConditionalVertex { lcVector3 Position[4]; }; enum class lcMeshLoaderMaterialType { Solid, Planar, Cylindrical, Spherical }; struct lcMeshLoaderMaterial { lcMeshLoaderMaterialType Type = lcMeshLoaderMaterialType::Solid; quint32 Color = 16; lcVector3 Points[3] = {}; float Angles[2] = {}; char Name[256] = {}; }; class lcMeshLoaderSection { public: lcMeshLoaderSection(lcMeshPrimitiveType PrimitiveType, lcMeshLoaderMaterial* Material) : mMaterial(Material), mPrimitiveType(PrimitiveType), mIndices(1024, 1024) { } lcMeshLoaderMaterial* mMaterial; lcMeshPrimitiveType mPrimitiveType; lcArray mIndices; }; struct lcMeshLoaderFinalSection { quint32 Color; lcMeshPrimitiveType PrimitiveType; char Name[256]; }; struct lcMeshLoaderTextureMap { union lcTextureMapParams { lcTextureMapParams() { } struct lcTextureMapSphericalParams { } Spherical; } Params; lcMeshLoaderMaterialType Type; lcVector3 Points[3]; float Angles[2]; char Name[LC_MAXPATH]; bool Fallback = false; bool Next = false; }; class lcMeshLoaderTypeData { public: lcMeshLoaderTypeData() { mVertices.SetGrow(1024); mConditionalVertices.SetGrow(1024); } lcMeshLoaderTypeData(const lcMeshLoaderTypeData&) = delete; lcMeshLoaderTypeData& operator=(const lcMeshLoaderTypeData&) = delete; bool IsEmpty() const { return mSections.empty(); } void Clear() { mSections.clear(); mVertices.RemoveAll(); mConditionalVertices.RemoveAll(); } void SetMeshData(lcLibraryMeshData* MeshData) { mMeshData = MeshData; } lcMeshLoaderSection* AddSection(lcMeshPrimitiveType PrimitiveType, lcMeshLoaderMaterial* Material); quint32 AddVertex(const lcVector3& Position, bool Optimize); quint32 AddVertex(const lcVector3& Position, const lcVector3& Normal, float NormalWeight, bool Optimize); quint32 AddConditionalVertex(const lcVector3 (&Position)[4]); void ProcessLine(int LineType, lcMeshLoaderMaterial* Material, bool WindingCCW, lcVector3 (&Vertices)[4], bool Optimize); void AddMeshData(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap); void AddMeshDataNoDuplicateCheck(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap); std::vector> mSections; lcArray mVertices; lcArray mConditionalVertices; protected: lcLibraryMeshData* mMeshData = nullptr; }; class lcLibraryMeshData { public: lcLibraryMeshData() { mHasTextures = false; mHasStyleStud = false; for (lcMeshLoaderTypeData& Data : mData) Data.SetMeshData(this); } lcLibraryMeshData(const lcLibraryMeshData&) = delete; lcLibraryMeshData& operator=(const lcLibraryMeshData&) = delete; bool IsEmpty() const { for (const lcMeshLoaderTypeData& Data : mData) if (!Data.IsEmpty()) return false; return true; } void Clear() { for (lcMeshLoaderTypeData& Data : mData) Data.Clear(); mHasTextures = false; mHasStyleStud = false; } void SetMeshLoader(lcMeshLoader* MeshLoader) { mMeshLoader = MeshLoader; } lcMesh* CreateMesh(); void AddVertices(lcMeshDataType MeshDataType, int VertexCount, int* BaseVertex, lcMeshLoaderVertex** VertexBuffer); void AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, int IndexCount, quint32** IndexBuffer); void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex); void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex); lcMeshLoaderMaterial* GetMaterial(quint32 ColorCode); lcMeshLoaderMaterial* GetTexturedMaterial(quint32 ColorCode, const lcMeshLoaderTextureMap& TextureMap); std::array mData; bool mHasTextures; bool mHasStyleStud; protected: lcMeshLoader* mMeshLoader = nullptr; std::vector> mMaterials; lcArray mTexturedVertices; void GenerateTexturedVertices(); void GeneratePlanarTexcoords(lcMeshLoaderSection* Section, const lcMeshLoaderTypeData& Data); void GenerateCylindricalTexcoords(lcMeshLoaderSection* Section, const lcMeshLoaderTypeData& Data); void GenerateSphericalTexcoords(lcMeshLoaderSection* Section, const lcMeshLoaderTypeData& Data); quint32 AddTexturedVertex(const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoords); template void WriteSections(lcMesh* Mesh, const lcArray (&FinalSections)[LC_NUM_MESH_LODS], int (&BaseVertices)[LC_NUM_MESHDATA_TYPES], int (&BaseConditionalVertices)[LC_NUM_MESHDATA_TYPES]); static void UpdateMeshBoundingBox(lcMesh* Mesh); template static void UpdateMeshSectionBoundingBox(const lcMesh* Mesh, const lcMeshSection& Section, lcVector3& SectionMin, lcVector3& SectionMax); }; class lcMeshLoader { public: lcMeshLoader(lcLibraryMeshData& MeshData, bool Optimize, Project* CurrentProject, bool SearchProjectFolder); bool LoadMesh(lcFile& File, lcMeshDataType MeshDataType); Project* mCurrentProject; bool mSearchProjectFolder; protected: bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, quint32 CurrentColorCode, bool InvertWinding, lcMeshDataType MeshDataType); std::vector mTextureStack; lcLibraryMeshData& mMeshData; bool mOptimize; }; leocad-23.03/common/lc_minifigdialog.cpp000066400000000000000000000204571440571307300202400ustar00rootroot00000000000000#include "lc_global.h" #include "lc_minifigdialog.h" #include "ui_lc_minifigdialog.h" #include "lc_viewwidget.h" #include "lc_qcolorpicker.h" #include "minifig.h" #include "lc_application.h" #include "pieceinf.h" #include "lc_library.h" #include "lc_view.h" #include "camera.h" lcMinifigDialog::lcMinifigDialog(QWidget* Parent) : QDialog(Parent), ui(new Ui::lcMinifigDialog) { ui->setupUi(this); mComboBoxes = { ui->hatsType, ui->hats2Type, ui->headType, ui->neckType, ui->bodyType, ui->body2Type, ui->body3Type, ui->rarmType, ui->larmType, ui->rhandType, ui->lhandType, ui->rhandaType, ui->lhandaType, ui->rlegType, ui->llegType, ui->rlegaType, ui->llegaType }; mColorPickers = { ui->hatsColor, ui->hats2Color, ui->headColor, ui->neckColor, ui->bodyColor, ui->body2Color, ui->body3Color, ui->rarmColor, ui->larmColor, ui->rhandColor, ui->lhandColor, ui->rhandaColor, ui->lhandaColor, ui->rlegColor, ui->llegColor, ui->rlegaColor, ui->llegaColor }; mSpinBoxes = { ui->hatsAngle, ui->hats2Angle, ui->headAngle, nullptr, nullptr, nullptr, nullptr, ui->rarmAngle, ui->larmAngle, ui->rhandAngle, ui->lhandAngle, ui->rhandaAngle, ui->lhandaAngle, ui->rlegAngle, ui->llegAngle, ui->rlegaAngle, ui->llegaAngle }; for (QComboBox* ComboBox : mComboBoxes) connect(ComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(TypeChanged(int))); for (lcQColorPicker* ColorPicker : mColorPickers) connect(ColorPicker, SIGNAL(colorChanged(int)), this, SLOT(ColorChanged(int))); for (QDoubleSpinBox* SpinBox : mSpinBoxes) if (SpinBox) connect(SpinBox, SIGNAL(valueChanged(double)), this, SLOT(AngleChanged(double))); QGridLayout* PreviewLayout = new QGridLayout(ui->minifigFrame); PreviewLayout->setContentsMargins(0, 0, 0, 0); mMinifigWizard = new MinifigWizard(); mView = new lcView(lcViewType::Minifig, mMinifigWizard->GetModel()); lcViewWidget* ViewWidget = new lcViewWidget(nullptr, mView); ViewWidget->setMinimumWidth(100); PreviewLayout->addWidget(ViewWidget); mView->MakeCurrent(); mMinifigWizard->LoadDefault(); for (int ItemIndex = 0; ItemIndex < LC_MFW_NUMITEMS; ItemIndex++) { const std::vector& PartList = mMinifigWizard->mSettings[ItemIndex]; QStringList ItemStrings; QVector Separators; for (const lcMinifigPieceInfo& MinifigPieceInfo : PartList) { const char* Description = MinifigPieceInfo.Description; if (Description[0] != '-' || Description[1] != '-') ItemStrings.append(Description); else Separators.append(ItemStrings.size()); } QComboBox* ItemCombo = mComboBoxes[ItemIndex]; ItemCombo->blockSignals(true); ItemCombo->addItems(ItemStrings); for (int SeparatorIndex = Separators.size() - 1; SeparatorIndex >= 0; SeparatorIndex--) ItemCombo->insertSeparator(Separators[SeparatorIndex]); ItemCombo->setCurrentIndex(mMinifigWizard->GetSelectionIndex(ItemIndex)); ItemCombo->blockSignals(false); lcQColorPicker* ColorPicker = mColorPickers[ItemIndex]; ColorPicker->blockSignals(true); ColorPicker->setCurrentColor(mMinifigWizard->mMinifig.Colors[ItemIndex]); ColorPicker->blockSignals(false); } UpdateTemplateCombo(); mMinifigWizard->Calculate(); mView->GetCamera()->SetViewpoint(lcVector3(0.0f, -270.0f, 90.0f)); mView->ZoomExtents(); } lcMinifigDialog::~lcMinifigDialog() { delete mMinifigWizard; delete ui; } void lcMinifigDialog::UpdateTemplateCombo() { ui->TemplateComboBox->clear(); const auto& Templates = mMinifigWizard->GetTemplates(); for (const auto& Template : Templates) ui->TemplateComboBox->addItem(Template.first); } void lcMinifigDialog::on_TemplateComboBox_currentIndexChanged(const QString& TemplateName) { const auto& Templates = mMinifigWizard->GetTemplates(); const auto& Position = Templates.find(TemplateName); if (Position == Templates.end()) return; const lcMinifigTemplate& Template = Position->second; for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++) { if (!Template.Parts[PartIdx].isEmpty()) { PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(Template.Parts[PartIdx].toLatin1(), nullptr, false, false); if (Info) { for (const lcMinifigPieceInfo& MinifigPieceInfo : mMinifigWizard->mSettings[PartIdx]) { if (Info == MinifigPieceInfo.Info) { mComboBoxes[PartIdx]->setCurrentText(MinifigPieceInfo.Description); break; } } } } else { mComboBoxes[PartIdx]->setCurrentText("None"); } mColorPickers[PartIdx]->setCurrentColorCode(Template.Colors[PartIdx]); QDoubleSpinBox* AngleSpinBox = mSpinBoxes[PartIdx]; if (AngleSpinBox) AngleSpinBox->setValue(Template.Angles[PartIdx]); } mMinifigWizard->Calculate(); } void lcMinifigDialog::on_TemplateSaveButton_clicked() { QString CurrentName = ui->TemplateComboBox->currentText(); bool Ok; QString TemplateName = QInputDialog::getText(this, tr("Save Template"), tr("Template Name:"), QLineEdit::Normal, CurrentName, &Ok); if (!Ok) return; if (TemplateName.isEmpty()) { QMessageBox::information(this, tr("Save Template"), tr("Template name cannot be empty.")); return; } if (TemplateName == CurrentName) { QString Question = tr("Are you sure you want to overwrite the template '%1'?").arg(TemplateName); if (QMessageBox::question(this, tr("Overwrite Template"), Question, QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; } lcMinifigTemplate Template; for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++) { Template.Parts[PartIdx] = mMinifigWizard->mSettings[PartIdx][mComboBoxes[PartIdx]->currentIndex()].Info->mFileName; Template.Colors[PartIdx] = mColorPickers[PartIdx]->currentColorCode(); QDoubleSpinBox* AngleSpinBox = mSpinBoxes[PartIdx]; Template.Angles[PartIdx] = AngleSpinBox ? AngleSpinBox->value() : 0.0f; } mMinifigWizard->SaveTemplate(TemplateName, Template); ui->TemplateComboBox->blockSignals(true); UpdateTemplateCombo(); ui->TemplateComboBox->setCurrentText(TemplateName); ui->TemplateComboBox->blockSignals(false); } void lcMinifigDialog::on_TemplateDeleteButton_clicked() { QString Template = ui->TemplateComboBox->currentText(); QString Question = tr("Are you sure you want to delete the template '%1'?").arg(Template); if (QMessageBox::question(this, tr("Delete Template"), Question, QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; mMinifigWizard->DeleteTemplate(Template); UpdateTemplateCombo(); } void lcMinifigDialog::on_TemplateImportButton_clicked() { QString FileName = QFileDialog::getOpenFileName(this, tr("Import Templates"), "", tr("Minifig Template Files (*.minifig);;All Files (*.*)")); if (FileName.isEmpty()) return; QFile File(FileName); if (!File.open(QIODevice::ReadOnly)) { QMessageBox::warning(this, tr("Error"), tr("Error reading file '%1':\n%2").arg(FileName, File.errorString())); return; } QByteArray FileData = File.readAll(); mMinifigWizard->AddTemplatesJson(FileData); UpdateTemplateCombo(); } void lcMinifigDialog::on_TemplateExportButton_clicked() { QString FileName = QFileDialog::getSaveFileName(this, tr("Export Templates"), "", tr("Minifig Template Files (*.minifig);;All Files (*.*)")); if (FileName.isEmpty()) return; QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) { QMessageBox::warning(this, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString())); return; } QByteArray Templates = mMinifigWizard->GetTemplatesJson(); File.write(Templates); } void lcMinifigDialog::TypeChanged(int Index) { std::array::iterator Search = std::find(mComboBoxes.begin(), mComboBoxes.end(), sender()); if (Search == mComboBoxes.end()) return; mView->MakeCurrent(); mMinifigWizard->SetSelectionIndex(std::distance(mComboBoxes.begin(), Search), Index); mView->Redraw(); } void lcMinifigDialog::ColorChanged(int Index) { std::array::iterator Search = std::find(mColorPickers.begin(), mColorPickers.end(), sender()); if (Search == mColorPickers.end()) return; mMinifigWizard->SetColor(std::distance(mColorPickers.begin(), Search), Index); mView->Redraw(); } void lcMinifigDialog::AngleChanged(double Value) { std::array::iterator Search = std::find(mSpinBoxes.begin(), mSpinBoxes.end(), sender()); if (Search == mSpinBoxes.end()) return; mMinifigWizard->SetAngle(std::distance(mSpinBoxes.begin(), Search), Value); mView->Redraw(); } leocad-23.03/common/lc_minifigdialog.h000066400000000000000000000015451440571307300177020ustar00rootroot00000000000000#pragma once #include "minifig.h" class lcQColorPicker; namespace Ui { class lcMinifigDialog; } class lcMinifigDialog : public QDialog { Q_OBJECT public: explicit lcMinifigDialog(QWidget* Parent); ~lcMinifigDialog(); MinifigWizard* mMinifigWizard; protected slots: void on_TemplateComboBox_currentIndexChanged(const QString& TemplateName); void on_TemplateSaveButton_clicked(); void on_TemplateDeleteButton_clicked(); void on_TemplateImportButton_clicked(); void on_TemplateExportButton_clicked(); void TypeChanged(int Index); void ColorChanged(int Index); void AngleChanged(double Value); protected: void UpdateTemplateCombo(); Ui::lcMinifigDialog* ui; lcView* mView; std::array mComboBoxes; std::array mColorPickers; std::array mSpinBoxes; }; leocad-23.03/common/lc_minifigdialog.ui000066400000000000000000000610451440571307300200710ustar00rootroot00000000000000 lcMinifigDialog 0 0 840 416 Minifig Wizard 1 0 QComboBox::AdjustToContents 24 60 16777215 1 -360.000000000000000 360.000000000000000 1 0 QFrame::NoFrame QFrame::Plain 60 16777215 1 -360.000000000000000 360.000000000000000 1 0 QComboBox::AdjustToContents 24 1 0 QComboBox::AdjustToContents 24 60 16777215 1 -360.000000000000000 360.000000000000000 1 0 QComboBox::AdjustToContents 24 1 0 QComboBox::AdjustToContents 24 1 0 QComboBox::AdjustToContents 24 60 16777215 1 -360.000000000000000 360.000000000000000 60 16777215 1 -360.000000000000000 360.000000000000000 1 0 QComboBox::AdjustToContents 24 1 0 QComboBox::AdjustToContents 24 60 16777215 1 -360.000000000000000 360.000000000000000 60 16777215 1 -360.000000000000000 360.000000000000000 1 0 QComboBox::AdjustToContents 24 1 0 QComboBox::AdjustToContents 24 60 16777215 1 -360.000000000000000 360.000000000000000 60 16777215 1 -360.000000000000000 360.000000000000000 1 0 QComboBox::AdjustToContents 24 1 0 QComboBox::AdjustToContents 24 1 0 QComboBox::AdjustToContents 24 1 0 QComboBox::AdjustToContents 24 60 16777215 1 -360.000000000000000 360.000000000000000 60 16777215 1 -360.000000000000000 360.000000000000000 1 0 QComboBox::AdjustToContents 24 1 0 QComboBox::AdjustToContents 24 60 16777215 1 -360.000000000000000 360.000000000000000 60 16777215 1 -360.000000000000000 360.000000000000000 1 0 QComboBox::AdjustToContents 24 0 0 Templates 0 0 Save... Delete... Import... Export... Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok lcQColorPicker QToolButton
lc_qcolorpicker.h
hatsType hatsColor hatsAngle headAngle headColor headType hats2Type hats2Color hats2Angle neckType neckColor bodyColor bodyType larmType larmColor larmAngle rarmAngle rarmColor rarmType lhandType lhandColor lhandAngle rhandAngle rhandColor rhandType lhandaType lhandaColor lhandaAngle rhandaAngle rhandaColor rhandaType body2Type body2Color body3Color body3Type llegType llegColor llegAngle rlegAngle rlegColor rlegType llegaType llegaColor llegaAngle rlegaAngle rlegaColor rlegaType TemplateComboBox TemplateSaveButton TemplateDeleteButton buttonBox accepted() lcMinifigDialog accept() 248 254 157 274 buttonBox rejected() lcMinifigDialog reject() 316 260 286 274
leocad-23.03/common/lc_model.cpp000066400000000000000000003103611440571307300165320ustar00rootroot00000000000000#include "lc_global.h" #include "lc_model.h" #include #include "piece.h" #include "camera.h" #include "light.h" #include "group.h" #include "lc_mainwindow.h" #include "lc_profile.h" #include "lc_library.h" #include "lc_scene.h" #include "lc_texture.h" #include "lc_synth.h" #include "lc_file.h" #include "pieceinf.h" #include "lc_view.h" #include "minifig.h" #include "lc_qarraydialog.h" #include "lc_qselectdialog.h" #include "lc_minifigdialog.h" #include "lc_qgroupdialog.h" #include "lc_qeditgroupsdialog.h" #include "lc_qpropertiesdialog.h" #include "lc_qutils.h" #include "lc_lxf.h" #include "lc_previewwidget.h" #include "lc_findreplacewidget.h" void lcModelProperties::LoadDefaults() { mAuthor = lcGetProfileString(LC_PROFILE_DEFAULT_AUTHOR_NAME); mAmbientColor = lcVector3FromColor(lcGetProfileInt(LC_PROFILE_DEFAULT_AMBIENT_COLOR)); } void lcModelProperties::SaveDefaults() { lcSetProfileInt(LC_PROFILE_DEFAULT_AMBIENT_COLOR, lcColorFromVector3(mAmbientColor)); } void lcModelProperties::SaveLDraw(QTextStream& Stream) const { const QLatin1String LineEnding("\r\n"); Stream << QLatin1String("0 ") << mDescription << LineEnding; Stream << QLatin1String("0 Name: ") << mModelName << LineEnding; Stream << QLatin1String("0 Author: ") << mAuthor << LineEnding; if (!mComments.isEmpty()) { QStringList Comments = mComments.split('\n'); for (const QString& Comment : Comments) Stream << QLatin1String("0 !LEOCAD MODEL COMMENT ") << Comment << LineEnding; } // lcVector3 mAmbientColor; } bool lcModelProperties::ParseLDrawHeader(QString Line, bool FirstLine) { QTextStream LineStream(&Line, QIODevice::ReadOnly); QString Token; LineStream >> Token; const int StartPos = LineStream.pos(); LineStream >> Token; if (Token == QLatin1String("!LEOCAD")) return false; if (Token == QLatin1String("Name:")) { mModelName = LineStream.readLine().mid(1); return true; } if (Token == QLatin1String("Author:")) { mAuthor = LineStream.readLine().mid(1); return true; } if (FirstLine) { LineStream.seek(StartPos); mDescription = LineStream.readLine().mid(1); return true; } return false; } void lcModelProperties::ParseLDrawLine(QTextStream& Stream) { QString Token; Stream >> Token; if (Token == QLatin1String("AUTHOR")) mAuthor = Stream.readLine().mid(1); else if (Token == QLatin1String("DESCRIPTION")) mDescription = Stream.readLine().mid(1); else if (Token == QLatin1String("COMMENT")) { QString Comment = Stream.readLine().mid(1); if (!mComments.isEmpty()) mComments += '\n'; mComments += Comment; } } lcModel::lcModel(const QString& FileName, Project* Project, bool Preview) : mProject(Project), mIsPreview(Preview) { mProperties.mModelName = FileName; mProperties.mFileName = FileName; mProperties.LoadDefaults(); mActive = false; mCurrentStep = 1; mPieceInfo = nullptr; } lcModel::~lcModel() { if (mPieceInfo) { if (!mIsPreview && gMainWindow && gMainWindow->GetCurrentPieceInfo() == mPieceInfo) gMainWindow->SetCurrentPieceInfo(nullptr); if (mPieceInfo->GetModel() == this) mPieceInfo->SetPlaceholder(); lcPiecesLibrary* Library = lcGetPiecesLibrary(); Library->ReleasePieceInfo(mPieceInfo); } DeleteModel(); DeleteHistory(); } bool lcModel::GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& ParentWorldMatrix) const { for (const lcPiece* ModelPiece : mPieces) { if (ModelPiece == Piece) { ParentWorldMatrix = lcMul(ModelPiece->mModelWorld, ParentWorldMatrix); return true; } const PieceInfo* Info = ModelPiece->mPieceInfo; if (Info->IsModel()) { lcMatrix44 WorldMatrix = lcMul(ModelPiece->mModelWorld, ParentWorldMatrix); if (Info->GetPieceWorldMatrix(Piece, WorldMatrix)) { ParentWorldMatrix = WorldMatrix; return true; } } } return false; } bool lcModel::IncludesModel(const lcModel* Model) const { if (Model == this) return true; for (const lcPiece* Piece : mPieces) if (Piece->mPieceInfo->IncludesModel(Model)) return true; return false; } void lcModel::DeleteHistory() { for (lcModelHistoryEntry* Entry : mUndoHistory) delete Entry; mUndoHistory.clear(); for (lcModelHistoryEntry* Entry : mRedoHistory) delete Entry; mRedoHistory.clear(); } void lcModel::DeleteModel() { if (gMainWindow) { std::vector Views = lcView::GetModelViews(this); // TODO: this is only needed to avoid a dangling pointer during undo/redo if a camera is set to a view but we should find a better solution instead for (lcView* View : Views) { lcCamera* Camera = View->GetCamera(); if (!Camera->IsSimple() && mCameras.FindIndex(Camera) != -1) View->SetCamera(Camera, true); } } mPieces.DeleteAll(); mCameras.DeleteAll(); mLights.DeleteAll(); mGroups.DeleteAll(); mFileLines.clear(); } void lcModel::CreatePieceInfo(Project* Project) { lcPiecesLibrary* Library = lcGetPiecesLibrary(); mPieceInfo = Library->FindPiece(mProperties.mFileName.toLatin1().constData(), Project, true, false); mPieceInfo->SetModel(this, true, Project, true); Library->LoadPieceInfo(mPieceInfo, true, true); } void lcModel::UpdateMesh() { mPieceInfo->SetModel(this, true, nullptr, false); } void lcModel::UpdateAllViews() const { lcView::UpdateProjectViews(mProject); } void lcModel::UpdatePieceInfo(std::vector& UpdatedModels) { if (std::find(UpdatedModels.begin(), UpdatedModels.end(), this) != UpdatedModels.end()) return; mPieceInfo->SetModel(this, false, nullptr, false); UpdatedModels.push_back(this); const lcMesh* Mesh = mPieceInfo->GetMesh(); if (mPieces.IsEmpty() && !Mesh) { mPieceInfo->SetBoundingBox(lcVector3(0.0f, 0.0f, 0.0f), lcVector3(0.0f, 0.0f, 0.0f)); return; } lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); for (lcPiece* Piece : mPieces) { if (Piece->IsVisibleInSubModel()) { Piece->mPieceInfo->UpdateBoundingBox(UpdatedModels); Piece->CompareBoundingBox(Min, Max); } } if (Mesh) { Min = lcMin(Min, Mesh->mBoundingBox.Min); Max = lcMax(Max, Mesh->mBoundingBox.Max); } mPieceInfo->SetBoundingBox(Min, Max); } void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly) const { const QLatin1String LineEnding("\r\n"); mProperties.SaveLDraw(Stream); lcArray CurrentGroups; lcStep Step = 1; int CurrentLine = 0; int AddedSteps = 0; for (lcPiece* Piece : mPieces) { if (SelectedOnly && !Piece->IsSelected()) continue; while (Piece->GetFileLine() > CurrentLine && CurrentLine < mFileLines.size()) { QString Line = mFileLines[CurrentLine]; QTextStream LineStream(&Line, QIODevice::ReadOnly); QString Token; LineStream >> Token; bool Skip = false; if (Token == QLatin1String("0")) { LineStream >> Token; if (Token == QLatin1String("STEP")) { if (Piece->GetStepShow() > Step) Step++; else Skip = true; } } if (!Skip) { Stream << mFileLines[CurrentLine]; if (AddedSteps > 0) AddedSteps--; } CurrentLine++; } while (Piece->GetStepShow() > Step) { Stream << QLatin1String("0 STEP\r\n"); AddedSteps++; Step++; } lcGroup* PieceGroup = Piece->GetGroup(); if (PieceGroup) { if (CurrentGroups.IsEmpty() || (!CurrentGroups.IsEmpty() && PieceGroup != CurrentGroups[CurrentGroups.GetSize() - 1])) { lcArray PieceParents; for (lcGroup* Group = PieceGroup; Group; Group = Group->mGroup) PieceParents.InsertAt(0, Group); int FoundParent = -1; while (!CurrentGroups.IsEmpty()) { lcGroup* Group = CurrentGroups[CurrentGroups.GetSize() - 1]; const int Index = PieceParents.FindIndex(Group); if (Index == -1) { CurrentGroups.RemoveIndex(CurrentGroups.GetSize() - 1); Stream << QLatin1String("0 !LEOCAD GROUP END\r\n"); } else { FoundParent = Index; break; } } for (int ParentIdx = FoundParent + 1; ParentIdx < PieceParents.GetSize(); ParentIdx++) { lcGroup* Group = PieceParents[ParentIdx]; CurrentGroups.Add(Group); Stream << QLatin1String("0 !LEOCAD GROUP BEGIN ") << Group->mName << LineEnding; } } } else { while (CurrentGroups.GetSize()) { CurrentGroups.RemoveIndex(CurrentGroups.GetSize() - 1); Stream << QLatin1String("0 !LEOCAD GROUP END\r\n"); } } if (Piece->mPieceInfo->GetSynthInfo()) { Stream << QLatin1String("0 !LEOCAD SYNTH BEGIN\r\n"); const lcArray& ControlPoints = Piece->GetControlPoints(); for (int ControlPointIdx = 0; ControlPointIdx < ControlPoints.GetSize(); ControlPointIdx++) { const lcPieceControlPoint& ControlPoint = ControlPoints[ControlPointIdx]; Stream << QLatin1String("0 !LEOCAD SYNTH CONTROL_POINT"); const float* FloatMatrix = ControlPoint.Transform; const float Numbers[13] = { FloatMatrix[12], -FloatMatrix[14], FloatMatrix[13], FloatMatrix[0], -FloatMatrix[8], FloatMatrix[4], -FloatMatrix[2], FloatMatrix[10], -FloatMatrix[6], FloatMatrix[1], -FloatMatrix[9], FloatMatrix[5], ControlPoint.Scale }; for (int NumberIdx = 0; NumberIdx < 13; NumberIdx++) Stream << ' ' << lcFormatValue(Numbers[NumberIdx], NumberIdx < 3 ? 4 : 6); Stream << LineEnding; } } Piece->SaveLDraw(Stream); if (Piece->mPieceInfo->GetSynthInfo()) Stream << QLatin1String("0 !LEOCAD SYNTH END\r\n"); } while (CurrentLine < mFileLines.size()) { QString Line = mFileLines[CurrentLine]; QTextStream LineStream(&Line, QIODevice::ReadOnly); QString Token; LineStream >> Token; bool Skip = false; if (Token == QLatin1String("0")) { LineStream >> Token; if (Token == QLatin1String("STEP") && AddedSteps-- > 0) Skip = true; } if (!Skip) Stream << mFileLines[CurrentLine]; CurrentLine++; } while (CurrentGroups.GetSize()) { CurrentGroups.RemoveIndex(CurrentGroups.GetSize() - 1); Stream << QLatin1String("0 !LEOCAD GROUP END\r\n"); } for (const lcCamera* Camera : mCameras) if (!SelectedOnly || Camera->IsSelected()) Camera->SaveLDraw(Stream); for (const lcLight* Light : mLights) if (!SelectedOnly || Light->IsSelected()) Light->SaveLDraw(Stream); Stream.flush(); } int lcModel::SplitMPD(QIODevice& Device) { qint64 ModelPos = Device.pos(); while (!Device.atEnd()) { const qint64 Pos = Device.pos(); QString OriginalLine = Device.readLine(); QString Line = OriginalLine.trimmed(); QTextStream LineStream(&Line, QIODevice::ReadOnly); QString Token; LineStream >> Token; if (Token == QLatin1String("0")) { LineStream >> Token; if (Token == QLatin1String("FILE")) { if (!mProperties.mFileName.isEmpty()) { Device.seek(Pos); break; } SetFileName(LineStream.readAll().trimmed()); ModelPos = Pos; } else if (Token == QLatin1String("NOFILE")) { break; } } } return ModelPos; } void lcModel::LoadLDraw(QIODevice& Device, Project* Project) { lcPiece* Piece = nullptr; lcCamera* Camera = nullptr; lcLight* Light = nullptr; lcArray CurrentGroups; lcArray ControlPoints; int CurrentStep = 1; lcPiecesLibrary* Library = lcGetPiecesLibrary(); mProperties.mAuthor.clear(); mProperties.mDescription.clear(); mProperties.mComments.clear(); bool ReadingHeader = true; bool FirstLine = true; while (!Device.atEnd()) { const qint64 Pos = Device.pos(); QString OriginalLine = Device.readLine(); QString Line = OriginalLine.trimmed(); QTextStream LineStream(&Line, QIODevice::ReadOnly); QString Token; LineStream >> Token; if (Token == QLatin1String("0")) { LineStream >> Token; if (Token == QLatin1String("FILE")) { QString Name = LineStream.readAll().trimmed(); if (mProperties.mFileName != Name) { Device.seek(Pos); break; } continue; } else if (Token == QLatin1String("NOFILE")) { break; } if (ReadingHeader) { ReadingHeader = mProperties.ParseLDrawHeader(Line, FirstLine); FirstLine = false; if (ReadingHeader) continue; } if (Token == QLatin1String("STEP")) { delete Piece; Piece = nullptr; CurrentStep++; mFileLines.append(OriginalLine); continue; } if (Token != QLatin1String("!LEOCAD")) { mFileLines.append(OriginalLine); continue; } LineStream >> Token; if (Token == QLatin1String("MODEL")) { mProperties.ParseLDrawLine(LineStream); } else if (Token == QLatin1String("PIECE")) { if (!Piece) Piece = new lcPiece(nullptr); Piece->ParseLDrawLine(LineStream); } else if (Token == QLatin1String("CAMERA")) { if (!Camera) Camera = new lcCamera(false); if (Camera->ParseLDrawLine(LineStream)) { Camera->CreateName(mCameras); mCameras.Add(Camera); Camera = nullptr; } } else if (Token == QLatin1String("LIGHT")) { } else if (Token == QLatin1String("GROUP")) { LineStream >> Token; if (Token == QLatin1String("BEGIN")) { QString Name = LineStream.readAll().trimmed(); lcGroup* Group = GetGroup(Name, true); if (!CurrentGroups.IsEmpty()) Group->mGroup = CurrentGroups[CurrentGroups.GetSize() - 1]; else Group->mGroup = nullptr; CurrentGroups.Add(Group); } else if (Token == QLatin1String("END")) { if (!CurrentGroups.IsEmpty()) CurrentGroups.RemoveIndex(CurrentGroups.GetSize() - 1); } } else if (Token == QLatin1String("SYNTH")) { LineStream >> Token; if (Token == QLatin1String("BEGIN")) { ControlPoints.RemoveAll(); } else if (Token == QLatin1String("END")) { ControlPoints.RemoveAll(); } else if (Token == QLatin1String("CONTROL_POINT")) { float Numbers[13]; for (int TokenIdx = 0; TokenIdx < 13; TokenIdx++) LineStream >> Numbers[TokenIdx]; lcPieceControlPoint& PieceControlPoint = ControlPoints.Add(); PieceControlPoint.Transform = lcMatrix44(lcVector4(Numbers[3], Numbers[9], -Numbers[6], 0.0f), lcVector4(Numbers[5], Numbers[11], -Numbers[8], 0.0f), lcVector4(-Numbers[4], -Numbers[10], Numbers[7], 0.0f), lcVector4(Numbers[0], Numbers[2], -Numbers[1], 1.0f)); PieceControlPoint.Scale = Numbers[12]; } } continue; } else if (Token == QLatin1String("1")) { ReadingHeader = false; int ColorCode; LineStream >> ColorCode; float IncludeMatrix[12]; for (int TokenIdx = 0; TokenIdx < 12; TokenIdx++) LineStream >> IncludeMatrix[TokenIdx]; lcMatrix44 IncludeTransform(lcVector4(IncludeMatrix[3], IncludeMatrix[6], IncludeMatrix[9], 0.0f), lcVector4(IncludeMatrix[4], IncludeMatrix[7], IncludeMatrix[10], 0.0f), lcVector4(IncludeMatrix[5], IncludeMatrix[8], IncludeMatrix[11], 0.0f), lcVector4(IncludeMatrix[0], IncludeMatrix[1], IncludeMatrix[2], 1.0f)); QString PartId = LineStream.readAll().trimmed(); if (PartId.isEmpty()) continue; QByteArray CleanId = PartId.toLatin1().toUpper().replace('\\', '/'); if (Library->IsPrimitive(CleanId.constData())) { mFileLines.append(OriginalLine); } else { if (!Piece) Piece = new lcPiece(nullptr); if (!CurrentGroups.IsEmpty()) Piece->SetGroup(CurrentGroups[CurrentGroups.GetSize() - 1]); PieceInfo* Info = Library->FindPiece(PartId.toLatin1().constData(), Project, true, true); const float* Matrix = IncludeTransform; const lcMatrix44 Transform(lcVector4(Matrix[0], Matrix[2], -Matrix[1], 0.0f), lcVector4(Matrix[8], Matrix[10], -Matrix[9], 0.0f), lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(Matrix[12], Matrix[14], -Matrix[13], 1.0f)); Piece->SetFileLine(mFileLines.size()); Piece->SetPieceInfo(Info, PartId, false); Piece->Initialize(Transform, CurrentStep); Piece->SetColorCode(ColorCode); Piece->VerifyControlPoints(ControlPoints); Piece->SetControlPoints(ControlPoints); ControlPoints.RemoveAll(); if (Piece->mPieceInfo->IsModel() && Piece->mPieceInfo->GetModel()->IncludesModel(this)) { delete Piece; Piece = nullptr; continue; } AddPiece(Piece); Piece = nullptr; } } else { ReadingHeader = false; mFileLines.append(OriginalLine); } FirstLine = false; } mCurrentStep = CurrentStep; CalculateStep(mCurrentStep); Library->WaitForLoadQueue(); Library->mBuffersDirty = true; Library->UnloadUnusedParts(); delete Piece; delete Camera; delete Light; } bool lcModel::LoadBinary(lcFile* file) { qint32 i, count; char id[32]; quint32 rgb; float fv = 0.4f; quint8 ch; quint16 sh; file->Seek(0, SEEK_SET); file->ReadBuffer(id, 32); sscanf(&id[7], "%f", &fv); if (memcmp(id, "LeoCAD ", 7)) return false; if (fv == 0.0f) { const lconv *loc = localeconv(); id[8] = loc->decimal_point[0]; sscanf(&id[7], "%f", &fv); if (fv == 0.0f) return false; } if (fv > 0.4f) file->ReadFloats(&fv, 1); file->ReadU32(&rgb, 1); if (fv < 0.6f) // old view { double eye[3], target[3]; file->ReadDoubles(eye, 3); file->ReadDoubles(target, 3); } file->Seek(28, SEEK_CUR); file->ReadS32(&i, 1); mCurrentStep = i; if (fv > 0.8f) file->ReadU32();//m_nScene file->ReadS32(&count, 1); lcPiecesLibrary* Library = lcGetPiecesLibrary(); const int FirstNewPiece = mPieces.GetSize(); while (count--) { if (fv > 0.4f) { lcPiece* pPiece = new lcPiece(nullptr); pPiece->FileLoad(*file); AddPiece(pPiece); } else { char name[LC_PIECE_NAME_LEN]; lcVector3 pos, rot; quint8 color, step, group; file->ReadFloats(pos, 3); file->ReadFloats(rot, 3); file->ReadU8(&color, 1); file->ReadBuffer(name, 9); strcat(name, ".dat"); file->ReadU8(&step, 1); file->ReadU8(&group, 1); pos *= 25.0f; lcMatrix44 WorldMatrix = lcMul(lcMatrix44RotationZ(rot[2] * LC_DTOR), lcMul(lcMatrix44RotationY(rot[1] * LC_DTOR), lcMatrix44RotationX(rot[0] * LC_DTOR))); WorldMatrix.SetTranslation(pos); PieceInfo* pInfo = Library->FindPiece(name, nullptr, true, false); lcPiece* pPiece = new lcPiece(pInfo); pPiece->Initialize(WorldMatrix, step); pPiece->SetColorCode(lcGetColorCodeFromOriginalColor(color)); AddPiece(pPiece); // pPiece->SetGroup((lcGroup*)group); } } if (fv >= 0.4f) { file->ReadBuffer(&ch, 1); if (ch == 0xFF) file->ReadU16(&sh, 1); else sh = ch; if (sh > 100) file->Seek(sh, SEEK_CUR); else { QByteArray Author; Author.resize(sh + 1); file->ReadBuffer(Author.data(), sh); Author[sh] = 0; mProperties.mAuthor = QString::fromUtf8(Author); } file->ReadBuffer(&ch, 1); if (ch == 0xFF) file->ReadU16(&sh, 1); else sh = ch; if (sh > 100) file->Seek(sh, SEEK_CUR); else { QByteArray Description; Description.resize(sh + 1); file->ReadBuffer(Description.data(), sh); Description[sh] = 0; mProperties.mDescription = QString::fromUtf8(Description); } file->ReadBuffer(&ch, 1); if (ch == 0xFF && fv < 1.3f) file->ReadU16(&sh, 1); else sh = ch; if (sh > 255) file->Seek(sh, SEEK_CUR); else { QByteArray Comments; Comments.resize(sh + 1); file->ReadBuffer(Comments.data(), sh); Comments[sh] = 0; mProperties.mComments = QString::fromUtf8(Comments); mProperties.mComments.replace(QLatin1String("\r\n"), QLatin1String("\n")); } } if (fv >= 0.5f) { const int NumGroups = mGroups.GetSize(); file->ReadS32(&count, 1); for (i = 0; i < count; i++) mGroups.Add(new lcGroup()); for (int GroupIdx = NumGroups; GroupIdx < mGroups.GetSize(); GroupIdx++) { lcGroup* Group = mGroups[GroupIdx]; if (fv < 1.0f) { char Name[LC_MAX_GROUP_NAME + 1]; file->ReadBuffer(Name, sizeof(Name)); Group->mName = QString::fromUtf8(Name); file->ReadBuffer(&ch, 1); Group->mGroup = (lcGroup*)-1; } else Group->FileLoad(file); } for (int GroupIdx = NumGroups; GroupIdx < mGroups.GetSize(); GroupIdx++) { lcGroup* Group = mGroups[GroupIdx]; i = (qint32)(quintptr)(Group->mGroup); Group->mGroup = nullptr; if (i > 0xFFFF || i == -1) continue; Group->mGroup = mGroups[NumGroups + i]; } for (int PieceIdx = FirstNewPiece; PieceIdx < mPieces.GetSize(); PieceIdx++) { lcPiece* Piece = mPieces[PieceIdx]; i = (qint32)(quintptr)(Piece->GetGroup()); Piece->SetGroup(nullptr); if (i > 0xFFFF || i == -1) continue; Piece->SetGroup(mGroups[NumGroups + i]); } RemoveEmptyGroups(); } if (fv >= 0.6f) { if (fv < 1.0f) file->Seek(4, SEEK_CUR); else file->Seek(2, SEEK_CUR); file->ReadS32(&count, 1); for (i = 0; i < count; i++) lcCamera::FileLoad(*file); } if (fv >= 0.7f) { file->Seek(24, SEEK_CUR); if (fv < 1.3f) { file->ReadU8(&ch, 1); if (ch == 0xFF) file->ReadU16(&sh, 1); sh = ch; } else file->ReadU16(&sh, 1); file->Seek(sh, SEEK_CUR); // Background } if (fv >= 0.8f) { file->ReadBuffer(&ch, 1); file->Seek(ch, SEEK_CUR); file->ReadBuffer(&ch, 1); file->Seek(ch, SEEK_CUR); } if (fv > 0.9f) { file->ReadU32(&rgb, 1); mProperties.mAmbientColor[0] = (float)((unsigned char) (rgb))/255; mProperties.mAmbientColor[1] = (float)((unsigned char) (((unsigned short) (rgb)) >> 8))/255; mProperties.mAmbientColor[2] = (float)((unsigned char) ((rgb) >> 16))/255; if (fv < 1.3f) file->Seek(23, SEEK_CUR); else file->Seek(11, SEEK_CUR); } if (fv > 1.0f) { file->ReadU32(&rgb, 1); file->ReadU32(&rgb, 1); } CalculateStep(mCurrentStep); lcGetPiecesLibrary()->UnloadUnusedParts(); return true; } bool lcModel::LoadLDD(const QString& FileData) { std::vector Pieces; std::vector> Groups; if (!lcImportLXFMLFile(FileData, Pieces, Groups)) return false; for (lcPiece* Piece : Pieces) AddPiece(Piece); for (const std::vector& Group : Groups) { lcGroup* NewGroup = AddGroup(tr("Group #"), nullptr); for (lcPiece* Piece : Group) Piece->SetGroup(NewGroup); } lcPiecesLibrary* Library = lcGetPiecesLibrary(); CalculateStep(mCurrentStep); Library->WaitForLoadQueue(); Library->mBuffersDirty = true; Library->UnloadUnusedParts(); return true; } bool lcModel::LoadInventory(const QByteArray& Inventory) { QJsonDocument Document = QJsonDocument::fromJson(Inventory); QJsonObject Root = Document.object(); QJsonArray Parts = Root["results"].toArray(); lcPiecesLibrary* Library = lcGetPiecesLibrary(); for (const QJsonValue& Part : Parts) { QJsonObject PartObject = Part.toObject(); QByteArray PartID = PartObject["part"].toObject()["part_num"].toString().toLatin1(); QJsonArray PartIDArray = PartObject["part"].toObject()["external_ids"].toObject()["LDraw"].toArray(); if (!PartIDArray.isEmpty()) PartID = PartIDArray.first().toString().toLatin1(); int Quantity = PartObject["quantity"].toInt(); int ColorCode = 16; QJsonArray ColorArray = PartObject["color"].toObject()["external_ids"].toObject()["LDraw"].toObject()["ext_ids"].toArray(); if (!ColorArray.isEmpty()) ColorCode = ColorArray.first().toInt(); PieceInfo* Info = Library->FindPiece(PartID + ".dat", nullptr, true, false); while (Quantity--) { lcPiece* Piece = new lcPiece(nullptr); Piece->SetPieceInfo(Info, QString(), false); Piece->Initialize(lcMatrix44Identity(), 1); Piece->SetColorCode(ColorCode); AddPiece(Piece); } } if (mPieces.IsEmpty()) return false; Library->WaitForLoadQueue(); Library->mBuffersDirty = true; Library->UnloadUnusedParts(); auto RoundBounds = [](float& Value) { Value = ((Value < 0.0f) ? floor((Value - 5.0f) / 10.0f) : ceil((Value + 5.0f) / 10.0f)) * 10.0f; }; constexpr float TargetHeight = 800.0f; float CurrentX = 0.0f; float CurrentY = 0.0f; float ColumnWidth = 0.0f; for (lcPiece* Piece : mPieces) { lcBoundingBox BoundingBox = Piece->mPieceInfo->GetBoundingBox(); RoundBounds(BoundingBox.Min.x); RoundBounds(BoundingBox.Min.y); RoundBounds(BoundingBox.Max.x); RoundBounds(BoundingBox.Max.y); const float PieceWidth = BoundingBox.Max.x - BoundingBox.Min.x; const float PieceHeight = BoundingBox.Max.y - BoundingBox.Min.y; if (CurrentY + PieceHeight > TargetHeight) { CurrentY = 0.0f; CurrentX += ColumnWidth; ColumnWidth = 0.0f; } Piece->SetPosition(lcVector3(CurrentX + PieceWidth / 2.0f, CurrentY + PieceHeight / 2.0f, 0.0f), 1, false); CurrentY += PieceHeight; ColumnWidth = qMax(ColumnWidth, PieceWidth); } CalculateStep(mCurrentStep); return true; } void lcModel::Merge(lcModel* Other) { for (int PieceIdx = 0; PieceIdx < Other->mPieces.GetSize(); PieceIdx++) { lcPiece* Piece = Other->mPieces[PieceIdx]; Piece->SetFileLine(-1); AddPiece(Piece); } Other->mPieces.RemoveAll(); for (int CameraIdx = 0; CameraIdx < Other->mCameras.GetSize(); CameraIdx++) { lcCamera* Camera = Other->mCameras[CameraIdx]; Camera->CreateName(mCameras); mCameras.Add(Camera); } Other->mCameras.RemoveAll(); for (int LightIdx = 0; LightIdx < Other->mLights.GetSize(); LightIdx++) { lcLight* Light = Other->mLights[LightIdx]; Light->CreateName(mLights); mLights.Add(Light); } Other->mLights.RemoveAll(); for (int GroupIdx = 0; GroupIdx < Other->mGroups.GetSize(); GroupIdx++) { lcGroup* Group = Other->mGroups[GroupIdx]; Group->CreateName(mGroups); mGroups.Add(Group); } Other->mGroups.RemoveAll(); delete Other; gMainWindow->UpdateTimeline(false, false); } void lcModel::Cut() { Copy(); if (RemoveSelectedObjects()) { gMainWindow->UpdateTimeline(false, false); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); SaveCheckpoint(tr("Cutting")); } } void lcModel::Copy() { QByteArray File; QTextStream Stream(&File, QIODevice::WriteOnly); SaveLDraw(Stream, true); gApplication->ExportClipboard(File); } void lcModel::Paste(bool PasteToCurrentStep) { if (gApplication->mClipboard.isEmpty()) return; lcModel* Model = new lcModel(QString(), nullptr, false); QBuffer Buffer(&gApplication->mClipboard); Buffer.open(QIODevice::ReadOnly); Model->LoadLDraw(Buffer, lcGetActiveProject()); const lcArray& PastedPieces = Model->mPieces; lcArray SelectedObjects; SelectedObjects.AllocGrow(PastedPieces.GetSize()); for (lcPiece* Piece : PastedPieces) { Piece->SetFileLine(-1); if (PasteToCurrentStep) { Piece->SetStepShow(mCurrentStep); SelectedObjects.Add(Piece); } else { if (Piece->GetStepShow() <= mCurrentStep) SelectedObjects.Add(Piece); } } Merge(Model); SaveCheckpoint(tr("Pasting")); if (SelectedObjects.GetSize() == 1) ClearSelectionAndSetFocus(SelectedObjects[0], LC_PIECE_SECTION_POSITION, false); else SetSelectionAndFocus(SelectedObjects, nullptr, 0, false); CalculateStep(mCurrentStep); gMainWindow->UpdateTimeline(false, false); UpdateAllViews(); } void lcModel::DuplicateSelectedPieces() { lcArray NewPieces; lcPiece* Focus = nullptr; std::map GroupMap; std::function GetNewGroup = [this, &GroupMap, &GetNewGroup](lcGroup* Group) { const auto GroupIt = GroupMap.find(Group); if (GroupIt != GroupMap.end()) return GroupIt->second; else { lcGroup* Parent = Group->mGroup ? GetNewGroup(Group->mGroup) : nullptr; QString GroupName = Group->mName; while (!GroupName.isEmpty()) { const QChar Last = GroupName[GroupName.size() - 1]; if (Last.isDigit()) GroupName.chop(1); else break; } if (GroupName.isEmpty()) GroupName = Group->mName; lcGroup* NewGroup = AddGroup(GroupName, Parent); GroupMap[Group] = NewGroup; return NewGroup; } }; for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) { lcPiece* Piece = mPieces[PieceIdx]; if (!Piece->IsSelected()) continue; lcPiece* NewPiece = new lcPiece(*Piece); NewPiece->UpdatePosition(mCurrentStep); NewPieces.Add(NewPiece); if (Piece->IsFocused()) Focus = NewPiece; PieceIdx++; InsertPiece(NewPiece, PieceIdx); lcGroup* Group = Piece->GetGroup(); if (Group) Piece->SetGroup(GetNewGroup(Group)); } if (NewPieces.IsEmpty()) return; gMainWindow->UpdateTimeline(false, false); SetSelectionAndFocus(NewPieces, Focus, LC_PIECE_SECTION_POSITION, false); SaveCheckpoint(tr("Duplicating Pieces")); } void lcModel::PaintSelectedPieces() { SetSelectedPiecesColorIndex(gMainWindow->mColorIndex); } void lcModel::GetScene(lcScene* Scene, const lcCamera* ViewCamera, bool AllowHighlight, bool AllowFade) const { if (mPieceInfo) mPieceInfo->AddRenderMesh(*Scene); for (const lcPiece* Piece : mPieces) { if (Piece->IsVisible(mCurrentStep)) { const lcStep StepShow = Piece->GetStepShow(); Piece->AddMainModelRenderMeshes(Scene, AllowHighlight && StepShow == mCurrentStep, AllowFade && StepShow < mCurrentStep); } } if (Scene->GetDrawInterface() && !Scene->GetActiveSubmodelInstance()) { for (const lcCamera* Camera : mCameras) if (Camera != ViewCamera && Camera->IsVisible()) Scene->AddInterfaceObject(Camera); for (const lcLight* Light : mLights) if (Light->IsVisible()) Scene->AddInterfaceObject(Light); } } void lcModel::AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const { for (const lcPiece* Piece : mPieces) if (Piece->IsVisibleInSubModel()) Piece->AddSubModelRenderMeshes(Scene, WorldMatrix, DefaultColorIndex, RenderMeshState, ParentActive); } QImage lcModel::GetStepImage(bool Zoom, int Width, int Height, lcStep Step) { const lcView* ActiveView = gMainWindow->GetActiveView(); const lcStep CurrentStep = mCurrentStep; lcCamera* Camera = ActiveView->GetCamera(); lcView View(lcViewType::View, this); View.SetCamera(Camera, true); View.SetOffscreenContext(); View.MakeCurrent(); if (!View.BeginRenderToImage(Width, Height)) { QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Error creating images.")); return QImage(); } SetTemporaryStep(Step); if (Zoom) ZoomExtents(Camera, (float)Width / (float)Height); View.OnDraw(); QImage Image = View.GetRenderImage(); View.EndRenderToImage(); SetTemporaryStep(CurrentStep); if (!mActive) CalculateStep(LC_STEP_MAX); return Image; } QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundColor, QFont Font, QColor TextColor) const { lcPartsList PartsList; if (Step == 0) GetPartsList(gDefaultColor, true, false, PartsList); else GetPartsListForStep(Step, gDefaultColor, PartsList); if (PartsList.empty()) return QImage(); struct lcPartsListImage { QImage Thumbnail; const PieceInfo* Info; int ColorIndex; int Count; QRect Bounds; QPoint Position; }; std::vector Images; for (const auto& PartIt : PartsList) { for (const auto& ColorIt : PartIt.second) { Images.push_back(lcPartsListImage()); lcPartsListImage& Image = Images.back(); Image.Info = PartIt.first; Image.ColorIndex = ColorIt.first; Image.Count = ColorIt.second; } } auto ImageCompare = [](const lcPartsListImage& Image1, const lcPartsListImage& Image2) { if (Image1.ColorIndex != Image2.ColorIndex) return Image1.ColorIndex < Image2.ColorIndex; return strcmp(Image1.Info->m_strDescription, Image2.Info->m_strDescription) < 0; }; std::sort(Images.begin(), Images.end(), ImageCompare); lcView View(lcViewType::PartsList, nullptr); View.SetOffscreenContext(); View.MakeCurrent(); lcContext* Context = View.mContext; const int ThumbnailSize = qMin(MaxWidth, 512); View.SetSize(ThumbnailSize, ThumbnailSize); if (!View.BeginRenderToImage(ThumbnailSize, ThumbnailSize)) { QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Error creating images.")); return QImage(); } float OrthoSize = 200.0f; lcMatrix44 ProjectionMatrix = lcMatrix44Ortho(-OrthoSize, OrthoSize, -OrthoSize, OrthoSize, -5000.0f, 5000.0f); const lcMatrix44 ViewMatrix = lcMatrix44LookAt(lcVector3(-100.0f, -100.0f, 75.0f), lcVector3(0.0f, 0.0f, 0.0f), lcVector3(0.0f, 0.0f, 1.0f)); const int Viewport[4] = { 0, 0, ThumbnailSize, ThumbnailSize }; float ExtraPixels = 0.0f; for (const lcPartsListImage& Image : Images) { const PieceInfo* Info = Image.Info; const lcBoundingBox& BoundingBox = Info->GetBoundingBox(); lcVector3 Points[8]; lcGetBoxCorners(BoundingBox.Min, BoundingBox.Max, Points); for (lcVector3& Point : Points) { Point = lcProjectPoint(Point, ViewMatrix, ProjectionMatrix, Viewport); ExtraPixels = qMax(ExtraPixels, -Point.x); ExtraPixels = qMax(ExtraPixels, Point.x - ThumbnailSize); ExtraPixels = qMax(ExtraPixels, -Point.y); ExtraPixels = qMax(ExtraPixels, Point.y - ThumbnailSize); } } if (ExtraPixels) { OrthoSize += ExtraPixels * (2.0f * OrthoSize / ThumbnailSize); ProjectionMatrix = lcMatrix44Ortho(-OrthoSize, OrthoSize, -OrthoSize, OrthoSize, -5000.0f, 5000.0f); } Context->SetViewport(0, 0, ThumbnailSize, ThumbnailSize); Context->SetDefaultState(); Context->SetProjectionMatrix(ProjectionMatrix); for (lcPartsListImage& Image : Images) { View.BindRenderFramebuffer(); Context->ClearColorAndDepth(lcVector4(lcVector3FromColor(BackgroundColor), 0.0f)); lcScene Scene; const lcPreferences& Preferences = lcGetPreferences(); lcShadingMode ShadingMode = Preferences.mShadingMode; if (ShadingMode == lcShadingMode::Wireframe) ShadingMode = lcShadingMode::Flat; Scene.SetShadingMode(ShadingMode); Scene.SetAllowLOD(false); Scene.Begin(ViewMatrix); Image.Info->AddRenderMeshes(&Scene, lcMatrix44Identity(), Image.ColorIndex, lcRenderMeshState::Default, true); Scene.End(); Scene.Draw(Context); View.UnbindRenderFramebuffer(); Image.Thumbnail = View.GetRenderFramebufferImage().convertToFormat(QImage::Format_ARGB32); } View.EndRenderToImage(); Context->ClearResources(); auto CalculateImageBounds = [](lcPartsListImage& Image) { const QImage& Thumbnail = Image.Thumbnail; const int Width = Thumbnail.width(); const int Height = Thumbnail.height(); int MinX = Width; int MinY = Height; int MaxX = 0; int MaxY = 0; for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { if (qAlpha(Thumbnail.pixel(x, y))) { MinX = qMin(x, MinX); MinY = qMin(y, MinY); MaxX = qMax(x, MaxX); MaxY = qMax(y, MaxY); } } } Image.Bounds = QRect(QPoint(MinX, MinY), QPoint(MaxX, MaxY)); }; QtConcurrent::blockingMap(Images, CalculateImageBounds); QImage DummyImage(16, 16, QImage::Format_ARGB32); QPainter DummyPainter(&DummyImage); DummyPainter.setFont(Font); QFontMetrics FontMetrics = DummyPainter.fontMetrics(); const int Ascent = FontMetrics.ascent(); int CurrentHeight = 0; int ImageWidth = MaxWidth; for (const lcPartsListImage& Image : Images) CurrentHeight = qMax(Image.Bounds.height() + Ascent, CurrentHeight); for (;;) { int CurrentWidth = 0; int CurrentX = 0; int CurrentY = 0; int ColumnWidth = 0; constexpr int Spacing = 20; int NextHeightIncrease = INT_MAX; for (lcPartsListImage& Image : Images) { if (CurrentY + Image.Bounds.height() + Ascent > CurrentHeight) { const int NeededSpace = Image.Bounds.height() + Ascent - (CurrentHeight - CurrentY); NextHeightIncrease = qMin(NeededSpace, NextHeightIncrease); CurrentY = 0; CurrentX += ColumnWidth + Spacing; ColumnWidth = 0; } Image.Position = QPoint(CurrentX, CurrentY); CurrentY += Image.Bounds.height() + Ascent + Spacing; CurrentWidth = qMax(CurrentWidth, CurrentX + Image.Bounds.width()); ColumnWidth = qMax(ColumnWidth, Image.Bounds.width()); } if (CurrentWidth <= MaxWidth) { ImageWidth = CurrentWidth; break; } CurrentHeight += NextHeightIncrease; } QImage PainterImage(ImageWidth + 40, CurrentHeight + 40, QImage::Format_ARGB32); PainterImage.fill(lcQColorFromRGBA(BackgroundColor)); QPainter Painter(&PainterImage); Painter.setFont(Font); Painter.setPen(TextColor); for (const lcPartsListImage& Image : Images) { const QPoint Position = Image.Position + QPoint(20, 20); Painter.drawImage(Position, Image.Thumbnail, Image.Bounds); Painter.drawText(QPoint(Position.x(), Position.y() + Image.Bounds.height() + Ascent), QString::number(Image.Count) + 'x'); } Painter.end(); return PainterImage; } void lcModel::SaveStepImages(const QString& BaseName, bool AddStepSuffix, bool Zoom, int Width, int Height, lcStep Start, lcStep End) { for (lcStep Step = Start; Step <= End; Step++) { QString FileName; if (AddStepSuffix) FileName = BaseName.arg(Step, 2, 10, QLatin1Char('0')); else FileName = BaseName; QImageWriter Writer(FileName); if (Writer.format().isEmpty()) Writer.setFormat("png"); QImage Image = GetStepImage(Zoom, Width, Height, Step); if (!Writer.write(Image)) { QMessageBox::information(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, Writer.errorString())); break; } } } void lcModel::RayTest(lcObjectRayTest& ObjectRayTest) const { for (const lcPiece* Piece : mPieces) if (Piece->IsVisible(mCurrentStep) && (!ObjectRayTest.IgnoreSelected || !Piece->IsSelected())) Piece->RayTest(ObjectRayTest); if (ObjectRayTest.PiecesOnly) return; for (const lcCamera* Camera : mCameras) if (Camera != ObjectRayTest.ViewCamera && Camera->IsVisible() && (!ObjectRayTest.IgnoreSelected || !Camera->IsSelected())) Camera->RayTest(ObjectRayTest); for (const lcLight* Light : mLights) if (Light->IsVisible() && (!ObjectRayTest.IgnoreSelected || !Light->IsSelected())) Light->RayTest(ObjectRayTest); } void lcModel::BoxTest(lcObjectBoxTest& ObjectBoxTest) const { for (const lcPiece* Piece : mPieces) if (Piece->IsVisible(mCurrentStep)) Piece->BoxTest(ObjectBoxTest); for (const lcCamera* Camera : mCameras) if (Camera != ObjectBoxTest.ViewCamera && Camera->IsVisible()) Camera->BoxTest(ObjectBoxTest); for (const lcLight* Light : mLights) if (Light->IsVisible()) Light->BoxTest(ObjectBoxTest); } bool lcModel::SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance, lcPieceInfoRayTest& PieceInfoRayTest) const { bool MinIntersect = false; for (const lcPiece* Piece : mPieces) { const lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(Piece->mModelWorld); const lcVector3 Start = lcMul31(WorldStart, InverseWorldMatrix); const lcVector3 End = lcMul31(WorldEnd, InverseWorldMatrix); if (Piece->IsVisibleInSubModel()) { if (Piece->mPieceInfo->MinIntersectDist(Start, End, MinDistance, PieceInfoRayTest)) // todo: this should check for piece->mMesh first { MinIntersect = true; PieceInfoRayTest.Transform = lcMul(PieceInfoRayTest.Transform, Piece->mModelWorld); } } } return MinIntersect; } bool lcModel::SubModelBoxTest(const lcVector4 Planes[6]) const { for (const lcPiece* Piece : mPieces) if (Piece->IsVisibleInSubModel() && Piece->mPieceInfo->BoxTest(Piece->mModelWorld, Planes)) return true; return false; } void lcModel::SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const { for (const lcPiece* Piece : mPieces) if (Piece->IsVisibleInSubModel()) Piece->SubModelCompareBoundingBox(WorldMatrix, Min, Max); } void lcModel::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector& Points) const { for (const lcPiece* Piece : mPieces) if (Piece->IsVisibleInSubModel()) Piece->SubModelAddBoundingBoxPoints(WorldMatrix, Points); } void lcModel::SaveCheckpoint(const QString& Description) { lcModelHistoryEntry* ModelHistoryEntry = new lcModelHistoryEntry(); ModelHistoryEntry->Description = Description; QTextStream Stream(&ModelHistoryEntry->File); SaveLDraw(Stream, false); mUndoHistory.insert(mUndoHistory.begin(), ModelHistoryEntry); for (lcModelHistoryEntry* Entry : mRedoHistory) delete Entry; mRedoHistory.clear(); if (!Description.isEmpty()) { gMainWindow->UpdateModified(IsModified()); gMainWindow->UpdateUndoRedo(mUndoHistory.size() > 1 ? mUndoHistory[0]->Description : QString(), !mRedoHistory.empty() ? mRedoHistory[0]->Description : QString()); } } void lcModel::LoadCheckPoint(lcModelHistoryEntry* CheckPoint) { lcPiecesLibrary* Library = lcGetPiecesLibrary(); std::vector LoadedInfos; for (lcPiece* Piece : mPieces) { PieceInfo* Info = Piece->mPieceInfo; Library->LoadPieceInfo(Info, true, true); LoadedInfos.push_back(Info); } DeleteModel(); QBuffer Buffer(&CheckPoint->File); Buffer.open(QIODevice::ReadOnly); LoadLDraw(Buffer, lcGetActiveProject()); gMainWindow->UpdateTimeline(true, false); gMainWindow->UpdateCameraMenu(); gMainWindow->UpdateCurrentStep(); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); for (PieceInfo* Info : LoadedInfos) Library->ReleasePieceInfo(Info); } void lcModel::SetActive(bool Active) { CalculateStep(Active ? mCurrentStep : LC_STEP_MAX); mActive = Active; } void lcModel::CalculateStep(lcStep Step) { for (lcPiece* Piece : mPieces) { Piece->UpdatePosition(Step); if (Piece->IsSelected()) { if (!Piece->IsVisible(Step)) Piece->SetSelected(false); else SelectGroup(Piece->GetTopGroup(), true); } } for (lcCamera* Camera : mCameras) Camera->UpdatePosition(Step); for (lcLight* Light : mLights) Light->UpdatePosition(Step); } void lcModel::SetCurrentStep(lcStep Step) { mCurrentStep = Step; CalculateStep(Step); gMainWindow->UpdateTimeline(false, false); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); gMainWindow->UpdateCurrentStep(); } void lcModel::ShowFirstStep() { if (mCurrentStep == 1) return; SetCurrentStep(1); } void lcModel::ShowLastStep() { const lcStep LastStep = GetLastStep(); if (mCurrentStep == LastStep) return; SetCurrentStep(LastStep); } void lcModel::ShowPreviousStep() { if (mCurrentStep == 1) return; SetCurrentStep(mCurrentStep - 1); } void lcModel::ShowNextStep() { if (mCurrentStep == LC_STEP_MAX) return; SetCurrentStep(mCurrentStep + 1); } lcStep lcModel::GetLastStep() const { lcStep Step = 1; for (const lcPiece* Piece : mPieces) Step = lcMax(Step, Piece->GetStepShow()); return Step; } void lcModel::InsertStep(lcStep Step) { for (lcPiece* Piece : mPieces) { Piece->InsertTime(Step, 1); if (Piece->IsSelected() && !Piece->IsVisible(mCurrentStep)) Piece->SetSelected(false); } for (lcCamera* Camera : mCameras) Camera->InsertTime(Step, 1); for (lcLight* Light : mLights) Light->InsertTime(Step, 1); SaveCheckpoint(tr("Inserting Step")); SetCurrentStep(mCurrentStep); } void lcModel::RemoveStep(lcStep Step) { for (lcPiece* Piece : mPieces) { Piece->RemoveTime(Step, 1); if (Piece->IsSelected() && !Piece->IsVisible(mCurrentStep)) Piece->SetSelected(false); } for (lcCamera* Camera : mCameras) Camera->RemoveTime(Step, 1); for (lcLight* Light : mLights) Light->RemoveTime(Step, 1); SaveCheckpoint(tr("Removing Step")); SetCurrentStep(mCurrentStep); } lcGroup* lcModel::AddGroup(const QString& Prefix, lcGroup* Parent) { lcGroup* Group = new lcGroup(); mGroups.Add(Group); Group->mName = GetGroupName(Prefix); Group->mGroup = Parent; return Group; } lcGroup* lcModel::GetGroup(const QString& Name, bool CreateIfMissing) { for (lcGroup* Group : mGroups) if (Group->mName == Name) return Group; if (CreateIfMissing) { lcGroup* Group = new lcGroup(); Group->mName = Name; mGroups.Add(Group); return Group; } return nullptr; } void lcModel::RemoveGroup(lcGroup* Group) { mGroups.Remove(Group); delete Group; } void lcModel::GroupSelection() { if (!AnyPiecesSelected()) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("No pieces selected.")); return; } lcQGroupDialog Dialog(gMainWindow, GetGroupName(tr("Group #"))); if (Dialog.exec() != QDialog::Accepted) return; lcGroup* NewGroup = GetGroup(Dialog.mName, true); for (lcPiece* Piece : mPieces) { if (Piece->IsSelected()) { lcGroup* Group = Piece->GetTopGroup(); if (!Group) Piece->SetGroup(NewGroup); else if (Group != NewGroup) Group->mGroup = NewGroup; } } SaveCheckpoint(tr("Grouping")); } void lcModel::UngroupSelection() { lcArray SelectedGroups; for (lcPiece* Piece : mPieces) { if (Piece->IsSelected()) { lcGroup* Group = Piece->GetTopGroup(); if (SelectedGroups.FindIndex(Group) == -1) { mGroups.Remove(Group); SelectedGroups.Add(Group); } } } for (lcPiece* Piece : mPieces) { lcGroup* Group = Piece->GetGroup(); if (SelectedGroups.FindIndex(Group) != -1) Piece->SetGroup(nullptr); } for (lcGroup* Group : mGroups) if (SelectedGroups.FindIndex(Group->mGroup) != -1) Group->mGroup = nullptr; SelectedGroups.DeleteAll(); RemoveEmptyGroups(); SaveCheckpoint(tr("Ungrouping")); } void lcModel::AddSelectedPiecesToGroup() { lcGroup* Group = nullptr; for (lcPiece* Piece : mPieces) { if (Piece->IsSelected()) { Group = Piece->GetTopGroup(); if (Group) break; } } if (Group) { for (lcPiece* Piece : mPieces) { if (Piece->IsFocused()) { Piece->SetGroup(Group); break; } } } RemoveEmptyGroups(); SaveCheckpoint(tr("Grouping")); } void lcModel::RemoveFocusPieceFromGroup() { for (lcPiece* Piece : mPieces) { if (Piece->IsFocused()) { Piece->SetGroup(nullptr); break; } } RemoveEmptyGroups(); SaveCheckpoint(tr("Ungrouping")); } void lcModel::ShowEditGroupsDialog() { QMap PieceParents; QMap GroupParents; for (lcPiece* Piece : mPieces) PieceParents[Piece] = Piece->GetGroup(); for (lcGroup* Group : mGroups) GroupParents[Group] = Group->mGroup; lcQEditGroupsDialog Dialog(gMainWindow, PieceParents, GroupParents, this); if (Dialog.exec() != QDialog::Accepted) return; bool Modified = Dialog.mNewGroups.isEmpty(); for (lcPiece* Piece : mPieces) { lcGroup* ParentGroup = Dialog.mPieceParents.value(Piece); if (ParentGroup != Piece->GetGroup()) { Piece->SetGroup(ParentGroup); Modified = true; } } for (lcGroup* Group : mGroups) { lcGroup* ParentGroup = Dialog.mGroupParents.value(Group); if (ParentGroup != Group->mGroup) { Group->mGroup = ParentGroup; Modified = true; } } if (Modified) { ClearSelection(true); SaveCheckpoint(tr("Editing Groups")); } } QString lcModel::GetGroupName(const QString& Prefix) { const int Length = Prefix.length(); int Max = 0; for (const lcGroup* Group : mGroups) { const QString& Name = Group->mName; if (Name.startsWith(Prefix)) { bool Ok = false; int GroupNumber = Name.mid(Length).toInt(&Ok); if (Ok && GroupNumber > Max) Max = GroupNumber; } } return Prefix + QString::number(Max + 1); } void lcModel::RemoveEmptyGroups() { bool Removed; do { Removed = false; for (int GroupIdx = 0; GroupIdx < mGroups.GetSize();) { lcGroup* Group = mGroups[GroupIdx]; int Ref = 0; for (lcPiece* Piece : mPieces) if (Piece->GetGroup() == Group) Ref++; for (int ParentIdx = 0; ParentIdx < mGroups.GetSize(); ParentIdx++) if (mGroups[ParentIdx]->mGroup == Group) Ref++; if (Ref > 1) { GroupIdx++; continue; } if (Ref != 0) { for (lcPiece* Piece : mPieces) { if (Piece->GetGroup() == Group) { Piece->SetGroup(Group->mGroup); break; } } for (int ParentIdx = 0; ParentIdx < mGroups.GetSize(); ParentIdx++) { if (mGroups[ParentIdx]->mGroup == Group) { mGroups[ParentIdx]->mGroup = Group->mGroup; break; } } } mGroups.RemoveIndex(GroupIdx); delete Group; Removed = true; } } while (Removed); } lcVector3 lcModel::SnapPosition(const lcVector3& Distance) const { lcVector3 NewDistance(Distance); float SnapXY = gMainWindow->GetMoveXYSnap(); if (SnapXY != 0.0f) { int i = (int)(NewDistance[0] / SnapXY); float Leftover = NewDistance[0] - (SnapXY * i); if (Leftover > SnapXY / 2) i++; else if (Leftover < -SnapXY / 2) i--; NewDistance[0] = SnapXY * i; i = (int)(NewDistance[1] / SnapXY); Leftover = NewDistance[1] - (SnapXY * i); if (Leftover > SnapXY / 2) i++; else if (Leftover < -SnapXY / 2) i--; NewDistance[1] = SnapXY * i; } float SnapZ = gMainWindow->GetMoveZSnap(); if (SnapZ != 0.0f) { int i = (int)(NewDistance[2] / SnapZ); const float Leftover = NewDistance[2] - (SnapZ * i); if (Leftover > SnapZ / 2) i++; else if (Leftover < -SnapZ / 2) i--; NewDistance[2] = SnapZ * i; } return NewDistance; } lcVector3 lcModel::SnapRotation(const lcVector3& Angles) const { const float AngleSnap = gMainWindow->GetAngleSnap(); lcVector3 NewAngles(Angles); if (AngleSnap != 0.0f) { int Snap[3]; for (int i = 0; i < 3; i++) Snap[i] = (int)(Angles[i] / AngleSnap); NewAngles = lcVector3((float)(AngleSnap * Snap[0]), (float)(AngleSnap * Snap[1]), (float)(AngleSnap * Snap[2])); } return NewAngles; } lcMatrix33 lcModel::GetRelativeRotation() const { if (gMainWindow->GetRelativeTransform()) { const lcObject* Focus = GetFocusObject(); if (Focus && Focus->IsPiece()) return ((lcPiece*)Focus)->GetRelativeRotation(); } return lcMatrix33Identity(); } void lcModel::AddPiece() { PieceInfo* CurPiece = gMainWindow->GetCurrentPieceInfo(); if (!CurPiece) return; lcPiece* Last = mPieces.IsEmpty() ? nullptr : mPieces[mPieces.GetSize() - 1]; for (lcPiece* Piece : mPieces) { if (Piece->IsFocused()) { Last = Piece; break; } } lcMatrix44 WorldMatrix; if (Last) { const lcBoundingBox& BoundingBox = Last->GetBoundingBox(); lcVector3 Dist(0, 0, BoundingBox.Max.z - BoundingBox.Min.z); Dist = SnapPosition(Dist); WorldMatrix = Last->mModelWorld; WorldMatrix.SetTranslation(lcMul31(Dist, Last->mModelWorld)); } else { const lcBoundingBox& BoundingBox = CurPiece->GetBoundingBox(); WorldMatrix = lcMatrix44Translation(lcVector3(0.0f, 0.0f, -BoundingBox.Min.z)); } lcPiece* Piece = new lcPiece(CurPiece); Piece->Initialize(WorldMatrix, mCurrentStep); Piece->SetColorIndex(gMainWindow->mColorIndex); AddPiece(Piece); gMainWindow->UpdateTimeline(false, false); ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION, false); SaveCheckpoint(tr("Adding Piece")); } void lcModel::AddPiece(lcPiece* Piece) { for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) { if (mPieces[PieceIdx]->GetStepShow() > Piece->GetStepShow()) { InsertPiece(Piece, PieceIdx); return; } } InsertPiece(Piece, mPieces.GetSize()); } void lcModel::InsertPiece(lcPiece* Piece, int Index) { const PieceInfo* Info = Piece->mPieceInfo; if (!Info->IsModel()) { const lcMesh* Mesh = Info->GetMesh(); if (Mesh && Mesh->mVertexCacheOffset == -1) lcGetPiecesLibrary()->mBuffersDirty = true; } mPieces.InsertAt(Index, Piece); } void lcModel::DeleteAllCameras() { if (mCameras.IsEmpty()) return; mCameras.DeleteAll(); gMainWindow->UpdateCameraMenu(); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); SaveCheckpoint(tr("Resetting Cameras")); } void lcModel::DeleteSelectedObjects() { if (RemoveSelectedObjects()) { if (!mIsPreview) { gMainWindow->UpdateTimeline(false, false); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); SaveCheckpoint(tr("Deleting")); } } } void lcModel::ResetSelectedPiecesPivotPoint() { for (lcPiece* Piece : mPieces) if (Piece->IsSelected()) Piece->ResetPivotPoint(); UpdateAllViews(); } void lcModel::RemoveSelectedPiecesKeyFrames() { for (lcPiece* Piece : mPieces) if (Piece->IsSelected()) Piece->RemoveKeyFrames(); for (lcCamera* Camera : mCameras) if (Camera->IsSelected()) Camera->RemoveKeyFrames(); for (lcLight* Light : mLights) if (Light->IsSelected()) Light->RemoveKeyFrames(); UpdateAllViews(); SaveCheckpoint(tr("Removing Key Frames")); } void lcModel::InsertControlPoint() { lcObject* Focus = GetFocusObject(); if (!Focus || !Focus->IsPiece()) return; lcPiece* Piece = (lcPiece*)Focus; lcVector3 Start, End; gMainWindow->GetActiveView()->GetRayUnderPointer(Start, End); if (Piece->InsertControlPoint(Start, End)) { SaveCheckpoint(tr("Modifying")); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } } void lcModel::RemoveFocusedControlPoint() { lcObject* Focus = GetFocusObject(); if (!Focus || !Focus->IsPiece()) return; lcPiece* Piece = (lcPiece*)Focus; if (Piece->RemoveFocusedControlPoint()) { SaveCheckpoint(tr("Modifying")); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } } void lcModel::ShowSelectedPiecesEarlier() { lcArray MovedPieces; for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); ) { lcPiece* Piece = mPieces[PieceIdx]; if (Piece->IsSelected()) { lcStep Step = Piece->GetStepShow(); if (Step > 1) { Step--; Piece->SetStepShow(Step); MovedPieces.Add(Piece); mPieces.RemoveIndex(PieceIdx); continue; } } PieceIdx++; } if (MovedPieces.IsEmpty()) return; for (int PieceIdx = 0; PieceIdx < MovedPieces.GetSize(); PieceIdx++) { lcPiece* Piece = MovedPieces[PieceIdx]; Piece->SetFileLine(-1); AddPiece(Piece); } SaveCheckpoint(tr("Modifying")); gMainWindow->UpdateTimeline(false, false); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } void lcModel::ShowSelectedPiecesLater() { lcArray MovedPieces; for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); ) { lcPiece* Piece = mPieces[PieceIdx]; if (Piece->IsSelected()) { lcStep Step = Piece->GetStepShow(); if (Step < LC_STEP_MAX) { Step++; Piece->SetStepShow(Step); if (!Piece->IsVisible(mCurrentStep)) Piece->SetSelected(false); MovedPieces.Add(Piece); mPieces.RemoveIndex(PieceIdx); continue; } } PieceIdx++; } if (MovedPieces.IsEmpty()) return; for (int PieceIdx = 0; PieceIdx < MovedPieces.GetSize(); PieceIdx++) { lcPiece* Piece = MovedPieces[PieceIdx]; Piece->SetFileLine(-1); AddPiece(Piece); } SaveCheckpoint(tr("Modifying")); gMainWindow->UpdateTimeline(false, false); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } void lcModel::SetPieceSteps(const QList>& PieceSteps) { if (PieceSteps.size() != mPieces.GetSize()) return; bool Modified = false; for (int PieceIdx = 0; PieceIdx < PieceSteps.size(); PieceIdx++) { const QPair& PieceStep = PieceSteps[PieceIdx]; lcPiece* Piece = mPieces[PieceIdx]; if (Piece != PieceStep.first || Piece->GetStepShow() != PieceStep.second) { Piece = PieceStep.first; const lcStep Step = PieceStep.second; mPieces[PieceIdx] = Piece; Piece->SetStepShow(Step); if (!Piece->IsVisible(mCurrentStep)) Piece->SetSelected(false); Modified = true; } } if (Modified) { SaveCheckpoint(tr("Modifying")); UpdateAllViews(); gMainWindow->UpdateTimeline(false, false); gMainWindow->UpdateSelectedObjects(true); } } void lcModel::RenamePiece(PieceInfo* Info) { for (lcPiece* Piece : mPieces) if (Piece->mPieceInfo == Info) Piece->UpdateID(); } void lcModel::MoveSelectionToModel(lcModel* Model) { if (!Model) return; lcArray Pieces; lcPiece* ModelPiece = nullptr; lcStep FirstStep = LC_STEP_MAX; lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); ) { lcPiece* Piece = mPieces[PieceIdx]; if (Piece->IsSelected()) { Piece->CompareBoundingBox(Min, Max); mPieces.RemoveIndex(PieceIdx); Piece->SetGroup(nullptr); // todo: copy groups Pieces.Add(Piece); FirstStep = qMin(FirstStep, Piece->GetStepShow()); if (!ModelPiece) { ModelPiece = new lcPiece(Model->mPieceInfo); ModelPiece->SetColorIndex(gDefaultColor); InsertPiece(ModelPiece, PieceIdx); PieceIdx++; } } else PieceIdx++; } lcVector3 ModelCenter = (Min + Max) / 2.0f; ModelCenter.z += (Min.z - Max.z) / 2.0f; for (int PieceIdx = 0; PieceIdx < Pieces.GetSize(); PieceIdx++) { lcPiece* Piece = Pieces[PieceIdx]; Piece->SetFileLine(-1); Piece->SetStepShow(Piece->GetStepShow() - FirstStep + 1); Piece->MoveSelected(Piece->GetStepShow(), false, -ModelCenter); Model->AddPiece(Piece); } std::vector UpdatedModels; Model->UpdatePieceInfo(UpdatedModels); if (ModelPiece) { ModelPiece->Initialize(lcMatrix44Translation(ModelCenter), FirstStep); ModelPiece->UpdatePosition(mCurrentStep); } SaveCheckpoint(tr("New Model")); gMainWindow->UpdateTimeline(false, false); ClearSelectionAndSetFocus(ModelPiece, LC_PIECE_SECTION_POSITION, false); } void lcModel::InlineSelectedModels() { lcArray NewPieces; for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); ) { lcPiece* Piece = mPieces[PieceIdx]; if (!Piece->IsSelected() || !Piece->mPieceInfo->IsModel()) { PieceIdx++; continue; } mPieces.RemoveIndex(PieceIdx); lcModel* Model = Piece->mPieceInfo->GetModel(); for (const lcPiece* ModelPiece : Model->mPieces) { lcPiece* NewPiece = new lcPiece(nullptr); // todo: recreate in groups in the current model int ColorIndex = ModelPiece->GetColorIndex(); if (ColorIndex == gDefaultColor) ColorIndex = Piece->GetColorIndex(); NewPiece->SetPieceInfo(ModelPiece->mPieceInfo, ModelPiece->GetID(), true); NewPiece->Initialize(lcMul(ModelPiece->mModelWorld, Piece->mModelWorld), Piece->GetStepShow()); NewPiece->SetColorIndex(ColorIndex); NewPiece->UpdatePosition(mCurrentStep); NewPieces.Add(NewPiece); InsertPiece(NewPiece, PieceIdx); PieceIdx++; } delete Piece; } if (!NewPieces.GetSize()) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("No models selected.")); return; } SaveCheckpoint(tr("Inlining")); gMainWindow->UpdateTimeline(false, false); SetSelectionAndFocus(NewPieces, nullptr, 0, false); } bool lcModel::RemoveSelectedObjects() { bool RemovedPiece = false; bool RemovedCamera = false; bool RemovedLight = false; for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); ) { lcPiece* Piece = mPieces[PieceIdx]; if (Piece->IsSelected()) { RemovedPiece = true; mPieces.Remove(Piece); delete Piece; } else PieceIdx++; } for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); ) { lcCamera* Camera = mCameras[CameraIdx]; if (Camera->IsSelected()) { std::vector Views = lcView::GetModelViews(this); for (lcView* View : Views) if (Camera == View->GetCamera()) View->SetCamera(Camera, true); RemovedCamera = true; mCameras.RemoveIndex(CameraIdx); delete Camera; } else CameraIdx++; } if (RemovedCamera) gMainWindow->UpdateCameraMenu(); for (int LightIdx = 0; LightIdx < mLights.GetSize(); ) { lcLight* Light = mLights[LightIdx]; if (Light->IsSelected()) { RemovedLight = true; mLights.RemoveIndex(LightIdx); delete Light; } else LightIdx++; } RemoveEmptyGroups(); return RemovedPiece || RemovedCamera || RemovedLight; } void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint) { bool Moved = false; lcMatrix33 RelativeRotation; if (AllowRelative) RelativeRotation = GetRelativeRotation(); else RelativeRotation = lcMatrix33Identity(); if (PieceDistance.LengthSquared() >= 0.001f) { lcVector3 TransformedPieceDistance = lcMul(PieceDistance, RelativeRotation); if (AlternateButtonDrag) { for (lcPiece* Piece : mPieces) { if (Piece->IsFocused()) { Piece->MovePivotPoint(TransformedPieceDistance); Moved = true; break; } } } else { for (lcPiece* Piece : mPieces) { if (Piece->IsSelected()) { if (gMainWindow->GetSeparateTransform()) TransformedPieceDistance = lcMul(PieceDistance, Piece->GetRelativeRotation()); Piece->MoveSelected(mCurrentStep, gMainWindow->GetAddKeys(), TransformedPieceDistance); Piece->UpdatePosition(mCurrentStep); Moved = true; } } } } if (ObjectDistance.LengthSquared() >= 0.001f && !AlternateButtonDrag) { const lcVector3 TransformedObjectDistance = lcMul(ObjectDistance, RelativeRotation); for (lcCamera* Camera : mCameras) { if (Camera->IsSelected()) { Camera->MoveSelected(mCurrentStep, gMainWindow->GetAddKeys(), TransformedObjectDistance); Camera->UpdatePosition(mCurrentStep); Moved = true; } } for (lcLight* Light : mLights) { if (Light->IsSelected()) { Light->MoveSelected(mCurrentStep, gMainWindow->GetAddKeys(), TransformedObjectDistance); Light->UpdatePosition(mCurrentStep); Moved = true; } } } if (Moved && Update) { UpdateAllViews(); if (Checkpoint) SaveCheckpoint(tr("Moving")); gMainWindow->UpdateSelectedObjects(false); } } void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint) { if (Angles.LengthSquared() < 0.001f) return; lcMatrix33 RotationMatrix = lcMatrix33Identity(); bool Rotated = false; if (Angles[0] != 0.0f) RotationMatrix = lcMul(lcMatrix33RotationX(Angles[0] * LC_DTOR), RotationMatrix); if (Angles[1] != 0.0f) RotationMatrix = lcMul(lcMatrix33RotationY(Angles[1] * LC_DTOR), RotationMatrix); if (Angles[2] != 0.0f) RotationMatrix = lcMul(lcMatrix33RotationZ(Angles[2] * LC_DTOR), RotationMatrix); if (RotatePivotPoint) { lcObject* Focus = GetFocusObject(); if (Focus && Focus->IsPiece()) { ((lcPiece*)Focus)->RotatePivotPoint(RotationMatrix); Rotated = true; } } else { if (!gMainWindow->GetSeparateTransform()) { lcVector3 Center; lcMatrix33 RelativeRotation; GetMoveRotateTransform(Center, RelativeRotation); lcMatrix33 WorldToFocusMatrix; if (Relative) { WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation); RotationMatrix = lcMul(RotationMatrix, RelativeRotation); } else WorldToFocusMatrix = lcMatrix33Identity(); for (lcPiece* Piece : mPieces) { if (!Piece->IsSelected()) continue; Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix); Piece->UpdatePosition(mCurrentStep); Rotated = true; } } else { for (lcPiece* Piece : mPieces) { if (!Piece->IsSelected()) continue; const lcVector3 Center = Piece->GetRotationCenter(); lcMatrix33 WorldToFocusMatrix; lcMatrix33 RelativeRotationMatrix; if (Relative) { const lcMatrix33 RelativeRotation = Piece->GetRelativeRotation(); WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation); RelativeRotationMatrix = lcMul(RotationMatrix, RelativeRotation); } else { WorldToFocusMatrix = lcMatrix33Identity(); RelativeRotationMatrix = RotationMatrix; } Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RelativeRotationMatrix, Center, WorldToFocusMatrix); Piece->UpdatePosition(mCurrentStep); Rotated = true; } } } if (Rotated && Update) { UpdateAllViews(); if (Checkpoint) SaveCheckpoint(tr("Rotating")); gMainWindow->UpdateSelectedObjects(false); } } void lcModel::ScaleSelectedPieces(const float Scale, bool Update, bool Checkpoint) { if (Scale < 0.001f) return; lcObject* Focus = GetFocusObject(); if (!Focus || !Focus->IsPiece()) return; lcPiece* Piece = (lcPiece*)Focus; const quint32 Section = Piece->GetFocusSection(); if (Section >= LC_PIECE_SECTION_CONTROL_POINT_FIRST && Section <= LC_PIECE_SECTION_CONTROL_POINT_LAST) { const int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST; Piece->SetControlPointScale(ControlPointIndex, Scale); if (Update) { UpdateAllViews(); if (Checkpoint) SaveCheckpoint(tr("Scaling")); gMainWindow->UpdateSelectedObjects(false); } } } void lcModel::TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform) { switch (TransformType) { case lcTransformType::AbsoluteTranslation: MoveSelectedObjects(Transform, false, false, true, true); break; case lcTransformType::RelativeTranslation: MoveSelectedObjects(Transform, true, false, true, true); break; case lcTransformType::AbsoluteRotation: RotateSelectedPieces(Transform, false, false, true, true); break; case lcTransformType::RelativeRotation: RotateSelectedPieces(Transform, true, false, true, true); break; case lcTransformType::Count: break; } } void lcModel::SetSelectedPiecesColorIndex(int ColorIndex) { bool Modified = false; for (lcPiece* Piece : mPieces) { if (Piece->IsSelected() && Piece->GetColorIndex() != ColorIndex) { Piece->SetColorIndex(ColorIndex); Modified = true; } } if (Modified) { SaveCheckpoint(tr("Painting")); gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); gMainWindow->UpdateTimeline(false, true); } } void lcModel::SetSelectedPiecesPieceInfo(PieceInfo* Info) { bool Modified = false; for (lcPiece* Piece : mPieces) { if (Piece->IsSelected() && Piece->mPieceInfo != Info) { lcPiecesLibrary* Library = lcGetPiecesLibrary(); Library->ReleasePieceInfo(Piece->mPieceInfo); Piece->SetPieceInfo(Info, QString(), true); Modified = true; } } if (Modified) { SaveCheckpoint(tr("Setting Part")); gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); gMainWindow->UpdateTimeline(false, true); } } void lcModel::SetSelectedPiecesStepShow(lcStep Step) { lcArray MovedPieces; bool SelectionChanged = false; for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); ) { lcPiece* Piece = mPieces[PieceIdx]; if (Piece->IsSelected() && Piece->GetStepShow() != Step) { Piece->SetStepShow(Step); if (!Piece->IsVisible(mCurrentStep)) { Piece->SetSelected(false); SelectionChanged = true; } MovedPieces.Add(Piece); mPieces.RemoveIndex(PieceIdx); continue; } PieceIdx++; } if (MovedPieces.IsEmpty()) return; for (int PieceIdx = 0; PieceIdx < MovedPieces.GetSize(); PieceIdx++) { lcPiece* Piece = MovedPieces[PieceIdx]; Piece->SetFileLine(-1); AddPiece(Piece); } SaveCheckpoint(tr("Showing Pieces")); UpdateAllViews(); gMainWindow->UpdateTimeline(false, false); gMainWindow->UpdateSelectedObjects(SelectionChanged); } void lcModel::SetSelectedPiecesStepHide(lcStep Step) { bool Modified = false; bool SelectionChanged = false; for (lcPiece* Piece : mPieces) { if (Piece->IsSelected() && Piece->GetStepHide() != Step) { Piece->SetStepHide(Step); if (!Piece->IsVisible(mCurrentStep)) { Piece->SetSelected(false); SelectionChanged = true; } Modified = true; } } if (Modified) { SaveCheckpoint(tr("Hiding Pieces")); UpdateAllViews(); gMainWindow->UpdateTimeline(false, false); gMainWindow->UpdateSelectedObjects(SelectionChanged); } } void lcModel::SetCameraOrthographic(lcCamera* Camera, bool Ortho) { if (Camera->IsOrtho() == Ortho) return; Camera->SetOrtho(Ortho); Camera->UpdatePosition(mCurrentStep); SaveCheckpoint(tr("Editing Camera")); UpdateAllViews(); gMainWindow->UpdatePerspective(); } void lcModel::SetCameraFOV(lcCamera* Camera, float FOV) { if (Camera->m_fovy == FOV) return; Camera->m_fovy = FOV; Camera->UpdatePosition(mCurrentStep); SaveCheckpoint(tr("Changing FOV")); UpdateAllViews(); } void lcModel::SetCameraZNear(lcCamera* Camera, float ZNear) { if (Camera->m_zNear == ZNear) return; Camera->m_zNear = ZNear; Camera->UpdatePosition(mCurrentStep); SaveCheckpoint(tr("Editing Camera")); UpdateAllViews(); } void lcModel::SetCameraZFar(lcCamera* Camera, float ZFar) { if (Camera->m_zFar == ZFar) return; Camera->m_zFar = ZFar; Camera->UpdatePosition(mCurrentStep); SaveCheckpoint(tr("Editing Camera")); UpdateAllViews(); } void lcModel::SetCameraName(lcCamera* Camera, const QString& Name) { if (Camera->GetName() == Name) return; Camera->SetName(Name); SaveCheckpoint(tr("Renaming Camera")); gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); gMainWindow->UpdateCameraMenu(); } bool lcModel::AnyPiecesSelected() const { for (const lcPiece* Piece : mPieces) if (Piece->IsSelected()) return true; return false; } bool lcModel::AnyObjectsSelected() const { for (const lcPiece* Piece : mPieces) if (Piece->IsSelected()) return true; for (const lcCamera* Camera : mCameras) if (Camera->IsSelected()) return true; for (const lcLight* Light : mLights) if (Light->IsSelected()) return true; return false; } lcObject* lcModel::GetFocusObject() const { for (lcPiece* Piece : mPieces) if (Piece->IsFocused()) return Piece; for (lcCamera* Camera : mCameras) if (Camera->IsFocused()) return Camera; for (lcLight* Light : mLights) if (Light->IsFocused()) return Light; return nullptr; } lcModel* lcModel::GetFirstSelectedSubmodel() const { for (const lcPiece* Piece : mPieces) if (Piece->IsSelected() && Piece->mPieceInfo->IsModel()) return Piece->mPieceInfo->GetModel(); return nullptr; } void lcModel::GetSubModels(lcArray& SubModels) const { for (const lcPiece* Piece : mPieces) { if (Piece->mPieceInfo->IsModel()) { lcModel* SubModel = Piece->mPieceInfo->GetModel(); if (SubModels.FindIndex(SubModel) == -1) SubModels.Add(SubModel); } } } bool lcModel::GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const { const bool Relative = gMainWindow->GetRelativeTransform(); int NumSelected = 0; Center = lcVector3(0.0f, 0.0f, 0.0f); RelativeRotation = lcMatrix33Identity(); for (const lcPiece* Piece : mPieces) { if (!Piece->IsSelected()) continue; if (Piece->IsFocused() && Relative) { Center = Piece->GetRotationCenter(); RelativeRotation = Piece->GetRelativeRotation(); return true; } Center += Piece->mModelWorld.GetTranslation(); NumSelected++; } for (const lcCamera* Camera : mCameras) { if (!Camera->IsSelected()) continue; if (Camera->IsFocused() && Relative) { Center = Camera->GetSectionPosition(Camera->GetFocusSection()); // RelativeRotation = Piece->GetRelativeRotation(); return true; } Center += Camera->GetSectionPosition(LC_CAMERA_SECTION_POSITION); Center += Camera->GetSectionPosition(LC_CAMERA_SECTION_TARGET); Center += Camera->GetSectionPosition(LC_CAMERA_SECTION_UPVECTOR); NumSelected += 3; } for (const lcLight* Light : mLights) { if (!Light->IsSelected()) continue; if (Light->IsFocused() && Relative) { Center = Light->GetSectionPosition(Light->GetFocusSection()); // RelativeRotation = Piece->GetRelativeRotation(); return true; } Center += Light->GetSectionPosition(LC_LIGHT_SECTION_POSITION); NumSelected++; if (Light->IsSpotLight() || Light->IsDirectionalLight()) { Center += Light->GetSectionPosition(LC_LIGHT_SECTION_TARGET); NumSelected++; } } if (NumSelected) { Center /= NumSelected; return true; } return false; } bool lcModel::GetPieceFocusOrSelectionCenter(lcVector3& Center) const { lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); lcPiece* Selected = nullptr; int NumSelected = 0; for (lcPiece* Piece : mPieces) { if (Piece->IsFocused()) { Center = Piece->mModelWorld.GetTranslation(); return true; } if (Piece->IsSelected()) { Piece->CompareBoundingBox(Min, Max); Selected = Piece; NumSelected++; } } if (NumSelected == 1) Center = Selected->mModelWorld.GetTranslation(); else if (NumSelected) Center = (Min + Max) / 2.0f; else Center = lcVector3(0.0f, 0.0f, 0.0f); return NumSelected != 0; } lcVector3 lcModel::GetSelectionOrModelCenter() const { lcVector3 Center; if (!GetSelectionCenter(Center)) { lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); if (GetVisiblePiecesBoundingBox(Min, Max)) Center = (Min + Max) / 2.0f; else Center = lcVector3(0.0f, 0.0f, 0.0f); } return Center; } bool lcModel::GetFocusPosition(lcVector3& Position) const { const lcObject* FocusObject = GetFocusObject(); if (FocusObject) { Position = FocusObject->GetSectionPosition(FocusObject->GetFocusSection()); return true; } else { Position = lcVector3(0.0f, 0.0f, 0.0f); return false; } } bool lcModel::GetSelectionCenter(lcVector3& Center) const { lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); lcPiece* SelectedPiece = nullptr; bool SinglePieceSelected = true; bool Selected = false; for (lcPiece* Piece : mPieces) { if (Piece->IsSelected()) { Piece->CompareBoundingBox(Min, Max); Selected = true; if (!SelectedPiece) SelectedPiece = Piece; else SinglePieceSelected = false; } } for (lcCamera* Camera : mCameras) { if (Camera->IsSelected()) { Camera->CompareBoundingBox(Min, Max); Selected = true; SinglePieceSelected = false; } } for (lcLight* Light : mLights) { if (Light->IsSelected()) { Light->CompareBoundingBox(Min, Max); Selected = true; SinglePieceSelected = false; } } if (SelectedPiece && SinglePieceSelected) Center = SelectedPiece->GetSectionPosition(LC_PIECE_SECTION_POSITION); else if (Selected) Center = (Min + Max) / 2.0f; else Center = lcVector3(0.0f, 0.0f, 0.0f); return Selected; } lcBoundingBox lcModel::GetAllPiecesBoundingBox() const { lcBoundingBox Box; if (!mPieces.IsEmpty()) { Box.Min = lcVector3(FLT_MAX, FLT_MAX, FLT_MAX); Box.Max = lcVector3(-FLT_MAX, -FLT_MAX, -FLT_MAX); for (const lcPiece* Piece : mPieces) Piece->CompareBoundingBox(Box.Min, Box.Max); } else Box.Min = Box.Max = lcVector3(0.0f, 0.0f, 0.0f); return Box; } bool lcModel::GetVisiblePiecesBoundingBox(lcVector3& Min, lcVector3& Max) const { bool Valid = false; Min = lcVector3(FLT_MAX, FLT_MAX, FLT_MAX); Max = lcVector3(-FLT_MAX, -FLT_MAX, -FLT_MAX); for (const lcPiece* Piece : mPieces) { if (Piece->IsVisible(mCurrentStep)) { Piece->CompareBoundingBox(Min, Max); Valid = true; } } return Valid; } std::vector lcModel::GetPiecesBoundingBoxPoints() const { std::vector Points; for (const lcPiece* Piece : mPieces) if (Piece->IsVisible(mCurrentStep)) Piece->SubModelAddBoundingBoxPoints(lcMatrix44Identity(), Points); return Points; } void lcModel::GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const { for (const lcPiece* Piece : mPieces) { if (!Piece->IsVisibleInSubModel()) continue; int ColorIndex = Piece->GetColorIndex(); if (ColorIndex == gDefaultColor) ColorIndex = DefaultColorIndex; Piece->mPieceInfo->GetPartsList(ColorIndex, ScanSubModels, AddSubModels, PartsList); } } void lcModel::GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList) const { for (const lcPiece* Piece : mPieces) { if (Piece->GetStepShow() != Step || Piece->IsHidden()) continue; int ColorIndex = Piece->GetColorIndex(); if (ColorIndex == gDefaultColor) ColorIndex = DefaultColorIndex; Piece->mPieceInfo->GetPartsList(ColorIndex, false, true, PartsList); } } void lcModel::GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector& ModelParts) const { for (const lcPiece* Piece : mPieces) Piece->GetModelParts(WorldMatrix, DefaultColorIndex, ModelParts); } void lcModel::GetSelectionInformation(int* Flags, lcArray& Selection, lcObject** Focus) const { *Flags = 0; *Focus = nullptr; if (mPieces.IsEmpty()) *Flags |= LC_SEL_NO_PIECES; else { lcGroup* Group = nullptr; bool First = true; for (lcPiece* Piece : mPieces) { if (Piece->IsSelected()) { Selection.Add(Piece); if (Piece->IsFocused()) *Focus = Piece; if (Piece->mPieceInfo->IsModel()) *Flags |= LC_SEL_MODEL_SELECTED; if (Piece->IsHidden()) *Flags |= LC_SEL_HIDDEN | LC_SEL_HIDDEN_SELECTED; else *Flags |= LC_SEL_VISIBLE_SELECTED; *Flags |= LC_SEL_PIECE | LC_SEL_SELECTED; if (Piece->CanAddControlPoint()) *Flags |= LC_SEL_CAN_ADD_CONTROL_POINT; if (Piece->CanRemoveControlPoint()) *Flags |= LC_SEL_CAN_REMOVE_CONTROL_POINT; if (Piece->GetGroup() != nullptr) { *Flags |= LC_SEL_GROUPED; if (Piece->IsFocused()) *Flags |= LC_SEL_FOCUS_GROUPED; } if (First) { Group = Piece->GetGroup(); First = false; } else { if (Group != Piece->GetGroup()) *Flags |= LC_SEL_CAN_GROUP; else if (Group == nullptr) *Flags |= LC_SEL_CAN_GROUP; } } else { *Flags |= LC_SEL_UNSELECTED; if (Piece->IsHidden()) *Flags |= LC_SEL_HIDDEN; } } } for (lcCamera* Camera : mCameras) { if (Camera->IsSelected()) { Selection.Add(Camera); *Flags |= LC_SEL_SELECTED; if (Camera->IsFocused()) *Focus = Camera; } } for (lcLight* Light : mLights) { if (Light->IsSelected()) { Selection.Add(Light); *Flags |= LC_SEL_SELECTED; if (Light->IsFocused()) *Focus = Light; } } } lcArray lcModel::GetSelectionModePieces(const lcPiece* SelectedPiece) const { const PieceInfo* Info = SelectedPiece->mPieceInfo; const int ColorIndex = SelectedPiece->GetColorIndex(); lcArray Pieces; switch (gMainWindow->GetSelectionMode()) { case lcSelectionMode::Single: break; case lcSelectionMode::Piece: for (lcPiece* Piece : mPieces) if (Piece->IsVisible(mCurrentStep) && Piece->mPieceInfo == Info && Piece != SelectedPiece) Pieces.Add(Piece); break; case lcSelectionMode::Color: for (lcPiece* Piece : mPieces) if (Piece->IsVisible(mCurrentStep) && Piece->GetColorIndex() == ColorIndex && Piece != SelectedPiece) Pieces.Add(Piece); break; case lcSelectionMode::PieceColor: for (lcPiece* Piece : mPieces) if (Piece->IsVisible(mCurrentStep) && Piece->mPieceInfo == Info && Piece->GetColorIndex() == ColorIndex && Piece != SelectedPiece) Pieces.Add(Piece); break; } return Pieces; } void lcModel::ClearSelection(bool UpdateInterface) { for (lcPiece* Piece : mPieces) Piece->SetSelected(false); for (lcCamera* Camera : mCameras) Camera->SetSelected(false); for (lcLight* Light : mLights) Light->SetSelected(false); if (UpdateInterface) { gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } } void lcModel::SelectGroup(lcGroup* TopGroup, bool Select) { if (!TopGroup) return; for (lcPiece* Piece : mPieces) if (!Piece->IsSelected() && Piece->IsVisible(mCurrentStep) && (Piece->GetTopGroup() == TopGroup)) Piece->SetSelected(Select); } void lcModel::FocusOrDeselectObject(const lcObjectSection& ObjectSection) { lcObject* FocusObject = GetFocusObject(); lcObject* Object = ObjectSection.Object; const quint32 Section = ObjectSection.Section; if (Object) { const bool WasSelected = Object->IsSelected(); if (!Object->IsFocused(Section)) { if (FocusObject) FocusObject->SetFocused(FocusObject->GetFocusSection(), false); Object->SetFocused(Section, true); } else Object->SetFocused(Section, false); const bool IsSelected = Object->IsSelected(); if (Object->IsPiece() && (WasSelected != IsSelected)) { lcPiece* Piece = (lcPiece*)Object; if (gMainWindow->GetSelectionMode() == lcSelectionMode::Single) SelectGroup(Piece->GetTopGroup(), IsSelected); else { lcArray Pieces = GetSelectionModePieces(Piece); AddToSelection(Pieces, false, false); } } } else { if (FocusObject) FocusObject->SetFocused(FocusObject->GetFocusSection(), false); } gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } void lcModel::ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, bool EnableSelectionMode) { ClearSelection(false); if (Object) { Object->SetFocused(Section, true); if (Object->IsPiece()) { SelectGroup(((lcPiece*)Object)->GetTopGroup(), true); if (EnableSelectionMode) { lcArray Pieces = GetSelectionModePieces((lcPiece*)Object); AddToSelection(Pieces, false, false); } } } gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } void lcModel::ClearSelectionAndSetFocus(const lcObjectSection& ObjectSection, bool EnableSelectionMode) { ClearSelectionAndSetFocus(ObjectSection.Object, ObjectSection.Section, EnableSelectionMode); } void lcModel::SetSelectionAndFocus(const lcArray& Selection, lcObject* Focus, quint32 Section, bool EnableSelectionMode) { ClearSelection(false); if (Focus) { Focus->SetFocused(Section, true); if (Focus->IsPiece()) { SelectGroup(((lcPiece*)Focus)->GetTopGroup(), true); if (EnableSelectionMode) { lcArray Pieces = GetSelectionModePieces((lcPiece*)Focus); AddToSelection(Pieces, false, false); } } } AddToSelection(Selection, EnableSelectionMode, true); } void lcModel::AddToSelection(const lcArray& Objects, bool EnableSelectionMode, bool UpdateInterface) { for (lcObject* Object : Objects) { const bool WasSelected = Object->IsSelected(); Object->SetSelected(true); if (Object->IsPiece()) { if (!WasSelected) SelectGroup(((lcPiece*)Object)->GetTopGroup(), true); if (EnableSelectionMode) { lcArray Pieces = GetSelectionModePieces((lcPiece*)Object); AddToSelection(Pieces, false, false); } } } if (UpdateInterface) { gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } } void lcModel::RemoveFromSelection(const lcArray& Objects) { for (lcObject* SelectedObject : Objects) { const bool WasSelected = SelectedObject->IsSelected(); SelectedObject->SetSelected(false); if (WasSelected && SelectedObject->IsPiece()) { lcPiece* Piece = (lcPiece*)SelectedObject; if (gMainWindow->GetSelectionMode() == lcSelectionMode::Single) SelectGroup(Piece->GetTopGroup(), false); else { lcArray Pieces = GetSelectionModePieces(Piece); for (lcObject* Object : Pieces) { if (Object->IsSelected()) { Object->SetSelected(false); SelectGroup(((lcPiece*)Object)->GetTopGroup(), false); } } } } } gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } void lcModel::RemoveFromSelection(const lcObjectSection& ObjectSection) { lcObject* SelectedObject = ObjectSection.Object; if (!SelectedObject) return; const bool WasSelected = SelectedObject->IsSelected(); if (SelectedObject->IsFocused(ObjectSection.Section)) SelectedObject->SetSelected(ObjectSection.Section, false); else SelectedObject->SetSelected(false); if (SelectedObject->IsPiece() && WasSelected) { lcPiece* Piece = (lcPiece*)SelectedObject; if (gMainWindow->GetSelectionMode() == lcSelectionMode::Single) SelectGroup(Piece->GetTopGroup(), false); else { lcArray Pieces = GetSelectionModePieces(Piece); for (lcObject* Object : Pieces) { if (Object->IsSelected()) { Object->SetSelected(false); SelectGroup(((lcPiece*)Object)->GetTopGroup(), false); } } } } gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } void lcModel::SelectAllPieces() { for (lcPiece* Piece : mPieces) if (Piece->IsVisible(mCurrentStep)) Piece->SetSelected(true); if (!mIsPreview) gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } void lcModel::InvertSelection() { for (lcPiece* Piece : mPieces) if (Piece->IsVisible(mCurrentStep)) Piece->SetSelected(!Piece->IsSelected()); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); } void lcModel::HideSelectedPieces() { bool Modified = false; for (lcPiece* Piece : mPieces) { if (Piece->IsSelected()) { Piece->SetHidden(true); Piece->SetSelected(false); Modified = true; } } if (!Modified) return; gMainWindow->UpdateTimeline(false, true); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); SaveCheckpoint(tr("Hide")); } void lcModel::HideUnselectedPieces() { bool Modified = false; for (lcPiece* Piece : mPieces) { if (!Piece->IsSelected()) { Piece->SetHidden(true); Modified = true; } } if (!Modified) return; gMainWindow->UpdateTimeline(false, true); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); SaveCheckpoint(tr("Hide")); } void lcModel::UnhideSelectedPieces() { bool Modified = false; for (lcPiece* Piece : mPieces) { if (Piece->IsSelected() && Piece->IsHidden()) { Piece->SetHidden(false); Modified = true; } } if (!Modified) return; gMainWindow->UpdateTimeline(false, true); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); SaveCheckpoint(tr("Unhide")); } void lcModel::UnhideAllPieces() { bool Modified = false; for (lcPiece* Piece : mPieces) { if (Piece->IsHidden()) { Piece->SetHidden(false); Modified = true; } } if (!Modified) return; gMainWindow->UpdateTimeline(false, true); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); SaveCheckpoint(tr("Unhide")); } void lcModel::FindReplacePiece(bool SearchForward, bool FindAll) { if (mPieces.IsEmpty()) return; auto PieceMatches = [](const lcPiece* Piece) { const lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); if (Params.FindInfo && Params.FindInfo != Piece->mPieceInfo) return false; if (!Params.FindString.isEmpty() && !strcasestr(Piece->mPieceInfo->m_strDescription, Params.FindString.toLatin1())) return false; return (lcGetColorCode(Params.FindColorIndex) == LC_COLOR_NOCOLOR) || (Piece->GetColorIndex() == Params.FindColorIndex); }; const lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); int StartIdx = mPieces.GetSize() - 1; for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) { lcPiece* Piece = mPieces[PieceIdx]; if (Piece->IsFocused() && Piece->IsVisible(mCurrentStep)) { if (PieceMatches(Piece)) { const bool ReplaceColor = lcGetColorCode(Params.FindColorIndex) != LC_COLOR_NOCOLOR; if (ReplaceColor) Piece->SetColorIndex(Params.ReplaceColorIndex); if (Params.ReplacePieceInfo) Piece->SetPieceInfo(Params.ReplacePieceInfo, QString(), true); if (ReplaceColor || Params.ReplacePieceInfo) { SaveCheckpoint(tr("Replacing Part")); gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); gMainWindow->UpdateTimeline(false, true); } } StartIdx = PieceIdx; break; } } int CurrentIdx = StartIdx; lcPiece* Focus = nullptr; lcArray Selection; for (;;) { if (SearchForward) CurrentIdx++; else CurrentIdx--; if (CurrentIdx < 0) CurrentIdx = mPieces.GetSize() - 1; else if (CurrentIdx >= mPieces.GetSize()) CurrentIdx = 0; lcPiece* Current = mPieces[CurrentIdx]; if (!Current->IsVisible(mCurrentStep)) continue; if (PieceMatches(Current)) { if (FindAll) Selection.Add(Current); else { Focus = Current; break; } } if (CurrentIdx == StartIdx) break; } if (FindAll) SetSelectionAndFocus(Selection, nullptr, 0, false); else ClearSelectionAndSetFocus(Focus, LC_PIECE_SECTION_POSITION, false); } void lcModel::UndoAction() { if (mUndoHistory.size() < 2) return; lcModelHistoryEntry* Undo = mUndoHistory.front(); mUndoHistory.erase(mUndoHistory.begin()); mRedoHistory.insert(mRedoHistory.begin(), Undo); LoadCheckPoint(mUndoHistory[0]); gMainWindow->UpdateModified(IsModified()); gMainWindow->UpdateUndoRedo(mUndoHistory.size() > 1 ? mUndoHistory[0]->Description : nullptr, !mRedoHistory.empty() ? mRedoHistory[0]->Description : nullptr); } void lcModel::RedoAction() { if (mRedoHistory.empty()) return; lcModelHistoryEntry* Redo = mRedoHistory.front(); mRedoHistory.erase(mRedoHistory.begin()); mUndoHistory.insert(mUndoHistory.begin(), Redo); LoadCheckPoint(Redo); gMainWindow->UpdateModified(IsModified()); gMainWindow->UpdateUndoRedo(mUndoHistory.size() > 1 ? mUndoHistory[0]->Description : nullptr, !mRedoHistory.empty() ? mRedoHistory[0]->Description : nullptr); } void lcModel::BeginMouseTool() { mMouseToolDistance = lcVector3(0.0f, 0.0f, 0.0f); } void lcModel::EndMouseTool(lcTool Tool, bool Accept) { if (!Accept) { if (!mUndoHistory.empty()) LoadCheckPoint(mUndoHistory.front()); return; } switch (Tool) { case lcTool::Insert: case lcTool::Light: break; case lcTool::SpotLight: SaveCheckpoint(tr("New SpotLight")); break; case lcTool::Camera: gMainWindow->UpdateCameraMenu(); SaveCheckpoint(tr("New Camera")); break; case lcTool::Select: break; case lcTool::Move: SaveCheckpoint(tr("Move")); break; case lcTool::Rotate: SaveCheckpoint(tr("Rotate")); break; case lcTool::Eraser: case lcTool::Paint: case lcTool::ColorPicker: break; case lcTool::Zoom: if (!gMainWindow->GetActiveView()->GetCamera()->IsSimple()) SaveCheckpoint(tr("Zoom")); break; case lcTool::Pan: if (!gMainWindow->GetActiveView()->GetCamera()->IsSimple()) SaveCheckpoint(tr("Pan")); break; case lcTool::RotateView: if (!gMainWindow->GetActiveView()->GetCamera()->IsSimple()) SaveCheckpoint(tr("Orbit")); break; case lcTool::Roll: if (!gMainWindow->GetActiveView()->GetCamera()->IsSimple()) SaveCheckpoint(tr("Roll")); break; case lcTool::ZoomRegion: break; case lcTool::Count: break; } } void lcModel::InsertPieceToolClicked(const lcMatrix44& WorldMatrix) { lcPiece* Piece = new lcPiece(gMainWindow->GetCurrentPieceInfo()); Piece->Initialize(WorldMatrix, mCurrentStep); Piece->SetColorIndex(gMainWindow->mColorIndex); Piece->UpdatePosition(mCurrentStep); AddPiece(Piece); gMainWindow->UpdateTimeline(false, false); ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION, false); SaveCheckpoint(tr("Insert")); } void lcModel::PointLightToolClicked(const lcVector3& Position) { lcLight* Light = new lcLight(Position[0], Position[1], Position[2]); Light->CreateName(mLights); mLights.Add(Light); ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_POSITION, false); SaveCheckpoint(tr("New Light")); } void lcModel::BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target) { lcLight* Light = new lcLight(Position[0], Position[1], Position[2], Target[0], Target[1], Target[2]); mLights.Add(Light); mMouseToolDistance = Target; ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_TARGET, false); } void lcModel::UpdateSpotLightTool(const lcVector3& Position) { lcLight* Light = mLights[mLights.GetSize() - 1]; Light->MoveSelected(1, false, Position - mMouseToolDistance); Light->UpdatePosition(1); mMouseToolDistance = Position; gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); } void lcModel::BeginCameraTool(const lcVector3& Position, const lcVector3& Target) { lcCamera* Camera = new lcCamera(Position[0], Position[1], Position[2], Target[0], Target[1], Target[2]); Camera->CreateName(mCameras); mCameras.Add(Camera); mMouseToolDistance = Position; ClearSelectionAndSetFocus(Camera, LC_CAMERA_SECTION_TARGET, false); } void lcModel::UpdateCameraTool(const lcVector3& Position) { lcCamera* Camera = mCameras[mCameras.GetSize() - 1]; Camera->MoveSelected(1, false, Position - mMouseToolDistance); Camera->UpdatePosition(1); mMouseToolDistance = Position; gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); } void lcModel::UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag) { const lcVector3 PieceDistance = SnapPosition(Distance) - SnapPosition(mMouseToolDistance); const lcVector3 ObjectDistance = Distance - mMouseToolDistance; MoveSelectedObjects(PieceDistance, ObjectDistance, AllowRelative, AlternateButtonDrag, true, false); mMouseToolDistance = Distance; gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); } void lcModel::UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag) { const lcVector3 Delta = SnapRotation(Angles) - SnapRotation(mMouseToolDistance); RotateSelectedPieces(Delta, true, AlternateButtonDrag, false, false); mMouseToolDistance = Angles; gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); } void lcModel::UpdateScaleTool(const float Scale) { ScaleSelectedPieces(Scale, true, false); gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); } void lcModel::EraserToolClicked(lcObject* Object) { if (!Object) return; switch (Object->GetType()) { case lcObjectType::Piece: mPieces.Remove((lcPiece*)Object); RemoveEmptyGroups(); break; case lcObjectType::Camera: { std::vector Views = lcView::GetModelViews(this); for (lcView* View : Views) { lcCamera* Camera = View->GetCamera(); if (Camera == Object) View->SetCamera(Camera, true); } mCameras.Remove((lcCamera*)Object); gMainWindow->UpdateCameraMenu(); } break; case lcObjectType::Light: mLights.Remove((lcLight*)Object); break; } delete Object; gMainWindow->UpdateTimeline(false, false); gMainWindow->UpdateSelectedObjects(true); UpdateAllViews(); SaveCheckpoint(tr("Deleting")); } void lcModel::PaintToolClicked(lcObject* Object) { if (!Object || !Object->IsPiece()) return; lcPiece* Piece = (lcPiece*)Object; if (Piece->GetColorIndex() != gMainWindow->mColorIndex) { Piece->SetColorIndex(gMainWindow->mColorIndex); SaveCheckpoint(tr("Painting")); gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); gMainWindow->UpdateTimeline(false, true); } } void lcModel::ColorPickerToolClicked(const lcObject* Object) { if (!Object || !Object->IsPiece()) return; const lcPiece* Piece = (lcPiece*)Object; gMainWindow->SetColorIndex(Piece->GetColorIndex()); } void lcModel::UpdateZoomTool(lcCamera* Camera, float Mouse) { Camera->Zoom(Mouse - mMouseToolDistance.x, mCurrentStep, gMainWindow->GetAddKeys()); mMouseToolDistance.x = Mouse; UpdateAllViews(); } void lcModel::UpdatePanTool(lcCamera* Camera, const lcVector3& Distance) { Camera->Pan(Distance, mCurrentStep, gMainWindow->GetAddKeys()); UpdateAllViews(); } void lcModel::UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY) { lcVector3 Center; GetSelectionCenter(Center); Camera->Orbit(MouseX - mMouseToolDistance.x, MouseY - mMouseToolDistance.y, Center, mCurrentStep, gMainWindow->GetAddKeys()); mMouseToolDistance.x = MouseX; mMouseToolDistance.y = MouseY; UpdateAllViews(); } void lcModel::UpdateRollTool(lcCamera* Camera, float Mouse) { Camera->Roll(Mouse - mMouseToolDistance.x, mCurrentStep, gMainWindow->GetAddKeys()); mMouseToolDistance.x = Mouse; UpdateAllViews(); } void lcModel::ZoomRegionToolClicked(lcCamera* Camera, float AspectRatio, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners) { Camera->ZoomRegion(AspectRatio, Position, TargetPosition, Corners, mCurrentStep, gMainWindow->GetAddKeys()); gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); if (!Camera->IsSimple()) SaveCheckpoint(tr("Zoom")); } void lcModel::LookAt(lcCamera* Camera) { lcVector3 Center; if (!GetSelectionCenter(Center)) { lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); if (GetVisiblePiecesBoundingBox(Min, Max)) Center = (Min + Max) / 2.0f; else Center = lcVector3(0.0f, 0.0f, 0.0f); } Camera->Center(Center, mCurrentStep, gMainWindow->GetAddKeys()); gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); if (!Camera->IsSimple()) SaveCheckpoint(tr("Look At")); } void lcModel::MoveCamera(lcCamera* Camera, const lcVector3& Direction) { Camera->MoveRelative(Direction, mCurrentStep, gMainWindow->GetAddKeys()); gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); if (!Camera->IsSimple()) SaveCheckpoint(tr("Moving Camera")); } void lcModel::ZoomExtents(lcCamera* Camera, float Aspect) { std::vector Points = GetPiecesBoundingBoxPoints(); if (Points.empty()) return; lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); for (const lcVector3& Point : Points) { Min = lcMin(Point, Min); Max = lcMax(Point, Max); } const lcVector3 Center = (Min + Max) / 2.0f; Camera->ZoomExtents(Aspect, Center, Points, mCurrentStep, gMainWindow ? gMainWindow->GetAddKeys() : false); if (!mIsPreview && gMainWindow) gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); if (!Camera->IsSimple()) SaveCheckpoint(tr("Zoom")); } void lcModel::Zoom(lcCamera* Camera, float Amount) { Camera->Zoom(Amount, mCurrentStep, gMainWindow->GetAddKeys()); if (!mIsPreview) gMainWindow->UpdateSelectedObjects(false); UpdateAllViews(); if (!Camera->IsSimple()) SaveCheckpoint(tr("Zoom")); } void lcModel::ShowPropertiesDialog() { lcPropertiesDialogOptions Options; Options.Properties = mProperties; Options.BoundingBox = GetAllPiecesBoundingBox(); GetPartsList(gDefaultColor, true, false, Options.PartsList); lcQPropertiesDialog Dialog(gMainWindow, &Options); if (Dialog.exec() != QDialog::Accepted) return; if (mProperties == Options.Properties) return; mProperties = Options.Properties; gMainWindow->GetPreviewWidget()->UpdatePreview(); SaveCheckpoint(tr("Changing Properties")); } void lcModel::ShowSelectByNameDialog() { if (mPieces.IsEmpty() && mCameras.IsEmpty() && mLights.IsEmpty()) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to select.")); return; } lcQSelectDialog Dialog(gMainWindow, this); if (Dialog.exec() != QDialog::Accepted) return; SetSelectionAndFocus(Dialog.mObjects, nullptr, 0, false); } void lcModel::ShowArrayDialog() { lcVector3 Center; if (!GetPieceFocusOrSelectionCenter(Center)) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("No pieces selected.")); return; } lcQArrayDialog Dialog(gMainWindow); if (Dialog.exec() != QDialog::Accepted) return; if (Dialog.mCounts[0] * Dialog.mCounts[1] * Dialog.mCounts[2] < 2) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Array only has 1 element or less, no pieces added.")); return; } lcArray NewPieces; for (int Step1 = 0; Step1 < Dialog.mCounts[0]; Step1++) { for (int Step2 = 0; Step2 < Dialog.mCounts[1]; Step2++) { for (int Step3 = (Step1 == 0 && Step2 == 0) ? 1 : 0; Step3 < Dialog.mCounts[2]; Step3++) { lcMatrix44 ModelWorld; lcVector3 Position; lcVector3 RotationAngles = Dialog.mRotations[0] * Step1 + Dialog.mRotations[1] * Step2 + Dialog.mRotations[2] * Step3; const lcVector3 Offset = Dialog.mOffsets[0] * Step1 + Dialog.mOffsets[1] * Step2 + Dialog.mOffsets[2] * Step3; for (lcPiece* Piece : mPieces) { if (!Piece->IsSelected()) continue; ModelWorld = Piece->mModelWorld; ModelWorld.r[3] -= lcVector4(Center, 0.0f); ModelWorld = lcMul(ModelWorld, lcMatrix44RotationX(RotationAngles[0] * LC_DTOR)); ModelWorld = lcMul(ModelWorld, lcMatrix44RotationY(RotationAngles[1] * LC_DTOR)); ModelWorld = lcMul(ModelWorld, lcMatrix44RotationZ(RotationAngles[2] * LC_DTOR)); ModelWorld.r[3] += lcVector4(Center, 0.0f); Position = lcVector3(ModelWorld.r[3].x, ModelWorld.r[3].y, ModelWorld.r[3].z); ModelWorld.SetTranslation(Position + Offset); lcPiece* NewPiece = new lcPiece(nullptr); NewPiece->SetPieceInfo(Piece->mPieceInfo, Piece->GetID(), true); NewPiece->Initialize(ModelWorld, mCurrentStep); NewPiece->SetColorIndex(Piece->GetColorIndex()); NewPieces.Add(NewPiece); } } } } for (int PieceIdx = 0; PieceIdx < NewPieces.GetSize(); PieceIdx++) { lcPiece* Piece = (lcPiece*)NewPieces[PieceIdx]; Piece->UpdatePosition(mCurrentStep); AddPiece(Piece); } AddToSelection(NewPieces, false, true); gMainWindow->UpdateTimeline(false, false); SaveCheckpoint(tr("Array")); } void lcModel::ShowMinifigDialog() { lcMinifigDialog Dialog(gMainWindow); if (Dialog.exec() != QDialog::Accepted) return; gMainWindow->GetActiveView()->MakeCurrent(); lcGroup* Group = AddGroup(tr("Minifig #"), nullptr); lcArray Pieces(LC_MFW_NUMITEMS); lcMinifig& Minifig = Dialog.mMinifigWizard->mMinifig; for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++) { if (Minifig.Parts[PartIdx] == nullptr) continue; lcPiece* Piece = new lcPiece(Minifig.Parts[PartIdx]); Piece->Initialize(Minifig.Matrices[PartIdx], mCurrentStep); Piece->SetColorIndex(Minifig.Colors[PartIdx]); Piece->SetGroup(Group); AddPiece(Piece); Piece->UpdatePosition(mCurrentStep); Pieces.Add(Piece); } SetSelectionAndFocus(Pieces, nullptr, 0, false); gMainWindow->UpdateTimeline(false, false); SaveCheckpoint(tr("Minifig")); } void lcModel::SetMinifig(const lcMinifig& Minifig) { DeleteModel(); lcArray Pieces(LC_MFW_NUMITEMS); for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++) { if (!Minifig.Parts[PartIdx]) continue; lcPiece* Piece = new lcPiece(Minifig.Parts[PartIdx]); Piece->Initialize(Minifig.Matrices[PartIdx], 1); Piece->SetColorIndex(Minifig.Colors[PartIdx]); AddPiece(Piece); Piece->UpdatePosition(1); Pieces.Add(Piece); } SetSelectionAndFocus(Pieces, nullptr, 0, false); } void lcModel::SetPreviewPieceInfo(PieceInfo* Info, int ColorIndex) { DeleteModel(); lcPiece* Piece = new lcPiece(Info); Piece->Initialize(lcMatrix44Identity(), 1); Piece->SetColorIndex(ColorIndex); AddPiece(Piece); Piece->UpdatePosition(1); SaveCheckpoint(QString()); } void lcModel::UpdateInterface() { if (!gMainWindow) return; gMainWindow->UpdateTimeline(true, false); gMainWindow->UpdateUndoRedo(mUndoHistory.size() > 1 ? mUndoHistory[0]->Description : nullptr, !mRedoHistory.empty() ? mRedoHistory[0]->Description : nullptr); gMainWindow->UpdatePaste(!gApplication->mClipboard.isEmpty()); gMainWindow->UpdateCategories(); gMainWindow->UpdateTitle(); gMainWindow->SetTool(gMainWindow->GetTool()); gMainWindow->UpdateSelectedObjects(true); gMainWindow->SetTransformType(gMainWindow->GetTransformType()); gMainWindow->UpdateLockSnap(); gMainWindow->UpdateSnap(); gMainWindow->UpdateCameraMenu(); gMainWindow->UpdateModels(); gMainWindow->UpdatePerspective(); gMainWindow->UpdateShadingMode(); gMainWindow->UpdateCurrentStep(); gMainWindow->UpdateSelectionMode(); } leocad-23.03/common/lc_model.h000066400000000000000000000305551440571307300162030ustar00rootroot00000000000000#pragma once #include "lc_math.h" #include "lc_commands.h" #include "lc_array.h" #define LC_SEL_NO_PIECES 0x0001 // No pieces in model #define LC_SEL_PIECE 0x0002 // At last 1 piece selected #define LC_SEL_SELECTED 0x0004 // At last 1 object selected #define LC_SEL_UNSELECTED 0x0008 // At least 1 piece unselected #define LC_SEL_HIDDEN 0x0010 // At least one piece hidden #define LC_SEL_HIDDEN_SELECTED 0x0020 // At least one piece selected is hidden #define LC_SEL_VISIBLE_SELECTED 0x0040 // At least one piece selected is not hidden #define LC_SEL_GROUPED 0x0080 // At least one piece selected is grouped #define LC_SEL_FOCUS_GROUPED 0x0100 // Focused piece is grouped #define LC_SEL_CAN_GROUP 0x0200 // Can make a new group #define LC_SEL_MODEL_SELECTED 0x0400 // At least one model reference is selected #define LC_SEL_CAN_ADD_CONTROL_POINT 0x0800 // Can add control points to focused piece #define LC_SEL_CAN_REMOVE_CONTROL_POINT 0x1000 // Can remove control points from focused piece enum class lcSelectionMode { Single, Piece, Color, PieceColor }; enum class lcTransformType { First, AbsoluteTranslation = First, RelativeTranslation, AbsoluteRotation, RelativeRotation, Count }; class lcModelProperties { public: void LoadDefaults(); void SaveDefaults(); bool operator==(const lcModelProperties& Properties) const { if (mFileName != Properties.mFileName || mModelName != Properties.mModelName || mAuthor != Properties.mAuthor || mDescription != Properties.mDescription || mComments != Properties.mComments) return false; if (mAmbientColor != Properties.mAmbientColor) return false; return true; } void SaveLDraw(QTextStream& Stream) const; bool ParseLDrawHeader(QString Line, bool FirstLine); void ParseLDrawLine(QTextStream& Stream); QString mFileName; QString mDescription; QString mModelName; QString mAuthor; QString mComments; lcVector3 mAmbientColor; }; struct lcModelHistoryEntry { QByteArray File; QString Description; }; class lcModel { public: lcModel(const QString& FileName, Project* Project, bool Preview); ~lcModel(); lcModel(const lcModel&) = delete; lcModel(lcModel&&) = delete; lcModel& operator=(const lcModel&) = delete; lcModel& operator=(lcModel&&) = delete; Project* GetProject() const { return mProject; } bool IsModified() const { return mSavedHistory != mUndoHistory[0]; } bool IsActive() const { return mActive; } bool GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& ParentWorldMatrix) const; bool IncludesModel(const lcModel* Model) const; void CreatePieceInfo(Project* Project); void UpdatePieceInfo(std::vector& UpdatedModels); void UpdateMesh(); void UpdateAllViews() const; PieceInfo* GetPieceInfo() const { return mPieceInfo; } const lcArray& GetPieces() const { return mPieces; } const lcArray& GetCameras() const { return mCameras; } const lcArray& GetLights() const { return mLights; } const lcArray& GetGroups() const { return mGroups; } const lcModelProperties& GetProperties() const { return mProperties; } void SetFileName(const QString& FileName) { if (mProperties.mModelName == mProperties.mFileName) mProperties.mModelName = FileName; mProperties.mFileName = FileName; } const QString& GetFileName() const { return mProperties.mFileName; } void SetDescription(const QString& Description) { mProperties.mDescription = Description; } const QStringList& GetFileLines() const { return mFileLines; } lcStep GetLastStep() const; lcStep GetCurrentStep() const { return mCurrentStep; } void SetActive(bool Active); void CalculateStep(lcStep Step); void SetCurrentStep(lcStep Step); void SetTemporaryStep(lcStep Step) { mCurrentStep = Step; CalculateStep(Step); } void ShowFirstStep(); void ShowLastStep(); void ShowPreviousStep(); void ShowNextStep(); void InsertStep(lcStep Step); void RemoveStep(lcStep Step); void AddPiece(); void DeleteAllCameras(); void DeleteSelectedObjects(); void ResetSelectedPiecesPivotPoint(); void RemoveSelectedPiecesKeyFrames(); void InsertControlPoint(); void RemoveFocusedControlPoint(); void ShowSelectedPiecesEarlier(); void ShowSelectedPiecesLater(); void SetPieceSteps(const QList>& PieceSteps); void RenamePiece(PieceInfo* Info); void MoveSelectionToModel(lcModel* Model); void InlineSelectedModels(); lcGroup* AddGroup(const QString& Prefix, lcGroup* Parent); lcGroup* GetGroup(const QString& Name, bool CreateIfMissing); void RemoveGroup(lcGroup* Group); void GroupSelection(); void UngroupSelection(); void AddSelectedPiecesToGroup(); void RemoveFocusPieceFromGroup(); void ShowEditGroupsDialog(); void SaveLDraw(QTextStream& Stream, bool SelectedOnly) const; void LoadLDraw(QIODevice& Device, Project* Project); bool LoadBinary(lcFile* File); bool LoadLDD(const QString& FileData); bool LoadInventory(const QByteArray& Inventory); int SplitMPD(QIODevice& Device); void Merge(lcModel* Other); void SetSaved() { if (mUndoHistory.empty()) SaveCheckpoint(QString()); if (!mIsPreview) mSavedHistory = mUndoHistory[0]; } void SetMinifig(const lcMinifig& Minifig); void SetPreviewPieceInfo(PieceInfo* Info, int ColorIndex); void Cut(); void Copy(); void Paste(bool PasteToCurrentStep); void DuplicateSelectedPieces(); void PaintSelectedPieces(); void GetScene(lcScene* Scene, const lcCamera* ViewCamera, bool AllowHighlight, bool AllowFade) const; void AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const; QImage GetStepImage(bool Zoom, int Width, int Height, lcStep Step); QImage GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundColor, QFont Font, QColor TextColor) const; void SaveStepImages(const QString& BaseName, bool AddStepSuffix, bool Zoom, int Width, int Height, lcStep Start, lcStep End); void RayTest(lcObjectRayTest& ObjectRayTest) const; void BoxTest(lcObjectBoxTest& ObjectBoxTest) const; bool SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance, lcPieceInfoRayTest& PieceInfoRayTest) const; bool SubModelBoxTest(const lcVector4 Planes[6]) const; void SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const; void SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector& Points) const; bool HasPieces() const { return !mPieces.IsEmpty(); } bool AnyPiecesSelected() const; bool AnyObjectsSelected() const; lcModel* GetFirstSelectedSubmodel() const; void GetSubModels(lcArray& SubModels) const; bool GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const; bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const; lcVector3 GetSelectionOrModelCenter() const; bool GetFocusPosition(lcVector3& Position) const; lcObject* GetFocusObject() const; bool GetSelectionCenter(lcVector3& Center) const; lcBoundingBox GetAllPiecesBoundingBox() const; bool GetVisiblePiecesBoundingBox(lcVector3& Min, lcVector3& Max) const; std::vector GetPiecesBoundingBoxPoints() const; void GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const; void GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList) const; void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector& ModelParts) const; void GetSelectionInformation(int* Flags, lcArray& Selection, lcObject** Focus) const; lcArray GetSelectionModePieces(const lcPiece* SelectedPiece) const; void FocusOrDeselectObject(const lcObjectSection& ObjectSection); void ClearSelection(bool UpdateInterface); void ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, bool EnableSelectionMode); void ClearSelectionAndSetFocus(const lcObjectSection& ObjectSection, bool EnableSelectionMode); void SetSelectionAndFocus(const lcArray& Selection, lcObject* Focus, quint32 Section, bool EnableSelectionMode); void AddToSelection(const lcArray& Objects, bool EnableSelectionMode, bool UpdateInterface); void RemoveFromSelection(const lcArray& Objects); void RemoveFromSelection(const lcObjectSection& ObjectSection); void SelectAllPieces(); void InvertSelection(); void HideSelectedPieces(); void HideUnselectedPieces(); void UnhideSelectedPieces(); void UnhideAllPieces(); void FindReplacePiece(bool SearchForward, bool FindAll); void UndoAction(); void RedoAction(); lcVector3 SnapPosition(const lcVector3& Delta) const; lcVector3 SnapRotation(const lcVector3& Delta) const; lcMatrix33 GetRelativeRotation() const; const lcVector3& GetMouseToolDistance() const { return mMouseToolDistance; } void BeginMouseTool(); void EndMouseTool(lcTool Tool, bool Accept); void InsertPieceToolClicked(const lcMatrix44& WorldMatrix); void PointLightToolClicked(const lcVector3& Position); void BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target); void UpdateSpotLightTool(const lcVector3& Position); void BeginCameraTool(const lcVector3& Position, const lcVector3& Target); void UpdateCameraTool(const lcVector3& Position); void UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag); void UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag); void UpdateScaleTool(const float Scale); void EraserToolClicked(lcObject* Object); void PaintToolClicked(lcObject* Object); void ColorPickerToolClicked(const lcObject* Object); void UpdateZoomTool(lcCamera* Camera, float Mouse); void UpdatePanTool(lcCamera* Camera, const lcVector3& Distance); void UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY); void UpdateRollTool(lcCamera* Camera, float Mouse); void ZoomRegionToolClicked(lcCamera* Camera, float AspectRatio, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners); void LookAt(lcCamera* Camera); void MoveCamera(lcCamera* Camera, const lcVector3& Direction); void ZoomExtents(lcCamera* Camera, float Aspect); void Zoom(lcCamera* Camera, float Amount); void MoveSelectedObjects(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint) { MoveSelectedObjects(Distance, Distance, AllowRelative, AlternateButtonDrag, Update, Checkpoint); } void MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint); void RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint); void ScaleSelectedPieces(const float Scale, bool Update, bool Checkpoint); void TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform); void SetSelectedPiecesColorIndex(int ColorIndex); void SetSelectedPiecesPieceInfo(PieceInfo* Info); void SetSelectedPiecesStepShow(lcStep Step); void SetSelectedPiecesStepHide(lcStep Step); void SetCameraOrthographic(lcCamera* Camera, bool Ortho); void SetCameraFOV(lcCamera* Camera, float FOV); void SetCameraZNear(lcCamera* Camera, float ZNear); void SetCameraZFar(lcCamera* Camera, float ZFar); void SetCameraName(lcCamera* Camera, const QString& Name); void ShowPropertiesDialog(); void ShowSelectByNameDialog(); void ShowArrayDialog(); void ShowMinifigDialog(); void UpdateInterface(); protected: void DeleteModel(); void DeleteHistory(); void SaveCheckpoint(const QString& Description); void LoadCheckPoint(lcModelHistoryEntry* CheckPoint); QString GetGroupName(const QString& Prefix); void RemoveEmptyGroups(); bool RemoveSelectedObjects(); void SelectGroup(lcGroup* TopGroup, bool Select); void AddPiece(lcPiece* Piece); void InsertPiece(lcPiece* Piece, int Index); lcModelProperties mProperties; Project* const mProject; PieceInfo* mPieceInfo; bool mIsPreview; bool mActive; lcStep mCurrentStep; lcVector3 mMouseToolDistance; lcArray mPieces; lcArray mCameras; lcArray mLights; lcArray mGroups; QStringList mFileLines; lcModelHistoryEntry* mSavedHistory; std::vector mUndoHistory; std::vector mRedoHistory; Q_DECLARE_TR_FUNCTIONS(lcModel); }; leocad-23.03/common/lc_pagesetupdialog.cpp000066400000000000000000000022001440571307300205750ustar00rootroot00000000000000#include "lc_global.h" #include "lc_pagesetupdialog.h" #include "ui_lc_pagesetupdialog.h" #include "lc_instructions.h" lcPageSetupDialog::lcPageSetupDialog(QWidget* Parent, lcInstructionsPageSetup* PageSetup) : QDialog(Parent), ui(new Ui::lcPageSetupDialog), mPageSetup(PageSetup) { ui->setupUi(this); ui->WidthEdit->setText(QString::number(PageSetup->Width)); ui->HeightEdit->setText(QString::number(PageSetup->Height)); ui->LeftEdit->setText(QString::number(PageSetup->MarginLeft)); ui->RightEdit->setText(QString::number(PageSetup->MarginRight)); ui->TopEdit->setText(QString::number(PageSetup->MarginTop)); ui->BottomEdit->setText(QString::number(PageSetup->MarginBottom)); } lcPageSetupDialog::~lcPageSetupDialog() { delete ui; } void lcPageSetupDialog::accept() { mPageSetup->Width = ui->WidthEdit->text().toFloat(); mPageSetup->Height = ui->HeightEdit->text().toFloat(); mPageSetup->MarginLeft = ui->LeftEdit->text().toFloat(); mPageSetup->MarginRight = ui->RightEdit->text().toFloat(); mPageSetup->MarginTop = ui->TopEdit->text().toFloat(); mPageSetup->MarginBottom = ui->BottomEdit->text().toFloat(); QDialog::accept(); } leocad-23.03/common/lc_pagesetupdialog.h000066400000000000000000000005161440571307300202520ustar00rootroot00000000000000#pragma once namespace Ui { class lcPageSetupDialog; } class lcPageSetupDialog : public QDialog { Q_OBJECT public: lcPageSetupDialog(QWidget* Parent, lcInstructionsPageSetup* PageSetup); ~lcPageSetupDialog(); public slots: void accept() override; private: Ui::lcPageSetupDialog *ui; lcInstructionsPageSetup* mPageSetup; }; leocad-23.03/common/lc_pagesetupdialog.ui000066400000000000000000000117071440571307300204440ustar00rootroot00000000000000 lcPageSetupDialog 0 0 400 300 Page Setup Size Width: WidthEdit Height: HeightEdit Preset: Units: Margins Left: LeftEdit Right: RightEdit Top: TopEdit Bottom: BottomEdit Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok WidthEdit HeightEdit comboBox_2 comboBox LeftEdit RightEdit TopEdit BottomEdit buttonBox accepted() lcPageSetupDialog accept() 227 282 157 274 buttonBox rejected() lcPageSetupDialog reject() 295 288 286 274 leocad-23.03/common/lc_partpalettedialog.cpp000066400000000000000000000123231440571307300211340ustar00rootroot00000000000000#include "lc_global.h" #include "lc_partpalettedialog.h" #include "ui_lc_partpalettedialog.h" #include "lc_partselectionwidget.h" #include "lc_setsdatabasedialog.h" lcPartPaletteDialog::lcPartPaletteDialog(QWidget* Parent, std::vector& PartPalettes) : QDialog(Parent), ui(new Ui::lcPartPaletteDialog), mPartPalettes(PartPalettes) { ui->setupUi(this); for (const lcPartPalette& Palette : PartPalettes) { QListWidgetItem* Item = new QListWidgetItem(Palette.Name); Item->setData(Qt::UserRole, QVariant::fromValue(reinterpret_cast(&Palette))); ui->PaletteList->addItem(Item); } ui->PaletteList->setCurrentRow(0); UpdateButtons(); } lcPartPaletteDialog::~lcPartPaletteDialog() { for (lcPartPalette* Palette : mImportedPalettes) delete Palette; delete ui; } void lcPartPaletteDialog::UpdateButtons() { int CurrentPalette = ui->PaletteList->currentRow(); int PaletteCount = ui->PaletteList->count(); ui->DeleteButton->setEnabled(PaletteCount > 1); ui->MoveUpButton->setEnabled(PaletteCount > 1 && CurrentPalette > 0); ui->MoveDownButton->setEnabled(PaletteCount > 1 && CurrentPalette < PaletteCount - 1); } void lcPartPaletteDialog::accept() { std::vector PartPalettes; PartPalettes.reserve(ui->PaletteList->count()); for (int ItemIdx = 0; ItemIdx < ui->PaletteList->count(); ItemIdx++) { QListWidgetItem* Item = ui->PaletteList->item(ItemIdx); lcPartPalette* OldPalette = reinterpret_cast(Item->data(Qt::UserRole).value()); lcPartPalette Palette; Palette.Name = Item->text(); if (OldPalette) Palette.Parts = std::move(OldPalette->Parts); PartPalettes.emplace_back(std::move(Palette)); } mPartPalettes = std::move(PartPalettes); QDialog::accept(); } void lcPartPaletteDialog::on_NewButton_clicked() { bool Ok = false; QString Name = QInputDialog::getText(this, tr("New Part Palette"), tr("Palette Name:"), QLineEdit::Normal, QString(), &Ok); if (!Ok || Name.isEmpty()) return; QListWidgetItem* Item = new QListWidgetItem(Name); Item->setData(Qt::UserRole, QVariant::fromValue(0)); ui->PaletteList->addItem(Item); ui->PaletteList->setCurrentRow(ui->PaletteList->count() - 1); UpdateButtons(); } void lcPartPaletteDialog::on_DeleteButton_clicked() { QList SelectedItems = ui->PaletteList->selectedItems(); if (SelectedItems.isEmpty()) return; QString Prompt = tr("Are you sure you want to delete the palette '%1'?").arg(SelectedItems[0]->text()); if (QMessageBox::question(this, tr("Delete Part Palette"), Prompt, QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; QListWidgetItem* SelectedItem = SelectedItems.first(); delete SelectedItem; UpdateButtons(); } void lcPartPaletteDialog::on_RenameButton_clicked() { QList SelectedItems = ui->PaletteList->selectedItems(); if (SelectedItems.isEmpty()) return; bool Ok = false; QString Name = SelectedItems[0]->text(); Name = QInputDialog::getText(this, tr("Rename Part Palette"), tr("Palette Name:"), QLineEdit::Normal, Name, &Ok); if (!Ok || Name.isEmpty()) return; if (!Name.isEmpty()) SelectedItems[0]->setText(Name); } void lcPartPaletteDialog::on_ImportButton_clicked() { lcSetsDatabaseDialog Dialog(this); if (Dialog.exec() != QDialog::Accepted) return; lcPartPalette* Palette = new lcPartPalette; Palette->Name = Dialog.GetSetDescription(); mImportedPalettes.push_back(Palette); QByteArray Inventory = Dialog.GetSetInventory(); QJsonDocument Document = QJsonDocument::fromJson(Inventory); QJsonObject Root = Document.object(); QJsonArray Parts = Root["results"].toArray(); for (const QJsonValue& Part : Parts) { QJsonObject PartObject = Part.toObject(); QByteArray PartID = PartObject["part"].toObject()["part_num"].toString().toLatin1(); QJsonArray PartIDArray = PartObject["part"].toObject()["external_ids"].toObject()["LDraw"].toArray(); if (!PartIDArray.isEmpty()) PartID = PartIDArray.first().toString().toLatin1(); Palette->Parts.push_back(PartID.toUpper().toStdString() + ".DAT"); } QListWidgetItem* Item = new QListWidgetItem(Palette->Name); Item->setData(Qt::UserRole, QVariant::fromValue(reinterpret_cast(Palette))); ui->PaletteList->addItem(Item); ui->PaletteList->setCurrentRow(ui->PaletteList->count() - 1); UpdateButtons(); } void lcPartPaletteDialog::on_MoveUpButton_clicked() { QList SelectedItems = ui->PaletteList->selectedItems(); if (SelectedItems.isEmpty()) return; QListWidgetItem* Item = SelectedItems[0]; int Row = ui->PaletteList->row(Item); if (Row == 0) return; ui->PaletteList->takeItem(Row); ui->PaletteList->insertItem(Row - 1, Item); ui->PaletteList->setCurrentItem(Item); UpdateButtons(); } void lcPartPaletteDialog::on_MoveDownButton_clicked() { QList SelectedItems = ui->PaletteList->selectedItems(); if (SelectedItems.isEmpty()) return; QListWidgetItem* Item = SelectedItems[0]; int Row = ui->PaletteList->row(Item); ui->PaletteList->takeItem(Row); ui->PaletteList->insertItem(Row + 1, Item); ui->PaletteList->setCurrentItem(Item); UpdateButtons(); } void lcPartPaletteDialog::on_PaletteList_currentRowChanged(int CurrentRow) { Q_UNUSED(CurrentRow); UpdateButtons(); } leocad-23.03/common/lc_partpalettedialog.h000066400000000000000000000013141440571307300205770ustar00rootroot00000000000000#pragma once namespace Ui { class lcPartPaletteDialog; } struct lcPartPalette; class lcPartPaletteDialog : public QDialog { Q_OBJECT public: lcPartPaletteDialog(QWidget* Parent, std::vector& PartPalettes); ~lcPartPaletteDialog(); protected slots: void accept() override; void on_NewButton_clicked(); void on_DeleteButton_clicked(); void on_RenameButton_clicked(); void on_ImportButton_clicked(); void on_MoveUpButton_clicked(); void on_MoveDownButton_clicked(); void on_PaletteList_currentRowChanged(int CurrentRow); private: void UpdateButtons(); Ui::lcPartPaletteDialog* ui; std::vector& mPartPalettes; std::vector mImportedPalettes; }; leocad-23.03/common/lc_partpalettedialog.ui000066400000000000000000000066531440571307300210000ustar00rootroot00000000000000 lcPartPaletteDialog 0 0 400 300 Part Palettes New... Delete... Rename... Import... Move Up Move Down Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok PaletteList NewButton DeleteButton RenameButton ImportButton MoveUpButton MoveDownButton buttonBox accepted() lcPartPaletteDialog accept() 248 254 157 274 buttonBox rejected() lcPartPaletteDialog reject() 316 260 286 274 leocad-23.03/common/lc_partselectionwidget.cpp000066400000000000000000000767521440571307300215270ustar00rootroot00000000000000#include "lc_global.h" #include "lc_partselectionwidget.h" #include "lc_partpalettedialog.h" #include "lc_profile.h" #include "lc_application.h" #include "lc_mainwindow.h" #include "lc_library.h" #include "lc_model.h" #include "project.h" #include "pieceinf.h" #include "camera.h" #include "lc_scene.h" #include "lc_view.h" #include "lc_glextensions.h" #include "lc_category.h" Q_DECLARE_METATYPE(QList) void lcPartSelectionItemDelegate::paint(QPainter* Painter, const QStyleOptionViewItem& Option, const QModelIndex& Index) const { mListModel->RequestPreview(Index.row()); QStyledItemDelegate::paint(Painter, Option, Index); } QSize lcPartSelectionItemDelegate::sizeHint(const QStyleOptionViewItem& Option, const QModelIndex& Index) const { QSize Size = QStyledItemDelegate::sizeHint(Option, Index); int IconSize = mListModel->GetIconSize(); if (IconSize) { QWidget* Widget = (QWidget*)parent(); const int PixmapMargin = Widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &Option, Widget) + 1; int PixmapWidth = IconSize + 2 * PixmapMargin; Size.setWidth(qMin(PixmapWidth, Size.width())); } return Size; } lcPartSelectionListModel::lcPartSelectionListModel(QObject* Parent) : QAbstractListModel(Parent) { mListView = (lcPartSelectionListView*)Parent; mIconSize = 0; mShowPartNames = lcGetProfileInt(LC_PROFILE_PARTS_LIST_NAMES); mListMode = lcGetProfileInt(LC_PROFILE_PARTS_LIST_LISTMODE); mShowDecoratedParts = lcGetProfileInt(LC_PROFILE_PARTS_LIST_DECORATED); mShowPartAliases = lcGetProfileInt(LC_PROFILE_PARTS_LIST_ALIASES); int ColorCode = lcGetProfileInt(LC_PROFILE_PARTS_LIST_COLOR); if (ColorCode == -1) { mColorIndex = gMainWindow->mColorIndex; mColorLocked = false; } else { mColorIndex = lcGetColorIndex(ColorCode); mColorLocked = true; } connect(lcGetPiecesLibrary(), &lcPiecesLibrary::PartLoaded, this, &lcPartSelectionListModel::PartLoaded); } lcPartSelectionListModel::~lcPartSelectionListModel() { ClearRequests(); mView.reset(); mModel.reset(); } void lcPartSelectionListModel::ClearRequests() { lcPiecesLibrary* Library = lcGetPiecesLibrary(); for (int RequestIdx : mRequestedPreviews) { PieceInfo* Info = mParts[RequestIdx].first; Library->ReleasePieceInfo(Info); } mRequestedPreviews.clear(); } void lcPartSelectionListModel::Redraw() { ClearRequests(); beginResetModel(); for (size_t PartIdx = 0; PartIdx < mParts.size(); PartIdx++) mParts[PartIdx].second = QPixmap(); endResetModel(); SetFilter(mFilter); } void lcPartSelectionListModel::SetColorIndex(int ColorIndex) { if (mColorLocked || ColorIndex == mColorIndex) return; mColorIndex = ColorIndex; Redraw(); } void lcPartSelectionListModel::ToggleColorLocked() { mColorLocked = !mColorLocked; SetColorIndex(gMainWindow->mColorIndex); lcSetProfileInt(LC_PROFILE_PARTS_LIST_COLOR, mColorLocked ? lcGetColorCode(mColorIndex) : -1); } void lcPartSelectionListModel::ToggleListMode() { mListMode = !mListMode; mListView->UpdateViewMode(); lcSetProfileInt(LC_PROFILE_PARTS_LIST_LISTMODE, mListMode); } void lcPartSelectionListModel::SetCategory(int CategoryIndex) { ClearRequests(); beginResetModel(); lcPiecesLibrary* Library = lcGetPiecesLibrary(); lcArray SingleParts, GroupedParts; if (CategoryIndex != -1) Library->GetCategoryEntries(CategoryIndex, false, SingleParts, GroupedParts); else { Library->GetParts(SingleParts); lcModel* ActiveModel = gMainWindow->GetActiveModel(); for (int PartIdx = 0; PartIdx < SingleParts.GetSize(); ) { PieceInfo* Info = SingleParts[PartIdx]; if (!Info->IsModel() || !Info->GetModel()->IncludesModel(ActiveModel)) PartIdx++; else SingleParts.RemoveIndex(PartIdx); } } auto lcPartSortFunc=[](const PieceInfo* a, const PieceInfo* b) { return strcmp(a->m_strDescription, b->m_strDescription) < 0; }; std::sort(SingleParts.begin(), SingleParts.end(), lcPartSortFunc); mParts.resize(SingleParts.GetSize()); for (int PartIdx = 0; PartIdx < SingleParts.GetSize(); PartIdx++) mParts[PartIdx] = std::pair(SingleParts[PartIdx], QPixmap()); endResetModel(); SetFilter(mFilter); } void lcPartSelectionListModel::SetModelsCategory() { ClearRequests(); beginResetModel(); mParts.clear(); const lcArray& Models = lcGetActiveProject()->GetModels(); lcModel* ActiveModel = gMainWindow->GetActiveModel(); for (int ModelIdx = 0; ModelIdx < Models.GetSize(); ModelIdx++) { lcModel* Model = Models[ModelIdx]; if (!Model->IncludesModel(ActiveModel)) mParts.emplace_back(std::pair(Model->GetPieceInfo(), QPixmap())); } auto lcPartSortFunc = [](const std::pair& a, const std::pair& b) { return strcmp(a.first->m_strDescription, b.first->m_strDescription) < 0; }; std::sort(mParts.begin(), mParts.end(), lcPartSortFunc); endResetModel(); SetFilter(mFilter); } void lcPartSelectionListModel::SetPaletteCategory(int SetIndex) { ClearRequests(); beginResetModel(); mParts.clear(); lcPartSelectionWidget* PartSelectionWidget = mListView->GetPartSelectionWidget(); const std::vector& Palettes = PartSelectionWidget->GetPartPalettes(); std::vector PartsList = lcGetPiecesLibrary()->GetPartsFromSet(Palettes[SetIndex].Parts); auto lcPartSortFunc = [](const PieceInfo* a, const PieceInfo* b) { return strcmp(a->m_strDescription, b->m_strDescription) < 0; }; std::sort(PartsList.begin(), PartsList.end(), lcPartSortFunc); mParts.reserve(PartsList.size()); for (PieceInfo* Favorite : PartsList) mParts.emplace_back(std::pair(Favorite, QPixmap())); endResetModel(); SetFilter(mFilter); } void lcPartSelectionListModel::SetCurrentModelCategory() { ClearRequests(); beginResetModel(); mParts.clear(); lcModel* ActiveModel = gMainWindow->GetActiveModel(); lcPartsList PartsList; if (ActiveModel) ActiveModel->GetPartsList(gDefaultColor, true, true, PartsList); for (const auto& PartIt : PartsList) mParts.emplace_back(std::pair((PieceInfo*)PartIt.first, QPixmap())); auto lcPartSortFunc = [](const std::pair& a, const std::pair& b) { return strcmp(a.first->m_strDescription, b.first->m_strDescription) < 0; }; std::sort(mParts.begin(), mParts.end(), lcPartSortFunc); endResetModel(); SetFilter(mFilter); } void lcPartSelectionListModel::SetFilter(const QString& Filter) { mFilter = Filter.toLatin1(); for (size_t PartIdx = 0; PartIdx < mParts.size(); PartIdx++) { PieceInfo* Info = mParts[PartIdx].first; bool Visible; if (!mShowDecoratedParts && Info->IsPatterned() && !Info->IsProjectPiece()) Visible = false; else if (!mShowPartAliases && Info->m_strDescription[0] == '=') Visible = false; else if (mFilter.isEmpty()) Visible = true; else { char Description[sizeof(Info->m_strDescription)]; char* Src = Info->m_strDescription; char* Dst = Description; for (;;) { *Dst = *Src; if (*Src == ' ' && *(Src + 1) == ' ') Src++; else if (*Src == 0) break; Src++; Dst++; } Visible = strcasestr(Description, mFilter) || strcasestr(Info->mFileName, mFilter); } mListView->setRowHidden((int)PartIdx, !Visible); } } int lcPartSelectionListModel::rowCount(const QModelIndex& Parent) const { Q_UNUSED(Parent); return (int)mParts.size(); } QVariant lcPartSelectionListModel::data(const QModelIndex& Index, int Role) const { size_t InfoIndex = Index.row(); if (Index.isValid() && InfoIndex < mParts.size()) { PieceInfo* Info = mParts[InfoIndex].first; switch (Role) { case Qt::DisplayRole: if (!mIconSize || mShowPartNames || mListMode) return QVariant(QString::fromLatin1(Info->m_strDescription)); break; case Qt::ToolTipRole: return QVariant(QString("%1 (%2)").arg(QString::fromLatin1(Info->m_strDescription), QString::fromLatin1(Info->mFileName))); case Qt::DecorationRole: if (!mParts[InfoIndex].second.isNull() && mIconSize) return QVariant(mParts[InfoIndex].second); else return QVariant(QColor(0, 0, 0, 0)); default: break; } } return QVariant(); } QVariant lcPartSelectionListModel::headerData(int Section, Qt::Orientation Orientation, int Role) const { Q_UNUSED(Section); Q_UNUSED(Orientation); return Role == Qt::DisplayRole ? QVariant(QLatin1String("Image")) : QVariant(); } Qt::ItemFlags lcPartSelectionListModel::flags(const QModelIndex& Index) const { Qt::ItemFlags DefaultFlags = QAbstractListModel::flags(Index); if (Index.isValid()) return Qt::ItemIsDragEnabled | DefaultFlags; else return DefaultFlags; } void lcPartSelectionListModel::RequestPreview(int InfoIndex) { if (!mIconSize || !mParts[InfoIndex].second.isNull()) return; if (std::find(mRequestedPreviews.begin(), mRequestedPreviews.end(), InfoIndex) != mRequestedPreviews.end()) return; PieceInfo* Info = mParts[InfoIndex].first; lcGetPiecesLibrary()->LoadPieceInfo(Info, false, false); if (Info->mState == lcPieceInfoState::Loaded) DrawPreview(InfoIndex); else mRequestedPreviews.push_back(InfoIndex); } void lcPartSelectionListModel::PartLoaded(PieceInfo* Info) { for (size_t PartIdx = 0; PartIdx < mParts.size(); PartIdx++) { if (mParts[PartIdx].first == Info) { auto PreviewIt = std::find(mRequestedPreviews.begin(), mRequestedPreviews.end(), static_cast(PartIdx)); if (PreviewIt != mRequestedPreviews.end()) { mRequestedPreviews.erase(PreviewIt); DrawPreview((int)PartIdx); } break; } } } void lcPartSelectionListModel::DrawPreview(int InfoIndex) { const int Width = mIconSize * 2; const int Height = mIconSize * 2; if (mView && (mView->GetWidth() != Width || mView->GetHeight() != Height)) mView.reset(); if (!mView) { if (!mModel) mModel = std::unique_ptr(new lcModel(QString(), nullptr, true)); mView = std::unique_ptr(new lcView(lcViewType::PartsList, mModel.get())); mView->SetOffscreenContext(); mView->MakeCurrent(); mView->SetSize(Width, Height); if (!mView->BeginRenderToImage(Width, Height)) { mView.reset(); return; } } mView->MakeCurrent(); mView->BindRenderFramebuffer(); const uint BackgroundColor = mListView->palette().color(QPalette::Base).rgba(); mView->SetBackgroundColorOverride(LC_RGBA(qRed(BackgroundColor), qGreen(BackgroundColor), qBlue(BackgroundColor), 0)); PieceInfo* Info = mParts[InfoIndex].first; mModel->SetPreviewPieceInfo(Info, mColorIndex); const lcVector3 Center = (Info->GetBoundingBox().Min + Info->GetBoundingBox().Max) / 2.0f; const lcVector3 Position = Center + lcVector3(100.0f, -100.0f, 75.0f); mView->GetCamera()->SetViewpoint(Position, Center, lcVector3(0, 0, 1)); mView->GetCamera()->m_fovy = 20.0f; mView->ZoomExtents(); mView->OnDraw(); mView->UnbindRenderFramebuffer(); QImage Image = mView->GetRenderFramebufferImage().convertToFormat(QImage::Format_ARGB32); if (Info->GetSynthInfo()) { QPainter Painter(&Image); QImage Icon = QImage(":/resources/flexible.png"); uchar* ImageBits = Icon.bits(); QRgb TextColor = mListView->palette().color(QPalette::WindowText).rgba(); int Red = qRed(TextColor); int Green = qGreen(TextColor); int Blue = qBlue(TextColor); for (int y = 0; y < Icon.height(); y++) { for (int x = 0; x < Icon.width(); x++) { QRgb& Pixel = ((QRgb*)ImageBits)[x]; Pixel = qRgba(Red, Green, Blue, qAlpha(Pixel)); } ImageBits += Icon.bytesPerLine(); } Painter.drawImage(QPoint(0, 0), Icon); Painter.end(); } mParts[InfoIndex].second = QPixmap::fromImage(Image).scaled(mIconSize, mIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); lcGetPiecesLibrary()->ReleasePieceInfo(Info); emit dataChanged(index(InfoIndex, 0), index(InfoIndex, 0), QVector() << Qt::DecorationRole); } void lcPartSelectionListModel::SetShowDecoratedParts(bool Show) { if (Show == mShowDecoratedParts) return; mShowDecoratedParts = Show; SetFilter(mFilter); } void lcPartSelectionListModel::SetShowPartAliases(bool Show) { if (Show == mShowPartAliases) return; mShowPartAliases = Show; SetFilter(mFilter); } void lcPartSelectionListModel::SetIconSize(int Size) { if (Size == mIconSize) return; mIconSize = Size; beginResetModel(); for (size_t PartIdx = 0; PartIdx < mParts.size(); PartIdx++) mParts[PartIdx].second = QPixmap(); endResetModel(); SetFilter(mFilter); } void lcPartSelectionListModel::SetShowPartNames(bool Show) { if (Show == mShowPartNames) return; mShowPartNames = Show; beginResetModel(); endResetModel(); SetFilter(mFilter); } lcPartSelectionListView::lcPartSelectionListView(QWidget* Parent, lcPartSelectionWidget* PartSelectionWidget) : QListView(Parent) { mPartSelectionWidget = PartSelectionWidget; mCategoryType = lcPartCategoryType::AllParts; mCategoryIndex = 0; setUniformItemSizes(true); setResizeMode(QListView::Adjust); setWordWrap(false); setDragEnabled(true); setContextMenuPolicy(Qt::CustomContextMenu); mListModel = new lcPartSelectionListModel(this); setModel(mListModel); lcPartSelectionItemDelegate* ItemDelegate = new lcPartSelectionItemDelegate(this, mListModel); setItemDelegate(ItemDelegate); connect(this, SIGNAL(customContextMenuRequested(QPoint)), SLOT(CustomContextMenuRequested(QPoint))); SetIconSize(lcGetProfileInt(LC_PROFILE_PARTS_LIST_ICONS)); } void lcPartSelectionListView::CustomContextMenuRequested(QPoint Pos) { QMenu* Menu = new QMenu(this); QModelIndex Index = indexAt(Pos); mContextInfo = Index.isValid() ? mListModel->GetPieceInfo(Index.row()) : nullptr; QMenu* SetMenu = Menu->addMenu(tr("Add to Palette")); const std::vector& Palettes = mPartSelectionWidget->GetPartPalettes(); if (!Palettes.empty()) { for (const lcPartPalette& Palette : Palettes) SetMenu->addAction(Palette.Name, mPartSelectionWidget, SLOT(AddToPalette())); } else { QAction* Action = SetMenu->addAction(tr("None")); Action->setEnabled(false); } QAction* RemoveAction = Menu->addAction(tr("Remove from Palette"), mPartSelectionWidget, SLOT(RemoveFromPalette())); RemoveAction->setEnabled(mCategoryType == lcPartCategoryType::Palette); Menu->exec(viewport()->mapToGlobal(Pos)); delete Menu; } void lcPartSelectionListView::SetCategory(lcPartCategoryType Type, int Index) { mCategoryType = Type; mCategoryIndex = Index; switch (Type) { case lcPartCategoryType::AllParts: mListModel->SetCategory(-1); break; case lcPartCategoryType::PartsInUse: mListModel->SetCurrentModelCategory(); break; case lcPartCategoryType::Submodels: mListModel->SetModelsCategory(); break; case lcPartCategoryType::Palette: mListModel->SetPaletteCategory(Index); break; case lcPartCategoryType::Category: mListModel->SetCategory(Index); break; case lcPartCategoryType::Count: break; } setCurrentIndex(mListModel->index(0, 0)); } void lcPartSelectionListView::SetNoIcons() { SetIconSize(0); } void lcPartSelectionListView::SetSmallIcons() { SetIconSize(32); } void lcPartSelectionListView::SetMediumIcons() { SetIconSize(64); } void lcPartSelectionListView::SetLargeIcons() { SetIconSize(96); } void lcPartSelectionListView::SetExtraLargeIcons() { SetIconSize(192); } void lcPartSelectionListView::TogglePartNames() { bool Show = !mListModel->GetShowPartNames(); mListModel->SetShowPartNames(Show); lcSetProfileInt(LC_PROFILE_PARTS_LIST_NAMES, Show); } void lcPartSelectionListView::ToggleDecoratedParts() { bool Show = !mListModel->GetShowDecoratedParts(); mListModel->SetShowDecoratedParts(Show); lcSetProfileInt(LC_PROFILE_PARTS_LIST_DECORATED, Show); } void lcPartSelectionListView::TogglePartAliases() { bool Show = !mListModel->GetShowPartAliases(); mListModel->SetShowPartAliases(Show); lcSetProfileInt(LC_PROFILE_PARTS_LIST_ALIASES, Show); } void lcPartSelectionListView::ToggleListMode() { mListModel->ToggleListMode(); } void lcPartSelectionListView::ToggleFixedColor() { mListModel->ToggleColorLocked(); } void lcPartSelectionListView::UpdateViewMode() { setViewMode(mListModel->GetIconSize() && !mListModel->IsListMode() ? QListView::IconMode : QListView::ListMode); setWordWrap(mListModel->IsListMode()); setDragEnabled(true); } void lcPartSelectionListView::SetIconSize(int Size) { setIconSize(QSize(Size, Size)); lcSetProfileInt(LC_PROFILE_PARTS_LIST_ICONS, Size); mListModel->SetIconSize(Size); UpdateViewMode(); int Width = Size + 2 * frameWidth() + 6; if (verticalScrollBar()) Width += verticalScrollBar()->sizeHint().width(); int Height = Size + 2 * frameWidth() + 2; if (horizontalScrollBar()) Height += horizontalScrollBar()->sizeHint().height(); setMinimumSize(Width, Height); } void lcPartSelectionListView::startDrag(Qt::DropActions SupportedActions) { Q_UNUSED(SupportedActions); PieceInfo* Info = GetCurrentPart(); if (!Info) return; QByteArray ItemData; QDataStream DataStream(&ItemData, QIODevice::WriteOnly); DataStream << QString(Info->mFileName); QMimeData* MimeData = new QMimeData; MimeData->setData("application/vnd.leocad-part", ItemData); QDrag* Drag = new QDrag(this); Drag->setMimeData(MimeData); Drag->exec(Qt::CopyAction); } void lcPartSelectionListView::mouseDoubleClickEvent(QMouseEvent* MouseEvent) { if (MouseEvent->button() == Qt::LeftButton ) PreviewSelection(currentIndex().row()); QListView::mouseDoubleClickEvent(MouseEvent); } void lcPartSelectionListView::PreviewSelection(int InfoIndex) { PieceInfo* Info = mListModel->GetPieceInfo(InfoIndex); if (!Info) return; quint32 ColorCode = lcGetColorCode(mListModel->GetColorIndex()); gMainWindow->PreviewPiece(Info->mFileName, ColorCode, true); } lcPartSelectionWidget::lcPartSelectionWidget(QWidget* Parent) : QWidget(Parent), mFilterAction(nullptr) { mSplitter = new QSplitter(this); mSplitter->setOrientation(Qt::Vertical); mSplitter->setChildrenCollapsible(false); mCategoriesWidget = new QTreeWidget(mSplitter); mCategoriesWidget->setHeaderHidden(true); mCategoriesWidget->setUniformRowHeights(true); mCategoriesWidget->setRootIsDecorated(false); QWidget* PartsGroupWidget = new QWidget(mSplitter); QVBoxLayout* PartsLayout = new QVBoxLayout(); PartsLayout->setContentsMargins(0, 0, 0, 0); PartsGroupWidget->setLayout(PartsLayout); QHBoxLayout* SearchLayout = new QHBoxLayout(); SearchLayout->setContentsMargins(0, 0, 0, 0); PartsLayout->addLayout(SearchLayout); mFilterWidget = new QLineEdit(PartsGroupWidget); mFilterWidget->setPlaceholderText(tr("Search Parts")); mFilterAction = mFilterWidget->addAction(QIcon(":/resources/parts_search.png"), QLineEdit::TrailingPosition); connect(mFilterAction, SIGNAL(triggered()), this, SLOT(FilterTriggered())); SearchLayout->addWidget(mFilterWidget); QToolButton* OptionsButton = new QToolButton(); OptionsButton->setIcon(QIcon(":/resources/gear_in.png")); OptionsButton->setToolTip(tr("Options")); OptionsButton->setPopupMode(QToolButton::InstantPopup); SearchLayout->addWidget(OptionsButton); QMenu* OptionsMenu = new QMenu(this); OptionsButton->setMenu(OptionsMenu); connect(OptionsMenu, SIGNAL(aboutToShow()), this, SLOT(OptionsMenuAboutToShow())); mPartsWidget = new lcPartSelectionListView(PartsGroupWidget, this); PartsLayout->addWidget(mPartsWidget); QHBoxLayout* Layout = new QHBoxLayout(this); Layout->setContentsMargins(0, 0, 0, 0); Layout->addWidget(mSplitter); setLayout(Layout); connect(mPartsWidget->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(PartChanged(const QModelIndex&, const QModelIndex&))); connect(mFilterWidget, SIGNAL(textChanged(const QString&)), this, SLOT(FilterChanged(const QString&))); connect(mCategoriesWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(CategoryChanged(QTreeWidgetItem*, QTreeWidgetItem*))); LoadPartPalettes(); UpdateCategories(); mSplitter->setStretchFactor(0, 0); mSplitter->setStretchFactor(1, 1); connect(Parent, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(DockLocationChanged(Qt::DockWidgetArea))); } bool lcPartSelectionWidget::event(QEvent* Event) { if (Event->type() == QEvent::ShortcutOverride) { QKeyEvent* KeyEvent = (QKeyEvent*)Event; int Key = KeyEvent->key(); if (KeyEvent->modifiers() == Qt::NoModifier && Key >= Qt::Key_A && Key <= Qt::Key_Z) Event->accept(); switch (Key) { case Qt::Key_Down: case Qt::Key_Up: case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_Home: case Qt::Key_End: case Qt::Key_PageUp: case Qt::Key_PageDown: case Qt::Key_Asterisk: case Qt::Key_Plus: case Qt::Key_Minus: Event->accept(); break; } } return QWidget::event(Event); } void lcPartSelectionWidget::LoadState(QSettings& Settings) { QList Sizes = Settings.value("PartSelectionSplitter").value>(); if (Sizes.size() != 2) { int Length = mSplitter->orientation() == Qt::Horizontal ? mSplitter->width() : mSplitter->height(); Sizes << Length / 3 << 2 * Length / 3; } mSplitter->setSizes(Sizes); } void lcPartSelectionWidget::SaveState(QSettings& Settings) { QList Sizes = mSplitter->sizes(); Settings.setValue("PartSelectionSplitter", QVariant::fromValue(Sizes)); } void lcPartSelectionWidget::DisableIconMode() { mPartsWidget->SetNoIcons(); } void lcPartSelectionWidget::DockLocationChanged(Qt::DockWidgetArea Area) { if (Area == Qt::LeftDockWidgetArea || Area == Qt::RightDockWidgetArea) mSplitter->setOrientation(Qt::Vertical); else mSplitter->setOrientation(Qt::Horizontal); } void lcPartSelectionWidget::resizeEvent(QResizeEvent* Event) { if (((QDockWidget*)parent())->isFloating()) { if (Event->size().width() > Event->size().height()) mSplitter->setOrientation(Qt::Horizontal); else mSplitter->setOrientation(Qt::Vertical); } QWidget::resizeEvent(Event); } void lcPartSelectionWidget::FilterChanged(const QString& Text) { if (mFilterAction) { if (Text.isEmpty()) mFilterAction->setIcon(QIcon(":/resources/parts_search.png")); else mFilterAction->setIcon(QIcon(":/resources/parts_cancel.png")); } mPartsWidget->GetListModel()->SetFilter(Text); } void lcPartSelectionWidget::FilterTriggered() { mFilterWidget->clear(); } void lcPartSelectionWidget::CategoryChanged(QTreeWidgetItem* Current, QTreeWidgetItem* Previous) { Q_UNUSED(Previous); if (!Current) return; int Type = Current->data(0, static_cast(lcPartCategoryRole::Type)).toInt(); int Index = Current->data(0, static_cast(lcPartCategoryRole::Index)).toInt(); mPartsWidget->SetCategory(static_cast(Type), Index); } void lcPartSelectionWidget::PartChanged(const QModelIndex& Current, const QModelIndex& Previous) { Q_UNUSED(Current); Q_UNUSED(Previous); gMainWindow->SetCurrentPieceInfo(mPartsWidget->GetCurrentPart()); } void lcPartSelectionWidget::OptionsMenuAboutToShow() { QMenu* Menu = (QMenu*)sender(); Menu->clear(); Menu->addAction(tr("Edit Palettes..."), this, SLOT(EditPartPalettes())); Menu->addSeparator(); lcPartSelectionListModel* ListModel = mPartsWidget->GetListModel(); if (gSupportsFramebufferObject) { QActionGroup* IconGroup = new QActionGroup(Menu); QAction* NoIcons = Menu->addAction(tr("No Icons"), mPartsWidget, SLOT(SetNoIcons())); NoIcons->setCheckable(true); NoIcons->setChecked(ListModel->GetIconSize() == 0); IconGroup->addAction(NoIcons); QAction* SmallIcons = Menu->addAction(tr("Small Icons"), mPartsWidget, SLOT(SetSmallIcons())); SmallIcons->setCheckable(true); SmallIcons->setChecked(ListModel->GetIconSize() == 32); IconGroup->addAction(SmallIcons); QAction* MediumIcons = Menu->addAction(tr("Medium Icons"), mPartsWidget, SLOT(SetMediumIcons())); MediumIcons->setCheckable(true); MediumIcons->setChecked(ListModel->GetIconSize() == 64); IconGroup->addAction(MediumIcons); QAction* LargeIcons = Menu->addAction(tr("Large Icons"), mPartsWidget, SLOT(SetLargeIcons())); LargeIcons->setCheckable(true); LargeIcons->setChecked(ListModel->GetIconSize() == 96); IconGroup->addAction(LargeIcons); QAction* ExtraLargeIcons = Menu->addAction(tr("Extra Large Icons"), mPartsWidget, SLOT(SetExtraLargeIcons())); ExtraLargeIcons->setCheckable(true); ExtraLargeIcons->setChecked(ListModel->GetIconSize() == 192); IconGroup->addAction(ExtraLargeIcons); Menu->addSeparator(); } if (ListModel->GetIconSize() != 0 && !ListModel->IsListMode()) { QAction* PartNames = Menu->addAction(tr("Show Part Names"), mPartsWidget, SLOT(TogglePartNames())); PartNames->setCheckable(true); PartNames->setChecked(ListModel->GetShowPartNames()); } QAction* DecoratedParts = Menu->addAction(tr("Show Decorated Parts"), mPartsWidget, SLOT(ToggleDecoratedParts())); DecoratedParts->setCheckable(true); DecoratedParts->setChecked(ListModel->GetShowDecoratedParts()); QAction* PartAliases = Menu->addAction(tr("Show Part Aliases"), mPartsWidget, SLOT(TogglePartAliases())); PartAliases->setCheckable(true); PartAliases->setChecked(ListModel->GetShowPartAliases()); if (ListModel->GetIconSize() != 0) { QAction* ListMode = Menu->addAction(tr("List Mode"), mPartsWidget, SLOT(ToggleListMode())); ListMode->setCheckable(true); ListMode->setChecked(ListModel->IsListMode()); QAction* FixedColor = Menu->addAction(tr("Lock Preview Color"), mPartsWidget, SLOT(ToggleFixedColor())); FixedColor->setCheckable(true); FixedColor->setChecked(ListModel->IsColorLocked()); } } void lcPartSelectionWidget::EditPartPalettes() { lcPartPaletteDialog Dialog(this, mPartPalettes); if (Dialog.exec() != QDialog::Accepted) return; SavePartPalettes(); UpdateCategories(); } void lcPartSelectionWidget::Redraw() { mPartsWidget->GetListModel()->Redraw(); } void lcPartSelectionWidget::SetDefaultPart() { for (int CategoryIdx = 0; CategoryIdx < mCategoriesWidget->topLevelItemCount(); CategoryIdx++) { QTreeWidgetItem* CategoryItem = mCategoriesWidget->topLevelItem(CategoryIdx); if (CategoryItem->text(0) == "Brick") { mCategoriesWidget->setCurrentItem(CategoryItem); break; } } } void lcPartSelectionWidget::LoadPartPalettes() { QByteArray Buffer = lcGetProfileBuffer(LC_PROFILE_PART_PALETTES); QJsonDocument Document = QJsonDocument::fromJson(Buffer); if (Document.isNull()) Document = QJsonDocument::fromJson((QString("{ \"Version\":1, \"Palettes\": { \"%1\": [] } }").arg(tr("Favorites"))).toUtf8()); QJsonObject RootObject = Document.object(); mPartPalettes.clear(); int Version = RootObject["Version"].toInt(0); if (Version != 1) return; QJsonObject PalettesObject = RootObject["Palettes"].toObject(); for (QJsonObject::const_iterator ElementIt = PalettesObject.constBegin(); ElementIt != PalettesObject.constEnd(); ElementIt++) { if (!ElementIt.value().isArray()) continue; lcPartPalette Palette; Palette.Name = ElementIt.key(); QJsonArray Parts = ElementIt.value().toArray(); for (const QJsonValue& Part : Parts) Palette.Parts.emplace_back(Part.toString().toStdString()); mPartPalettes.emplace_back(std::move(Palette)); } } void lcPartSelectionWidget::SavePartPalettes() { QJsonObject RootObject; RootObject["Version"] = 1; QJsonObject PalettesObject; for (const lcPartPalette& Palette : mPartPalettes) { QJsonArray Parts; for (const std::string& PartId : Palette.Parts) Parts.append(QString::fromStdString(PartId)); PalettesObject[Palette.Name] = Parts; } RootObject["Palettes"] = PalettesObject; QByteArray Buffer = QJsonDocument(RootObject).toJson(); lcSetProfileBuffer(LC_PROFILE_PART_PALETTES, Buffer); } void lcPartSelectionWidget::AddToPalette() { PieceInfo* Info = mPartsWidget->GetContextInfo(); if (!Info) return; QString SetName = ((QAction*)sender())->text(); std::vector::iterator SetIt = std::find_if(mPartPalettes.begin(), mPartPalettes.end(), [&SetName](const lcPartPalette& Set) { return Set.Name == SetName; }); if (SetIt == mPartPalettes.end()) return; std::string PartId = lcGetPiecesLibrary()->GetPartId(Info); std::vector& Parts = SetIt->Parts; if (std::find(Parts.begin(), Parts.end(), PartId) == Parts.end()) { Parts.emplace_back(PartId); SavePartPalettes(); } } void lcPartSelectionWidget::RemoveFromPalette() { PieceInfo* Info = mPartsWidget->GetContextInfo(); if (!Info) return; QTreeWidgetItem* CurrentItem = mCategoriesWidget->currentItem(); if (!CurrentItem || CurrentItem->data(0, static_cast(lcPartCategoryRole::Type)) != static_cast(lcPartCategoryType::Palette)) return; int SetIndex = CurrentItem->data(0, static_cast(lcPartCategoryRole::Index)).toInt(); lcPartPalette& Palette = mPartPalettes[SetIndex]; std::string PartId = lcGetPiecesLibrary()->GetPartId(Info); std::vector::iterator PartIt = std::find(Palette.Parts.begin(), Palette.Parts.end(), PartId); if (PartIt != Palette.Parts.end()) { Palette.Parts.erase(PartIt); mPartsWidget->SetCategory(lcPartCategoryType::Palette, SetIndex); SavePartPalettes(); } } void lcPartSelectionWidget::UpdateCategories() { QTreeWidgetItem* CurrentItem = mCategoriesWidget->currentItem(); lcPartCategoryType CurrentType = lcPartCategoryType::Count; int CurrentIndex = -1; if (CurrentItem) { CurrentType = static_cast(CurrentItem->data(0, static_cast(lcPartCategoryRole::Type)).toInt()); CurrentIndex = CurrentItem->data(0, static_cast(lcPartCategoryRole::Index)).toInt(); CurrentItem = nullptr; } mCategoriesWidget->clear(); QTreeWidgetItem* AllPartsCategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(tr("All Parts"))); AllPartsCategoryItem->setData(0, static_cast(lcPartCategoryRole::Type), static_cast(lcPartCategoryType::AllParts)); if (CurrentType == lcPartCategoryType::AllParts && CurrentIndex == 0) CurrentItem = AllPartsCategoryItem; QTreeWidgetItem* CurrentModelCategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(tr("In Use"))); CurrentModelCategoryItem->setData(0, static_cast(lcPartCategoryRole::Type), static_cast(lcPartCategoryType::PartsInUse)); if (CurrentType == lcPartCategoryType::PartsInUse && CurrentIndex == 0) CurrentItem = CurrentModelCategoryItem; QTreeWidgetItem* SubmodelsCategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(tr("Submodels"))); SubmodelsCategoryItem->setData(0, static_cast(lcPartCategoryRole::Type), static_cast(lcPartCategoryType::Submodels)); if (CurrentType == lcPartCategoryType::Submodels && CurrentIndex == 0) CurrentItem = SubmodelsCategoryItem; for (int PaletteIdx = 0; PaletteIdx < static_cast(mPartPalettes.size()); PaletteIdx++) { const lcPartPalette& Set = mPartPalettes[PaletteIdx]; QTreeWidgetItem* PaletteCategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(Set.Name)); PaletteCategoryItem->setData(0, static_cast(lcPartCategoryRole::Type), static_cast(lcPartCategoryType::Palette)); PaletteCategoryItem->setData(0, static_cast(lcPartCategoryRole::Index), PaletteIdx); if (CurrentType == lcPartCategoryType::Palette && CurrentIndex == PaletteIdx) CurrentItem = PaletteCategoryItem; } for (int CategoryIdx = 0; CategoryIdx < static_cast(gCategories.size()); CategoryIdx++) { QTreeWidgetItem* CategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(gCategories[CategoryIdx].Name)); CategoryItem->setData(0, static_cast(lcPartCategoryRole::Type), static_cast(lcPartCategoryType::Category)); CategoryItem->setData(0, static_cast(lcPartCategoryRole::Index), CategoryIdx); if (CurrentType == lcPartCategoryType::Category && CurrentIndex == CategoryIdx) CurrentItem = CategoryItem; } if (CurrentItem) mCategoriesWidget->setCurrentItem(CurrentItem); } void lcPartSelectionWidget::UpdateModels() { QTreeWidgetItem* CurrentItem = mCategoriesWidget->currentItem(); if (CurrentItem && CurrentItem->data(0, static_cast(lcPartCategoryRole::Type)) == static_cast(lcPartCategoryType::Submodels)) mPartsWidget->SetCategory(lcPartCategoryType::Submodels, 0); } leocad-23.03/common/lc_partselectionwidget.h000066400000000000000000000124431440571307300211570ustar00rootroot00000000000000#pragma once #include "lc_context.h" class lcPartSelectionListModel; class lcPartSelectionListView; class lcPartSelectionWidget; enum class lcPartCategoryType { AllParts, PartsInUse, Submodels, Palette, Category, Count }; enum class lcPartCategoryRole { Type = Qt::UserRole, Index }; struct lcPartPalette { QString Name; std::vector Parts; }; class lcPartSelectionItemDelegate : public QStyledItemDelegate { Q_OBJECT public: lcPartSelectionItemDelegate(QObject* Parent, lcPartSelectionListModel* ListModel) : QStyledItemDelegate(Parent), mListModel(ListModel) { } void paint(QPainter* Painter, const QStyleOptionViewItem& Option, const QModelIndex& Index) const override; QSize sizeHint(const QStyleOptionViewItem& Option, const QModelIndex& Index) const override; protected: lcPartSelectionListModel* mListModel; }; class lcPartSelectionListModel : public QAbstractListModel { Q_OBJECT public: lcPartSelectionListModel(QObject* Parent); ~lcPartSelectionListModel(); int rowCount(const QModelIndex& Parent = QModelIndex()) const override; QVariant data(const QModelIndex& Index, int Role = Qt::DisplayRole) const override; QVariant headerData(int Section, Qt::Orientation Orientation, int Role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex& Index) const override; PieceInfo* GetPieceInfo(const QModelIndex& Index) const { return Index.isValid() ? mParts[Index.row()].first : nullptr; } PieceInfo* GetPieceInfo(int Row) const { return mParts[Row].first; } bool GetShowDecoratedParts() const { return mShowDecoratedParts; } bool GetShowPartAliases() const { return mShowPartAliases; } int GetIconSize() const { return mIconSize; } bool GetShowPartNames() const { return mShowPartNames; } int GetColorIndex() const { return mColorIndex; } bool IsColorLocked() const { return mColorLocked; } bool IsListMode() const { return mListMode; } void Redraw(); void SetColorIndex(int ColorIndex); void ToggleColorLocked(); void ToggleListMode(); void SetCategory(int CategoryIndex); void SetModelsCategory(); void SetPaletteCategory(int SetIndex); void SetCurrentModelCategory(); void SetFilter(const QString& Filter); void RequestPreview(int InfoIndex); void SetShowDecoratedParts(bool Show); void SetShowPartAliases(bool Show); void SetIconSize(int Size); void SetShowPartNames(bool Show); protected slots: void PartLoaded(PieceInfo* Info); protected: void ClearRequests(); void DrawPreview(int InfoIndex); lcPartSelectionListView* mListView; std::vector> mParts; std::vector mRequestedPreviews; int mIconSize; bool mColorLocked; int mColorIndex; bool mShowPartNames; bool mListMode; bool mShowDecoratedParts; bool mShowPartAliases; QByteArray mFilter; std::unique_ptr mView; std::unique_ptr mModel; }; class lcPartSelectionListView : public QListView { Q_OBJECT public: lcPartSelectionListView(QWidget* Parent, lcPartSelectionWidget* PartSelectionWidget); void startDrag(Qt::DropActions SupportedActions) override; void SetCategory(lcPartCategoryType Type, int Index); PieceInfo* GetCurrentPart() const { return mListModel->GetPieceInfo(currentIndex()); } lcPartSelectionListModel* GetListModel() const { return mListModel; } lcPartSelectionWidget* GetPartSelectionWidget() const { return mPartSelectionWidget; } PieceInfo* GetContextInfo() const { return mContextInfo; } void UpdateViewMode(); public slots: void CustomContextMenuRequested(QPoint Pos); void SetNoIcons(); void SetSmallIcons(); void SetMediumIcons(); void SetLargeIcons(); void SetExtraLargeIcons(); void TogglePartNames(); void ToggleDecoratedParts(); void TogglePartAliases(); void ToggleListMode(); void ToggleFixedColor(); protected: void SetIconSize(int Size); void PreviewSelection(int InfoIndex); void mouseDoubleClickEvent(QMouseEvent* MouseEvent) override; lcPartSelectionListModel* mListModel; lcPartSelectionWidget* mPartSelectionWidget; PieceInfo* mContextInfo; lcPartCategoryType mCategoryType; int mCategoryIndex; }; class lcPartSelectionWidget : public QWidget { Q_OBJECT public: lcPartSelectionWidget(QWidget* Parent); void Redraw(); void SetDefaultPart(); void UpdateModels(); void UpdateCategories(); void LoadState(QSettings& Settings); void SaveState(QSettings& Settings); void DisableIconMode(); void SetColorIndex(int ColorIndex) { mPartsWidget->GetListModel()->SetColorIndex(ColorIndex); } const std::vector& GetPartPalettes() const { return mPartPalettes; } public slots: void AddToPalette(); void RemoveFromPalette(); protected slots: void DockLocationChanged(Qt::DockWidgetArea Area); void FilterChanged(const QString& Text); void FilterTriggered(); void CategoryChanged(QTreeWidgetItem* Current, QTreeWidgetItem* Previous); void PartChanged(const QModelIndex& Current, const QModelIndex& Previous); void OptionsMenuAboutToShow(); void EditPartPalettes(); protected: void LoadPartPalettes(); void SavePartPalettes(); void resizeEvent(QResizeEvent* Event) override; bool event(QEvent* Event) override; QTreeWidget* mCategoriesWidget; QLineEdit* mFilterWidget; QAction* mFilterAction; lcPartSelectionListView* mPartsWidget; QSplitter* mSplitter; std::vector mPartPalettes; }; leocad-23.03/common/lc_previewwidget.cpp000066400000000000000000000101451440571307300203140ustar00rootroot00000000000000#include "lc_global.h" #include "lc_previewwidget.h" #include "pieceinf.h" #include "piece.h" #include "project.h" #include "lc_model.h" #include "lc_library.h" #include "lc_viewwidget.h" #include "lc_view.h" lcPreviewDockWidget::lcPreviewDockWidget(QMainWindow* Parent) : QMainWindow(Parent) { mPreview = new lcPreview(); mViewWidget = new lcViewWidget(nullptr, mPreview); setCentralWidget(mViewWidget); setMinimumSize(200, 200); mLockAction = new QAction(QIcon(":/resources/action_preview_unlocked.png"),tr("Lock Preview"), this); mLockAction->setCheckable(true); mLockAction->setChecked(false); mLockAction->setShortcut(tr("Ctrl+L")); connect(mLockAction, SIGNAL(triggered()), this, SLOT(SetPreviewLock())); SetPreviewLock(); mLabel = new QLabel(); mToolBar = addToolBar(tr("Toolbar")); mToolBar->setObjectName("Toolbar"); mToolBar->setStatusTip(tr("Preview Toolbar")); mToolBar->setMovable(false); mToolBar->addAction(mLockAction); mToolBar->addSeparator(); mToolBar->addWidget(mLabel); if (mToolBar->isHidden()) mToolBar->show(); } bool lcPreviewDockWidget::SetCurrentPiece(const QString& PartType, int ColorCode) { if (mLockAction->isChecked()) return true; mLabel->setText(tr("Loading...")); if (mPreview->SetCurrentPiece(PartType, ColorCode)) { mLabel->setText(mPreview->GetDescription()); return true; } return false; } void lcPreviewDockWidget::UpdatePreview() { mPreview->UpdatePreview(); } void lcPreviewDockWidget::ClearPreview() { if (mPreview->GetModel()->GetPieces().GetSize()) mPreview->ClearPreview(); mLabel->setText(QString()); } void lcPreviewDockWidget::SetPreviewLock() { bool Locked = mLockAction->isChecked(); if (Locked && mPreview->GetModel()->GetPieces().IsEmpty()) { mLockAction->setChecked(false); return; } QIcon LockIcon(Locked ? ":/resources/action_preview_locked.png" : ":/resources/action_preview_unlocked.png"); QString StatusTip(Locked ? tr("Unlock the preview display to enable updates") : tr("Lock the preview display to disable updates")); mLockAction->setToolTip(Locked ? tr("Unlock Preview") : tr("Lock Preview")); mLockAction->setIcon(LockIcon); mLockAction->setStatusTip(StatusTip); } lcPreview::lcPreview() : lcView(lcViewType::Preview, nullptr), mLoader(new Project(true)) { mLoader->SetActiveModel(0); mModel = mLoader->GetActiveModel(); } bool lcPreview::SetCurrentPiece(const QString& PartType, int ColorCode) { lcPiecesLibrary* Library = lcGetPiecesLibrary(); PieceInfo* Info = Library->FindPiece(PartType.toLatin1().constData(), nullptr, false, false); if (Info) { for (lcPiece* ModelPiece : mModel->GetPieces()) { if (Info == ModelPiece->mPieceInfo) { int ModelColorCode = ModelPiece->GetColorCode(); if (ModelColorCode == ColorCode) return true; } } mIsModel = Info->IsModel(); mDescription = Info->m_strDescription; mModel->SelectAllPieces(); mModel->DeleteSelectedObjects(); Library->LoadPieceInfo(Info, false, true); Library->WaitForLoadQueue(); mModel->SetPreviewPieceInfo(Info, lcGetColorIndex(ColorCode)); Library->ReleasePieceInfo(Info); } else { QString ModelPath = QString("%1/%2").arg(QDir::currentPath()).arg(PartType); if (!mLoader->Load(ModelPath, false)) return false; mLoader->SetActiveModel(0); lcGetPiecesLibrary()->RemoveTemporaryPieces(); mModel = mLoader->GetActiveModel(); if (!mModel->GetProperties().mDescription.isEmpty()) mDescription = mModel->GetProperties().mDescription; else mDescription = PartType; mIsModel = true; } ZoomExtents(); return true; } void lcPreview::ClearPreview() { mLoader = std::unique_ptr(new Project(true/*IsPreview*/)); mLoader->SetActiveModel(0); mModel = mLoader->GetActiveModel(); lcGetPiecesLibrary()->UnloadUnusedParts(); Redraw(); } void lcPreview::UpdatePreview() { QString PartType; int ColorCode = -1; for (lcPiece* ModelPiece : mModel->GetPieces()) { if (ModelPiece->mPieceInfo) { PartType = ModelPiece->mPieceInfo->mFileName; ColorCode = ModelPiece->GetColorCode(); break; } } ClearPreview(); if (!PartType.isEmpty() && ColorCode > -1) SetCurrentPiece(PartType, ColorCode); } leocad-23.03/common/lc_previewwidget.h000066400000000000000000000015031440571307300177570ustar00rootroot00000000000000#pragma once #include "lc_view.h" class lcPreview; class lcPreviewDockWidget : public QMainWindow { Q_OBJECT public: explicit lcPreviewDockWidget(QMainWindow* Parent = nullptr); bool SetCurrentPiece(const QString& PartType, int ColorCode); void ClearPreview(); void UpdatePreview(); protected slots: void SetPreviewLock(); protected: QAction* mLockAction; QToolBar* mToolBar; QLabel* mLabel; lcPreview* mPreview; lcViewWidget* mViewWidget; }; class lcPreview : public lcView { public: lcPreview(); QString GetDescription() const { return mDescription; } bool IsModel() const { return mIsModel; } void ClearPreview(); void UpdatePreview(); bool SetCurrentPiece(const QString& PartType, int ColorCode); protected: std::unique_ptr mLoader; QString mDescription; bool mIsModel = false; }; leocad-23.03/common/lc_profile.cpp000066400000000000000000000374731440571307300171040ustar00rootroot00000000000000#include "lc_global.h" #include "lc_profile.h" #include "lc_context.h" #include "image.h" #include "lc_model.h" #include "project.h" #include "lc_viewsphere.h" lcProfileEntry::lcProfileEntry(const char* Section, const char* Key, int DefaultValue) { mType = LC_PROFILE_ENTRY_INT; mSection = Section; mKey = Key; mDefault.IntValue = DefaultValue; } lcProfileEntry::lcProfileEntry(const char* Section, const char* Key, uint DefaultValue) { mType = LC_PROFILE_ENTRY_INT; mSection = Section; mKey = Key; mDefault.UIntValue = DefaultValue; } lcProfileEntry::lcProfileEntry(const char* Section, const char* Key, float DefaultValue) { mType = LC_PROFILE_ENTRY_FLOAT; mSection = Section; mKey = Key; mDefault.FloatValue = DefaultValue; } lcProfileEntry::lcProfileEntry(const char* Section, const char* Key, const char* DefaultValue) { mType = LC_PROFILE_ENTRY_STRING; mSection = Section; mKey = Key; mDefault.StringValue = DefaultValue; } lcProfileEntry::lcProfileEntry(const char* Section, const char* Key, const QStringList& /*StringList*/) { mType = LC_PROFILE_ENTRY_STRINGLIST; mSection = Section; mKey = Key; mDefault.IntValue = 0; } lcProfileEntry::lcProfileEntry(const char* Section, const char* Key) { mType = LC_PROFILE_ENTRY_BUFFER; mSection = Section; mKey = Key; mDefault.IntValue = 0; } static lcProfileEntry gProfileEntries[LC_NUM_PROFILE_KEYS] = { lcProfileEntry("Settings", "FixedAxes", false), // LC_PROFILE_FIXED_AXES lcProfileEntry("Settings", "LineWidth", 1.0f), // LC_PROFILE_LINE_WIDTH lcProfileEntry("Settings", "AllowLOD", true), // LC_PROFILE_ALLOW_LOD lcProfileEntry("Settings", "LODDistance", 750.0f), // LC_PROFILE_LOD_DISTANCE lcProfileEntry("Settings", "FadeSteps", false), // LC_PROFILE_FADE_STEPS lcProfileEntry("Settings", "FadeStepsColor", LC_RGBA(128, 128, 128, 128)), // LC_PROFILE_FADE_STEPS_COLOR lcProfileEntry("Settings", "HighlightNewParts", 0), // LC_PROFILE_HIGHLIGHT_NEW_PARTS lcProfileEntry("Settings", "HighlightNewPartsColor", LC_RGBA(255, 242, 0, 192)), // LC_PROFILE_HIGHLIGHT_NEW_PARTS_COLOR lcProfileEntry("Settings", "ShadingMode", static_cast(lcShadingMode::DefaultLights)), // LC_PROFILE_SHADING_MODE lcProfileEntry("Settings", "BackgroundGradient", false), // LC_PROFILE_BACKGROUND_GRADIENT lcProfileEntry("Settings", "BackgroundColor", LC_RGB(49, 52, 55)), // LC_PROFILE_BACKGROUND_COLOR lcProfileEntry("Settings", "GradientColorTop", LC_RGB(54, 72, 95)), // LC_PROFILE_GRADIENT_COLOR_TOP lcProfileEntry("Settings", "GradientColorBottom", LC_RGB(49, 52, 55)), // LC_PROFILE_GRADIENT_COLOR_BOTTOM lcProfileEntry("Settings", "DrawAxes", 0), // LC_PROFILE_DRAW_AXES lcProfileEntry("Settings", "DrawAxesLocation", static_cast(lcAxisIconLocation::BottomLeft)), // LC_PROFILE_DRAW_AXES_LOCATION lcProfileEntry("Settings", "AxesColor", LC_RGBA(0, 0, 0, 255)), // LC_PROFILE_AXES_COLOR lcProfileEntry("Settings", "TextColor", LC_RGBA(0, 0, 0, 255)), // LC_PROFILE_TEXT_COLOR lcProfileEntry("Settings", "MarqueeBorderColor", LC_RGBA(64, 64, 255, 255)), // LC_PROFILE_MARQUEE_BORDER_COLOR lcProfileEntry("Settings", "MarqueeFillColor", LC_RGBA(64, 64, 255, 64)), // LC_PROFILE_MARQUEE_FILL_COLOR lcProfileEntry("Settings", "OverlayColor", LC_RGBA(0, 0, 0, 255)), // LC_PROFILE_OVERLAY_COLOR lcProfileEntry("Settings", "ActiveViewColor", LC_RGBA(41, 128, 185, 255)), // LC_PROFILE_ACTIVE_VIEW_COLOR lcProfileEntry("Settings", "InactiveViewColor", LC_RGBA(69, 69, 69, 255)), // LC_PROFILE_INACTIVE_VIEW_COLOR lcProfileEntry("Settings", "DrawEdgeLines", 1), // LC_PROFILE_DRAW_EDGE_LINES lcProfileEntry("Settings", "DrawConditionalLines", 1), // LC_PROFILE_DRAW_CONDITIONAL_LINES lcProfileEntry("Settings", "GridStuds", 1), // LC_PROFILE_GRID_STUDS lcProfileEntry("Settings", "GridStudColor", LC_RGBA(24, 24, 24, 192)), // LC_PROFILE_GRID_STUD_COLOR lcProfileEntry("Settings", "GridLines", 1), // LC_PROFILE_GRID_LINES lcProfileEntry("Settings", "GridLineSpacing", 5), // LC_PROFILE_GRID_LINE_SPACING lcProfileEntry("Settings", "GridLineColor", LC_RGBA(24, 24, 24, 255)), // LC_PROFILE_GRID_LINE_COLOR lcProfileEntry("Settings", "GridOrigin", 0), // LC_PROFILE_GRID_ORIGIN lcProfileEntry("Settings", "AASamples", 1), // LC_PROFILE_ANTIALIASING_SAMPLES lcProfileEntry("Settings", "ViewSphereEnabled", 1), // LC_PROFILE_VIEW_SPHERE_ENABLED lcProfileEntry("Settings", "ViewSphereLocation", (int)lcViewSphereLocation::TopRight), // LC_PROFILE_VIEW_SPHERE_LOCATION lcProfileEntry("Settings", "ViewSphereSize", 100), // LC_PROFILE_VIEW_SPHERE_SIZE lcProfileEntry("Settings", "ViewSphereColor", LC_RGBA(35, 38, 41, 255)), // LC_PROFILE_VIEW_SPHERE_COLOR lcProfileEntry("Settings", "ViewSphereTextColor", LC_RGBA(224, 224, 224, 255)), // LC_PROFILE_VIEW_SPHERE_TEXT_COLOR lcProfileEntry("Settings", "ViewSphereHighlightColor", LC_RGBA(41, 128, 185, 255)), // LC_PROFILE_VIEW_SPHERE_HIGHLIGHT_COLOR lcProfileEntry("Settings", "ObjectSelectedColor", static_cast(LC_RGBA(229, 76, 102, 255))), // LC_PROFILE_OBJECT_SELECTED_COLOR lcProfileEntry("Settings", "ObjectFocusedColor", static_cast(LC_RGBA(102, 76, 229, 255))), // LC_PROFILE_OBJECT_FOCUSED_COLOR lcProfileEntry("Settings", "CameraColor", static_cast(LC_RGBA(128, 204, 128, 255))), // LC_PROFILE_CAMERA_COLOR lcProfileEntry("Settings", "LightColor", static_cast(LC_RGBA(128, 204, 128, 255))), // LC_PROFILE_LIGHT_COLOR lcProfileEntry("Settings", "ControlPointColor", static_cast(LC_RGBA(128, 204, 128, 128))), // LC_PROFILE_CONTROL_POINT_COLOR lcProfileEntry("Settings", "ControlPointFocusedColor", static_cast(LC_RGBA(102, 76, 229, 128))), // LC_PROFILE_CONTROL_POINT_FOCUSED_COLOR lcProfileEntry("Settings", "Language", ""), // LC_PROFILE_LANGUAGE lcProfileEntry("Settings", "ColorTheme", static_cast(lcColorTheme::Dark)), // LC_PROFILE_COLOR_THEME lcProfileEntry("Settings", "CheckUpdates", 1), // LC_PROFILE_CHECK_UPDATES lcProfileEntry("Settings", "ProjectsPath", ""), // LC_PROFILE_PROJECTS_PATH lcProfileEntry("Settings", "PartsLibrary", ""), // LC_PROFILE_PARTS_LIBRARY lcProfileEntry("Settings", "PartPalettes"), // LC_PROFILE_PART_PALETTES lcProfileEntry("Settings", "MinifigSettings", ""), // LC_PROFILE_MINIFIG_SETTINGS lcProfileEntry("Settings", "ColorConfig", ""), // LC_PROFILE_COLOR_CONFIG lcProfileEntry("Settings", "Shortcuts"), // LC_PROFILE_KEYBOARD_SHORTCUTS lcProfileEntry("Settings", "MouseShortcuts", QStringList()), // LC_PROFILE_MOUSE_SHORTCUTS lcProfileEntry("Settings", "Categories"), // LC_PROFILE_CATEGORIES lcProfileEntry("Settings", "RecentFile1", ""), // LC_PROFILE_RECENT_FILE1 lcProfileEntry("Settings", "RecentFile2", ""), // LC_PROFILE_RECENT_FILE2 lcProfileEntry("Settings", "RecentFile3", ""), // LC_PROFILE_RECENT_FILE3 lcProfileEntry("Settings", "RecentFile4", ""), // LC_PROFILE_RECENT_FILE4 lcProfileEntry("Settings", "AutoLoadMostRecent", false), // LC_PROFILE_AUTOLOAD_MOSTRECENT lcProfileEntry("Settings", "RestoreTabLayout", true), // LC_PROFILE_RESTORE_TAB_LAYOUT lcProfileEntry("Settings", "AutosaveInterval", 10), // LC_PROFILE_AUTOSAVE_INTERVAL lcProfileEntry("Settings", "MouseSensitivity", 11), // LC_PROFILE_MOUSE_SENSITIVITY lcProfileEntry("Settings", "ImageWidth", 1280), // LC_PROFILE_IMAGE_WIDTH lcProfileEntry("Settings", "ImageHeight", 720), // LC_PROFILE_IMAGE_HEIGHT lcProfileEntry("Settings", "ImageExtension", ".png"), // LC_PROFILE_IMAGE_EXTENSION lcProfileEntry("Settings", "PartsListIcons", 64), // LC_PROFILE_PARTS_LIST_ICONS lcProfileEntry("Settings", "PartsListNames", 0), // LC_PROFILE_PARTS_LIST_NAMES lcProfileEntry("Settings", "PartsListFixedColor", -1), // LC_PROFILE_PARTS_LIST_FIXED_COLOR lcProfileEntry("Settings", "PartsListDecorated", 1), // LC_PROFILE_PARTS_LIST_DECORATED lcProfileEntry("Settings", "PartsListAliases", 1), // LC_PROFILE_PARTS_LIST_ALIASES lcProfileEntry("Settings", "PartsListListMode", 0), // LC_PROFILE_PARTS_LIST_LISTMODE lcProfileEntry("Settings", "StudStyle", 0), // LC_PROFILE_STUD_STYLE lcProfileEntry("Defaults", "Author", ""), // LC_PROFILE_DEFAULT_AUTHOR_NAME lcProfileEntry("Defaults", "AmbientColor", LC_RGB(75, 75, 75)), // LC_PROFILE_DEFAULT_AMBIENT_COLOR lcProfileEntry("HTML", "Options", LC_HTML_SINGLEPAGE), // LC_PROFILE_HTML_OPTIONS lcProfileEntry("HTML", "ImageOptions", LC_IMAGE_TRANSPARENT), // LC_PROFILE_HTML_IMAGE_OPTIONS lcProfileEntry("HTML", "ImageWidth", 640), // LC_PROFILE_HTML_IMAGE_WIDTH lcProfileEntry("HTML", "ImageHeight", 480), // LC_PROFILE_HTML_IMAGE_HEIGHT lcProfileEntry("POVRay", "Path", "/usr/bin/povray"), // LC_PROFILE_POVRAY_PATH lcProfileEntry("POVRay", "LGEOPath", ""), // LC_PROFILE_POVRAY_LGEO_PATH lcProfileEntry("POVRay", "Width", 1280), // LC_PROFILE_POVRAY_WIDTH lcProfileEntry("POVRay", "Height", 720), // LC_PROFILE_POVRAY_HEIGHT lcProfileEntry("Settgins", "PreviewViewSphereEnabled", 0), // LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED lcProfileEntry("Settings", "PreviewViewSphereSize", 75), // LC_PROFILE_PREVIEW_VIEW_SPHERE_SIZE lcProfileEntry("Settings", "PreviewViewSphereLocation", (int)lcViewSphereLocation::TopRight), // LC_PROFILE_PREVIEW_VIEW_SPHERE_LOCATION lcProfileEntry("Settings", "DrawPreviewAxis", 0), // LC_PROFILE_PREVIEW_DRAW_AXES lcProfileEntry("Settings", "StudCylinderColor", LC_RGBA(27, 42, 52, 255)), // LC_PROFILE_STUD_CYLINDER_COLOR lcProfileEntry("Settings", "PartEdgeColor", LC_RGBA(0, 0, 0, 255)), // LC_PROFILE_PART_EDGE_COLOR lcProfileEntry("Settings", "BlackEdgeColor", LC_RGBA(255, 255, 255, 255)), // LC_PROFILE_BLACK_EDGE_COLOR lcProfileEntry("Settings", "DarkEdgeColor", LC_RGBA(27, 42, 52, 255)), // LC_PROFILE_DARK_EDGE_COLOR lcProfileEntry("Settings", "PartEdgeContrast", 0.5f), // LC_PROFILE_PART_EDGE_CONTRAST lcProfileEntry("Settings", "mPartColorValueLDIndex", 0.5f), // LC_PROFILE_PART_COLOR_VALUE_LD_INDEX lcProfileEntry("Settings", "AutomateEdgeColor", 0) // LC_PROFILE_AUTOMATE_EDGE_COLOR }; void lcRemoveProfileKey(LC_PROFILE_KEY Key) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; Settings.remove(QString("%1/%2").arg(Entry.mSection, Entry.mKey)); } int lcGetProfileInt(LC_PROFILE_KEY Key) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; return Settings.value(QString("%1/%2").arg(Entry.mSection, Entry.mKey), Entry.mDefault.IntValue).toInt(); } uint lcGetProfileUInt(LC_PROFILE_KEY Key) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; return Settings.value(QString("%1/%2").arg(Entry.mSection, Entry.mKey), Entry.mDefault.UIntValue).toUInt(); } float lcGetProfileFloat(LC_PROFILE_KEY Key) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; return Settings.value(QString("%1/%2").arg(Entry.mSection, Entry.mKey), Entry.mDefault.FloatValue).toFloat(); } QString lcGetProfileString(LC_PROFILE_KEY Key) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; return Settings.value(QString("%1/%2").arg(Entry.mSection, Entry.mKey), Entry.mDefault.StringValue).toString(); } QStringList lcGetProfileStringList(LC_PROFILE_KEY Key) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; return Settings.value(QString("%1/%2").arg(Entry.mSection, Entry.mKey), QStringList()).toStringList(); } QByteArray lcGetProfileBuffer(LC_PROFILE_KEY Key) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; return Settings.value(QString("%1/%2").arg(Entry.mSection, Entry.mKey)).toByteArray(); } void lcSetProfileInt(LC_PROFILE_KEY Key, int Value) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; Settings.setValue(QString("%1/%2").arg(Entry.mSection, Entry.mKey), Value); } void lcSetProfileUInt(LC_PROFILE_KEY Key, uint Value) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; Settings.setValue(QString("%1/%2").arg(Entry.mSection, Entry.mKey), Value); } void lcSetProfileFloat(LC_PROFILE_KEY Key, float Value) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; Settings.setValue(QString("%1/%2").arg(Entry.mSection, Entry.mKey), Value); } void lcSetProfileString(LC_PROFILE_KEY Key, const QString& Value) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; Settings.setValue(QString("%1/%2").arg(Entry.mSection, Entry.mKey), Value); } void lcSetProfileStringList(LC_PROFILE_KEY Key, const QStringList& Value) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; Settings.setValue(QString("%1/%2").arg(Entry.mSection, Entry.mKey), Value); } void lcSetProfileBuffer(LC_PROFILE_KEY Key, const QByteArray& Buffer) { lcProfileEntry& Entry = gProfileEntries[Key]; QSettings Settings; Settings.setValue(QString("%1/%2").arg(Entry.mSection, Entry.mKey), Buffer); } leocad-23.03/common/lc_profile.h000066400000000000000000000105371440571307300165410ustar00rootroot00000000000000#pragma once enum LC_PROFILE_KEY { // Settings. LC_PROFILE_FIXED_AXES, LC_PROFILE_LINE_WIDTH, LC_PROFILE_ALLOW_LOD, LC_PROFILE_LOD_DISTANCE, LC_PROFILE_FADE_STEPS, LC_PROFILE_FADE_STEPS_COLOR, LC_PROFILE_HIGHLIGHT_NEW_PARTS, LC_PROFILE_HIGHLIGHT_NEW_PARTS_COLOR, LC_PROFILE_SHADING_MODE, LC_PROFILE_BACKGROUND_GRADIENT, LC_PROFILE_BACKGROUND_COLOR, LC_PROFILE_GRADIENT_COLOR_TOP, LC_PROFILE_GRADIENT_COLOR_BOTTOM, LC_PROFILE_DRAW_AXES, LC_PROFILE_DRAW_AXES_LOCATION, LC_PROFILE_AXES_COLOR, LC_PROFILE_TEXT_COLOR, LC_PROFILE_MARQUEE_BORDER_COLOR, LC_PROFILE_MARQUEE_FILL_COLOR, LC_PROFILE_OVERLAY_COLOR, LC_PROFILE_ACTIVE_VIEW_COLOR, LC_PROFILE_INACTIVE_VIEW_COLOR, LC_PROFILE_DRAW_EDGE_LINES, LC_PROFILE_DRAW_CONDITIONAL_LINES, LC_PROFILE_GRID_STUDS, LC_PROFILE_GRID_STUD_COLOR, LC_PROFILE_GRID_LINES, LC_PROFILE_GRID_LINE_SPACING, LC_PROFILE_GRID_LINE_COLOR, LC_PROFILE_GRID_ORIGIN, LC_PROFILE_ANTIALIASING_SAMPLES, LC_PROFILE_VIEW_SPHERE_ENABLED, LC_PROFILE_VIEW_SPHERE_LOCATION, LC_PROFILE_VIEW_SPHERE_SIZE, LC_PROFILE_VIEW_SPHERE_COLOR, LC_PROFILE_VIEW_SPHERE_TEXT_COLOR, LC_PROFILE_VIEW_SPHERE_HIGHLIGHT_COLOR, LC_PROFILE_OBJECT_SELECTED_COLOR, LC_PROFILE_OBJECT_FOCUSED_COLOR, LC_PROFILE_CAMERA_COLOR, LC_PROFILE_LIGHT_COLOR, LC_PROFILE_CONTROL_POINT_COLOR, LC_PROFILE_CONTROL_POINT_FOCUSED_COLOR, LC_PROFILE_LANGUAGE, LC_PROFILE_COLOR_THEME, LC_PROFILE_CHECK_UPDATES, LC_PROFILE_PROJECTS_PATH, LC_PROFILE_PARTS_LIBRARY, LC_PROFILE_PART_PALETTES, LC_PROFILE_MINIFIG_SETTINGS, LC_PROFILE_COLOR_CONFIG, LC_PROFILE_KEYBOARD_SHORTCUTS, LC_PROFILE_MOUSE_SHORTCUTS, LC_PROFILE_CATEGORIES, LC_PROFILE_RECENT_FILE1, LC_PROFILE_RECENT_FILE2, LC_PROFILE_RECENT_FILE3, LC_PROFILE_RECENT_FILE4, LC_PROFILE_AUTOLOAD_MOSTRECENT, LC_PROFILE_RESTORE_TAB_LAYOUT, LC_PROFILE_AUTOSAVE_INTERVAL, LC_PROFILE_MOUSE_SENSITIVITY, LC_PROFILE_IMAGE_WIDTH, LC_PROFILE_IMAGE_HEIGHT, LC_PROFILE_IMAGE_EXTENSION, LC_PROFILE_PARTS_LIST_ICONS, LC_PROFILE_PARTS_LIST_NAMES, LC_PROFILE_PARTS_LIST_COLOR, LC_PROFILE_PARTS_LIST_DECORATED, LC_PROFILE_PARTS_LIST_ALIASES, LC_PROFILE_PARTS_LIST_LISTMODE, LC_PROFILE_STUD_STYLE, // Defaults for new projects. LC_PROFILE_DEFAULT_AUTHOR_NAME, LC_PROFILE_DEFAULT_AMBIENT_COLOR, // Exporters. LC_PROFILE_HTML_OPTIONS, LC_PROFILE_HTML_IMAGE_OPTIONS, LC_PROFILE_HTML_IMAGE_WIDTH, LC_PROFILE_HTML_IMAGE_HEIGHT, LC_PROFILE_POVRAY_PATH, LC_PROFILE_POVRAY_LGEO_PATH, LC_PROFILE_POVRAY_WIDTH, LC_PROFILE_POVRAY_HEIGHT, LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED, LC_PROFILE_PREVIEW_VIEW_SPHERE_SIZE, LC_PROFILE_PREVIEW_VIEW_SPHERE_LOCATION, LC_PROFILE_PREVIEW_DRAW_AXES, LC_PROFILE_STUD_CYLINDER_COLOR, LC_PROFILE_PART_EDGE_COLOR, LC_PROFILE_BLACK_EDGE_COLOR, LC_PROFILE_DARK_EDGE_COLOR, LC_PROFILE_PART_EDGE_CONTRAST, LC_PROFILE_PART_COLOR_VALUE_LD_INDEX, LC_PROFILE_AUTOMATE_EDGE_COLOR, LC_NUM_PROFILE_KEYS }; enum LC_PROFILE_ENTRY_TYPE { LC_PROFILE_ENTRY_INT, LC_PROFILE_ENTRY_FLOAT, LC_PROFILE_ENTRY_STRING, LC_PROFILE_ENTRY_STRINGLIST, LC_PROFILE_ENTRY_BUFFER }; class lcProfileEntry { public: lcProfileEntry(const char* Section, const char* Key, int DefaultValue); lcProfileEntry(const char* Section, const char* Key, uint DefaultValue); lcProfileEntry(const char* Section, const char* Key, float DefaultValue); lcProfileEntry(const char* Section, const char* Key, const char* DefaultValue); lcProfileEntry(const char* Section, const char* Key, const QStringList& StringList); lcProfileEntry(const char* Section, const char* Key); LC_PROFILE_ENTRY_TYPE mType; const char* mSection; const char* mKey; union { int IntValue; uint UIntValue; float FloatValue; const char* StringValue; } mDefault; }; void lcRemoveProfileKey(LC_PROFILE_KEY Key); int lcGetProfileInt(LC_PROFILE_KEY Key); uint lcGetProfileUInt(LC_PROFILE_KEY Key); float lcGetProfileFloat(LC_PROFILE_KEY Key); QString lcGetProfileString(LC_PROFILE_KEY Key); QStringList lcGetProfileStringList(LC_PROFILE_KEY Key); QByteArray lcGetProfileBuffer(LC_PROFILE_KEY Key); void lcSetProfileInt(LC_PROFILE_KEY Key, int Value); void lcSetProfileUInt(LC_PROFILE_KEY Key, uint Value); void lcSetProfileFloat(LC_PROFILE_KEY Key, float Value); void lcSetProfileString(LC_PROFILE_KEY Key, const QString& Value); void lcSetProfileStringList(LC_PROFILE_KEY Key, const QStringList& Value); void lcSetProfileBuffer(LC_PROFILE_KEY Key, const QByteArray& Buffer); leocad-23.03/common/lc_scene.cpp000066400000000000000000000377771440571307300165500ustar00rootroot00000000000000#include "lc_global.h" #include "lc_scene.h" #include "lc_context.h" #include "pieceinf.h" #include "lc_texture.h" #include "lc_library.h" #include "lc_application.h" #include "object.h" lcScene::lcScene() : mRenderMeshes(0, 1024), mOpaqueMeshes(0, 1024), mTranslucentMeshes(0, 1024), mInterfaceObjects(0, 1024) { mActiveSubmodelInstance = nullptr; mDrawInterface = false; mShadingMode = lcShadingMode::DefaultLights; mAllowLOD = true; mMeshLODDistance = 250.0f; mHasFadedParts = false; mPreTranslucentCallback = nullptr; } void lcScene::Begin(const lcMatrix44& ViewMatrix) { mViewMatrix = ViewMatrix; mActiveSubmodelInstance = nullptr; mPreTranslucentCallback = nullptr; mRenderMeshes.RemoveAll(); mOpaqueMeshes.RemoveAll(); mTranslucentMeshes.RemoveAll(); mInterfaceObjects.RemoveAll(); const lcPreferences& Preferences = lcGetPreferences(); mHighlightColor = lcVector4FromColor(Preferences.mHighlightNewPartsColor); mFadeColor = lcVector4FromColor(Preferences.mFadeStepsColor); mHasFadedParts = false; mTranslucentFade = mFadeColor.w != 1.0f; } void lcScene::End() { const auto OpaqueMeshCompare = [this](int Index1, int Index2) { const lcMesh* Mesh1 = mRenderMeshes[Index1].Mesh; const lcMesh* Mesh2 = mRenderMeshes[Index2].Mesh; const int Texture1 = Mesh1->mFlags & lcMeshFlag::HasTexture; const int Texture2 = Mesh2->mFlags & lcMeshFlag::HasTexture; if (Texture1 == Texture2) return Mesh1 < Mesh2; return Texture1 ? false : true; }; std::sort(mOpaqueMeshes.begin(), mOpaqueMeshes.end(), OpaqueMeshCompare); auto TranslucentMeshCompare = [](const lcTranslucentMeshInstance& Mesh1, const lcTranslucentMeshInstance& Mesh2) { return Mesh1.Distance > Mesh2.Distance; }; std::sort(mTranslucentMeshes.begin(), mTranslucentMeshes.end(), TranslucentMeshCompare); } void lcScene::AddMesh(lcMesh* Mesh, const lcMatrix44& WorldMatrix, int ColorIndex, lcRenderMeshState State) { lcRenderMesh& RenderMesh = mRenderMeshes.Add(); RenderMesh.WorldMatrix = WorldMatrix; RenderMesh.Mesh = Mesh; RenderMesh.ColorIndex = ColorIndex; RenderMesh.State = State; const float Distance = fabsf(lcMul31(WorldMatrix[3], mViewMatrix).z) - mMeshLODDistance; RenderMesh.LodIndex = mAllowLOD ? RenderMesh.Mesh->GetLodIndex(Distance) : LC_MESH_LOD_HIGH; const bool ForceTranslucent = (mTranslucentFade && State == lcRenderMeshState::Faded); const bool Translucent = lcIsColorTranslucent(ColorIndex) || ForceTranslucent; const lcMeshFlags Flags = Mesh->mFlags; mHasFadedParts |= State == lcRenderMeshState::Faded; if ((Flags & (lcMeshFlag::HasSolid | lcMeshFlag::HasLines)) || ((Flags & lcMeshFlag::HasDefault) && !Translucent)) mOpaqueMeshes.Add(mRenderMeshes.GetSize() - 1); if ((Flags & lcMeshFlag::HasTranslucent) || ((Flags & lcMeshFlag::HasDefault) && Translucent)) { const lcMeshLod& Lod = Mesh->mLods[RenderMesh.LodIndex]; for (int SectionIdx = 0; SectionIdx < Lod.NumSections; SectionIdx++) { const lcMeshSection* Section = &Lod.Sections[SectionIdx]; if ((Section->PrimitiveType & (LC_MESH_TRIANGLES | LC_MESH_TEXTURED_TRIANGLES)) == 0) continue; int SectionColorIndex = Section->ColorIndex; if (SectionColorIndex == gDefaultColor) SectionColorIndex = RenderMesh.ColorIndex; if (!lcIsColorTranslucent(SectionColorIndex) && !ForceTranslucent) continue; const lcVector3 Center = (Section->BoundingBox.Min + Section->BoundingBox.Max) / 2; const float InstanceDistance = fabsf(lcMul31(lcMul31(Center, WorldMatrix), mViewMatrix).z); lcTranslucentMeshInstance& Instance = mTranslucentMeshes.Add(); Instance.Section = Section; Instance.Distance = InstanceDistance; Instance.RenderMeshIndex = mRenderMeshes.GetSize() - 1; } } } void lcScene::DrawDebugNormals(lcContext* Context, const lcMesh* Mesh) const { const lcVertex* const VertexBuffer = Mesh->GetVertexData(); const lcVertexTextured* const TexturedVertexBuffer = Mesh->GetTexturedVertexData(); lcVector3* const Vertices = (lcVector3*)malloc((Mesh->mNumVertices + Mesh->mNumTexturedVertices) * 2 * sizeof(lcVector3)); for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++) { Vertices[VertexIdx * 2] = VertexBuffer[VertexIdx].Position; Vertices[VertexIdx * 2 + 1] = VertexBuffer[VertexIdx].Position + lcUnpackNormal(VertexBuffer[VertexIdx].Normal); } for (int VertexIdx = 0; VertexIdx < Mesh->mNumTexturedVertices; VertexIdx++) { Vertices[(Mesh->mNumVertices + VertexIdx) * 2] = TexturedVertexBuffer[VertexIdx].Position; Vertices[(Mesh->mNumVertices + VertexIdx) * 2 + 1] = TexturedVertexBuffer[VertexIdx].Position + lcUnpackNormal(TexturedVertexBuffer[VertexIdx].Normal); } Context->SetVertexBufferPointer(Vertices); Context->SetVertexFormatPosition(3); Context->DrawPrimitives(GL_LINES, 0, (Mesh->mNumVertices + Mesh->mNumTexturedVertices) * 2); free(Vertices); } void lcScene::DrawOpaqueMeshes(lcContext* Context, bool DrawLit, int PrimitiveTypes, bool DrawFaded, bool DrawNonFaded) const { if (mOpaqueMeshes.IsEmpty()) return; lcMaterialType FlatMaterial, TexturedMaterial; if (DrawLit) { FlatMaterial = lcMaterialType::FakeLitColor; TexturedMaterial = lcMaterialType::FakeLitTextureDecal; } else { FlatMaterial = lcMaterialType::UnlitColor; TexturedMaterial = lcMaterialType::UnlitTextureDecal; } Context->SetPolygonOffset(lcPolygonOffset::Opaque); const lcPreferences& Preferences = lcGetPreferences(); const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor); const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor); for (const int MeshIndex : mOpaqueMeshes) { const lcRenderMesh& RenderMesh = mRenderMeshes[MeshIndex]; const lcMesh* Mesh = RenderMesh.Mesh; const int LodIndex = RenderMesh.LodIndex; if (!DrawFaded && RenderMesh.State == lcRenderMeshState::Faded) continue; if (!DrawNonFaded && RenderMesh.State != lcRenderMeshState::Faded) continue; Context->BindMesh(Mesh); Context->SetWorldMatrix(RenderMesh.WorldMatrix); for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LodIndex].NumSections; SectionIdx++) { const lcMeshSection* const Section = &Mesh->mLods[LodIndex].Sections[SectionIdx]; if ((Section->PrimitiveType & PrimitiveTypes) == 0) continue; int ColorIndex = Section->ColorIndex; if (Section->PrimitiveType & (LC_MESH_TRIANGLES | LC_MESH_TEXTURED_TRIANGLES)) { if (ColorIndex == gDefaultColor) ColorIndex = RenderMesh.ColorIndex; if (lcIsColorTranslucent(ColorIndex)) continue; switch (RenderMesh.State) { case lcRenderMeshState::Default: case lcRenderMeshState::Highlighted: Context->SetColorIndex(ColorIndex); break; case lcRenderMeshState::Selected: Context->SetColorIndexTinted(ColorIndex, SelectedColor, 0.5f); break; case lcRenderMeshState::Focused: Context->SetColorIndexTinted(ColorIndex, FocusedColor, 0.5f); break; case lcRenderMeshState::Faded: if (mTranslucentFade) continue; Context->SetColorIndexTinted(ColorIndex, mFadeColor); break; } } else if (Section->PrimitiveType & (LC_MESH_LINES | LC_MESH_CONDITIONAL_LINES)) { switch (RenderMesh.State) { case lcRenderMeshState::Default: if (mShadingMode != lcShadingMode::Wireframe) { if (ColorIndex != gEdgeColor) Context->SetColorIndex(ColorIndex); else Context->SetEdgeColorIndex(RenderMesh.ColorIndex); } else { if (ColorIndex == gEdgeColor) ColorIndex = RenderMesh.ColorIndex; Context->SetColorIndex(ColorIndex); } break; case lcRenderMeshState::Selected: Context->SetColor(SelectedColor); break; case lcRenderMeshState::Focused: Context->SetColor(FocusedColor); break; case lcRenderMeshState::Highlighted: Context->SetColor(mHighlightColor); break; case lcRenderMeshState::Faded: Context->SetEdgeColorIndexTinted(ColorIndex, mFadeColor); break; } if (Section->PrimitiveType == LC_MESH_CONDITIONAL_LINES) { int VertexBufferOffset = Mesh->mVertexCacheOffset != -1 ? Mesh->mVertexCacheOffset : 0; VertexBufferOffset += Mesh->mNumVertices * sizeof(lcVertex) + Mesh->mNumTexturedVertices * sizeof(lcVertexTextured); const int IndexBufferOffset = Mesh->mIndexCacheOffset != -1 ? Mesh->mIndexCacheOffset : 0; Context->SetMaterial(lcMaterialType::UnlitColorConditional); Context->SetVertexFormatConditional(VertexBufferOffset); Context->DrawIndexedPrimitives(GL_LINES, Section->NumIndices, Mesh->mIndexType, IndexBufferOffset + Section->IndexOffset); continue; } } int VertexBufferOffset = Mesh->mVertexCacheOffset != -1 ? Mesh->mVertexCacheOffset : 0; const int IndexBufferOffset = Mesh->mIndexCacheOffset != -1 ? Mesh->mIndexCacheOffset : 0; if (Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) { Context->SetMaterial(FlatMaterial); Context->SetVertexFormat(VertexBufferOffset, 3, 1, 0, 0, DrawLit); } else { lcTexture* const Texture = Section->Texture; if (Texture) { if (Texture->NeedsUpload()) Texture->Upload(Context); Context->SetMaterial(TexturedMaterial); Context->BindTexture2D(Texture); } else { Context->SetMaterial(FlatMaterial); } VertexBufferOffset += Mesh->mNumVertices * sizeof(lcVertex); Context->SetVertexFormat(VertexBufferOffset, 3, 1, 2, 0, DrawLit); } const GLenum DrawPrimitiveType = Section->PrimitiveType & (LC_MESH_TRIANGLES | LC_MESH_TEXTURED_TRIANGLES) ? GL_TRIANGLES : GL_LINES; Context->DrawIndexedPrimitives(DrawPrimitiveType, Section->NumIndices, Mesh->mIndexType, IndexBufferOffset + Section->IndexOffset); } #ifdef LC_DEBUG_NORMALS DrawDebugNormals(Context, Mesh); #endif } Context->ClearTexture2D(); Context->SetPolygonOffset(lcPolygonOffset::None); } void lcScene::DrawTranslucentMeshes(lcContext* Context, bool DrawLit, bool DrawFadePrepass, bool DrawFaded, bool DrawNonFaded) const { if (mTranslucentMeshes.IsEmpty()) return; lcMaterialType FlatMaterial, TexturedMaterial; if (DrawLit) { FlatMaterial = lcMaterialType::FakeLitColor; TexturedMaterial = lcMaterialType::FakeLitTextureDecal; } else { FlatMaterial = lcMaterialType::UnlitColor; TexturedMaterial = lcMaterialType::UnlitTextureDecal; } if (!DrawFadePrepass) { Context->EnableColorBlend(true); Context->SetDepthWrite(false); } else Context->EnableColorWrite(false); Context->SetPolygonOffset(lcPolygonOffset::Translucent); const lcPreferences& Preferences = lcGetPreferences(); const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor); const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor); for (const lcTranslucentMeshInstance& MeshInstance : mTranslucentMeshes) { const lcRenderMesh& RenderMesh = mRenderMeshes[MeshInstance.RenderMeshIndex]; const lcMesh* Mesh = RenderMesh.Mesh; if (!DrawFaded && RenderMesh.State == lcRenderMeshState::Faded) continue; if (!DrawNonFaded && RenderMesh.State != lcRenderMeshState::Faded) continue; Context->BindMesh(Mesh); Context->SetWorldMatrix(RenderMesh.WorldMatrix); const lcMeshSection* Section = MeshInstance.Section; int ColorIndex = Section->ColorIndex; if (ColorIndex == gDefaultColor) ColorIndex = RenderMesh.ColorIndex; if (DrawFadePrepass && lcIsColorTranslucent(ColorIndex)) continue; switch (RenderMesh.State) { case lcRenderMeshState::Default: case lcRenderMeshState::Highlighted: Context->SetColorIndex(ColorIndex); break; case lcRenderMeshState::Selected: Context->SetColorIndexTinted(ColorIndex, SelectedColor, 0.5f); break; case lcRenderMeshState::Focused: Context->SetColorIndexTinted(ColorIndex, FocusedColor, 0.5f); break; case lcRenderMeshState::Faded: Context->SetColorIndexTinted(ColorIndex, mFadeColor); break; } lcTexture* const Texture = Section->Texture; int VertexBufferOffset = Mesh->mVertexCacheOffset != -1 ? Mesh->mVertexCacheOffset : 0; const int IndexBufferOffset = Mesh->mIndexCacheOffset != -1 ? Mesh->mIndexCacheOffset : 0; if (!Texture) { Context->SetMaterial(FlatMaterial); Context->SetVertexFormat(VertexBufferOffset, 3, 1, 0, 0, DrawLit); } else { if (Texture->NeedsUpload()) Texture->Upload(Context); Context->SetMaterial(TexturedMaterial); VertexBufferOffset += Mesh->mNumVertices * sizeof(lcVertex); Context->SetVertexFormat(VertexBufferOffset, 3, 1, 2, 0, DrawLit); Context->BindTexture2D(Texture); } const GLenum DrawPrimitiveType = Section->PrimitiveType & (LC_MESH_TRIANGLES | LC_MESH_TEXTURED_TRIANGLES) ? GL_TRIANGLES : GL_LINES; Context->DrawIndexedPrimitives(DrawPrimitiveType, Section->NumIndices, Mesh->mIndexType, IndexBufferOffset + Section->IndexOffset); #ifdef LC_DEBUG_NORMALS DrawDebugNormals(Context, Mesh); #endif } Context->ClearTexture2D(); Context->SetPolygonOffset(lcPolygonOffset::None); if (!DrawFadePrepass) { Context->SetDepthWrite(true); Context->EnableColorBlend(false); } else Context->EnableColorWrite(true); } void lcScene::Draw(lcContext* Context) const { // TODO: find a better place for these updates lcGetPiecesLibrary()->UpdateBuffers(Context); Context->SetViewMatrix(mViewMatrix); const lcPreferences& Preferences = lcGetPreferences(); const bool DrawLines = Preferences.mDrawEdgeLines && Preferences.mLineWidth > 0.0f; const bool DrawConditional = Preferences.mDrawConditionalLines && Preferences.mLineWidth > 0.0f; // lcShadingMode ShadingMode = Preferences.mShadingMode; // if (ShadingMode == lcShadingMode::Wireframe && !mAllowWireframe) // ShadingMode = lcShadingMode::Flat; if (mShadingMode == lcShadingMode::Wireframe) { DrawOpaqueMeshes(Context, false, LC_MESH_LINES, true, true); if (DrawConditional) DrawOpaqueMeshes(Context, false, LC_MESH_CONDITIONAL_LINES, true, true); if (mPreTranslucentCallback) mPreTranslucentCallback(); } else if (mShadingMode == lcShadingMode::Flat) { const int SolidPrimitiveTypes = LC_MESH_TRIANGLES | LC_MESH_TEXTURED_TRIANGLES | (DrawLines ? LC_MESH_LINES : 0); if (mTranslucentFade && mHasFadedParts) { DrawOpaqueMeshes(Context, false, SolidPrimitiveTypes, false, true); if (mPreTranslucentCallback) mPreTranslucentCallback(); DrawTranslucentMeshes(Context, false, true, true, false); if (DrawLines) DrawOpaqueMeshes(Context, false, LC_MESH_LINES, true, false); if (DrawConditional) DrawOpaqueMeshes(Context, false, LC_MESH_CONDITIONAL_LINES, true, false); DrawTranslucentMeshes(Context, false, false, true, true); } else { DrawOpaqueMeshes(Context, false, SolidPrimitiveTypes, true, true); if (DrawConditional) DrawOpaqueMeshes(Context, false, LC_MESH_CONDITIONAL_LINES, true, true); if (mPreTranslucentCallback) mPreTranslucentCallback(); DrawTranslucentMeshes(Context, false, false, true, true); } } else { if (mTranslucentFade && mHasFadedParts) { DrawOpaqueMeshes(Context, true, LC_MESH_TRIANGLES | LC_MESH_TEXTURED_TRIANGLES, false, true); if (DrawLines) DrawOpaqueMeshes(Context, false, LC_MESH_LINES, false, true); if (DrawConditional) DrawOpaqueMeshes(Context, false, LC_MESH_CONDITIONAL_LINES, false, true); if (mPreTranslucentCallback) mPreTranslucentCallback(); DrawTranslucentMeshes(Context, false, true, true, false); if (DrawLines) DrawOpaqueMeshes(Context, false, LC_MESH_LINES, true, false); if (DrawConditional) DrawOpaqueMeshes(Context, false, LC_MESH_CONDITIONAL_LINES, true, false); DrawTranslucentMeshes(Context, true, false, true, true); } else { if (DrawLines) DrawOpaqueMeshes(Context, false, LC_MESH_LINES, true, true); if (DrawConditional) DrawOpaqueMeshes(Context, false, LC_MESH_CONDITIONAL_LINES, true, true); DrawOpaqueMeshes(Context, true, LC_MESH_TRIANGLES | LC_MESH_TEXTURED_TRIANGLES, true, true); if (mPreTranslucentCallback) mPreTranslucentCallback(); DrawTranslucentMeshes(Context, true, false, true, true); } } } void lcScene::DrawInterfaceObjects(lcContext* Context) const { for (const lcObject* Object : mInterfaceObjects) Object->DrawInterface(Context, *this); } leocad-23.03/common/lc_scene.h000066400000000000000000000051121440571307300161670ustar00rootroot00000000000000#pragma once #include "lc_mesh.h" #include "lc_array.h" enum class lcRenderMeshState : int { Default, Selected, Focused, Faded, Highlighted }; struct lcRenderMesh { lcMatrix44 WorldMatrix; lcMesh* Mesh; int ColorIndex; int LodIndex; lcRenderMeshState State; }; struct lcTranslucentMeshInstance { const lcMeshSection* Section; int RenderMeshIndex; float Distance; }; class lcScene { public: lcScene(); void SetActiveSubmodelInstance(lcPiece* ActiveSubmodelInstance, const lcMatrix44& ActiveSubmodelTransform) { mActiveSubmodelInstance = ActiveSubmodelInstance; mActiveSubmodelTransform = ActiveSubmodelTransform; } lcPiece* GetActiveSubmodelInstance() const { return mActiveSubmodelInstance; } const lcMatrix44& GetViewMatrix() const { return mViewMatrix; } void SetDrawInterface(bool DrawInterface) { mDrawInterface = DrawInterface; } bool GetDrawInterface() const { return mDrawInterface; } void SetShadingMode(lcShadingMode ShadingMode) { mShadingMode = ShadingMode; } void SetAllowLOD(bool AllowLOD) { mAllowLOD = AllowLOD; } void SetLODDistance(float Distance) { mMeshLODDistance = Distance; } void SetPreTranslucentCallback(std::function Callback) { mPreTranslucentCallback = Callback; } lcMatrix44 ApplyActiveSubmodelTransform(const lcMatrix44& WorldMatrix) const { return !mActiveSubmodelInstance ? WorldMatrix : lcMul(WorldMatrix, mActiveSubmodelTransform); } void Begin(const lcMatrix44& ViewMatrix); void End(); void AddMesh(lcMesh* Mesh, const lcMatrix44& WorldMatrix, int ColorIndex, lcRenderMeshState State); void AddInterfaceObject(const lcObject* Object) { mInterfaceObjects.Add(Object); } void Draw(lcContext* Context) const; void DrawInterfaceObjects(lcContext* Context) const; protected: void DrawOpaqueMeshes(lcContext* Context, bool DrawLit, int PrimitiveTypes, bool DrawFaded, bool DrawNonFaded) const; void DrawTranslucentMeshes(lcContext* Context, bool DrawLit, bool DrawFadePrepass, bool DrawFaded, bool DrawNonFaded) const; void DrawDebugNormals(lcContext* Context, const lcMesh* Mesh) const; lcMatrix44 mViewMatrix; lcMatrix44 mActiveSubmodelTransform; lcPiece* mActiveSubmodelInstance; lcShadingMode mShadingMode; bool mDrawInterface; bool mAllowLOD; float mMeshLODDistance; lcVector4 mFadeColor; lcVector4 mHighlightColor; bool mHasFadedParts; bool mTranslucentFade; std::function mPreTranslucentCallback; lcArray mRenderMeshes; lcArray mOpaqueMeshes; lcArray mTranslucentMeshes; lcArray mInterfaceObjects; }; leocad-23.03/common/lc_shortcuts.cpp000066400000000000000000000146761440571307300175020ustar00rootroot00000000000000#include "lc_global.h" #include "lc_shortcuts.h" #include "lc_profile.h" lcKeyboardShortcuts gKeyboardShortcuts; lcMouseShortcuts gMouseShortcuts; void lcLoadDefaultKeyboardShortcuts() { QByteArray Buffer = lcGetProfileBuffer(LC_PROFILE_KEYBOARD_SHORTCUTS); QTextStream Stream(Buffer, QIODevice::ReadOnly); if (Buffer.isEmpty() || !gKeyboardShortcuts.Load(Stream)) gKeyboardShortcuts.Reset(); } void lcSaveDefaultKeyboardShortcuts() { QByteArray Buffer; QTextStream Stream(&Buffer, QIODevice::WriteOnly); gKeyboardShortcuts.Save(Stream); lcSetProfileBuffer(LC_PROFILE_KEYBOARD_SHORTCUTS, Buffer); } void lcResetDefaultKeyboardShortcuts() { gKeyboardShortcuts.Reset(); lcRemoveProfileKey(LC_PROFILE_KEYBOARD_SHORTCUTS); } void lcLoadDefaultMouseShortcuts() { QStringList Shortcuts = lcGetProfileStringList(LC_PROFILE_MOUSE_SHORTCUTS); if (Shortcuts.isEmpty() || !gMouseShortcuts.Load(Shortcuts)) gMouseShortcuts.Reset(); } void lcSaveDefaultMouseShortcuts() { QStringList Shortcuts; gMouseShortcuts.Save(Shortcuts); lcSetProfileStringList(LC_PROFILE_MOUSE_SHORTCUTS, Shortcuts); } void lcResetDefaultMouseShortcuts() { gMouseShortcuts.Reset(); lcRemoveProfileKey(LC_PROFILE_MOUSE_SHORTCUTS); } void lcKeyboardShortcuts::Reset() { for (int CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++) mShortcuts[CommandIdx] = gCommands[CommandIdx].DefaultShortcut; } bool lcKeyboardShortcuts::Save(const QString& FileName) { QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) return false; QTextStream Stream(&File); return Save(Stream); } bool lcKeyboardShortcuts::Save(QTextStream& Stream) { for (int CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++) { if (mShortcuts[CommandIdx].isEmpty()) continue; Stream << gCommands[CommandIdx].ID << QLatin1String("=") << mShortcuts[CommandIdx] << QLatin1String("\n"); } Stream.flush(); return true; } bool lcKeyboardShortcuts::Load(const QString& FileName) { QFile File(FileName); if (!File.open(QIODevice::ReadOnly)) return false; QTextStream Stream(&File); return Load(Stream); } bool lcKeyboardShortcuts::Load(QTextStream& Stream) { for (int CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++) mShortcuts[CommandIdx].clear(); for (QString Line = Stream.readLine(); !Line.isNull(); Line = Stream.readLine()) { int Equals = Line.indexOf('='); if (Equals == -1) continue; QString Key = Line.left(Equals); int CommandIdx; for (CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++) if (gCommands[CommandIdx].ID == Key) break; if (CommandIdx == LC_NUM_COMMANDS) continue; mShortcuts[CommandIdx] = Line.mid(Equals + 1); } return true; } void lcMouseShortcuts::Reset() { memset(mShortcuts, 0, sizeof(mShortcuts)); lcToolShortcut& RotateViewShortcut = mShortcuts[static_cast(lcTool::RotateView)]; RotateViewShortcut.Modifiers1 = Qt::AltModifier; RotateViewShortcut.Button1 = Qt::LeftButton; RotateViewShortcut.Modifiers2 = Qt::NoModifier; RotateViewShortcut.Button2 = Qt::RightButton; lcToolShortcut& PanShortcut = mShortcuts[static_cast(lcTool::Pan)]; PanShortcut.Modifiers1 = Qt::AltModifier; PanShortcut.Button1 = Qt::MiddleButton; PanShortcut.Modifiers2 = Qt::ShiftModifier; PanShortcut.Button2 = Qt::RightButton; lcToolShortcut& ZoomShortcut = mShortcuts[static_cast(lcTool::Zoom)]; ZoomShortcut.Modifiers1 = Qt::AltModifier; ZoomShortcut.Button1 = Qt::RightButton; } bool lcMouseShortcuts::Save(const QString& FileName) { QStringList Shortcuts; if (!Save(Shortcuts)) return false; QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) return false; QTextStream Stream(&File); for (const QString& Shortcut : Shortcuts) Stream << Shortcut << QLatin1String("\n"); Stream.flush(); return true; } bool lcMouseShortcuts::Save(QStringList& Shortcuts) { Shortcuts.clear(); for (int ToolIdx = 0; ToolIdx < static_cast(lcTool::Count); ToolIdx++) { int ButtonIndex1 = 0; for (int Button1 = mShortcuts[ToolIdx].Button1; Button1; Button1 >>= 1) ButtonIndex1++; if (!ButtonIndex1) continue; QString Shortcut = QKeySequence(mShortcuts[ToolIdx].Modifiers1 | (Qt::Key_0 + ButtonIndex1)).toString(QKeySequence::PortableText); int ButtonIndex2 = 0; for (int Button2 = mShortcuts[ToolIdx].Button2; Button2; Button2 >>= 1) ButtonIndex2++; if (ButtonIndex2) Shortcut += ',' + QKeySequence(mShortcuts[ToolIdx].Modifiers2 | (Qt::Key_0 + ButtonIndex2)).toString(QKeySequence::PortableText); Shortcuts << QString::fromLatin1(gToolNames[ToolIdx]) + QLatin1String("=") + Shortcut; } return true; } bool lcMouseShortcuts::Load(const QString& FileName) { QFile File(FileName); if (!File.open(QIODevice::ReadOnly)) return false; QTextStream Stream(&File); QStringList Lines; while (!Stream.atEnd()) Lines += Stream.readLine(); return Load(Lines); } bool lcMouseShortcuts::Load(const QStringList& FullShortcuts) { memset(mShortcuts, 0, sizeof(mShortcuts)); for (const QString& FullShortcut : FullShortcuts) { int Equals = FullShortcut.indexOf('='); if (Equals == -1) continue; QString Key = FullShortcut.left(Equals); int ToolIdx; for (ToolIdx = 0; ToolIdx < static_cast(lcTool::Count); ToolIdx++) if (Key == gToolNames[ToolIdx]) break; if (ToolIdx == static_cast(lcTool::Count)) continue; QStringList Shortcuts = FullShortcut.mid(Equals + 1).split(','); bool AddedShortcut = false; for (const QString& Shortcut : Shortcuts) { QKeySequence KeySequence(Shortcut); if (KeySequence.isEmpty()) continue; int ShortcutKey = KeySequence[0]; Qt::KeyboardModifiers Modifiers = (Qt::KeyboardModifier)(ShortcutKey & Qt::KeyboardModifierMask); Qt::MouseButton Button = (Qt::MouseButton)(1 << ((ShortcutKey & ~Qt::KeyboardModifierMask) - Qt::Key_0 - 1)); if (!AddedShortcut) { mShortcuts[ToolIdx].Modifiers1 = Modifiers; mShortcuts[ToolIdx].Button1 = Button; AddedShortcut = true; } else { mShortcuts[ToolIdx].Modifiers2 = Modifiers; mShortcuts[ToolIdx].Button2 = Button; } } } return true; } lcTool lcMouseShortcuts::GetTool(Qt::MouseButton Button, Qt::KeyboardModifiers Modifiers) const { for (int ToolIdx = 0; ToolIdx < static_cast(lcTool::Count); ToolIdx++) if ((mShortcuts[ToolIdx].Button1 == Button && mShortcuts[ToolIdx].Modifiers1 == Modifiers) || (mShortcuts[ToolIdx].Button2 == Button && mShortcuts[ToolIdx].Modifiers2 == Modifiers)) return (lcTool)ToolIdx; return lcTool::Count; } leocad-23.03/common/lc_shortcuts.h000066400000000000000000000021111440571307300171240ustar00rootroot00000000000000#pragma once #include "lc_commands.h" class lcKeyboardShortcuts { public: void Reset(); bool Save(const QString& FileName); bool Save(QTextStream& Stream); bool Load(const QString& FileName); bool Load(QTextStream& Stream); QString mShortcuts[LC_NUM_COMMANDS]; }; extern lcKeyboardShortcuts gKeyboardShortcuts; void lcLoadDefaultKeyboardShortcuts(); void lcSaveDefaultKeyboardShortcuts(); void lcResetDefaultKeyboardShortcuts(); class lcMouseShortcuts { public: void Reset(); bool Save(const QString& FileName); bool Save(QStringList& Shortcuts); bool Load(const QString& FileName); bool Load(const QStringList& Shortcuts); lcTool GetTool(Qt::MouseButton Button, Qt::KeyboardModifiers Modifiers) const; struct lcToolShortcut { Qt::KeyboardModifiers Modifiers1; Qt::MouseButton Button1; Qt::KeyboardModifiers Modifiers2; Qt::MouseButton Button2; }; lcToolShortcut mShortcuts[static_cast(lcTool::Count)]; }; extern lcMouseShortcuts gMouseShortcuts; void lcLoadDefaultMouseShortcuts(); void lcSaveDefaultMouseShortcuts(); void lcResetDefaultMouseShortcuts(); leocad-23.03/common/lc_stringcache.cpp000066400000000000000000000114761440571307300177310ustar00rootroot00000000000000#include "lc_global.h" #include "lc_stringcache.h" #include "lc_texture.h" #include "lc_context.h" lcStringCache gStringCache; lcStringCache::lcStringCache() : mTexture(nullptr) { } lcStringCache::~lcStringCache() { delete mTexture; } void lcStringCache::Initialize(lcContext* Context) { Q_UNUSED(Context); mTexture = new lcTexture(); } void lcStringCache::Reset() { delete mTexture; mTexture = nullptr; } void lcStringCache::CacheStrings(const QStringList& Strings) { bool Update = false; for (const QString& String : Strings) { if (mStrings.find(String) == mStrings.end()) { mStrings[String] = lcStringCacheEntry(); Update = true; } } if (!Update) return; Image TextureImage; TextureImage.Allocate(256, 256, lcPixelFormat::L8A8); QImage Image(128, 128, QImage::Format_ARGB32); QPainter Painter; QFont Font("Helvetica", 20); int DestX = 0, DestY = 0, DestHeight = 0; memset(TextureImage.mData, 0, TextureImage.mWidth * TextureImage.mHeight * 2); for (auto& Entry : mStrings) { QRect SourceRect; Painter.begin(&Image); Painter.fillRect(0, 0, Image.width(), Image.height(), QColor(0, 0, 0)); Painter.setBrush(QColor(255, 255, 255)); Painter.setPen(QColor(255, 255, 255)); Painter.setFont(Font); Painter.drawText(0, 0, Image.width(), Image.height(), 0, Entry.first, &SourceRect); Painter.end(); if (DestX + SourceRect.width() + 2 > TextureImage.mWidth) { DestX = 0; DestY += DestHeight + 2; DestHeight = 0; } lcStringCacheEntry& String = Entry.second; if (SourceRect.width() + 2 > TextureImage.mWidth || DestY + SourceRect.height() + 2 > TextureImage.mHeight || DestY + SourceRect.height() + 2 > TextureImage.mHeight) { memset(&String, 0, sizeof(String)); break; } String.Top = TextureImage.mHeight - DestY - 2; String.Bottom = String.Top - SourceRect.height() + 1; String.Left = DestX + 1; String.Right = String.Left + SourceRect.width() - 2; for (int y = SourceRect.top(); y < SourceRect.bottom(); y++) { unsigned char* Dest = TextureImage.mData + ((String.Top - y) * TextureImage.mWidth + String.Left) * 2; for (int x = SourceRect.left(); x < SourceRect.right(); x++) { *Dest = *(Dest + 1) = qRed(Image.pixel(x, y)); Dest += 2; } } DestX += SourceRect.width() + 2; DestHeight = qMax(DestHeight, SourceRect.height()); } mTexture->SetImage(std::move(TextureImage), LC_TEXTURE_LINEAR); } void lcStringCache::GetStringDimensions(int* cx, int* cy, const QString& String) const { const auto& Entry = mStrings.find(String); if (Entry != mStrings.end()) { const lcStringCacheEntry& FontString = Entry->second; *cx = FontString.Right - FontString.Left; *cy = FontString.Top - FontString.Bottom; } else *cx = *cy = 0; } void lcStringCache::DrawStrings(lcContext* Context, const lcMatrix44* Transforms, const QStringList& Strings) const { float* Verts = (float*)alloca(Strings.size() * 6 * 5 * sizeof(float)); float* Buffer = Verts; for (int StringIdx = 0; StringIdx < Strings.size(); StringIdx++) { const auto& Entry = mStrings.find(Strings[StringIdx]); if (Entry == mStrings.end()) continue; const lcStringCacheEntry& FontString = Entry->second; float u0 = (float)FontString.Left / (float)(mTexture->mWidth - 1); float u1 = (float)FontString.Right / (float)(mTexture->mWidth - 1); float v0 = (float)FontString.Bottom / (float)(mTexture->mHeight - 1); float v1 = (float)FontString.Top / (float)(mTexture->mHeight - 1); float Width = FontString.Right - FontString.Left; float Height = FontString.Top - FontString.Bottom; float Left = -Width / 2.0f; float Top = Height / 2.0f; float Z = 0.0f; lcVector3 Points[4] = { lcVector3(Left, Top, Z), lcVector3(Left, Top - Height, Z), lcVector3(Left + Width, Top - Height, Z), lcVector3(Left + Width, Top, Z), }; for (int PointIdx = 0; PointIdx < 4; PointIdx++) Points[PointIdx] = lcMul31(Points[PointIdx], Transforms[StringIdx]); *Buffer++ = Points[0].x; *Buffer++ = Points[0].y; *Buffer++ = Points[0].z; *Buffer++ = u0; *Buffer++ = v1; *Buffer++ = Points[1].x; *Buffer++ = Points[1].y; *Buffer++ = Points[1].z; *Buffer++ = u0; *Buffer++ = v0; *Buffer++ = Points[2].x; *Buffer++ = Points[2].y; *Buffer++ = Points[2].z; *Buffer++ = u1; *Buffer++ = v0; *Buffer++ = Points[2].x; *Buffer++ = Points[2].y; *Buffer++ = Points[2].z; *Buffer++ = u1; *Buffer++ = v0; *Buffer++ = Points[3].x; *Buffer++ = Points[3].y; *Buffer++ = Points[3].z; *Buffer++ = u1; *Buffer++ = v1; *Buffer++ = Points[0].x; *Buffer++ = Points[0].y; *Buffer++ = Points[0].z; *Buffer++ = u0; *Buffer++ = v1; } Context->SetVertexBufferPointer(Verts); Context->SetVertexFormat(0, 3, 0, 2, 0, false); Context->BindTexture2D(mTexture); Context->SetColor(0.0f, 0.0f, 0.0f, 1.0f); Context->DrawPrimitives(GL_TRIANGLES, 0, Strings.size() * 6); } leocad-23.03/common/lc_stringcache.h000066400000000000000000000010461440571307300173660ustar00rootroot00000000000000#pragma once struct lcStringCacheEntry { int Left, Right, Top, Bottom; }; class lcStringCache { public: lcStringCache(); ~lcStringCache(); void Initialize(lcContext* Context); void Reset(); void CacheStrings(const QStringList& Strings); void GetStringDimensions(int* cx, int* cy, const QString& String) const; void DrawStrings(lcContext* Context, const lcMatrix44* Transforms, const QStringList& Strings) const; protected: lcTexture* mTexture; std::map mStrings; }; extern lcStringCache gStringCache; leocad-23.03/common/lc_synth.cpp000066400000000000000000001710531440571307300166020ustar00rootroot00000000000000#include "lc_global.h" #include "lc_synth.h" #include "lc_library.h" #include "lc_application.h" #include "lc_file.h" #include "lc_meshloader.h" #include "pieceinf.h" #include class lcSynthInfoCurved : public lcSynthInfo { public: lcSynthInfoCurved(float Length, float DefaultScale, int NumSections, bool RigidEdges); void GetDefaultControlPoints(lcArray& ControlPoints) const override; void VerifyControlPoints(lcArray& ControlPoints) const override; protected: float GetSectionTwist(const lcMatrix44& StartTransform, const lcMatrix44& EndTransform) const; void CalculateSections(const lcArray& ControlPoints, lcArray& Sections, SectionCallbackFunc SectionCallback) const override; static void AddTubeParts(lcLibraryMeshData& MeshData, const lcArray& Sections, float Radius, bool IsInner); struct lcSynthComponent { lcMatrix44 Transform; float Length; }; lcSynthComponent mStart; lcSynthComponent mMiddle; lcSynthComponent mEnd; float mCenterLength = 0.0f; int mNumSections; float mDefaultScale; bool mRigidEdges; }; class lcSynthInfoFlexibleHose : public lcSynthInfoCurved { public: lcSynthInfoFlexibleHose(float Length, int NumSections, const char* EdgePart2); protected: void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const override; const char* mEdgePart2; }; class lcSynthInfoFlexSystemHose : public lcSynthInfoCurved { public: lcSynthInfoFlexSystemHose(float Length, int NumSections); void GetDefaultControlPoints(lcArray& ControlPoints) const override; protected: void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const override; }; class lcSynthInfoPneumaticTube : public lcSynthInfoCurved { public: lcSynthInfoPneumaticTube(float Length, int NumSections, const char* EndPart); protected: void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const override; const char* mEndPart; }; class lcSynthInfoRibbedHose : public lcSynthInfoCurved { public: lcSynthInfoRibbedHose(float Length, int NumSections); protected: void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const override; }; class lcSynthInfoFlexibleAxle : public lcSynthInfoCurved { public: lcSynthInfoFlexibleAxle(float Length, int NumSections); protected: void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const override; }; class lcSynthInfoBraidedString : public lcSynthInfoCurved { public: lcSynthInfoBraidedString(float Length, int NumSections); protected: void CalculateSections(const lcArray& ControlPoints, lcArray& Sections, SectionCallbackFunc SectionCallback) const override; void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const override; }; class lcSynthInfoStraight : public lcSynthInfo { public: explicit lcSynthInfoStraight(float Length); void VerifyControlPoints(lcArray& ControlPoints) const override; protected: void CalculateSections(const lcArray& ControlPoints, lcArray& Sections, SectionCallbackFunc SectionCallback) const override; }; class lcSynthInfoShockAbsorber : public lcSynthInfoStraight { public: explicit lcSynthInfoShockAbsorber(const char* SpringPart); void GetDefaultControlPoints(lcArray& ControlPoints) const override; protected: void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const override; const char* mSpringPart; }; class lcSynthInfoActuator : public lcSynthInfoStraight { public: explicit lcSynthInfoActuator(const char* BodyPart, const char* PistonPart, const char* AxlePart, float Length, float AxleOffset); void GetDefaultControlPoints(lcArray& ControlPoints) const override; protected: void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const override; const char* mBodyPart; const char* mPistonPart; const char* mAxlePart; float mAxleOffset; }; class lcSynthInfoUniversalJoint : public lcSynthInfo { public: lcSynthInfoUniversalJoint(float Length, float EndOffset, const char* EndPart, const char* CenterPart); void GetDefaultControlPoints(lcArray& ControlPoints) const override; void VerifyControlPoints(lcArray& ControlPoints) const override; protected: void CalculateSections(const lcArray& ControlPoints, lcArray& Sections, SectionCallbackFunc SectionCallback) const override; void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const override; float mEndOffset; const char* mEndPart; const char* mCenterPart; }; void lcSynthInit() { lcPiecesLibrary* Library = lcGetPiecesLibrary(); static const struct { char PartID[16]; float Length; int NumSections; char EdgePart2[8]; } FlexibleHoses[] = { { "73590a.dat", 140.0f, 51, "752.dat" }, // Hose Flexible 8.5L without Tabs { "73590b.dat", 140.0f, 51, "750.dat" }, // Hose Flexible 8.5L with Tabs }; for (const auto& HoseInfo: FlexibleHoses) { PieceInfo* Info = Library->FindPiece(HoseInfo.PartID, nullptr, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfoFlexibleHose(HoseInfo.Length, HoseInfo.NumSections, HoseInfo.EdgePart2)); } static const struct { char PartID[16]; float Length; int NumSections; } FlexSystemHoses[] = { { "76263.dat", 60.0f, 29 }, // Technic Flex-System Hose 3L (60LDU) { "76250.dat", 80.0f, 39 }, // Technic Flex-System Hose 4L (80LDU) { "76307.dat", 100.0f, 49 }, // Technic Flex-System Hose 5L (100LDU) { "76279.dat", 120.0f, 59 }, // Technic Flex-System Hose 6L (120LDU) { "76289.dat", 140.0f, 69 }, // Technic Flex-System Hose 7L (140LDU) { "76260.dat", 160.0f, 79 }, // Technic Flex-System Hose 8L (160LDU) { "76324.dat", 180.0f, 89 }, // Technic Flex-System Hose 9L (180LDU) { "76348.dat", 200.0f, 99 }, // Technic Flex-System Hose 10L (200LDU) { "71505.dat", 220.0f, 109 }, // Technic Flex-System Hose 11L (220LDU) { "71175.dat", 240.0f, 119 }, // Technic Flex-System Hose 12L (240LDU) { "71551.dat", 260.0f, 129 }, // Technic Flex-System Hose 13L (260LDU) { "71177.dat", 280.0f, 139 }, // Technic Flex-System Hose 14L (280LDU) { "71194.dat", 300.0f, 149 }, // Technic Flex-System Hose 15L (300LDU) { "71192.dat", 320.0f, 159 }, // Technic Flex-System Hose 16L (320LDU) { "76270.dat", 340.0f, 169 }, // Technic Flex-System Hose 17L (340LDU) { "71582.dat", 360.0f, 179 }, // Technic Flex-System Hose 18L (360LDU) { "22463.dat", 380.0f, 189 }, // Technic Flex-System Hose 19L (380LDU) { "76276.dat", 400.0f, 199 }, // Technic Flex-System Hose 20L (400LDU) { "70978.dat", 420.0f, 209 }, // Technic Flex-System Hose 21L (420LDU) { "76252.dat", 440.0f, 219 }, // Technic Flex-System Hose 22L (440LDU) { "76254.dat", 460.0f, 229 }, // Technic Flex-System Hose 23L (460LDU) { "76277.dat", 480.0f, 239 }, // Technic Flex-System Hose 24L (480LDU) { "53475.dat", 520.0f, 259 }, // Technic Flex-System Hose 26L (520LDU) { "76280.dat", 560.0f, 279 }, // Technic Flex-System Hose 28L (560LDU) { "76389.dat", 580.0f, 289 }, // Technic Flex-System Hose 29L (580LDU) { "76282.dat", 600.0f, 299 }, // Technic Flex-System Hose 30L (600LDU) { "76283.dat", 620.0f, 309 }, // Technic Flex-System Hose 31L (620LDU) { "57274.dat", 640.0f, 319 }, // Technic Flex-System Hose 32L (640LDU) { "42688.dat", 660.0f, 329 }, // Technic Flex-System Hose 33L (660LDU) { "22461.dat", 680.0f, 339 }, // Technic Flex-System Hose 34L (680LDU) { "46305.dat", 800.0f, 399 }, // Technic Flex-System Hose 40L (800LDU) { "76281.dat", 900.0f, 449 }, // Technic Flex-System Hose 45L (900LDU) { "22296.dat", 1060.0f, 529 }, // Technic Flex-System Hose 53L (1060LDU) }; for (const auto& HoseInfo: FlexSystemHoses) { PieceInfo* Info = Library->FindPiece(HoseInfo.PartID, nullptr, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfoFlexSystemHose(HoseInfo.Length, HoseInfo.NumSections)); } static const struct { char PartID[16]; float Length; int NumSections; } PneumaticTubes[] = { { "21761-f1.dat", 60.0f, 10 }, // Technic Pneumatic Tube 3L { "26445-f1.dat", 80.0f, 20 }, // Technic Pneumatic Tube 4L { "14653-f1.dat", 100.0f, 20 }, // Technic Pneumatic Tube 5L { "21766-f1.dat", 120.0f, 40 }, // Technic Pneumatic Tube 6L { "14657-f1.dat", 140.0f, 40 }, // Technic Pneumatic Tube 7L { "21837-f1.dat", 160.0f, 40 }, // Technic Pneumatic Tube 8L { "21826-f1.dat", 180.0f, 40 }, // Technic Pneumatic Tube 9L { "21767-f1.dat", 200.0f, 80 }, // Technic Pneumatic Tube 10L { "63539-f1.dat", 240.0f, 80 }, // Technic Pneumatic Tube 12L { "37467-f1.dat", 260.0f, 80 }, // Technic Pneumatic Tube 13L { "37461-f1.dat", 280.0f, 80 }, // Technic Pneumatic Tube 14L { "87948-f1.dat", 320.0f, 80 }, // Technic Pneumatic Tube 16L { "53168-f1.dat", 340.0f, 80 }, // Technic Pneumatic Tube 17L { "21839-f1.dat", 380.0f, 160 }, // Technic Pneumatic Tube 19L { "87950-f1.dat", 400.0f, 160 }, // Technic Pneumatic Tube 20L { "53184-f1.dat", 420.0f, 160 }, // Technic Pneumatic Tube 21L { "26436-f1.dat", 460.0f, 160 }, // Technic Pneumatic Tube 23L { "21830-f1.dat", 540.0f, 160 }, // Technic Pneumatic Tube 27L { "21825-f1.dat", 560.0f, 160 }, // Technic Pneumatic Tube 28L { "21833-f1.dat", 600.0f, 160 }, // Technic Pneumatic Tube 30L { "26440-f1.dat", 640.0f, 160 }, // Technic Pneumatic Tube 32L { "96889-f1.dat", 660.0f, 160 }, // Technic Pneumatic Tube 33L { "87949-f1.dat", 720.0f, 320 }, // Technic Pneumatic Tube 36L { "21835-f1.dat", 740.0f, 320 }, // Technic Pneumatic Tube 37L { "14661-f1.dat", 780.0f, 320 }, // Technic Pneumatic Tube 39L { "26438-f1.dat", 800.0f, 320 }, // Technic Pneumatic Tube 40L { "44079-f1.dat", 840.0f, 320 }, // Technic Pneumatic Tube 42L { "26439-f1.dat", 960.0f, 320 }, // Technic Pneumatic Tube 48L { "96890-f1.dat", 1080.0f, 320 }, // Technic Pneumatic Tube 54L { "96891-f1.dat", 1600.0f, 320 }, // Technic Pneumatic Tube 80L }; for (const auto& TubeInfo: PneumaticTubes) { PieceInfo* Info = Library->FindPiece(TubeInfo.PartID, nullptr, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfoPneumaticTube(TubeInfo.Length, TubeInfo.NumSections, "71533k02.dat")); auto RegularInfo = TubeInfo; RegularInfo.PartID[7] = '2'; RegularInfo.Length -= 40.0f; Info = Library->FindPiece(RegularInfo.PartID, nullptr, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfoPneumaticTube(RegularInfo.Length, RegularInfo.NumSections, "71533k01.dat")); } static const struct { char PartID[16]; float Length; int NumSections; } RibbedHoses[] = { { "72504.dat", 31.25f, 4 }, // Technic Ribbed Hose 2L { "72706.dat", 50.00f, 7 }, // Technic Ribbed Hose 3L { "71952.dat", 75.00f, 11 }, // Technic Ribbed Hose 4L { "72853.dat", 93.75f, 14 }, // Technic Ribbed Hose 5L { "71944.dat", 112.50f, 17 }, // Technic Ribbed Hose 6L { "57719.dat", 131.25f, 20 }, // Technic Ribbed Hose 7L { "71951.dat", 150.00f, 23 }, // Technic Ribbed Hose 8L { "71917.dat", 175.00f, 27 }, // Technic Ribbed Hose 9L { "71949.dat", 193.75f, 30 }, // Technic Ribbed Hose 10L { "71986.dat", 212.50f, 33 }, // Technic Ribbed Hose 11L { "71819.dat", 231.25f, 36 }, // Technic Ribbed Hose 12L { "71923.dat", 275.00f, 43 }, // Technic Ribbed Hose 14L { "71946.dat", 293.75f, 46 }, // Technic Ribbed Hose 15L { "71947.dat", 312.50f, 49 }, // Technic Ribbed Hose 16L { "22900.dat", 331.25f, 52 }, // Technic Ribbed Hose 17L { "72039.dat", 350.00f, 55 }, // Technic Ribbed Hose 18L { "43675.dat", 375.00f, 58 }, // Technic Ribbed Hose 19L { "23397.dat", 468.75f, 74 }, // Technic Ribbed Hose 24L { "33763.dat", 512.50f, 81 }, // Technic Ribbed Hose 26L }; for (const auto& HoseInfo: RibbedHoses) { PieceInfo* Info = Library->FindPiece(HoseInfo.PartID, nullptr, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfoRibbedHose(HoseInfo.Length, HoseInfo.NumSections)); } static const struct { char PartID[16]; float Length; int NumSections; } FlexibleAxles[] = { { "32580.dat", 120.00f, 15 }, // Technic Axle Flexible 7 { "32199.dat", 200.00f, 35 }, // Technic Axle Flexible 11 { "55709.dat", 200.00f, 35 }, // Technic Axle Flexible 11 { "32200.dat", 220.00f, 40 }, // Technic Axle Flexible 12 { "32201.dat", 260.00f, 50 }, // Technic Axle Flexible 14 { "32202.dat", 300.00f, 60 }, // Technic Axle Flexible 16 { "32235.dat", 360.00f, 75 }, // Technic Axle Flexible 19 }; for (const auto& AxleInfo: FlexibleAxles) { PieceInfo* Info = Library->FindPiece(AxleInfo.PartID, nullptr, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfoFlexibleAxle(AxleInfo.Length, AxleInfo.NumSections)); } static const struct { char PartID[16]; float Length; int NumSections; } BraidedStrings[] = { { "76384.dat", 200.00f, 46 }, // String Braided 11L with End Studs { "75924.dat", 400.00f, 96 }, // String Braided 21L with End Studs { "572C02.dat", 800.00f, 196 }, // String Braided 41L with End Studs }; for (const auto& StringInfo: BraidedStrings) { PieceInfo* Info = Library->FindPiece(StringInfo.PartID, nullptr, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfoBraidedString(StringInfo.Length, StringInfo.NumSections)); } static const struct { char PartID[16]; char SpringPart[16]; } ShockAbsorbers[] = { { "73129.dat", "70038.dat" }, // Technic Shock Absorber 6.5L { "41838.dat", "41837.dat" }, // Technic Shock Absorber 6.5L Soft { "76138.dat", "71953.dat" }, // Technic Shock Absorber 6.5L Stiff { "76537.dat", "22977.dat" }, // Technic Shock Absorber 6.5L Extra Stiff }; for (const auto& AbsorberInfo: ShockAbsorbers) { PieceInfo* Info = Library->FindPiece(AbsorberInfo.PartID, nullptr, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfoShockAbsorber(AbsorberInfo.SpringPart)); } static const struct { char PartID[16]; char BodyPart[16]; char PistonPart[16]; char AxlePart[16]; float Length; float AxleOffset; } Actuators[] = { { "61927-F1.dat", "62271c01.dat", "62274c01.dat", "47157.dat", 170.00f, 0.0f }, // Technic Linear Actuator 8 x 2 x 2 (Contracted) { "61927-F2.dat", "62271c01.dat", "62274c01.dat", "47157.dat", 270.00f, 0.0f }, // Technic Linear Actuator 8 x 2 x 2 (Extended) { "61927C01.dat", "62271c01.dat", "62274c01.dat", "47157.dat", 270.00f, 0.0f }, // Moved to 61927-f2 (was Technic Power Functions Linear Actuator (Extended)) { "61927.dat", "62271c01.dat", "62274c01.dat", "47157.dat", 170.00f, 0.0f }, // Moved to 61927-f1 (was Technic Power Functions Linear Actuator (Contracted)) { "92693C01-F1.dat", "92693c01.dat", "92696.dat", "92695.dat", 120.00f, 30.0f }, // Technic Linear Actuator 4 x 1 x 1 (Contracted) { "92693C01-F2.dat", "92693c01.dat", "92696.dat", "92695.dat", 180.00f, 30.0f }, // Technic Linear Actuator 4 x 1 x 1 (Extended) { "92693C02.dat", "92693c01.dat", "92696.dat", "92695.dat", 120.00f, 30.0f }, // Moved to 92693c01-f1 (was Technic Linear Actuator Small (Contracted)) { "92693C03.dat", "92693c01.dat", "92696.dat", "92695.dat", 180.00f, 30.0f }, // Moved to 92693c01-f2 (was Technic Linear Actuator Small (Extended)) }; for (const auto& ActuatorInfo: Actuators) { PieceInfo* Info = Library->FindPiece(ActuatorInfo.PartID, nullptr, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfoActuator(ActuatorInfo.BodyPart, ActuatorInfo.PistonPart, ActuatorInfo.AxlePart, ActuatorInfo.Length, ActuatorInfo.AxleOffset)); } static const struct { char PartID[16]; float Length; float EndOffset; char EndPart[16]; char CenterPart[16]; } UniversalJoints[] = { { "61903.dat", 60.00f, 0.0f, "62520.dat", "62519.dat" }, // Technic Universal Joint 3L (Complete) { "3712C01.dat", 60.00f, 30.0f, "3712.dat", "3326.dat" }, // Technic Universal Joint 4L with Bush Ends with Centre Type 2 (Complete) { "3712C03.dat", 60.00f, 30.0f, "3712.dat", "3326a.dat" }, // Technic Universal Joint 4L with Bush Ends with Centre Type 1 (Complete) { "575C01.dat", 60.00f, 30.0f, "575.dat", "3326a.dat" } // Technic Universal Joint Type 1 (Complete) }; for (const auto& JointInfo: UniversalJoints) { PieceInfo* Info = Library->FindPiece(JointInfo.PartID, nullptr, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfoUniversalJoint(JointInfo.Length, JointInfo.EndOffset, JointInfo.EndPart, JointInfo.CenterPart)); } // "758C01" // Hose Flexible 12L } lcSynthInfo::lcSynthInfo(float Length) : mLength(Length) { } lcSynthInfoCurved::lcSynthInfoCurved(float Length, float DefaultScale, int NumSections, bool RigidEdges) : lcSynthInfo(Length), mNumSections(NumSections), mDefaultScale(DefaultScale), mRigidEdges(RigidEdges) { mCurve = true; mStart.Transform = lcMatrix44(lcMatrix33(lcVector3(0.0f, 0.0f, 1.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f)); mEnd.Transform = lcMatrix44(lcMatrix33(lcVector3(0.0f, 0.0f, 1.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f)); } lcSynthInfoFlexibleHose::lcSynthInfoFlexibleHose(float Length, int NumSections, const char* EdgePart2) : lcSynthInfoCurved(Length, 12.f, NumSections, true), mEdgePart2(EdgePart2) { mStart.Length = 5.0f; mMiddle.Length = 2.56f; mEnd.Length = 5.0f; mCenterLength = 4.56f; } lcSynthInfoFlexSystemHose::lcSynthInfoFlexSystemHose(float Length, int NumSections) : lcSynthInfoCurved(Length, 12.f, NumSections, true) { mStart.Transform = lcMatrix44Identity(); mEnd.Transform = lcMatrix44Identity(); mStart.Length = 1.0f; mMiddle.Length = 2.0f; mEnd.Length = 1.0f; } lcSynthInfoPneumaticTube::lcSynthInfoPneumaticTube(float Length, int NumSections, const char* EndPart) : lcSynthInfoCurved(Length, 12.f, NumSections, true), mEndPart(EndPart) { mStart.Length = 0.0f; mMiddle.Length = mLength / NumSections; mEnd.Length = 0.0f; } lcSynthInfoRibbedHose::lcSynthInfoRibbedHose(float Length, int NumSections) : lcSynthInfoCurved(Length, 80.0f, NumSections, false) { mStart.Length = 6.25f; mMiddle.Length = 6.25f; mEnd.Length = 6.25f; } lcSynthInfoFlexibleAxle::lcSynthInfoFlexibleAxle(float Length, int NumSections) : lcSynthInfoCurved(Length, 12.0f, NumSections, true) { mStart.Length = 30.0f; mMiddle.Length = 4.0f; mEnd.Length = 30.0f; } lcSynthInfoBraidedString::lcSynthInfoBraidedString(float Length, int NumSections) : lcSynthInfoCurved(Length, 12.0f, NumSections, true) { mStart.Transform = lcMatrix44Identity(); mEnd.Transform = lcMatrix44Identity(); mStart.Length = 8.0f; mMiddle.Length = 4.0f; mEnd.Length = 8.0f; } lcSynthInfoStraight::lcSynthInfoStraight(float Length) : lcSynthInfo(Length) { mUnidirectional = true; } lcSynthInfoShockAbsorber::lcSynthInfoShockAbsorber(const char* SpringPart) : lcSynthInfoStraight(110.00f), mSpringPart(SpringPart) { } lcSynthInfoActuator::lcSynthInfoActuator(const char* BodyPart, const char* PistonPart, const char* AxlePart, float Length, float AxleOffset) : lcSynthInfoStraight(Length), mBodyPart(BodyPart), mPistonPart(PistonPart), mAxlePart(AxlePart), mAxleOffset(AxleOffset) { } lcSynthInfoUniversalJoint::lcSynthInfoUniversalJoint(float Length, float EndOffset, const char* EndPart, const char* CenterPart) : lcSynthInfo(Length), mEndOffset(EndOffset), mEndPart(EndPart), mCenterPart(CenterPart) { mNondirectional = true; } void lcSynthInfoCurved::GetDefaultControlPoints(lcArray& ControlPoints) const { ControlPoints.SetSize(2); float HalfLength = mLength / 2.0f; float Scale = lcMin(mDefaultScale, HalfLength); ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(-HalfLength, 0.0f, 0.0f)); ControlPoints[1].Transform = lcMatrix44Translation(lcVector3( HalfLength, 0.0f, 0.0f)); ControlPoints[0].Scale = Scale; ControlPoints[1].Scale = Scale; } void lcSynthInfoCurved::VerifyControlPoints(lcArray& ControlPoints) const { if (ControlPoints.GetSize() < 2) GetDefaultControlPoints(ControlPoints); } void lcSynthInfoFlexSystemHose::GetDefaultControlPoints(lcArray& ControlPoints) const { lcSynthInfoCurved::GetDefaultControlPoints(ControlPoints); ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(0.0f, 0.0f, -mLength)); ControlPoints[1].Transform = lcMatrix44Translation(lcVector3(0.0f, 0.0f, 0.0f)); } void lcSynthInfoStraight::VerifyControlPoints(lcArray& ControlPoints) const { if (ControlPoints.GetSize() < 2) GetDefaultControlPoints(ControlPoints); else ControlPoints.SetSize(2); } void lcSynthInfoShockAbsorber::GetDefaultControlPoints(lcArray& ControlPoints) const { ControlPoints.SetSize(2); ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(0.0f, 0.0f, -mLength)); ControlPoints[1].Transform = lcMatrix44Translation(lcVector3(0.0f, 0.0f, 0.0f)); ControlPoints[0].Scale = 1.0f; ControlPoints[1].Scale = 1.0f; } void lcSynthInfoActuator::GetDefaultControlPoints(lcArray& ControlPoints) const { ControlPoints.SetSize(2); ControlPoints[0].Transform = lcMatrix44(lcMatrix33(lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 0.0f, -1.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f)); ControlPoints[1].Transform = lcMatrix44(lcMatrix33(lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 0.0f, -1.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, mLength, 0.0f)); ControlPoints[0].Scale = 1.0f; ControlPoints[1].Scale = 1.0f; } void lcSynthInfoUniversalJoint::GetDefaultControlPoints(lcArray& ControlPoints) const { ControlPoints.SetSize(1); float HalfLength = mLength / 2; ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(0.0f, HalfLength, 0.0f)); ControlPoints[0].Scale = 1.0f; } void lcSynthInfoUniversalJoint::VerifyControlPoints(lcArray& ControlPoints) const { if (ControlPoints.IsEmpty()) GetDefaultControlPoints(ControlPoints); else ControlPoints.SetSize(1); } float lcSynthInfoCurved::GetSectionTwist(const lcMatrix44& StartTransform, const lcMatrix44& EndTransform) const { lcVector3 StartTangent(StartTransform[1].x, StartTransform[1].y, StartTransform[1].z); lcVector3 EndTangent(EndTransform[1].x, EndTransform[1].y, EndTransform[1].z); lcVector3 StartUp(StartTransform[2].x, StartTransform[2].y, StartTransform[2].z); lcVector3 EndUp(EndTransform[2].x, EndTransform[2].y, EndTransform[2].z); float TangentDot = lcDot(StartTangent, EndTangent); float UpDot = lcDot(StartUp, EndUp); if (TangentDot > 0.99f && UpDot > 0.99f) return 0.0f; if (fabs(TangentDot) > 0.99f) { return acosf(lcClamp(lcDot(EndUp, StartUp), -1.0f, 1.0f)); } else if (TangentDot > -0.99f) { lcVector3 Axis = lcCross(StartTangent, EndTangent); float Angle = acosf(lcClamp(TangentDot, -1.0f, 1.0f)); lcMatrix33 Rotation = lcMatrix33FromAxisAngle(Axis, Angle); lcVector3 AdjustedStartUp = lcMul(StartUp, Rotation); return acosf(lcClamp(lcDot(EndUp, AdjustedStartUp), -1.0f, 1.0f)); } lcVector3 StartSide(StartTransform[0].x, StartTransform[0].y, StartTransform[0].z); lcVector3 EndSide(EndTransform[0].x, EndTransform[0].y, EndTransform[0].z); float SideDot = lcDot(StartSide, EndSide); if (fabs(SideDot) < 0.99f) { lcVector3 Axis = lcCross(StartSide, EndSide); float Angle = acosf(SideDot); lcMatrix33 Rotation = lcMatrix33FromAxisAngle(Axis, Angle); lcVector3 AdjustedStartUp = lcMul(StartUp, Rotation); return acosf(lcClamp(lcDot(EndUp, AdjustedStartUp), -1.0f, 1.0f)); } return 0.0f; } void lcSynthInfoCurved::CalculateSections(const lcArray& ControlPoints, lcArray& Sections, SectionCallbackFunc SectionCallback) const { float SectionLength = 0.0f; for (int ControlPointIdx = 0; ControlPointIdx < ControlPoints.GetSize() - 1 && Sections.GetSize() < mNumSections + 2; ControlPointIdx++) { lcVector3 SegmentControlPoints[4]; lcMatrix44 StartTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx].Transform); lcMatrix44 EndTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx + 1].Transform); StartTransform = lcMatrix44(lcMul(lcMul(lcMatrix33(mStart.Transform), lcMatrix33(StartTransform)), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), StartTransform.GetTranslation()); if (ControlPointIdx == 0) { if (mRigidEdges) { StartTransform.SetTranslation(lcMul30(lcVector3(0.0f, mStart.Length, 0.0f), StartTransform) + StartTransform.GetTranslation()); SectionLength = 0.0f; } else SectionLength = mStart.Length; Sections.Add(StartTransform); } EndTransform = lcMatrix44(lcMul(lcMul(lcMatrix33(mEnd.Transform), lcMatrix33(EndTransform)), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), EndTransform.GetTranslation()); SegmentControlPoints[0] = StartTransform.GetTranslation(); SegmentControlPoints[1] = lcMul31(lcVector3(0.0f, ControlPoints[ControlPointIdx].Scale, 0.0f), StartTransform); SegmentControlPoints[2] = lcMul31(lcVector3(0.0f, -ControlPoints[ControlPointIdx + 1].Scale, 0.0f), EndTransform); SegmentControlPoints[3] = EndTransform.GetTranslation(); const int NumCurvePoints = 8192; lcArray CurvePoints; CurvePoints.AllocGrow(NumCurvePoints); for (int PointIdx = 0; PointIdx < NumCurvePoints; PointIdx++) { float t = (float)PointIdx / (float)(NumCurvePoints - 1); float it = 1.0f - t; lcVector3 Position = it * it * it * SegmentControlPoints[0] + it * it * 3.0f * t * SegmentControlPoints[1] + it * 3.0 * t * t * SegmentControlPoints[2] + t * t * t * SegmentControlPoints[3]; CurvePoints.Add(Position); } float CurrentSegmentLength = 0.0f; float TotalSegmentLength = 0.0f; for (int PointIdx = 0; PointIdx < CurvePoints.GetSize() - 1; PointIdx++) TotalSegmentLength += lcLength(CurvePoints[PointIdx] - CurvePoints[PointIdx + 1]); lcVector3 StartUp = lcMul30(lcVector3(1.0f, 0.0f, 0.0f), StartTransform); float Twist = GetSectionTwist(StartTransform, EndTransform); int CurrentPointIndex = 0; while (CurrentPointIndex < CurvePoints.GetSize() - 1) { float Length = lcLength(CurvePoints[CurrentPointIndex + 1] - CurvePoints[CurrentPointIndex]); CurrentSegmentLength += Length; SectionLength -= Length; CurrentPointIndex++; if (SectionLength > 0.0f) continue; float t = (float)CurrentPointIndex / (float)(NumCurvePoints - 1); float it = 1.0f - t; lcVector3 Tangent = lcNormalize(-3.0f * it * it * SegmentControlPoints[0] + (3.0f * it * it - 6.0f * t * it) * SegmentControlPoints[1] + (-3.0f * t * t + 6.0f * t * it) * SegmentControlPoints[2] + 3.0f * t * t * SegmentControlPoints[3]); lcVector3 Up; if (Twist) { Up = lcMul(StartUp, lcMatrix33FromAxisAngle(Tangent, Twist * (CurrentSegmentLength / TotalSegmentLength))); CurrentSegmentLength = 0.0f; } else Up = StartUp; lcVector3 Side = lcNormalize(lcCross(Tangent, Up)); Up = lcNormalize(lcCross(Side, Tangent)); StartUp = Up; Sections.Add(lcMatrix44(lcMatrix33(Up, Tangent, Side), CurvePoints[CurrentPointIndex])); if (SectionCallback) SectionCallback(CurvePoints[CurrentPointIndex], ControlPointIdx, t); if (Sections.GetSize() == mNumSections + 2) break; if (mCenterLength != 0.0f && (Sections.GetSize() == mNumSections / 2 + 1)) SectionLength += mCenterLength; else SectionLength += mMiddle.Length; if (Sections.GetSize() == mNumSections + 1 && !mRigidEdges) SectionLength += mEnd.Length; } } while (Sections.GetSize() < mNumSections + 2) { lcMatrix44 EndTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPoints.GetSize() - 1].Transform); EndTransform = lcMatrix44(lcMul(lcMul(lcMatrix33(mEnd.Transform), lcMatrix33(EndTransform)), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), EndTransform.GetTranslation()); lcVector3 Position = lcMul31(lcVector3(0.0f, SectionLength, 0.0f), EndTransform); EndTransform.SetTranslation(Position); Sections.Add(EndTransform); if (SectionCallback) SectionCallback(Position, ControlPoints.GetSize() - 1, 1.0f); if (mCenterLength != 0.0f && (Sections.GetSize() == mNumSections / 2 + 1)) SectionLength += mCenterLength; else SectionLength += mMiddle.Length; if (Sections.GetSize() == mNumSections + 1 && !mRigidEdges) SectionLength += mEnd.Length; } } void lcSynthInfoBraidedString::CalculateSections(const lcArray& ControlPoints, lcArray& Sections, SectionCallbackFunc SectionCallback) const { float SectionLength = 0.0f; for (int ControlPointIdx = 0; ControlPointIdx < ControlPoints.GetSize() - 1 && Sections.GetSize() < mNumSections + 2; ControlPointIdx++) { lcVector3 SegmentControlPoints[4]; lcMatrix44 StartTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx].Transform); lcMatrix44 EndTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx + 1].Transform); StartTransform = lcMatrix44(lcMul(lcMul(lcMatrix33(mStart.Transform), lcMatrix33(StartTransform)), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), StartTransform.GetTranslation()); if (ControlPointIdx == 0) { if (mRigidEdges) { StartTransform.SetTranslation(lcMul30(lcVector3(mStart.Length, 0.0f, 0.0f), StartTransform) + StartTransform.GetTranslation()); SectionLength = 0.0f; } else SectionLength = mStart.Length; Sections.Add(StartTransform); } EndTransform = lcMatrix44(lcMul(lcMul(lcMatrix33(mEnd.Transform), lcMatrix33(EndTransform)), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), EndTransform.GetTranslation()); SegmentControlPoints[0] = StartTransform.GetTranslation(); SegmentControlPoints[1] = lcMul31(lcVector3(ControlPoints[ControlPointIdx].Scale, 0.0f, 0.0f), StartTransform); SegmentControlPoints[2] = lcMul31(lcVector3(-ControlPoints[ControlPointIdx + 1].Scale, 0.0f, 0.0f), EndTransform); SegmentControlPoints[3] = EndTransform.GetTranslation(); const int NumCurvePoints = 8192; lcArray CurvePoints; CurvePoints.AllocGrow(NumCurvePoints); for (int PointIdx = 0; PointIdx < NumCurvePoints; PointIdx++) { float t = (float)PointIdx / (float)(NumCurvePoints - 1); float it = 1.0f - t; lcVector3 Position = it * it * it * SegmentControlPoints[0] + it * it * 3.0f * t * SegmentControlPoints[1] + it * 3.0 * t * t * SegmentControlPoints[2] + t * t * t * SegmentControlPoints[3]; CurvePoints.Add(Position); } float CurrentSegmentLength = 0.0f; float TotalSegmentLength = 0.0f; for (int PointIdx = 0; PointIdx < CurvePoints.GetSize() - 1; PointIdx++) TotalSegmentLength += lcLength(CurvePoints[PointIdx] - CurvePoints[PointIdx + 1]); lcVector3 StartUp = lcMul30(lcVector3(0.0f, 1.0f, 0.0f), StartTransform); float Twist = GetSectionTwist(StartTransform, EndTransform); int CurrentPointIndex = 0; while (CurrentPointIndex < CurvePoints.GetSize() - 1) { float Length = lcLength(CurvePoints[CurrentPointIndex + 1] - CurvePoints[CurrentPointIndex]); CurrentSegmentLength += Length; SectionLength -= Length; CurrentPointIndex++; if (SectionLength > 0.0f) continue; float t = (float)CurrentPointIndex / (float)(NumCurvePoints - 1); float it = 1.0f - t; lcVector3 Tangent = lcNormalize(-3.0f * it * it * SegmentControlPoints[0] + (3.0f * it * it - 6.0f * t * it) * SegmentControlPoints[1] + (-3.0f * t * t + 6.0f * t * it) * SegmentControlPoints[2] + 3.0f * t * t * SegmentControlPoints[3]); lcVector3 Up; if (Twist) { Up = lcMul(StartUp, lcMatrix33FromAxisAngle(Tangent, Twist * (CurrentSegmentLength / TotalSegmentLength))); CurrentSegmentLength = 0.0f; } else Up = StartUp; lcVector3 Side = lcNormalize(lcCross(Tangent, Up)); Up = lcNormalize(lcCross(Side, Tangent)); StartUp = Up; Sections.Add(lcMatrix44(lcMatrix33(Tangent, Up, -Side), CurvePoints[CurrentPointIndex])); if (SectionCallback) SectionCallback(CurvePoints[CurrentPointIndex], ControlPointIdx, t); if (Sections.GetSize() == mNumSections + 2) break; if (mCenterLength != 0.0f && (Sections.GetSize() == mNumSections / 2 + 1)) SectionLength += mCenterLength; else SectionLength += mMiddle.Length; if (Sections.GetSize() == mNumSections + 1 && !mRigidEdges) SectionLength += mEnd.Length; } } while (Sections.GetSize() < mNumSections + 2) { lcMatrix44 EndTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPoints.GetSize() - 1].Transform); EndTransform = lcMatrix44(lcMul(lcMul(lcMatrix33(mEnd.Transform), lcMatrix33(EndTransform)), lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), EndTransform.GetTranslation()); lcVector3 Position = lcMul31(lcVector3(SectionLength, 0.0f, 0.0f), EndTransform); EndTransform.SetTranslation(Position); Sections.Add(EndTransform); if (SectionCallback) SectionCallback(Position, ControlPoints.GetSize() - 1, 1.0f); if (mCenterLength != 0.0f && (Sections.GetSize() == mNumSections / 2 + 1)) SectionLength += mCenterLength; else SectionLength += mMiddle.Length; if (Sections.GetSize() == mNumSections + 1 && !mRigidEdges) SectionLength += mEnd.Length; } } void lcSynthInfoStraight::CalculateSections(const lcArray& ControlPoints, lcArray& Sections, SectionCallbackFunc SectionCallback) const { for (int ControlPointIdx = 0; ControlPointIdx < ControlPoints.GetSize(); ControlPointIdx++) { lcMatrix44 Transform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx].Transform); Sections.Add(Transform); if (SectionCallback) SectionCallback(Transform.GetTranslation(), ControlPointIdx, 1.0f); } } void lcSynthInfoUniversalJoint::CalculateSections(const lcArray& ControlPoints, lcArray& Sections, SectionCallbackFunc SectionCallback) const { for (int ControlPointIdx = 0; ControlPointIdx < ControlPoints.GetSize(); ControlPointIdx++) { lcMatrix44 Transform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx].Transform); Sections.Add(Transform); if (SectionCallback) SectionCallback(Transform.GetTranslation(), ControlPointIdx, 1.0f); } } void lcSynthInfoFlexibleHose::AddParts(lcMemFile& File, lcLibraryMeshData&, const lcArray& Sections) const { char Line[256]; const int NumEdgeParts = 2; const lcMatrix33 EdgeTransforms[2] = { lcMatrix33(lcVector3(0.0f, 0.0f, -1.0f), lcVector3(0.0f, -1.0f, 0.0f), lcVector3(1.0f, 0.0f, 0.0f)), lcMatrix33(lcVector3(0.0f, 0.0f, -1.0f), lcVector3(0.0f, 1.0f, 0.0f), lcVector3(1.0f, 0.0f, 0.0f)) }; const char* EdgeParts[2] = { "755.dat", mEdgePart2 }; for (int PartIdx = 0; PartIdx < NumEdgeParts; PartIdx++) { const int SectionIdx = 0; lcMatrix33 Transform(lcMul(lcMul(EdgeTransforms[PartIdx], lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), lcMatrix33(Sections[SectionIdx]))); lcVector3 Offset = lcMul31(lcVector3(0.0f, -5.0f, 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f %s\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2], EdgeParts[PartIdx]); File.WriteBuffer(Line, strlen(Line)); } for (int SectionIdx = 1; SectionIdx < Sections.GetSize() - 1; SectionIdx++) { lcMatrix33 Transform = lcMatrix33(Sections[SectionIdx]); lcVector3 Offset = Sections[SectionIdx].GetTranslation(); if (SectionIdx < Sections.GetSize() / 2) Transform = lcMul(lcMatrix33(lcVector3(0.0f, 0.0f, -1.0f), lcVector3(0.0f, -1.0f, 0.0f), lcVector3(-1.0f, 0.0f, 0.0f)), Transform); else if (SectionIdx != Sections.GetSize() / 2) Transform = lcMul(lcMatrix33(lcVector3(0.0f, 0.0f, -1.0f), lcVector3(0.0f, 1.0f, 0.0f), lcVector3( 1.0f, 0.0f, 0.0f)), Transform); else Transform = lcMul(lcMatrix33(lcVector3(0.0f, 0.0f, -1.0f), lcVector3(0.0f, 1.0f, 0.0f), lcVector3( 1.0f, 0.0f, 0.0f)), Transform); const char* Part = SectionIdx != Sections.GetSize() / 2 ? "754.dat" : "756.dat"; sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f %s\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2], Part); File.WriteBuffer(Line, strlen(Line)); } for (int PartIdx = 0; PartIdx < NumEdgeParts; PartIdx++) { const int SectionIdx = Sections.GetSize() - 1; lcMatrix33 Transform(lcMul(EdgeTransforms[PartIdx], lcMatrix33(Sections[SectionIdx]))); lcVector3 Offset = lcMul31(lcVector3(0.0f, 5.0f - 2.56f, 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f %s\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2], EdgeParts[PartIdx]); File.WriteBuffer(Line, strlen(Line)); } } void lcSynthInfoCurved::AddTubeParts(lcLibraryMeshData& MeshData, const lcArray& Sections, float Radius, bool IsInner) { // a unit circle static const lcVector3 Vertices[16] = { { 1.000000f, 0.0f, 0.000000f }, { 0.923880f, 0.0f, 0.382683f }, { 0.707107f, 0.0f, 0.707107f }, { 0.382683f, 0.0f, 0.923880f }, { 0.000000f, 0.0f, 1.000000f }, { -0.382683f, 0.0f, 0.923880f }, { -0.707107f, 0.0f, 0.707107f }, { -0.923880f, 0.0f, 0.382683f }, { -1.000000f, 0.0f, 0.000000f }, { -0.923879f, 0.0f, -0.382684f }, { -0.707107f, 0.0f, -0.707107f }, { -0.382683f, 0.0f, -0.923880f }, { 0.000000f, 0.0f, -1.000000f }, { 0.382684f, 0.0f, -0.923879f }, { 0.707107f, 0.0f, -0.707107f }, { 0.923880f, 0.0f, -0.382683f }, }; const int NumSectionVertices = LC_ARRAY_COUNT(Vertices); int BaseVertex; lcMeshLoaderVertex* VertexBuffer; quint32* IndexBuffer; MeshData.AddVertices(LC_MESHDATA_SHARED, NumSectionVertices * (Sections.GetSize() - 1), &BaseVertex, &VertexBuffer); float NormalDirection = IsInner ? -1.0f : 1.0f; for (int SectionIdx = 1; SectionIdx < Sections.GetSize(); SectionIdx++) { for (int VertexIdx = 0; VertexIdx < NumSectionVertices; VertexIdx++) { VertexBuffer->Position = lcMul31(Radius * Vertices[VertexIdx], Sections[SectionIdx]); VertexBuffer->Normal = lcMul30(NormalDirection * Vertices[VertexIdx], Sections[SectionIdx]); VertexBuffer->NormalWeight = 4.0f; VertexBuffer++; } } MeshData.AddIndices(LC_MESHDATA_SHARED, LC_MESH_TRIANGLES, 16, 6 * NumSectionVertices * (Sections.GetSize() - 2), &IndexBuffer); int Offset1, Offset2; if (IsInner) { Offset1 = NumSectionVertices - 1; // -1 mod NumVertices Offset2 = 0; } else { Offset1 = 0; Offset2 = 1; } for (int SectionIdx = 1; SectionIdx < Sections.GetSize() - 1; SectionIdx++) { for (int VertexIdx = 0; VertexIdx < NumSectionVertices; VertexIdx++) { int Vertex1 = BaseVertex + (VertexIdx + Offset1) % NumSectionVertices; int Vertex2 = BaseVertex + (VertexIdx + Offset2) % NumSectionVertices; *IndexBuffer++ = Vertex1; *IndexBuffer++ = Vertex2; *IndexBuffer++ = Vertex1 + NumSectionVertices; *IndexBuffer++ = Vertex2; *IndexBuffer++ = Vertex2 + NumSectionVertices; *IndexBuffer++ = Vertex1 + NumSectionVertices; } BaseVertex += NumSectionVertices; } } void lcSynthInfoFlexSystemHose::AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const { char Line[256]; { const int SectionIdx = 0; lcMatrix33 Transform(lcMul(lcMatrix33Scale(lcVector3(-1.0f, 1.0f, 1.0f)), lcMatrix33(Sections[SectionIdx]))); lcVector3 Offset = lcMul31(lcVector3(0.0f, -1.0f, 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f u9053.dat\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2]); File.WriteBuffer(Line, strlen(Line)); } { const int SectionIdx = Sections.GetSize() - 1; lcMatrix33 Transform(lcMul(lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f)), lcMatrix33(Sections[SectionIdx]))); lcVector3 Offset = lcMul31(lcVector3(0.0f, 1.0f, 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f u9053.dat\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2]); File.WriteBuffer(Line, strlen(Line)); } AddTubeParts(MeshData, Sections, 4.0f, false); AddTubeParts(MeshData, Sections, 2.0f, true); } void lcSynthInfoPneumaticTube::AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const { char Line[256]; { const int SectionIdx = 0; lcMatrix33 EdgeTransform(lcVector3(0.0f, 0.0f, -1.0f), lcVector3(0.0f, -1.0f, 0.0f), lcVector3(1.0f, 0.0f, 0.0f)); lcMatrix33 Transform(lcMul(lcMul(EdgeTransform, lcMatrix33Scale(lcVector3(1.0f, 1.0f, 1.0f))), lcMatrix33(Sections[SectionIdx]))); lcVector3 Offset = lcMul31(lcVector3(0.0f, 0.0f, 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f %s\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2], mEndPart); File.WriteBuffer(Line, strlen(Line)); } { const int SectionIdx = Sections.GetSize() - 1; lcMatrix33 EdgeTransform(lcVector3(0.0f, 0.0f, -1.0f), lcVector3(0.0f, -1.0f, 0.0f), lcVector3(1.0f, 0.0f, 0.0f)); lcMatrix33 Transform(lcMul(lcMul(EdgeTransform, lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), lcMatrix33(Sections[SectionIdx]))); lcVector3 Offset = lcMul31(lcVector3(0.0f, 0.0f, 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f %s\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2], mEndPart); File.WriteBuffer(Line, strlen(Line)); } AddTubeParts(MeshData, Sections, 5.0f, false); AddTubeParts(MeshData, Sections, 3.0f, true); } void lcSynthInfoRibbedHose::AddParts(lcMemFile& File, lcLibraryMeshData&, const lcArray& Sections) const { char Line[256]; { const int SectionIdx = 0; lcMatrix33 Transform(lcMul(lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f)), lcMatrix33(Sections[SectionIdx]))); lcVector3 Offset = Sections[SectionIdx].GetTranslation(); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f 79.dat\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2]); File.WriteBuffer(Line, strlen(Line)); } for (int SectionIdx = 1; SectionIdx < Sections.GetSize() - 1; SectionIdx++) { const lcMatrix44& Transform = Sections[SectionIdx]; sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f 80.dat\n", Transform[3][0], Transform[3][1], Transform[3][2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2]); File.WriteBuffer(Line, strlen(Line)); } { const int SectionIdx = Sections.GetSize() - 1; lcMatrix33 Transform(Sections[SectionIdx]); lcVector3 Offset = lcMul31(lcVector3(0.0f, -6.25f, 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f 79.dat\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2]); File.WriteBuffer(Line, strlen(Line)); } } void lcSynthInfoFlexibleAxle::AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const { char Line[256]; const int NumEdgeParts = 6; lcMatrix33 EdgeTransforms[6] = { lcMatrix33(lcVector3(-1.0f, 0.0f, 0.0f), lcVector3(0.0f, -5.0f, 0.0f), lcVector3(0.0f, 0.0f, 1.0f)), lcMatrix33(lcVector3( 0.0f, 1.0f, 0.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 0.0f, -1.0f)), lcMatrix33(lcVector3( 0.0f, 1.0f, 0.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 0.0f, -1.0f)), lcMatrix33(lcVector3( 0.0f, 1.0f, 0.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 0.0f, -1.0f)), lcMatrix33(lcVector3( 0.0f, 1.0f, 0.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 0.0f, -1.0f)), lcMatrix33(lcVector3( 0.0f, 1.0f, 0.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 0.0f, -1.0f)), }; const char* EdgeParts[6] = { "stud3a.dat", "s/faxle1.dat", "s/faxle2.dat", "s/faxle3.dat", "s/faxle4.dat", "s/faxle5.dat" }; for (int PartIdx = 0; PartIdx < NumEdgeParts; PartIdx++) { const int SectionIdx = 0; lcMatrix33 Transform(lcMul(lcMul(EdgeTransforms[PartIdx], lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f))), lcMatrix33(Sections[SectionIdx]))); lcVector3 Offset = lcMul31(lcVector3(0.0f, -4.0f * (5 - PartIdx), 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f %s\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2], EdgeParts[PartIdx]); File.WriteBuffer(Line, strlen(Line)); } for (int PartIdx = 0; PartIdx < NumEdgeParts; PartIdx++) { const int SectionIdx = Sections.GetSize() - 1; lcMatrix33 Transform(lcMul(EdgeTransforms[PartIdx], lcMatrix33(Sections[SectionIdx]))); lcVector3 Offset = lcMul31(lcVector3(0.0f, 4.0f * (5 - PartIdx), 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f %s\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2], EdgeParts[PartIdx]); File.WriteBuffer(Line, strlen(Line)); } const lcMeshLoaderVertex SectionVertices[28] = { { lcVector3(-6.000f, 0.0f, 0.000f), lcVector3(-1.000f, 0.0f, 0.000f), 2.0f }, { lcVector3(-5.602f, 0.0f, 2.000f), lcVector3(-0.942f, 0.0f, 0.336f), 4.0f }, { lcVector3(-5.602f, 0.0f, 2.000f), lcVector3( 0.000f, 0.0f, 1.000f), 4.0f }, { lcVector3(-2.000f, 0.0f, 2.000f), lcVector3( 0.000f, 0.0f, 1.000f), 4.0f }, { lcVector3(-2.000f, 0.0f, 2.000f), lcVector3(-1.000f, 0.0f, 0.000f), 4.0f }, { lcVector3(-2.000f, 0.0f, 5.602f), lcVector3(-1.000f, 0.0f, 0.000f), 4.0f }, { lcVector3(-2.000f, 0.0f, 5.602f), lcVector3(-0.336f, 0.0f, 0.942f), 4.0f }, { lcVector3( 0.000f, 0.0f, 6.000f), lcVector3( 0.000f, 0.0f, 1.000f), 2.0f }, { lcVector3( 2.000f, 0.0f, 5.602f), lcVector3( 0.336f, 0.0f, 0.942f), 4.0f }, { lcVector3( 2.000f, 0.0f, 5.602f), lcVector3( 1.000f, 0.0f, 0.000f), 4.0f }, { lcVector3( 2.000f, 0.0f, 2.000f), lcVector3( 1.000f, 0.0f, 0.000f), 4.0f }, { lcVector3( 2.000f, 0.0f, 2.000f), lcVector3( 0.000f, 0.0f, 1.000f), 4.0f }, { lcVector3( 5.602f, 0.0f, 2.000f), lcVector3( 0.000f, 0.0f, 1.000f), 4.0f }, { lcVector3( 5.602f, 0.0f, 2.000f), lcVector3( 0.942f, 0.0f, 0.336f), 4.0f }, { lcVector3( 6.000f, 0.0f, 0.000f), lcVector3( 1.000f, 0.0f, 0.000f), 2.0f }, { lcVector3( 5.602f, 0.0f, -2.000f), lcVector3( 0.942f, 0.0f, -0.336f), 4.0f }, { lcVector3( 5.602f, 0.0f, -2.000f), lcVector3( 0.000f, 0.0f, -1.000f), 4.0f }, { lcVector3( 2.000f, 0.0f, -2.000f), lcVector3( 0.000f, 0.0f, -1.000f), 4.0f }, { lcVector3( 2.000f, 0.0f, -2.000f), lcVector3( 1.000f, 0.0f, 0.000f), 4.0f }, { lcVector3( 2.000f, 0.0f, -5.602f), lcVector3( 1.000f, 0.0f, 0.000f), 4.0f }, { lcVector3( 2.000f, 0.0f, -5.602f), lcVector3( 0.336f, 0.0f, -0.942f), 4.0f }, { lcVector3( 0.000f, 0.0f, -6.000f), lcVector3( 0.000f, 0.0f, -1.000f), 2.0f }, { lcVector3(-2.000f, 0.0f, -5.602f), lcVector3(-0.336f, 0.0f, -0.942f), 4.0f }, { lcVector3(-2.000f, 0.0f, -5.602f), lcVector3(-1.000f, 0.0f, 0.000f), 4.0f }, { lcVector3(-2.000f, 0.0f, -2.000f), lcVector3(-1.000f, 0.0f, 0.000f), 4.0f }, { lcVector3(-2.000f, 0.0f, -2.000f), lcVector3( 0.000f, 0.0f, -1.000f), 4.0f }, { lcVector3(-5.602f, 0.0f, -2.000f), lcVector3( 0.000f, 0.0f, -1.000f), 4.0f }, { lcVector3(-5.602f, 0.0f, -2.000f), lcVector3(-0.942f, 0.0f, -0.336f), 4.0f } }; const int NumSectionVertices = LC_ARRAY_COUNT(SectionVertices); int BaseVertex; lcMeshLoaderVertex* VertexBuffer; quint32* IndexBuffer; MeshData.AddVertices(LC_MESHDATA_SHARED, NumSectionVertices * (Sections.GetSize() - 1), &BaseVertex, &VertexBuffer); MeshData.AddIndices(LC_MESHDATA_SHARED, LC_MESH_LINES, 24, 2 * 12 * (Sections.GetSize() - 2), &IndexBuffer); for (int SectionIdx = 1; SectionIdx < Sections.GetSize(); SectionIdx++) { for (int VertexIdx = 0; VertexIdx < NumSectionVertices; VertexIdx++) { VertexBuffer->Position = lcMul31(SectionVertices[VertexIdx].Position, Sections[SectionIdx]); VertexBuffer->Normal = lcMul30(SectionVertices[VertexIdx].Normal, Sections[SectionIdx]); VertexBuffer->NormalWeight = SectionVertices[VertexIdx].NormalWeight; VertexBuffer++; } } int BaseLinesVertex = BaseVertex; for (int SectionIdx = 1; SectionIdx < Sections.GetSize() - 1; SectionIdx++) { const int Indices[] = { 1, 3, 5, 8, 10, 12, 15, 17, 19, 22, 24, 26 }; for (int VertexIdx = 0; VertexIdx < 12; VertexIdx++) { *IndexBuffer++ = BaseLinesVertex + Indices[VertexIdx]; *IndexBuffer++ = BaseLinesVertex + Indices[VertexIdx] + NumSectionVertices; } BaseLinesVertex += NumSectionVertices; } MeshData.AddIndices(LC_MESHDATA_SHARED, LC_MESH_TRIANGLES, 16, 6 * NumSectionVertices * (Sections.GetSize() - 2), &IndexBuffer); for (int SectionIdx = 1; SectionIdx < Sections.GetSize() - 1; SectionIdx++) { for (int VertexIdx = 0; VertexIdx < NumSectionVertices; VertexIdx++) { int Vertex1 = BaseVertex + VertexIdx; int Vertex2 = BaseVertex + (VertexIdx + 1) % NumSectionVertices; *IndexBuffer++ = Vertex1; *IndexBuffer++ = Vertex2; *IndexBuffer++ = Vertex1 + NumSectionVertices; *IndexBuffer++ = Vertex2; *IndexBuffer++ = Vertex2 + NumSectionVertices; *IndexBuffer++ = Vertex1 + NumSectionVertices; } BaseVertex += NumSectionVertices; } } void lcSynthInfoBraidedString::AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& SectionsIn) const { lcArray Sections; Sections.SetSize(SectionsIn.GetSize()); for (int SectionIdx = 0; SectionIdx < Sections.GetSize(); SectionIdx++) { lcMatrix33 Transform(lcMul(lcMatrix33Scale(lcVector3(1.0f, -1.0f, 1.0f)), lcMatrix33(SectionsIn[SectionIdx]))); lcVector3 Offset = SectionsIn[SectionIdx].GetTranslation(); Sections[SectionIdx] = lcMatrix44(Transform, Offset); } char Line[256]; { const int SectionIdx = 0; lcMatrix33 Transform(Sections[SectionIdx]); lcVector3 Offset = lcMul31(lcVector3(-8.0f, 0.0f, 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f 572A.dat\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2]); File.WriteBuffer(Line, strlen(Line)); } const int NumSegments = 16; const int NumBraids = 4; const float PositionTable[16] = { -1.5f, -1.386f, -1.061f, -0.574f, 0.0f, 0.574f, 1.061f, 1.386f, 1.5f, 1.386f, 1.061f, 0.574f, 0.0f, -0.574f, -1.061f, -1.386f }; int BaseVertex; lcMeshLoaderVertex* VertexBuffer; quint32* IndexBuffer; MeshData.AddVertices(LC_MESHDATA_SHARED, NumBraids * ((Sections.GetSize() - 2) * NumSegments + 1), &BaseVertex, &VertexBuffer); MeshData.AddIndices(LC_MESHDATA_SHARED, LC_MESH_LINES, 24, NumBraids * (Sections.GetSize() - 2) * NumSegments * 2, &IndexBuffer); for (int BraidIdx = 0; BraidIdx < NumBraids; BraidIdx++) { int BaseX = (BraidIdx == 0 || BraidIdx == 2) ? 0 : 8; int BaseY = (BraidIdx == 0 || BraidIdx == 3) ? 12 : 4; for (int SectionIdx = 1; SectionIdx < Sections.GetSize() - 1; SectionIdx++) { lcMatrix33 Transform1 = lcMatrix33(Sections[SectionIdx]); lcMatrix33 Transform2 = lcMatrix33(Sections[SectionIdx + 1]); lcVector3 Offset1 = Sections[SectionIdx].GetTranslation(); lcVector3 Offset2 = Sections[SectionIdx + 1].GetTranslation(); for (int SegmentIdx = 0; SegmentIdx < ((SectionIdx < Sections.GetSize() - 2) ? NumSegments : NumSegments + 1); SegmentIdx++) { float t = (float)SegmentIdx / (float)NumSegments; lcVector3 Vertex1 = lcVector3(t * 4.0f, PositionTable[(BaseX + SegmentIdx) % NumSegments], PositionTable[(BaseY + SegmentIdx) % NumSegments]) + lcVector3(0.0f, 1.5f, 0.0f); lcVector3 Vertex2 = lcVector3((1.0f - t) * -4.0f, PositionTable[(BaseX + SegmentIdx) % NumSegments], PositionTable[(BaseY + SegmentIdx) % NumSegments]) + lcVector3(0.0f, 1.5f, 0.0f); lcVector3 Vertex = (lcMul(Vertex1, Transform1) + Offset1) * (1.0f - t) + (lcMul(Vertex2, Transform2) + Offset2) * t; VertexBuffer->Position = Vertex; VertexBuffer->Normal = lcVector3(0.0f, 0.0f, 0.0f); VertexBuffer->NormalWeight = 0.0f; VertexBuffer++; if (SegmentIdx != NumSegments) { *IndexBuffer++ = BaseVertex; *IndexBuffer++ = BaseVertex + 1; BaseVertex++; } } } BaseVertex++; } int NumSlices = 16; MeshData.AddVertices(LC_MESHDATA_SHARED, NumSlices * ((Sections.GetSize() - 2) * NumSegments + 1), &BaseVertex, &VertexBuffer); MeshData.AddIndices(LC_MESHDATA_SHARED, LC_MESH_TRIANGLES, 16, NumSlices * (Sections.GetSize() - 2) * NumSegments * 6, &IndexBuffer); for (int SectionIdx = 1; SectionIdx < Sections.GetSize() - 1; SectionIdx++) { lcMatrix33 Transform1 = lcMatrix33(Sections[SectionIdx]); lcMatrix33 Transform2 = lcMatrix33(Sections[SectionIdx + 1]); lcVector3 Offset1 = Sections[SectionIdx].GetTranslation(); lcVector3 Offset2 = Sections[SectionIdx + 1].GetTranslation(); for (int SegmentIdx = 0; SegmentIdx < ((SectionIdx < Sections.GetSize() - 2) ? NumSegments : NumSegments + 1); SegmentIdx++) { float t1 = (float)SegmentIdx / (float)NumSegments; int BaseX = 8; int BaseY = 4; for (int SliceIdx = 0; SliceIdx < NumSlices; SliceIdx++) { lcVector3 Vertex11 = lcVector3(t1 * 4.0f, PositionTable[(BaseX + SliceIdx) % NumSlices], PositionTable[(BaseY + SliceIdx) % NumSlices]) + lcVector3(0.0f, 1.5f, 0.0f); lcVector3 Vertex12 = lcVector3((1.0f - t1) * -4.0f, PositionTable[(BaseX + SliceIdx) % NumSlices], PositionTable[(BaseY + SliceIdx) % NumSlices]) + lcVector3(0.0f, 1.5f, 0.0f); VertexBuffer->Position = (lcMul(Vertex11, Transform1) + Offset1) * (1.0f - t1) + (lcMul(Vertex12, Transform2) + Offset2) * t1; lcVector3 Normal11 = lcVector3(0.0f, PositionTable[(BaseX + SliceIdx) % NumSlices] / 1.5f, PositionTable[(BaseY + SliceIdx) % NumSlices] / 1.5f); lcVector3 Normal12 = lcVector3(0.0f, PositionTable[(BaseX + SliceIdx) % NumSlices] / 1.5f, PositionTable[(BaseY + SliceIdx) % NumSlices] / 1.5f); VertexBuffer->Normal = lcMul(Normal11, Transform1) * (1.0f - t1) + lcMul(Normal12, Transform2) * t1; VertexBuffer->NormalWeight = 1.0f; VertexBuffer++; if (SegmentIdx != NumSegments) { *IndexBuffer++ = BaseVertex + SliceIdx; *IndexBuffer++ = BaseVertex + (SliceIdx + 1) % NumSlices; *IndexBuffer++ = BaseVertex + (SliceIdx + 1) % NumSlices + NumSlices; *IndexBuffer++ = BaseVertex + SliceIdx + NumSlices; *IndexBuffer++ = BaseVertex + SliceIdx; *IndexBuffer++ = BaseVertex + (SliceIdx + 1) % NumSlices + NumSlices; } } BaseVertex += NumSlices; } } { const int SectionIdx = Sections.GetSize() - 1; lcMatrix33 Transform(Sections[SectionIdx]); lcVector3 Offset = lcMul31(lcVector3(8.0f, 0.0f, 0.0f), Sections[SectionIdx]); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f 572A.dat\n", Offset[0], Offset[1], Offset[2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2]); File.WriteBuffer(Line, strlen(Line)); } } void lcSynthInfoShockAbsorber::AddParts(lcMemFile& File, lcLibraryMeshData&, const lcArray& Sections) const { char Line[256]; lcVector3 Offset; Offset = Sections[0].GetTranslation(); sprintf(Line, "1 0 %f %f %f 1 0 0 0 1 0 0 0 1 4254.dat\n", Offset[0], Offset[1], Offset[2]); File.WriteBuffer(Line, strlen(Line)); Offset = Sections[1].GetTranslation(); sprintf(Line, "1 16 %f %f %f 1 0 0 0 1 0 0 0 1 4255.dat\n", Offset[0], Offset[1], Offset[2]); File.WriteBuffer(Line, strlen(Line)); float Distance = Sections[0].GetTranslation().y - Sections[1].GetTranslation().y; float Scale = (Distance - 66.0f) / 44.0f; Offset = Sections[0].GetTranslation(); sprintf(Line, "1 494 %f %f %f 1 0 0 0 %f 0 0 0 1 %s\n", Offset[0], Offset[1] - 10 - 44.0f * Scale, Offset[2], Scale, mSpringPart); File.WriteBuffer(Line, strlen(Line)); } void lcSynthInfoActuator::AddParts(lcMemFile& File, lcLibraryMeshData&, const lcArray& Sections) const { char Line[256]; lcVector3 Offset; Offset = Sections[0].GetTranslation(); sprintf(Line, "1 16 %f %f %f 1 0 0 0 1 0 0 0 1 %s\n", Offset[0], Offset[1], Offset[2], mBodyPart); File.WriteBuffer(Line, strlen(Line)); Offset = lcMul(Sections[0], lcMatrix44Translation(lcVector3(0.0f, 0.0f, mAxleOffset))).GetTranslation(); sprintf(Line, "1 25 %f %f %f 0 1 0 -1 0 0 0 0 1 %s\n", Offset[0], Offset[1], Offset[2], mAxlePart); File.WriteBuffer(Line, strlen(Line)); Offset = Sections[1].GetTranslation(); sprintf(Line, "1 72 %f %f %f 1 0 0 0 1 0 0 0 1 %s\n", Offset[0], Offset[1], Offset[2], mPistonPart); File.WriteBuffer(Line, strlen(Line)); } void lcSynthInfoUniversalJoint::AddParts(lcMemFile& File, lcLibraryMeshData&, const lcArray& Sections) const { char Line[256]; lcVector3 Offset = Sections[0].GetTranslation(); float Angle = atan2f(Offset.x, Offset.z); lcMatrix44 Rotation = lcMatrix44RotationZ(Angle); lcMatrix44 Transform = lcMatrix44LeoCADToLDraw(Rotation); sprintf(Line, "1 16 0 0 0 %f %f %f %f %f %f %f %f %f %s\n", Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2], mCenterPart); File.WriteBuffer(Line, strlen(Line)); Angle = atan2f(Offset.y, hypotf(Offset.x, Offset.z)); Rotation = lcMul(Rotation, lcMatrix44RotationX(Angle)); Transform = lcMul( lcMatrix44Translation(lcVector3(0.0f, 0.0f, mEndOffset)), lcMatrix44LeoCADToLDraw(Rotation) ); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f %s\n", Transform[3][0], Transform[3][1], Transform[3][2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2], mEndPart); File.WriteBuffer(Line, strlen(Line)); Rotation = lcMatrix44FromEulerAngles(lcVector3(0.0f, LC_PI/2, LC_PI)); Transform = lcMatrix44LeoCADToLDraw(lcMul(lcMatrix44Translation(lcVector3(0.0f, mEndOffset, 0.0f)), Rotation)); sprintf(Line, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f %s\n", Transform[3][0], Transform[3][1], Transform[3][2], Transform[0][0], Transform[1][0], Transform[2][0], Transform[0][1], Transform[1][1], -Transform[2][1], Transform[0][2], Transform[1][2], Transform[2][2], mEndPart); File.WriteBuffer(Line, strlen(Line)); } lcMesh* lcSynthInfo::CreateMesh(const lcArray& ControlPoints) const { lcArray Sections; CalculateSections(ControlPoints, Sections, nullptr); lcLibraryMeshData MeshData; lcMemFile File; // todo: rewrite this to pass the parts directly AddParts(File, MeshData, Sections); File.WriteU8(0); lcArray TextureStack; File.Seek(0, SEEK_SET); lcMeshLoader MeshLoader(MeshData, false, nullptr, false); if (MeshLoader.LoadMesh(File, LC_MESHDATA_SHARED)) return MeshData.CreateMesh(); return nullptr; } int lcSynthInfo::InsertControlPoint(lcArray& ControlPoints, const lcVector3& Start, const lcVector3& End) const { lcArray Sections; int BestSegment = -1; float BestTime; float BestDistance = FLT_MAX; lcVector3 BestPosition; CalculateSections(ControlPoints, Sections, [&](const lcVector3& CurvePoint, int SegmentIndex, float t) { float Distance = lcRayPointDistance(CurvePoint, Start, End); if (Distance < BestDistance) { BestSegment = SegmentIndex; BestTime = t; BestDistance = Distance; BestPosition = lcVector3LDrawToLeoCAD(CurvePoint); } } ); if (BestSegment != -1) { lcPieceControlPoint ControlPoint = ControlPoints[BestSegment]; ControlPoint.Transform.SetTranslation(BestPosition); if (BestSegment != ControlPoints.GetSize() - 1) { lcPieceControlPoint NextControlPoint = ControlPoints[BestSegment + 1]; ControlPoint.Scale = ControlPoint.Scale * (1.0f - BestTime) + NextControlPoint.Scale * BestTime; } ControlPoints.InsertAt(BestSegment + 1, ControlPoint); } return BestSegment + 1; } leocad-23.03/common/lc_synth.h000066400000000000000000000027421440571307300162450ustar00rootroot00000000000000#pragma once #include "lc_math.h" #include "piece.h" class lcLibraryMeshData; class lcSynthInfo { public: explicit lcSynthInfo(float Length); virtual ~lcSynthInfo() = default; lcSynthInfo(const lcSynthInfo&) = delete; lcSynthInfo(lcSynthInfo&&) = delete; lcSynthInfo& operator=(const lcSynthInfo&) = delete; lcSynthInfo& operator=(lcSynthInfo&&) = delete; bool CanAddControlPoints() const { return mCurve; } bool IsCurve() const { return mCurve; } bool IsUnidirectional() const { return mUnidirectional; } bool IsNondirectional() const { return mNondirectional; } virtual void GetDefaultControlPoints(lcArray& ControlPoints) const = 0; virtual void VerifyControlPoints(lcArray& ControlPoints) const = 0; int InsertControlPoint(lcArray& ControlPoints, const lcVector3& Start, const lcVector3& End) const; lcMesh* CreateMesh(const lcArray& ControlPoints) const; protected: using SectionCallbackFunc = std::function; virtual void CalculateSections(const lcArray& ControlPoints, lcArray& Sections, SectionCallbackFunc SectionCallback) const = 0; virtual void AddParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const = 0; bool mCurve = false; bool mUnidirectional = false; bool mNondirectional = false; float mLength; }; void lcSynthInit(); leocad-23.03/common/lc_texture.cpp000066400000000000000000000126461440571307300171370ustar00rootroot00000000000000#include "lc_global.h" #include "lc_texture.h" #include "lc_application.h" #include "lc_library.h" #include "image.h" #include "lc_glextensions.h" lcTexture* gGridTexture; lcTexture* lcLoadTexture(const QString& FileName, int Flags) { lcTexture* Texture = new lcTexture(); if (!Texture->Load(FileName, Flags)) { delete Texture; Texture = nullptr; } else { strcpy(Texture->mName, QFileInfo(FileName).baseName().toLatin1()); Texture->SetTemporary(true); } return Texture; } void lcReleaseTexture(lcTexture* Texture) { if (Texture && !Texture->Release()) delete Texture; } lcTexture::lcTexture() { mTexture = 0; mRefCount = 0; mTemporary = false; } lcTexture::~lcTexture() { Unload(); } void lcTexture::CreateGridTexture() { constexpr int NumLevels = 9; mImages.resize(NumLevels); quint8* Previous = nullptr; for (int ImageLevel = 0; ImageLevel < NumLevels; ImageLevel++) { Image& GridImage = mImages[ImageLevel]; const int GridSize = 256 >> ImageLevel; GridImage.Allocate(GridSize, GridSize, lcPixelFormat::A8); if (Previous) { const int PreviousGridSize = 2 * GridSize; for (int y = 0; y < GridSize - 1; y++) { for (int x = 0; x < GridSize - 1; x++) { const quint8 a = Previous[x * 2 + y * 2 * PreviousGridSize] > 64 ? 255 : 0; const quint8 b = Previous[x * 2 + 1 + y * 2 * PreviousGridSize] > 64 ? 255 : 0; const quint8 c = Previous[x * 2 + (y * 2 + 1) * PreviousGridSize] > 64 ? 255 : 0; const quint8 d = Previous[x * 2 + 1 + (y * 2 + 1) * PreviousGridSize] > 64 ? 255 : 0; GridImage.mData[x + y * GridSize] = (a + b + c + d) / 4; } int x = GridSize - 1; const quint8 a = Previous[x * 2 + y * 2 * PreviousGridSize]; const quint8 c = Previous[x * 2 + (y * 2 + 1) * PreviousGridSize]; GridImage.mData[x + y * GridSize] = (a + c) / 2; } int y = GridSize - 1; for (int x = 0; x < GridSize - 1; x++) { const quint8 a = Previous[x * 2 + y * 2 * PreviousGridSize]; const quint8 b = Previous[x * 2 + 1 + y * 2 * PreviousGridSize]; GridImage.mData[x + y * GridSize] = (a + b) / 2; } int x = GridSize - 1; GridImage.mData[x + y * GridSize] = Previous[x + y * PreviousGridSize]; } else { const float Radius1 = (80 >> ImageLevel) * (80 >> ImageLevel); const float Radius2 = (72 >> ImageLevel) * (72 >> ImageLevel); quint8* TempBuffer = new quint8[GridSize * GridSize]; for (int y = 0; y < GridSize; y++) { quint8* Pixel = TempBuffer + y * GridSize; memset(Pixel, 0, GridSize); const float y2 = (y - GridSize / 2) * (y - GridSize / 2); if (Radius1 <= y2) continue; if (Radius2 <= y2) { const int x1 = sqrtf(Radius1 - y2); for (int x = GridSize / 2 - x1; x < GridSize / 2 + x1; x++) Pixel[x] = 255; } else { const int x1 = sqrtf(Radius1 - y2); const int x2 = sqrtf(Radius2 - y2); for (int x = GridSize / 2 - x1; x < GridSize / 2 - x2; x++) Pixel[x] = 255; for (int x = GridSize / 2 + x2; x < GridSize / 2 + x1; x++) Pixel[x] = 255; } } for (int y = 0; y < GridSize - 1; y++) { for (int x = 0; x < GridSize - 1; x++) { const quint8 a = TempBuffer[x + y * GridSize]; const quint8 b = TempBuffer[x + 1 + y * GridSize]; const quint8 c = TempBuffer[x + (y + 1) * GridSize]; const quint8 d = TempBuffer[x + 1 + (y + 1) * GridSize]; GridImage.mData[x + y * GridSize] = (a + b + c + d) / 4; } int x = GridSize - 1; const quint8 a = TempBuffer[x + y * GridSize]; const quint8 c = TempBuffer[x + (y + 1) * GridSize]; GridImage.mData[x + y * GridSize] = (a + c) / 2; } int y = GridSize - 1; for (int x = 0; x < GridSize - 1; x++) { const quint8 a = TempBuffer[x + y * GridSize]; const quint8 b = TempBuffer[x + 1 + y * GridSize]; GridImage.mData[x + y * GridSize] = (a + b) / 2; } int x = GridSize - 1; GridImage.mData[x + y * GridSize] = TempBuffer[x + y * GridSize]; delete[] TempBuffer; } Previous = GridImage.mData; } mRefCount = 1; mFlags = LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV | LC_TEXTURE_MIPMAPS | LC_TEXTURE_ANISOTROPIC; lcContext* Context = lcContext::GetGlobalOffscreenContext(); Context->MakeCurrent(); Upload(Context); } bool lcTexture::Load() { return lcGetPiecesLibrary()->LoadTexture(this); } bool lcTexture::Load(const QString& FileName, int Flags) { Image Image; if (!Image.FileLoad(FileName)) return false; SetImage(std::move(Image), Flags); return true; } bool lcTexture::Load(lcMemFile& File, int Flags) { Image Image; if (!Image.FileLoad(File)) return false; SetImage(std::move(Image), Flags); return true; } void lcTexture::SetImage(Image&& Image, int Flags) { mImages.clear(); mImages.emplace_back(std::move(Image)); mFlags = Flags; LoadImages(); } void lcTexture::SetImage(std::vector&& Images, int Flags) { mImages = std::move(Images); mFlags = Flags; LoadImages(); } void lcTexture::Upload(lcContext* Context) { if (!NeedsUpload()) return; mWidth = mImages[0].mWidth; mHeight = mImages[0].mHeight; Context->UploadTexture(this); mImages.clear(); } bool lcTexture::LoadImages() { for (Image& Image : mImages) Image.ResizePow2(); if (QThread::currentThread() == qApp->thread()) { lcContext* Context = lcContext::GetGlobalOffscreenContext(); Context->MakeCurrent(); Upload(Context); } return true; } void lcTexture::Unload() { if (mTexture) glDeleteTextures(1, &mTexture); mTexture = 0; } leocad-23.03/common/lc_texture.h000066400000000000000000000036041440571307300165760ustar00rootroot00000000000000#pragma once #define LC_TEXTURE_WRAPU 0x01 #define LC_TEXTURE_WRAPV 0x02 #define LC_TEXTURE_MIPMAPS 0x04 #define LC_TEXTURE_CUBEMAP 0x08 #define LC_TEXTURE_POINT 0x00 #define LC_TEXTURE_LINEAR 0x10 #define LC_TEXTURE_BILINEAR 0x20 #define LC_TEXTURE_TRILINEAR 0x30 #define LC_TEXTURE_ANISOTROPIC 0x40 #define LC_TEXTURE_FILTER_MASK 0xf0 #define LC_TEXTURE_FILTER_SHIFT 4 #define LC_TEXTURE_NAME_LEN 256 #include "image.h" class lcTexture { public: lcTexture(); ~lcTexture(); lcTexture(const lcTexture&) = delete; lcTexture(lcTexture&&) = delete; lcTexture& operator=(const lcTexture&) = delete; lcTexture& operator=(lcTexture&&) = delete; void CreateGridTexture(); bool Load(const QString& FileName, int Flags = 0); bool Load(lcMemFile& File, int Flags = 0); void SetImage(Image&& Image, int Flags = 0); void SetImage(std::vector&& Images, int Flags = 0); void Upload(lcContext* Context); void Unload(); void AddRef() { mRefCount.ref(); if (mRefCount == 1) Load(); } bool Release() { const bool InUse = mRefCount.deref(); if (!InUse) Unload(); return InUse; } void SetTemporary(bool Temporary) { mTemporary = Temporary; } bool IsTemporary() const { return mTemporary; } bool NeedsUpload() const { return mTexture == 0 && !mImages.empty(); } int GetFlags() const { return mFlags; } const Image& GetImage(int Index) const { return mImages[Index]; } size_t GetImageCount() const { return mImages.size(); } int mWidth; int mHeight; char mName[LC_TEXTURE_NAME_LEN]; QString mFileName; GLuint mTexture; protected: bool Load(); bool LoadImages(); bool mTemporary; QAtomicInt mRefCount; std::vector mImages; int mFlags; }; lcTexture* lcLoadTexture(const QString& FileName, int Flags); void lcReleaseTexture(lcTexture* Texture); extern lcTexture* gGridTexture; leocad-23.03/common/lc_timelinewidget.cpp000066400000000000000000000372201440571307300204440ustar00rootroot00000000000000#include "lc_global.h" #include "lc_timelinewidget.h" #include "lc_model.h" #include "piece.h" #include "pieceinf.h" #include "lc_mainwindow.h" #include "lc_viewwidget.h" #include "lc_previewwidget.h" lcTimelineWidget::lcTimelineWidget(QWidget* Parent) : QTreeWidget(Parent) { mCurrentStepItem = nullptr; mIgnoreUpdates = false; setSelectionMode(QAbstractItemView::ExtendedSelection); setDragEnabled(true); setDragDropMode(QAbstractItemView::InternalMove); setUniformRowHeights(true); setHeaderHidden(true); setContextMenuPolicy(Qt::CustomContextMenu); invisibleRootItem()->setFlags(invisibleRootItem()->flags() & ~Qt::ItemIsDropEnabled); connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), SLOT(CurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); connect(this, SIGNAL(itemSelectionChanged()), SLOT(ItemSelectionChanged())); connect(this, SIGNAL(customContextMenuRequested(QPoint)), SLOT(CustomMenuRequested(QPoint))); } lcTimelineWidget::~lcTimelineWidget() { } void lcTimelineWidget::CustomMenuRequested(QPoint Pos) { QMenu* Menu = new QMenu(this); lcObject* FocusObject = gMainWindow->GetActiveModel()->GetFocusObject(); if (FocusObject && FocusObject->IsPiece()) { lcPiece* Piece = (lcPiece*)FocusObject; if (Piece->mPieceInfo->IsModel()) { Menu->addAction(gMainWindow->mActions[LC_PIECE_EDIT_SELECTED_SUBMODEL]); Menu->addAction(gMainWindow->mActions[LC_PIECE_VIEW_SELECTED_MODEL]); Menu->addAction(gMainWindow->mActions[LC_PIECE_INLINE_SELECTED_MODELS]); Menu->addSeparator(); } } Menu->addAction(gMainWindow->mActions[LC_TIMELINE_SET_CURRENT]); Menu->addAction(gMainWindow->mActions[LC_TIMELINE_INSERT_BEFORE]); Menu->addAction(gMainWindow->mActions[LC_TIMELINE_INSERT_AFTER]); Menu->addAction(gMainWindow->mActions[LC_TIMELINE_DELETE]); Menu->addSeparator(); Menu->addAction(gMainWindow->mActions[LC_TIMELINE_MOVE_SELECTION]); Menu->addAction(gMainWindow->mActions[LC_TIMELINE_MOVE_SELECTION_BEFORE]); Menu->addAction(gMainWindow->mActions[LC_TIMELINE_MOVE_SELECTION_AFTER]); Menu->addSeparator(); Menu->addAction(gMainWindow->mActions[LC_PIECE_HIDE_SELECTED]); Menu->addAction(gMainWindow->mActions[LC_PIECE_HIDE_UNSELECTED]); Menu->addAction(gMainWindow->mActions[LC_PIECE_UNHIDE_SELECTED]); Menu->addAction(gMainWindow->mActions[LC_PIECE_UNHIDE_ALL]); Menu->exec(viewport()->mapToGlobal(Pos)); delete Menu; } void lcTimelineWidget::Update(bool Clear, bool UpdateItems) { if (mIgnoreUpdates) return; lcModel* Model = gMainWindow->GetActiveModel(); bool Blocked = blockSignals(true); if (!Model) { mCurrentStepItem = nullptr; mItems.clear(); clear(); blockSignals(Blocked); return; } if (Clear) { mCurrentStepItem = nullptr; mItems.clear(); clear(); } lcStep LastStep = Model->GetLastStep(); if (Model->HasPieces()) LastStep++; LastStep = lcMax(LastStep, Model->GetCurrentStep()); for (int TopLevelItemIdx = LastStep; TopLevelItemIdx < topLevelItemCount(); ) { QTreeWidgetItem* StepItem = topLevelItem(TopLevelItemIdx); while (StepItem->childCount()) { QTreeWidgetItem* PieceItem = StepItem->child(0); lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); mItems.remove(Piece); delete PieceItem; } if (mCurrentStepItem == StepItem) mCurrentStepItem = nullptr; delete StepItem; } for (unsigned int TopLevelItemIdx = topLevelItemCount(); TopLevelItemIdx < LastStep; TopLevelItemIdx++) { QTreeWidgetItem* StepItem = new QTreeWidgetItem(this, QStringList(tr("Step %1").arg(TopLevelItemIdx + 1))); StepItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDropEnabled); addTopLevelItem(StepItem); StepItem->setExpanded(true); } const lcArray& Pieces = Model->GetPieces(); QTreeWidgetItem* StepItem = nullptr; int PieceItemIndex = 0; lcStep Step = 0; for (lcPiece* Piece : Pieces) { while (Step != Piece->GetStepShow()) { if (StepItem) { while (PieceItemIndex < StepItem->childCount()) { QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIndex); lcPiece* RemovePiece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); if (Pieces.FindIndex(RemovePiece) == -1) { mItems.remove(RemovePiece); delete PieceItem; } else { PieceItem->parent()->removeChild(PieceItem); topLevelItem(RemovePiece->GetStepShow() - 1)->addChild(PieceItem); } } } Step++; StepItem = topLevelItem(Step - 1); PieceItemIndex = 0; } QTreeWidgetItem* PieceItem = mItems.value(Piece); bool UpdateItem = UpdateItems; if (StepItem) { if (!PieceItem) { PieceItem = new QTreeWidgetItem(); PieceItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); PieceItem->setData(0, Qt::UserRole, QVariant::fromValue((uintptr_t)Piece)); StepItem->insertChild(PieceItemIndex, PieceItem); mItems[Piece] = PieceItem; UpdateItem = true; } else { if (PieceItemIndex >= StepItem->childCount() || PieceItem != StepItem->child(PieceItemIndex)) { QTreeWidgetItem* PieceParent = PieceItem->parent(); if (PieceParent) PieceParent->removeChild(PieceItem); StepItem->insertChild(PieceItemIndex, PieceItem); } } } if (UpdateItem) { PieceItem->setText(0, Piece->mPieceInfo->m_strDescription); int ColorIndex = Piece->GetColorIndex(); if (!mIcons.contains(ColorIndex)) { int Size = rowHeight(indexFromItem(PieceItem)); QImage Image(Size, Size, QImage::Format_ARGB32); Image.fill(0); float* Color = gColorList[ColorIndex].Value; QPainter Painter(&Image); Painter.setPen(Qt::darkGray); Painter.setBrush(QColor::fromRgbF(Color[0], Color[1], Color[2])); Painter.drawEllipse(0, 0, Size - 1, Size - 1); mIcons[ColorIndex] = QIcon(QPixmap::fromImage(Image)); } PieceItem->setIcon(0, mIcons[ColorIndex]); QColor Color = palette().text().color(); if (Piece->mPieceInfo->IsPlaceholder()) Color = QColor(208, 0, 0); else if (Piece->IsHidden()) Color.setAlpha(128); PieceItem->setForeground(0, Color); } PieceItem->setSelected(Piece->IsSelected()); PieceItemIndex++; } if (Step == 0) { Step = 1; StepItem = topLevelItem(0); } while (Step <= LastStep && StepItem) { while (PieceItemIndex < StepItem->childCount()) { QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIndex); lcPiece* RemovePiece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); mItems.remove(RemovePiece); delete PieceItem; } Step++; StepItem = topLevelItem(Step - 1); PieceItemIndex = 0; } UpdateCurrentStepItem(); blockSignals(Blocked); } void lcTimelineWidget::UpdateCurrentStepItem() { lcModel* Model = gMainWindow->GetActiveModel(); lcStep CurrentStep = Model->GetCurrentStep(); QTreeWidgetItem* CurrentStepItem = topLevelItem(CurrentStep - 1); if (CurrentStepItem != mCurrentStepItem) { if (mCurrentStepItem) { QFont Font = mCurrentStepItem->font(0); Font.setBold(false); mCurrentStepItem->setFont(0, Font); } if (CurrentStepItem) { QFont Font = CurrentStepItem->font(0); Font.setBold(true); CurrentStepItem->setFont(0, Font); setCurrentItem(CurrentStepItem); } mCurrentStepItem = CurrentStepItem; } } void lcTimelineWidget::UpdateSelection() { if (mIgnoreUpdates) return; QItemSelection ItemSelection; for (int TopLevelItemIdx = 0; TopLevelItemIdx < topLevelItemCount(); TopLevelItemIdx++) { QTreeWidgetItem* StepItem = topLevelItem(TopLevelItemIdx); for (int PieceItemIdx = 0; PieceItemIdx < StepItem->childCount(); PieceItemIdx++) { QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIdx); lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); if (Piece && Piece->IsSelected()) { QModelIndex Index = indexFromItem(PieceItem); ItemSelection.select(Index, Index); } } } bool Blocked = blockSignals(true); selectionModel()->select(ItemSelection, QItemSelectionModel::ClearAndSelect); blockSignals(Blocked); } void lcTimelineWidget::InsertStepBefore() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; gMainWindow->GetActiveModel()->InsertStep(Step + 1); } void lcTimelineWidget::InsertStepAfter() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; gMainWindow->GetActiveModel()->InsertStep(Step + 2); } void lcTimelineWidget::RemoveStep() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; gMainWindow->GetActiveModel()->RemoveStep(Step + 1); } void lcTimelineWidget::MoveSelection() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; Step++; QList SelectedItems = selectedItems(); for (QTreeWidgetItem* PieceItem : SelectedItems) { QTreeWidgetItem* Parent = PieceItem->parent(); if (!Parent) continue; int ChildIndex = Parent->indexOfChild(PieceItem); CurrentItem->addChild(Parent->takeChild(ChildIndex)); } UpdateModel(); lcModel* Model = gMainWindow->GetActiveModel(); if (Step > static_cast(Model->GetCurrentStep())) Model->SetCurrentStep(Step); } void lcTimelineWidget::MoveSelectionBefore() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; Step++; QList SelectedItems = selectedItems(); gMainWindow->GetActiveModel()->InsertStep(Step); CurrentItem = topLevelItem(Step - 1); for (QTreeWidgetItem* PieceItem : SelectedItems) { QTreeWidgetItem* Parent = PieceItem->parent(); if (!Parent) continue; int ChildIndex = Parent->indexOfChild(PieceItem); CurrentItem->addChild(Parent->takeChild(ChildIndex)); } UpdateModel(); lcModel* Model = gMainWindow->GetActiveModel(); if (Step > static_cast(Model->GetCurrentStep())) Model->SetCurrentStep(Step); } void lcTimelineWidget::MoveSelectionAfter() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; Step += 2; QList SelectedItems = selectedItems(); gMainWindow->GetActiveModel()->InsertStep(Step); for (int TopLevelItemIdx = topLevelItemCount(); TopLevelItemIdx < Step; TopLevelItemIdx++) { QTreeWidgetItem* StepItem = new QTreeWidgetItem(this, QStringList(tr("Step %1").arg(TopLevelItemIdx + 1))); StepItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDropEnabled); addTopLevelItem(StepItem); StepItem->setExpanded(true); } CurrentItem = topLevelItem(Step - 1); for (QTreeWidgetItem* PieceItem : SelectedItems) { QTreeWidgetItem* Parent = PieceItem->parent(); if (!Parent) continue; int ChildIndex = Parent->indexOfChild(PieceItem); CurrentItem->addChild(Parent->takeChild(ChildIndex)); } UpdateModel(); lcModel* Model = gMainWindow->GetActiveModel(); if (Step > static_cast(Model->GetCurrentStep())) Model->SetCurrentStep(Step); } void lcTimelineWidget::SetCurrentStep() { QTreeWidgetItem* CurrentItem = currentItem(); if (!CurrentItem) return; if (CurrentItem->parent()) CurrentItem = CurrentItem->parent(); int Step = indexOfTopLevelItem(CurrentItem); if (Step == -1) return; gMainWindow->GetActiveModel()->SetCurrentStep(Step + 1); } void lcTimelineWidget::CurrentItemChanged(QTreeWidgetItem* Current, QTreeWidgetItem* Previous) { Q_UNUSED(Previous); if (Current && !Current->parent()) SetCurrentStep(); } void lcTimelineWidget::ItemSelectionChanged() { lcArray Selection; lcStep LastStep = 1; QList SelectedItems = selectedItems(); for (QTreeWidgetItem* PieceItem : SelectedItems) { lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); if (Piece) { LastStep = lcMax(LastStep, Piece->GetStepShow()); Selection.Add(Piece); } } lcPiece* CurrentPiece = nullptr; QTreeWidgetItem* CurrentItem = currentItem(); if (CurrentItem && CurrentItem->isSelected()) CurrentPiece = (lcPiece*)CurrentItem->data(0, Qt::UserRole).value(); bool Blocked = blockSignals(true); mIgnoreUpdates = true; lcModel* Model = gMainWindow->GetActiveModel(); if (LastStep > Model->GetCurrentStep()) { Model->SetCurrentStep(LastStep); UpdateCurrentStepItem(); } Model->SetSelectionAndFocus(Selection, CurrentPiece, LC_PIECE_SECTION_POSITION, false); mIgnoreUpdates = false; blockSignals(Blocked); } void lcTimelineWidget::dropEvent(QDropEvent* Event) { QTreeWidgetItem* DropItem = itemAt(Event->pos()); lcModel* Model = gMainWindow->GetActiveModel(); QList SelectedItems = selectedItems(); clearSelection(); if (DropItem) { QTreeWidgetItem* ParentItem = DropItem->parent(); lcStep Step = indexOfTopLevelItem(ParentItem ? ParentItem : DropItem) + 1; if (Step > Model->GetCurrentStep()) Model->SetCurrentStep(Step); } auto SortItems = [this](QTreeWidgetItem* Item1, QTreeWidgetItem* Item2) { QTreeWidgetItem* StepItem1 = Item1->parent(); QTreeWidgetItem* StepItem2 = Item2->parent(); if (StepItem1 == StepItem2) return StepItem1->indexOfChild(Item1) < StepItem1->indexOfChild(Item2); return indexOfTopLevelItem(StepItem1) < indexOfTopLevelItem(StepItem2); }; std::sort(SelectedItems.begin(), SelectedItems.end(), SortItems); for (QTreeWidgetItem* SelectedItem : SelectedItems) SelectedItem->setSelected(true); QTreeWidget::dropEvent(Event); UpdateModel(); Update(false, false); } void lcTimelineWidget::mousePressEvent(QMouseEvent* Event) { if (Event->button() == Qt::RightButton) { QItemSelection Selection = selectionModel()->selection(); bool Blocked = blockSignals(true); QTreeWidget::mousePressEvent(Event); blockSignals(Blocked); selectionModel()->select(Selection, QItemSelectionModel::ClearAndSelect); } else QTreeWidget::mousePressEvent(Event); } void lcTimelineWidget::mouseDoubleClickEvent(QMouseEvent* MouseEvent) { if (MouseEvent->button() == Qt::LeftButton) { QTreeWidgetItem* CurrentItem = currentItem(); PreviewSelection(CurrentItem); } QTreeWidget::mouseDoubleClickEvent(MouseEvent); } void lcTimelineWidget::PreviewSelection(QTreeWidgetItem* CurrentItem) { if (!CurrentItem) return; lcPiece* Piece = (lcPiece*)CurrentItem->data(0, Qt::UserRole).value(); if (!Piece) return; PieceInfo* Info = Piece->mPieceInfo; if (!Info) return; gMainWindow->PreviewPiece(Info->mFileName, Piece->GetColorCode(), false); } void lcTimelineWidget::UpdateModel() { QList> PieceSteps; for (int TopLevelItemIdx = 0; TopLevelItemIdx < topLevelItemCount(); TopLevelItemIdx++) { QTreeWidgetItem* StepItem = topLevelItem(TopLevelItemIdx); for (int PieceItemIdx = 0; PieceItemIdx < StepItem->childCount(); PieceItemIdx++) { QTreeWidgetItem* PieceItem = StepItem->child(PieceItemIdx); lcPiece* Piece = (lcPiece*)PieceItem->data(0, Qt::UserRole).value(); PieceSteps.append(QPair(Piece, TopLevelItemIdx + 1)); } } mIgnoreUpdates = true; gMainWindow->GetActiveModel()->SetPieceSteps(PieceSteps); mIgnoreUpdates = false; } leocad-23.03/common/lc_timelinewidget.h000066400000000000000000000016771440571307300201200ustar00rootroot00000000000000#pragma once class lcTimelineWidget : public QTreeWidget { Q_OBJECT public: lcTimelineWidget(QWidget* Parent); ~lcTimelineWidget(); void Update(bool Clear, bool UpdateItems); void UpdateSelection(); void InsertStepBefore(); void InsertStepAfter(); void RemoveStep(); void MoveSelection(); void MoveSelectionBefore(); void MoveSelectionAfter(); void SetCurrentStep(); public slots: void CurrentItemChanged(QTreeWidgetItem* Current, QTreeWidgetItem* Previous); void ItemSelectionChanged(); void CustomMenuRequested(QPoint Pos); void PreviewSelection(QTreeWidgetItem* Current); protected: void dropEvent(QDropEvent* DropEvent) override; void mousePressEvent(QMouseEvent* MouseEvent) override; void mouseDoubleClickEvent(QMouseEvent* MouseEvent) override; void UpdateModel(); void UpdateCurrentStepItem(); QMap mIcons; QMap mItems; QTreeWidgetItem* mCurrentStepItem; bool mIgnoreUpdates; }; leocad-23.03/common/lc_view.cpp000066400000000000000000002342451440571307300164120ustar00rootroot00000000000000#include "lc_global.h" #include "lc_view.h" #include "lc_viewwidget.h" #include #include "lc_mainwindow.h" #include "camera.h" #include "texfont.h" #include "lc_texture.h" #include "piece.h" #include "pieceinf.h" #include "lc_synth.h" #include "lc_scene.h" #include "lc_context.h" #include "lc_viewmanipulator.h" #include "lc_viewsphere.h" #include "lc_findreplacewidget.h" lcFindReplaceParams lcView::mFindReplaceParams; lcFindReplaceWidget* lcView::mFindWidget; lcView* lcView::mLastFocusedView; std::vector lcView::mViews; lcView::lcView(lcViewType ViewType, lcModel* Model) : mViewType(ViewType), mScene(new lcScene()), mModel(Model) { mContext = new lcContext(); mViews.push_back(this); mViewManipulator = std::unique_ptr(new lcViewManipulator(this)); mViewSphere = std::unique_ptr(new lcViewSphere(this)); memset(mGridSettings, 0, sizeof(mGridSettings)); mDragState = lcDragState::None; mTrackToolFromOverlay = false; lcView* ActiveView = gMainWindow ? gMainWindow->GetActiveView() : nullptr; if (ActiveView) SetCamera(ActiveView->mCamera, false); else { mCamera = new lcCamera(true); mCamera->SetViewpoint(lcViewpoint::Home); } } lcView::~lcView() { mContext->DestroyVertexBuffer(mGridBuffer); if (gMainWindow && mViewType == lcViewType::View) gMainWindow->RemoveView(this); if (mCamera && mCamera->IsSimple()) delete mCamera; mViews.erase(std::find(mViews.begin(), mViews.end(), this)); if (mLastFocusedView == this) mLastFocusedView = nullptr; if (mDeleteContext) delete mContext; } std::vector lcView::GetModelViews(const lcModel* Model) { std::vector Views; for (lcView* View : mViews) if (View->GetModel() == Model) Views.push_back(View); return Views; } void lcView::UpdateProjectViews(const Project* Project) { for (lcView* View : mViews) { const lcModel* ViewModel = View->GetActiveModel(); if (ViewModel && ViewModel->GetProject() == Project) View->Redraw(); } } void lcView::UpdateAllViews() { for (lcView* View : mViews) View->Redraw(); } void lcView::MakeCurrent() { mContext->MakeCurrent(); } void lcView::Redraw() { if (mWidget) mWidget->update(); } void lcView::SetOffscreenContext() { mContext->SetOffscreenContext(); } void lcView::SetFocus(bool Focus) { if (Focus) { if (mLastFocusedView != this) { delete mFindWidget; mFindWidget = nullptr; mLastFocusedView = this; } emit FocusReceived(); } } void lcView::SetMousePosition(int MouseX, int MouseY) { mMouseX = MouseX; mMouseY = MouseY; } void lcView::SetMouseModifiers(Qt::KeyboardModifiers MouseModifiers) { mMouseModifiers = MouseModifiers; } lcModel* lcView::GetActiveModel() const { return !mActiveSubmodelInstance ? mModel : mActiveSubmodelInstance->mPieceInfo->GetModel(); } void lcView::SetTopSubmodelActive() { lcModel* ActiveModel = GetActiveModel(); if (mActiveSubmodelInstance) { ActiveModel->SetActive(false); mActiveSubmodelInstance = nullptr; } GetActiveModel()->UpdateInterface(); } void lcView::SetSelectedSubmodelActive() { lcModel* ActiveModel = GetActiveModel(); lcObject* Object = ActiveModel->GetFocusObject(); if (mActiveSubmodelInstance) { ActiveModel->SetActive(false); mActiveSubmodelInstance = nullptr; } if (Object && Object->IsPiece()) { lcPiece* Piece = (lcPiece*)Object; if (Piece->mPieceInfo->IsModel()) { mActiveSubmodelTransform = lcMatrix44Identity(); mModel->GetPieceWorldMatrix(Piece, mActiveSubmodelTransform); mActiveSubmodelInstance = Piece; ActiveModel = mActiveSubmodelInstance->mPieceInfo->GetModel(); ActiveModel->SetActive(true); RemoveCamera(); } } GetActiveModel()->UpdateInterface(); } void lcView::CreateResources(lcContext* Context) { Q_UNUSED(Context); gGridTexture = new lcTexture; gGridTexture->CreateGridTexture(); } void lcView::DestroyResources(lcContext* Context) { Q_UNUSED(Context); delete gGridTexture; gGridTexture = nullptr; } void lcView::RemoveCamera() { if (mCamera && mCamera->IsSimple()) return; lcCamera* Camera = mCamera; mCamera = new lcCamera(true); if (Camera) mCamera->CopyPosition(Camera); else mCamera->SetViewpoint(lcViewpoint::Home); emit CameraChanged(); Redraw(); } lcVector3 lcView::ProjectPoint(const lcVector3& Point) const { int Viewport[4] = { 0, 0, mWidth, mHeight }; return lcProjectPoint(Point, mCamera->mWorldView, GetProjectionMatrix(), Viewport); } lcVector3 lcView::UnprojectPoint(const lcVector3& Point) const { int Viewport[4] = { 0, 0, mWidth, mHeight }; return lcUnprojectPoint(Point, mCamera->mWorldView, GetProjectionMatrix(), Viewport); } void lcView::UnprojectPoints(lcVector3* Points, int NumPoints) const { int Viewport[4] = { 0, 0, mWidth, mHeight }; lcUnprojectPoints(Points, NumPoints, mCamera->mWorldView, GetProjectionMatrix(), Viewport); } lcMatrix44 lcView::GetProjectionMatrix() const { float AspectRatio = (float)mWidth / (float)mHeight; if (mCamera->IsOrtho()) { float OrthoHeight = mCamera->GetOrthoHeight() / 2.0f; float OrthoWidth = OrthoHeight * AspectRatio; return lcMatrix44Ortho(-OrthoWidth, OrthoWidth, -OrthoHeight, OrthoHeight, mCamera->m_zNear, mCamera->m_zFar * 4); } else return lcMatrix44Perspective(mCamera->m_fovy, AspectRatio, mCamera->m_zNear, mCamera->m_zFar); } lcMatrix44 lcView::GetTileProjectionMatrix(int CurrentRow, int CurrentColumn, int CurrentTileWidth, int CurrentTileHeight) const { int ImageWidth = mRenderImage.width(); int ImageHeight = mRenderImage.height(); double ImageLeft, ImageRight, ImageBottom, ImageTop, Near, Far; double AspectRatio = (double)ImageWidth / (double)ImageHeight; if (mCamera->IsOrtho()) { float OrthoHeight = mCamera->GetOrthoHeight() / 2.0f; float OrthoWidth = OrthoHeight * AspectRatio; ImageLeft = -OrthoWidth; ImageRight = OrthoWidth; ImageBottom = -OrthoHeight; ImageTop = OrthoHeight; Near = mCamera->m_zNear; Far = mCamera->m_zFar * 4; } else { double xmin, xmax, ymin, ymax; ymax = mCamera->m_zNear * tan(mCamera->m_fovy * 3.14159265 / 360.0); ymin = -ymax; xmin = ymin * AspectRatio; xmax = ymax * AspectRatio; ImageLeft = xmin; ImageRight = xmax; ImageBottom = ymin; ImageTop = ymax; Near = mCamera->m_zNear; Far = mCamera->m_zFar; } double Left = ImageLeft + (ImageRight - ImageLeft) * (CurrentColumn * mWidth) / ImageWidth; double Right = Left + (ImageRight - ImageLeft) * CurrentTileWidth / ImageWidth; double Bottom = ImageBottom + (ImageTop - ImageBottom) * (CurrentRow * mHeight) / ImageHeight; double Top = Bottom + (ImageTop - ImageBottom) * CurrentTileHeight / ImageHeight; if (mCamera->IsOrtho()) return lcMatrix44Ortho(Left, Right, Bottom, Top, Near, Far); else return lcMatrix44Frustum(Left, Right, Bottom, Top, Near, Far); } void lcView::ShowContextMenu() const { if (mViewType != lcViewType::View) return; QAction** Actions = gMainWindow->mActions; QMenu* Popup = new QMenu(); Popup->addAction(Actions[LC_EDIT_CUT]); Popup->addAction(Actions[LC_EDIT_COPY]); Popup->addAction(Actions[LC_EDIT_PASTE]); Popup->addAction(Actions[LC_EDIT_PASTE_STEPS]); Popup->addAction(Actions[LC_PIECE_DUPLICATE]); Popup->addSeparator(); Popup->addAction(Actions[LC_PIECE_CONTROL_POINT_INSERT]); Popup->addAction(Actions[LC_PIECE_CONTROL_POINT_REMOVE]); Popup->addSeparator(); Popup->addAction(Actions[LC_PIECE_EDIT_SELECTED_SUBMODEL]); Popup->addAction(Actions[LC_PIECE_EDIT_END_SUBMODEL]); Popup->addAction(Actions[LC_PIECE_VIEW_SELECTED_MODEL]); Popup->addAction(Actions[LC_PIECE_INLINE_SELECTED_MODELS]); Popup->addAction(Actions[LC_PIECE_MOVE_SELECTION_TO_MODEL]); Popup->addSeparator(); Popup->addMenu(gMainWindow->GetToolsMenu()); Popup->addMenu(gMainWindow->GetViewpointMenu()); Popup->addMenu(gMainWindow->GetCameraMenu()); Popup->addMenu(gMainWindow->GetProjectionMenu()); Popup->addMenu(gMainWindow->GetShadingMenu()); Popup->addSeparator(); Popup->addAction(Actions[LC_VIEW_SPLIT_HORIZONTAL]); Popup->addAction(Actions[LC_VIEW_SPLIT_VERTICAL]); Popup->addAction(Actions[LC_VIEW_REMOVE_VIEW]); Popup->addAction(Actions[LC_VIEW_RESET_VIEWS]); Popup->exec(QCursor::pos()); delete Popup; } bool lcView::CloseFindReplaceDialog() { if (mFindWidget && (mWidget->hasFocus() || mFindWidget->focusWidget())) { delete mFindWidget; mFindWidget = nullptr; return true; } return false; } void lcView::ShowFindReplaceWidget(bool Replace) { delete mFindWidget; mFindReplaceParams = lcFindReplaceParams(); mFindWidget = new lcFindReplaceWidget(mWidget, GetActiveModel(), Replace); } lcVector3 lcView::GetMoveDirection(const lcVector3& Direction) const { if (lcGetPreferences().mFixedAxes) return Direction; // TODO: rewrite this lcVector3 axis = Direction; lcVector3 Pts[3] = { lcVector3(5.0f, 5.0f, 0.1f), lcVector3(10.0f, 5.0f, 0.1f), lcVector3(5.0f, 10.0f, 0.1f) }; UnprojectPoints(Pts, 3); float ax, ay; lcVector3 vx((Pts[1][0] - Pts[0][0]), (Pts[1][1] - Pts[0][1]), 0);//Pts[1][2] - Pts[0][2] }; vx.Normalize(); lcVector3 x(1, 0, 0); ax = acosf(lcDot(vx, x)); lcVector3 vy((Pts[2][0] - Pts[0][0]), (Pts[2][1] - Pts[0][1]), 0);//Pts[2][2] - Pts[0][2] }; vy.Normalize(); lcVector3 y(0, -1, 0); ay = acosf(lcDot(vy, y)); if (ax > 135) axis[0] = -axis[0]; if (ay < 45) axis[1] = -axis[1]; if (ax >= 45 && ax <= 135) { float tmp = axis[0]; ax = acosf(lcDot(vx, y)); if (ax > 90) { axis[0] = -axis[1]; axis[1] = tmp; } else { axis[0] = axis[1]; axis[1] = -tmp; } } return axis; } lcMatrix44 lcView::GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info) const { lcModel* ActiveModel = GetActiveModel(); lcPieceInfoRayTest PieceInfoRayTest = FindPieceInfoUnderPointer(IgnoreSelected); if (PieceInfoRayTest.Info) { lcVector3 Position = PieceInfoRayTest.Plane; if (Position.x > 0.0f) Position.x += fabsf(Info->GetBoundingBox().Min.x); else if (Position.x < 0.0f) Position.x -= fabsf(Info->GetBoundingBox().Max.x); else if (Position.y > 0.0f) Position.y += fabsf(Info->GetBoundingBox().Min.y); else if (Position.y < 0.0f) Position.y -= fabsf(Info->GetBoundingBox().Max.y); else if (Position.z > 0.0f) Position.z += fabsf(Info->GetBoundingBox().Min.z); else if (Position.z < 0.0f) Position.z -= fabsf(Info->GetBoundingBox().Max.z); if (gMainWindow->GetRelativeTransform()) Position = lcMul31(ActiveModel->SnapPosition(Position), PieceInfoRayTest.Transform); else Position = ActiveModel->SnapPosition(lcMul31(Position, PieceInfoRayTest.Transform)); lcMatrix44 WorldMatrix = PieceInfoRayTest.Transform; WorldMatrix.SetTranslation(Position); return WorldMatrix; } std::array ClickPoints = {{ lcVector3((float)mMouseX, (float)mMouseY, 0.0f), lcVector3((float)mMouseX, (float)mMouseY, 1.0f) }}; UnprojectPoints(ClickPoints.data(), 2); if (ActiveModel != mModel) { lcMatrix44 InverseMatrix = lcMatrix44AffineInverse(mActiveSubmodelTransform); for (lcVector3& Point : ClickPoints) Point = lcMul31(Point, InverseMatrix); } const lcBoundingBox& BoundingBox = Info->GetBoundingBox(); lcVector3 Intersection; if (lcLineSegmentPlaneIntersection(&Intersection, ClickPoints[0], ClickPoints[1], lcVector4(0, 0, 1, BoundingBox.Min.z))) { Intersection = ActiveModel->SnapPosition(Intersection); return lcMatrix44Translation(Intersection); } lcVector3 Position; if (!ActiveModel->GetFocusPosition(Position)) Position = ActiveModel->GetSelectionOrModelCenter(); lcVector3 FrontVector(mCamera->mTargetPosition - mCamera->mPosition); if (lcLineSegmentPlaneIntersection(&Intersection, ClickPoints[0], ClickPoints[1], lcVector4(FrontVector, -lcDot(FrontVector, Position)))) { Intersection = ActiveModel->SnapPosition(Intersection); return lcMatrix44Translation(Intersection); } return lcMatrix44Translation(UnprojectPoint(lcVector3((float)mMouseX, (float)mMouseY, 0.9f))); } lcVector3 lcView::GetCameraLightInsertPosition() const { lcModel* ActiveModel = GetActiveModel(); std::array ClickPoints = { { lcVector3((float)mMouseX, (float)mMouseY, 0.0f), lcVector3((float)mMouseX, (float)mMouseY, 1.0f) } }; UnprojectPoints(ClickPoints.data(), 2); if (ActiveModel != mModel) { lcMatrix44 InverseMatrix = lcMatrix44AffineInverse(mActiveSubmodelTransform); for (lcVector3& Point : ClickPoints) Point = lcMul31(Point, InverseMatrix); } lcVector3 Min, Max; lcVector3 Center; if (ActiveModel->GetVisiblePiecesBoundingBox(Min, Max)) Center = (Min + Max) / 2.0f; else Center = lcVector3(0.0f, 0.0f, 0.0f); return lcRayPointClosestPoint(Center, ClickPoints[0], ClickPoints[1]); } void lcView::GetRayUnderPointer(lcVector3& Start, lcVector3& End) const { lcVector3 StartEnd[2] = { lcVector3((float)mMouseX, (float)mMouseY, 0.0f), lcVector3((float)mMouseX, (float)mMouseY, 1.0f) }; UnprojectPoints(StartEnd, 2); Start = StartEnd[0]; End = StartEnd[1]; } lcObjectSection lcView::FindObjectUnderPointer(bool PiecesOnly, bool IgnoreSelected) const { lcVector3 StartEnd[2] = { lcVector3((float)mMouseX, (float)mMouseY, 0.0f), lcVector3((float)mMouseX, (float)mMouseY, 1.0f) }; UnprojectPoints(StartEnd, 2); lcObjectRayTest ObjectRayTest; ObjectRayTest.PiecesOnly = PiecesOnly; ObjectRayTest.IgnoreSelected = IgnoreSelected; ObjectRayTest.ViewCamera = mCamera; ObjectRayTest.Start = StartEnd[0]; ObjectRayTest.End = StartEnd[1]; lcModel* ActiveModel = GetActiveModel(); if (ActiveModel != mModel) { lcMatrix44 InverseMatrix = lcMatrix44AffineInverse(mActiveSubmodelTransform); ObjectRayTest.Start = lcMul31(ObjectRayTest.Start, InverseMatrix); ObjectRayTest.End = lcMul31(ObjectRayTest.End, InverseMatrix); } ActiveModel->RayTest(ObjectRayTest); return ObjectRayTest.ObjectSection; } lcPieceInfoRayTest lcView::FindPieceInfoUnderPointer(bool IgnoreSelected) const { lcVector3 StartEnd[2] = { lcVector3((float)mMouseX, (float)mMouseY, 0.0f), lcVector3((float)mMouseX, (float)mMouseY, 1.0f) }; UnprojectPoints(StartEnd, 2); lcObjectRayTest ObjectRayTest; ObjectRayTest.PiecesOnly = true; ObjectRayTest.IgnoreSelected = IgnoreSelected; ObjectRayTest.ViewCamera = mCamera; ObjectRayTest.Start = StartEnd[0]; ObjectRayTest.End = StartEnd[1]; lcModel* ActiveModel = GetActiveModel(); if (ActiveModel != mModel) { lcMatrix44 InverseMatrix = lcMatrix44AffineInverse(mActiveSubmodelTransform); ObjectRayTest.Start = lcMul31(ObjectRayTest.Start, InverseMatrix); ObjectRayTest.End = lcMul31(ObjectRayTest.End, InverseMatrix); } ActiveModel->RayTest(ObjectRayTest); return ObjectRayTest.PieceInfoRayTest; } lcArray lcView::FindObjectsInBox(float x1, float y1, float x2, float y2) const { float Left, Top, Bottom, Right; if (x1 < x2) { Left = x1; Right = x2; } else { Left = x2; Right = x1; } if (y1 > y2) { Top = y1; Bottom = y2; } else { Top = y2; Bottom = y1; } std::array Corners = {{ lcVector3(Left, Top, 0), lcVector3(Left, Bottom, 0), lcVector3(Right, Bottom, 0), lcVector3(Right, Top, 0), lcVector3(Left, Top, 1), lcVector3(Right, Bottom, 1) }}; UnprojectPoints(Corners.data(), (int)Corners.size()); lcModel* ActiveModel = GetActiveModel(); if (ActiveModel != mModel) { lcMatrix44 InverseMatrix = lcMatrix44AffineInverse(mActiveSubmodelTransform); for (lcVector3& Point : Corners) Point = lcMul31(Point, InverseMatrix); } lcVector3 PlaneNormals[6]; PlaneNormals[0] = lcNormalize(lcCross(Corners[4] - Corners[0], Corners[1] - Corners[0])); // Left PlaneNormals[1] = lcNormalize(lcCross(Corners[5] - Corners[2], Corners[3] - Corners[2])); // Right PlaneNormals[2] = lcNormalize(lcCross(Corners[3] - Corners[0], Corners[4] - Corners[0])); // Top PlaneNormals[3] = lcNormalize(lcCross(Corners[1] - Corners[2], Corners[5] - Corners[2])); // Bottom PlaneNormals[4] = lcNormalize(lcCross(Corners[1] - Corners[0], Corners[3] - Corners[0])); // Front PlaneNormals[5] = lcNormalize(lcCross(Corners[1] - Corners[2], Corners[3] - Corners[2])); // Back lcObjectBoxTest ObjectBoxTest; ObjectBoxTest.ViewCamera = mCamera; ObjectBoxTest.Planes[0] = lcVector4(PlaneNormals[0], -lcDot(PlaneNormals[0], Corners[0])); ObjectBoxTest.Planes[1] = lcVector4(PlaneNormals[1], -lcDot(PlaneNormals[1], Corners[5])); ObjectBoxTest.Planes[2] = lcVector4(PlaneNormals[2], -lcDot(PlaneNormals[2], Corners[0])); ObjectBoxTest.Planes[3] = lcVector4(PlaneNormals[3], -lcDot(PlaneNormals[3], Corners[5])); ObjectBoxTest.Planes[4] = lcVector4(PlaneNormals[4], -lcDot(PlaneNormals[4], Corners[0])); ObjectBoxTest.Planes[5] = lcVector4(PlaneNormals[5], -lcDot(PlaneNormals[5], Corners[5])); ActiveModel->BoxTest(ObjectBoxTest); return ObjectBoxTest.Objects; } std::vector lcView::GetStepImages(lcStep Start, lcStep End) { std::vector Images; if (!BeginRenderToImage(mWidth, mHeight)) { QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Error creating images.")); return Images; } const lcStep CurrentStep = mModel->GetCurrentStep(); for (lcStep Step = Start; Step <= End; Step++) { mModel->SetTemporaryStep(Step); OnDraw(); Images.emplace_back(GetRenderImage()); } EndRenderToImage(); mModel->SetTemporaryStep(CurrentStep); if (!mModel->IsActive()) mModel->CalculateStep(LC_STEP_MAX); return Images; } void lcView::SaveStepImages(const QString& BaseName, bool AddStepSuffix, lcStep Start, lcStep End, std::function ProgressCallback) { std::vector Images = GetStepImages(Start, End); for (lcStep Step = Start; Step <= End; Step++) { QString FileName; if (AddStepSuffix) FileName = BaseName.arg(Step, 2, 10, QLatin1Char('0')); else FileName = BaseName; QImageWriter Writer(FileName); if (Writer.format().isEmpty()) Writer.setFormat("png"); if (!Writer.write(Images[Step - Start])) { QMessageBox::information(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, Writer.errorString())); break; } if (ProgressCallback) ProgressCallback(FileName); } } bool lcView::BeginRenderToImage(int Width, int Height) { GLint MaxTexture; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxTexture); MaxTexture = qMin(MaxTexture, 2048); const int Samples = QSurfaceFormat::defaultFormat().samples(); if (Samples > 1) MaxTexture /= Samples; int TileWidth = qMin(Width, MaxTexture); int TileHeight = qMin(Height, MaxTexture); mWidth = TileWidth; mHeight = TileHeight; mRenderImage = QImage(Width, Height, QImage::Format_ARGB32); QOpenGLFramebufferObjectFormat Format; Format.setAttachment(QOpenGLFramebufferObject::Depth); if (QSurfaceFormat::defaultFormat().samples() > 1) Format.setSamples(QSurfaceFormat::defaultFormat().samples()); mRenderFramebuffer = std::unique_ptr(new QOpenGLFramebufferObject(QSize(TileWidth, TileHeight), Format)); return mRenderFramebuffer->bind(); } void lcView::EndRenderToImage() { mRenderFramebuffer.reset(); } QImage lcView::GetRenderImage() const { return mRenderImage; } void lcView::BindRenderFramebuffer() { mRenderFramebuffer->bind(); } void lcView::UnbindRenderFramebuffer() { mRenderFramebuffer->release(); } QImage lcView::GetRenderFramebufferImage() const { return mRenderFramebuffer->toImage(); } void lcView::OnDraw() { if (!mModel) return; //#define LC_PROFILE_DRAW #ifdef LC_PROFILE_DRAW static std::array QueryResults; static std::array TimerResults; static int FrameNumber; QElapsedTimer Timer; QOpenGLTimerQuery Query; if (!Query.isCreated()) Query.create(); Query.begin(); Timer.start(); #endif const lcPreferences& Preferences = lcGetPreferences(); const bool DrawOverlays = mWidget != nullptr; const bool DrawInterface = mWidget != nullptr && mViewType == lcViewType::View; lcShadingMode ShadingMode = Preferences.mShadingMode; if (ShadingMode == lcShadingMode::Wireframe && !mWidget) ShadingMode = lcShadingMode::Flat; mScene->SetShadingMode(ShadingMode); mScene->SetAllowLOD(Preferences.mAllowLOD && mWidget != nullptr); mScene->SetLODDistance(Preferences.mMeshLODDistance); mScene->Begin(mCamera->mWorldView); mScene->SetActiveSubmodelInstance(mActiveSubmodelInstance, mActiveSubmodelTransform); mScene->SetDrawInterface(DrawInterface); mModel->GetScene(mScene.get(), mCamera, Preferences.mHighlightNewParts, Preferences.mFadeSteps); if (DrawInterface && mTrackTool == lcTrackTool::Insert) { PieceInfo* Info = gMainWindow->GetCurrentPieceInfo(); if (Info) { lcMatrix44 WorldMatrix = GetPieceInsertPosition(false, Info); if (GetActiveModel() != mModel) WorldMatrix = lcMul(WorldMatrix, mActiveSubmodelTransform); Info->AddRenderMeshes(mScene.get(), WorldMatrix, gMainWindow->mColorIndex, lcRenderMeshState::Focused, false); } } if (DrawInterface) mScene->SetPreTranslucentCallback([this]() { DrawGrid(); }); mScene->End(); int TotalTileRows = 1; int TotalTileColumns = 1; if (!mRenderImage.isNull()) { int ImageWidth = mRenderImage.width(); int ImageHeight = mRenderImage.height(); if (ImageWidth > mWidth || ImageHeight > mHeight) { TotalTileColumns = (mWidth + ImageWidth - 1) / mWidth; TotalTileRows = (mHeight + ImageHeight - 1) / mHeight; } } for (int CurrentTileRow = 0; CurrentTileRow < TotalTileRows; CurrentTileRow++) { for (int CurrentTileColumn = 0; CurrentTileColumn < TotalTileColumns; CurrentTileColumn++) { mContext->SetDefaultState(); mContext->SetViewport(0, 0, mWidth, mHeight); int CurrentTileWidth, CurrentTileHeight; if (!mRenderImage.isNull() && (TotalTileRows > 1 || TotalTileColumns > 1)) { if (CurrentTileRow < TotalTileRows - 1) CurrentTileHeight = mHeight; else CurrentTileHeight = mRenderImage.height() - (TotalTileRows - 1) * (mHeight); if (CurrentTileColumn < TotalTileColumns - 1) CurrentTileWidth = mWidth; else CurrentTileWidth = mRenderImage.width() - (TotalTileColumns - 1) * (mWidth); DrawBackground(CurrentTileRow, TotalTileRows, CurrentTileHeight); mContext->SetViewport(0, 0, CurrentTileWidth, CurrentTileHeight); mContext->SetProjectionMatrix(GetTileProjectionMatrix(CurrentTileRow, CurrentTileColumn, CurrentTileWidth, CurrentTileHeight)); } else { CurrentTileWidth = mWidth; CurrentTileHeight = mHeight; DrawBackground(CurrentTileRow, TotalTileRows, CurrentTileHeight); mContext->SetProjectionMatrix(GetProjectionMatrix()); } mContext->SetLineWidth(Preferences.mLineWidth); mScene->Draw(mContext); if (!mRenderImage.isNull()) { UnbindRenderFramebuffer(); QImage TileImage = GetRenderFramebufferImage(); BindRenderFramebuffer(); quint8* Buffer = TileImage.bits(); uchar* ImageBuffer = mRenderImage.bits(); quint32 TileY = 0, SrcY = 0; if (CurrentTileRow != TotalTileRows - 1) TileY = (TotalTileRows - CurrentTileRow - 1) * mHeight - ((mHeight - mRenderImage.height() % mHeight) % mHeight); else if (TotalTileRows > 1) SrcY = (mHeight - mRenderImage.height() % mHeight) % mHeight; quint32 TileStart = ((CurrentTileColumn * mWidth) + (TileY * mRenderImage.width())) * 4; for (int y = 0; y < CurrentTileHeight; y++) { quint8* src = Buffer + (SrcY + y) * mWidth * 4; quint8* dst = ImageBuffer + TileStart + y * mRenderImage.width() * 4; memcpy(dst, src, CurrentTileWidth * 4); } } } } if (DrawInterface) mScene->DrawInterfaceObjects(mContext); if (DrawOverlays) DrawAxes(); if (DrawInterface) { lcTool Tool = gMainWindow->GetTool(); lcModel* ActiveModel = GetActiveModel(); if ((Tool == lcTool::Select || Tool == lcTool::Move) && mTrackButton == lcTrackButton::None && ActiveModel->AnyObjectsSelected()) mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool); else if (GetCurrentTool() == lcTool::Move && mTrackButton != lcTrackButton::None) mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool); else if ((Tool == lcTool::Rotate || (Tool == lcTool::Select && mTrackButton != lcTrackButton::None && mTrackTool >= lcTrackTool::RotateX && mTrackTool <= lcTrackTool::RotateXYZ)) && ActiveModel->AnyPiecesSelected()) mViewManipulator->DrawRotate(mTrackButton, mTrackTool); else if ((mTrackTool == lcTrackTool::Select || mTrackTool == lcTrackTool::ZoomRegion) && mTrackButton != lcTrackButton::None) DrawSelectZoomRegionOverlay(); else if (Tool == lcTool::RotateView && mTrackButton == lcTrackButton::None) DrawRotateViewOverlay(); } if (DrawOverlays) { mViewSphere->Draw(); DrawViewport(); } #ifdef LC_PROFILE_DRAW qint64 TimerElapsed = Timer.nsecsElapsed(); Query.end(); GLuint64 QueryElapsed = Query.waitForResult(); QueryResults[FrameNumber % QueryResults.size()] = QueryElapsed; TimerResults[FrameNumber % TimerResults.size()] = TimerElapsed; FrameNumber++; GLuint64 QueryAverage = 0; for (GLuint64 Result : QueryResults) QueryAverage += Result; QueryAverage /= QueryResults.size(); GLuint64 TimerAverage = 0; for (GLuint64 Result : TimerResults) TimerAverage += Result; TimerAverage /= TimerResults.size(); mContext->SetWorldMatrix(lcMatrix44Identity()); mContext->SetViewMatrix(lcMatrix44Translation(lcVector3(0.375, 0.375, 0.0))); mContext->SetProjectionMatrix(lcMatrix44Ortho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f)); QString Line = QString("GPU: %1 CPU: %2").arg(QString::number(QueryAverage / 1000000.0, 'f', 2), QString::number(TimerAverage / 1000000.0, 'f', 2)); mContext->SetMaterial(lcMaterialType::UnlitTextureModulate); mContext->SetColor(lcVector4FromColor(lcGetPreferences().mTextColor)); mContext->BindTexture2D(gTexFont.GetTexture()); mContext->EnableDepthTest(false); mContext->EnableColorBlend(true); gTexFont.PrintText(mContext, 3.0f, (float)mHeight - 1.0f - 6.0f, 0.0f, Line.toLatin1().constData()); mContext->EnableColorBlend(false); mContext->EnableDepthTest(true); Redraw(); #endif mContext->ClearResources(); } void lcView::DrawBackground(int CurrentTileRow, int TotalTileRows, int CurrentTileHeight) const { if (mOverrideBackgroundColor) { lcVector4 BackgroundColor(lcVector4FromColor(mBackgroundColor)); mContext->ClearColorAndDepth(BackgroundColor); return; } const lcPreferences& Preferences = lcGetPreferences(); if (!Preferences.mBackgroundGradient) { lcVector4 BackgroundColor(lcVector3FromColor(Preferences.mBackgroundSolidColor), 0.0f); mContext->ClearColorAndDepth(BackgroundColor); return; } mContext->ClearDepth(); mContext->SetDepthWrite(false); mContext->EnableDepthTest(false); float ViewWidth = (float)mWidth; float ViewHeight = (float)mHeight; mContext->SetWorldMatrix(lcMatrix44Identity()); mContext->SetViewMatrix(lcMatrix44Identity()); mContext->SetProjectionMatrix(lcMatrix44Ortho(0.0f, ViewWidth, 0.0f, ViewHeight, -1.0f, 1.0f)); const int TotalHeight = TotalTileRows == 1 ? mHeight : mRenderImage.height(); const quint32 TopY = CurrentTileRow * mHeight + CurrentTileHeight; const double t1 = 1.0 - (double)TopY / (double)TotalHeight; const double t2 = 1.0 - (double)(TopY - CurrentTileHeight) / (double)TotalHeight; const quint32 ColorTop = Preferences.mBackgroundGradientColorTop; const quint32 ColorBottom = Preferences.mBackgroundGradientColorBottom; double TopRed = LC_RGBA_RED(ColorTop); double TopGreen = LC_RGBA_GREEN(ColorTop); double TopBlue = LC_RGBA_BLUE(ColorTop); double TopAlpha = LC_RGBA_ALPHA(ColorTop); double BottomRed = LC_RGBA_RED(ColorBottom); double BottomGreen = LC_RGBA_GREEN(ColorBottom); double BottomBlue = LC_RGBA_BLUE(ColorBottom); double BottomAlpha = LC_RGBA_ALPHA(ColorBottom); const double DeltaRed = BottomRed - TopRed; const double DeltaGreen = BottomGreen - TopGreen; const double DeltaBlue = BottomBlue - TopBlue; const double DeltaAlpha = BottomAlpha - TopAlpha; BottomRed = TopRed + DeltaRed * t2; BottomGreen = TopGreen + DeltaGreen * t2; BottomBlue = TopBlue + DeltaBlue * t2; BottomAlpha = TopAlpha + DeltaAlpha * t2; TopRed = TopRed + DeltaRed * t1; TopGreen = TopGreen + DeltaGreen * t1; TopBlue = TopBlue + DeltaBlue * t1; TopAlpha = TopAlpha + DeltaAlpha * t1; const quint32 Color1 = LC_RGBA(TopRed, TopGreen, TopBlue, TopAlpha); const quint32 Color2 = LC_RGBA(BottomRed, BottomGreen, BottomBlue, BottomAlpha); struct lcBackgroundVertex { float x, y; quint32 Color; }; const lcBackgroundVertex Verts[4] = { { ViewWidth, ViewHeight, Color1 }, { 0.0f, ViewHeight, Color1 }, { 0.0f, 0.0f, Color2 }, { ViewWidth, 0.0f, Color2 } }; mContext->SetMaterial(lcMaterialType::UnlitVertexColor); mContext->SetVertexBufferPointer(Verts); mContext->SetVertexFormat(0, 2, 0, 0, 4, false); mContext->DrawPrimitives(GL_TRIANGLE_FAN, 0, 4); mContext->EnableDepthTest(true); mContext->SetDepthWrite(true); } void lcView::DrawViewport() const { mContext->SetWorldMatrix(lcMatrix44Identity()); mContext->SetViewMatrix(lcMatrix44Translation(lcVector3(0.375, 0.375, 0.0))); mContext->SetProjectionMatrix(lcMatrix44Ortho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f)); mContext->SetLineWidth(1.0f); mContext->SetDepthWrite(false); mContext->EnableDepthTest(false); mContext->SetMaterial(lcMaterialType::UnlitColor); if (mLastFocusedView == this) mContext->SetColor(lcVector4FromColor(lcGetPreferences().mActiveViewColor)); else mContext->SetColor(lcVector4FromColor(lcGetPreferences().mInactiveViewColor)); float Verts[8] = { 0.0f, 0.0f, mWidth - 1.0f, 0.0f, mWidth - 1.0f, mHeight - 1.0f, 0.0f, mHeight - 1.0f }; mContext->SetVertexBufferPointer(Verts); mContext->SetVertexFormatPosition(2); mContext->DrawPrimitives(GL_LINE_LOOP, 0, 4); QString CameraName = mCamera->GetName(); if (!CameraName.isEmpty()) { mContext->SetMaterial(lcMaterialType::UnlitTextureModulate); mContext->SetColor(lcVector4FromColor(lcGetPreferences().mTextColor)); mContext->BindTexture2D(gTexFont.GetTexture()); mContext->EnableColorBlend(true); gTexFont.PrintText(mContext, 3.0f, (float)mHeight - 1.0f - 6.0f, 0.0f, CameraName.toLatin1().constData()); mContext->EnableColorBlend(false); } mContext->SetDepthWrite(true); mContext->EnableDepthTest(true); } void lcView::DrawAxes() const { const lcPreferences& Preferences = lcGetPreferences(); switch (mViewType) { case lcViewType::View: if (!Preferences.mDrawAxes) return; break; case lcViewType::Preview: if (!Preferences.mDrawPreviewAxis) return; break; case lcViewType::Minifig: case lcViewType::PartsList: case lcViewType::Count: return; } // mContext->ClearDepth(); struct lcAxisVertex { float x, y, z; quint32 Color; }; const quint32 Red = LC_RGBA(204, 0, 0, 255); const quint32 Green = LC_RGBA(0, 204, 0, 255); const quint32 Blue = LC_RGBA(0, 0, 204, 255); const lcAxisVertex Verts[30] = { { 0.00f, 0.00f, 0.00f, Red }, { 20.00f, 0.00f, 0.00f, Red }, { 12.00f, 3.00f, 0.00f, Red }, { 12.00f, 2.12f, 2.12f, Red }, { 12.00f, 0.00f, 3.00f, Red }, { 12.00f, -2.12f, 2.12f, Red }, { 12.00f, -3.00f, 0.00f, Red }, { 12.00f, -2.12f, -2.12f, Red }, { 12.00f, 0.00f, -3.00f, Red }, { 12.00f, 2.12f, -2.12f, Red }, { 0.00f, 0.00f, 0.00f, Green }, { 0.00f, 20.00f, 0.00f, Green }, { 3.00f, 12.00f, 0.00f, Green }, { 2.12f, 12.00f, 2.12f, Green }, { 0.00f, 12.00f, 3.00f, Green }, { -2.12f, 12.00f, 2.12f, Green }, { -3.00f, 12.00f, 0.00f, Green }, { -2.12f, 12.00f, -2.12f, Green }, { 0.00f, 12.00f, -3.00f, Green }, { 2.12f, 12.00f, -2.12f, Green }, { 0.00f, 0.00f, 0.00f, Blue }, { 0.00f, 0.00f, 20.00f, Blue }, { 0.00f, 3.00f, 12.00f, Blue }, { 2.12f, 2.12f, 12.00f, Blue }, { 3.00f, 0.00f, 12.00f, Blue }, { 2.12f, -2.12f, 12.00f, Blue }, { 0.00f, -3.00f, 12.00f, Blue }, { -2.12f, -2.12f, 12.00f, Blue }, { -3.00f, 0.00f, 12.00f, Blue }, { -2.12f, 2.12f, 12.00f, Blue } }; const GLushort Indices[78] = { 0, 1, 10, 11, 20, 21, 1, 2, 3, 1, 3, 4, 1, 4, 5, 1, 5, 6, 1, 6, 7, 1, 7, 8, 1, 8, 9, 1, 9, 2, 11, 12, 13, 11, 13, 14, 11, 14, 15, 11, 15, 16, 11, 16, 17, 11, 17, 18, 11, 18, 19, 11, 19, 12, 21, 22, 23, 21, 23, 24, 21, 24, 25, 21, 25, 26, 21, 26, 27, 21, 27, 28, 21, 28, 29, 21, 29, 22 }; lcMatrix44 TranslationMatrix; switch (Preferences.mAxisIconLocation) { default: case lcAxisIconLocation::BottomLeft: TranslationMatrix = lcMatrix44Translation(lcVector3(32, 32, 0.0f)); break; case lcAxisIconLocation::BottomRight: TranslationMatrix = lcMatrix44Translation(lcVector3(mWidth - 36, 32, 0.0f)); break; case lcAxisIconLocation::TopLeft: TranslationMatrix = lcMatrix44Translation(lcVector3(32, mHeight - 36, 0.0f)); break; case lcAxisIconLocation::TopRight: TranslationMatrix = lcMatrix44Translation(lcVector3(mWidth - 36, mHeight - 36, 0.0f)); break; } lcMatrix44 WorldViewMatrix = mCamera->mWorldView; WorldViewMatrix.SetTranslation(lcVector3(0, 0, 0)); mContext->SetLineWidth(1.0f); mContext->SetMaterial(lcMaterialType::UnlitVertexColor); mContext->SetWorldMatrix(lcMatrix44Identity()); mContext->SetViewMatrix(lcMul(WorldViewMatrix, TranslationMatrix)); mContext->SetProjectionMatrix(lcMatrix44Ortho(0, mWidth, 0, mHeight, -50, 50)); mContext->SetVertexBufferPointer(Verts); mContext->SetVertexFormat(0, 3, 0, 0, 4, false); mContext->SetIndexBufferPointer(Indices); mContext->DrawIndexedPrimitives(GL_LINES, 6, GL_UNSIGNED_SHORT, 0); mContext->DrawIndexedPrimitives(GL_TRIANGLES, 72, GL_UNSIGNED_SHORT, 6 * 2); mContext->SetMaterial(lcMaterialType::UnlitTextureModulate); mContext->SetViewMatrix(TranslationMatrix); mContext->BindTexture2D(gTexFont.GetTexture()); mContext->EnableColorBlend(true); float TextBuffer[6 * 5 * 3]; lcVector3 PosX = lcMul30(lcVector3(25.0f, 0.0f, 0.0f), WorldViewMatrix); gTexFont.GetGlyphTriangles(PosX.x, PosX.y, PosX.z, 'X', TextBuffer); lcVector3 PosY = lcMul30(lcVector3(0.0f, 25.0f, 0.0f), WorldViewMatrix); gTexFont.GetGlyphTriangles(PosY.x, PosY.y, PosY.z, 'Y', TextBuffer + 5 * 6); lcVector3 PosZ = lcMul30(lcVector3(0.0f, 0.0f, 25.0f), WorldViewMatrix); gTexFont.GetGlyphTriangles(PosZ.x, PosZ.y, PosZ.z, 'Z', TextBuffer + 5 * 6 * 2); mContext->SetVertexBufferPointer(TextBuffer); mContext->SetVertexFormat(0, 3, 0, 2, 0, false); mContext->SetColor(lcVector4FromColor(lcGetPreferences().mAxesColor)); mContext->DrawPrimitives(GL_TRIANGLES, 0, 6 * 3); mContext->EnableColorBlend(false); } void lcView::DrawSelectZoomRegionOverlay() { mContext->SetMaterial(lcMaterialType::UnlitColor); mContext->SetWorldMatrix(lcMatrix44Identity()); mContext->SetViewMatrix(lcMatrix44Translation(lcVector3(0.375, 0.375, 0.0))); mContext->SetProjectionMatrix(lcMatrix44Ortho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f)); mContext->SetLineWidth(1.0f); mContext->EnableDepthTest(false); float pt1x = (float)mMouseDownX; float pt1y = (float)mMouseDownY; float pt2x = (float)mMouseX; float pt2y = (float)mMouseY; float Left, Right, Bottom, Top; if (pt1x < pt2x) { Left = pt1x; Right = pt2x; } else { Left = pt2x; Right = pt1x; } if (pt1y < pt2y) { Bottom = pt1y; Top = pt2y; } else { Bottom = pt2y; Top = pt1y; } Left = lcMax(Left, 0.0f); Right = lcMin(Right, mWidth - 1.0f); Bottom = lcMax(Bottom, 0.0f); Top = lcMin(Top, mHeight - 1.0f); float BorderX = lcMin(2.0f, Right - Left); float BorderY = lcMin(2.0f, Top - Bottom); float Verts[14][2] = { { Left, Bottom }, { Left + BorderX, Bottom + BorderY }, { Right, Bottom }, { Right - BorderX, Bottom + BorderY }, { Right, Top }, { Right - BorderX, Top - BorderY }, { Left, Top }, { Left + BorderX, Top - BorderY }, { Left, Bottom }, { Left + BorderX, Bottom + BorderY }, { Left + BorderX, Bottom + BorderY }, { Right - BorderX, Bottom + BorderY }, { Left + BorderX, Top - BorderY }, { Right - BorderX, Top - BorderY }, }; mContext->SetVertexBufferPointer(Verts); mContext->SetVertexFormatPosition(2); const lcPreferences& Preferences = lcGetPreferences(); mContext->SetColor(lcVector4FromColor(Preferences.mMarqueeBorderColor)); mContext->DrawPrimitives(GL_TRIANGLE_STRIP, 0, 10); if (LC_RGBA_ALPHA(Preferences.mMarqueeFillColor)) { mContext->EnableColorBlend(true); mContext->SetColor(lcVector4FromColor(Preferences.mMarqueeFillColor)); mContext->DrawPrimitives(GL_TRIANGLE_STRIP, 10, 4); mContext->EnableColorBlend(false); } mContext->EnableDepthTest(true); } void lcView::DrawRotateViewOverlay() { int x, y, w, h; x = 0; y = 0; w = mWidth; h = mHeight; mContext->SetMaterial(lcMaterialType::UnlitColor); mContext->SetWorldMatrix(lcMatrix44Identity()); mContext->SetViewMatrix(lcMatrix44Translation(lcVector3(0.375, 0.375, 0.0))); mContext->SetProjectionMatrix(lcMatrix44Ortho(0, w, 0, h, -1, 1)); mContext->SetLineWidth(1.0f); mContext->EnableDepthTest(false); mContext->SetColor(lcVector4FromColor(lcGetPreferences().mOverlayColor)); float Verts[32 * 16 * 2]; float* CurVert = Verts; float r = lcMin(w, h) * 0.35f; float cx = x + w / 2.0f; float cy = y + h / 2.0f; for (int i = 0; i < 32; i++) { *CurVert++ = cosf((float)i / 32.0f * (2.0f * LC_PI)) * r + cx; *CurVert++ = sinf((float)i / 32.0f * (2.0f * LC_PI)) * r + cy; } const float OverlayCameraSquareSize = lcMax(8.0f, (w + h) / 200.0f); *CurVert++ = cx + OverlayCameraSquareSize; *CurVert++ = cy + r + OverlayCameraSquareSize; *CurVert++ = cx - OverlayCameraSquareSize; *CurVert++ = cy + r + OverlayCameraSquareSize; *CurVert++ = cx - OverlayCameraSquareSize; *CurVert++ = cy + r - OverlayCameraSquareSize; *CurVert++ = cx + OverlayCameraSquareSize; *CurVert++ = cy + r - OverlayCameraSquareSize; *CurVert++ = cx + OverlayCameraSquareSize; *CurVert++ = cy - r + OverlayCameraSquareSize; *CurVert++ = cx - OverlayCameraSquareSize; *CurVert++ = cy - r + OverlayCameraSquareSize; *CurVert++ = cx - OverlayCameraSquareSize; *CurVert++ = cy - r - OverlayCameraSquareSize; *CurVert++ = cx + OverlayCameraSquareSize; *CurVert++ = cy - r - OverlayCameraSquareSize; *CurVert++ = cx + r + OverlayCameraSquareSize; *CurVert++ = cy + OverlayCameraSquareSize; *CurVert++ = cx + r - OverlayCameraSquareSize; *CurVert++ = cy + OverlayCameraSquareSize; *CurVert++ = cx + r - OverlayCameraSquareSize; *CurVert++ = cy - OverlayCameraSquareSize; *CurVert++ = cx + r + OverlayCameraSquareSize; *CurVert++ = cy - OverlayCameraSquareSize; *CurVert++ = cx - r + OverlayCameraSquareSize; *CurVert++ = cy + OverlayCameraSquareSize; *CurVert++ = cx - r - OverlayCameraSquareSize; *CurVert++ = cy + OverlayCameraSquareSize; *CurVert++ = cx - r - OverlayCameraSquareSize; *CurVert++ = cy - OverlayCameraSquareSize; *CurVert++ = cx - r + OverlayCameraSquareSize; *CurVert++ = cy - OverlayCameraSquareSize; mContext->SetVertexBufferPointer(Verts); mContext->SetVertexFormatPosition(2); GLushort Indices[64 + 32] = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 0, 32, 33, 33, 34, 34, 35, 35, 32, 36, 37, 37, 38, 38, 39, 39, 36, 40, 41, 41, 42, 42, 43, 43, 40, 44, 45, 45, 46, 46, 47, 47, 44 }; mContext->SetIndexBufferPointer(Indices); mContext->DrawIndexedPrimitives(GL_LINES, 96, GL_UNSIGNED_SHORT, 0); mContext->EnableDepthTest(true); } void lcView::DrawGrid() { const lcPreferences& Preferences = lcGetPreferences(); if (!Preferences.mDrawGridStuds && !Preferences.mDrawGridLines && !Preferences.mDrawGridOrigin) return; if (!Preferences.mGridEnabled) return; const int Spacing = lcMax(Preferences.mGridLineSpacing, 1); int MinX, MaxX, MinY, MaxY; lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); bool GridSizeValid = mModel->GetVisiblePiecesBoundingBox(Min, Max); if (mTrackTool == lcTrackTool::Insert) { PieceInfo* CurPiece = gMainWindow->GetCurrentPieceInfo(); if (CurPiece) { lcVector3 Points[8]; lcGetBoxCorners(CurPiece->GetBoundingBox(), Points); lcMatrix44 WorldMatrix = GetPieceInsertPosition(false, CurPiece); for (int i = 0; i < 8; i++) { lcVector3 Point = lcMul31(Points[i], WorldMatrix); Min = lcMin(Point, Min); Max = lcMax(Point, Max); } GridSizeValid = true; } } if (GridSizeValid) { MinX = (int)(floorf(Min[0] / (20.0f * Spacing))) - 1; MinY = (int)(floorf(Min[1] / (20.0f * Spacing))) - 1; MaxX = (int)(ceilf(Max[0] / (20.0f * Spacing))) + 1; MaxY = (int)(ceilf(Max[1] / (20.0f * Spacing))) + 1; MinX = lcMin(MinX, -2); MinY = lcMin(MinY, -2); MaxX = lcMax(MaxX, 2); MaxY = lcMax(MaxY, 2); } else { MinX = -2; MinY = -2; MaxX = 2; MaxY = 2; } if (!mGridBuffer.IsValid() || MinX != mGridSettings[0] || MinY != mGridSettings[1] || MaxX != mGridSettings[2] || MaxY != mGridSettings[3] || Spacing != mGridSettings[4] || (Preferences.mDrawGridStuds ? 1 : 0) != mGridSettings[5] || (Preferences.mDrawGridLines ? 1 : 0) != mGridSettings[6]) { int VertexBufferSize = 0; if (Preferences.mDrawGridStuds) VertexBufferSize += 4 * 5 * sizeof(float); if (Preferences.mDrawGridLines) VertexBufferSize += 2 * (MaxX - MinX + MaxY - MinY + 2) * 3 * sizeof(float); float* Verts = (float*)malloc(VertexBufferSize); if (!Verts) return; float* CurVert = Verts; if (Preferences.mDrawGridStuds) { float Left = MinX * 20.0f * Spacing; float Right = MaxX * 20.0f * Spacing; float Top = MinY * 20.0f * Spacing; float Bottom = MaxY * 20.0f * Spacing; float Z = 0; float U = (MaxX - MinX) * Spacing; float V = (MaxY - MinY) * Spacing; *CurVert++ = Left; *CurVert++ = Top; *CurVert++ = Z; *CurVert++ = 0.0f; *CurVert++ = V; *CurVert++ = Right; *CurVert++ = Top; *CurVert++ = Z; *CurVert++ = U; *CurVert++ = V; *CurVert++ = Left; *CurVert++ = Bottom; *CurVert++ = Z; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = Right; *CurVert++ = Bottom; *CurVert++ = Z; *CurVert++ = U; *CurVert++ = 0.0f; } if (Preferences.mDrawGridLines) { float LineSpacing = Spacing * 20.0f; for (int Step = MinX; Step < MaxX + 1; Step++) { *CurVert++ = Step * LineSpacing; *CurVert++ = MinY * LineSpacing; *CurVert++ = 0.0f; *CurVert++ = Step * LineSpacing; *CurVert++ = MaxY * LineSpacing; *CurVert++ = 0.0f; } for (int Step = MinY; Step < MaxY + 1; Step++) { *CurVert++ = MinX * LineSpacing; *CurVert++ = Step * LineSpacing; *CurVert++ = 0.0f; *CurVert++ = MaxX * LineSpacing; *CurVert++ = Step * LineSpacing; *CurVert++ = 0.0f; } } mGridSettings[0] = MinX; mGridSettings[1] = MinY; mGridSettings[2] = MaxX; mGridSettings[3] = MaxY; mGridSettings[4] = Spacing; mGridSettings[5] = (Preferences.mDrawGridStuds ? 1 : 0); mGridSettings[6] = (Preferences.mDrawGridLines ? 1 : 0); mContext->DestroyVertexBuffer(mGridBuffer); mGridBuffer = mContext->CreateVertexBuffer(VertexBufferSize, Verts); free(Verts); } int BufferOffset = 0; mContext->SetVertexBuffer(mGridBuffer); mContext->SetWorldMatrix(lcMatrix44Identity()); if (Preferences.mDrawGridStuds) { mContext->BindTexture2D(gGridTexture); mContext->SetDepthWrite(false); mContext->EnableColorBlend(true); mContext->SetMaterial(lcMaterialType::UnlitTextureModulate); mContext->SetColor(lcVector4FromColor(Preferences.mGridStudColor)); mContext->SetVertexFormat(0, 3, 0, 2, 0, false); mContext->DrawPrimitives(GL_TRIANGLE_STRIP, 0, 4); mContext->EnableColorBlend(false); mContext->SetDepthWrite(true); BufferOffset = 4 * 5 * sizeof(float); } if (Preferences.mDrawGridLines) { mContext->SetLineWidth(1.0f); mContext->SetMaterial(lcMaterialType::UnlitColor); mContext->SetColor(lcVector4FromColor(Preferences.mGridLineColor)); int NumVerts = 2 * (MaxX - MinX + MaxY - MinY + 2); mContext->SetVertexFormat(BufferOffset, 3, 0, 0, 0, false); mContext->DrawPrimitives(GL_LINES, 0, NumVerts); } if (Preferences.mDrawGridOrigin) { struct lcGridVertex { float x, y; quint32 Color; }; const quint32 Red = LC_RGBA(204, 0, 0, 255); const quint32 Green = LC_RGBA(0, 204, 0, 255); const float Scale = 20.0f * Spacing; const lcGridVertex Verts[4] = { { 0.0f, MinY * Scale, Green }, { 0.0f, MaxY * Scale, Green }, { MinX * Scale, 0.0f, Red }, { MaxX * Scale, 0.0f, Red } }; mContext->SetMaterial(lcMaterialType::UnlitVertexColor); mContext->SetVertexBufferPointer(Verts); mContext->SetVertexFormat(0, 2, 0, 0, 4, false); mContext->DrawPrimitives(GL_LINES, 0, 4); } } lcTrackTool lcView::GetOverrideTrackTool(Qt::MouseButton Button) const { if (mTrackToolFromOverlay) return lcTrackTool::None; lcTool OverrideTool = gMouseShortcuts.GetTool(Button, mMouseModifiers); if (OverrideTool == lcTool::Count) return lcTrackTool::None; constexpr lcTrackTool TrackToolFromTool[] = { lcTrackTool::Insert, // lcTool::Insert lcTrackTool::PointLight, // lcTool::Light lcTrackTool::SpotLight, // lcTool::SpotLight lcTrackTool::Camera, // lcTool::Camera lcTrackTool::Select, // lcTool::Select lcTrackTool::MoveXYZ, // lcTool::Move lcTrackTool::RotateXYZ, // lcTool::Rotate lcTrackTool::Eraser, // lcTool::Eraser lcTrackTool::Paint, // lcTool::Paint lcTrackTool::ColorPicker, // lcTool::ColorPicker lcTrackTool::Zoom, // lcTool::Zoom lcTrackTool::Pan, // lcTool::Pan lcTrackTool::OrbitXY, // lcTool::RotateView lcTrackTool::Roll, // lcTool::Roll lcTrackTool::ZoomRegion // lcTool::ZoomRegion }; LC_ARRAY_SIZE_CHECK(TrackToolFromTool, lcTool::Count); return TrackToolFromTool[static_cast(OverrideTool)]; } float lcView::GetOverlayScale() const { lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; lcModel* ActiveModel = GetActiveModel(); ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation); lcMatrix44 WorldMatrix = lcMatrix44(RelativeRotation, OverlayCenter); if (ActiveModel != mModel) WorldMatrix = lcMul(WorldMatrix, mActiveSubmodelTransform); lcVector3 ScreenPos = ProjectPoint(WorldMatrix.GetTranslation()); ScreenPos[0] += 10.0f; lcVector3 Point = UnprojectPoint(ScreenPos); lcVector3 Dist(Point - WorldMatrix.GetTranslation()); return Dist.Length() * 5.0f; } void lcView::BeginDrag(lcDragState DragState) { mDragState = DragState; UpdateTrackTool(); } void lcView::EndDrag(bool Accept) { lcModel* ActiveModel = GetActiveModel(); if (Accept) { switch (mDragState) { case lcDragState::None: break; case lcDragState::Piece: { PieceInfo* Info = gMainWindow->GetCurrentPieceInfo(); if (Info) ActiveModel->InsertPieceToolClicked(GetPieceInsertPosition(false, Info)); } break; case lcDragState::Color: ActiveModel->PaintToolClicked(FindObjectUnderPointer(true, false).Object); break; } } mDragState = lcDragState::None; UpdateTrackTool(); ActiveModel->UpdateAllViews(); } void lcView::SetViewpoint(lcViewpoint Viewpoint) { if (!mCamera || !mCamera->IsSimple()) { lcCamera* OldCamera = mCamera; mCamera = new lcCamera(true); if (OldCamera) mCamera->CopySettings(OldCamera); } mCamera->SetViewpoint(Viewpoint); ZoomExtents(); Redraw(); emit CameraChanged(); } void lcView::SetViewpoint(const lcVector3& Position) { if (!mCamera || !mCamera->IsSimple()) { lcCamera* OldCamera = mCamera; mCamera = new lcCamera(true); if (OldCamera) mCamera->CopySettings(OldCamera); } mCamera->SetViewpoint(Position); ZoomExtents(); Redraw(); emit CameraChanged(); } void lcView::SetViewpoint(const lcVector3& Position, const lcVector3& Target, const lcVector3& Up) { if (!mCamera || !mCamera->IsSimple()) { lcCamera* OldCamera = mCamera; mCamera = new lcCamera(true); if (OldCamera) mCamera->CopySettings(OldCamera); } mCamera->SetViewpoint(Position, Target, Up); Redraw(); emit CameraChanged(); } void lcView::SetCameraAngles(float Latitude, float Longitude) { if (!mCamera || !mCamera->IsSimple()) { lcCamera* OldCamera = mCamera; mCamera = new lcCamera(true); if (OldCamera) mCamera->CopySettings(OldCamera); } mCamera->SetAngles(Latitude, Longitude, 1.0f); ZoomExtents(); Redraw(); } void lcView::SetDefaultCamera() { if (!mCamera || !mCamera->IsSimple()) mCamera = new lcCamera(true); mCamera->SetViewpoint(lcViewpoint::Home); ZoomExtents(); Redraw(); emit CameraChanged(); } void lcView::SetCamera(lcCamera* Camera, bool ForceCopy) { if (Camera->IsSimple() || ForceCopy) { if (!mCamera || !mCamera->IsSimple()) mCamera = new lcCamera(true); mCamera->CopyPosition(Camera); } else { if (mCamera && mCamera->IsSimple()) delete mCamera; mCamera = Camera; } } void lcView::SetCamera(const QString& CameraName) { const lcArray& Cameras = mModel->GetCameras(); for (int CameraIdx = 0; CameraIdx < Cameras.GetSize(); CameraIdx++) { if (CameraName.compare(Cameras[CameraIdx]->GetName(), Qt::CaseInsensitive) == 0) { SetCameraIndex(CameraIdx); return; } } } void lcView::SetCameraIndex(int Index) { const lcArray& Cameras = mModel->GetCameras(); if (Index >= Cameras.GetSize()) return; lcCamera* Camera = Cameras[Index]; SetCamera(Camera, false); emit CameraChanged(); Redraw(); } void lcView::SetProjection(bool Ortho) { if (mCamera->IsSimple()) { mCamera->SetOrtho(Ortho); Redraw(); if (gMainWindow) gMainWindow->UpdatePerspective(); } else { lcModel* ActiveModel = GetActiveModel(); if (ActiveModel) ActiveModel->SetCameraOrthographic(mCamera, Ortho); } } void lcView::LookAt() { lcModel* ActiveModel = GetActiveModel(); if (ActiveModel) ActiveModel->LookAt(mCamera); } void lcView::MoveCamera(const lcVector3& Direction) { lcModel* ActiveModel = GetActiveModel(); if (ActiveModel) ActiveModel->MoveCamera(mCamera, Direction); } void lcView::Zoom(float Amount) { lcModel* ActiveModel = GetActiveModel(); if (ActiveModel) ActiveModel->Zoom(mCamera, Amount); } void lcView::ZoomExtents() { lcModel* ActiveModel = GetActiveModel(); if (ActiveModel) ActiveModel->ZoomExtents(mCamera, (float)mWidth / (float)mHeight); } lcCursor lcView::GetCursor() const { if (mTrackButton != lcTrackButton::None) return lcCursor::Hidden; if (mTrackTool == lcTrackTool::Select) { if (mMouseModifiers & Qt::ControlModifier) return lcCursor::SelectAdd; if (mMouseModifiers & Qt::ShiftModifier) return lcCursor::SelectRemove; } constexpr lcCursor CursorFromTrackTool[] = { lcCursor::Select, // lcTrackTool::None lcCursor::Brick, // lcTrackTool::Insert lcCursor::Light, // lcTrackTool::PointLight lcCursor::Spotlight, // lcTrackTool::SpotLight lcCursor::Camera, // lcTrackTool::Camera lcCursor::Select, // lcTrackTool::Select lcCursor::Move, // lcTrackTool::MoveX lcCursor::Move, // lcTrackTool::MoveY lcCursor::Move, // lcTrackTool::MoveZ lcCursor::Move, // lcTrackTool::MoveXY lcCursor::Move, // lcTrackTool::MoveXZ lcCursor::Move, // lcTrackTool::MoveYZ lcCursor::Move, // lcTrackTool::MoveXYZ lcCursor::Rotate, // lcTrackTool::RotateX lcCursor::Rotate, // lcTrackTool::RotateY lcCursor::Rotate, // lcTrackTool::RotateZ lcCursor::Rotate, // lcTrackTool::RotateXY lcCursor::Rotate, // lcTrackTool::RotateXYZ lcCursor::Move, // lcTrackTool::ScalePlus lcCursor::Move, // lcTrackTool::ScaleMinus lcCursor::Delete, // lcTrackTool::Eraser lcCursor::Paint, // lcTrackTool::Paint lcCursor::ColorPicker, // lcTrackTool::ColorPicker lcCursor::Zoom, // lcTrackTool::Zoom lcCursor::Pan, // lcTrackTool::Pan lcCursor::RotateX, // lcTrackTool::OrbitX lcCursor::RotateY, // lcTrackTool::OrbitY lcCursor::RotateView, // lcTrackTool::OrbitXY lcCursor::Roll, // lcTrackTool::Roll lcCursor::ZoomRegion // lcTrackTool::ZoomRegion }; LC_ARRAY_SIZE_CHECK(CursorFromTrackTool, lcTrackTool::Count); if (mTrackTool >= lcTrackTool::None && mTrackTool < lcTrackTool::Count) return CursorFromTrackTool[static_cast(mTrackTool)]; return lcCursor::Select; } void lcView::SetCursor(lcCursor CursorType) { if (mCursor == CursorType) return; struct lcCursorInfo { int x, y; const char* Name; }; constexpr lcCursorInfo Cursors[] = { { 0, 0, "" }, // lcCursor::Hidden { 0, 0, "" }, // lcCursor::Default { 8, 3, ":/resources/cursor_insert" }, // lcCursor::Brick { 15, 15, ":/resources/cursor_light" }, // lcCursor::Light { 7, 10, ":/resources/cursor_spotlight" }, // lcCursor::Spotlight { 15, 9, ":/resources/cursor_camera" }, // lcCursor::Camera { 0, 2, ":/resources/cursor_select" }, // lcCursor::Select { 0, 2, ":/resources/cursor_select_add" }, // lcCursor::SelectAdd { 0, 2, ":/resources/cursor_select_remove" }, // lcCursor::SelectRemove { 15, 15, ":/resources/cursor_move" }, // lcCursor::Move { 15, 15, ":/resources/cursor_rotate" }, // lcCursor::Rotate { 15, 15, ":/resources/cursor_rotatex" }, // lcCursor::RotateX { 15, 15, ":/resources/cursor_rotatey" }, // lcCursor::RotateY { 0, 10, ":/resources/cursor_delete" }, // lcCursor::Delete { 14, 14, ":/resources/cursor_paint" }, // lcCursor::Paint { 1, 13, ":/resources/cursor_color_picker" }, // lcCursor::ColorPicker { 15, 15, ":/resources/cursor_zoom" }, // lcCursor::Zoom { 9, 9, ":/resources/cursor_zoom_region" }, // lcCursor::ZoomRegion { 15, 15, ":/resources/cursor_pan" }, // lcCursor::Pan { 15, 15, ":/resources/cursor_roll" }, // lcCursor::Roll { 15, 15, ":/resources/cursor_rotate_view" }, // lcCursor::RotateView }; LC_ARRAY_SIZE_CHECK(Cursors, lcCursor::Count); if (CursorType == lcCursor::Hidden) { mWidget->setCursor(Qt::BlankCursor); mCursor = CursorType; } else if (CursorType >= lcCursor::First && CursorType < lcCursor::Count) { const lcCursorInfo& Cursor = Cursors[static_cast(CursorType)]; mWidget->setCursor(QCursor(QPixmap(Cursor.Name), Cursor.x, Cursor.y)); mCursor = CursorType; } else { mWidget->unsetCursor(); mCursor = lcCursor::Default; } } void lcView::UpdateCursor() { SetCursor(GetCursor()); } lcTool lcView::GetCurrentTool() const { constexpr lcTool ToolFromTrackTool[] = { lcTool::Select, // lcTrackTool::None lcTool::Insert, // lcTrackTool::Insert lcTool::Light, // lcTrackTool::PointLight lcTool::SpotLight, // lcTrackTool::SpotLight lcTool::Camera, // lcTrackTool::Camera lcTool::Select, // lcTrackTool::Select lcTool::Move, // lcTrackTool::MoveX lcTool::Move, // lcTrackTool::MoveY lcTool::Move, // lcTrackTool::MoveZ lcTool::Move, // lcTrackTool::MoveXY lcTool::Move, // lcTrackTool::MoveXZ lcTool::Move, // lcTrackTool::MoveYZ lcTool::Move, // lcTrackTool::MoveXYZ lcTool::Rotate, // lcTrackTool::RotateX lcTool::Rotate, // lcTrackTool::RotateY lcTool::Rotate, // lcTrackTool::RotateZ lcTool::Rotate, // lcTrackTool::RotateXY lcTool::Rotate, // lcTrackTool::RotateXYZ lcTool::Move, // lcTrackTool::ScalePlus lcTool::Move, // lcTrackTool::ScaleMinus lcTool::Eraser, // lcTrackTool::Eraser lcTool::Paint, // lcTrackTool::Paint lcTool::ColorPicker, // lcTrackTool::ColorPicker lcTool::Zoom, // lcTrackTool::Zoom lcTool::Pan, // lcTrackTool::Pan lcTool::RotateView, // lcTrackTool::OrbitX lcTool::RotateView, // lcTrackTool::OrbitY lcTool::RotateView, // lcTrackTool::OrbitXY lcTool::Roll, // lcTrackTool::Roll lcTool::ZoomRegion // lcTrackTool::ZoomRegion }; LC_ARRAY_SIZE_CHECK(ToolFromTrackTool, lcTrackTool::Count); if (mTrackTool >= lcTrackTool::None && mTrackTool < lcTrackTool::Count) return ToolFromTrackTool[static_cast(mTrackTool)]; return lcTool::Select; } void lcView::UpdateTrackTool() { if (mViewType != lcViewType::View) { mTrackTool = lcTrackTool::None; UpdateCursor(); return; } lcTool CurrentTool = gMainWindow->GetTool(); lcTrackTool NewTrackTool = mTrackTool; int x = mMouseX; int y = mMouseY; bool Redraw = false; mTrackToolFromOverlay = false; lcModel* ActiveModel = GetActiveModel(); switch (CurrentTool) { case lcTool::Insert: NewTrackTool = lcTrackTool::Insert; break; case lcTool::Light: NewTrackTool = lcTrackTool::PointLight; break; case lcTool::SpotLight: NewTrackTool = lcTrackTool::SpotLight; break; case lcTool::Camera: NewTrackTool = lcTrackTool::Camera; break; case lcTool::Select: case lcTool::Move: { mMouseDownPiece = nullptr; NewTrackTool = mViewManipulator->UpdateSelectMove(); mTrackToolFromOverlay = NewTrackTool != lcTrackTool::MoveXYZ && NewTrackTool != lcTrackTool::Select; Redraw = NewTrackTool != mTrackTool; if (CurrentTool == lcTool::Select && NewTrackTool == lcTrackTool::Select && mMouseModifiers == Qt::NoModifier) { lcObjectSection ObjectSection = FindObjectUnderPointer(false, false); lcObject* Object = ObjectSection.Object; if (Object && Object->IsPiece() && ObjectSection.Section == LC_PIECE_SECTION_POSITION && Object->IsSelected()) { lcPiece* Piece = (lcPiece*)Object; mMouseDownPosition = Piece->mModelWorld.GetTranslation(); mMouseDownPiece = Piece->mPieceInfo; NewTrackTool = lcTrackTool::MoveXYZ; } } } break; case lcTool::Rotate: { NewTrackTool = mViewManipulator->UpdateRotate(); mTrackToolFromOverlay = NewTrackTool != lcTrackTool::RotateXYZ; Redraw = NewTrackTool != mTrackTool; } break; case lcTool::Eraser: NewTrackTool = lcTrackTool::Eraser; break; case lcTool::Paint: NewTrackTool = lcTrackTool::Paint; break; case lcTool::ColorPicker: NewTrackTool = lcTrackTool::ColorPicker; break; case lcTool::Zoom: NewTrackTool = lcTrackTool::Zoom; break; case lcTool::Pan: NewTrackTool = lcTrackTool::Pan; break; case lcTool::RotateView: { int vx, vy, vw, vh; vx = 0; vy = 0; vw = mWidth; vh = mHeight; int cx = vx + vw / 2; int cy = vy + vh / 2; float d = sqrtf((float)((cx - x) * (cx - x) + (cy - y) * (cy - y))); float r = lcMin(vw, vh) * 0.35f; const float SquareSize = lcMax(8.0f, (vw + vh) / 200.0f); if ((d < r + SquareSize) && (d > r - SquareSize)) { if ((cx - x < SquareSize) && (cx - x > -SquareSize)) { NewTrackTool = lcTrackTool::OrbitY; mTrackToolFromOverlay = true; } if ((cy - y < SquareSize) && (cy - y > -SquareSize)) { NewTrackTool = lcTrackTool::OrbitX; mTrackToolFromOverlay = true; } } else { if (d < r) NewTrackTool = lcTrackTool::OrbitXY; else NewTrackTool = lcTrackTool::Roll; } } break; case lcTool::Roll: NewTrackTool = lcTrackTool::Roll; break; case lcTool::ZoomRegion: NewTrackTool = lcTrackTool::ZoomRegion; break; case lcTool::Count: break; } switch (mDragState) { case lcDragState::None: break; case lcDragState::Piece: NewTrackTool = lcTrackTool::Insert; Redraw = true; break; case lcDragState::Color: NewTrackTool = lcTrackTool::Paint; break; } mTrackTool = NewTrackTool; UpdateCursor(); if (Redraw) ActiveModel->UpdateAllViews(); } void lcView::StartOrbitTracking() { mTrackTool = lcTrackTool::OrbitXY; UpdateCursor(); OnButtonDown(lcTrackButton::Left); } void lcView::StartPanGesture() { lcModel* ActiveModel = GetActiveModel(); StartPan(mWidth / 2, mHeight / 2); ActiveModel->BeginMouseTool(); } void lcView::UpdatePanGesture(int dx, int dy) { UpdatePan(mPanX + dx, mPanY + dy); } void lcView::StartPan(int x, int y) { mPanX = x; mPanY = y; } void lcView::UpdatePan(int x, int y) { if (x == mPanX && y == mPanY) return; lcModel* ActiveModel = GetActiveModel(); lcVector3 Points[4] = { lcVector3((float)x, (float)y, 0.0f), lcVector3((float)x, (float)y, 1.0f), lcVector3(mPanX, mPanY, 0.0f), lcVector3(mPanX, mPanY, 1.0f) }; UnprojectPoints(Points, 4); const lcVector3& CurrentStart = Points[0]; const lcVector3& CurrentEnd = Points[1]; const lcVector3& MouseDownStart = Points[2]; const lcVector3& MouseDownEnd = Points[3]; lcVector3 Center = ActiveModel->GetSelectionOrModelCenter(); lcVector3 PlaneNormal(mCamera->mPosition - mCamera->mTargetPosition); lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center)); lcVector3 Intersection, MoveStart; if (!lcLineSegmentPlaneIntersection(&Intersection, CurrentStart, CurrentEnd, Plane) || !lcLineSegmentPlaneIntersection(&MoveStart, MouseDownStart, MouseDownEnd, Plane)) { Center = MouseDownStart + lcNormalize(MouseDownEnd - MouseDownStart) * 10.0f; Plane = lcVector4(PlaneNormal, -lcDot(PlaneNormal, Center)); if (!lcLineSegmentPlaneIntersection(&Intersection, CurrentStart, CurrentEnd, Plane) || !lcLineSegmentPlaneIntersection(&MoveStart, MouseDownStart, MouseDownEnd, Plane)) return; } mPanX = x; mPanY = y; ActiveModel->UpdatePanTool(mCamera, MoveStart - Intersection); } void lcView::EndPanGesture(bool Accept) { lcModel* ActiveModel = GetActiveModel(); ActiveModel->EndMouseTool(lcTool::Pan, Accept); } void lcView::StartTracking(lcTrackButton TrackButton) { mTrackButton = TrackButton; mTrackUpdated = false; mMouseDownX = mMouseX; mMouseDownY = mMouseY; lcTool Tool = GetCurrentTool(); lcModel* ActiveModel = GetActiveModel(); switch (Tool) { case lcTool::Insert: case lcTool::Light: break; case lcTool::SpotLight: { lcVector3 Position = GetCameraLightInsertPosition(); lcVector3 Target = Position + lcVector3(0.1f, 0.1f, 0.1f); ActiveModel->BeginSpotLightTool(Position, Target); } break; case lcTool::Camera: { lcVector3 Position = GetCameraLightInsertPosition(); lcVector3 Target = Position + lcVector3(0.1f, 0.1f, 0.1f); ActiveModel->BeginCameraTool(Position, Target); } break; case lcTool::Select: break; case lcTool::Move: case lcTool::Rotate: ActiveModel->BeginMouseTool(); break; case lcTool::Eraser: case lcTool::Paint: case lcTool::ColorPicker: break; case lcTool::Pan: StartPan(mMouseX, mMouseY); ActiveModel->BeginMouseTool(); break; case lcTool::Zoom: case lcTool::RotateView: case lcTool::Roll: ActiveModel->BeginMouseTool(); break; case lcTool::ZoomRegion: break; case lcTool::Count: break; } UpdateCursor(); } void lcView::StopTracking(bool Accept) { if (mTrackButton == lcTrackButton::None) return; lcTool Tool = GetCurrentTool(); lcModel* ActiveModel = GetActiveModel(); switch (Tool) { case lcTool::Insert: case lcTool::Light: break; case lcTool::SpotLight: case lcTool::Camera: ActiveModel->EndMouseTool(Tool, Accept); break; case lcTool::Select: if (Accept && mMouseDownX != mMouseX && mMouseDownY != mMouseY) { lcArray Objects = FindObjectsInBox(mMouseDownX, mMouseDownY, mMouseX, mMouseY); if (mMouseModifiers & Qt::ControlModifier) ActiveModel->AddToSelection(Objects, true, true); else if (mMouseModifiers & Qt::ShiftModifier) ActiveModel->RemoveFromSelection(Objects); else ActiveModel->SetSelectionAndFocus(Objects, nullptr, 0, true); } break; case lcTool::Move: case lcTool::Rotate: ActiveModel->EndMouseTool(Tool, Accept); break; case lcTool::Eraser: case lcTool::Paint: case lcTool::ColorPicker: break; case lcTool::Zoom: case lcTool::Pan: case lcTool::RotateView: case lcTool::Roll: ActiveModel->EndMouseTool(Tool, Accept); break; case lcTool::ZoomRegion: { if (mMouseX == mMouseDownX || mMouseY == mMouseDownY) break; lcVector3 Points[6] = { lcVector3((mMouseDownX + lcMin(mMouseX, mWidth - 1)) / 2, (mMouseDownY + lcMin(mMouseY, mHeight - 1)) / 2, 0.0f), lcVector3((mMouseDownX + lcMin(mMouseX, mWidth - 1)) / 2, (mMouseDownY + lcMin(mMouseY, mHeight - 1)) / 2, 1.0f), lcVector3((float)mMouseX, (float)mMouseY, 0.0f), lcVector3((float)mMouseX, (float)mMouseY, 1.0f), lcVector3(mMouseDownX, mMouseDownY, 0.0f), lcVector3(mMouseDownX, mMouseDownY, 1.0f) }; UnprojectPoints(Points, 5); lcVector3 Center = ActiveModel->GetSelectionOrModelCenter(); lcVector3 PlaneNormal(mCamera->mPosition - mCamera->mTargetPosition); lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center)); lcVector3 Target, Corners[2]; if (lcLineSegmentPlaneIntersection(&Target, Points[0], Points[1], Plane) && lcLineSegmentPlaneIntersection(&Corners[0], Points[2], Points[3], Plane) && lcLineSegmentPlaneIntersection(&Corners[1], Points[3], Points[4], Plane)) { float AspectRatio = (float)mWidth / (float)mHeight; ActiveModel->ZoomRegionToolClicked(mCamera, AspectRatio, Points[0], Target, Corners); } } break; case lcTool::Count: break; } mTrackButton = lcTrackButton::None; UpdateTrackTool(); ActiveModel->UpdateAllViews(); } void lcView::CancelTrackingOrClearSelection() { if (mTrackButton != lcTrackButton::None) StopTracking(false); else { lcModel* ActiveModel = GetActiveModel(); if (ActiveModel) ActiveModel->ClearSelection(true); } } void lcView::OnButtonDown(lcTrackButton TrackButton) { lcModel* ActiveModel = GetActiveModel(); mToolClicked = false; switch (mTrackTool) { case lcTrackTool::None: break; case lcTrackTool::Insert: { PieceInfo* CurPiece = gMainWindow->GetCurrentPieceInfo(); if (!CurPiece) break; ActiveModel->InsertPieceToolClicked(GetPieceInsertPosition(false, gMainWindow->GetCurrentPieceInfo())); if ((mMouseModifiers & Qt::ControlModifier) == 0) gMainWindow->SetTool(lcTool::Select); mToolClicked = true; UpdateTrackTool(); } break; case lcTrackTool::PointLight: { ActiveModel->PointLightToolClicked(GetCameraLightInsertPosition()); if ((mMouseModifiers & Qt::ControlModifier) == 0) gMainWindow->SetTool(lcTool::Select); mToolClicked = true; UpdateTrackTool(); } break; case lcTrackTool::SpotLight: case lcTrackTool::Camera: StartTracking(TrackButton); break; case lcTrackTool::Select: { lcObjectSection ObjectSection = FindObjectUnderPointer(false, false); if (mMouseModifiers & Qt::ControlModifier) ActiveModel->FocusOrDeselectObject(ObjectSection); else if (mMouseModifiers & Qt::ShiftModifier) ActiveModel->RemoveFromSelection(ObjectSection); else ActiveModel->ClearSelectionAndSetFocus(ObjectSection, true); StartTracking(TrackButton); } break; case lcTrackTool::MoveX: case lcTrackTool::MoveY: case lcTrackTool::MoveZ: case lcTrackTool::MoveXY: case lcTrackTool::MoveXZ: case lcTrackTool::MoveYZ: case lcTrackTool::MoveXYZ: if (ActiveModel->AnyObjectsSelected()) StartTracking(TrackButton); break; case lcTrackTool::RotateX: case lcTrackTool::RotateY: case lcTrackTool::RotateZ: case lcTrackTool::RotateXY: case lcTrackTool::RotateXYZ: if (ActiveModel->AnyPiecesSelected()) StartTracking(TrackButton); break; case lcTrackTool::ScalePlus: case lcTrackTool::ScaleMinus: if (ActiveModel->AnyPiecesSelected()) StartTracking(TrackButton); break; case lcTrackTool::Eraser: ActiveModel->EraserToolClicked(FindObjectUnderPointer(false, false).Object); mToolClicked = true; break; case lcTrackTool::Paint: ActiveModel->PaintToolClicked(FindObjectUnderPointer(true, false).Object); mToolClicked = true; break; case lcTrackTool::ColorPicker: ActiveModel->ColorPickerToolClicked(FindObjectUnderPointer(true, false).Object); mToolClicked = true; break; case lcTrackTool::Zoom: case lcTrackTool::Pan: case lcTrackTool::OrbitX: case lcTrackTool::OrbitY: case lcTrackTool::OrbitXY: case lcTrackTool::Roll: case lcTrackTool::ZoomRegion: StartTracking(TrackButton); break; case lcTrackTool::Count: break; } } void lcView::OnLeftButtonDown() { if (mTrackButton != lcTrackButton::None) { StopTracking(false); return; } if (mViewSphere->OnLeftButtonDown()) return; lcTrackTool OverrideTool = GetOverrideTrackTool(Qt::LeftButton); if (OverrideTool != lcTrackTool::None) { mTrackTool = OverrideTool; UpdateCursor(); } OnButtonDown(lcTrackButton::Left); } void lcView::OnLeftButtonUp() { StopTracking(mTrackButton == lcTrackButton::Left); if (mViewSphere->OnLeftButtonUp()) return; } void lcView::OnLeftButtonDoubleClick() { if (mViewType != lcViewType::View) { ZoomExtents(); return; } lcObjectSection ObjectSection = FindObjectUnderPointer(false, false); lcModel* ActiveModel = GetActiveModel(); if (mMouseModifiers & Qt::ControlModifier) ActiveModel->FocusOrDeselectObject(ObjectSection); else if (mMouseModifiers & Qt::ShiftModifier) ActiveModel->RemoveFromSelection(ObjectSection); else ActiveModel->ClearSelectionAndSetFocus(ObjectSection, true); } void lcView::OnMiddleButtonDown() { if (mTrackButton != lcTrackButton::None) { StopTracking(false); return; } lcTrackTool OverrideTool = GetOverrideTrackTool(Qt::MiddleButton); if (OverrideTool != lcTrackTool::None) { mTrackTool = OverrideTool; UpdateCursor(); } OnButtonDown(lcTrackButton::Middle); } void lcView::OnMiddleButtonUp() { StopTracking(mTrackButton == lcTrackButton::Middle); } void lcView::OnRightButtonDown() { if (mTrackButton != lcTrackButton::None) { StopTracking(false); return; } lcTrackTool OverrideTool = GetOverrideTrackTool(Qt::RightButton); if (OverrideTool != lcTrackTool::None) { mTrackTool = OverrideTool; UpdateCursor(); } OnButtonDown(lcTrackButton::Right); } void lcView::OnRightButtonUp() { bool ShowMenu = !mToolClicked && (mTrackButton == lcTrackButton::None || !mTrackUpdated); if (mTrackButton != lcTrackButton::None) StopTracking(mTrackButton == lcTrackButton::Right); if (ShowMenu) ShowContextMenu(); } void lcView::OnBackButtonDown() { } void lcView::OnBackButtonUp() { gMainWindow->HandleCommand(LC_VIEW_TIME_PREVIOUS); } void lcView::OnForwardButtonDown() { } void lcView::OnForwardButtonUp() { gMainWindow->HandleCommand(LC_VIEW_TIME_NEXT); } void lcView::OnMouseMove() { lcModel* ActiveModel = GetActiveModel(); if (!ActiveModel) return; if (mTrackButton == lcTrackButton::None) { if (mViewSphere->OnMouseMove()) { lcTrackTool NewTrackTool = mViewSphere->IsDragging() ? lcTrackTool::OrbitXY : lcTrackTool::None; if (NewTrackTool != mTrackTool) { mTrackTool = NewTrackTool; UpdateCursor(); } return; } UpdateTrackTool(); if (mTrackTool == lcTrackTool::Insert) ActiveModel->UpdateAllViews(); return; } mTrackUpdated = true; const float MouseSensitivity = 0.5f / (21.0f - lcGetPreferences().mMouseSensitivity); switch (mTrackTool) { case lcTrackTool::None: case lcTrackTool::Insert: case lcTrackTool::PointLight: break; case lcTrackTool::SpotLight: ActiveModel->UpdateSpotLightTool(GetCameraLightInsertPosition()); break; case lcTrackTool::Camera: ActiveModel->UpdateCameraTool(GetCameraLightInsertPosition()); break; case lcTrackTool::Select: Redraw(); break; case lcTrackTool::MoveX: case lcTrackTool::MoveY: case lcTrackTool::MoveZ: case lcTrackTool::MoveXY: case lcTrackTool::MoveXZ: case lcTrackTool::MoveYZ: case lcTrackTool::MoveXYZ: case lcTrackTool::ScalePlus: case lcTrackTool::ScaleMinus: { lcVector3 Points[4] = { lcVector3((float)mMouseX, (float)mMouseY, 0.0f), lcVector3((float)mMouseX, (float)mMouseY, 1.0f), lcVector3(mMouseDownX, mMouseDownY, 0.0f), lcVector3(mMouseDownX, mMouseDownY, 1.0f) }; UnprojectPoints(Points, 4); const lcVector3& CurrentStart = Points[0]; const lcVector3& CurrentEnd = Points[1]; const lcVector3& MouseDownStart = Points[2]; const lcVector3& MouseDownEnd = Points[3]; lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation); lcMatrix44 WorldMatrix = lcMatrix44(RelativeRotation, OverlayCenter); if (ActiveModel != mModel) WorldMatrix = lcMul(WorldMatrix, mActiveSubmodelTransform); const lcVector3 Center = WorldMatrix.GetTranslation(); if (mTrackTool == lcTrackTool::MoveX || mTrackTool == lcTrackTool::MoveY || mTrackTool == lcTrackTool::MoveZ) { lcVector3 Direction; if (mTrackTool == lcTrackTool::MoveX) Direction = lcVector3(1.0f, 0.0f, 0.0f); else if (mTrackTool == lcTrackTool::MoveY) Direction = lcVector3(0.0f, 1.0f, 0.0f); else Direction = lcVector3(0.0f, 0.0f, 1.0f); Direction = lcMul30(Direction, WorldMatrix); lcVector3 Intersection; lcClosestPointsBetweenLines(Center, Center + Direction, CurrentStart, CurrentEnd, &Intersection, nullptr); lcVector3 MoveStart; lcClosestPointsBetweenLines(Center, Center + Direction, MouseDownStart, MouseDownEnd, &MoveStart, nullptr); lcVector3 Distance = Intersection - MoveStart; Distance = lcMul(Distance, lcMatrix33AffineInverse(lcMatrix33(WorldMatrix))); ActiveModel->UpdateMoveTool(Distance, true, mTrackButton != lcTrackButton::Left); } else if (mTrackTool == lcTrackTool::MoveXY || mTrackTool == lcTrackTool::MoveXZ || mTrackTool == lcTrackTool::MoveYZ) { lcVector3 PlaneNormal; if (mTrackTool == lcTrackTool::MoveXY) PlaneNormal = lcVector3(0.0f, 0.0f, 1.0f); else if (mTrackTool == lcTrackTool::MoveXZ) PlaneNormal = lcVector3(0.0f, 1.0f, 0.0f); else PlaneNormal = lcVector3(1.0f, 0.0f, 0.0f); PlaneNormal = lcMul30(PlaneNormal, WorldMatrix); lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center)); lcVector3 Intersection; if (lcLineSegmentPlaneIntersection(&Intersection, CurrentStart, CurrentEnd, Plane)) { lcVector3 MoveStart; if (lcLineSegmentPlaneIntersection(&MoveStart, MouseDownStart, MouseDownEnd, Plane)) { lcVector3 Distance = Intersection - MoveStart; Distance = lcMul(Distance, lcMatrix33AffineInverse(lcMatrix33(WorldMatrix))); ActiveModel->UpdateMoveTool(Distance, true, mTrackButton != lcTrackButton::Left); } } } else if (mTrackTool == lcTrackTool::MoveXYZ && mMouseDownPiece) { lcMatrix44 NewPosition = GetPieceInsertPosition(true, mMouseDownPiece); lcVector3 Distance = NewPosition.GetTranslation() - mMouseDownPosition; ActiveModel->UpdateMoveTool(Distance, false, mTrackButton != lcTrackButton::Left); } else if (mTrackTool == lcTrackTool::ScalePlus || mTrackTool == lcTrackTool::ScaleMinus) { lcVector3 Direction; if (mTrackTool == lcTrackTool::ScalePlus) Direction = lcVector3(1.0f, 0.0f, 0.0f); else Direction = lcVector3(-1.0f, 0.0f, 0.0f); Direction = lcMul30(Direction, WorldMatrix); lcVector3 Intersection; lcClosestPointsBetweenLines(Center, Center + Direction, CurrentStart, CurrentEnd, &Intersection, nullptr); lcObject* Focus = ActiveModel->GetFocusObject(); if (Focus && Focus->IsPiece()) { lcPiece* Piece = (lcPiece*)Focus; quint32 Section = Piece->GetFocusSection(); if (Section >= LC_PIECE_SECTION_CONTROL_POINT_FIRST && Section <= LC_PIECE_SECTION_CONTROL_POINT_LAST) { const float ScaleMax = 200.0f; const float OverlayScale = GetOverlayScale(); const float ScaleStart = 2.0f * OverlayScale; lcVector3 Position = Piece->GetSectionPosition(Section); lcVector3 Start = Position + Direction * ScaleStart; float Distance = lcLength(Intersection - Start); if (lcDot(Direction, Intersection - Start) < 0.0f) Distance = 0.0f; float Scale = lcClamp(Distance, 0.1f, ScaleMax); ActiveModel->UpdateScaleTool(Scale); } } } else { lcVector3 PlaneNormal = lcNormalize(mCamera->mTargetPosition - mCamera->mPosition); lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center)); lcVector3 Intersection; if (lcLineSegmentPlaneIntersection(&Intersection, CurrentStart, CurrentEnd, Plane)) { lcVector3 MoveStart; if (lcLineSegmentPlaneIntersection(&MoveStart, MouseDownStart, MouseDownEnd, Plane)) { lcVector3 Distance = Intersection - MoveStart; ActiveModel->UpdateMoveTool(Distance, true, mTrackButton != lcTrackButton::Left); } } } } break; case lcTrackTool::RotateX: case lcTrackTool::RotateY: case lcTrackTool::RotateZ: { lcVector3 ScreenX = lcNormalize(lcCross(mCamera->mTargetPosition - mCamera->mPosition, mCamera->mUpVector)); lcVector3 ScreenY = mCamera->mUpVector; lcVector3 Dir1; switch (mTrackTool) { case lcTrackTool::RotateX: Dir1 = lcVector3(1.0f, 0.0f, 0.0f); break; case lcTrackTool::RotateY: Dir1 = lcVector3(0.0f, 1.0f, 0.0f); break; case lcTrackTool::RotateZ: Dir1 = lcVector3(0.0f, 0.0f, 1.0f); break; default: Dir1 = lcVector3(0.0f, 0.0f, 1.0f); break; } lcVector3 MoveX, MoveY; float dx1 = lcDot(ScreenX, Dir1); float dy1 = lcDot(ScreenY, Dir1); if (fabsf(dx1) > fabsf(dy1)) { if (dx1 >= 0.0f) MoveX = Dir1; else MoveX = -Dir1; MoveY = lcVector3(0, 0, 0); } else { MoveX = lcVector3(0, 0, 0); if (dy1 > 0.0f) MoveY = Dir1; else MoveY = -Dir1; } MoveX *= 36.0f * (float)(mMouseX - mMouseDownX) * MouseSensitivity; MoveY *= 36.0f * (float)(mMouseY - mMouseDownY) * MouseSensitivity; ActiveModel->UpdateRotateTool(MoveX + MoveY, mTrackButton != lcTrackButton::Left); } break; case lcTrackTool::RotateXY: { lcVector3 ScreenZ = lcNormalize(mCamera->mTargetPosition - mCamera->mPosition); lcVector3 ScreenX = lcCross(ScreenZ, mCamera->mUpVector); lcVector3 ScreenY = mCamera->mUpVector; lcVector3 MoveX = 36.0f * (float)(mMouseX - mMouseDownX) * MouseSensitivity * ScreenX; lcVector3 MoveY = 36.0f * (float)(mMouseY - mMouseDownY) * MouseSensitivity * ScreenY; ActiveModel->UpdateRotateTool(MoveX + MoveY, mTrackButton != lcTrackButton::Left); } break; case lcTrackTool::RotateXYZ: { lcVector3 ScreenZ = lcNormalize(mCamera->mTargetPosition - mCamera->mPosition); ActiveModel->UpdateRotateTool(36.0f * (float)(mMouseY - mMouseDownY) * MouseSensitivity * ScreenZ, mTrackButton != lcTrackButton::Left); } break; case lcTrackTool::Eraser: case lcTrackTool::Paint: case lcTrackTool::ColorPicker: break; case lcTrackTool::Zoom: ActiveModel->UpdateZoomTool(mCamera, 2.0f * MouseSensitivity * (mMouseY - mMouseDownY)); break; case lcTrackTool::Pan: UpdatePan(mMouseX, mMouseY); break; case lcTrackTool::OrbitX: ActiveModel->UpdateOrbitTool(mCamera, 0.1f * MouseSensitivity * (mMouseX - mMouseDownX), 0.0f); break; case lcTrackTool::OrbitY: ActiveModel->UpdateOrbitTool(mCamera, 0.0f, 0.1f * MouseSensitivity * (mMouseY - mMouseDownY)); break; case lcTrackTool::OrbitXY: ActiveModel->UpdateOrbitTool(mCamera, 0.1f * MouseSensitivity * (mMouseX - mMouseDownX), 0.1f * MouseSensitivity * (mMouseY - mMouseDownY)); break; case lcTrackTool::Roll: ActiveModel->UpdateRollTool(mCamera, 2.0f * MouseSensitivity * (mMouseX - mMouseDownX) * LC_DTOR); break; case lcTrackTool::ZoomRegion: Redraw(); break; case lcTrackTool::Count: break; } } void lcView::OnMouseWheel(float Direction) { float Scale = 10.0f; if (mMouseModifiers & Qt::ControlModifier) Scale = 100.0f; else if (mMouseModifiers & Qt::ShiftModifier) Scale = 1.0f; mModel->Zoom(mCamera, static_cast(Direction * Scale)); } leocad-23.03/common/lc_view.h000066400000000000000000000163751440571307300160610ustar00rootroot00000000000000#pragma once #include "lc_context.h" #include "lc_math.h" #include "lc_commands.h" enum class lcDragState { None, Piece, Color }; enum class lcCursor { First, Hidden = First, Default, Brick, Light, Spotlight, Camera, Select, SelectAdd, SelectRemove, Move, Rotate, RotateX, RotateY, Delete, Paint, ColorPicker, Zoom, ZoomRegion, Pan, Roll, RotateView, Count }; enum class lcTrackButton { None, Left, Middle, Right }; enum class lcTrackTool { None, Insert, PointLight, SpotLight, Camera, Select, MoveX, MoveY, MoveZ, MoveXY, MoveXZ, MoveYZ, MoveXYZ, RotateX, RotateY, RotateZ, RotateXY, RotateXYZ, ScalePlus, ScaleMinus, Eraser, Paint, ColorPicker, Zoom, Pan, OrbitX, OrbitY, OrbitXY, Roll, ZoomRegion, Count }; enum class lcViewType { View, Preview, Minifig, PartsList, Count }; struct lcFindReplaceParams { PieceInfo* FindInfo = nullptr; QString FindString; int FindColorIndex = 0; PieceInfo* ReplacePieceInfo = nullptr; int ReplaceColorIndex = 0; }; class lcView : public QObject { Q_OBJECT public: lcView(lcViewType ViewType, lcModel* Model); ~lcView(); lcView(const lcView&) = delete; lcView(lcView&&) = delete; lcView& operator=(const lcView&) = delete; lcView& operator=(lcView&&) = delete; static lcFindReplaceParams& GetFindReplaceParams() { return mFindReplaceParams; } lcModel* GetModel() const { return mModel; } lcViewType GetViewType() const { return mViewType; } lcCamera* GetCamera() const { return mCamera; } bool IsLastFocused() const { return mLastFocusedView == this; } bool IsTracking() const { return mTrackButton != lcTrackButton::None; } int GetWidth() const { return mWidth; } int GetHeight() const { return mHeight; } void SetSize(int Width, int Height) { mWidth = Width; mHeight = Height; } lcViewWidget* GetWidget() const { return mWidget; } void SetWidget(lcViewWidget* Widget) { mWidget = Widget; } int GetMouseX() const { return mMouseX; } int GetMouseY() const { return mMouseY; } void SetBackgroundColorOverride(quint32 BackgroundColor) { mOverrideBackgroundColor = true; mBackgroundColor = BackgroundColor; } lcMatrix44 GetActiveSubmodelTransform() const { return mActiveSubmodelTransform; } static std::vector GetModelViews(const lcModel* Model); static void UpdateProjectViews(const Project* Project); static void UpdateAllViews(); static void CreateResources(lcContext* Context); static void DestroyResources(lcContext* Context); void MakeCurrent(); void Redraw(); void SetOffscreenContext(); void SetFocus(bool Focus); void SetMousePosition(int MouseX, int MouseY); void SetMouseModifiers(Qt::KeyboardModifiers MouseModifiers); lcModel* GetActiveModel() const; void SetTopSubmodelActive(); void SetSelectedSubmodelActive(); void OnDraw(); void OnLeftButtonDown(); void OnLeftButtonUp(); void OnLeftButtonDoubleClick(); void OnMiddleButtonDown(); void OnMiddleButtonUp(); void OnRightButtonDown(); void OnRightButtonUp(); void OnBackButtonDown(); void OnBackButtonUp(); void OnForwardButtonDown(); void OnForwardButtonUp(); void OnMouseMove(); void OnMouseWheel(float Direction); void BeginDrag(lcDragState DragState); void EndDrag(bool Accept); void UpdateCursor(); void StartPanGesture(); void UpdatePanGesture(int dx, int dy); void EndPanGesture(bool Accept); void StartOrbitTracking(); void CancelTrackingOrClearSelection(); void SetViewpoint(lcViewpoint Viewpoint); void SetViewpoint(const lcVector3& Position); void SetViewpoint(const lcVector3& Position, const lcVector3& Target, const lcVector3& Up); void SetCameraAngles(float Latitude, float Longitude); void SetDefaultCamera(); void SetCamera(lcCamera* Camera, bool ForceCopy); void SetCamera(const QString& CameraName); void SetCameraIndex(int Index); void SetProjection(bool Ortho); void LookAt(); void MoveCamera(const lcVector3& Direction); void Zoom(float Amount); void ZoomExtents(); void RemoveCamera(); void ShowContextMenu() const; bool CloseFindReplaceDialog(); void ShowFindReplaceWidget(bool Replace); float GetOverlayScale() const; lcVector3 GetMoveDirection(const lcVector3& Direction) const; lcMatrix44 GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info) const; lcVector3 GetCameraLightInsertPosition() const; void GetRayUnderPointer(lcVector3& Start, lcVector3& End) const; lcObjectSection FindObjectUnderPointer(bool PiecesOnly, bool IgnoreSelected) const; lcPieceInfoRayTest FindPieceInfoUnderPointer(bool IgnoreSelected) const; lcArray FindObjectsInBox(float x1, float y1, float x2, float y2) const; lcVector3 ProjectPoint(const lcVector3& Point) const; lcVector3 UnprojectPoint(const lcVector3& Point) const; void UnprojectPoints(lcVector3* Points, int NumPoints) const; lcMatrix44 GetProjectionMatrix() const; bool BeginRenderToImage(int Width, int Height); void EndRenderToImage(); QImage GetRenderImage() const; void BindRenderFramebuffer(); void UnbindRenderFramebuffer(); QImage GetRenderFramebufferImage() const; std::vector GetStepImages(lcStep Start, lcStep End); void SaveStepImages(const QString& BaseName, bool AddStepSuffix, lcStep Start, lcStep End, std::function ProgressCallback); lcContext* mContext = nullptr; signals: void FocusReceived(); void CameraChanged(); protected: void DrawBackground(int CurrentTileRow, int TotalTileRows, int CurrentTileHeight) const; void DrawViewport() const; void DrawAxes() const; void DrawSelectZoomRegionOverlay(); void DrawRotateViewOverlay(); void DrawGrid(); lcMatrix44 GetTileProjectionMatrix(int CurrentRow, int CurrentColumn, int CurrentTileWidth, int CurrentTileHeight) const; lcCursor GetCursor() const; void SetCursor(lcCursor Cursor); lcTool GetCurrentTool() const; void UpdateTrackTool(); lcTrackTool GetOverrideTrackTool(Qt::MouseButton Button) const; void StartTracking(lcTrackButton TrackButton); void StopTracking(bool Accept); void OnButtonDown(lcTrackButton TrackButton); void StartPan(int x, int y); void UpdatePan(int x, int y); lcViewWidget* mWidget = nullptr; int mWidth = 1; int mHeight = 1; bool mDeleteContext = true; lcViewType mViewType; int mMouseX = 0; int mMouseY = 0; int mMouseDownX = 0; int mMouseDownY = 0; Qt::KeyboardModifiers mMouseModifiers = Qt::NoModifier; bool mTrackUpdated = false; bool mToolClicked = false; lcTrackTool mTrackTool = lcTrackTool::None; lcTrackButton mTrackButton = lcTrackButton::None; lcCursor mCursor = lcCursor::Default; lcDragState mDragState; bool mTrackToolFromOverlay; lcVector3 mMouseDownPosition; PieceInfo* mMouseDownPiece; int mPanX = 0; int mPanY = 0; QImage mRenderImage; std::unique_ptr mRenderFramebuffer; bool mOverrideBackgroundColor = false; quint32 mBackgroundColor = 0; std::unique_ptr mScene; std::unique_ptr mViewManipulator; std::unique_ptr mViewSphere; lcModel* mModel = nullptr; lcPiece* mActiveSubmodelInstance = nullptr; lcMatrix44 mActiveSubmodelTransform; lcCamera* mCamera = nullptr; lcVertexBuffer mGridBuffer; int mGridSettings[7]; static lcFindReplaceWidget* mFindWidget; static lcFindReplaceParams mFindReplaceParams; static lcView* mLastFocusedView; static std::vector mViews; }; leocad-23.03/common/lc_viewmanipulator.cpp000066400000000000000000001021441440571307300206560ustar00rootroot00000000000000#include "lc_global.h" #include "lc_viewmanipulator.h" #include "lc_view.h" #include "lc_model.h" #include "object.h" #include "piece.h" #include "camera.h" #include "pieceinf.h" #include "lc_synth.h" #include "lc_mainwindow.h" #include "texfont.h" lcVertexBuffer lcViewManipulator::mRotateMoveVertexBuffer; lcIndexBuffer lcViewManipulator::mRotateMoveIndexBuffer; lcViewManipulator::lcViewManipulator(lcView* View) : mView(View) { } void lcViewManipulator::CreateResources(lcContext* Context) { float Verts[(51 + 138 + 10) * 3]; float* CurVert = Verts; const float OverlayMovePlaneSize = 0.5f; const float OverlayMoveArrowSize = 1.5f; const float OverlayMoveArrowCapSize = 0.9f; const float OverlayMoveArrowCapRadius = 0.1f; const float OverlayMoveArrowBodySize = 1.2f; const float OverlayMoveArrowBodyRadius = 0.05f; const float OverlayRotateArrowStart = 1.0f; const float OverlayRotateArrowEnd = 1.5f; const float OverlayRotateArrowCenter = 1.2f; *CurVert++ = OverlayMoveArrowSize; *CurVert++ = 0.0f; *CurVert++ = 0.0f; for (int EdgeIdx = 0; EdgeIdx < 8; EdgeIdx++) { *CurVert++ = OverlayMoveArrowCapSize; *CurVert++ = cosf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius; *CurVert++ = sinf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius; } *CurVert++ = 0.0f; *CurVert++ = -OverlayMoveArrowBodyRadius; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = OverlayMoveArrowBodyRadius; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = -OverlayMoveArrowBodyRadius; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = OverlayMoveArrowBodyRadius; *CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = -OverlayMoveArrowBodyRadius; *CurVert++ = 0.0f; *CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = OverlayMoveArrowBodyRadius; *CurVert++ = 0.0f; *CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = 0.0f; *CurVert++ = -OverlayMoveArrowBodyRadius; *CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = 0.0f; *CurVert++ = OverlayMoveArrowBodyRadius; for (int VertIdx = 0; VertIdx < 17; VertIdx++) { *CurVert = *(CurVert - 50); CurVert++; *CurVert = *(CurVert - 52); CurVert++; *CurVert = *(CurVert - 51); CurVert++; } for (int VertIdx = 0; VertIdx < 17; VertIdx++) { *CurVert = *(CurVert - 100); CurVert++; *CurVert = *(CurVert - 102); CurVert++; *CurVert = *(CurVert - 104); CurVert++; } *CurVert++ = 0.0f; *CurVert++ = OverlayRotateArrowEnd - OverlayMoveArrowCapRadius; *CurVert++ = OverlayRotateArrowStart; for (int EdgeIdx = 0; EdgeIdx < 8; EdgeIdx++) { *CurVert++ = cosf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius; *CurVert++ = sinf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius + OverlayRotateArrowEnd - OverlayMoveArrowCapRadius; *CurVert++ = OverlayRotateArrowCenter; } *CurVert++ = 0.0f; *CurVert++ = OverlayRotateArrowStart; *CurVert++ = OverlayRotateArrowEnd - OverlayMoveArrowCapRadius; for (int EdgeIdx = 0; EdgeIdx < 8; EdgeIdx++) { *CurVert++ = cosf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius; *CurVert++ = OverlayRotateArrowCenter; *CurVert++ = sinf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius + OverlayRotateArrowEnd - OverlayMoveArrowCapRadius; } for (int EdgeIdx = 0; EdgeIdx < 7; EdgeIdx++) { const float Radius1 = OverlayRotateArrowEnd - OverlayMoveArrowCapRadius - OverlayRotateArrowCenter - OverlayMoveArrowBodyRadius; const float Radius2 = OverlayRotateArrowEnd - OverlayMoveArrowCapRadius - OverlayRotateArrowCenter + OverlayMoveArrowBodyRadius; float x = cosf(LC_2PI / 4 * EdgeIdx / 6); float y = sinf(LC_2PI / 4 * EdgeIdx / 6); *CurVert++ = 0.0f; *CurVert++ = OverlayRotateArrowCenter + x * Radius1; *CurVert++ = OverlayRotateArrowCenter + y * Radius1; *CurVert++ = 0.0f; *CurVert++ = OverlayRotateArrowCenter + x * Radius2; *CurVert++ = OverlayRotateArrowCenter + y * Radius2; } for (int EdgeIdx = 0; EdgeIdx < 7; EdgeIdx++) { const float Radius = OverlayRotateArrowEnd - OverlayMoveArrowCapRadius - OverlayRotateArrowCenter; float x = cosf(LC_2PI / 4 * EdgeIdx / 6); float y = sinf(LC_2PI / 4 * EdgeIdx / 6); *CurVert++ = -OverlayMoveArrowBodyRadius; *CurVert++ = OverlayRotateArrowCenter + x * Radius; *CurVert++ = OverlayRotateArrowCenter + y * Radius; *CurVert++ = OverlayMoveArrowBodyRadius; *CurVert++ = OverlayRotateArrowCenter + x * Radius; *CurVert++ = OverlayRotateArrowCenter + y * Radius; } for (int VertIdx = 0; VertIdx < 46; VertIdx++) { *CurVert = *(CurVert - 137); CurVert++; *CurVert = *(CurVert - 139); CurVert++; *CurVert = *(CurVert - 138); CurVert++; } for (int VertIdx = 0; VertIdx < 46; VertIdx++) { *CurVert = *(CurVert - 274); CurVert++; *CurVert = *(CurVert - 276); CurVert++; *CurVert = *(CurVert - 278); CurVert++; } *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f; *CurVert++ = 0.0f; const GLushort Indices[108 + 360 + 12] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7, 0, 7, 8, 0, 8, 1, 9, 10, 14, 14, 13, 9, 11, 12, 15, 15, 16, 12, 17, 18, 19, 17, 19, 20, 17, 20, 21, 17, 21, 22, 17, 22, 23, 17, 23, 24, 17, 24, 25, 17, 25, 18, 26, 27, 31, 31, 30, 26, 28, 29, 32, 32, 33, 29, 34, 35, 36, 34, 36, 37, 34, 37, 38, 34, 38, 39, 34, 39, 40, 34, 40, 41, 34, 41, 42, 34, 42, 35, 43, 44, 48, 48, 47, 43, 45, 46, 49, 49, 50, 46, 51, 52, 53, 51, 53, 54, 51, 54, 55, 51, 55, 56, 51, 56, 57, 51, 57, 58, 51, 58, 59, 51, 59, 52, 60, 61, 62, 60, 62, 63, 60, 63, 64, 60, 64, 65, 60, 65, 66, 60, 66, 67, 60, 67, 68, 60, 68, 61, 69, 70, 71, 71, 72, 70, 71, 72, 73, 73, 74, 72, 73, 74, 75, 75, 76, 74, 75, 76, 77, 77, 78, 76, 77, 78, 79, 79, 80, 78, 79, 80, 81, 81, 82, 80, 83, 84, 85, 85, 86, 84, 85, 86, 87, 87, 88, 86, 87, 88, 89, 89, 90, 88, 89, 90, 91, 91, 92, 90, 91, 92, 93, 93, 94, 92, 93, 94, 95, 95, 96, 94, 97, 98, 99, 97, 99, 100, 97, 100, 101, 97, 101, 102, 97, 102, 103, 97, 103, 104, 97, 104, 105, 97, 105, 98, 106, 107, 108, 106, 108, 109, 106, 109, 110, 106, 110, 111, 106, 111, 112, 106, 112, 113, 106, 113, 114, 106, 114, 107, 115, 116, 117, 117, 118, 116, 117, 118, 119, 119, 120, 118, 119, 120, 121, 121, 122, 120, 121, 122, 123, 123, 124, 122, 123, 124, 125, 125, 126, 124, 125, 126, 127, 127, 128, 126, 129, 130, 131, 131, 132, 130, 131, 132, 133, 133, 134, 132, 133, 134, 135, 135, 136, 134, 135, 136, 137, 137, 138, 136, 137, 138, 139, 139, 140, 138, 139, 140, 141, 141, 142, 140, 143, 144, 145, 143, 145, 146, 143, 146, 147, 143, 147, 148, 143, 148, 149, 143, 149, 150, 143, 150, 151, 143, 151, 144, 152, 153, 154, 152, 154, 155, 152, 155, 156, 152, 156, 157, 152, 157, 158, 152, 158, 159, 152, 159, 160, 152, 160, 153, 161, 162, 163, 163, 164, 162, 163, 164, 165, 165, 166, 164, 165, 166, 167, 167, 168, 166, 167, 168, 169, 169, 170, 168, 169, 170, 171, 171, 172, 170, 171, 172, 173, 173, 174, 172, 175, 176, 177, 177, 178, 176, 177, 178, 179, 179, 180, 178, 179, 180, 181, 181, 182, 180, 181, 182, 183, 183, 184, 182, 183, 184, 185, 185, 186, 184, 185, 186, 187, 187, 188, 186, 189, 190, 191, 192, 189, 193, 194, 195, 189, 196, 197, 198 }; mRotateMoveVertexBuffer = Context->CreateVertexBuffer(sizeof(Verts), Verts); mRotateMoveIndexBuffer = Context->CreateIndexBuffer(sizeof(Indices), Indices); } void lcViewManipulator::DestroyResources(lcContext* Context) { Context->DestroyVertexBuffer(mRotateMoveVertexBuffer); Context->DestroyIndexBuffer(mRotateMoveIndexBuffer); } void lcViewManipulator::DrawSelectMove(lcTrackButton TrackButton, lcTrackTool TrackTool) { const lcCamera* Camera = mView->GetCamera(); lcContext* Context = mView->mContext; Context->SetMaterial(lcMaterialType::UnlitColor); Context->SetViewMatrix(Camera->mWorldView); Context->SetProjectionMatrix(mView->GetProjectionMatrix()); Context->EnableDepthTest(false); lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; lcModel* ActiveModel = mView->GetActiveModel(); ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation); bool AnyPiecesSelected = ActiveModel->AnyPiecesSelected(); lcMatrix44 WorldMatrix = lcMatrix44(RelativeRotation, OverlayCenter); if (ActiveModel != mView->GetModel()) WorldMatrix = lcMul(WorldMatrix, mView->GetActiveSubmodelTransform()); const float OverlayScale = mView->GetOverlayScale(); WorldMatrix = lcMul(lcMatrix44Scale(lcVector3(OverlayScale, OverlayScale, OverlayScale)), WorldMatrix); Context->SetWorldMatrix(WorldMatrix); Context->SetLineWidth(1.0f); Context->SetIndexBuffer(mRotateMoveIndexBuffer); Context->SetVertexBuffer(mRotateMoveVertexBuffer); Context->SetVertexFormatPosition(3); lcObject* Focus = ActiveModel->GetFocusObject(); quint32 AllowedTransforms = Focus ? Focus->GetAllowedTransforms() : LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z; if (TrackButton == lcTrackButton::None || (TrackTool >= lcTrackTool::MoveX && TrackTool <= lcTrackTool::MoveXYZ)) { if (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_X) { if ((TrackTool == lcTrackTool::MoveX) || (TrackTool == lcTrackTool::MoveXY) || (TrackTool == lcTrackTool::MoveXZ)) { Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f); Context->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); } else if (TrackButton == lcTrackButton::None) { Context->SetColor(0.8f, 0.0f, 0.0f, 1.0f); Context->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); } } if (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Y) { if (((TrackTool == lcTrackTool::MoveY) || (TrackTool == lcTrackTool::MoveXY) || (TrackTool == lcTrackTool::MoveYZ)) && (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Y)) { Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f); Context->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 36 * 2); } else if (TrackButton == lcTrackButton::None) { Context->SetColor(0.0f, 0.8f, 0.0f, 1.0f); Context->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 36 * 2); } } if (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Z) { if (((TrackTool == lcTrackTool::MoveZ) || (TrackTool == lcTrackTool::MoveXZ) || (TrackTool == lcTrackTool::MoveYZ)) && (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Z)) { Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f); Context->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 72 * 2); } else if (TrackButton == lcTrackButton::None) { Context->SetColor(0.0f, 0.0f, 0.8f, 1.0f); Context->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 72 * 2); } } } if (gMainWindow->GetTool() == lcTool::Select && TrackButton == lcTrackButton::None && AnyPiecesSelected) { if (AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_X) { if (TrackTool == lcTrackTool::RotateX) Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f); else Context->SetColor(0.8f, 0.0f, 0.0f, 1.0f); Context->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, 108 * 2); } if (AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Y) { if (TrackTool == lcTrackTool::RotateY) Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f); else Context->SetColor(0.0f, 0.8f, 0.0f, 1.0f); Context->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, (108 + 120) * 2); } if (AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Z) { if (TrackTool == lcTrackTool::RotateZ) Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f); else Context->SetColor(0.0f, 0.0f, 0.8f, 1.0f); Context->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, (108 + 240) * 2); } } if ((TrackTool == lcTrackTool::MoveXY) || (TrackTool == lcTrackTool::MoveXZ) || (TrackTool == lcTrackTool::MoveYZ)) { Context->EnableColorBlend(true); Context->SetColor(0.8f, 0.8f, 0.0f, 0.3f); if (TrackTool == lcTrackTool::MoveXY) Context->DrawIndexedPrimitives(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, (108 + 360 + 8) * 2); else if (TrackTool == lcTrackTool::MoveXZ) Context->DrawIndexedPrimitives(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, (108 + 360 + 4) * 2); else if (TrackTool == lcTrackTool::MoveYZ) Context->DrawIndexedPrimitives(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, (108 + 360) * 2); Context->EnableColorBlend(false); } if (Focus && Focus->IsPiece()) { lcPiece* Piece = (lcPiece*)Focus; quint32 Section = Piece->GetFocusSection(); if (Section >= LC_PIECE_SECTION_CONTROL_POINT_FIRST && Section <= LC_PIECE_SECTION_CONTROL_POINT_LAST && Piece->mPieceInfo->GetSynthInfo() && Piece->mPieceInfo->GetSynthInfo()->IsCurve()) { int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST; float Strength = Piece->GetControlPoints()[ControlPointIndex].Scale; const float ScaleStart = 2.0f; float Length = ScaleStart + Strength / OverlayScale; const float OverlayScaleInnerRadius = 0.075f; const float OverlayScaleRadius = 0.125f; lcVector3 Verts[38]; int NumVerts = 0; Verts[NumVerts++] = lcVector3(Length - OverlayScaleRadius, 0.0f, 0.0f); Verts[NumVerts++] = lcVector3(OverlayScaleRadius - Length, 0.0f, 0.0f); float SinTable[9], CosTable[9]; for (int Step = 0; Step <= 8; Step++) { SinTable[Step] = sinf((float)Step / 8.0f * LC_2PI); CosTable[Step] = cosf((float)Step / 8.0f * LC_2PI); } for (int Step = 0; Step <= 8; Step++) { float x = CosTable[Step]; float y = SinTable[Step]; Verts[NumVerts++] = lcVector3(Length + x * OverlayScaleInnerRadius, 0.0f, y * OverlayScaleInnerRadius); Verts[NumVerts++] = lcVector3(Length + x * OverlayScaleRadius, 0.0f, y * OverlayScaleRadius); } for (int Step = 0; Step <= 8; Step++) { float x = CosTable[Step]; float y = SinTable[Step]; Verts[NumVerts++] = lcVector3(-Length + x * OverlayScaleInnerRadius, 0.0f, y * OverlayScaleInnerRadius); Verts[NumVerts++] = lcVector3(-Length + x * OverlayScaleRadius, 0.0f, y * OverlayScaleRadius); } if (TrackTool == lcTrackTool::ScalePlus || TrackTool == lcTrackTool::ScaleMinus) Context->SetColor(0.8f, 0.8f, 0.0f, 0.3f); else Context->SetColor(0.0f, 0.0f, 0.8f, 1.0f); Context->SetVertexBufferPointer(Verts); Context->ClearIndexBuffer(); Context->SetVertexFormatPosition(3); Context->DrawPrimitives(GL_LINES, 0, 2); Context->DrawPrimitives(GL_TRIANGLE_STRIP, 2, 18); Context->DrawPrimitives(GL_TRIANGLE_STRIP, 20, 18); } } Context->EnableDepthTest(true); } void lcViewManipulator::DrawRotate(lcTrackButton TrackButton, lcTrackTool TrackTool) { const lcCamera* Camera = mView->GetCamera(); lcContext* Context = mView->mContext; const float OverlayScale = mView->GetOverlayScale(); const float OverlayRotateRadius = 2.0f; Context->SetMaterial(lcMaterialType::UnlitColor); Context->SetViewMatrix(Camera->mWorldView); Context->SetProjectionMatrix(mView->GetProjectionMatrix()); Context->SetLineWidth(1.0f); Context->EnableDepthTest(false); int j; lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; lcModel* ActiveModel = mView->GetActiveModel(); ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation); lcVector3 MouseToolDistance = ActiveModel->SnapRotation(ActiveModel->GetMouseToolDistance()); bool HasAngle = false; lcMatrix44 WorldMatrix = lcMatrix44(RelativeRotation, OverlayCenter); if (ActiveModel != mView->GetModel()) WorldMatrix = lcMul(WorldMatrix, mView->GetActiveSubmodelTransform()); // Draw a disc showing the rotation amount. if (MouseToolDistance.LengthSquared() != 0.0f && (TrackButton != lcTrackButton::None)) { lcVector4 Rotation; float Angle, Step; HasAngle = true; switch (TrackTool) { case lcTrackTool::RotateX: Context->SetColor(0.8f, 0.0f, 0.0f, 0.3f); Angle = MouseToolDistance[0]; Rotation = lcVector4(0.0f, 0.0f, 0.0f, 1.0f); break; case lcTrackTool::RotateY: Context->SetColor(0.0f, 0.8f, 0.0f, 0.3f); Angle = MouseToolDistance[1]; Rotation = lcVector4(90.0f, 0.0f, 0.0f, 1.0f); break; case lcTrackTool::RotateZ: Context->SetColor(0.0f, 0.0f, 0.8f, 0.3f); Angle = MouseToolDistance[2]; Rotation = lcVector4(90.0f, 0.0f, -1.0f, 0.0f); break; default: Rotation = lcVector4(0.0f, 0.0f, 0.0f, 1.0f); Angle = 0.0f; break; }; if (Angle > 0.0f) { Step = 360.0f / 32; } else { Angle = -Angle; Step = -360.0f / 32; } if (fabsf(Angle) >= fabsf(Step)) { lcMatrix44 RotatedWorldMatrix = lcMul(lcMatrix44FromAxisAngle(lcVector3(Rotation[1], Rotation[2], Rotation[3]), Rotation[0] * LC_DTOR), WorldMatrix); Context->SetWorldMatrix(RotatedWorldMatrix); Context->EnableColorBlend(true); lcVector3 Verts[33]; Verts[0] = lcVector3(0.0f, 0.0f, 0.0f); int NumVerts = 1; Context->SetVertexBufferPointer(Verts); Context->SetVertexFormatPosition(3); float StartAngle; int i = 0; if (Step < 0) StartAngle = -Angle; else StartAngle = Angle; do { float x = cosf((Step * i - StartAngle) * LC_DTOR) * OverlayRotateRadius * OverlayScale; float y = sinf((Step * i - StartAngle) * LC_DTOR) * OverlayRotateRadius * OverlayScale; Verts[NumVerts++] = lcVector3(0.0f, x, y); if (NumVerts == 33) { Context->DrawPrimitives(GL_TRIANGLE_FAN, 0, NumVerts); Verts[1] = Verts[32]; NumVerts = 2; } i++; if (Step > 0) Angle -= Step; else Angle += Step; } while (Angle >= 0.0f); if (NumVerts > 2) Context->DrawPrimitives(GL_TRIANGLE_FAN, 0, NumVerts); Context->EnableColorBlend(false); } } // Draw the circles. if (gMainWindow->GetTool() == lcTool::Rotate && !HasAngle && TrackButton == lcTrackButton::None) { lcMatrix44 Mat = lcMatrix44AffineInverse(Camera->mWorldView); Mat.SetTranslation(WorldMatrix.GetTranslation()); lcVector3 Verts[32]; for (j = 0; j < 32; j++) { lcVector3 Pt; Pt[0] = cosf(LC_2PI * j / 32) * OverlayRotateRadius * OverlayScale; Pt[1] = sinf(LC_2PI * j / 32) * OverlayRotateRadius * OverlayScale; Pt[2] = 0.0f; Verts[j] = lcMul31(Pt, Mat); } Context->SetColor(0.1f, 0.1f, 0.1f, 1.0f); Context->SetWorldMatrix(lcMatrix44Identity()); Context->SetVertexBufferPointer(Verts); Context->SetVertexFormatPosition(3); Context->DrawPrimitives(GL_LINE_LOOP, 0, 32); } lcVector3 ViewDir = Camera->mTargetPosition - Camera->mPosition; ViewDir.Normalize(); // Transform ViewDir to local space. ViewDir = lcMul(ViewDir, lcMatrix33AffineInverse(lcMatrix33(WorldMatrix))); Context->SetWorldMatrix(WorldMatrix); // Draw each axis circle. for (int i = 0; i < 3; i++) { if (static_cast(TrackTool) == static_cast(lcTrackTool::RotateX) + i) { Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f); } else { if (gMainWindow->GetTool() != lcTool::Rotate || HasAngle || TrackButton != lcTrackButton::None) continue; switch (i) { case 0: Context->SetColor(0.8f, 0.0f, 0.0f, 1.0f); break; case 1: Context->SetColor(0.0f, 0.8f, 0.0f, 1.0f); break; case 2: Context->SetColor(0.0f, 0.0f, 0.8f, 1.0f); break; } } lcVector3 Verts[64]; int NumVerts = 0; for (j = 0; j < 32; j++) { lcVector3 v1, v2; switch (i) { case 0: v1 = lcVector3(0.0f, cosf(LC_2PI * j / 32), sinf(LC_2PI * j / 32)); v2 = lcVector3(0.0f, cosf(LC_2PI * (j + 1) / 32), sinf(LC_2PI * (j + 1) / 32)); break; case 1: v1 = lcVector3(cosf(LC_2PI * j / 32), 0.0f, sinf(LC_2PI * j / 32)); v2 = lcVector3(cosf(LC_2PI * (j + 1) / 32), 0.0f, sinf(LC_2PI * (j + 1) / 32)); break; case 2: v1 = lcVector3(cosf(LC_2PI * j / 32), sinf(LC_2PI * j / 32), 0.0f); v2 = lcVector3(cosf(LC_2PI * (j + 1) / 32), sinf(LC_2PI * (j + 1) / 32), 0.0f); break; } if (gMainWindow->GetTool() != lcTool::Rotate || HasAngle || TrackButton != lcTrackButton::None || lcDot(ViewDir, v1 + v2) <= 0.0f) { Verts[NumVerts++] = v1 * (OverlayRotateRadius * OverlayScale); Verts[NumVerts++] = v2 * (OverlayRotateRadius * OverlayScale); } } Context->SetVertexBufferPointer(Verts); Context->SetVertexFormatPosition(3); Context->DrawPrimitives(GL_LINES, 0, NumVerts); } // Draw tangent vector. if (TrackButton != lcTrackButton::None && ((TrackTool == lcTrackTool::RotateX) || (TrackTool == lcTrackTool::RotateY) || (TrackTool == lcTrackTool::RotateZ))) { const float OverlayRotateArrowSize = 1.5f; const float OverlayRotateArrowCapSize = 0.25f; lcVector4 Rotation; float Angle; switch (TrackTool) { case lcTrackTool::RotateX: Angle = MouseToolDistance[0]; Rotation = lcVector4(0.0f, 0.0f, 0.0f, 1.0f); break; case lcTrackTool::RotateY: Angle = MouseToolDistance[1]; Rotation = lcVector4(90.0f, 0.0f, 0.0f, 1.0f); break; case lcTrackTool::RotateZ: Angle = MouseToolDistance[2]; Rotation = lcVector4(90.0f, 0.0f, -1.0f, 0.0f); break; default: Angle = 0.0f; Rotation = lcVector4(0.0f, 0.0f, 1.0f, 0.0f); break; }; lcMatrix44 RotatedWorldMatrix = lcMul(lcMatrix44FromAxisAngle(lcVector3(Rotation[1], Rotation[2], Rotation[3]), Rotation[0] * LC_DTOR), WorldMatrix); Context->SetWorldMatrix(RotatedWorldMatrix); Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f); if (HasAngle) { float StartY = OverlayScale * OverlayRotateRadius; float EndZ = (Angle > 0.0f) ? OverlayScale * OverlayRotateArrowSize : -OverlayScale * OverlayRotateArrowSize; float TipZ = (Angle > 0.0f) ? -OverlayScale * OverlayRotateArrowCapSize : OverlayScale * OverlayRotateArrowCapSize; lcVector3 Verts[6]; Verts[0] = lcVector3(0.0f, StartY, 0.0f); Verts[1] = lcVector3(0.0f, StartY, EndZ); Verts[2] = lcVector3(0.0f, StartY, EndZ); Verts[3] = lcVector3(0.0f, StartY + OverlayScale * OverlayRotateArrowCapSize, EndZ + TipZ); Verts[4] = lcVector3(0.0f, StartY, EndZ); Verts[5] = lcVector3(0.0f, StartY - OverlayScale * OverlayRotateArrowCapSize, EndZ + TipZ); Context->SetVertexBufferPointer(Verts); Context->SetVertexFormatPosition(3); Context->DrawPrimitives(GL_LINES, 0, 6); } // Draw text. lcVector3 ScreenPos = mView->ProjectPoint(WorldMatrix.GetTranslation()); Context->SetMaterial(lcMaterialType::UnlitTextureModulate); Context->SetWorldMatrix(lcMatrix44Identity()); Context->SetViewMatrix(lcMatrix44Translation(lcVector3(0.375, 0.375, 0.0))); Context->SetProjectionMatrix(lcMatrix44Ortho(0.0f, mView->GetWidth(), 0.0f, mView->GetHeight(), -1.0f, 1.0f)); Context->BindTexture2D(gTexFont.GetTexture()); Context->EnableColorBlend(true); char buf[32]; sprintf(buf, "[%.2f]", fabsf(Angle)); int cx, cy; gTexFont.GetStringDimensions(&cx, &cy, buf); Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f); gTexFont.PrintText(Context, ScreenPos[0] - (cx / 2), ScreenPos[1] + (cy / 2), 0.0f, buf); Context->EnableColorBlend(false); } Context->EnableDepthTest(true); } bool lcViewManipulator::IsTrackToolAllowed(lcTrackTool TrackTool, quint32 AllowedTransforms) { switch (TrackTool) { case lcTrackTool::None: case lcTrackTool::Insert: case lcTrackTool::PointLight: case lcTrackTool::SpotLight: case lcTrackTool::Camera: case lcTrackTool::Select: return true; case lcTrackTool::MoveX: return AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_X; case lcTrackTool::MoveY: return AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Y; case lcTrackTool::MoveZ: return AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Z; case lcTrackTool::MoveXY: return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y)) == (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y); case lcTrackTool::MoveXZ: return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Z)) == (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Z); case lcTrackTool::MoveYZ: return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z)) == (LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z); case lcTrackTool::MoveXYZ: return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z)) == (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z); case lcTrackTool::RotateX: return AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_X; case lcTrackTool::RotateY: return AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Y; case lcTrackTool::RotateZ: return AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Z; case lcTrackTool::RotateXY: return (AllowedTransforms & (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y)) == (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y); case lcTrackTool::RotateXYZ: return (AllowedTransforms & (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z)) == (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z); case lcTrackTool::ScalePlus: case lcTrackTool::ScaleMinus: return AllowedTransforms & (LC_OBJECT_TRANSFORM_SCALE_X | LC_OBJECT_TRANSFORM_SCALE_Y | LC_OBJECT_TRANSFORM_SCALE_Z); case lcTrackTool::Eraser: case lcTrackTool::Paint: case lcTrackTool::ColorPicker: case lcTrackTool::Zoom: case lcTrackTool::Pan: case lcTrackTool::OrbitX: case lcTrackTool::OrbitY: case lcTrackTool::OrbitXY: case lcTrackTool::Roll: case lcTrackTool::ZoomRegion: return true; case lcTrackTool::Count: return false; } return false; } lcTrackTool lcViewManipulator::UpdateSelectMove() { lcModel* ActiveModel = mView->GetActiveModel(); const float OverlayScale = mView->GetOverlayScale(); const float OverlayMovePlaneSize = 0.5f * OverlayScale; const float OverlayMoveArrowSize = 1.5f * OverlayScale; const float OverlayMoveArrowCapRadius = 0.1f * OverlayScale; const float OverlayRotateArrowStart = 1.0f * OverlayScale; const float OverlayRotateArrowEnd = 1.5f * OverlayScale; const float OverlayScaleRadius = 0.125f; lcTool CurrentTool = gMainWindow->GetTool(); lcTrackTool NewTrackTool = (CurrentTool == lcTool::Move) ? lcTrackTool::MoveXYZ : lcTrackTool::Select; lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; if (!ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation)) return NewTrackTool; lcMatrix44 WorldMatrix = lcMatrix44(RelativeRotation, OverlayCenter); if (ActiveModel != mView->GetModel()) WorldMatrix = lcMul(WorldMatrix, mView->GetActiveSubmodelTransform()); OverlayCenter = WorldMatrix.GetTranslation(); lcVector3 PlaneNormals[3] = { lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f), lcVector3(0.0f, 0.0f, 1.0f), }; for (int i = 0; i < 3; i++) PlaneNormals[i] = lcMul30(PlaneNormals[i], WorldMatrix); const int x = mView->GetMouseX(); const int y = mView->GetMouseY(); lcVector3 StartEnd[2] = { lcVector3((float)x, (float)y, 0.0f), lcVector3((float)x, (float)y, 1.0f) }; mView->UnprojectPoints(StartEnd, 2); const lcVector3& Start = StartEnd[0]; const lcVector3& End = StartEnd[1]; float ClosestIntersectionDistance = FLT_MAX; lcObject* Focus = ActiveModel->GetFocusObject(); int ControlPointIndex = -1; if (Focus && Focus->IsPiece()) { lcPiece* Piece = (lcPiece*)Focus; quint32 Section = Piece->GetFocusSection(); if (Section >= LC_PIECE_SECTION_CONTROL_POINT_FIRST && Section <= LC_PIECE_SECTION_CONTROL_POINT_LAST) ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST; } quint32 AllowedTransforms = Focus ? Focus->GetAllowedTransforms() : LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z; for (int AxisIndex = 0; AxisIndex < 3; AxisIndex++) { lcVector4 Plane(PlaneNormals[AxisIndex], -lcDot(PlaneNormals[AxisIndex], OverlayCenter)); lcVector3 Intersection; if (!lcLineSegmentPlaneIntersection(&Intersection, Start, End, Plane)) continue; float IntersectionDistance = lcLengthSquared(Intersection - Start); if (IntersectionDistance > ClosestIntersectionDistance) continue; lcVector3 Dir(Intersection - OverlayCenter); float Proj1 = lcDot(Dir, PlaneNormals[(AxisIndex + 1) % 3]); float Proj2 = lcDot(Dir, PlaneNormals[(AxisIndex + 2) % 3]); if (Proj1 > 0.0f && Proj1 < OverlayMovePlaneSize && Proj2 > 0.0f && Proj2 < OverlayMovePlaneSize) { lcTrackTool PlaneModes[] = { lcTrackTool::MoveYZ, lcTrackTool::MoveXZ, lcTrackTool::MoveXY }; if (IsTrackToolAllowed(PlaneModes[AxisIndex], AllowedTransforms)) { NewTrackTool = PlaneModes[AxisIndex]; ClosestIntersectionDistance = IntersectionDistance; } } if (CurrentTool == lcTool::Select && Proj1 > OverlayRotateArrowStart && Proj1 < OverlayRotateArrowEnd && Proj2 > OverlayRotateArrowStart && Proj2 < OverlayRotateArrowEnd && ActiveModel->AnyPiecesSelected()) { lcTrackTool PlaneModes[] = { lcTrackTool::RotateX, lcTrackTool::RotateY, lcTrackTool::RotateZ }; if (IsTrackToolAllowed(PlaneModes[AxisIndex], AllowedTransforms)) { NewTrackTool = PlaneModes[AxisIndex]; ClosestIntersectionDistance = IntersectionDistance; } } if (fabs(Proj1) < OverlayMoveArrowCapRadius && Proj2 > 0.0f && Proj2 < OverlayMoveArrowSize) { lcTrackTool DirModes[] = { lcTrackTool::MoveZ, lcTrackTool::MoveX, lcTrackTool::MoveY }; if (IsTrackToolAllowed(DirModes[AxisIndex], AllowedTransforms)) { NewTrackTool = DirModes[AxisIndex]; ClosestIntersectionDistance = IntersectionDistance; } } if (fabs(Proj2) < OverlayMoveArrowCapRadius && Proj1 > 0.0f && Proj1 < OverlayMoveArrowSize) { lcTrackTool DirModes[] = { lcTrackTool::MoveY, lcTrackTool::MoveZ, lcTrackTool::MoveX }; if (IsTrackToolAllowed(DirModes[AxisIndex], AllowedTransforms)) { NewTrackTool = DirModes[AxisIndex]; ClosestIntersectionDistance = IntersectionDistance; } } lcPiece* Piece = (lcPiece*)Focus; if (ControlPointIndex != -1 && Piece->mPieceInfo->GetSynthInfo() && Piece->mPieceInfo->GetSynthInfo()->IsCurve()) { float Strength = Piece->GetControlPoints()[ControlPointIndex].Scale; const float ScaleStart = (2.0f - OverlayScaleRadius) * OverlayScale + Strength; const float ScaleEnd = (2.0f + OverlayScaleRadius) * OverlayScale + Strength; if (AxisIndex == 1 && fabs(Proj1) < OverlayScaleRadius * OverlayScale) { if (Proj2 > ScaleStart && Proj2 < ScaleEnd) { if (IsTrackToolAllowed(lcTrackTool::ScalePlus, AllowedTransforms)) { NewTrackTool = lcTrackTool::ScalePlus; ClosestIntersectionDistance = IntersectionDistance; } } else if (Proj2 < -ScaleStart && Proj2 > -ScaleEnd) { if (IsTrackToolAllowed(lcTrackTool::ScaleMinus, AllowedTransforms)) { NewTrackTool = lcTrackTool::ScaleMinus; ClosestIntersectionDistance = IntersectionDistance; } } } else if (AxisIndex == 2 && fabs(Proj2) < OverlayScaleRadius * OverlayScale) { if (Proj1 > ScaleStart && Proj1 < ScaleEnd) { if (IsTrackToolAllowed(lcTrackTool::ScalePlus, AllowedTransforms)) { NewTrackTool = lcTrackTool::ScalePlus; ClosestIntersectionDistance = IntersectionDistance; } } else if (Proj1 < -ScaleStart && Proj1 > -ScaleEnd) { if (IsTrackToolAllowed(lcTrackTool::ScaleMinus, AllowedTransforms)) { NewTrackTool = lcTrackTool::ScaleMinus; ClosestIntersectionDistance = IntersectionDistance; } } } } } return NewTrackTool; } lcTrackTool lcViewManipulator::UpdateRotate() { const lcModel* ActiveModel = mView->GetActiveModel(); const float OverlayScale = mView->GetOverlayScale(); const float OverlayRotateRadius = 2.0f; lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; if (!ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation)) return lcTrackTool::RotateXYZ; lcMatrix44 WorldMatrix = lcMatrix44(RelativeRotation, OverlayCenter); if (ActiveModel != mView->GetModel()) WorldMatrix = lcMul(WorldMatrix, mView->GetActiveSubmodelTransform()); OverlayCenter = WorldMatrix.GetTranslation(); const int x = mView->GetMouseX(); const int y = mView->GetMouseY(); lcVector3 StartEnd[2] = { lcVector3((float)x, (float)y, 0.0f), lcVector3((float)x, (float)y, 1.0f) }; mView->UnprojectPoints(StartEnd, 2); lcVector3 Intersection; if (lcSphereRayIntersection(OverlayCenter, OverlayRotateRadius * OverlayScale, StartEnd[0], StartEnd[1], Intersection)) { const lcVector3 LocalIntersection = lcMul(Intersection - OverlayCenter, lcMatrix33AffineInverse(RelativeRotation)); const float Epsilon = 0.25f * OverlayScale; const float dx = fabsf(LocalIntersection[0]); const float dy = fabsf(LocalIntersection[1]); const float dz = fabsf(LocalIntersection[2]); if (dx < dy) { if (dx < dz) { if (dx < Epsilon) return lcTrackTool::RotateX; } else { if (dz < Epsilon) return lcTrackTool::RotateZ; } } else { if (dy < dz) { if (dy < Epsilon) return lcTrackTool::RotateY; } else { if (dz < Epsilon) return lcTrackTool::RotateZ; } } } return lcTrackTool::RotateXYZ; } leocad-23.03/common/lc_viewmanipulator.h000066400000000000000000000011711440571307300203210ustar00rootroot00000000000000#pragma once #include "lc_context.h" class lcViewManipulator { public: lcViewManipulator(lcView* View); void DrawSelectMove(lcTrackButton TrackButton, lcTrackTool TrackTool); void DrawRotate(lcTrackButton TrackButton, lcTrackTool TrackTool); lcTrackTool UpdateSelectMove(); lcTrackTool UpdateRotate(); static void CreateResources(lcContext* Context); static void DestroyResources(lcContext* Context); protected: static bool IsTrackToolAllowed(lcTrackTool TrackTool, quint32 AllowedTransforms); lcView* mView = nullptr; static lcVertexBuffer mRotateMoveVertexBuffer; static lcIndexBuffer mRotateMoveIndexBuffer; }; leocad-23.03/common/lc_viewsphere.cpp000066400000000000000000000306431440571307300176150ustar00rootroot00000000000000#include "lc_global.h" #include "lc_viewsphere.h" #include "lc_view.h" #include "camera.h" #include "lc_context.h" #include "lc_stringcache.h" #include "lc_application.h" #include "image.h" #include "lc_texture.h" lcTexture* lcViewSphere::mTexture; lcVertexBuffer lcViewSphere::mVertexBuffer; lcIndexBuffer lcViewSphere::mIndexBuffer; const float lcViewSphere::mRadius = 1.0f; const float lcViewSphere::mHighlightRadius = 0.35f; const int lcViewSphere::mSubdivisions = 7; lcViewSphere::lcViewSphere(lcView* View) : mView(View) { UpdateSettings(); } void lcViewSphere::UpdateSettings() { const lcPreferences& Preferences = lcGetPreferences(); switch (mView->GetViewType()) { case lcViewType::View: mSize = Preferences.mViewSphereSize; mEnabled = Preferences.mViewSphereEnabled; mLocation = Preferences.mViewSphereLocation; break; case lcViewType::Preview: mSize = Preferences.mPreviewViewSphereSize; mEnabled = Preferences.mPreviewViewSphereEnabled; mLocation = Preferences.mPreviewViewSphereLocation; break; case lcViewType::Minifig: case lcViewType::PartsList: case lcViewType::Count: break; } } lcMatrix44 lcViewSphere::GetViewMatrix() const { lcMatrix44 ViewMatrix = mView->GetCamera()->mWorldView; ViewMatrix.SetTranslation(lcVector3(0, 0, 0)); return ViewMatrix; } lcMatrix44 lcViewSphere::GetProjectionMatrix() const { return lcMatrix44Ortho(-mRadius * 1.25f, mRadius * 1.25f, -mRadius * 1.25f, mRadius * 1.25f, -mRadius * 1.25f, mRadius * 1.25f); } void lcViewSphere::CreateResources(lcContext* Context) { constexpr int ImageSize = 128; mTexture = new lcTexture(); const QString ViewNames[6] = { QCoreApplication::translate("ViewName", "Left"), QCoreApplication::translate("ViewName", "Right"), QCoreApplication::translate("ViewName", "Back"), QCoreApplication::translate("ViewName", "Front"), QCoreApplication::translate("ViewName", "Top"), QCoreApplication::translate("ViewName", "Bottom") }; const QTransform ViewTransforms[6] = { QTransform(0, 1, 1, 0, 0, 0), QTransform(0, -1, -1, 0, ImageSize, ImageSize), QTransform(-1, 0, 0, 1, ImageSize, 0), QTransform(1, 0, 0, -1, 0, ImageSize), QTransform(1, 0, 0, -1, 0, ImageSize), QTransform(-1, 0, 0, 1, ImageSize, 0) }; QImage PainterImage(ImageSize, ImageSize, QImage::Format_ARGB32); QPainter Painter; QFont Font("Helvetica", 20); std::vector Images; for (int ViewIdx = 0; ViewIdx < 6; ViewIdx++) { Image TextureImage; TextureImage.Allocate(ImageSize, ImageSize, lcPixelFormat::A8); Painter.begin(&PainterImage); Painter.fillRect(0, 0, PainterImage.width(), PainterImage.height(), QColor(0, 0, 0)); Painter.setBrush(QColor(255, 255, 255)); Painter.setPen(QColor(255, 255, 255)); Painter.setFont(Font); Painter.setTransform(ViewTransforms[ViewIdx]); Painter.drawText(0, 0, PainterImage.width(), PainterImage.height(), Qt::AlignCenter, ViewNames[ViewIdx]); Painter.end(); for (int y = 0; y < ImageSize; y++) { unsigned char* Dest = TextureImage.mData + (ImageSize - y - 1) * TextureImage.mWidth; for (int x = 0; x < ImageSize; x++) *Dest++ = qRed(PainterImage.pixel(x, y)); } Images.emplace_back(std::move(TextureImage)); } mTexture->SetImage(std::move(Images), LC_TEXTURE_CUBEMAP | LC_TEXTURE_LINEAR); lcVector3 Verts[(mSubdivisions + 1) * (mSubdivisions + 1) * 6]; GLushort Indices[mSubdivisions * mSubdivisions * 6 * 6]; lcMatrix44 Transforms[6] = { lcMatrix44(lcVector4(0.0f, 1.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(1.0f, 0.0f, 0.0f, 1.0f)), lcMatrix44(lcVector4(0.0f, -1.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(-1.0f, 0.0f, 0.0f, 1.0f)), lcMatrix44(lcVector4(-1.0f, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 1.0f, 0.0f, 0.0f), lcVector4(0.0f, 1.0f, 0.0f, 1.0f)), lcMatrix44(lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 1.0f, 0.0f, 0.0f), lcVector4(0.0f, -1.0f, 0.0f, 1.0f)), lcMatrix44(lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, 1.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 1.0f)), lcMatrix44(lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, -1.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 0.0f, -1.0f, 1.0f)), }; constexpr float Step = 2.0f / mSubdivisions; lcVector3* CurVert = Verts; for (int FaceIdx = 0; FaceIdx < 6; FaceIdx++) { for (int y = 0; y <= mSubdivisions; y++) { for (int x = 0; x <= mSubdivisions; x++) { const lcVector3 Vert = lcMul31(lcVector3(Step * x - 1.0f, Step * y - 1.0f, 0.0f), Transforms[FaceIdx]); const lcVector3 Vert2 = Vert * Vert; *CurVert++ = lcVector3(Vert.x * sqrt(1.0 - 0.5 * (Vert2.y + Vert2.z) + Vert2.y * Vert2.z / 3.0), Vert.y * sqrt(1.0 - 0.5 * (Vert2.z + Vert2.x) + Vert2.z * Vert2.x / 3.0), Vert.z * sqrt(1.0 - 0.5 * (Vert2.x + Vert2.y) + Vert2.x * Vert2.y / 3.0) ) * mRadius; } } } GLushort* CurIndex = Indices; for (int FaceIdx = 0; FaceIdx < 6; FaceIdx++) { const int FaceBase = FaceIdx * (mSubdivisions + 1) * (mSubdivisions + 1); for (int y = 0; y < mSubdivisions; y++) { int RowBase = FaceBase + (mSubdivisions + 1) * y; for (int x = 0; x < mSubdivisions; x++) { *CurIndex++ = RowBase + x; *CurIndex++ = RowBase + x + 1; *CurIndex++ = RowBase + x + (mSubdivisions + 1); *CurIndex++ = RowBase + x + 1; *CurIndex++ = RowBase + x + 1 + (mSubdivisions + 1); *CurIndex++ = RowBase + x + (mSubdivisions + 1); } } } mVertexBuffer = Context->CreateVertexBuffer(sizeof(Verts), Verts); mIndexBuffer = Context->CreateIndexBuffer(sizeof(Indices), Indices); } void lcViewSphere::DestroyResources(lcContext* Context) { delete mTexture; mTexture = nullptr; Context->DestroyVertexBuffer(mVertexBuffer); Context->DestroyIndexBuffer(mIndexBuffer); } void lcViewSphere::Draw() { UpdateSettings(); if (!mSize || !mEnabled) return; lcContext* Context = mView->mContext; const int Width = mView->GetWidth(); const int Height = mView->GetHeight(); const int ViewportSize = mSize; const int Left = (mLocation == lcViewSphereLocation::BottomLeft || mLocation == lcViewSphereLocation::TopLeft) ? 0 : Width - ViewportSize; const int Bottom = (mLocation == lcViewSphereLocation::BottomLeft || mLocation == lcViewSphereLocation::BottomRight) ? 0 : Height - ViewportSize; Context->SetViewport(Left, Bottom, ViewportSize, ViewportSize); Context->SetDepthFunction(lcDepthFunction::Always); Context->EnableCullFace(true); Context->SetVertexBuffer(mVertexBuffer); Context->SetVertexFormatPosition(3); Context->SetIndexBuffer(mIndexBuffer); Context->SetMaterial(lcMaterialType::UnlitColor); Context->SetColor(lcVector4(0.0f, 0.0f, 0.0f, 1.0f)); float Scale = 1.005f + 2.0f / (float)ViewportSize; Context->SetWorldMatrix(lcMatrix44Scale(lcVector3(Scale, Scale, Scale))); Context->SetViewMatrix(GetViewMatrix()); Context->SetProjectionMatrix(GetProjectionMatrix()); Context->DrawIndexedPrimitives(GL_TRIANGLES, mSubdivisions * mSubdivisions * 6 * 6, GL_UNSIGNED_SHORT, 0); Context->SetMaterial(lcMaterialType::UnlitViewSphere); Context->BindTextureCubeMap(mTexture); Context->SetWorldMatrix(lcMatrix44Identity()); Context->SetViewMatrix(GetViewMatrix()); Context->SetProjectionMatrix(GetProjectionMatrix()); lcVector4 HighlightPosition(0.0f, 0.0f, 0.0f, 0.0f); if (mIntersectionFlags.any()) { for (int AxisIdx = 0; AxisIdx < 3; AxisIdx++) { if (mIntersectionFlags.test(2 * AxisIdx)) HighlightPosition[AxisIdx] = 1.0f; else if (mIntersectionFlags.test(2 * AxisIdx + 1)) HighlightPosition[AxisIdx] = -1.0f; } HighlightPosition = lcVector4(lcNormalize(lcVector3(HighlightPosition)), mHighlightRadius); } const lcPreferences& Preferences = lcGetPreferences(); const lcVector4 TextColor = lcVector4FromColor(Preferences.mViewSphereTextColor); const lcVector4 BackgroundColor = lcVector4FromColor(Preferences.mViewSphereColor); const lcVector4 HighlightColor = lcVector4FromColor(Preferences.mViewSphereHighlightColor); Context->SetHighlightParams(HighlightPosition, TextColor, BackgroundColor, HighlightColor); Context->DrawIndexedPrimitives(GL_TRIANGLES, mSubdivisions * mSubdivisions * 6 * 6, GL_UNSIGNED_SHORT, 0); Context->EnableCullFace(false); Context->SetDepthFunction(lcDepthFunction::LessEqual); Context->SetViewport(0, 0, Width, Height); } bool lcViewSphere::OnLeftButtonDown() { if (!mSize || !mEnabled) return false; mIntersectionFlags = GetIntersectionFlags(mIntersection); if (!mIntersectionFlags.any()) return false; mMouseDownX = mView->GetMouseX(); mMouseDownY = mView->GetMouseY(); mMouseDown = true; return true; } bool lcViewSphere::OnLeftButtonUp() { if (!mSize || !mEnabled) return false; if (!mMouseDown) return false; mMouseDown = false; if (!mIntersectionFlags.any()) return false; lcVector3 Position(0.0f, 0.0f, 0.0f); for (int AxisIdx = 0; AxisIdx < 3; AxisIdx++) { if (mIntersectionFlags.test(AxisIdx * 2)) Position[AxisIdx] = 1250.0f; else if (mIntersectionFlags.test(AxisIdx * 2 + 1)) Position[AxisIdx] = -1250.0f; } mView->SetViewpoint(Position); return true; } bool lcViewSphere::OnMouseMove() { if (!mSize || !mEnabled) return false; if (IsDragging()) { mIntersectionFlags.reset(); mView->StartOrbitTracking(); return true; } if (mView->IsTracking()) return false; std::bitset<6> IntersectionFlags = GetIntersectionFlags(mIntersection); if (IntersectionFlags != mIntersectionFlags) { mIntersectionFlags = IntersectionFlags; mView->Redraw(); } return mIntersectionFlags.any(); } bool lcViewSphere::IsDragging() const { int InputStateX = mView->GetMouseX(); int InputStateY = mView->GetMouseY(); return mMouseDown && (qAbs(mMouseDownX - InputStateX) > 3 || qAbs(mMouseDownY - InputStateY) > 3); } std::bitset<6> lcViewSphere::GetIntersectionFlags(lcVector3& Intersection) const { const int Width = mView->GetWidth(); const int Height = mView->GetHeight(); const int ViewportSize = mSize; const int Left = (mLocation == lcViewSphereLocation::BottomLeft || mLocation == lcViewSphereLocation::TopLeft) ? 0 : Width - ViewportSize; const int Bottom = (mLocation == lcViewSphereLocation::BottomLeft || mLocation == lcViewSphereLocation::BottomRight) ? 0 : Height - ViewportSize; const int x = mView->GetMouseX() - Left; const int y = mView->GetMouseY() - Bottom; std::bitset<6> IntersectionFlags; if (x < 0 || x > Width || y < 0 || y > Height) return IntersectionFlags; lcVector3 StartEnd[2] = { lcVector3(x, y, 0), lcVector3(x, y, 1) }; const int Viewport[4] = { 0, 0, ViewportSize, ViewportSize }; lcUnprojectPoints(StartEnd, 2, GetViewMatrix(), GetProjectionMatrix(), Viewport); float Distance; if (lcSphereRayMinIntersectDistance(lcVector3(0.0f, 0.0f, 0.0f), mRadius, StartEnd[0], StartEnd[1], &Distance)) { Intersection = (StartEnd[0] + (StartEnd[1] - StartEnd[0]) * Distance) / mRadius; auto CheckIntersection = [&]() { for (int Axis1Idx = 0; Axis1Idx < 6; Axis1Idx++) { lcVector3 Point1(0.0f, 0.0f, 0.0f); Point1[Axis1Idx / 2] = Axis1Idx % 2 ? -1.0f : 1.0f; if (lcLengthSquared(Point1 - Intersection) < mHighlightRadius * mHighlightRadius) { IntersectionFlags.set(Axis1Idx); return; } for (int Axis2Idx = 0; Axis2Idx < 6; Axis2Idx++) { if (Axis1Idx / 2 == Axis2Idx / 2) continue; lcVector3 Point2(0.0f, 0.0f, 0.0f); Point2[Axis1Idx / 2] = Axis1Idx % 2 ? -0.70710678118f : 0.70710678118f; Point2[Axis2Idx / 2] = Axis2Idx % 2 ? -0.70710678118f : 0.70710678118f; if (lcLengthSquared(Point2 - Intersection) < mHighlightRadius * mHighlightRadius) { IntersectionFlags.set(Axis1Idx); IntersectionFlags.set(Axis2Idx); return; } for (int Axis3Idx = 0; Axis3Idx < 6; Axis3Idx++) { if (Axis1Idx / 2 == Axis3Idx / 2 || Axis2Idx / 2 == Axis3Idx / 2) continue; lcVector3 Point3(0.0f, 0.0f, 0.0f); Point3[Axis1Idx / 2] = Axis1Idx % 2 ? -0.57735026919f : 0.57735026919f; Point3[Axis2Idx / 2] = Axis2Idx % 2 ? -0.57735026919f : 0.57735026919f; Point3[Axis3Idx / 2] = Axis3Idx % 2 ? -0.57735026919f : 0.57735026919f; if (lcLengthSquared(Point3 - Intersection) < mHighlightRadius * mHighlightRadius) { IntersectionFlags.set(Axis1Idx); IntersectionFlags.set(Axis2Idx); IntersectionFlags.set(Axis3Idx); return; } } } } }; CheckIntersection(); } return IntersectionFlags; } leocad-23.03/common/lc_viewsphere.h000066400000000000000000000021111440571307300172470ustar00rootroot00000000000000#pragma once #include "lc_math.h" #include "lc_context.h" #include enum class lcViewSphereLocation { TopLeft, TopRight, BottomLeft, BottomRight }; class lcViewSphere { public: lcViewSphere(lcView* View); void Draw(); bool OnMouseMove(); bool OnLeftButtonUp(); bool OnLeftButtonDown(); bool IsDragging() const; static void CreateResources(lcContext* Context); static void DestroyResources(lcContext* Context); protected: void UpdateSettings(); lcMatrix44 GetViewMatrix() const; lcMatrix44 GetProjectionMatrix() const; std::bitset<6> GetIntersectionFlags(lcVector3& Intersection) const; lcView* const mView = nullptr; int mSize = 1; bool mEnabled = false; lcViewSphereLocation mLocation = lcViewSphereLocation::TopRight; int mMouseDownX = 0; int mMouseDownY = 0; bool mMouseDown = false; lcVector3 mIntersection; std::bitset<6> mIntersectionFlags; static lcTexture* mTexture; static lcVertexBuffer mVertexBuffer; static lcIndexBuffer mIndexBuffer; static const float mRadius; static const float mHighlightRadius; static const int mSubdivisions; }; leocad-23.03/common/lc_viewwidget.cpp000066400000000000000000000160161440571307300176100ustar00rootroot00000000000000#include "lc_global.h" #include "lc_viewwidget.h" #include "lc_glextensions.h" #include "project.h" #include "lc_library.h" #include "lc_application.h" #include "lc_mainwindow.h" #include "lc_context.h" #include "lc_view.h" #include "lc_texture.h" #include "lc_mesh.h" #include "lc_profile.h" #include "lc_previewwidget.h" lcViewWidget::lcViewWidget(QWidget* Parent, lcView* View) : QOpenGLWidget(Parent), mView(View) { mView->SetWidget(this); setMouseTracking(true); if (View->GetViewType() == lcViewType::View) { setFocusPolicy(Qt::StrongFocus); setAcceptDrops(true); } } lcViewWidget::~lcViewWidget() { } QSize lcViewWidget::sizeHint() const { return mPreferredSize.isEmpty() ? QOpenGLWidget::sizeHint() : mPreferredSize; } lcView* lcViewWidget::GetView() const { return mView.get(); } void lcViewWidget::SetView(lcView* View) { if (View) { if (context()) { makeCurrent(); View->mContext->SetGLContext(context(), this); } View->SetWidget(this); const float Scale = GetDeviceScale(); View->SetSize(width() * Scale, height() * Scale); if (hasFocus()) View->SetFocus(true); } mView = std::unique_ptr(View); } void lcViewWidget::initializeGL() { mView->mContext->SetGLContext(context(), this); } void lcViewWidget::resizeGL(int Width, int Height) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) const float Scale = devicePixelRatioF(); #else const int Scale = devicePixelRatio(); #endif mView->SetSize(Width * Scale, Height * Scale); } void lcViewWidget::paintGL() { mView->OnDraw(); } void lcViewWidget::focusInEvent(QFocusEvent* FocusEvent) { if (mView) mView->SetFocus(true); QOpenGLWidget::focusInEvent(FocusEvent); } void lcViewWidget::focusOutEvent(QFocusEvent* FocusEvent) { if (mView) mView->SetFocus(false); QOpenGLWidget::focusOutEvent(FocusEvent); } void lcViewWidget::keyPressEvent(QKeyEvent* KeyEvent) { if (KeyEvent->key() == Qt::Key_Control || KeyEvent->key() == Qt::Key_Shift) { mView->SetMouseModifiers(KeyEvent->modifiers()); mView->UpdateCursor(); } QOpenGLWidget::keyPressEvent(KeyEvent); } void lcViewWidget::keyReleaseEvent(QKeyEvent* KeyEvent) { if (KeyEvent->key() == Qt::Key_Control || KeyEvent->key() == Qt::Key_Shift) { mView->SetMouseModifiers(KeyEvent->modifiers()); mView->UpdateCursor(); } QOpenGLWidget::keyReleaseEvent(KeyEvent); } void lcViewWidget::mousePressEvent(QMouseEvent* MouseEvent) { float DeviceScale = GetDeviceScale(); mView->SetMousePosition(MouseEvent->x() * DeviceScale, mView->GetHeight() - MouseEvent->y() * DeviceScale - 1); mView->SetMouseModifiers(MouseEvent->modifiers()); switch (MouseEvent->button()) { case Qt::LeftButton: mView->OnLeftButtonDown(); break; case Qt::MiddleButton: mView->OnMiddleButtonDown(); break; case Qt::RightButton: mView->OnRightButtonDown(); break; case Qt::BackButton: mView->OnBackButtonDown(); break; case Qt::ForwardButton: mView->OnForwardButtonDown(); break; default: break; } } void lcViewWidget::mouseReleaseEvent(QMouseEvent* MouseEvent) { float DeviceScale = GetDeviceScale(); mView->SetMousePosition(MouseEvent->x() * DeviceScale, mView->GetHeight() - MouseEvent->y() * DeviceScale - 1); mView->SetMouseModifiers(MouseEvent->modifiers()); switch (MouseEvent->button()) { case Qt::LeftButton: mView->OnLeftButtonUp(); break; case Qt::MiddleButton: mView->OnMiddleButtonUp(); break; case Qt::RightButton: mView->OnRightButtonUp(); break; case Qt::BackButton: mView->OnBackButtonUp(); break; case Qt::ForwardButton: mView->OnForwardButtonUp(); break; default: break; } } void lcViewWidget::mouseDoubleClickEvent(QMouseEvent* MouseEvent) { float DeviceScale = GetDeviceScale(); mView->SetMousePosition(MouseEvent->x() * DeviceScale, mView->GetHeight() - MouseEvent->y() * DeviceScale - 1); mView->SetMouseModifiers(MouseEvent->modifiers()); switch (MouseEvent->button()) { case Qt::LeftButton: mView->OnLeftButtonDoubleClick(); break; default: break; } } void lcViewWidget::mouseMoveEvent(QMouseEvent* MouseEvent) { float DeviceScale = GetDeviceScale(); mView->SetMousePosition(MouseEvent->x() * DeviceScale, mView->GetHeight() - MouseEvent->y() * DeviceScale - 1); mView->SetMouseModifiers(MouseEvent->modifiers()); mView->OnMouseMove(); } void lcViewWidget::wheelEvent(QWheelEvent* WheelEvent) { if (WheelEvent->source() == Qt::MouseEventSynthesizedBySystem) { switch (WheelEvent->phase()) { case Qt::NoScrollPhase: break; case Qt::ScrollBegin: mView->StartPanGesture(); WheelEvent->accept(); return; case Qt::ScrollUpdate: #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) case Qt::ScrollMomentum: #endif mView->UpdatePanGesture(WheelEvent->pixelDelta().x(), -WheelEvent->pixelDelta().y()); WheelEvent->accept(); return; case Qt::ScrollEnd: mView->EndPanGesture(true); WheelEvent->accept(); return; } } if (WheelEvent->angleDelta().y() == 0) { WheelEvent->ignore(); return; } float DeviceScale = GetDeviceScale(); #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) mView->SetMousePosition(WheelEvent->position().x() * DeviceScale, mView->GetHeight() - WheelEvent->position().y() * DeviceScale - 1); #else mView->SetMousePosition(WheelEvent->x() * DeviceScale, mView->GetHeight() - WheelEvent->y() * DeviceScale - 1); #endif mView->SetMouseModifiers(WheelEvent->modifiers()); mWheelAccumulator += WheelEvent->angleDelta().y(); int Steps = mWheelAccumulator / 8; if (Steps) { mView->OnMouseWheel(Steps / 15); mWheelAccumulator -= Steps * 8; } WheelEvent->accept(); } void lcViewWidget::dragEnterEvent(QDragEnterEvent* DragEnterEvent) { const QMimeData* MimeData = DragEnterEvent->mimeData(); if (MimeData->hasFormat("application/vnd.leocad-part")) { DragEnterEvent->acceptProposedAction(); mView->BeginDrag(lcDragState::Piece); return; } else if (MimeData->hasFormat("application/vnd.leocad-color")) { DragEnterEvent->acceptProposedAction(); mView->BeginDrag(lcDragState::Color); return; } DragEnterEvent->ignore(); } void lcViewWidget::dragLeaveEvent(QDragLeaveEvent* DragLeaveEvent) { mView->EndDrag(false); DragLeaveEvent->accept(); } void lcViewWidget::dragMoveEvent(QDragMoveEvent* DragMoveEvent) { const QMimeData* MimeData = DragMoveEvent->mimeData(); if (MimeData->hasFormat("application/vnd.leocad-part") || MimeData->hasFormat("application/vnd.leocad-color")) { float DeviceScale = GetDeviceScale(); mView->SetMousePosition(DragMoveEvent->pos().x() * DeviceScale, mView->GetHeight() - DragMoveEvent->pos().y() * DeviceScale - 1); mView->SetMouseModifiers(DragMoveEvent->keyboardModifiers()); mView->OnMouseMove(); DragMoveEvent->accept(); return; } QOpenGLWidget::dragMoveEvent(DragMoveEvent); } void lcViewWidget::dropEvent(QDropEvent* DropEvent) { const QMimeData* MimeData = DropEvent->mimeData(); if (MimeData->hasFormat("application/vnd.leocad-part") || MimeData->hasFormat("application/vnd.leocad-color")) { mView->EndDrag(true); setFocus(Qt::MouseFocusReason); DropEvent->accept(); return; } QOpenGLWidget::dropEvent(DropEvent); } leocad-23.03/common/lc_viewwidget.h000066400000000000000000000024611440571307300172540ustar00rootroot00000000000000#pragma once class lcViewWidget : public QOpenGLWidget { Q_OBJECT public: lcViewWidget(QWidget* Parent, lcView* View); ~lcViewWidget(); lcView* GetView() const; void SetView(lcView* View); QSize sizeHint() const override; protected: float GetDeviceScale() const { #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) return devicePixelRatioF(); #else return devicePixelRatio(); #endif } void initializeGL() override; void resizeGL(int Width, int Height) override; void paintGL() override; void focusInEvent(QFocusEvent* FocusEvent) override; void focusOutEvent(QFocusEvent* FocusEvent) override; void keyPressEvent(QKeyEvent* KeyEvent) override; void keyReleaseEvent(QKeyEvent* KeyEvent) override; void mousePressEvent(QMouseEvent* MouseEvent) override; void mouseReleaseEvent(QMouseEvent* MouseEvent) override; void mouseDoubleClickEvent(QMouseEvent* MouseEvent) override; void mouseMoveEvent(QMouseEvent* MouseEvent) override; void wheelEvent(QWheelEvent* WheelEvent) override; void dragEnterEvent(QDragEnterEvent* DragEnterEvent) override; void dragLeaveEvent(QDragLeaveEvent* DragLeaveEvent) override; void dragMoveEvent(QDragMoveEvent* DragMoveEvent) override; void dropEvent(QDropEvent* DropEvent) override; std::unique_ptr mView; QSize mPreferredSize; int mWheelAccumulator = 0; }; leocad-23.03/common/lc_zipfile.cpp000066400000000000000000000411311440571307300170700ustar00rootroot00000000000000#include "lc_global.h" #include "lc_zipfile.h" #include "lc_file.h" #include "lc_math.h" #include #include #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif lcZipFile::lcZipFile() { mModified = false; } lcZipFile::~lcZipFile() { } bool lcZipFile::OpenRead(const QString& FileName) { std::unique_ptr File(new lcDiskFile(FileName)); if (!File->Open(QIODevice::ReadOnly)) return false; return OpenRead(std::move(File)); } bool lcZipFile::OpenRead(std::unique_ptr File) { mFile = std::move(File); if (!Open()) { mFile = nullptr; return false; } return true; } bool lcZipFile::OpenWrite(const QString& FileName) { std::unique_ptr File(new lcDiskFile(FileName)); if (!File->Open(QIODevice::WriteOnly)) return false; mFile = std::move(File); mNumEntries = 0; mCentralDirSize = 0; mCentralDirOffset = 0; mBytesBeforeZipFile = 0; mCentralPos = 0; return true; } quint64 lcZipFile::SearchCentralDir() { quint64 SizeFile, MaxBack, BackRead, PosFound; constexpr int CommentBufferSize = 1024; quint8 buf[CommentBufferSize + 4]; SizeFile = mFile->GetLength(); MaxBack = lcMin(SizeFile, 0xffffULL); BackRead = 4; PosFound = 0; while (BackRead < MaxBack) { quint64 ReadPos, ReadSize; if (BackRead + CommentBufferSize > MaxBack) BackRead = MaxBack; else BackRead += CommentBufferSize; ReadPos = SizeFile - BackRead; ReadSize = ((CommentBufferSize + 4) < (SizeFile - ReadPos)) ? (CommentBufferSize + 4) : (SizeFile - ReadPos); mFile->Seek(ReadPos, SEEK_SET); if (mFile->ReadBuffer(buf, (long)ReadSize) != ReadSize) break; for (int i = (int)ReadSize - 3; (i--) > 0;) { if (((*(buf+i)) == 0x50) && ((*(buf+i+1)) == 0x4b) && ((*(buf+i+2)) == 0x05) && ((*(buf+i+3)) == 0x06)) { PosFound = ReadPos + i; break; } } if (PosFound != 0) break; } return PosFound; } quint64 lcZipFile::SearchCentralDir64() { quint64 SizeFile, MaxBack, BackRead, PosFound; const int CommentBufferSize = 1024; quint8 buf[CommentBufferSize + 4]; SizeFile = mFile->GetLength(); MaxBack = lcMin(SizeFile, 0xffffULL); BackRead = 4; PosFound = 0; while (BackRead < MaxBack) { quint64 ReadPos, ReadSize; if (BackRead + CommentBufferSize > MaxBack) BackRead = MaxBack; else BackRead += CommentBufferSize; ReadPos = SizeFile - BackRead; ReadSize = ((CommentBufferSize + 4) < (SizeFile - ReadPos)) ? (CommentBufferSize + 4) : (SizeFile - ReadPos); mFile->Seek(ReadPos, SEEK_SET); if (mFile->ReadBuffer(buf, (long)ReadSize) != ReadSize) break; for (int i=(int)ReadSize - 3; (i--) > 0; ) { if (((*(buf+i)) == 0x50) && ((*(buf+i+1)) == 0x4b) && ((*(buf+i+2)) == 0x06) && ((*(buf+i+3)) == 0x07)) { PosFound = ReadPos + i; break; } } if (PosFound != 0) break; } if (PosFound == 0) return 0; mFile->Seek(PosFound, SEEK_SET); quint32 Number; quint64 RelativeOffset; // Signature. if (mFile->ReadU32(&Number, 1) != 1) return 0; // Number of the disk with the start of the zip64 end of central directory. if (mFile->ReadU32(&Number, 1) != 1) return 0; if (Number != 0) return 0; // Relative offset of the zip64 end of central directory record. if (mFile->ReadU64(&RelativeOffset, 1) != 1) return 0; // Total number of disks. if (mFile->ReadU32(&Number, 1) != 1) return 0; if (Number != 0) return 0; // Go to end of central directory record. mFile->Seek(RelativeOffset, SEEK_SET); // The signature. if (mFile->ReadU32(&Number, 1) != 1) return 0; if (Number != 0x06064b50) return 0; return RelativeOffset; } bool lcZipFile::CheckFileCoherencyHeader(int FileIndex, quint32* SizeVar, quint64* OffsetLocalExtraField, quint32* SizeLocalExtraField) { quint16 Number16, Flags; quint32 Number32, Magic; quint16 SizeFilename, SizeExtraField; const lcZipFileInfo& FileInfo = mFiles[FileIndex]; *SizeVar = 0; *OffsetLocalExtraField = 0; *SizeLocalExtraField = 0; mFile->Seek(FileInfo.offset_curfile + mBytesBeforeZipFile, SEEK_SET); if (mFile->ReadU32(&Magic, 1) != 1 || Magic != 0x04034b50) return false; if (mFile->ReadU16(&Number16, 1) != 1) return false; if (mFile->ReadU16(&Flags, 1) != 1) return false; if (mFile->ReadU16(&Number16, 1) != 1 || Number16 != FileInfo.compression_method) return false; if (FileInfo.compression_method != 0 && FileInfo.compression_method != Z_DEFLATED) return false; if (mFile->ReadU32(&Number32, 1) != 1) return false; if (mFile->ReadU32(&Number32, 1) != 1 || ((Number32 != FileInfo.crc) && ((Flags & 8)==0))) return false; if (mFile->ReadU32(&Number32, 1) != 1 || (Number32 != 0xffffffffU && (Number32 != FileInfo.compressed_size) && ((Flags & 8)==0))) return false; if (mFile->ReadU32(&Number32, 1) != 1 || (Number32 != 0xffffffffU && (Number32 != FileInfo.uncompressed_size) && ((Flags & 8)==0))) return false; if (mFile->ReadU16(&SizeFilename, 1) != 1 || SizeFilename != FileInfo.size_filename) return false; *SizeVar += SizeFilename; if (mFile->ReadU16(&SizeExtraField, 1) != 1) return false; *OffsetLocalExtraField= FileInfo.offset_curfile + 0x1e + SizeFilename; *SizeLocalExtraField = SizeExtraField; *SizeVar += SizeExtraField; return true; } bool lcZipFile::Open() { quint64 NumberEntriesCD, CentralPos; CentralPos = SearchCentralDir64(); if (CentralPos) { quint32 NumberDisk, NumberDiskWithCD; mZip64 = true; // Skip signature, size and versions. mFile->Seek(CentralPos + 4 + 8 + 2 + 2, SEEK_SET); // Number of this disk. if (mFile->ReadU32(&NumberDisk, 1) != 1) return false; // Number of the disk with the start of the central directory. if (mFile->ReadU32(&NumberDiskWithCD, 1) != 1) return false; // Total number of entries in the central directory on this disk. if (mFile->ReadU64(&mNumEntries, 1) != 1) return false; // Total number of entries in the central directory. if (mFile->ReadU64(&NumberEntriesCD, 1) != 1) return false; if ((NumberEntriesCD != mNumEntries) || (NumberDiskWithCD != 0) || (NumberDisk != 0)) return false; // Size of the central directory. if (mFile->ReadU64(&mCentralDirSize, 1) != 1) return false; // Offset of start of central directory with respect to the starting disk number. if (mFile->ReadU64(&mCentralDirOffset, 1) != 1) return false; // us.gi.size_comment = 0; } else { quint16 NumberDisk, NumberDiskWithCD; quint16 Number16; quint32 Number32; CentralPos = SearchCentralDir(); if (CentralPos == 0) return false; mZip64 = false; // Skip signature. mFile->Seek(CentralPos + 4, SEEK_SET); // Number of this disk. if (mFile->ReadU16(&NumberDisk, 1) != 1) return false; // Number of the disk with the start of the central directory. if (mFile->ReadU16(&NumberDiskWithCD, 1) != 1) return false; // Total number of entries in the central dir on this disk. if (mFile->ReadU16(&Number16, 1) != 1) return false; mNumEntries = Number16; // Total number of entries in the central dir. if (mFile->ReadU16(&Number16, 1) != 1) return false; NumberEntriesCD = Number16; if ((NumberEntriesCD != mNumEntries) || (NumberDiskWithCD != 0) || (NumberDisk != 0)) return false; // Size of the central directory. if (mFile->ReadU32(&Number32, 1) != 1) return false; mCentralDirSize = Number32; // Offset of start of central directory with respect to the starting disk number. if (mFile->ReadU32(&Number32, 1) != 1) return false; mCentralDirOffset= Number32; // zipfile comment length. // if (mFile->ReadU16(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=1) // return false; } if (CentralPos < mCentralDirOffset + mCentralDirSize) return false; mBytesBeforeZipFile = CentralPos - (mCentralDirOffset + mCentralDirSize); mCentralPos = CentralPos; return ReadCentralDir(); } bool lcZipFile::ReadCentralDir() { quint64 PosInCentralDir = mCentralDirOffset; mFile->Seek(PosInCentralDir + mBytesBeforeZipFile, SEEK_SET); mFiles.AllocGrow((int)mNumEntries); for (quint64 FileNum = 0; FileNum < mNumEntries; FileNum++) { quint32 Magic, Number32; lcZipFileInfo& FileInfo = mFiles.Add(); long Seek = 0; FileInfo.write_buffer = nullptr; FileInfo.deleted = false; if (mFile->ReadU32(&Magic, 1) != 1 || Magic != 0x02014b50) return false; if (mFile->ReadU16(&FileInfo.version, 1) != 1) return false; if (mFile->ReadU16(&FileInfo.version_needed, 1) != 1) return false; if (mFile->ReadU16(&FileInfo.flag, 1) != 1) return false; if (mFile->ReadU16(&FileInfo.compression_method, 1) != 1) return false; if (mFile->ReadU32(&FileInfo.dosDate, 1) != 1) return false; quint32 Date = FileInfo.dosDate >> 16; FileInfo.tmu_date.tm_mday = (quint32)(Date & 0x1f); FileInfo.tmu_date.tm_mon = (quint32)((((Date) & 0x1E0) / 0x20) - 1); FileInfo.tmu_date.tm_year = (quint32)(((Date & 0x0FE00) / 0x0200) + 1980); FileInfo.tmu_date.tm_hour = (quint32)((FileInfo.dosDate & 0xF800) / 0x800); FileInfo.tmu_date.tm_min = (quint32)((FileInfo.dosDate & 0x7E0) / 0x20); FileInfo.tmu_date.tm_sec = (quint32)(2*(FileInfo.dosDate & 0x1f)); if (mFile->ReadU32(&FileInfo.crc, 1) != 1) return false; if (mFile->ReadU32(&Number32, 1) != 1) return false; FileInfo.compressed_size = Number32; if (mFile->ReadU32(&Number32, 1) != 1) return false; FileInfo.uncompressed_size = Number32; if (mFile->ReadU16(&FileInfo.size_filename, 1) != 1) return false; if (mFile->ReadU16(&FileInfo.size_file_extra, 1) != 1) return false; if (mFile->ReadU16(&FileInfo.size_file_comment, 1) != 1) return false; if (mFile->ReadU16(&FileInfo.disk_num_start, 1) != 1) return false; if (mFile->ReadU16(&FileInfo.internal_fa, 1) != 1) return false; if (mFile->ReadU32(&FileInfo.external_fa, 1) != 1) return false; // relative offset of local header if (mFile->ReadU32(&Number32, 1) != 1) return false; FileInfo.offset_curfile = Number32; Seek += FileInfo.size_filename; quint32 SizeRead; if (FileInfo.size_filename < sizeof(FileInfo.file_name) - 1) { *(FileInfo.file_name + FileInfo.size_filename) = '\0'; SizeRead = FileInfo.size_filename; } else { *(FileInfo.file_name + sizeof(FileInfo.file_name) - 1) = '\0'; SizeRead = sizeof(FileInfo.file_name) - 1; } if (FileInfo.size_filename > 0) if (mFile->ReadBuffer(FileInfo.file_name, SizeRead) != SizeRead) return false; Seek -= SizeRead; /* // Read extrafield if ((err==UNZ_OK) && (extraField!=nullptr)) { ZPOS64_T uSizeRead ; if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) lSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) err=UNZ_ERRNO; lSeek += file_info.size_file_extra - (uLong)uSizeRead; } else lSeek += file_info.size_file_extra; */ Seek += FileInfo.size_file_extra; if (FileInfo.size_file_extra != 0) { quint32 acc = 0; // since lSeek now points to after the extra field we need to move back Seek -= FileInfo.size_file_extra; if (Seek != 0) { mFile->Seek(Seek, SEEK_CUR); Seek = 0; } while (acc < FileInfo.size_file_extra) { quint16 HeaderId, DataSize; if (mFile->ReadU16(&HeaderId, 1) != 1) return false; if (mFile->ReadU16(&DataSize, 1) != 1) return false; // ZIP64 extra fields. if (HeaderId == 0x0001) { if (FileInfo.uncompressed_size == (quint64)(unsigned long)-1) { if (mFile->ReadU64(&FileInfo.uncompressed_size, 1) != 1) return false; } if (FileInfo.compressed_size == (quint64)(unsigned long)-1) { if (mFile->ReadU64(&FileInfo.compressed_size, 1) != 1) return false; } if (FileInfo.offset_curfile == (quint64)-1) { // Relative Header offset. if (mFile->ReadU64(&FileInfo.offset_curfile, 1) != 1) return false; } if (FileInfo.disk_num_start == (quint16)-1) { // Disk Start Number. if (mFile->ReadU32(&Number32, 1) != 1) return false; } } else { mFile->Seek(DataSize, SEEK_CUR); } acc += 2 + 2 + DataSize; } } /* if ((err==UNZ_OK) && (szComment!=nullptr)) { uLong uSizeRead ; if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) lSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_comment>0) && (commentBufferSize>0)) if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) err=UNZ_ERRNO; lSeek+=file_info.size_file_comment - uSizeRead; } else lSeek+=file_info.size_file_comment; */ Seek += FileInfo.size_file_comment; mFile->Seek(Seek, SEEK_CUR); } return true; } bool lcZipFile::ExtractFile(const char* FileName, lcMemFile& File, quint32 MaxLength) { for (int FileIdx = 0; FileIdx < mFiles.GetSize(); FileIdx++) { lcZipFileInfo& FileInfo = mFiles[FileIdx]; if (!qstricmp(FileInfo.file_name, FileName)) return ExtractFile(FileIdx, File, MaxLength); } return false; } bool lcZipFile::ExtractFile(int FileIndex, lcMemFile& File, quint32 MaxLength) { QMutexLocker Lock(&mMutex); quint32 SizeVar; quint64 OffsetLocalExtraField; quint32 SizeLocalExtraField; const lcZipFileInfo& FileInfo = mFiles[FileIndex]; if (!CheckFileCoherencyHeader(FileIndex, &SizeVar, &OffsetLocalExtraField, &SizeLocalExtraField)) return false; const int BufferSize = 16384; char ReadBuffer[BufferSize]; z_stream Stream; quint32 Crc32; quint64 PosInZipfile; quint64 RestReadCompressed; quint64 RestReadUncompressed; Crc32 = 0; Stream.total_out = 0; if (FileInfo.compression_method == Z_DEFLATED) { Stream.zalloc = (alloc_func)0; Stream.zfree = (free_func)0; Stream.opaque = (voidpf)0; Stream.next_in = 0; Stream.avail_in = 0; int err = inflateInit2(&Stream, -MAX_WBITS); if (err != Z_OK) return false; } RestReadCompressed = FileInfo.compressed_size; RestReadUncompressed = FileInfo.uncompressed_size; PosInZipfile = FileInfo.offset_curfile + 0x1e + SizeVar; Stream.avail_in = (uInt)0; quint32 Length = lcMin((quint32)FileInfo.uncompressed_size, MaxLength); File.SetLength(Length); File.Seek(0, SEEK_SET); Stream.next_in = (Bytef*)ReadBuffer; Stream.next_out = (Bytef*)File.mBuffer; Stream.avail_out = Length; quint32 Read = 0; while (Stream.avail_out > 0) { if ((Stream.avail_in == 0) && (RestReadCompressed > 0)) { quint32 ReadThis = BufferSize; if (RestReadCompressed < ReadThis) ReadThis = (quint32)RestReadCompressed; if (ReadThis == 0) return false; mFile->Seek(PosInZipfile + mBytesBeforeZipFile, SEEK_SET); if (mFile->ReadBuffer(ReadBuffer, ReadThis) != ReadThis) return false; PosInZipfile += ReadThis; RestReadCompressed -= ReadThis; Stream.next_in = (Bytef*)ReadBuffer; Stream.avail_in = (uInt)ReadThis; } if (FileInfo.compression_method == 0) { quint32 DoCopy, i; if ((Stream.avail_in == 0) && (RestReadCompressed == 0)) return (Read == 0) ? false : true; if (Stream.avail_out < Stream.avail_in) DoCopy = Stream.avail_out; else DoCopy = Stream.avail_in; for (i = 0; i < DoCopy; i++) *(Stream.next_out+i) = *(Stream.next_in+i); Crc32 = crc32(Crc32, Stream.next_out, DoCopy); RestReadUncompressed -= DoCopy; Stream.avail_in -= DoCopy; Stream.avail_out -= DoCopy; Stream.next_out += DoCopy; Stream.next_in += DoCopy; Stream.total_out += DoCopy; Read += DoCopy; } else { quint64 TotalOutBefore, TotalOutAfter; const Bytef *bufBefore; quint64 OutThis; int flush = Z_SYNC_FLUSH; TotalOutBefore = Stream.total_out; bufBefore = Stream.next_out; int err = inflate(&Stream,flush); if ((err >= 0) && (Stream.msg != nullptr)) err = Z_DATA_ERROR; TotalOutAfter = Stream.total_out; OutThis = TotalOutAfter - TotalOutBefore; Crc32 = crc32(Crc32, bufBefore, (uInt)(OutThis)); RestReadUncompressed -= OutThis; Read += (uInt)(TotalOutAfter - TotalOutBefore); if (err != Z_OK) { inflateEnd(&Stream); if (RestReadUncompressed == 0) { if (Crc32 != FileInfo.crc) return false; } if (err == Z_STREAM_END) return (Read == 0) ? false : true; return false; } } } if (FileInfo.compression_method == Z_DEFLATED) inflateEnd(&Stream); return true; } leocad-23.03/common/lc_zipfile.h000066400000000000000000000053221440571307300165370ustar00rootroot00000000000000#pragma once #include "lc_array.h" #ifdef DeleteFile #undef DeleteFile #endif class lcFile; // Date/time info. struct tm_unz { quint32 tm_sec; // seconds after the minute - [0,59] quint32 tm_min; // minutes after the hour - [0,59] quint32 tm_hour; // hours since midnight - [0,23] quint32 tm_mday; // day of the month - [1,31] quint32 tm_mon; // months since January - [0,11] quint32 tm_year; // years - [1980..2044] }; // Information about a file in the zipfile. struct lcZipFileInfo { quint16 version; // version made by 2 bytes quint16 version_needed; // version needed to extract 2 bytes quint16 flag; // general purpose bit flag 2 bytes quint16 compression_method; // compression method 2 bytes quint32 dosDate; // last mod file date in Dos fmt 4 bytes quint32 crc; // crc-32 4 bytes quint64 compressed_size; // compressed size 8 bytes quint64 uncompressed_size; // uncompressed size 8 bytes quint16 size_filename; // filename length 2 bytes quint16 size_file_extra; // extra field length 2 bytes quint16 size_file_comment; // file comment length 2 bytes quint16 disk_num_start; // disk number start 2 bytes quint16 internal_fa; // internal file attributes 2 bytes quint32 external_fa; // external file attributes 4 bytes quint64 offset_curfile; // relative offset of local header 8 bytes char file_name[256]; tm_unz tmu_date; lcMemFile* write_buffer; bool deleted; }; class lcZipFile { public: lcZipFile(); ~lcZipFile(); lcZipFile(const lcZipFile&) = delete; lcZipFile(lcZipFile&&) = delete; lcZipFile& operator=(const lcZipFile&) = delete; lcZipFile& operator=(lcZipFile&&) = delete; bool OpenRead(const QString& FileName); bool OpenRead(std::unique_ptr File); bool OpenWrite(const QString& FileName); bool ExtractFile(int FileIndex, lcMemFile& File, quint32 MaxLength = 0xffffffff); bool ExtractFile(const char* FileName, lcMemFile& File, quint32 MaxLength = 0xffffffff); lcArray mFiles; protected: bool Open(); bool ReadCentralDir(); quint64 SearchCentralDir(); quint64 SearchCentralDir64(); bool CheckFileCoherencyHeader(int FileIndex, quint32* SizeVar, quint64* OffsetLocalExtraField, quint32* SizeLocalExtraField); QMutex mMutex; std::unique_ptr mFile; bool mModified; bool mZip64; quint64 mNumEntries; quint64 mCentralDirSize; quint64 mCentralDirOffset; quint64 mBytesBeforeZipFile; quint64 mCentralPos; }; leocad-23.03/common/light.cpp000066400000000000000000000414441440571307300160660ustar00rootroot00000000000000#include "lc_global.h" #include "lc_math.h" #include "lc_colors.h" #include #include #include #include "light.h" #include "lc_application.h" #include "lc_context.h" #define LC_LIGHT_POSITION_EDGE 7.5f #define LC_LIGHT_TARGET_EDGE 5.0f #define LC_LIGHT_SPHERE_RADIUS 5.0f // New omni light. lcLight::lcLight(float px, float py, float pz) : lcObject(lcObjectType::Light) { Initialize(lcVector3(px, py, pz), lcVector3(0.0f, 0.0f, 0.0f)); UpdatePosition(1); } // New directional or spot light. lcLight::lcLight(float px, float py, float pz, float tx, float ty, float tz) : lcObject(lcObjectType::Light) { Initialize(lcVector3(px, py, pz), lcVector3(tx, ty, tz)); mState |= LC_LIGHT_SPOT; UpdatePosition(1); } void lcLight::Initialize(const lcVector3& Position, const lcVector3& TargetPosition) { mState = 0; mPositionKeys.ChangeKey(Position, 1, true); mTargetPositionKeys.ChangeKey(TargetPosition, 1, true); mAmbientColorKeys.ChangeKey(lcVector4(0.0f, 0.0f, 0.0f, 1.0f), 1, true); mDiffuseColorKeys.ChangeKey(lcVector4(0.8f, 0.8f, 0.8f, 1.0f), 1, true); mSpecularColorKeys.ChangeKey(lcVector4(1.0f, 1.0f, 1.0f, 1.0f), 1, true); mAttenuationKeys.ChangeKey(lcVector3(1.0f, 0.0f, 0.0f), 1, true); mSpotCutoffKeys.ChangeKey(30.0f, 1, true); mSpotExponentKeys.ChangeKey(0.0f, 1, true); } lcLight::~lcLight() { } void lcLight::SaveLDraw(QTextStream& Stream) const { Q_UNUSED(Stream); } void lcLight::CreateName(const lcArray& Lights) { if (!mName.isEmpty()) { bool Found = false; for (const lcLight* Light : Lights) { if (Light->GetName() == mName) { Found = true; break; } } if (!Found) return; } int MaxLightNumber = 0; const QLatin1String Prefix("Light "); for (const lcLight* Light : Lights) { QString LightName = Light->GetName(); if (LightName.startsWith(Prefix)) { bool Ok = false; int LightNumber = LightName.mid(Prefix.size()).toInt(&Ok); if (Ok && LightNumber > MaxLightNumber) MaxLightNumber = LightNumber; } } mName = Prefix + QString::number(MaxLightNumber + 1); } void lcLight::CompareBoundingBox(lcVector3& Min, lcVector3& Max) { const lcVector3 Points[2] = { mPosition, mTargetPosition }; for (int i = 0; i < (IsPointLight() ? 1 : 2); i++) { const lcVector3& Point = Points[i]; // TODO: this should check the entire mesh Min = lcMin(Point, Min); Max = lcMax(Point, Max); } } void lcLight::RayTest(lcObjectRayTest& ObjectRayTest) const { if (IsPointLight()) { float Distance; if (lcSphereRayMinIntersectDistance(mPosition, LC_LIGHT_SPHERE_RADIUS, ObjectRayTest.Start, ObjectRayTest.End, &Distance)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_POSITION; ObjectRayTest.Distance = Distance; } return; } lcVector3 Min = lcVector3(-LC_LIGHT_POSITION_EDGE, -LC_LIGHT_POSITION_EDGE, -LC_LIGHT_POSITION_EDGE); lcVector3 Max = lcVector3(LC_LIGHT_POSITION_EDGE, LC_LIGHT_POSITION_EDGE, LC_LIGHT_POSITION_EDGE); lcVector3 Start = lcMul31(ObjectRayTest.Start, mWorldLight); lcVector3 End = lcMul31(ObjectRayTest.End, mWorldLight); float Distance; lcVector3 Plane; if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, nullptr, &Plane) && (Distance < ObjectRayTest.Distance)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_POSITION; ObjectRayTest.Distance = Distance; ObjectRayTest.PieceInfoRayTest.Plane = Plane; } Min = lcVector3(-LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE); Max = lcVector3(LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE); lcMatrix44 WorldTarget = mWorldLight; WorldTarget.SetTranslation(lcMul30(-mTargetPosition, WorldTarget)); Start = lcMul31(ObjectRayTest.Start, WorldTarget); End = lcMul31(ObjectRayTest.End, WorldTarget); if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, nullptr, &Plane) && (Distance < ObjectRayTest.Distance)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_TARGET; ObjectRayTest.Distance = Distance; ObjectRayTest.PieceInfoRayTest.Plane = Plane; } } void lcLight::BoxTest(lcObjectBoxTest& ObjectBoxTest) const { if (IsPointLight()) { for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) if (lcDot3(mPosition, ObjectBoxTest.Planes[PlaneIdx]) + ObjectBoxTest.Planes[PlaneIdx][3] > LC_LIGHT_SPHERE_RADIUS) return; ObjectBoxTest.Objects.Add(const_cast(this)); return; } lcVector3 Min(-LC_LIGHT_POSITION_EDGE, -LC_LIGHT_POSITION_EDGE, -LC_LIGHT_POSITION_EDGE); lcVector3 Max(LC_LIGHT_POSITION_EDGE, LC_LIGHT_POSITION_EDGE, LC_LIGHT_POSITION_EDGE); lcVector4 LocalPlanes[6]; for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) { const lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], mWorldLight); LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(mWorldLight[3], Normal)); } if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes)) { ObjectBoxTest.Objects.Add(const_cast(this)); return; } Min = lcVector3(-LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE, -LC_LIGHT_TARGET_EDGE); Max = lcVector3(LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE, LC_LIGHT_TARGET_EDGE); lcMatrix44 WorldTarget = mWorldLight; WorldTarget.SetTranslation(lcMul30(-mTargetPosition, WorldTarget)); for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) { const lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], WorldTarget); LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(WorldTarget[3], Normal)); } if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes)) { ObjectBoxTest.Objects.Add(const_cast(this)); return; } } void lcLight::MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance) { if (IsSelected(LC_LIGHT_SECTION_POSITION)) { mPosition += Distance; mPositionKeys.ChangeKey(mPosition, Step, AddKey); } if (IsSelected(LC_LIGHT_SECTION_TARGET)) { mTargetPosition += Distance; mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey); } } void lcLight::InsertTime(lcStep Start, lcStep Time) { mPositionKeys.InsertTime(Start, Time); mTargetPositionKeys.InsertTime(Start, Time); mAmbientColorKeys.InsertTime(Start, Time); mDiffuseColorKeys.InsertTime(Start, Time); mSpecularColorKeys.InsertTime(Start, Time); mAttenuationKeys.InsertTime(Start, Time); mSpotCutoffKeys.InsertTime(Start, Time); mSpotExponentKeys.InsertTime(Start, Time); } void lcLight::RemoveTime(lcStep Start, lcStep Time) { mPositionKeys.RemoveTime(Start, Time); mTargetPositionKeys.RemoveTime(Start, Time); mAmbientColorKeys.RemoveTime(Start, Time); mDiffuseColorKeys.RemoveTime(Start, Time); mSpecularColorKeys.RemoveTime(Start, Time); mAttenuationKeys.RemoveTime(Start, Time); mSpotCutoffKeys.RemoveTime(Start, Time); mSpotExponentKeys.RemoveTime(Start, Time); } void lcLight::UpdatePosition(lcStep Step) { mPosition = mPositionKeys.CalculateKey(Step); mTargetPosition = mTargetPositionKeys.CalculateKey(Step); mAmbientColor = mAmbientColorKeys.CalculateKey(Step); mDiffuseColor = mDiffuseColorKeys.CalculateKey(Step); mSpecularColor = mSpecularColorKeys.CalculateKey(Step); mAttenuation = mAttenuationKeys.CalculateKey(Step); mSpotCutoff = mSpotCutoffKeys.CalculateKey(Step); mSpotExponent = mSpotExponentKeys.CalculateKey(Step); if (IsPointLight()) { mWorldLight = lcMatrix44Identity(); mWorldLight.SetTranslation(-mPosition); } else { lcVector3 FrontVector(mTargetPosition - mPosition); lcVector3 UpVector(1, 1, 1); if (fabs(FrontVector[0]) < fabs(FrontVector[1])) { if (fabs(FrontVector[0]) < fabs(FrontVector[2])) UpVector[0] = -(UpVector[1] * FrontVector[1] + UpVector[2] * FrontVector[2]); else UpVector[2] = -(UpVector[0] * FrontVector[0] + UpVector[1] * FrontVector[1]); } else { if (fabs(FrontVector[1]) < fabs(FrontVector[2])) UpVector[1] = -(UpVector[0] * FrontVector[0] + UpVector[2] * FrontVector[2]); else UpVector[2] = -(UpVector[0] * FrontVector[0] + UpVector[1] * FrontVector[1]); } mWorldLight = lcMatrix44LookAt(mPosition, mTargetPosition, UpVector); } } void lcLight::DrawInterface(lcContext* Context, const lcScene& Scene) const { Q_UNUSED(Scene); Context->SetMaterial(lcMaterialType::UnlitColor); if (IsPointLight()) DrawPointLight(Context); else DrawSpotLight(Context); } void lcLight::DrawSpotLight(lcContext* Context) const { lcVector3 FrontVector(mTargetPosition - mPosition); lcVector3 UpVector(1, 1, 1); if (fabs(FrontVector[0]) < fabs(FrontVector[1])) { if (fabs(FrontVector[0]) < fabs(FrontVector[2])) UpVector[0] = -(UpVector[1] * FrontVector[1] + UpVector[2] * FrontVector[2]); else UpVector[2] = -(UpVector[0] * FrontVector[0] + UpVector[1] * FrontVector[1]); } else { if (fabs(FrontVector[1]) < fabs(FrontVector[2])) UpVector[1] = -(UpVector[0] * FrontVector[0] + UpVector[2] * FrontVector[2]); else UpVector[2] = -(UpVector[0] * FrontVector[0] + UpVector[1] * FrontVector[1]); } lcMatrix44 LightMatrix = lcMatrix44LookAt(mPosition, mTargetPosition, UpVector); LightMatrix = lcMatrix44AffineInverse(LightMatrix); LightMatrix.SetTranslation(lcVector3(0, 0, 0)); const lcMatrix44 LightViewMatrix = lcMul(LightMatrix, lcMatrix44Translation(mPosition)); Context->SetWorldMatrix(LightViewMatrix); float Verts[(20 + 8 + 2 + 16) * 3]; float* CurVert = Verts; for (int EdgeIdx = 0; EdgeIdx < 8; EdgeIdx++) { float c = cosf((float)EdgeIdx / 4 * LC_PI) * LC_LIGHT_POSITION_EDGE; float s = sinf((float)EdgeIdx / 4 * LC_PI) * LC_LIGHT_POSITION_EDGE; *CurVert++ = c; *CurVert++ = s; *CurVert++ = LC_LIGHT_POSITION_EDGE; *CurVert++ = c; *CurVert++ = s; *CurVert++ = -LC_LIGHT_POSITION_EDGE; } *CurVert++ = -12.5f; *CurVert++ = -12.5f; *CurVert++ = -LC_LIGHT_POSITION_EDGE; *CurVert++ = 12.5f; *CurVert++ = -12.5f; *CurVert++ = -LC_LIGHT_POSITION_EDGE; *CurVert++ = 12.5f; *CurVert++ = 12.5f; *CurVert++ = -LC_LIGHT_POSITION_EDGE; *CurVert++ = -12.5f; *CurVert++ = 12.5f; *CurVert++ = -LC_LIGHT_POSITION_EDGE; float Length = FrontVector.Length(); *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - Length; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - Length; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - Length; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - Length; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - Length; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - Length; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - Length; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - Length; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = -Length; const GLushort Indices[56 + 24 + 2 + 40] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 0, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15, 1, 16, 17, 17, 18, 18, 19, 19, 16, 20, 21, 21, 22, 22, 23, 23, 20, 24, 25, 25, 26, 26, 27, 27, 24, 20, 24, 21, 25, 22, 26, 23, 27, 28, 29, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 30, 28, 30, 28, 34, 28, 38, 28, 42 }; Context->SetVertexBufferPointer(Verts); Context->SetVertexFormatPosition(3); Context->SetIndexBufferPointer(Indices); const lcPreferences& Preferences = lcGetPreferences(); const float LineWidth = Preferences.mLineWidth; const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor); const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor); const lcVector4 LightColor = lcVector4FromColor(Preferences.mLightColor); if (!IsSelected()) { Context->SetLineWidth(LineWidth); Context->SetColor(LightColor); Context->DrawIndexedPrimitives(GL_LINES, 56 + 24 + 2, GL_UNSIGNED_SHORT, 0); } else { if (IsSelected(LC_LIGHT_SECTION_POSITION)) { Context->SetLineWidth(2.0f * LineWidth); if (IsFocused(LC_LIGHT_SECTION_POSITION)) Context->SetColor(FocusedColor); else Context->SetColor(SelectedColor); } else { Context->SetLineWidth(LineWidth); Context->SetColor(LightColor); } Context->DrawIndexedPrimitives(GL_LINES, 56, GL_UNSIGNED_SHORT, 0); if (IsSelected(LC_LIGHT_SECTION_TARGET)) { Context->SetLineWidth(2.0f * LineWidth); if (IsFocused(LC_LIGHT_SECTION_TARGET)) Context->SetColor(FocusedColor); else Context->SetColor(SelectedColor); } else { Context->SetLineWidth(LineWidth); Context->SetColor(LightColor); } Context->DrawIndexedPrimitives(GL_LINES, 24, GL_UNSIGNED_SHORT, 56 * 2); Context->SetLineWidth(LineWidth); Context->SetColor(LightColor); float Radius = tanf(LC_DTOR * mSpotCutoff) * Length; for (int EdgeIdx = 0; EdgeIdx < 16; EdgeIdx++) { *CurVert++ = cosf((float)EdgeIdx / 16 * LC_2PI) * Radius; *CurVert++ = sinf((float)EdgeIdx / 16 * LC_2PI) * Radius; *CurVert++ = -Length; } Context->DrawIndexedPrimitives(GL_LINES, 2 + 40, GL_UNSIGNED_SHORT, (56 + 24) * 2); } } void lcLight::DrawPointLight(lcContext* Context) const { constexpr int Slices = 6; constexpr int NumIndices = 3 * Slices + 6 * Slices * (Slices - 2) + 3 * Slices; constexpr int NumVertices = (Slices - 1) * Slices + 2; constexpr float Radius = LC_LIGHT_SPHERE_RADIUS; lcVector3 Vertices[NumVertices]; quint16 Indices[NumIndices]; lcVector3* Vertex = Vertices; quint16* Index = Indices; *Vertex++ = lcVector3(0, 0, Radius); for (int i = 1; i < Slices; i++ ) { const float r0 = Radius * sinf(i * (LC_PI / Slices)); const float z0 = Radius * cosf(i * (LC_PI / Slices)); for (int j = 0; j < Slices; j++) { const float x0 = r0 * sinf(j * (LC_2PI / Slices)); const float y0 = r0 * cosf(j * (LC_2PI / Slices)); *Vertex++ = lcVector3(x0, y0, z0); } } *Vertex++ = lcVector3(0, 0, -Radius); for (quint16 i = 0; i < Slices - 1; i++ ) { *Index++ = 0; *Index++ = 1 + i; *Index++ = 1 + i + 1; } *Index++ = 0; *Index++ = 1; *Index++ = 1 + Slices - 1; for (quint16 i = 0; i < Slices - 2; i++ ) { quint16 Row1 = 1 + i * Slices; quint16 Row2 = 1 + (i + 1) * Slices; for (quint16 j = 0; j < Slices - 1; j++ ) { *Index++ = Row1 + j; *Index++ = Row2 + j + 1; *Index++ = Row2 + j; *Index++ = Row1 + j; *Index++ = Row1 + j + 1; *Index++ = Row2 + j + 1; } *Index++ = Row1 + Slices - 1; *Index++ = Row2 + 0; *Index++ = Row2 + Slices - 1; *Index++ = Row1 + Slices - 1; *Index++ = Row2 + 0; *Index++ = Row1 + 0; } for (quint16 i = 0; i < Slices - 1; i++ ) { *Index++ = (Slices - 1) * Slices + 1; *Index++ = (Slices - 1) * (Slices - 1) + i; *Index++ = (Slices - 1) * (Slices - 1) + i + 1; } *Index++ = (Slices - 1) * Slices + 1; *Index++ = (Slices - 1) * (Slices - 1) + (Slices - 2) + 1; *Index++ = (Slices - 1) * (Slices - 1); Context->SetWorldMatrix(lcMatrix44Translation(mPosition)); const lcPreferences& Preferences = lcGetPreferences(); if (IsFocused(LC_LIGHT_SECTION_POSITION)) { const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor); Context->SetColor(FocusedColor); } else if (IsSelected(LC_LIGHT_SECTION_POSITION)) { const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor); Context->SetColor(SelectedColor); } else { const lcVector4 LightColor = lcVector4FromColor(Preferences.mLightColor); Context->SetColor(LightColor); } Context->SetVertexBufferPointer(Vertices); Context->SetVertexFormatPosition(3); Context->SetIndexBufferPointer(Indices); Context->DrawIndexedPrimitives(GL_TRIANGLES, NumIndices, GL_UNSIGNED_SHORT, 0); } void lcLight::RemoveKeyFrames() { mPositionKeys.RemoveAll(); mPositionKeys.ChangeKey(mPosition, 1, true); mTargetPositionKeys.RemoveAll(); mTargetPositionKeys.ChangeKey(mTargetPosition, 1, true); mAmbientColorKeys.RemoveAll(); mAmbientColorKeys.ChangeKey(mAmbientColor, 1, true); mDiffuseColorKeys.RemoveAll(); mDiffuseColorKeys.ChangeKey(mDiffuseColor, 1, true); mSpecularColorKeys.RemoveAll(); mSpecularColorKeys.ChangeKey(mSpecularColor, 1, true); mAttenuationKeys.RemoveAll(); mAttenuationKeys.ChangeKey(mAttenuation, 1, true); mSpotCutoffKeys.RemoveAll(); mSpotCutoffKeys.ChangeKey(mSpotCutoff, 1, true); mSpotExponentKeys.RemoveAll(); mSpotExponentKeys.ChangeKey(mSpotExponent, 1, true); } bool lcLight::Setup(int LightIndex) { Q_UNUSED(LightIndex); return true; } leocad-23.03/common/light.h000066400000000000000000000126061440571307300155310ustar00rootroot00000000000000#pragma once #include "object.h" #include "lc_math.h" #define LC_LIGHT_HIDDEN 0x0001 #define LC_LIGHT_DISABLED 0x0002 #define LC_LIGHT_SPOT 0x0004 #define LC_LIGHT_DIRECTIONAL 0x0008 #define LC_LIGHT_POSITION_SELECTED 0x0010 #define LC_LIGHT_POSITION_FOCUSED 0x0020 #define LC_LIGHT_TARGET_SELECTED 0x0040 #define LC_LIGHT_TARGET_FOCUSED 0x0080 #define LC_LIGHT_SELECTION_MASK (LC_LIGHT_POSITION_SELECTED | LC_LIGHT_TARGET_SELECTED) #define LC_LIGHT_FOCUS_MASK (LC_LIGHT_POSITION_FOCUSED | LC_LIGHT_TARGET_FOCUSED) enum lcLightSection { LC_LIGHT_SECTION_POSITION, LC_LIGHT_SECTION_TARGET }; class lcLight : public lcObject { public: lcLight(float px, float py, float pz); lcLight(float px, float py, float pz, float tx, float ty, float tz); ~lcLight(); lcLight(const lcLight&) = delete; lcLight(lcLight&&) = delete; lcLight& operator=(const lcLight&) = delete; lcLight& operator=(lcLight&&) = delete; bool IsPointLight() const { return (mState & (LC_LIGHT_SPOT | LC_LIGHT_DIRECTIONAL)) == 0; } bool IsSpotLight() const { return (mState & LC_LIGHT_SPOT) != 0; } bool IsDirectionalLight() const { return (mState & LC_LIGHT_DIRECTIONAL) != 0; } bool IsSelected() const override { return (mState & LC_LIGHT_SELECTION_MASK) != 0; } bool IsSelected(quint32 Section) const override { switch (Section) { case LC_LIGHT_SECTION_POSITION: return (mState & LC_LIGHT_POSITION_SELECTED) != 0; break; case LC_LIGHT_SECTION_TARGET: return (mState & LC_LIGHT_TARGET_SELECTED) != 0; break; } return false; } void SetSelected(bool Selected) override { if (Selected) { if (IsPointLight()) mState |= LC_LIGHT_POSITION_SELECTED; else mState |= LC_LIGHT_SELECTION_MASK; } else mState &= ~(LC_LIGHT_SELECTION_MASK | LC_LIGHT_FOCUS_MASK); } void SetSelected(quint32 Section, bool Selected) override { switch (Section) { case LC_LIGHT_SECTION_POSITION: if (Selected) mState |= LC_LIGHT_POSITION_SELECTED; else mState &= ~(LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED); break; case LC_LIGHT_SECTION_TARGET: if (Selected) { if (!IsPointLight()) mState |= LC_LIGHT_TARGET_SELECTED; } else mState &= ~(LC_LIGHT_TARGET_SELECTED | LC_LIGHT_TARGET_FOCUSED); break; } } bool IsFocused() const override { return (mState & LC_LIGHT_FOCUS_MASK) != 0; } bool IsFocused(quint32 Section) const override { switch (Section) { case LC_LIGHT_SECTION_POSITION: return (mState & LC_LIGHT_POSITION_FOCUSED) != 0; break; case LC_LIGHT_SECTION_TARGET: return (mState & LC_LIGHT_TARGET_FOCUSED) != 0; break; } return false; } void SetFocused(quint32 Section, bool Focused) override { switch (Section) { case LC_LIGHT_SECTION_POSITION: if (Focused) mState |= LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED; else mState &= ~(LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED); break; case LC_LIGHT_SECTION_TARGET: if (Focused) { if (!IsPointLight()) mState |= LC_LIGHT_TARGET_SELECTED | LC_LIGHT_TARGET_FOCUSED; } else mState &= ~(LC_LIGHT_TARGET_SELECTED | LC_LIGHT_TARGET_FOCUSED); break; } } quint32 GetFocusSection() const override { if (mState & LC_LIGHT_POSITION_FOCUSED) return LC_LIGHT_SECTION_POSITION; if (!IsPointLight() && (mState & LC_LIGHT_TARGET_FOCUSED)) return LC_LIGHT_SECTION_TARGET; return ~0U; } quint32 GetAllowedTransforms() const override { return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z; } lcVector3 GetSectionPosition(quint32 Section) const override { switch (Section) { case LC_LIGHT_SECTION_POSITION: return mPosition; case LC_LIGHT_SECTION_TARGET: return mTargetPosition; } return lcVector3(0.0f, 0.0f, 0.0f); } void SaveLDraw(QTextStream& Stream) const; public: void RayTest(lcObjectRayTest& ObjectRayTest) const override; void BoxTest(lcObjectBoxTest& ObjectBoxTest) const override; void DrawInterface(lcContext* Context, const lcScene& Scene) const override; void RemoveKeyFrames() override; void InsertTime(lcStep Start, lcStep Time); void RemoveTime(lcStep Start, lcStep Time); bool IsVisible() const { return (mState & LC_LIGHT_HIDDEN) == 0; } QString GetName() const override { return mName; } void CompareBoundingBox(lcVector3& Min, lcVector3& Max); void UpdatePosition(lcStep Step); void MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance); bool Setup(int LightIndex); void CreateName(const lcArray& Lights); // Temporary parameters lcMatrix44 mWorldLight; lcVector3 mPosition; lcVector3 mTargetPosition; lcVector4 mAmbientColor; lcVector4 mDiffuseColor; lcVector4 mSpecularColor; lcVector3 mAttenuation; float mSpotCutoff; float mSpotExponent; protected: lcObjectKeyArray mPositionKeys; lcObjectKeyArray mTargetPositionKeys; lcObjectKeyArray mAmbientColorKeys; lcObjectKeyArray mDiffuseColorKeys; lcObjectKeyArray mSpecularColorKeys; lcObjectKeyArray mAttenuationKeys; lcObjectKeyArray mSpotCutoffKeys; lcObjectKeyArray mSpotExponentKeys; void Initialize(const lcVector3& Position, const lcVector3& TargetPosition); void DrawPointLight(lcContext* Context) const; void DrawSpotLight(lcContext* Context) const; QString mName; quint32 mState; }; leocad-23.03/common/minifig.cpp000066400000000000000000000335011440571307300163740ustar00rootroot00000000000000#include "lc_global.h" #include "minifig.h" #include "lc_colors.h" #include "pieceinf.h" #include "lc_model.h" #include "lc_library.h" #include "lc_application.h" #include "lc_file.h" #include "lc_profile.h" const char* MinifigWizard::mSectionNames[LC_MFW_NUMITEMS] = { "HATS", // LC_MFW_HATS "HATS2", // LC_MFW_HATS2 "HEAD", // LC_MFW_HEAD "NECK", // LC_MFW_NECK "BODY", // LC_MFW_BODY "BODY2", // LC_MFW_BODY2 "BODY3", // LC_MFW_BODY3 "RARM", // LC_MFW_RARM "LARM", // LC_MFW_LARM "RHAND", // LC_MFW_RHAND "LHAND", // LC_MFW_LHAND "RHANDA", // LC_MFW_RHANDA "LHANDA", // LC_MFW_LHANDA "RLEG", // LC_MFW_RLEG "LLEG", // LC_MFW_LLEG "RLEGA", // LC_MFW_RLEGA "LLEGA", // LC_MFW_LLEGA }; MinifigWizard::MinifigWizard() : mModel(new lcModel(QString(), nullptr, false)) { LoadSettings(); LoadTemplates(); } MinifigWizard::~MinifigWizard() { lcPiecesLibrary* Library = lcGetPiecesLibrary(); for (int i = 0; i < LC_MFW_NUMITEMS; i++) if (mMinifig.Parts[i]) Library->ReleasePieceInfo(mMinifig.Parts[i]); // todo: don't call ReleasePieceInfo here because it may release textures and they need a GL context current SaveTemplates(); } void MinifigWizard::LoadSettings() { QString CustomSettingsPath = lcGetProfileString(LC_PROFILE_MINIFIG_SETTINGS); if (!CustomSettingsPath.isEmpty()) { lcDiskFile DiskSettings(CustomSettingsPath); if (DiskSettings.Open(QIODevice::ReadOnly)) { ParseSettings(DiskSettings); return; } } lcDiskFile MinifigFile(":/resources/minifig.ini"); if (MinifigFile.Open(QIODevice::ReadOnly)) ParseSettings(MinifigFile); } void MinifigWizard::LoadDefault() { LC_ARRAY_SIZE_CHECK(MinifigWizard::mSectionNames, LC_MFW_NUMITEMS); const int ColorCodes[LC_MFW_NUMITEMS] = { 4, 7, 14, 7, 1, 0, 7, 4, 4, 14, 14, 7, 7, 0, 0, 7, 7 }; const char* const Pieces[LC_MFW_NUMITEMS] = { "3624.dat", "", "3626bp01.dat", "", "973.dat", "3815.dat", "", "3819.dat", "3818.dat", "3820.dat", "3820.dat", "", "", "3817.dat", "3816.dat", "", "" }; lcPiecesLibrary* Library = lcGetPiecesLibrary(); for (int i = 0; i < LC_MFW_NUMITEMS; i++) { mMinifig.Colors[i] = lcGetColorIndex(ColorCodes[i]); mMinifig.Angles[i] = 0.0f; mMinifig.Matrices[i] = lcMatrix44Identity(); PieceInfo* Info = Library->FindPiece(Pieces[i], nullptr, false, false); mMinifig.Parts[i] = Info; if (Info) Library->LoadPieceInfo(Info, false, true); } Library->WaitForLoadQueue(); Calculate(); } void MinifigWizard::ParseSettings(lcFile& Settings) { for (int SectionIndex = 0; SectionIndex < LC_MFW_NUMITEMS; SectionIndex++) { std::vector& InfoArray = mSettings[SectionIndex]; InfoArray.clear(); Settings.Seek(0, SEEK_SET); char Line[1024]; bool FoundSection = false; const char* SectionName = mSectionNames[SectionIndex]; const size_t SectionNameLength = strlen(SectionName); while (Settings.ReadLine(Line, sizeof(Line))) { if (Line[0] == '[' && !strncmp(Line + 1, SectionName, SectionNameLength) && Line[SectionNameLength + 1] == ']') { FoundSection = true; break; } } if (!FoundSection) { lcMinifigPieceInfo MinifigInfo; strncpy(MinifigInfo.Description, "None", sizeof(MinifigInfo.Description)); MinifigInfo.Description[sizeof(MinifigInfo.Description)-1] = 0; MinifigInfo.Offset = lcMatrix44Identity(); MinifigInfo.Info = nullptr; InfoArray.emplace_back(std::move(MinifigInfo)); continue; } while (Settings.ReadLine(Line, sizeof(Line))) { if (Line[0] == '[') break; char* DescriptionStart = strchr(Line, '"'); if (!DescriptionStart) continue; DescriptionStart++; char* DescriptionEnd = strchr(DescriptionStart, '"'); if (!DescriptionEnd) continue; *DescriptionEnd = 0; DescriptionEnd++; char* NameStart = strchr(DescriptionEnd, '"'); if (!NameStart) continue; NameStart++; char* NameEnd = strchr(NameStart, '"'); if (!NameEnd) continue; *NameEnd = 0; NameEnd++; PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(NameStart, nullptr, false, false); if (!Info && *NameStart) continue; float Mat[12]; int Flags; if (sscanf(NameEnd, "%d %g %g %g %g %g %g %g %g %g %g %g %g", &Flags, &Mat[0], &Mat[1], &Mat[2], &Mat[3], &Mat[4], &Mat[5], &Mat[6], &Mat[7], &Mat[8], &Mat[9], &Mat[10], &Mat[11]) != 13) continue; lcMatrix44 Offset = lcMatrix44Identity(); float* OffsetMatrix = &Offset[0][0]; OffsetMatrix[0] = Mat[0]; OffsetMatrix[8] = -Mat[1]; OffsetMatrix[4] = Mat[2]; OffsetMatrix[2] = -Mat[3]; OffsetMatrix[10] = Mat[4]; OffsetMatrix[6] = -Mat[5]; OffsetMatrix[1] = Mat[6]; OffsetMatrix[9] = -Mat[7]; OffsetMatrix[5] = Mat[8]; OffsetMatrix[12] = Mat[9]; OffsetMatrix[14] = -Mat[10]; OffsetMatrix[13] = Mat[11]; lcMinifigPieceInfo MinifigInfo; strncpy(MinifigInfo.Description, DescriptionStart, sizeof(MinifigInfo.Description)); MinifigInfo.Description[sizeof(MinifigInfo.Description)-1] = 0; MinifigInfo.Offset = Offset; MinifigInfo.Info = Info; InfoArray.emplace_back(std::move(MinifigInfo)); } } } void MinifigWizard::SaveTemplate(const QString& TemplateName, const lcMinifigTemplate& Template) { mTemplates[TemplateName] = Template; } void MinifigWizard::DeleteTemplate(const QString& TemplateName) { mTemplates.erase(TemplateName); } void MinifigWizard::AddTemplatesJson(const QByteArray& TemplateData) { QJsonDocument Document = QJsonDocument::fromJson(TemplateData); QJsonObject RootObject = Document.object(); int Version = RootObject["Version"].toInt(0); QJsonObject TemplatesObject; if (Version > 0) TemplatesObject = RootObject["Templates"].toObject(); else TemplatesObject = RootObject; for (QJsonObject::const_iterator ElementIt = TemplatesObject.constBegin(); ElementIt != TemplatesObject.constEnd(); ElementIt++) { if (!ElementIt.value().isObject()) continue; QJsonObject TemplateObject = ElementIt.value().toObject(); lcMinifigTemplate Template; for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++) { QJsonObject PartObject = TemplateObject.value(QLatin1String(mSectionNames[PartIdx])).toObject(); Template.Parts[PartIdx] = PartObject["Id"].toString(); Template.Colors[PartIdx] = PartObject["Color"].toInt(); Template.Angles[PartIdx] = PartObject["Angle"].toDouble(); } mTemplates.emplace(ElementIt.key(), std::move(Template)); } } QByteArray MinifigWizard::GetTemplatesJson() const { QJsonObject TemplatesObject; for (const auto& TemplateEntry : mTemplates) { const lcMinifigTemplate& Template = TemplateEntry.second; QJsonObject TemplateObject; for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++) { QJsonObject PartObject; PartObject["Id"] = Template.Parts[PartIdx]; PartObject["Color"] = Template.Colors[PartIdx]; PartObject["Angle"] = Template.Angles[PartIdx]; TemplateObject[QLatin1String(mSectionNames[PartIdx])] = PartObject; } TemplatesObject[TemplateEntry.first] = TemplateObject; } QJsonObject RootObject; RootObject["Templates"] = TemplatesObject; RootObject["Version"] = 1; return QJsonDocument(RootObject).toJson(); } void MinifigWizard::LoadTemplates() { mTemplates.clear(); QSettings Settings; Settings.beginGroup("Minifig"); QByteArray TemplateData = Settings.value("Templates").toByteArray(); AddTemplatesJson(TemplateData); } void MinifigWizard::SaveTemplates() { QSettings Settings; Settings.beginGroup("Minifig"); Settings.setValue("Templates", GetTemplatesJson()); } void MinifigWizard::Calculate() { float HeadOffset = 0.0f; lcMatrix44 Root, Mat, Mat2; PieceInfo** Parts = mMinifig.Parts; const float* Angles = mMinifig.Angles; lcMatrix44* Matrices = mMinifig.Matrices; const bool DroidTorso = Parts[LC_MFW_BODY] && !qstricmp(Parts[LC_MFW_BODY]->mFileName, "30375.dat"); const bool SkeletonTorso = Parts[LC_MFW_BODY] && !qstricmp(Parts[LC_MFW_BODY]->mFileName, "6260.dat"); if (Parts[LC_MFW_BODY3]) Root = lcMatrix44Translation(lcVector3(0, 0, 74.0f)); else Root = lcMatrix44Translation(lcVector3(0, 0, 72.0f)); Matrices[LC_MFW_BODY] = lcMul(mSettings[LC_MFW_BODY][GetSelectionIndex(LC_MFW_BODY)].Offset, Root); if (Parts[LC_MFW_NECK]) { Matrices[LC_MFW_NECK] = lcMul(mSettings[LC_MFW_NECK][GetSelectionIndex(LC_MFW_NECK)].Offset, Root); HeadOffset = 0.08f; } if (Parts[LC_MFW_HEAD]) { Mat = lcMatrix44RotationZ(-LC_DTOR * Angles[LC_MFW_HEAD]); Mat.SetTranslation(lcVector3(0.0f, 0.0f, 24.0f + HeadOffset)); Mat = lcMul(mSettings[LC_MFW_HEAD][GetSelectionIndex(LC_MFW_HEAD)].Offset, Mat); Matrices[LC_MFW_HEAD] = lcMul(Mat, Root); } if (Parts[LC_MFW_HATS]) { Mat = lcMatrix44RotationZ(-LC_DTOR * Angles[LC_MFW_HATS]); Mat = lcMul(mSettings[LC_MFW_HATS][GetSelectionIndex(LC_MFW_HATS)].Offset, Mat); Matrices[LC_MFW_HATS] = lcMul(Mat, Matrices[LC_MFW_HEAD]); } if (Parts[LC_MFW_HATS2]) { Mat = lcMatrix44RotationX(-LC_DTOR * Angles[LC_MFW_HATS2]); Mat = lcMul(mSettings[LC_MFW_HATS2][GetSelectionIndex(LC_MFW_HATS2)].Offset, Mat); Matrices[LC_MFW_HATS2] = lcMul(Mat, Matrices[LC_MFW_HATS]); } if (Parts[LC_MFW_RARM]) { Mat = lcMatrix44RotationX(-LC_DTOR * Angles[LC_MFW_RARM]); if (DroidTorso || SkeletonTorso) Mat2 = lcMatrix44Identity(); else Mat2 = lcMatrix44RotationY(-LC_DTOR * 9.791f); Mat2.SetTranslation(lcVector3(15.552f, 0, -8.88f)); Mat = lcMul(mSettings[LC_MFW_RARM][GetSelectionIndex(LC_MFW_RARM)].Offset, Mat); Mat = lcMul(Mat, Mat2); Matrices[LC_MFW_RARM] = lcMul(Mat, Root); } if (Parts[LC_MFW_RHAND]) { Mat = lcMatrix44RotationY(-LC_DTOR * Angles[LC_MFW_RHAND]); Mat2 = lcMatrix44RotationX(LC_DTOR * 45); Mat = lcMul(mSettings[LC_MFW_RHAND][GetSelectionIndex(LC_MFW_RHAND)].Offset, Mat); Mat = lcMul(Mat, Mat2); Mat.SetTranslation(lcVector3(5.0f, -10.0f, -19.0f)); Matrices[LC_MFW_RHAND] = lcMul(Mat, Matrices[LC_MFW_RARM]); } if (Parts[LC_MFW_RHANDA]) { Mat = lcMatrix44RotationZ(LC_DTOR * Angles[LC_MFW_RHANDA]); Mat.SetTranslation(lcVector3(0, -9.25f, 0)); Mat = lcMul(mSettings[LC_MFW_RHANDA][GetSelectionIndex(LC_MFW_RHANDA)].Offset, Mat); Mat = lcMul(Mat, lcMatrix44RotationX(LC_DTOR * 15.0f)); Matrices[LC_MFW_RHANDA] = lcMul(Mat, Matrices[LC_MFW_RHAND]); } if (Parts[LC_MFW_LARM]) { Mat = lcMatrix44RotationX(-LC_DTOR * Angles[LC_MFW_LARM]); if (DroidTorso || SkeletonTorso) Mat2 = lcMatrix44Identity(); else Mat2 = lcMatrix44RotationY(LC_DTOR * 9.791f); Mat2.SetTranslation(lcVector3(-15.552f, 0.0f, -8.88f)); Mat = lcMul(mSettings[LC_MFW_LARM][GetSelectionIndex(LC_MFW_LARM)].Offset, Mat); Mat = lcMul(Mat, Mat2); Matrices[LC_MFW_LARM] = lcMul(Mat, Root); } if (Parts[LC_MFW_LHAND]) { Mat = lcMatrix44RotationY(-LC_DTOR * Angles[LC_MFW_LHAND]); Mat2 = lcMatrix44RotationX(LC_DTOR * 45); Mat = lcMul(mSettings[LC_MFW_LHAND][GetSelectionIndex(LC_MFW_LHAND)].Offset, Mat); Mat = lcMul(Mat, Mat2); Mat.SetTranslation(lcVector3(-5.0f, -10.0f, -19.0f)); Matrices[LC_MFW_LHAND] = lcMul(Mat, Matrices[LC_MFW_LARM]); } if (Parts[LC_MFW_LHANDA]) { Mat = lcMatrix44RotationZ(LC_DTOR * Angles[LC_MFW_LHANDA]); Mat.SetTranslation(lcVector3(0, -9.25f, 0)); Mat = lcMul(mSettings[LC_MFW_LHANDA][GetSelectionIndex(LC_MFW_LHANDA)].Offset, Mat); Mat = lcMul(Mat, lcMatrix44RotationX(LC_DTOR * 15.0f)); Matrices[LC_MFW_LHANDA] = lcMul(Mat, Matrices[LC_MFW_LHAND]); } if (Parts[LC_MFW_BODY2]) { Mat = lcMatrix44Identity(); Mat.SetTranslation(lcVector3(0, 0, -32.0f)); Mat = lcMul(mSettings[LC_MFW_BODY2][GetSelectionIndex(LC_MFW_BODY2)].Offset, Mat); Matrices[LC_MFW_BODY2] = lcMul(Mat, Root); } if (Parts[LC_MFW_BODY3]) { Mat = lcMatrix44Identity(); Mat.SetTranslation(lcVector3(0, 0, -32.0f)); Mat = lcMul(mSettings[LC_MFW_BODY3][GetSelectionIndex(LC_MFW_BODY3)].Offset, Mat); Matrices[LC_MFW_BODY3] = lcMul(Mat, Root); } if (Parts[LC_MFW_RLEG]) { Mat = lcMatrix44RotationX(-LC_DTOR * Angles[LC_MFW_RLEG]); Mat.SetTranslation(lcVector3(0, 0, -44.0f)); Mat = lcMul(mSettings[LC_MFW_RLEG][GetSelectionIndex(LC_MFW_RLEG)].Offset, Mat); Matrices[LC_MFW_RLEG] = lcMul(Mat, Root); } if (Parts[LC_MFW_RLEGA]) { const lcVector3 Center(-10.0f, -1.0f, -28.0f); Mat = lcMatrix44RotationZ(LC_DTOR * Angles[LC_MFW_RLEGA]); Mat2 = mSettings[LC_MFW_RLEGA][GetSelectionIndex(LC_MFW_RLEGA)].Offset; Mat2.SetTranslation(lcMul31(-Center, Mat2)); Mat = lcMul(Mat2, Mat); Mat.SetTranslation(lcMul31(Center, Mat2)); Matrices[LC_MFW_RLEGA] = lcMul(Mat, Matrices[LC_MFW_RLEG]); } if (Parts[LC_MFW_LLEG]) { Mat = lcMatrix44RotationX(-LC_DTOR * Angles[LC_MFW_LLEG]); Mat.SetTranslation(lcVector3(0, 0, -44.0f)); Mat = lcMul(mSettings[LC_MFW_LLEG][GetSelectionIndex(LC_MFW_LLEG)].Offset, Mat); Matrices[LC_MFW_LLEG] = lcMul(Mat, Root); } if (Parts[LC_MFW_LLEGA]) { const lcVector3 Center(10.0f, -1.0f, -28.0f); Mat = lcMatrix44RotationZ(LC_DTOR * Angles[LC_MFW_LLEGA]); Mat2 = mSettings[LC_MFW_LLEGA][GetSelectionIndex(LC_MFW_LLEGA)].Offset; Mat2.SetTranslation(lcMul31(-Center, Mat2)); Mat = lcMul(Mat2, Mat); Mat.SetTranslation(lcMul31(Center, Mat2)); Matrices[LC_MFW_LLEGA] = lcMul(Mat, Matrices[LC_MFW_LLEG]); } mModel->SetMinifig(mMinifig); } int MinifigWizard::GetSelectionIndex(int Type) const { const std::vector& InfoArray = mSettings[Type]; for (size_t Index = 0; Index < InfoArray.size(); Index++) if (InfoArray[Index].Info == mMinifig.Parts[Type]) return (int)Index; return 0; } void MinifigWizard::SetSelectionIndex(int Type, int Index) { lcPiecesLibrary* Library = lcGetPiecesLibrary(); if (mMinifig.Parts[Type]) Library->ReleasePieceInfo(mMinifig.Parts[Type]); mMinifig.Parts[Type] = mSettings[Type][Index].Info; if (mMinifig.Parts[Type]) Library->LoadPieceInfo(mMinifig.Parts[Type], true, true); Calculate(); } void MinifigWizard::SetColor(int Type, int Color) { mMinifig.Colors[Type] = Color; Calculate(); } void MinifigWizard::SetAngle(int Type, float Angle) { mMinifig.Angles[Type] = Angle; Calculate(); } leocad-23.03/common/minifig.h000066400000000000000000000035601440571307300160430ustar00rootroot00000000000000#pragma once #include "lc_math.h" enum LC_MFW_TYPES { LC_MFW_HATS, LC_MFW_HATS2, LC_MFW_HEAD, LC_MFW_NECK, LC_MFW_BODY, LC_MFW_BODY2, LC_MFW_BODY3, LC_MFW_RARM, LC_MFW_LARM, LC_MFW_RHAND, LC_MFW_LHAND, LC_MFW_RHANDA, LC_MFW_LHANDA, LC_MFW_RLEG, LC_MFW_LLEG, LC_MFW_RLEGA, LC_MFW_LLEGA, LC_MFW_NUMITEMS }; struct lcMinifigPieceInfo { char Description[128]; PieceInfo* Info; lcMatrix44 Offset; }; struct lcMinifig { PieceInfo* Parts[LC_MFW_NUMITEMS]; int Colors[LC_MFW_NUMITEMS]; float Angles[LC_MFW_NUMITEMS]; lcMatrix44 Matrices[LC_MFW_NUMITEMS]; }; struct lcMinifigTemplate { QString Parts[LC_MFW_NUMITEMS]; int Colors[LC_MFW_NUMITEMS]; float Angles[LC_MFW_NUMITEMS]; }; class MinifigWizard { public: MinifigWizard(); ~MinifigWizard(); MinifigWizard(const MinifigWizard&) = delete; MinifigWizard(MinifigWizard&&) = delete; MinifigWizard& operator=(const MinifigWizard&) = delete; MinifigWizard& operator=(MinifigWizard&&) = delete; lcModel* GetModel() const { return mModel.get(); } const std::map& GetTemplates() const { return mTemplates; } void SaveTemplate(const QString& TemplateName, const lcMinifigTemplate& Template); void DeleteTemplate(const QString& TemplateName); void AddTemplatesJson(const QByteArray& TemplateData); QByteArray GetTemplatesJson() const; void LoadDefault(); void Calculate(); int GetSelectionIndex(int Type) const; void SetSelectionIndex(int Type, int Index); void SetColor(int Type, int Color); void SetAngle(int Type, float Angle); std::vector mSettings[LC_MFW_NUMITEMS]; lcMinifig mMinifig; protected: void LoadSettings(); void ParseSettings(lcFile& Settings); void LoadTemplates(); void SaveTemplates(); std::unique_ptr mModel; std::map mTemplates; static const char* mSectionNames[LC_MFW_NUMITEMS]; }; leocad-23.03/common/object.cpp000066400000000000000000000114141440571307300162170ustar00rootroot00000000000000#include "lc_global.h" #include "object.h" lcObject::lcObject(lcObjectType ObjectType) : mObjectType(ObjectType) { } lcObject::~lcObject() { } template void lcObjectKeyArray::SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const; template void lcObjectKeyArray::LoadKeysLDraw(QTextStream& Stream); template const float& lcObjectKeyArray::CalculateKey(lcStep Step) const; template void lcObjectKeyArray::ChangeKey(const float& Value, lcStep Step, bool AddKey); template void lcObjectKeyArray::InsertTime(lcStep Start, lcStep Time); template void lcObjectKeyArray::RemoveTime(lcStep Start, lcStep Time); template void lcObjectKeyArray::SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const; template void lcObjectKeyArray::LoadKeysLDraw(QTextStream& Stream); template const lcVector3& lcObjectKeyArray::CalculateKey(lcStep Step) const; template void lcObjectKeyArray::ChangeKey(const lcVector3& Value, lcStep Step, bool AddKey); template void lcObjectKeyArray::InsertTime(lcStep Start, lcStep Time); template void lcObjectKeyArray::RemoveTime(lcStep Start, lcStep Time); template void lcObjectKeyArray::SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const; template void lcObjectKeyArray::LoadKeysLDraw(QTextStream& Stream); template const lcVector4& lcObjectKeyArray::CalculateKey(lcStep Step) const; template void lcObjectKeyArray::ChangeKey(const lcVector4& Value, lcStep Step, bool AddKey); template void lcObjectKeyArray::InsertTime(lcStep Start, lcStep Time); template void lcObjectKeyArray::RemoveTime(lcStep Start, lcStep Time); template void lcObjectKeyArray::SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const; template void lcObjectKeyArray::LoadKeysLDraw(QTextStream& Stream); template const lcMatrix33& lcObjectKeyArray::CalculateKey(lcStep Step) const; template void lcObjectKeyArray::ChangeKey(const lcMatrix33& Value, lcStep Step, bool AddKey); template void lcObjectKeyArray::InsertTime(lcStep Start, lcStep Time); template void lcObjectKeyArray::RemoveTime(lcStep Start, lcStep Time); template void lcObjectKeyArray::SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const { constexpr int Count = sizeof(T) / sizeof(float); for (const lcObjectKey& Key : mKeys) { Stream << QLatin1String("0 !LEOCAD ") << KeyName << Key.Step << ' '; for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++) Stream << ((float*)&Key.Value)[ValueIdx] << ' '; Stream << QLatin1String("\r\n"); } } template void lcObjectKeyArray::LoadKeysLDraw(QTextStream& Stream) { QString Token; Stream >> Token; const int Step = Token.toInt(); T Value; constexpr int Count = sizeof(T) / sizeof(float); for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++) Stream >> ((float*)&Value)[ValueIdx]; ChangeKey(Value, Step, true); } template const T& lcObjectKeyArray::CalculateKey(lcStep Step) const { const lcObjectKey* PreviousKey = &mKeys[0]; for (const lcObjectKey& Key : mKeys) { if (Key.Step > Step) break; PreviousKey = &Key; } return PreviousKey->Value; } template void lcObjectKeyArray::ChangeKey(const T& Value, lcStep Step, bool AddKey) { for (typename std::vector>::iterator KeyIt = mKeys.begin(); KeyIt != mKeys.end(); KeyIt++) { if (KeyIt->Step < Step) continue; if (KeyIt->Step == Step) KeyIt->Value = Value; else if (AddKey) mKeys.insert(KeyIt, lcObjectKey{ Step, Value }); else if (KeyIt == mKeys.begin()) KeyIt->Value = Value; else { KeyIt = KeyIt - 1; KeyIt->Value = Value; } return; } if (AddKey || mKeys.empty()) mKeys.emplace_back(lcObjectKey{ Step, Value }); else mKeys.back().Value = Value; } template void lcObjectKeyArray::InsertTime(lcStep Start, lcStep Time) { bool EndKey = false; for (typename std::vector>::iterator KeyIt = mKeys.begin(); KeyIt != mKeys.end();) { if ((KeyIt->Step < Start) || (KeyIt->Step == 1)) { KeyIt++; continue; } if (EndKey) { KeyIt = mKeys.erase(KeyIt); continue; } if (KeyIt->Step >= LC_STEP_MAX - Time) { KeyIt->Step = LC_STEP_MAX; EndKey = true; } else KeyIt->Step += Time; KeyIt++; } } template void lcObjectKeyArray::RemoveTime(lcStep Start, lcStep Time) { for (typename std::vector>::iterator KeyIt = mKeys.begin(); KeyIt != mKeys.end();) { if ((KeyIt->Step < Start) || (KeyIt->Step == 1)) { KeyIt++; continue; } if (KeyIt->Step < Start + Time) { KeyIt = mKeys.erase(KeyIt); continue; } KeyIt->Step -= Time; KeyIt++; } } leocad-23.03/common/object.h000066400000000000000000000057311440571307300156710ustar00rootroot00000000000000#pragma once #include "lc_math.h" #include "lc_array.h" enum class lcObjectType { Piece, Camera, Light }; template struct lcObjectKey { lcStep Step; T Value; }; template class lcObjectKeyArray { public: int GetSize() const { return static_cast(mKeys.size()); } bool IsEmpty() const { return mKeys.empty(); } void RemoveAll() { mKeys.clear(); } void SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const; void LoadKeysLDraw(QTextStream& Stream); const T& CalculateKey(lcStep Step) const; void ChangeKey(const T& Value, lcStep Step, bool AddKey); void InsertTime(lcStep Start, lcStep Time); void RemoveTime(lcStep Start, lcStep Time); protected: std::vector> mKeys; }; struct lcObjectSection { lcObject* Object = nullptr; quint32 Section = 0; }; struct lcPieceInfoRayTest { const PieceInfo* Info = nullptr; lcMatrix44 Transform; lcVector3 Plane; }; struct lcObjectRayTest { lcCamera* ViewCamera; bool PiecesOnly; bool IgnoreSelected; lcVector3 Start; lcVector3 End; float Distance = FLT_MAX; lcObjectSection ObjectSection; lcPieceInfoRayTest PieceInfoRayTest; }; struct lcObjectBoxTest { lcCamera* ViewCamera; lcVector4 Planes[6]; lcArray Objects; }; #define LC_OBJECT_TRANSFORM_MOVE_X 0x001 #define LC_OBJECT_TRANSFORM_MOVE_Y 0x002 #define LC_OBJECT_TRANSFORM_MOVE_Z 0x004 #define LC_OBJECT_TRANSFORM_ROTATE_X 0x010 #define LC_OBJECT_TRANSFORM_ROTATE_Y 0x020 #define LC_OBJECT_TRANSFORM_ROTATE_Z 0x040 #define LC_OBJECT_TRANSFORM_SCALE_X 0x100 #define LC_OBJECT_TRANSFORM_SCALE_Y 0x200 #define LC_OBJECT_TRANSFORM_SCALE_Z 0x400 class lcObject { public: lcObject(lcObjectType ObjectType); virtual ~lcObject(); lcObject(const lcObject&) = delete; lcObject(lcObject&&) = delete; lcObject& operator=(const lcObject&) = delete; lcObject& operator=(lcObject&&) = delete; public: bool IsPiece() const { return mObjectType == lcObjectType::Piece; } bool IsCamera() const { return mObjectType == lcObjectType::Camera; } bool IsLight() const { return mObjectType == lcObjectType::Light; } lcObjectType GetType() const { return mObjectType; } virtual bool IsSelected() const = 0; virtual bool IsSelected(quint32 Section) const = 0; virtual void SetSelected(bool Selected) = 0; virtual void SetSelected(quint32 Section, bool Selected) = 0; virtual bool IsFocused() const = 0; virtual bool IsFocused(quint32 Section) const = 0; virtual void SetFocused(quint32 Section, bool Focused) = 0; virtual quint32 GetFocusSection() const = 0; virtual quint32 GetAllowedTransforms() const = 0; virtual lcVector3 GetSectionPosition(quint32 Section) const = 0; virtual void RayTest(lcObjectRayTest& ObjectRayTest) const = 0; virtual void BoxTest(lcObjectBoxTest& ObjectBoxTest) const = 0; virtual void DrawInterface(lcContext* Context, const lcScene& Scene) const = 0; virtual void RemoveKeyFrames() = 0; virtual QString GetName() const = 0; private: lcObjectType mObjectType; }; leocad-23.03/common/piece.cpp000066400000000000000000000674501440571307300160510ustar00rootroot00000000000000#include "lc_global.h" #include "lc_mesh.h" #include "lc_colors.h" #include #include #include #include "pieceinf.h" #include "piece.h" #include "group.h" #include "lc_file.h" #include "lc_application.h" #include "lc_library.h" #include "lc_context.h" #include "lc_scene.h" #include "lc_qutils.h" #include "lc_synth.h" constexpr float LC_PIECE_CONTROL_POINT_SIZE = 10.0f; lcPiece::lcPiece(PieceInfo* Info) : lcObject(lcObjectType::Piece) { mMesh = nullptr; SetPieceInfo(Info, QString(), true); mFocusedSection = LC_PIECE_SECTION_INVALID; mColorIndex = gDefaultColor; mColorCode = 16; mStepShow = 1; mStepHide = LC_STEP_MAX; mGroup = nullptr; mFileLine = -1; mPivotMatrix = lcMatrix44Identity(); } lcPiece::lcPiece(const lcPiece& Other) : lcObject(lcObjectType::Piece) { mMesh = nullptr; SetPieceInfo(Other.mPieceInfo, Other.mID, true); mHidden = Other.mHidden; mSelected = Other.mSelected; mFocusedSection = LC_PIECE_SECTION_INVALID; mColorIndex = Other.mColorIndex; mColorCode = Other.mColorCode; mStepShow = Other.mStepShow; mStepHide = Other.mStepHide; mGroup = Other.mGroup; mFileLine = -1; mPivotMatrix = Other.mPivotMatrix; mPivotPointValid = Other.mPivotPointValid; mPositionKeys = Other.mPositionKeys; mRotationKeys = Other.mRotationKeys; mControlPoints = Other.mControlPoints; UpdateMesh(); } lcPiece::~lcPiece() { if (mPieceInfo) { lcPiecesLibrary* Library = lcGetPiecesLibrary(); Library->ReleasePieceInfo(mPieceInfo); } delete mMesh; } void lcPiece::SetPieceInfo(PieceInfo* Info, const QString& ID, bool Wait) { lcPiecesLibrary* Library = lcGetPiecesLibrary(); mPieceInfo = Info; if (mPieceInfo) Library->LoadPieceInfo(mPieceInfo, Wait, true); if (!ID.isEmpty()) mID = ID; else if (mPieceInfo) mID = mPieceInfo->mFileName; else mID.clear(); mControlPoints.RemoveAll(); delete mMesh; mMesh = nullptr; const lcSynthInfo* SynthInfo = mPieceInfo ? mPieceInfo->GetSynthInfo() : nullptr; if (SynthInfo) { SynthInfo->GetDefaultControlPoints(mControlPoints); UpdateMesh(); } } void lcPiece::UpdateID() { mID = mPieceInfo->mFileName; } void lcPiece::SaveLDraw(QTextStream& Stream) const { const QLatin1String LineEnding("\r\n"); if (mStepHide != LC_STEP_MAX) Stream << QLatin1String("0 !LEOCAD PIECE STEP_HIDE ") << mStepHide << LineEnding; if (IsHidden()) Stream << QLatin1String("0 !LEOCAD PIECE HIDDEN") << LineEnding; if (mPivotPointValid) { const float* PivotMatrix = mPivotMatrix; const float PivotNumbers[12] = { PivotMatrix[12], -PivotMatrix[14], PivotMatrix[13], PivotMatrix[0], -PivotMatrix[8], PivotMatrix[4], -PivotMatrix[2], PivotMatrix[10], -PivotMatrix[6], PivotMatrix[1], -PivotMatrix[9], PivotMatrix[5] }; Stream << QLatin1String("0 !LEOCAD PIECE PIVOT "); for (int NumberIdx = 0; NumberIdx < 12; NumberIdx++) Stream << ' ' << lcFormatValue(PivotNumbers[NumberIdx], NumberIdx < 3 ? 4 : 6); Stream << LineEnding; } if (mPositionKeys.GetSize() > 1) mPositionKeys.SaveKeysLDraw(Stream, "PIECE POSITION_KEY "); if (mRotationKeys.GetSize() > 1) mRotationKeys.SaveKeysLDraw(Stream, "PIECE ROTATION_KEY "); Stream << "1 " << mColorCode << ' '; const float* Matrix = mModelWorld; const float Numbers[12] = { Matrix[12], -Matrix[14], Matrix[13], Matrix[0], -Matrix[8], Matrix[4], -Matrix[2], Matrix[10], -Matrix[6], Matrix[1], -Matrix[9], Matrix[5] }; for (int NumberIdx = 0; NumberIdx < 12; NumberIdx++) Stream << lcFormatValue(Numbers[NumberIdx], NumberIdx < 3 ? 4 : 6) << ' '; Stream << mID << LineEnding; } bool lcPiece::ParseLDrawLine(QTextStream& Stream) { while (!Stream.atEnd()) { QString Token; Stream >> Token; if (Token == QLatin1String("STEP_HIDE")) Stream >> mStepHide; else if (Token == QLatin1String("HIDDEN")) SetHidden(true); else if (Token == QLatin1String("PIVOT")) { float PivotNumbers[12]; for (int TokenIdx = 0; TokenIdx < 12; TokenIdx++) Stream >> PivotNumbers[TokenIdx]; const lcMatrix44 PivotMatrix(lcVector4( PivotNumbers[3], PivotNumbers[9], -PivotNumbers[6], 0.0f), lcVector4(PivotNumbers[5], PivotNumbers[11], -PivotNumbers[8], 0.0f), lcVector4(-PivotNumbers[4], -PivotNumbers[10], PivotNumbers[7], 0.0f), lcVector4(PivotNumbers[0], PivotNumbers[2], -PivotNumbers[1], 1.0f)); mPivotMatrix = PivotMatrix; mPivotPointValid = true; } else if (Token == QLatin1String("POSITION_KEY")) mPositionKeys.LoadKeysLDraw(Stream); else if (Token == QLatin1String("ROTATION_KEY")) mRotationKeys.LoadKeysLDraw(Stream); } return false; } bool lcPiece::FileLoad(lcFile& file) { quint8 version, ch; version = file.ReadU8(); if (version > 12) // LeoCAD 0.80 return false; const float PositionScale = (version < 12) ? 25.0f : 1.0f; if (version > 8) { if (file.ReadU8() != 1) return false; quint16 time; float param[4]; quint8 type; quint32 n; file.ReadU32(&n, 1); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 4); file.ReadU8(&type, 1); if (type == 0) mPositionKeys.ChangeKey(lcVector3(param[0], param[1], param[2]) * PositionScale, time, true); else if (type == 1) mRotationKeys.ChangeKey(lcMatrix33FromAxisAngle(lcVector3(param[0], param[1], param[2]), param[3] * LC_DTOR), time, true); } file.ReadU32(&n, 1); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 4); file.ReadU8(&type, 1); } } if (version < 9) { quint16 time; quint8 type; if (version > 5) { quint32 keys; float param[4]; file.ReadU32(&keys, 1); while (keys--) { file.ReadFloats(param, 4); file.ReadU16(&time, 1); file.ReadU8(&type, 1); if (type == 0) mPositionKeys.ChangeKey(lcVector3(param[0], param[1], param[2]) * PositionScale, time, true); else if (type == 1) mRotationKeys.ChangeKey(lcMatrix33FromAxisAngle(lcVector3(param[0], param[1], param[2]), param[3] * LC_DTOR), time, true); } file.ReadU32(&keys, 1); while (keys--) { file.ReadFloats(param, 4); file.ReadU16(&time, 1); file.ReadU8(&type, 1); } } else { if (version > 2) { file.ReadU8(&ch, 1); while (ch--) { lcMatrix44 ModelWorld; if (version > 3) { file.ReadFloats(ModelWorld, 16); } else { lcVector3 Translation; float Rotation[3]; file.ReadFloats(Translation, 3); file.ReadFloats(Rotation, 3); ModelWorld = lcMatrix44Translation(Translation); ModelWorld = lcMul(lcMatrix44RotationZ(Rotation[2] * LC_DTOR), lcMul(lcMatrix44RotationY(Rotation[1] * LC_DTOR), lcMul(lcMatrix44RotationX(Rotation[0] * LC_DTOR), ModelWorld))); } quint8 b; file.ReadU8(&b, 1); time = b; mPositionKeys.ChangeKey(ModelWorld.GetTranslation() * PositionScale, 1, true); mRotationKeys.ChangeKey(lcMatrix33(ModelWorld), time, true); qint32 bl; file.ReadS32(&bl, 1); } } else { lcVector3 Translation; float Rotation[3]; file.ReadFloats(Translation, 3); file.ReadFloats(Rotation, 3); lcMatrix44 ModelWorld = lcMatrix44Translation(Translation); ModelWorld = lcMul(lcMatrix44RotationZ(Rotation[2] * LC_DTOR), lcMul(lcMatrix44RotationY(Rotation[1] * LC_DTOR), lcMul(lcMatrix44RotationX(Rotation[0] * LC_DTOR), ModelWorld))); mPositionKeys.ChangeKey(lcVector3(ModelWorld.r[3][0], ModelWorld.r[3][1], ModelWorld.r[3][2]) * PositionScale, 1, true); mRotationKeys.ChangeKey(lcMatrix33(ModelWorld), 1, true); } } } // Common to all versions. char name[LC_PIECE_NAME_LEN]; if (version < 10) { memset(name, 0, LC_PIECE_NAME_LEN); file.ReadBuffer(name, 9); } else file.ReadBuffer(name, LC_PIECE_NAME_LEN); strcat(name, ".dat"); PieceInfo* pInfo = lcGetPiecesLibrary()->FindPiece(name, nullptr, true, false); SetPieceInfo(pInfo, QString(), true); // 11 (0.77) if (version < 11) { quint8 Color; file.ReadU8(&Color, 1); if (version < 5) mColorCode = lcGetColorCodeFromOriginalColor(Color); else mColorCode = lcGetColorCodeFromExtendedColor(Color); } else file.ReadU32(&mColorCode, 1); mColorIndex = lcGetColorIndex(mColorCode); quint8 Step; file.ReadU8(&Step, 1); mStepShow = Step; if (version > 1) { file.ReadU8(&Step, 1); mStepHide = Step == 255 ? LC_STEP_MAX : Step; } else mStepHide = LC_STEP_MAX; if (version > 5) { file.ReadU16(); // m_nFrameShow file.ReadU16(); // m_nFrameHide if (version > 7) { quint8 Hidden; file.ReadU8(&Hidden, 1); if (Hidden & 1) mHidden = true; file.ReadU8(&ch, 1); file.Seek(ch, SEEK_CUR); } else { qint32 hide; file.ReadS32(&hide, 1); if (hide != 0) mHidden = true; file.Seek(81, SEEK_CUR); } // 7 (0.64) qint32 i = -1; if (version > 6) file.ReadS32(&i, 1); mGroup = (lcGroup*)(quintptr)i; } else { file.ReadU8(&ch, 1); if (ch == 0) mGroup = (lcGroup*)-1; else mGroup = (lcGroup*)(quintptr)ch; file.ReadU8(&ch, 1); if (ch & 0x01) mHidden = true; } return true; } void lcPiece::Initialize(const lcMatrix44& WorldMatrix, lcStep Step) { mStepShow = Step; if (mPositionKeys.IsEmpty()) mPositionKeys.ChangeKey(WorldMatrix.GetTranslation(), 1, true); if (mRotationKeys.IsEmpty()) mRotationKeys.ChangeKey(lcMatrix33(WorldMatrix), 1, true); UpdatePosition(Step); } void lcPiece::InsertTime(lcStep Start, lcStep Time) { if (mStepShow >= Start) { if (mStepShow < LC_STEP_MAX - Time) mStepShow += Time; else mStepShow = LC_STEP_MAX; } if (mStepHide >= Start) { if (mStepHide < LC_STEP_MAX - Time) mStepHide += Time; else mStepHide = LC_STEP_MAX; } if (mStepShow >= mStepHide) { if (mStepShow != LC_STEP_MAX) mStepHide = mStepShow + 1; else { mStepShow = LC_STEP_MAX - 1; mStepHide = LC_STEP_MAX; } } mPositionKeys.InsertTime(Start, Time); mRotationKeys.InsertTime(Start, Time); } void lcPiece::RemoveTime(lcStep Start, lcStep Time) { if (mStepShow >= Start) { if (mStepShow > Time) mStepShow -= Time; else mStepShow = 1; } if (mStepHide != LC_STEP_MAX) { if (mStepHide > Time) mStepHide -= Time; else mStepHide = 1; } if (mStepShow >= mStepHide) { if (mStepShow != LC_STEP_MAX) mStepHide = mStepShow + 1; else { mStepShow = LC_STEP_MAX - 1; mStepHide = LC_STEP_MAX; } } mPositionKeys.RemoveTime(Start, Time); mRotationKeys.RemoveTime(Start, Time); } void lcPiece::RayTest(lcObjectRayTest& ObjectRayTest) const { const lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(mModelWorld); const lcVector3 Start = lcMul31(ObjectRayTest.Start, InverseWorldMatrix); const lcVector3 End = lcMul31(ObjectRayTest.End, InverseWorldMatrix); if (mMesh) { if (mMesh->MinIntersectDist(Start, End, ObjectRayTest.Distance, ObjectRayTest.PieceInfoRayTest.Plane)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_PIECE_SECTION_POSITION; ObjectRayTest.PieceInfoRayTest.Transform = mModelWorld; } } else { if (mPieceInfo->MinIntersectDist(Start, End, ObjectRayTest.Distance, ObjectRayTest.PieceInfoRayTest)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_PIECE_SECTION_POSITION; ObjectRayTest.PieceInfoRayTest.Transform = lcMul(ObjectRayTest.PieceInfoRayTest.Transform, mModelWorld); } } if (AreControlPointsVisible()) { const lcVector3 Min(-LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE); const lcVector3 Max(LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE); for (int ControlPointIdx = 0; ControlPointIdx < mControlPoints.GetSize(); ControlPointIdx++) { const lcMatrix44 InverseTransform = lcMatrix44AffineInverse(mControlPoints[ControlPointIdx].Transform); const lcVector3 PointStart = lcMul31(Start, InverseTransform); const lcVector3 PointEnd = lcMul31(End, InverseTransform); float Distance; lcVector3 Plane; if (lcBoundingBoxRayIntersectDistance(Min, Max, PointStart, PointEnd, &Distance, nullptr, &Plane)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_PIECE_SECTION_CONTROL_POINT_FIRST + ControlPointIdx; ObjectRayTest.Distance = Distance; ObjectRayTest.PieceInfoRayTest.Plane = Plane; } } } } void lcPiece::BoxTest(lcObjectBoxTest& ObjectBoxTest) const { if (mPieceInfo->BoxTest(mModelWorld, ObjectBoxTest.Planes)) ObjectBoxTest.Objects.Add(const_cast(this)); } void lcPiece::DrawInterface(lcContext* Context, const lcScene& Scene) const { const lcPreferences& Preferences = lcGetPreferences(); const float LineWidth = Preferences.mLineWidth; Context->SetLineWidth(2.0f * LineWidth); const lcBoundingBox& BoundingBox = GetBoundingBox(); const lcVector3& Min = BoundingBox.Min; const lcVector3& Max = BoundingBox.Max; lcVector3 Edge((Max - Min) * 0.33f); const float LineVerts[48][3] = { { Max[0], Max[1], Max[2] }, { Max[0] - Edge[0], Max[1], Max[2] }, { Max[0], Max[1], Max[2] }, { Max[0], Max[1] - Edge[1], Max[2] }, { Max[0], Max[1], Max[2] }, { Max[0], Max[1], Max[2] - Edge[2] }, { Min[0], Max[1], Max[2] }, { Min[0] + Edge[0], Max[1], Max[2] }, { Min[0], Max[1], Max[2] }, { Min[0], Max[1] - Edge[1], Max[2] }, { Min[0], Max[1], Max[2] }, { Min[0], Max[1], Max[2] - Edge[2] }, { Max[0], Min[1], Max[2] }, { Max[0] - Edge[0], Min[1], Max[2] }, { Max[0], Min[1], Max[2] }, { Max[0], Min[1] + Edge[1], Max[2] }, { Max[0], Min[1], Max[2] }, { Max[0], Min[1], Max[2] - Edge[2] }, { Min[0], Min[1], Max[2] }, { Min[0] + Edge[0], Min[1], Max[2] }, { Min[0], Min[1], Max[2] }, { Min[0], Min[1] + Edge[1], Max[2] }, { Min[0], Min[1], Max[2] }, { Min[0], Min[1], Max[2] - Edge[2] }, { Max[0], Max[1], Min[2] }, { Max[0] - Edge[0], Max[1], Min[2] }, { Max[0], Max[1], Min[2] }, { Max[0], Max[1] - Edge[1], Min[2] }, { Max[0], Max[1], Min[2] }, { Max[0], Max[1], Min[2] + Edge[2] }, { Min[0], Max[1], Min[2] }, { Min[0] + Edge[0], Max[1], Min[2] }, { Min[0], Max[1], Min[2] }, { Min[0], Max[1] - Edge[1], Min[2] }, { Min[0], Max[1], Min[2] }, { Min[0], Max[1], Min[2] + Edge[2] }, { Max[0], Min[1], Min[2] }, { Max[0] - Edge[0], Min[1], Min[2] }, { Max[0], Min[1], Min[2] }, { Max[0], Min[1] + Edge[1], Min[2] }, { Max[0], Min[1], Min[2] }, { Max[0], Min[1], Min[2] + Edge[2] }, { Min[0], Min[1], Min[2] }, { Min[0] + Edge[0], Min[1], Min[2] }, { Min[0], Min[1], Min[2] }, { Min[0], Min[1] + Edge[1], Min[2] }, { Min[0], Min[1], Min[2] }, { Min[0], Min[1], Min[2] + Edge[2] }, }; const lcMatrix44 WorldMatrix = Scene.ApplyActiveSubmodelTransform(mModelWorld); Context->SetMaterial(lcMaterialType::UnlitColor); Context->SetWorldMatrix(WorldMatrix); if (IsFocused(LC_PIECE_SECTION_POSITION)) { const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor); Context->SetColor(FocusedColor); } else { const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor); Context->SetColor(SelectedColor); } Context->SetVertexBufferPointer(LineVerts); Context->SetVertexFormatPosition(3); Context->DrawPrimitives(GL_LINES, 0, 48); if (IsPivotPointVisible()) { constexpr float Size = 5.0f; constexpr float Verts[8 * 3] = { -Size, -Size, -Size, -Size, Size, -Size, Size, Size, -Size, Size, -Size, -Size, -Size, -Size, Size, -Size, Size, Size, Size, Size, Size, Size, -Size, Size }; const GLushort Indices[24] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 }; Context->SetWorldMatrix(lcMul(mPivotMatrix, WorldMatrix)); Context->SetVertexBufferPointer(Verts); Context->SetVertexFormatPosition(3); Context->SetIndexBufferPointer(Indices); Context->DrawIndexedPrimitives(GL_LINES, 24, GL_UNSIGNED_SHORT, 0); } if (!mControlPoints.IsEmpty() && AreControlPointsVisible()) { float Verts[8 * 3]; float* CurVert = Verts; lcVector3 CubeMin(-LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE); lcVector3 CubeMax(LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE); *CurVert++ = CubeMin[0]; *CurVert++ = CubeMin[1]; *CurVert++ = CubeMin[2]; *CurVert++ = CubeMin[0]; *CurVert++ = CubeMax[1]; *CurVert++ = CubeMin[2]; *CurVert++ = CubeMax[0]; *CurVert++ = CubeMax[1]; *CurVert++ = CubeMin[2]; *CurVert++ = CubeMax[0]; *CurVert++ = CubeMin[1]; *CurVert++ = CubeMin[2]; *CurVert++ = CubeMin[0]; *CurVert++ = CubeMin[1]; *CurVert++ = CubeMax[2]; *CurVert++ = CubeMin[0]; *CurVert++ = CubeMax[1]; *CurVert++ = CubeMax[2]; *CurVert++ = CubeMax[0]; *CurVert++ = CubeMax[1]; *CurVert++ = CubeMax[2]; *CurVert++ = CubeMax[0]; *CurVert++ = CubeMin[1]; *CurVert++ = CubeMax[2]; const GLushort Indices[36] = { 0, 1, 2, 0, 2, 3, 7, 6, 5, 7, 5, 4, 5, 1, 0, 4, 5, 0, 7, 3, 2, 6, 7, 2, 0, 3, 7, 0, 7, 4, 6, 2, 1, 5, 6, 1 }; Context->EnableColorBlend(true); Context->EnableCullFace(true); const lcVector4 ControlPointColor = lcVector4FromColor(Preferences.mControlPointColor); const lcVector4 ControlPointFocusedColor = lcVector4FromColor(Preferences.mControlPointFocusedColor); for (int ControlPointIdx = 0; ControlPointIdx < mControlPoints.GetSize(); ControlPointIdx++) { Context->SetWorldMatrix(lcMul(mControlPoints[ControlPointIdx].Transform, WorldMatrix)); Context->SetVertexBufferPointer(Verts); Context->SetVertexFormatPosition(3); Context->SetIndexBufferPointer(Indices); if (IsFocused(LC_PIECE_SECTION_CONTROL_POINT_FIRST + ControlPointIdx)) Context->SetColor(ControlPointFocusedColor); else Context->SetColor(ControlPointColor); Context->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); } Context->EnableCullFace(false); Context->EnableColorBlend(false); } } void lcPiece::RemoveKeyFrames() { mPositionKeys.RemoveAll(); mPositionKeys.ChangeKey(mModelWorld.GetTranslation(), 1, true); mRotationKeys.RemoveAll(); mRotationKeys.ChangeKey(lcMatrix33(mModelWorld), 1, true); } void lcPiece::AddMainModelRenderMeshes(lcScene* Scene, bool Highlight, bool Fade) const { lcRenderMeshState RenderMeshState = lcRenderMeshState::Default; bool ParentActive = false; if (Highlight) RenderMeshState = lcRenderMeshState::Highlighted; if (Fade) RenderMeshState = lcRenderMeshState::Faded; if (Scene->GetDrawInterface()) { const lcPiece* ActiveSubmodelInstance = Scene->GetActiveSubmodelInstance(); if (!ActiveSubmodelInstance) RenderMeshState = IsFocused() ? lcRenderMeshState::Focused : (IsSelected() ? lcRenderMeshState::Selected : RenderMeshState); else if (ActiveSubmodelInstance == this) ParentActive = true; else RenderMeshState = lcRenderMeshState::Faded; } if (!mMesh) mPieceInfo->AddRenderMeshes(Scene, mModelWorld, mColorIndex, RenderMeshState, ParentActive); else Scene->AddMesh(mMesh, mModelWorld, mColorIndex, RenderMeshState); if (RenderMeshState == lcRenderMeshState::Focused || RenderMeshState == lcRenderMeshState::Selected) Scene->AddInterfaceObject(this); } void lcPiece::AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const { int ColorIndex = mColorIndex; if (ColorIndex == gDefaultColor) ColorIndex = DefaultColorIndex; const lcPiece* ActiveSubmodelInstance = Scene->GetActiveSubmodelInstance(); if (ActiveSubmodelInstance == this) RenderMeshState = lcRenderMeshState::Default; else if (ParentActive) RenderMeshState = IsFocused() ? lcRenderMeshState::Focused : (IsSelected() ? lcRenderMeshState::Selected : lcRenderMeshState::Default); if (!mMesh) mPieceInfo->AddRenderMeshes(Scene, lcMul(mModelWorld, WorldMatrix), ColorIndex, RenderMeshState, ActiveSubmodelInstance == this); else Scene->AddMesh(mMesh, lcMul(mModelWorld, WorldMatrix), ColorIndex, RenderMeshState); if (ParentActive && (RenderMeshState == lcRenderMeshState::Focused || RenderMeshState == lcRenderMeshState::Selected)) Scene->AddInterfaceObject(this); } void lcPiece::SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const { mPieceInfo->CompareBoundingBox(lcMul(mModelWorld, WorldMatrix), Min, Max); } void lcPiece::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector& Points) const { if (!mMesh) mPieceInfo->AddSubModelBoundingBoxPoints(lcMul(mModelWorld, WorldMatrix), Points); else { lcVector3 BoxPoints[8]; lcGetBoxCorners(mMesh->mBoundingBox, BoxPoints); for (int i = 0; i < 8; i++) Points.emplace_back(lcMul31(BoxPoints[i], mModelWorld)); } } void lcPiece::MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance) { const quint32 Section = GetFocusSection(); if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID) { const lcVector3 Position = mModelWorld.GetTranslation() + Distance; SetPosition(Position, Step, AddKey); mModelWorld.SetTranslation(Position); } else { const int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST; if (ControlPointIndex >= 0 && ControlPointIndex < mControlPoints.GetSize()) { const lcMatrix33 InverseWorldMatrix = lcMatrix33AffineInverse(lcMatrix33(mModelWorld)); lcMatrix44& Transform = mControlPoints[ControlPointIndex].Transform; Transform.SetTranslation(Transform.GetTranslation() + lcMul(Distance, InverseWorldMatrix)); } UpdateMesh(); } } void lcPiece::Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame) { const quint32 Section = GetFocusSection(); if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID) { lcVector3 Distance = mModelWorld.GetTranslation() - Center; const lcMatrix33 LocalToWorldMatrix = lcMatrix33(mModelWorld); const lcMatrix33 LocalToFocusMatrix = lcMul(LocalToWorldMatrix, RotationFrame); lcMatrix33 NewLocalToWorldMatrix = lcMul(LocalToFocusMatrix, RotationMatrix); const lcMatrix33 WorldToLocalMatrix = lcMatrix33AffineInverse(LocalToWorldMatrix); Distance = lcMul(Distance, WorldToLocalMatrix); Distance = lcMul(Distance, NewLocalToWorldMatrix); NewLocalToWorldMatrix.Orthonormalize(); SetPosition(Center + Distance, Step, AddKey); SetRotation(NewLocalToWorldMatrix, Step, AddKey); } else { const int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST; if (ControlPointIndex >= 0 && ControlPointIndex < mControlPoints.GetSize()) { lcMatrix44& Transform = mControlPoints[ControlPointIndex].Transform; const lcMatrix33 PieceWorldMatrix(mModelWorld); const lcMatrix33 LocalToWorldMatrix = lcMul(lcMatrix33(Transform), PieceWorldMatrix); const lcMatrix33 LocalToFocusMatrix = lcMul(LocalToWorldMatrix, RotationFrame); lcMatrix33 NewLocalToWorldMatrix = lcMul(lcMul(LocalToFocusMatrix, RotationMatrix), lcMatrix33AffineInverse(PieceWorldMatrix)); NewLocalToWorldMatrix.Orthonormalize(); Transform = lcMatrix44(NewLocalToWorldMatrix, Transform.GetTranslation()); } UpdateMesh(); } } void lcPiece::MovePivotPoint(const lcVector3& Distance) { if (!IsFocused(LC_PIECE_SECTION_POSITION)) return; mPivotMatrix.SetTranslation(mPivotMatrix.GetTranslation() + lcMul30(Distance, lcMatrix44AffineInverse(mModelWorld))); mPivotPointValid = true; } void lcPiece::RotatePivotPoint(const lcMatrix33& RotationMatrix) { if (!IsFocused(LC_PIECE_SECTION_POSITION)) return; lcMatrix33 NewPivotRotationMatrix = lcMul(RotationMatrix, lcMatrix33(mPivotMatrix)); NewPivotRotationMatrix.Orthonormalize(); mPivotMatrix = lcMatrix44(NewPivotRotationMatrix, mPivotMatrix.GetTranslation()); mPivotPointValid = true; } quint32 lcPiece::GetAllowedTransforms() const { constexpr quint32 Move = LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z; constexpr quint32 Rotate = LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z; const quint32 Section = GetFocusSection(); if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID) return Move | Rotate; const lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo(); if (SynthInfo) { if (SynthInfo->IsUnidirectional()) return LC_OBJECT_TRANSFORM_MOVE_Z; if (SynthInfo->IsCurve()) return Move | Rotate | LC_OBJECT_TRANSFORM_SCALE_X; if (SynthInfo->IsNondirectional()) return Move; } return 0; } bool lcPiece::CanAddControlPoint() const { if (mControlPoints.GetSize() >= LC_MAX_CONTROL_POINTS) return false; const lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo(); return SynthInfo && SynthInfo->CanAddControlPoints(); } bool lcPiece::CanRemoveControlPoint() const { const quint32 Section = GetFocusSection(); return Section >= LC_PIECE_SECTION_CONTROL_POINT_FIRST && Section <= LC_PIECE_SECTION_CONTROL_POINT_LAST && mControlPoints.GetSize() > 2; } bool lcPiece::InsertControlPoint(const lcVector3& WorldStart, const lcVector3& WorldEnd) { if (!CanAddControlPoint()) return false; const lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(mModelWorld); const lcVector3 Start = lcMul31(WorldStart, InverseWorldMatrix); const lcVector3 End = lcMul31(WorldEnd, InverseWorldMatrix); const lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo(); const int ControlPointIndex = SynthInfo->InsertControlPoint(mControlPoints, Start, End); if (ControlPointIndex) { SetFocused(GetFocusSection(), false); SetFocused(LC_PIECE_SECTION_CONTROL_POINT_FIRST + ControlPointIndex, true); UpdateMesh(); return true; } return false; } bool lcPiece::RemoveFocusedControlPoint() { const int ControlPointIndex = GetFocusSection() - LC_PIECE_SECTION_CONTROL_POINT_FIRST; if (ControlPointIndex < 0 || ControlPointIndex >= mControlPoints.GetSize() || mControlPoints.GetSize() <= 2) return false; SetFocused(GetFocusSection(), false); SetFocused(LC_PIECE_SECTION_POSITION, true); mControlPoints.RemoveIndex(ControlPointIndex); UpdateMesh(); return true; } void lcPiece::VerifyControlPoints(lcArray& ControlPoints) const { const lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo(); if (!SynthInfo) { ControlPoints.RemoveAll(); } else { if (ControlPoints.GetSize() > LC_MAX_CONTROL_POINTS) ControlPoints.SetSize(LC_MAX_CONTROL_POINTS); SynthInfo->VerifyControlPoints(ControlPoints); } } QString lcPiece::GetName() const { return QString::fromLatin1(mPieceInfo->m_strDescription); } bool lcPiece::IsVisible(lcStep Step) const { return !mHidden && (mStepShow <= Step) && (mStepHide > Step || mStepHide == LC_STEP_MAX); } bool lcPiece::IsVisibleInSubModel() const { return (mStepHide == LC_STEP_MAX) && !mHidden; } void lcPiece::GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector& ModelParts) const { if (!IsVisibleInSubModel()) return; int ColorIndex = mColorIndex; if (ColorIndex == gDefaultColor) ColorIndex = DefaultColorIndex; if (!mMesh) mPieceInfo->GetModelParts(lcMul(mModelWorld, WorldMatrix), ColorIndex, ModelParts); else ModelParts.emplace_back(lcModelPartsEntry{ lcMul(mModelWorld, WorldMatrix), mPieceInfo, mMesh, ColorIndex }); } const lcBoundingBox& lcPiece::GetBoundingBox() const { if (!mMesh) return mPieceInfo->GetBoundingBox(); else return mMesh->mBoundingBox; } void lcPiece::CompareBoundingBox(lcVector3& Min, lcVector3& Max) const { if (!mMesh) mPieceInfo->CompareBoundingBox(mModelWorld, Min, Max); else { lcVector3 Points[8]; lcGetBoxCorners(mMesh->mBoundingBox, Points); for (int i = 0; i < 8; i++) { const lcVector3 Point = lcMul31(Points[i], mModelWorld); Min = lcMin(Point, Min); Max = lcMax(Point, Max); } } } lcGroup* lcPiece::GetTopGroup() { return mGroup ? mGroup->GetTopGroup() : nullptr; } void lcPiece::UpdatePosition(lcStep Step) { const lcVector3 Position = mPositionKeys.CalculateKey(Step); const lcMatrix33 Rotation = mRotationKeys.CalculateKey(Step); mModelWorld = lcMatrix44(Rotation, Position); } void lcPiece::UpdateMesh() { delete mMesh; const lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo(); mMesh = SynthInfo ? SynthInfo->CreateMesh(mControlPoints) : nullptr; } leocad-23.03/common/piece.h000066400000000000000000000200361440571307300155030ustar00rootroot00000000000000#pragma once class PieceInfo; #include "object.h" #include "lc_colors.h" #include "lc_math.h" #define LC_MAX_CONTROL_POINTS 1000 enum lcPieceSection : quint32 { LC_PIECE_SECTION_INVALID = ~0U, LC_PIECE_SECTION_POSITION = 0, LC_PIECE_SECTION_CONTROL_POINT_FIRST, LC_PIECE_SECTION_CONTROL_POINT_LAST = LC_PIECE_SECTION_CONTROL_POINT_FIRST + LC_MAX_CONTROL_POINTS - 1, }; struct lcPieceControlPoint { lcMatrix44 Transform; float Scale; }; class lcPiece : public lcObject { public: lcPiece(PieceInfo* Info); lcPiece(const lcPiece& Other); ~lcPiece(); lcPiece(lcPiece&&) = delete; lcPiece& operator=(const lcPiece&) = delete; lcPiece& operator=(lcPiece&&) = delete; bool IsSelected() const override { return mSelected; } bool IsSelected(quint32 Section) const override { Q_UNUSED(Section); return mSelected; } void SetSelected(bool Selected) override { mSelected = Selected; if (!Selected) mFocusedSection = LC_PIECE_SECTION_INVALID; } void SetSelected(quint32 Section, bool Selected) override { Q_UNUSED(Section); mSelected = Selected; if (!Selected) mFocusedSection = LC_PIECE_SECTION_INVALID; } bool IsFocused() const override { return mFocusedSection != LC_PIECE_SECTION_INVALID; } bool IsFocused(quint32 Section) const override { return mFocusedSection == Section; } void SetFocused(quint32 Section, bool Focused) override { if (Focused) { mFocusedSection = Section; mSelected = true; } else mFocusedSection = LC_PIECE_SECTION_INVALID; } quint32 GetFocusSection() const override { return mFocusedSection; } quint32 GetAllowedTransforms() const override; lcVector3 GetSectionPosition(quint32 Section) const override { if (Section == LC_PIECE_SECTION_POSITION) { if (mPivotPointValid) return lcMul(mPivotMatrix, mModelWorld).GetTranslation(); else return mModelWorld.GetTranslation(); } else { const int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST; if (ControlPointIndex >= 0 && ControlPointIndex < mControlPoints.GetSize()) { const lcMatrix44& Transform = mControlPoints[ControlPointIndex].Transform; return lcMul(Transform, mModelWorld).GetTranslation(); } } return lcVector3(0.0f, 0.0f, 0.0f); } void SaveLDraw(QTextStream& Stream) const; bool ParseLDrawLine(QTextStream& Stream); void SetFileLine(int Line) { mFileLine = Line; } int GetFileLine() const { return mFileLine; } void RayTest(lcObjectRayTest& ObjectRayTest) const override; void BoxTest(lcObjectBoxTest& ObjectBoxTest) const override; void DrawInterface(lcContext* Context, const lcScene& Scene) const override; void RemoveKeyFrames() override; void AddMainModelRenderMeshes(lcScene* Scene, bool Highlight, bool Fade) const; void AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const; void SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const; void SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector& Points) const; void InsertTime(lcStep Start, lcStep Time); void RemoveTime(lcStep Start, lcStep Time); bool IsHidden() const { return mHidden; } void SetHidden(bool Hidden) { mHidden = Hidden; } const lcArray& GetControlPoints() const { return mControlPoints; } void SetControlPoints(const lcArray& ControlPoints) { mControlPoints = ControlPoints; UpdateMesh(); } void SetControlPointScale(int ControlPointIndex, float Scale) { mControlPoints[ControlPointIndex].Scale = Scale; UpdateMesh(); } const QString& GetID() const { return mID; } void UpdateID(); QString GetName() const override; bool IsVisible(lcStep Step) const; bool IsVisibleInSubModel() const; void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector& ModelParts) const; void Initialize(const lcMatrix44& WorldMatrix, lcStep Step); const lcBoundingBox& GetBoundingBox() const; void CompareBoundingBox(lcVector3& Min, lcVector3& Max) const; void SetPieceInfo(PieceInfo* Info, const QString& ID, bool Wait); bool FileLoad(lcFile& file); void UpdatePosition(lcStep Step); void MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance); void Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame); void MovePivotPoint(const lcVector3& Distance); void RotatePivotPoint(const lcMatrix33& RotationMatrix); bool CanAddControlPoint() const; bool CanRemoveControlPoint() const; bool InsertControlPoint(const lcVector3& WorldStart, const lcVector3& WorldEnd); bool RemoveFocusedControlPoint(); void VerifyControlPoints(lcArray& ControlPoints) const; lcGroup* GetTopGroup(); void SetGroup(lcGroup* Group) { mGroup = Group; } lcGroup* GetGroup() { return mGroup; } lcStep GetStepShow() const { return mStepShow; } lcStep GetStepHide() const { return mStepHide; } void SetStepHide(lcStep Step) { if (Step < 2) Step = 2; mStepHide = Step; if (mStepHide <= mStepShow) SetStepShow(mStepHide - 1); } void SetStepShow(lcStep Step) { if (Step == LC_STEP_MAX) Step = LC_STEP_MAX - 1; if (mStepShow != Step) { mFileLine = -1; mStepShow = Step; } if (mStepHide <= mStepShow) mStepHide = mStepShow + 1; } quint32 GetColorCode() const { return mColorCode; } void SetColorCode(quint32 ColorCode) { mColorCode = ColorCode; mColorIndex = lcGetColorIndex(ColorCode); } int GetColorIndex() const { return mColorIndex; } void SetColorIndex(int ColorIndex) { mColorIndex = ColorIndex; mColorCode = lcGetColorCode(ColorIndex); } void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey) { mPositionKeys.ChangeKey(Position, Step, AddKey); } void SetRotation(const lcMatrix33& Rotation, lcStep Step, bool AddKey) { mRotationKeys.ChangeKey(Rotation, Step, AddKey); } lcVector3 GetRotationCenter() const { const quint32 Section = GetFocusSection(); if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID) { if (mPivotPointValid) return lcMul31(mPivotMatrix.GetTranslation(), mModelWorld); else return mModelWorld.GetTranslation(); } else { const int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST; if (ControlPointIndex >= 0 && ControlPointIndex < mControlPoints.GetSize()) { const lcMatrix44& Transform = mControlPoints[ControlPointIndex].Transform; return lcMul31(Transform.GetTranslation(), mModelWorld); } return mModelWorld.GetTranslation(); } } lcMatrix33 GetRelativeRotation() const { const quint32 Section = GetFocusSection(); if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID) { if (mPivotPointValid) return lcMatrix33(lcMul(mModelWorld, mPivotMatrix)); else return lcMatrix33(mModelWorld); } else { const int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST; if (ControlPointIndex >= 0 && ControlPointIndex < mControlPoints.GetSize()) { const lcMatrix44& Transform = mControlPoints[ControlPointIndex].Transform; return lcMatrix33(lcMul(Transform, mModelWorld)); } return lcMatrix33Identity(); } } void ResetPivotPoint() { mPivotPointValid = false; mPivotMatrix = lcMatrix44Identity(); } public: PieceInfo* mPieceInfo; lcMatrix44 mModelWorld; lcMatrix44 mPivotMatrix; protected: void UpdateMesh(); bool IsPivotPointVisible() const { return mPivotPointValid && IsFocused(); } bool AreControlPointsVisible() const { return IsSelected(); } lcObjectKeyArray mPositionKeys; lcObjectKeyArray mRotationKeys; int mFileLine; QString mID; lcGroup* mGroup; int mColorIndex; quint32 mColorCode; lcStep mStepShow; lcStep mStepHide; bool mPivotPointValid = false; bool mHidden = false; bool mSelected = false; quint32 mFocusedSection; lcArray mControlPoints; lcMesh* mMesh; }; leocad-23.03/common/pieceinf.cpp000066400000000000000000000251541440571307300165410ustar00rootroot00000000000000#include "lc_global.h" #include "lc_math.h" #include "lc_mesh.h" #include "lc_meshloader.h" #include "lc_colors.h" #include "lc_texture.h" #include "pieceinf.h" #include "lc_library.h" #include "lc_application.h" #include "lc_model.h" #include "project.h" #include "lc_scene.h" #include "lc_synth.h" #include "lc_file.h" #include PieceInfo::PieceInfo() { mZipFileType = lcZipFileType::Count; mZipFileIndex = -1; mFolderType = -1; mFolderIndex = -1; mState = lcPieceInfoState::Unloaded; mRefCount = 0; mType = lcPieceInfoType::Part; mMesh = nullptr; mModel = nullptr; mProject = nullptr; mSynthInfo = nullptr; mFileName[0] = 0; m_strDescription[0] = 0; } PieceInfo::~PieceInfo() { delete mSynthInfo; if (mState == lcPieceInfoState::Loaded) Unload(); } void PieceInfo::SetMesh(lcMesh* Mesh) { mBoundingBox = Mesh->mBoundingBox; ReleaseMesh(); mMesh = Mesh; } void PieceInfo::SetPlaceholder() { lcMesh* Mesh = new lcMesh; Mesh->CreateBox(); SetMesh(Mesh); mType = lcPieceInfoType::Placeholder; mModel = nullptr; mProject = nullptr; } void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh, Project* CurrentProject, bool SearchProjectFolder) { if (mModel != Model) { mType = lcPieceInfoType::Model; mModel = Model; delete mMesh; mMesh = nullptr; } strncpy(mFileName, Model->GetProperties().mFileName.toLatin1().data(), sizeof(mFileName) - 1); mFileName[sizeof(mFileName)-1] = 0; strncpy(m_strDescription, Model->GetProperties().mFileName.toLatin1().data(), sizeof(m_strDescription) - 1); m_strDescription[sizeof(m_strDescription)-1] = 0; const QStringList& MeshLines = Model->GetFileLines(); if (UpdateMesh && !MeshLines.isEmpty()) { lcMemFile PieceFile; for (const QString& Line : MeshLines) { QByteArray Buffer = Line.toLatin1(); PieceFile.WriteBuffer(Buffer.constData(), Buffer.size()); PieceFile.WriteBuffer("\r\n", 2); } lcLibraryMeshData MeshData; lcArray TextureStack; PieceFile.Seek(0, SEEK_SET); lcMeshLoader MeshLoader(MeshData, true, CurrentProject, SearchProjectFolder); const bool Ret = MeshLoader.LoadMesh(PieceFile, LC_MESHDATA_SHARED); if (Ret && !MeshData.IsEmpty()) SetMesh(MeshData.CreateMesh()); } } void PieceInfo::CreateProject(Project* Project, const char* PieceName) { if (mProject != Project) { mType = lcPieceInfoType::Project; mProject = Project; mState = lcPieceInfoState::Loaded; } strncpy(mFileName, PieceName, sizeof(mFileName) - 1); mFileName[sizeof(mFileName) - 1] = 0; strncpy(m_strDescription, Project->GetFileName().toLatin1().data(), sizeof(m_strDescription) - 1); m_strDescription[sizeof(m_strDescription) - 1] = 0; } bool PieceInfo::IsProjectPiece() const { if (mProject) return !strcmp(m_strDescription, mProject->GetFileName().toLatin1().data()); return false; } bool PieceInfo::GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& WorldMatrix) const { if (IsModel()) return mModel->GetPieceWorldMatrix(Piece, WorldMatrix); return false; } bool PieceInfo::IncludesModel(const lcModel* Model) const { if (IsModel()) { if (mModel == Model) return true; return mModel->IncludesModel(Model); } return false; } void PieceInfo::CreatePlaceholder(const char* Name) { strncpy(mFileName, Name, sizeof(mFileName)); mFileName[sizeof(mFileName) - 1] = 0; strncpy(m_strDescription, Name, sizeof(m_strDescription)); m_strDescription[sizeof(m_strDescription) - 1] = 0; SetPlaceholder(); } void PieceInfo::Load() { if (!IsModel() && !IsProject()) { mState = lcPieceInfoState::Loading; // todo: mutex lock when changing load state if (IsPlaceholder()) { if (lcGetPiecesLibrary()->LoadPieceData(this)) mType = lcPieceInfoType::Part; } else lcGetPiecesLibrary()->LoadPieceData(this); } mState = lcPieceInfoState::Loaded; } void PieceInfo::ReleaseMesh() { if (mMesh) { for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { for (int SectionIdx = 0; SectionIdx < mMesh->mLods[LodIdx].NumSections; SectionIdx++) { lcMeshSection& Section = mMesh->mLods[LodIdx].Sections[SectionIdx]; if (Section.Texture) Section.Texture->Release(); } } delete mMesh; mMesh = nullptr; } } void PieceInfo::Unload() { ReleaseMesh(); mState = lcPieceInfoState::Unloaded; mModel = nullptr; if (IsModel()) lcGetPiecesLibrary()->RemovePiece(this); else if (IsProject()) { delete mProject; mProject = nullptr; lcGetPiecesLibrary()->RemovePiece(this); } } bool PieceInfo::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance, lcPieceInfoRayTest& PieceInfoRayTest) const { bool Intersect = false; if (IsPlaceholder() || IsModel() || IsProject()) { float Distance; lcVector3 Plane; if (!lcBoundingBoxRayIntersectDistance(mBoundingBox.Min, mBoundingBox.Max, Start, End, &Distance, nullptr, &Plane) || (Distance >= MinDistance)) return false; if (IsPlaceholder()) { PieceInfoRayTest.Info = this; PieceInfoRayTest.Transform = lcMatrix44Identity(); MinDistance = Distance; PieceInfoRayTest.Plane = Plane; return true; } if (IsModel()) Intersect |= mModel->SubModelMinIntersectDist(Start, End, MinDistance, PieceInfoRayTest); else if (IsProject()) { const lcModel* const Model = mProject->GetMainModel(); if (Model) Intersect |= Model->SubModelMinIntersectDist(Start, End, MinDistance, PieceInfoRayTest); } } if (mMesh) { if (mMesh->MinIntersectDist(Start, End, MinDistance, PieceInfoRayTest.Plane)) { PieceInfoRayTest.Info = this; PieceInfoRayTest.Transform = lcMatrix44Identity(); Intersect = true; } } return Intersect; } bool PieceInfo::BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 WorldPlanes[6]) const { lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(WorldMatrix); constexpr int NumCorners = 8; constexpr int NumPlanes = 6; lcVector4 LocalPlanes[NumPlanes]; for (int PlaneIdx = 0; PlaneIdx < NumPlanes; PlaneIdx++) { const lcVector3 PlaneNormal = lcMul30(WorldPlanes[PlaneIdx], InverseWorldMatrix); LocalPlanes[PlaneIdx] = lcVector4(PlaneNormal, WorldPlanes[PlaneIdx][3] - lcDot3(InverseWorldMatrix[3], PlaneNormal)); } lcVector3 Box[NumCorners]; lcGetBoxCorners(mBoundingBox, Box); int Outcodes[NumCorners]; for (int CornerIdx = 0; CornerIdx < NumCorners; CornerIdx++) { Outcodes[CornerIdx] = 0; for (int PlaneIdx = 0; PlaneIdx < NumPlanes; PlaneIdx++) { if (lcDot3(Box[CornerIdx], LocalPlanes[PlaneIdx]) + LocalPlanes[PlaneIdx][3] > 0) Outcodes[CornerIdx] |= 1 << PlaneIdx; } } int OutcodesOR = 0, OutcodesAND = 0x3f; for (int CornerIdx = 0; CornerIdx < NumCorners; CornerIdx++) { OutcodesAND &= Outcodes[CornerIdx]; OutcodesOR |= Outcodes[CornerIdx]; } if (OutcodesAND != 0) return false; if (OutcodesOR == 0) return true; if (mMesh && mMesh->IntersectsPlanes(LocalPlanes)) return true; if (IsModel()) return mModel->SubModelBoxTest(LocalPlanes); else if (IsProject()) { const lcModel* const Model = mProject->GetMainModel(); return Model ? Model->SubModelBoxTest(LocalPlanes) : false; } return false; } void PieceInfo::ZoomExtents(float FoV, float AspectRatio, lcMatrix44& ProjectionMatrix, lcMatrix44& ViewMatrix) const { lcVector3 Points[8]; lcGetBoxCorners(mBoundingBox, Points); const lcVector3 Center = (mBoundingBox.Min + mBoundingBox.Max) / 2.0f; lcVector3 Position = Center + lcVector3(100.0f, -100.0f, 75.0f); ProjectionMatrix = lcMatrix44Perspective(FoV, AspectRatio, 1.0f, 12500.0f); const lcMatrix44 ModelView = lcMatrix44LookAt(Position, Center, lcVector3(0, 0, 1)); float FarDistance; std::tie(Position, FarDistance) = lcZoomExtents(Position, ModelView, ProjectionMatrix, Points, 8); ViewMatrix = lcMatrix44LookAt(Position, Center, lcVector3(0, 0, 1)); ProjectionMatrix = lcMatrix44Perspective(FoV, AspectRatio, 1.0f, FarDistance); } void PieceInfo::AddRenderMesh(lcScene& Scene) { if (mMesh) Scene.AddMesh(mMesh, lcMatrix44Identity(), gDefaultColor, lcRenderMeshState::Default); } void PieceInfo::AddRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int ColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const { if (mMesh || IsPlaceholder()) Scene->AddMesh(mMesh, WorldMatrix, ColorIndex, RenderMeshState); if (IsModel()) mModel->AddSubModelRenderMeshes(Scene, WorldMatrix, ColorIndex, RenderMeshState, ParentActive); else if (IsProject()) { const lcModel* const Model = mProject->GetMainModel(); if (Model) Model->AddSubModelRenderMeshes(Scene, WorldMatrix, ColorIndex, RenderMeshState, ParentActive); } } void PieceInfo::GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const { if (IsModel()) { if (ScanSubModels) mModel->GetPartsList(DefaultColorIndex, ScanSubModels, AddSubModels, PartsList); if (AddSubModels) PartsList[this][DefaultColorIndex]++; } else if (IsProject() && !IsProjectPiece()) { const lcModel* const Model = mProject->GetMainModel(); if (Model) Model->GetPartsList(DefaultColorIndex, ScanSubModels, AddSubModels, PartsList); } else PartsList[this][DefaultColorIndex]++; } void PieceInfo::GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector& ModelParts) const { if (IsModel()) { mModel->GetModelParts(WorldMatrix, DefaultColorIndex, ModelParts); return; } else if (IsProject()) { const lcModel* const Model = mProject->GetMainModel(); if (Model) Model->GetModelParts(WorldMatrix, DefaultColorIndex, ModelParts); return; } ModelParts.emplace_back(lcModelPartsEntry{ WorldMatrix, this, nullptr, DefaultColorIndex }); } void PieceInfo::CompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const { if (!IsModel()) { lcVector3 Points[8]; if (!mMesh) lcGetBoxCorners(GetBoundingBox(), Points); else lcGetBoxCorners(mMesh->mBoundingBox, Points); for (int i = 0; i < 8; i++) { const lcVector3 Point = lcMul31(Points[i], WorldMatrix); Min = lcMin(Point, Min); Max = lcMax(Point, Max); } } else { mModel->SubModelCompareBoundingBox(WorldMatrix, Min, Max); } } void PieceInfo::AddSubModelBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector& Points) const { if (!IsModel()) { lcVector3 BoxPoints[8]; if (!mMesh) lcGetBoxCorners(GetBoundingBox(), BoxPoints); else lcGetBoxCorners(mMesh->mBoundingBox, BoxPoints); for (int i = 0; i < 8; i++) Points.emplace_back(lcMul31(BoxPoints[i], WorldMatrix)); } else { mModel->SubModelAddBoundingBoxPoints(WorldMatrix, Points); } } void PieceInfo::UpdateBoundingBox(std::vector& UpdatedModels) { if (IsModel()) mModel->UpdatePieceInfo(UpdatedModels); else if (IsProject()) mProject->UpdatePieceInfo(this); } leocad-23.03/common/pieceinf.h000066400000000000000000000100531440571307300161760ustar00rootroot00000000000000#pragma once #include #include "lc_math.h" #include "lc_array.h" enum class lcPieceInfoType { Part, Placeholder, Model, Project }; #define LC_PIECE_NAME_LEN 256 enum class lcPieceInfoState { Unloaded, Loading, Loaded }; struct lcModelPartsEntry { lcMatrix44 WorldMatrix; const PieceInfo* Info; lcMesh* Mesh; int ColorIndex; }; class lcSynthInfo; enum class lcZipFileType; class PieceInfo { public: PieceInfo(); ~PieceInfo(); PieceInfo(const PieceInfo&) = delete; PieceInfo(PieceInfo&&) = delete; PieceInfo& operator=(const PieceInfo&) = delete; PieceInfo& operator=(PieceInfo&&) = delete; const lcBoundingBox& GetBoundingBox() const { return mBoundingBox; } void SetBoundingBox(const lcVector3& Min, const lcVector3& Max) { mBoundingBox.Min = Min; mBoundingBox.Max = Max; } lcSynthInfo* GetSynthInfo() const { return mSynthInfo; } void SetSynthInfo(lcSynthInfo* SynthInfo) { mSynthInfo = SynthInfo; } lcMesh* GetMesh() const { return mMesh; } lcModel* GetModel() const { return mModel; } Project* GetProject() const { return mProject; } void SetMesh(lcMesh* Mesh); int AddRef() { mRefCount++; return mRefCount; } int Release() { mRefCount--; return mRefCount; } int GetRefCount() const { return mRefCount; } bool IsPlaceholder() const { return mType == lcPieceInfoType::Placeholder; } bool IsModel() const { return mType == lcPieceInfoType::Model; } bool IsProject() const { return mType == lcPieceInfoType::Project; } bool IsTemporary() const { return mType != lcPieceInfoType::Part; } void SetZipFile(lcZipFileType ZipFileType, int ZipFileIndex) { mZipFileType = ZipFileType; mZipFileIndex = ZipFileIndex; } bool IsPatterned() const { if (mType != lcPieceInfoType::Part) return false; const char* Name = mFileName; // Heuristic: Names matching '^[Uu]?[0-9]*[A-Za-z][^.][^.]' are patterned. if (*Name == 'U' || *Name == 'u') Name++; while (*Name) { if (*Name < '0' || *Name > '9') break; Name++; } if (!*Name || !((*Name >= 'A' && *Name <= 'Z') || (*Name >= 'a' && *Name <= 'z'))) return false; if (Name[1] && Name[1] != '.' && Name[2] && Name[2] != '.') return true; return false; } bool IsSubPiece() const { return (m_strDescription[0] == '~'); } bool IsProjectPiece() const; void ZoomExtents(float FoV, float AspectRatio, lcMatrix44& ProjectionMatrix, lcMatrix44& ViewMatrix) const; void AddRenderMesh(lcScene& Scene); void AddRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int ColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const; void CreatePlaceholder(const char* Name); void SetPlaceholder(); void SetModel(lcModel* Model, bool UpdateMesh, Project* CurrentProject, bool SearchProjectFolder); void CreateProject(Project* Project, const char* PieceName); bool GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& WorldMatrix) const; bool IncludesModel(const lcModel* Model) const; bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance, lcPieceInfoRayTest& PieceInfoRayTest) const; bool BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 Planes[6]) const; void GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const; void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector& ModelParts) const; void CompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const; void AddSubModelBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector& Points) const; void UpdateBoundingBox(std::vector& UpdatedModels); void Load(); void Unload(); public: char mFileName[LC_PIECE_NAME_LEN]; char m_strDescription[128]; lcZipFileType mZipFileType; int mZipFileIndex; lcPieceInfoState mState; int mFolderType; int mFolderIndex; protected: void ReleaseMesh(); int mRefCount; lcPieceInfoType mType; lcModel* mModel; Project* mProject; lcMesh* mMesh; lcBoundingBox mBoundingBox; lcSynthInfo* mSynthInfo; }; leocad-23.03/common/project.cpp000066400000000000000000001742601440571307300164300ustar00rootroot00000000000000#include "lc_global.h" #include "lc_math.h" #include "lc_mesh.h" #include #include "pieceinf.h" #include "camera.h" #include "project.h" #include "lc_instructions.h" #include "image.h" #include "lc_mainwindow.h" #include "lc_view.h" #include "lc_library.h" #include "lc_application.h" #include "lc_profile.h" #include "lc_file.h" #include "lc_zipfile.h" #include "lc_qimagedialog.h" #include "lc_qmodellistdialog.h" #include "lc_bricklink.h" lcHTMLExportOptions::lcHTMLExportOptions(const Project* Project) { QString FileName = Project->GetFileName(); if (!FileName.isEmpty()) PathName = QFileInfo(FileName).canonicalPath(); int ImageOptions = lcGetProfileInt(LC_PROFILE_HTML_IMAGE_OPTIONS); int HTMLOptions = lcGetProfileInt(LC_PROFILE_HTML_OPTIONS); TransparentImages = (ImageOptions & LC_IMAGE_TRANSPARENT) != 0; SubModels = (HTMLOptions & (LC_HTML_SUBMODELS)) != 0; CurrentOnly = (HTMLOptions & LC_HTML_CURRENT_ONLY) != 0; SinglePage = (HTMLOptions & LC_HTML_SINGLEPAGE) != 0; IndexPage = (HTMLOptions & LC_HTML_INDEX) != 0; StepImagesWidth = lcGetProfileInt(LC_PROFILE_HTML_IMAGE_WIDTH); StepImagesHeight = lcGetProfileInt(LC_PROFILE_HTML_IMAGE_HEIGHT); PartsListStep = (HTMLOptions & LC_HTML_LISTSTEP) != 0; PartsListEnd = (HTMLOptions & LC_HTML_LISTEND) != 0; } void lcHTMLExportOptions::SaveDefaults() { int HTMLOptions = 0; if (SubModels) HTMLOptions |= LC_HTML_SUBMODELS; if (CurrentOnly) HTMLOptions |= LC_HTML_CURRENT_ONLY; if (SinglePage) HTMLOptions |= LC_HTML_SINGLEPAGE; if (IndexPage) HTMLOptions |= LC_HTML_INDEX; if (PartsListStep) HTMLOptions |= LC_HTML_LISTSTEP; if (PartsListEnd) HTMLOptions |= LC_HTML_LISTEND; lcSetProfileInt(LC_PROFILE_HTML_IMAGE_OPTIONS, TransparentImages ? LC_IMAGE_TRANSPARENT : 0); lcSetProfileInt(LC_PROFILE_HTML_OPTIONS, HTMLOptions); lcSetProfileInt(LC_PROFILE_HTML_IMAGE_WIDTH, StepImagesWidth); lcSetProfileInt(LC_PROFILE_HTML_IMAGE_HEIGHT, StepImagesHeight); } Project::Project(bool IsPreview) : mIsPreview(IsPreview) { mModified = false; mActiveModel = new lcModel(tr(mIsPreview ? "Preview.ldr" : "New Model.ldr"), this, mIsPreview); mActiveModel->CreatePieceInfo(this); mActiveModel->SetSaved(); mModels.Add(mActiveModel); if (!mIsPreview && gMainWindow) QObject::connect(&mFileWatcher, SIGNAL(fileChanged(const QString&)), gMainWindow, SLOT(ProjectFileChanged(const QString&))); } Project::~Project() { mModels.DeleteAll(); } lcModel* Project::GetModel(const QString& FileName) const { for (lcModel* Model : mModels) if (Model->GetProperties().mFileName == FileName) return Model; return nullptr; } bool Project::IsModified() const { if (mModified) return true; for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) if (mModels[ModelIdx]->IsModified()) return true; return false; } QString Project::GetTitle() const { if (!mFileName.isEmpty()) return QFileInfo(mFileName).fileName(); return mModels.GetSize() == 1 ? tr("New Model.ldr") : tr("New Model.mpd"); } QString Project::GetImageFileName(bool AllowCurrentFolder) const { QString FileName = GetFileName(); if (!FileName.isEmpty()) { QString Extension = QFileInfo(FileName).suffix(); if (!Extension.isEmpty()) FileName = FileName.left(FileName.length() - Extension.length() - 1); } else { if (AllowCurrentFolder) FileName = QLatin1String("image"); else { QStringList CachePathList = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); FileName = CachePathList.first(); FileName = QDir(FileName).absoluteFilePath(QLatin1String("image")); } } return QDir::toNativeSeparators(FileName) + lcGetProfileString(LC_PROFILE_IMAGE_EXTENSION); } void Project::SetActiveModel(int ModelIndex) { if (ModelIndex < 0 || ModelIndex >= mModels.GetSize()) return; for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) mModels[ModelIdx]->SetActive(ModelIdx == ModelIndex); std::vector UpdatedModels; UpdatedModels.reserve(mModels.GetSize()); for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) mModels[ModelIdx]->UpdatePieceInfo(UpdatedModels); mActiveModel = mModels[ModelIndex]; if (!mIsPreview && gMainWindow) { gMainWindow->SetCurrentModelTab(mActiveModel); mActiveModel->UpdateInterface(); } } void Project::SetActiveModel(const QString& FileName) { for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) { if (FileName.compare(mModels[ModelIdx]->GetFileName(), Qt::CaseInsensitive) == 0) { SetActiveModel(ModelIdx); return; } } } QString Project::GetNewModelName(QWidget* ParentWidget, const QString& DialogTitle, const QString& CurrentName, const QStringList& ExistingModels) const { QString Name = CurrentName; if (Name.isEmpty()) { const QString Prefix = tr("Submodel #"); int Max = 0; for (int ModelIdx = 0; ModelIdx < ExistingModels.size(); ModelIdx++) { const QString& ExistingName = ExistingModels[ModelIdx]; if (ExistingName.startsWith(Prefix)) { QString NumberString = ExistingName.mid(Prefix.length()); QTextStream Stream(&NumberString); int Number; Stream >> Number; Max = qMax(Max, Number); } } Name = Prefix + QString::number(Max + 1) + ".ldr"; } for (;;) { bool Ok = false; Name = QInputDialog::getText(ParentWidget, DialogTitle, tr("Submodel Name:"), QLineEdit::Normal, Name, &Ok); if (!Ok) return QString(); if (Name.isEmpty()) { QMessageBox::information(ParentWidget, tr("Empty Name"), tr("The submodel name cannot be empty.")); continue; } bool ExtensionValid = false; if (Name.length() < 5) ExtensionValid = false; else { QString Extension = Name.right(4); if (Extension.compare(".dat", Qt::CaseInsensitive) == 0 || Extension.compare(".ldr", Qt::CaseInsensitive) == 0 || Extension.compare(".mpd", Qt::CaseInsensitive) == 0) ExtensionValid = true; } if (!ExtensionValid) Name += ".ldr"; if (ExistingModels.contains(Name, Qt::CaseInsensitive) && Name != CurrentName) { QMessageBox::information(ParentWidget, tr("Duplicate Submodel"), tr("A submodel named '%1' already exists, please enter a unique name.").arg(Name)); continue; } break; } return Name; } lcModel* Project::CreateNewModel(bool ShowModel) { QStringList ModelNames; for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) ModelNames.append(mModels[ModelIdx]->GetProperties().mFileName); QString Name = GetNewModelName(gMainWindow, tr("New Submodel"), QString(), ModelNames); if (Name.isEmpty()) return nullptr; mModified = true; lcModel* Model = new lcModel(Name, this, false); Model->CreatePieceInfo(this); Model->SetSaved(); mModels.Add(Model); if (ShowModel) { SetActiveModel(mModels.GetSize() - 1); lcView* ActiveView = gMainWindow ? gMainWindow->GetActiveView() : nullptr; if (ActiveView) ActiveView->GetCamera()->SetViewpoint(lcViewpoint::Home); gMainWindow->UpdateTitle(); } else SetActiveModel(mModels.FindIndex(mActiveModel)); return Model; } void Project::ShowModelListDialog() { lcQModelListDialog Dialog(gMainWindow, mModels); if (Dialog.exec() != QDialog::Accepted) return; lcArray NewModels; std::vector Results = Dialog.GetResults(); for (const lcModelListDialogEntry& Entry : Results) { lcModel* Model = Entry.ExistingModel; if (!Model) { const lcModel* Source = Entry.DuplicateSource; if (!Source) { Model = new lcModel(Entry.Name, this, false); } else { Model = new lcModel(Source->GetProperties().mFileName, this, false); QByteArray File; QTextStream SaveStream(&File); Source->SaveLDraw(SaveStream, false); SaveStream.flush(); QBuffer Buffer(&File); Buffer.open(QIODevice::ReadOnly); Model->LoadLDraw(Buffer, this); Model->SetFileName(Entry.Name); Model->CreatePieceInfo(this); } Model->CreatePieceInfo(this); Model->SetSaved(); mModified = true; } else if (Model->GetProperties().mFileName != Entry.Name) { Model->SetFileName(Entry.Name); lcGetPiecesLibrary()->RenamePiece(Model->GetPieceInfo(), Entry.Name.toLatin1().constData()); for (lcModel* CheckModel : mModels) CheckModel->RenamePiece(Model->GetPieceInfo()); mModified = true; } NewModels.Add(Model); } for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) { lcModel* Model = mModels[ModelIdx]; if (NewModels.FindIndex(Model) == -1) { delete Model; mModified = true; } } mModels = NewModels; gMainWindow->UpdateTitle(); gMainWindow->UpdateModels(); int ModelIndex = Dialog.GetActiveModelIndex(); if (ModelIndex != -1) SetActiveModel(ModelIndex); } void Project::SetFileName(const QString& FileName) { if (mFileName == FileName) return; if (!mIsPreview && !mFileName.isEmpty()) mFileWatcher.removePath(mFileName); if (!mIsPreview && !FileName.isEmpty()) mFileWatcher.addPath(FileName); mFileName = FileName; } bool Project::Load(const QString& FileName, bool ShowErrors) { QWidget *parent = nullptr; if (!mIsPreview) parent = gMainWindow; QFile File(FileName); if (!File.open(QIODevice::ReadOnly)) { if (ShowErrors) QMessageBox::warning(parent, tr("Error"), tr("Error reading file '%1':\n%2").arg(FileName, File.errorString())); return false; } mModels.DeleteAll(); SetFileName(FileName); QFileInfo FileInfo(FileName); QString Extension = FileInfo.suffix().toLower(); QByteArray FileData = File.readAll(); bool LoadDAT; if (Extension == QLatin1String("dat") || Extension == QLatin1String("ldr") || Extension == QLatin1String("mpd")) LoadDAT = true; else if (Extension == QLatin1String("lcd") || Extension == QLatin1String("leocad")) LoadDAT = false; else LoadDAT = FileData.size() > 7 && memcmp(FileData, "LeoCAD ", 7); if (LoadDAT) { QBuffer Buffer(&FileData); Buffer.open(QIODevice::ReadOnly); std::vector> Models; while (!Buffer.atEnd()) { lcModel* Model = new lcModel(QString(), this, mIsPreview); int Pos = Model->SplitMPD(Buffer); if (Models.empty() || !Model->GetFileName().isEmpty()) { auto ModelCompare = [Model](const std::pair& ModelIt) { return ModelIt.second->GetFileName().compare(Model->GetFileName(), Qt::CaseInsensitive) == 0; }; if (std::find_if(Models.begin(), Models.end(), ModelCompare) == Models.end()) { mModels.Add(Model); Models.emplace_back(std::make_pair(Pos, Model)); Model->CreatePieceInfo(this); } else delete Model; } else delete Model; } for (size_t ModelIdx = 0; ModelIdx < Models.size(); ModelIdx++) { Buffer.seek(Models[ModelIdx].first); lcModel* Model = Models[ModelIdx].second; Model->LoadLDraw(Buffer, this); Model->SetSaved(); } } else { lcMemFile MemFile; MemFile.WriteBuffer(FileData.constData(), FileData.size()); MemFile.Seek(0, SEEK_SET); lcModel* Model = new lcModel(QString(), this, mIsPreview); if (Model->LoadBinary(&MemFile)) { mModels.Add(Model); Model->CreatePieceInfo(this); Model->SetSaved(); } else delete Model; } if (mModels.IsEmpty()) { if (ShowErrors) QMessageBox::warning(parent, tr("Error"), tr("Error loading file '%1':\nFile format is not recognized.").arg(FileName)); return false; } if (mModels.GetSize() == 1) { lcModel* Model = mModels[0]; if (Model->GetProperties().mFileName.isEmpty()) { Model->SetFileName(FileInfo.fileName()); lcGetPiecesLibrary()->RenamePiece(Model->GetPieceInfo(), FileInfo.fileName().toLatin1()); } } std::vector UpdatedModels; UpdatedModels.reserve(mModels.GetSize()); for (lcModel* Model : mModels) { Model->UpdateMesh(); Model->UpdatePieceInfo(UpdatedModels); } mModified = false; return true; } bool Project::Save(const QString& FileName) { SetFileName(QString()); QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString())); return false; } QTextStream Stream(&File); bool Success = Save(Stream); File.close(); if (Success) { SetFileName(FileName); mModified = false; } return Success; } bool Project::Save(QTextStream& Stream) { bool MPD = mModels.GetSize() > 1; for (lcModel* Model : mModels) { if (MPD) Stream << QLatin1String("0 FILE ") << Model->GetProperties().mFileName << QLatin1String("\r\n"); Model->SaveLDraw(Stream, false); Model->SetSaved(); if (MPD) Stream << QLatin1String("0 NOFILE\r\n"); } return true; } void Project::Merge(Project* Other) { for (lcModel* Model : Other->mModels) { QString FileName = Model->GetProperties().mFileName; for (;;) { bool Duplicate = false; for (int SearchIdx = 0; SearchIdx < mModels.GetSize(); SearchIdx++) { if (mModels[SearchIdx]->GetProperties().mFileName == FileName) { Duplicate = true; break; } } if (!Duplicate) break; FileName = tr("Merged ") + FileName; Model->SetFileName(FileName); } mModels.Add(Model); } Other->mModels.RemoveAll(); mModified = true; } bool Project::ImportLDD(const QString& FileName) { lcZipFile ZipFile; if (!ZipFile.OpenRead(FileName)) return false; lcMemFile XMLFile; if (!ZipFile.ExtractFile("IMAGE100.LXFML", XMLFile)) return false; mModels.DeleteAll(); QString ModelName = QFileInfo(FileName).completeBaseName(); lcModel* Model = new lcModel(ModelName, this, false); if (Model->LoadLDD(QString::fromUtf8((const char*)XMLFile.mBuffer))) { mModels.Add(Model); Model->SetSaved(); } else { delete Model; return false; } for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) mModels[ModelIdx]->CreatePieceInfo(this); std::vector UpdatedModels; UpdatedModels.reserve(mModels.GetSize()); for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) mModels[ModelIdx]->UpdatePieceInfo(UpdatedModels); mModified = false; return true; } bool Project::ImportInventory(const QByteArray& Inventory, const QString& Name, const QString& Description) { if (Inventory.isEmpty()) return false; mModels.DeleteAll(); lcModel* Model = new lcModel(Name, this, false); if (Model->LoadInventory(Inventory)) { mModels.Add(Model); Model->SetSaved(); } else { delete Model; return false; } Model->SetDescription(Description); for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) mModels[ModelIdx]->CreatePieceInfo(this); std::vector UpdatedModels; UpdatedModels.reserve(mModels.GetSize()); for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) mModels[ModelIdx]->UpdatePieceInfo(UpdatedModels); mModified = false; return true; } std::vector Project::GetModelParts() { std::vector ModelParts; if (mModels.IsEmpty()) return ModelParts; for (lcModel* Model : mModels) Model->CalculateStep(LC_STEP_MAX); mModels[0]->GetModelParts(lcMatrix44Identity(), gDefaultColor, ModelParts); SetActiveModel(mModels.FindIndex(mActiveModel)); return ModelParts; } bool Project::ExportModel(const QString& FileName, lcModel* Model) const { QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString())); return false; } QTextStream Stream(&File); Model->SaveLDraw(Stream, false); return true; } QString Project::GetExportFileName(const QString& FileName, const QString& DefaultExtension, const QString& DialogTitle, const QString& DialogFilter) const { if (!FileName.isEmpty()) return FileName; QString SaveFileName; if (!mFileName.isEmpty()) SaveFileName = mFileName; else SaveFileName = GetTitle(); QString Extension = QFileInfo(SaveFileName).suffix().toLower(); if (Extension.isEmpty()) SaveFileName += "." + DefaultExtension; else if (Extension != DefaultExtension && SaveFileName.length() > 4) { SaveFileName = SaveFileName.left(SaveFileName.length() - Extension.length() - 1); SaveFileName += "." + DefaultExtension; } return QFileDialog::getSaveFileName(gMainWindow, DialogTitle, SaveFileName, DialogFilter); } bool Project::Export3DStudio(const QString& FileName) { std::vector ModelParts = GetModelParts(); if (ModelParts.empty()) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export.")); return false; } QString SaveFileName = GetExportFileName(FileName, "3ds", tr("Export 3D Studio"), tr("3DS Files (*.3ds);;All Files (*.*)")); if (SaveFileName.isEmpty()) return false; lcDiskFile File(SaveFileName); if (!File.Open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName)); return false; } long M3DStart = File.GetPosition(); File.WriteU16(0x4D4D); // CHK_M3DMAGIC File.WriteU32(0); File.WriteU16(0x0002); // CHK_M3D_VERSION File.WriteU32(10); File.WriteU32(3); long MDataStart = File.GetPosition(); File.WriteU16(0x3D3D); // CHK_MDATA File.WriteU32(0); File.WriteU16(0x3D3E); // CHK_MESH_VERSION File.WriteU32(10); File.WriteU32(3); const int MaterialNameLength = 11; char MaterialName[32]; for (size_t ColorIdx = 0; ColorIdx < gColorList.size(); ColorIdx++) { lcColor* Color = &gColorList[ColorIdx]; sprintf(MaterialName, "Material%03d", (int)ColorIdx); long MaterialStart = File.GetPosition(); File.WriteU16(0xAFFF); // CHK_MAT_ENTRY File.WriteU32(0); File.WriteU16(0xA000); // CHK_MAT_NAME File.WriteU32(6 + MaterialNameLength + 1); File.WriteBuffer(MaterialName, MaterialNameLength + 1); File.WriteU16(0xA010); // CHK_MAT_AMBIENT File.WriteU32(24); File.WriteU16(0x0011); // CHK_COLOR_24 File.WriteU32(9); File.WriteU8(floor(255.0 * Color->Value[0] + 0.5)); File.WriteU8(floor(255.0 * Color->Value[1] + 0.5)); File.WriteU8(floor(255.0 * Color->Value[2] + 0.5)); File.WriteU16(0x0012); // CHK_LIN_COLOR_24 File.WriteU32(9); File.WriteU8(floor(255.0 * Color->Value[0] + 0.5)); File.WriteU8(floor(255.0 * Color->Value[1] + 0.5)); File.WriteU8(floor(255.0 * Color->Value[2] + 0.5)); File.WriteU16(0xA020); // CHK_MAT_AMBIENT File.WriteU32(24); File.WriteU16(0x0011); // CHK_COLOR_24 File.WriteU32(9); File.WriteU8(floor(255.0 * Color->Value[0] + 0.5)); File.WriteU8(floor(255.0 * Color->Value[1] + 0.5)); File.WriteU8(floor(255.0 * Color->Value[2] + 0.5)); File.WriteU16(0x0012); // CHK_LIN_COLOR_24 File.WriteU32(9); File.WriteU8(floor(255.0 * Color->Value[0] + 0.5)); File.WriteU8(floor(255.0 * Color->Value[1] + 0.5)); File.WriteU8(floor(255.0 * Color->Value[2] + 0.5)); File.WriteU16(0xA030); // CHK_MAT_SPECULAR File.WriteU32(24); File.WriteU16(0x0011); // CHK_COLOR_24 File.WriteU32(9); File.WriteU8(floor(255.0 * 0.9f + 0.5)); File.WriteU8(floor(255.0 * 0.9f + 0.5)); File.WriteU8(floor(255.0 * 0.9f + 0.5)); File.WriteU16(0x0012); // CHK_LIN_COLOR_24 File.WriteU32(9); File.WriteU8(floor(255.0 * 0.9f + 0.5)); File.WriteU8(floor(255.0 * 0.9f + 0.5)); File.WriteU8(floor(255.0 * 0.9f + 0.5)); File.WriteU16(0xA040); // CHK_MAT_SHININESS File.WriteU32(14); File.WriteU16(0x0030); // CHK_INT_PERCENTAGE File.WriteU32(8); File.WriteS16((quint8)floor(100.0 * 0.25 + 0.5)); File.WriteU16(0xA041); // CHK_MAT_SHIN2PCT File.WriteU32(14); File.WriteU16(0x0030); // CHK_INT_PERCENTAGE File.WriteU32(8); File.WriteS16((quint8)floor(100.0 * 0.05 + 0.5)); File.WriteU16(0xA050); // CHK_MAT_TRANSPARENCY File.WriteU32(14); File.WriteU16(0x0030); // CHK_INT_PERCENTAGE File.WriteU32(8); File.WriteS16((quint8)floor(100.0 * (1.0f - Color->Value[3]) + 0.5)); File.WriteU16(0xA052); // CHK_MAT_XPFALL File.WriteU32(14); File.WriteU16(0x0030); // CHK_INT_PERCENTAGE File.WriteU32(8); File.WriteS16((quint8)floor(100.0 * 0.0 + 0.5)); File.WriteU16(0xA053); // CHK_MAT_REFBLUR File.WriteU32(14); File.WriteU16(0x0030); // CHK_INT_PERCENTAGE File.WriteU32(8); File.WriteS16((quint8)floor(100.0 * 0.2 + 0.5)); File.WriteU16(0xA100); // CHK_MAT_SHADING File.WriteU32(8); File.WriteS16(3); File.WriteU16(0xA084); // CHK_MAT_SELF_ILPCT File.WriteU32(14); File.WriteU16(0x0030); // CHK_INT_PERCENTAGE File.WriteU32(8); File.WriteS16((quint8)floor(100.0 * 0.0 + 0.5)); File.WriteU16(0xA081); // CHK_MAT_TWO_SIDE File.WriteU32(6); File.WriteU16(0xA087); // CHK_MAT_WIRE_SIZE File.WriteU32(10); File.WriteFloat(1.0f); long MaterialEnd = File.GetPosition(); File.Seek(MaterialStart + 2, SEEK_SET); File.WriteU32(MaterialEnd - MaterialStart); File.Seek(MaterialEnd, SEEK_SET); } const lcModelProperties& Properties = mModels[0]->GetProperties(); File.WriteU16(0x0100); // CHK_MASTER_SCALE File.WriteU32(10); File.WriteFloat(1.0f); File.WriteU16(0x1400); // CHK_LO_SHADOW_BIAS File.WriteU32(10); File.WriteFloat(1.0f); File.WriteU16(0x1420); // CHK_SHADOW_MAP_SIZE File.WriteU32(8); File.WriteS16(512); File.WriteU16(0x1450); // CHK_SHADOW_FILTER File.WriteU32(10); File.WriteFloat(3.0f); File.WriteU16(0x1460); // CHK_RAY_BIAS File.WriteU32(10); File.WriteFloat(1.0f); File.WriteU16(0x1500); // CHK_O_CONSTS File.WriteU32(18); File.WriteFloat(0.0f); File.WriteFloat(0.0f); File.WriteFloat(0.0f); File.WriteU16(0x2100); // CHK_AMBIENT_LIGHT File.WriteU32(42); File.WriteU16(0x0010); // CHK_COLOR_F File.WriteU32(18); File.WriteFloats(Properties.mAmbientColor, 3); File.WriteU16(0x0013); // CHK_LIN_COLOR_F File.WriteU32(18); File.WriteFloats(Properties.mAmbientColor, 3); File.WriteU16(0x1200); // CHK_SOLID_BGND File.WriteU32(42); File.WriteU16(0x0010); // CHK_COLOR_F File.WriteU32(18); const lcPreferences& Preferences = lcGetPreferences(); lcVector3 BackgroundSolidColor = lcVector3FromColor(Preferences.mBackgroundSolidColor); File.WriteFloats(BackgroundSolidColor, 3); File.WriteU16(0x0013); // CHK_LIN_COLOR_F File.WriteU32(18); File.WriteFloats(BackgroundSolidColor, 3); File.WriteU16(0x1300); // CHK_V_GRADIENT File.WriteU32(118); File.WriteFloat(1.0f); File.WriteU16(0x0010); // CHK_COLOR_F File.WriteU32(18); const lcVector3 BackgroundGradientColor1 = lcVector3FromColor(Preferences.mBackgroundGradientColorTop); const lcVector3 BackgroundGradientColor2 = lcVector3FromColor(Preferences.mBackgroundGradientColorBottom); File.WriteFloats(BackgroundGradientColor1, 3); File.WriteU16(0x0013); // CHK_LIN_COLOR_F File.WriteU32(18); File.WriteFloats(BackgroundGradientColor1, 3); File.WriteU16(0x0010); // CHK_COLOR_F File.WriteU32(18); File.WriteFloats((BackgroundGradientColor1 + BackgroundGradientColor2) / 2.0f, 3); File.WriteU16(0x0013); // CHK_LIN_COLOR_F File.WriteU32(18); File.WriteFloats((BackgroundGradientColor1 + BackgroundGradientColor2) / 2.0f, 3); File.WriteU16(0x0010); // CHK_COLOR_F File.WriteU32(18); File.WriteFloats(BackgroundGradientColor2, 3); File.WriteU16(0x0013); // CHK_LIN_COLOR_F File.WriteU32(18); File.WriteFloats(BackgroundGradientColor2, 3); if (Preferences.mBackgroundGradient) { File.WriteU16(0x1301); // LIB3DS_USE_V_GRADIENT File.WriteU32(6); } else { File.WriteU16(0x1201); // LIB3DS_USE_SOLID_BGND File.WriteU32(6); } int NumPieces = 0; for (const lcModelPartsEntry& ModelPart : ModelParts) { lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh; if (!Mesh || Mesh->mIndexType == GL_UNSIGNED_INT) continue; long NamedObjectStart = File.GetPosition(); File.WriteU16(0x4000); // CHK_NAMED_OBJECT File.WriteU32(0); char Name[32]; sprintf(Name, "Piece%.3d", NumPieces); NumPieces++; File.WriteBuffer(Name, strlen(Name) + 1); long TriObjectStart = File.GetPosition(); File.WriteU16(0x4100); // CHK_N_TRI_OBJECT File.WriteU32(0); File.WriteU16(0x4110); // CHK_POINT_ARRAY File.WriteU32(8 + 12 * Mesh->mNumVertices); File.WriteU16(Mesh->mNumVertices); lcVertex* Verts = (lcVertex*)Mesh->mVertexData; const lcMatrix44& ModelWorld = ModelPart.WorldMatrix; for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++) { lcVector3 Pos = lcMul31(Verts[VertexIdx].Position, ModelWorld); File.WriteFloat(Pos[0]); File.WriteFloat(Pos[1]); File.WriteFloat(Pos[2]); } File.WriteU16(0x4160); // CHK_MESH_MATRIX File.WriteU32(54); lcMatrix44 Matrix = lcMatrix44Identity(); File.WriteFloats(Matrix[0], 3); File.WriteFloats(Matrix[1], 3); File.WriteFloats(Matrix[2], 3); File.WriteFloats(Matrix[3], 3); File.WriteU16(0x4165); // CHK_MESH_COLOR File.WriteU32(7); File.WriteU8(0); long FaceArrayStart = File.GetPosition(); File.WriteU16(0x4120); // CHK_FACE_ARRAY File.WriteU32(0); int NumTriangles = 0; for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) { lcMeshSection* Section = &Mesh->mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) continue; NumTriangles += Section->NumIndices / 3; } File.WriteU16(NumTriangles); for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) { lcMeshSection* Section = &Mesh->mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) continue; quint16* Indices = (quint16*)Mesh->mIndexData + Section->IndexOffset / sizeof(quint16); for (int IndexIdx = 0; IndexIdx < Section->NumIndices; IndexIdx += 3) { File.WriteU16(Indices[IndexIdx + 0]); File.WriteU16(Indices[IndexIdx + 1]); File.WriteU16(Indices[IndexIdx + 2]); File.WriteU16(7); } } NumTriangles = 0; for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) { lcMeshSection* Section = &Mesh->mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) continue; int MaterialIndex = Section->ColorIndex == gDefaultColor ? ModelPart.ColorIndex : Section->ColorIndex; File.WriteU16(0x4130); // CHK_MSH_MAT_GROUP File.WriteU32(6 + MaterialNameLength + 1 + 2 + 2 * Section->NumIndices / 3); sprintf(MaterialName, "Material%03d", MaterialIndex); File.WriteBuffer(MaterialName, MaterialNameLength + 1); File.WriteU16(Section->NumIndices / 3); for (int IndexIdx = 0; IndexIdx < Section->NumIndices; IndexIdx += 3) File.WriteU16(NumTriangles++); } long FaceArrayEnd = File.GetPosition(); File.Seek(FaceArrayStart + 2, SEEK_SET); File.WriteU32(FaceArrayEnd - FaceArrayStart); File.Seek(FaceArrayEnd, SEEK_SET); long TriObjectEnd = File.GetPosition(); File.Seek(TriObjectStart + 2, SEEK_SET); File.WriteU32(TriObjectEnd - TriObjectStart); File.Seek(TriObjectEnd, SEEK_SET); long NamedObjectEnd = File.GetPosition(); File.Seek(NamedObjectStart + 2, SEEK_SET); File.WriteU32(NamedObjectEnd - NamedObjectStart); File.Seek(NamedObjectEnd, SEEK_SET); } long MDataEnd = File.GetPosition(); File.Seek(MDataStart + 2, SEEK_SET); File.WriteU32(MDataEnd - MDataStart); File.Seek(MDataEnd, SEEK_SET); long KFDataStart = File.GetPosition(); File.WriteU16(0xB000); // CHK_KFDATA File.WriteU32(0); File.WriteU16(0xB00A); // LIB3DS_KFHDR File.WriteU32(6 + 2 + 1 + 4); File.WriteS16(5); File.WriteU8(0); File.WriteS32(100); long KFDataEnd = File.GetPosition(); File.Seek(KFDataStart + 2, SEEK_SET); File.WriteU32(KFDataEnd - KFDataStart); File.Seek(KFDataEnd, SEEK_SET); long M3DEnd = File.GetPosition(); File.Seek(M3DStart + 2, SEEK_SET); File.WriteU32(M3DEnd - M3DStart); File.Seek(M3DEnd, SEEK_SET); return true; } void Project::ExportBrickLink() { lcPartsList PartsList; if (!mModels.IsEmpty()) mModels[0]->GetPartsList(gDefaultColor, true, false, PartsList); if (PartsList.empty()) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export.")); return; } QString SaveFileName = GetExportFileName(QString(), "xml", tr("Export BrickLink"), tr("XML Files (*.xml);;All Files (*.*)")); if (SaveFileName.isEmpty()) return; lcExportBrickLink(SaveFileName, PartsList); } bool Project::ExportCOLLADA(const QString& FileName) { std::vector ModelParts = GetModelParts(); if (ModelParts.empty()) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export.")); return false; } QString SaveFileName = GetExportFileName(FileName, "dae", tr("Export COLLADA"), tr("COLLADA Files (*.dae);;All Files (*.*)")); if (SaveFileName.isEmpty()) return false; QFile File(SaveFileName); if (!File.open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName)); return false; } QTextStream Stream(&File); Stream << "\r\n"; Stream << "\r\n"; Stream << "\r\n"; Stream << "\t" << QDateTime::currentDateTime().toString(Qt::ISODate) << "\r\n"; Stream << "\t" << QDateTime::currentDateTime().toString(Qt::ISODate) << "\r\n"; Stream << "\r\n"; Stream << "\tZ_UP\r\n"; Stream << "\r\n"; Stream << "\r\n"; for (const lcColor& Color : gColorList) { const char* ColorName = Color.SafeName; Stream << QString("\t\r\n").arg(ColorName); Stream << "\t\t\r\n"; Stream << "\t\t\t\r\n"; Stream << "\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\t0.0 0.0 0.0 0.0\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << QString("\t\t\t\t\t\t%1 %2 %3 1.0\r\n").arg(QString::number(Color.Value[0]), QString::number(Color.Value[1]), QString::number(Color.Value[2])); Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << QString("\t\t\t\t\t\t%1 %2 %3 1.0\r\n").arg(QString::number(Color.Value[0]), QString::number(Color.Value[1]), QString::number(Color.Value[2])); Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\t0.9 0.9 0.9 1.0\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\t20.0\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << QString("\t\t\t\t\t\t%1 %2 %3 %4\r\n").arg(QString::number(Color.Value[0]), QString::number(Color.Value[1]), QString::number(Color.Value[2]), QString::number(Color.Value[3])); Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\t1.0\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\r\n"; Stream << "\t\t\t\r\n"; Stream << "\t\t\r\n"; Stream << "\t\r\n"; } Stream << "\r\n"; Stream << "\r\n"; for (const lcColor& Color : gColorList) { const char* ColorName = Color.SafeName; Stream << QString("\t\r\n").arg(ColorName); Stream << QString("\t\t\r\n").arg(ColorName); Stream << "\t\r\n"; } Stream << "\r\n"; Stream << "\r\n"; std::set AddedMeshes; auto GetMeshID = [](const lcModelPartsEntry& ModelPart) { const PieceInfo* Info = ModelPart.Info; QString ID = QString(Info->mFileName).replace('.', '_'); if (ModelPart.Mesh) ID += "_" + QString::number((quintptr)ModelPart.Mesh, 16); return ID; }; for (const lcModelPartsEntry& ModelPart : ModelParts) { lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh; if (!AddedMeshes.insert(Mesh).second) continue; QString ID = GetMeshID(ModelPart); if (!Mesh) continue; Stream << QString("\t\r\n").arg(ID); Stream << "\t\t\r\n"; Stream << QString("\t\t\t\r\n").arg(ID); Stream << QString("\t\t\t\t\r\n").arg(ID, QString::number(Mesh->mNumVertices)); lcVertex* Verts = (lcVertex*)Mesh->mVertexData; for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++) { lcVector3& Position = Verts[VertexIdx].Position; Stream << QString("\t\t\t\t\t%1 %2 %3\r\n").arg(QString::number(Position.x), QString::number(Position.y), QString::number(Position.z)); } Stream << "\t\t\t\t\r\n"; Stream << "\t\t\t\t\r\n"; Stream << QString("\t\t\t\t\t\r\n").arg(ID, QString::number(Mesh->mNumVertices)); Stream << "\t\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\r\n"; Stream << "\t\t\t\r\n"; Stream << QString("\t\t\t\r\n").arg(ID); Stream << QString("\t\t\t\t\r\n").arg(ID, QString::number(Mesh->mNumVertices)); for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++) { lcVector3 Normal = lcUnpackNormal(Verts[VertexIdx].Normal); Stream << QString("\t\t\t\t\t%1 %2 %3\r\n").arg(QString::number(Normal.x), QString::number(Normal.y), QString::number(Normal.z)); } Stream << "\t\t\t\t\r\n"; Stream << "\t\t\t\t\r\n"; Stream << QString("\t\t\t\t\t\r\n").arg(ID, QString::number(Mesh->mNumVertices)); Stream << "\t\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\r\n"; Stream << "\t\t\t\r\n"; Stream << QString("\t\t\t\r\n").arg(ID); Stream << QString("\t\t\t\t\r\n").arg(ID); Stream << "\t\t\t\r\n"; for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) { lcMeshSection* Section = &Mesh->mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) continue; const char* ColorName = gColorList[Section->ColorIndex].SafeName; if (Mesh->mIndexType == GL_UNSIGNED_SHORT) { quint16* Indices = (quint16*)Mesh->mIndexData + Section->IndexOffset / sizeof(quint16); Stream << QString("\t\t\t\r\n").arg(QString::number(Section->NumIndices / 3), ColorName); Stream << QString("\t\t\t\r\n").arg(ID); Stream << QString("\t\t\t\r\n").arg(ID); Stream << "\t\t\t

\r\n"; for (int Idx = 0; Idx < Section->NumIndices; Idx += 3) { QString idx1 = QString::number(Indices[Idx + 0]); QString idx2 = QString::number(Indices[Idx + 1]); QString idx3 = QString::number(Indices[Idx + 2]); Stream << QString("\t\t\t\t %1 %2 %3\r\n").arg(idx1, idx2, idx3); } } else { quint32* Indices = (quint32*)Mesh->mIndexData + Section->IndexOffset / sizeof(quint32); Stream << QString("\t\t\t\r\n").arg(QString::number(Section->NumIndices / 3), ColorName); Stream << QString("\t\t\t\r\n").arg(ID); Stream << QString("\t\t\t\r\n").arg(ID); Stream << "\t\t\t

\r\n"; for (int Idx = 0; Idx < Section->NumIndices; Idx += 3) { QString idx1 = QString::number(Indices[Idx + 0]); QString idx2 = QString::number(Indices[Idx + 1]); QString idx3 = QString::number(Indices[Idx + 2]); Stream << QString("\t\t\t\t %1 %2 %3\r\n").arg(idx1, idx2, idx3); } } Stream << "\t\t\t\t

\r\n"; Stream << "\t\t\t
\r\n"; } Stream << "\t\t
\r\n"; Stream << "\t
\r\n"; } Stream << "
\r\n"; Stream << "\r\n"; Stream << "\t\r\n"; for (const lcModelPartsEntry& ModelPart : ModelParts) { lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh; if (!Mesh) continue; QString ID = GetMeshID(ModelPart); Stream << "\t\t\r\n"; Stream << "\t\t\t\r\n"; const lcMatrix44& Matrix = ModelPart.WorldMatrix; Stream << QString("\t\t\t\t%1 %2 %3 %4\r\n").arg(QString::number(Matrix[0][0]), QString::number(Matrix[1][0]), QString::number(Matrix[2][0]), QString::number(Matrix[3][0])); Stream << QString("\t\t\t\t%1 %2 %3 %4\r\n").arg(QString::number(Matrix[0][1]), QString::number(Matrix[1][1]), QString::number(Matrix[2][1]), QString::number(Matrix[3][1])); Stream << QString("\t\t\t\t%1 %2 %3 %4\r\n").arg(QString::number(Matrix[0][2]), QString::number(Matrix[1][2]), QString::number(Matrix[2][2]), QString::number(Matrix[3][2])); Stream << QString("\t\t\t\t%1 %2 %3 %4\r\n").arg(QString::number(Matrix[0][3]), QString::number(Matrix[1][3]), QString::number(Matrix[2][3]), QString::number(Matrix[3][3])); Stream << "\t\t\t\r\n"; Stream << QString("\t\t\t\r\n").arg(ID); Stream << "\t\t\t\t\r\n"; Stream << "\t\t\t\t\t\r\n"; for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) { lcMeshSection* Section = &Mesh->mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) continue; const char* SourceColorName = gColorList[Section->ColorIndex].SafeName; const char* TargetColorName; if (Section->ColorIndex == gDefaultColor) TargetColorName = gColorList[ModelPart.ColorIndex].SafeName; else TargetColorName = gColorList[Section->ColorIndex].SafeName; Stream << QString("\t\t\t\t\t\t\r\n").arg(SourceColorName, TargetColorName); } Stream << "\t\t\t\t\t\r\n"; Stream << "\t\t\t\t\r\n"; Stream << "\t\t\t\r\n"; Stream << "\t\t\r\n"; } Stream << "\t\r\n"; Stream << "\r\n"; Stream << "\r\n"; Stream << "\t\r\n"; Stream << "\r\n"; Stream << "
\r\n"; return true; } bool Project::ExportCSV(const QString& FileName) { lcPartsList PartsList; if (!mModels.IsEmpty()) mModels[0]->GetPartsList(gDefaultColor, true, false, PartsList); if (PartsList.empty()) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export.")); return false; } QString SaveFileName = GetExportFileName(FileName, "csv", tr("Export CSV"), tr("CSV Files (*.csv);;All Files (*.*)")); if (SaveFileName.isEmpty()) return false; lcDiskFile CSVFile(SaveFileName); char Line[1024]; if (!CSVFile.Open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName)); return false; } CSVFile.WriteLine("Part Name,Color,Quantity,Part ID,Color Code\n"); for (const auto& PartIt : PartsList) { const PieceInfo* Info = PartIt.first; for (const auto& ColorIt : PartIt.second) { std::string Description = Info->m_strDescription; Description.erase(std::remove(Description.begin(), Description.end(), ','), Description.end()); sprintf(Line, "\"%s\",\"%s\",%d,%s,%d\n", Description.c_str(), gColorList[ColorIt.first].Name, ColorIt.second, Info->mFileName, gColorList[ColorIt.first].Code); CSVFile.WriteLine(Line); } } return true; } lcInstructions* Project::GetInstructions() { mInstructions.reset(); mInstructions = std::unique_ptr(new lcInstructions(this)); return mInstructions.get(); } void Project::ExportHTML(const lcHTMLExportOptions& Options) { QDir Dir(Options.PathName); Dir.mkpath(QLatin1String(".")); lcArray Models; if (Options.CurrentOnly) Models.Add(mActiveModel); else if (Options.SubModels) { Models.Add(mActiveModel); mActiveModel->GetSubModels(Models); } else Models = mModels; QString ProjectTitle = GetTitle(); auto AddPartsListImage = [&Dir](QTextStream& Stream, lcModel* Model, lcStep Step, const QString& BaseName) { QImage Image = Model->GetPartsListImage(1024, Step, LC_RGBA(255, 255, 255, 0), QFont("Arial", 16, QFont::Bold), Qt::black); if (!Image.isNull()) { QString ImageName = BaseName + QLatin1String("-parts.png"); QString FileName = QFileInfo(Dir, ImageName).absoluteFilePath(); Image.save(FileName); Stream << QString::fromLatin1("



\r\n").arg(ImageName); } }; for (lcModel* Model : Models) { QString BaseName = ProjectTitle.left(ProjectTitle.length() - QFileInfo(ProjectTitle).suffix().length() - 1); lcStep LastStep = Model->GetLastStep(); QString PageTitle; if (Models.GetSize() > 1) { BaseName += '-' + Model->GetProperties().mFileName; PageTitle = Model->GetProperties().mFileName; } else PageTitle = ProjectTitle; BaseName.replace('#', '_'); if (Options.SinglePage) { QString FileName = QFileInfo(Dir, BaseName + QLatin1String(".html")).absoluteFilePath(); QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString())); return; } QTextStream Stream(&File); Stream << QString::fromLatin1("\r\n\r\nInstructions for %1\r\n\r\n
\r\n
\r\n").arg(PageTitle); for (lcStep Step = 1; Step <= LastStep; Step++) { QString StepString = QString::fromLatin1("%1").arg(Step, 2, 10, QLatin1Char('0')); Stream << QString::fromLatin1("

\"Step



\r\n").arg(BaseName, StepString, StepString, QString::number(Options.StepImagesWidth), QString::number(Options.StepImagesHeight)); if (Options.PartsListStep) AddPartsListImage(Stream, Model, Step, QString("%1-%2").arg(BaseName, StepString)); } if (Options.PartsListEnd) AddPartsListImage(Stream, Model, 0, BaseName); Stream << QLatin1String("
\r\n


Created by LeoCAD
\r\n"); } else { if (Options.IndexPage) { QString FileName = QFileInfo(Dir, BaseName + QLatin1String("-index.html")).absoluteFilePath(); QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString())); return; } QTextStream Stream(&File); Stream << QString::fromLatin1("\r\n\r\nInstructions for %1\r\n\r\n
\r\n
\r\n").arg(PageTitle); for (lcStep Step = 1; Step <= LastStep; Step++) Stream << QString::fromLatin1("Step %3
\r\n
").arg(BaseName, QString("%1").arg(Step, 2, 10, QLatin1Char('0')), QString::number(Step)); if (Options.PartsListEnd) Stream << QString::fromLatin1("Pieces Used
\r\n").arg(BaseName); Stream << QLatin1String("
\r\n


Created by LeoCAD
\r\n"); } for (lcStep Step = 1; Step <= LastStep; Step++) { QString StepString = QString::fromLatin1("%1").arg(Step, 2, 10, QLatin1Char('0')); QString FileName = QFileInfo(Dir, QString("%1-%2.html").arg(BaseName, StepString)).absoluteFilePath(); QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString())); return; } QTextStream Stream(&File); Stream << QString::fromLatin1("\r\n\r\n%1 - Step %2\r\n\r\n
\r\n
\r\n").arg(PageTitle, QString::number(Step)); Stream << QString::fromLatin1("\"Step

\r\n").arg(BaseName, StepString, StepString, QString::number(Options.StepImagesWidth), QString::number(Options.StepImagesHeight)); if (Options.PartsListStep) AddPartsListImage(Stream, Model, Step, QString("%1-%2").arg(BaseName, StepString)); Stream << QLatin1String("
\r\n


"); if (Step != 1) Stream << QString::fromLatin1("Previous ").arg(BaseName, QString("%1").arg(Step - 1, 2, 10, QLatin1Char('0'))); if (Options.IndexPage) Stream << QString::fromLatin1("Index ").arg(BaseName); if (Step != LastStep) Stream << QString::fromLatin1("Next").arg(BaseName, QString("%1").arg(Step + 1, 2, 10, QLatin1Char('0'))); else if (Options.PartsListEnd) Stream << QString::fromLatin1("Pieces Used").arg(BaseName); Stream << QLatin1String("
\r\n"); } if (Options.PartsListEnd) { QString FileName = QFileInfo(Dir, BaseName + QLatin1String("-pieces.html")).absoluteFilePath(); QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString())); return; } QTextStream Stream(&File); Stream << QString::fromLatin1("\r\n\r\nPieces used by %1\r\n\r\n
\r\n
\n").arg(PageTitle); AddPartsListImage(Stream, Model, 0, BaseName); Stream << QLatin1String("
\r\n


"); Stream << QString::fromLatin1("Previous ").arg(BaseName, QString("%1").arg(LastStep, 2, 10, QLatin1Char('0'))); if (Options.IndexPage) Stream << QString::fromLatin1("Index ").arg(BaseName); Stream << QLatin1String("
\r\n"); } } QString StepImageBaseName = QFileInfo(Dir, BaseName + QLatin1String("-%1.png")).absoluteFilePath(); Model->SaveStepImages(StepImageBaseName, true, false, Options.StepImagesWidth, Options.StepImagesHeight, 1, LastStep); } if (Models.GetSize() > 1) { QString BaseName = ProjectTitle.left(ProjectTitle.length() - QFileInfo(ProjectTitle).suffix().length() - 1); QString FileName = QFileInfo(Dir, BaseName + QLatin1String("-index.html")).absoluteFilePath(); QFile File(FileName); if (!File.open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString())); return; } QTextStream Stream(&File); Stream << QString::fromLatin1("\r\n\r\nInstructions for %1\r\n\r\n
\r\n
\r\n").arg(ProjectTitle); for (int ModelIdx = 0; ModelIdx < Models.GetSize(); ModelIdx++) { lcModel* Model = Models[ModelIdx]; BaseName = ProjectTitle.left(ProjectTitle.length() - QFileInfo(ProjectTitle).suffix().length() - 1) + '-' + Model->GetProperties().mFileName; BaseName.replace('#', '_'); if (Options.SinglePage) { FileName = BaseName + QLatin1String(".html"); Stream << QString::fromLatin1("

%2").arg(FileName, Model->GetProperties().mFileName); } else if (Options.IndexPage) { FileName = BaseName + QLatin1String("-index.html"); Stream << QString::fromLatin1("

%2").arg(FileName, Model->GetProperties().mFileName); } else { lcStep LastStep = Model->GetLastStep(); Stream << QString::fromLatin1("

%1

").arg(Model->GetProperties().mFileName); for (lcStep Step = 1; Step <= LastStep; Step++) Stream << QString::fromLatin1("Step %3
\r\n
").arg(BaseName, QString("%1").arg(Step, 2, 10, QLatin1Char('0')), QString::number(Step)); if (Options.PartsListEnd) Stream << QString::fromLatin1("Pieces Used
\r\n").arg(BaseName); } } Stream << QLatin1String("
\r\n


Created by LeoCAD
\r\n"); } } bool Project::ExportPOVRay(const QString& FileName) { std::vector ModelParts = GetModelParts(); if (ModelParts.empty()) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export.")); return false; } QString SaveFileName = GetExportFileName(FileName, QLatin1String("pov"), tr("Export POV-Ray"), tr("POV-Ray Files (*.pov);;All Files (*.*)")); if (SaveFileName.isEmpty()) return false; lcDiskFile POVFile(SaveFileName); if (!POVFile.Open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName)); return false; } POVFile.WriteLine("#version 3.7;\n\nglobal_settings {\n assumed_gamma 1.0\n}\n\n"); char Line[1024]; lcPiecesLibrary* Library = lcGetPiecesLibrary(); std::map> PieceTable; size_t NumColors = gColorList.size(); std::vector> ColorTable(NumColors); enum { LGEO_PIECE_LGEO = 0x01, LGEO_PIECE_AR = 0x02, LGEO_PIECE_SLOPE = 0x04 }; enum { LGEO_COLOR_SOLID = 0x01, LGEO_COLOR_TRANSPARENT = 0x02, LGEO_COLOR_CHROME = 0x04, LGEO_COLOR_PEARL = 0x08, LGEO_COLOR_METALLIC = 0x10, LGEO_COLOR_RUBBER = 0x20, LGEO_COLOR_GLITTER = 0x40 }; QString LGEOPath; // todo: load lgeo from registry and make sure it still works if (!LGEOPath.isEmpty()) { lcDiskFile TableFile(QFileInfo(QDir(LGEOPath), QLatin1String("lg_elements.lst")).absoluteFilePath()); if (!TableFile.Open(QIODevice::ReadOnly)) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Could not find LGEO files in folder '%1'.").arg(LGEOPath)); return false; } while (TableFile.ReadLine(Line, sizeof(Line))) { char Src[129], Dst[129], Flags[11]; if (*Line == ';') continue; if (sscanf(Line,"%128s%128s%10s", Src, Dst, Flags) != 3) continue; strcat(Src, ".dat"); PieceInfo* Info = Library->FindPiece(Src, nullptr, false, false); if (!Info) continue; if (strchr(Flags, 'L')) { std::pair& Entry = PieceTable[Info]; Entry.second |= LGEO_PIECE_LGEO; sprintf(Entry.first, "lg_%s", Dst); } if (strchr(Flags, 'A')) { std::pair& Entry = PieceTable[Info]; Entry.second |= LGEO_PIECE_AR; sprintf(Entry.first, "ar_%s", Dst); } if (strchr(Flags, 'S')) { std::pair& Entry = PieceTable[Info]; Entry.second |= LGEO_PIECE_SLOPE; Entry.first[0] = 0; } } lcDiskFile ColorFile(QFileInfo(QDir(LGEOPath), QLatin1String("lg_colors.lst")).absoluteFilePath()); if (!ColorFile.Open(QIODevice::ReadOnly)) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Could not find LGEO files in folder '%1'.").arg(LGEOPath)); return false; } while (ColorFile.ReadLine(Line, sizeof(Line))) { char Name[1024], Flags[1024]; int Code; if (*Line == ';') continue; if (sscanf(Line,"%d%s%s", &Code, Name, Flags) != 3) continue; size_t Color = lcGetColorIndex(Code); if (Color >= NumColors) continue; strcpy(ColorTable[Color].data(), Name); } } std::set AddedMeshes; if (!LGEOPath.isEmpty()) { POVFile.WriteLine("#include \"lg_defs.inc\"\n#include \"lg_color.inc\"\n\n"); for (const lcModelPartsEntry& ModelPart : ModelParts) { if (ModelPart.Mesh) continue; auto Search = PieceTable.find(ModelPart.Info); if (Search == PieceTable.end()) continue; lcMesh* Mesh = ModelPart.Info->GetMesh(); if (!Mesh) continue; if (!AddedMeshes.insert(Mesh).second) continue; const std::pair& Entry = Search->second; if (Entry.first[0]) { sprintf(Line, "#include \"%s.inc\"\n", Entry.first); POVFile.WriteLine(Line); } } POVFile.WriteLine("\n"); } for (size_t ColorIdx = 0; ColorIdx < gColorList.size(); ColorIdx++) { lcColor* Color = &gColorList[ColorIdx]; if (lcIsColorTranslucent(ColorIdx)) { sprintf(Line, "#declare lc_%s = texture { pigment { rgb <%f, %f, %f> filter 0.9 } finish { ambient 0.3 diffuse 0.2 reflection 0.25 phong 0.3 phong_size 60 } }\n", Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]); } else { sprintf(Line, "#declare lc_%s = texture { pigment { rgb <%f, %f, %f> } finish { ambient 0.1 phong 0.2 phong_size 20 } }\n", Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]); } POVFile.WriteLine(Line); if (!ColorTable[ColorIdx][0]) sprintf(ColorTable[ColorIdx].data(), "lc_%s", Color->SafeName); } POVFile.WriteLine("\n"); std::vector ColorTablePointer; ColorTablePointer.resize(NumColors); for (size_t ColorIdx = 0; ColorIdx < NumColors; ColorIdx++) ColorTablePointer[ColorIdx] = ColorTable[ColorIdx].data(); auto GetMeshName = [](const lcModelPartsEntry& ModelPart, char (&Name)[LC_PIECE_NAME_LEN]) { strcpy(Name, ModelPart.Info->mFileName); for (char* c = Name; *c; c++) if (*c == '-' || *c == '.') *c = '_'; if (ModelPart.Mesh) { char Suffix[32]; sprintf(Suffix, "_%p", ModelPart.Mesh); strncat(Name, Suffix, sizeof(Name) - 1); Name[sizeof(Name) - 1] = 0; } }; for (const lcModelPartsEntry& ModelPart : ModelParts) { lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh; if (!AddedMeshes.insert(Mesh).second) continue; if (!Mesh) continue; char Name[LC_PIECE_NAME_LEN]; GetMeshName(ModelPart, Name); if (!ModelPart.Mesh) { std::pair& Entry = PieceTable[ModelPart.Info]; strcpy(Entry.first, "lc_"); strncat(Entry.first, Name, sizeof(Entry.first) - 1); Entry.first[sizeof(Entry.first) - 1] = 0; } Mesh->ExportPOVRay(POVFile, Name, &ColorTablePointer[0]); sprintf(Line, "#declare lc_%s_clear = lc_%s\n\n", Name, Name); POVFile.WriteLine(Line); } const lcCamera* Camera = gMainWindow->GetActiveView()->GetCamera(); const lcVector3& Position = Camera->mPosition; const lcVector3& Target = Camera->mTargetPosition; const lcVector3& Up = Camera->mUpVector; sprintf(Line, "camera {\n perspective\n right x * image_width / image_height\n sky<%1g,%1g,%1g>\n location <%1g, %1g, %1g>\n look_at <%1g, %1g, %1g>\n angle %.0f * image_width / image_height\n}\n\n", Up[1], Up[0], Up[2], Position[1] / 25.0f, Position[0] / 25.0f, Position[2] / 25.0f, Target[1] / 25.0f, Target[0] / 25.0f, Target[2] / 25.0f, Camera->m_fovy); POVFile.WriteLine(Line); lcVector3 BackgroundColor = lcVector3FromColor(lcGetPreferences().mBackgroundSolidColor); sprintf(Line, "background { color rgb <%1g, %1g, %1g> }\n\n", BackgroundColor[0], BackgroundColor[1], BackgroundColor[2]); POVFile.WriteLine(Line); lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX); lcVector3 Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); for (const lcModelPartsEntry& ModelPart : ModelParts) { lcVector3 Points[8]; lcGetBoxCorners(ModelPart.Info->GetBoundingBox(), Points); for (int PointIdx = 0; PointIdx < 8; PointIdx++) { lcVector3 Point = lcMul31(Points[PointIdx], ModelPart.WorldMatrix); Min = lcMin(Point, Min); Max = lcMax(Point, Max); } } lcVector3 Center = (Min + Max) / 2.0f; float Radius = (Max - Center).Length() / 25.0f; Center = lcVector3(Center[1], Center[0], Center[2]) / 25.0f; sprintf(Line, "light_source{ <%f, %f, %f>\n color rgb 0.75\n area_light 200, 200, 10, 10\n jitter\n}\n\n", 0.0f * Radius + Center.x, -1.5f * Radius + Center.y, -1.5f * Radius + Center.z); POVFile.WriteLine(Line); sprintf(Line, "light_source{ <%f, %f, %f>\n color rgb 0.75\n area_light 200, 200, 10, 10\n jitter\n}\n\n", 1.5f * Radius + Center.x, -1.0f * Radius + Center.y, 0.866026f * Radius + Center.z); POVFile.WriteLine(Line); sprintf(Line, "light_source{ <%f, %f, %f>\n color rgb 0.5\n area_light 200, 200, 10, 10\n jitter\n}\n\n", 0.0f * Radius + Center.x, -2.0f * Radius + Center.y, 0.0f * Radius + Center.z); POVFile.WriteLine(Line); sprintf(Line, "light_source{ <%f, %f, %f>\n color rgb 0.5\n area_light 200, 200, 10, 10\n jitter\n}\n\n", 2.0f * Radius + Center.x, 0.0f * Radius + Center.y, -2.0f * Radius + Center.z); POVFile.WriteLine(Line); for (const lcModelPartsEntry& ModelPart : ModelParts) { int Color = ModelPart.ColorIndex; const char* Suffix = lcIsColorTranslucent(Color) ? "_clear" : ""; const float* f = ModelPart.WorldMatrix; if (!ModelPart.Mesh) { std::pair& Entry = PieceTable[ModelPart.Info]; if (Entry.second & LGEO_PIECE_SLOPE) { sprintf(Line, "merge {\n object {\n %s%s\n texture { %s }\n }\n" " object {\n %s_slope\n texture { %s normal { bumps 0.3 scale 0.02 } }\n }\n" " matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f>\n}\n", Entry.first, Suffix, ColorTable[Color].data(), Entry.first, ColorTable[Color].data(), -f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13] / 25.0f, f[12] / 25.0f, f[14] / 25.0f); } else { if (!ModelPart.Info || !ModelPart.Info->GetMesh()) continue; sprintf(Line, "object {\n %s%s\n texture { %s }\n matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f>\n}\n", Entry.first, Suffix, ColorTable[Color].data(), -f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13] / 25.0f, f[12] / 25.0f, f[14] / 25.0f); } } else { char Name[LC_PIECE_NAME_LEN]; GetMeshName(ModelPart, Name); sprintf(Line, "object {\n lc_%s%s\n texture { %s }\n matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f>\n}\n", Name, Suffix, ColorTable[Color].data(), -f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13] / 25.0f, f[12] / 25.0f, f[14] / 25.0f); } POVFile.WriteLine(Line); } return true; } bool Project::ExportWavefront(const QString& FileName) { std::vector ModelParts = GetModelParts(); if (ModelParts.empty()) { QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export.")); return false; } QString SaveFileName = GetExportFileName(FileName, QLatin1String("obj"), tr("Export Wavefront"), tr("Wavefront Files (*.obj);;All Files (*.*)")); if (SaveFileName.isEmpty()) return false; lcDiskFile OBJFile(SaveFileName); char Line[1024]; if (!OBJFile.Open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName)); return false; } quint32 vert = 1; OBJFile.WriteLine("# Model exported from LeoCAD\n"); QFileInfo SaveInfo(SaveFileName); QString MaterialFileName = QDir(SaveInfo.absolutePath()).absoluteFilePath(SaveInfo.completeBaseName() + QLatin1String(".mtl")); sprintf(Line, "#\n\nmtllib %s\n\n", QFileInfo(MaterialFileName).fileName().toLatin1().constData()); OBJFile.WriteLine(Line); lcDiskFile MaterialFile(MaterialFileName); if (!MaterialFile.Open(QIODevice::WriteOnly)) { QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(MaterialFileName)); return false; } MaterialFile.WriteLine("# Colors used by LeoCAD\n\n"); for (const lcColor& Color : gColorList) { if (Color.Translucent) sprintf(Line, "newmtl %s\nKd %.2f %.2f %.2f\nD %.2f\n\n", Color.SafeName, Color.Value[0], Color.Value[1], Color.Value[2], Color.Value[3]); else sprintf(Line, "newmtl %s\nKd %.2f %.2f %.2f\n\n", Color.SafeName, Color.Value[0], Color.Value[1], Color.Value[2]); MaterialFile.WriteLine(Line); } for (const lcModelPartsEntry& ModelPart : ModelParts) { lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh; if (!Mesh) continue; const lcMatrix44& ModelWorld = ModelPart.WorldMatrix; lcVertex* Verts = (lcVertex*)Mesh->mVertexData; for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++) { lcVector3 Vertex = lcMul31(Verts[VertexIdx].Position, ModelWorld); sprintf(Line, "v %.2f %.2f %.2f\n", Vertex[0], Vertex[1], Vertex[2]); OBJFile.WriteLine(Line); } OBJFile.WriteLine("#\n\n"); } for (const lcModelPartsEntry& ModelPart : ModelParts) { lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh; if (!Mesh) continue; const lcMatrix44& ModelWorld = ModelPart.WorldMatrix; lcVertex* Verts = (lcVertex*)Mesh->mVertexData; for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++) { lcVector3 Normal = lcMul30(lcUnpackNormal(Verts[VertexIdx].Normal), ModelWorld); sprintf(Line, "vn %.2f %.2f %.2f\n", Normal[0], Normal[1], Normal[2]); OBJFile.WriteLine(Line); } OBJFile.WriteLine("#\n\n"); } int NumPieces = 0; for (const lcModelPartsEntry& ModelPart : ModelParts) { sprintf(Line, "g Piece%.3d\n", NumPieces++); OBJFile.WriteLine(Line); lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh; if (Mesh) { Mesh->ExportWavefrontIndices(OBJFile, ModelPart.ColorIndex, vert); vert += Mesh->mNumVertices; } } return true; } void Project::SaveImage() { lcQImageDialog Dialog(gMainWindow); if (Dialog.exec() != QDialog::Accepted) return; QString Extension = QFileInfo(Dialog.mFileName).suffix(); if (!Extension.isEmpty()) lcSetProfileString(LC_PROFILE_IMAGE_EXTENSION, Dialog.mFileName.right(Extension.length() + 1)); if (Dialog.mStart != Dialog.mEnd) Dialog.mFileName = Dialog.mFileName.insert(Dialog.mFileName.length() - Extension.length() - 1, QLatin1String("%1")); mActiveModel->SaveStepImages(Dialog.mFileName, Dialog.mStart != Dialog.mEnd, false, Dialog.mWidth, Dialog.mHeight, Dialog.mStart, Dialog.mEnd); } void Project::UpdatePieceInfo(PieceInfo* Info) const { if (!mModels.IsEmpty()) { std::vector UpdatedModels; mModels[0]->UpdatePieceInfo(UpdatedModels); lcBoundingBox BoundingBox = mModels[0]->GetPieceInfo()->GetBoundingBox(); Info->SetBoundingBox(BoundingBox.Min, BoundingBox.Max); } } void Project::MarkAsModified() { mModified = true; } leocad-23.03/common/project.h000066400000000000000000000057771440571307300161030ustar00rootroot00000000000000#pragma once #include "lc_array.h" #include "lc_application.h" #define LC_HTML_SINGLEPAGE 0x01 #define LC_HTML_INDEX 0x02 #define LC_HTML_LISTEND 0x08 #define LC_HTML_LISTSTEP 0x10 #define LC_HTML_SUBMODELS 0x40 #define LC_HTML_CURRENT_ONLY 0x80 class lcHTMLExportOptions { public: lcHTMLExportOptions(const Project* Project); void SaveDefaults(); QString PathName; bool TransparentImages; bool SubModels; bool CurrentOnly; bool SinglePage; bool IndexPage; int StepImagesWidth; int StepImagesHeight; bool PartsListStep; bool PartsListEnd; }; class Project { public: Project(bool IsPreview = false); ~Project(); Project(const Project&) = delete; Project(Project&&) = delete; Project& operator=(const Project&) = delete; Project& operator=(Project&&) = delete; const lcArray& GetModels() const { return mModels; } lcModel* GetModel(const QString& FileName) const; lcModel* GetActiveModel() const { return mActiveModel; } int GetActiveModelIndex() const { return mModels.FindIndex(mActiveModel); } lcModel* GetMainModel() const { return !mModels.IsEmpty() ? mModels[0] : nullptr; } bool IsModified() const; void MarkAsModified(); QString GetTitle() const; QString GetFileName() const { return mFileName; } QString GetImageFileName(bool AllowCurrentFolder) const; lcInstructions* GetInstructions(); void SetActiveModel(int ModelIndex); void SetActiveModel(const QString& FileName); lcModel* CreateNewModel(bool ShowModel); QString GetNewModelName(QWidget* ParentWidget, const QString& DialogTitle, const QString& CurrentName, const QStringList& ExistingModels) const; void ShowModelListDialog(); bool Load(const QString& FileName, bool ShowErrors); bool Save(const QString& FileName); bool Save(QTextStream& Stream); void Merge(Project* Other); bool ImportLDD(const QString& FileName); bool ImportInventory(const QByteArray& Inventory, const QString& Name, const QString& Description); void SaveImage(); bool ExportModel(const QString& FileName, lcModel* Model) const; bool Export3DStudio(const QString& FileName); void ExportBrickLink(); bool ExportCOLLADA(const QString& FileName); bool ExportCSV(const QString& FileName); void ExportHTML(const lcHTMLExportOptions& Options); bool ExportPOVRay(const QString& FileName); bool ExportWavefront(const QString& FileName); void UpdatePieceInfo(PieceInfo* Info) const; protected: QString GetExportFileName(const QString& FileName, const QString& DefaultExtension, const QString& DialogTitle, const QString& DialogFilter) const; std::vector GetModelParts(); void SetFileName(const QString& FileName); bool mIsPreview; bool mModified; QString mFileName; QFileSystemWatcher mFileWatcher; lcArray mModels; lcModel* mActiveModel; std::unique_ptr mInstructions; Q_DECLARE_TR_FUNCTIONS(Project); }; inline lcModel* lcGetActiveModel() { const Project* const Project = lcGetActiveProject(); return Project ? Project->GetActiveModel() : nullptr; } leocad-23.03/common/texfont.cpp000066400000000000000000000474651440571307300164570ustar00rootroot00000000000000#include "lc_global.h" #include #include "texfont.h" #include "lc_context.h" #include "lc_texture.h" #include "image.h" static const unsigned char TextureData[2048] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0xe0, 0x00, 0x18, 0x60, 0x66, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x60, 0x66, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb1, 0x03, 0x0f, 0x6e, 0x78, 0xfc, 0xb8, 0xd9, 0x61, 0x66, 0xcc, 0xec, 0x1c, 0x3b, 0x00, 0x0c, 0x73, 0x86, 0x19, 0x73, 0xcc, 0x30, 0xcc, 0x39, 0x63, 0x66, 0xc6, 0x9c, 0x33, 0x67, 0x00, 0x00, 0x33, 0xcc, 0x90, 0x61, 0x86, 0x31, 0x86, 0x19, 0x66, 0x66, 0xc3, 0x8c, 0x31, 0xc3, 0x00, 0xe0, 0x33, 0xcc, 0x80, 0x61, 0x86, 0x31, 0x86, 0x19, 0x66, 0xe6, 0xc1, 0x8c, 0x31, 0xc3, 0x00, 0x38, 0x33, 0xcc, 0x80, 0x61, 0xfe, 0x31, 0x86, 0x19, 0x66, 0xe6, 0xc1, 0x8c, 0x31, 0xc3, 0x00, 0x0c, 0x33, 0xcc, 0x80, 0x61, 0x06, 0x30, 0x86, 0x19, 0x66, 0x66, 0xc3, 0x8c, 0x31, 0xc3, 0x00, 0x0c, 0x33, 0xcc, 0x90, 0x61, 0x06, 0x30, 0x86, 0x19, 0x66, 0x66, 0xc6, 0x8c, 0x31, 0xc3, 0x00, 0x0c, 0x73, 0x86, 0x19, 0x73, 0x8c, 0x31, 0xcc, 0x19, 0x66, 0x66, 0xcc, 0x8c, 0x31, 0xc3, 0x00, 0xf8, 0xb6, 0x03, 0x0f, 0x6e, 0xf8, 0x30, 0xb8, 0x19, 0x66, 0x66, 0xd8, 0x8c, 0x31, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0xf0, 0xb0, 0x03, 0x37, 0x3b, 0x9f, 0xdf, 0xb0, 0xc1, 0x03, 0xf0, 0xf0, 0x60, 0x3f, 0x63, 0x00, 0x98, 0x71, 0x86, 0x39, 0x8f, 0x31, 0xc6, 0xb0, 0xc1, 0xc3, 0xf0, 0xf0, 0x60, 0x30, 0x63, 0x00, 0x0c, 0x33, 0xcc, 0x30, 0x87, 0x01, 0xc6, 0x30, 0x63, 0xc6, 0x98, 0x99, 0x31, 0x18, 0x63, 0x00, 0x0c, 0x33, 0xcc, 0x30, 0x83, 0x03, 0xc6, 0x30, 0x63, 0xe6, 0x19, 0x8f, 0x31, 0x18, 0x63, 0x00, 0x0c, 0x33, 0xcc, 0x30, 0x03, 0x1f, 0xc6, 0x30, 0x63, 0xe6, 0x19, 0x86, 0x31, 0x0c, 0x63, 0x00, 0x0c, 0x33, 0xcc, 0x30, 0x03, 0x38, 0xc6, 0x30, 0x36, 0x2c, 0x0d, 0x0f, 0x1b, 0x06, 0x63, 0x00, 0x0c, 0x33, 0xcc, 0x30, 0x03, 0x30, 0xc6, 0x30, 0x36, 0x3c, 0x8f, 0x19, 0x1b, 0x06, 0x63, 0x00, 0x98, 0x71, 0x86, 0x39, 0x83, 0x31, 0x86, 0x39, 0x1c, 0x18, 0xc6, 0x30, 0x0e, 0x03, 0x36, 0x00, 0xf0, 0xb0, 0x03, 0x37, 0x03, 0x1f, 0x1c, 0x37, 0x1c, 0x18, 0xc6, 0x30, 0x0e, 0x3f, 0x1c, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xf0, 0xe1, 0x03, 0xc6, 0x1f, 0x1e, 0x7f, 0x7c, 0xf8, 0x00, 0x01, 0x7f, 0x80, 0x0f, 0x00, 0x78, 0x18, 0x33, 0x06, 0xc6, 0x00, 0x03, 0x60, 0xc6, 0x8c, 0x81, 0x03, 0xc3, 0xc0, 0x18, 0x00, 0x60, 0x08, 0x13, 0x06, 0xc7, 0x80, 0x01, 0x60, 0xc6, 0x8c, 0x81, 0x03, 0x83, 0x61, 0x30, 0x00, 0x60, 0x00, 0x03, 0x06, 0xc7, 0x80, 0x01, 0x30, 0xc6, 0x8c, 0xc1, 0x06, 0x83, 0x61, 0x30, 0x00, 0x60, 0x00, 0x03, 0x86, 0xc7, 0x8f, 0x01, 0x30, 0xc6, 0x8c, 0xc1, 0x06, 0xc3, 0x30, 0x00, 0x00, 0x60, 0x80, 0xc1, 0xc3, 0xc6, 0x98, 0x1f, 0x18, 0x7c, 0x8c, 0x61, 0x0c, 0x7f, 0x30, 0x00, 0x00, 0x60, 0xc0, 0x00, 0xc6, 0x06, 0x98, 0x31, 0x18, 0xc6, 0xf8, 0x61, 0x0c, 0xc3, 0x30, 0x00, 0x00, 0x60, 0x60, 0x00, 0x66, 0x06, 0x98, 0x31, 0x18, 0xc6, 0x80, 0x31, 0x18, 0x83, 0x31, 0x00, 0x00, 0x60, 0x30, 0x00, 0xe6, 0x0f, 0x98, 0x31, 0x0c, 0xc6, 0x80, 0xf1, 0x1f, 0x83, 0x61, 0x30, 0x00, 0x60, 0x18, 0x10, 0x06, 0x46, 0x98, 0x31, 0x0c, 0xc6, 0x80, 0x19, 0x30, 0x83, 0x61, 0x30, 0x00, 0x60, 0x18, 0x30, 0x06, 0xc6, 0x98, 0x31, 0x0c, 0xc6, 0xc0, 0x18, 0x30, 0xc3, 0xc0, 0x18, 0x00, 0x60, 0xf8, 0xe3, 0x03, 0x86, 0x0f, 0x1f, 0x0c, 0x7c, 0x78, 0x18, 0x30, 0x7f, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x81, 0x7f, 0xfc, 0x83, 0x0f, 0x06, 0x63, 0xc0, 0x18, 0xc6, 0x00, 0x03, 0xc6, 0x60, 0x00, 0x18, 0x83, 0x01, 0x0c, 0xc0, 0x18, 0x06, 0x63, 0xc0, 0x18, 0xc3, 0x00, 0x03, 0xc6, 0x60, 0x00, 0x18, 0x86, 0x01, 0x0c, 0x60, 0x30, 0x06, 0x63, 0xc0, 0x98, 0xc1, 0x00, 0x07, 0xc7, 0x61, 0x00, 0x18, 0x86, 0x01, 0x0c, 0x60, 0x30, 0x06, 0x63, 0xc0, 0xd8, 0xc0, 0x00, 0x07, 0xc7, 0x63, 0x00, 0x18, 0x8c, 0x01, 0x0c, 0x30, 0x00, 0x06, 0x63, 0xc0, 0x78, 0xc0, 0x00, 0x8f, 0xc7, 0x67, 0x00, 0x18, 0x8c, 0x3f, 0xfc, 0x31, 0x00, 0xfe, 0x63, 0xc0, 0x38, 0xc0, 0x00, 0x8f, 0xc7, 0x66, 0x00, 0x18, 0x8c, 0x01, 0x0c, 0x30, 0x3e, 0x06, 0x63, 0xc0, 0x78, 0xc0, 0x00, 0xdb, 0xc6, 0x6c, 0x00, 0x18, 0x8c, 0x01, 0x0c, 0x30, 0x30, 0x06, 0x63, 0xc0, 0xd8, 0xc0, 0x00, 0xdb, 0xc6, 0x7c, 0x00, 0x18, 0x86, 0x01, 0x0c, 0x60, 0x30, 0x06, 0x63, 0xc6, 0x98, 0xc1, 0x00, 0x73, 0xc6, 0x78, 0x00, 0x18, 0x86, 0x01, 0x0c, 0x60, 0x38, 0x06, 0x63, 0xc6, 0x18, 0xc3, 0x00, 0x73, 0xc6, 0x70, 0x00, 0x18, 0x83, 0x01, 0x0c, 0xc0, 0x38, 0x06, 0x63, 0x6c, 0x18, 0xc6, 0x00, 0x23, 0xc6, 0x60, 0x00, 0xf8, 0x81, 0x7f, 0x0c, 0x80, 0x2f, 0x06, 0x63, 0x38, 0x18, 0xcc, 0x3f, 0x23, 0xc6, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x7f, 0xc0, 0x03, 0x7f, 0xc0, 0xe3, 0x7f, 0x06, 0x33, 0xb0, 0x01, 0xd8, 0xc0, 0x00, 0x60, 0x06, 0xc3, 0x60, 0x06, 0xc3, 0x60, 0x06, 0x06, 0x06, 0x33, 0xb0, 0x61, 0xd8, 0xc0, 0x00, 0x30, 0x0c, 0x83, 0x31, 0x0c, 0x83, 0x31, 0x0c, 0x06, 0x06, 0x63, 0x98, 0x61, 0x98, 0x61, 0x00, 0x30, 0x0c, 0x83, 0x31, 0x0c, 0x83, 0x31, 0x00, 0x06, 0x06, 0x63, 0x18, 0x63, 0x0c, 0x33, 0x00, 0x18, 0x18, 0x83, 0x19, 0x18, 0x83, 0x61, 0x00, 0x06, 0x06, 0x63, 0x18, 0xf3, 0x0c, 0x1e, 0x00, 0x18, 0x18, 0xc3, 0x18, 0x18, 0xc3, 0xc0, 0x03, 0x06, 0x06, 0xc3, 0x0c, 0xf3, 0x0c, 0x0c, 0x00, 0x18, 0x18, 0x7f, 0x18, 0x18, 0x7f, 0x00, 0x06, 0x06, 0x06, 0xc3, 0x0c, 0x96, 0x06, 0x0c, 0x00, 0x18, 0x18, 0x03, 0x98, 0x19, 0xc3, 0x00, 0x0c, 0x06, 0x06, 0x83, 0x04, 0x9e, 0x07, 0x1e, 0x00, 0x30, 0x0c, 0x03, 0x30, 0x0f, 0x83, 0x01, 0x0c, 0x06, 0x06, 0x83, 0x07, 0x9e, 0x07, 0x33, 0x00, 0x30, 0x0c, 0x03, 0x30, 0x0e, 0x83, 0x31, 0x0c, 0x06, 0x06, 0x83, 0x07, 0x0c, 0x83, 0x61, 0x00, 0x60, 0x06, 0x03, 0x60, 0x0e, 0x83, 0x61, 0x06, 0x06, 0x8c, 0x01, 0x03, 0x0c, 0xc3, 0xc0, 0x00, 0xc0, 0x03, 0x03, 0xc0, 0x1b, 0x03, 0xc3, 0x03, 0x06, 0xf8, 0x00, 0x03, 0x0c, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xec, 0x3f, 0x00, 0x03, 0x00, 0x00, 0x80, 0xf1, 0x80, 0x07, 0xf0, 0x03, 0x08, 0x1c, 0x18, 0x0c, 0x0c, 0x30, 0x00, 0x03, 0x00, 0x66, 0x80, 0x99, 0xc1, 0x0c, 0x1c, 0x0e, 0x3e, 0x36, 0x0c, 0x18, 0x06, 0x18, 0x00, 0x03, 0x00, 0xc3, 0x80, 0x0d, 0x63, 0x18, 0x06, 0x18, 0x6b, 0x36, 0x06, 0x30, 0x03, 0x0c, 0x00, 0x33, 0x83, 0x81, 0x81, 0x01, 0x63, 0x18, 0xc6, 0x19, 0x6b, 0x36, 0x03, 0x30, 0x03, 0x0c, 0x00, 0x33, 0xc3, 0x00, 0xc3, 0x00, 0x63, 0x18, 0x63, 0x33, 0x0b, 0x9c, 0x01, 0xe0, 0x01, 0x06, 0x00, 0x03, 0x60, 0x00, 0xc6, 0x80, 0x61, 0x18, 0x33, 0x33, 0x0b, 0xc0, 0x00, 0xe0, 0x01, 0x03, 0x00, 0x03, 0x30, 0x00, 0xcc, 0xc0, 0x60, 0x18, 0x33, 0x33, 0x3e, 0x60, 0x00, 0xc0, 0x80, 0x01, 0x00, 0x03, 0x60, 0x00, 0xc6, 0x60, 0x30, 0x30, 0x33, 0x33, 0x68, 0x30, 0x07, 0xc0, 0x80, 0x01, 0x00, 0x03, 0xc0, 0x00, 0x63, 0x60, 0x60, 0x18, 0x33, 0x1b, 0x68, 0x98, 0x0d, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x81, 0x61, 0x00, 0x60, 0x18, 0xe6, 0x0e, 0x6b, 0x8c, 0x0d, 0xc0, 0x60, 0x80, 0x19, 0x33, 0x03, 0xc3, 0x60, 0x60, 0x60, 0x18, 0x06, 0x00, 0x6b, 0x86, 0x0d, 0xc0, 0xe0, 0xbf, 0x19, 0x33, 0x03, 0x66, 0x60, 0x60, 0x60, 0x18, 0x1c, 0x00, 0x3e, 0x03, 0x07, 0x00, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0xf0, 0x03, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x66, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, 0x33, 0xc3, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x33, 0xc3, 0x00, 0x0c, 0x7f, 0x00, 0x0c, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x1e, 0xc3, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x81, 0x7f, 0xc3, 0x80, 0x7f, 0x00, 0x00, 0x0c, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1b, 0x1e, 0xc3, 0x3e, 0x0c, 0x7f, 0x00, 0x0c, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x33, 0xc3, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x83, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x33, 0xc3, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x03, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00, 0xc3, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x03, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0d, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xff, 0x0d, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const unsigned char GlyphData[] = { 0x20, 0x4b, 0x80, 0x04, 0x21, 0x1e, 0x70, 0x05, 0x23, 0x4f, 0x80, 0x09, 0x24, 0x67, 0x70, 0x09, 0x25, 0x70, 0x70, 0x0d, 0x26, 0x03, 0x80, 0x0b, 0x28, 0x17, 0x80, 0x05, 0x29, 0x1c, 0x80, 0x05, 0x2a, 0x0e, 0x80, 0x09, 0x2b, 0x26, 0x80, 0x09, 0x2c, 0x16, 0x70, 0x04, 0x2d, 0x21, 0x80, 0x05, 0x2e, 0x1a, 0x70, 0x04, 0x2f, 0x3d, 0x70, 0x04, 0x30, 0x6f, 0x24, 0x09, 0x31, 0x01, 0x37, 0x09, 0x32, 0x0a, 0x37, 0x09, 0x33, 0x13, 0x37, 0x09, 0x34, 0x1c, 0x37, 0x09, 0x35, 0x25, 0x37, 0x09, 0x36, 0x2e, 0x37, 0x09, 0x37, 0x37, 0x37, 0x09, 0x38, 0x40, 0x37, 0x09, 0x39, 0x49, 0x37, 0x09, 0x3a, 0x27, 0x70, 0x04, 0x3b, 0x23, 0x70, 0x04, 0x3c, 0x2b, 0x70, 0x09, 0x3d, 0x2f, 0x80, 0x09, 0x3e, 0x34, 0x70, 0x09, 0x3f, 0x41, 0x70, 0x0a, 0x40, 0x57, 0x70, 0x10, 0x41, 0x52, 0x37, 0x0c, 0x42, 0x5e, 0x37, 0x0c, 0x43, 0x6a, 0x37, 0x0c, 0x44, 0x01, 0x4a, 0x0c, 0x45, 0x0d, 0x4a, 0x0b, 0x46, 0x18, 0x4a, 0x0a, 0x47, 0x22, 0x4a, 0x0d, 0x48, 0x2f, 0x4a, 0x0c, 0x49, 0x3b, 0x4a, 0x05, 0x4a, 0x40, 0x4a, 0x09, 0x4b, 0x49, 0x4a, 0x0b, 0x4c, 0x54, 0x4a, 0x0a, 0x4d, 0x5e, 0x4a, 0x0e, 0x4e, 0x6c, 0x4a, 0x0c, 0x4f, 0x01, 0x5d, 0x0d, 0x50, 0x0e, 0x5d, 0x0b, 0x51, 0x19, 0x5d, 0x0d, 0x52, 0x26, 0x5d, 0x0c, 0x53, 0x32, 0x5d, 0x0b, 0x54, 0x3d, 0x5d, 0x0a, 0x55, 0x47, 0x5d, 0x0c, 0x56, 0x53, 0x5d, 0x0b, 0x57, 0x5e, 0x5d, 0x0f, 0x58, 0x6d, 0x5d, 0x0b, 0x59, 0x01, 0x70, 0x0b, 0x5a, 0x0c, 0x70, 0x0a, 0x5b, 0x41, 0x80, 0x05, 0x5d, 0x46, 0x80, 0x05, 0x5f, 0x38, 0x80, 0x09, 0x61, 0x01, 0x11, 0x0a, 0x62, 0x0b, 0x11, 0x0a, 0x63, 0x15, 0x11, 0x09, 0x64, 0x1e, 0x11, 0x0a, 0x65, 0x28, 0x11, 0x0a, 0x66, 0x32, 0x11, 0x06, 0x67, 0x38, 0x11, 0x0a, 0x68, 0x42, 0x11, 0x0a, 0x69, 0x4c, 0x11, 0x04, 0x6a, 0x50, 0x11, 0x04, 0x6b, 0x54, 0x11, 0x09, 0x6c, 0x5d, 0x11, 0x04, 0x6d, 0x61, 0x11, 0x0e, 0x6e, 0x6f, 0x11, 0x0a, 0x6f, 0x01, 0x24, 0x0a, 0x70, 0x0b, 0x24, 0x0a, 0x71, 0x15, 0x24, 0x0a, 0x72, 0x1f, 0x24, 0x07, 0x73, 0x26, 0x24, 0x09, 0x74, 0x2f, 0x24, 0x06, 0x75, 0x35, 0x24, 0x0a, 0x76, 0x3f, 0x24, 0x09, 0x77, 0x48, 0x24, 0x0e, 0x78, 0x56, 0x24, 0x08, 0x79, 0x5e, 0x24, 0x09, 0x7a, 0x67, 0x24, 0x08, 0x7b, 0x4b, 0x70, 0x06, 0x7d, 0x51, 0x70, 0x06, 0x00 }; // ============================================================================ TexFont gTexFont; TexFont::TexFont() { memset(&mGlyphs, 0, sizeof(mGlyphs)); } bool TexFont::Initialize(lcContext* Context) { if (mTexture) return true; mFontHeight = 16; mTextureWidth = 128; mTextureHeight = 128; Image Image; Image.Allocate(mTextureWidth, mTextureHeight, lcPixelFormat::L8A8); unsigned char* ExpandedData = Image.mData; for (unsigned int TexelIdx = 0; TexelIdx < sizeof(TextureData) * 8; TexelIdx++) { const unsigned char Texel = TextureData[TexelIdx / 8] & (1 << (TexelIdx % 8)) ? 255 : 0; ExpandedData[TexelIdx * 2] = ExpandedData[TexelIdx * 2 + 1] = Texel; } mTexture = new lcTexture(); mTexture->SetImage(std::move(Image), LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV | LC_TEXTURE_POINT); mTexture->Upload(Context); const unsigned char* Ptr = GlyphData; for (;;) { unsigned char Glyph = *Ptr++; if (!Glyph) break; mGlyphs[Glyph].left = *Ptr++; mGlyphs[Glyph].bottom = *Ptr++; mGlyphs[Glyph].width = *Ptr++; mGlyphs[Glyph].right = mGlyphs[Glyph].left + mGlyphs[Glyph].width; mGlyphs[Glyph].top = mGlyphs[Glyph].bottom - mFontHeight; mGlyphs[Glyph].left /= mTextureWidth; mGlyphs[Glyph].right /= mTextureWidth; mGlyphs[Glyph].top /= mTextureHeight; mGlyphs[Glyph].bottom /= mTextureHeight; } return true; } void TexFont::Reset() { mTexture = 0; } void TexFont::GetStringDimensions(int* cx, int* cy, const char* Text) const { *cx = 0; *cy = mFontHeight; while (*Text != 0) { *cx += mGlyphs[(int)(*Text)].width; Text++; } } void TexFont::PrintText(lcContext* Context, float Left, float Top, float Z, const char* Text) const { const size_t Length = strlen(Text); if (!Length) return; float* Verts = new float[6 * 5 * Length]; float* CurVert = Verts; while (*Text) { int ch = *Text; *CurVert++ = Left; *CurVert++ = Top; *CurVert++ = Z; *CurVert++ = mGlyphs[ch].left; *CurVert++ = mGlyphs[ch].top; *CurVert++ = Left; *CurVert++ = Top - mFontHeight; *CurVert++ = Z; *CurVert++ = mGlyphs[ch].left; *CurVert++ = mGlyphs[ch].bottom; *CurVert++ = Left + mGlyphs[ch].width; *CurVert++ = Top - mFontHeight; *CurVert++ = Z; *CurVert++ = mGlyphs[ch].right; *CurVert++ = mGlyphs[ch].bottom; *CurVert++ = Left + mGlyphs[ch].width; *CurVert++ = Top - mFontHeight; *CurVert++ = Z; *CurVert++ = mGlyphs[ch].right; *CurVert++ = mGlyphs[ch].bottom; *CurVert++ = Left + mGlyphs[ch].width; *CurVert++ = Top; *CurVert++ = Z; *CurVert++ = mGlyphs[ch].right; *CurVert++ = mGlyphs[ch].top; *CurVert++ = Left; *CurVert++ = Top; *CurVert++ = Z; *CurVert++ = mGlyphs[ch].left; *CurVert++ = mGlyphs[ch].top; Left += mGlyphs[ch].width; Text++; } Context->SetVertexBufferPointer(Verts); Context->SetVertexFormat(0, 3, 0, 2, 0, false); Context->DrawPrimitives(GL_TRIANGLES, 0, 6 * (GLsizei)Length); delete[] Verts; } void TexFont::GetTriangles(const lcMatrix44& Transform, const char* Text, float* Buffer) const { float Width = 0.0f; for (const char* ch = Text; *ch; ch++) { const int Glyph = *ch; Width += mGlyphs[Glyph].width; } float Left = -Width / 2.0f; const float Top = mFontHeight / 2.0f; const float Z = 0.0f; while (*Text) { int ch = *Text; lcVector3 Points[4] = { lcVector3(Left, Top, Z), lcVector3(Left, Top - mFontHeight, Z), lcVector3(Left + mGlyphs[ch].width, Top - mFontHeight, Z), lcVector3(Left + mGlyphs[ch].width, Top, Z), }; for (int PointIdx = 0; PointIdx < 4; PointIdx++) Points[PointIdx] = lcMul31(Points[PointIdx], Transform); *Buffer++ = Points[0].x; *Buffer++ = Points[0].y; *Buffer++ = Points[0].z; *Buffer++ = mGlyphs[ch].left; *Buffer++ = mGlyphs[ch].top; *Buffer++ = Points[1].x; *Buffer++ = Points[1].y; *Buffer++ = Points[1].z; *Buffer++ = mGlyphs[ch].left; *Buffer++ = mGlyphs[ch].bottom; *Buffer++ = Points[2].x; *Buffer++ = Points[2].y; *Buffer++ = Points[2].z; *Buffer++ = mGlyphs[ch].right; *Buffer++ = mGlyphs[ch].bottom; *Buffer++ = Points[2].x; *Buffer++ = Points[2].y; *Buffer++ = Points[2].z; *Buffer++ = mGlyphs[ch].right; *Buffer++ = mGlyphs[ch].bottom; *Buffer++ = Points[3].x; *Buffer++ = Points[3].y; *Buffer++ = Points[3].z; *Buffer++ = mGlyphs[ch].right; *Buffer++ = mGlyphs[ch].top; *Buffer++ = Points[0].x; *Buffer++ = Points[0].y; *Buffer++ = Points[0].z; *Buffer++ = mGlyphs[ch].left; *Buffer++ = mGlyphs[ch].top; Left += mGlyphs[ch].width; Text++; } } void TexFont::GetGlyphTriangles(float Left, float Top, float Z, int Glyph, float* Buffer) const { Left -= mGlyphs[Glyph].width / 2.0f; Top += mFontHeight / 2.0f; *Buffer++ = Left; *Buffer++ = Top; *Buffer++ = Z; *Buffer++ = mGlyphs[Glyph].left; *Buffer++ = mGlyphs[Glyph].top; *Buffer++ = Left; *Buffer++ = Top - mFontHeight; *Buffer++ = Z; *Buffer++ = mGlyphs[Glyph].left; *Buffer++ = mGlyphs[Glyph].bottom; *Buffer++ = Left + mGlyphs[Glyph].width; *Buffer++ = Top - mFontHeight; *Buffer++ = Z; *Buffer++ = mGlyphs[Glyph].right; *Buffer++ = mGlyphs[Glyph].bottom; *Buffer++ = Left + mGlyphs[Glyph].width; *Buffer++ = Top - mFontHeight; *Buffer++ = Z; *Buffer++ = mGlyphs[Glyph].right; *Buffer++ = mGlyphs[Glyph].bottom; *Buffer++ = Left + mGlyphs[Glyph].width; *Buffer++ = Top; *Buffer++ = Z; *Buffer++ = mGlyphs[Glyph].right; *Buffer++ = mGlyphs[Glyph].top; *Buffer++ = Left; *Buffer++ = Top; *Buffer++ = Z; *Buffer++ = mGlyphs[Glyph].left; *Buffer++ = mGlyphs[Glyph].top; } leocad-23.03/common/texfont.h000066400000000000000000000014141440571307300161040ustar00rootroot00000000000000#pragma once class TexFont { public: TexFont(); bool IsLoaded() const { return mTexture != nullptr; } lcTexture* GetTexture() const { return mTexture; } bool Initialize(lcContext* Context); void Reset(); void PrintText(lcContext* Context, float Left, float Top, float Z, const char* Text) const; void GetTriangles(const lcMatrix44& Transform, const char* Text, float* Buffer) const; void GetGlyphTriangles(float Left, float Top, float Z, int Glyph, float* Buffer) const; void GetStringDimensions(int* cx, int* cy, const char* Text) const; protected: struct { unsigned char width; float left, right, top, bottom; } mGlyphs[256]; lcTexture* mTexture = nullptr; int mTextureWidth; int mTextureHeight; int mFontHeight; }; extern TexFont gTexFont; leocad-23.03/docs/000077500000000000000000000000001440571307300137045ustar00rootroot00000000000000leocad-23.03/docs/COPYING.txt000066400000000000000000000432531440571307300155640ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.leocad-23.03/docs/CREDITS.txt000066400000000000000000000012371440571307300155450ustar00rootroot00000000000000The following people have contributed to LeoCAD: Author, Original Design: Leonardo Zide Contributions (in alphabetical order): Christian Höltje David Paleino Hubert Figuiere Joerg Scheurich Nicolas Guilbert Nicolas Schodet Pat Mahoney Petter Reinholdtsen Renaud Breard Rodney Rushing Torbjörn Söderstedt Translations: Sylvain L. Sauvage Zezinho leocad-23.03/docs/README.md000066400000000000000000000044671440571307300151760ustar00rootroot00000000000000# About LeoCAD LeoCAD is a CAD program for creating virtual LEGO(R) models. It's available for free under the GNU Public License v2 and works on the Windows, Linux and macOS Operating Systems. # Installation You can download the latest version of LeoCAD and its Parts Library from the main website at https://www.leocad.org It's recommended that you install the latest drivers for your video card since LeoCAD uses OpenGL to take advantage of hardware acceleration for rendering. ## LeoCAD for Windows Download the latest LeoCAD-Windows.exe to your computer, double click on the icon to launch the installer and follow the instructions. ## LeoCAD for Linux There are multiple ways to install LeoCAD on Linux. * Snap Store You can find LeoCAD in your distribution's Snap Store. Alternatively, you can enter `sudo snap install leocad` to install it using the command line. * AppImage Download the latest LeoCAD-Linux.AppImage, make the file executable (`chmod +x`) and run it. * Flatpak You can also install LeoCAD releases as a Flatpak from Flathub: https://flathub.org/apps/details/org.leocad.LeoCAD Note: there might be a delay for new releases to appear there. If you have it already installed, it will be updated. * From source If you prefer to compile LeoCAD yourself, go to the GitHub releases page at https://github.com/leozide/leocad/releases/latest and download the source archive from there. If you do not already have a Parts Library installed, you will need to download one and follow the installation instructions. More information on how to compile your own executable is available in the Documentation section of https://www.leocad.org ## LeoCAD for macOS Download the latest LeoCAD-macOS.dmg to your computer, double click on the icon to open the archive, copy LeoCAD.app to your Applications folder and then launch it from there. New users should read the online tutorial located at https://www.leocad.org/docs/tutorial1.html to learn how to use LeoCAD. # Online Resources - Website: https://www.leocad.org - GitHub page: https://github.com/leozide/leocad - Unstable builds: https://github.com/leozide/leocad/releases/tag/continuous # Legal Disclaimer LEGO(R) is a trademark of the LEGO Group of companies which does not sponsor, authorize or endorse this software. leocad-23.03/docs/leocad.1000066400000000000000000000133341440571307300152210ustar00rootroot00000000000000.TH LEOCAD 1 "5 June 2021" .\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection .\" other params are allowed: see man(7), man(1) .SH NAME LeoCAD \- CAD program for LEGO models. .SH SYNOPSIS \fIleocad \fR[\fIOPTIONS\fR] [\fIINFILE\fR] .SH "DESCRIPTION" \fILeoCAD \fR is a CAD program for creating virtual LEGO models. It has an easy to use interface and includes thousands of different parts in its library. .SH OPTIONS Below is a summary of all of the options that \fILeoCAD\fR accepts. Many options have two equivalent names, one of which is a single letter preceded by -, and the other of which is a long name preceded by --. Brackets ([ and ]) indicate that an option takes an optional parameter. .TP .B infile Loads the project file \fIinfile\fR .TP \fB\-l \fIpath\fR, \fB\-\-libpath \fIpath .br Set the parts library location. .TP \fB\-i \fR[\fIoutfile.ext\fR], \fB\-\-image \fR[\fIoutfile.ext\fR] .br Saves a picture to \fIoutfile.ext \fR in the image format specified by \fIext\fR and exits. If outfile is not given then the program will use a name based on \fIinfile\fR. The file format is selected by \fIext\fR and can be gif, bmp, png or jpg (if \fIext\fR is not present then the default preferences format will be used). .TP \fB\-w \fIwidth\fR, \fB\-\-width \fIwidth .br Sets the width of the picture to \fIwidth\fR. .TP \fB\-h \fIheight\fR, \fB\-\-height \fIheight .br Sets the height of the picture to \fIheight\fR. .TP \fB\-f \fItime\fR, \fB\-\-from \fItime .br Start saving pictures at the step \fItime\fR. Steps start at 1. .TP \fB\-t \fItime\fR, \fB\-\-to \fItime .br Save pictures until the step \fItime\fR. .TP \fB\-s \fIsubmodel\fR, \fB\-\-submodel \fIsubmodel .br Sets the active submodel to \fIsubmodel\fR. .TP \fB\-c \fIcamera\fR, \fB\-\-camera \fIcamera .br Sets the active camera to \fIcamera\fR. .TP \fB\-ss \fIid\fR,\ \fB\-\-stud\-style\ \fIid .br Set the stud style. Valid values 0=Plain, 1=Thin Lines Logo, 2=Outline Logo, 3=Sharp Top Logo, 4=Rounded Top Logo, 5=Flattened Logo, 6=High Contrast, 7=High Contrast with Logo. .TP \fB\-\-viewpoint \fRfront\ |\ back\ |\ left\ |\ right\ |\ top\ |\ bottom\ |\ home .br Sets the viewpoint to one of the predefined view angles. .TP .BI "\-\-camera\-angles " latitude " " longitude Set the camera angles in degrees around the model. .TP .BI "\-\-camera\-position " x " " y " " z " " tx " " ty " " tz " " ux " " uy " " uz Set the camera position, target and up vector using the \fILeoCAD\fR coordinate system. .TP .BI "\-\-camera\-position-ldraw " x " " y " " z " " tx " " ty " " tz " " ux " " uy " " uz Set the camera position, target and up vector using the \fILDraw\fR coordinate system. .TP .B \-\-orthographic Use an orthographic projection. .TP .BI "\-\-fov " degrees Set the vertical field of view used to render images. .TP .BI "\-\-zplanes " near " " far Set the near and far clipping planes used to render images (1 <= \fInear\fR < \fIfar\fR). .TP .B \-\-fade\-steps Render parts from prior steps faded. .TP .B \-\-no\-fade\-steps Do not render parts from prior steps faded. .TP .BI "\-\-fade\-steps\-color " color Color to use for rendering faded parts. (#AARRGGBB where AA, RR, GG, and BB are hexadecimal values for alpha, red, green, and blue respectively.) .TP .B \-\-highlight Highlight parts in the steps they appear. .TP .B \-\-no\-highlight Do not highlight parts in the steps they appear. .TP .BI "\-\-highlight\-color " color Color to use to highlight parts, (#AARRGGBB where AA, RR, GG, and BB are hexadecimal values for alpha, red, green, and blue respectively.) .TP \fB\-\-shading \fRwireframe\ |\ flat\ |\ default\ |\ full .br Select shading mode for rendering. .TP .BI "\-\-line-width " width Set the width of the edge lines. .TP .BI "\-\-aa\-samples " count AntiAliasing sample size (1, 2, 4, or 8). .TP \fB\-scc \fI#AARRGGBB\fR,\ \fB\-\-stud\-cylinder\-color\ \fI#AARRGGBB .br High contrast stud cylinder color. .TP \fB\-ec \fI#AARRGGBB\fR,\ \fB\-\-edge\-color\ \fI#AARRGGBB .br High contrast edge color. .TP \fB\-bec \fI#AARRGGBB\fR,\ \fB\-\-black\-edge\-color\ \fI#AARRGGBB .br High contrast edge color for black parts. .TP \fB\-dec \fI#AARRGGBB\fR,\ \fB\-\-dark\-edge\-color\ \fI#AARRGGBB .br High contrast edge color for dark color parts. .TP \fB\-aec,\ \fB\-\-automate\-edge\-color .br Enable automatically adjusted edge colors.\ .TP \fB\-cc \fIfloat\fR,\ \fB\-\-color\-contrast\ \ffloat .br Set the near and far clipping planes used to render images (1 <= \fInear\fR < \fIfar\fR). .TP \fB\-ldv \fIfloat\fR,\ \fB\-\-light\-dark\-value\ \ffloat .br Set the value to indicate a light or dark color. .TP \fB\-obj \fR[\fIoutfile.obj\fR] .br Exports the model to wavefront format. .TP \fB\-3ds \fR[\fIoutfile.3ds\fR] .br Exports the model to 3DS format. .TP \fB\-dae \fR[\fIoutfile.dae\fR] .br Exports the model to COLLADA DAE format. .TP \fB\-html \fR[\fIpath\fR] .br Creates an HTML page for the model. .TP .BR \-v ",\ " \-\-version Output version information and exit. .TP .BR \-? ",\ " \-\-help Display a brief usage synopsis and exit. .SH ENVIRONMENT ``LEOCAD_LIB'' may be set to the path of the parts library. .SH EXAMPLES .PP $ leocad car.lcd \-i car.png \-w 640 \-h 480 .PP This will start LeoCAD, load the file "car.lcd," create a png called "car.png" with a resolution of 640x480 and exit when done. .SH FILES .TP .I ~/.config/LeoCAD Software/LeoCAD.conf User preferences file .SH BUGS If you find any bugs please report them at https://github.com/leozide/leocad/issues .SH AUTHOR \fILeoCAD \fRis written by Leonardo Zide . You can visit the LeoCAD homepage at https://www.leocad.org/ This manual page was originally written by Patrick Mahoney , for the Debian GNU/Linux system (but may be used by others). It has since been edited by others. leocad-23.03/leocad.pro000066400000000000000000000213161440571307300147300ustar00rootroot00000000000000QT += core gui widgets opengl network xml concurrent QT *= printsupport TEMPLATE = app lessThan(QT_MAJOR_VERSION, 5) { error("LeoCAD requires Qt5.4 or later.") } equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 4) { error("LeoCAD requires Qt5.4 or later.") } greaterThan(QT_MAJOR_VERSION, 5) { QT += openglwidgets win32-msvc* { QMAKE_CXXFLAGS += /std:c++17 } } qtHaveModule(gamepad) { QT += gamepad DEFINES += LC_ENABLE_GAMEPAD } INCLUDEPATH += qt common CONFIG += precompile_header incremental c++11 force_debug_info win32 { RC_ICONS = resources/leocad.ico VERSION = 23.3.0.0 QMAKE_TARGET_COMPANY = LeoCAD Software QMAKE_TARGET_DESCRIPTION = LeoCAD QMAKE_TARGET_COPYRIGHT = "Copyright (C) LeoCAD.org" QMAKE_TARGET_PRODUCT = LeoCAD RC_CODEPAGE = 1252 RC_LANG = 0x0409 LIBS += -lwininet } win32-msvc* { QMAKE_CXXFLAGS_WARN_ON += /W4 -wd4100 QMAKE_CXXFLAGS *= /MP PRECOMPILED_HEADER = common/lc_global.h PRECOMPILED_SOURCE = common/lc_global.cpp DEFINES += _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE=1 _CRT_NONSTDC_NO_WARNINGS=1 INCLUDEPATH += $$[QT_INSTALL_HEADERS]/QtZlib QMAKE_LFLAGS += /INCREMENTAL LIBS += -ladvapi32 -lshell32 -lopengl32 -luser32 } else { PRECOMPILED_HEADER = common/lc_global.h LIBS += -lz QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter } isEmpty(QMAKE_LRELEASE) { win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\\lrelease.exe else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease unix { !exists($$QMAKE_LRELEASE) { QMAKE_LRELEASE = lrelease-qt4 } } else { !exists($$QMAKE_LRELEASE) { QMAKE_LRELEASE = lrelease } } } TRAVIS_TAG = $$(TRAVIS_TAG) TRAVIS_COMMIT = $$(TRAVIS_COMMIT) !isEmpty(TRAVIS_COMMIT) { isEmpty(TRAVIS_TAG) { DEFINES += "LC_CONTINUOUS_BUILD=$$system(git rev-parse --short HEAD)" } } APPVEYOR_REPO_TAG = $$(APPVEYOR_REPO_TAG) APPVEYOR_REPO_COMMIT = $$(APPVEYOR_REPO_COMMIT) !isEmpty(APPVEYOR_REPO_COMMIT) { isEmpty(APPVEYOR_REPO_TAG) { DEFINES += "LC_CONTINUOUS_BUILD=$$system(git rev-parse --short HEAD)" VERSION = 0.0.0.1 QMAKE_TARGET_DESCRIPTION = "LeoCAD Continuous Build $$system(git rev-parse --short HEAD)" } } TSFILES = resources/leocad_fr.ts resources/leocad_pt.ts resources/leocad_de.ts resources/leocad_uk.ts resources/leocad_cs.ts resources/leocad_es.ts lrelease.input = TSFILES lrelease.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.qm lrelease.commands = $$QMAKE_LRELEASE -silent ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.qm lrelease.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += lrelease system($$QMAKE_LRELEASE -silent $$TSFILES) unix:!macx { TARGET = leocad } else { TARGET = LeoCAD } CONFIG(debug, debug|release) { DESTDIR = build/debug } else { DESTDIR = build/release } OBJECTS_DIR = $$DESTDIR/.obj MOC_DIR = $$DESTDIR/.moc RCC_DIR = $$DESTDIR/.qrc UI_DIR = $$DESTDIR/.ui unix:!macx { isEmpty(INSTALL_PREFIX):INSTALL_PREFIX = /usr isEmpty(BIN_DIR):BIN_DIR = $$INSTALL_PREFIX/bin isEmpty(DOCS_DIR):DOCS_DIR = $$INSTALL_PREFIX/share/doc/leocad isEmpty(ICON_DIR):ICON_DIR = $$INSTALL_PREFIX/share/icons isEmpty(MAN_DIR):MAN_DIR = $$INSTALL_PREFIX/share/man/man1 isEmpty(DESKTOP_DIR):DESKTOP_DIR = $$INSTALL_PREFIX/share/applications isEmpty(MIME_DIR):MIME_DIR = $$INSTALL_PREFIX/share/mime/packages isEmpty(APPDATA_DIR):APPDATA_DIR = $$INSTALL_PREFIX/share/metainfo target.path = $$BIN_DIR docs.path = $$DOCS_DIR docs.files = docs/README.md docs/CREDITS.txt docs/COPYING.txt man.path = $$MAN_DIR man.files = docs/leocad.1 desktop.path = $$DESKTOP_DIR desktop.files = qt/leocad.desktop icons.path = $$ICON_DIR/hicolor icons.files += tools/icon/128x128 icons.files += tools/icon/16x16 icons.files += tools/icon/24x24 icons.files += tools/icon/256x256 icons.files += tools/icon/32x32 icons.files += tools/icon/48x48 icons.files += tools/icon/512x512 icons.files += tools/icon/64x64 icons.files += tools/icon/scalable mime.path = $$MIME_DIR mime.files = qt/leocad.xml appdata.path = $$APPDATA_DIR appdata.files = tools/setup/leocad.appdata.xml INSTALLS += target docs man desktop icons mime appdata !isEmpty(DISABLE_UPDATE_CHECK) { DEFINES += LC_DISABLE_UPDATE_CHECK=$$DISABLE_UPDATE_CHECK } !isEmpty(LDRAW_LIBRARY_PATH) { DEFINES += LC_LDRAW_LIBRARY_PATH=\\\"$$LDRAW_LIBRARY_PATH\\\" } } macx { ICON = resources/leocad.icns QMAKE_INFO_PLIST = qt/Info.plist document_icon.files += $$_PRO_FILE_PWD_/resources/leocad_document.icns document_icon.path = Contents/Resources library.files += $$_PRO_FILE_PWD_/library.bin library.path = Contents/Resources povray.files += $$_PRO_FILE_PWD_/povray povray.path = Contents/MacOS QMAKE_BUNDLE_DATA += document_icon library povray DEFINES += LC_DISABLE_UPDATE_CHECK=1 } SOURCES += \ common/texfont.cpp \ common/project.cpp \ common/pieceinf.cpp \ common/piece.cpp \ common/object.cpp \ common/minifig.cpp \ common/light.cpp \ common/lc_application.cpp \ common/lc_bricklink.cpp \ common/lc_category.cpp \ common/lc_collapsiblewidget.cpp \ common/lc_colors.cpp \ common/lc_commands.cpp \ common/lc_context.cpp \ common/lc_edgecolordialog.cpp \ common/lc_file.cpp \ common/lc_findreplacewidget.cpp \ common/lc_glextensions.cpp \ common/lc_http.cpp \ common/lc_instructions.cpp \ common/lc_instructionsdialog.cpp \ common/lc_library.cpp \ common/lc_lxf.cpp \ common/lc_mainwindow.cpp \ common/lc_mesh.cpp \ common/lc_meshloader.cpp \ common/lc_minifigdialog.cpp \ common/lc_model.cpp \ common/lc_pagesetupdialog.cpp \ common/lc_partselectionwidget.cpp \ common/lc_previewwidget.cpp \ common/lc_profile.cpp \ common/lc_scene.cpp \ common/lc_shortcuts.cpp \ common/lc_stringcache.cpp \ common/lc_synth.cpp \ common/lc_texture.cpp \ common/lc_timelinewidget.cpp \ common/lc_view.cpp \ common/lc_viewmanipulator.cpp \ common/lc_viewsphere.cpp \ common/lc_viewwidget.cpp \ common/lc_zipfile.cpp \ common/image.cpp \ common/group.cpp \ common/camera.cpp \ qt/system.cpp \ qt/qtmain.cpp \ qt/lc_qarraydialog.cpp \ qt/lc_qgroupdialog.cpp \ qt/lc_qaboutdialog.cpp \ qt/lc_qeditgroupsdialog.cpp \ qt/lc_qselectdialog.cpp \ qt/lc_qpropertiesdialog.cpp \ qt/lc_qhtmldialog.cpp \ qt/lc_qpreferencesdialog.cpp \ qt/lc_qcategorydialog.cpp \ qt/lc_qimagedialog.cpp \ qt/lc_qupdatedialog.cpp \ qt/lc_qutils.cpp \ qt/lc_qpropertiestree.cpp \ qt/lc_qcolorpicker.cpp \ qt/lc_qcolorlist.cpp \ qt/lc_qmodellistdialog.cpp \ qt/lc_renderdialog.cpp \ qt/lc_setsdatabasedialog.cpp \ common/lc_partpalettedialog.cpp HEADERS += \ common/texfont.h \ common/project.h \ common/pieceinf.h \ common/piece.h \ common/object.h \ common/minifig.h \ common/light.h \ common/lc_application.h \ common/lc_array.h \ common/lc_bricklink.h \ common/lc_category.h \ common/lc_collapsiblewidget.h \ common/lc_colors.h \ common/lc_commands.h \ common/lc_context.h \ common/lc_edgecolordialog.h \ common/lc_file.h \ common/lc_findreplacewidget.h \ common/lc_glextensions.h \ common/lc_global.h \ common/lc_http.h \ common/lc_instructions.h \ common/lc_instructionsdialog.h \ common/lc_library.h \ common/lc_lxf.h \ common/lc_mainwindow.h \ common/lc_math.h \ common/lc_mesh.h \ common/lc_meshloader.h \ common/lc_minifigdialog.h \ common/lc_model.h \ common/lc_pagesetupdialog.h \ common/lc_previewwidget.h \ common/lc_profile.h \ common/lc_scene.h \ common/lc_shortcuts.h \ common/lc_stringcache.h \ common/lc_synth.h \ common/lc_texture.h \ common/lc_view.h \ common/lc_viewmanipulator.h \ common/lc_viewsphere.h \ common/lc_viewwidget.h \ common/lc_zipfile.h \ common/lc_partselectionwidget.h \ common/lc_timelinewidget.h \ common/image.h \ common/group.h \ common/camera.h \ qt/lc_qarraydialog.h \ qt/lc_qgroupdialog.h \ qt/lc_qaboutdialog.h \ qt/lc_qeditgroupsdialog.h \ qt/lc_qselectdialog.h \ qt/lc_qpropertiesdialog.h \ qt/lc_qhtmldialog.h \ qt/lc_qpreferencesdialog.h \ qt/lc_qcategorydialog.h \ qt/lc_qimagedialog.h \ qt/lc_qupdatedialog.h \ qt/lc_qutils.h \ qt/lc_qpropertiestree.h \ qt/lc_qcolorpicker.h \ qt/lc_qcolorlist.h \ qt/lc_qmodellistdialog.h \ qt/lc_renderdialog.h \ qt/lc_setsdatabasedialog.h \ common/lc_partpalettedialog.h FORMS += \ qt/lc_qarraydialog.ui \ qt/lc_qgroupdialog.ui \ qt/lc_qaboutdialog.ui \ qt/lc_qeditgroupsdialog.ui \ qt/lc_qselectdialog.ui \ qt/lc_qpropertiesdialog.ui \ qt/lc_qhtmldialog.ui \ qt/lc_qpreferencesdialog.ui \ qt/lc_qcategorydialog.ui \ qt/lc_qimagedialog.ui \ qt/lc_qupdatedialog.ui \ qt/lc_qmodellistdialog.ui \ qt/lc_renderdialog.ui \ qt/lc_setsdatabasedialog.ui \ common/lc_minifigdialog.ui \ common/lc_pagesetupdialog.ui \ common/lc_partpalettedialog.ui OTHER_FILES += RESOURCES += leocad.qrc resources/stylesheet/stylesheet.qrc !win32 { TRANSLATIONS = resources/leocad_pt.ts resources/leocad_fr.ts resources/leocad_de.ts resources/leocad_uk.ts resources/leocad_cs.ts resources/leocad_es.ts } leocad-23.03/leocad.qrc000066400000000000000000000156731440571307300147260ustar00rootroot00000000000000 resources/action_delete_16.png resources/action_insert_16.png resources/action_light_16.png resources/action_move_16.png resources/action_paint_16.png resources/action_pan_16.png resources/action_rotate_16.png resources/action_select_16.png resources/action_spotlight_16.png resources/action_zoom_16.png resources/edit_copy_16.png resources/edit_cut_16.png resources/edit_paste_16.png resources/edit_redo_16.png resources/edit_undo_16.png resources/file_new_16.png resources/file_open_16.png resources/file_print_16.png resources/file_print_preview_16.png resources/file_save_16.png resources/action_camera.png resources/action_color_picker.png resources/action_color_picker_16.png resources/action_delete.png resources/action_insert.png resources/action_light.png resources/action_move.png resources/action_next.png resources/action_paint.png resources/action_pan.png resources/action_preview_locked.png resources/action_preview_unlocked.png resources/action_previous.png resources/action_roll.png resources/action_rotate.png resources/action_rotate_view.png resources/action_select.png resources/action_spotlight.png resources/action_zoom.png resources/action_zoom_extents.png resources/action_zoom_region.png resources/cursor_camera.png resources/cursor_color_picker.png resources/cursor_delete.png resources/cursor_insert.png resources/cursor_light.png resources/cursor_move.png resources/cursor_paint.png resources/cursor_pan.png resources/cursor_roll.png resources/cursor_rotate.png resources/cursor_rotatex.png resources/cursor_rotatey.png resources/cursor_rotate_view.png resources/cursor_select.png resources/cursor_select_add.png resources/cursor_select_remove.png resources/cursor_spotlight.png resources/cursor_zoom.png resources/cursor_zoom_region.png resources/edit_copy.png resources/edit_cut.png resources/edit_find.png resources/edit_find_next.png resources/edit_find_previous.png resources/edit_find_all.png resources/edit_replace_next.png resources/edit_replace_all.png resources/edit_paste.png resources/edit_redo.png resources/edit_snap_angle.png resources/edit_snap_move.png resources/edit_undo.png resources/file_new.png resources/file_open.png resources/file_print.png resources/file_print_preview.png resources/file_save.png resources/time_first.png resources/time_last.png resources/time_next.png resources/time_previous.png resources/time_stop.png tools/icon/64x64/apps/leocad.png resources/help_homepage.png resources/view_zoomextents.png resources/view_split_horizontal.png resources/view_split_vertical.png resources/file_picture.png resources/edit_transform_relative.png resources/edit_transform_absolute_rotation.png resources/edit_transform_absolute_translation.png resources/edit_transform_relative_rotation.png resources/edit_transform_relative_translation.png resources/piece_show_earlier.png resources/piece_show_later.png resources/time_add_keys.png resources/parts_search.png resources/parts_cancel.png resources/archive.png resources/library.zip resources/studlogo1.zip resources/studlogo2.zip resources/studlogo3.zip resources/studlogo4.zip resources/studlogo5.zip resources/studslegostyle1.zip resources/studslegostyle2.zip resources/ldconfig.ldr resources/minifig.ini resources/ldraw.xml resources/ldraw2bl.txt resources/leocad_fr.qm resources/leocad_pt.qm resources/leocad_de.qm resources/leocad_es.qm resources/leocad_uk.qm resources/leocad_cs.qm resources/shaders/fakelit_color_ps.glsl resources/shaders/fakelit_color_vs.glsl resources/shaders/fakelit_texture_decal_ps.glsl resources/shaders/fakelit_texture_decal_vs.glsl resources/shaders/unlit_color_conditional_ps.glsl resources/shaders/unlit_color_conditional_vs.glsl resources/shaders/unlit_color_ps.glsl resources/shaders/unlit_color_vs.glsl resources/shaders/unlit_texture_decal_ps.glsl resources/shaders/unlit_texture_decal_vs.glsl resources/shaders/unlit_texture_modulate_ps.glsl resources/shaders/unlit_texture_modulate_vs.glsl resources/shaders/unlit_vertex_color_ps.glsl resources/shaders/unlit_vertex_color_vs.glsl resources/shaders/unlit_view_sphere_ps.glsl resources/shaders/unlit_view_sphere_vs.glsl resources/gear_in.png resources/flexible.png leocad-23.03/leocad.spec000066400000000000000000000172331440571307300150650ustar00rootroot00000000000000%define qt5 1 %if 0%{?suse_version} %define dist .openSUSE%(echo %{suse_version} | sed 's/0$//') %endif %if 0%{?sles_version} %define dist .SUSE%(echo %{sles_version} | sed 's/0$//') %endif %if %(if [[ "%{vendor}" == obs://* ]] ; then echo 1 ; else echo 0 ; fi) %define opensuse_bs 1 %endif %if 0%{?centos_ver} %define centos_version %{centos_ver}00 %endif Summary: CAD program for creating virtual LEGO models Name: leocad URL: http://leocad.org %if 0%{?suse_version} || 0%{?sles_version} Group: Productivity/Graphics/Viewers %endif %if 0%{?mdkversion} || 0%{?rhel_version} Group: Graphics %endif %if 0%{?fedora} || 0%{?centos_version} Group: Amusements/Graphics %endif Version: 23.03 %if 0%{?opensuse_bs} Release: .%{?dist} %else Release: 1%{?dist} %endif %if 0%{?mdkversion} || 0%{?rhel_version} || 0%{?fedora} || 0%{?centos_version} || 0%{?scientificlinux_version} || 0%{?mageia} License: GPLv2+ %endif %if 0%{?suse_version} || 0%{?sles_version} License: GPL-2.0+ BuildRequires: fdupes %endif Packager: Peter Bartfai BuildRoot: %{_builddir}/%{name} %if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos_version} || 0%{?scientificlinux_version} %if ( 0%{?centos_version}>=600 || 0%{?rhel_version}>=600 || 0%{?scientificlinux_version}>=600 ) %if 0%{?qt5} BuildRequires: qt5-qtbase-devel >= 5.4.0, qt5-linguist %else BuildRequires: qt-devel >= 1:4.7.0 %endif %endif %endif %if 0%{?fedora} %if 0%{?qt5} BuildRequires: qt5-qtbase-devel >= 5.4.0, qt5-linguist, qt5-qtgamepad-devel %else BuildRequires: qt-devel %endif %endif %if 0%{?opensuse_bs}!=1 BuildRequires: git %endif %if (0%{?rhel_version}<700 && 0%{?centos_version}<700 && 0%{?scientificlinux_version}<600) %else BuildRequires: libjpeg-turbo-devel %endif BuildRequires: gcc-c++, libpng-devel, make %if 0%{?fedora} BuildRequires: libjpeg-turbo-devel %if 0%{?opensuse_bs} BuildRequires: samba4-libs %if 0%{?fedora_version}==22 BuildRequires: qca %endif %if 0%{?fedora_version}==23 BuildRequires: qca, gnu-free-sans-fonts %endif %endif %endif %if 0%{?suse_version} BuildRequires: update-desktop-files %if 0%{?qt5} BuildRequires: libqt5-qtbase-devel >= 5.4.0, zlib-devel, libqt5-linguist %else BuildRequires: libqt4-devel %endif Requires(pre): gconf2 %if 0%{?suse_version} > 1220 BuildRequires: glu-devel %endif %if 0%{?opensuse_bs} BuildRequires: -post-build-checks %endif %endif %if 0%{?sles_version} %if 0%{?opensuse_bs} BuildRequires: -post-build-checks %endif Requires(post): desktop-file-utils %endif %if 0%{?mageia} %if 0%{?qt5} BuildRequires: qttools5 %ifarch x86_64 BuildRequires: lib64qt5base5-devel %else BuildRequires: libqt5base5-devel %endif %if 0%{?opensuse_bs} %ifarch x86_64 BuildRequires: lib64sane1, lib64proxy-webkit %else BuildRequires: libsane1, libproxy-webkit %endif %endif %else BuildRequires: libqt4-devel %if 0%{?opensuse_bs} %ifarch x86_64 BuildRequires: lib64sane1, lib64uuid-devel, lib64proxy-webkit %else BuildRequires: libsane1, libuuid-devel, libproxy-webkit %endif %endif %endif %endif %if 0%{?mdkversion} BuildRequires: libqt4-devel # For openSUSE Build Service %if 0%{?opensuse_bs} %if (0%{?mdkversion} != 200910) && (0%{?mdkversion} != 201000) BuildRequires: kde-l10n-en_GB %endif BuildRequires: aspell-en, myspell-en_US %endif %endif %if ( 0%{?centos_version}<600 && 0%{?centos_version}>=500 ) || ( 0%{?rhel_version}<600 && 0%{?rhel_version}>=500 ) BuildRequires: qt4-devel >= 1:4.7.0 %endif %description CAD program for creating virtual LEGO models. It has an intuitive interface, designed to allow new users to start creating new models without having to spend too much time learning the application. %prep cd $RPM_SOURCE_DIR if [ -s leocad.tar.gz ] ; then if [ -d leocad ] ; then rm -rf leocad ; fi tar zxf leocad.tar.gz else if [ -f leocad-git.tar.gz ] ; then if [ -d leocad ] ; then rm -rf leocad ; fi mkdir leocad cd leocad tar zxf ../leocad-git.tar.gz --strip=1 elif [ -d leocad ] ; then cd leocad git pull cd .. else git clone https://github.com/leozide/leocad fi fi %build cd $RPM_SOURCE_DIR/leocad %ifarch i386 i486 i586 i686 %define qplatform linux-g++-32 %endif %ifarch x86_64 %define qplatform linux-g++-64 %endif %if ( 0%{?centos_version}<600 && 0%{?centos_version}>=500 ) || ( 0%{?rhel_version}<600 && 0%{?rhel_version}>=500 ) if [ -x %{_libdir}/qt4/bin/qmake ] ; then export PATH=%{_libdir}/qt4/bin:$PATH fi %endif %if (0%{?qt5}!=1) %ifarch x86_64 export RPM_OPT_FLAGS="$RPM_OPT_FLAGS -I%{_libdir}/qt4/include" %endif %endif %if 0%{?fedora}==23 %ifarch x86_64 export RPM_OPT_FLAGS="$RPM_OPT_FLAGS -fPIC" export Q_CXXFLAGS="$Q_CXXFLAGS -fPIC" %endif %endif %if 0%{?qt5} export RPM_OPT_FLAGS="$RPM_OPT_FLAGS -fPIC" if which qmake-qt5 >/dev/null 2>/dev/null ; then qmake-qt5 -spec %{qplatform} DISABLE_UPDATE_CHECK=1 LDRAW_LIBRARY_PATH=/usr/share/ldraw QMAKE_CXXFLAGS+="$Q_CXXFLAGS" else qmake -spec %{qplatform} DISABLE_UPDATE_CHECK=1 LDRAW_LIBRARY_PATH=/usr/share/ldraw QMAKE_CXXFLAGS+="$Q_CXXFLAGS" fi %else if which qmake-qt4 >/dev/null 2>/dev/null ; then qmake-qt4 -spec %{qplatform} DISABLE_UPDATE_CHECK=1 LDRAW_LIBRARY_PATH=/usr/share/ldraw QMAKE_CXXFLAGS+="$Q_CXXFLAGS" else qmake -spec %{qplatform} DISABLE_UPDATE_CHECK=1 LDRAW_LIBRARY_PATH=/usr/share/ldraw QMAKE_CXXFLAGS+="$Q_CXXFLAGS" fi %endif make clean make TESTING="$RPM_OPT_FLAGS" %if 0%{?qt5} if which lrelease-qt5 >/dev/null 2>/dev/null ; then lrelease-qt5 leocad.pro else lrelease leocad.pro fi %else if which lrelease-qt4 >/dev/null 2>/dev/null ; then lrelease-qt4 leocad.pro else lrelease leocad.pro fi %endif %if 0%{?qt5} != 1 %endif %install cd $RPM_SOURCE_DIR/leocad install -d $RPM_BUILD_ROOT%{_bindir} install -d $RPM_BUILD_ROOT%{_datadir}/leocad install -d $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/scalable/mimetypes install -d $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/scalable/apps install -d $RPM_BUILD_ROOT%{_mandir}/man1 install -m 755 build/release/leocad $RPM_BUILD_ROOT%{_bindir}/leocad install -m 644 docs/README.md $RPM_BUILD_ROOT%{_datadir}/leocad/README.md install -m 644 docs/CREDITS.txt $RPM_BUILD_ROOT%{_datadir}/leocad/CREDITS.txt install -m 644 docs/COPYING.txt $RPM_BUILD_ROOT%{_datadir}/leocad/COPYING.txt install -m 644 docs/leocad.1 $RPM_BUILD_ROOT%{_mandir}/man1/leocad.1 gzip -f $RPM_BUILD_ROOT%{_mandir}/man1/leocad.1 mkdir -p $RPM_BUILD_ROOT%{_datadir}/mime/packages/ mkdir -p $RPM_BUILD_ROOT%{_datadir}/applications/ install -m 644 qt/leocad.xml \ $RPM_BUILD_ROOT%{_datadir}/mime/packages/leocad.xml install -m 644 qt/leocad.desktop \ $RPM_BUILD_ROOT%{_datadir}/applications/leocad.desktop install -m 644 tools/icon/scalable/mimetypes/application-vnd.leocad.svg \ $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/scalable/mimetypes/application-vnd.leocad.svg install -m 644 tools/icon/scalable/apps/leocad.svg \ $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/scalable/apps/leocad.svg %if 0%{?suse_version} %suse_update_desktop_file leocad Graphics %endif %files %if 0%{?sles_version} || 0%{?suse_version} %defattr(-,root,root) %endif %{_bindir}/leocad %dir %{_datadir}/leocad %doc %{_datadir}/leocad/README.md %doc %{_datadir}/leocad/CREDITS.txt %doc %{_datadir}/leocad/COPYING.txt %{_datadir}/mime/packages/leocad.xml %{_datadir}/applications/leocad.desktop %{_datadir}/icons/hicolor/scalable/mimetypes/application-vnd.leocad.svg %{_datadir}/icons/hicolor/scalable/apps/leocad.svg %if 0%{?mdkversion} || 0%{?mageia} %{_mandir}/man1/leocad.1.xz %else %{_mandir}/man1/leocad.1.gz %endif %clean rm -rf $RPM_BUILD_ROOT %changelog * Sun Jan 30 2022 - sT331h0rs3 (at) gmail.com 0.92 - Actualize LeoCAD version * Sat May 08 2021 - sT331h0rs3 (at) gmail.com 0.91 - Build with Qt5 by default - Actualize LeoCAD version - Fix paths to SVG files * Tue Sep 16 2016 - pbartfai (at) stardust.hu 0.90 - Initial version leocad-23.03/qt/000077500000000000000000000000001440571307300134005ustar00rootroot00000000000000leocad-23.03/qt/Info.plist000066400000000000000000000037231440571307300153550ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleDocumentTypes CFBundleTypeExtensions lcd leocad CFBundleTypeIconFile leocad_document.icns CFBundleTypeMIMETypes application/vnd.leocad CFBundleTypeName LeoCAD Project CFBundleTypeRole Editor LSTypeIsPackage LSHandlerRank Owner CFBundleTypeExtensions ldr dat mpd CFBundleTypeIconFile leocad_document.icns CFBundleTypeMIMETypes application/x-ldraw application/x-multi-part-ldraw application/x-ldlite CFBundleTypeName LDraw Document CFBundleTypeRole Editor LSTypeIsPackage CFBundleExecutable leocad CFBundleIconFile leocad.icns CFBundleIdentifier com.leozide.leocad CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType APPL CFBundleSignature LCAD CFBundleVersion 23.03.0 CFBundleDisplayName LeoCAD CFBundleName LeoCAD NSPrincipalClass NSApplication leocad-23.03/qt/lc_qaboutdialog.cpp000066400000000000000000000045771440571307300172520ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qaboutdialog.h" #include "ui_lc_qaboutdialog.h" #include "lc_mainwindow.h" #include "lc_view.h" #include "lc_glextensions.h" #include "lc_viewwidget.h" lcQAboutDialog::lcQAboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::lcQAboutDialog) { ui->setupUi(this); #ifdef LC_CONTINUOUS_BUILD ui->version->setText(tr("LeoCAD Continuous Build %1").arg(QString::fromLatin1(QT_STRINGIFY(LC_CONTINUOUS_BUILD)))); #else ui->version->setText(tr("LeoCAD Version %1").arg(QString::fromLatin1(LC_VERSION_TEXT))); #endif lcViewWidget* Widget = gMainWindow->GetActiveView()->GetWidget(); QSurfaceFormat Format = Widget->context()->format(); int ColorDepth = Format.redBufferSize() + Format.greenBufferSize() + Format.blueBufferSize() + Format.alphaBufferSize(); const QString QtVersionFormat = tr("Qt Version %1 (compiled with %2)\n\n"); const QString QtVersion = QtVersionFormat.arg(qVersion(), QT_VERSION_STR); const QString VersionFormat = tr("OpenGL Version %1 (GLSL %2)\n%3 - %4\n\n"); const QString Version = VersionFormat.arg(QString((const char*)glGetString(GL_VERSION)), QString((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION)), QString((const char*)glGetString(GL_RENDERER)), QString((const char*)glGetString(GL_VENDOR))); const QString BuffersFormat = tr("Color Buffer: %1 bits\nDepth Buffer: %2 bits\nStencil Buffer: %3 bits\n\n"); const QString Buffers = BuffersFormat.arg(QString::number(ColorDepth), QString::number(Format.depthBufferSize()), QString::number(Format.stencilBufferSize())); const QString ExtensionsFormat = tr("Buffers: %1\nShaders: %2\nFramebuffers: %3\nBlendFuncSeparate: %4\nAnisotropic: %5\n"); const QString VertexBuffers = gSupportsVertexBufferObject ? tr("Supported") : tr("Not supported"); const QString Shaders = gSupportsShaderObjects ? tr("Supported") : tr("Not supported"); const QString Framebuffers = gSupportsFramebufferObject ? tr("Supported") : tr("Not supported"); const QString BlendFuncSeparate = gSupportsBlendFuncSeparate ? tr("Supported") : tr("Not supported"); const QString Anisotropic = gSupportsAnisotropic ? tr("Supported (max %1)").arg(gMaxAnisotropy) : tr("Not supported"); const QString Extensions = ExtensionsFormat.arg(VertexBuffers, Shaders, Framebuffers, BlendFuncSeparate, Anisotropic); ui->info->setText(QtVersion + Version + Buffers + Extensions); } lcQAboutDialog::~lcQAboutDialog() { delete ui; } leocad-23.03/qt/lc_qaboutdialog.h000066400000000000000000000003531440571307300167030ustar00rootroot00000000000000#pragma once #include namespace Ui { class lcQAboutDialog; } class lcQAboutDialog : public QDialog { Q_OBJECT public: explicit lcQAboutDialog(QWidget *parent); ~lcQAboutDialog(); private: Ui::lcQAboutDialog *ui; }; leocad-23.03/qt/lc_qaboutdialog.ui000066400000000000000000000074201440571307300170730ustar00rootroot00000000000000 lcQAboutDialog 0 0 400 215 About LeoCAD :/resources/leocad.png Qt::AlignCenter 16 LeoCAD Version 0.00.0 LeoCAD is a free application for creating virtual LEGO models. true <a href="https://www.leocad.org">https://www.leocad.org</a> true System Information false Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Qt::Horizontal QDialogButtonBox::Ok buttonBox accepted() lcQAboutDialog accept() 248 254 157 274 buttonBox rejected() lcQAboutDialog reject() 316 260 286 274 leocad-23.03/qt/lc_qarraydialog.cpp000066400000000000000000000106171440571307300172460ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qarraydialog.h" #include "ui_lc_qarraydialog.h" #include "lc_qutils.h" lcQArrayDialog::lcQArrayDialog(QWidget* Parent) : QDialog(Parent), ui(new Ui::lcQArrayDialog) { ui->setupUi(this); ui->offset1x->setValidator(new QDoubleValidator(ui->offset1x)); ui->offset1y->setValidator(new QDoubleValidator(ui->offset1y)); ui->offset1z->setValidator(new QDoubleValidator(ui->offset1z)); ui->offset2x->setValidator(new QDoubleValidator(ui->offset2x)); ui->offset2y->setValidator(new QDoubleValidator(ui->offset2y)); ui->offset2z->setValidator(new QDoubleValidator(ui->offset2z)); ui->offset3x->setValidator(new QDoubleValidator(ui->offset3x)); ui->offset3y->setValidator(new QDoubleValidator(ui->offset3y)); ui->offset3z->setValidator(new QDoubleValidator(ui->offset3z)); ui->rotation1x->setValidator(new QDoubleValidator(ui->rotation1x)); ui->rotation1y->setValidator(new QDoubleValidator(ui->rotation1y)); ui->rotation1z->setValidator(new QDoubleValidator(ui->rotation1z)); ui->rotation2x->setValidator(new QDoubleValidator(ui->rotation2x)); ui->rotation2y->setValidator(new QDoubleValidator(ui->rotation2y)); ui->rotation2z->setValidator(new QDoubleValidator(ui->rotation2z)); ui->rotation3x->setValidator(new QDoubleValidator(ui->rotation3x)); ui->rotation3y->setValidator(new QDoubleValidator(ui->rotation3y)); ui->rotation3z->setValidator(new QDoubleValidator(ui->rotation3z)); mCounts[0] = 10; mCounts[1] = 1; mCounts[2] = 1; mOffsets[0] = mOffsets[1] = mOffsets[2] = lcVector3(0.0f, 0.0f, 0.0f); mRotations[0] = mRotations[1] = mRotations[2] = lcVector3(0.0f, 0.0f, 0.0f); ui->count1->setValue(mCounts[0]); ui->count2->setValue(mCounts[1]); ui->count3->setValue(mCounts[2]); ui->offset1x->setText(lcFormatValueLocalized(mOffsets[0].x)); ui->offset1y->setText(lcFormatValueLocalized(mOffsets[0].y)); ui->offset1z->setText(lcFormatValueLocalized(mOffsets[0].z)); ui->offset2x->setText(lcFormatValueLocalized(mOffsets[1].x)); ui->offset2y->setText(lcFormatValueLocalized(mOffsets[1].y)); ui->offset2z->setText(lcFormatValueLocalized(mOffsets[1].z)); ui->offset3x->setText(lcFormatValueLocalized(mOffsets[2].x)); ui->offset3y->setText(lcFormatValueLocalized(mOffsets[2].y)); ui->offset3z->setText(lcFormatValueLocalized(mOffsets[2].z)); ui->rotation1x->setText(lcFormatValueLocalized(mRotations[0].x)); ui->rotation1y->setText(lcFormatValueLocalized(mRotations[0].y)); ui->rotation1z->setText(lcFormatValueLocalized(mRotations[0].z)); ui->rotation2x->setText(lcFormatValueLocalized(mRotations[1].x)); ui->rotation2y->setText(lcFormatValueLocalized(mRotations[1].y)); ui->rotation2z->setText(lcFormatValueLocalized(mRotations[1].z)); ui->rotation3x->setText(lcFormatValueLocalized(mRotations[2].x)); ui->rotation3y->setText(lcFormatValueLocalized(mRotations[2].y)); ui->rotation3z->setText(lcFormatValueLocalized(mRotations[2].z)); } lcQArrayDialog::~lcQArrayDialog() { delete ui; } void lcQArrayDialog::accept() { int Counts[3]; Counts[0] = ui->count1->value(); Counts[1] = ui->count2->value(); Counts[2] = ui->count3->value(); if (Counts[0] * Counts[1] * Counts[2] < 2) { QMessageBox::information(this, "LeoCAD", tr("Array is empty.")); return; } mCounts[0] = Counts[0]; mCounts[1] = Counts[1]; mCounts[2] = Counts[2]; mOffsets[0].x = lcParseValueLocalized(ui->offset1x->text()); mOffsets[0].y = lcParseValueLocalized(ui->offset1y->text()); mOffsets[0].z = lcParseValueLocalized(ui->offset1z->text()); mOffsets[1].x = lcParseValueLocalized(ui->offset2x->text()); mOffsets[1].y = lcParseValueLocalized(ui->offset2y->text()); mOffsets[1].z = lcParseValueLocalized(ui->offset2z->text()); mOffsets[2].x = lcParseValueLocalized(ui->offset3x->text()); mOffsets[2].y = lcParseValueLocalized(ui->offset3y->text()); mOffsets[2].z = lcParseValueLocalized(ui->offset3z->text()); mRotations[0].x = lcParseValueLocalized(ui->rotation1x->text()); mRotations[0].y = lcParseValueLocalized(ui->rotation1y->text()); mRotations[0].z = lcParseValueLocalized(ui->rotation1z->text()); mRotations[1].x = lcParseValueLocalized(ui->rotation2x->text()); mRotations[1].y = lcParseValueLocalized(ui->rotation2y->text()); mRotations[1].z = lcParseValueLocalized(ui->rotation2z->text()); mRotations[2].x = lcParseValueLocalized(ui->rotation3x->text()); mRotations[2].y = lcParseValueLocalized(ui->rotation3y->text()); mRotations[2].z = lcParseValueLocalized(ui->rotation3z->text()); QDialog::accept(); } leocad-23.03/qt/lc_qarraydialog.h000066400000000000000000000005431440571307300167100ustar00rootroot00000000000000#pragma once #include #include "lc_math.h" namespace Ui { class lcQArrayDialog; } class lcQArrayDialog : public QDialog { Q_OBJECT public: lcQArrayDialog(QWidget* Parent); ~lcQArrayDialog(); int mCounts[3]; lcVector3 mOffsets[3]; lcVector3 mRotations[3]; public slots: void accept() override; private: Ui::lcQArrayDialog *ui; }; leocad-23.03/qt/lc_qarraydialog.ui000066400000000000000000000134441440571307300171020ustar00rootroot00000000000000 lcQArrayDialog 0 0 492 156 Array Dimensions 1 1000 1 1000 1 1000 Offsets Rotations Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok count1 offset1x offset1y offset1z rotation1x rotation1y rotation1z count2 offset2x offset2y offset2z rotation2x rotation2y rotation2z count3 offset3x offset3y offset3z rotation3x rotation3y rotation3z buttonBox buttonBox accepted() lcQArrayDialog accept() 227 141 157 158 buttonBox rejected() lcQArrayDialog reject() 295 147 286 158 leocad-23.03/qt/lc_qcategorydialog.cpp000066400000000000000000000017301440571307300177410ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qcategorydialog.h" #include "ui_lc_qcategorydialog.h" #include "lc_category.h" lcQCategoryDialog::lcQCategoryDialog(QWidget *parent, void *data) : QDialog(parent), ui(new Ui::lcQCategoryDialog) { ui->setupUi(this); options = (lcLibraryCategory*)data; if (!options->Name.isEmpty()) setWindowTitle(tr("Edit Category")); else setWindowTitle(tr("New Category")); ui->name->setText(options->Name); ui->keywords->setText(options->Keywords); } lcQCategoryDialog::~lcQCategoryDialog() { delete ui; } void lcQCategoryDialog::accept() { QString name = ui->name->text(); if (name.isEmpty()) { QMessageBox::information(this, "LeoCAD", tr("Name cannot be empty.")); return; } QString keywords = ui->keywords->text(); if (keywords.isEmpty()) { QMessageBox::information(this, "LeoCAD", tr("Keywords cannot be empty.")); return; } options->Name = name; options->Keywords = keywords.toLatin1(); QDialog::accept(); } leocad-23.03/qt/lc_qcategorydialog.h000066400000000000000000000005471440571307300174130ustar00rootroot00000000000000#pragma once #include struct lcLibraryCategory; namespace Ui { class lcQCategoryDialog; } class lcQCategoryDialog : public QDialog { Q_OBJECT public: explicit lcQCategoryDialog(QWidget *parent, void *data); ~lcQCategoryDialog(); lcLibraryCategory *options; public slots: void accept() override; private: Ui::lcQCategoryDialog *ui; }; leocad-23.03/qt/lc_qcategorydialog.ui000066400000000000000000000043171440571307300176000ustar00rootroot00000000000000 lcQCategoryDialog 0 0 400 95 Category Name: name Keywords: keywords Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() lcQCategoryDialog accept() 222 88 157 102 buttonBox rejected() lcQCategoryDialog reject() 290 94 286 102 leocad-23.03/qt/lc_qcolorlist.cpp000066400000000000000000000260331440571307300167610ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qcolorlist.h" #include "lc_application.h" #include "lc_library.h" #include "lc_colors.h" void lcDrawNoColorRect(QPainter& Painter, const QRect& Rect) { Painter.setBrush(Qt::black); Painter.drawRect(Rect); const int SquareSize = 3; int Column = 0; for (;;) { int x = Rect.left() + 1 + Column * SquareSize; if (x >= Rect.right()) break; int Row = Column & 1; for (;;) { int y = Rect.top() + 1 + Row * SquareSize; if (y >= Rect.bottom()) break; QRect GridRect(x, y, SquareSize, SquareSize); if (GridRect.right() > Rect.right()) GridRect.setRight(Rect.right()); if (GridRect.bottom() > Rect.bottom()) GridRect.setBottom(Rect.bottom()); Painter.fillRect(GridRect, Qt::white); Row += 2; } Column++; } } lcQColorList::lcQColorList(QWidget* Parent, bool AllowNoColor) : QWidget(Parent), mAllowNoColor(AllowNoColor) { setFocusPolicy(Qt::StrongFocus); UpdateCells(); connect(lcGetPiecesLibrary(), &lcPiecesLibrary::ColorsLoaded, this, &lcQColorList::ColorsLoaded); } void lcQColorList::UpdateCells() { mCells.clear(); mGroups.clear(); for (int GroupIdx = 0; GroupIdx < LC_NUM_COLORGROUPS; GroupIdx++) { lcColorGroup* Group = &gColorGroups[GroupIdx]; lcColorListGroup ListGroup; for (int ColorIndex : Group->Colors) { mCells.emplace_back(lcColorListCell{ QRect(), ColorIndex }); ListGroup.Name = Group->Name; ListGroup.Cells.emplace_back(mCells.size()); } mGroups.emplace_back(std::move(ListGroup)); } if (mAllowNoColor) { mCells.emplace_back(lcColorListCell{ QRect(), lcGetColorIndex(LC_COLOR_NOCOLOR) }); mGroups[LC_COLORGROUP_SPECIAL].Cells.emplace_back(mCells.size()); } mColumns = 14; mRows = 0; for (const lcColorListGroup& Group : mGroups) mRows += ((int)Group.Cells.size() + mColumns - 1) / mColumns; QFontMetrics Metrics(font()); int TextHeight = 0; for (lcColorListGroup& Group : mGroups) { Group.Rect = Metrics.boundingRect(rect(), Qt::TextSingleLine | Qt::AlignCenter, Group.Name); TextHeight += Group.Rect.height(); } mPreferredHeight = TextHeight + 10 * mRows; setMinimumHeight(TextHeight + 5 * mRows); } void lcQColorList::UpdateRects() { QFontMetrics Metrics(font()); int TextHeight = 0; for (lcColorListGroup& Group : mGroups) { Group.Rect = Metrics.boundingRect(rect(), Qt::TextSingleLine | Qt::AlignCenter, Group.Name); TextHeight += Group.Rect.height(); } mPreferredHeight = TextHeight + 10 * mRows; float CellWidth = (float)(width() + 1) / (float)mColumns; float CellHeight = (float)(height() - TextHeight) / (float)mRows; while (CellWidth / CellHeight > 1.5f) { mColumns++; mRows = 0; for (const lcColorListGroup& Group : mGroups) mRows += ((int)Group.Cells.size() + mColumns - 1) / mColumns; CellWidth = (float)(width() + 1) / (float)mColumns; CellHeight = (float)(height() - TextHeight) / (float)mRows; if (mRows <= LC_NUM_COLORGROUPS) break; } while (CellHeight / CellWidth > 1.5f) { mColumns--; mRows = 0; for (const lcColorListGroup& Group : mGroups) mRows += ((int)Group.Cells.size() + mColumns - 1) / mColumns; CellWidth = (float)(width() + 1) / (float)mColumns; CellHeight = (float)(height() - TextHeight) / (float)mRows; if (mColumns <= 5) break; } int CurCell = 0; float GroupY = 0.0f; int TotalRows = 1; for (lcColorListGroup& Group : mGroups) { int CurColumn = 0; int NumRows = 0; Group.Rect = QRect(0, (int)GroupY, width(), Group.Rect.height()); GroupY += Group.Rect.height(); for (size_t ColorIdx = 0; ColorIdx < Group.Cells.size(); ColorIdx++) { const int Left = CellWidth * CurColumn - 1; const int Right = (CurColumn + 1) * CellWidth - 1; const int Top = GroupY + CellHeight * NumRows; const int Bottom = (TotalRows != mRows) ? GroupY + CellHeight * (NumRows + 1) : height() - 1; mCells[CurCell].Rect = QRect(Left, Top, Right - Left, Bottom - Top); CurColumn++; if (CurColumn == mColumns) { CurColumn = 0; NumRows++; TotalRows++; } CurCell++; } if (CurColumn != 0) { NumRows++; TotalRows++; } GroupY += NumRows * CellHeight; } } void lcQColorList::ColorsLoaded() { UpdateCells(); UpdateRects(); setCurrentColor(lcGetColorIndex(mColorCode)); update(); } QSize lcQColorList::sizeHint() const { return QSize(200, mPreferredHeight); } void lcQColorList::setCurrentColor(int ColorIndex) { for (size_t CellIndex = 0; CellIndex < mCells.size(); CellIndex++) { if (mCells[CellIndex].ColorIndex == ColorIndex) { SelectCell(CellIndex); break; } } } bool lcQColorList::event(QEvent *event) { if (event->type() == QEvent::ToolTip) { QHelpEvent *helpEvent = static_cast(event); for (size_t CellIndex = 0; CellIndex < mCells.size(); CellIndex++) { if (!mCells[CellIndex].Rect.contains(helpEvent->pos())) continue; lcColor* color = &gColorList[mCells[CellIndex].ColorIndex]; QColor rgb(color->Value[0] * 255, color->Value[1] * 255, color->Value[2] * 255); QImage image(16, 16, QImage::Format_RGB888); image.fill(rgb); QPainter painter(&image); painter.setPen(Qt::darkGray); if (color->Code != LC_COLOR_NOCOLOR) painter.drawRect(0, 0, image.width() - 1, image.height() - 1); else lcDrawNoColorRect(painter, QRect(0, 0, image.width() - 1, image.height() - 1)); painter.end(); QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); image.save(&buffer, "PNG"); buffer.close(); int colorIndex = mCells[CellIndex].ColorIndex; QString text; if (color->Code != LC_COLOR_NOCOLOR) { const char* format = "
%2 (%3)
"; text = QString(format).arg(QString(buffer.data().toBase64()), gColorList[colorIndex].Name, QString::number(gColorList[colorIndex].Code)); } else { const char* format = "
%2
"; text = QString(format).arg(QString(buffer.data().toBase64()), gColorList[colorIndex].Name); } QToolTip::showText(helpEvent->globalPos(), text); return true; } QToolTip::hideText(); event->ignore(); return true; } else if (event->type() == QEvent::ShortcutOverride) { QKeyEvent* keyEvent = static_cast(event); if (keyEvent->modifiers() == Qt::NoModifier || keyEvent->modifiers() == Qt::KeypadModifier) { switch (keyEvent->key()) { case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_Up: case Qt::Key_Down: keyEvent->accept(); default: break; } } } return QWidget::event(event); } void lcQColorList::mousePressEvent(QMouseEvent* MouseEvent) { for (size_t CellIndex = 0; CellIndex < mCells.size(); CellIndex++) { if (!mCells[CellIndex].Rect.contains(MouseEvent->pos())) continue; SelectCell(CellIndex); emit colorSelected(mCells[CellIndex].ColorIndex); break; } mDragStartPosition = MouseEvent->pos(); } void lcQColorList::mouseMoveEvent(QMouseEvent* MouseEvent) { if (!(MouseEvent->buttons() & Qt::LeftButton)) return; if ((MouseEvent->pos() - mDragStartPosition).manhattanLength() < QApplication::startDragDistance()) return; QMimeData* MimeData = new QMimeData; MimeData->setData("application/vnd.leocad-color", QString::number(mCells[mCurrentCell].ColorIndex).toLatin1()); QDrag* Drag = new QDrag(this); Drag->setMimeData(MimeData); Drag->exec(Qt::CopyAction); } void lcQColorList::keyPressEvent(QKeyEvent *event) { size_t NewCell = mCurrentCell; if (event->key() == Qt::Key_Left) { if (mCurrentCell > 0) NewCell = mCurrentCell - 1; } else if (event->key() == Qt::Key_Right) { if (mCurrentCell < mCells.size() - 1) NewCell = mCurrentCell + 1; } else if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) { if (mCurrentCell >= mCells.size()) mCurrentCell = 0; size_t CurGroup = 0; size_t NumCells = 0; for (CurGroup = 0; CurGroup < mGroups.size(); CurGroup++) { int NumColors = (int)mGroups[CurGroup].Cells.size(); if (mCurrentCell < NumCells + NumColors) break; NumCells += NumColors; } size_t Row = (mCurrentCell - NumCells) / mColumns; size_t Column = (mCurrentCell - NumCells) % mColumns; if (event->key() == Qt::Key_Up) { if (Row > 0) NewCell = mCurrentCell - mColumns; else if (CurGroup > 0) { size_t NumColors = mGroups[CurGroup - 1].Cells.size(); size_t NumColumns = NumColors % mColumns; if (NumColumns < Column + 1) NewCell = mCurrentCell - NumColumns - mColumns; else NewCell = mCurrentCell - NumColumns; } } else if (event->key() == Qt::Key_Down) { int NumColors = (int)mGroups[CurGroup].Cells.size(); if (mCurrentCell + mColumns < NumCells + NumColors) NewCell = mCurrentCell + mColumns; else { size_t NumColumns = NumColors % mColumns; if (NumColumns > Column) { if (mCurrentCell + NumColumns < mCells.size()) NewCell = mCurrentCell + NumColumns; } else NewCell = mCurrentCell + mColumns + NumColumns; } } } else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { emit colorSelected(mCells[mCurrentCell].ColorIndex); } if (NewCell != mCurrentCell) SelectCell(NewCell); else QWidget::keyPressEvent(event); } void lcQColorList::resizeEvent(QResizeEvent* Event) { if (mWidth == width() && mHeight == height()) return; UpdateRects(); mWidth = width(); mHeight = height(); QWidget::resizeEvent(Event); } void lcQColorList::paintEvent(QPaintEvent* Event) { Q_UNUSED(Event); QPainter Painter(this); Painter.fillRect(rect(), palette().brush(QPalette::Window)); Painter.setFont(font()); Painter.setPen(palette().color(QPalette::Text)); for (const lcColorListGroup& Group : mGroups) Painter.drawText(Group.Rect, Qt::TextSingleLine | Qt::AlignLeft, Group.Name); Painter.setPen(palette().color(QPalette::Shadow)); for (size_t CellIndex = 0; CellIndex < mCells.size(); CellIndex++) { const lcColor* Color = &gColorList[mCells[CellIndex].ColorIndex]; const QRect& Rect = mCells[CellIndex].Rect; if (Color->Code != LC_COLOR_NOCOLOR) { QColor CellColor(Color->Value[0] * 255, Color->Value[1] * 255, Color->Value[2] * 255); Painter.setBrush(CellColor); Painter.drawRect(Rect); } else lcDrawNoColorRect(Painter, Rect); } if (mCurrentCell < mCells.size()) { const lcColor* Color = &gColorList[mCells[mCurrentCell].ColorIndex]; QColor EdgeColor(255 - Color->Value[0] * 255, 255 - Color->Value[1] * 255, 255 - Color->Value[2] * 255); Painter.setPen(EdgeColor); Painter.setBrush(Qt::NoBrush); QRect CellRect = mCells[mCurrentCell].Rect; CellRect.adjust(1, 1, -1, -1); Painter.drawRect(CellRect); /* if (GetFocus() == this) { rc.DeflateRect(2, 2); dc.DrawFocusRect(rc); } */ } } void lcQColorList::SelectCell(size_t CellIndex) { if (CellIndex >= mCells.size()) return; if (CellIndex == mCurrentCell) return; mCurrentCell = CellIndex; mColorCode = lcGetColorCode(mCells[CellIndex].ColorIndex); emit colorChanged(mCells[mCurrentCell].ColorIndex); update(); } leocad-23.03/qt/lc_qcolorlist.h000066400000000000000000000023501440571307300164220ustar00rootroot00000000000000#pragma once struct lcColorListCell { QRect Rect; int ColorIndex; }; struct lcColorListGroup { QRect Rect; QString Name; std::vector Cells; }; void lcDrawNoColorRect(QPainter& Painter, const QRect& Rect); class lcQColorList : public QWidget { Q_OBJECT public: lcQColorList(QWidget* Parent = nullptr, bool AllowNoColor = false); ~lcQColorList() = default; QSize sizeHint() const override; void setCurrentColor(int colorIndex); signals: void colorChanged(int colorIndex); void colorSelected(int colorIndex); protected slots: void ColorsLoaded(); protected: void UpdateCells(); void UpdateRects(); void SelectCell(size_t CellIndex); bool event(QEvent* Event) override; void paintEvent(QPaintEvent* PaintEvent) override; void resizeEvent(QResizeEvent* ResizeEvent) override; void mousePressEvent(QMouseEvent* MouseEvent) override; void mouseMoveEvent(QMouseEvent* MouseEvent) override; void keyPressEvent(QKeyEvent* KeyEvent) override; std::vector mCells; std::vector mGroups; size_t mCurrentCell = 0; quint32 mColorCode = 0; int mColumns = 0; int mRows = 0; int mWidth = 0; int mHeight = 0; int mPreferredHeight = 0; bool mAllowNoColor; QPoint mDragStartPosition; }; leocad-23.03/qt/lc_qcolorpicker.cpp000066400000000000000000000105101440571307300172540ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qcolorpicker.h" #include "lc_qcolorlist.h" #include "lc_colors.h" lcQColorPickerPopup::lcQColorPickerPopup(QWidget* Parent, int ColorIndex, bool AllowNoColor) : QFrame(Parent, Qt::Popup) { setFrameStyle(QFrame::StyledPanel); setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); setFocusPolicy(Qt::StrongFocus); setMouseTracking(true); QGridLayout *layout = new QGridLayout(this); layout->setContentsMargins(0, 0, 0, 0); setLayout(layout); colorList = new lcQColorList(this, AllowNoColor); connect(colorList, SIGNAL(colorChanged(int)), this, SLOT(colorChanged(int))); connect(colorList, SIGNAL(colorSelected(int)), this, SLOT(colorSelected(int))); layout->addWidget(colorList); colorList->blockSignals(true); colorList->setCurrentColor(ColorIndex); colorList->blockSignals(false); eventLoop = nullptr; } lcQColorPickerPopup::~lcQColorPickerPopup() { if (eventLoop) eventLoop->exit(); } void lcQColorPickerPopup::exec() { show(); QEventLoop e; eventLoop = &e; (void) e.exec(); eventLoop = nullptr; } void lcQColorPickerPopup::mouseReleaseEvent(QMouseEvent *e) { if (!rect().contains(e->pos())) hide(); } void lcQColorPickerPopup::hideEvent(QHideEvent *e) { if (eventLoop) eventLoop->exit(); emit hid(); QFrame::hideEvent(e); } void lcQColorPickerPopup::colorChanged(int colorIndex) { emit changed(colorIndex); } void lcQColorPickerPopup::colorSelected(int colorIndex) { emit selected(colorIndex); hide(); } void lcQColorPickerPopup::showEvent(QShowEvent *) { colorList->setFocus(); } lcQColorPicker::lcQColorPicker(QWidget* Parent, bool AllowNoColor) : QPushButton(Parent), mAllowNoColor(AllowNoColor) { setFocusPolicy(Qt::StrongFocus); setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); setAutoDefault(false); setCheckable(true); UpdateIcon(); connect(this, SIGNAL(toggled(bool)), SLOT(buttonPressed(bool))); } lcQColorPicker::~lcQColorPicker() { } void lcQColorPicker::setCurrentColor(int colorIndex) { selected(colorIndex); } void lcQColorPicker::setCurrentColorCode(int colorCode) { setCurrentColor(lcGetColorIndex(colorCode)); } int lcQColorPicker::currentColor() const { return mCurrentColorIndex; } int lcQColorPicker::currentColorCode() const { return gColorList[mCurrentColorIndex].Code; } void lcQColorPicker::buttonPressed(bool toggled) { if (!toggled) return; lcQColorPickerPopup *popup = new lcQColorPickerPopup(this, mCurrentColorIndex, mAllowNoColor); connect(popup, SIGNAL(changed(int)), SLOT(changed(int))); connect(popup, SIGNAL(selected(int)), SLOT(selected(int))); connect(popup, SIGNAL(hid()), SLOT(popupClosed())); popup->setMinimumSize(300, 200); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QScreen* Screen = screen(); const QRect desktop = Screen ? Screen->geometry() : QRect(); #else const QRect desktop = QApplication::desktop()->geometry(); #endif QPoint pos = mapToGlobal(rect().bottomLeft()); if (pos.x() < desktop.left()) pos.setX(desktop.left()); if (pos.y() < desktop.top()) pos.setY(desktop.top()); if ((pos.x() + popup->width()) > desktop.width()) pos.setX(desktop.width() - popup->width()); if ((pos.y() + popup->height()) > desktop.bottom()) pos.setY(desktop.bottom() - popup->height()); popup->move(pos); clearFocus(); update(); popup->setFocus(); popup->show(); } void lcQColorPicker::UpdateIcon() { const int IconSize = 14;//style()->pixelMetric(QStyle::PM_SmallIconSize); QPixmap Pixmap(IconSize, IconSize); QPainter Painter(&Pixmap); Painter.setPen(Qt::darkGray); const lcColor* Color = &gColorList[mCurrentColorIndex]; if (Color->Code != LC_COLOR_NOCOLOR) { Painter.setBrush(QColor::fromRgbF(Color->Value[0], Color->Value[1], Color->Value[2])); Painter.drawRect(0, 0, Pixmap.width() - 1, Pixmap.height() - 1); } else lcDrawNoColorRect(Painter, QRect(0, 0, Pixmap.width() - 1, Pixmap.height() - 1)); Painter.end(); setIcon(QIcon(Pixmap)); } void lcQColorPicker::popupClosed() { if (mInitialColorIndex != mCurrentColorIndex) changed(mInitialColorIndex); setChecked(false); setFocus(); } void lcQColorPicker::changed(int colorIndex) { if (colorIndex == mCurrentColorIndex) return; mCurrentColorIndex = colorIndex; UpdateIcon(); repaint(); emit colorChanged(mCurrentColorIndex); } void lcQColorPicker::selected(int colorIndex) { mInitialColorIndex = colorIndex; changed(colorIndex); } leocad-23.03/qt/lc_qcolorpicker.h000066400000000000000000000023711440571307300167270ustar00rootroot00000000000000#pragma once #include class lcQColorList; class lcQColorPickerPopup : public QFrame { Q_OBJECT public: lcQColorPickerPopup(QWidget* Parent = nullptr, int ColorIndex = 0, bool AllowNoColor = false); ~lcQColorPickerPopup(); void exec(); signals: void changed(int colorIndex); void selected(int colorIndex); void hid(); public slots: void colorChanged(int colorIndex); void colorSelected(int colorIndex); protected: void showEvent(QShowEvent* ShowEvent) override; void hideEvent(QHideEvent* HideEvent) override; void mouseReleaseEvent(QMouseEvent* MouseEvent) override; private: QEventLoop* eventLoop; lcQColorList* colorList; }; class lcQColorPicker : public QPushButton { Q_OBJECT public: lcQColorPicker(QWidget* Parent = nullptr, bool AllowNoColor = false); ~lcQColorPicker(); int currentColor() const; int currentColorCode() const; void setCurrentColor(int colorIndex); void setCurrentColorCode(int colorCode); public slots: void changed(int colorIndex); void selected(int colorIndex); signals: void colorChanged(int colorIndex); private slots: void buttonPressed(bool toggled); void popupClosed(); protected: void UpdateIcon(); int mCurrentColorIndex = 0; int mInitialColorIndex = 0; bool mAllowNoColor = false; }; leocad-23.03/qt/lc_qeditgroupsdialog.cpp000066400000000000000000000114351440571307300203140ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qeditgroupsdialog.h" #include "ui_lc_qeditgroupsdialog.h" #include "lc_application.h" #include "lc_model.h" #include "piece.h" #include "group.h" lcQEditGroupsDialog::lcQEditGroupsDialog(QWidget* Parent, const QMap& PieceParents, const QMap& GroupParents, lcModel* Model) : QDialog(Parent), mPieceParents(PieceParents), mGroupParents(GroupParents) { mLastItemClicked = nullptr; mModel = Model; ui = new Ui::lcQEditGroupsDialog; ui->setupUi(this); connect(ui->treeWidget,SIGNAL(itemClicked(QTreeWidgetItem *,int)), this, SLOT(onItemClicked(QTreeWidgetItem *,int))); connect(ui->treeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem *,int)), this, SLOT(onItemDoubleClicked(QTreeWidgetItem *,int))); QPushButton *newGroup = ui->buttonBox->addButton(tr("New Group"), QDialogButtonBox::ActionRole); connect(newGroup, SIGNAL(clicked()), this, SLOT(on_newGroup_clicked())); AddChildren(ui->treeWidget->invisibleRootItem(), nullptr); ui->treeWidget->expandAll(); } lcQEditGroupsDialog::~lcQEditGroupsDialog() { delete ui; } void lcQEditGroupsDialog::accept() { UpdateParents(ui->treeWidget->invisibleRootItem(), nullptr); QDialog::accept(); } void lcQEditGroupsDialog::reject() { for (int GroupIdx = 0; GroupIdx < mNewGroups.size(); GroupIdx++) mModel->RemoveGroup(mNewGroups[GroupIdx]); QDialog::reject(); } void lcQEditGroupsDialog::on_newGroup_clicked() { QTreeWidgetItem* CurrentItem = ui->treeWidget->currentItem(); if (CurrentItem && CurrentItem->data(0, PieceRole).value()) CurrentItem = CurrentItem->parent(); if (!CurrentItem) CurrentItem = ui->treeWidget->invisibleRootItem(); lcGroup* ParentGroup = (lcGroup*)CurrentItem->data(0, GroupRole).value(); lcGroup* NewGroup = mModel->AddGroup(tr("Group #"), ParentGroup); mGroupParents[NewGroup] = ParentGroup; mNewGroups.append(NewGroup); QTreeWidgetItem* GroupItem = new QTreeWidgetItem(CurrentItem, QStringList(NewGroup->mName)); GroupItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable); GroupItem->setData(0, GroupRole, QVariant::fromValue((uintptr_t)NewGroup)); } void lcQEditGroupsDialog::onItemClicked(QTreeWidgetItem *item, int column) { Q_UNUSED(column); if (item->flags() & Qt::ItemIsEditable) { mClickTimer.stop(); if (mLastItemClicked != item) { mLastItemClicked = item; mEditableDoubleClicked = false; } else { mClickTimer.start(QApplication::doubleClickInterval() + 50, this); } } } void lcQEditGroupsDialog::onItemDoubleClicked(QTreeWidgetItem *item, int column) { Q_UNUSED(column); if (item->flags() & Qt::ItemIsEditable) { mEditableDoubleClicked = true; } } void lcQEditGroupsDialog::timerEvent(QTimerEvent *event) { Q_UNUSED(event); mClickTimer.stop(); if (!mEditableDoubleClicked) { ui->treeWidget->editItem(mLastItemClicked); } mEditableDoubleClicked = false; } void lcQEditGroupsDialog::UpdateParents(QTreeWidgetItem* ParentItem, lcGroup* ParentGroup) { for (int ChildIdx = 0; ChildIdx < ParentItem->childCount(); ChildIdx++) { QTreeWidgetItem* ChildItem = ParentItem->child(ChildIdx); lcPiece* Piece = (lcPiece*)ChildItem->data(0, PieceRole).value(); if (Piece) { mPieceParents[Piece] = ParentGroup; } else { lcGroup* Group = (lcGroup*)ChildItem->data(0, GroupRole).value(); // todo: validate unique group name if (Group) Group->mName = ChildItem->text(0); mGroupParents[Group] = ParentGroup; UpdateParents(ChildItem, Group); } } } void lcQEditGroupsDialog::AddChildren(QTreeWidgetItem* ParentItem, lcGroup* ParentGroup) { for (QMap::const_iterator it = mGroupParents.constBegin(); it != mGroupParents.constEnd(); it++) { lcGroup* Group = it.key(); lcGroup* Parent = it.value(); if (Parent != ParentGroup) continue; QTreeWidgetItem* GroupItem = new QTreeWidgetItem(ParentItem, QStringList(Group->mName)); GroupItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable); GroupItem->setData(0, GroupRole, QVariant::fromValue((uintptr_t)Group)); AddChildren(GroupItem, Group); } for (QMap::const_iterator it = mPieceParents.constBegin(); it != mPieceParents.constEnd(); it++) { lcPiece* Piece = it.key(); lcGroup* Parent = it.value(); if (Parent != ParentGroup) continue; QTreeWidgetItem* PieceItem = new QTreeWidgetItem(ParentItem, QStringList(Piece->GetName())); PieceItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); PieceItem->setData(0, PieceRole, QVariant::fromValue((uintptr_t)Piece)); } } leocad-23.03/qt/lc_qeditgroupsdialog.h000066400000000000000000000021561440571307300177610ustar00rootroot00000000000000#pragma once #include namespace Ui { class lcQEditGroupsDialog; } class lcQEditGroupsDialog : public QDialog { Q_OBJECT public: lcQEditGroupsDialog(QWidget* Parent, const QMap& PieceParents, const QMap& GroupParents, lcModel* Model); ~lcQEditGroupsDialog(); QMap mPieceParents; QMap mGroupParents; QList mNewGroups; //QList mDeletedGroups; // todo: support deleting groups in the edit groups dialog enum { PieceRole = Qt::UserRole, GroupRole }; public slots: void accept() override; void reject() override; void on_newGroup_clicked(); void onItemClicked(QTreeWidgetItem* Item, int Column); void onItemDoubleClicked(QTreeWidgetItem* Item, int Column); private: Ui::lcQEditGroupsDialog *ui; void UpdateParents(QTreeWidgetItem* ParentItem, lcGroup* ParentGroup); void AddChildren(QTreeWidgetItem* ParentItem, lcGroup* ParentGroup); void timerEvent(QTimerEvent* Event) override; lcModel* mModel; QTreeWidgetItem* mLastItemClicked; bool mEditableDoubleClicked; QBasicTimer mClickTimer; }; leocad-23.03/qt/lc_qeditgroupsdialog.ui000066400000000000000000000040661440571307300201510ustar00rootroot00000000000000 lcQEditGroupsDialog 0 0 450 350 Edit Groups QAbstractItemView::NoEditTriggers true QAbstractItemView::InternalMove true true 1 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() lcQEditGroupsDialog accept() 248 254 157 274 buttonBox rejected() lcQEditGroupsDialog reject() 316 260 286 274 leocad-23.03/qt/lc_qgroupdialog.cpp000066400000000000000000000010341440571307300172550ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qgroupdialog.h" #include "ui_lc_qgroupdialog.h" #include "group.h" lcQGroupDialog::lcQGroupDialog(QWidget *parent, const QString& Name) : QDialog(parent), ui(new Ui::lcQGroupDialog) { ui->setupUi(this); ui->name->setText(Name); } lcQGroupDialog::~lcQGroupDialog() { delete ui; } void lcQGroupDialog::accept() { QString Name = ui->name->text(); if (Name.isEmpty()) { QMessageBox::information(this, "LeoCAD", tr("Name cannot be empty.")); return; } mName = Name; QDialog::accept(); } leocad-23.03/qt/lc_qgroupdialog.h000066400000000000000000000004701440571307300167250ustar00rootroot00000000000000#pragma once #include namespace Ui { class lcQGroupDialog; } class lcQGroupDialog : public QDialog { Q_OBJECT public: explicit lcQGroupDialog(QWidget* Parent, const QString& Name); ~lcQGroupDialog(); QString mName; public slots: void accept() override; private: Ui::lcQGroupDialog *ui; }; leocad-23.03/qt/lc_qgroupdialog.ui000066400000000000000000000035201440571307300171120ustar00rootroot00000000000000 lcQGroupDialog 0 0 350 75 Group Name name Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() lcQGroupDialog accept() 248 254 157 274 buttonBox rejected() lcQGroupDialog reject() 316 260 286 274 leocad-23.03/qt/lc_qhtmldialog.cpp000066400000000000000000000043441440571307300170740ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qhtmldialog.h" #include "ui_lc_qhtmldialog.h" #include "project.h" lcQHTMLDialog::lcQHTMLDialog(QWidget* Parent, lcHTMLExportOptions* Options) : QDialog(Parent), ui(new Ui::lcQHTMLDialog) { ui->setupUi(this); ui->stepWidth->setValidator(new QIntValidator(0, 2048, ui->stepWidth)); ui->stepHeight->setValidator(new QIntValidator(0, 2048, ui->stepHeight)); mOptions = Options; ui->outputFolder->setText(QDir::toNativeSeparators(mOptions->PathName)); if (mOptions->CurrentOnly) ui->currentModelOnly->setChecked(true); else if (mOptions->SubModels) ui->currentModelSubmodels->setChecked(true); else ui->allModels->setChecked(true); ui->transparentImages->setChecked(mOptions->TransparentImages); ui->singlePage->setChecked(mOptions->SinglePage); ui->oneStepPerPage->setChecked(!mOptions->SinglePage); ui->indexPage->setChecked(mOptions->SinglePage); ui->stepWidth->setText(QString::number(mOptions->StepImagesWidth)); ui->stepHeight->setText(QString::number(mOptions->StepImagesHeight)); ui->partsAfterEachStep->setChecked(mOptions->PartsListStep); ui->partsAtTheEnd->setChecked(mOptions->PartsListEnd); } lcQHTMLDialog::~lcQHTMLDialog() { delete ui; } void lcQHTMLDialog::accept() { QString pathName = ui->outputFolder->text(); if (pathName.isEmpty()) { QMessageBox::information(this, "LeoCAD", tr("Output folder cannot be empty.")); return; } mOptions->PathName = pathName; mOptions->SubModels = ui->currentModelSubmodels->isChecked(); mOptions->CurrentOnly = ui->currentModelOnly->isChecked(); mOptions->TransparentImages = ui->transparentImages->isChecked(); mOptions->SinglePage = ui->singlePage->isChecked(); mOptions->IndexPage = ui->indexPage->isChecked(); mOptions->StepImagesWidth = ui->stepWidth->text().toInt(); mOptions->StepImagesHeight = ui->stepHeight->text().toInt(); mOptions->PartsListStep = ui->partsAfterEachStep->isChecked(); mOptions->PartsListEnd = ui->partsAtTheEnd->isChecked(); QDialog::accept(); } void lcQHTMLDialog::on_outputFolderBrowse_clicked() { QString result = QFileDialog::getExistingDirectory(this, tr("Select Output Folder"), ui->outputFolder->text()); if (!result.isEmpty()) ui->outputFolder->setText(QDir::toNativeSeparators(result)); } leocad-23.03/qt/lc_qhtmldialog.h000066400000000000000000000006161440571307300165370ustar00rootroot00000000000000#pragma once #include class lcHTMLExportOptions; namespace Ui { class lcQHTMLDialog; } class lcQHTMLDialog : public QDialog { Q_OBJECT public: explicit lcQHTMLDialog(QWidget* Parent, lcHTMLExportOptions* Options); ~lcQHTMLDialog(); public slots: void accept() override; void on_outputFolderBrowse_clicked(); private: lcHTMLExportOptions* mOptions; Ui::lcQHTMLDialog *ui; }; leocad-23.03/qt/lc_qhtmldialog.ui000066400000000000000000000153411440571307300167260ustar00rootroot00000000000000 lcQHTMLDialog 0 0 400 460 0 0 HTML Options 0 0 General Output folder: outputFolder ... Transparent image background Models All Models Current Model and Submodels Current Model Only Steps Single Page One Step per Page Index page Width: stepWidth 75 16777215 Height: stepHeight 75 16777215 Parts List At the end After each step Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok outputFolder outputFolderBrowse transparentImages allModels currentModelSubmodels currentModelOnly singlePage oneStepPerPage indexPage stepWidth stepHeight partsAtTheEnd partsAfterEachStep buttonBox accepted() lcQHTMLDialog accept() 252 564 157 274 buttonBox rejected() lcQHTMLDialog reject() 320 564 286 274 leocad-23.03/qt/lc_qimagedialog.cpp000066400000000000000000000060241440571307300172070ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qimagedialog.h" #include "ui_lc_qimagedialog.h" #include "lc_application.h" #include "project.h" #include "lc_model.h" #include "lc_profile.h" lcQImageDialog::lcQImageDialog(QWidget* Parent) : QDialog(Parent), ui(new Ui::lcQImageDialog) { ui->setupUi(this); ui->width->setValidator(new QIntValidator(1, 32768, this)); ui->height->setValidator(new QIntValidator(1, 32768, this)); ui->firstStep->setValidator(new QIntValidator(this)); ui->lastStep->setValidator(new QIntValidator(this)); Project* Project = lcGetActiveProject(); lcModel* Model = Project->GetActiveModel(); mWidth = lcGetProfileInt(LC_PROFILE_IMAGE_WIDTH); mHeight = lcGetProfileInt(LC_PROFILE_IMAGE_HEIGHT); mStart = Model->GetCurrentStep(); mEnd = Model->GetLastStep(); mFileName = Project->GetImageFileName(false); ui->fileName->setText(mFileName); ui->width->setText(QString::number(mWidth)); ui->height->setText(QString::number(mHeight)); ui->firstStep->setText(QString::number(mStart)); ui->lastStep->setText(QString::number(mEnd)); ui->rangeCurrent->setChecked(true); } lcQImageDialog::~lcQImageDialog() { delete ui; } void lcQImageDialog::accept() { QString fileName = ui->fileName->text(); if (fileName.isEmpty()) { QMessageBox::information(this, tr("Error"), tr("Output File cannot be empty.")); return; } int width = ui->width->text().toInt(); if (width < 1 || width > 32768) { QMessageBox::information(this, tr("Error"), tr("Please enter a width between 1 and 32768.")); return; } int height = ui->height->text().toInt(); if (height < 1 || height > 32768) { QMessageBox::information(this, tr("Error"), tr("Please enter a height between 1 and 32768.")); return; } int start = mStart, end = mStart; if (ui->rangeAll->isChecked()) { start = 1; end = mEnd; } else if (ui->rangeCurrent->isChecked()) { start = mStart; end = mStart; } else if (ui->rangeCustom->isChecked()) { start = ui->firstStep->text().toInt(); if (start < 1 || start > mEnd) { QMessageBox::information(this, tr("Error"), tr("First step must be between 1 and %1.").arg(QString::number(mEnd))); return; } end = ui->lastStep->text().toInt(); if (end < 1 || end > mEnd) { QMessageBox::information(this, tr("Error"), tr("Last step must be between 1 and %1.").arg(QString::number(mEnd))); return; } if (end < start) { QMessageBox::information(this, tr("Error"), tr("Last step must be greater than first step.")); return; } } mFileName = fileName; mWidth = width; mHeight = height; mStart = start; mEnd = end; lcSetProfileInt(LC_PROFILE_IMAGE_WIDTH, mWidth); lcSetProfileInt(LC_PROFILE_IMAGE_HEIGHT, mHeight); QDialog::accept(); } void lcQImageDialog::on_fileNameBrowse_clicked() { QString result = QFileDialog::getSaveFileName(this, tr("Save Image File"), ui->fileName->text(), tr("Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*)")); if (!result.isEmpty()) ui->fileName->setText(QDir::toNativeSeparators(result)); } leocad-23.03/qt/lc_qimagedialog.h000066400000000000000000000005661440571307300166610ustar00rootroot00000000000000#pragma once #include namespace Ui { class lcQImageDialog; } class lcQImageDialog : public QDialog { Q_OBJECT public: lcQImageDialog(QWidget* Parent); ~lcQImageDialog(); QString mFileName; int mWidth; int mHeight; int mStart; int mEnd; public slots: void accept() override; void on_fileNameBrowse_clicked(); private: Ui::lcQImageDialog *ui; }; leocad-23.03/qt/lc_qimagedialog.ui000066400000000000000000000154441440571307300170500ustar00rootroot00000000000000 lcQImageDialog 0 0 545 180 Save Image File name: fileName ... Dimensions Width: width 75 0 75 16777215 Height: height 75 0 75 16777215 Step Range All Steps Current Step Custom Range From: 75 0 75 16777215 To: 75 0 75 16777215 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok fileName fileNameBrowse width height rangeAll rangeCurrent rangeCustom firstStep lastStep buttonBox buttonBox accepted() lcQImageDialog accept() 222 225 157 239 buttonBox rejected() lcQImageDialog reject() 290 231 286 239 leocad-23.03/qt/lc_qmodellistdialog.cpp000066400000000000000000000214561440571307300201270ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qmodellistdialog.h" #include "ui_lc_qmodellistdialog.h" #include "project.h" #include "lc_profile.h" #include "lc_model.h" enum class lcModelListRole { ExistingModel = Qt::UserRole, DuplicateModel }; lcQModelListDialog::lcQModelListDialog(QWidget* Parent, const lcArray Models) : QDialog(Parent), ui(new Ui::lcQModelListDialog) { mActiveModelItem = nullptr; ui->setupUi(this); for (const lcModel* Model : Models) { QListWidgetItem* Item = new QListWidgetItem(Model->GetProperties().mFileName); Item->setData(static_cast(lcModelListRole::ExistingModel), QVariant::fromValue((uintptr_t)Model)); ui->ModelList->addItem(Item); } ui->ModelList->setCurrentRow(lcGetActiveProject()->GetActiveModelIndex()); QSettings Settings; ui->SetActiveModel->setChecked(Settings.value("Settings/ModelListSetActive", true).toBool()); UpdateButtons(); } lcQModelListDialog::~lcQModelListDialog() { delete ui; } int lcQModelListDialog::GetActiveModelIndex() const { return ui->ModelList->row(mActiveModelItem); } std::vector lcQModelListDialog::GetResults() const { std::vector Models; Models.reserve(ui->ModelList->count()); for (int ItemIdx = 0; ItemIdx < ui->ModelList->count(); ItemIdx++) { QListWidgetItem* Item = ui->ModelList->item(ItemIdx); lcModelListDialogEntry Entry; Entry.Name = Item->text(); Entry.ExistingModel = reinterpret_cast(Item->data(static_cast(lcModelListRole::ExistingModel)).value()); Entry.DuplicateSource = reinterpret_cast(Item->data(static_cast(lcModelListRole::DuplicateModel)).value()); Models.emplace_back(Entry); } return Models; } void lcQModelListDialog::UpdateButtons() { int ModelCount = ui->ModelList->count(); ui->DeleteModel->setEnabled(ModelCount > 1); ui->SetActiveModel->setEnabled(ui->ModelList->currentItem() != nullptr); bool MoveUp = false; bool MoveDown = false; for (int Row = 0; Row < ui->ModelList->count(); Row++) { QListWidgetItem* Item = ui->ModelList->item(Row); if (!Item->isSelected()) continue; if (Row > 0 && !ui->ModelList->item(Row - 1)->isSelected()) MoveUp = true; if (Row < ModelCount - 1 && !ui->ModelList->item(Row + 1)->isSelected()) MoveDown = true; } ui->MoveUp->setEnabled(MoveUp); ui->MoveDown->setEnabled(MoveDown); } void lcQModelListDialog::accept() { if (ui->SetActiveModel->isChecked()) mActiveModelItem = ui->ModelList->currentItem(); QSettings Settings; Settings.setValue("Settings/ModelListSetActive", ui->SetActiveModel->isChecked()); QDialog::accept(); } void lcQModelListDialog::on_NewModel_clicked() { QStringList ModelNames; for (int ItemIdx = 0; ItemIdx < ui->ModelList->count(); ItemIdx++) ModelNames.append(ui->ModelList->item(ItemIdx)->text()); QString Name = lcGetActiveProject()->GetNewModelName(this, tr("New Submodel"), QString(), ModelNames); if (Name.isEmpty()) return; QListWidgetItem* Item = new QListWidgetItem(Name); ui->ModelList->addItem(Item); UpdateButtons(); } void lcQModelListDialog::on_DeleteModel_clicked() { if (ui->ModelList->count() == 1) { QMessageBox::information(this, tr("Delete Submodel"), tr("The model cannot be empty.")); return; } QList SelectedItems = ui->ModelList->selectedItems(); if (SelectedItems.isEmpty()) { QMessageBox::information(this, tr("Delete Submodel"), tr("No submodel selected.")); return; } QString Prompt; if (SelectedItems.size() == 1) Prompt = tr("Are you sure you want to delete the submodel '%1'?").arg(SelectedItems[0]->text()); else Prompt = tr("Are you sure you want to delete %1 submodels?").arg(QString::number(SelectedItems.size())); if (QMessageBox::question(this, tr("Delete Submodel"), Prompt, QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; for (QListWidgetItem* SelectedItem : SelectedItems) { if (mActiveModelItem == SelectedItem) mActiveModelItem = nullptr; delete SelectedItem; } UpdateButtons(); } void lcQModelListDialog::on_RenameModel_clicked() { QList SelectedItems = ui->ModelList->selectedItems(); if (SelectedItems.isEmpty()) { QMessageBox::information(this, tr("Rename Submodel"), tr("No submodel selected.")); return; } for (QListWidgetItem* CurrentItem : SelectedItems) { QStringList ModelNames; for (int ItemIdx = 0; ItemIdx < ui->ModelList->count(); ItemIdx++) ModelNames.append(ui->ModelList->item(ItemIdx)->text()); QString Name = lcGetActiveProject()->GetNewModelName(this, tr("Rename Submodel"), CurrentItem->text(), ModelNames); if (!Name.isEmpty()) CurrentItem->setText(Name); } } void lcQModelListDialog::on_ExportModel_clicked() { QList SelectedItems = ui->ModelList->selectedItems(); if (SelectedItems.isEmpty()) { QMessageBox::information(this, tr("Export Submodel"), tr("No submodel selected.")); return; } if (SelectedItems.size() == 1) { QListWidgetItem* CurrentItem = SelectedItems[0]; lcModel* Model = (lcModel*)CurrentItem->data(static_cast(lcModelListRole::ExistingModel)).value(); if (!Model) { Model = (lcModel*)CurrentItem->data(static_cast(lcModelListRole::DuplicateModel)).value(); if (!Model) { QMessageBox::information(this, tr("LeoCAD"), tr("Nothing to export.")); return; } } QString SaveFileName = QFileInfo(QDir(lcGetProfileString(LC_PROFILE_PROJECTS_PATH)), CurrentItem->text()).absoluteFilePath(); SaveFileName = QFileDialog::getSaveFileName(this, tr("Export Model"), SaveFileName, tr("Supported Files (*.ldr *.dat);;All Files (*.*)")); if (SaveFileName.isEmpty()) return; lcGetActiveProject()->ExportModel(SaveFileName, Model); lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(SaveFileName).absolutePath()); } else { QString Folder = QFileDialog::getExistingDirectory(this, tr("Select Export Folder"), lcGetProfileString(LC_PROFILE_PROJECTS_PATH)); for (QListWidgetItem* CurrentItem : SelectedItems) { lcModel* Model = (lcModel*)CurrentItem->data(static_cast(lcModelListRole::ExistingModel)).value(); if (!Model) Model = (lcModel*)CurrentItem->data(static_cast(lcModelListRole::DuplicateModel)).value(); if (Model) { QString SaveFileName = QFileInfo(QDir(Folder), CurrentItem->text()).absoluteFilePath(); lcGetActiveProject()->ExportModel(SaveFileName, Model); } } lcSetProfileString(LC_PROFILE_PROJECTS_PATH, Folder); } } void lcQModelListDialog::on_DuplicateModel_clicked() { QList SelectedItems = ui->ModelList->selectedItems(); if (SelectedItems.isEmpty()) { QMessageBox::information(this, tr("Duplicate Submodel"), tr("No submodel selected.")); return; } for (QListWidgetItem* CurrentItem : SelectedItems) { QStringList ModelNames; for (int ItemIdx = 0; ItemIdx < ui->ModelList->count(); ItemIdx++) ModelNames.append(ui->ModelList->item(ItemIdx)->text()); QString Name = CurrentItem->text(); do { Name = tr("Copy of ") + Name; } while (ModelNames.contains(Name, Qt::CaseInsensitive)); Name = lcGetActiveProject()->GetNewModelName(this, tr("Duplicate Submodel"), Name, ModelNames); if (Name.isEmpty()) continue; QListWidgetItem* Item = new QListWidgetItem(Name); uintptr_t ExistingModel = CurrentItem->data(static_cast(lcModelListRole::ExistingModel)).value(); if (!ExistingModel) ExistingModel = CurrentItem->data(static_cast(lcModelListRole::DuplicateModel)).value(); Item->setData(static_cast(lcModelListRole::DuplicateModel), QVariant::fromValue(ExistingModel)); ui->ModelList->addItem(Item); } UpdateButtons(); } void lcQModelListDialog::on_MoveUp_clicked() { bool Blocked = ui->ModelList->blockSignals(true); for (int Row = 1; Row < ui->ModelList->count(); Row++) { QListWidgetItem* Item = ui->ModelList->item(Row); if (!Item->isSelected()) continue; if (ui->ModelList->item(Row - 1)->isSelected()) continue; ui->ModelList->takeItem(Row); ui->ModelList->insertItem(Row - 1, Item); Item->setSelected(true); } ui->ModelList->blockSignals(Blocked); UpdateButtons(); } void lcQModelListDialog::on_MoveDown_clicked() { bool Blocked = ui->ModelList->blockSignals(true); for (int Row = ui->ModelList->count() - 2; Row >= 0; Row--) { QListWidgetItem* Item = ui->ModelList->item(Row); if (!Item->isSelected()) continue; if (ui->ModelList->item(Row + 1)->isSelected()) continue; ui->ModelList->takeItem(Row); ui->ModelList->insertItem(Row + 1, Item); Item->setSelected(true); } ui->ModelList->blockSignals(Blocked); UpdateButtons(); } void lcQModelListDialog::on_ModelList_itemDoubleClicked(QListWidgetItem* Item) { mActiveModelItem = Item; accept(); } void lcQModelListDialog::on_ModelList_itemSelectionChanged() { UpdateButtons(); } leocad-23.03/qt/lc_qmodellistdialog.h000066400000000000000000000016001440571307300175610ustar00rootroot00000000000000#pragma once #include "lc_array.h" namespace Ui { class lcQModelListDialog; } struct lcModelListDialogEntry { QString Name; lcModel* ExistingModel; lcModel* DuplicateSource; }; class lcQModelListDialog : public QDialog { Q_OBJECT public: lcQModelListDialog(QWidget* Parent, const lcArray Models); ~lcQModelListDialog(); int GetActiveModelIndex() const; std::vector GetResults() const; public slots: void accept() override; void on_NewModel_clicked(); void on_DeleteModel_clicked(); void on_RenameModel_clicked(); void on_ExportModel_clicked(); void on_DuplicateModel_clicked(); void on_MoveUp_clicked(); void on_MoveDown_clicked(); void on_ModelList_itemDoubleClicked(QListWidgetItem* Item); void on_ModelList_itemSelectionChanged(); private: QListWidgetItem* mActiveModelItem; void UpdateButtons(); Ui::lcQModelListDialog* ui; }; leocad-23.03/qt/lc_qmodellistdialog.ui000066400000000000000000000077531440571307300177660ustar00rootroot00000000000000 lcQModelListDialog 0 0 421 348 Submodels QAbstractItemView::ExtendedSelection &New... D&elete... &Rename... Export... Duplicate... Move &Up Move &Down Set Active Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok ModelList NewModel DeleteModel RenameModel ExportModel DuplicateModel MoveUp MoveDown SetActiveModel buttonBox accepted() lcQModelListDialog accept() 248 254 157 274 buttonBox rejected() lcQModelListDialog reject() 316 260 286 274 leocad-23.03/qt/lc_qpreferencesdialog.cpp000066400000000000000000001324371440571307300204360ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qpreferencesdialog.h" #include "ui_lc_qpreferencesdialog.h" #include "lc_qutils.h" #include "lc_qcategorydialog.h" #include "lc_library.h" #include "lc_application.h" #include "lc_qutils.h" #include "lc_glextensions.h" #include "pieceinf.h" #include "lc_edgecolordialog.h" static const char* gLanguageLocales[] = { "", "cs_CZ", "de_DE", "en_US", "fr_FR", "pt_PT", "es_ES" }; lcQPreferencesDialog::lcQPreferencesDialog(QWidget* Parent, lcPreferencesDialogOptions* Options) : QDialog(Parent), mOptions(Options), ui(new Ui::lcQPreferencesDialog) { ui->setupUi(this); #if defined(Q_OS_WIN) || defined(Q_OS_MACOS) ui->povrayLabel->hide(); ui->povrayExecutable->hide(); ui->povrayExecutableBrowse->hide(); delete ui->povrayLabel; delete ui->povrayLayout; #endif connect(ui->BackgroundSolidColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->BackgroundGradient1ColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->BackgroundGradient2ColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->ActiveViewColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->InactiveViewColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->AxesColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->TextColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->MarqueeBorderColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->MarqueeFillColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->OverlayColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->FadeStepsColor, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->HighlightNewPartsColor, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->gridStudColor, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->gridLineColor, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->ViewSphereColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->ViewSphereTextColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->ViewSphereHighlightColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->ObjectSelectedColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->ObjectFocusedColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->CameraColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->LightColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->ControlPointColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->ControlPointFocusedColorButton, &QToolButton::clicked, this, &lcQPreferencesDialog::ColorButtonClicked); connect(ui->categoriesTree, SIGNAL(itemSelectionChanged()), this, SLOT(updateParts())); ui->shortcutEdit->installEventFilter(this); connect(ui->commandList, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(commandChanged(QTreeWidgetItem*))); connect(ui->mouseTree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(MouseTreeItemChanged(QTreeWidgetItem*))); connect(ui->HighContrastButton, SIGNAL(clicked()), this, SLOT(AutomateEdgeColor())); connect(ui->AutomateEdgeColorButton, SIGNAL(clicked()), this, SLOT(AutomateEdgeColor())); ui->partsLibrary->setText(mOptions->LibraryPath); ui->ColorConfigEdit->setText(mOptions->ColorConfigPath); ui->MinifigSettingsEdit->setText(mOptions->MinifigSettingsPath); ui->povrayExecutable->setText(mOptions->POVRayPath); ui->lgeoPath->setText(mOptions->LGEOPath); ui->authorName->setText(mOptions->DefaultAuthor); ui->mouseSensitivity->setValue(mOptions->Preferences.mMouseSensitivity); const bool ColorThemeBlocked = ui->ColorTheme->blockSignals(true); ui->ColorTheme->setCurrentIndex(static_cast(mOptions->Preferences.mColorTheme)); ui->ColorTheme->blockSignals(ColorThemeBlocked); for (unsigned int LanguageIdx = 0; LanguageIdx < LC_ARRAY_COUNT(gLanguageLocales); LanguageIdx++) { if (mOptions->Language == gLanguageLocales[LanguageIdx]) { ui->Language->setCurrentIndex(LanguageIdx); break; } } ui->checkForUpdates->setCurrentIndex(mOptions->CheckForUpdates); ui->fixedDirectionKeys->setChecked(mOptions->Preferences.mFixedAxes); ui->autoLoadMostRecent->setChecked(mOptions->Preferences.mAutoLoadMostRecent); ui->RestoreTabLayout->setChecked(mOptions->Preferences.mRestoreTabLayout); ui->AutomateEdgeColor->setChecked(mOptions->Preferences.mAutomateEdgeColor); ui->antiAliasing->setChecked(mOptions->AASamples != 1); if (mOptions->AASamples == 8) ui->antiAliasingSamples->setCurrentIndex(2); else if (mOptions->AASamples == 4) ui->antiAliasingSamples->setCurrentIndex(1); else ui->antiAliasingSamples->setCurrentIndex(0); ui->edgeLines->setChecked(mOptions->Preferences.mDrawEdgeLines); ui->ConditionalLinesCheckBox->setChecked(mOptions->Preferences.mDrawConditionalLines); if (!gSupportsShaderObjects) { ui->ConditionalLinesCheckBox->setChecked(false); ui->ConditionalLinesCheckBox->setEnabled(false); } #ifndef LC_OPENGLES if (QSurfaceFormat::defaultFormat().samples() > 1) { glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, mLineWidthRange); glGetFloatv(GL_SMOOTH_LINE_WIDTH_GRANULARITY, &mLineWidthGranularity); } else #endif { glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, mLineWidthRange); mLineWidthGranularity = 1.0f; } ui->LineWidthSlider->setRange(0, (mLineWidthRange[1] - mLineWidthRange[0]) / mLineWidthGranularity); ui->LineWidthSlider->setValue((mOptions->Preferences.mLineWidth - mLineWidthRange[0]) / mLineWidthGranularity); ui->MeshLOD->setChecked(mOptions->Preferences.mAllowLOD); ui->MeshLODSlider->setRange(0, 1500.0f / mMeshLODMultiplier); ui->MeshLODSlider->setValue(mOptions->Preferences.mMeshLODDistance / mMeshLODMultiplier); ui->FadeSteps->setChecked(mOptions->Preferences.mFadeSteps); ui->HighlightNewParts->setChecked(mOptions->Preferences.mHighlightNewParts); ui->gridStuds->setChecked(mOptions->Preferences.mDrawGridStuds); ui->gridLines->setChecked(mOptions->Preferences.mDrawGridLines); ui->gridLineSpacing->setText(QString::number(mOptions->Preferences.mGridLineSpacing)); ui->GridOriginCheckBox->setChecked(mOptions->Preferences.mDrawGridOrigin); ui->AxisIconCheckBox->setChecked(mOptions->Preferences.mDrawAxes); ui->AxisIconLocationCombo->setCurrentIndex((int)mOptions->Preferences.mAxisIconLocation); if (!mOptions->Preferences.mBackgroundGradient) ui->BackgroundSolidRadio->setChecked(true); else ui->BackgroundGradientRadio->setChecked(true); ui->ViewSphereLocationCombo->setCurrentIndex((int)mOptions->Preferences.mViewSphereLocation); if (mOptions->Preferences.mViewSphereEnabled) { switch (mOptions->Preferences.mViewSphereSize) { case 200: ui->ViewSphereSizeCombo->setCurrentIndex(3); break; case 100: ui->ViewSphereSizeCombo->setCurrentIndex(2); break; case 50: ui->ViewSphereSizeCombo->setCurrentIndex(1); break; default: ui->ViewSphereSizeCombo->setCurrentIndex(0); break; } } else ui->ViewSphereSizeCombo->setCurrentIndex(0); ui->PreviewAxisIconCheckBox->setChecked(mOptions->Preferences.mDrawPreviewAxis); ui->PreviewViewSphereLocationCombo->setCurrentIndex((int)mOptions->Preferences.mPreviewViewSphereLocation); if (mOptions->Preferences.mPreviewViewSphereEnabled) { switch (mOptions->Preferences.mPreviewViewSphereSize) { case 100: ui->PreviewViewSphereSizeCombo->setCurrentIndex(3); break; case 75: ui->PreviewViewSphereSizeCombo->setCurrentIndex(2); break; case 50: ui->PreviewViewSphereSizeCombo->setCurrentIndex(1); break; default: ui->PreviewViewSphereSizeCombo->setCurrentIndex(0); break; } } else ui->PreviewViewSphereSizeCombo->setCurrentIndex(0); if (!lcGetPiecesLibrary()->SupportsStudStyle()) ui->studStyleCombo->setEnabled(false); ui->studStyleCombo->setCurrentIndex(static_cast(mOptions->StudStyle)); if (!gSupportsShaderObjects) ui->ShadingMode->removeItem(static_cast(lcShadingMode::DefaultLights)); ui->ShadingMode->setCurrentIndex(static_cast(mOptions->Preferences.mShadingMode)); auto SetButtonPixmap = [](quint32 Color, QToolButton* Button) { QPixmap Pixmap(12, 12); Pixmap.fill(QColor(LC_RGBA_RED(Color), LC_RGBA_GREEN(Color), LC_RGBA_BLUE(Color))); Button->setIcon(Pixmap); }; SetButtonPixmap(mOptions->Preferences.mBackgroundSolidColor, ui->BackgroundSolidColorButton); SetButtonPixmap(mOptions->Preferences.mBackgroundGradientColorTop, ui->BackgroundGradient1ColorButton); SetButtonPixmap(mOptions->Preferences.mBackgroundGradientColorBottom, ui->BackgroundGradient2ColorButton); SetButtonPixmap(mOptions->Preferences.mAxesColor, ui->AxesColorButton); SetButtonPixmap(mOptions->Preferences.mTextColor, ui->TextColorButton); SetButtonPixmap(mOptions->Preferences.mMarqueeBorderColor, ui->MarqueeBorderColorButton); SetButtonPixmap(mOptions->Preferences.mMarqueeFillColor, ui->MarqueeFillColorButton); SetButtonPixmap(mOptions->Preferences.mOverlayColor, ui->OverlayColorButton); SetButtonPixmap(mOptions->Preferences.mActiveViewColor, ui->ActiveViewColorButton); SetButtonPixmap(mOptions->Preferences.mInactiveViewColor, ui->InactiveViewColorButton); SetButtonPixmap(mOptions->Preferences.mFadeStepsColor, ui->FadeStepsColor); SetButtonPixmap(mOptions->Preferences.mHighlightNewPartsColor, ui->HighlightNewPartsColor); SetButtonPixmap(mOptions->Preferences.mGridStudColor, ui->gridStudColor); SetButtonPixmap(mOptions->Preferences.mGridLineColor, ui->gridLineColor); SetButtonPixmap(mOptions->Preferences.mViewSphereColor, ui->ViewSphereColorButton); SetButtonPixmap(mOptions->Preferences.mViewSphereTextColor, ui->ViewSphereTextColorButton); SetButtonPixmap(mOptions->Preferences.mViewSphereHighlightColor, ui->ViewSphereHighlightColorButton); SetButtonPixmap(mOptions->Preferences.mObjectSelectedColor, ui->ObjectSelectedColorButton); SetButtonPixmap(mOptions->Preferences.mObjectFocusedColor, ui->ObjectFocusedColorButton); SetButtonPixmap(mOptions->Preferences.mCameraColor, ui->CameraColorButton); SetButtonPixmap(mOptions->Preferences.mLightColor, ui->LightColorButton); SetButtonPixmap(mOptions->Preferences.mControlPointColor, ui->ControlPointColorButton); SetButtonPixmap(mOptions->Preferences.mControlPointFocusedColor, ui->ControlPointFocusedColorButton); on_studStyleCombo_currentIndexChanged(ui->studStyleCombo->currentIndex()); on_antiAliasing_toggled(); on_AutomateEdgeColor_toggled(); on_edgeLines_toggled(); on_LineWidthSlider_valueChanged(); on_MeshLODSlider_valueChanged(); on_FadeSteps_toggled(); on_HighlightNewParts_toggled(); on_gridStuds_toggled(); on_gridLines_toggled(); on_ViewSphereSizeCombo_currentIndexChanged(ui->ViewSphereSizeCombo->currentIndex()); on_PreviewViewSphereSizeCombo_currentIndexChanged(ui->PreviewViewSphereSizeCombo->currentIndex()); updateCategories(); ui->categoriesTree->setCurrentItem(ui->categoriesTree->topLevelItem(0)); updateCommandList(); new lcQTreeWidgetColumnStretcher(ui->commandList, 0); commandChanged(nullptr); UpdateMouseTree(); ui->mouseTree->header()->setSectionResizeMode(0, QHeaderView::Stretch); ui->mouseTree->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); ui->mouseTree->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); MouseTreeItemChanged(nullptr); } lcQPreferencesDialog::~lcQPreferencesDialog() { delete ui; } void lcQPreferencesDialog::accept() { int gridLineSpacing = ui->gridLineSpacing->text().toInt(); if (gridLineSpacing < 1) { QMessageBox::information(this, "LeoCAD", tr("Grid spacing must be greater than 0.")); return; } mOptions->LibraryPath = ui->partsLibrary->text(); mOptions->MinifigSettingsPath = ui->MinifigSettingsEdit->text(); mOptions->ColorConfigPath = ui->ColorConfigEdit->text(); mOptions->POVRayPath = ui->povrayExecutable->text(); mOptions->LGEOPath = ui->lgeoPath->text(); mOptions->DefaultAuthor = ui->authorName->text(); mOptions->Preferences.mMouseSensitivity = ui->mouseSensitivity->value(); mOptions->Preferences.mColorTheme = static_cast(ui->ColorTheme->currentIndex()); mOptions->Preferences.mAutomateEdgeColor = ui->AutomateEdgeColor->isChecked(); int Language = ui->Language->currentIndex(); if (Language < 0 || Language > static_cast(LC_ARRAY_COUNT(gLanguageLocales))) Language = 0; mOptions->Language = gLanguageLocales[Language]; mOptions->CheckForUpdates = ui->checkForUpdates->currentIndex(); mOptions->Preferences.mFixedAxes = ui->fixedDirectionKeys->isChecked(); mOptions->Preferences.mAutoLoadMostRecent = ui->autoLoadMostRecent->isChecked(); mOptions->Preferences.mRestoreTabLayout = ui->RestoreTabLayout->isChecked(); if (!ui->antiAliasing->isChecked()) mOptions->AASamples = 1; else if (ui->antiAliasingSamples->currentIndex() == 2) mOptions->AASamples = 8; else if (ui->antiAliasingSamples->currentIndex() == 1) mOptions->AASamples = 4; else mOptions->AASamples = 2; mOptions->Preferences.mDrawEdgeLines = ui->edgeLines->isChecked(); mOptions->Preferences.mDrawConditionalLines = ui->ConditionalLinesCheckBox->isChecked(); mOptions->Preferences.mLineWidth = mLineWidthRange[0] + static_cast(ui->LineWidthSlider->value()) * mLineWidthGranularity; mOptions->Preferences.mAllowLOD = ui->MeshLOD->isChecked(); mOptions->Preferences.mMeshLODDistance = ui->MeshLODSlider->value() * mMeshLODMultiplier; mOptions->Preferences.mFadeSteps = ui->FadeSteps->isChecked(); mOptions->Preferences.mHighlightNewParts = ui->HighlightNewParts->isChecked(); mOptions->Preferences.mDrawGridStuds = ui->gridStuds->isChecked(); mOptions->Preferences.mDrawGridLines = ui->gridLines->isChecked(); mOptions->Preferences.mGridLineSpacing = gridLineSpacing; mOptions->Preferences.mDrawGridOrigin = ui->GridOriginCheckBox->isChecked(); mOptions->Preferences.mBackgroundGradient = ui->BackgroundGradientRadio->isChecked(); mOptions->Preferences.mDrawAxes = ui->AxisIconCheckBox->isChecked(); mOptions->Preferences.mAxisIconLocation = (lcAxisIconLocation)ui->AxisIconLocationCombo->currentIndex(); mOptions->Preferences.mViewSphereEnabled = ui->ViewSphereSizeCombo->currentIndex() > 0; mOptions->Preferences.mViewSphereLocation = (lcViewSphereLocation)ui->ViewSphereLocationCombo->currentIndex(); switch (ui->ViewSphereSizeCombo->currentIndex()) { case 3: mOptions->Preferences.mViewSphereSize = 200; break; case 2: mOptions->Preferences.mViewSphereSize = 100; break; case 1: mOptions->Preferences.mViewSphereSize = 50; break; } mOptions->Preferences.mShadingMode = (lcShadingMode)ui->ShadingMode->currentIndex(); mOptions->StudStyle = static_cast(ui->studStyleCombo->currentIndex()); mOptions->Preferences.mDrawPreviewAxis = ui->PreviewAxisIconCheckBox->isChecked(); mOptions->Preferences.mPreviewViewSphereEnabled = ui->PreviewViewSphereSizeCombo->currentIndex() > 0; mOptions->Preferences.mPreviewViewSphereLocation = (lcViewSphereLocation)ui->PreviewViewSphereLocationCombo->currentIndex(); switch (ui->PreviewViewSphereSizeCombo->currentIndex()) { case 3: mOptions->Preferences.mPreviewViewSphereSize = 100; break; case 2: mOptions->Preferences.mPreviewViewSphereSize = 75; break; case 1: mOptions->Preferences.mPreviewViewSphereSize = 50; break; } QDialog::accept(); } void lcQPreferencesDialog::on_partsLibraryBrowse_clicked() { QString result = QFileDialog::getExistingDirectory(this, tr("Select Parts Library Folder"), ui->partsLibrary->text()); if (!result.isEmpty()) ui->partsLibrary->setText(QDir::toNativeSeparators(result)); } void lcQPreferencesDialog::on_partsArchiveBrowse_clicked() { QString result = QFileDialog::getOpenFileName(this, tr("Select Parts Library Archive"), ui->partsLibrary->text(), tr("Supported Archives (*.zip *.bin);;All Files (*.*)")); if (!result.isEmpty()) ui->partsLibrary->setText(QDir::toNativeSeparators(result)); } void lcQPreferencesDialog::on_ColorConfigBrowseButton_clicked() { QString Result = QFileDialog::getOpenFileName(this, tr("Select Color Configuration File"), ui->ColorConfigEdit->text(), tr("Settings Files (*.ldr);;All Files (*.*)")); if (!Result.isEmpty()) ui->ColorConfigEdit->setText(QDir::toNativeSeparators(Result)); } void lcQPreferencesDialog::on_MinifigSettingsBrowseButton_clicked() { QString Result = QFileDialog::getOpenFileName(this, tr("Select Minifig Settings File"), ui->MinifigSettingsEdit->text(), tr("Settings Files (*.ini);;All Files (*.*)")); if (!Result.isEmpty()) ui->MinifigSettingsEdit->setText(QDir::toNativeSeparators(Result)); } void lcQPreferencesDialog::on_povrayExecutableBrowse_clicked() { #ifdef Q_OS_WIN QString filter(tr("Executable Files (*.exe);;All Files (*.*)")); #else QString filter(tr("All Files (*.*)")); #endif QString result = QFileDialog::getOpenFileName(this, tr("Select POV-Ray Executable"), ui->povrayExecutable->text(), filter); if (!result.isEmpty()) ui->povrayExecutable->setText(QDir::toNativeSeparators(result)); } void lcQPreferencesDialog::on_lgeoPathBrowse_clicked() { QString result = QFileDialog::getExistingDirectory(this, tr("Open LGEO Folder"), ui->lgeoPath->text()); if (!result.isEmpty()) ui->lgeoPath->setText(QDir::toNativeSeparators(result)); } void lcQPreferencesDialog::on_ColorTheme_currentIndexChanged(int Index) { Q_UNUSED(Index); if (QMessageBox::question(this, tr("Reset Colors"), tr("Would you like to also reset the interface colors to match the color theme?")) == QMessageBox::Yes) mOptions->Preferences.SetInterfaceColors(static_cast(ui->ColorTheme->currentIndex())); } void lcQPreferencesDialog::ColorButtonClicked() { QObject* Button = sender(); QString Title; quint32* Color = nullptr; QColorDialog::ColorDialogOptions DialogOptions; if (Button == ui->BackgroundSolidColorButton) { Color = &mOptions->Preferences.mBackgroundSolidColor; Title = tr("Select Background Color"); } else if (Button == ui->BackgroundGradient1ColorButton) { Color = &mOptions->Preferences.mBackgroundGradientColorTop; Title = tr("Select Gradient Top Color"); } else if (Button == ui->BackgroundGradient2ColorButton) { Color = &mOptions->Preferences.mBackgroundGradientColorBottom; Title = tr("Select Gradient Bottom Color"); } else if (Button == ui->AxesColorButton) { Color = &mOptions->Preferences.mAxesColor; Title = tr("Select Axes Color"); } else if (Button == ui->TextColorButton) { Color = &mOptions->Preferences.mTextColor; Title = tr("Select Text Color"); } else if (Button == ui->MarqueeBorderColorButton) { Color = &mOptions->Preferences.mMarqueeBorderColor; Title = tr("Select Marquee Border Color"); } else if (Button == ui->MarqueeFillColorButton) { Color = &mOptions->Preferences.mMarqueeFillColor; Title = tr("Select Marquee Fill Color"); DialogOptions = QColorDialog::ShowAlphaChannel; } else if (Button == ui->OverlayColorButton) { Color = &mOptions->Preferences.mOverlayColor; Title = tr("Select Overlay Color"); } else if (Button == ui->ActiveViewColorButton) { Color = &mOptions->Preferences.mActiveViewColor; Title = tr("Select Active View Color"); } else if (Button == ui->InactiveViewColorButton) { Color = &mOptions->Preferences.mInactiveViewColor; Title = tr("Select Inactive View Color"); } else if (Button == ui->FadeStepsColor) { Color = &mOptions->Preferences.mFadeStepsColor; Title = tr("Select Fade Color"); DialogOptions = QColorDialog::ShowAlphaChannel; } else if (Button == ui->HighlightNewPartsColor) { Color = &mOptions->Preferences.mHighlightNewPartsColor; Title = tr("Select Highlight Color"); DialogOptions = QColorDialog::ShowAlphaChannel; } else if (Button == ui->gridStudColor) { Color = &mOptions->Preferences.mGridStudColor; Title = tr("Select Grid Stud Color"); DialogOptions = QColorDialog::ShowAlphaChannel; } else if (Button == ui->gridLineColor) { Color = &mOptions->Preferences.mGridLineColor; Title = tr("Select Grid Line Color"); } else if (Button == ui->ViewSphereColorButton) { Color = &mOptions->Preferences.mViewSphereColor; Title = tr("Select View Sphere Color"); } else if (Button == ui->ViewSphereTextColorButton) { Color = &mOptions->Preferences.mViewSphereTextColor; Title = tr("Select View Sphere Text Color"); } else if (Button == ui->ViewSphereHighlightColorButton) { Color = &mOptions->Preferences.mViewSphereHighlightColor; Title = tr("Select View Sphere Highlight Color"); } else if (Button == ui->ObjectSelectedColorButton) { Color = &mOptions->Preferences.mObjectSelectedColor; Title = tr("Select Object Selected Color"); } else if (Button == ui->ObjectFocusedColorButton) { Color = &mOptions->Preferences.mObjectFocusedColor; Title = tr("Select Object Focused Color"); } else if (Button == ui->CameraColorButton) { Color = &mOptions->Preferences.mCameraColor; Title = tr("Select Camera Color"); } else if (Button == ui->LightColorButton) { Color = &mOptions->Preferences.mLightColor; Title = tr("Select Light Color"); } else if (Button == ui->ControlPointColorButton) { Color = &mOptions->Preferences.mControlPointColor; Title = tr("Select Control Point Color"); DialogOptions = QColorDialog::ShowAlphaChannel; } else if (Button == ui->ControlPointFocusedColorButton) { Color = &mOptions->Preferences.mControlPointFocusedColor; Title = tr("Select Control Point Focused Color"); DialogOptions = QColorDialog::ShowAlphaChannel; } else return; QColor oldColor = QColor(LC_RGBA_RED(*Color), LC_RGBA_GREEN(*Color), LC_RGBA_BLUE(*Color), LC_RGBA_ALPHA(*Color)); QColor newColor = QColorDialog::getColor(oldColor, this, Title, DialogOptions); if (newColor == oldColor || !newColor.isValid()) return; *Color = LC_RGBA(newColor.red(), newColor.green(), newColor.blue(), newColor.alpha()); QPixmap pix(12, 12); newColor.setAlpha(255); pix.fill(newColor); ((QToolButton*)Button)->setIcon(pix); } void lcQPreferencesDialog::on_antiAliasing_toggled() { ui->antiAliasingSamples->setEnabled(ui->antiAliasing->isChecked()); } void lcQPreferencesDialog::on_edgeLines_toggled() { const bool Enable = ui->edgeLines->isChecked() || ui->ConditionalLinesCheckBox->isChecked(); ui->LineWidthSlider->setEnabled(Enable); ui->LineWidthLabel->setEnabled(Enable); } void lcQPreferencesDialog::on_ConditionalLinesCheckBox_toggled() { const bool Enable = ui->edgeLines->isChecked() || ui->ConditionalLinesCheckBox->isChecked(); ui->LineWidthSlider->setEnabled(Enable); ui->LineWidthLabel->setEnabled(Enable); } void lcQPreferencesDialog::on_LineWidthSlider_valueChanged() { float Value = mLineWidthRange[0] + static_cast(ui->LineWidthSlider->value()) * mLineWidthGranularity; ui->LineWidthLabel->setText(QString::number(Value)); } void lcQPreferencesDialog::on_MeshLODSlider_valueChanged() { float Value = ui->MeshLODSlider->value() * mMeshLODMultiplier; ui->MeshLODLabel->setText(QString::number(static_cast(Value))); } void lcQPreferencesDialog::on_FadeSteps_toggled() { ui->FadeStepsColor->setEnabled(ui->FadeSteps->isChecked()); } void lcQPreferencesDialog::on_HighlightNewParts_toggled() { ui->HighlightNewPartsColor->setEnabled(ui->HighlightNewParts->isChecked()); } void lcQPreferencesDialog::on_gridStuds_toggled() { ui->gridStudColor->setEnabled(ui->gridStuds->isChecked()); } void lcQPreferencesDialog::on_gridLines_toggled() { ui->gridLineColor->setEnabled(ui->gridLines->isChecked()); ui->gridLineSpacing->setEnabled(ui->gridLines->isChecked()); } void lcQPreferencesDialog::on_PreviewViewSphereSizeCombo_currentIndexChanged(int Index) { ui->PreviewViewSphereLocationCombo->setEnabled(Index != 0); } void lcQPreferencesDialog::on_ViewSphereSizeCombo_currentIndexChanged(int Index) { ui->ViewSphereLocationCombo->setEnabled(Index != 0); } void lcQPreferencesDialog::on_AutomateEdgeColor_toggled() { ui->AutomateEdgeColorButton->setEnabled(ui->AutomateEdgeColor->isChecked()); } void lcQPreferencesDialog::on_studStyleCombo_currentIndexChanged(int index) { ui->HighContrastButton->setEnabled(lcIsHighContrast(static_cast(index))); } void lcQPreferencesDialog::AutomateEdgeColor() { lcAutomateEdgeColorDialog Dialog(this, sender() == ui->HighContrastButton); if (Dialog.exec() == QDialog::Accepted) { mOptions->Preferences.mStudCylinderColor = Dialog.mStudCylinderColor; mOptions->Preferences.mPartEdgeColor = Dialog.mPartEdgeColor; mOptions->Preferences.mBlackEdgeColor = Dialog.mBlackEdgeColor; mOptions->Preferences.mDarkEdgeColor = Dialog.mDarkEdgeColor; mOptions->Preferences.mPartEdgeContrast = Dialog.mPartEdgeContrast; mOptions->Preferences.mPartColorValueLDIndex = Dialog.mPartColorValueLDIndex; } } void lcQPreferencesDialog::updateCategories() { QTreeWidgetItem* CategoryItem; QTreeWidget* CategoriesTree = ui->categoriesTree; CategoriesTree->clear(); for (int CategoryIndex = 0; CategoryIndex < static_cast(mOptions->Categories.size()); CategoryIndex++) { CategoryItem = new QTreeWidgetItem(CategoriesTree, QStringList(mOptions->Categories[CategoryIndex].Name)); CategoryItem->setData(0, CategoryRole, QVariant(CategoryIndex)); } CategoryItem = new QTreeWidgetItem(CategoriesTree, QStringList(tr("Unassigned"))); CategoryItem->setData(0, CategoryRole, QVariant(-1)); } void lcQPreferencesDialog::updateParts() { lcPiecesLibrary *Library = lcGetPiecesLibrary(); QTreeWidget *tree = ui->partsTree; tree->clear(); QList selectedItems = ui->categoriesTree->selectedItems(); if (selectedItems.empty()) return; QTreeWidgetItem *categoryItem = selectedItems.first(); int categoryIndex = categoryItem->data(0, CategoryRole).toInt(); if (categoryIndex != -1) { lcArray singleParts, groupedParts; Library->GetCategoryEntries(mOptions->Categories[categoryIndex].Keywords.constData(), false, singleParts, groupedParts); for (int partIndex = 0; partIndex < singleParts.GetSize(); partIndex++) { PieceInfo *info = singleParts[partIndex]; QStringList rowList(info->m_strDescription); rowList.append(info->mFileName); new QTreeWidgetItem(tree, rowList); } } else { for (const auto& PartIt : Library->mPieces) { PieceInfo* Info = PartIt.second; for (categoryIndex = 0; categoryIndex < static_cast(mOptions->Categories.size()); categoryIndex++) { if (Library->PieceInCategory(Info, mOptions->Categories[categoryIndex].Keywords.constData())) break; } if (categoryIndex == static_cast(mOptions->Categories.size())) { QStringList rowList(Info->m_strDescription); rowList.append(Info->mFileName); new QTreeWidgetItem(tree, rowList); } } } tree->resizeColumnToContents(0); tree->resizeColumnToContents(1); } void lcQPreferencesDialog::on_newCategory_clicked() { lcLibraryCategory category; lcQCategoryDialog dialog(this, &category); if (dialog.exec() != QDialog::Accepted) return; mOptions->CategoriesModified = true; mOptions->CategoriesDefault = false; mOptions->Categories.emplace_back(std::move(category)); updateCategories(); ui->categoriesTree->setCurrentItem(ui->categoriesTree->topLevelItem(static_cast(mOptions->Categories.size()) - 1)); } void lcQPreferencesDialog::on_editCategory_clicked() { QList selectedItems = ui->categoriesTree->selectedItems(); if (selectedItems.empty()) return; QTreeWidgetItem *categoryItem = selectedItems.first(); int categoryIndex = categoryItem->data(0, CategoryRole).toInt(); if (categoryIndex == -1) return; lcQCategoryDialog dialog(this, &mOptions->Categories[categoryIndex]); if (dialog.exec() != QDialog::Accepted) return; mOptions->CategoriesModified = true; mOptions->CategoriesDefault = false; updateCategories(); ui->categoriesTree->setCurrentItem(ui->categoriesTree->topLevelItem(categoryIndex)); } void lcQPreferencesDialog::on_deleteCategory_clicked() { QList selectedItems = ui->categoriesTree->selectedItems(); if (selectedItems.empty()) return; QTreeWidgetItem *categoryItem = selectedItems.first(); int categoryIndex = categoryItem->data(0, CategoryRole).toInt(); if (categoryIndex == -1) return; QString question = tr("Are you sure you want to delete the category '%1'?").arg(mOptions->Categories[categoryIndex].Name); if (QMessageBox::question(this, "LeoCAD", question, QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; mOptions->CategoriesModified = true; mOptions->CategoriesDefault = false; mOptions->Categories.erase(mOptions->Categories.begin() + categoryIndex); updateCategories(); } void lcQPreferencesDialog::on_importCategories_clicked() { QString FileName = QFileDialog::getOpenFileName(this, tr("Import Categories"), "", tr("Text Files (*.txt);;All Files (*.*)")); if (FileName.isEmpty()) return; std::vector Categories; if (!lcLoadCategories(FileName, Categories)) { QMessageBox::warning(this, "LeoCAD", tr("Error loading categories file.")); return; } mOptions->Categories = Categories; mOptions->CategoriesModified = true; mOptions->CategoriesDefault = false; } void lcQPreferencesDialog::on_exportCategories_clicked() { QString FileName = QFileDialog::getSaveFileName(this, tr("Export Categories"), "", tr("Text Files (*.txt);;All Files (*.*)")); if (FileName.isEmpty()) return; if (!lcSaveCategories(FileName, mOptions->Categories)) { QMessageBox::warning(this, "LeoCAD", tr("Error saving categories file.")); return; } } void lcQPreferencesDialog::on_resetCategories_clicked() { if (QMessageBox::question(this, "LeoCAD", tr("Are you sure you want to load the default categories?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; lcResetCategories(mOptions->Categories); mOptions->CategoriesModified = true; mOptions->CategoriesDefault = true; updateCategories(); } bool lcQPreferencesDialog::eventFilter(QObject *object, QEvent *event) { Q_UNUSED(object); if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); int nextKey = keyEvent->key(); if (nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift || nextKey == Qt::Key_Meta || nextKey == Qt::Key_Alt) return true; Qt::KeyboardModifiers state = keyEvent->modifiers(); QString text = QKeySequence(nextKey).toString(); if ((state & Qt::ShiftModifier) && (text.isEmpty() || !text.at(0).isPrint() || text.at(0).isLetter() || text.at(0).isSpace())) nextKey |= Qt::SHIFT; if (state & Qt::ControlModifier) nextKey |= Qt::CTRL; if (state & Qt::MetaModifier) nextKey |= Qt::META; if (state & Qt::AltModifier) nextKey |= Qt::ALT; QKeySequence ks(nextKey); ui->shortcutEdit->setText(ks.toString(QKeySequence::NativeText)); keyEvent->accept(); return true; } if (event->type() == QEvent::Shortcut || event->type() == QEvent::KeyRelease || event->type() == QEvent::ShortcutOverride) { event->accept(); return true; } return QDialog::eventFilter(object, event); } void lcQPreferencesDialog::updateCommandList() { ui->commandList->clear(); QMap sections; for (unsigned int actionIdx = 0; actionIdx < LC_NUM_COMMANDS; actionIdx++) { if (!gCommands[actionIdx].ID[0]) continue; const QString identifier = tr(gCommands[actionIdx].ID); int pos = identifier.indexOf(QLatin1Char('.')); int subPos = identifier.indexOf(QLatin1Char('.'), pos + 1); if (subPos == -1) subPos = pos; const QString parentSection = identifier.left(pos); if (subPos != pos) { if (!sections.contains(parentSection)) { QTreeWidgetItem *categoryItem = new QTreeWidgetItem(ui->commandList, QStringList(parentSection)); QFont f = categoryItem->font(0); f.setBold(true); categoryItem->setFont(0, f); sections.insert(parentSection, categoryItem); ui->commandList->expandItem(categoryItem); } } const QString section = identifier.left(subPos); const QString subId = identifier.mid(subPos + 1); if (!sections.contains(section)) { QTreeWidgetItem *parent = sections[parentSection]; QTreeWidgetItem *categoryItem; QString subSection; if (pos != subPos) subSection = identifier.mid(pos + 1, subPos - pos - 1); else subSection = section; if (parent) categoryItem = new QTreeWidgetItem(parent, QStringList(subSection)); else categoryItem = new QTreeWidgetItem(ui->commandList, QStringList(subSection)); QFont f = categoryItem->font(0); f.setBold(true); categoryItem->setFont(0, f); sections.insert(section, categoryItem); ui->commandList->expandItem(categoryItem); } QTreeWidgetItem *item = new QTreeWidgetItem; QKeySequence sequence(mOptions->KeyboardShortcuts.mShortcuts[actionIdx]); item->setText(0, qApp->translate("Menu", gCommands[actionIdx].MenuName).remove('&').remove(QLatin1String("..."))); item->setText(1, sequence.toString(QKeySequence::NativeText)); item->setData(0, Qt::UserRole, QVariant::fromValue(actionIdx)); if (mOptions->KeyboardShortcuts.mShortcuts[actionIdx] != gCommands[actionIdx].DefaultShortcut) setShortcutModified(item, true); sections[section]->addChild(item); } } void lcQPreferencesDialog::setShortcutModified(QTreeWidgetItem *treeItem, bool modified) { QFont font = treeItem->font(0); font.setItalic(modified); treeItem->setFont(0, font); font.setBold(modified); treeItem->setFont(1, font); } void lcQPreferencesDialog::commandChanged(QTreeWidgetItem *current) { if (!current || !current->data(0, Qt::UserRole).isValid()) { ui->shortcutEdit->setText(QString()); ui->shortcutGroup->setEnabled(false); return; } ui->shortcutGroup->setEnabled(true); int shortcutIndex = qvariant_cast(current->data(0, Qt::UserRole)); QKeySequence key(mOptions->KeyboardShortcuts.mShortcuts[shortcutIndex]); ui->shortcutEdit->setText(key.toString(QKeySequence::NativeText)); } void lcQPreferencesDialog::on_KeyboardFilterEdit_textEdited(const QString& Text) { if (Text.isEmpty()) { std::function ShowItems = [&ShowItems](QTreeWidgetItem* ParentItem) { for (int ChildIdx = 0; ChildIdx < ParentItem->childCount(); ChildIdx++) ShowItems(ParentItem->child(ChildIdx)); ParentItem->setHidden(false); }; ShowItems(ui->commandList->invisibleRootItem()); } else { std::function ShowItems = [&ShowItems, &Text](QTreeWidgetItem* ParentItem, bool ForceVisible) { ForceVisible |= (bool)ParentItem->text(0).contains(Text, Qt::CaseInsensitive) | (bool)ParentItem->text(1).contains(Text, Qt::CaseInsensitive); bool Visible = ForceVisible; for (int ChildIdx = 0; ChildIdx < ParentItem->childCount(); ChildIdx++) Visible |= ShowItems(ParentItem->child(ChildIdx), ForceVisible); ParentItem->setHidden(!Visible); return Visible; }; ShowItems(ui->commandList->invisibleRootItem(), false); } } void lcQPreferencesDialog::on_shortcutAssign_clicked() { QTreeWidgetItem* CurrentItem = ui->commandList->currentItem(); if (!CurrentItem || !CurrentItem->data(0, Qt::UserRole).isValid()) return; uint ShortcutIndex = CurrentItem->data(0, Qt::UserRole).toUInt(); QString (&Shortcuts)[LC_NUM_COMMANDS] = mOptions->KeyboardShortcuts.mShortcuts; if (ShortcutIndex >= LC_ARRAY_COUNT(Shortcuts)) return; QString NewShortcut = ui->shortcutEdit->text(); if (!NewShortcut.isEmpty()) { for (uint ExistingIndex = 0; ExistingIndex < LC_ARRAY_COUNT(Shortcuts); ExistingIndex++) { if (NewShortcut == Shortcuts[ExistingIndex] && ExistingIndex != ShortcutIndex) { QString ActionText = qApp->translate("Menu", gCommands[ExistingIndex].MenuName).remove('&').remove(QLatin1String("...")); QString QuestionText = tr("The shortcut '%1' is already assigned to '%2'. Do you want to replace it?").arg(NewShortcut, ActionText); if (QMessageBox::question(this, tr("Override Shortcut"), QuestionText, QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; mOptions->KeyboardShortcuts.mShortcuts[ExistingIndex].clear(); std::function FindItem = [&FindItem, ExistingIndex](QTreeWidgetItem* ParentItem) -> QTreeWidgetItem* { for (int ChildIdx = 0; ChildIdx < ParentItem->childCount(); ChildIdx++) { QTreeWidgetItem* ChildItem = ParentItem->child(ChildIdx); uint ChildIndex = ChildItem->data(0, Qt::UserRole).toUInt(); if (ChildIndex == ExistingIndex) return ChildItem; QTreeWidgetItem* ExistingItem = FindItem(ChildItem); if (ExistingItem) return ExistingItem; } return nullptr; }; QTreeWidgetItem* ExistingItem = FindItem(ui->commandList->invisibleRootItem()); if (ExistingItem) { ExistingItem->setText(1, QString()); setShortcutModified(ExistingItem, gCommands[ShortcutIndex].DefaultShortcut[0] != 0); } } } } mOptions->KeyboardShortcuts.mShortcuts[ShortcutIndex] = NewShortcut; CurrentItem->setText(1, NewShortcut); setShortcutModified(CurrentItem, mOptions->KeyboardShortcuts.mShortcuts[ShortcutIndex] != gCommands[ShortcutIndex].DefaultShortcut); mOptions->KeyboardShortcutsModified = true; mOptions->KeyboardShortcutsDefault = false; } void lcQPreferencesDialog::on_shortcutRemove_clicked() { ui->shortcutEdit->setText(QString()); on_shortcutAssign_clicked(); } void lcQPreferencesDialog::on_shortcutsImport_clicked() { QString FileName = QFileDialog::getOpenFileName(this, tr("Import shortcuts"), "", tr("Text Files (*.txt);;All Files (*.*)")); if (FileName.isEmpty()) return; lcKeyboardShortcuts Shortcuts; if (!Shortcuts.Load(FileName)) { QMessageBox::warning(this, "LeoCAD", tr("Error loading keyboard shortcuts file.")); return; } mOptions->KeyboardShortcuts = Shortcuts; mOptions->KeyboardShortcutsModified = true; mOptions->KeyboardShortcutsDefault = false; } void lcQPreferencesDialog::on_shortcutsExport_clicked() { QString FileName = QFileDialog::getSaveFileName(this, tr("Export shortcuts"), "", tr("Text Files (*.txt);;All Files (*.*)")); if (FileName.isEmpty()) return; if (!mOptions->KeyboardShortcuts.Save(FileName)) { QMessageBox::warning(this, "LeoCAD", tr("Error saving keyboard shortcuts file.")); return; } } void lcQPreferencesDialog::on_shortcutsReset_clicked() { if (QMessageBox::question(this, "LeoCAD", tr("Are you sure you want to load the default keyboard shortcuts?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; mOptions->KeyboardShortcuts.Reset(); updateCommandList(); mOptions->KeyboardShortcutsModified = true; mOptions->KeyboardShortcutsDefault = true; } void lcQPreferencesDialog::UpdateMouseTree() { ui->mouseTree->clear(); for (int ToolIdx = 0; ToolIdx < static_cast(lcTool::Count); ToolIdx++) UpdateMouseTreeItem(ToolIdx); } void lcQPreferencesDialog::UpdateMouseTreeItem(int ItemIndex) { auto GetShortcutText = [](Qt::MouseButton Button, Qt::KeyboardModifiers Modifiers) { QString Shortcut = QKeySequence(Modifiers).toString(QKeySequence::NativeText); switch (Button) { case Qt::LeftButton: Shortcut += tr("Left Button"); break; case Qt::MiddleButton: Shortcut += tr("Middle Button"); break; case Qt::RightButton: Shortcut += tr("Right Button"); break; default: Shortcut.clear(); } return Shortcut; }; QString Shortcut1 = GetShortcutText(mOptions->MouseShortcuts.mShortcuts[ItemIndex].Button1, mOptions->MouseShortcuts.mShortcuts[ItemIndex].Modifiers1); QString Shortcut2 = GetShortcutText(mOptions->MouseShortcuts.mShortcuts[ItemIndex].Button2, mOptions->MouseShortcuts.mShortcuts[ItemIndex].Modifiers2); QTreeWidgetItem* Item = ui->mouseTree->topLevelItem(ItemIndex); if (Item) { Item->setText(1, Shortcut1); Item->setText(2, Shortcut2); } else new QTreeWidgetItem(ui->mouseTree, QStringList() << tr(gToolNames[ItemIndex]) << Shortcut1 << Shortcut2); } void lcQPreferencesDialog::on_mouseAssign_clicked() { QTreeWidgetItem* Current = ui->mouseTree->currentItem(); if (!Current) return; int ButtonIndex = ui->mouseButton->currentIndex(); Qt::MouseButton Button = Qt::NoButton; Qt::KeyboardModifiers Modifiers = Qt::NoModifier; if (ButtonIndex) { switch (ButtonIndex) { case 1: Button = Qt::LeftButton; break; case 2: Button = Qt::MiddleButton; break; case 3: Button = Qt::RightButton; break; } if (ui->mouseControl->isChecked()) Modifiers |= Qt::ControlModifier; if (ui->mouseShift->isChecked()) Modifiers |= Qt::ShiftModifier; if (ui->mouseAlt->isChecked()) Modifiers |= Qt::AltModifier; for (int ToolIdx = 0; ToolIdx < static_cast(lcTool::Count); ToolIdx++) { if (ToolIdx == ButtonIndex) continue; if (mOptions->MouseShortcuts.mShortcuts[ToolIdx].Button2 == Button && mOptions->MouseShortcuts.mShortcuts[ToolIdx].Modifiers2 == Modifiers) { if (QMessageBox::question(this, tr("Override Shortcut"), tr("This shortcut is already assigned to '%1', do you want to replace it?").arg(tr(gToolNames[ToolIdx])), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; mOptions->MouseShortcuts.mShortcuts[ToolIdx].Button2 = Qt::NoButton; mOptions->MouseShortcuts.mShortcuts[ToolIdx].Modifiers2 = Qt::NoModifier; } if (mOptions->MouseShortcuts.mShortcuts[ToolIdx].Button1 == Button && mOptions->MouseShortcuts.mShortcuts[ToolIdx].Modifiers1 == Modifiers) { if (QMessageBox::question(this, tr("Override Shortcut"), tr("This shortcut is already assigned to '%1', do you want to replace it?").arg(tr(gToolNames[ToolIdx])), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; mOptions->MouseShortcuts.mShortcuts[ToolIdx].Button1 = mOptions->MouseShortcuts.mShortcuts[ToolIdx].Button2; mOptions->MouseShortcuts.mShortcuts[ToolIdx].Modifiers1 = mOptions->MouseShortcuts.mShortcuts[ToolIdx].Modifiers2; mOptions->MouseShortcuts.mShortcuts[ToolIdx].Button2 = Qt::NoButton; mOptions->MouseShortcuts.mShortcuts[ToolIdx].Modifiers2 = Qt::NoModifier; UpdateMouseTreeItem(ToolIdx); } } } int ItemIndex = ui->mouseTree->indexOfTopLevelItem(Current); mOptions->MouseShortcuts.mShortcuts[ItemIndex].Button2 = mOptions->MouseShortcuts.mShortcuts[ItemIndex].Button1; mOptions->MouseShortcuts.mShortcuts[ItemIndex].Modifiers2 = mOptions->MouseShortcuts.mShortcuts[ItemIndex].Modifiers1; mOptions->MouseShortcuts.mShortcuts[ItemIndex].Button1 = Button; mOptions->MouseShortcuts.mShortcuts[ItemIndex].Modifiers1 = Modifiers; mOptions->MouseShortcutsModified = true; mOptions->MouseShortcutsDefault = false; UpdateMouseTreeItem(ItemIndex); } void lcQPreferencesDialog::on_mouseRemove_clicked() { QTreeWidgetItem* Current = ui->mouseTree->currentItem(); if (!Current) return; int ItemIndex = ui->mouseTree->indexOfTopLevelItem(Current); mOptions->MouseShortcuts.mShortcuts[ItemIndex].Button1 = mOptions->MouseShortcuts.mShortcuts[ItemIndex].Button2; mOptions->MouseShortcuts.mShortcuts[ItemIndex].Modifiers1 = mOptions->MouseShortcuts.mShortcuts[ItemIndex].Modifiers2; mOptions->MouseShortcuts.mShortcuts[ItemIndex].Button2 = Qt::NoButton; mOptions->MouseShortcuts.mShortcuts[ItemIndex].Modifiers2 = Qt::NoModifier; mOptions->MouseShortcutsModified = true; mOptions->MouseShortcutsDefault = false; UpdateMouseTreeItem(ItemIndex); MouseTreeItemChanged(Current); } void lcQPreferencesDialog::on_MouseImportButton_clicked() { QString FileName = QFileDialog::getOpenFileName(this, tr("Import Shortcuts"), "", tr("Text Files (*.txt);;All Files (*.*)")); if (FileName.isEmpty()) return; lcMouseShortcuts Shortcuts; if (!Shortcuts.Load(FileName)) { QMessageBox::warning(this, "LeoCAD", tr("Error loading mouse shortcuts file.")); return; } mOptions->MouseShortcuts = Shortcuts; UpdateMouseTree(); mOptions->MouseShortcutsModified = true; mOptions->MouseShortcutsDefault = false; } void lcQPreferencesDialog::on_MouseExportButton_clicked() { QString FileName = QFileDialog::getSaveFileName(this, tr("Export Shortcuts"), "", tr("Text Files (*.txt);;All Files (*.*)")); if (FileName.isEmpty()) return; if (!mOptions->MouseShortcuts.Save(FileName)) QMessageBox::warning(this, "LeoCAD", tr("Error saving mouse shortcuts file.")); } void lcQPreferencesDialog::on_mouseReset_clicked() { if (QMessageBox::question(this, "LeoCAD", tr("Are you sure you want to load the default mouse shortcuts?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; mOptions->MouseShortcuts.Reset(); UpdateMouseTree(); mOptions->MouseShortcutsModified = true; mOptions->MouseShortcutsDefault = true; } void lcQPreferencesDialog::MouseTreeItemChanged(QTreeWidgetItem* Current) { if (!Current) { ui->MouseShortcutGroup->setEnabled(false); return; } ui->MouseShortcutGroup->setEnabled(true); int ToolIndex = ui->mouseTree->indexOfTopLevelItem(Current); Qt::MouseButton Button = mOptions->MouseShortcuts.mShortcuts[ToolIndex].Button1; switch (Button) { case Qt::LeftButton: ui->mouseButton->setCurrentIndex(1); break; case Qt::MiddleButton: ui->mouseButton->setCurrentIndex(2); break; case Qt::RightButton: ui->mouseButton->setCurrentIndex(3); break; default: ui->mouseButton->setCurrentIndex(0); break; } Qt::KeyboardModifiers Modifiers = mOptions->MouseShortcuts.mShortcuts[ToolIndex].Modifiers1; ui->mouseControl->setChecked((Modifiers & Qt::ControlModifier) != 0); ui->mouseShift->setChecked((Modifiers & Qt::ShiftModifier) != 0); ui->mouseAlt->setChecked((Modifiers & Qt::AltModifier) != 0); } leocad-23.03/qt/lc_qpreferencesdialog.h000066400000000000000000000057661440571307300201070ustar00rootroot00000000000000#pragma once #include "lc_application.h" #include "lc_shortcuts.h" #include "lc_category.h" struct lcPreferencesDialogOptions { lcPreferences Preferences; QString LibraryPath; QString ColorConfigPath; QString MinifigSettingsPath; QString POVRayPath; QString LGEOPath; QString DefaultAuthor; QString Language; int CheckForUpdates; int AASamples; lcStudStyle StudStyle; std::vector Categories; bool CategoriesModified; bool CategoriesDefault; lcKeyboardShortcuts KeyboardShortcuts; bool KeyboardShortcutsModified; bool KeyboardShortcutsDefault; lcMouseShortcuts MouseShortcuts; bool MouseShortcutsModified; bool MouseShortcutsDefault; }; namespace Ui { class lcQPreferencesDialog; } class lcQPreferencesDialog : public QDialog { Q_OBJECT public: lcQPreferencesDialog(QWidget* Parent, lcPreferencesDialogOptions* Options); ~lcQPreferencesDialog(); lcPreferencesDialogOptions* mOptions; enum { CategoryRole = Qt::UserRole }; bool eventFilter(QObject* Object, QEvent* Event) override; public slots: void accept() override; void on_partsLibraryBrowse_clicked(); void on_partsArchiveBrowse_clicked(); void on_ColorConfigBrowseButton_clicked(); void on_MinifigSettingsBrowseButton_clicked(); void on_povrayExecutableBrowse_clicked(); void on_lgeoPathBrowse_clicked(); void on_ColorTheme_currentIndexChanged(int Index); void ColorButtonClicked(); void AutomateEdgeColor(); void on_AutomateEdgeColor_toggled(); void on_studStyleCombo_currentIndexChanged(int index); void on_antiAliasing_toggled(); void on_edgeLines_toggled(); void on_ConditionalLinesCheckBox_toggled(); void on_LineWidthSlider_valueChanged(); void on_MeshLODSlider_valueChanged(); void on_FadeSteps_toggled(); void on_HighlightNewParts_toggled(); void on_gridStuds_toggled(); void on_gridLines_toggled(); void on_ViewSphereSizeCombo_currentIndexChanged(int Index); void on_PreviewViewSphereSizeCombo_currentIndexChanged(int Index); void updateParts(); void on_newCategory_clicked(); void on_editCategory_clicked(); void on_deleteCategory_clicked(); void on_importCategories_clicked(); void on_exportCategories_clicked(); void on_resetCategories_clicked(); void on_shortcutAssign_clicked(); void on_shortcutRemove_clicked(); void on_shortcutsImport_clicked(); void on_shortcutsExport_clicked(); void on_shortcutsReset_clicked(); void commandChanged(QTreeWidgetItem *current); void on_KeyboardFilterEdit_textEdited(const QString& Text); void on_mouseAssign_clicked(); void on_mouseRemove_clicked(); void on_MouseImportButton_clicked(); void on_MouseExportButton_clicked(); void on_mouseReset_clicked(); void MouseTreeItemChanged(QTreeWidgetItem* Current); private: Ui::lcQPreferencesDialog *ui; void updateCategories(); void updateCommandList(); void UpdateMouseTree(); void UpdateMouseTreeItem(int ItemIndex); void setShortcutModified(QTreeWidgetItem *treeItem, bool modified); float mLineWidthRange[2]; float mLineWidthGranularity; static constexpr float mMeshLODMultiplier = 25.0f; }; leocad-23.03/qt/lc_qpreferencesdialog.ui000066400000000000000000002051641440571307300202670ustar00rootroot00000000000000 lcQPreferencesDialog 0 0 621 503 Preferences 0 General QFormLayout::ExpandingFieldsGrow Application Language: Language Default Czech Deutsch English Français Português Español Never Once a day Once a week Check for updates: checkForUpdates Qt::Horizontal 40 20 Color Theme: Language Dark System Default author name: authorName Fixed direction keys Open most recent file on startup Custom Paths Parts Library: partsLibrary :/resources/file_open.png:/resources/file_open.png :/resources/archive.png:/resources/archive.png Color Configuration: ColorConfigEdit ... Minifig Settings: MinifigSettingsEdit ... PO&V-Ray Executable: povrayExecutable ... &LGEO Library: lgeoPath ... Restore tab layout Rendering Contrast Settings... Wireframe Flat Shading Default Lights Plain Thin Lines Logo Outline Logo Sharp Top Logo Rounded Top Logo Flattened Logo High Contrast High Contrast with Logo Shading Mode: Qt::Horizontal 40 20 Stud Style Anti-aliasing 2x 4x 8x Highlight New Parts Mesh LOD 0 0 Qt::Horizontal QSlider::NoTicks Fade Previous Steps Lines Conditional Lines Qt::Horizontal 40 20 Line Width: 0 0 Qt::Horizontal QSlider::NoTicks Edge Lines Automate Edge Color Settings... Qt::Vertical 20 40 Views Model Views Axis Icon Location: View Sphere: Disabled Small Medium Large Top Left Top Right Bottom Left Bottom Right Qt::Horizontal 40 20 Location: Top Left Top Right Bottom Left Bottom Right Base Grid studs Qt::Horizontal 40 20 Draw lines every 75 16777215 Draw origin lines Draw studs Part Preview Axis Icon Top Left Top Right Bottom Left Bottom Right Location: Disabled Small Medium Large View Sphere: Qt::Horizontal 40 20 Qt::Vertical 20 40 Colors Interface Marquee Border: Inactive View Border: Camera Name: Marquee Fill: Overlay Color: Axis Icon Labels: Qt::Horizontal 40 20 Active View Border: Qt::Horizontal QSizePolicy::Fixed 20 20 View Sphere Color: Qt::Horizontal QSizePolicy::Fixed 20 20 Text Color: Qt::Horizontal QSizePolicy::Fixed 20 20 Highlight Color: Qt::Horizontal 40 20 Qt::Vertical 20 40 Grid Lines: Qt::Horizontal QSizePolicy::Fixed 20 20 Studs: Qt::Horizontal 40 20 Background Top Color: Qt::Horizontal QSizePolicy::Fixed 20 20 Bottom Color: Qt::Horizontal 40 20 So&lid Color &Gradient Qt::Horizontal 40 20 Objects Light: Qt::Horizontal QSizePolicy::Fixed 20 20 Focused: Control Point Focused: Control Point: Selected: Camera: Qt::Horizontal 40 20 Categories Parts Library Categories 0 0 Qt::Horizontal 1 0 false true false false Categories 2 0 QAbstractItemView::NoSelection false true false true 2 true Name Number Import... Export... Reset... Qt::Horizontal 40 20 Category New... Edit... Delete... Qt::Horizontal 40 20 Keyboard Keyboard Shortcuts true true Command Shortcut Search shortcuts Import... Export... Reset... Qt::Horizontal 40 20 Shortcut Key se&quence: shortcutEdit Assign Remove shortcutEdit label_7 shortcutAssign shortcutRemove Mouse Mouse Shortcuts false true Action Shortcut 1 Shortcut 2 Import... Export... Reset... Qt::Horizontal 40 20 Shortcut Button: None Left Middle Right Modifiers: Control Alt Shift Assign Remove Mouse sensitivity: 1 20 5 Qt::Horizontal Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok tabWidget partsLibrary partsLibraryBrowse partsArchiveBrowse ColorConfigEdit ColorConfigBrowseButton MinifigSettingsEdit MinifigSettingsBrowseButton povrayExecutable povrayExecutableBrowse lgeoPath lgeoPathBrowse ColorTheme Language checkForUpdates authorName fixedDirectionKeys autoLoadMostRecent RestoreTabLayout antiAliasing antiAliasingSamples FadeSteps FadeStepsColor HighlightNewParts HighlightNewPartsColor MeshLOD MeshLODSlider studStyleCombo HighContrastButton ShadingMode edgeLines ConditionalLinesCheckBox AutomateEdgeColor AutomateEdgeColorButton LineWidthSlider ViewSphereSizeCombo ViewSphereLocationCombo AxisIconCheckBox AxisIconLocationCombo gridStuds gridLines gridLineSpacing GridOriginCheckBox PreviewViewSphereSizeCombo PreviewViewSphereLocationCombo PreviewAxisIconCheckBox BackgroundSolidRadio BackgroundSolidColorButton BackgroundGradientRadio BackgroundGradient1ColorButton BackgroundGradient2ColorButton ObjectSelectedColorButton ObjectFocusedColorButton CameraColorButton LightColorButton ControlPointColorButton ControlPointFocusedColorButton ActiveViewColorButton InactiveViewColorButton TextColorButton AxesColorButton MarqueeBorderColorButton MarqueeFillColorButton OverlayColorButton gridLineColor gridStudColor ViewSphereColorButton ViewSphereTextColorButton ViewSphereHighlightColorButton categoriesTree partsTree importCategories exportCategories resetCategories newCategory editCategory deleteCategory commandList KeyboardFilterEdit shortcutsImport shortcutsExport shortcutsReset shortcutEdit shortcutAssign shortcutRemove mouseTree MouseImportButton MouseExportButton mouseReset mouseButton mouseControl mouseAlt mouseShift mouseAssign mouseRemove mouseSensitivity buttonBox accepted() lcQPreferencesDialog accept() 261 440 157 274 buttonBox rejected() lcQPreferencesDialog reject() 329 440 286 274 leocad-23.03/qt/lc_qpropertiesdialog.cpp000066400000000000000000000113621440571307300203220ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qpropertiesdialog.h" #include "ui_lc_qpropertiesdialog.h" #include "lc_qutils.h" #include "lc_colors.h" #include "lc_application.h" #include "pieceinf.h" class lcPartsTableWidgetItem : public QTableWidgetItem { public: explicit lcPartsTableWidgetItem(const QString& Text, int Type = QTableWidgetItem::Type) : QTableWidgetItem(Text, Type) { mLast = false; } bool operator<(const QTableWidgetItem& Other) const override { if (mLast) return false; if (((const lcPartsTableWidgetItem&)Other).mLast) return true; if (column() > 0) { int Count = text().toInt(); int OtherCount = Other.text().toInt(); return Count < OtherCount; } return QTableWidgetItem::operator<(Other); } bool mLast; }; lcQPropertiesDialog::lcQPropertiesDialog(QWidget* Parent, lcPropertiesDialogOptions* Options) : QDialog(Parent), mOptions(Options), ui(new Ui::lcQPropertiesDialog) { ui->setupUi(this); setWindowTitle(tr("%1 Properties").arg(mOptions->Properties.mFileName)); ui->DescriptionEdit->setText(mOptions->Properties.mDescription); ui->AuthorEdit->setText(mOptions->Properties.mAuthor); ui->CommentsEdit->setText(mOptions->Properties.mComments); const lcVector3 Dimensions = Options->BoundingBox.Max - Options->BoundingBox.Min; QString Format = tr("%1 x %2 x %3 cm\n%4 x %5 x %6 inches\n%7 x %8 x %9 LDU"); QString Measurements = Format.arg(QString::number(Dimensions.x * 0.04, 'f', 2), QString::number(Dimensions.y * 0.04, 'f', 2), QString::number(Dimensions.z * 0.04, 'f', 2), QString::number(Dimensions.x / 64.0, 'f', 2), QString::number(Dimensions.y / 64.0, 'f', 2), QString::number(Dimensions.z / 64.0, 'f', 2), QString::number(Dimensions.x, 'f', 2), QString::number(Dimensions.y, 'f', 2), QString::number(Dimensions.z, 'f', 2)); ui->MeasurementsLabel->setText(Measurements); const lcPartsList& PartsList = mOptions->PartsList; QStringList HorizontalLabels; std::vector ColorsUsed(gColorList.size()); for (const auto& PartIt : PartsList) for (const auto& ColorIt : PartIt.second) ColorsUsed[ColorIt.first] = true; std::vector ColorColumns(gColorList.size()); int ColorCount = 0; HorizontalLabels.append(tr("Part")); for (size_t ColorIndex = 0; ColorIndex < gColorList.size(); ColorIndex++) { if (ColorsUsed[ColorIndex]) { ColorColumns[ColorIndex] = ColorCount++; HorizontalLabels.append(gColorList[ColorIndex].Name); } } HorizontalLabels.append(tr("Total")); QTableWidget* PartsTable = ui->PartsTable; PartsTable->setColumnCount(ColorCount + 2); PartsTable->setRowCount((int)PartsList.size() + 1); PartsTable->setHorizontalHeaderLabels(HorizontalLabels); PartsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); std::vector InfoTotals(PartsList.size()); std::vector ColorTotals(ColorCount); int Row = 0, Total = 0; for (const auto& PartIt : PartsList) { PartsTable->setItem(Row, 0, new lcPartsTableWidgetItem(PartIt.first->m_strDescription)); for (const auto& ColorIt : PartIt.second) { int ColorIndex = ColorIt.first; int Count = ColorIt.second; lcPartsTableWidgetItem* Item = new lcPartsTableWidgetItem(QString::number(Count)); Item->setTextAlignment(Qt::AlignCenter); PartsTable->setItem(Row, ColorColumns[ColorIndex] + 1, Item); InfoTotals[Row] += Count; ColorTotals[ColorColumns[ColorIndex]] += Count; Total += Count; } for (int Column = 0; Column <= ColorCount; Column++) if (!PartsTable->item(Row, Column)) PartsTable->setItem(Row, Column, new lcPartsTableWidgetItem(QString())); Row++; } lcPartsTableWidgetItem* Item = new lcPartsTableWidgetItem(tr("Total")); Item->mLast = true; PartsTable->setItem((int)InfoTotals.size(), 0, Item); for (Row = 0; Row < (int)InfoTotals.size(); Row++) { Item = new lcPartsTableWidgetItem(QString::number(InfoTotals[Row])); Item->setTextAlignment(Qt::AlignCenter); PartsTable->setItem(Row, ColorCount + 1, Item); } for (int ColorIndex = 0; ColorIndex < ColorCount; ColorIndex++) { Item = new lcPartsTableWidgetItem(QString::number(ColorTotals[ColorIndex])); Item->mLast = true; Item->setTextAlignment(Qt::AlignCenter); PartsTable->setItem((int)InfoTotals.size(), ColorIndex + 1, Item); } Item = new lcPartsTableWidgetItem(QString::number(Total)); Item->mLast = true; Item->setTextAlignment(Qt::AlignCenter); PartsTable->setItem((int)InfoTotals.size(), ColorCount + 1, Item); } lcQPropertiesDialog::~lcQPropertiesDialog() { delete ui; } void lcQPropertiesDialog::accept() { mOptions->Properties.mDescription = ui->DescriptionEdit->text(); mOptions->Properties.mAuthor = ui->AuthorEdit->text(); mOptions->Properties.mComments = ui->CommentsEdit->toPlainText(); QDialog::accept(); } leocad-23.03/qt/lc_qpropertiesdialog.h000066400000000000000000000007531440571307300177710ustar00rootroot00000000000000#pragma once #include "lc_model.h" struct lcPropertiesDialogOptions { lcModelProperties Properties; lcPartsList PartsList; lcBoundingBox BoundingBox; }; namespace Ui { class lcQPropertiesDialog; } class lcQPropertiesDialog : public QDialog { Q_OBJECT public: lcQPropertiesDialog(QWidget* Parent, lcPropertiesDialogOptions* Options); ~lcQPropertiesDialog(); lcPropertiesDialogOptions* mOptions; public slots: void accept() override; private: Ui::lcQPropertiesDialog* ui; }; leocad-23.03/qt/lc_qpropertiesdialog.ui000066400000000000000000000112731440571307300201560ustar00rootroot00000000000000 lcQPropertiesDialog 0 0 500 442 Properties 0 0 0 Summary Author: Description: Comments: 0 0 false Measurements: Parts Used QAbstractItemView::NoEditTriggers true 75 true false Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok tabWidget buttonBox AuthorEdit DescriptionEdit CommentsEdit PartsTable buttonBox accepted() lcQPropertiesDialog accept() 257 352 157 274 buttonBox rejected() lcQPropertiesDialog reject() 325 352 286 274 leocad-23.03/qt/lc_qpropertiestree.cpp000066400000000000000000000767511440571307300200370ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qpropertiestree.h" #include "lc_qcolorpicker.h" #include "lc_application.h" #include "lc_model.h" #include "lc_mainwindow.h" #include "object.h" #include "piece.h" #include "camera.h" #include "light.h" #include "pieceinf.h" #include "lc_library.h" #include "lc_qutils.h" #include "lc_viewwidget.h" #include "lc_previewwidget.h" // Draw an icon indicating opened/closing branches static QIcon drawIndicatorIcon(const QPalette &palette, QStyle *style) { QPixmap pix(14, 14); pix.fill(Qt::transparent); QStyleOption branchOption; branchOption.rect = QRect(2, 2, 9, 9); // ### hardcoded in qcommonstyle.cpp branchOption.palette = palette; branchOption.state = QStyle::State_Children; QPainter p; // Draw closed state p.begin(&pix); style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p); p.end(); QIcon rc = pix; rc.addPixmap(pix, QIcon::Selected, QIcon::Off); // Draw opened state branchOption.state |= QStyle::State_Open; pix.fill(Qt::transparent); p.begin(&pix); style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p); p.end(); rc.addPixmap(pix, QIcon::Normal, QIcon::On); rc.addPixmap(pix, QIcon::Selected, QIcon::On); return rc; } static QIcon drawCheckBox(bool value) { QStyleOptionButton opt; opt.state |= value ? QStyle::State_On : QStyle::State_Off; opt.state |= QStyle::State_Enabled; const QStyle *style = QApplication::style(); // Figure out size of an indicator and make sure it is not scaled down in a list view item // by making the pixmap as big as a list view icon and centering the indicator in it. // (if it is smaller, it can't be helped) const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt); const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt); const int listViewIconSize = indicatorWidth; const int pixmapWidth = indicatorWidth; const int pixmapHeight = qMax(indicatorHeight, listViewIconSize); opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight); QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight); pixmap.fill(Qt::transparent); { // Center? const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0; const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0; QPainter painter(&pixmap); painter.translate(xoff, yoff); style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter); } return QIcon(pixmap); } int lcQPropertiesTreeDelegate::indentation(const QModelIndex &index) const { if (!m_treeWidget) return 0; QTreeWidgetItem *item = m_treeWidget->indexToItem(index); int indent = 0; while (item->parent()) { item = item->parent(); ++indent; } if (m_treeWidget->rootIsDecorated()) ++indent; return indent * m_treeWidget->indentation(); } void lcQPropertiesTreeDelegate::slotEditorDestroyed(QObject *object) { if (m_editedWidget == object) { m_editedWidget = nullptr; m_editedItem = nullptr; } } QWidget *lcQPropertiesTreeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &style, const QModelIndex &index) const { Q_UNUSED(style); if (index.column() == 1 && m_treeWidget) { QTreeWidgetItem *item = m_treeWidget->indexToItem(index); if (item && (item->flags() & Qt::ItemIsEnabled)) { QWidget *editor = m_treeWidget->createEditor(parent, item); if (editor) { editor->setAutoFillBackground(true); editor->installEventFilter(const_cast(this)); m_editedItem = item; m_editedWidget = editor; connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); return editor; } } } return nullptr; } void lcQPropertiesTreeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) editor->setGeometry(option.rect.adjusted(0, 0, 0, -1)); } void lcQPropertiesTreeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { bool hasValue = true; if (m_treeWidget) hasValue = m_treeWidget->indexToItem(index)->data(0, lcQPropertiesTree::PropertyTypeRole).toInt() != lcQPropertiesTree::PropertyGroup; QStyleOptionViewItem opt = option; opt.state &= ~QStyle::State_HasFocus; if (index.column() == 1 && m_treeWidget) { QTreeWidgetItem *item = m_treeWidget->indexToItem(index); if (m_editedItem && m_editedItem == item) m_disablePainting = true; } QItemDelegate::paint(painter, opt, index); if (option.type) m_disablePainting = false; opt.palette.setCurrentColorGroup(QPalette::Active); QColor color = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt)); painter->save(); painter->setPen(QPen(color)); if (!m_treeWidget || (!m_treeWidget->lastColumn(index.column()) && hasValue)) { int right = (option.direction == Qt::LeftToRight) ? option.rect.right() : option.rect.left(); painter->drawLine(right, option.rect.y(), right, option.rect.bottom()); } painter->restore(); } void lcQPropertiesTreeDelegate::drawDecoration(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QPixmap &pixmap) const { if (m_disablePainting) return; QItemDelegate::drawDecoration(painter, option, rect, pixmap); } void lcQPropertiesTreeDelegate::drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const { if (m_disablePainting) return; QItemDelegate::drawDisplay(painter, option, rect, text); } QSize lcQPropertiesTreeDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { return QItemDelegate::sizeHint(option, index) + QSize(3, 4); } bool lcQPropertiesTreeDelegate::eventFilter(QObject *object, QEvent *event) { if (event->type() == QEvent::FocusOut) { QFocusEvent *fe = static_cast(event); if (fe->reason() == Qt::ActiveWindowFocusReason) return false; } return QItemDelegate::eventFilter(object, event); } lcQPropertiesTree::lcQPropertiesTree(QWidget *parent) : QTreeWidget(parent) { setIconSize(QSize(18, 18)); setColumnCount(2); QStringList labels; labels.append(tr("Property")); labels.append(tr("Value")); setHeaderLabels(labels); header()->setSectionsMovable(false); header()->setSectionResizeMode(QHeaderView::ResizeToContents); header()->setVisible(false); setAlternatingRowColors(true); setRootIsDecorated(false); setEditTriggers(QAbstractItemView::EditKeyPressed); m_expandIcon = drawIndicatorIcon(palette(), style()); m_checkedIcon = drawCheckBox(true); m_uncheckedIcon = drawCheckBox(false); m_delegate = new lcQPropertiesTreeDelegate(parent); m_delegate->setTreeWidget(this); setItemDelegate(m_delegate); SetEmpty(); connect(header(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(resizeColumnToContents(int))); } QSize lcQPropertiesTree::sizeHint() const { return QSize(200, -1); } void lcQPropertiesTree::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; QTreeWidgetItem *item = itemFromIndex(index); if (item->data(0, lcQPropertiesTree::PropertyTypeRole).toInt() == lcQPropertiesTree::PropertyGroup) { const QColor c = option.palette.color(QPalette::Dark); painter->fillRect(option.rect, c); opt.palette.setColor(QPalette::AlternateBase, c); } QTreeWidget::drawRow(painter, opt, index); QColor color = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt)); painter->save(); painter->setPen(QPen(color)); painter->drawLine(opt.rect.x(), opt.rect.bottom(), opt.rect.right(), opt.rect.bottom()); painter->restore(); } void lcQPropertiesTree::keyPressEvent(QKeyEvent *event) { switch (event->key()) { case Qt::Key_Return: case Qt::Key_Enter: case Qt::Key_Space: // Trigger Edit if (!m_delegate->editedItem()) { if (const QTreeWidgetItem *item = currentItem()) { if (item->columnCount() >= 2 && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) { event->accept(); // If the current position is at column 0, move to 1. QModelIndex index = currentIndex(); if (index.column() == 0) { index = index.sibling(index.row(), 1); setCurrentIndex(index); } edit(index); return; } } } break; default: break; } QTreeWidget::keyPressEvent(event); } void lcQPropertiesTree::mousePressEvent(QMouseEvent *event) { QTreeWidget::mousePressEvent(event); QTreeWidgetItem *item = itemAt(event->pos()); if (item) { if ((item != m_delegate->editedItem()) && (event->button() == Qt::LeftButton) && (header()->logicalIndexAt(event->pos().x()) == 1) && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) editItem(item, 1); } } void lcQPropertiesTree::Update(const lcArray& Selection, lcObject* Focus) { lcPropertyWidgetMode Mode = LC_PROPERTY_WIDGET_EMPTY; if (Focus) { switch (Focus->GetType()) { case lcObjectType::Piece: Mode = LC_PROPERTY_WIDGET_PIECE; break; case lcObjectType::Camera: Mode = LC_PROPERTY_WIDGET_CAMERA; break; case lcObjectType::Light: Mode = LC_PROPERTY_WIDGET_LIGHT; break; } } else { for (int ObjectIdx = 0; ObjectIdx < Selection.GetSize(); ObjectIdx++) { switch (Selection[ObjectIdx]->GetType()) { case lcObjectType::Piece: if (Mode == LC_PROPERTY_WIDGET_EMPTY) Mode = LC_PROPERTY_WIDGET_PIECE; else if (Mode != LC_PROPERTY_WIDGET_PIECE) { Mode = LC_PROPERTY_WIDGET_MULTIPLE; ObjectIdx = Selection.GetSize(); } break; case lcObjectType::Camera: if (Mode != LC_PROPERTY_WIDGET_EMPTY) { Mode = LC_PROPERTY_WIDGET_MULTIPLE; ObjectIdx = Selection.GetSize(); } else { Mode = LC_PROPERTY_WIDGET_CAMERA; Focus = Selection[ObjectIdx]; } break; case lcObjectType::Light: if (Mode != LC_PROPERTY_WIDGET_EMPTY) { Mode = LC_PROPERTY_WIDGET_MULTIPLE; ObjectIdx = Selection.GetSize(); } else { Mode = LC_PROPERTY_WIDGET_LIGHT; Focus = Selection[ObjectIdx]; } break; } } } switch (Mode) { case LC_PROPERTY_WIDGET_EMPTY: SetEmpty(); break; case LC_PROPERTY_WIDGET_PIECE: SetPiece(Selection, Focus); break; case LC_PROPERTY_WIDGET_CAMERA: SetCamera(Focus); break; case LC_PROPERTY_WIDGET_LIGHT: SetLight(Focus); break; case LC_PROPERTY_WIDGET_MULTIPLE: SetMultiple(); break; } } class lcStepValidator : public QIntValidator { public: lcStepValidator(lcStep Min, lcStep Max, bool AllowEmpty) : QIntValidator(1, INT_MAX), mMin(Min), mMax(Max), mAllowEmpty(AllowEmpty) { } QValidator::State validate(QString& Input, int& Pos) const override { if (mAllowEmpty && Input.isEmpty()) return Acceptable; bool Ok; lcStep Step = Input.toUInt(&Ok); if (Ok) return (Step >= mMin && Step <= mMax) ? Acceptable : Invalid; return QIntValidator::validate(Input, Pos); } protected: lcStep mMin; lcStep mMax; bool mAllowEmpty; }; QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item) const { PropertyType propertyType = (PropertyType)item->data(0, lcQPropertiesTree::PropertyTypeRole).toInt(); switch (propertyType) { case PropertyGroup: return nullptr; case PropertyBool: { QCheckBox *editor = new QCheckBox(parent); bool value = item->data(0, PropertyValueRole).toBool(); editor->setChecked(value); connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotToggled(bool))); return editor; } case PropertyFloat: { QLineEdit *editor = new QLineEdit(parent); float value = item->data(0, PropertyValueRole).toFloat(); editor->setValidator(new QDoubleValidator(editor)); editor->setText(lcFormatValueLocalized(value)); connect(editor, SIGNAL(returnPressed()), this, SLOT(slotReturnPressed())); return editor; } case PropertyStep: { QLineEdit* Editor = new QLineEdit(parent); lcStep Value = item->data(0, PropertyValueRole).toUInt(); lcStep Show = partShow->data(0, PropertyValueRole).toUInt(); lcStep Hide = partHide->data(0, PropertyValueRole).toUInt(); if (Show && Hide) { if (item == partShow) Editor->setValidator(new lcStepValidator(1, Hide - 1, false)); else Editor->setValidator(new lcStepValidator(Show + 1, LC_STEP_MAX, true)); } else Editor->setValidator(new lcStepValidator(1, LC_STEP_MAX, item == partHide)); if (item != partHide || Value != LC_STEP_MAX) Editor->setText(QString::number(Value)); connect(Editor, SIGNAL(returnPressed()), this, SLOT(slotReturnPressed())); return Editor; } case PropertyString: { QLineEdit *editor = new QLineEdit(parent); QString value = item->data(0, PropertyValueRole).toString(); editor->setText(value); connect(editor, SIGNAL(returnPressed()), this, SLOT(slotReturnPressed())); return editor; } case PropertyColor: { QPushButton *editor = new QPushButton(parent); int value = item->data(0, PropertyValueRole).toInt(); updateColorEditor(editor, value); connect(editor, SIGNAL(clicked()), this, SLOT(slotColorButtonClicked())); return editor; } case PropertyPart: { QComboBox *editor = new QComboBox(parent); editor->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); editor->setMinimumContentsLength(1); lcPiecesLibrary* Library = lcGetPiecesLibrary(); std::vector SortedPieces; SortedPieces.reserve(Library->mPieces.size()); const lcModel* ActiveModel = gMainWindow->GetActiveModel(); for (const auto& PartIt : Library->mPieces) { PieceInfo* Info = PartIt.second; if (!Info->IsModel() || !Info->GetModel()->IncludesModel(ActiveModel)) SortedPieces.push_back(PartIt.second); } auto PieceCompare = [](PieceInfo* Info1, PieceInfo* Info2) { return strcmp(Info1->m_strDescription, Info2->m_strDescription) < 0; }; std::sort(SortedPieces.begin(), SortedPieces.end(), PieceCompare); for (PieceInfo* Info : SortedPieces) editor->addItem(Info->m_strDescription, QVariant::fromValue((void*)Info)); PieceInfo *info = (PieceInfo*)item->data(0, PropertyValueRole).value(); editor->setCurrentIndex(editor->findData(QVariant::fromValue((void*)info))); connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int))); return editor; } } return nullptr; } void lcQPropertiesTree::updateColorEditor(QPushButton *editor, int value) const { QImage img(12, 12, QImage::Format_ARGB32); img.fill(0); lcColor* color = &gColorList[value]; QPainter painter(&img); painter.setCompositionMode(QPainter::CompositionMode_Source); painter.setPen(Qt::darkGray); painter.setBrush(QColor::fromRgbF(color->Value[0], color->Value[1], color->Value[2])); painter.drawRect(0, 0, img.width() - 1, img.height() - 1); painter.end(); editor->setStyleSheet("Text-align:left"); editor->setIcon(QPixmap::fromImage(img)); editor->setText(color->Name); } void lcQPropertiesTree::slotToggled(bool Value) { QTreeWidgetItem* Item = m_delegate->editedItem(); lcModel* Model = gMainWindow->GetActiveModel(); if (mWidgetMode == LC_PROPERTY_WIDGET_CAMERA) { lcObject* Focus = Model->GetFocusObject(); if (Focus && Focus->IsCamera()) { lcCamera* Camera = (lcCamera*)Focus; if (Item == cameraOrtho) { Model->SetCameraOrthographic(Camera, Value); } } } } void lcQPropertiesTree::slotReturnPressed() { QLineEdit* Editor = (QLineEdit*)sender(); QTreeWidgetItem* Item = m_delegate->editedItem(); lcModel* Model = gMainWindow->GetActiveModel(); if (mWidgetMode == LC_PROPERTY_WIDGET_PIECE) { lcPiece* Piece = (mFocus && mFocus->IsPiece()) ? (lcPiece*)mFocus : nullptr; if (Item == partPositionX || Item == partPositionY || Item == partPositionZ) { lcVector3 Center; lcMatrix33 RelativeRotation; Model->GetMoveRotateTransform(Center, RelativeRotation); lcVector3 Position = Center; float Value = lcParseValueLocalized(Editor->text()); if (Item == partPositionX) Position[0] = Value; else if (Item == partPositionY) Position[1] = Value; else if (Item == partPositionZ) Position[2] = Value; lcVector3 Distance = Position - Center; Model->MoveSelectedObjects(Distance, Distance, false, false, true, true); } else if (Item == partRotationX || Item == partRotationY || Item == partRotationZ) { lcVector3 InitialRotation; if (Piece) InitialRotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD; else InitialRotation = lcVector3(0.0f, 0.0f, 0.0f); lcVector3 Rotation = InitialRotation; float Value = lcParseValueLocalized(Editor->text()); if (Item == partRotationX) Rotation[0] = Value; else if (Item == partRotationY) Rotation[1] = Value; else if (Item == partRotationZ) Rotation[2] = Value; Model->RotateSelectedPieces(Rotation - InitialRotation, true, false, true, true); } else if (Item == partShow) { bool Ok = false; lcStep Step = Editor->text().toUInt(&Ok); if (Ok) Model->SetSelectedPiecesStepShow(Step); } else if (Item == partHide) { QString Text = Editor->text(); if (Text.isEmpty()) Model->SetSelectedPiecesStepHide(LC_STEP_MAX); else { bool Ok = false; lcStep Step = Text.toUInt(&Ok); if (Ok) Model->SetSelectedPiecesStepHide(Step); } } } else if (mWidgetMode == LC_PROPERTY_WIDGET_CAMERA) { lcCamera* Camera = (mFocus && mFocus->IsCamera()) ? (lcCamera*)mFocus : nullptr; if (Camera) { if (Item == cameraPositionX || Item == cameraPositionY || Item == cameraPositionZ) { lcVector3 Center = Camera->mPosition; lcVector3 Position = Center; float Value = lcParseValueLocalized(Editor->text()); if (Item == cameraPositionX) Position[0] = Value; else if (Item == cameraPositionY) Position[1] = Value; else if (Item == cameraPositionZ) Position[2] = Value; lcVector3 Distance = Position - Center; Model->MoveSelectedObjects(Distance, Distance, false, false, true, true); } else if (Item == cameraTargetX || Item == cameraTargetY || Item == cameraTargetZ) { lcVector3 Center = Camera->mTargetPosition; lcVector3 Position = Center; float Value = lcParseValueLocalized(Editor->text()); if (Item == cameraTargetX) Position[0] = Value; else if (Item == cameraTargetY) Position[1] = Value; else if (Item == cameraTargetZ) Position[2] = Value; lcVector3 Distance = Position - Center; Model->MoveSelectedObjects(Distance, Distance, false, false, true, true); } else if (Item == cameraUpX || Item == cameraUpY || Item == cameraUpZ) { lcVector3 Center = Camera->mUpVector; lcVector3 Position = Center; float Value = lcParseValueLocalized(Editor->text()); if (Item == cameraUpX) Position[0] = Value; else if (Item == cameraUpY) Position[1] = Value; else if (Item == cameraUpZ) Position[2] = Value; lcVector3 Distance = Position - Center; Model->MoveSelectedObjects(Distance, Distance, false, false, true, true); } else if (Item == cameraFOV) { float Value = lcParseValueLocalized(Editor->text()); Model->SetCameraFOV(Camera, Value); } else if (Item == cameraNear) { float Value = lcParseValueLocalized(Editor->text()); Model->SetCameraZNear(Camera, Value); } else if (Item == cameraFar) { float Value = lcParseValueLocalized(Editor->text()); Model->SetCameraZFar(Camera, Value); } else if (Item == cameraName) { QString Value = Editor->text(); Model->SetCameraName(Camera, Value); } } } } void lcQPropertiesTree::slotSetValue(int Value) { QTreeWidgetItem* Item = m_delegate->editedItem(); lcModel* Model = gMainWindow->GetActiveModel(); if (mWidgetMode == LC_PROPERTY_WIDGET_PIECE) { if (Item == partColor) { Model->SetSelectedPiecesColorIndex(Value); QPushButton *editor = (QPushButton*)m_delegate->editor(); updateColorEditor(editor, Value); } else if (Item == partID) { QComboBox *editor = (QComboBox*)sender(); PieceInfo* Info = (PieceInfo*)editor->itemData(Value).value(); Model->SetSelectedPiecesPieceInfo(Info); int ColorIndex = gDefaultColor; lcObject* Focus = gMainWindow->GetActiveModel()->GetFocusObject(); if (Focus && Focus->IsPiece()) ColorIndex = ((lcPiece*)Focus)->GetColorIndex(); quint32 ColorCode = lcGetColorCode(ColorIndex); gMainWindow->PreviewPiece(Info->mFileName, ColorCode, false); } } } void lcQPropertiesTree::slotColorButtonClicked() { int ColorIndex = gDefaultColor; lcObject* Focus = gMainWindow->GetActiveModel()->GetFocusObject(); if (Focus && Focus->IsPiece()) ColorIndex = ((lcPiece*)Focus)->GetColorIndex(); QWidget* Button = (QWidget*)sender(); if (!Button) return; lcQColorPickerPopup* Popup = new lcQColorPickerPopup(Button, ColorIndex); connect(Popup, SIGNAL(selected(int)), SLOT(slotSetValue(int))); Popup->setMinimumSize(qMax(300, width()), qMax(200, static_cast(width() * 2 / 3))); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QScreen* Screen = Button->screen(); const QRect ScreenRect = Screen ? Screen->geometry() : QRect(); #elif (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) QScreen* Screen = QGuiApplication::screenAt(Button->mapToGlobal(Button->rect().bottomLeft())); const QRect ScreenRect = Screen ? Screen->geometry() : QApplication::desktop()->geometry(); #else const QRect ScreenRect = QApplication::desktop()->geometry(); #endif int x = mapToGlobal(QPoint(0, 0)).x(); int y = Button->mapToGlobal(Button->rect().bottomLeft()).y(); if (x < ScreenRect.left()) x = ScreenRect.left(); if (y < ScreenRect.top()) y = ScreenRect.top(); if (x + Popup->width() > ScreenRect.right()) x = ScreenRect.right() - Popup->width(); if (y + Popup->height() > ScreenRect.bottom()) y = ScreenRect.bottom() - Popup->height(); Popup->move(QPoint(x, y)); Popup->setFocus(); Popup->show(); } QTreeWidgetItem *lcQPropertiesTree::addProperty(QTreeWidgetItem *parent, const QString& label, PropertyType propertyType) { QTreeWidgetItem *newItem; if (parent) newItem = new QTreeWidgetItem(parent, QStringList(label)); else newItem = new QTreeWidgetItem(this, QStringList(label)); newItem->setData(0, PropertyTypeRole, QVariant(propertyType)); newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); newItem->setExpanded(true); if (propertyType == PropertyGroup) { newItem->setFirstColumnSpanned(true); newItem->setIcon(0, m_expandIcon); } return newItem; } void lcQPropertiesTree::SetEmpty() { clear(); partPosition = nullptr; partPositionX = nullptr; partPositionY = nullptr; partPositionZ = nullptr; partRotation = nullptr; partRotationX = nullptr; partRotationY = nullptr; partRotationZ = nullptr; partVisibility = nullptr; partShow = nullptr; partHide = nullptr; partAppearance = nullptr; partColor = nullptr; partID = nullptr; cameraPosition = nullptr; cameraPositionX = nullptr; cameraPositionY = nullptr; cameraPositionZ = nullptr; cameraTarget = nullptr; cameraTargetX = nullptr; cameraTargetY = nullptr; cameraTargetZ = nullptr; cameraUp = nullptr; cameraUpX = nullptr; cameraUpY = nullptr; cameraUpZ = nullptr; cameraSettings = nullptr; cameraOrtho = nullptr; cameraFOV = nullptr; cameraNear = nullptr; cameraFar = nullptr; cameraName = nullptr; mWidgetMode = LC_PROPERTY_WIDGET_EMPTY; mFocus = nullptr; } void lcQPropertiesTree::SetPiece(const lcArray& Selection, lcObject* Focus) { if (mWidgetMode != LC_PROPERTY_WIDGET_PIECE) { SetEmpty(); partPosition = addProperty(nullptr, tr("Position"), PropertyGroup); partPositionX = addProperty(partPosition, tr("X"), PropertyFloat); partPositionY = addProperty(partPosition, tr("Y"), PropertyFloat); partPositionZ = addProperty(partPosition, tr("Z"), PropertyFloat); partRotation = addProperty(nullptr, tr("Rotation"), PropertyGroup); partRotationX = addProperty(partRotation, tr("X"), PropertyFloat); partRotationY = addProperty(partRotation, tr("Y"), PropertyFloat); partRotationZ = addProperty(partRotation, tr("Z"), PropertyFloat); partVisibility = addProperty(nullptr, tr("Visible Steps"), PropertyGroup); partShow = addProperty(partVisibility, tr("Show"), PropertyStep); partHide = addProperty(partVisibility, tr("Hide"), PropertyStep); partAppearance = addProperty(nullptr, tr("Appearance"), PropertyGroup); partColor = addProperty(partAppearance, tr("Color"), PropertyColor); partID = addProperty(partAppearance, tr("Part"), PropertyPart); mWidgetMode = LC_PROPERTY_WIDGET_PIECE; } lcModel* Model = gMainWindow->GetActiveModel(); lcPiece* Piece = (Focus && Focus->IsPiece()) ? (lcPiece*)Focus : nullptr; mFocus = Piece; lcVector3 Position; lcMatrix33 RelativeRotation; Model->GetMoveRotateTransform(Position, RelativeRotation); partPositionX->setText(1, lcFormatValueLocalized(Position[0])); partPositionX->setData(0, PropertyValueRole, Position[0]); partPositionY->setText(1, lcFormatValueLocalized(Position[1])); partPositionY->setData(0, PropertyValueRole, Position[1]); partPositionZ->setText(1, lcFormatValueLocalized(Position[2])); partPositionZ->setData(0, PropertyValueRole, Position[2]); lcVector3 Rotation; if (Piece) Rotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD; else Rotation = lcVector3(0.0f, 0.0f, 0.0f); partRotationX->setText(1, lcFormatValueLocalized(Rotation[0])); partRotationX->setData(0, PropertyValueRole, Rotation[0]); partRotationY->setText(1, lcFormatValueLocalized(Rotation[1])); partRotationY->setData(0, PropertyValueRole, Rotation[1]); partRotationZ->setText(1, lcFormatValueLocalized(Rotation[2])); partRotationZ->setData(0, PropertyValueRole, Rotation[2]); lcStep Show = 0; lcStep Hide = 0; int ColorIndex = gDefaultColor; PieceInfo* Info = nullptr; if (Piece) { Show = Piece->GetStepShow(); Hide = Piece->GetStepHide(); ColorIndex = Piece->GetColorIndex(); Info = Piece->mPieceInfo; quint32 ColorCode = lcGetColorCode(ColorIndex); gMainWindow->PreviewPiece(Info->mFileName, ColorCode, false); } else { bool FirstPiece = true; for (int ObjectIdx = 0; ObjectIdx < Selection.GetSize(); ObjectIdx++) { lcObject* Object = Selection[ObjectIdx]; if (!Object->IsPiece()) continue; lcPiece* SelectedPiece = (lcPiece*)Object; if (FirstPiece) { Show = SelectedPiece->GetStepShow(); Hide = SelectedPiece->GetStepHide(); ColorIndex = SelectedPiece->GetColorIndex(); Info = SelectedPiece->mPieceInfo; FirstPiece = false; } else { if (SelectedPiece->GetStepShow() != Show) Show = 0; if (SelectedPiece->GetStepHide() != Hide) Hide = 0; if (SelectedPiece->GetColorIndex() != ColorIndex) ColorIndex = gDefaultColor; if (SelectedPiece->mPieceInfo != Info) Info = nullptr; } } } partShow->setText(1, QString::number(Show)); partShow->setData(0, PropertyValueRole, Show); partHide->setText(1, Hide == LC_STEP_MAX ? QString() : QString::number(Hide)); partHide->setData(0, PropertyValueRole, Hide); QImage img(16, 16, QImage::Format_ARGB32); img.fill(0); lcColor* color = &gColorList[ColorIndex]; QPainter painter(&img); painter.setCompositionMode(QPainter::CompositionMode_Source); painter.setPen(Qt::darkGray); painter.setBrush(QColor::fromRgbF(color->Value[0], color->Value[1], color->Value[2])); painter.drawRect(0, 0, img.width() - 1, img.height() - 1); painter.end(); partColor->setIcon(1, QIcon(QPixmap::fromImage(img))); partColor->setText(1, color->Name); partColor->setData(0, PropertyValueRole, ColorIndex); QString text = Info ? Info->m_strDescription : QString(); partID->setText(1, text); partID->setToolTip(1, text); partID->setData(0, PropertyValueRole, QVariant::fromValue((void*)Info)); } void lcQPropertiesTree::SetCamera(lcObject* Focus) { if (mWidgetMode != LC_PROPERTY_WIDGET_CAMERA) { SetEmpty(); cameraPosition = addProperty(nullptr, tr("Position"), PropertyGroup); cameraPositionX = addProperty(cameraPosition, tr("X"), PropertyFloat); cameraPositionY = addProperty(cameraPosition, tr("Y"), PropertyFloat); cameraPositionZ = addProperty(cameraPosition, tr("Z"), PropertyFloat); cameraTarget = addProperty(nullptr, tr("Target"), PropertyGroup); cameraTargetX = addProperty(cameraTarget, tr("X"), PropertyFloat); cameraTargetY = addProperty(cameraTarget, tr("Y"), PropertyFloat); cameraTargetZ = addProperty(cameraTarget, tr("Z"), PropertyFloat); cameraUp = addProperty(nullptr, tr("Up"), PropertyGroup); cameraUpX = addProperty(cameraUp, tr("X"), PropertyFloat); cameraUpY = addProperty(cameraUp, tr("Y"), PropertyFloat); cameraUpZ = addProperty(cameraUp, tr("Z"), PropertyFloat); cameraSettings = addProperty(nullptr, tr("Up"), PropertyGroup); cameraOrtho = addProperty(cameraSettings, tr("Orthographic"), PropertyBool); cameraFOV = addProperty(cameraSettings, tr("FOV"), PropertyFloat); cameraNear = addProperty(cameraSettings, tr("Near"), PropertyFloat); cameraFar = addProperty(cameraSettings, tr("Far"), PropertyFloat); cameraName = addProperty(cameraSettings, tr("Name"), PropertyString); mWidgetMode = LC_PROPERTY_WIDGET_CAMERA; } lcCamera* Camera = (Focus && Focus->IsCamera()) ? (lcCamera*)Focus : nullptr; mFocus = Camera; lcVector3 Position(0.0f, 0.0f, 0.0f); lcVector3 Target(0.0f, 0.0f, 0.0f); lcVector3 UpVector(0.0f, 0.0f, 0.0f); bool Ortho = false; float FoV = 60.0f; float ZNear = 1.0f; float ZFar = 100.0f; QString Name; if (Camera) { Position = Camera->mPosition; Target = Camera->mTargetPosition; UpVector = Camera->mUpVector; Ortho = Camera->IsOrtho(); FoV = Camera->m_fovy; ZNear = Camera->m_zNear; ZFar = Camera->m_zFar; Name = Camera->GetName(); } cameraPositionX->setText(1, lcFormatValueLocalized(Position[0])); cameraPositionX->setData(0, PropertyValueRole, Position[0]); cameraPositionY->setText(1, lcFormatValueLocalized(Position[1])); cameraPositionY->setData(0, PropertyValueRole, Position[1]); cameraPositionZ->setText(1, lcFormatValueLocalized(Position[2])); cameraPositionZ->setData(0, PropertyValueRole, Position[2]); cameraTargetX->setText(1, lcFormatValueLocalized(Target[0])); cameraTargetX->setData(0, PropertyValueRole, Target[0]); cameraTargetY->setText(1, lcFormatValueLocalized(Target[1])); cameraTargetY->setData(0, PropertyValueRole, Target[1]); cameraTargetZ->setText(1, lcFormatValueLocalized(Target[2])); cameraTargetZ->setData(0, PropertyValueRole, Target[2]); cameraUpX->setText(1, lcFormatValueLocalized(UpVector[0])); cameraUpX->setData(0, PropertyValueRole, UpVector[0]); cameraUpY->setText(1, lcFormatValueLocalized(UpVector[1])); cameraUpY->setData(0, PropertyValueRole, UpVector[1]); cameraUpZ->setText(1, lcFormatValueLocalized(UpVector[2])); cameraUpZ->setData(0, PropertyValueRole, UpVector[2]); cameraOrtho->setText(1, Ortho ? "True" : "False"); cameraOrtho->setData(0, PropertyValueRole, Ortho); cameraFOV->setText(1, lcFormatValueLocalized(FoV)); cameraFOV->setData(0, PropertyValueRole, FoV); cameraNear->setText(1, lcFormatValueLocalized(ZNear)); cameraNear->setData(0, PropertyValueRole, ZNear); cameraFar->setText(1, lcFormatValueLocalized(ZFar)); cameraFar->setData(0, PropertyValueRole, ZFar); cameraName->setText(1, Name); cameraName->setData(0, PropertyValueRole, Name); } void lcQPropertiesTree::SetLight(lcObject* Focus) { Q_UNUSED(Focus); SetEmpty(); mFocus = nullptr; // todo: light properties } void lcQPropertiesTree::SetMultiple() { if (mWidgetMode != LC_PROPERTY_WIDGET_MULTIPLE) { SetEmpty(); addProperty(nullptr, tr("Multiple Objects Selected"), PropertyGroup); mWidgetMode = LC_PROPERTY_WIDGET_MULTIPLE; } mFocus = nullptr; } bool lcQPropertiesTree::lastColumn(int column) const { return header()->visualIndex(column) == columnCount() - 1; } leocad-23.03/qt/lc_qpropertiestree.h000066400000000000000000000106071440571307300174700ustar00rootroot00000000000000#pragma once #include "lc_array.h" struct lcPartProperties; class lcQPropertiesTreeDelegate; enum lcPropertyWidgetMode { LC_PROPERTY_WIDGET_EMPTY, LC_PROPERTY_WIDGET_PIECE, LC_PROPERTY_WIDGET_CAMERA, LC_PROPERTY_WIDGET_LIGHT, LC_PROPERTY_WIDGET_MULTIPLE }; class lcQPropertiesTree : public QTreeWidget { Q_OBJECT public: lcQPropertiesTree(QWidget *parent = 0); QSize sizeHint() const override; QTreeWidgetItem *indexToItem(const QModelIndex &index) const { return itemFromIndex(index); } void Update(const lcArray& Selection, lcObject* Focus); QWidget *createEditor(QWidget *parent, QTreeWidgetItem *item) const; bool lastColumn(int column) const; enum { PropertyTypeRole = Qt::UserRole, PropertyValueRole }; enum PropertyType { PropertyGroup, PropertyBool, PropertyFloat, PropertyStep, PropertyString, PropertyColor, PropertyPart }; protected slots: void slotToggled(bool value); void slotReturnPressed(); void slotSetValue(int value); void slotColorButtonClicked(); protected: void keyPressEvent(QKeyEvent *event) override; void mousePressEvent(QMouseEvent *event) override; void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void updateColorEditor(QPushButton *editor, int value) const; QTreeWidgetItem *addProperty(QTreeWidgetItem *parent, const QString& label, PropertyType propertyType); void SetEmpty(); void SetPiece(const lcArray& Selection, lcObject* Focus); void SetCamera(lcObject* Focus); void SetLight(lcObject* Focus); void SetMultiple(); void getPartProperties(lcPartProperties *properties); lcPropertyWidgetMode mWidgetMode; lcObject* mFocus; lcQPropertiesTreeDelegate *m_delegate; QIcon m_expandIcon; QIcon m_checkedIcon; QIcon m_uncheckedIcon; QTreeWidgetItem *partPosition; QTreeWidgetItem *partPositionX; QTreeWidgetItem *partPositionY; QTreeWidgetItem *partPositionZ; QTreeWidgetItem *partRotation; QTreeWidgetItem *partRotationX; QTreeWidgetItem *partRotationY; QTreeWidgetItem *partRotationZ; QTreeWidgetItem *partVisibility; QTreeWidgetItem *partShow; QTreeWidgetItem *partHide; QTreeWidgetItem *partAppearance; QTreeWidgetItem *partColor; QTreeWidgetItem *partID; QTreeWidgetItem *cameraPosition; QTreeWidgetItem *cameraPositionX; QTreeWidgetItem *cameraPositionY; QTreeWidgetItem *cameraPositionZ; QTreeWidgetItem *cameraTarget; QTreeWidgetItem *cameraTargetX; QTreeWidgetItem *cameraTargetY; QTreeWidgetItem *cameraTargetZ; QTreeWidgetItem *cameraUp; QTreeWidgetItem *cameraUpX; QTreeWidgetItem *cameraUpY; QTreeWidgetItem *cameraUpZ; QTreeWidgetItem *cameraSettings; QTreeWidgetItem *cameraOrtho; QTreeWidgetItem *cameraFOV; QTreeWidgetItem *cameraNear; QTreeWidgetItem *cameraFar; QTreeWidgetItem *cameraName; }; class lcQPropertiesTreeDelegate : public QItemDelegate { Q_OBJECT public: lcQPropertiesTreeDelegate(QObject *parent = 0) : QItemDelegate(parent), m_treeWidget(0), m_editedItem(0), m_editedWidget(0), m_disablePainting(false) {} void setTreeWidget(lcQPropertiesTree *treeWidget) { m_treeWidget = treeWidget; } QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setModelData(QWidget *, QAbstractItemModel *, const QModelIndex &) const override {} void setEditorData(QWidget *, const QModelIndex &) const override {} bool eventFilter(QObject *object, QEvent *event) override; QTreeWidgetItem *editedItem() const { return m_editedItem; } QWidget *editor() const { return m_editedWidget; } protected: void drawDecoration(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QPixmap &pixmap) const override; void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const override; private slots: void slotEditorDestroyed(QObject *object); private: int indentation(const QModelIndex &index) const; lcQPropertiesTree *m_treeWidget; mutable QTreeWidgetItem *m_editedItem; mutable QWidget *m_editedWidget; mutable bool m_disablePainting; }; leocad-23.03/qt/lc_qselectdialog.cpp000066400000000000000000000122071440571307300174040ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qselectdialog.h" #include "ui_lc_qselectdialog.h" #include "lc_application.h" #include "lc_model.h" #include "piece.h" #include "camera.h" #include "light.h" #include "group.h" lcQSelectDialog::lcQSelectDialog(QWidget* Parent, lcModel* Model) : QDialog(Parent), ui(new Ui::lcQSelectDialog) { ui->setupUi(this); AddChildren(ui->treeWidget->invisibleRootItem(), nullptr, Model); ui->treeWidget->expandAll(); connect(ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(itemChanged(QTreeWidgetItem*, int))); } lcQSelectDialog::~lcQSelectDialog() { delete ui; } void lcQSelectDialog::accept() { mObjects.RemoveAll(); QList Items; Items.append(ui->treeWidget->invisibleRootItem()); while (!Items.isEmpty()) { QTreeWidgetItem* Item = Items[0]; Items.removeFirst(); if (!Item->childCount()) { if (Item->checkState(0) == Qt::Checked) { lcObject* Object = (lcObject*)Item->data(0, IndexRole).value(); mObjects.Add(Object); } } else { for (int ChildIdx = 0; ChildIdx < Item->childCount(); ChildIdx++) Items.append(Item->child(ChildIdx)); } } QDialog::accept(); } void lcQSelectDialog::on_selectAll_clicked() { ui->treeWidget->blockSignals(true); QList Items; Items.append(ui->treeWidget->invisibleRootItem()); while (!Items.isEmpty()) { QTreeWidgetItem* Item = Items[0]; Items.removeFirst(); if (!Item->childCount()) Item->setCheckState(0, Qt::Checked); else { for (int ChildIdx = 0; ChildIdx < Item->childCount(); ChildIdx++) Items.append(Item->child(ChildIdx)); } } ui->treeWidget->blockSignals(false); } void lcQSelectDialog::on_selectNone_clicked() { ui->treeWidget->blockSignals(true); QList Items; Items.append(ui->treeWidget->invisibleRootItem()); while (!Items.isEmpty()) { QTreeWidgetItem* Item = Items[0]; Items.removeFirst(); if (!Item->childCount()) Item->setCheckState(0, Qt::Unchecked); else { for (int ChildIdx = 0; ChildIdx < Item->childCount(); ChildIdx++) Items.append(Item->child(ChildIdx)); } } ui->treeWidget->blockSignals(false); } void lcQSelectDialog::on_selectInvert_clicked() { ui->treeWidget->blockSignals(true); QList Items; Items.append(ui->treeWidget->invisibleRootItem()); while (!Items.isEmpty()) { QTreeWidgetItem* Item = Items[0]; Items.removeFirst(); if (!Item->childCount()) Item->setCheckState(0, Item->checkState(0) == Qt::Checked ? Qt::Unchecked : Qt::Checked); else { for (int ChildIdx = 0; ChildIdx < Item->childCount(); ChildIdx++) Items.append(Item->child(ChildIdx)); } } ui->treeWidget->blockSignals(false); } void lcQSelectDialog::itemChanged(QTreeWidgetItem *item, int column) { Q_UNUSED(column); QTreeWidgetItem* ParentItem = item->parent(); if (!ParentItem) return; Qt::CheckState State = item->checkState(0); for (;;) { QTreeWidgetItem* ParentParentItem = ParentItem->parent(); if (ParentParentItem) ParentItem = ParentParentItem; else break; } ui->treeWidget->blockSignals(true); QList Items; Items.append(ParentItem); while (!Items.isEmpty()) { QTreeWidgetItem* Item = Items[0]; Items.removeFirst(); if (!Item->childCount()) Item->setCheckState(0, State); else { for (int ChildIdx = 0; ChildIdx < Item->childCount(); ChildIdx++) Items.append(Item->child(ChildIdx)); } } ui->treeWidget->blockSignals(false); } void lcQSelectDialog::AddChildren(QTreeWidgetItem* ParentItem, lcGroup* ParentGroup, lcModel* Model) { const lcArray& Groups = Model->GetGroups(); for (lcGroup* Group : Groups) { if (Group->mGroup != ParentGroup) continue; QTreeWidgetItem* GroupItem = new QTreeWidgetItem(ParentItem, QStringList(Group->mName)); AddChildren(GroupItem, Group, Model); } const lcArray& Pieces = Model->GetPieces(); lcStep currentStep = Model->GetCurrentStep(); for (lcPiece* Piece : Pieces) { if (Piece->GetGroup() != ParentGroup || !Piece->IsVisible(currentStep)) continue; QTreeWidgetItem* PieceItem = new QTreeWidgetItem(ParentItem, QStringList(Piece->GetName())); PieceItem->setData(0, IndexRole, QVariant::fromValue((uintptr_t)Piece)); PieceItem->setCheckState(0, Piece->IsSelected() ? Qt::Checked : Qt::Unchecked); } if (!ParentGroup) { const lcArray& Cameras = Model->GetCameras(); for (lcCamera* Camera : Cameras) { if (!Camera->IsVisible()) continue; QTreeWidgetItem *cameraItem = new QTreeWidgetItem(ParentItem, QStringList(Camera->GetName())); cameraItem->setData(0, IndexRole, QVariant::fromValue((uintptr_t)Camera)); cameraItem->setCheckState(0, Camera->IsSelected() ? Qt::Checked : Qt::Unchecked); } const lcArray& Lights = Model->GetLights(); for (lcLight* Light : Lights) { if (!Light->IsVisible()) continue; QTreeWidgetItem *lightItem = new QTreeWidgetItem(ParentItem, QStringList(Light->GetName())); lightItem->setData(0, IndexRole, QVariant::fromValue((uintptr_t)Light)); lightItem->setCheckState(0, Light->IsSelected() ? Qt::Checked : Qt::Unchecked); } } } leocad-23.03/qt/lc_qselectdialog.h000066400000000000000000000011511440571307300170450ustar00rootroot00000000000000#pragma once #include #include "lc_array.h" namespace Ui { class lcQSelectDialog; } class lcQSelectDialog : public QDialog { Q_OBJECT public: lcQSelectDialog(QWidget* Parent, lcModel* Model); ~lcQSelectDialog(); lcArray mObjects; enum { IndexRole = Qt::UserRole }; public slots: void accept() override; void on_selectAll_clicked(); void on_selectNone_clicked(); void on_selectInvert_clicked(); void itemChanged(QTreeWidgetItem *item, int column); private: Ui::lcQSelectDialog *ui; void AddChildren(QTreeWidgetItem* ParentItem, lcGroup* ParentGroup, lcModel* Model); }; leocad-23.03/qt/lc_qselectdialog.ui000066400000000000000000000044441440571307300172430ustar00rootroot00000000000000 lcQSelectDialog 0 0 450 350 Select Objects false 1 All None Invert Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() lcQSelectDialog accept() 248 254 157 274 buttonBox rejected() lcQSelectDialog reject() 316 260 286 274 leocad-23.03/qt/lc_qupdatedialog.cpp000066400000000000000000000073501440571307300174120ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qupdatedialog.h" #include "ui_lc_qupdatedialog.h" #include "lc_application.h" #include "lc_library.h" #include "lc_profile.h" #include "lc_http.h" void lcDoInitialUpdateCheck() { int updateFrequency = lcGetProfileInt(LC_PROFILE_CHECK_UPDATES); if (updateFrequency == 0) return; QSettings settings; QDateTime CheckTime = settings.value("Updates/LastCheck", QDateTime()).toDateTime(); if (!CheckTime.isNull()) { QDateTime NextCheckTime = CheckTime.addDays(updateFrequency == 1 ? 1 : 7); if (NextCheckTime > QDateTime::currentDateTimeUtc()) return; } new lcQUpdateDialog(nullptr, true); } lcQUpdateDialog::lcQUpdateDialog(QWidget* Parent, bool InitialUpdate) : QDialog(Parent), ui(new Ui::lcQUpdateDialog), mInitialUpdate(InitialUpdate) { ui->setupUi(this); connect(this, SIGNAL(finished(int)), this, SLOT(finished(int))); ui->status->setText(tr("Connecting to update server...")); mHttpManager = new lcHttpManager(this); connect(mHttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), this, SLOT(DownloadFinished(lcHttpReply*))); mHttpManager->DownloadFile(QLatin1String("https://www.leocad.org/updates.txt")); } lcQUpdateDialog::~lcQUpdateDialog() { delete ui; } void lcQUpdateDialog::accept() { QSettings settings; settings.setValue("Updates/IgnoreVersion", versionData); QDialog::accept(); } void lcQUpdateDialog::reject() { QDialog::reject(); } void lcQUpdateDialog::finished(int result) { Q_UNUSED(result); if (mInitialUpdate) deleteLater(); } void lcQUpdateDialog::DownloadFinished(lcHttpReply *reply) { bool updateAvailable = false; if (reply->error() == QNetworkReply::NoError) { int majorVersion, minorVersion, patchVersion; int parts; versionData = reply->readAll(); const char *update = versionData; QSettings settings; QByteArray ignoreUpdate = settings.value("Updates/IgnoreVersion", QByteArray()).toByteArray(); if (mInitialUpdate && ignoreUpdate == versionData) { updateAvailable = false; } else if (sscanf(update, "%d.%d.%d %d", &majorVersion, &minorVersion, &patchVersion, &parts) == 4) { QString status; if (majorVersion > LC_VERSION_MAJOR) updateAvailable = true; else if (majorVersion == LC_VERSION_MAJOR) { if (minorVersion > LC_VERSION_MINOR) updateAvailable = true; else if (minorVersion == LC_VERSION_MINOR) { if (patchVersion > LC_VERSION_PATCH) updateAvailable = true; } } if (updateAvailable) status = QString(tr("

There's a newer version of LeoCAD available for download (%1.%2.%3).

")).arg(QString::number(majorVersion), QString::number(minorVersion), QString::number(patchVersion)); else status = tr("

You are using the latest LeoCAD version.

"); lcPiecesLibrary* library = lcGetPiecesLibrary(); if (library->mNumOfficialPieces) { if (parts > library->mNumOfficialPieces) { status += tr("

There are new parts available.

"); updateAvailable = true; } else status += tr("

There are no new parts available at this time.

"); } if (updateAvailable) { status += tr("

Visit https://github.com/leozide/leocad/releases to download.

"); } ui->status->setText(status); } else ui->status->setText(tr("Error parsing update information.")); settings.setValue("Updates/LastCheck", QDateTime::currentDateTimeUtc()); } else ui->status->setText(tr("Error connecting to the update server.")); if (mInitialUpdate) { if (updateAvailable) show(); else deleteLater(); } if (updateAvailable) ui->buttonBox->setStandardButtons(QDialogButtonBox::Close | QDialogButtonBox::Ignore); else ui->buttonBox->setStandardButtons(QDialogButtonBox::Close); } leocad-23.03/qt/lc_qupdatedialog.h000066400000000000000000000011151440571307300170500ustar00rootroot00000000000000#pragma once #include class lcHttpReply; class lcHttpManager; namespace Ui { class lcQUpdateDialog; } void lcDoInitialUpdateCheck(); class lcQUpdateDialog : public QDialog { Q_OBJECT public: explicit lcQUpdateDialog(QWidget* Parent, bool InitialUpdate); ~lcQUpdateDialog(); void parseUpdate(const char *update); public slots: void DownloadFinished(lcHttpReply* Reply); void accept() override; void reject() override; void finished(int result); private: Ui::lcQUpdateDialog *ui; lcHttpManager* mHttpManager; QByteArray versionData; bool mInitialUpdate; }; leocad-23.03/qt/lc_qupdatedialog.ui000066400000000000000000000032771440571307300172510ustar00rootroot00000000000000 lcQUpdateDialog 0 0 400 98 LeoCAD Updates Qt::RichText true Qt::Horizontal QDialogButtonBox::Cancel buttonBox accepted() lcQUpdateDialog accept() 248 254 157 274 buttonBox rejected() lcQUpdateDialog reject() 316 260 286 274 leocad-23.03/qt/lc_qutils.cpp000066400000000000000000000052721440571307300161110ustar00rootroot00000000000000#include "lc_global.h" #include "lc_qutils.h" #include "lc_application.h" #include "lc_library.h" #include "pieceinf.h" QString lcFormatValue(float Value, int Precision) { QString String = QString::number(Value, 'f', Precision); const int Dot = String.indexOf('.'); if (Dot != -1) { while (String.endsWith('0')) String.chop(1); if (String.endsWith('.')) String.chop(1); } return String; } QString lcFormatValueLocalized(float Value) { QLocale Locale = QLocale::system(); Locale.setNumberOptions(QLocale::OmitGroupSeparator); QString DecimalPoint = Locale.decimalPoint(); QString String = Locale.toString(Value, 'f', 4); if (String.indexOf(DecimalPoint) != -1) { while (String.endsWith('0')) String.chop(1); if (String.endsWith(DecimalPoint)) String.chop(1); } return String; } float lcParseValueLocalized(const QString& Value) { return QLocale::system().toFloat(Value); } // Resize all columns to content except for one stretching column. (taken from QT creator) lcQTreeWidgetColumnStretcher::lcQTreeWidgetColumnStretcher(QTreeWidget *treeWidget, int columnToStretch) : QObject(treeWidget->header()), m_columnToStretch(columnToStretch), m_interactiveResize(false), m_stretchWidth(0) { parent()->installEventFilter(this); connect(treeWidget->header(), SIGNAL(sectionResized(int, int, int)), SLOT(sectionResized(int, int, int))); QHideEvent fake; lcQTreeWidgetColumnStretcher::eventFilter(parent(), &fake); } void lcQTreeWidgetColumnStretcher::sectionResized(int LogicalIndex, int OldSize, int NewSize) { Q_UNUSED(OldSize) if (LogicalIndex == m_columnToStretch) { QHeaderView* HeaderView = qobject_cast(parent()); if (HeaderView->isVisible()) m_interactiveResize = true; m_stretchWidth = NewSize; } } bool lcQTreeWidgetColumnStretcher::eventFilter(QObject* Object, QEvent* Event) { if (Object == parent()) { QHeaderView* HeaderView = qobject_cast(Object); if (Event->type() == QEvent::Show) { for (int i = 0; i < HeaderView->count(); ++i) HeaderView->setSectionResizeMode(i, QHeaderView::Interactive); m_stretchWidth = HeaderView->sectionSize(m_columnToStretch); } else if (Event->type() == QEvent::Hide) { if (!m_interactiveResize) for (int i = 0; i < HeaderView->count(); ++i) HeaderView->setSectionResizeMode(i, i == m_columnToStretch ? QHeaderView::Stretch : QHeaderView::ResizeToContents); } else if (Event->type() == QEvent::Resize) { if (HeaderView->sectionResizeMode(m_columnToStretch) == QHeaderView::Interactive) { const int StretchWidth = HeaderView->isVisible() ? m_stretchWidth : 32; HeaderView->resizeSection(m_columnToStretch, StretchWidth); } } } return false; } leocad-23.03/qt/lc_qutils.h000066400000000000000000000032071440571307300155520ustar00rootroot00000000000000#pragma once #include QString lcFormatValue(float Value, int Precision); QString lcFormatValueLocalized(float Value); float lcParseValueLocalized(const QString& Value); class lcQTreeWidgetColumnStretcher : public QObject { Q_OBJECT public: lcQTreeWidgetColumnStretcher(QTreeWidget* TreeWidget, int ColumnToStretch); bool eventFilter(QObject* Object, QEvent* Event) override; private slots: void sectionResized(int LogicalIndex, int OldSize, int NewSize); private: const int m_columnToStretch; bool m_interactiveResize; int m_stretchWidth; }; class lcSmallLineEdit : public QLineEdit { Q_OBJECT public: QSize sizeHint() const override { QFontMetrics FontMetrics(font()); #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) const int Width = FontMetrics.horizontalAdvance(QLatin1Char('x')) * 10; #else const int Width = FontMetrics.width(QLatin1Char('x')) * 10; #endif return QLineEdit::sizeHint() - QSize(Width, 0); } }; class lcTransformLineEdit : public lcSmallLineEdit { Q_OBJECT protected: bool event(QEvent* Event) override { if (Event->type() == QEvent::ShortcutOverride) { const QKeyEvent* KeyEvent = (QKeyEvent*)Event; const int Key = KeyEvent->key(); if (KeyEvent->modifiers() == Qt::NoModifier && Key >= Qt::Key_A && Key <= Qt::Key_Z) Event->accept(); switch (Key) { case Qt::Key_Down: case Qt::Key_Up: case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_Home: case Qt::Key_End: case Qt::Key_PageUp: case Qt::Key_PageDown: case Qt::Key_Plus: case Qt::Key_Minus: case Qt::Key_Enter: Event->accept(); break; } } return QLineEdit::event(Event); } }; leocad-23.03/qt/lc_renderdialog.cpp000066400000000000000000000210521440571307300172210ustar00rootroot00000000000000#include "lc_global.h" #include "lc_renderdialog.h" #include "ui_lc_renderdialog.h" #include "project.h" #include "lc_application.h" #include "lc_profile.h" #define LC_POVRAY_PREVIEW_WIDTH 768 #define LC_POVRAY_PREVIEW_HEIGHT 432 #if defined(Q_OS_WIN) || defined(Q_OS_MACOS) #define LC_POVRAY_MEMORY_MAPPED_FILE 1 #endif void lcRenderPreviewWidget::resizeEvent(QResizeEvent* Event) { mScaledImage = QImage(); QWidget::resizeEvent(Event); } void lcRenderPreviewWidget::paintEvent(QPaintEvent* PaintEvent) { Q_UNUSED(PaintEvent); QPainter Painter(this); if (!mImage.isNull()) { QSize Size = size(); if (mScaledImage.isNull()) mScaledImage = mImage.scaled(Size, Qt::KeepAspectRatio, Qt::SmoothTransformation); Painter.drawImage((Size.width() - mScaledImage.width()) / 2, (Size.height() - mScaledImage.height()) / 2, mScaledImage); } else Painter.fillRect(rect(), Qt::white); } lcRenderDialog::lcRenderDialog(QWidget* Parent) : QDialog(Parent), ui(new Ui::lcRenderDialog) { #ifndef QT_NO_PROCESS mProcess = nullptr; #endif mOutputBuffer = nullptr; ui->setupUi(this); ui->WidthEdit->setText(QString::number(lcGetProfileInt(LC_PROFILE_POVRAY_WIDTH))); ui->WidthEdit->setValidator(new QIntValidator(16, INT_MAX)); ui->HeightEdit->setText(QString::number(lcGetProfileInt(LC_PROFILE_POVRAY_HEIGHT))); ui->HeightEdit->setValidator(new QIntValidator(16, INT_MAX)); ui->OutputEdit->setText(lcGetActiveProject()->GetImageFileName(false)); QImage Image(LC_POVRAY_PREVIEW_WIDTH, LC_POVRAY_PREVIEW_HEIGHT, QImage::Format_RGB32); Image.fill(QColor(255, 255, 255)); ui->preview->SetImage(Image); connect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(Update())); mUpdateTimer.start(500); } lcRenderDialog::~lcRenderDialog() { delete ui; } QString lcRenderDialog::GetOutputFileName() const { return QDir(QDir::tempPath()).absoluteFilePath("leocad-render.out"); } QString lcRenderDialog::GetPOVFileName() const { return QDir(QDir::tempPath()).absoluteFilePath("leocad-render.pov"); } void lcRenderDialog::CloseProcess() { #ifndef QT_NO_PROCESS delete mProcess; mProcess = nullptr; #endif #if LC_POVRAY_MEMORY_MAPPED_FILE mOutputFile.unmap((uchar*)mOutputBuffer); mOutputBuffer = nullptr; mOutputFile.close(); QFile::remove(GetOutputFileName()); #endif QFile::remove(GetPOVFileName()); ui->RenderButton->setText(tr("Render")); } bool lcRenderDialog::PromptCancel() { #ifndef QT_NO_PROCESS if (mProcess) { if (QMessageBox::question(this, tr("Cancel Render"), tr("Are you sure you want to cancel the current render?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { if (mProcess) { mProcess->kill(); CloseProcess(); } } else return false; } #endif return true; } void lcRenderDialog::reject() { if (PromptCancel()) QDialog::reject(); } void lcRenderDialog::on_RenderButton_clicked() { #ifndef QT_NO_PROCESS if (mProcess) { PromptCancel(); return; } QString FileName = GetPOVFileName(); if (!lcGetActiveProject()->ExportPOVRay(FileName)) return; QStringList Arguments; Arguments.append(QString::fromLatin1("+I\"%1\"").arg(FileName)); Arguments.append(QString::fromLatin1("+W%1").arg(ui->WidthEdit->text())); Arguments.append(QString::fromLatin1("+H%1").arg(ui->HeightEdit->text())); Arguments.append("-O-"); #if LC_POVRAY_MEMORY_MAPPED_FILE Arguments.append(QString::fromLatin1("+SM\"%1\"").arg(GetOutputFileName())); #endif int Quality = ui->QualityComboBox->currentIndex(); switch (Quality) { case 0: Arguments.append("+Q11"); Arguments.append("+R3"); Arguments.append("+A0.1"); Arguments.append("+J0.5"); break; case 1: Arguments.append("+Q5"); Arguments.append("+A0.1"); break; case 2: break; } /* if (!LGEOPath.isEmpty()) { Arguments.append(QString::fromLatin1("+L%1lg/").arg(LGEOPath)); Arguments.append(QString::fromLatin1("+L%1ar/").arg(LGEOPath)); } */ QString POVRayPath; #ifdef Q_OS_WIN POVRayPath = QDir::cleanPath(QCoreApplication::applicationDirPath() + QLatin1String("/povconsole32-sse2.exe")); #endif #ifdef Q_OS_LINUX POVRayPath = lcGetProfileString(LC_PROFILE_POVRAY_PATH); Arguments.append("+FN"); Arguments.append("-D"); #endif #ifdef Q_OS_MACOS POVRayPath = QDir::cleanPath(QCoreApplication::applicationDirPath() + QLatin1String("/povray")); #endif mProcess = new QProcess(this); #ifdef Q_OS_LINUX connect(mProcess, SIGNAL(readyReadStandardError()), this, SLOT(ReadStdErr())); #endif mProcess->start(POVRayPath, Arguments); mImage = QImage(ui->WidthEdit->text().toInt(), ui->HeightEdit->text().toInt(), QImage::Format_ARGB32); mImage.fill(QColor(255, 255, 255)); ui->preview->SetImage(mImage); if (mProcess->waitForStarted()) { ui->RenderButton->setText(tr("Cancel")); ui->RenderProgress->setValue(ui->RenderProgress->minimum()); mStdErrList.clear(); } else { QMessageBox::warning(this, tr("Error"), tr("Error starting POV-Ray.")); CloseProcess(); } #endif } void lcRenderDialog::ReadStdErr() { QString StdErr = QString(mProcess->readAllStandardError()); mStdErrList.append(StdErr); #ifdef Q_OS_LINUX QRegExp RegexPovRayProgress("Rendered (\\d+) of (\\d+) pixels.*"); RegexPovRayProgress.setCaseSensitivity(Qt::CaseInsensitive); if (RegexPovRayProgress.indexIn(StdErr) == 0) { ui->RenderProgress->setMaximum(RegexPovRayProgress.cap(2).toInt()); ui->RenderProgress->setValue(RegexPovRayProgress.cap(1).toInt()); } #endif } void lcRenderDialog::Update() { #ifndef QT_NO_PROCESS if (!mProcess) return; if (mProcess->state() == QProcess::NotRunning) { #ifdef Q_OS_LINUX QByteArray Output = mProcess->readAllStandardOutput(); mImage = QImage::fromData(Output); #endif ShowResult(); CloseProcess(); } #endif #if LC_POVRAY_MEMORY_MAPPED_FILE if (!mOutputBuffer) { mOutputFile.setFileName(GetOutputFileName()); if (!mOutputFile.open(QFile::ReadWrite)) return; mOutputBuffer = mOutputFile.map(0, mOutputFile.size()); if (!mOutputBuffer) { mOutputFile.close(); return; } } struct lcSharedMemoryHeader { quint32 Version; quint32 Width; quint32 Height; quint32 PixelsWritten; quint32 PixelsRead; }; lcSharedMemoryHeader* Header = (lcSharedMemoryHeader*)mOutputBuffer; if (Header->PixelsWritten == Header->PixelsRead) return; int Width = Header->Width; int Height = Header->Height; int PixelsWritten = Header->PixelsWritten; quint8* Pixels = (quint8*)(Header + 1); for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { mImage.setPixel(x, y, qRgba(Pixels[0], Pixels[1], Pixels[2], Pixels[3])); Pixels += 4; } } Header->PixelsRead = PixelsWritten; ui->RenderProgress->setMaximum(mImage.width() * mImage.height()); ui->RenderProgress->setValue(int(Header->PixelsRead)); ui->preview->SetImage(mImage); #endif } void lcRenderDialog::ShowResult() { ReadStdErr(); ui->RenderProgress->setValue(ui->RenderProgress->maximum()); bool Error = (mProcess->exitStatus() != QProcess::NormalExit || mProcess->exitCode() != 0); if (Error) { WriteStdLog(Error); QMessageBox MessageBox; MessageBox.setWindowTitle(tr("Error")); MessageBox.setIcon(QMessageBox::Information); MessageBox.setText(tr("An error occurred while rendering. Check details or try again.")); MessageBox.setDetailedText(mStdErrList.join(QString())); MessageBox.exec(); return; } ui->preview->SetImage(mImage); QString FileName = ui->OutputEdit->text(); if (!FileName.isEmpty()) { QImageWriter Writer(FileName); bool Result = Writer.write(mImage); if (!Result) QMessageBox::information(this, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, Writer.errorString())); } WriteStdLog(); } void lcRenderDialog::WriteStdLog(bool Error) { QString FileName = lcGetActiveProject()->GetFileName(); if (FileName.isEmpty()) return; QFile LogFile(QDir::toNativeSeparators(QFileInfo(FileName).absolutePath() + "/" + (Error ? "stderr-povrayrender" : "stdout-povrayrender"))); if (LogFile.open(QFile::WriteOnly | QIODevice::Truncate | QFile::Text)) { QTextStream Out(&LogFile); for (const QString& Line : mStdErrList) Out << Line; LogFile.close(); } else { QMessageBox::information(this, tr("Error"), tr("Error writing to %1 file '%2':\n%3") .arg(Error ? "stderr" : "stdout").arg(LogFile.fileName(), LogFile.errorString())); } } void lcRenderDialog::on_OutputBrowseButton_clicked() { QString Result = QFileDialog::getSaveFileName(this, tr("Select Output File"), ui->OutputEdit->text(), tr("Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*)")); if (!Result.isEmpty()) ui->OutputEdit->setText(QDir::toNativeSeparators(Result)); } leocad-23.03/qt/lc_renderdialog.h000066400000000000000000000021231440571307300166640ustar00rootroot00000000000000#pragma once #include namespace Ui { class lcRenderDialog; } class lcRenderPreviewWidget : public QWidget { Q_OBJECT public: lcRenderPreviewWidget(QWidget* Parent) : QWidget(Parent) { } void SetImage(QImage Image) { mImage = Image; mScaledImage = QImage(); update(); } protected: void resizeEvent(QResizeEvent* Event) override; void paintEvent(QPaintEvent* PaintEvent) override; QImage mImage; QImage mScaledImage; }; class lcRenderDialog : public QDialog { Q_OBJECT public: explicit lcRenderDialog(QWidget* Parent); ~lcRenderDialog(); public slots: void reject() override; void on_RenderButton_clicked(); void on_OutputBrowseButton_clicked(); void Update(); protected slots: void ReadStdErr(); void WriteStdLog(bool = false); protected: QString GetOutputFileName() const; QString GetPOVFileName() const; void CloseProcess(); bool PromptCancel(); void ShowResult(); #ifndef QT_NO_PROCESS QProcess* mProcess; #endif QTimer mUpdateTimer; QFile mOutputFile; void* mOutputBuffer; QImage mImage; QStringList mStdErrList; Ui::lcRenderDialog* ui; }; leocad-23.03/qt/lc_renderdialog.ui000066400000000000000000000073351440571307300170640ustar00rootroot00000000000000 lcRenderDialog 0 0 576 424 Render 0 0 Settings Width: Height: Quality: High Medium Low Output: ... 1 0 Render lcRenderPreviewWidget QWidget
lc_renderdialog.h
1
QualityComboBox OutputEdit OutputBrowseButton
leocad-23.03/qt/lc_setsdatabasedialog.cpp000066400000000000000000000126301440571307300204070ustar00rootroot00000000000000#include "lc_global.h" #include "lc_setsdatabasedialog.h" #include "ui_lc_setsdatabasedialog.h" #include "lc_http.h" lcSetsDatabaseDialog::lcSetsDatabaseDialog(QWidget* Parent) : QDialog(Parent), ui(new Ui::lcSetsDatabaseDialog) { ui->setupUi(this); ui->SearchEdit->installEventFilter(this); mHttpManager = new lcHttpManager(this); connect(ui->SetsTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(accept())); connect(this, SIGNAL(finished(int)), this, SLOT(Finished(int))); connect(mHttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), this, SLOT(DownloadFinished(lcHttpReply*))); mKeyListReply = mHttpManager->DownloadFile(QLatin1String("https://www.leocad.org/rebrickable.json")); } lcSetsDatabaseDialog::~lcSetsDatabaseDialog() { delete ui; } QString lcSetsDatabaseDialog::GetSetName() const { QTreeWidgetItem* Current = ui->SetsTree->currentItem(); return Current ? Current->text(0) : QString(); } QString lcSetsDatabaseDialog::GetSetDescription() const { QTreeWidgetItem* Current = ui->SetsTree->currentItem(); return Current ? Current->text(1) : QString(); } bool lcSetsDatabaseDialog::eventFilter(QObject* Object, QEvent* Event) { if (Event->type() == QEvent::KeyPress) { QKeyEvent* KeyEvent = static_cast(Event); int Key = KeyEvent->key(); if (Key == Qt::Key_Return || Key == Qt::Key_Enter) { KeyEvent->accept(); on_SearchButton_clicked(); return true; } } return QDialog::eventFilter(Object, Event); } void lcSetsDatabaseDialog::accept() { QTreeWidgetItem* Current = ui->SetsTree->currentItem(); if (!Current) { QMessageBox::information(this, "LeoCAD", tr("Please select a set from the list.")); return; } QString SetNum = Current->text(0); QProgressDialog ProgressDialog(this); ProgressDialog.setWindowTitle(tr("Downloading")); ProgressDialog.setLabelText(tr("Downloading set inventory")); ProgressDialog.setMaximum(0); ProgressDialog.setMinimum(0); ProgressDialog.setValue(0); ProgressDialog.show(); int KeyIndex = QTime::currentTime().msec() % mKeys.size(); QString DownloadUrl = QString("https://rebrickable.com/api/v3/lego/sets/%1/parts/?key=%2&page_size=1000").arg(SetNum, mKeys[KeyIndex]); mInventoryReply = mHttpManager->DownloadFile(DownloadUrl); while (mInventoryReply) { QApplication::processEvents(); if (ProgressDialog.wasCanceled()) { mInventoryReply->abort(); mInventoryReply->deleteLater(); mInventoryReply = nullptr; return; } } QDialog::accept(); } void lcSetsDatabaseDialog::Finished(int Result) { Q_UNUSED(Result); if (mKeyListReply) { mKeyListReply->abort(); mKeyListReply->deleteLater(); } } void lcSetsDatabaseDialog::on_SearchButton_clicked() { QString Keyword = ui->SearchEdit->text(); if (Keyword.isEmpty()) { QMessageBox::information(this, "LeoCAD", tr("Keyword cannot be empty.")); return; } QProgressDialog ProgressDialog(this); ProgressDialog.setWindowTitle(tr("Searching")); ProgressDialog.setLabelText(tr("Connecting to server")); ProgressDialog.setMaximum(0); ProgressDialog.setMinimum(0); ProgressDialog.setValue(0); ProgressDialog.show(); while (mKeyListReply) { QApplication::processEvents(); if (ProgressDialog.wasCanceled()) return; } if (mKeys.isEmpty()) return; int KeyIndex = QTime::currentTime().msec() % mKeys.size(); QString SearchUrl = QString("https://rebrickable.com/api/v3/lego/sets/?search=%1&key=%2").arg(Keyword, mKeys[KeyIndex]); mSearchReply = mHttpManager->DownloadFile(SearchUrl); while (mSearchReply) { QApplication::processEvents(); if (ProgressDialog.wasCanceled()) { mSearchReply->abort(); mSearchReply->deleteLater(); mSearchReply = nullptr; break; } } } void lcSetsDatabaseDialog::DownloadFinished(lcHttpReply* Reply) { if (Reply == mKeyListReply) { if (!Reply->error()) { QJsonDocument Document = QJsonDocument::fromJson(Reply->readAll()); QJsonObject Root = Document.object(); int Version = Root["Version"].toInt(); if (Version == 1) { QJsonArray Keys = Root["Keys"].toArray(); for (const QJsonValue& Key : Keys) mKeys.append(Key.toString()); } } if (mKeys.isEmpty()) { QMessageBox::information(this, "LeoCAD", tr("Error connecting to server.")); close(); } mKeyListReply = nullptr; } else if (Reply == mSearchReply) { QTreeWidget* SetsTree = ui->SetsTree; SetsTree->clear(); if (!Reply->error()) { QJsonDocument Document = QJsonDocument::fromJson(Reply->readAll()); QJsonObject Root = Document.object(); QJsonArray Sets = Root["results"].toArray(); for (const QJsonValue& Set : Sets) { QJsonObject SetObject = Set.toObject(); QStringList SetInfo; SetInfo << SetObject["set_num"].toString(); SetInfo << SetObject["name"].toString(); SetInfo << QString::number(SetObject["year"].toInt()); SetInfo << QString::number(SetObject["num_parts"].toInt()); new QTreeWidgetItem(ui->SetsTree, SetInfo); } if (!Sets.isEmpty()) { SetsTree->resizeColumnToContents(0); SetsTree->resizeColumnToContents(1); SetsTree->resizeColumnToContents(2); SetsTree->resizeColumnToContents(3); SetsTree->setCurrentItem(SetsTree->topLevelItem(0)); } } mSearchReply = nullptr; } else if (Reply == mInventoryReply) { if (!Reply->error()) mInventory = Reply->readAll(); else QMessageBox::information(this, "LeoCAD", tr("Error downloading set inventory.")); mInventoryReply = nullptr; } Reply->deleteLater(); } leocad-23.03/qt/lc_setsdatabasedialog.h000066400000000000000000000014471440571307300200600ustar00rootroot00000000000000#pragma once #include class lcHttpReply; class lcHttpManager; namespace Ui { class lcSetsDatabaseDialog; } class lcSetsDatabaseDialog : public QDialog { Q_OBJECT public: explicit lcSetsDatabaseDialog(QWidget* Parent); ~lcSetsDatabaseDialog(); QString GetSetName() const; QString GetSetDescription() const; QByteArray GetSetInventory() const { return mInventory; } bool eventFilter(QObject* Object, QEvent* Event) override; public slots: void DownloadFinished(lcHttpReply* Reply); void on_SearchButton_clicked(); void accept() override; void Finished(int Result); protected: lcHttpManager* mHttpManager; lcHttpReply* mKeyListReply; lcHttpReply* mSearchReply; lcHttpReply* mInventoryReply; QStringList mKeys; QByteArray mInventory; Ui::lcSetsDatabaseDialog* ui; }; leocad-23.03/qt/lc_setsdatabasedialog.ui000066400000000000000000000060211440571307300202370ustar00rootroot00000000000000 lcSetsDatabaseDialog 0 0 495 331 Sets Database Set Name or Number Search false true true 4 Number Name Year Parts Sets Database provided by <a href="https://www.rebrickable.com">Rebrickable</a> true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() lcSetsDatabaseDialog accept() 248 254 157 274 buttonBox rejected() lcSetsDatabaseDialog reject() 316 260 286 274 leocad-23.03/qt/leocad.desktop000066400000000000000000000010501440571307300162160ustar00rootroot00000000000000[Desktop Entry] Version=1.0 Name=LeoCAD Comment=Create virtual LEGO models Comment[eo]=Kreu virtualajn LEGO-ajn modelojn Comment[it]=Crea modelli LEGO virtuali Comment[nb]=Lag virtuelle LEGO-modeller Comment[pt_BR]=Criar modelos virtuais de LEGO Comment[de]=Erstelle virtuelle Lego Modelle Exec=leocad %f Terminal=false Type=Application Icon=leocad MimeType=application/vnd.leocad;application/x-ldraw;application/x-multi-part-ldraw;application/x-multipart-ldraw;application/x-ldlite; Categories=Graphics;3DGraphics;Education; Keywords=CAD;LEGO;LDraw; leocad-23.03/qt/leocad.xml000066400000000000000000000012621440571307300153520ustar00rootroot00000000000000 LeoCAD Project LDraw File Multi-part LDraw File leocad-23.03/qt/qtmain.cpp000066400000000000000000000155431440571307300154050ustar00rootroot00000000000000#include "lc_global.h" #include "lc_application.h" #include "lc_qupdatedialog.h" #include "lc_profile.h" #include "pieceinf.h" #include #include #ifdef Q_OS_WIN #pragma warning(push) #pragma warning(disable : 4091) #include #include #include #pragma warning(pop) #ifdef UNICODE #ifndef _UNICODE #define _UNICODE #endif #endif #include static TCHAR gMinidumpPath[_MAX_PATH]; static LONG WINAPI lcSehHandler(PEXCEPTION_POINTERS exceptionPointers) { if (IsDebuggerPresent()) return EXCEPTION_CONTINUE_SEARCH; HMODULE dbgHelp = LoadLibrary(TEXT("dbghelp.dll")); if (dbgHelp == nullptr) return EXCEPTION_EXECUTE_HANDLER; HANDLE file = CreateFile(gMinidumpPath, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (file == INVALID_HANDLE_VALUE) return EXCEPTION_EXECUTE_HANDLER; typedef BOOL (WINAPI *LPMINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserEncoderParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); LPMINIDUMPWRITEDUMP miniDumpWriteDump = (LPMINIDUMPWRITEDUMP)GetProcAddress(dbgHelp, "MiniDumpWriteDump"); if (!miniDumpWriteDump) return EXCEPTION_EXECUTE_HANDLER; MINIDUMP_EXCEPTION_INFORMATION mei; mei.ThreadId = GetCurrentThreadId(); mei.ExceptionPointers = exceptionPointers; mei.ClientPointers = TRUE; BOOL writeDump = miniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpNormal, exceptionPointers ? &mei : nullptr, nullptr, nullptr); CloseHandle(file); FreeLibrary(dbgHelp); if (writeDump) { TCHAR message[_MAX_PATH + 256]; lstrcpy(message, TEXT("LeoCAD just crashed. Crash information was saved to the file '")); lstrcat(message, gMinidumpPath); lstrcat(message, TEXT("', please send it to the developers for debugging.")); MessageBox(nullptr, message, TEXT("LeoCAD"), MB_OK); } return EXCEPTION_EXECUTE_HANDLER; } static void lcSehInit() { if (GetTempPath(LC_ARRAY_COUNT(gMinidumpPath), gMinidumpPath)) lstrcat(gMinidumpPath, TEXT("leocad.dmp")); SetUnhandledExceptionFilter(lcSehHandler); } static void lcRegisterShellFileTypes() { TCHAR modulePath[_MAX_PATH], longModulePath[_MAX_PATH]; TCHAR temp[2*_MAX_PATH]; GetModuleFileName(nullptr, longModulePath, _MAX_PATH); if (GetShortPathName(longModulePath, modulePath, _MAX_PATH) == 0) lstrcpy(modulePath, longModulePath); if (RegSetValue(HKEY_CLASSES_ROOT, TEXT("LeoCAD.Project"), REG_SZ, TEXT("LeoCAD Project"), lstrlen(TEXT("LeoCAD Project")) * sizeof(TCHAR)) != ERROR_SUCCESS) return; lstrcpy(temp, modulePath); lstrcat(temp, TEXT(",0")); if (RegSetValue(HKEY_CLASSES_ROOT, TEXT("LeoCAD.Project\\DefaultIcon"), REG_SZ, temp, lstrlen(temp) * sizeof(TCHAR)) != ERROR_SUCCESS) return; lstrcpy(temp, modulePath); lstrcat(temp, TEXT(" \"%1\"")); if (RegSetValue(HKEY_CLASSES_ROOT, TEXT("LeoCAD.Project\\shell\\open\\command"), REG_SZ, temp, lstrlen(temp) * sizeof(TCHAR)) != ERROR_SUCCESS) return; LONG size = 2 * _MAX_PATH; LONG result = RegQueryValue(HKEY_CLASSES_ROOT, TEXT(".lcd"), temp, &size); if (result != ERROR_SUCCESS || !lstrlen(temp) || lstrcmp(temp, TEXT("LeoCAD.Project"))) { if (RegSetValue(HKEY_CLASSES_ROOT, TEXT(".lcd"), REG_SZ, TEXT("LeoCAD.Project"), lstrlen(TEXT("LeoCAD.Project")) * sizeof(TCHAR)) != ERROR_SUCCESS) return; HKEY key; DWORD disposition = 0; if (RegCreateKeyEx(HKEY_CLASSES_ROOT, TEXT(".lcd\\ShellNew"), 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, nullptr, &key, &disposition) != ERROR_SUCCESS) return; result = RegSetValueEx(key, TEXT("NullFile"), 0, REG_SZ, (CONST BYTE*)TEXT(""), (lstrlen(TEXT("")) + 1) * sizeof(TCHAR)); if (RegCloseKey(key) != ERROR_SUCCESS || result != ERROR_SUCCESS) return; } } #endif static void lcInitializeSurfaceFormat(int argc, char* argv[]) { QCoreApplication Application(argc, argv); const lcCommandLineOptions Options = lcApplication::ParseCommandLineOptions(); if (Options.ParseOK && Options.AASamples > 1) { QSurfaceFormat Format = QSurfaceFormat::defaultFormat(); Format.setSamples(Options.AASamples); QSurfaceFormat::setDefaultFormat(Format); } } int main(int argc, char *argv[]) { QCoreApplication::setOrganizationDomain(QLatin1String("leocad.org")); QCoreApplication::setOrganizationName(QLatin1String("LeoCAD Software")); QCoreApplication::setApplicationName(QLatin1String("LeoCAD")); QCoreApplication::setApplicationVersion(QLatin1String(LC_VERSION_TEXT)); lcInitializeSurfaceFormat(argc, argv); QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); lcApplication Application(argc, argv); QString Language = lcGetProfileString(LC_PROFILE_LANGUAGE); QLocale Locale; if (!Language.isEmpty()) Locale = QLocale(Language); QTranslator QtTranslator; if (QtTranslator.load(Locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) Application.installTranslator(&QtTranslator); #ifdef Q_OS_WIN else if (QtTranslator.load(Locale, "qt", "_", qApp->applicationDirPath() + "/translations")) Application.installTranslator(&QtTranslator); #endif QTranslator QtBaseTranslator; if (QtBaseTranslator.load("qtbase_" + Locale.name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) Application.installTranslator(&QtBaseTranslator); #ifdef Q_OS_WIN else if (QtBaseTranslator.load("qtbase_" + Locale.name(), qApp->applicationDirPath() + "/translations")) Application.installTranslator(&QtBaseTranslator); #endif QTranslator Translator; if (Translator.load("leocad_" + Locale.name(), ":/resources")) Application.installTranslator(&Translator); qRegisterMetaType("PieceInfo*"); qRegisterMetaType >("QList"); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) qRegisterMetaTypeStreamOperators >("QList"); #endif QList> LibraryPaths; #ifdef Q_OS_WIN lcRegisterShellFileTypes(); lcSehInit(); LibraryPaths += qMakePair(QDir::cleanPath(QCoreApplication::applicationDirPath() + "/library.bin"), true); #endif #ifdef Q_OS_LINUX LibraryPaths += qMakePair(QDir::cleanPath(QCoreApplication::applicationDirPath() + "/../share/leocad/library.bin"), true); #endif #ifdef Q_OS_MAC LibraryPaths += qMakePair(QDir::cleanPath(QCoreApplication::applicationDirPath() + "/../../Contents/Resources/library.bin"), true); #endif #ifdef LC_LDRAW_LIBRARY_PATH LibraryPaths += qMakePair(QString::fromLatin1(LC_LDRAW_LIBRARY_PATH), false); #endif setlocale(LC_NUMERIC, "C"); lcStartupMode StartupMode = Application.Initialize(LibraryPaths); if (StartupMode == lcStartupMode::Error) { Application.Shutdown(); return 1; } int ExecReturn = 0; if (StartupMode == lcStartupMode::ShowWindow) { #if !LC_DISABLE_UPDATE_CHECK lcDoInitialUpdateCheck(); #endif ExecReturn = Application.exec(); } Application.Shutdown(); return ExecReturn; } leocad-23.03/qt/system.cpp000066400000000000000000000010061440571307300154250ustar00rootroot00000000000000#include "lc_global.h" #ifdef Q_OS_WIN char* strcasestr(const char *s, const char *find) { char c, sc; if ((c = *find++) != 0) { c = tolower((unsigned char)c); const int len = (int)strlen(find); do { do { if ((sc = *s++) == 0) return (nullptr); } while ((char)tolower((unsigned char)sc) != c); } while (qstrnicmp(s, find, len) != 0); s--; } return ((char *)s); } #else char* strupr(char *string) { for (char *c = string; *c; c++) *c = toupper(*c); return string; } #endif leocad-23.03/resources/000077500000000000000000000000001440571307300147665ustar00rootroot00000000000000leocad-23.03/resources/action_camera.png000066400000000000000000000016531440571307300202660ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFPLTEÿÿÿÿÿÿõõõfffbbb\\\UUUNNNEEE===444+++""" '''ççç```ZZZTTTMMMDDD<<<333***›››×××VVVQQQJJJBBB:::111(((  ¡¡¡ÄÄÄLLL>>>666...&&& °°°@@@999222 ˆˆˆ,,,%%%œœœddduuvuuueeeWWWÿÿÿ¢>s.]tRNSWÙ6ÙÓÙÙÙÙÙÙÙÙÙÙÙÙÙÙ3ÔÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÕÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙٵٲ­ ¦/ý bKGDˆH pHYs  šœtIMEã KkÅIDAT(ϽÑY[‚P`ŽŸe. i®¨¹"¤© ™ áš–-fûÿÿC7=<^û]Ìżs33wˆøà#ÄÏq8ò´L!p …#¼‰Ò© @Îâ ž'SéL6§ˆy øãÅPò¢T®Tkuµ¡é@—…&ƒV8UºâÛ®aöú×@ hº0ˆ¤ËüÍp¤ˆc˾€ã¸Àg*ían25gš>ÿ ![íŒ&†*-í»°ÖkN4Wë*SU²úúüžŽ‚Àà!¦Ô Ñ”,MÞ<ÒÅŸ€ç[QTÍñlÙ—7+v‘-^i¥°“òž¥Ùú_;¼½»öäã{¯KÈ×÷ÞOB~ññ_§$Yñ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_color_picker.png000066400000000000000000000006621440571307300215100ustar00rootroot00000000000000‰PNG  IHDRàw=øsRGB®ÎégAMA± üa pHYsÃÃÇo¨dGIDATHK­•1NÄ0E'”¡mª] Z¨÷‹”jÏ€@”¥Î h€Šc¤Ý.Ô¹Ú~Ózó­™ÈÊšÄ±ó¥‘Æ¶òþÌXr"¥-©Ëûç¸ÿy5ü|uË+¢Ãß/iƒî€·´+gÓ’jQéÁàŒóÙ Ây˜²ÁQ=:ó6ÀÇ€Ø$päA¼lV6&oƒ²,UÇ´û~Ô&¦‘Ü r/§iª×¯kzÛÞX»™m`“$¡ªª¨ijÛ¶¿Dð^×µE!°°À¡Yfõ&œ­r60á2’)8äd0„›#™Ò¬ œ—Nš4@õY–9d¨QûT.ú×@àyž;ÏÛ¦ÑçÔ[VTRµ©ƒ%áPÿO¾~øêÎÝ[dÐ=œq€ËK ?:¸Ú|*ò‹»'½·L(:BLüƒHèßIEND®B`‚leocad-23.03/resources/action_color_picker_16.png000066400000000000000000000006351440571307300220160ustar00rootroot00000000000000‰PNG  IHDRóÿasRGB®ÎégAMA± üa pHYsÃÃÇo¨d2IDAT8Ocd ™åÊ03ü b32±m€¨YÎF†?ÿïp‹ëu32|}q™ *€4sKè2€5ƒh f ÊÍ ÛÀš¡Äçbä Ê€|/q•$9¶Ÿ "ðî;Á0hiiqgccÛ¨¬¬Ìâ¯Ù}…áø3 †??>2üüðˆ°˜™™wÀ4ߺu‹AOž ì|æ×§¦ …ÐÞÞþ_DD„AHH¬™‹‹‹#??ÿ'T pÓ oÞ¼a¨¬¬Äª«mƧ0 èèèQSS³AÎÆ§0 øÿÿÿãwÀø!d3VrúìÙ³ÿC¹D¸ @ñ ¢SSSI³èd0VÞô_Áo&I¶ƒ£¢ßÌP ®U¬¼’ ·—ú‘f;ù2sœ5¹µIEND®B`‚leocad-23.03/resources/action_delete.png000066400000000000000000000025001440571307300202700ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFFPLTEÿÿÿXXXzzz€€€………°%±%²%´%®$«$¨#¥#OOOooouuuFFFccciiiWWW]]]ž!œ!Õ€‘NO###µ&´&´%³%´%³%²%±%²%²%¯%®$±%¬$«$°%°%©$¨#„„„®$¦#¥#}}}£"yyyxxx "tttrrrŸ"ž!nnnlll!œ!hhhfff›!›!bbb```™!™!\\\ZZZ˜ — VVVSSSKKK=== 222,,, """þ¸Éþ¹Êý·Èñ«¼í§¸üµÆð©ºì¥¶ì¦·û²Ã醴룴뤵ú°Áí¤µé¡²ê¢³ð¸Åæ®î™ªì¡²èž¯é ±ï¶Äç®ã—¨ß‘¢ùùùîµÂ䘨ߑ¡ÛŠ›í˜©öööôôôõõõí³Á㘨ߡڊ›ë–§ñññðððóóóì±¾ÛŠšé”¥ïïïîîîߢ摢íííëëëâããä éééâãâÝÝÜÕÕÕçççìììÜÝÝÎÍÍÜÜÜèèèåååêêêãããÜÝÜÍÎÎ×××ÎÎÎÔÔÔáááÎÍÎÑÑÑßßßÎÎÍÏÏÏÞÞÞÍÍÍÿÿÿd&íptRNS>{{>>|~@?}@~‚B@…D4€‰E4fŒ4f4f‘I4f’J4f”K4f–L4f˜M4ff4ff4ff44ff44ff44ff4JfffEJ\“¤bKGDˆH pHYs  šœtIMEã KkÅfIDAT(Ïc` 03 +;'—‚¢’27/X‚_@P"¡¢ZP¨¦•ƒJhh—jiC$Ä%`ê:¥eå%…ºz¨ú•UÕ5 C#¸66©­«oÊ465›š!$Ì-j[ZÛ€2í]Í–p +ëî–Ö LOGo_ÿ˜„­ÝÄI“;€2Sš¦N›>ÃÞ*áè4yæ¬Y³;Zç4uöÍçì" ‘pu›4ÌŠ/œ»ÈÝC "áé5{ñ˜¿´³¯™·4DÂ×oæ’å °xÅÊUýËü¤!A³–¯5+Ö®Z·>8(–¿a#lÚ¼eÕÖmaá —‘ó7ƒÀòÍëWmß 3çΫW¬_µkwlBB.>aþž@õ{÷%&1 I0Ê'§ì?©iŒpQž‘˜™š••ï9¹¹yùD¦ÄŒ`ýå¼%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_delete_16.png000066400000000000000000000016131440571307300206020ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<hPLTEŠ‹®vž«xœ©vš±| ©uš°zž¬sœ‰ŒŠ‹‹‹ŠŠŠçèèåææôõõ¦q—­v›–g‰†††~~„„„|||¥o–¢m”ÿìòþéïÿîôꟽ韽Ꞽÿìó¢l“ÿðöì£Áì¥Ãë¡Áùäìÿëñ¦k•ÿñ÷ñ§Æï©ÇïªÇï§Æúéîå—µ¤o•ƒ„ƒñöõݱÅô¬Ìñ¬ÌñªÊùéïæœ¸î¥Âÿóùƒƒƒ÷ö÷¿ÂĽÄÄã·Ìö®Ïï¨Äú´Ñ¢o•‚‚‚øùùÆÈÊÇÉËÆÊËÂÊÊúçðæ›·úµÑ£r—ûûüÎÏÐÏÏÐÏÐÑËÍÎíïïÓ®½ï§ÄýþþÔÕÖÕÖ×ÒÓÔîîî¾ÀÁÎÒÓàåäÿÿÿÛÜÝÙÚÛíîîÏÐÓãåæ‚‡ƒêììãååáääÞààîïîÏÐÒäåæ„„„xxxñòòèéé|||÷ùøÃÆÇÔÕ×åæç‡‡‡,óétRNS¨½¹"3Ôì.é¹›ôŽbKGD`Å·|tIMEã KkÅÕIDATÓc`F&ff)fV˜‹´Œ¬Œ4\€MZN^AQI™*À!­¢ª¦¦®¡)àÔÒÖÑÕÓ70T2ó¹ŒMLÍÌ-,­¬m„À|[;{G'K+gWa ŸÛÍÝÃÓËÛÇ×ÙÏ_„Ä  wò™¸Ü""£¢¢cbã⥀|fÑ„ÄÄĤ䨔Ô4Ÿ™A,=#3+;6'7O„ , ž_P”ò!<"EÅ%¥ey" P^>‰òrI˜??¿¸ˆˆ0? •%™¡•:%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+tEXtSoftwareAdobe ImageReadyqÉe<IEND®B`‚leocad-23.03/resources/action_insert.png000066400000000000000000000010541440571307300203350ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFPLTEÿÿÿ¸¸ñ€ô——öªªö··ò€îLLùËËô››ô••óóˆˆò€€ñttñkkïaaîVVìBBë99ë00é&&çùÆÆçøÂÂæ÷¹¹å ö±±äö¨¨ãôžžáó’’Üò††Øñwwï__ÿÿÿÈãmtRNS¿-Mc%bKGDˆH pHYs  šœtIMEã KkÅ…IDAT(Ï…ÑÛBPEav:mRI’œ6ïÿ‚ 7æOÖåü.—eý›­¦Ù+PÇݺŽZÃηµØ ¾!ö‡ãé¬ÃÈ»H˜{,ý*ý&ýNHÐ E¦€ ý•rôw(Ð? D¯J@ÞԀݴ€Ýtn4 üzðÛÉ'_Úï?x%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_insert_16.png000066400000000000000000000007401440571307300206440ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF]PLTEÿÿÿîîî¸ì‘‘áZZöÈÈìxxëooêddèXXæKKå??õÃÃã44ó¼¼á))ô¸¸ßó®®Ýñ££Ûñ™™Ú ïÙØé€€ÿÿÿ±X¾wtRNSv“Í8bKGDˆH pHYs  šœtIMEã KkÅ]IDATÓmÏÛ@ …áJÎ’$I¼ÿkb]7í›Yÿw7ŒÆ9ßÞ›¡’2ƒÈû¡Æ4m×ã”@QÏ  © 0Ô«XêÍõîžúð€@}@¤¾"àÆDá—c~¤ E…·%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_light.png000066400000000000000000000027241440571307300201450ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYsÄÄ•+ÖIDATHÇ…•[leÇß73»í^ÚÒn©Ü/VÑIÐDÐÔÄĭЉ‰1áÁø¤Qc0>h4š(O% Æðà%$ ƒ1"‘Q¨(¥…²lo,Û½ÍÎ|Vl·éÊ?9™™sÎüÿ9ç|gFXk¹ß{Þg:Î]ís›Þî[š>aM4οA8V¸ò£×P~²Y®,1÷¼øîÌÀÝ‹D:ßfÿ»Ooºm~çm "^û2E,©qÜjºQšR¯ýò’GGu~¼|ú¥‡_ùl{Ðÿ&'¿ÕðÕXcÀZ|ðÔs‹æÞ¹{y—"Þâ@ëhè$CÂï'Ñr”öe¡¼xbEÏÁŸY(à*ÑTWätü°ï–ŽøŸv® ‰7{жëÍÃV2X¸j• Ö›miŒ{ܺÖ'•XñúO_ÿµ kj*¨ˆ9íßÌ]nec¤€.S†ÒF!¯Z0Zõ™26º€¨,1…"œûÕHá° u*øüPï’–Ø‚ûš[±H¬V? ®ÍjÆOcµÂ"‰'.ÓÞ2ù±¿ÜÛ1õZ$D«®›œ“ÄšT¡²N]§ß ••Åš€xKÏ“Bk–öž:ôoÍ…µ.£Cd0ŠÒGB¨5®+•ÅuTޝæ:­DĦ*˜qL-Âj£µ”)* \¹ˆtIS¼š>YT€Á(ŸÎyŒp0F`Œ¶ÆšÀ÷ë Ùb4A¹TÔá. Ò’ÍåY”äóEòù"‹R‚l.Oƒ´€‹¥‚F«@a ‹õB­' ¥BoörÒj<”ˆ°°£ O:,눱¬#†'v4¡Dð°"F.$›ÏýnŒÛüÀ3«@%ÔWŽþ9¼«0aÊù|œ®ë„c”qQÆÅX‡ ¸®n„\Îçú¨ ~95üI%TÓNi­À ­/¥Ç‹Çú/ì›òLÙ÷˜“Œã+?tÒEJ?tð•Üdœ âQ¸±g2ße&ЇŸhÃdÝMPJg>•îɤ'ÿÎ ‰7D‰56r½"08<®‚X¬‘xc”Üå"rC¿ö¥{´2W­1XLm°X•/TÎ8:ðòÕþ0( ÑÚœ$ ŠÂCYA Z›šðÇÉœÇ:>øV¹\9i!ÀX„©Ó"ìì¹Û…Ñë¥#ã#gÇ2DLÅím¸B© ²4:HDh&FIg&®Mäʽžc¯íèYe¢þ·HÇ÷7óñÁ^³ëà_:¹CgΜÁ ƒÄZ‹#£8B‘>}/cÙÜ9WšÜ¶GÌñýÍ lÕ¦–wêá·¶Ö¨÷MîLeÛwdxõâ\©±&o¨°fî©kïíÊ<¸å‘õý›î»¿æ§³öÕwfÛäZÜÕ´¥ðѹ“>öøæÅëÖ­«‰õ÷÷³mÛ¶¢?žoŒya=Žš fÃSÝÝo—Êå­ŽãÔøµÖ8ŽüR©àÙo¿ýÎQíÿtÎÿ­ «º»»Y³fMhhˆíÛ·¯¼A^7H$;÷ìÙóàÞ½{“3*('‰7{kíMÍó¼Õ¦R© •Jé¶¶¶Ï¢Ñh×̼Ù8o:ƒéèêêj"'NœÈÌ:ÐYfð¯èªÉ`I‘·%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_light_16.png000066400000000000000000000015731440571307300204540ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<_PLTEÿÿÿË­3Á£#º™º™£$̯7ǧ'»™»™É©*ɦ ½™Í«&ÞÅ À™›Á˜™Ç›ÉÊ ¿’ À’ Π Éš Æ– Ëœ ‘ Ã’ Æ• È— ·Œº™}/ƒn7ˆq5›2WWWWWW___VVV```$$$000'''À¡ À¡!ÚÁUöè˜ýò¬öç—ÙÁTêÒdýì“ýïªüñ·Ó±,þämýë—üðºüóÍÓ²-åÀ,þß[ýêœüòÉûöâüòÊþß\æÀ,ä¹þÙCüè“üòËûøêþÙDå¹Ï¢ þÒ ýâwüï»ûöàýâxþÒ!è¹ ýÜVüê¢ûòÍüê£ýÜWéº üÒ+ýã|üë©üëªç¶ ýØDýáqè· ×¤þÎ þÓ(þΠإ̘÷ÄùÅZXTWWWºººÑÑѵµµÿÿÿ8º{Y1tRNS’çè6çè7 ãhjŸ¡˜›VWÐÓ7ý9±²_a9;ÎÊÚÏoôiBÈBÊxMbKGDˆH pHYsÄÄ•+tIMEã KkÅÇIDATÓc`F&fC#V6(`ç061553çä‚ð¹y,,­¬­­,-xxÁ|6¶vööv¶Žü`'gW77wOA°€—·¯ŸŸ¯€0X@$0(8$44$,!1)!^ZæÙä”ÔÔ”49ŸA>=#33+[. ˜“›——›£PVÉ/(ÈWUƒ 0¨k ø šZZÚp®ŽŽ®ž¾¾®Žmî%„t`KÌ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_move.png000066400000000000000000000022221440571307300177750ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF°PLTEÿÿÿ3yË2uÅ3uÅ1o¾2o½0h´/h´/aª.aª,T™€¤ã€¤ã€¤ã}¢á}¢á~¢á{ŸÞ{ŸÞxÜxœÛt™Øp•Õp•Õp”Õl‘Ñl‘Ñl‘Ñk‘ÒlÑgŒÍgÍbˆÉbˆÉIp³Jp³Iq³Dl¯Dl¯El¯Ek¯Ag«@g«@g«Ag«@h«@g«L?<>‘~îtÆàÐsØöøêëð þ‚#£oa Ô÷±ñØ›[&>>Õ¯ Kü/±¾¿ Ñçhßh¶O5Š—%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_move_16.png000066400000000000000000000014641440571307300203120ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF/PLTE555ææædÈJdÁPiÏHbÀJb»NgÃE^±MgÉOjÏE^²;Jª;M±HZ¶EQÂEUÌAQÁ>J³?JÃ@M²?HÂO`½CNÆDJ¶CSÊEKºDUÊBRÆ?PÀ9M°7Jª3C¦;G½Mõaw!qƒ ~ÂWˆ¢±xBü)žL¥erN(ðL6  d…JM‹\¾ Ñ2BÁiŠ¥2ME¡Z«7š-‚hw:ín׈L½þ€f8$Gcr25#d™QÔ|±\®Ö›õÖʵÙvûýÀádߺÇãÀÍóxOçóóýªû¯·û#ð·°ç+Èc aßðÎU"`P™%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_next.png000066400000000000000000000042151440571307300200110ustar00rootroot00000000000000‰PNG  IHDR szzôgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYs  šœIDATXõ—kŒ]UÇûqιwÛ:ÓíЗ¥¯q …‘Blj ‹XCÀøHŒˆõBÚ¨Ã?h£b‚€PˆÖò°cI(A(efڙδµ¯i§óºÏsÎ^~8gÞ¶ع;ë<ö=ë¿×­ÿÞ[qñMßóØþï Gj‡Òz~6“AFóEŠåÒéÀz<ñýÏþp—ðMì%ŒÍÔ74üú–O/g¤ùŠ‘P …rÌüCGŽìž —@_ä8uÃwÚaè “€ˆ Ά1ËšW°õÇ¿º!}uÑm¶ÁúîÇÞøöH¤wNõH¾H¾\Âó«ðô„W^¡ýÕŸrpþÿíá Éî%4.Øðù+[n½ï¡EKW^±té2–7fyë`?öÜ8ªÔ52MçE Šà_O®ûú`ïË´·ÿœ{cÀàÅ" P Ôë·Ýµ¹¹mÛNC﾿=pðù_ìO)œþ=oëÏØsçÐu^ÙM{ûÃãÎ/ñ¥œbà¥e{YÚÎCÌ~ð˜{óÃt\ׯîåüK÷óE oÌ9\ÚÙp,I/¤‰z.}^ÊÌXhÓÐØ×ÎðK÷óeàÄdçc³ú$Û\ 9è~ œ<à“àUéu~ºs€ÿ‡Eµ?úQC%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_paint.png000066400000000000000000000030001440571307300201350ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYsÄÄ•+IDATHÇ­–mlU†ß3»3l? »mÙnpKƒÅZƒ‚ò‘šÖb? òQ¡1*‘HR@þ¡b&šXc¢ T"‰úƒñTƒPB«PC,vgg·ÓÝnéÎÌ=þpÑb 5†“Üç>ï{ßÜ9wÀ̸ÛJOO—œNgiFF†2VïhKÂeÛv­ªª?!Þ«w´S@’$=77D´øÿ3ßµAUsÒdÙ¡+Š"NŸù»,Ëû¿ûæËîÙ ¦L&Ý2µììlÇŠ¥5‚©M5 kwÜUu YîÜ£¥¥OLv8tüø1<µ Tz¸dFã’¥kþ“ÈV×5d†Ã‘¶7®©xfQ ‰wuuA‘eÞüòš?ïñK–=¿Šªv¹UM÷ª÷{þÍqÞÉy89º¾~å“þ¼Ø^7LÓ3£ß0 8ØòJl[4–Vo,NJÅp¸T° Tî;‡üÒoß¾zuÔ¬®kÈÐ4ýè õ«*òórˆòù|˜QTDn·ç;:Ȳ,J$¨~í ©ª´¨6 !r¬<n5„u,PÓì!°º®!S GÚ6¬_UáÏó‚öª*{½^TUV2áô™3‹ÅX×u¾víÖ”óò9Yœ= f–dF†·ÖжÛVÕ5dhÃb!^U…×ëEÖ„ (œ6 }}}èìêBã®]…Bè½~—.]¼¹3ñììL¤?ƒ@IƒWúݤHP·vÓðXFÀEÁ‰“'¡iTUÅ÷§Náò•+ë:‚¡º»»1Þ#X6' iý@`’1ù¦~ù>iÉÒµMÓ4l\³  yU•RpR…,ËB  Y–ÑÛÛK‡†’I2 Éd’©§§µËÑ× baƒ$‡d&“œñâ²²ù•L/à˜aP¶ÇÃÃàlYbñ8•—•ñÖ-[¨»»›‹fÌ@"‘€iš€N'Ün7uýÒÍ7úlÀ$0³0ÇI®4×ÕŽŽÎ9(ÏçCŽ×K)8,Ë¢x ŒŸÄ˜ff¶FŒŠÖC-¶Õïìi IN’$Á¶í;ÆbÛV ä`„{Ï´ÀB 0ÛºiDG¦GZ?í0-«ºù@‹6Ñ—G.—‹ü~?L“éV,·àBØÿ¼ZÌç l3f"vÇqýÕ‘ÏÎ[–UõÑÇŸ QRR‚Ë85ÛCý±„ökHó¯`Îܲ²…‹Ÿ»þÖö¢ø¡ÇNK’cÖX{ü³7OÏyÐåL÷*c¾É ªg‘$MèÁ!ÄcnVSýþ^ùí%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_paint_16.png000066400000000000000000000017401440571307300204540ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF°PLTEÿÿÿ ()/ 8:GABLABK%&/9;HRWgVXb?AM9;G8Lx'Gˆ#E‰"J’WXc"E‹"HXYd"Eˆ[]g4i<>K2f1dMOZ"?x1dMOZ @2eMOZ B‡2fKMX  A„,ZIKW 69u"EŒ 2"E!!!"""ˆˆŒ§§ªŒ‹‹»º¿·¸»ÎÍÍ***ZYYöôôµµ¹7=P$R™!Q Ú××ljj®¬¬ÖÔÔªª¯7>Q$Rœ!N›¸¸»ñííbaa >>>«ªª¼¼¼¬­±#QœÂÂÅÓÓÓÚØØýùù€~~FFF’‘‘©©©ßßßrs|(Iƒ333ääåäââòîîôððÕÒÒmll‰‰‰™™™½½½¦§¬"L”ëêëüùùôññÜÙÙ¼ººž¹¹¹ ¡¦!K–ìëìäááÀ¾¾Ÿžž"L™Ø×ض¶¶–––ššš$M›ÉÉÊÁÁÁ¡¢¦$K˜àà੪¯+++ÿÿÿ¹éaØ5tRNS­ò-Ú®¡ç*G÷ç)G÷狪vGºGOG™ó·º‡ú¹Š;ð³‹멌 Ì‘Œ küIy.abKGDˆH pHYsÄÄ•+tIMEã KkÅ×IDATÓc`F&fÀbÊʆ"ÀnfÎÁ‰Äçâ¶°´âá…óùø­m,lí…„E@|Q~{G3'gW7w1q ßÃÓÌËÛÇ×Ï?@’AŠ?ÐÁ#(8$4,<"Ò/JšA&:&6(.>!1)9%5-]–!#3+;.'7Ï)¿ °(£XŽA>£¤´¬¼¢²ª º&C¡V‘A)£®¾¡ÌWViRZ«–ÑÜÒÚâ«k´k‚¢•ÑÑÒÙäkët낪—ÑÓ äëC¯××§¬f™:—4Ã.ü÷ë%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_pan.png000066400000000000000000000023471440571307300176150ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYs  šœéIDATHÇ–MlTUÇç¾™)ý`(- …ð¢ $hE3„hTb\uAb0]©‰ø…qåW" —HŒÄ7Tc q& ¢å µ@i;m™Ï7óÞ½ÇÅ{Ó¡M¬'yÉ}'ïþ÷œÿÉÍU¥™L†ûÅëÒ=]WîhX¿²CG‡®§_úæïâü½Ùlvv- îý`àíþ]K»»¡Kuv/oÛòÊ>‚;ƒ :L¹XÌoèípAµ–ó …ŸœN…ó÷šÄÑ·ú—ttu}¿íõýÛßø¸møÖ]ÔÖp~€Ýï}–ÞüÜ SAꡱiõBMùêê‰2­©Ö˜:%EÀó eç¶,€êTCP¥œƒ jgóë×õٿ輻S¨{¥nV€o~Ôºòá/¸-xÿ,êbQµÑɬ­[RÐÓeäÂíòÎEDÔQŸ6UU1 ã¥TR‹DŠ4©E\½uA¤?O3qïËÞMÅÞdKêÕw3}Çì|3ƒÛ§&;‹¯mU0/æŠûúú7½Ó³fÃgÿÜ=6sýµÈ‡ªåɧ¶¢.ŒÌ‚ÑlÜî1¾ W zSíËèé{žªjâ¯+7¿A£”/B¢…j©Œgà™[#ãë~ØðÁ€¤èÑÁÁ /v¯9‘XÙ·‹þ¡««’b ÆqVuÔÂØXk±µƒãÙ§7âl° `Ž!ËÛ“'&&¦s7þçX»ùqÚÒËÅAŒÁˆà‰Á!tŽjh©Tò—ÃZi@uÜ/”ŒŒR>EÏ#;X½ù TbñÀxL 3F0O›Ó漚..kóOMNUË3w(^û¤Ô¢^zF " žAD0bðˆ!žZE{ÿ QËý”òø¾OP«"µGŒÌž\Œ &šL„B±Œ¨›l hoMLІŽ*ÙrJ¡‚ ˜D,,4ZEazº¤FÝŦ€¯/v„kW´ž”Ò̾ãÇNú•Â]ª~‰Ç­#„H\ÉUWu&l øül›¿biê§ÜØÄ·ƒgÎ9Ö¢ 2DÓÃðâŠ<¡R¨TkçÜèÉ„Üêh‘—.^ÿaäòU @$6·©?FÈ}$¨Ýüÿøê|{Ø“N]ZÞf>=sæR®43Cä*4†QÐÈgÆ'‹hX;"2 I|q®=Üûhihh<ÿë±?†÷$R7£ëÚi㊠ºmLJnäÒžþ|àr§¿gîT>ø·%›Í’ÉdÖ6;P6›^(ÿ/ô°þSúçá%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_pan_16.png000066400000000000000000000015671440571307300201260ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFzPLTEÿÿÿĈSÈSŇSŇSĆQÃ…RÎVŇSćRÃ…PÁƒN²zK™jCÇTÄ‹U¾‚N­yL½N“hCĆQÍ“ZóÒ©ÇŒPƉTí˦ƉNèµ}ƉOð˞ƊRÃ…P뻅ʼnNʼnOå¯nÇŒQë¼…ÅŠPå®nÆŠPíÓŊVňNå­nÅ‹Qâ¦`ÉTíÁćMĈOä­mÅ‹Râ§aÉŽUîѰ„OìÀ‹Ù¥sà­uå°uã«lÄŠQá¥aó̔͡aÀ‚M쿊ڦtØ£mØ¢iÞ¦hâ¨gîǛݭ|½~I꼈۩uÛ§pÚ¢kØŸeÙ`Ý ^Ù§vïÇ—ëÀŽè¹†ß­xݪrܦlÚ£fÙ bØœ[Þ­|â°zà¬tߨnÝ¥hÝ¡cÜŸ]Ûªxä´}â¯váªpߨjߥdÜ ^Û§tç·€ä°wã¬ráªká§eÎ’XÁƒP踂ä±xá§fŇTÿÿÿ*'õ tRNSªèJØú¤¬`ƒûá¹`ì×.é”éH- 3›ß#ùbKGDˆH pHYs  šœtIMEã KkÅ¿IDATÓc```&)fÅ@šEJZFVŽ!À&¯ ¨¤¬‚PUSWÔÐÔbGh«+êèêésÀ Ô uŒŒMLÁœR\ªf抖VÖ6`n[;{G'gWˆ€ª›»‡§—·¯T€×? 0(8$4,<"ÀŸ˜àHŽŽIIMKÏÈ„X+$œ”“›—_ u‡haQqIiY¹Ìaâ•U%¥Õ50FIú¥Ë#Ý2Óªè%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_preview_locked.png000066400000000000000000000021661440571307300220400ustar00rootroot00000000000000‰PNG  IHDRàw=øsRGB®ÎégAMA± üa pHYsÃÃÇo¨d IDATHK¥UÉoUþfñxÆÎ8“8Žã¤[Ú‚K(­ºW RÛR%N$$$8 wNÜ‘\(eQÄ!.@€ÄR94‰³7qZÇû¬ß{c;“TDý¤/ö{óÞ÷ý¶q$.¿ÿí©AÖ |±~¨DE•–n¼õÂ<_sAåÒ»_~víÅ3Wc*ühPàÃÏoßüê—®ÒÒ—éìzŽöôãYV©áÓ'¿—Êa&Ÿƒãùî% ‰R„©”ê¾/V ÈÜ÷`ÃôDs:_tKQÒÈ.À€>|`&â&bTžþ&F øB¡üàAÉïÑÇ1à RøÊd_*Œ ‚”W"nÁô@C“î1q·…J;Ú>Œ!€õà/L±9\Pç1­-b&¹‚s±%¤ë¨R_èZês˜æÃJ´õ'ÎX-ÈNÅâ"æþ¹‹Êý&­fÆ<ÍŠÐéE×€C¡/Ó^â²[CN*Ã÷=ü½\BÁÏ¢ ÀíÕ: EXº ©µÆG²]ž™(1N‚ýå]GÚ±±Y‚=x£§Îcâ±)èGÎb~£ŒÀµá4*¤Ã„^QZ‰&sö5W–(2ª1£"ë) ‰¤ÈÁL§Qw|ƒç¸t&Ôë kÀ÷I7Ì‚¾ô“OŠïV!y è¬ÝÛFÜ-!ÁÊ€Wsjô¬!CD3àb´£qAþÙ¦îlãtí&òÉ_qv¬€gÍpÑ»!ø”ÿ.å—‘ ~Ä“ê-TæfÉcׂ’ß…˜"ä%ê9¹±ŠãÃ;V¾Æý{KBÀåµß[Y–`›i›ºŒâoŸP£¯„$· 1¢´'Û^*Ìä·×bÉä`š&æ\üò{-[ÆÐÈÌ*óàÙÍHtÐÍ:~^,GøÇZ.MQàp\‡~Ë,¬¯¹¨Õ}x´çÓ3æ7áù¼}ÂxÒÒðöô^?—ÂçwùòIÄ%<Ø­&ÛÁ…)#ƒ2¬•‡ö<—&È·… TaíŠñú'¨«Õ©—½ÌmB×;„‰Ã'aÑÛ;< !;>ŽLöÌA‹ÊhS~(Ö†0P¨IÜD4y/RŠÌm¡Ù¨a}ek« T.ÇNh(oobc­ˆò6½la‰T®×†˜"j¤ýêG·ýÓz²ë"Õ,àÍÓUd #ÙqŠ…øÁ®ƒ¬j™»÷è½°+wÚÄJ&Ž£Moã™|lò½W&?8:‘8ê9v¸Ù¿(jŒ¢—ýo¾[˜½þqù5ÚZ&zc<n´âמ7žJHyÊrÏ $Vÿô§Öìò–wÄÿó?Ñ âawøO)SgNS?“ø‹ÞÒIEND®B`‚leocad-23.03/resources/action_preview_unlocked.png000066400000000000000000000011721440571307300223770ustar00rootroot00000000000000‰PNG  IHDRàw=øsRGB®ÎégAMA± üa pHYsÃÃÇo¨dIDATHKµ•½OÛPůcdž(PµÈB¬…• ¡veãCBÙ;vè_Ð ¤®ül*µ èR&6ÄÊÐ  ¨ª€‰$þàœg‡ÆNhôqÄøÙïÞ“{ïKb´¼¾7H0Ö|µîE0-ã|ûÓü ×Lh.¬í~û°8]Ê[|Ü›,SdcëhççêR K?‡¹†W·ß¾“þaW†F]yñRÆF\y7éJÝó_ÑK#¢RþTë²v'f޾z ÂPfÇ‹2ãöqñØêD&vg@úFµ)8ƒ’G{ÒCLpab7êÂ8¼´)aÀ™ @%ºð|06­„ß……;vòb¤zÄ{J˜sTfÆYŒE6æiգŠlS§ÝPí…Iª€| ZlîÔ†§p[›ëj€•2I ±]+öDUàBÆйšJVÀ͸cãµS+þ«æÀ“§ˆRï"Þ¬[„8Î ­6žgZÄFŒO{$ øô÷uUOËzœ•åø²'i—=÷ùûn¹R k^ÞÞûá]-ˆ»oà;š[Ù:@^‡É£ âºØÿ&Ö>iƒ8«yŒZ¤ Ìø¢†Ü#”Õ2m^ÙKk?¾‹C%h´ža]1¬þÞ\lþúòþ#–5uL€× 9ôlòÁ¸^³¶Ž¿YE/º|V‰<„Áùbä^IEND®B`‚leocad-23.03/resources/action_previous.png000066400000000000000000000042211440571307300207040ustar00rootroot00000000000000‰PNG  IHDR szzôgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYs  šœ“IDATXõ—kŒ]UÇûqî9wfÚf˜é:3eÚ í´µ`„4J„áA_$F1&jI+ü`¢‰|P‚m+_T* Ò‰ ¶¥Ò¦¶Cã´¶S:Îã¾Ï9{ùáœ;ï’ÖÄ»²îÙgŸ½þký×ÚÅÅ7½ak÷c#‘Ú¤´ž› D —/R,—ú}ëmÜö¥~¸‹™LD°— hljúñúw0Z„|ÅH(†B9fîÁ#Gž¶…K˜}‘ãÔÚ/<½"Âpv(L:R/Ä9Â0æªöEÜñõ­M_]t›i°~bë[Ÿô扡ÍÉ—Kx™<Ï#ð}|ß'ÈÌò½'Nb´àˆ$<KÅÓ ³êŸzî³+¦QóA MÏ®_µˆ\êB$”B¡ÁžC„Q„Ò …®4Èk¯%(„‰”BG®Í;|ìØR3)ËüVݧ>±~ë°j¸ïÚŽ¾G!„|è(V¹²#Å‚&d†ž÷ްª£ ð(Tªããt¼&>»ïÎý'ðÆ¦»·U#Q€ô­›þp÷ƒ·,Ûtukëò’öøÞ¯ß¤¶&Kñ§…úh_ÊE8¥0$[WQjl¼ïùø~Ï X³¨†¬„t:ÂîÃ'¿ÿ«/¯{RDâ*~Ksãïæ·Ô’ "ÎŒx¬ZÚÉ©3gˆâpœ3Àyðæë¨ˆ"_ò¡Xq —"Ž÷!—f'8£-uÙ,ç BûÜ2÷^?}ǾlrUÙÑbÄï÷ŽâÛan^RË£màøðÕô s¤5=:J¾‘ÉxI¿Î9ho_Ä‚¦ç ˆ´Ô +猖‹tõÀ@Á0˜‚‰¬VàYE%Rl?ão=y–_éó‘… •ê86d‰ì;~š÷Î d‚ÀÇÏd2‰ö<ŸJQ -uŽUsrT*vN(ŒVd}QjRùUVk­ åÈÑ}¬ÄîÞÓ\×°bÁ,Šª‘5+—Òsò,q&µ&àhm©ÍfiÊ:V6VJìêI [cÈx ­ƘiU0ÀZM´D4V„ØÁî¾ o`é¼aîZÖÀ­Ë:èL²]ÆBíXÙñH*k¯®T½Iû*$G¦\îý¾C¯þüå‘|¡·ì7¬™=»ÞÖd³ˆ$¹ •BÐÌ¥ÊØÛó¿©“¾ó¯£4`@™4ËÌdižõ!¶ïÝ͉×Ùb¦röðîÞmßú[×pEM¨3Ùšj‚ªË´Ì²Œæ œéï¢bö0»!FTbTiÐÔ©>××Ìgç;‡é› Úb äü‰·_ÞóîKÏþÆ»rYGEtëe —amr&lžm°A–9M÷ò—¤þò³45‚èÄ{Ï/v‚˜ Ôuìzç4½;Ùr¡‹‰¤ B’“Ëù¿~÷Ñ óVÜxMÿ}_}úжŠÛÚ®¢Pñè~÷0èí~.÷Bnˆ{î\Ï5mm ]?}¬§®Ú”Úƒg––à \ì%µ@#вüžÇom_sÏfèízqãŸÙ «7°qݽ¬Z²~öqr.’9‘ù¨ûvˆz@ëEâÜ»‘Z-¼È¼ô©õ5îÄ`æ Q:—„3‘yáÈ‚ÌR HÞJç¾|ì¶Ç—nÌ0#É9áœPŠ&¡À*™”ùHDpjÎ)ɼ“2¯&äÎÑŒ|Àp€sй –.KY†(b¢{"xÈ|ùÏÊM!%RLªä"s›°ÿøò^Cò(E[ü'zýt´¥J–ØÙ¹o—aæL’–¯%–®Dœ%¼“uVQ^Å’TÆîލ7-¹cD’¼K… Y"x”à T+¦X8$0‹rÌ$R"¥ôŸ çHeXZ²Òy[Z²2ñÎŒ/þlΊ(žý·!¡”ÊØƒ°2‘8g® ˜OæÌa1&ûDð¨57Ú[±Ú-S%7«Õ#ãƒ]<òô,ÏOŽ[,DQDR4¤$5Däœcbb²· 89•y‘©[äÞÝF%” ­­;Ifõu`|¤Sä¡©YŽÿðCH& HP…àéîÞÜé6ÞaΉ"!l|—[ͽ³çN]æÀ‘¿`”+ݱ±þÍ8rºT‹w„àðÞ@KKÎðp_{s¹OÊB¤D–0mÔÇ/^\æ÷o,ò‰{FjeGßvn¬¬ñÕŸŸ³éÇGd©1ÙÞÞÊÐPÏÖ&àþ=†¼3 N\¹.ªÓòjã¯/òõ}c¬Õ Î_¼ÁHÿV.]¹Áü•U^xrŒeÎ%m¨¨³³'wÿ¯š!êMì†þmR{Uª­I·ÖÅwŸ9ÃþOŒp~y…ß¾òWÞ¾°À…¥«œ:û^>ôQ¼÷d™çkOÿÝò<3€³«]$³j ©Ù{ p.‰z)‰WgÞáǹv³àÌ;ËüùìEŽÿh €$ØÿÓÓÔ×Y¸¶Zð›7I–5õBV¢H²#ÁÉÌ„düásL?þA¼Ak昙_âÄÁqÚZ<7o%öýd–{†{¨­'Ö£øÂ¡SL<0èv«xû|$„D¤j.Ú«NÁCàÛûÈ]ÔÚZ"fÏÿ`®QPÏòÀh#;»˜_¼Ä¾CsìýÈ ÎÁ›€ÕZ"‰”CîEpɼCÕÜøìhN½^à{lXeBÅç¾Å'w÷1ÐsWCº=ììî %<{bŽÇ&j¿n²ä}Â;p±LÏ|k‡Š¢ 9+˜:zƆ·´±}KG³ñŒlÅÇ^˜ã3{TŠšXT¢i´Vý€š¨ ’@ŒiRkLŒ­|©i0ÑTI‹‘J[?TåÑ Bé ÃÀÀó€;sïÜsï9gŸ½·†4%¥ñ“+ù\ë¿÷Zë¿þbãÏOŒŒ»•ÿ+NKÁc¡-ë`,“u…#%Gk4ß±¼ñ‹u¸Õò­ëW.aKO'…¬ƒâcÅË¡â·úîc…6О/ ,ÖòumÌ®sâ^sþö£ôW÷^ÂÚìºEíŸükp ÑäM,Òðd{sáÏ“uE”èß ÁN@4M¦µÒÔÀ_ž~üÄÙ¾ôì•ÛŸL` XXИâf 8®ÇD-ùÙæe<»m%]­¹ŸD‰:8wäŠË"•ÏÜ8¼ïŸ½—ÆP©Fܳ¾FÉ‘Wvsì•Ý\¹>²gUW~Uc!ËH9æ[,bn{þ õ$ÝûÑ|ÙØµTW}qöœ‡v<±eõlšó>ö^ÒÓÄ^ÃËÀixjõŠ¥2’‰šb¤ñµÏ,Âö‡±Ò'Q4Mбp-m=Ûöß7·“ùÍ„±Á">ŒÆñs¨°„ަüèÚ©Óç.Sª‚ïºT$ [·R%ü«¸³,®Nê²yÉ¢µÝ3I5˜; ªT#¦j1³:šîÌX#¬djè2×’”Þ~ò£×káö?õغEž¦RS,ìj¡1tcÖ§äÄÈЮΖ¹€$ÕcÐÚðïSýzç¼½1^ÆZcUŽ‹t}ŸÞ÷ô¾zxàz‰T§¤ÚF1«tP«Ç;¦·Hx[g¶æP*!UŠT)‡Çêë½ÚÿÚî_:zŽ‘ñ ¬I1µÛ V§¸¹féd[lxaÿ‹'{ß«…aŠVŠ0¬ÓÙ’¥^¯? 3M]³šrJéqexœ©Á#/„7Nï½ø¯ç_zãØûƦi=š÷ô¢“Xk„è±sû‡/_«Ç µ%Š ù @EÉ<о#\’”šÆD¹Jçâ ï4-x°\»°ëê‘?¬I+Ã=Ö¤è¤&Åb±€—o£V)ÅI JIÒŒu‘vZo²^íÅú¤‰$U’J%!œŠ†¤“;¹äá$nãÜÐZ{¦aæÒ‹BJ¬5` ÒÉâ¸>&UxŽp´‚$™F¦ND·/õ—Êu´$ €CC.Û¡üg#Yñ¥gIU¤db êåó<¾óu23“ï\F¾ëSÝmmÅV‘ZTZ J“!¦š`´ïðè­Û¸®‡Õ†Œ0§8#[­%;ãZ‰›×YýÐ÷ˆ¯õ#\‹EEºÖ|‡¹k¿IPܰ«{IOkà ´Õ¸®ÇÈØ(¾‡ääÐÑC£·&ÐÆ``-KæÍbþÌâV•ê=ÖZŒIï¨{Z#Öt×+ßž¿üï®ê^ˆ@` xžÇààe|×y@¢“±± oì¼B>Ÿ'V)Âsøòç6²pnñù(N^5Æ.¿ëlXÛÇÉK-m³ÿ´mëf²Ÿ(IÈd†® †SÂqÎÇË „³ºçìݼq=…B8ŠimÊÒÒ`¼Âɳ”® ×êqìû®3»³­ýþžîâòîÅÔb—±R„ãH¤#9xèu0µM^¾íøñ}OàÊ ªŽïë7ÏärϽðé «Édn•ëĉϜy é^<·Õ÷l+Öb…@iI¤$¥²a²ZÇs=ßãí£Ç˜>óë|Kçñ¤VÀqü8ñ÷—}Ç<4´‚Û7áØ;“•ÒSµñó'K7ûÆ+væm Åb'¾ Òi…'©!Õk%¾W®^æø‰“œ{ëÅç5µ+ÛT4^®¬eÇöMé7|h‰íhe¤[è™±ò+¿ì˜¿þ‘®®9tÍžCSc3~ ”¢Z™bdd˜kÃÃŒyïvÿïgŠïfŠ4tÜG¶}ÖhξöSÜ»mEh ”Òó¼æGCgÑò³oî8}~äóÆš%p„ès]ïM¯0ó÷Òx_`ŽwO§ÖZþŸñ_cÍB³ÿ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_rotate_16.png000066400000000000000000000021161440571307300206350ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFæPLTEÿÿÿ5|Î0yÍ7}Ï1xË8|ÌE…Ñ0wË7|ÍP‹ÓEƒÏ3wÈ8zÊA€Í2vÈ7zÊL‡Ð;zÈ5vÆ7xÆB}È9vÄ>zÆ1pÀ>zÆ:tÀE~Ç0m¼7r¿0i¶:r½.h¶-gµ>u¿-gµ,c°>r»5l·-d°/f²Cv¿-c°,`«:l¶Aqº+\¥7f¯=k´+\¥3`¨,Z¢?i®Gpµ,Z¢1^§8bª,WEm¯Nt´Ot´Fn°,W5`§0Xž/Wž?e¬,R—,R–c©/S—.R—;`¦"9i8l

l¶l“ÝT~ÇeŒÕbŠÓyžèU~È3]¤tšå…¨ìZÃW~Á„§ëFn¶’³ïzœ×Hn¯.V›Gm®xšÕ“´ðGn¶Gl³‰«íœ»ò©Æö¼ò‰¬í2UšUyÁl’Üvœç2VšÿÿÿØ'NtRNS¥ûµÙFæ•Ýؽ ˜H—.ýá/”à”ÕuÛûTÖúÅ–ûû ×XLÙ–Û Õ—4×L IÔ5Ÿ¡  ¢£ °åýþ±(?]íbKGDˆH pHYsÄÄ•+tIMEã KkÅöIDATÓc`dòf`ñ ae`cçà pq‡†A8/_D$¿PD0*(à %ÌÀ "–˜””Ì &ž’&*Á ™š–ž‘š™ÅÀ %–#à ››—/'_ Ô¬X˜W¤Ä \\Rª¢ª¦Ð(+)×dЪ¨¬Ò†¸@§º²F‹A·¶®^" ßP×hÀ`ØT×ld ⛘¶´¶™1˜·wtvYXZYÛØv÷t´Û10Ø÷ÖõõO˜8qÒä)uS€*¦uLŸ1sæ¬ÙÓœ]@z]ÝæÌ7þ¼¹ Ü= >Ö÷ôòöñòÕ±œ!Be#ø¤å%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_rotate_view.png000066400000000000000000000031471440571307300213660ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYsÄÄ•+iIDATHÇ­–ËoÝGÇ?gf~÷Þß½¶ëWüÈõuÆÁMHÚÔmÚ´‘pA‚JUšJ¡@Å„ʦ,Ü •h7U"TV<tÑ (¨BlE•ÜJ NbGibbljÛ×Îã:Žïó7sX\û† –i4Òhæû™sÎÌ9#§Nº øêÛÒäää° “““K_1déôéÓ·=Qx÷7‰½»•“–8 !fS—<‘Q"ëu|LeϨ*$pí–§R 8«DVõ¥gw·ëþ+€ˆ@S\U±FI»æ˜r*FÕ& ¨b¥)n›]*þó!@‚Ó\¨Á‹*ªª8ƒ´Å¨³È@d@PÄYÕÔö¬ÕG|ÕŒæX °vW5ED X#XÎÁV5B ø ™4¤,XLSÏ0-Àw'U‹/«÷Ð ÿâD5+ù]ƒ{ ""ªAïÜÜÝlÚ`éˆE#'BPÕ¦ÎY€¨ȤT½÷¨ª:£ª©dcÈŢ锕¦WŒ´Ç Þ£(ê"pVÕ{a[/“ȶÛâ¨*F”lZÉe•ßMejþ>><ê[€c£mò“ã½YA$`Œ¶ ¹\ ÐÕÌ.1¨Z‹@ ß§´Å¢××·xék=ë¥-¶ˆ4/Ii«ÁÏþü%™L¿™›uÞûd•—÷çxçõ~:;s}-ÀÔ¬×È*™”êÈ€òô>! ¿þÞ?ühžz=á©‘žGMžT$$‰ðá_W™øú ——J¼ýñoìëÈ›µÖ Ö*ÎŒQŒ "Hßc/޶so³BääQý¤8¿X¦\W:³¼ú\õû »öÀP ²AÓΓ²ŠsJPUPŠ>=[dâÐ>ë¥2Š4»OPUF2_ãìÕUT‡†øl>¿j·Ï=‰<= Fîv•Ҧʃ²òÉçEö÷n®Ýçg.q~n™ @ÒÀû@gVøè­1–VŠ,®”û‡{ùÓ”¾Ðì úx?ä{UÛc´RS­'Ê—×ìÊR«Ö¸øå ~|âqVVV˜¾¼ˆ Iâ·!†·O sáÊ jÕƒÝ1æ*c ª­ÜÛÏÞÀâòiQ­Ön—øÎ3=üê­ƒÔÜáÄ‘¼÷º³ïÙ½í¬­—¨Öi›bíN½½u‹ê‰JPU#ˆú ÎZ1FѤAµ*¡QÇôv¤øå‘$^›éña²Ô¤A­J3ú- ænx—=KÅD·ª\F5픡îˆÒF™F:â˜sWî"¢ˆÆ±V°Ö`Œ0³°AGœ¡Q‡R©Lw6Ùl¶*J%P«+Þ+Î zôÀ.Šëkì.ð‹?ÌR®œ³D‘%ŠÎYªõÀ‡¿½ÈèpŠëëIßl"ÔÚ€5!x¯Iâyõ…Ý\¿>O’xF†úéêêãÍ÷þι+wI<4žayõ6ƒý=S\t+ˆ tPAG‘ƒ¨çbµ½&©½[îýÝûððÞpš¤¿¥·ù›\­/¶ílÄè,ì\­Qü7å#Q€$ f#] Æù`Ž};l|C ,†xÁ µèÝÑ( (qh ƒ@°ÀabIb,ùÁðµë©ï±ó¼ úÉ(¤\é¶0ö¾-bbN7{k?÷»ï®ì©ð±ò» öÃ(ýÒ0â±/ì¶+ÿò˜ZM!j[.þÀò±í¨ î¬ó¶ö¿!øÈ(à¯/üë—÷Æ$úÂ!ø¼ó±î¨ ï­ÛšÂ~#À~"¾~$¿&óÃ$ïµî®ï®Ý›Ýœí¹/ýí™íº/ßõÈ'ò¾!Ó~ÿñ›öÉ(Õz"ñ¹ï¯Ð}!øÌ(ó¿!Íy&ð¯æ¨#ð±Ñ~&Þžáò® ó²ßž¼r$¹p$ÿÿÿ¤[^4tRNS¶¶¯¯®®®®®®³® ®¯¸¿®Â,®Á2¿ÁÁÅÁGC?.¿Á3¿³ÁÁÁÁÅÅR1º­bKGDÿ-Þ pHYs  šœtIMEã KkÅPIDAT(Ïc`@LÌ,L X«‰)v3s KNv q.+k[;{n4vG'gW7w^&>O/o_?ÿ€@~d àаðˆÈ¨è˜XA$¡¸ø„Ĥä”Ô´ôŒÌ,a„ÛD²sróò ‹ŠKJËÊ+D•UÕ5µuõ MÍ-­mbp7‰·wtvÕu÷ôöõO˜8IB&.5yÊÔiÓ»{fÌœ5{Î\i!ˆ¸¬Ü¼ù .Zܳdé²å+VÊË(0AÅW­^³vÝú 7mÞ²b«¢Œ;L|Ûö;wíÞ³wßþ•Åu>²áè1eUU5u˜¸Lü¸¦–¶ˆˆÔ|'aâ03À@÷Ôé3g±ˆ3œ;áâ¥Ë˜â W®^»t½á†8ƒÞÍÂ[ ·ï裋3¨ܽwÿ!†8£ŒÑÃGƘ⫃S˜ÍI%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_spotlight_16.png000066400000000000000000000013561440571307300213610ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF#PLTEÿÿÿOQTRRS9DU=AL„…ŒKKMã„ÿÿæÿí67=OhjrHIJÛ‚ÿÿäÞzÿ×/ÿÑ"4;OOR[DEEÛÿÿÝøÑ*Þ ÷½ÿ·19KRTeGGHàÿÿÜõ ð¸߃&ö² ÿÊ9>JBCE6CW,9UýÉ!ðµíªî®á„%ÿÙ)/6CÓ|*8UÿÐ%õ¸ï«ð¯õ¿þÓ,Ù€ ÆqÿÿáýÉ"ô¹ð¬ò²Æu%Çw$Êy#ÁnÿÿßõÃñµï¬ò²Âu$½mï´ï«½r$¶lÿÿâó³¹n$²iûÊ$ñ¶ï¬´l$¯i!úÂô±öµ±i$«h!ªg"ªh"ÿÿÿÌ%ÏtRNS3E¦¥ÈbKGDˆH pHYs  šœtIMEã KkŤIDATÓc``„fÉ`ecç@àäâæáåCð  ‹ˆŠÁÄ%$¥¤edåäa ŠJÊ*ªjêPM-m]=}C&ˆ€‘±‰©™¹…¥Ä k[;{G'g&ˆ-.®nîž^LLLwx»ºùøzú1ALg`ðòƒ | @pHhX`8ŒˆˆŒŠŽó ±qñ>Hb: Éj¯¨NÙ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_zoom.png000066400000000000000000000035321440571307300200200ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYsÄÄ•+\IDATHÇ­”kp”ÕÇÿç½ï»—d7—’°!›@‚Ë&µ†:…‘臢T,-Z;¶;AZ§íر­3©ãØN+~°´Ú©6$1)P@ eB²¹@²$&1löžÛ^ÞÝ÷Ý}÷=ýtŒ¡­3í3sæùrÎï÷œç™s¥Ÿ'޾ÐâJ*Ê·SвMÓ2n6qIe‹å¬Õjyý‡‡L~öùo‚_ú­) è÷6oÚ$®[·%%_€( д ‚¡0FF†Ñ}érÇJKKŸzbÿ÷ÓŸKðü¯[Vøýþö;ïl¼ë¾íÛ14t ž~|ÓÓÈhÊ q®,ECCêÝõ8ýîi\½Úç)++»ÿG‡øÿ£àè /I>ŸïBsss“»¾'Nœ@’1ÍÛk›æ’²¸ šr¼®²¹è´50ØSšKÅ{Ù¯÷ººº<® ׿Ãæþ]õ33Ñçêêëšjëjñû?¼bX¿2.WÝž¥]`X*“(¶²¼ùWõ‚2Ö_xìÕcÕíû‰„GFFŽxâ¶7xæ—Ï9c ±±'Ÿ<,?þG ¦×n ¦YÉ2*±€Ì"@$ª£*37ÒSìíé^»wïchiyQ+,(XËÜ®ú”¢<êv7Hã˜Ï"N×o ª‚Ù°H5‹ f°p€™¬"¨Eâ(Ù¨t7…EÙ:çõŽ ÁÝ &’ÉGo/H¥î^]U…Á~8Ü›*'S‹@¨Ì/Vmb{+3€Ì&‘¡„“hã†þ¬©ª†’T¶-üì™gY]×kŠ‹ŠáàpºRvÊàò9°äÓp‰Ä[™çYêtUÆ~?ŠŠŠ‘Éh5K†|äù£$Ïfá#á°•x¨i+ò-|‘ FZÜ™ÓsÈP #È}  €gÑlÖU- AàJ­KzV‡£ÀÁ@†°ðM~˜_ZZŠp8„¹™èвLL³MNtŽŽzQWçÆÐ¥ öœÕ ÐE€³00ÛEØì³L0“u7Ãox<}Šse òÌ&ӥ޶|UG,e eYž€1±DYàò™Î2ÔVQá‚§¯/ ‡þ¼L Ø«Qè~dciäNµ·á›»wc| §ä\ûÉü”†•"iPdYp Ï€ÈäRgGyo÷…ʇzïtœB¿ÇÓÂrlhÉKÞùTIg²; ¹üý; …+]¯Ãµ²Í÷Ü‹“­'1 j[¶5/TUWk&٪ƒ‰ìøØ˜xùüÙ’"GùÁ]âü¹shmm}¿³óÝÕÕkŸvì‹„‚¾ì«·¾yh÷jaN ÅpíBž…î¯q%þ>>ššB<‘€ÕlAyù*¸ܰÛxû­·qñâ…‹ï´ív:Ëf“Š¢J)îü8 };[ÿrhO˜È‰ͧ¨¨wRœjo“¸žýÒkù;Ö­C™Ó I’ j*¦}ÓñzÑÛÛŸìííùÍ`ïË«5A@²ñxŒr_Ýû ‰FÛå_~óà·î†ˆð‚†…9«WÈèGïD÷Èß_Û74P{Ÿ«¢r‹ÅbYÀB #™‰^Ÿ¾9uñÚÐà_ÌJ’)“Éfu-¦@î>¸¥¸rë{öm”Ò¬ ¡y ó³9”ó˜Cûé÷¯ôúÉ×ÇÆ¨žäªªª„ 6H¢(2ÃÃÙÁÁÁŒ¢(:ãx]׳9ú©Áršj<üÀ=k¤ oChv¾ªˆÇÔ¨ç¯öuü|—ÃY3›ŒrVÉœe&ã÷ûÓ‡ƒQ%g³Ù Â0¹d"ad³™e?œìî½òϰ :æçáþ±ëèh?ãé9ý쮢²Úð¬¯G×â~: å¼^o†RªF£Ñ”,ËZ È$âñ%U6\5Mß}ïñÿ¶}¡¿úÝt㽿øzJ)þ×…[bW^AMk]ÓÞù5ëwöÿ¿à”Rü NXeѳ‘%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_zoom_16.png000066400000000000000000000023441440571307300203260ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFLPLTEÿÿÿ‡‰Žvx}motmot‰ŠŒ“xz’—tv|lotwy~‚‡x’ ‰Æá”ÔòËᇗ¡‚…Šnquw’ ÒöÕüÛýÝû³àõŽš¢oqvz|€fhmŒËç†Ûÿ•ãÿ¥éÿ±ëÿºéÿÂÛéfhmnoseglgjn·êÿµîÿ±îÿ¶ïÿÁòÿËóÿ×ðÿhkoegldfmdfkÒçòíÿÿàýÿËöÿÎõÿÕ÷ÿÒåòcej^n‰LNQ•£þÿÿþÿÿæþÿÙøÿàùÿ“›£HIL]xª3Rˆ˜œ¡æíòòÿÿÓåð‘™¡,-/Y~Ã@oÇ9:>]~ÂAk¾qtw89<"#$=[£+<_=?A\^b^ad\]b<>@ >Y¥$7l666 "/](7k   !A1;n"A€…ÇÈÌðòôûüþ”—›íïó«­°xzxy~ª¬¯ìîò“•š}ƒéëð…†Š‚…‰æéî|~ƒº½Ã¦©¬£¥ª¹½ÂÝáçtvyqtwÜàæäçîâåëÙÜâpswnpuØÛá·¹½ ¢§ ¥¶·¼vwzàâæƒ‡€†ÞáåuwzfØŒ•¤ˆŠŒäå鬮±vx|efkvw|ãä爉ŒjŽÕÅÛûŽ±é‚Œ¡stxµ¶¸àáãðò󴶸h‡ÊÈÞþ“¹õ®Æò[x¼ÊÛø”¼ö³Ê÷cz¼n€¸¼Ìófx´ÿÿÿrb¶ztRNS9¦âû9—ýBèÊÃÊç?ªçÂÁÁÁÂæ©çÊÁ¿¿¿ÀÈåýþÑÌÄ¿¿¿ÁüüèæèÚÅ¿¿Æå¬õðïÓÁ¿æª³öîÚÍçC£’žþ’’¤¢ÝòÝ¢D ìš  Ÿºñ¯sƒD˜bKGDˆH pHYsÄÄ•+tIMEã KkÅúIDATÓc`F&ff&V(`c¯ª®©­©®bç€pÖÕ74r55·´rƒùtIMEã KkÅ€IDAT8ËíTI!ƒÉ DI‰C®Mêˆ;çÆÔÞ{㌉gÞï~ê¯÷‚À˜:¥h¸÷o;§âäÔ &¸%Q³}O¨i?†Ðí±%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/action_zoom_region.png000066400000000000000000000030521440571307300213600ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYsÄÄ•+,IDATHÇ­ÕMlT×Àñÿ¹÷}xÆÛÈA`#“Œ1†ú'”6…@¤(­ZÀnªª¢†vuÓ.ÝU·•@ªuÕEÕ`PHqšJI«C ±±Md@†àZ(ÅØã™7ïž.LGA˜,Ú\éJOoq~ïÜsÎ}²ÿþë@-_ýšìîî^íµÝÝÝ“_12yàÀZïþ‹Ú_þ® ‚cMÒ±Õ’Á9ÇÈ„c`4Æ7Šocm[§’^ ªJTp\¹“Í:<«øVõ™5Åõ¾È bÀ±\U1¢øV±Fñ=AQ]bç°²Ü.nùbÌ" ‚NQŒQÔÅ23{O‡‡G¹,·nÝe©å„¹4aƒ¦Reäsy±Æ¨oµˆ, Ô¯ ` T”)ï½ÿ‘~’é—¶¶§xáùg)) A„ÜBŽË—¯ðûƒ‡eMýZš[4,]†o+Š< èÜ*¨Z\\ÃGþ„ÆYöíë"“Éðúë ¾Ÿ¦Q¥¥¥™}{÷òÎñw8úÇ^ùéË/kè#Nuñì–JÕ8Ž9qú”ÆÑœlÛ¶C‡³<ÝDÛî”—9ˆ²sLgxµ§‡ïï%œûcoôJÇîïh.—#™L>˜ÿ>ÄqÌôô4}'ûå¹í;èíí¥ñë/²ªm a%3„ÜÕ»A%¥­[©ÞòG{²}Ǧ¦§¹sçß„aøP¿‘ 'Çû†¤±±™Ìà u­ÔÔ­%L„$¾ñ <k"/ĬªgÙºVÎ=ˆÖ'½(‹õ``$Ö±OÇ©««ãâÅ1žjo'UPUîQ¬ ž<1š ¿ €sñD±Ö ó³ÿÀó<ŒõH¥ÊÉŠ„È@Â(FÀ1VpXB¿c}<Ïgjj PŒ±KÏA`jìDÕ-¦f ¾QB €g!á/N£+Xp.F[òÎ(ѦõH"QB>—'·åÞì·&dç®ê©ß’ƒ=‡hoßȾ½]x¾‡  1ã—Æyõ`å¥YÑÔÉØ åm+95Xà•ÞKòÊ/ð=§žU<+$l‚Ý»vêÕ‰ ††‡%3˜a!›EEH&“TV¤¨©­×ÓWWÈ6ùŒß ùô¦£©9ͦ¯UÑñó¿Ñ¸,ÿ àYßSõŒˆßgÍš:]½ºVs¢ª:77'Q©1Fü  $qU½}^^üÖs\¿9VU•³óùz^ëx˜üf{u- ÓÓÓDQtì8瘙™!ŸÏK*•BDDÄ "òì–Fr n\cõÚ&®ÿ+b}u¿œ§Pˆ‹@ñý¿®gþÎvimmàØ‘wùüJ?[Ÿ nûÿÿÝÀKõ»‡ZžþÉÝŠª¦?{€gT•ÿ òjY5ȵ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/archive.png000066400000000000000000000017061440571307300171210ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxœ­•]hU†Ÿ33ûߤ›à&´ L Y©FÝ6È lü©kE¡"‰Ì…Þ öÂË*üG¨µ´*ˆŠ^XÌ…DI ´±ÚBmÚºe³njÍ&m³›™9çx1ÝÉnþš_8?ß¼/ïwÎù>¡µ@AeœÍ¼Á2(Û6§ÏžãéÇv €‰É«ˆ%â65%°*“coíàħ/,I.µÁX± h#H8º/‡~ÔO=ò°ÏåÓBx¦aP‰L×Ç"€y¶–Ù\V§îºƒÞËñY:Q#ú÷[ÆF5L¹·u+çÿº¢›jb?>r”CogÇ/ED%-{zº8Ðß^tgãrùQZsmª„+3›÷ÑÖr§¿w³$¹6s™ÙÃ?œ ý4™ŽíqßÁñï XÎÆe¸=¥q×K™šæøðù%ãâqz;f?š X7|Å?ß×â+ží"ÌÙ.Ù+S ûkýÎa‚€iL“x1nT6L9‹’rM_À47Åè§sÇv‚JJКhÐÁ€5ÈB¹(×\“€ipðð'þ\º’HÈ¢>"T}MQéºkÐZ38ÐÏèØ§NŸAÉ"Òu='T]SÐ(gíT9PŽ‹vM´»HÀ³· ì÷H©@)PʬÐJ#Õÿã@ÊJêX­€Ö(¹>Ú3àJ„V,XoŠªH)A+\©É&8XÇ-Zè)Q®Äžs)ÛvÍ-²WKz=ùêüĶٖJ±-•¼b·?S¤/Gª0‹ÄžX ù£1¢ùaÚR÷q³4ŸÖJ±›*ù>—&“TA_à§‘ñݹ†>íN_Bhï'¡\ RŸ4TÚŠ¡1ÍÈoË»WžVœ»x¿ØUðáç_iûÆä-òÈõ-!V3šàågúÀëßÖ9޼sHüqá"uÑhíCËO^¥³­EÌ–“”m‡`0„eY˜–E8Æ0¼Ú(ØU¯þ¥}Ïñ˯#8vÙçi¬¯«m™àõÐMMµl!Ú;»øî›¯+¶@!Ÿ§©)ÁÝ¡>O6_ÐÙ|aqŠn‡öÎ.úz{ôLiŽ-ÉÍô<¹›7ß}tW†ßGOú±õ‘P­ƒÕâñî]ü|ê ÍÉ$OL¸[¶¶òÏdŽ®-€\.Gæþ{0Vdº övï{»wŠ•Öþ©PÍ8vffåIEND®B`‚leocad-23.03/resources/cursor_camera.png000066400000000000000000000005271440571307300203250ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅvIDATHÇí‘AÀ ‰ÿÿsz¨ZpZmìEI@0ûêIwcx‘ Ø5±@irœ¥C¬TI+ècÙ€vôñþ â Ï¿`mPU£ bÎÜ€Ï SƒâS1Jå̧&u€[¡¾ÍÉ¡›ÅF‹­À¦Á‹®“$Iþá_s pÐö8%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_color_picker.png000066400000000000000000000005571440571307300215530ustar00rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎégAMA± üa pHYsÃÃÇo¨dIDATXGí•M‚0…[7º6‘•;=ƒ1^@.ÃÂxl¹(W¨óÆi„ÿ¸°_R¦›y¯?‚™Êñ–)8´äþ~q’pΩÚ,xzdDä 5ÍJ>hM²–'{0FÀ£ž_ÂNb/]â×4;ÈPÍ <ÏSDYq ªÌ^ºÛAâO 8}?–>ƒ¡¦ Ýúý«#Ç@ÁabÓ;Ð/Ë’Ï&’¶ ]…âx´rŸ_JÛ@§øZኢÀ›Ž™*¾u^ý\qíx!_eöªÕG ÿw0[| ¬_AûvOE½¹¶ØÂüŠÑ¯áÖDÑ@4 DÑÀ¿0æ-Á†‰IEND®B`‚leocad-23.03/resources/cursor_delete.png000066400000000000000000000004671440571307300203420ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅVIDATHÇí‘A ! [ñÿ_îD–H—’ºÇÌMìkÜ€“[ ŽDœWeÄøÖ£r€–þ>1Ñøƒ¶¾†.ôdYN7›X½“:Ö¸#=ë‹Ò…BüÊQ¡Öµ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_insert.png000066400000000000000000000004711440571307300203770ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅXIDATHÇí’1À ãŠÿÙ¢ ZpÙPsľ,1ÛÜ^ þ%«4W„ìl¨õç€AP|]Ÿã¬Ùìm¿Ê!'S°"P®` Ðêb8I’äOœáa :곃%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_light.png000066400000000000000000000004721440571307300202030ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅYIDATHÇí“[ ·âþWæ×#­%iˆt~Ù¡-@ðb®–õNKP†¼ì º¸®6®)Ò^Ëfî Üš8)´1:–P/1ƒ2èçØ7 ‹šüÁgâj‚'¨?7Ë¿Í%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_move.png000066400000000000000000000005221440571307300200360ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅqIDATHÇíSA€0£þÿÏõ`t$–AäfèiÙhÂÌÿÙ¥3“ÀŽ~=Ò€7=—h¶pÄÒ] à‹÷½j h:Í*/ èW^í ´…\§§ó`ÂD@EFÙåUhT|{Ûa‹Ê*çƒA'½@@ò¤Í„Õ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_paint.png000066400000000000000000000005301440571307300202020ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅwIDATHÇí’AÀ þÿçí¡ÓöÊ\4ÑL\Â0&ÑÍ¥€,Kt‹ƒó’E@?KJL@¿›éލ 8Þ1«P:!ŇXü\ˆ“cC<ù#"?âoAQ‰ÛEˆUÖƒ¡¨Æ=…Ü4M³óÄÚ!3Oï%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_pan.png000066400000000000000000000005221440571307300176460ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅqIDATHÇí“;! BÁûß™-] Ø‡Î™?@«u“ B3Òè F5.sïu•øB¡YѪsÄ \‡Qúg¸]Ãn úÈp–—¹QðS2¶ò‡wð`\JÚ1Cº qŠ—¿ÐjY}^§Ȉƒ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_roll.png000066400000000000000000000005661440571307300200500ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅ•IDATHÇíT[À k—ÝÿÊÝÇÜ2TÐe“e|I„R-|Ý$(Ž˜®–ÀÆ€ò4Àš¼{.ÃdJ\Bƒ‰MßÅ32 ’úÒ(!.«ÖwBLĽ :êÆ·òs¹Þ^ 2u,ªŸ© éØÐw?!qðÄT^¿Â 5oùý\}gd‚Y Öãví…ß^³£DütéI%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_rotate.png000066400000000000000000000007061440571307300203720ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅåIDATHÇÅU[Ä dïåÙE” 65›š4µÅÞ(òõB.&ED€—d3¥È´³oyO)®¦=ÕÏYk`CjdïûÆ…=EHÀ‰"¦qùÕƒpdhO“â2ƒa¸2¢“FR Ž~B¡êŠ9ÀnY)®Ž{aWíh"} Þk€Koÿj È4€úi÷¶zXÊ•"éʹu\# Yš>-MÃ6Xaª5˜5ôÌ/‚jÉ¥X„•ÈEZV•…ÄŸU‹„Ëúéx"ýk¤}?T |<‘<Åþf:¾×@!ú%§•%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_rotate_view.png000066400000000000000000000006711440571307300214250ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅØIDATHÇÅUÑà  Üþÿ—³‡‰ŠFëîÊKÛB§MòcDnŸc¦YvöWž„ƒ€hJ?yÐå\ØtFg·(‡»«×RB 1 ¾b›ÓèDÖqR‚ i^ž©I6É”èݼš¨êñK8¯Â䦽²kÃJk«Nâ°Âî´&í“Øvã1tXܬ;5žq«»M…·}^Q¡·Vˆ+¥Ø•ÿÌA…Q´LJd¼$ ²vÛ¹ÀÀ~áË˽¶Ö/–ã«íy{ÔMìbÝŠÇ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_rotatex.png000066400000000000000000000005551440571307300205640ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅŒIDATHÇí’AÄ kÿÿåÎ%£(ÔSÎÅ’‘éèÛˆO•iŠeoÇ[•ÿ˜ÈìÞ[¨÷½Ã4Ôíš €nk<4R[¦j@ˆ9âö`Ž3$ר¦…½ç¥'æ~kßL •Ì¡„üGÄYH×Þ͸‰m©JM⿚DôVî_ŽŽþÐàíQÜs3ñ"%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_rotatey.png000066400000000000000000000005461440571307300205650ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅ…IDATHÇíUA€ ëŒÿÿr=%*nƒ†p‘ÉBWJË€Õ˼" fƒd)2€øîÎkKåx± ëîïr¬È)ਠ3Ø|˶¬T·ŸÆî¼‚ÙÍ’¯\$4¨­X¥D,éT¶ŸQ¶²a’þ8ÏÒ`ý§úààÎy2ɳQ^žFĆb%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_select.png000066400000000000000000000005141440571307300203500ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅkIDATHÇí“Á À C_Ãþÿ—³ƒÈt;µ= ÌÅTÈ« ]Ùv'/:A¡qÔš¦ŠÐck­E¡½Ì#ô¾È"6€1†âšÑý£4áÒ@#ž­ÿöâLzµÔêþ}MoµŽŽ~­‘‘+~µ·%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_select_add.png000066400000000000000000000005411440571307300211600ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅ€IDATHÇí“Á€ C_‰ÿÿËõ¢Æ‰’Mo†^ {+eÀ­l²²ûÃ6Î"èÒoßå "ÂÔ€3B2Œ‘Ò€ˆˆkpu‘+€;EÉà€:"ÌöIJ—ªx÷àÀH~•4’ó¨óSøD‡ƒOÝ{7õ ¦¦¦~£=T?ùkŽ”%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_select_remove.png000066400000000000000000000005671440571307300217350ustar00rootroot00000000000000‰PNG  IHDR ’ggAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ< PLTEÿÿÿøùùrE/tRNS@æØfbKGDÿ-Þ pHYsÄÄ•+tIMEã KkÅFIDATÓc`€#…AÂÎdÈZfd9@E²&@Õ@%€Œ•0Æ*ª(ki„‘ Sœ’ ³ Æp‚êb€3Xd¸¦Ãïr%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_spotlight.png000066400000000000000000000004711440571307300211100ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅXIDATHÇí‘1À0ÃäþÿÏt¢LÜuBsä3Ž0Döù¹Þx²c~L­AŒ° qÔFn[Î+#ˆˆº—•)Ó‚½ÏÔ¾l°5†aþç3¡ :) %tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_zoom.png000066400000000000000000000006151440571307300200570ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿ‡Ì¿ pHYs  šœtIMEã KkÅ€IDATHÇí“A À ]ñÿ_ÞZDMB”´Th½™Ù˜ ˜b'ù_°… ô%ú’ã=A7<¥Ý{Û4&jñwÌÀPÆé=¼¿ÆÇ;ƒºHsˆÆÚ'¬™5†±Ø8Olt¹‚ŸyEŽáÆ æq)À®u€üú葳ï_ø’à°£I•ù%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/cursor_zoom_region.png000066400000000000000000000006041440571307300214200ustar00rootroot00000000000000‰PNG  IHDR Ùs²gAMA± üabKGDÿ‡Ì¿ pHYsHHFÉk>tIMEã KkÅ£IDATHÇí“Í€0ƒ[ãû¿r=˜-ûÁ1äàEK4ðkL!!A©n?à1B2²×¬ó¯8!Ç)´@¤'HßÁ¤‚{ ßûà{ÀéfP51~ KîKI×"¥¾$* ¸ ¬…[—Ø©ëIà™Ò¬wTÖ›+´{sB¸‰ŠÆžûB…~¢W*´®ðÓr®-+ß͸.Æ?s.[¾%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_copy.png000066400000000000000000000017321440571307300174560ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF\PLTEÿÿÿ²²²®®® ¢¢¬®®®®®¬®®½¿¿ª««·¸¸žŸŸ—˜˜”••xxxƒƒƒ***BBB 666111///(((ƒƒƒhhh###$$$­­­ŽŽŽ………lll®®®­­­ùùùûûûßàà¶··ìíîììíëìíêëìêëëéêë÷÷÷ž  îîïííîëëì÷÷øþþþ·¸¸ïïðîïïíîïøøù¤¦¦ŸŸëë룤¤ÌÎÎîïðùùúÊÌÌÊËËïððÆÇÇïðñšš›ððñðññ………ñòòèééòòóññòòóóçèèòòòóóôôôôèèèôôõóôôõõöéééõööôõõöö÷íííö÷÷öööƒƒƒ}}}„„„øùùøøøùúúúûûúúúÿÿÿéN_/tRNS°þ÷„û‹‹‚ðû   þ¶ % ûû± söZ³bKGDˆH pHYs  šœtIMEã KkÅ+IDAT(Ï…WSÂ@F±bرkìe#”€6ÐÝX¢AÁ‚õÿ?¸Éîf/~OwæÌ™3»ÀkiÝv·ÓÖî@$Ûvý@ŠÅ{ûIYŒvuû@J‘âj"-găžÞF=Ìa)t,Ÿôõ7VOÏ 9EÊ‹@äB¾ê9‘TÀ ù«š#Å7<ÒT½Ô±¤`0ÚT½Ê^k…PóªH…P×0 ÎªèÆ(ÝBîðM«èþÁ, <â’*z2­²ÉÀ³UÆ’[E/V¥j1ðZ©IèÍy.àÆÆ~ÿ µÏšmÛá‰É)|Õ“TÜô ÏGfçæð êDÂÕÅ%A–WVñﮟ_*Ñ*Ý:û]¯J·¶½‘*ÝæV„§£Uwf#‰òo%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_copy_16.png000066400000000000000000000010321440571307300177550ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFuPLTEÿÿÿ°·»±³³¯±±­²µª¯²©®²«°³¬¯±¬®¯¬®®«³ºÿÿÿÅÆÆª²¸àâãàá⪱·èééæèè«®®ëëí«­­ððñóôôøùù«²¸ííîüüüòòó­°°õöö¬³¸úûû­¯¯­´¹ýýý°·»®°±Ò~ÊìtRNSì°ò¤rÖbKGDˆH pHYs  šœtIMEã KkÅ}IDATÓuŒI!{ÜÅBQi´wÿÿD§‚“y̨,¢L7›/–«µ¡ÊŠÅ¤Š-vÎ9ãP7{¼÷ÆØÐò£‚ØrÛ¨h93«hyJIÅ ç’‹‚ŠKÿËõkPqeÎy7ÜSÊyŒá1%zâ%RòÌ…áŸè>!Ö|ä Ne U'×4%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_cut.png000066400000000000000000000032561440571307300173020ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYs  šœ°IDATHÇ•”{LÓWÇϯï}ÐRÚþÚò(¾æ‹-¶% .ê@ñµlYdhcf.ÎW6‚Y$8f6!êtÉ|`–9ç2•¹dÉ"F¦Æ©ˆ–€Bk[ B)}ÑÇïþ~¿»? Ôí$çŸsÎ=Ÿ{Ï½ß c˜ðââ⢂‚‚PeeeÚäx)/¯ÈT(”Ð~ÿ„Ãá;$I⸵Z}©µµòòò@«ÕªZüô¢íÛ?œ+—+ª×®[4bàjK ƒÁßb1𛲓É7¾cÇÞ† :Fa»ÝŽ×¬Ys½¦¦F0QSUµƒ·bÅŠkcïX÷Û8++ë.I’2Š¢ˆ¸¯èàÁƒœJ¥ª¿páF(,,\jµZ+'jìvûö¢¢Í¹”Þ4Bpîdz`·Û+•JzhhhʈŒŸŒíܹS`±XÚ›šš)•J`JKK:õ£†y‘‘“§—.öµÇU²G¦;’â´Ì⥤BäìYÿ¹+A@G€ „€¶9‹€ä½÷!Öû"? Œ ê#É7ßúµ[&͸›¬Ÿ?;Ó´ë àøö]ºä³½¦ì܇ŽpŒÏ>¸û4ãp@èè18 œûÕžô¬úNüfe Ð9»#RÕë3 Ê2Yp„8sÒUßçs ©‘ãN¹®±t€wÈÃ<"$v¦·ú@n¢ýIaÿÑ6uÊÇ¡·¼nð‹È-­ÉZbZŸãrA¥»” Þã¡SËÃÑðÞ‡vH,ƒ3Šz;¼þvÖN àeF£ôçý½HLGN(t^0¤AŠA—c‘ˆùÓŒÒÂc~–(¬sh:¸ÏÚÅ3-|YI%¥;»áV Üê‰núÝ^P(¥’±àÁ‡Èë¾öú€õލ<"‰tZÍùcþ È$B£žaE—Œ¤Æ˜z”Àp(!ï²Ôíº0œD1bÁ\µ¾îŠÁ$n¥Rx“Ƀñ0v …Ìd€à1@ þ#2>º@Ç‹iW •mBm²@ëêJ£ÝIin`®"‚J’.˽ý¯èþ¬A]ú=–àÆUÖŒHdº”©­c<šVWRç©â/ý˜Ó(À€1 ÌÁ€ŒòSH6*tût§™>gZ®‰oh}.ƒ‚Žea@¦ó6ÈÅ–i;Õif¦.›ê‰öÊX&'Jê oÞrßñYd¥X=ÝiÆuC¤l—ѹŽM°ˆw® ‰Cf;7ßN>Á?¦Í‚€–À,&%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_cut_16.png000066400000000000000000000021631440571307300176040ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFPLTEÿÿÿÜ Ð …!'“ ½!m'*R*-]]]CCCYYYNNN555TUUZZZIII}}}sss@@@NNNZZZ^^^TTUYYYqqqzzzYYY{{{iijZZZ\\]oopHHHHHHkkl??@CCCfff```VVW]]^hhiIHHTTT__`DBC{UQGCCA76zQNƒ/&p0,k*'e# t/*‚-$‰%“!œÑB>Å’Ë:9‹ ª!¡ L)0q"~à4/¸… j %˜-0Œ #°$!ž!!‚ Œ"(‡ «z"!·'+«%$ˆ!"ƒ œ !v%*~ª$%¹ b(-¼$„£ a #I,/V“"œ!\*0§§§•••±±±¡¡¡––—÷÷÷ððòäääÑÑÑÑÒÓÈÊÌûûûŽŽŽ™š›èéìÂÂÂôôôçèì–—šÞÞßÄÅÈÙÛÞ±³¶•+“(ÜF@øC;ç:3÷UMÿaRèE=ã+"ùE<Ó72ýYOÄæD9þyònhþrhÜ+#Ò*!ýf]÷9/¬ôHBÒCCò0)á0)½$%è/-µ"Û30ä é@>¹ "Ú()Ù**Ø!!á))ÒÇ Ì"$ÚÙ¿$(× ª"³!ÿÿÿò™q®ftRNS2ö-8ôqÁÌY]boFýî!óö ¹¯ÁŸ;þWqø$žêöÙº8sóâWCÂñ(‰Öòàh§þ.(P÷Zþs/JÂð»éý}î–8þü1 èù· …ô÷OѧzbKGDˆH pHYsÄÄ•+tIMEã KkÅâIDATÓc``ààäbn^0Í—Æ/¢…Ò…Á"™¢ Z,+[, !™#%ÍÀ #›+'Ñ«—¯È ¤\P¨á3¨ª«k””jjA´ËÊut+*õ`|}ƒªêšZC#¸€±‰i]½™¹…%„keÝÐØÔÜÒÚÖnc˰ëèìêîéíëŸ0Ñž Èwpœää·½ƒ£“³‹«›½»£“P€ÁÞÃÓÜÂËÛÇ×Ï?À"•!(8D?4L4Á;1)ÈH±dHMKÏÈÌÊNuKÍ2r€t^~AaU˜¡(ÎÌ*(1JŠJËÊ+* y˜Šª@ K† êšÚºz}^>C…A"µ¡±©Y’— Ê`àG|´>äó)%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_find_all.png000066400000000000000000000003331440571307300202500ustar00rootroot00000000000000‰PNG  IHDRóÿa pHYsÄÄ•+IDAT8Ëc` 5ð,ºð“¬yÑ¢EÿïܾóÿÑÃÇÿwíÚM¼! …'ŽŸüÿáýGüìÙs†€444`h†a‚.I®^µ§ ï4`áÂE8 … QÞxÿîV@K”Ó§OÇ0°DiFÆ Aa‚%-0áÕŒ.†¦”‹(Íd%YújÆãGúËå…Κ uIEND®B`‚leocad-23.03/resources/edit_find_next.png000066400000000000000000000001621440571307300204560ustar00rootroot00000000000000‰PNG  IHDRóÿa pHYsÄÄ•+$IDAT8Ëc`xgÑ…ÿ0CFî$`}¡ZÚßIEND®B`‚leocad-23.03/resources/edit_paste.png000066400000000000000000000025301440571307300176150ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFsPLTEÿÿÿ“““ xE¬®®¬®®½¿¿ª««·¸¸žŸŸ”••ƒƒƒˆ`;ŽŽŽ………ƒƒƒhhh•••”””åååããã‘¡xD vB¢t;’–›ÒÓ×ÏÐÒÌÍÏÊÌÎÊËÍÍÏÒ vAñÒ¯îЭíЮòÑªŽ’—âäæÃÄÈÃÄÇŽ’˜îÑ®s?øèØÑœZÒž^ן[“šõ÷úãäç“›ÓŸ_q?õæÐÏš[ÐaÔŸ_¨™†”œŽ“™Ñžbq>œr>óáËÍš[Ôž[šq>ïÛÂÊ—ZÌš`Ì›aÌ›`º«™®®®­­­  Ÿ›o>ìպǖYɘ]É™^É™_ʘ\®®­ùùùûûûßàà¶··šn?èвŔWÇ–\Ç—]È–Zìíîììíëìíêëìêëëéêë÷÷÷ž  ™o>ã˫’WÄ”[Ä•\Å”Yîîïííîëëì÷÷øþþþ·¸¸˜n?ßÄ£ÀUÂ’Y“ZÑWïïðîïïíîïøøù¤¦¦ŸŸëëë˜m>Û½š¾S¿W¿XÀŽTðññïððîïðùùú˜l?׸’ºŒS»ŽV»ŽW»ŒS®­­ñòòïðñ–l?ѱ‰¸ŠR¹ŒT¹ŒU¹ŠQòóóòòóññò•k?̪µˆQ¶ŠT¶ˆPôôôóóô–j>Ç£x²†O³ˆQ³ˆR³†Nõõöôôõóôôððñ•j?Áœo°…N±†P±„Löö÷õööôõõ”j?º•f®‚N®ƒO®Kö÷÷ööö”i@´Ž^«L«M«I®­¬øùùøøø°‰Tùúú“h?­¬«úûûúúú„„„ÿÿÿwctRNS³ ´„‹‹‚ðûÊû±þ¶ÍhbKGDÿ-Þ pHYsÄÄ•+tIMEã KkŬIDAT(Ïc`&fQ11Qf&0‡ â ,â’’R,H¬Ò22²rò ŠJÊÊŠ*r²ª2Ò¬L 5u M-m] ÐÑÖÓÔ×P“aI›˜š™ƒ™…‰¥±¡HÂÊÚÆÖÎÞÁ ìíœl­ÙA.®nî(ÀÍÕl¹‡§—·¯¯¯Ÿ?r€$‚‚CBÃÂÂÂÃ#"£¢! &–“‹‘!.>!1 ’#£RRÓÒ32³²£c¹yrróò @ 02ª¨8%­$½4»,ºœ—¡¢²ªºj#£êꀚ›š³[øZÛÚ;:A +2ª»§·¡8¥±¯/*šŸ¡ÂÄI“A`ÊÔ¨iÝÓ!šJ¢øfÌœ5{Ì5oþˆ¦T ÄÂE‹—€ÁÒ©Q˖χh*J¬X¹jõX;5jÝú @M{z‹€›6oÙ Û¦Fmß±¢©(±k÷ž½`°ojTéþMÝ@‰ƒ‡ƒ£Ç¢ŽŸÈ‚jIœ<—8u¢i9PBà4 œ‰:{ªi=P‚a¡ (BÂçá@X)ØÄ%‡%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_paste_16.png000066400000000000000000000017711440571307300201310ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFÈPLTE¥|J¦|H©{B}„¥{H£v>µ»À³¶·³µµ¤yD£s9´º¾³µ·¡r9µ¼Ã´·¹³ºÀ³·¸²´µÿÿÿ£zG£yG±³³ˆ`;°·»¯±±~€~~~¢xC¤w=y€ˆ¶¶¹µµ·ŸuBòÒ¯óЩ‡Ž—ÈÊÎÆÈËÈÊ͇–ôШòÑ­žs=r>÷çÔÓ›V– ­˜Ÿª˜ž§™ž¤—¥Õ˜NøäÌšj/šp=ðÞÆÌ—WÏšZÑšXÒ˜S¾ª’­²µª¯²©®²«°³¬¯±¬®¯¬®®šo>êչǔWÈ—[ɘ[Ê•S«³ºÿÿÿÅÆÆ™n>äʬÁ‘VÓZÓYÃPª²¸àâãàáâ—m>ÝÁŸ½ŽS¿‘W¿‘V¿ŒMª±·èééæèè«®®—l>Õ¶‘º‹R»ŒU»ŒT»ˆK«²¸ííîëëí«­­—k?Ì«‚µˆP¶ŠR¶‰Qµ„Gòòóððñ•k?át±†O²‡Q²†O°Eõööóôô•j?»”e®ƒL®ƒN®‚L¬}B¬³¸úûûøùù”j?°ŠV«‚L«‚M«K¨{A­´¹ýýýüüü“h@“h?“g>_3°·»­°°®°±­¯¯”ý~ tRNS°°°À#3ìòÓØT[bKGD »\– pHYs  šœtIMEã KkÅðIDATÓc``db–•“efbd`aecç`•WPTRVRTãäâæá`PQUS×ÐÔÒÖÑÕãåãçà`Ð70426153·°æ`°²¶±µ³wptrvqusfððôòöñõóqa†À àаpÿˆÈÈH÷Hw†¨è˜Ø¸øÿĤ¤$w÷€d†”Ô´ôŒÌ,ÿìðÏeÈË/(,*Îò/) @YyEeUu–M-êꛚ[ü[Û@(ÐÞÑÙÕÝÓëß×þÉ &N˜4yŠ?Le”$0ž–œ ÉÓeÔnLÕIÊÞZ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_redo.png000066400000000000000000000030571440571307300174370ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“ pHYsÄÄ•+1IDATHǵ•ilTUÇÿ÷-3¯3Ó™iËt Ú2](”’R¡R6 0¡q‰@ý‚&&$’bTb”Èb¢©’#›,¶R,â”B2l¥t­í¼7}Û½~h©¥Or¾Üäü÷Þÿ¹÷ÆþÏÆZ¬ØyÍ)ðÜ$Žƒ•RD A°jCúoäÁ Vìh&ŠF×De}Àseã’-¼ÈsP4á~Mxò‡ÝÊÿì°òûoœrÿI¢³6_äë+KÍaÀ²/.;²þ“Çi]º¨Ø‹\¯”1PÐRp¹5†Æ;1ƒçÈiqËáME7F‹/¬lœÜ—0Ž‚K Ÿ>¿Œ,Ù ½ŠþËä,÷’—¦g`@§PT#­!H²p°YÂPßBms÷€ÍÂ}–b??¸©X€Å•¢¨¬xy†o|MC›î¢!‰ÌßÜðºdªÞœ— Ãd0Ì'›.ðÎ$ªa¢¦¡wºúÏùÒl«ªéèîSO,/Ëöfyø¦æ²Ñ{î[‡PµwÊ Ò¡ &gŒ!&«P5É6 ì’8 0L†H\‡$rxcŽç¯w•Ÿmj¯3)VÌò§çf8“uÀ4p?pDTU+ÏHsÀ¤Á€ªãhÃM´wt´jý]!)5'Ë“êòåxPàKá ¡3h†Žùé—,e”bâx7úÀ5¡ËQ^àu‹¢:´Ãúæ6\ûýàþ{'¶W‚Q…ð"œþ9åm3×¼×”S8oA©i.ûài‰›ÈJw‚‚^ÅeƒMs°‰jèšn˜~hgí]Q„«÷èá%W‚%(W«Ö-[‹½»}niž3?Ë3|m‘8}È'J`Cš-áhïTwrjê Û')ñû—ôEî¼ùUB{ƒÕ\På)¥EÏMö{ÇlÆö`åØomÑ©v«B§däö‚¥qdQ,x–ÐÊÖîN(ŒŠ)v+x ht p‡ƒ·ïuC×C¼©.¸&Î}Õæòr£ ¬?”§Z¼ÇÏ.àÏô@V(t ¤¦ CÂèéh4ììé…®ã6½0ß—âô ½[ƒª†ñø2™ ÀQc¸§k}{gç´ç|(̈»m«Ø@d?€£MÞfÅ«öÙ FO–ß>É[“Íáß´¸b[¹à˜pæÅÙóÅ· ¡p§ëêÛ\6~zíwkCE;HäV­ØÙTm àÇL ›§@6’ã-çû;š·þ¸%aÀëñ 0Ïï‹'Œ ×U‰Wª72Ó4 É-Þ%¼"¼Ø3vZÂBRJ\—Ã:9Ñ&-Ú$RÁY“?å…%%ÓJàr8vê z£Ñ¯vëû¿îyë™ÇßC­xýä—ºiY¼z±éÆëèSL,^0IIÒ†Þ~eKIÅNòŸÀ[ݱ¾»g^k¼X× ¶@N峿 ‘ø(iµ=+à‘™|³v¥ä£té_”¥†éëîjG¼ûÚïíÀWò³ò€â`F8^“R²Ss}¨Ë¡{á[§vBú5a*c¬ç™£c|Ñ ®·= êrHà-v“’´Dì.}šèÈøZ•õ½8%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_redo_16.png000066400000000000000000000020621440571307300177400ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<àPLTEÿÿÿIÞKŽÞMàQ‘Þ<ƒØ)xÔ/|Õ,{Ô>…ÙLÜ0{Ó4}ÔNÛ+wÐ+wÐ8€ÔH‰Ø3|Ñ6Õ*vÏ8~Ñ/vÍ8~Ñ6|Ð(oÇ)mÂ+oÃ2tÈ,oÄ'g¼;wÈ5rÄ*i¾(d¶7pÀ8qÀ1h·/f¶2h·.eµ7j¸'\«&[ª3e´+^­*^¯+\ª'X¦4d±$V¤'Y§8f´$Rž+Y¦6b®%O›,W£,W¢4\§(Pš"J”%L—3Z¥(N˜$K”6$H 7‚Ø>…ÚX–á¤Êü¸Øÿ·×ÿ¶×ÿ’¾ö_›äTݨÌþžÅü—Àú˜Áú¢Èý­ÏÿÄúPŽÛ”½ö(rË…³òšÂû’½÷k åešâ{«ë–¿ú¡Çý®Ïÿq¤æ7zÍ–¿öÄü(oÇ•¿û–ÀûMˆÕ;zË|«î˜Áü©Íÿ¯Ñÿ£Éþ'jÁŽºö¼ø.mÀe˜Þ‘½ø•¿ø&f¼r¡ã‰³ñ4n¾1k¼ˆ²ïŠ´ñ%bµL~Ë€©ñLÌ„­í‘·ö%]¯pšén˜çq›æ{£ñx¡ñ$Y¨?n½w¡ñN|É#U£X‚Ñ}¥ñ6c¯eŽÝ~¤ëi‘âm”á;b­ÿÿÿbp¶MtRNS$ †äüÇr0 ÅïsZúÛ…ÈoûÜþµŒËøSçÉ)l}ƒPúöï)ù„ªÚ´Öx)õüQKúò Súµ(ˆÈ9ðõ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_replace_all.png000066400000000000000000000002241440571307300207420ustar00rootroot00000000000000‰PNG  IHDRóÿa pHYsÄÄ•+FIDAT8Ëc` ð,ºðŒ±jÀ†±ˆÓbùD@È…$À@¬éT uJÕÑÙ¥C˜ÈI ”:‰òEF͉-J•PIEND®B`‚leocad-23.03/resources/edit_replace_next.png000066400000000000000000000002111440571307300211440ustar00rootroot00000000000000‰PNG  IHDRóÿa pHYsÄÄ•+;IDAT8Ëc` ð,ºðŒ±jÀ†±ˆÓbùD@È…$À@¬éT õ!†0)þ8¨•ôŽcR+ÓIEND®B`‚leocad-23.03/resources/edit_snap_angle.png000066400000000000000000000020051440571307300206050ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF†PLTEÿÿÿ¤§BBBPPP©ªªª§©öÿ‘‰ÿ¡š¤¦ÿ3(¢ð ÿ**Õ•ŸÿxË€€œÿ{s˜€”ˆ€666777666$$$'''%%%&&&ÝÞà>?A<=?ÒÓ×Þßá<=AÌÐÓ;>C:=D?Cßà⎒•:?C;@FÚÛÝ=>@ÎÒÕ9CB6?HQRVãäæÔØ×9BGÇÍÉ8=C«¬®YZ\ÜáÚ>>HÔȨ̈¨ªrsu=;IÉËÆvwy¼½¿ÐÑÓ@ACuvx®¯±ÈÉËPQSÿ”ŽÿDDKLPרÚÿ‰„x|©­°ú""±²´}~€ðAF9>D;>EüSKè=ADÿ;4èÿ)$îÑÑÑ££ÁÌÌ̬¬Èää䮮̳³Ïÿÿÿ^¾aò6tRNS Z¡Ã¥Ý÷þ ¦èZÝýãÑ¡÷ãŠÃþÑÌÌÌÌõõesfenennrnri€ig‚eÇÃ#bKGDˆH pHYs  šœtIMEã KkÅ%IDAT(Ïc`@fæ X™…%Vq+\âÖ6¶vöâŽÖN Î.¶â®nî ž^Þhâ>¾~@ÒŸ! U&(8Ê C‘€3#£°û…!:Ê`dbecçà`gceb ÄÆA%8¹¸yxyy¸¹8!ñ  >~Ä$ Hà烈$§€)A¡TaQQáT!AˆDZ:˜Ï”’’”ȃHdf)i™lY))Ùli°€ƒ½KŽ=–ËÍ“ñåóòå : ‹@”Bq D¢¤XêƒR0©XV‘(/Sd°€¥ŠJe„re…J¨TU«23³°¨ÕÔª¢H¨WUk€hÍšZ- íºz­[× ‡"¡o`h¢MLÅû0ô6¦x%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_snap_move.png000066400000000000000000000015411440571307300204710ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFPLTEÿÿÿ¤§€€€€€€€€€©ªªªª~~~§©öÿ‘‰ÿ¡š“@@¤¦ÿ3(¢ð ÿ**Õ•Ÿ {{{€€€ŸÿxË€€EE€œÿ{s€€€˜€€€€”€€€€€€ˆ€666777666$$$'''%%%&&&€€€ÿ”ŽÿDDÿ‰„ú""ðþjaé ýh`üSKèÿ;4èÿ)$îÑÑÑ££ÁÌÌ̬¬Èää䮮̳³Ïÿÿÿà{OÆEtRNSþ<ò Z¡ÃÃ[¥Ý÷þ. ¦èZÝýãÑ_dö¡÷ãŠ4ÃþÑuÌÌäÌûÌ õõesfenennrnri€ig‚"«bKGDˆH pHYs  šœtIMEã KkÅäIDAT(Ï’åÂ@„Š»»Š”âîî”âïÿ p $]Òóc'Ù/s›ÝB_5‘(R€z·?EQÔ÷Äÿ3~‚‰„^HAŠ&dr•Z£ÕiÔ*½Á€Él±ÚlV‹ÙŽbàt¹§³§¦n—<åñÎ}þ@Àï›{ƒ¡°hx$º cq&F/¢H$—)&˜Ô2™ ³Zc”E¯7rÛFìì¶9ò{s,Ëa~ŸçÄ›B‘ܹ( Q:žÊTΗ2Õã©F¼~¾4À?h^o-âíë½@·×ŽÆqÿÛ5Dñ HÛ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_transform_absolute_rotation.png000066400000000000000000000024331440571307300243330ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF4PLTEÿÿÿ€€€Ì€€€€€€€€€KKK€€€€€€€€€€€€€€€€€€111L‹€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ddd€€€IˆBp €€€€€€Hˆ€€€€€€€€€€€€€€€€€€Ex €€€€€€€€€€€€GŠH‰€€€€€€LF„€€€ÌÌ€€€6d€€€Ë€€€€€€€€€€€€€€€€€€€€€€€€Gˆ€€€€€€€€€€€€€€€€€€€€€LŒGˆˆÅHˆE‡§Ü1 â}¿\W˜F‡HжÞL×›ÕœÖØŸÙ¡Û’Ëc¡Æák›É™ÇÑç‚Óè~Óé¿ÞKË¡Îv¬C‡Ò቞Ã}¬@…JŒ…±A¶ÐKŸÃ£ÆdÕæ£Eˆ^—ªÍ; É”ÁIŒ` Ò£ÕG‰Å ]œ ØªÞî{{þ££÷MM`ŸŸÚ·æ1FˆÌ¦Ø´ØQÿ¦¦ý  ûœœù˜˜÷““þ¤¤ýyyûttønnöhhóaaõ‹‹ùqq÷kkôddñ]]îVVñƒƒúššðYYíRRêJJëNNèFFå==êrræBBã99à11çjjá55Þ--Û&&äbbÝ))Ú""×á[[èllæhhâ]]àYYÞUUÿÿÿQ—ÿÿLtRNSû¥í3råüïÍ”USó=q’Ÿ«ÃÝñþ›2fmù˜.óWêáËà±a!§ºîý\gù²2êj¯çè)qÒä)æ.Ì@žŸŸŸ+ƒDÇÔiÓgÌœ5ÛÜÄs‰‰sæÎ›¿`!D¬Ø"±hæ¬ÅK–¶A$Ø@„DbÊüË–¯XiãâÍÆ%©’`7Ÿ½déªÕkÖBtø bÐ|áòëÖo؈)ѶzͦÍ[¶š£'ó•Û¶oܱs¦   â¾cS*ÚÃ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_transform_absolute_translation.png000066400000000000000000000021711440571307300250310ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFžPLTEÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€777€€€JJJ€€€LEYYY€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€NŒ€€€€€€€€€€€€€€€€€€ÌË€€€€€€ÌË€€€€€€€€€€€€;;;222€€€€€€By€€€€€€€€€€€€€€€€€€€€€€€€€€€JŒ€€€D‡·ÛaE‡Å܆žÓ½éÝlwÎæ€ˆ€ˆ¿?ŽcVpôb§€Ïx™ø<Ê8Å8Y5sáo8ŸSI€ã~kÛ‹ÉPúG8ì'zr²†ëšX<« ™_‡€NX¼³Z%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/edit_undo.png000066400000000000000000000030331440571307300174450ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“ pHYsÄÄ•+IDATHǵUkl“U~Îwé×µk×Òu¥Ý˜£œËa†ÁÄq‰A„ñ€QcDb%L4üð‡þbŒ Æå¢ Èe2F™l6¶ŒmÝÚ­í×ö»œsü±0Á"$>Éûç\žç<ïyÏy çÿ'¤{ݸüÓ…sL¸ƒfRvqÏk%ñ[בë¦×5ˆ'ÞJG#}bë…ü¤FŸQ5ú¨Iùƒ‡E¶Y$”¡/¡S“²“n»ü™Í"ìØ»¾” T½u¦žs”;³¤ù¿ÖMiA¼%4±?i¼M_1¥È%•ºP˜k`2!¸Ô“ÄÁ¦DâÚ/»¼¬þͲ$™ýz½0(äfUÈ?îìvÛ-µê*B°tK“%¦S:ÛTSšg>)œ¤4iáæë#°)"¬²€ŸÿêBsÇÀ¾›¼Í\­äT¿˜|yQ™ÔI⇓í=yN¥6K“ý©]E>Gõ¢ªB(’ˆxÚ„IG/ I$D‚¯\BF3—‹j´#Ë;uÅÆò WxlÈsZ³½˒i㹇Êü¥ó+ÇAÓ v ·š1g`P«,‚ÆÎY$wÅ’¡ÆDÎ(À iŠâ€ Kfó$A@ÑX'¢ C‡&Î8Z:ûj‹ Œd¢m‡/7à÷.¨*†U‘AðdCÓôj ¥à  œ ž¦úÝàœ#š¿ŽþA‡.£«íï#=§v|¿|ì8§@[¼vC]Ž}ÕšÙ•Ap²,CàÌ5ô¨ Ê0ý }Dn[;"8ÚŽwþñņh¨~·huê’m cFTKdõ5îù¼«|áÆØ%ã`¦¡KÀ© ÃÐAn‹æË=8ÞºÚ±ÿý%–lÏyGá4s ü;»>Ÿ_Ι©«Œ0t À@" 0ÚrC@g ·Q°Z¸í ÎäY—>¹}Ý{6W3M}’Ójappt^‹AøÀLè:`Ü&ÔC0ß‹ÚSýšÅ·ÎKßO!ãrÆ×,õÉi í»ÒÑ IÀw €~›Èd€ž>Á|fUÜŸSÍߪ×î-¾Y@¬E®@Ùã\/ èŽ "Î 8¨ ÓÄCÓ®^n§•% Iußä§¾$Pµj› dç¿S\¯XDšÎj Ã*‘Žm{Ì”DÅAS½­<`Î.öÑAð³M_=Ë€iž{ì¤U%ÅãÁtuw£?Òs.ÛfÝ’âôëWöo^ €xR€ÈŒ¼85&Xc@ÍóÛs5¦|>§r2‘e±š.4$Y{b÷H†ÚoHYî$ÕÕÀGq@ 8üŒRJC{Öó¹k¿‘“isWÉ„âŸ×‹„jàÌÙÓH\»ðžÝåûsøoÒÕ>Àü©ÆÜv’¸ªmñ¸Ýó¦M)Ã`ÒDÓùsènía|Ðøí«Ãoä®;ZÅ≨do¶Ùí¯ÔΩA…Ù,{Ô/|Õ)xÔ<ƒØQ‘Þ*vÏ6Õ3|ÑH‰Ø8€Ô+wÐ+wÐNÛ6|Ð8~Ñ/vÍ8~Ñ(oÇ,oÄ2tÈ+oÃ)mÂ*i¾5rÄ;wÈ'g¼8qÀ7pÀ(d¶.eµ2h·/f¶1h·*^¯+^­3e´&[ª'\«7j¸'Y§$V¤4d±'X¦+\ª+Y¦$Rž8f´,W¢,W£%O›6b®%L—"J”(Pš4\§$K”(N˜3Z¥ $H6>…Ú7‚Ø_›ä’¾ö¶×ÿ·×ÿ¸Øÿ¤ÊüX–á(rË”½öPŽÛÄú­Ïÿ¢Èý˜Áú—ÀúžÅü¨ÌþTÝ(oÇÄü–¿ö7zÍq¤æ®Ïÿ¡Çý–¿ú{«ëešâk å’½÷šÂû…³ò'jÁ–Àû£Éþ¯Ñÿ©Íÿ˜Áü|«î;zËMˆÕ•¿û&f¼¼ø•¿ø‘½øe˜Þ.mÀŽºö%bµ‰³ñŠ´ñˆ²ï1k¼4n¾r¡ã%]¯€©ñ‘·ö„­íLÌL~Ë$Y¨x¡ñ{£ñq›æn˜çpšé#U£N|Éw¡ñ?n½6c¯}¥ñX‚Ñ~¤ëeŽÝm”ái‘â;b­ÿÿÿ3CߺMtRNS $0rÇüä† ÛúZsïÅ ûoÈ…ÜËŒµþçSøl)ÉúPƒ}ù)ïö´Úª„xÖQüõ)òúK µúS(.uΊO:%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_new.png000066400000000000000000000016711440571307300172710ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<YPLTEÿÿÿ¯¯¯¤¦¦¹¹¹³³³¢££¸¹¹²²²¡££µ¶¶œžž«­­—˜˜™šš›|||………555MMMƒƒƒ>>>888¯¯¯©©©ŸŸŸ777”””///†††ƒƒƒiii+++ttt111 888±±±³³³¢¤¤¯¯¯ûûûüüüýýýÊËËíîîìíîììíëìíëëìêëìêëëéêë÷÷÷¬­­ËÌÌîîïíîïííîž  ùúúÌÍÍïïðîïïÿÿÿÍÎÎððñïððîïðëììøøù¤¦¦ŸŸª««ññòðññïðñ÷øøùùúùùùòòóòóóñòòóôôóóôôõõôôõõööõõõöö÷öööõõö÷÷øö÷÷øøøðñòúúúøùùñòóúúû®®®¦¦¦ûûü–––ûüü‰‰‰„„„ ¾©-tRNSÓÅÏÔÖÍý øû    ¶þµ 7Y|µbKGDˆH pHYsÄÄ•+tIMEã KkÅIDAT(Ï]ÑWWÂ@…ѱ÷{ïb'3“1QDEEa@Å‚±—ÿÿ`X3rïâ¼îõ=BHÝls«¾¨5úueÛMÍ ZüzÀØ1-¾kÛ¶³Çö[Ûª ¦É¹á;lïø‡èQHFÜ GØIg—‚Øé™ŒÎã‰Ä%ëîQL]©(BÐÞ¾~ ÙdªqÎ…60(!—½†È²„64,!“Ã@¡˜G‘p{WDQ tÿ€¢ ÀãS EQ€rÚAQ @ÄË(zpÅ Š^ÞÜ ŽŒ¼{¹8R0ú¡ÓOŒ}é”~ãHhãLþè5ÚÔtå™ßšÍÎÍ/T`qiÙ·‚æ[]['ä9Á~[\÷ù%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_new_16.png000066400000000000000000000010711440571307300175710ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF‡PLTEÿÿÿ±³³®°°¬®®¬¯¯®°°¢¤¤­°°¬®®«®®«®­­¯¯ÿÿÿéééÞßàÞßáßàᣥ¥èèèâãããäääå䤧§êëëäåçæçèÊËË«­­èéééêêòôóêëìëìíéëìéêëîïïíîîðñòóôôöööøøúøøùýýýýüüì¦9wtRNSïꦧ¬ÀpábKGDˆH pHYs  šœtIMEã KkņIDATÓmÍK‚0DÑÄ¡I"ˆÄ€(¢"î}‚m'¾áT)µ0!Ed—Zk5eñ-^1„HÒmš ÃnýB^ì‹åñf†•s®Â±Ì`g𨛦©Oó 1´ç©öÒuð W®ïn’À]xHÓã‹ùÖà—ù %Ï‘ ”zìjŽ™%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_open.png000066400000000000000000000022631440571307300174370ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFPLTEÿÿÿ ¬¸Žœ©Œš§Œš§’ ¬¦²½Œš§“¡­Œš§’Ÿ¬Œš§Œš§©”Q¹‘#ŸŠPº‘!L@º!  ¸Ž µŒ ²‰ ¯†¬‚¨¥| ¢x ¡wžuŸxtseJ1& ŒnK; B2/"(% Œš§Üâçøûþøüÿöúü¸ÁÊœ©ùüÿ©Ðÿ§Ðÿ©ÓÿªÖÿ¬Úÿ®Ýÿ¯àÿÃèÿöùý¢®¹©½æÿìõÿòøÿòöùõúÿëõÿâðÿßïÿô÷û¬”I»‘ »’#»’"ýóÚþôÛüñÖ¼’"þôÚýá{ýò×þôØýàyüàzüàyýàzýßyüßzýòÕº ÿôÖýÞwüßwüÞwýßxþòÓ·ÿóÕüÝuüÝtüÜtûÝtûÜtûÜuûÝuþñÒ´‹ÿóÓûÛqûÚqüÚqûÚrýñѱ‡ýðÌûØnúØnüîÉ®„ýðÎúÖkùÖkúÕjúÖjúÕkùÖjüî˪þñÑúÓhùÔgúÔhùÓhúÔgùÔhùÓgüïΧ}þòÔùÒeøÒeùÑeøÒdüñѤz øÐbøÐcùÐbøÑbøÑcùÐcùÑbþôÙÿõÚøìÍžtÿÿÿA;²Û8tRNSGÕýø± å­û’ðóõýþþ þ þ þ þ þþ þ þ þù ¯þûŽ  QPÿ·bKGDˆH pHYsÄÄ•+tIMEã KkÅVIDAT(Ïc` `db¶V6 vK+k0°±å@‘°³wptrvqus÷ð´€N./˜„·/øq%ü  0‚yBB±€0^†ðˆHLÅÇÏ‹ âÂã’’’’TJBrrjRš0CzFfVvvvNvvf6de犈2äå—–•–•—‹‰3TTVUWUW×T×V×T™UµµÕÕu’ õ M` „M`VS³”4CKk[[{Gg[{{[W[gwW{ôÈH3ôöõO˜8qÒ¤I“§L™4aÊÄ)S'OèŸ&+Ç0}ÆÌY3gÏœ $!4Ì™+¯À0/~þ‚…ó-X°`ñ‚% -Y¸`þÒ…iŠJ ÊË–c‚*ª jê+1†¦ƒ¶Ž®ž>:004Æ¡±‰):03g‚ù·2™Á`%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_open_16.png000066400000000000000000000014361440571307300177460ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF&PLTEÿÿÿŽ¢´€“¦€“¦ˆœ®µÆÕ€“¦ˆ™§€“¦©‹,¿‡Á‡¾„º€´z®t§m¢gŸcœbšc™^˜^[0U% €“¦üÿÿèÿÿêÿÿëÿÿíÿÿþÿÿ°¾Ì„˜©±æÿ´ëÿ¸òÿ»ùÿÕÿÿÿÿÿ­‹"‡ˆÿÿîÿÿïÿÿèĈÿÿíýá{Á…üàyüßxýßyüßyýàyýßxÿÿ漂üÝuüÝtûÝuüÞuûÝtÿÿã·}ÿÿàûÚpûÚqûÛpûÛqÿÿܱvÿÿÝúØlú×lú×múØmÿÿÙªpÿÿáùÕhúÕh¤jøÓeøÒeùÓdøÒdùÒdùÒeùÓeÿÿä™^3þ*ñtRNS~öû¯ü©úüþþþþþþþþþü¯ýú›  \…!bKGDˆH pHYsÄÄ•+tIMEã KkŵIDATÓ]ÈUÂ@@ч»»»;EJ±Ái ´¸Ûþ7AC€L8Éý¹ÿDâ€@"•}‡8 G¢±xàM®€D4™Jg²¹%ä ¸¢ Š¥2†PC¥Zèdƒj¶HªÝ ÚdG ÝB½>Bh0"4ÒÁx2¥–¥Y†ž2ìLóÇ/9Žç9Ájm€Ív·ß öïF8ÇÓùx¹Þn÷ëåô0¹ZÂl-`µ=1v8]n÷Çç¶F2ÑQC%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_picture.png000066400000000000000000000017161440571307300201530ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<¼PLTEÿÿÿ<<<>>>„„„———œœšœ™›—š˜“š’‘‘‘………………“…KKKLLL```IIIIIIdddTTT‹‹‹âââòòóòòòñññïãÉïÉyîÈyßÓ·}}}ññò×ר…ˆ‹^`daeh‘“ÞÞßéééá»sÿæ]ÿè{ß¹pzzzyyyïïñÖרehktwz“–—‘hmooqsØÙÙÙθ̨gÆ¢aÅ¡`ÐÅ®qqqîîî—˜˜‹ŒÏÏÏÀÀÀ¶¶¶µµµ{|}¡¢¤ÓÔÔËËÌÌÌÎÖÖÖkkkèèè|||¯¯¯­­­“““‚‚‚¹¹¹œœœ………××××ØØØØÙÞÞÞhhheeeààá455«««¨¨¨†ˆˆEFGÖÖ×ÚÚÝáââèèéééë___SST}}~ËË˃ƒƒÉÊÊVXYmmnÕÖÖÝÝÝãããYYY²´´==?‰‰‹ÀÀÁ¸¸¸oop<=>»»¼æææSSSçç笭­TUVABD?AB]]^¹¹ºÎÎϸ¸¹ÈÈÈÅÅÅÚÚÚÊÊÊææçäææÐÒÒÕÕÖãääIIIÿÿÿÖé߯tRNS ÙÝ eñògîðëíQæçS)'s`bKGDˆH pHYsÄÄ•+tIMEã KkÅÕIDATÓc`ÀŒL’’Ì,¬lìœ\Ü< ¼|RH€_€APZFFFVä•„”UTTÕÔ54µ´utõtõ  ŒMLÍÌ-,­¬mlíìœ]\ÝÜ=<­¼¼}|ýüüƒ‚CBÃÂ#"£¢¥cbãâ“’SRÓÒ32c²´³sró‚ó ‹ŠK´µ³JýËÊ+*«ªkj£´êüýKꛚ[ZÛÒÚ;:»ºë„{z{ûú'””Lœ×Û›+ *6 ˆK0Â<ÙJx¨9%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_print.png000066400000000000000000000027411440571307300176330ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFâPLTEÿÿÿ­°µ©«±©«±¨«±’”™¦¨®¥¨®OQSIKM¢¥ª¢¥ª:;=’¨¶ ¦ ¦08>„¬Á™œ¡™œ¡HXa™™œ„„ˆ„„ˆ††Š“”—‹‹††Š}}€224  bcf_`cTUXcdhVWZY[^XZ]PQT MNQ)*+qswrtx679}ƒ}ƒ †ˆ†ˆ wy}}€…}€…_advx|*+,+,.©«±óöûõøþô÷ýòõúðò÷òôùñóøçêðêíòéìñ„„ˆ“zzz{{{ŒŒÍÎÐãäåìîð···³³³´´´~~~ëìíäåçÆÇÊ––šããåÅÆÆñóõyyy»»»©©©¨¨¨ªªª¹¹¹}}}òóôëìî””˜››Ÿåæèôöøxxxµµµ¿¿¿|||ö÷øñòôéê옘œššžïïñâãåùúüwww™™™———ššš±±±ûûýøøûððó’’–ññôùùüúûýuuuŸŸŸüüþ”…†Šêëíòòõö÷úttt¢¢¢œœœ¡¡¡øøúƒƒ‡{{àáäçèìóóõsssrrr«««òòôxy}uvyÚÛßáâæååêððòõõööö÷ïðòååérswoptÕÖÚÜÝáÝßã­%%­lmqjkoÐÑÕרܨÙÞghldeiÉËÎÒÓ×kln>?@;<>78:^_aÊÌÐÑÓ×ÉÊΨ©¬ÈÉÍÊËÏSTWŽ’š’—ŸUWY´µ¹ÇÈË ¡¤Y[^YZ^efjÒÖÞÙÝåØÜãfhlKLNUVYáäìåè🢧¢¥ªçêòåéðçëóìðøêîöðôüîòú~€…ÿÿÿÚ1›ZtRNS«ýþ°÷û÷û÷û÷üMâýÖDçÚ þÝÕHÙþüÔE öýL) ôü3öûµýþÀ( %2ÜÅbKGDˆH pHYsÄÄ•+tIMEã KkÅIDAT(Ïc`F¦(`fae@¶èˆeçàDHpÅÅÂ@47/\œ?>…àÂ"IÉ0"*&”LMKG™RÒ2 ²YÙ9é¹y_PXT,'ÏPRZV^QYU 5µuõ E MÍ5-­mùp í]Ý=½Š }ý&NÊ›<¦N˘>cf¯ìÙsæÎ›ŸÞ óÓÌ™½P™aÑâ%K—-_+3V-Y¼Z…aÍÚuë—o؈Ë6m^·v‹*ÃÖmÛwìܵvíÙ»}Û>5†ýB‡8ªÎpìø‰“èàÄñS §Ï?{öÜù 0pñÒå+ǯjj1h_»~ãÆÍ[·áàÎÝ{÷îëè2èéûˆùÂ"ÐOÌ?à ‡ Ch˜m¸ ˜GD‚… ™‘O¶%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_print_16.png000066400000000000000000000016501440571307300201370ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF•PLTEÿÿÿ©¬²¨«°‘“˜˜£¬£¦¬NUZ_fk‘¡¬ ¦nx’’•††‰ƒƒ†ŒŒ‘‘•‘‘•——›““—‚‚†tuylmqefi^_b\^a`adXZ]WX\&&(Z[^Z[^y{€bdggjm~€…}€„78:¬¯µ¦©®õøþô÷ý £©òõúñôù’’•hhhfff††‰ÕÖØëìíeee½½½ººº¼¼¼gggààâÒÓÕ¾¾¿ÎÎÎcccÃÃò²²±±±ÂÂÂëëíääæ˜˜œîîðúúü```¥¥¥¤¤¤ddd÷÷øïïò””˜ëìïùùû\\\„„„îîñƒ„ˆÞßâêêíôôö÷÷ù÷øùóóõÜÎÑààãvvzÕÖÚÞßãàáåϼ¿Æɸ»mnrÌÍÑÔÕÚ«¬°FGI?@BŸŸ£ÌÄÈÎÏÓfgk´µ¸ÉÊ΋‘”›±µ½–™ ÇÈ˲³·YZ^fhlµ¸¾ãçÅegkWX[ÁÄÊæêòª­³ìï÷ÆÉÐÇËÒðôüÌÐ×~†ÿÿÿÑå &tRNSÔµûûpóñmìðûûûûûûêî^êêf¥¹Ÿ³eõöË2PJbKGDˆH pHYsÄÄ•+tIMEã KkÅÉIDATÓc````Tƒ&f`Q×€MV6v‡–6èprq30ððêêéCž?ƒ€¡‘±‰)˜™[X 2YYÛØÚÙƒ¾£“3ƒ°‹«›»xzyûø2ˆøùBApƒhhXxD$DDEÇÄ2ˆÅÅ'À@bRr ƒxjZzF&ddeçä2HäåAqHI©$ƒ”tYyE%TU×ÈÈ‚Ü.W[§®®^ßÐ(Ï MÍ`ТPRnU 4­?vB§R%%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_print_preview.png000066400000000000000000000023651440571307300213760ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFPLTEÿÿÿ²²²®®®±±±®®®ªªªœœœ888MMMŒŒŒ ;;;„„„222ƒƒƒ///¸¸¸ £íííÚÚÚúûûÿÿÿƒƒ†ŒŒ‘‘•\^aWX\&&(………ƒƒƒWWYnnn•Œ”&&&®®®ùùùûûûíîïìíîììíëìíëëìêëìêëëéêëèéêçèéîïïííîéêêçéêïððíîîððñîïðîîïññòðññïðñïïðìííëììòòóóóôñòòôôõòóóõõõóôôöö÷öööõööõõöôõõüüüö÷÷µ·½¬¯µøøø £©òõúñôù ¥÷÷ø÷÷÷ÈÉÊ‹‹Ž’’•{{{zzz|||††‰÷øøùùú˜˜œÕÖØyyy»»»¹¹¹ºººààâÒÓÕøøùúúú¾¾¿ÎÎÎxxx¿¿¿²²²±±±¾¾¾ëëíääæ„„ˆëìïùùûsssîîñƒ„ˆúûûùúúnosÕÖÚÞßãàáåϼ¿Æɸ»mnrghkÌÍÑÔÕÚ«¬°FGI?@BŸŸ£ÌÄÈÎÏÓfgkûûü‹‘”›±µ½–™ ªªªüüýklo´µ¸ÉÊÎÇÈ˲³·ýýýÂÂÃegjYZ^fhlµ¸¾ãçÅegkWX[„„„¸¸¸¶¶¶ˆ‰ŠŽ‘–ÿÿÿùõ¡Ù.tRNS°þ°ûûûû ûûýþu~olñmðîêf±þÖ)  õö: C4bKGDˆH pHYsÄÄ•+tIMEã KkÅ„IDAT(ÏUÑeSQ†áµ»»»ã,ºâ.v'‚ ‹b¡ba»vawwwwüAÏžEÑûë5ÏÌ;ób¦§ý?} eðÿ#c-ðbb‰8~}s{wÿðø{~yõô‚àíó†zÿP}ràëç!0(8$T[Ø,<"2 û¦¾%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_print_preview_16.png000066400000000000000000000016171440571307300217030ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFtPLTEÿÿÿ²²²íííz|~ÿÿÿùúú|}€qswefiabe^_b[\_WX[Z[^ŒŒŒ{}‰ŠŠ‘jlp®®®­­­¯¯¯ÿÿÿíîïìíîëìíëëìêëì“““îïðîîïííîìííëììððñïððîïïþþþñòòðñòïðñöö÷úúûúúúèèèóóôòòóññòö÷÷œŸ|||ôõõóôôòóóøøøóôõuvwô÷ýwxyöööõõõôôõùùùŸŸ¢}}€www‡‡‡÷÷øõõöüüühilßàâ‚‚‚´´´¶¶¶ÜÝàøøù÷øøccgïïñ”””‹‹‹ìíðùúúüüý_`cÑÒ×ççêëëîëìïçèëÐÑÖûûûýýþ]^b®¯µlmpEFHKMOMNPxy|¬¬²   ¨¨ª^_aikn¿Ã˾ÂɼÀÈgilÍÍÍÌÌÌ}ƒíñùìï÷Š’ÌÈ„tRNSµ“¼ˆŽý™÷ûûöõ…µû ¼þ¼ I¤w„bKGDˆH pHYsÄÄ•+tIMEã KkÅÞIDATÓc`”„) `die ÈÉ+(*€Œ23X@EUM]Ad”YÀšZÚròòò J:ʬ`]=}UuC#c6°€‰©™¦¶¹…%°s€¬¬mtmíì€À‘“(àäìâêæîá \Ü@/o_?ÿ€ÀÀÀ ` @H¨¹OXxD$ÈFñ¢]mcbãâ’’ù€)F®©ié™YÙÙ9¹ü y`_ä—” 2É*AYyEeee•°ÐeLÌ` Z]]-&.Á¿(0i+? e%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_save.png000066400000000000000000000023301440571307300174270ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF=PLTEÿÿÿLLLbuž]o—`t_p™^r˜^p˜^p—Xa}V^r]n’]o—ËÝ÷Ìáûÿ­ ÿ¬Ÿþªœþ©œÿ¨›ÿ§šÿ§™ÿ¦˜ÿ¤˜ÿ¤–ÿ£•ÿ¡“þœŽÿœŒ»Òò¸ÐñÊÞ÷^kyÿI.ÿI-„­æ¶ÐïÈÜ÷Œ¹ñÿÿÿ‚«äµÍîÆÛöйðùùúúúú‚ªã³ËíÄÙôеîøúùüþý€¨á±ÉíÂÖôˆ´íõõö÷÷ø§à®ÇëÀÕò‡³ìðñðñòò~¦ß¬Åé½Ôò†±êîððóõô¤Ý©Ãè¼Ññ…°ééêìêìí}£Ü§¿æ^r˜ºÏðäæåæèç|¡Ú¤¿å^p˜±Èêx›Ô›´ß®Æê€¦ß¥Þ~¤Ý}¢Û|¢Û{ ÙzŸØxÖxšÓx™Ów™Òš²Ý­Äç‚—µ…†ˆ†††’°v˜Òu˜Ñ—°ÛªÂç¿¿¿ÆÆÆÈÈÈÍÍÍÏÏÏÒÒÒÔÔÔÖÖÖÙÙÙ×××u—Г­Ù| ÚÉÉÉÌÌÌ–—š˜™œÓÓÓu–Ït•Ïs•Α«×^p—£»âzÖy×qËÎÎÎÊÊÊÄÄÄÁÁÁt“Ìr‘Ìq’Ë‹¦Õ ¹àyœÕxœÖÃÃÃÀÀÀ½½½ºººqËrʉ¤Óž·ßw™Ó¼¼¼¹¹¹µµµ²²²rÉqÉoŽÉ‡¡ÐˆŸË¬Ú’“–”°°°­­­ªªª§§§¤¤¤oÇnŒÆ‚›Ì†ŸÊ–¯Ú”®Ú¶¶¶¬¬¬©©©¦¦¦¢¢¢   œœœƒœÎ‚›Í‚šÌ˜É›÷š tRNS•þ«õöööRe¿Ì˜pbKGDˆH pHYs  šœtIMEã KkÅkIDAT(ÏuÒeOC1€a\‡»;ÅÝÝ]‡3Æð\·]t¸»»»»Ãoã¶ ÉÂû±ON“¦GBâߤ¤Y“¡AVEUM]CSK[GWOßÀÀÐÈØØÄ”Eƒœ™¹…å,¬¬ ØØ¢_ÙÙppDNÌœ‘‹+7wäÁÌyyðñE~ÌüQ@  `Â,……ˆˆDQÌ¢QL,¸x”À,%%cHIµBiÌÒ;Cf–×ïwdçÈÍËÏçp’ ¸lva!WT\RZ†A¾œ>®àÃw•¥UÕ5j9\~]}CcSs‹@(âSÕŠA!™ËnƒöŽNè â&èîéíÃÐ?À±†ad´al&&§¦ÉÄÌàìE4ÔÏ/,.ÁÔòÊ*µ¢âu ¯†ºÍ­mØÙÝÛÇÀ:8¤(?‚ã“Ó³ó ¸¼¼ºÆ (s{K÷'OÏ/¯ðöþñ‰AR‰þ|`„—AùÿåùÖŒí] !%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/file_save_16.png000066400000000000000000000015361440571307300177440ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFSPLTEKw°Ht­Ht­Ht­Ht­Jv¯Ju®eˆºHt­Iu­Ow©Nv¨Lw®It­Ht­¹Íéÿ¨›ÿ§šÿ§™ÿ¦˜ÿ¤˜ÿ¤–ÿ£•©Áá¶ÌèÿI-¨¿à³Éæÿÿÿüüü£»Þ°Æå ¹Ü¬Ãã÷÷÷ö÷÷öö÷÷ö÷œµÙïïï™±×§¾ßççççèç•®Õ¢ºÝªÒŸ·Ûq•Éy…˜{|~{}~{}v„›lŽÃŒ§Ïœ´ØqÀÁÁÁÇÇÇÊÊÊÎÎÎÑÑÑÓÓÓÆÆÆ{{|‰£Ì—±Öp޾}~ÐÐÐzzzÕÕÕÏÏÏÅÅÅ¿¿¿…ŸÊnŒ¼~ØØØÈÈȽ½½···±±±z{}›Ç©Ñq޼}ËË˺ººµµµ¯¯¯ªªª¤¤¤|—ÈŸÅ}~€¨¨¨¥¥¥­­­§§§¢¢¢œœœ–––zz|wºx“Áz{~zz}yz|yz{‹¢ŽûtRNS­þýüû¡Ç÷ ÑøôõÏpÔóbKGDœA pHYs  šœtIMEã KkÅÙIDATÓc`àãcdddfffV~A!aQ1çc`‘DR| ÌÒ2²p #GP (Ê*)+)©(«*))ɨñ10‰Ë¨ÃŒP@SFKKK[ LÈête€£¾¡›˜š™,,¬¬mlíìmÍœ€Î.®nîîž6^ÞFf>| |:¾~þîîAÁ!¡fa@ðˆÈ(w÷è˜Ø¸øP³>6öĤ ä”Ô´ôŒÌ¬ì>N.÷Üмüü‚‚wn^ò*ryÙÅ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/flexible.png000066400000000000000000000006741440571307300172750ustar00rootroot00000000000000‰PNG  IHDR szzô pHYsÄÄ•+nIDATXÃc`£`P üÿÿ_ˆ 8ˆ9èmy:ÿúX’^–¢Y;€˜‘X÷7p¥µåâ@üÉÂM@ü‰¿“ÖˆA²ìkq’Ø1Ùq9Ž'”€òs‘,»ÄL@,*‹‰q@Ž8ü u #}—‘ÔÎ@Ÿ Aä:*°èáFKý)HrŠ@üÍû€x#.E6,ˆ¯#á@üÉ€Ÿ ‚Í&hŽ4A“Ï"à©øB„ˆÑ|¸MM"’H3Êp”ø€dÈd´PB’›€$wjÐ(^ ÄË‘p1PƒÆ  ÉÀ:ÔÎë',: câOHâe´t@1’E „)ÄÖhñiCKÈ£åˆ6PžGâbvZ¹»ÐŠÜHüEô¨ñÐB¹€1¥W½ß‹Å½ôlõ€*š Þ Ä»8$6Ú£€R.ØXo&S&IEND®B`‚leocad-23.03/resources/gear_in.png000077500000000000000000000041731440571307300171100ustar00rootroot00000000000000‰PNG  IHDR szzôtEXtSoftwareAdobe ImageReadyqÉe<IDATxÚ´W T“W¾É’@„$ÈŽ âÈA¥JØ,ZåŒ"¥Z 3ÖžñxÚ©3.tœª]FG[×*Щ§N»ÌQ¨3¥gDYB €†°Œ†ˆ²IÈJ sßßß–3g(E:ÿ9÷¼¼ûÞûßýïýîwoXð¿ΉSg E"á½Þ ÝõÊoÔ¢8z'§ÏÍÍU<<¬»úê®ì§Qg‡<ìIô·cÍ/‘"‘H¼{ïëä"ŠŒdNôdìƒ>“à444tý¶¢¢J@ ˜õÔ ÈHæDOÖɾÿ—vYUežB¡„À ¹ÀãqŸ:x舎ŒdNôd}¦î§c=™É+Væ.Àa³aëË/‹ÅF·8ˆ+\€¬ß,+ ©,bÄ¡·Žâ¸ã 6›í3‹%Mˆ“ΊŽeS i‡éx7¸‹E°P"ÆÆFUËïkúûÓ¼¼½÷q8œ \¾ºïÍצL 8¼üW›ž—Yh¼­x~H«……QQP-¯>ßGG3Ÿf‹Ô÷Úi½4v<ìîœ={¶" q±hñ"ÈÉÉ{LÃ5€"àZ"Pµ©—i4àçï‹Eƒ¢Q N\.DF†Auµšš[`dÄ‹—DƒNg „åI‰z½þu­ŒF£ÃB°ašŽìúºoþ}³¬´Àn·?|Ý÷»ÀÏæC]}=”––^»üEÁÛè(ßɉ;?<,úú4àïç ¹yïB]]}¼Z–÷×óçöáûQ,Ó ÙüEwµèŠ.>>qŸÅf>‡èw‚ŽŽh¨¯;×ܤláóùZ‰D’‚ñ¦×Ç3V« rÏžÎÆóý(Zãt@H1Ø",gyaó–Ÿã$=))ô:=8;»€Á GôkΜÀÚ°ðð—CCC"ý|ýÀb1ƒX,†ÚÚZXºtYð’'–µ}S[£œnjp³‘áö"òßƘF@ð¼¹´‹Q®n³í50 Ñ€‡§'ÄÅň~„>êå5Æ13Õj5Ô74à™¾Nß*6›½q||¬è÷¿ËNŸÊ BD|rù‹[¶@ZZ*L Å×KÑ Å‹Ù ñR)<“þ4=ZqNôîîbÈ/¸ .|&³ 6mÚccãs1•7fïØc㎵?†ª x&“©òÜûçÇñsJrÃ0Þ~Ri,X1õœßs´“py\¨’É@©Tª”ŠswUªôââI==Ý—===7XC££$ªÀgR’sôØÉ$3ôˆ£hïî]ßy†`Ï=ûÎV=QÆ<ðИOGŒFÿUO­ü6V,‡ã[#ð2¸ÕPßvâØ±_¸Õp+_3 9¹‘@Š\ÎÆýHpm«õ E%„„,H_—ºNž:³v"WÌ(÷“+ÆPÜÌfc£»ØÝ_­¾—.å£Û)tñdeebxÜA.¯Î+üú«ÓY™Àår3‘A!>.«§úû5ðÒ‹[`X«s«’ËsyÈ')«WAáWWˆ7I¦ð@1_mcÈÃĤ%;!qùùÌÌ PVVòêªÃùÿö–P(ì‰ÅËW®L•Jƒ)؃¬éž’² à^{;Rw t÷ôâïN°Ùaé1€™EEÿDúVö<ð‡T|ÿÀ#®˜¬RÞÞÞH=^tJn\ÏG]+ïܹC3rg“²ñ‚Ùl“É 20›-HÛ ñÒ%ôHæDOÖɾŽööñ=ݹ‚šÄÁ¼yÁ ·Š€þ¾¾¿´¶4_A]ñ–¯/´¶Þ‘hú/‡GHžMKMõàáC'‡¦e,PÐÒÚÊÐö"BÏÈ%#ŠìÚ]Q~ó(ö,Ç–?8ÿk‚†Z 6,È‘|¾ åáá••Ü0æ*u;„,˜¸¨òòòkØ+\ŠOHÌÂôL‘ÆÆÂ]•ÂÃBÈ{]_s¿Žà A]tèàôÉ xL²nÀí,.—¿vÏžWi¤Ñ ë€ ûaÚæÒ,;{'ÆÄ[Gާ³aÒ†d’’J †ŠÃ‡ßN"ÁÆ\Û¾}pù\ì#ìàáá±Ò¸çƒþìëçûɲðß™'OžBætÐ…˜¨À÷qYÓl`\Qæ>™¼"Y§M^±úøæÍ/¸²–íxvËtéîêꢳ‚жiyóÛ}ô‰¡¬´x·P(rÂê[†ïꤦiIYKgG‡º···Ç×Ïo iÆA=f/IíØùÊŘ˜˜´t,R_~YˆS3øúù€›PˆØ`ÓqÇ0ÑÒ=lãÖ¯SÒ4OR[#¿ÈœÇ4ÀYìî¾nÃút(øâïPYYY2<¬mU©Ú6S[ðÚžÝpôØqRíêƒ2x>Ïn€¦¦æuÿ] çáiµZã?þI€Y!ûüÓ o0éZ°uÛŽR ]O@ù^^Î:æ¢üßnßYˆ¶Ðj6WôOEDSb!çÌé$&+†™¸îðb#ÃÜ'#>](²ïÝܳ«™/djÏŒ \Þ>¨Ì @ùØ[Èöï?y.ùž3sfâþïZ²Ÿò! D3 êý©þ#üÔp7s7›§ê ÿ#À‘ô¢rs¾¤¶IEND®B`‚leocad-23.03/resources/help_homepage.png000066400000000000000000000022361440571307300202740ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<CPLTEÿÿÿÌnÂVÁTÄq$Èj¾S¼T ¶xB€}‚{€ŒÇh»Q®T‚†‘Æd·Oƒ}€Å`³LŽseÄ^¯J¡hBºVªH¨I ´[ŸA C†9ˆ:8 ^']D[$6 M6&€€€@,€†††,++–––778˜˜˜„„„999•••ƒƒƒ@@A’’’ƒƒƒhhhiiiÛ0Û1v|ˆØ‹,à™6à—5ÙŒ,xzƒáéötz†Ù‰,á•4ÃdÃcà”4ÙŠ-¢W&ÚÞéot€Üƒ,å4Â`´\³\Â_åŽ4݆/¶m?lluß}+ëˆ3Á\¶ƒaÔÕÖÑÒÓ³`À\ê‡3á~,—Nâz-ï‚2ÀX´‚bØØÚåæèâãåÎÏÒ­}^¿Xî‚3ãz,Þq$ï‚3¾W²‚cÙÙÚççéçèêãäçÜÝàÉËΩz]¼Vï2¿Y»V²ƒeÚÚÛèèêèéêáâåÝÞâÖØÜÃÅÊ©|`ºU‰dLßßàééê—š¤uz‡‘•ŸÐÓ×ÌÍÐŽŽŽïððêëìpußçõrw‚ÐÓØÚÜß•••òòóèéëiny믏٫ÕÍØèkpzÏÑÖÜÞâ”””ðñòæçéchrÈÒãÄÏáeisÍÐÕÜÝá’’’ïïñ„‡^bl‚‹ÛÝáüüüûûûúúûúúúùùúøùùøøùöö÷ŒŒŒŠŠŠ‰‰‰ˆˆˆ‡‡‡†††………„„„ÿÿÿ[‰9tRNS ¢³¶¶µµ¼¶·¸ ¹½ žww“ü– øøøø¶ý¯ËãÌúbKGDˆH pHYsÄÄ•+tIMEã KkÅþIDATÓc`F&f$ÀÊfiÅÎÁiÍåsóØØÚÙó:8:ñùüÎ.®nîž^Þ‚ ¾°¯Ÿ@`PpH¨/*Ÿ ÎÀ !™˜”œ’š–ž‘™•#%Í “›—_PXT\RZV^Q™+Ë WU]S[WŸÖÐØÔÜÒZ%Ï  ØÖÞÑÙÝ=½JÊ* ªj}ý&:Nšä8yÊTu M­iÓgÌœ5{öœ¹óækë­Õ]°pÑâ%K—.Y¶|…¶P@媒Õk€`íòu†@£õ6nÚ¼eËÖmÛ¶›€œnºcç®Ý{öîÛ·ßÌÜ‚/ RöNNQé%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/ldconfig.ldr000066400000000000000000001125411440571307300172620ustar00rootroot000000000000000 LDraw.org Configuration File 0 Name: LDConfig.ldr 0 Author: LDraw.org 0 !LDRAW_ORG Configuration UPDATE 2022-03-31 0 // * LDraw and BrickLink mostly share naming conventions for their colours. 0 // * Where possible LEGO colour numbers were used. 0 // * The LEGO numbers, names and LDD colours are taken directly from LEGO Digital Designer. 0 // * Colours were compared with Ryan Howerter's colour list. 0 // * Most transparent colours were altered so that they can be displayed with their LDraw alpha level. 0 // * Edge colours for solid, pearl, metallic, solid internal common material were calculated 0 // the following way: 0 // If the lightness value L in the HSL colours system was above 20%, a Gray with 20% relative 0 // luminance in the terms of RGB-Gray was used. 0 // If the lightness value L in the HSL colours system was below 20%, a Gray with 50% relative 0 // luminance in the terms of RGB-Gray was used. 0 // * Edge colours for transparent, chrome, milky, glitter, transparent internal common material 0 // were calculated the following way: 0 // The lightness value L in the HSL colours system was lowered by 20 percentage points. If the 0 // lightness value L in the HSL colours system was below 20% it was raised by 20 percentage points. 0 // * Edge colours for speckle colours are defined by the value of the MATERIAL colour. 0 // * Rubber colours got their value from the corresponding solid or transparent colour. This applies 0 // also to the edge colours. 0 // * Material Glitter colours were calculated the following way: 0 // The lightness value L and the hue value H in the HSL colours system was lowered by 20 percentage 0 // points and 20 degree. 0 // LDraw Solid Colours 0 // LEGOID 26 - Black 0 !COLOUR Black CODE 0 VALUE #1B2A34 EDGE #808080 0 // LEGOID 23 - Bright Blue 0 !COLOUR Blue CODE 1 VALUE #1E5AA8 EDGE #333333 0 // LEGOID 28 - Dark Green 0 !COLOUR Green CODE 2 VALUE #00852B EDGE #333333 0 // LEGOID 107 - Bright Bluish Green 0 !COLOUR Dark_Turquoise CODE 3 VALUE #069D9F EDGE #333333 0 // LEGOID 21 - Bright Red 0 !COLOUR Red CODE 4 VALUE #B40000 EDGE #333333 0 // LEGOID 22 / 221 - Medium Reddish Violet / Bright Purple 0 !COLOUR Dark_Pink CODE 5 VALUE #D3359D EDGE #333333 0 // LEGOID 25 - Earth Orange 0 !COLOUR Brown CODE 6 VALUE #543324 EDGE #1E1E1E 0 // LEGOID 2 - Grey 0 !COLOUR Light_Grey CODE 7 VALUE #8A928D EDGE #333333 0 // LEGOID 27 - Dark Grey 0 !COLOUR Dark_Grey CODE 8 VALUE #545955 EDGE #333333 0 // LEGOID 45 - Light Blue 0 !COLOUR Light_Blue CODE 9 VALUE #97CBD9 EDGE #333333 0 // LEGOID 37 - Bright Green 0 !COLOUR Bright_Green CODE 10 VALUE #58AB41 EDGE #333333 0 // LEGOID 116 - Medium Bluish Green 0 !COLOUR Light_Turquoise CODE 11 VALUE #00AAA4 EDGE #333333 0 // LEGOID 101 - Medium Red 0 !COLOUR Salmon CODE 12 VALUE #F06D61 EDGE #333333 0 // LEGOID 9 - Light Reddish Violet 0 !COLOUR Pink CODE 13 VALUE #F6A9BB EDGE #333333 0 // LEGOID 24 - Bright Yellow 0 !COLOUR Yellow CODE 14 VALUE #FAC80A EDGE #333333 0 // LEGOID 1 - White 0 !COLOUR White CODE 15 VALUE #F4F4F4 EDGE #333333 0 // LEGOID 6 - Light Green 0 !COLOUR Light_Green CODE 17 VALUE #ADD9A8 EDGE #333333 0 // LEGOID 3 - Light Yellow 0 !COLOUR Light_Yellow CODE 18 VALUE #FFD67F EDGE #333333 0 // LEGOID 5 - Brick Yellow 0 !COLOUR Tan CODE 19 VALUE #B0A06F EDGE #333333 0 // LEGOID 39 - Light Bluish Violet 0 !COLOUR Light_Violet CODE 20 VALUE #AFBED6 EDGE #333333 0 // LEGOID 104 - Bright Violet 0 !COLOUR Purple CODE 22 VALUE #671F81 EDGE #333333 0 // LEGOID 196 - Dark Royal Blue 0 !COLOUR Dark_Blue_Violet CODE 23 VALUE #0E3E9A EDGE #333333 0 // LEGOID 106 - Bright Orange 0 !COLOUR Orange CODE 25 VALUE #D67923 EDGE #333333 0 // LEGOID 124 - Bright Reddish Violet 0 !COLOUR Magenta CODE 26 VALUE #901F76 EDGE #333333 0 // LEGOID 119 - Bright Yellowish Green 0 !COLOUR Lime CODE 27 VALUE #A5CA18 EDGE #333333 0 // LEGOID 138 - Sand Yellow 0 !COLOUR Dark_Tan CODE 28 VALUE #897D62 EDGE #333333 0 // LEGOID 222 - Light Purple 0 !COLOUR Bright_Pink CODE 29 VALUE #FF9ECD EDGE #333333 0 // LEGOID 324 - Medium Lavender 0 !COLOUR Medium_Lavender CODE 30 VALUE #A06EB9 EDGE #333333 0 // LEGOID 325 - Lavender 0 !COLOUR Lavender CODE 31 VALUE #CDA4DE EDGE #333333 0 // LEGOID 36 - Light Yellowish Orange 0 !COLOUR Very_Light_Orange CODE 68 VALUE #FDC383 EDGE #333333 0 // LEGOID 198 - Bright Reddish Lilac 0 !COLOUR Bright_Reddish_Lilac CODE 69 VALUE #8A12A8 EDGE #333333 0 // LEGOID 192 - Reddish Brown 0 !COLOUR Reddish_Brown CODE 70 VALUE #5F3109 EDGE #808080 0 // LEGOID 194 - Medium Stone Grey 0 !COLOUR Light_Bluish_Grey CODE 71 VALUE #969696 EDGE #333333 0 // LEGOID 199 - Dark Stone Grey 0 !COLOUR Dark_Bluish_Grey CODE 72 VALUE #646464 EDGE #333333 0 // LEGOID 102 - Medium Blue 0 !COLOUR Medium_Blue CODE 73 VALUE #7396C8 EDGE #333333 0 // LEGOID 29 - Medium Green 0 !COLOUR Medium_Green CODE 74 VALUE #7FC475 EDGE #333333 0 // LEGOID 223 - Light Pink 0 !COLOUR Light_Pink CODE 77 VALUE #FECCCF EDGE #333333 0 // LEGOID 283 - Light Nougat 0 !COLOUR Light_Nougat CODE 78 VALUE #FFC995 EDGE #333333 0 // LEGOID 312 - Medium Nougat 0 !COLOUR Medium_Nougat CODE 84 VALUE #AA7D55 EDGE #333333 0 // LEGOID 268 - Medium Lilac 0 !COLOUR Medium_Lilac CODE 85 VALUE #441A91 EDGE #333333 0 // LEGOID 217 - Brown 0 !COLOUR Medium_Brown CODE 86 VALUE #7B5D41 EDGE #333333 0 // LEGOID 195 - Medium Royal Blue 0 !COLOUR Blue_Violet CODE 89 VALUE #1C58A7 EDGE #333333 0 // LEGOID 18 - Nougat 0 !COLOUR Nougat CODE 92 VALUE #BB805A EDGE #333333 0 // LEGOID 100 - Light Red 0 !COLOUR Light_Salmon CODE 100 VALUE #F9B7A5 EDGE #333333 0 // LEGOID 110 - Bright Bluish Violet 0 !COLOUR Violet CODE 110 VALUE #26469A EDGE #333333 0 // LEGOID 112 - Medium Bluish Violet 0 !COLOUR Medium_Violet CODE 112 VALUE #4861AC EDGE #333333 0 // LEGOID 115 - Medium Yellowish Green 0 !COLOUR Medium_Lime CODE 115 VALUE #B7D425 EDGE #333333 0 // LEGOID 118 - Light Bluish Green 0 !COLOUR Aqua CODE 118 VALUE #9CD6CC EDGE #333333 0 // LEGOID 120 - Light Yellowish Green 0 !COLOUR Light_Lime CODE 120 VALUE #DEEA92 EDGE #333333 0 // LEGOID 125 - Light Orange 0 !COLOUR Light_Orange CODE 125 VALUE #F9A777 EDGE #333333 0 // LEGOID 128 - Dark Nougat 0 !COLOUR Dark_Nougat CODE 128 VALUE #AD6140 EDGE #333333 0 // LEGOID 208 - Light Stone Grey 0 !COLOUR Very_Light_Bluish_Grey CODE 151 VALUE #C8C8C8 EDGE #333333 0 // LEGOID 191 - Flame Yellowish Orange 0 !COLOUR Bright_Light_Orange CODE 191 VALUE #FCAC00 EDGE #333333 0 // LEGOID 212 - Light Royal Blue 0 !COLOUR Bright_Light_Blue CODE 212 VALUE #9DC3F7 EDGE #333333 0 // LEGOID 216 - Rust 0 !COLOUR Rust CODE 216 VALUE #872B17 EDGE #333333 0 // LEGOID 218 - Reddish Lilac 0 !COLOUR Reddish_Lilac CODE 218 VALUE #8E5597 EDGE #333333 0 // LEGOID 219 - Lilac 0 !COLOUR Lilac CODE 219 VALUE #564E9D EDGE #333333 0 // LEGOID 226 - Cool Yellow 0 !COLOUR Bright_Light_Yellow CODE 226 VALUE #FFEC6C EDGE #333333 0 // LEGOID 232 - Dove Blue 0 !COLOUR Sky_Blue CODE 232 VALUE #77C9D8 EDGE #333333 0 // LEGOID 140 - Earth Blue 0 !COLOUR Dark_Blue CODE 272 VALUE #19325A EDGE #333333 0 // LEGOID 141 - Earth Green 0 !COLOUR Dark_Green CODE 288 VALUE #00451A EDGE #808080 0 // LEGOID 295 - Flamingo Pink 0 !COLOUR Flamingo_Pink CODE 295 VALUE #FF94C2 EDGE #333333 0 // LEGOID 308 - Dark Brown 0 !COLOUR Dark_Brown CODE 308 VALUE #352100 EDGE #808080 0 // LEGOID 11 - Pastel Blue 0 !COLOUR Maersk_Blue CODE 313 VALUE #ABD9FF EDGE #333333 0 // LEGOID 154 - New Dark Red 0 !COLOUR Dark_Red CODE 320 VALUE #720012 EDGE #333333 0 // LEGOID 321 - Dark Azur 0 !COLOUR Dark_Azure CODE 321 VALUE #469BC3 EDGE #333333 0 // LEGOID 322 - Medium Azur 0 !COLOUR Medium_Azure CODE 322 VALUE #68C3E2 EDGE #333333 0 // LEGOID 323 - Aqua 0 !COLOUR Light_Aqua CODE 323 VALUE #D3F2EA EDGE #333333 0 // LEGOID 326 - Spring Yellowish Green 0 !COLOUR Yellowish_Green CODE 326 VALUE #E2F99A EDGE #333333 0 // LEGOID 330 - Olive Green 0 !COLOUR Olive_Green CODE 330 VALUE #77774E EDGE #333333 0 // LEGOID 153 - Sand Red 0 !COLOUR Sand_Red CODE 335 VALUE #88605E EDGE #333333 0 // LEGOID 16 - Pink 0 !COLOUR Medium_Dark_Pink CODE 351 VALUE #F785B1 EDGE #333333 0 // LEGOID 353 - Vibrant Coral 0 !COLOUR Coral CODE 353 VALUE #FF6D77 EDGE #333333 0 // LEGOID 12 - Light Orange Brown 0 !COLOUR Earth_Orange CODE 366 VALUE #D86D2C EDGE #333333 0 // LEGOID 368 - Vibrant Yellow 0 !COLOUR Vibrant_Yellow CODE 368 VALUE #EDFF21 EDGE #333333 0 // LEGOID 370 - Medium Brown 0 !COLOUR Medium_Brown CODE 370 VALUE #755945 EDGE #333333 0 // LEGOID 136 - Sand Violet 0 !COLOUR Sand_Purple CODE 373 VALUE #75657D EDGE #333333 0 // LEGOID 151 - Sand Green 0 !COLOUR Sand_Green CODE 378 VALUE #708E7C EDGE #333333 0 // LEGOID 135 - Sand Blue 0 !COLOUR Sand_Blue CODE 379 VALUE #70819A EDGE #333333 0 // LEGOID 4 - Brick Red 0 !COLOUR Fabuland_Brown CODE 450 VALUE #D27744 EDGE #333333 0 // LEGOID 105 - Bright Yellowish Orange 0 !COLOUR Medium_Orange CODE 462 VALUE #F58624 EDGE #333333 0 // LEGOID 38 - Dark Orange 0 !COLOUR Dark_Orange CODE 484 VALUE #91501C EDGE #333333 0 // LEGOID 103 - Light Grey 0 !COLOUR Very_Light_Grey CODE 503 VALUE #BCB4A5 EDGE #333333 0 // LEGOID 12 - Light Orange Brown 0 !COLOUR Light_Orange_Brown CODE 507 VALUE #FA9C1C EDGE #333333 0 // LEGOID 13 - Red Orange 0 !COLOUR Fabuland_Red CODE 508 VALUE #FF8014 EDGE #333333 0 // LEGOID 19 - Light Brown 0 !COLOUR Fabuland_Orange CODE 509 VALUE #CF8A47 EDGE #333333 0 // LEGOID 14 - Pastel Green 0 !COLOUR Fabuland_Pastel_Green CODE 510 VALUE #78FC78 EDGE #333333 0 // LDraw Transparent Colours 0 // LEGOID 43 - Transparent Blue 0 !COLOUR Trans_Dark_Blue CODE 33 VALUE #0020A0 EDGE #000B38 ALPHA 128 0 // LEGOID 48 - Transparent Green 0 !COLOUR Trans_Green CODE 34 VALUE #237841 EDGE #174F2B ALPHA 128 0 // LEGOID 311 - Transparent Bright Green 0 !COLOUR Trans_Bright_Green CODE 35 VALUE #56E646 EDGE #27AF18 ALPHA 128 0 // LEGOID 41 - Transparent Red 0 !COLOUR Trans_Red CODE 36 VALUE #C91A09 EDGE #660D05 ALPHA 128 0 // LEGOID 113 - Transparent Medium Reddish Violet 0 !COLOUR Trans_Dark_Pink CODE 37 VALUE #DF6695 EDGE #B9275F ALPHA 128 0 // LEGOID 47 - Transparent Fluorescent Reddish Orange 0 !COLOUR Trans_Neon_Orange CODE 38 VALUE #FF800D EDGE #A85100 ALPHA 128 0 // LEGOID 229 - Transparent Light Bluish Green 0 !COLOUR Trans_Very_Light_Blue CODE 39 VALUE #C1DFF0 EDGE #6FB4DC ALPHA 128 0 // LEGOID 111 - Transparent Brown 0 !COLOUR Trans_Black CODE 40 VALUE #635F52 EDGE #2A2823 ALPHA 128 0 // LEGOID 143 - Transparent Fluorescent Blue 0 !COLOUR Trans_Medium_Blue CODE 41 VALUE #559AB7 EDGE #326276 ALPHA 128 0 // LEGOID 49 - Transparent Fluorescent Green 0 !COLOUR Trans_Neon_Green CODE 42 VALUE #C0FF00 EDGE #739900 ALPHA 128 0 // LEGOID 42 - Transparent Light Blue 0 !COLOUR Trans_Light_Blue CODE 43 VALUE #AEE9EF EDGE #59D1DE ALPHA 128 0 // LEGOID 236 - Transparent Bright Reddish Lilac 0 !COLOUR Trans_Bright_Reddish_Lilac CODE 44 VALUE #96709F EDGE #5F4365 ALPHA 128 0 // LEGOID 230 - Transparent Bright Pink 0 !COLOUR Trans_Pink CODE 45 VALUE #FC97AC EDGE #F9345B ALPHA 128 0 // LEGOID 44 - Transparent Yellow 0 !COLOUR Trans_Yellow CODE 46 VALUE #F5CD2F EDGE #B49208 ALPHA 128 0 // LEGOID 40 - Transparent 0 !COLOUR Trans_Clear CODE 47 VALUE #FCFCFC EDGE #C9C9C9 ALPHA 128 0 // LEGOID 126 - Transparent Bright Bluish Violet 0 !COLOUR Trans_Purple CODE 52 VALUE #A5A5CB EDGE #6464A6 ALPHA 128 0 // LEGOID 157 - Transparent Fluorescent Yellow 0 !COLOUR Trans_Neon_Yellow CODE 54 VALUE #DAB000 EDGE #755E00 ALPHA 128 0 // LEGOID 182 - Trans Bright Orange 0 !COLOUR Trans_Orange CODE 57 VALUE #F08F1C EDGE #9E5C0A ALPHA 128 0 // LEGOID 227 - Transparent Bright Yellowish Green 0 !COLOUR Trans_Bright_Light_Green CODE 227 VALUE #B5D96C EDGE #86B22E ALPHA 128 0 // LEGOID 231 - Transparent Flame Yellowish Orange 0 !COLOUR Trans_Bright_Light_Orange CODE 231 VALUE #FCB76D EDGE #FA860A ALPHA 128 0 // LEGOID 234 - Transparent Fire Yellow 0 !COLOUR Trans_Fire_Yellow CODE 234 VALUE #FBE890 EDGE #F7D22B ALPHA 128 0 // LEGOID 284 - Transparent Reddish Lilac 0 !COLOUR Trans_Reddish_Lilac CODE 284 VALUE #C281A5 EDGE #944771 ALPHA 128 0 // LEGOID 285 - Transparent Light Green 0 !COLOUR Trans_Light_Green CODE 285 VALUE #7DC291 EDGE #46955D ALPHA 128 0 // LEGOID 293 - Transparent Light Royal Blue 0 !COLOUR Trans_Light_Blue_Violet CODE 293 VALUE #6BABE4 EDGE #247BC6 ALPHA 128 0 // LDraw Chrome Plated Colours 0 !COLOUR Chrome_Antique_Brass CODE 60 VALUE #645A4C EDGE #665B4D CHROME 0 !COLOUR Chrome_Blue CODE 61 VALUE #6C96BF EDGE #3D638A CHROME 0 !COLOUR Chrome_Green CODE 62 VALUE #3CB371 EDGE #226741 CHROME 0 !COLOUR Chrome_Pink CODE 63 VALUE #AA4D8E EDGE #632C52 CHROME 0 !COLOUR Chrome_Black CODE 64 VALUE #1B2A34 EDGE #3D5F76 CHROME 0 // LEGOID 310 - Metalized Gold 0 !COLOUR Chrome_Gold CODE 334 VALUE #DFC176 EDGE #C2982E CHROME 0 // LEGOID 309 - Metalized Silver 0 !COLOUR Chrome_Silver CODE 383 VALUE #CECECE EDGE #9C9C9C CHROME 0 // LDraw Pearlescent Plastic Colours 0 // LEGOID 149 - Metallic Black 0 !COLOUR Metallic_Black CODE 83 VALUE #0A1327 EDGE #333333 PEARLESCENT 0 // LEGOID 139 - Copper 0 !COLOUR Copper CODE 134 VALUE #764D3B EDGE #333333 PEARLESCENT 0 // LEGOID 296 / 131 / 315 - Cool Silver / Silver / Silver Metallic 0 !COLOUR Pearl_Light_Grey CODE 135 VALUE #A0A0A0 EDGE #333333 PEARLESCENT 0 // LEGOID 145 - Sand Blue Metallic 0 !COLOUR Metallic_Blue CODE 137 VALUE #5B7590 EDGE #333333 PEARLESCENT 0 // LEGOID 127 - Gold 0 !COLOUR Pearl_Light_Gold CODE 142 VALUE #DEAC66 EDGE #333333 PEARLESCENT 0 // LEGOID 148 - Metallic Dark Grey 0 !COLOUR Pearl_Dark_Grey CODE 148 VALUE #484D48 EDGE #333333 PEARLESCENT 0 // LEGOID 150 - Metallic Light Grey 0 !COLOUR Pearl_Very_Light_Grey CODE 150 VALUE #989B99 EDGE #333333 PEARLESCENT 0 // LEGOID 147 - Metallic Sand Yellow 0 !COLOUR Flat_Dark_Gold CODE 178 VALUE #83724F EDGE #333333 PEARLESCENT 0 // LEGOID 179 - Silver Flip-flop 0 !COLOUR Flat_Silver CODE 179 VALUE #898788 EDGE #333333 PEARLESCENT 0 // LEGOID 183 - Metallic White 0 !COLOUR Pearl_White CODE 183 VALUE #F6F2DF EDGE #333333 PEARLESCENT 0 // LEGOID 184 - Metallic Bright Red 0 !COLOUR Metallic_Bright_Red CODE 184 VALUE #D60026 EDGE #333333 PEARLESCENT 0 // LEGOID 185 - Metallic Bright Blue 0 !COLOUR Metallic_Bright_Blue CODE 185 VALUE #0059A3 EDGE #333333 PEARLESCENT 0 // LEGOID 186 - Metallic Dark Green 0 !COLOUR Metallic_Dark_Green CODE 186 VALUE #008E3C EDGE #333333 PEARLESCENT 0 // LEGOID 189 - Reddish Gold 0 !COLOUR Reddish_Gold CODE 189 VALUE #AC8247 EDGE #333333 PEARLESCENT 0 // LEGOID 200 - Lemon Metallic 0 !COLOUR Lemon_Metallic CODE 200 VALUE #708224 EDGE #333333 PEARLESCENT 0 // LEGOID 297 - Warm Gold 0 !COLOUR Pearl_Gold CODE 297 VALUE #AA7F2E EDGE #333333 PEARLESCENT 0 // LDraw Metallic Paint Colours 0 // LEGOID 298 / 336 - Cool Silver Drum Lacq / Silver Ink 0 !COLOUR Metallic_Silver CODE 80 VALUE #767676 EDGE #333333 METAL 0 // BricksetID 910 - Metallic Green 0 !COLOUR Metallic_Green CODE 81 VALUE #C2C06F EDGE #333333 METAL 0 // LEGOID 299 / 335 - Warm Gold Drum Lacq / Gold Ink 0 !COLOUR Metallic_Gold CODE 82 VALUE #DBAC34 EDGE #333333 METAL 0 // LEGOID 337 - Titanium 0 !COLOUR Metallic_Dark_Grey CODE 87 VALUE #3E3C39 EDGE #333333 METAL 0 // LEGOID 300 / 334 - Copper Drum Lacq / Copper Ink 0 !COLOUR Metallic_Copper CODE 300 VALUE #C27F53 EDGE #333333 METAL 0 !COLOUR Metallic_Light_Blue CODE 10045 VALUE #97CBD9 EDGE #333333 METAL 0 // BricksetID 911 - Metallic Pink 0 !COLOUR Metallic_Pink CODE 10046 VALUE #AD659A EDGE #333333 METAL 0 !COLOUR Metallic_Light_Pink CODE 10049 VALUE #FECCCF EDGE #333333 METAL 0 // LDraw Milky Colours 0 // LEGOID 20 - Nature 0 !COLOUR Milky_White CODE 79 VALUE #EEEEEE EDGE #BABABA ALPHA 240 0 // LEGOID 294 - Phosphorescent Green 0 !COLOUR Glow_In_Dark_Opaque CODE 21 VALUE #E0FFB0 EDGE #B8FF4D ALPHA 240 LUMINANCE 15 0 // LEGOID 50 - Phosphorescent White 0 !COLOUR Glow_In_Dark_Trans CODE 294 VALUE #BDC6AD EDGE #8D9D72 ALPHA 240 LUMINANCE 15 0 // LEGOID 329 - White Glow 0 !COLOUR Glow_In_Dark_White CODE 329 VALUE #F5F3D7 EDGE #E0DA85 ALPHA 240 LUMINANCE 15 0 // LDraw Glitter Colours 0 // LEGOID 114 - Transparent Medium Reddish-Violet w. Glitter 2% 0 !COLOUR Glitter_Trans_Dark_Pink CODE 114 VALUE #DF6695 EDGE #B9275F ALPHA 128 MATERIAL GLITTER VALUE #B92790 FRACTION 0.17 VFRACTION 0.2 SIZE 1 0 // LEGOID 117 - Transparent Glitter 0 !COLOUR Glitter_Trans_Clear CODE 117 VALUE #EEEEEE EDGE #BABABA ALPHA 128 MATERIAL GLITTER VALUE #FFFFFF FRACTION 0.08 VFRACTION 0.1 SIZE 1 0 // LEGOID 129 - Transparent Bright Bluish Violet w. Glitter 2% 0 !COLOUR Glitter_Trans_Purple CODE 129 VALUE #640061 EDGE #000000 ALPHA 128 MATERIAL GLITTER VALUE #8F00CC FRACTION 0.03 VFRACTION 0.4 SIZE 1 0 // LEGOID 302 - Transparent Light Blue with Glitter 2% 0 !COLOUR Glitter_Trans_Light_Blue CODE 302 VALUE #AEE9EF EDGE #59D1DE ALPHA 128 MATERIAL GLITTER VALUE #59DEBF FRACTION 0.17 VFRACTION 0.2 SIZE 1 0 // LEGOID 339 - Transparent Fluorescent Green with Glitter 2% 0 !COLOUR Glitter_Trans_Neon_Green CODE 339 VALUE #C0FF00 EDGE #739900 ALPHA 128 MATERIAL GLITTER VALUE #998C00 FRACTION 0.17 VFRACTION 0.2 SIZE 1 0 // LEGOID 341 - Transparent Bright Orange with Glitter 2% 0 !COLOUR Glitter_Trans_Orange CODE 341 VALUE #F08F1C EDGE #9E5C0A ALPHA 128 MATERIAL GLITTER VALUE #9E2A0A FRACTION 0.17 VFRACTION 0.2 SIZE 1 0 // LEGOID 360 - Transparent Clear Opal 0 !COLOUR Opal_Trans_Clear CODE 360 VALUE #FCFCFC EDGE #C9C9C9 ALPHA 240 LUMINANCE 5 MATERIAL GLITTER VALUE #FFFFFF FRACTION 0.8 VFRACTION 0.6 MINSIZE 0.02 MAXSIZE 0.1 0 // LEGOID 362 - Transparent Blue Opal 0 !COLOUR Opal_Trans_Light_Blue CODE 362 VALUE #AEE9EF EDGE #59D1DE ALPHA 200 LUMINANCE 5 MATERIAL GLITTER VALUE #59DEBF FRACTION 0.8 VFRACTION 0.6 MINSIZE 0.02 MAXSIZE 0.1 0 // LEGOID 363 - Transparent Brown Opal 0 !COLOUR Opal_Trans_Black CODE 363 VALUE #635F52 EDGE #2A2823 ALPHA 200 LUMINANCE 5 MATERIAL GLITTER VALUE #292522 FRACTION 0.8 VFRACTION 0.6 MINSIZE 0.02 MAXSIZE 0.1 0 // LEGOID 364 - Transparent Medium Reddish Violet Opal 0 !COLOUR Opal_Trans_Dark_Pink CODE 364 VALUE #DF6695 EDGE #B9275F ALPHA 200 LUMINANCE 5 MATERIAL GLITTER VALUE #B92790 FRACTION 0.8 VFRACTION 0.6 MINSIZE 0.02 MAXSIZE 0.1 0 // LEGOID 365 - Transparent Violet Opal 0 !COLOUR Opal_Trans_Purple CODE 365 VALUE #671F81 EDGE #441456 ALPHA 200 LUMINANCE 5 MATERIAL GLITTER VALUE #2F1456 FRACTION 0.8 VFRACTION 0.6 MINSIZE 0.02 MAXSIZE 0.1 0 // LEGOID 367 - Transparent Green Opal 0 !COLOUR Opal_Trans_Green CODE 367 VALUE #237841 EDGE #174F2B ALPHA 200 LUMINANCE 5 MATERIAL GLITTER VALUE #0B270B FRACTION 0.8 VFRACTION 0.6 MINSIZE 0.02 MAXSIZE 0.1 0 // LEGOID 351 - Transparent Bright Green with Glitter 2% 0 !COLOUR Glitter_Trans_Bright_Green CODE 10351 VALUE #56E646 EDGE #27AF18 ALPHA 128 MATERIAL GLITTER VALUE #59AF18 FRACTION 0.17 VFRACTION 0.2 SIZE 1 0 // LEGOID 366 - Transparent Blue Opal 0 !COLOUR Opal_Trans_Dark_Blue CODE 10366 VALUE #0020A0 EDGE #000B38 ALPHA 200 LUMINANCE 5 MATERIAL GLITTER VALUE #001D38 FRACTION 0.8 VFRACTION 0.6 MINSIZE 0.02 MAXSIZE 0.1 0 // LDraw Speckle Colours 0 !COLOUR Speckle_Black_Copper CODE 75 VALUE #000000 EDGE #AB6038 MATERIAL SPECKLE VALUE #AB6038 FRACTION 0.4 MINSIZE 1 MAXSIZE 3 0 !COLOUR Speckle_Dark_Bluish_Grey_Silver CODE 76 VALUE #635F61 EDGE #898788 MATERIAL SPECKLE VALUE #898788 FRACTION 0.4 MINSIZE 1 MAXSIZE 3 0 // LEGOID 132 - Black Glitter 0 !COLOUR Speckle_Black_Silver CODE 132 VALUE #000000 EDGE #898788 MATERIAL SPECKLE VALUE #898788 FRACTION 0.4 MINSIZE 1 MAXSIZE 3 0 !COLOUR Speckle_Black_Gold CODE 133 VALUE #000000 EDGE #DBAC34 MATERIAL SPECKLE VALUE #DBAC34 FRACTION 0.4 MINSIZE 1 MAXSIZE 3 0 // LDraw Rubber Colours 0 !COLOUR Rubber_Yellow CODE 65 VALUE #FAC80A EDGE #333333 RUBBER 0 !COLOUR Rubber_Black CODE 256 VALUE #1B2A34 EDGE #808080 RUBBER 0 !COLOUR Rubber_Blue CODE 273 VALUE #1E5AA8 EDGE #333333 RUBBER 0 !COLOUR Rubber_Red CODE 324 VALUE #B40000 EDGE #333333 RUBBER 0 !COLOUR Rubber_Orange CODE 350 VALUE #D67923 EDGE #333333 RUBBER 0 !COLOUR Rubber_Light_Grey CODE 375 VALUE #8A928D EDGE #333333 RUBBER 0 !COLOUR Rubber_Dark_Blue CODE 406 VALUE #19325A EDGE #333333 RUBBER 0 !COLOUR Rubber_Purple CODE 449 VALUE #671F81 EDGE #333333 RUBBER 0 !COLOUR Rubber_Lime CODE 490 VALUE #A5CA18 EDGE #333333 RUBBER 0 !COLOUR Rubber_Light_Bluish_Grey CODE 496 VALUE #969696 EDGE #333333 RUBBER 0 !COLOUR Rubber_Flat_Silver CODE 504 VALUE #898788 EDGE #333333 RUBBER 0 !COLOUR Rubber_White CODE 511 VALUE #F4F4F4 EDGE #333333 RUBBER 0 !COLOUR Rubber_Green CODE 10002 VALUE #00852B EDGE #333333 RUBBER 0 !COLOUR Rubber_Bright_Green CODE 10010 VALUE #58AB41 EDGE #333333 RUBBER 0 !COLOUR Rubber_Magenta CODE 10026 VALUE #901F76 EDGE #333333 RUBBER 0 !COLOUR Rubber_Medium_Lavender CODE 10030 VALUE #A06EB9 EDGE #333333 RUBBER 0 !COLOUR Rubber_Lavender CODE 10031 VALUE #CDA4DE EDGE #333333 RUBBER 0 !COLOUR Rubber_Reddish_Brown CODE 10070 VALUE #5F3109 EDGE #808080 RUBBER 0 !COLOUR Rubber_Medium_Blue CODE 10073 VALUE #7396C8 EDGE #333333 RUBBER 0 !COLOUR Rubber_Light_Nougat CODE 10078 VALUE #FFC995 EDGE #333333 RUBBER 0 !COLOUR Rubber_Bright_Light_Yellow CODE 10226 VALUE #FFEC6C EDGE #333333 RUBBER 0 !COLOUR Rubber_Dark_Brown CODE 10308 VALUE #352100 EDGE #808080 RUBBER 0 !COLOUR Rubber_Dark_Red CODE 10320 VALUE #720012 EDGE #333333 RUBBER 0 !COLOUR Rubber_Dark_Azure CODE 10321 VALUE #469BC3 EDGE #333333 RUBBER 0 !COLOUR Rubber_Medium_Azure CODE 10322 VALUE #68C3E2 EDGE #333333 RUBBER 0 !COLOUR Rubber_Light_Aqua CODE 10323 VALUE #D3F2EA EDGE #333333 RUBBER 0 !COLOUR Rubber_Sand_Green CODE 10378 VALUE #708E7C EDGE #333333 RUBBER 0 !COLOUR Rubber_Dark_Orange CODE 10484 VALUE #91501C EDGE #333333 RUBBER 0 // LDraw Transparent Rubber Colours 0 !COLOUR Rubber_Trans_Yellow CODE 66 VALUE #F5CD2F EDGE #B49208 ALPHA 128 RUBBER 0 !COLOUR Rubber_Trans_Clear CODE 67 VALUE #FCFCFC EDGE #C9C9C9 ALPHA 128 RUBBER 0 !COLOUR Rubber_Trans_Bright_Green CODE 10035 VALUE #56E646 EDGE #27AF18 ALPHA 128 RUBBER 0 !COLOUR Rubber_Trans_Red CODE 10036 VALUE #C91A09 EDGE #660D05 ALPHA 128 RUBBER 0 !COLOUR Rubber_Trans_Light_Blue CODE 10043 VALUE #AEE9EF EDGE #59D1DE ALPHA 128 RUBBER 0 // LDraw Internal Common Material Colours 0 !COLOUR Main_Colour CODE 16 VALUE #FFFF80 EDGE #333333 0 !COLOUR Edge_Colour CODE 24 VALUE #7F7F7F EDGE #333333 0 // LEGOID 109 - Black IR 0 !COLOUR Trans_Black_IR_Lens CODE 32 VALUE #000000 EDGE #333333 ALPHA 210 0 !COLOUR Magnet CODE 493 VALUE #656761 EDGE #333333 METAL 0 !COLOUR Electric_Contact_Alloy CODE 494 VALUE #D0D0D0 EDGE #333333 METAL 0 !COLOUR Electric_Contact_Copper CODE 495 VALUE #AE7A59 EDGE #333333 METAL 0 !COLOUR Trans_Sticker CODE 10047 VALUE #FFFFFF EDGE #FFFFFF ALPHA 16 0 leocad-23.03/resources/ldraw.xml000066400000000000000000047461651440571307300166500ustar00rootroot00000000000000 leocad-23.03/resources/ldraw2bl.txt000066400000000000000000000254371440571307300172530ustar00rootroot00000000000000{ "Comment": "LDraw to BrickLink mappings. CC-0 licensed", "Parts": { "10199": "4672", "10201": "2436b", "10314": "6191", "10498": "90641", "10830": "10830c01", "10830p01": "10830c01", "11153": "61678", "12825": "2555", "13670": "6587", "13731": "85970", "14395": "2339", "14533": "90640", "14696": "3711", "14769p06": "14769pb003", "14769p07": "14769pb011", "14769ps2": "14769pb025", "15207": "30413", "15379": "3873", "15556": "64567", "15646": "90202", "15672": "92946", "15712": "2555", "16091": "30663", "167": "6190", "17514": "88000", "18228": "98385", "18575": "32269", "18626": "4025", "18738": "30193", "18759": "2341", "18841": "553c", "19475-f1": "19475c01", "19478-f1": "19467c01", "20401": "20401pb01", "20430": "6259", "21599": "44375b", "21709": "30394", "21731": "93274", "22749": "32190", "22750": "32191", "22972": "32188", "22973": "32189", "23065": "41250", "23221": "x153", "23893": "87580", "2431p70": "2431pb499", "2436a": "2436", "24505": "3648", "2454b": "2454", "2476a": "2476", "25194": "19729", "2533c01": "x110c01", "2543": "x70", "25866c01": "93094c01", "25866c02": "93094c02", "25866c03": "93094c03", "2588": "2888", "2654a": "2654", "26674-f1": "bb875", "27059": "90541", "2714": "2714a", "2723": "2958", "2748": "3857", "28290": "56890", "2850a": "2850", "28618": "6126b", "28653": "3023", "28738": "bb0892c01", "28809": "18677", "28920": "13770", "2894c01": "590", "28959": "43892", "28964": "76766", "2910": "109", "29219": "62462", "298": "4592", "30007": "4215", "30008": "3024", "30009": "2362b", "30010": "4865", "30039": "3070b", "30057": "4073", "30059": "4346", "3005pf0": "3005pb016", "30060": "4345", "30061": "4218", "30063": "4740", "30065": "3960", "30068": "3062b", "30069": "4070", "30070": "3069b", "30071": "3005", "30089a": "30089", "30124": "2446", "30125": "4533", "30130": "6133", "30224": "x59", "30234": "4285b", "30244": "2412b", "30258p01": "30258pb001", "30259": "892", "30296p01": "30296px1", "30320": "30117", "30337": "6192", "30345": "989", "30367": "553a", "30367b": "553b", "30367c": "553c", "30369": "x52", "30370": "x164", "30385": "52", "3039p04": "3039px16", "3039p101": "3039ps1", "3039pc8": "3039pb013", "3039pc9": "3039pb045", "3040b": "3040", "3046": "3046a", "30475": "x161", "30480": "x134", "30499": "3684a", "30561": "x132", "30646": "30646a", "3068bp00": "3068bpb0116", "3069bp0i": "3069bpb436", "3069bp12": "3069p12", "3069p25": "3069bp25", "3070bpty": "3070bpb033", "30": "70644", "30741": "62576", "31459": "3011", "31460": "3437", "3149d": "3149", "314d": "314", "31511": "98585", "32005": "2739a", "32006": "2825", "32064a": "32064", "32086": "551", "32123": "4265c", "32123a": "4265c", "32123b": "4265c", "32126": "44", "32239": "6588", "32277": "41239", "3228": "3228a", "32294": "x136", "3245a": "3245b", "32476": "x240", "32495c01": "x873c01", "32496": "x873", "32531": "40344", "32531b": "40344", "32532": "40345", "32532b": "40345", "33122": "x112", "33176": "x12", "33299a": "33299", "33763": "78c26", "34432": "3649", "35331": "87606", "35334": "2447", "35338": "54200", "35343": "22388", "35382": "3005", "35386": "3069b", "3626cp8k": "3626cpb0405", "3626bps0": "3626bpx48", "3626bp08": "3626bpx83", "3626bp80": "3626bpb0023", "3626bp84": "3626bpb0628", "3648b": "3648", "3650c": "3650b", "3660b": "3660", "3665b": "3665", "3729": "3731", "37364": "970cm00", "3747": "3747a", "3815": "970", "3815b": "970", "3816": "971", "3816b": "971", "3817": "972", "3817b": "972", "3818": "982", "3819": "981", "3820": "983", "3957a": "3957", "40240": "x219", "4032a": "4032", "40620": "71137b", "41357": "40249", "4150ps0": "4150px24", "41669": "x346", "41751": "x224", "41761": "42021", "41762": "42022", "41763": "42023", "42019": "41749", "42020": "41750", "4210a": "194", "42114": "x156", "42284": "30293", "42291": "30294", "42409": "x789", "42534": "41539", "42657": "4066", "4268": "353", "4275b": "4275", "4276b": "4276", "4287a": "4287", "4287b": "4287", "4287c": "4287", "43127": "2419", "4328": "x93", "43337": "30413", "4345b": "4345", "43675": "78c19", "43802": "4201", "44041": "4204", "44042": "2356", "44237": "2456", "44360": "x181", "44590": "3754", "4476": "4476b", "44882": "43898", "4503": "x167", "45505": "3622", "45729": "44375a", "46361": "30562", "46667": "x577", "47223d-f1": "4694cc01", "4770": "4773", "47904": "30602", "482": "30553", "48310": "47543", "4865a": "4865", "48729a": "48729", "48729b": "48729", "49673": "49668", "50231": "522", "50746": "54200", "50903": "x1307", "50951": "50945", "51000": "x1435", "51011": "42611", "58119": "59510c01", "51373": "50990", "51595": "30225", "51930": "41250", "52211": "3471", "52639": "6510", "52901": "2958", "53454": "53705", "53933": "30293", "53934": "30294", "54196": "2654", "55295": "6246b", "55298": "6246a", "55299": "6246e", "55300": "6246d", "55539": "42604", "55709": "32199", "56204": "45411", "56640": "43898", "56907": "x1825", "57488": "32558", "577": "64567", "577b": "64567", "578": "30374", "58120": "58120c01", "58121": "58121c01", "58123": "58123c01", "58123p01": "58123bc01", "58572": "4094", "58772": "44359", "58773": "44359", "59195": "45705", "59350": "59349", "59426": "32209", "59443": "6538c", "59858": "x167", "59900": "4589b", "60033": "4202", "6014": "6014b", "6014c02": "6014bc05", "60169": "30104", "60288": "57587", "604547": "11402h", "604548": "11402c", "604549": "11402b", "604550": "11402a", "604551": "11402g", "604552": "11402i", "604553": "11402d", "604614": "11402f", "604615": "11402e", "60470a": "60470", "60475": "30241", "60475b": "30241b", "60616a": "60616", "60801": "60583", "60803": "57895", "60897": "4085d", "6090": "x41", "6093": "x104", "6098": "3867", "6116": "3941", "61183": "43753", "6135": "2536b", "6135b": "2536b", "6141": "4073", "6143": "3941", "6188": "4589", "61903": "62520c01", "61929": "bb0339c01", "6218": "6259", "6221": "424", "6223": "3003", "6225": "3023", "6227": "3039", "6234": "600", "6237": "601", "6255": "x8", "62622": "4738a", "62623": "4739a", "6264": "3899", "6269": "2343", "6270": "3040", "62808": "40359a", "62821": "62821b", "62930": "54930c02", "63965a": "63965", "64228": "87513c01", "64288": "4589b", "64289": "40490", "64290": "32525", "64634": "62576", "64871": "32278", "6562": "3749", "6590": "3713", "70358": "590", "70973": "48245", "71014": "59", "71075a": "71076", "71076a": "71075", "71128": "x85", "71137": "71137b", "71551": "75c13", "71874": "4740", "71944": "78c06", "71951": "78c08", "71952": "78c04", "71986": "78c11", "72039": "78c18", "72040": "71612cx1", "72504": "78c02", "72706": "78c03", "72824": "x45", "731": "731c02", "73603": "3403c01", "74695": "60483", "75347": "6168c01", "75974": "67c01", "75977": "30086", "76019": "60c01", "76116": "98313", "76324": "75c09", "76385": "989", "769": "23318", "85543": "x71", "85544": "x37", "85545": "x89", "85546": "x90", "86035": "4485b", "86209": "60601", "86210": "60603", "88072": "4623b", "88323": "57518", "88412": "3878", "88415": "2446", "88422": "42511", "88513": "53451", "89650": "61053", "90194": "48183", "90393": "90370", "90508": "90301", "90510": "30171", "91143": "2431", "92290": "92289", "92410": "4532", "92411": "44728", "92538": "3006", "92693c02": "92693c01", "92693c01-f1": "92693c01", "92756": "30410", "92903": "6005", "93094": "93094pb01", "93094p01": "93094pb01", "!93221": "LDraw has only one version", "93221": "93221pb01", "93549": "93549pb01", "93791": "2654", "93792": "3004", "93794": "2555", "!93888": "Unoffical LDraw part", "93888": "3007", "94148": "3022", "94638": "87552", "95820": "30237b", "96910": "99563", "973p101": "973ps1", "973p6x": "973px132", "973paw": "973pb1336", "973pr3": "973px58", "975": "982", "976": "981", "977": "983", "98313": "53989", "98384": "98384pb01", "98570": "98570pb01", "99498": "99498c01", "99499": "99499c01", "u9026": "3062old", "x223": "33320" }, "Colors": { "0": "11", "1": "7", "2": "6", "3": "39", "4": "5", "5": "47", "6": "8", "7": "9", "8": "10", "9": "62", "10": "36", "11": "40", "12": "25", "13": "23", "14": "3", "15": "1", "16": "-1", "17": "38", "18": "33", "19": "2", "20": "44", "21": "46", "22": "24", "23": "109", "24": "-1", "25": "4", "26": "71", "27": "34", "28": "69", "29": "104", "30": "157", "31": "154", "32": "11", "33": "14", "34": "20", "35": "108", "36": "17", "37": "50", "38": "18", "39": "113", "40": "13", "41": "74", "42": "16", "43": "15", "44": "114", "45": "107", "46": "19", "47": "12", "52": "51", "54": "121", "57": "98", "60": "57", "61": "52", "62": "64", "63": "82", "64": "122", "65": "3", "66": "19", "67": "12", "68": "96", "69": "93", "70": "88", "71": "86", "72": "85", "73": "42", "74": "37", "75": "116", "76": "117", "77": "56", "78": "90", "79": "60", "80": "67", "81": "70", "82": "65", "83": "11", "84": "150", "85": "89", "86": "91", "87": "77", "89": "97", "92": "28", "100": "26", "110": "43", "112": "73", "114": "100", "115": "76", "117": "101", "118": "41", "120": "35", "125": "32", "128": "68", "129": "102", "132": "111", "133": "151", "134": "84", "135": "66", "137": "78", "142": "61", "148": "77", "150": "119", "151": "99", "178": "81", "179": "95", "183": "83", "191": "110", "212": "105", "216": "27", "226": "103", "232": "87", "256": "11", "272": "63", "273": "7", "284": "114", "288": "80", "294": "118", "297": "115", "308": "120", "313": "72", "320": "59", "321": "153", "322": "156", "323": "152", "324": "5", "326": "158", "330": "155", "334": "21", "335": "58", "350": "4", "351": "94", "366": "29", "373": "54", "375": "9", "378": "48", "379": "55", "383": "22", "406": "63", "449": "24", "450": "106", "462": "31", "484": "68", "490": "34", "493": "-10", "494": "-11", "495": "-12", "496": "86", "503": "49", "504": "95", "511": "1", "10001": "159", "10002": "160", "10003": "161", "10004": "162", "10005": "163", "10006": "164", "10007": "165", "10008": "220", "10009": "166", "10010": "221" } } leocad-23.03/resources/leocad.icns000066400000000000000000021613241440571307300171040ustar00rootroot00000000000000icnsâÔs8mkZÐââÐ\ FóÿÿÿÿôG 9¢äÿÿúýýúÿÿå¦<§ÿÿûýÿþþÿýûÿÿ¨‰ÿøþþÿþþþþþøÿ‰{ÿúþþþÿÿÿþÿúÿ|jÿúþþÿÿÿÿþþúÿkZÿúÿþÿÿÿÿþþúÿZIÿûþþþÿÿþþþûÿJ:ÿüþþÿÿÿÿþþüÿ;,þþþþþþþþþþþþ, ÿýûÿþÿÿþÿûýÿ!¨ÿÿùýÿÿþùÿÿ¥NÜÿÿúûÿÿÝL~ûÿÿý³¹#is32Åÿ€€¢¤§¬@ÿÆ«§¬š”‘u~€ÿ¡‘— ±žrE6{ŒsÐᣌ]YbL;Ux}fÝïÝÏ­wSZYdf`lhàðÞâåß»hadffriåôàâáåäu`ggfqiãõääååßvafggpiãðäåæéáxb€f1mgÜçáäåçâwbgech_ËÖÜàâæâv_eb_]W·ÈÔÙÜâÞt^b^ZTF€ ¤ÂÎÓÚ×qY[UMA‚ ¥ÇÉÌnRSA6‚U–ªÃgA?…€{–U„‚[QPPQV… UT:<8SMh1DEIJEA/ ,:  ;.&€ €! €  ‚  … ˆƒ‚XSQQSV… UW,020.( ;PMXˆ`NJHJK+*!  ,KKGHJSƒ!6CIFA>B,'$ -C@AFJB4$"(8>??,+??>9*%' .;+ -0#&-  #    ",7  ,<€!…+@ €  "#$„@‚!€€ !"%‚ƒ" !""%‚ƒ$ !"#%ƒ$ !""%‚ƒ% !""%ƒƒ&  !""$…ƒ'  !""$†ƒ(  !""#„ƒ'!€ !"#…ƒ) € !"‚ƒ+ €€ !‚ƒ,€ ƒ € „€‡ €€‹Ž ‘ •˜ ‹ic07HʉPNG  IHDR€€Ã>aË$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxí} ÐeÇU^ßûö÷/³oZ¼I¶$Ë‹ÛÁNÁPPÆÈ1ˆJUªR@eWÀ¡H‚f ¸’qÛ‰NÊ…l Ça+oC)8¶el!YHI#F³ÿûÛß»7ßwNŸ{û¾åŸÿm3NúÿïíîÓçœî>çôé¾Ý÷½¹«8ÜqÇ¥[ÏŸŽ;6ïFúÕ¯6ï»ï¾CÝó§Fѵ½v{oÔìM£tWš¦ ç¢ÚÈEeÒ¥i2Š#×E¢[rn¥T©œ¯ÌÏ_H{fþºëžùön8½ímãuq®üàw¤ŸøÄ'FãeWK>ºZ¶óÈáÃe(B‡Ž4Ü÷ÁÞ²qæü;«+ov»¯ ¯HúýýPh•ZŽ\ìÈ¥I=ƒ WFLQ„½˜f­já¿ ƒ¨TŸ¨6ëSoÎ}eÏ¡ë¿üºŸý©oL5ø6M¢•_©ñUeñmºèî¯ïºë-Μ¹c°¾ñ½½N÷Õ]×`8r(ÈI„!N¤q¬:OjÚë„ (œF‘•ÄÒ(‚cpq9Ž]­T‚%•]©\rà—kÕ‡kóóŸÛ±gß'ß|ä_óÌœoãUãL Öþ+6Gؽïÿ­=uê½£nçM¥ÑÀuz¸ thqHuBÑì=Í<‡vq¼œÙPJ2Aðf¡†‡CÂ…QT®Ã šµšKaIµúüÇ¿w׿ýo¤ ÛÊü•® 0ÿÈGn|ð«_ý½òúú[:í®k‡ tËÑC11<¼ô'Žâ)RW7൫¨À²üÁ~ ühq vð,I7Ê¥R£Ñtƒzãë‡^ÿšòïyÏý‡±>8¦³ˆq¹"ã+ÞR¸ý‹¬‡~ï÷ÞüÍ{¾ø…dy©¾1 ¢RÇ£4¦\Z²¡’tÍ G9QP#w`X)4 pJ-$"þGi’&såRÅ-,¸k^÷úïû®ñsŸ½¦ëç”Þ½ø 4¨Ž÷äÉÝò+¿úðʉ{‡årðê–Z…Š¿…· ,*X´lڞΓUÁ- *ɨRÞ·¯së»ßuÓkßõ®“àGça3ÌûPðl/vcÆë?ú¶·aï܃ðñæV—÷v\ÚÃ@«b‰r?ùG5dTÊ”‹SDvA5 2 s\¦í¢öXÄÓxJã“Ê Žú•V«ñÀÿþÒO„é늖±<KÛ¯ÄÛ±cÒªÞ¹¥×¬/­`9ïJ‘,èÕqAÙLnÍ'l+Áh‹ø– J 4Æt þ¡íxymÍ­=ój’àquuŒ×‹™½¢ àA©sõJ©Z…¬×*nq~òRaSû¶P“л’Yz¶xM3ôHci‹µdf޾³•ÛètÜòFÛ•^z}E)¯ìûëž8ÿ¿õÆ­Ô›£kâØÅŸpçÏwÝ^«.¨ ~y8‚{Æ5¢· ¡KW·ÎŸi]<ñŒ¡C®éI#S§e|PÒ¬‡ëåÅ4é°ñäÎ_XrO<ýŒ;“Œ\¥9'›B?pãeöåJ5ƒ+ÊPPœ÷ÁõcñGöDpµZ·9×t7bxêøSîÔBÍ•÷íu‹ ‹®QÅzÆ¡“´ÆÀÈ\’Ó­\‡-ç÷,I…Q¹¦;¤ý„£5¸A¿çV×7ÜÙ \»ßw½zÝ-6®:×ì“ÇŸ?ÞãƒÊΕÎ>ÝsÏ=#.l³:_ä„õîEk†)ýAÌ•ŸÀã”5$½çžù/þùgߺtáüí×ìÞõ#Ãû¾¾§ýĉtÐîEçÎ.»ÓnÍ­,ìtÉÞ=®±sÑ5s®Q«ºr© {à†@Þ5ŽP†\êy*ZÕjKÆÁYÐc GØiì\»Ýv+˜ë/^¼è–W–ܨÙtµ]»]¥^OŒn~ýëVíö6÷îýÔ ×^û—o{ï{Wò \ ‹CžaÐT½Õ¥/`2—Ò X)ªŠ¹:WúƒùÈîÓ=ôÝ­¥•Ûû­ï©¤É¡Q·ëwítµ3çÓÇžˆ"ßaço8¹V§ë–{m·„ÍÙU×tý½ó.šŸ‡ûmº*véêÞ *%L¼ðÇÑ(ÆžgÏ ÄOœ0 ÄÍDá^Ïu ôv»åÚ«k®Óm;´Ä¹Å®Toº¸RÆÑRÉaµâæL¯;t(j´;K.‰ãóõzãžùÅùO_{ë­ŸÇOÿô™@Ü"‹;a hÏ n ™ ‚=/I  ø(”>nõøÃ{àïi­®¿k¸Ñþîr2Ü“`>íà`vÇv|RnµË;ÛhtqÙ —Ö]Å®RREÊ®/z1À\ÜôÝÚFÏ­Œ6à†0 çú®î’EþÁ"(#ÂÖmc_1Z=×ÉhäF¼°­<„;§ñ:-qKÔ ýFZm¸¤Qw)x¥àƒ n=»! f„ 箾¸àvÌÍ¥;±lH¢j—æªñNpqëÍfó/ óÿsßÁƒŸýûGŽœ[ Fi|`Xáó?¯0KéþÆï¾ääc}_{eù]½õÖ[.]AyŒîaš 9CAØkMb‡=÷ÑÅWúÚîZ‡Ð×;®Ú¨¸zJ…ÀKPB¥R‚~«® !GÄG¯†8 ÂV±kcÁØÆèmó¼ =pÝd£ÀèÆòbˆ˜Jå¼#Ê-ÄU—â©cE0²‡¨gHE“7¬†‡¬‡ë졎Œ¦Œù„:¯»éF·wÏ> ñì'%Cò(ªGå9ð¬Áû)– ÍÆ—ó‹ŸÞ{`ߟ½û—ù¡PÉGxÜŒ¦aj4û ‹Ÿ“4šÿÜôÑFºÉU*¸÷×~톥'ŸüþþêÚíÝvç­Í$©±€ê ¡tL­‰ÐyŒe¹Ù!/ž‚­¬¹èþG\s{©5tq:rÍÝ ´WÆ­ •qè[…”àŠK.]>¥6%®cèÁ£ðêãê2«ïGíêàÂû¢àxR±Œ»ˆ{L£c8·O#å[ÑèqìZëð˜d0õPé×¼òF·k÷nIÃç¸2“pZh{šbwk„ù¨Ü@[ë0~Z™›ÿJµ9÷Ç{öïýã¹ë®¿5s]…9¥wÃÀ­ynx=ûÀî­º¨)œ‡ÿÅ‘#¯¾pöì;z+«?4ìtÿN3M*}.  ÈaÈù¡¤¾ØÚ¡ó0µ+®™£ ‹­øoqUÀhQÒs ì¹W tÈÓÜkµ„<T~î=.Éøæ£áe}¬ú0¶Þ`ˆ4r„Á88’ÍØxI£ž!D…Sù|QåãåâfÀ)Ês­ ]ik´!Å4r€µK„:ø¨%†Š¸Ä˜0t6Ï€y"M+ ,`ë0`^\­=PŸküÙܾ}Ÿþ‡øÀ— «L¶‡i xåî»ïæQȳ2ÑÚ²í JÇ =B™á3GŽÜÖ~æÌ;ÚkPz«ýÆ&pzp-¥Y'û_¨›Y õLqdÑ@g}Ý•xÔÕAQîÀ0]”ãªkìjB°`¡UpU1’J0ŠI¢ “—w0¨€0 Å ÀŸóv8T¸€*X]½Ïÿó@b(|iÂ?*¹.†½ué(ÓÀNäcšx¶tªøÜÄ+ðu1†$)cŠˆô °p¬7Ž×š?¯íØñé[¾ÿûï}Ã;ßÙ‰„Ã`{øðawçe>^¢Y[PL|בq¥ÿË#oX}æäíÝõw¦ÝÞëë=̃]t#Ûãðtí2äUÃTr$›* F@C))Fr«µáF=âàü*¨¤„qT]h¸F{œh¾L4L T0×}>¾aäàÄýƒ7 B^áü\1ÔË´¹ûl F;ñpI;¡¾|Ò[ZÆjë,a…¬ÔxÕnŸ`øX™ˆ¡ª¤jè+Á¼‚;Ë4Ïáà(a×iXhç T~ºÖl~nnÇâí½í¶/~ïOþä*ØHà d"|œÖ’Ù÷-Ú‹1¥Ã”žë3¿ð ß¹vþÂuV×~Ú¾µ Aw12!Š•†ªt,⼟7kSl¼kŽÂd NfHËHC§[­–ë>ô¨›‡Ò½‘+uàhpõM¬ðku>ÿc@OPæJs1òÂ#œ®î_\?&kÄ0R1à§\衃á\/SÚÁiÀŒ‚‹¶qå`TÝ '¯0€˜€QË×Î8ìÀFUÀ©K<D#4˜PéÔXh4€Å0˜Ž1 ð‰Ñ“ÒéĘJJ ôsÄñ¹R³ñùʧ®{ùË?ÿö_üÅ‹ ÙV`]— h·(ÿßÿÄO¼öP»ûíÖb?öfZw…KÅŠfRé³õS;>0^bhÝw‚^ÇóôÆßw ¶Þºjwð ¡Ì'€¦ìÀU°j· PZÍùy„UfÞhÀ¹ÓQOl÷íçã[å#h#Á(cÌyžó0†}°á–Ê×¹0Ò:ñFÒŽÆa @ ç’Eàܼ+£^<€f€Ó(8¦|…(Ûb6j *(éQ±Dܤ@1m”¸fˆ!l7.cÝpOËEýçôÉ?&âV‚pÜ Õö]òWïxû-÷}óÄ7W™Ã¬Þh&j}‡yâ¥Zºw6ÚÿoÆRÊ´[¹âi„ñ²î½àV±ásñ‘㮎‘\ícNE¾†¹·Žùž¯fUqÕ˜®×`˜ Š^°&ŽTîÞñ1Ê· cz€Œd…bßÇhêˆîVŒŠ‡&˜“hLº ÄˆouĆ¢|¬Ðuó4Üëo¸Áí‚TÀ›Õ“X ý£7((p€ä¢0-±43ì oT•&||^_[+¯/cK Ó_ó†—¿á7ï¹ç>`‘msf ñm~Ô·a÷F:x}àž¹p¡ÿžŠŸÞ¹öï­,îÜáæ0úhÙ˜²„—4ZÍ!ç-@dÙxFÈK’ýac)Ñ› s”ÀU°-ðbTñ-Ïò=ä»ð5x‰*]- £WÏ—7c®tG#O=¯l.úú\Ô¡YÕ£ÙÝ0àu° Äç~äÅPƺI‹:èîÅPP§,Á‡†š€žíg»É«š*ÛÏ @]ýsTc†Ž\ °<éÀª(Mâ1à)!ãÏ¡–`0À3Æç——â çÏ»þz'©Ì7FÍ;+¥î"ÛR¸¤à¹SôS}í-ëÃ'ž]ߨQ½¶ZJWÚýè©GžvO¸“îÔµ{\mÏn·87çj=2íC`¸8bÇÂΡ·èO¶¬Ä–!y®J¯°xé¤I·JÓ=wa$ÀjÈ—!˜26{¢˜Oõ ŒŸA¸ñCÅÏ']ùëè°Fåð,# ,8\ØÄvlGF89Žàm¨pY¢ƒy,©õ”á°MÅÇ<½@GAsUBÍÈ:ÂÔpÌ„ºiBäa—(<D¦ˆéÉVðTtþâ·zö‚‹°9V‡§iÌ/ ËI‹Ðt×Ë®k¹¿2%–äôÛ% ÀÈÒ´†ÕtöÓRZIÜN,¼vaþ*ŒŠ3§ÖÝã§Î¸gv.¸dÿ·¸¸S¼6:@Â#WpAš† ÖD‰FT½t¤P$4t{þέB*Q5(‰æ>WqDÀÑ4î¶Á9ÚÙ]n²å©òéùÜq-Â-8à!s=Fù }î xÒ½OS>½5GÎ#]G†©Ê†!Î4ß\-ƒ•KùðÕRQ´øU>ŠD°7ÍVñ”q~ 'Žx"Á´Æ °]‡®U@/KÅûÀ3t¢×ïÂZÐg}ò6„)ñ¥ €fˆðª¹¹ÖCåÒ:¶4wbŽcТÄn—MÞ=WsP»» ‹.õ §áv¸tß·€gb®0­Š2  ž?3ò%¡ò)  :G—?‡z8Ÿö°‘Þ/Ã¥—qèƒOx•aˆUº®À“O"XÏ—Ó€øˆGÒi9‚YR‘2Up„ƒkCÀi$(cšJec ?ñÔ9ÚBOCÅWQ?•_G=Œh#=¥Çu€õƒmâE8/ŽyrRÛ8„ZZ]Å &ÜÆÊ²+Cv={aðØ4%>×ZˆP»ò#ðW”¢ëwîÔ±²µ:ÆciÃ80̳ јJßrÛõÇÎÝÜipi–É—m‘€~KšLyôJá.ã‘íÄ`Ã=ØÖ õ]»Ü‚¬èØ…±Ò£–°1äI³bí#lØœ{ê)×ÆÊ›«ö~§tˆ¹KoÄGµƒ  yÒWBÌQG/`F@V²­‚ÚÐ83„7Ÿç›ExÆùÊÈæƒâ¹HųMì# ÓL9(“…ŸDðÙ€*êžÃÉãË^úLÇX©€·)Üb¶Åo†Ê7ŠÖ±ßqaiÉ-c[™Þ§†SE9ß`G(qð¢2LRHj Œ¶‹Í6·{Ç£¿ýÐ7_5g*¢°Ù3Ã%=8øE£G^û­2$ÏQ–žwÀÈj£ ‰±^aoZw·Â+œÊÖ ‹ê°QR§W@¯8µ¦¼­Æš|¨R¨(¸èâ!Â¸ÚæZ Á3¾¬âËíÓ>à)µÏ!MZò†âq§º.l5«ažçþy T¨¬$Ð*Ö¥×ÄõKžDŠGâÊÜŽXô!ô4"r,»|ÙSùT ï“@¬âGšY~”P"yUz |e "2÷<ÔìtZa0¬Ã›ñM"ŽöA·ïª»v¸ùƒ‡P?,cXo’Ö%P½±L¨+ÆnfÒí­{(Žï¥‡L‰¶d Óº*•evu‰ÜŒkÊZ‰$«!Y#)¾´AÃØ?_wûbxb$âɃ5YmyÚ`ÄЀê!n——=HÉ aF¼%8êë«6«6²7ãN…ð_ÌO¤'RÒŽÎNB6ó˜7oÞµ€—=çÜyx…'–¹¯àÜÉMª9´•k’elØ,//» <»Gµ:Fû¼ô…D¦F{ò{~“âq5}=Îû¯ÁüõxD:ùôš{ ÃòÌîºAÈüÞïá¥8Žt>ˆ~Á‹Ü¤.¦DÐGh/R4‚ʸ”#¯YO)E¾Ü§}58ƒÁ3(^OÃñs¯§ójˆ9ÿìùsnØânÞ-Xï¦Ö¨ŒóVzyäUHK¤7Åc40¶t@’•bS‰nˆ/ÄlëHxKpÔjl4Öøqi¶”.Ö†/•éå›)ÖHKÃå–C Ÿ¡GLc1y\2*Ú…#ÖÝ{v¸›qކOqO`«m¯_ñ· 8_çs=|°NÆœªØNÏ“¦@#þ¸1–´À‘a^à 5ƒÑÞi(ãCŒgüxû“p7·¥hK`œÊ s«xO›bÛ¼ ƒd“N,¶P±‘РYŽ>Ÿ—nôÝœÐ1#Q{ƒâP\Ã1àËv4ÝKz…¾;‰CMît-r=¼ª-‡-ðik}J’üÈË»ÖÆv±:[xñ‰€ÂÔP4­y±/ˆ]Ʀœ¸ï#ãÁRsbs0†&> ‹:!%CÈ ¬|¤'Lddù1$f4CùF'17°”[„uš/ÚR´%¸m=vÃ¥å%zx™jÔ•6Ĥ—(ëœB°?­¸b°JÁîËåu§1úwz׸û†-º4“âì?Åû|Û‡|ÅKBÅ"*ÜÄ#€)•omƒ@F¦ ÷ø¦/?SÀ5E`€#gLêøPÃÕyô,­%ö‚œpé¿”Ø%aó¤¶ÂÃ4ËÍh̸”Fk¥¢NGÖ|ƒXË6¿oÉðN€„êþÝë½ÇŸvÑZ‚—nuÖÙ”½Í›â°½”ŽÎj2%Œ²‡j#:ð A_°ÅœÀSÂc£ž; #Î7Ä+Èô€Å£P@‘Ø)ÃÒ+ m¾ôÀà‡R\ŠwùË cOáÖù6ß âjƒŸô©ÁÈJ|,E>÷cÈÌÂJÙdwm´kÛ¦Ñq`‰²ÅÔÄ̘/±”ãš¼#ˆ÷·¶döN@Š!pÅ‹21^|Ã[Ȇ d–é{¥£BËè&mÍhíž+ö”»1ЍD=Ýï^¬ xÝ2j¸Óxßïx»çžÄ9ñ:Þбp,á`?Åëe >N&j¯NcÀbNwüñvÑ<>o€½|žýwFü° ^9AãËØ²ækÛħҹ¢GRöl¯^˜MµvÍHŠ˜¼¬H 4äýš ò›fÃrÈ3]:jÜC1wÍ͸oÉdõƒÞŽv^³ÊùŽd…K!žeS‘ f™"«šVS>ñÌ0fÅÄ)„@š™ÑxbÏ^„G4n ±ê9Ìѯħ‰_†ïƒ¼ˆéáÞz ïÅû #l;—S¼¾¥Œh ð¥…9¼\‡¹Þ¤‹y½ÕëÊ ¤1F{»uz¸D¥³Ÿªx*ß¡qQqÖìñØDcpËúìÍ¡ËYç½,¤çqÜÃá‘ÀÁôìÖ €½Ehzt½¥˜eçal»LÙf‚„›´É7,Ó¸ŽwÎ$‘•'rã«ÎW•Ái¶ÎÏ^› £W¤W8€ù{?<À«1w?Óí¸ãk-÷Ô|ÙµñѲ*vyz×Ç‚r½Óv­õU97(Ã3Ôçxt]Cº.À™¼EñŒÎ[¦^…9 H>„0¦Ù¾,„…“fpšO ÛüLO¦[Ký¾l±Õ“Æ)aó“ ÙWß}wïäM·m”{®OâdÜĔ_€»ÎÎÈ#eG»=­û„M ‘¤"¯¼Zí:Õfû|óX´ÝŒ}÷Wàõ©‹ýOœk»G+ëîé*^:ʼnG{+üÜ<_B¾P¼W»ðžT>êÑ(uRùÚ mµ¥­oÓûC,-1|¥F5ãæ=ññ åkÄN™ÊÑmå2Û Ì¥zÆ[téœp¬‘Æd¢‘O8Gj¬|<#ðb‰ ]K<®ÇÓ\~7±ç<<5<`ÛäØ1·ùBé!|€óÍö¸Û{ÀÝ‚#¾p1ÃÐ.xÀ£ê¤wñO’…‘Ÿ×î[Ⱦ…@¤-oí+ž’UмïSP¦€(OþË+pq¼ñ³¿õ[ú¥fIShBÐv<e ¦ëü$ŽÓ<­‘y*5뽨R[(å[¾†´&EäanJ˜”ŒÝ”š¤Là5…¬¸uÄsX0.pC~"ûò)ïÆI¥”ÊWò¾ ×ö1„)4JߟYe’H'€AùXÒdïÁœhGjóVÍÕDvŒÍDy0ùa'l‰çΨNÄ!M—qF„ËÂ$ã  …£ öÌo0bHÚ+!$%Ü‚º}æ¼F|塇¡ñ„|‰"½ d¯] 1(^>ö$Ï‚¥ÅsIÞcûrAÚî- Í“ÓR›0¶AôK¾›Uvà%² ½/Ú2¢±ŠwíX+á“4 …’pfãƒá‘wT¾!,LSòÌÛÅzL©’Êl*!Ü‚(ŒÊ€ËøH0…›ÒÍr<³-ã—ÇÀ%1‚&âieB0õf\r~ãh9…ãðR½ž}N0@Û49®®™ÈG³öE«‘¾Î\ Qø²mC.ÕDc‚r…$€{zåâÄÀèØh-÷X¾Vî¡B,Õ#%4(`Y¶6@šçF‡d&ウïËú áÄÖ¾€…òÀºÌ²übJ¶©Ïp”%¤ó—ÁdØ ,ð³å²lVÖêf /ºÍP´ìN2ŽVxìˆÖ{U!‰”(Žñ&¬&ÊÆz:KùÓ˜†56¦µKEEÃdÁzåeg̶Qp}C¸ Î"^ʳH+8Snæ=¢qÞãù7zÃÁ62=Àê+'é…-X4±Ê¬ó,·†[¬4Ȇ–éãè ÅñQfõSÒ…—•çÍ9ÓªíÒyÉh¡øÍXdqX$uQ»!<@&E[¹å¤–¢Õ(I¿m~òjz<ßJý!å´­ܽƷm…ÐÚLfY1SÍ…ŠÍÊ‘(~±K|é”etc-Ïx_Ü=$ÊØé¬ãa1qf¥þ²ã±6­// ë7œ‰8X²Œ‡XåÅùçÏõ-H¢ÚjÞT¯È ÅLÊ¤Ð¥ŠŒúÀÆCËÏ´âëÒG=ŸÙjdMÁ·¹ßŠ ÕbÂ--^ÉÇãP¾Œ »ÆÑ³¼1{®4¯5LeT _fÁ(Íê­V·uLÆ›‰z €;½gJÚ­~nJÎŽd’óTİ˃&pÂÊ—dþ"ÍfÄ[K„< m |Öü1–lÃD»ìï(5Ä<ϘBg¡@à KC`>d4›%Àw˜uòBè>¯«ÍÈ­lËAv$ŒW"–;ÜNƒöq ¬GìȘÈlf}CÌ-Úp°ŠmƒFÞÑ…‚þŠ<ëÛ†“'Ê• .§•r«Û*Blâ@Ú^`¹á9‡³ÓSªÌ‘ ÃL˜Ö5@Nté½µŽCª;æ‹:8ÖW·zÌZr™^¢N Ê-/mãx§Ea<½‚Ç.(_Ê/¨Öó $€*·À*&ʈ‘ÑêšDÐÇÚdYÆr‰ÿTöã†â*Æø†„"ˆâ0^ZˤVEšy˜ÎÄ™,`W°‘…ˆß.…UØg‹M›$ Så”gIkbR«áƒ‡Q/Τ7ɂЖ¹>áBqy¶Æ4«%4‚5¹OÖ0…×¼)쳚ÆË‚¦f8LäxHåÁËè&»»)v‘v›9rÆtÙ4¶¼e“²A ‘‹Ôñ˜ëPf‹ŸCÅððò†ý E©â‹Ê·f̨HÀ:¢g7n†0ÇÀÓÍdB…†Œ±ð­áS:–_¬Ç®ŒYÆhV+2Ìg•€Œd©„à6~©$; Þ*ÓÙ2žÁá×\ÓIj•u¾€9­k›3 J3…©h¬°P¦ŽÔìBi¨ŒñåUä)aL-acXYQ°~Ì`¦ði2(z ã:3ã÷lR>ºï’ï°·Âs–¬'hÁTz9Òð Ô>Ÿo° ä©€ ª±2« \H2âòl°–#öuiã¦V à$#ƒ˜1Í¢¸!{¤±ì$iÁ2ÓÛ=I¼=×"¿ReãÎ~t[GÁ¬)ÐÊ–*VüÑhßÑg]Ûå2µjêüœá(•a³• •ÁQ.ÚH1ŠMÚâÎBãyA ™ü¥¤=‘ÛÀv0+ÚJó²š31fMà®Ì“dI>9}Ø„ЦjÓHt®µã"ú%ú¶YñŒ²à¡@:'h—Ñ ²°‰³ÓX®ú<5›`û%x\ƃ1ا‚·¥Óm![óÒfc…ÏéÖ%N©3¦UOTJÜJœ‹º¨tCb¹Õ¨†1 Ϧ9'£“‡à{"Fve)_r™š^oÞäü9MK[*ûTð¶xš¹4ÝQ“U½²fà[s67Ú{IÍ ´®¼F@žfVËV ‚Ä.¦£¸,ç‡ÃnQ¦æ¶ew‹Þè"¿¾Ç·+g3iy™‘OâX b“jONF6’=rÎØÈ0/WX3Z–§ÉBüˆyž Ï3V9x2D²Êñó”!‡¦‰†ñ¼•a).˜.Ëly+Ø*”8rKü÷hˆ¯]ô߆‘¯'ÇÕË|ÑŠ9ã<«‹œ/2s#avØ4•ƒ§Á†%ÜK›íP4»[lÇ—ÙRì"̳΀¼ˆ)-æ=çÆœ‘åPbË0GüÉšh8¸P,ÝZnº..Aí\\åשMŸøg³ÔM#~Š©¬³Ehž“Ñ ¤ÉOì8¾ZÃÜ&•一9<¯‡)ÂË0RÔù·&‘…8ù*J˜W>–"O… ÃàF åÅ;r—ñ:ÙmË% ®®ñ£Sö‰T…†÷éF­¤ÍÚüœÊw$R:â d6§)`«ŒsI MÚ<Ž›SÍLIÈÒ`…fÁ<š2#Eq¯Ô*Ñ’Œ‹%Ö2I:Ž·ý.©ƒ^+³Íîwz‘¥ÝÎEþ‚†îøÉq3VÚq/`EE¥dP¿Ð›.Œk25N!‚h¾€˜…€ÀàÈÈ2ôi â‡4‚Cf¼& ¶šŠi¡Ëˆóœ¥H9ÊQð0Jä1p;GÁä³-°#áá\i­Ë/…Æ—ÂHëy›v±’‰PRl´¸€T•AB6òé­¬m PM!&{)ÂMóUâ€,স†9‡ˆV66VAž•§#(”$?¤ÒX>µ<Ðw¶sL&Û2;n8°/cBýº-´¬Ø`æŠyÒ xÌY9éDÊÄeéSàÄÕòYH9%1¦aY}çyJêɳyÊ3 ùjzbf–‘åõ3i‚¯›Ó¯‡Í‹òú6Imˬ³8sä±#?%¬£ ŽF½0ŸAº::ÙLmjž*¶fÒŠå[Í™@¼f…ÌÚ+™ ¹0“§-ÅØÒÄ.ð!À‡q<ƒ3žEc8™÷“°.+ŸŒu¢Ð:•BÓRY¿Ä¶í£`Ö±-@…RsŠ÷Ïñ%,þûð´5ÝP#P£Èššce˜ðì&%0°ÑñŽaeŠÈ‚T5VT$¢ˆ>Ýö§‚­Òm€â qW¹`Šclik4Uœ»s}: =W.¦4]ŨXBÞv ß¶°#áQ­´Ú–/ äϘSe|¶ãXÓNðåüóƒ€ÃBØpØ…êˬÏàŒ³ ›F ž€ÆA1•ê$NÆ”y–‡¸¾±$3De5vâØ¨CØrÖúe1 ‹i•™1´2‹‹ø€â]eqL/ ÑÛ+áÆb˱é`Ëv$¼pÝuÃrÄß`–©ã/mòGso Óƒxp× bG©/S{ÃË‚äq3XÁx$+#bо„©G0jaf°0.¶',Ñ´'”a‡´UÈÂñ´G:ŸÎ@HiX£Öª€°EñW’:ê™/À8äðI:ê•JvHÛ Ûöh… ö¥^y_¬ÛÅ5ów›Ù7¹ø­[lð¡€:KD– ïÞæå€eERŽªè9@GR3é, âÌŒ!N©CnÄ 9ú<%(4¸e(Å…hÆÊ″ J#óz„³„Ê´2ÁDÆò†Ë˜Æ!Œ}Dú 3#ÈëbÊÀ–¶¼>‹[¦8¨–ñã0-­%>€ Efp-”§Ø|šEa¯Ÿ;—Ûäm*bÛñ!á#ÃßNÍI ”¿¬Ðkþ®0Gó„°“ f‡²2ñ©ª– ¸d}àAZ<Ž\ù#$ $ÈóLò)A@˜e>ÁÈ.‚ƒ¡0K†$㊖< ±)“0‚³ØÐ<®áù¬gAe{¹X,tÚ{ÈšdüUóûî»?s"Aªñé-EÛ_€-jáDúÕ:wÑ €¿íK+å|c(šHE£H¾¦M¾ØõNåˆ\ Ã]ÒJ¥F@ògRài`ýÔdO¾4 x}2!A#Éó¦%YVãX’s (£m'@²$cUk¾šÈ ŠÊ‚õŸ ßÃð%M¶ L1C€˜——e`+rJ*Õ‹œûñÓL™"ýÉ€4X¾† %2;@Û@KÓË „áÊî1äa£Ø AÐDdŠGæÂŸY’…"‚`/†0éXj±7²1–X’Æuμ–Q­Jm¸ç8¾~¡>Ñ%m<´m!Œ<ÐùidüH†ýN §$æÖÃeÀQ/Þ^»¨ ?#)߹ˆ±²xÄü+Sº•gyP,ÁÜ=·²€Ââ§ xBò”å'*6á = ¼cÐ ïžUœ—LMºóÌYÈ:ÏkÚ`@C‘Ѳâ HJ8óšÌ‹•¹ðV˜)Ui ¿¤.£E ÅãFo9¥çX~¹áYÀ`~n¹·Êý 4aÃKhHESM"•WÂð”Š4e ?Ø\Ò¡W„q&[¾dY'x ÒËx ºŽ”tˆhj0^…j ÊшÙ˜"¾1Ö_Ž(3,âç`æ,›Åó5h=©â‚)ó3/߉rÀ^a;{ŒUo;<+€ç_ê¡5øf¢¨ŒÆPˆù¢4…Ê’iiQÊø&1þ‘×QJ=¨W`wrC`Oˆ'½•ˆ4.þ–怃„ðCBñýB¶C‚UÎ µ™áš(7¢)3_˜3‘«›±¥Yš)iOGž†Ãæi…3_¸@§yåV(󸔞ý•J/¼<èûÔï÷Ï(O6=Ö‘¯?ã.ŠBù+à&™"¡l¨j›ØIó,S@(Ü;"ò·¯œ%TŒ1 R ‰:pâÛõƒÌÍâE„!^dÑXK‰@D2Aä“Ræé™fÃô8W˜!Q ªx3æs\ò’ õ0f³2‰Ž˜üØLæi”ë Iìe‚·.ËàˆRYûС³µ‹k®Ôs¥Qšð;}üȨ4N~ÈÍ!"-U•¯1•ÏyŸ¡|eº"•i 'œZ5ž9“—ܽ¨t®†… W:+œ5#‰Ñ IùŽ]àPˆ²„6Z8H¤ØJ[š©0opƒyS,…åø9Žòc;DÁž¿•LvÿP9Ã÷ã×Ûâ¨ÊÁ‡…ÀIÜH²í@½\N`{£7?¾ô]{÷ôFýáÛù›ÚÝ$Ág…ðX8š% ‰½ûfÇÈHá>ÏNy-n†@8•… i¸|MÚÒ†*#ÐÏZ¸[×á—BŸF ×謥º°Œ€0?žÎô4`J\½Ì´^ù";)§| l×8ˆ™%XóaaÇåNš^Ä·¶ÿø½§NÝ T6ךäÖÃx?·N`¾çС[ö’ßÜïJoŽ’A5ŠÊøåM¾+ £Ÿ;ƒœÿ9Ú9úm´strAH‹¡ŽØ ™`š—ýîÓ Ð[÷âö0-ÏŸ „†ŒQ–&üñ‡/>3躿ÂyfymäaÁ¤j1åÌ´]Ä›–F·3¸œ{x‚ö“ÕYHp)Cš?R߆Ž+Üóí¥É‡K’÷­ Ën‘åe…ËõYeG0xîÚØ8÷¹Nëc¯›k>І¾y!*íÄouãWeè"êO[©ò£Z×íà¡ ±`xBFšôŒÀ‡¼28ÁäãG9ržŸÖCeØ6´g+‰ÜñR ’§KkÞ•wXδäq³´Ä蟴åãs»ˆ“<2ÀÇbQ<ˆåMà áó9˜JQòu¾ÜñååvÀ–S8I.;…jlíÆµà³ Á˜yV|¸Iްag϶î\9ós»äõ§£ä Q\*c·0î&£¬9ÅW ;~Šo²h ±qa5ñõ"þ;·–mÞ³­fyÛxI,ç«P¼ƒ!œ/¨KC i16–Ñø¡ò £1Rà"t£'^vå H‚Ð"•ãiòÄ¥e¬§Ø&–qþæŸ)×Òø† 黼×çË1ZR¬ì9êKøÀG©&?¹W}}eé7|s8h)váY‡gíÂSYD§ñóò¿Ûmþ|·õû¯iÌ= å½e§+íìa;¿1]GXÔ˸TáÑS‚©¦DèHr‘A=b8ƒ•8‚á]¸‡ œ‰7¹q>*½¹À ‰þ»†0 ä º¡1f"Ë#Áhĺl`ø¢\Þ|‘)Y3y­À=žŽðˆ'¯œŒ ò´ ü‘)º{Å1˜´ 71 öÅוx¿Èökˆ)SÞÆX†»;.ýÔ…4}çÃ+ËÿË×KåÓ݇MñEÏMô¼€5ï˜ÊL¦…ßélœÁ´ðß_Ó¨?ŒñøF<-ìÆz@¦õ#ÊFw©` ² BxË0Àt(9-X!²¡ÒÉCøJ¬nŸîAØCñj°R©“ü4XÌÓT˜Ä’Wåf0)³‘îËØÀuÞg¬ôf xžbÄ;µœçÓã-—þÓû——ß¿ÒíòÑŽîžÕ=/£|³àEšåŸïD SƒÃN"W¯µ£»]LÒ÷íÁA?˜¸GÀ³N Ø]ÔéT§î'pJ°ý>âqt³3ã{„êÔaö£Ê—ŽcŸúž¤)_´ mÙn؈ô›âT™€ÃØlÄSCj¹òÅøP*^=yÊÁ°‡»ÿ“åÑð‡þvmõ“$ÅEw/[üˆ_°ˆä«Ó*Š~þ €_Øqè‡÷¸ä×FñË{xVæÁ°‚g`óeH–£ž' ˽;Á‘NkÆTÂAp çZyÃÉaHU"w ‹À/#®B­¡Pɹ¢©\(€Ü¼òE<Þ˜¢‰#—ÁÐa™«“&OvÓäçî_Å“’îþyçYɬðB{€B;îS9qZˆ?ÔÛxð³½ÖoßÖœ4ý» ØïƖ炇u} ŽÈrD3ˆ»…P••ÁâlÔ œ@\Ghãàæ?Ò†W¦l*e¡R5»þ£L•/pÜ$|­rTæÞGÏ¥w}ueù޳½ÞýÈRö´i*ÿE /ªø^Ë´pÞà§…ÎÆ=×-6?^I£W4¢øfN }n‡RXÜ¢|(„‚÷£|èrei1(74*FŒÀ …¤?Á €)œ¸ráfPÌËä-×6„s½âäîި̭¼vê>·Ûë~ h¨áÅw÷hÃD¸â À·0œ†Ç:­¿8°sþTÓä:L ·b.Èž8¼9êuüêÊ[F8‰Â¡4?âõ»vùMIDAT´æ°B|cœ@ ‰2QFñ‘¯Þ<ðg†`†"yþ€¶*çIøöÌ4ýâêÀÝþÀúòïƒ%¸WŒ»G[&•jÒÐÐ 2-|´Õºø…Nëî›_ÆK&ßiá&SL zp"#Û<a7¥…Ó‡–ÁĹÐPˆ'¸@0…SùÜ«µùÞŒ‚î¸1~F·ÔIÜÙ–K~æk++ï½8èž›+ÎÝ«0Š÷+Ú¬©á´€õÁ#Xüçok4Û˜kߊÝĶ”³§>‹óUqª_ ʼn² Ã0—“A2¦ôÔ*Sx’˜t¡£'y±7"âÁÛ£n>ÓWèó1êÿÓWW—ß}¦Ûý?àLgÂëE]Ý£þ-…«Â|OÂi!Á&Ò½‡šÕ•£è`-Š_WÿÅc#Ö P«L T64 wNMÓ0P F!^L¹B8ik”óž4âd•/€£Zuwá[Ò{—G£y`uõ# å϶rÔ ÄWE¸š @zB=´L ÿµÛ]¾§ÛúÃWÍÍÝ‹O}¦…CxW_bŽcUìѨd*”)Úƒ.‘@ ‡x §±ठ’Ë£œŸüT€clh«ûî>½ˆsú÷ÀÝÿÌÅ^ï°²m*ÿª W˜tmZ8‚'¸»:­ãxZøíoo,àǬ’·ÌÇqïKAãX¡ùC&Žlø bP>-â$ ã 6M€5üÊ^”Ï—RF<«Å¨7wWÝ>ôpšÜþäêê½`fîþªS¼…<þZújŒÓc ‡1O >ÖÝøÒÎró£²Û_ãÛ8-àÈ•›HP3uL%Ó2èÔ#<Ìr~>‘Gµ0q÷|A£•º¯¬'ÃþÆêêïôz=¾wÕ¹{´y"\µ ìÉ èyn"}lÐ^ôð©WÕî’_op=ùmVx$ÃGXeZ@ІpŠ)ðƒª|Cy„÷¡ü¨Ìíè$]^Ò÷~meù§Î÷z§P|Õº{Êh<|K€u*œþ]wã‰/ôZ~mcþnož¢9~Œ jq{VžàNax†î#_Ü=ž¢VâþËÓÉðöã««‰bbQ^W­»GÛ'·”øÞÉ´ÀWÒàíÝ/·÷îúð¾A²ï¼±Ž5F5Ö‰˜0±Ÿ¦àÎ"`˜tuŸ¤_Ywé?Àûx\ï÷±£û­áî'´€·ýiEß0N väüS{¾éÐÈ}`_äÞÊŽcš|AÅi¹†ibc4ZÁ‰Ý¿úÞ»÷½§»—§Âo iLöâ[ÑzN èlœÄBñ£7Õ›O`Yø¦…¸´ó\œ–ž'Àkë:9ÜþÈêêÁ t÷2q˜þÿÌÕ)N h9ÝßTþùÝûéG÷ìÿØËvïþNé«ûÿgÂÿ€‘›k iKIEND®B`‚ic08ìU‰PNG  IHDR\r¨f$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì½i°mÉu¹Ï9wÞüjP©J¥* –l ¶„ í¶xLh0tGG¨"ˆá mLw¿ˆV)ºÿt4Ýý‚°qà†h° -É˨Œ¶0l4•TRÕ«7Üûîøît†þ¾µ2÷Ù÷¾WB®ºKÖË{÷ÉÌ•+Wf®Ìµrܹ{Í}óÍÌÞd2iš§žê¿ÿÆÞÓÏ<3&³>_×g„ùµÏ}îìÜÖ•ýÖ–÷öæ'/. æ‡ûûs½¦M&ýÁ¨iú3½1©Œfz½Þa³¿¿779<˜»ôð^oqqçB¿¿Õ¼å-·¡9$Ô¯kúO_¹ÒßåË“Þ?hî'¤õŸ‹óu Þ¼w nî›o %ÖGïýÐ×öÉ¿xöÚ¾ðèÞÑÑ#ëŸûÜ«Ž÷?Ú;|õ¸ß»8><ºx´»s~8Å}¶çÇãÑ 7÷¥²Âõ‡„ í‚™ úã™Ą́7ý­ÁìÌæ`qqc0¿°ÖŽ×æ–æ_˜™ýÒùÇ¿:îÜó<òÈsÍ›ß|ë%D*…}lLî+„o–gcû&ÊË·eVµž=üSü`óAzá.ëo|üã]ÿÊWÞ´ù¥/çptô{÷vŸØÛÜy‚^üòh8œEpûãa3Ž›ááa3œŒén{͈¾—øÑõ*qaRÃ.Ò.04ÀÔ1éõCI“áòÚkúúýððÏÎÍ6ýÁ ™ÌÌ6Œ"šQ¿?š[Z\›_Y}vnyåKó3ƒOŸòµŸ~ø oøì™ïýÞ/Cch 3˜¼÷½MóŒ_BatPï;ï%jÓ¸—iܧ}¼÷½ï4'„Áœ¹õѾ髿õ¹·í¬¯ÿáíÝïÞÛØ|ãäðpev4l†‡ÍÁð¨9RØm%¹ßGâCRÑýZŸ9NO×*ìÚUÚeªþ+”@ËX•XPèÛs«0£P/Òë1Â@3ôz*‰9”ÂìÌL3;?ߌ3ÍdvfoáÌê—άþÆò¹s¿òêïþîwéïø èû’)¦2èÝW•ÿeíZÇÿeSý6M ¡‹Þž¹qÛÓOž}öÜ—~ñãßó¹/¾soãÖº½µý¦™ápf|pÐìíïg;fŠÞïèvÚ:%qDÄSØCpS'{‘Í4Ž:¢8¤Øðçi`Fä7GROBí¯Yˆ‚d¢–“G%1W˜DïÍ¡QƒyF ½þdáâùÏ/ž=÷K—{ôçÞø®wýbïá‡oT¬̼ïcÕ"Uø}ûÞqÀš»oî1ü÷¿ãæõíPøË?ó3ïxñsŸÿ“Û7¯½s´¹ûèàè ÙÙCàž1#xeŒáxŸV—YW·•ðÖ'HðÃõÒ‰hx‰c×íA¸ úïf¾«?IšX]®^ª&ý~(ÒGSM³./,6½…¹f²¸|cåK}øµ¯ýG¯û³ö_‚ rÂübrzì¼§¿ÓZ»§É|ûgx;¨=>2±ú[çïüÉ_þÊܾ¹ö¶þÞífÛ^~ìr|o¤ÀOFãÎXa(òªXTgµ[© ìdeNN„¹†µñ¬Ž*èǪå•~›’•j¡Òj’NDg±zX`¾cã;)lÒ “Þhİ¡é³~Ñ_Fô—›¹sg>sæ5¯þ¿ßúÇÿÛ¿ß{Ýë®KÉAWi »oN—µvO—ê}jȦ`L™0Oæ?ý?ñ¯}æ³ÿãøÖ­Çoïì6{áò>âé˜G[ŠxøÖèù À—E¬ <|…Ùµ/rZK¡ÑVOñw;ü6¬8ºz¢º«Ýâ:í DùT2týÕO„pƒos="Ëýyxµ´¼ÔLVW¯_|òuûmõ¯ü_ðïhî^ˆÛU1@î›Óà€õpßœ2x–Òí{›æÙ|àÏ~âßÿÃk×¾k{s«9ìõzÄ€'S.-¼õ-!~ÂÀãψäl¡…1¦@ŠX:¢ð¶ÊgdÒ8°œˆÏVQè3­)} si.µÕœH+hK¢k*­®Mx%¡+²ÛëÀ™™³+«Íäü¹ç_õ–ïýëßó#?ò÷%ç¢é;k'Âî›WÎi=¼rZ÷)ÀnCýµ¿õ·þëŸúÌÿ°yýzsä!š™™>kdENNôîr¯]ÔGÀFHÙ¡íés¨cé"¤1'Ü!|ÆíºM`jZšSÐËwUbJ² æåà†"³`5ig(SÅ%eIDcäü» ã™ñdæÌ¹óÍÊ“OüÌÛßÿ¾?BÝêN§^~fïÇìrà¾èrãºkϽúïþ·¿ñÿ®ý‡Oþáë›[ã™ùy–´Fwè[c7+÷k/Aðñ:Lîn- …§’r>ù€ó£­!nfÿnDå·ó«¢c”4žÏ/-ÎÌ?ùºÏüà_û«ïì]¼øµ®‚ýíо{wœNÍÝö·¡§“rí{²ðÉ¿ù¿ÿâóÿöão»¹p4ÓïͰpŸ[ûz\ªH]%”B¥D; * Špq# cë¬Q kQJܤÆoJcx#™’Ž;zÓ©¦ú)?p—ûOÚ`‚o”ÄÁŽŸÒ‹IÓ”XŒ àêÑòx<»ôæïüÒïÿKÿý\~ì±H£bÕ<Ü·_f^^´û±Nr@é6ùÜßû{?qí×~õm7ö÷gú3s£Inùw¦ÆíÈP€Za,!0å)GpZÁ‹UvˆÚ3‡©Ê@áL@X±ª!qº6B*"T£€@Òè€?ü…®Â¯¹Ã6–´Á«Ø Ä+&™ŸT Nú½þìn¿wÔû­Ï>ñëÿ§ÿ1o‡Õ¥ÂÅß¼tôü+ òmÕ¹),ïþÒ/ýñ¿ù›ê«×oŽfúƒ¹Ñx ^¹ˆ/ŸløÅTyœú3¬Å% dª<ÂK|q"¾~ÿCÈZj-\È4Š qóI¡&rÅÑ)­“qºa?p ­J3ó²ù¡5Õ=µ¯yš¶j-|l8qšÌn>ûåø7?ýÓ?.¹§8>Ý’½ïxÙ¸?xÙ¬›FdŸ?ÖÜžÿôgÿ2{üÍ`a>ÎäWÁ´i‡ðبm×ùVx+)<>²BÛ8&2ÕÒ¹€i¨ Ò©•qÒߦ'šE”ªÀ J.Y•Ê1Û˜„iZ¢é­ nºmHÅýÏÙ5D8lÈ!ÈÙÁÆ‹/6{ÿés?FïÿwÞT&½|û¾}ù¼‹˜6BŽô>¾õÜW¾o}k[_x •‰¶î“m?‚ËO„ñ“xSÌÖ…ÀfX±‹¿,ûwˆ×Tò8„½¦§€E^+Õ’Á½µ‹ÃÈ‚„ŽÃ#°ü¨ÅmP!¡³5¯ÔK&>#>ïAL6®^}ãÇþçÁ«*¨F»oÿ69pðÛdØè9í?ûì“ÃÍ¥á~ìÇq¾‡²{Ƙ6éì8ÓU!¾ëâYà%n¨›)ªêÇž6ÕPE-qî´J ¼Î$Û¦ø˜eÈnx%¬€]§ç‰<ê­µ¯<¯íìœéĺï|¸¯^ó"ê>Â2éÏÎÏ! {“mÏó//ç{ó4tמ/Úwiä ÁTJF k% wõ×8 g1ÔâÏЂC‘§qÂUi:ÕšÆ%Ï*›v.ÌÅ®Cðv®ØCífèx@Çwœz« RƘ]…ð5[{{ÍÖÁÞd‰ÑÕÂòò|‡Ð}ç+àÀ}ð ˜w,êâ?׬ ‡ÍïîoÓS-œ=ÓÌëñVާâìUmãÊeÈ>!¾€£LvåR·FYwŽg˜!!,»äÚE'…HXÀ§¸w†fŽ4އ¤Ïø%n$OJ¹J Ù‘Ö]sVP •°¢òƒ0Ýq‚€££Ãfkg§Ù>6{GÞ<^XXô}s ¸¯N‰’@`F=Þ{_áý 4Ö£Û;ÍÎþasxnµY\\â%8ßå/‚îÉp-™V=+þP,°¥V”ÄNHÚNñ§ô+Œé€nDá§D +© j*väåÍ@-?/²±jú4‹g +Ia™ë8®Ü ,é9Ü᛽ƒýfs{»¹ÍÔêþmróÑ¥……ff0`¡såJÓ<óŒ®ûæerà¾x™Œk£=õT8Ùö?j¸gna¡wîp{22 8Øi¶öo7ûgÎ4ÜŠÃh`Þƒ-H¯ûÛk†BP€]7Ìóû*…”qÇþoØà*ÝöàÚù£×TšZWutl©lª Oi¦Šj5ž ÜÅÔ[M¦o&W‚´ÆòÄèJ+òŸ¯FÁ ow!~ÿ†‡GÍöÎv³É[“‡£Q3DøooÌöêÀµ•ªÚTî;^.î+€—˹ï;¿³çÕ^eh¤}îË›[˜ï]Ø?hzG“f†©ÀöÞæoΞ;×,¯,£¸SÏ]ÅM% 2zùÆ^ xBÄRÐTÙI :6¼Wl¤¦0ñk7>,BJ œ5Lh1-è^äÈžF®ŠÝͽMOz„kzÉ!Éû®ÖÆGÂràˆ‘Ó6B¿±µÙp§šæ>È„Ùùfn~ásÀki ¹o^î+€—Ǽ¸åöégžõž~:nùY}üñ5®°±qöú33“y–ÏÓ çFÍÌ^ìúfó¹šËç›… ç›3Œ ÎÎ PÙŽUš´sº ð õ­¿4!F8OÚ«»½m ¯pc‡ÔÝwŠZ¥YäL¸†U»ÂA²dï}Xˆ§b®XÎãàNmµÄˆaýÊrc{§Y»µÑlÞ\ç¾Ãq3 ú¨°~â=ƒŒ®èùƒWç/]Ú2O?ýô¡‰_¹reð1®L';U1|ß|¨­ê@ýöF¡ýöËuÝʤ­:ÌäŸxôßý쿼2»ºô§ÖÖÿØÚ/ýÊäèö^oĶ98jF{Íöî^s‹ÎmÍ./ÛzV›ÁÅóÍò¹³ÍòÒR³ä½y³3¹X¨dEͤ·#S­J"“¿ë¯Q3ƒS×qÄ—€ýã˜Õ×@d » K7¿(ªt#‹zƒ@u¨zâœnß¾Ýlmm5·Ö×›½íÍ^ÎP7G}†ù«+ÍâÒròd~ŽQÕb3³0?yò{ÞÒ{òÑWÿÊøÖÍŸúŽ·¾íßòÔS_¨yÔ¾Ò43›^'–Éwî»q Öå1à}Or€«ÿ~ºç§y—¿Ë“ç>ò‘'¯þ‡ÿøG·×n¼g÷æÚŒ7·Î-_¾Ô¼úÁ'×åã½áön3aåzD#óp'3bH»³Ã½L v!ç³ ¡iŽ–PgÏ6‹4ú%”ÁCÝ9¦ \kª»íÿ›§Ô¿ÍjÝÙ!+#/ÿ.òSѱÛÐ fnºQ‡á¯÷7‡,äí³¨·{{¯ÙFî0Ì?(B?žaêãã, Nf›Ù%„^ß! G€ãhõ,£¥¹ÅÅæ‰ßûÝ“³ãQïöó/6ý3«»gΟû·«çÏø5¯ýG¿ÿ‡øÓÝpñø€ špT›,¶Ùíâ|»»_ªæ¿]ùâû¼½w ôÏœú¯üóþ/þƧþØæúÚ{v¯ßøƒ3‡GËGÜé·Ç–ßÑh4Z8{®yãc 6?õéæˆ¡ìˆ¹ìáox¸ç¯™ÐëÙƒYÔ:86û·›Ûôy{Ì’°Ü…tžñʹfe`ƒŸ_ZhY<ô`Ñ #„†ÄL2|_¾Èm‘>›·­»VjgÊOëG˜ü¯‰oP,ì·C e"üV“P…ÝÕûö#¶BCàÚ{³ñmzúÛ»;Í!ë `„$ö(Ç!woˆ¤÷æâæàC} àtÊoôQ î œE).°~òèw|GÓßÞïÝ\Ÿ0}ÌÇy”t†«Îþû3«gîñïú®Ÿûþá_g*ÕUÜîàöñûß"¨u§]ÛJömåV^žzï{ûw¹£¿÷…ø3ßsó‹¿õîëkï¹}ký-s‡‡³4æ=–¹¹Ð/®öbÂËu¼ŸÊ\öɇn& g÷_¸ÆÐ¯¡Ëk&ôü\uÕŒQ*B£¤Ú3øpÊmŸgo2 ¥°2ØC)@—‹€Ü±¿ÂV"Û‰\.â"# bÅì,÷ðó (n3èAc“eùø+ÓÓ,©bSâ’~jªÄIc£P‘´Åá¼Þ} ßnVÐUd>.ܰW@9íáxoól«ÞP~qm‚ïðá€Ùl÷ðøäß`1ÔQm÷ÈW\Gfîìž# Ê7ƒ°¸zñbsîÒ¥¦¹u+?TB–ââòC (ÿÊ€ï›5ËçÏ}jõÜùñàkûð;ÿÒõ‰^ï­ê×jú(ƒÞ}e-¡òäÛǶ—¿Û×x€>ÿÿñ[_üìo½{ïæ÷ìÜÚü„žË{w›Vª¹†"…žk½’+ÅñÏ8=¶®.ÐóAH‡kkÍp‡öFï7¦§÷‹= =·×æWãá ÿ ´å¤{l{í›}„‹³ïÍ{Ÿ>Ò祠BP€ìÚ¤4™áŠm!qB¦8m@) èYBÛƒòY/²§rpÔÐ#¤ÇƒoZûEØ®›?û1&Ÿ\VJŠO‹!è¬Ê+ðú÷!er•ùˆ2:>ÐXÆx˜Ã÷]^&}w"¯$7rˆ@ ïûá‘ÉGì>àŽQäÓs¦?°,*¹EGœ±8¾™ lVQó(A(ŠDuX=ì lÍÌŒ?\bÔ0† ++Ÿ_>{æ£?ñćÞùîwÿrïõ¯EDSÇÔÏ–}[~6}{˜*ô¼ºk]È |áÓ?ù“pí‹Ï¾ûöæÆî­ßú}s4²=z±ýh`´_Vö›ñˆ._©ÑT¶ÑÖln4B{ðå¯6+4Ø0 `Ì kÃMŽ,ðŒ•…h´GçëˆÜlï×WP•‚$î¡‚‡Ðí»hFO«½Ïˆáøíüˆî˜È e(’‚fÁªrF( lijìeéZÕFxBc}+Ë(ƒß3±kãYâú„3*é»hiÏ pILe–DØaåჄ›ÂOÙ,x›' Ð;Ü7Èp·GMða”9FUfŒvfèÙå‘ÓªG_û8 EBZª2ŸžP*®GS32˜!“.²2dB™,>·zñÂ3ì$|èÍoû3¯ûÛÛ“ý ; Ï|ƒaÿ[Þȳߵ¦#ô¶OÛ]àg>õw~âûמý&ÍÎs|zx×LSžˆàèh‰…ÀW?ñ¼bdAž…/I7HHKR…¦_Y †ßk›\3ˆÂf¤Ö_d”âèb2;»ÍÃ/3:øÙGž|òç¿ïÏý¹ß½5WT¿ ·åÕïÓÌ¡0¶×0“_ÿõËŸøØ¿¾²uõùÚ¾±öƒ,E?ܰ uûðÀÊ0¡§Epˆ+él‚F¥!#82&}‚I6iwMÌF=úÊW›þ‹k44-‚6@¹·E 0ì±’½ÓÅÊžËËTp‡ÿ1_§±+ø.è9ˆÅ°W˜+ò=(ùôqî~d¬­"@)¨ bÎîÈ„7G¤íUe!¨þ¨$Èò¯BpènþœÄHAÁÇÍ5mm¬˜nàwíÂQ†=½Ê&ÂðÇð<ý¡d°åWÒu„ ßô0¸{”ÙÅý›7šþ ²‡®_ȯŕ•æ‘'QäÇ7‰–J"ÁKì~á<†kB<ÌÑ)C 7âö7Hbqnqe0·¿rñÒÇÏ^¸ðáG¾ã ?ÿþôŸþ¤’¿¿›¶+ºåû–p[—ï¿r¥ïi<2Œ7ÍÍ_ø…G¾ðÉOþá[W¯þÐîõ›ïèíí_ž°]·ƒÐóý?eKgåÓ6u"¶1 ü¯;¶¨Ý°ŒJC$ù1Bqø•çš™PàÙûÐg˜Î Yól³x~%Þtm‹Ù+¥P„ wåBÑDã/ÀÀÔlÙ¦­à)´º£‡GŠ*°+9õ«†r0œÇŽ_¡'{”Ÿøø½£_}ÓlþCÀSp;B-®adñ“WÝ­>mhÞýKG˜t«ÐK§NäʸÙãüÄçúŒ–BÀã(W³üU¯}mð0†ÿÀ›(ìÁËð¥ôüñY¡ “nŸª´5²4F(QÇ`ž¼Ì±øÈ"âhñÜÙ_;{þüG.>þøÏ½ãÇ~ÌíÅ|)£~Ko/Ê‹oCã鿟çiÛoÇ|åCzâ…O}ê­_}у9ßßß?8?då~ŸE-atD4Û‡-°kðwA2¤ëTq0LÓ Wx ¢Žžûj3sõfô6 ½  ÏоÍe‚°›g;oŽ/åO D´ìÁìñièÑû£b_çßcM ñ¢ó6/Ê5{q’4½‰Ø9ÿ¤˜ (ô<¹.`¸Â ®šÀ…ZAÚæ­öäÑ{á†w*€ÄãkG„çœ>pó(Mñk¼b· ¿ÌÇr;ÙçdàdÄ® ß t Б•L²ü¢/9Û<ôøká±Tü«sÿ»)¢F ÚÆz1rÀŽ0 ä{æC¿f€NDáÈ4ì8”Á#ƒ!; gÏ~féâ…ÉõäþÁ+W>Þû½¿w7cÅï·Ü§Î£ :ø¦sÒÀïzïkÿôÃoxö3¿ú®Íëk?´sƒƒ9‡+‡!ôÖžíÑOUóù-jÖêX›ÇʘUox NuÁÊfƒ§:°“8I1æØ4àáWŸof^¸ `€ÐûòâÓ›¸ €a>々óKmƒÎö ]®ÄV -§Óí»:ŽC(IQáרë;Ì7c!ôœ'àmÄìíQGùC1€G7Ͻ|Ú7QRø¥å0^’öìÒo…˜ PÆy< ÿQ ’¯ÜޏWF…g?Ü™P ]ê?`zv´µAðaµ*ø§âs@âK¸zðñÇà£õ™Õ¢àæ“J +¸ÚÃðC!× •°Ù“à/…>ašª8®²»äòdfº lAŽYŸ˜]YýâÒ¹ó}ð‘Wÿô½ÿÝ/÷ž|r3©$©§¡~³î\ž|³™‡4î8˜c&¿ðOÿéw}õ?~ú»k7ß½ãi¼ƒƒÅ†÷®€3¼ŸîÑ[ï¶Ô0±õwuÁ‰\~ ¨¬±¡H!ã¤B ²aÑàÞƒç_hf9Äò‚?lfÈû ¡&“é̞YŒƒ<¬J;ºÆk´Øœÿ» hÏïZ±"˜¾J sÅ <‚yGèéÞ™Þ¤ÀÖïBa®À'±«`ÌâvšsrýR' );Z°|98îV }œ8$óq*QçþéïÄ1¹È{òM¥ˆåé–&ªNœ.9<Å\ߨ (?¸K¼QùÀc¯‰/†:ôwXgÕ8ÔWhsdý*Ø–5š Ôþà&®ôKªÆ)d%=}d‹; Ì£…ŸÐZ÷ŽÇ¨¤BMÂU¸MY`Ün|ÝšÀÃãˆ#pt‡Ë;Ž3Œ ô`&ã©-¶Už7X\¸¾xöÜ3KçÏýìƒo~ó¿ú¯ø‡Ÿ“n1½+è§g «+ðwÊ®eþ/ž¾¼}‰#¸³Ÿú©ŸzëÏ}éÝ›ë7Þ}ûæÚ÷Ì ‡½#È><§' §'ÛEè³JJö ×ß5V¶­5à|=SC«­„„Îî#\r1d¦·ÞåÞú†—TØenæþÏЛ9ßœa 00¸VçyéLôZ1ß·¡çtÀ€=  Á±lUQ–ZÓ¶•’FÎýzÝ5€z@( "Lau# £D®î K—c ­Â®Ôư®Å@pU)üÉ‹˜ µð,îPÀ51J¾ÂÏ!'¶e9åwD„ž\:àcª¡0´((€‹š^ýh(£+Œ leqëŸÂ²ö9­ {}“*Ð[:ºYëØÂ…iˆ#Ž üÇU¶Ñ ¨¶Q}êw4;·¹táü/¯^¸ü‘‡ßô†þ?óg>—Tò÷ÊïðYƒZ¦nžî™›öõRB?÷ÙðÞöµÿô›ïÙ¹¶öC·×Ö¾k–Ó`{ûô JX¿?¤G¤{É#¸ Ð0 ºÓÄ8šãºô“\¤lðFÒk3ÊÁv%š~â¡ÓH·¯ñÀ×®6óàòY f.Öˆ‰P6›e\ 9~¡AŸ1ÇÉÀyÎDƒRÈËžöþù  4l¬Ñ ¢Îpë7S¦_ÎQ IÏü…¡Ï5€Øò£ÛÅ@G à†p£ \t3oE~‚4C¡IÛdVÁÕ_?hŒp‹çSÃr* §½=Á®íª¿S˜NMNxÇ” žãáQì¤á² Df–/]l˜sãf…¼¥ +ÌÙ«k»EX…8á‰GËT!›FøÍ¦*& /¯#÷*Ûpâ(ûa:£^páÇË”ÔÚrG:äUæf8;{{ñÂù/=û¡^ÿúñö¿ø?küj®üœ50ï÷ÔÈ {z¾ín:¶0hÊ…_ÿÉŸü¾ëŸÿ<+÷·Þ¹kýÍŽz0ÇEÏ8³ÆQNù,ïáªÌ•½²û0 ¥pG :/Û¬‰¹'é˜R÷)$Z¡ˆ!®ä¢­k×Q/´S€YvæèVàŸŒöi”<jKÁ~0×o\]ža¨‹, ˜ØàP ~®¤ £‚@|ódÎh!Ç– îØæ ó{ÿÜÀO¸øG„».0椢#a¡<Ü#müòMQ)YÎ*ÜÕvd`ü®QpÅK%q#ÇÒ5óêsì”ü˜Þ߃XÈôäwtG®Xï˼ tù‘G¾T ®\ [þU7ôuŠÏ±õ€†uLÔ8«_£a¦a!0µ÷pZÝ€ksòB§Â w¨ëY^nbGápñâ…¿|î܇Î?ñÄÏ]ùÑý H!ÊgæÉ÷MKQ6Þ3Sóy/èSˆbßúå_ûÛûû¯}ñ‹b÷Æúno½¡Àï!ø‡ä„£°Ãz’•|ÛgͨªîÈtÄHLÕ-^r4 žº’³VðI›žt´Bk"ÕB¡¢f³pÑ«"°Û7n²ø|3‡4Ï `sæ ëNúœCàT{4(›•ßw¿nPÞìS Øë÷ò(°=?n×b À†_wûé.sd»âÇ…½X PøñÇÑßPŽêz€ ‚Å6zÿœ&XváªYúô8ßoY‡¤g¹äM(¹Â§pÜ9-``ÎPa†N óT`(˜hüäcò9ù˜á‡Ôýˆ}¸Cšò•¼Â.TŒƒ@ž† E¬ð›7ÂW.?Ð\~Õ«Ø«ç ô§ À5U¬#l#Ú†ÛÈb´‹ØÇÞ:”pm¼'n}Œ¯ §…[˜©ÌâÓÒǰ8@ЬNÊ aï6÷E§}^bbTðëKçÎ~ä¡×¿þÃ?ðã?þ«ä¯m–*ƒ®E§ôcŽï…‘GQʼø‰¿ù¾ýÚWŸý»7×ß9ÜÚzBaØã¥ uN™ÒÓs£•=ÍO•Â`h'sï–á“'ýmIhÃGà¦òB°t«tª[[C~l¼°#~GhvÀ![³C àÏ"\Ty3àÅ ‡þ¼ß‚ìå }Föò¾ã?ËÙ€æqîåI@‚ʦMn£›£TÑsÃ'§Î2ô§ð§¨ Âü°Æù‰ž_|ã)øD´¢‚]ùÄ×èf}U×ã½Y‰†Ë¯:Ï·ÌáX®TáQC ϸÚᆞc8óuHÏ?rèÏ´gb ‚Š#ð˜Þ‰@*€I³úÀÍ?ÌþBOnGøåã1¥T€ \ÎQÄI…b°˜6˜‰ˆeÜŒ“/•„!f¡¤Ú# 8%Ñ1‰€ÖñˆÈYƒI¼½è;’=ÖçšøÎYƒÿ°xæÌGxÃëÿÙù+år§îlótŠ”CøÿÙ_ûëo<Ø^û4üstkó ¾»ç+¤´¶·PßLê½F³+ô_'Vb-XQÚ2?ªÊ@Í îWP•6Ÿqƒ†I.]I¡R¹›=XâÙ˹àÃoÀ¯ï>÷µfŽÖå·SÐ`x»Ðþß^˳þ ½ ^Šƒ>(½æQñ\¨ d‘£ƒ`´mÀl{FÆd‹2a<íÑ›#`íê?‚2d‘Í£Á1 Ï9bÀ&–Ñ‚!ä(ˆX æ>7uÄ“B©€§pÛä-w ·ð<¬§R¬sþª M£† é݇,莹+aŒð+½Ê@Ìý©œ\pÀ‹SE@4¥…lÎ<ø`óÀCqÈJÿ(|ŽìùüN°£‰T¿‚nðm O%7”ˆðfóR˜Ã.pñ ÷×õ=]0,p5ÅavÂöcçðšjAU9kaÏìS÷G3³¿Ú,¯þÝÿéýß<íT¼¹*u*¤¢Ü6Ëñ¿ø±ûÿð?ûW‡×o.õ—›¥óç'K«+#¶½8ÁêhÌëb49veäyH–UÆÙ@ȯ)¶š¾ Ãm#0'6ÂÖ.þ6j:’„îŒ3à·f;C:i…ð Ö]žp!{H£Duˆl¾ ŠÞ¸{ÝsñU0fá±ÆÏC݃kƒýz^š±gž#ž·ÙBð³\f !?æé¸UhñRôMK¿‚‹ý‘ó|9,'d,{tó”ü‹-BÊlüœ> LTN –£€—ºÍgÙªˆtñב$²ìغƒ/* VùãþÜLõ$ ´Šå1ýIÈ8yp~DyÒà!¶©§èJTªS;Ú~yXþ‡@ažþZ Ç£rЛ±J ÒFÖ‡»ÅHžIj*~–9Ò0Ð4¦HASo$_ÊAÉa,ïOÂÊ9Ù9:š¼°±1¾yýúÌöÕçߺðÚ'Þú¿¾÷½Ûýƒü™Óžœªx©³sŸùÍßÿ¶/¾¸ôéý¼×1»õÜRæÁ 3«ìá.³½ãPÇWîxG3œõl fÁˆù—씜•{šâ·ÑU F¦FXµ+n§&pÖøÒ a "ÆOXÕ¦6k>-B3a}(‡°®eh"/¸yù áš p²§R€§èM:8-P øÞ›ŠÀ¡x½|cf„žä…_ rìà9SËÆ ‡Èd,¨ÍÕ~„L¡ç±§õ•Ý8óm{o6y0^<À£§Fuë©6ÿÄçNÃØR$-”Óµ°?ËwË+M2ø²^>)ðÎçC¹˜i°²?æ†äÀíyÄŽÙa å*„±#lçÈUOmp"ʭл…:Χ’ ˆ0~äTå•ðÌeºŒßâFîñùoâ'¼–$bŠ[áôûc™‹3ìâM`‰+,âë/½ˆŠ O ¡nÝfd´¾±Ù[_»ÙÛÝXgb„î]\<ìoïÌßøÒ—_m NEÒºOܪ¨º87·ýŸÅº0ÌÞúÏo7W¯~­ÙâÙ8s¡Y`+gÅepùcœx“/DŽÞÍòQ«Ö&J›ÜK@÷œiP6¼À—ÉšB7k XÐ,Â\èÛø2‘”i\d.vm A9‰§½“ÿ\׸·/iĆ4\Üc¹ ¼x‡‘–ù¹õ«<ä~µs[uÀÐýŠ÷Œ8,½c `Ð a!oqBØä˜ÓC'^®PFOLú5_¦Âo8 C˜ìË…Á<0!¼hñÐ’ShQF1Ê!?AÏ8Ò04S\ Bž& ¾ CƒE™y“„ÇôøâN{~yª¬äŸøÕ¨ úYÄÄ66Y¾BžªL¡—7)üÆÉö”ê³ ¾Ø¸ ‹x‰£Û ¯tÂ/L4Ó¦;Iâ1<:§íF¨åÓØÛÔ²¶¹»Ý¬­ßj6^¼Îe/žeàÅKO³ ‹lõg¸réÒ…î-FAã4~NU¼ò=M®.î ¾Ø,SñÞÑöªñ|sëh¥¹Ê¼ïyÎz¯o­£ÉšÙ‡/rwÛùfq9GV.M…–aÑ’õ¾Šj˼0€õ·á¸“ïY‘FÝ”6BÄâ§SI %jET#­ QÇ< Ìô2Ýhd´lãlgÚA±öè3¤å*y©ÀD//<ü S¬ h3óF‰¸.>hf¡ j¬x‡è!ìѼZFK\§Ú± ð’Ãsí$°ÂB؇CS¡·˜LÌ\K„_!‡¦ ‚Éxôö±>ÀÜÛ‹D¼éhäb¡‡œØÎ;â`º0Þ+6ŠkºHL&Ønñ©âø¦‡ëöôyôèýbØoÎá!Éš¨?ä¤ó5nP<òÈ<ÆÜFì\PE¥[˜±ü¶¥ÍSᡨ»ªôràd{bHCKSmaÕ茩H…Y?ºÃonÓi\{û}da“ôöÍέµàÿA_˜¿ÈÕ‰,û8úÍ!8¢X¦8üªû4Í©*€š±þÃßžÐ8&GÌ÷gmÔ½æA†ý—83ýÚábsÆsu´×\»ú|çÙZ½ÐÌqGþ Wc/p ®]Qy¾À[8OTnEPx12Yuµ3rTF8!4$&@»i§”4z£Üé·úŠX¤#ž·äYf®À ¡³š”Cý7˜¥÷$G “]̲ÇîC㈚ž!Ì•‚#„!ÖHßQDnæ°7…¤d…pWÖS ¨À¤^¶çwÈ‚n,æ™eˆè攌,Þ$'¶K¼¤LaGã‚Sºïð'†îŠÞ\úмÐÓ³®TðIôüæL Ð ¡ Êôus§)ŒÂ󱲡—BÐl âøJ7éNaÔ?­À&^<ÄM:øHK¸)©`ÓNx'‚™¹‹9&‘UžföDžôr¸mkw·YçâØ Œö"µ:À…y®BWðcšG$â»¶žÓ£³—/Ç¥¦—ƒê]2ñ2A§ªž*™\º¼ãM1œ…r“‡"à„¼FÑœE1œ]j^=^h6†«ÍÕ½ýæêöÎXoÖ=BóÐÅf±|BkΗ,¨Ay™=žBF%á—³Z1î–Ë+3LTBå”XY©F ˜ˆÙÚSŒ oƒZÌ.éVæ€"d/î{ä±ÍÅWárZ=-sh¦<.òÍ Üa¿š+Ùø¡å•^ú½[Ð^;æºÄ‰x”º‘% ã¯Å¶Ç×W{y…7†ù A¡ €© sD=;ysw „,Yª :Ë‘J‹žÞ¹»=yöüØôôÑó32°¡zµ 'aç"r„êã­¨ C‹0±èH€4¤=¿®¥àü0î<Aþ…ÀO…?á¶aÇS•AÔa/8 ´‚ªÛ0¢­é.øÒ“7ŽÈJc ·¦Xò¾¾bÌ0‡«æö›[¼æ¬àï¬ß¤<Ä÷Ûtxs\‡n‡gKÀ)B(!¼Aúá|]¾|y×$NÛœª('—âKÛˆ=튖•%l¤6<Ë<„€_bôñÑbscï°ya²ßÜ|ñùfÇgå|3wéB³Â×uø*L|JY)ØÑÛÊ ‰–Š’v˜ZKá!К/ˆ%§¿Ïš `øý!zÖ©¶‘§=…&g˜Ìdñ!ÀC…î+´øƒÉÔº¯˜»ÿooÊ€@ÃTfqÜ£,öN6r×BØ(€Ù0l¼m>LF?f=l`"´‚Ž_~3@ 70cÇß6.ù Å@^å3“ðPçX˜ˆ¡zŒXÍgâÎv¬¸kç ŒG™Ç³Ùó;þ‰9}߀uGÙMºfaVc¤QòC1cŠ`ˆå5ܨXqË[ÝòK|ÓÆ+¬ºâ&?åW ¦—°.Üð|²®ð’gé‹…ÎVÈ+ÓI“á¢Èófx|à”—ÖÖ¸ÞìÖµ›\ûx3XöÛ¿ßy`Q5hÉ›H3S ] IòÆF#€‡æSSMSeL÷i˜SU5CG_ø'<&|.›œ[BKâc+·þ‹7FiÏ2ôñyd´Ð¬,7W¹êÆÎfskç£ báðü¹fÅðbnDd+ºNÛš´å®Îðت@x×D|EITê!°(â)˜&`éŒÆfÕØ#(¬6Ð9â•ì“·ìqÊ·ÞÆk/Ÿ7pýA‡8Õï{ö†i’2väËüh²ñEîlˆÍ§´µ}¥?sož–åBù‰ppH'u&ÒOŽºÔodÑp‡QÁ5îÔ‘oæ¬1"ØvTÀÂ<[‰+«Œ ØA˜¥Òr‚BŒ¢Vd©Ž¤óé!*X7cºãwú¸/!S@4h#Xiè¶Zm”*¸Y=0ƒqxŸ¿ïÿ;<ôjÚCbOxȹ¿qR)ÀañÇ`z¥­¨H¯6ZÝiÒUÓÓBM¹¬’è}µž4„ÇŠ?Èåì¥3ÜíK®0@¨Ap˜O#óŠ3ïºy`žÙy¼#¤–S¦IÌù½‰‰ø„9p:hz·7MP>V‡‚9æ 2(yÜ|²HÖx–‘b1u–郇dÜ2Õ$Oà+^k[! ·¶py–°i‚Ì}âZo€ù,ôôŠ$ „-äU¦gt@7éíoñ¹³[7׸R>:k¾×ÀíO,‚‡à÷æKÜcB´Ã—ùMO$N›7G„Fë/¼Cˆ‚{ZÖé*€’«ÑCmóÙ¦D`Ù9¬Ì"•Bã‰BËYxáÎjRÈÅÎ9*83Û<ÊZÁ:‹'/r|øEv6yÖé ú²VÀ¨ ΀'墿<„¦&jC‹¦’y0¢eÒ#òƒ­1X“0«;•Ñš  Xå¢=6½Î<‰eÏÞÏûýÉÅñQw G8ô„[Ò3LÌÄ‘AÓžp5ä'Ë‘<ÌFj&,žpAÓ2¨„”Ž®ãÏZLÿNmü$kÏ º†¹Ê¯R˜w ¿´Ä±Çï+ìÀQiæ#·ö å!¢˜RàŽQ‚¥2®ã†‰¯8šVE2‚\Ma—O>ŽªæI+§0R’3ò\csÒé£B p…á·ÖS„á×l⊃ÛühTÕcÛô?áüÚÛÓ&7y‘É-¼­›×¢·÷ú¶šú'¿ÚWÄ׸ ¾ “§¦¯í¤+° Íô¹ùöÃo|ch)¬kÍÎ+2§«JÆ^ýªWí~ninⲘy.ÙìTÆÛÈ4VLýê»8Áp Ž Y4ÁÐCv8Nüâd¯Y»öB³ËSG|ù…{Ê›uвQGv°mX‘vö¥¤gÚÍŸ®»ò_-Ÿ4Àmk)ñ[¯8…Žv KÙCJ˜[_¾Ñ<¤‡ôÇv'³4pæÝj¥á9ÿwô@#¾9Õíh à Øtd™2¬+©ùËÑħöî ¨!üFÜè™ñe<3‹›^š‚ÄŸBï\ßaÿ˜s špɉýx( v©T1.x2ëŠMávÎ1©mðS{~Êi['¦CYb¤BfÜuâ`Wût¯ß’nûiGïO…¸3bþÛs¸ƒ÷r'x”õV‡ÿ¯¬óZŸ­m`52LS,yÞBS~{ÓòNØaáÁ¿ÍTU¬>[x³³|î£Ü®WÙ"¡·nBäYòâ“tä»k'¤d 0øé÷wXýÏ)@d¼¼rût@ÍÏ»Þ5ìýÏÿËv‘íä¾-cE3ݲ~„[g  ƒ‚?Àk”—ØN|œ­Ä›(‚«ÃÃæ:#‚­pÃ; î ðñˆØAˆÔjç±RµJ&ªõ%¦uVwµ#X¸Å‰!9_ÇÁ¥7 ò¦>SCØ!ó@?³uÄ–`¬ôÓÄcjà?Õô¼5"À­ßTr4*³@ú5Ÿá-8!Ü%,æà šÏÌnƉµÆb„E©Cv·rý³?@€ýÊ/ïP>îd!‚‚­J@ …ÛãÇ¢!yU‘¸Ï_„¿â8÷wkˆ…èI,ÐÁ8_“vÕC*…  /C¸;bºòÃ6f¶³­%¿AKÉ „­R…~ã NÃÉ»´u`·wláñÉwNê5›Üû ôÙÂðñÖõàÅ”H¦£›§K__·äÃ!02? îRA|·`ëÊÌŒß=usª €2×`ÌèsßweÇž‹Òºs&zûD •9Q,f ©ù3Œß‚´‚ЬðéG˜Üb­à:;/²ƒàZÁmÎÌr®`™Ó†¾o?뼕È;“ý&„Á_MÖw›‹ žÚ¢ NÍ%¨àÕ¶h‡[?&zXÖ,x!òàˆƒCôªôÃæÌ³ìûsŽxÈëÁÌgP4&ðhSA#VºÉdͲ7Êbz¸ÍMô«:0¥‡+zzeú²x#OŒ@lìòFM½7 {·üJÏϰ%”€ÕSò4á&Ðà:„¹¥GéZr=>-á—¶8™ãrF‚ü bÔ§pöéæû”¿‡Ò±Ýļ_8qã˜4ŠÁƒVÖ¤#óBá'TÍ{áMòÅ”"¹¢ô$´3'%U&a†xïY…]ÞâÜdn¿Î¾ýוGÜ9öìm*ôŒœ¾µñ[¼ ôW@Ä ×Á1ŠÑâ&0•\o§ùó~Øü…¿P0OÏ:UPË=鯮 \*²òÓX9ɈdÉÔ7õƒQ¥Ñ2Œø!Ê1¦¢!ö ¢¼DEÄV";/róÎuÎlòÜò\ÁƒÚs®À:4 Y€h,Bvj«*‡È&á5ÝN¶Í^ôµ–ʼnS£§f£6žùÕØ¬{©óï3ôˆÑí3çwj€$Ðá7ó(ƒÑž‹fìÿ3Ô>¤çõ-¸h6~{˜’9“Sàkƒo>Â+—3– ;óM¯M¦ã¯ÓècÎ/\©Ú·Ç'/ 1qí½cTAÞ]Ä3)«Bxœ*Œ¸Àz²î¨Bö*°–‘ÝAŠC¯ßváÈ&7AÉÑ@ŸI~ƒ}N¹›bò!¾£ƒìýÄÐßlùnˆÂ–ð´A \íŠDŠé¶ü¶3óDž:2Ûæóî·66næÎ:_ûK|¡Ù}{Þ”ô» ‘†‰B#Üü$,M­ºjÛª~ÃZPxÍŸ¸º¥ÜCùÎ./mÓ2¸¢µ‘_™ãž)€fey+·Y–)'Ìo-­/Ū¥«ÁÚEÎu¦1F’†¥f±ò{Í*=æ*;n%n —âØñ5¾ÆãZÁžëg/ÆÂ’;Œ |ß>z+­´Î¼™ ØÃظ£q ©t¤'ªüDf%…F<ÝÐ%‚ñ£'MW͹<€|€Ó5ûÖŸq˜Ý?dŠÀÀá¶/ÉŒÙÄ!¾|ÄÜÒs¾¡çðÙ‘AÐÇmîÍ ?m6˜øµlům3 &Oã“Âp“WOíÑÍfüyG'Á¡ö«ˆ&ìøý?ðRÊi)ÐðÕfË«°÷X'èsÝÙ y÷µÞž7ý:°7-’é3Âè¡ìzK(¸}®[ ŒÝæ €8úË’E¯O®œÊKssý¨7Ë(ÄÒ™êdÎI†‰¶~ÌKÆÂéñÜýfƒ›‰7n­7¼Œìéñrî`ñL|ž|–ÞÞs¦–édÊ´jJ‘ôg %¬þfœ–”U€i¡8‰EÛè/-Æü¿wùÿ~@IDATO {™ö©+^Wô ¿âºí¦ ÎJ“ÕÚÑд1 §<”¹«d¥¬¶¸],ªD¥f»b¹irTPŽߨ?l®l®5[<·8WÐç\_{i¹t"+•ÆD!‚lu¹´ŒÑ,Ãtó˜9,XYÑÄË(Q6E. –dçtˆŽÕú®ÿ„7ä¼3—ÏÀ‹m2ÂITR¹ðæíB^á5žáq[!s¡Óíºø /Á^7¸VÊ`öã)Ù°ÑÆŸ™PpE־ÌÀÇ4 ~ÑU»ˆyw9†..®Í¢@âsÉtçlćž Dá—aNà™BxõY܉HFzŒ|Ü´ÜN+ܹám'Cø”6®ÇÊŸ}¿:E¥©RS¸!?t×…¾*„€ŠÉ2Y¶7³ÃûpeYƒÒˆ@Þž²¨·Ûl8·ç«N‡ã<žëÞLÛ;uë¤`Ô¨gazZÓõTwÙ"…£ ·?A8~ÖÒøXÿš[¨/U¬ãÄ^ïÔ'•‚YýÍ­­þ*ç·¨p»+Ûf-t¶Ó,¨Cf“aÓíÕ¬X­`ˆÈ6(kÞZÕ]iáK „²Vºmì=Ð9zŸÇÜJ2=àŒ°N°Çã¨`–­ÄÅ3«±ƒÚ=ÒµÑglœætš¡)G`6¼D³—2!9 %„“ž_¡’v¬¦Á¡$á1n°sÝQö„Ñ€Ãå ócÄ&9^ÕLØq*á FÎÛÇHÊØ/ó ò1ë zoŽž!„s( zm?HŠM¢¤òPkðÏÑü8ä3A±ô\{€¯/)eÌ÷·£×î;9Ÿ(™øAˆÒÙjvÒã{åØÄÕ¦7¯~Ú8¡P0Îí= Ñ×ï%š'‘[¢îx!joäMǹóH2¹®BÊĨ‡pÀ‡…Ñ'Ç© °õÉLáXòÚµ o¤ÚæxîÃüÛ¼Œcë1 ,­æ¢[xîÚ„1z’«4„/X­mÛM5SW…œ°E¨ykãQÏdxÝÚȃÓ¤Nxù^«òTÍûK&g–oºýÃÕžA¿2A^¦Ié·ÊéˆI%;cQ¥6J#cŸ2 It~»ôkES€Þ<ù0#‚Ë<±V€"xkº×ʨ`³·Øl³VÀUL¼™¸§µ‚ É”m‰5‘NºÕYƒT"Õ3/–!=™#hB*\Z\{:‹UF”9ü`A/.~±b…žEº0FF³ð‰Sd<Á Õ%æž| íÚ8Å@`'®¬E/ BÀYTàôú(è¨'<£”ƒKDzNÜ#pëÒãPQ “åÄu´ Ñ6OÚàö­ðÕöïî=lòæÔÀ õJ/qQ¸‡Ø3ÈqíAeƒ1¼ð/V+Òƒ„‹× ^=^™'ÏGäËwî7éí·Önñ2NY;%t ÏÅGÉ"Z¥T«¿õC«¶1aÕm^l«Y«™³ãù;™_#©ØXµÏöŸ©Ù[t—èþ²­SWï#+OópäÖˆm»Þöa/-us’ÝrGÛ#žÌ®Ùv³?°-å?Â[:Fp×Xé&j¥(¾ˆsžçìÊ ;‹0bT@Op„2*¸}ŽQ§ Y+˜Gax)§‘óÉ©L%~ —y 09Æ¡z ¸eQ¸-‹Âì@Üxl©Іz†á¶¿Õˆ—.š‚~‡7a¾S/eW®¸ñŒ#¯ Ãnw&¦ç}~OØØ¡7̹YÝB;b3‰ý8‹=µý¡‰‡øìñRâ:…éymXã¸_å3‡­-`Û›/BÄŠ4.Z>†ýÕ6G §(^ 2¯É¿ä[¸‰n®Úù7n9•ÔÆÈØÈ0‚îô ?d¸Í[x±o¿ÆÍÍ`z×â láy[ÜÁhV s4?L´£t&KÀ«É×°ZÖ”ÁÕtPtGØ4Û‘á[0 œÕOøÓï¯ù Ï3<§iN]4ï}ï¤á ð™ ¶F1Ì]@ªÿ˜©Œ¨å7PýÕ(0a:EÐXA ¡ŽÀ5’@Œ5þ17ÀXDÅv˰%À2šßFÛœ+¸F#yqÌVâÆZ³Í³5àû}—9z|Ž‹K8äá…µr]?ËV$hâ/&>äY7]Ãud&k>ì§¢ÒÅ+eŒÆŒ;ø4À€PU¥¸A+’â'醚LØÊN<±7\!WŠè¹§žÙ[#ج-Ä){~@ Û‘Ó·‡ï™§;UÉ[\Oþ(Jj"ºvÐCø£ŒÒP¹8´!½ž˜‹Ab.c"ì¹ÈaÏð;:é“Gæ&d~°ýPÛ‹Ô5 d,2ꉡxªl BŸ>iŒDoÏ;÷ÛØ9¨ÇsÙ¾ÌòÐÛÇÝ‹òœhÆ”D¤W`5í’B†éÉdZÅÓŽ¶Ù†´µ{ž ™¤Gä¤SË„–ø¾Åâ¹3ãôO_äýÿå·ýfœ5W+Óìg!§©þjOC¦®hczA y‡nØÖ„½ ÿ!PrÔ‡À<Ówn‘È —©áOF«£.0=Ï ïkX+XcTp•kʯs_Áæ‹_ã\/ô8*`­`—‘yÓ…­¶±˜/2OÌeMÈ˲l´™wÃýKÜøuhO^\íÒ&Ù3†¿ÄnŸÊ®¦n’L6Ü∡<Å•ìS…íÜ;dC?ñ&,:Åörókov˜Ì³ sÂíÛ7æÚQ|Åafñ+°N3ìñYì- ØÑ‹Ûá¿qAY6ðX ® …ÕCÄ:G¤k½˜¢Sl½­Mæó‚T’‰¥µyñ,hÝÂÛØÜhvoÜ€uQXvøÖ /â0ª›q*bÌ*ñ‹·*m¼IW‡¦Ä©q#Íò“µžÄ-ÄMzÓ°ê2épûcåd£-1ÄÌ‘×Á\¬œö]&tê  Þ ÐÍ«·Ý˶hjª&Ø…»ÛOðànÀ‚IØQïxJ;)LË€ŠÓÒ‰FáUSj¹Ð¯¸AØv\—Z/•QÁ£‚xEà¨`—g‡QÁîì ¸VÀ–#ï;İT ¶™I×…¤¸¾ÛÆo©#{™¾õ›=?yRØýsþ.ôÛƒ¥Èe5ŽaÖ”²EáåCÁJý§Ÿ„¢GÄi"å15(€ô…_bv¾AÄ^Ü^Ûa½‚ìÔ@Á¶÷öÞ-‡÷V¡£™ë9*–ìÅC€ËüÝ‘FžÂ¥¦ŽÚ¸ÆA cÄaÏOS”M²pL.ëNáB·\B!áá(­)ZTøð³Æq›-¼-õ6ÛïæGz{œé3ÂëÓÛ{.ßE½àÌóÁè×o†ã¯ð¬?©ÚžÂ¯gPR”¡™ó.F'i´ `Œh9V4¬,ÖEÀš“S³O]Ô÷•_óšíÝAoÔßã=/”¿¦ËTËÜõwÃï°NýuM¨ê–hJàt©dñ ÄQ cO¬¨$j¦‰ 2Ü\dÈžã5Ãùææk=¾>b»èêךý«W›Ûç9mÈôÀµ‚q‚"#‰˜çš°0…Í”TDöl~f§4 ‡ñ´¨o‡å ©ø¥ 1¿7’Cê  «2ˆ¸Ø±pHœðZç¦kqÙ~³~ëîF³5»Òl_bzàV" ϕ乳«ÍðúM„J!86ð4Ó‘ÒU¶P2æBcvù怯Ú)4 èhÍ:Ì=³TÄ6(q€óï(n±9ÌŽ2zi†ð±S®p‘Gy"ŽT1¤ „©ª~)h1^öbú¿nóIømÞÂSð÷x$Œ£1¾%àüÞ•ü¸Z BuT”H¦{wSáɳŠ¥J Ébä´,C}Ü]ëÆ¨-{“þpVš.b5ð‡Â qÖs5äÔìÓW¡Ê(ÕÆÆ6Ux›á079áï”ë·“ûÊÚ“q*9ÛmÅAÙ´¦[ÅÓT[·iNA ÍÆbŸ¡™eÞ™y¬#ƒ×xƒQY+¸qDtu§9¸Ú0*¸ÔÌqÀh]¸Üì¯oðáKnr’&ÂfƒpzÒö蚞Ÿ8` D±Ï-¾OŒ"R 0ô3Öˆc`Ä'h¦-<„ßôù <çÜSç1žãý–¬É´s~® WDz|wìñ¹ß ¸\ÅÖ”üGÊmX ;ĵ–R±dÓȸ¡ÊTJ*Mò6b¡rž_¸Ìå±ÚÚBè7¸agçÆ3Œ<°Ó°@Ûw^Ï™‡_¿5QÊõ…¨üRfžÌWÁÓÙ`É£Á ozã5M×•î ™¦z•¼4ÇţЉú…#“Éáp?FŽ B–NxþÓW…S¾¾¸=7³M'rí:òy7Xa•sß`aD—Ô]È…cähOU0¢­Ù¾hsۻƩnTDk¥Äô¤H‹H ð* tu†cÇ,Þ:Zb­€» xQ~ýÖM•Ül¶yCŒXÎ2Xä’S?}}´Å}ì¹+¨¹–Ãü \{þjÓÄ‹\õ·$¤«`•Bdï™þ:[¨XQ'—ùŸ®LˆÌg™láN/4Y)~Ý銛®9Q ܲէÀ&…\ãg‚S»ª¹„+ôöü)üb¥™¦FZ y7¡os®®rYæÂ›‡Í³Ï}µ¹½î¢,dŽÖ_ð-<_Æñ\¾ŠI“ÊPáË¿FQ2<ýþVÁÖ¹(Å–P «và€$ÛvŒ˜±kd130ËßAÌ¢Šp‡©zxJeŠL[Ù\»–k¥Þî 𠧯jf~ôG?ýÿìxE„»Å4µh2²+ô]e|7¼’íÚ•aÕ>Öúm5©Mÿ„ð‹ë“áÊ¡&¬âÎV„§P(âØ1=Ôì¥?ÁÁ–‡KÍ (ƒ6Ùúê—›^FjX4¬,7s,¹5fxk‹m/”OL!Êyv]—¨‰D.ìéM†Dòh.çÀžÇ÷’¡ÃJ‹¼JBpËKÜüÊçì‰ £ÒÊœÄL¼J¿Ä7¨5•Ái‡‚"•ìÙEMþ¶ H( s‚‘Ë5&l/.œåH¦S~&í€-ĵžoö¹4VÓçnH{ùxýÖa¾í*èd™Ûµ`™š±¦î€e„iQ {Ã6 ËÆ’@Xmü Ú]‚Ó´º®šÙ+íšžð)ÍÂÓ牦È•ÂìœÓ›â6 À%ì4Í©+€N&‡¨ð|!ˆbÒ|*’Ñ2>ëmÚ8KÉ‚I%ì?WX™)Ç:é†G}a'ó ,{wrv,ò´ù‹f“V´[Î\a$nøYÿÎÒ(eT°>bTÀk¤q®àú q¡ûˆ†íÛds]nF(‰ÑÖŠ€·Ì<;ïõÈgòc¿¿ä'Å^1VáIÛ!}¬¨³ÃÇCè㌔RðÙø,¶G+*ˆ©·¹=QÖ`V½–$h±ðM …°–0ý©Ð3‡Û†MÇ“r$ALêEŽ9¿·ŽÆ,ÜYø˜61Ì÷#({ûÍ[͈Z_}áÌíã>½8' "—ß,7^p§y§ßhÆ ¼êÀ޶RüÓº$޵£…’Vr¦ÂO¦xÔe¯¼¿{Û´]ƒúæÊðíwýø›¿ü—»§æ>u@ÎäLëM¾òö?Ì­@êp)ªÒ¤#™rRT¿áÕ]™'옉ԠCÛ¬g¦@!YMíh¤ï¦Ñ'v‰°«GrÅø|jUüy&¡0õÆc]Ýçƒ(4ò››·šíÍõæpqµésܸwñ\Þ°ÃöÕä¶Órè¹{âÇêÐÊ¡: , ¡îú‡pb7[¦Xh†,Y:pÍ[‹ä5K+!s˜ù´¬ ‡V‚ÁÑC~‘ZMd¹V£‹¨0çåa²œY‰Îósš~GÖtµUSÕÉEþx?7 Ýž[àŒV«-<9›¿'cn¦Õ³²9Øš4"Ëe6ä"g6©S™ª)Òs¿÷B˜K«™3's,ÕÂêí”·+´¨2I¾¸ˆ^M”0Ï´á*­ïÒ=æ.H™—l’Ò­iéÖœô Ð—Djî’ù(Oöþ‘7 ±¦rmž—‘œi¡ nð„ÛÍÆÞ6_šo†ÌqÇŒ &,dy®~r{³óØ(UEg\¹Gø=2›«ÿeANf(ìò r€ÃÅ qõ‡bÇr ·¤ijy[u[Ï(ÇÔ€PÆIÞY7¾¬ò%XÀÞ* ±2GÙ˜øÒ]ÁÌ"S"ÊÌø–C‡\±ÅM;û| 2ÍÀ+à¹õi–m<¯ÍV¡Å¨! 8¥‰«s¨©vúîþ+Žé´í @·= ËtAËcìLKWmMYÒª¥ý‘~K¶D›—=<‘—òÛFÀµå9š£á={Øôn°±·ºÂ+Ááj̶M™j5Æ(ȆÌÂî @ÍÈ·’jíä(¸V†M[£+ÓÀ—þ)‘\IéT¾™ œÚì“”´‹ÀÄcššzîÇØF|˜žn‹éÁµ½£æù£½ææÖZãäÎQÁp‘-.v|ç¾ÇËJF!xA°nã™—ä ·}Ól™e˜ÌrÊPJî¨ÁAæJÕ”â^Þš¶œÆ÷î‚nïno.•,UÎó €»'án3fûùjq¹ûk!nÓÙzÅÖ>ÇsGðAÓ礞§ô¼A7®ÍŽ‚I…'ÜŪ„#VT|_ߪB_é‰-¹6³º1%¹ôtÒ«eŸFH^VüjÆ•V$€»¶ã6ÐðâɸS ù@crÇÂòr=$j¥Ö%ñŠÜ÷RØnr|£d°[Ô²qvËd[ªE¤‘Ô†°âM ^œ’ n C¦Ršjí*ü¦U…7ó¿Â; L(*óaz9”@ñKÔ.ꛟ\ªý¤´½×F¬Z_àyíp¡¹1Zn^ØáßPÛÛiöy+q¸:ߌyÝ÷ÑcTÀˆ€·YÈÏB9ÀCÆhјÈCùXÏXˆÚÒb^„?¶;r8ê”ÁŒÊG«; @ÈÇì¾#‚0S.’ ¬àF]ü©¡ákÉ$=³DO¾r0à%ÂI³{´ßî²þÁ¢ip_~\­Å¸HÓ¢" KAÍ®Ï1¦ëÇ<í¯0ëHÓ†ˆr °«¸l¡8¶nx = à¦[ŒðdI˜õÖÀ«HD;L¥šv¢v#{™ô»  F>5ûž(€÷Öö66o6gê1uhhÒ¶µ(\ S޼´¿à…6Æ‚Šíä8ÿ:LªÕ[íiÏÝ&KÑcúÛ‰y7籊½!¨4³S~£Qå¨Ä4ÙÊzl†Q=âç ®²hø½áúÖ-¾„ÐoYø3jh˜'÷Ç(Äüð¦j¼K öÊ¡ùuÎJ N>@‹‰&ád6v z%5 œ¶Üp½¡6ãP§n'š{´w–³–ç¸;W¾ñGð„Æl‡öY™÷M;çöÔ­«ù{Óñ-<ëº7ï)^¿u ϲ˜žÒ…Á—ÿÍ“:ë¸+P¾îÏ4V–§+Û!"tä_†„§K2€ÔŨ<3¬¦PìDÏöˆ»m—ò½¢ù‚hzÇü‰P•9PN:]"½bëž(€÷‘­§y¸Ãn}¼H»Ü)Y8‹Ö±i”wÊ? ϰpçUûlmw„àG£ç]¿‡çÜ~à¹üH‚4Joì ^dÒá'L¦,¬Â«]Z«[}¥mXf>½Eß$A#‚ZI£RJü ®°äCÅÍÚ»›2ȺŽz.QÛtkû-íª¦Zr7Í\GIÎ,.ä›M‰pê¿÷D¼;žæµàþco Õ^©® O‡Þ<–˜ìé-V+•'ÊXà•_âžt{"UVAH«VUU™~¥QÚ~Æõ˜hLýkÝ㯺?&lmwpKwßÅJ7¸µÉˆ®Ûž's „ÌyŽýnȽÄ#ß´ñïÑϽQõ•à +Ü ÐÛ§•›²¢¢,¥çq0ª©üÑ-34•‘á­4WCx:€6 á)`Ò-x¸:)‡¯ý¹а»˜6Ò>6¤‰t¦¦x5Ï5_✠n1*w¬;R±L»–&(É,Ž fDp™¹ö;¾~ÈZ‹‚×ø>ý/ÐðŽÁ» \'XR)°Ä<ýhƒ¯1Kµ&-Á>«øó«|@…)…+ù·¹eÏbí­¯Q?àÒZòj-¿lá!aV·Ä\ɯ4mËVføÃ}gñKQ[˺¶Þƒ–ö ´:°“þ6¨¤Wû¤*,d­ôÈo¦F&‚ eÈL‰Wã·ip´e8o° ¤Ûà/é‡32¿ûƒ£¥‹¿@Ô|Ó¬a}k¶éo±P¼šƒÉGº+n°Î®àWw0O¦óJ­UįUXmïd•DÁ NÉ»ýÔ¸ÝÖSÇèmEC¸«*bM¯“ÍœN€`:šbW±J~Ð8HßhNAtyäØçÕì¬VšÙF¼ÊVáúÍëÍ.Ͼ‡q8i8ïw.²xÇ»öCNãy–/àø¢WP2¬ß —ß&Î!«ù&ï>«ù|¦š¹½×f[òàJ~)ƒ¹È"fÞnÜZðª;Ü0ž4¸Â#M º ~õÄ;¬“á%jKG½$Ž&’À'¬?)ðSEvãWEPÑ»öIÁ?顯m¢Ú¦c­OÒNwæ•QÚÎêâb¬ `Aéd®›ð+pß›@ÉÐëšõý/ÏÏî ¼Rš¢QZ ‘ÉÞ?"veÄe;&ôš«§6™(½Ê¨®»C© Îä#ò·x;¤U¡§- “ù¬éhúÓæõÎð.‹ Ù¦$ÓŽZ: Oa«ü VØ€æY|{!õ;¯G\ãÍﱃpaÞäSÖûñå‚ WñÙE˜gø>dØ¿ÃzÂ&=ýî7™#¦ qµ•ìíãÚlÓí»:̯YÊ|™]ó–vòFo@´Kù#Ð"Fr(ᵾѶ^iU»RD;éÉ›Re‰R£»%Ð hmð1Ô’X­‹âm¹–·Â[;5eë5oÁƒtxó[$ƒØ:ØÙ‰9×½~S½§  yßûFýŸýh|$”åè(¤‰Z^Kè½|U+Þ± ¢Ff‰\MÕÚÁÈ*ô Çm‚¡¬·­âµÌÔüˆ6u‡he¯UÒ¯Ù¨)ÔSj™ž1gµt‰ÏÄQø3ú+åBż•iÙ³fx—F»E ˱q[®XÁ/#1üzŒ]„u>œêmÇ/°K°vã:·ê\oÖ–›#Âö¹§àèÀÕXÊnCÏûôzI|±Çôƒa™ïΚw3@Ä(SºõV.U2UXEq*~–½Fjë)ƒÿįѫ©îc¶YAXØ'ü5À0Ý5®ÞjІגGs» f‘Û©‚ ¢•Ê ÛNA#±$ÞºÎ!sÿÁΟeâöçZàé;:Y8=â03ùêkŒgÏlåÙ +ÝY&V™ýR±Ýµ âŽ,¯¶.Í@F‰ß¥m™¨6ÒJA;2m¼H§¨ ¸¢Ÿ˜Ñd­ùÏFÓ5õáÉÕ“ВV%ž1ê±æJ£ÚDSS×ü!c–tá£~·ßÜßwçU&øe¤GX0ü}L~àâåæûÎ<ÔüžÁ¹æQ—Y8ô‚’ßÂóÕÜå3±0çâž Ša>¼0-~²'2'ò'S÷÷˜»ËŒ&Š®X7i½!5…Çš¨¬±v¬“AÆé&YQ+^×¼ ¨ˆa¶ù(”-o¦s·”È.઎‘ízj#ÇŽöXÛ¶CW>ÃwíØ‰vIœ¶ûž(N42¼Åntt 1D/«g²;O­M‹$Zžà&lYÓa ¡Rå/+® Ä1,™îñºŒMSº*šéeƒ®)Rè‰ã&&ç^¢Öƒèqû°vF‰x—Ÿ*B5•:j‘Š#ó‚§Ð0+Æqç!ïÄcÈuŒ¿qÈ[\•S‹ó|7ð¼7q›ñfïRó™këÍ'ÆÍ¦ß»G‰ zØÒH¯90~H¯$qDü@0ܸz°u§35®yM`ÇÁŒãA¢™_í—ŠbxBâ©€ð;ã%¤Â[Þƒ)¬¶7ãj¢.¨ìOè]~Kã6rU@¤ÚÍ >>áȹJæÿð¿¶E¹ õ— ª"õ² |ˆ–µéïîs'€£í°Ï[e‹”çÙs‘¾•®F¨ñl@ÐÊʘVÉtõz¥qÕFx,étŸcݪèHÏ*¨Õ@½„"°";h'mOàÏx™ÿ“4ŽûKÂ5mㆻl)¶pøB¹2,m˯à{}V}íÆ)ÂÇŽ_Å}–æ¸õ˜ŽÌMTQÉ^ãÊç*xKžÓ®þÖnó‘qïRäÂ?[ÜiýU%Þ -}|5š0ÝÚÇÌB r#~¥3Û…TwÚ¶´ ™â§«4³cà»Áj›:´÷hNx¬«Z_•ˆ ¸ÏÎ÷CÔ€»•ª¢¿"ûžÈUdºwf…{-vÑ  {ÔD–)zQ‹P”€V&N¬ !]wå.v(Gý…ƒm˜ôº&‰N!ú_ÂDÖ",ª WÉ;ÙŠ8”tkó5ž¦ÆÒ´J€ó~WzÛÅ?0R‹8µœ .!Õ‘š@E® §Cõ¢W žŸPÇ¥·ÁWX|ãÑËxW€ßLÌâ˜ÿÐ-å W¤´"=â‹_M8%éÖ”_ñ'qƒ+zM%Úx­#ÀW!müê8Õ_í‚k áa ÄÅO–³›B Nò·æ1Õ‘Œ\Vá=Æ61iSê×QomÏ1¾ .(ÔïÊ¡‹JäômÛÂ=1ï/<¦,ë,MÓðmŽÒÚÛÀ=Áòóx<~ᕹ ¸½|ôôrÞ€ZÒèºõS{aÓ©t#ÝŠTìN;!¦•é…‹Däh/ÍC«+åmÕÏHs¢Ê§Ô¤_ ¹Ì ­š"È"âð¿’E †´©S"7•‚v…ñ1hìš¿eq„^ms›%³d­o˜”nÁXÖÀÕ®M‡¯xMoúNm€ø?òÆq ÖqŠ@Éqçjuk/1qe9!w3ø):v|†Ïùʈ%]yÄ´Ž’¤Žt•бëø&ÎM…éMÀþUÏÔýá8³?…ÓWõèü­ÏÕ‡3nò} òu¾Ü‚»ÅÅ׿^•ŸùêÓ }:M_W{מ¢;Ö:ðm½’k½LÏ¥·=ª¥Ë•îdÓékrrÑ®¶c 0ÜáÊ—\ç¶ú’b—1’.˜……ub§&Þq˜$]Ҫ𾀊ñÂWžҘv>º;ÐiÅouuƒs阆K@;s4ÂRóíËXñ‰—©‹?ëÀ„NÇ×2l9(¡ðñg™NPd‘ƒÙPGÙNb‡ D9SÏ?ŒŠ‡«Ò\YùÖnh“•dLEmM^v¾Ö +ÝêͲ³“×~ê·ù!à—ö€üÑ™»{à—~Éí}ôƃ÷ôµþ"f7yLMuˆVú´W£Ç aV§ÚÈŸ¦tu€«á^ ݾå_l25ðgŸÐ 6ÆÝÆl Q°fŠÖÙ"ê1LðÙªjep‘£ís·C>Ë4mÊË—ø²SU*_Ù˹uñán+ç†Ë YX·¯ÃÚ¿áå?üÊ3´SŸT_ ¢†$}ˆ>}‰ÕÆCÛºÿ¬(m§³ºs"·AW¿Ãwût ‘Ú.{~¤bL¦ÿédr,~jkñÖÕ¡J·Gø‘=&rîM7ã‹Zcä9Øce,'¢vbz Poé/hil_ûÊÏÔw¹ñ}Ge7mn?Ê‹ï|ÿ™æ×%_o>V2ÙÝ ¨'˜±ôˆw¿{§z¨7P!™Ø0ÕŒ4n‰²è7Ñ«Ï+ÚFAÈŠS®´H* O€t*“QßãÖzñ:g3j:Sg2¬rKà]?qdy`énVžkô”+kÒÏ"N‹n†+ùmÖ}Ôaz¡¤&Oñ cׯ°É6Áç8ZQK¹(#!tå;±'ºö-b7Çh'Y©êÓPl JÅ­öeCçc cÕcžaf잺¼¼üð;ïøswõ·iÝ@t;%m>ý…ßñüúÁùÅÙGjeÍÀM€9Ù‡…pÕ#^ÔêÕ‰)ÓúºïÆP‡ 7ØÆóÖ¢j…©ð) ÈZÏ E@Áï„Ô·²ÀC¼V@a·ñ–DâS <"^Û{ 4ü˜¹2!äžO&‡akãò?›>À¦S‹þXœ¡[cwf|"nÖ"=¤ÌŠ)ñÛ>K±ÛèZè¾Zi{–XÛ͈y,äº[²;«fgXÕ}|Õ—æNÞ6ÞÚl$ßuÙé7/>:ýÉ}À­ ÍyñöÛõÝògü 1øÝöÙÕðnþX´y+iÕÖâǵ݋¶—í ²É:|F¸±-Ï™H¡H3Ñ ¡s_e·–­Åo+Ö6­Xä#¾ åfr¼Z—o=MÌ…£/¥\Ϋåx« ýªp•À}ê}Ñkˬ;SÙqÇp)]ß‹0òøä’H»#_<}*v¬Rìü1ôléd/º™tµ Øñø\ñ1ôVss?qcYâÒW䕹T+B–ƒˆÑ’‘€ú+š½ñ»ÆwYK7Æü=­7™öìþ™ÇŸé«¥ïñ£º½®ž]l–fwŒ©² ª{êN`éa[ÈeÏÊAe¿¡~’íð ±–bFl»ÜSO%÷ÐŒ›ä¨ìT#ÖÖ60d‹í|9„° 6ÁoBÛ#)½tà„}/õäÑ&‹¥X÷L¼10õbÕ&`G{F¯x‹ZüÖ¢Ïhâb†‰Ã)Y [‹ºª½w/ó)0|”?ú36\,ÏuÑü£üßéWÉbLñ¤tËÔ½tú¹7Ÿžñ[SGz ÔKúó@Å•>ã@ÂÝsà›.zßî/uLÖB5)I”žÑ‚ò»â}× ü7/‹þÂïÔάï?¢C`X-dÉ2C,]ŠõÂ'pç™ ²ªâ¯‚ísËË 9ĺP§Ôý’˜d“‰Þ O:ýà3z㥮»&uœ„?P¢˜¥R› fƒˆ|jp¹Ö¦—qcÈûâ±Å–¿ -ïò-8}ø©.ž±Ø&¼uð#ÕöóáGrvÄØ­;}xþïå«tCª]îLI¼é¥#};EèÛ¼|É[k÷ré³×dÁŽ‹‹Pû¢êÏ\ùV™aVŠx.ñ©S'dvãÊžt:Z„Lƒ €ß€Ã„–¼i±]àqgÝʹlõ§K°Þ€/ÛŠå³ôµê DcAHìv[1ŸªT 'V®‡U4‡ÐÊTÒS²ÖWÕŸhqծЍ€Õf€S_î§³5èOS˜‹LÕL×lÒ+*†Ïú;§¯Ž_úaBÆé'Ò;ÝôYÀJþÉ“çgü¤•kŽÖÞÍcay#Èjhy0/p¹õçK<¦Ý4`ûº£Ò“({솟ö[™Í\FNÒ{“Gç⻀Ž©º&¾z£XÔƒ­VVÕ¼g‚ê²s=9‹%¹fóºÞFÝçŽ^ÇÆEÆVJ?'°T¥€‡‹;“Z5·0¶;ÅK«mÁ ø”ÈÍùÅ4þ7I7(²Õ÷ÊŒKX.ë<[3 fÛ÷rJ°$Úò˜´Ø _*O§èؤ71cëCYúÉG}yîý÷Ÿ´‹XuõvI¦Ìízmoú—ÓGŸðC’Û)×Ê&Ùý 6õVÝø ;MàP±ûžq]'ÛBo¬ ZWÄÅ!bOÒLø]Á·ïԜܲs³3SU‹PnÝᢾ2ãžPna6l]ÅqÑÀ—LeS}鈒TáfëÄIPÍÍÏÕ¯pKÄOY†Ή˜ãÓÙÛx[·O‹9 *Œq>•¬,­ÑÂ=¾h¹ÝcfŸ´“…¬‰-b±Þ÷¥v¨ó듃òí%FáüËÏWã3»n}ÿ¨µ—N—Õ¹ì¼ö+ýM·Ó[!M%t‡ÒYÒ¡Æ2¬x;k1¦Ô7€ÍꌸòºwF,î,‹ËñÛHüðcû:ªûkçG¡%Uh>»0^Ë˽åJÞWø‘ã`úÊ]ñ6wˆ’Þd ôÃQòB^-Ÿ§ér­•`tE…Îý,yh|FŸú†z3¡ÃØüT•øþÄ [÷`[#c§®— Ã1XŒK*¡ÃCg¡÷æ2nKÓOÓ .-()mê|Pi\Æ+{ƨ 1 ª XOËÏ}Õ×*ÑFÝ>YR¸}çñxúðÁ»Þj e[ Z”žpÒ-­h’…Jç"òD—ùè`›Ê*‚¶“X…kß¶pà;áÌ|”eÜÉшjÎÖ!â>PTD¾Þ\wd=Ú¿¸;‹’ÐÛ&+»ÑÑÄšLž¼ à¿¿2 éöÔÔñý¶¹å-jâ ‰”úKK€IÒ`Y}‚!ê #yèÇÏmq¸Dá2çF `Š®›R¬f™p-ÊõˆAö59lyÎ+ñ3ï¿w¦ï»ãîîË@ÝëW^yvÁe¬Weµ›3S±§ãرP“V=¸ÔóƙèYë6ÛÎä¶#FÅ«Ûþ%€|ø÷ý°Ó|׆ ?¸ Lêá-J‡+ÉêU¾âÒ’.Z™U¼Â Cà\°£4Ý* 3«¾ªHe±cÆÏt…×µ,‹m&.òнMgPâ +IJÖŬ®q­Gà2c”aä¢ò㾎L«Ég.~„í‚ËÕ­ª…`O3òò‹«U»ßRñòÐîi] ¡±Vªõ‘xãÔ¥Ç{¢üt¸ lPv4Ny @’ØpCf¯.ÔŽRñåIÖn ‘Í1€KÆédã¶™Õh¡9ÐîùiAKgEÞýwL㈿CKG;"ö¦€YÊxÈãq÷¯¿òÊ ø.¿ LøýšKJ·EÝÌóŸÿÙ'õGAtÇžÙÅÕgPün=éÊÞ½Ô˜:ôà®@®re¿¶Ió gú‡?®´Ë¨ÀêðK‹El}Ê3ƒ¼gž^ËŸ-+ï«ÅžoÇŽ¥S¥±­Ï%J5_û7tqãê¡(Êw× Ò;äF¦¨ö¤?°[«Ät§¦ÚO ÄkÜllNl Åx_†¦ÏÄ[jS$D¶¦œsëÆ¿bV~ ¦¦ŸfÕ†<ºÊf,ìp³Èã¯|H×Ó”ÏükLN/5±^ûò—ó7nn»’rÛ~7þ®¿ð…ÇꀋÍ]¾*W°úÉÜ þ R³¼Êž ,øuÑS[ë} •[ËÕXøµHÄ Ä·Ø›KØ‹¾wªuúñ—ì{&:‹r–90ëÌ)}&ÐDcÛNǬ’ˆg©+Ù¡|®ù[2^¨NÏpñiY§¶P)¼¿›ÆpF]“Ý©I×"‚ÀP×ájóˆ)Ð ‹ÔªqÊ|Øö™æÉqøòáP ¾¶þí }XZpñU.|MÆETÜÕk?õ%à.¿ L¼;}Àà¸|ûÛÏ/¯¯/žž<ð[ j¡¯¸n3¯¯¹:oË:9=ʨã0´M2È[³V¾1êNF¡~”ãoé»(±}®Ès7P œgLžÐûGBX”rUoÍ <Š­(!×™ºä6´œªI¦¹øÐÕ=ªô×ÚŽÚ<§I²ˆMêиl`–U1¿À2´†»I1\|!ß­…°>äí§äÑBg”º×) 7—ÀÚvK´øè§NdiÎöÒÚK6b¦ê´}vzzqqyò“À- }uýÖ[OO=x~¾~²yiø¸"/»NÎ13z`F}Á²ÓŒKÆ&sd1Šj5[š3ßë6}º=„J’ÉSÊJ¸dâÙ¨à#m1ð†„’T°¡{óøˆü¯;è 3™—žÉ—ëÎâ>Mwɶ¬¤ØTšZ80:ª^tå1Üw_› Ÿ¹ ÚY8,àø.ýf­7b1H—3}PG-~tÑ;Îp5˜r¸ø+ç¤_WêÊ”ñ!.ñÅf{ÆZsìÃËïÿÿ90ÕË¡äwQöãq»1<#NN¾òs?÷ôôá£'§/´{t˜OhÉ9Átôž¾4Ûu°t§Ñ£êA‰¯OL¥“”»Oê¬ 6.=ØmZª&WFOnÅŸ)äú»Ê–Æu?.‹ÒÑt"˜œ®MÏ[•« Ú³Ntl1Ϧ ’*ݤTMK67`B…ƒ}ÝòÎù-€ô[l·49Æ õªÕ+|ÖøLºµXk;Ÿ µBÜ{S€oß2y/9ZÎÀ*!ýLû³Ÿyûíß:ïœ|ý럾öêã3½Pö/§ÜŸ»Nµî˜,FŸDééô6/-êm<Óîñ£ãvà¶sè+ÿpÉBŠû¶É@n¶ìÑù£Êž½šdÔ¥Z[˜Ý•Ít$mÛÈÀm±´GPM·À­Ý¢KXÍ¥¼ó¥êb2”µ?jìÓF­;Š‘‘[´3Î>h´µ}˜ÙEÊËœÒÍs›/c:‘“‹Í”¬Ü.ÉVÅ¿ Ÿ¥<äÍc]‡×åñá£Çè÷ý¾pU­l§w@vSùv#ÐF<ò•` ÈÓós-ÃñbZ k}ÚÞÊ~ð$çåÎWþ}/îëE€ªÎä Út5rôdé¤2qBh3!ÛÆÞ¶×D>tÚEàÊ·¯tmLW˜ÈHP¹*oGtÉÑ!ïUgV#žWà6Þ÷íK¬ýÉðˆß`ÇìýïëÕ‰ùƒ`| þ™æ_šŠâÖK¦Ê­;^Vw½úúÿM€µ÷Ü4N/»é”z³`TYºäl(Ø<³é £Jb‹+cK"©l­“+7 ]gXBká×R´¶å@IDATÕs<ÞÀf㘊¼´±O9buO7‰)>Ø„†ß€Pd ¥…ב8à·‰ )”Ð?(>¹t¤ZPÝÏM†q0nrØòBFnl*m<š³:J»;ûlá›ÝL‰Ðr“å¢IB#ö`ЖÝûw]m}… »i_üXëk¯çõZ¿uz‹µ;߯W‚OOŸœkæÓvç?š³ûÖIç,—T‡-ó7òz½_ÖÈrpAîÎm×1G Ï#¸YúZ˜K£Ü'HD+Y»f`ÃÏðúù¦²’¯Cí Nñ#_¥áIÉMUVmPYJ±ÅÚ0¶z hmAÊ ÝDQb—`‰‡aÝãÒ(· åL«‹aÎÊ|ôS|5M•„f(¸8bùÏúvl…¶iu·µ0¾nG=bn}­µÛµºMª’1Õ¼yŸýÖÙÆW‚Ÿ¼÷ÞÉ[¯êGBû’Ó0 ðští™tcd² jȸ„mìykq}{qýô_Ìéûâ×;$Òh‹öØL,ñÛ‰Rõõ½c`ãªêxÊËLqîü®§´Ä«E AÏÚ\5 ˆÈ¤JM­…"ú®s|„Yë…)|ÎûS1K ïzº“\,ØjoÕ± RØÍb; åÀ9ËÎþlÏi=0L½œ°°,ííÛU¨œ {$ÛDø'QÝ6£¿WtÝ.½ Ÿzá•tÞ>Ÿýÿö=O5æççï\=â+ÁÛÞ› ð´ e>TH³ 5pzˆ=W||Þ¶n匉«‰’«YÑ’FÇó‹íÄáê¼È’JÞ9Ø´§¢æÊ?±ÏU~˜$¨|‚ê°UenD²aU>§‘;åL61·uçH,)1 dx³,ŠQÓ<$GŒ¬êÊà3ãµëEBR3çµ%t륶sÙºãxYÜJÝâÆ,ò=v__ GÙr»U­>Ä;?ÖÆÃ'W/>º—¯“P¦ì6¹;¨¾ñÚ{þ@ýLørA\.ŽôÒÚSáEeà×úÅ:4ÉòQß²©×üÒk”³ð×;€X„®c±¹¼4 ™,Éî4pJò6¾Ü1,÷¢oQöÁƒ‰¸5Q$Èn‘¨Ѽ{Ï ð“.ZìqçØ>±¹´Óî»5ǵ_‡Ú*¶MÑùA¨(¢¨í2pC7˜)C´ˆ'ßB· ´x5ˆŒK%¯þI+¦™¯EÊ´a¡³hgAºÖgÍ^¸Gtïfqá¤ÜOÇ W耸â#Zd ;=qåiáu¢ú‚;±ƒËUI‹Qp:'iÈâ§[Ö*üWŒÚ&ä«%޾‚qšÑ.“lÜ­ÌhpSá]_¨]pêcÞI¶2Iv[ßÔÞŽõ%pÔFöNáÀ¥DZ\me³·J^ÈéRWKmú=*œê£\lèXñT5~…òèѹŸÜõWÉ+Sþ®Š›úè‹_Y¾¬žôlg½ÔTãi>k‡;‚mRUŸw yÚ–ø@Þ½ÚW»qÕ¯7´o¯\êÍFrü ­SéØä@]o²çÚíg7DŸKMW×Ä“ ØÄ]9Ü$òºæFªZ;q ? ¶?uðð ã5$C‡í¡Ô_8C ï;uˆûUÔeB&e;êÍ,u…Úé"ljB["_á’!Ž®š[çV¼‘C\9F¶Ï8ýŒ>%˜Ô›6䦨• °3Tñ˜c$ùõµ.‰gõæÿåõ™ïôMÀ;/YEwèäg¾òôäìüâDßðÑD]ïXþµ¹¨Í€ !ð&X¯õK‹³ñÚß=ìµgøêµßò=!2}É¡vX21¤M*Iî;º]¶íF¿÷ÔÛ¾ÄY¬¬ámÌmÍ Ô¢UîY4È_§ï€Fj´cQ´ÚPçÒÝ}‰.y™Ç[v±#†â3þ­e•㓃mh:ªaÇÄ·øˆn-ìzQè& õ@äÓ¼$;yW·ÖÓft ¸õ‚‘íňjª\}îí·ò6 5ÀîªÜýÐß|ô9¿ùãL¦1«ºe¬‘yû¿]1Ñt«C¶oDÝU7‚áÛŸ´*»ó:%J5‡Ò.fu±¼ilêÊ¿IjYx‹±ø8tNÌzíŒDG¯GÚ=@ç ž­åtV]³mƒqÄÆ¨feY—`HýìÂ5a¥³º1 txhè `yÅ Š”•8ÃîhcíµŸœÕy+Ÿód• x\xÄÌh˽áè"yýúë¿…žô½Ù³_ÿ;O57Ÿž÷Bä2·),ã,åPlOÁH¦=^Ø"¸M¥RCŒ`c¢ÌKaæÄb»giKÚÃ0Ê7wÇR ìͨlbûq™-ˆ-ÆIŒCC+‡d2RZ<Û¬ëÕîíÆ€Ma¤Õ™FÍ@G“á::Lºú07âZ™¡Øîí°ÖÆÖ•OA*~²€ÎL§(½5uv½«V¸ø:üˆÊC6ävøþ+ý£ Ío·"Ê»g/sòÛß~ûùé+žžì[ý# ;¼²gT’è§ë…¯Éšç äYr¢¾µž£7wö ¥ë M&4ÑUª ÆÛp Ó¤PP$±šî¦ÕªÊëùñÔSx³Ú)ŠÑBuE§Ež=Õð%~k*ÙQšˆ–/×#”4,–kYëåuúŠÛ؇Ÿ`©S" ] ™˜ð´þ°$òªçnÂyk5ÑøĈ%fðÃCmšÁÆz_GnY+4-<\º@>~ÿwü·Žå·E·kâ¶¼óï¿ñº~%Xï×3{Ùª³]›&•CZë9›Ç¶+«^²è•ßðÇR²lëN¢êvïÌ7¡80Ü û ïdª.›Ê 2Ô¼šÉû¤æ•?]ãC(%XªuÔæ×Ã:5lóŽSù”=¾ô|bmnë%ŽBíÀJûЏ$7Ÿc¶â‘­Öè_zÈÀm' ýA‘/¶xN]b"=jf,‡£ÏÀT™¶³/#›´ûܶåëèKLe}E™YaãÂØ?|þÕŸú©;ÿUà„ÌjKýÖi&~%øÏ=ö¯W?éÜúÒèµrÖ«<ðõ¹Áþa GØr¼[{%œã^õ6b‚91F¨!Ÿ‚ÔŠì I`×ã ‚ ›Ä‘~Iºë\æ•Ù«»}Lv°­Ð gÝ)‡¡Z‡xpˆ(ˆRZªipy(ò‘½ŒŽfu Ûš×IÿgœØYxgñë¹Z·.ÜÉGw˜²éd+™ÑWü^꜠_¹8êgÁžêWïå«Àäµ›Žkª·Ç«{ÜîÓ>Ö¯룎^]ò?FðH¬Ž4¥Zo æmÀ`Ö·ÿØ0b =ÜjHjGÕM"lQ´K‘ ’’:mݣײ8Û‰¬‹møJ’‚·é%n»nÀ°SÜzó*iú?]|u_‚ŽŒ`ˆ+³MwÛ_“``ÁY[5xt7•u7*f¬Qðãî, Ñ!“žTš¦ŽÌ¥Œº9 žŒ>*²ÂÃ…_ý8аž–Á”uõcòAwÀ˽ÞäôXãuh¹»ƒó:íîÀýpé~8}ý¡¾è9W [&å@†Yg»e‡K—å\O÷q?õãí¿t_¨P‡ ^”ŽÓõ,¤®ºâ©¶Èè:•t4Ç® 2S@HRœiªÂ¤*oþœEQhr ŠÈžËLRy0Õõ&`x쯣´ïddê8¡ÊV/,üvà¡2•ðÿ_M- ÆŠÓl/»MȨ,´=)W†lã[º` ®s˨þ7W–ÈJ^ˆ €ŸH‘Sª^|l«› uõÀšZ®?˜svywF3vÐ[­®‡[u_Îþ…ƒ ýBÐ& 3:¿ÐqÇkvo‚+>õ--u^6ÎAÛiweÏÿ®¤v|¡vyq¹¤,ÃÑjÙM³ˆ°Y³ÆúKA´±-º I¯l+@ÂØ8&°”ÈXÔ–Vî†s¢­³Þ±s}n&“܆¤¼º ÛþF}Q#[«á1¡PÏ‘ú è(›Ê#c,§I}‘Å1cʸ¬ªY‹´ç@’1¶ËQhd”²1kTy®äuN»µåªõ¹>ãÂñ ~ädkpKµƒá¿%¿7ÿh÷öé‹‹ï¼®§¾B²XÔ‘ýûé÷ñß+i¿d÷õ ›yåïwä”Í«é̶žj'¯A"qI¼xª¹Â š¥ñ-k–¯"ºÐ‰†÷UÜÁfpþ£’¸ ¥íêâŒL[g¥ø`…²fÄVÀƒÑÖÔú¸-®Á’§è"*3}Š>ñÊëf§"Jºà°-›PÀæÁ aû@Ö¶âÌ»Zn"›yí.0uþ±‡V)ÎÕdz^b1Ñå•íâxAžùQÞ&o¼½£5‘ÝäfÝw0%nÁç‹o´äìùûß¹xã i4Ž—;›Ê¦‡3cS·OH7ØAkácÅFkæ|øNÍ„A{úÈЂ­²’?ÏËøFÏbË«§C8â»°Óìvðž|Ó¬F5—+¼&¦`9P °‹½¦­üÅ„ÂL?…I=9§]Ð`"£žb[)tºìýGn N·³ýDo8qŽm =V¬ëà<§«½J³Õc=5Å![KÚ‘‚Šœvð÷À®//»¯ÅåêäøcëàÖÃ|³=^|þ'üFà©^ðòV OÊó{t„;C=d^'®ã[½÷É‘Ÿñ£†ƒîÖ¦¹#ȼ7 fµÛðÄgÿ/ê„6˜ýèì2w8[9 ”2Ó(Á@&Ùuµ‹Ø¶ö“,éG+tN àÈLÌl&CMe{“½>È›˜ö`5.R‡†·<•ÕÑ"{iøç~U="×eœþ¶û¡¬`¥«¾ÛÆ™ÀÒÎ:–UãÜ}iZò»ª»¦SY"«BÝ_Ö…C9ûû‘ß½— àÝg¿ôÅç´Ëé~<>xvssÕóÌSz› Çõ¹áå]Ä3®ü)veY$Çh2cî‹§:EÃ`z¢ t ]7æ*7h{§EGluœ­¶ ;°#±î6Õ–^Ó[ù »J¾•"ÇÛ¹@vÅîݧ5ß‚È7?ŸÃ_üC•Xô«súˆœ ZçµÅuåG]Y—$òÐxv¢f”µ‡‚/ïBkzèWßxÍšÚ»å¥þàã×øsÒQÇßíÑLÍÛóøO?ÿøñû×0 nÒl…C>G´8­:)Ó›…šl:}ÀymîäØ×P™©aXfUÖ‚2ã&š½&è®Çë;3¥áÚ á®¦¦Çò>Ô8 }¤êЕÅóšµµ›…dÝuÚ>$-N=ô&yôÐ5oøƨ²ê÷xcÚf´U6±ãDÔ¸¦±'H 샀EoÙÆû‚ÏlÁC¼8¢êeSRbÀ•Nœgž^5¾÷þ‹úM€X;ÜžvÓñ#áú߸<ÓÛ§Óðjbu J:e]wŽa%/¬—²±~™Ý~ðÀÝoóã?74uYôã£Ä8S©Læ„èTJyôÜÃvC(/þu3°nUÇDì‡|ø¡Q²9ær/«¦Ì|í~wZ_ ÓÂÎxCI¥ŽrQHì§~Õì©߇šC Xü®eÝsVØàѹ¾w£…Á`õÈÅÊÎ#6Ñ…îäT³ìéͤP²ê¿š×™·8:ìWìNOÏŸ|ûÛ/@ÜWÙÏ¡;‰«Æ¹Ûô óòäµ×žž]\2£Ç\L¬º°:V£Ö^ŸÉ›úšzYãw}Ô7‘Ë*¬]ÃÆùàÐÖS«|º%Í’é¶t„þ Péª=æ K/á‘צ5³CÆ’ÆúmÁݬ]Ý«“·Êv|›£ú¾»÷6¼šæÊb%'îÉÝŸRíÒ(»ö¡oJäÇh¢¢Û—诶ÁYÆi6?tØRö‘Êœf 8¹; »À©Tu‘[À©4¡Ùr%púðìÙð×ÿºÇýýTÏý5“¹w}õè‘þ&@ºAÅfÔ¢›»)’Y+n? Ó ^vÓ¥{@Ëû‹~›Ë—Éݾ'œ×åÆ)ÊSíÝ=›š-e¹‰pçóN$Ùˆr{ɪ=¿8µA…ñ»Á›úŽý“¢©ˆzb§o ”…±a>%gaÄ’>Tå‘XüÁ¢ã8V¢[L ‹sÝ@;b‘Nc˜Ä×ü)»H@|ºÝ;¿©šÚÙ‘¼ê¸´+ØpPÀ…_êívêŽ5ЦsVñy×s9¼:×Ï‚ÏËÃ>¢Üz¹· @™»oNŸ?röúChLéì†ÕºZàëÐTO¬“|1ƱÕõ…­ÉíwÆ(Éž…éD–UØYøj:f™”'hq]~3Å-7~‚žvž´IxLxÓñV )C1 óȳ`ΛT½ ±˜¯ × ýÙ»Ëti'ÝÒ8®{3µ{ié:ø=~6³s¿UË8þ6ŠÈ‰!à8™6¹c´ÂmDßqp‘áIJálh¶Ìª_ùÕá"7»Ôk`+UœV ã8ÕŽ¯!^p ßfukµ\_nÍáMŽò•à“×^yîÁÊmr&ö0¬—Ž©aÊ9 <Ø‹žˆªÖ‹Z̓CWóÿYµ(ºŸCíq=eá.ÞåÐV¢˜y“_\ k+Ú¿„ƒ#¡Mé @ÊŒLoPµÚ çõbõX(:ñ«ûò·‘¬Žóé#ü¶ï5Äq£OÊÁ149†ÆSð½ÇYœ–X§S(Ê_x„±±ƒdÁKN`7Æ ö&¹ ˜%L,jötÇw•·÷°ÀofšÝºã½Ã|%øüüüû'úî`<È«ÛX‹ú4Û¿^éÛôoQp…enF‡¤©CñSW†hºéži…D2>‚+¾ÊÌ üÈ—O>Ñõj“µË©,ÿÈ®.Ýæì²¸" 9¼è|YÑ `b#êHk^  –†âžǪ̀¯B+¥Q·å­[Ú•vÇæ&jW3Dªöê‘“al£¤>ºc¯·‘Ó©TGÔâòÛ6É¿‰:@«ESHD«þÀÖ–Ã'™ÙNä3øŸ}yz~¿ €T{ÀÞmùF»¿øà£pùêuF-éeé°Ú%™(CÕ`uu_Õj•;zÓ:]ÁÓû=BN¡gPÖù¬ëjò˜A£M Õ]kÖÍ)¾Ã-6üômìê^ú`ô­Ñ*+Fªö¢Ý)ë힨»â˜²Ëbk ~f“¨—Æ!†©ÿ¯mܽÃ>‘K€ÙZÖúÊãc­c“ºi‚£ÿà9(¤6ømä¾ ìjìR -À°‡ óˆoWðÄÕs™ëËëïàãk³ÉTï´d*Ýiœ3ô9€K}!茫ˆ:ÄsQ<´Žêž9GÓ]59o¹¥.\%Ç;Ó‰¼ÇO‚k´¾^ÞÀ¤:¥ððå†z|ˆ"äeŒh» E9T ê#e[ùI\NÎòŦü·¿Æövrµ>'Žnº¬4®z¦Ûëð¶Ó9Ër¥¬ K-%½UPås-ìÀ¦ {:­røý.˜•â7õÉ,2 UÖüJR˜Èã#Ô6 D–ücšø`ðûÕ¯uèƒm°¦ØÅ¥ U ¡÷výI ïZx§{Û¾Qm=yðöO?{¡KíT#1ÌéúCŸáŽÂ Œ¸>mkîW+¹úµ®Öb”Lõ,LC T—à¢RŽ<:RåBí¶uã×€-{ÙÉÑÚ¬ùTáy(§¼—ÉÁ»#·Gõ$¯·Q¸ ˜¹Þ × J蘌IoMÀhå€×ªvÔX«ñÑÌN¼‰ dK½Í7®ñµêS‡†ÇnÅP§ _K0{ùЉî˜ï؃_qÔWÝZš!Cï'©‹JTo=|˜g‹önÙOœC·þú«¿íé =Ð×ܹ"^¦cXq*óO|W=Ý_[×¶Ý:éæõI5³×;æ5Q¾u¸¥õRø¥@á×X§ØP±+°ónð†‹‹ ‹]µÆÏ Ò˜XJŸödg~¤Ó_öaxûŠ)9âÍ}B_ ÚDG_,Ð|V`¦)¸\K\D–úê/º•fØW|äÐÕ—WKƒƒéªI°« þ&ùw¯m×vÄ×M²Ä3.àøQ=vÙ€5ú*°¦£þf&¶ñÓ§ üG*÷¹TWüÔ›ï½ðšåûZz¬€\áÖ¦(³ÌÑ¢=q5Ò§†L¯ÝåÊAÅ¥ÌE†+íÈŒ^Wåb ›m­J)…w †ÔᶔѯÝt¤›‰qôŒomÜäÀ¸¡–¿ ³‚#̦ÄCÒŠ¤’|*§Õ¬ÜÄN—jh Ôs ñ[ŽÌe1¤Ÿcº‰l¨Àú«Àó‚.Ú qWçý<¿«8cßøÙ·Ÿ]Ÿ½`ñÐÊjélo‚×£ÄPJ&ýJc5iqx.³,žvÒC苽|Æ7þ±ô"iaâ £¤£Vyñí[ê«Þ†ûÓþŠl|lŸ`VÒ^lýíÂ5o»ÇG´ Oîyvš&t@|õ¬fð6]˜r!ëÕÏÎhØìäkµü¬’â7¶ñÅ`I#™y»¥Žz´æ;Í`»÷Ì*nOƒ=J•ÐMøSýŒ‹>x~Ôî…Ǧ̈́SÃiûÉ»''O®ÏÏžùãÀþë4Ý)Ý9ûàY¬«|;ßk˜q¾xutÝ›_/ð‡ïíbÒ`Ê¡²ä»óXðbÜ™-òžÎ3€e6¹H^mhR¦}\탅.Ÿvnp!«)/öé—ŽO.8˜I†M´ZhÝ‹«à¦å'sŸÆÆ™Ø4ÕAÆ©Z9¤›;ÉbýŠYù³]åÓâbü˜[­@ÎQ9~ðà‹_¼×¯“Æ2ý¨Þ}ù5~%øáƒ÷êöy®· h:‹L<¹Õ;¡Ç³›éÐPº7÷Ó6xi´Èk—¬U½|àÓ‚A’@Þ&ŒŸýú¥Îƒ9z4:Ëb`ÚqD*V”‰*yœˆµ”D)õIªPßþ Ojm5`[ö‰—E´½ª+ b|”¼ú"5Ǥ²º¬˜%Ù96/ÿL·÷½ÇRçHœ=žúÞæf/‹ßÕþe1‚[íü|JF‘%éùÕé㮯½|’ï}~?JýÞ7€Z¿̯Ÿð;hY tN§¤“ö ˤEÛ=&õm'fš'(,†X¨fõŠ™º±â$ZÖ¦øOo®Ê6Ÿ¹.Á¤›W„ÈCŸ1îDsµ§šƒ0VcÞ¦°åMAQØôtE§Ã×öZ›Ó´dŽuGÌÄdì´úd¿”ä‘zIç9ñoÒOääbƒdµƒ?V_åé+hÍ­òyÕJwzvúäï}üñ½ý*pbßÛ >pñÀóúןž~ì•â5Çg[ÒyéØ=%i:/õ¬øµÄÙÞoÉJš­aÚÖÇL(" ­ûá \G#™#=:EàìÕ–vçT.3S0»¢žª(:÷l‚pd#ÁÊuQ°UHÅÂÖ8ÌDE=3Œµ0mg]çËÐBß|v8©CƒŒ}è^¾ÖWLøøK=øPä{Ý^¶ê£‹lOñ»ÊÂxJ(‹|Oi<ùfcËä0[ÎìµhÆbcñÃU¶qnöÑÑo´&8èžOÝPU\ï 0hdŒsêÃI3™o¾ÄQú}÷ËfnOO«×â1a.Œ?‚Ç{+÷º¤UúÎýw.>8¹ä“À-„žѳ¢AƒØ¦š¶*›a5¶³õjßëÉzM–ïÌ:Ñxè(&%Ûj¼“ØpVV b’N§_Ý-˜Ï;SÛñºš²n:èDs³Dfš@ªT¦ó ³4m¶¶§dœ£mIdX„ ¹¦½«ËÕÁÀÿ .> O¾{̶Þ5š±ÁÎZðЕ§ŠSäTŠúgóÑ[(‡Ü½äkíþ>Ê2…î#\Ÿzå•Ç|!H-÷Ë÷tZo Z!\ÉæÆ ¯Üê¸tϱ ÃέzmdeÙgjÕB­“‰)>:  µ9ná˜Ý=عhËËUî8v°vzR¶Où;"ŠVÒÆ5C·›Ü¥w?$Qe\€¯Û!SðHhSÐ1m’¡ƒSørÞ€Vƒá®Ød‘í¡«~¯[ÌŽ²Áï}ŒYÁåLgÒ þÍkšG[AQÜßÅVÙ±£×ͱØÂÊÖkàäôÁ÷vª{©®sñÎ~£ûñìµ×Ÿ\Ô¼ó|ÏNéŽDÎÞÐWÄ‘TêÒ׺ðr”ºÍ`¬žauÀÐà^W• æåbQ`!<%õ¢ã.ÃÎZ¦×;²«óˆ©êÊ£í÷C äã¾sC±hÜÙP›ùÖ^ýÇlr?.*æ"ä£b³O­ñ‚Ye˜ÍÒή¯õ)(/]÷³z‘Eê¾OÇ—Â ÃßdX_&fm°kW)®¢e¸Ê2_>µ‡qvÁ1é1ìÍ$Ö(åS·ÚbÌ+TaC,baz…]Ídkõ³Á5R¤Ky.§%"Ÿº<#êdc]Ô‹ž°*Õ†òå-²¡±ÈU;¯_Ó®²®sY¯’À˜ñÛ¶§êÉæK“Ñr™Œœâ>ïX$`ሮº‹¦ò_°Írw`%[ç ÝéTuÿ!îüKU‹ Þ}\2ôë\p—HF1¼mÒï´…’?ƒ§<Ý´ë¯øS€VÞã)sÿ^Bþ©î“W¾üÅÇúþÿ¼ªé꼬BvΚٕgøõ“ñ§õn`Ê—fvËón⢩—·«`dzà+cxïoêÅßΩ+ ¾úT=¾Ë?î 7Jâ‚-aïYafo«þ¤Ô’ÂÇñêÀô8´V€uñŠæ·êqHüNtïÃƹ*SÛPçèž?bœ1)ô{{sÅ tD’ÓŽ‹Êq—<¬­”qƒÚC+fï>‹:†ßí¤ "Š67Žyñàá£lQs×§O5o+‰týÕ«Ÿ|y¦¯÷íªý3°ÝyßýѽíA` âL8/¬¦øŠÎþ2JÈ}lû7·ÁØ¥ŒÁ“ lJS–žÎÕEJW¸qvïjŒ$ÉR0ß4Uë}ª>œv#Æ´âqN’¥O&@ÂBb`±ë½(q¦ÒˆªôÙØä8Î#,rǴҼЮvÆjž¾*Öm±5lQ*÷Æ#®FY<ä26@Ü/pU³ ¹`'²=µEtPc[à\:U >£kŸ¶A,F#êÀ®®¯..üÿà]ïxjðGÿàÿ}®mý†çJ—`Þæ[¿|Óý6¶¿OÇõ!²)«œE{@ÖM€ZO ”KYßÊ/^jñΖ/c<ĵ1w|`f>Ð,ˆã)< ûE b7Å›ˆp.nTØäÓº ‘.6ÈG•Ü«„võÖa}#QlõUF¡0%¯à%q{-¢h(^F6zo :¥¯6©Efçášìñã.[`}#ÒIÙ‹FØ´Ü›|Ë3=BÁ&ÄõÙÙ‹‹‹‹ü,8Þî­Üë@ÝÒœ<üéŸ~|ýÀ¿‚¢¡Ô¤gRl{¸åê “jé’Ñqa,‹(ß-ˆªn› v¹PµóŸ*´øõֿ̔lE‹EÑ`¦®¸¼cpl¨‰Äâ)¬'À®¯Qºà7·öùðÐt5ÌT楽­¼œÚhÐ6ݵ=iÂF–~Þѵ?Žå_1K³úµDúÙ)AÛ4cf}tͲIÛ–¨ÆªÕåžŠÊÆ‡‚éÿÓ‹W_ý­ÿ šrò{¿úÕ®_{íÉé¥f`­L/ZúG%Ò]·Ý² ÃX˜ë¢vÇjûJg‚ìþ-£>g¯í½Âò>ÆØå@v ;½ÀéP2Š|1 &3uµÍ¼%%㪳/Ħ„Vm7ã$Äu™s®cugɲÈÊOÝ›oÕÞ_½1ý'ó)9Î1Ö”A«º=ï·vô‰Ï™Xµ‚.²~Ýï+¼0ËŒMB½çÏ à\÷&ؼ‹`ÜZ£N=ƒS’HXKÄ¡èÄû‚Ù²¨zÈÛZµ©Ì#?dóµm4m†{ ÝŽ&C™ š–øóÄÚÄ‹~nD–Їÿ–—`ލs6ûž’ÊjÙž“¸P0©£÷¢'AÛƒézI—³Ñ™ÚÙl 2ûhg­.‹­›O}è8-wÑgC\ýÍ…`$­ä§¾†–1‹Lc,–ù}úøä—~‰©M‰ºjw|®ùtÇAvîóêõמœi5eáƒÉÑ—B¥³üí3] t¼–EB}ÞOUÿ#¢Džº_J0ú@—‚Þ67^G6˜U|`‡ÿþ_ï—ªï›æk!w:š#õ¹Âx*’‚cqŠšØ}‚ÓQdÊJôÜÛ´q•Y~ V2Ç_t¶_êI5¾MJœè©W£EeýؘQ¯~Á«ŽÈ¶‹~ض®>´¥ŠëYôª¤óD³ dưÕÌÇUò› tŸU[ÜaÝkùzõóÉÉ£þ%T]íû%@/FɨºX®¸~P¨óÏ'å®AY38,NvÒÔ [ÊAÁV1^”j‹„K-’E/‘¥+D¼_´Ìzœ«_Cî›Èî'J€,ƒ­vKâbˆ´hro¤Im¼4 †DuÒyë=}`8O7¹NU¶ÙEzHËKlŠâ1^£O7xlú †ôÃ;g*}¬õµ=ÑOoÅ­x$v3œO ¸ƒ#Yt OžOÑ+JÞóF>\—½(ÃF”æ9ÅÕ†žÂس~8w=RùÝåùÞ7}ÈåêÙûï^½¢ß¬©«³ÚNHK'z‚ˆ§SÝY|D–^5&Y=˜׌—Ø©e‹´Pî©÷XŠÛ–Zx%ËÂ¥† £bÛ¦"£tJÒ-ãzITo FGâ½d<øä.Àw ~1ìqJl ^Í®¨T7ÂÝXÒ{DÇ€¶—Œ–nKrßJk{Ëô׊tk+h‰Å¯ý¾b …ñGœ›öiÒÀà1·üX‚è¬#}l"Šmä®gÑcÛ}W›çŒ³Ö·¾jÄã/㯿q‘¿°Ï’wZ²<î4Èêü›îê““‹Ë“w.žkQ_ûWQüEun~!ˆÅ>:ªÇ/œ±ºN³ ƒç‹¥0\ó’›…ãòŒDûʳ¿Xq ðè•2Úÿb0RYª˜…ê°N |½”)ézö²cÁKX“AtYøžèôC9ioåߤé6 †Q¯}%BOAX…ÍmÔİÁzN÷ªB}è° ³Ðc˜Ê¤ã56¸Ð1x ™°Õ±­íg£G5ÚPÎëỡnGl‡ß¶Ý·snúåiú«þð…hiõDA?o%ld³>°2às0úãXþ& K„ÂßõyLõ»tàÿó¯¿wQßôPÑyéßò«+ 8)«sÕÑX.|ÉʳmÙ–@æQtaŽ÷<È4µ÷í»ùnÁƈŠzo·ÑKÝô;¯§¥«ózõE;ü‘¯/ð޵m_ò®¸±ªïRX&QmöT°åŒmƒz“r¢•­u’CSf;"9œ±`b;Q7|x£r¶vñ±ÆŸþ*НÀo‹ÛöSìÖÕ¹¼o7ÒZéõ9AÆ$šq@äˆí€K?ÆK浊·}Æ? ú5‹î÷tïÀ7ª/NNß~ëñGúB>ò«¿ZBúd=花Øw¿S¯øðøóƒ:]‘ÑóÖ1ð › xbéh•‡ÆüºÓ‹¯+AÑBã¯â`Oñ ÌÇUp·ÅRÙT ‘o«náëÊG[ÊÒÍm'Õô®ˆøNA8·G>ÖR9ÎLáÚÒÜÔ¯òòP¸)_äµ\Ú“ÅRÞbìªn™ùâ8GV˜x›òèÓ6r\ãSV…É9ñQ–©A}÷è9 læó ³)¾(ýl;ä«¡JÍ rwþžû—ggù&`îñ|¯ß¤]ú³`.g'ó7õ`O7A ÑrïÛúÌW0u|ÿMkаàÎ¥£0Fà©v_kó(%gìWݸ4*@l1dÀÏ4Š•ªÙº»Ùz˜÷)Ζ%ßöCõM¢­>£™:Ù'Œû2~+Óc¶ŒYŠÇS/ø!Ãâ¶ïNÙuª‡N=¬cªÍÀÝyú@¿“Q¥ëÊ}{ßøF }öñçð7t!g©éçÂ{ñõÞsu=ÁÂôëo‚<öY\lÔùDk2uÛ‹R཰{Ô¬ï‘Î÷çcÃhå$¶c‹ñs……Ú1«‹uò_UÔ@1Çøurx²42ö8ð„·ž8Pl¶˜øê®ÛĞ˒¶ËÚÎxyÐ9©Ž}½–?YuòµÐm$Ó-íC¾/…í€Ã6õ Ëç¬ÍV®äåñtîÓç˜ ¹Ý4‚„D‚ÂkoTR¢¥,‘{Âà3ÚBh¡Ñí{£ÃÓb4Øk¼ë\â:FS]ò4ú}\"Ï·U¹ß²ÎÍ{‰œÉóêÛ_~|y~vÁkzžâWËy¯„= b> ˆÜ% O±^”ªoß±k[d«ÞÍßÒIWVs2 ¯Ü4Xñ#êçÒåsúcfÉ96Ô“”by±®1Èä…y°[ਖ¸œ‘á¼þâ䰀߹궀­É+ÇNÅTq:o( ¿?ÊE¬iâÍÌ‚¼Ù¦°•+g,8’¹¨ÿ/cb§Š"5R§´ÁõM>å ¹MÛ{pPó‹’ù°–`‘¿Ò`ƒƒ’ÏŠ Ï…$w‘¹ÚxWïâêÕWý–x|ß'½÷;v>¾ßýäò•ÇêŒ÷ÕØG¾Š«SØ<ê-…MºJMªsÎÞ‚(~(ØÄ湈Ä2â­ß5hˆFˆŠ.‹¾7³FƒHL2ñj¸+®ãH¿tXâYŠ­dðù#Ô¼‰I‘—6sóÈ”¥"E·\~†³ÒåœH½°Í§-+¸2*´,0Â5¬NU »´ j”Pá±&ÏÔÑl%{¿v5¯¦mè¡EÕÎ8ª¸Þ”ŠëÂ@SŽñégœE íZ_å«ùÈ…J°ÁYo}O@ôôŠç“¾ xzy™ÏðÏ÷¾Ô}›:ï{ïÉåù¹~àô Z¸¼ðáÖÛ:˜»èù¹êzþ^ ¸îÀçó-½œÂ…É„\@3R<,d²žõÀ ˜“·†±]´!Ƴ`Æ ² PàWÿ®3R·ÎfUŒœP%¦}W‰lrÞ,8¼Ùmðm-…Û¯Óô՛𤠢«mÛŠ³Æm—²©…Ž€zMq«ÍÇyFÉ—ÁÜhPË  ;ܲó8ô~i3;~Œ¾Ö²ÖÃCà ¿§^Àí¬fKU&né“1Hø«Þu®¯?}röýᦙû"™»÷ùíòOýÂ/|túÊÃ'Ü[s;Ä‘eÁ'ÿªÓ™\Ù-3FSK+šàs§P]ªs¯J^¯£ãðËa)øó!9óÞ?ü)†Â~LÅÀ(øÐªrÆG`ÔÉ•:Èò'†Ò¦aS­—Õ–ª•öQÉLp’¤aq¦b\WˆYqÑKA€X­ÉI…™MSÖÙ.¬+Q{h`+ d˜RÚ²6_‚¨,òСD@]؈,›ò-G-»Ð|ðœÔc{”–Ml7öŽÚ]·ø^±5Þ«÷Še?Iæ8]ïY,zuvöø7^p'ü™”{ßÔÊê—?öÇ..^Í¿Ì ]8Þè ºª#‹Ù¯­´<‡uâJîÅ.ªÿ=à¢îqu½Z¹êq Ž’õt©!ñ_+Z×—F|Ùw¨j<¿ ±L°õí7cA~ì°hñ%`#;VÒæ‘¤A_¶íw]ýõÑ̨/A’I)Yò…¿©”ZÚÅ×y๳°7bK‡ºë¶r} ;Á¥~[QöÆ€‰2ÿ•DR‚1VcÁ!sFÎ&ži7òñ™ùèñšãÐOe¶ÚSOÁÍÃ…ÂñôjøWõW¹¡ýLÊý¿¨f2\×ú8à{×Îø}¿¦g‘2dÜtž À~Éè<Æšçt"R”:Å:Qnë+ˆôŒB6‹ó<`„ØBÆã?YŠL‡'WëÏ(¦ˆ·)¾ÄãžÅÅ÷Dîe!!òÈ SÂú}—9KÕì´/\ù˜>“Zä©O¯•Ã^?œË b`q€Š;©¤K®Î_boåz<‘gkjVTЙG˜Aã¿•ÎrçUIdÌ<Âó`™v–MÓn‘±år´×£`7*ÅSßËÈ$ÓnÕ1mïwšõ³@Üþg6­P‰ï¾|¦ÀÅéùãW*fÉ‘dû!еn$eDpâOj<pò—+,ŸÕ¿$V£ìΓENÝŽªÕ¹sÎdâ¹G‹¬'cþ;{ç”Ä$ °EÆÊŠ–y}D/™YáÖ|l¯:»h&uÛXχdå°F¼£¥æœÜ³q.†r˜šûÞp,šÎ,‘KJ`æÛwdÐÈmX.2ÖS.ј,õ¡¶Ûiß­Âép>Зiwœ×Ç}ZcäW¾Ëšñí¿z‡ÅO瞈z:Î8ÕX¼,,ßZir‹°n ÜžC¹â#æðEÏ ÇA¦ÃwžèRªdªas)¿.€U´[•!|«,礂%´Í\GvLî¹ï7õp`cÏa¼Tj«Z©u;¨dI•gµï6Ê$ÖXÚ†hØu]¢)²…‹ $6NE·÷9€# ‰Ã‚íE+àÔ”õÈ<þ%®so^CߨÍ"£ŸWl}Ú´Æ€3:æÞ*/YrH¥°5vñ[2>‡áyët¯ÏÇ‚®=YNîáü™Üð¿¤Æ]^|üú‰°« ]uiã Éí:ÅÎäÓ >u±îÀÈèµ¼T€Ï›µ„'dlî `9‡2ùë¥Wé”2*œÍ`½4Ðhr&…”OÉ=ª­/[{f2ðU¤éÅ^™TÕ!RÏ@—ÿrYâ‰î&bqI<ë`³QÙ§0^XȤC—ϵ"‰«ÂV¿2ðYà¸2¿ØvÓ]ij>„éÇf=’NÕÉX¦StdT£]í*ÐÜ8J?Ñp{|´iϨ iÞ}&C%RöxU PãÅ®zD¦ >­ÂÌóöêêïëŒæUõ~ΟÉ0šöèÁ;ë A—|Nƒ¥æu3‹;ÃÂöÕ^?efÑ#£“½ÄÔBî×ù’³øÐÓ»ü nzùL£ nŒê*øz°d:ÕÇ‹måð3JÏvKáNäJ™¾àåOr<ÒÚËÄ ÆöaÛ•…E3Ë¢€Å¨2­Z|Ø7½LˆwÓpÕ ÓbWÀ4ªëíµ fàÀ~3(£:ÏQ‰´œeQFºÒŵ›5:L 9²e±b‘¤>é6ÞK“ àWÓ7_úêwŸýš6@‹ x]…Yõ?U‹¤–añLdlèXoš ØÛYŸÁXÖ—fc¥Ãc6ƒÕ‡Ä¤Rz**þ, ¼pTçc³jÚœ*= µqi”“'«Ú1…Ilp±7NÚJáYî\—ÞHÇX#ƒô] vØ¿¹# ÈâÀ“N'î´(¼ ²$ÊK:ì(¡U;¬¯˜Æ&äPI°º‰~•¬äk+¼èÖNx ºsd}ÜG¼–ÿé#qB;¾ñlêÛlÜjs¤ ‡};t½O< ›O®ÄsŒve F±)Ön€HìSì+K+@ Žß”a'A6ì)äébü¬àè4}V¼¨?‰×bØ_‰Ñdcº—aW q¦WkÃ,ùÆtS‰~Òä‹ñºÒF‹0]³ßãø‰ vÅaHÎd½Êã©ÿ•[䂼e××/œž>Ô·õ7òþM'4Cwõ~H­•û‰µF¡Nþ‹_ù•ïü“?ÿ»¾øÊûïÿA]íùb€þ6‚þ@H_g ò©:žQÌ`Ï¢« " ŒV²‡(«œÎ_À±iߪºPõd [l Þ ªªóĘ âXâ±÷ ›¶µ™ŽÄ@Öf°£x‚µGÙI:'ÀIDATôci>W©ÍÉ8 Öö:Hýgƒ`Áóå ¾Tõ±èw^¼8ù Í‚çê·±q´×O"Ä£@‰C©x[yPµì vSò}¿‰±Ñu@÷1®;ì:ÑØ{¡.þ2®¶Å¹JñœqZwz«>›mdÄ'Ž>ËÚÿÔÙ¼¬ìòZ¿-у󳞜¾{òè•å¿û¿ÿî_ª Iè{-ŸÕ@#=,î7ÿþŸýÇ~ögÿöÇ|øáôô úÛÈzxÅÝ€ç£'sÆ‹ñ :jOnMèܪ{`¤óΫE=olíÞ¸© Êžjl€˜LÌCª¼vÇξ`T†_ÙÖ¾$E¾N|t­ÄlãÃõÖ×ÓC|BL±=L'ë ×^ H½L)K¿ù,Á™<ï¾|WÀ·— w£”ÉarD5°bV[øªsžè¹ØVÙê%v%‹Ï¢Ëص[HÆh`q­£ê¬þÁgù€«\*< õBFÙ¥æ Ø­jå¿æ^x„ÌE×áå^«óK}þDÏ¡OOŸ__ÿ©ï_^üsÿëoþý¿*(ó|˜‹¿×òYn4”Þ?ûï¿ûίüùßù;þäïùðÃG¯®ÿ‰7ô[I__^¾P¿©¿¼†½À{ðè-Š~Ë„¢ ™ÜÞ™ñªÃW;`)`šÏfÀÕ‚‘/3Ì¢ÇǰA%ü˜pØ"0¢¸X›¶ åPÆ¢+ËÒ­çXM_…¬º‘´2q»êºÇE™†‡šÈsFýY벺ÊzNݸ¼ ãùÔ¶¶7ÏU½zkÕ3>Ó~¯®x§úüLåƒë«ÿóÉååþ•ï}ïß~÷ƒø/ÁóÜYìý—Ïz Å×_SG|ëwžÿåçOÿÜçÞ~ëϽr}ý{ß:9û¹s½Ð& ÕpÔZ¬…ãA”!ƒèq`ñvçi²L,k¹ŠÉA= ›…¢RãÎÒŠåÖGÃ<7ê4ŒBlÄDoß’±ˆy¡îºNÄÉ,\3‡@ÏKn÷U½ÔgZt»vöüäê¿ùÍë¾þwß{üŸ ʯÿäª_A$ø,‹šücW¸+ñÎøå/ù+ääü›¿íÅõ/¾¥îúèêÚŸÐ}¨kžæ«ß)`ÚbÀ[†<5€ò9~ž™t,V¿ :xM>ºËƒXŠíf¸yH&#v>^l?ÂÕâ/Âö‰i0ñEŠœ&õP0ù 3<Å1Šgð%_-Kö QjŠÕÔí4JÆÔü<~òלü¦ž ÒØ¤¬üM²¹„’KI»ø ]eŸÈË(vP󽉭òøéµ»±¡bÛ%©,ز«œé&ìUÏY*!Ya¥7®dãªo%óóô\OøOÞ¿¾þö“«ëëï¼÷îŸ(˯…ß9ýxÜ$™¦îë¯i§üÕçÏŸþåçÏþÌ[oþÏ¿z}ò¼u}ús\¨>Öï© Ë®© ‹ñ K|-Z ÅJ‘ §Ô½"<€ð¼®ÖW*IQÔíœä=×–„CìjµBL‹Åo Rñ³Ö^€Vï;ˆæ­ÐÂu lR^YÔ D+²ü+\Õmíu‘2uy8ïê]r9Ú;GÛD^Z (åÒññÄñ²}Ñø¯°Öx–q¨~Ù k",F‘¡Ó2ò£ÄjD†é´À™x¡”H§ˆ —'I,ìx,uÕŽug8Óç/xðÿýO¸ˆ¿ÐrëP£íÊÄ+Ï]P 3)Зɬ ˜‰×â#•Pó·¬,è µ¸)5-pu–0P•z9@ge¡‡Zí ‚u2gÑãEoUÉ®úZø ž]_ýÕï_^þë¿þäÉÿXV¾ês±ú±-Üõý8—k= ¯}wúמ?ûŸþüW¾ôŸþž‹ËÏ¿zrúû?§›þzË×ú„ÛX=Ò2c'GÌ’“›ú¯ªkžTn¼äe\xÏå^8åèZ?dCéEç;{×äe–8¼Ã5£˜<ŠO$\éìã[äuSùÏdåµ>ŽÉ G6Q˹ò³Z4îv$ò7¥ÿ^?X?̪ëq†¤2MŠS‡ŒJ“`BKY𑻟Ë}¹bèì«j›Å@û¡êƒ“l’{`ÑK;ʸm]í`ÛêTñ…A€\qtýá¢tÊèý“Óï<;=ù7þÖ»ïþâ“>⣽ÌWZðcyÕW^£ü¸oIÔ]ÿ5Þ-xï½'ÿÃûÏþÌÛo¾ù^99ùÝožžþü­(mÕ…Þ«©Ó<1´äzqØYOZx³w4pC¡t¾²d &°ÚlH¢}¶Gã¬×)þŒÉò¾0L6¤ž|²–c*±c@7Åè@6;¨Rðy®&—rêwtýÊK€ÂUûÉhµ+{œI*’âþë‹8jSüÄW( Û.:Ë„ŒO⟘Eê: ¨¥_ØZÐñ¥ K¿²ÒŒ›u>O܈Õy\øé>ÈçôüR;쳫«ÿðûøã¯÷ñã_&† kŠ…_© ù1.?)€»ð[µyYpö§Þö­¿øÁ³?ñ Ÿûüoœž^þ/œœ¿uÁŸãsDõ[šDÛ ìffIÞOjhX!5ð¸JøkúµtOŽ—ôö?óþÓÿù/¼õæò{NN?ÿÚééWW—šÚ {ÊÌÀ“+R¨Žš9…ñ„Ó­4ººZPQ±°L<ѨsÈ&+¼&aQ6›2«3y[`¦y©J °å‰’óÀà÷þ4 ‡+A*‡2ì¦OÊî{ú*6~&7”¤Uµ>·Ð.†ï‰8jÓ¾¢sß.î†|‰ˆÿ!of­£7BBäëQš ©Õj,L¶—9ž«m6‡Ø@ѳšõÖ{FŸæ9=ÿèDÄóúêßü›ßÿþyüá‡ßB¬ƒ¬~ìo÷•ãAùIÜÒˆëoŠû/ ž={öWô²à oþ¿}õúúÞ<9ýu®w ´ëŸ&þܲܲMPp_žU¬UCàÒ"<•ƒ­5†ƒºµ Ä[Ny(™í€p)èýN¦í-¶Á$ú¡*Þ|0èö>‘j3Ð^庎é£À§'ᄄ àùØì°k¿$‚:±k7¸ÿÀtYëëâÏ%ÒúöE{ð‹lÅÆ‡åö›+8õƒˆme¹b©PG:åµ!Ïz-p¿solÙ†õtã˳óÓWºš<½¾þÏíúúŸÿõ÷Þû¯Á¨°~~bn÷ñîô“¼¸)ߪ±òË‚_zúô×ô²àOþÜ›oüºÈý·OÎÞúX³D©?êÃGj20aüwáä…ãº&Sý˜ 0/GÝëäI‡€ ‹¬ÞЬ:FÃV~²±shŒeÒn̬AåÜÚ&^ âƒ(~ü±e'bA/ŠÊ…xØ-=6<È@6€´Õ®–¼,—iäÅÍóÞnÅ9_ ‚aÚUõ}üÐØÑN,ë¿}?Í'%ˆ; tl<ÁC—>œo÷õŒOOùÎôžþÿ¢?]õ/ÿí÷¾ÿï~øá‡üˆOýW—ªþd–Ÿø  »}ó²àŸ}ÿ¹_üç'¯>º>ùƒŸ×û4y·@¿Ö“¤YF’+£…YOHf©1¦Ë"/u£GÖ…Éi\m­¯¨ÑÍÉ»È¶à”»¼J*}µ‚PcƒYð¶ –ŠV–öúè—l妵½Ó÷ Ã*É!Å„².þÈJS¹¾™`V;TCÞ|-ð™ÉÔ¯ÏJï=ìÊ[ÞÊÃŽ>3¯Û}>ì§o£œtzúìÉõÕ7t»ÿ‡ßûèƒÿKjÖ N"o÷•÷Aù­²¤a›—õýgö‹_xó¿zÈ»'§¿KT/ ®õnß,ÐKâZ`Y m]uj{R1Pp«àEŸPE3yPÛ¾ÕT±c#€¯“*~sÝ$ÂG»‘)~0'ˆÊŠFîþü›/­ŒCpðÝeèÔv¾*þ‰¹ÆYy\S_eë"® ªÊšóÀÉ9ƒPcRÞæ•›:/zp‰W‹~.tÚ_ºi[õÈ¡ÑAù¯Œôa„—Ûý?ýÿ<¸øúo|ïñÙ®X+?Ñ·ûÊÿ üVÛÜÀoÕØÖ»Ïžýú_úàÙü³Ÿ{Sßz½úýoŸž½ÅWŽõÇEõñþà, H ‚IÁbñÄBÆ”§^¢f$àj­b•혔õÀk¹¯¦øûÿÚ;ÿ K®ªŽw¿™$ìîÌìì¯dw³"†X#&EªÔæË*­’¢L%X©RJ,)KQ´RTb Eª ‚ˆ©UXP ù¡  Qä§ "&!6?HÆ]³»a³óÞ̼yo~½n¿Ÿsîé×3›X–ÍîLß™î{ï¹çœÛ}ßýžû£o߆Ë*&Ì:ÌPÙ¤Mù$•¦»âqqÎæ\…Ë ?®ÙôWœ~ý¤™! Å}?& ÒëÀ"gªçà÷ÂCÿ…èGb¨=Òb¨K]?Ñêô³ß( 'ôKC]O„ÃGVà6A«ûv-Ú‡BC|›ÝïçÙÁNV¾ù`§ý§K½%vëÙ0Ý}+„u§ iÒ=®üR¯ûõ/ïšüÈ¥ƒR˶ʫÆ3-Û´EDà’öPÕÂÎî£ÃêÑj­¨Ji ‹0µ —P•ÛÞnJé°ºSqäL·½»ï“„®+ !b¼Îg€‚fèp]q.+š<)#ËÓ[UÑÄ\MÒPï¡SôlHš¢Ú©Ê'ш¯¥¡C4 '¿ {ÖUZRáq“ÓiÁ›´DftšaMJˆsî[Dá¡qztý‘e ¯ÞÑüžÞØÓòý¹¢¸YÝý_›Y\|TÉØdnmÃt÷u/'¹lâf‡Ã‚ùù…ÿèw¿xîøäç¶æå«'²üUÕ"" ôkf¼²­½ˆ0Î*qj˜œ%»&3²8›ë25»<&t½T`?Pd²®Ö"Ç·kT>Ñ ZÞÁ LÒ%Ä!’áeJ””3z`zDU½šSð…ÿÿçÒ­GT> £`üZS%¥È„ñ yçv>O#Eå!™àåâĦÃrH2(ƒ×¡ïFÂh:ùõh›8Ÿöר5RèÔËŠÏ=3ýåC³3·‰¥»´ú®»¯{:Ém`7=í¿>¥÷‹½ù#w÷»=0>vHï\±3ÏwèWϵ9¹6É4¨¤T:*ŸIë$ØìP€žpª¡ñx0*¥%Ye5EÞž?Êå,òp]©ÈDuØ:‹x¼º&d%HRHšÒåd&tBj˜`À†Z”z1 Ë8‹°üõ®~¯Ö )?þ#ÍékyìúÃÄÖò"ËTn¸2/À¾åŸÐLÄë>¼è7fn_³ûYñôlžýÖ·Ûíwô–z¾»_c-°i @Üó´{ëV¿²w÷‡/Y]néiÁUzZpŽÖø""PCåK(¥òX•*XJP5W’ ÈŠ×x8!“â¨À¹/ÒäG:¤p 9"n:SBè0yåm8ÇOé.9ŠšÒÐÁ† 6C€$dº©ê"°&oçóVw­ŒéoèYã+bBç £6Âõ‰>+»”Æï†¹â…fú†ºH«‡j ¯žék‰¥¹¬|¯ºû¿ªyþ[¬*+² ÝÝ×=žä6H%0t:½û{ _jMLþó–,»x¼•_rŽF<-P'‹@]ƒ 'š‘-*>Ûù»LkxŲ©»ûºÿ“\cÖÉ´×½|ʆsÇîéuoÙ;1þM½;óÚY¾G³D>,`Q Ð*þ°5·VYz1ð[ ÜÀN…® È­¢Ã›˜Ý«$+='éL×Ož´ê–Y%F¿¨¤þC¢CQ¯ØÞœÑv*þ]€µöœKÑ_úH7£ç,FXOæ¤Ìd‚?®ÕtÕí ÈÂãk½¸6èQôµývž=ÓÍ‹ß}t¦}ýìÒߌz—‚𯩢ø›Âxþˆ6µÈØrýâê{å çùy= V[3®í˵ÁÖŸj%µÍú™ Jâ4“lÆ£ˆÅ¡'â– ABΖç·RaB‡|ÛÆL{ÅWd—¯ùƃÑLU2Fu“’EYµï,/eÿ¥MAŸÓ›=2 ?ù XW­¿”C·4"ÀµÖØõ'^Èv=)¾&MBÄ+ƒ Hô‚ÏåásŠñ&9r ¾È~3 èJéChJÇ2h9·ý>»¡¯íÜ}b_÷älûÙòr_,£ïÚ T6îyJ 1ÏS(ëIÓ^‘ò©ôþáÀöm_WŸôò­|¯*k®çÌ|ä¼å{ ¨ª[g¢/+*3ˆ7« ê†B ìuòìm·ov¹X,Ôi”mºgúºçíð"ŠlÚëŸõä_¿°ðØ]‹Ý½jëØªzÒ?=©§úŠ‘žvé`~ i`P&ò;"ô¨ƒ“€3p'vW®&ä¬}'i˜ì`SRÒfÙ*û6 sGGs=ô5)›J2qF·q£Y ðÐÊòOÌÎÞ£dn‘ú¼)–ðê>O‰k À‹/Fž”S ´˜î«ýî]ÅÎí·Ž—Ù…ÛòüÇϲ|ƒRA„~6á  =(ß+· RÇ ±ªLu­š(¤O¨³µðâšcõ|L\¼È'/å`â&Ùé1àQ¦žháà ^®g4Óëë™]$K×Ù}±TçsºÝ_’!\ñš¼ó@äV#Ù}YV­Ý×ì>tdåýZ·{Ýcíöߨ»ûñ…ºÈ¸ñ¿‡h À÷PHÏÇ2]Ü9?ÿ]-"úäþñ±ÿÔ›†—Oä­}’É5Aµª¹Õ[ ªê,ßžõ [»íè£âÛT¾³9ÞÅcCñIãËw•®À€bN2äÅŽt1ðƒÐY[keŽjÄ‚”sI¦7ùˆ„ÎxÔÉ}-¥y^‘'I&…È«zç^”éãF“œ¥s)Îì¾òÖÇò‘Ų<¡oìÝôH§ý–öââ!±Pnºû*„ïÇ5àû)µšÌtmXð†^÷‰;û ºdÛ6=‰*µSqkËŠf©µhŇVÏUå¼h=Qå èYUŸÚ¥Á!’cD!nðÇHìF–¢S°™a‘~ ÀŒ uÁh•\ÌÊ‹.Åô!ìZ hÎó¹ÁY©JÓ ’OPü^L‰i±8… gž'Uišäcž%¼£¶ýv–ýíC£Ko|nfîK&Ôt÷S1ü`^c~°ò é5Âú ÷¶'Ç?±«,/ÐÓ‚Ë_ư@Ÿ‰Ö²baCM¼”M:éî‹xŽ^ÜYÌÊ™ù<{çÃöotŸ’uEMw_…pª\cNUIÖôL{·-É>¾Ð}â. ^91ÖÕ»¯›Ì[[5,†O |-u[ðX“·œ…(0[È(Ÿx•.Rtû-ÑSABòðI€ÃÆ€=ñR½Ef„Ÿuï lRc}y%¤´³ÄŒ¼NzÍ1k _ÇÄÏ Í5& º^‡,ü ùÉvСAp€W@— b{;ÍåJuDòÝý‡ŽçÙ›¶Ûï_í÷ç$Ö¼±§BøaºÆü0KWºÓÇMó)UæûúýÎ}ý…Ïî»[Kq_³£Ì0ˆï27os\C©_q€Ü! ¬f0d(a4#˜þÄ@ad ¥ÃãJ×ß@:ÚZIËc@^»¼Z‰:ÈÑ¡DZõЈ­å·œLM‡ñ î¡Ïì>†dTÝý^–Íé“Ú¤îþ¯wúsûm+„3ðÔ€Óô£L;6lXðÉ^÷)íTüÁß:§'pWnÏ[cìS¥a½¿€16¶×õ„*Ì) @èF@ 6ÆÇOƒG÷€p¢Cr8*Ih§0› @_qXICAË'ŒŽÓ]¯ã~˜m“2ÊFOîÇ €©}Ú~»å_Ûɳ[Ÿ*Wît¾àÚšî>Åzº\cNWI{>õaAñÕÞÂýìÝú±‹V[[õÍ‚×ùw Ë-3“„váøÄÁ‘rp…íÒã¼\`dH/쫳’“¬8ºëÿ*ME™UÊ1ÑÍ|øÕZ~c‚ÏO«¯Ü´vàkí>t|áèêêÕOÍÍÒê/ëhZ}ÂÙàªêp6\lsVÃaÁž=coÍFoº`eðöóõ¹sv*¦Õ¨€æ—Cûš!?8C× ÀaÙGÔ ÌŠÈÄ¢-B’O[Oë¯õ²´öX!£2 1J£[OÏÙMÏÙg¶¸¸ø”ÂYäpýXõKØîLÂ_Üsákb0x÷ùeù 窩çsf`Ü^¨—c@#Ï8 ó|Žƒ>S €Ã>=/kîÙ]A™–‘~Q¬hÝÀûôqÍ÷HmÓÝW!œ­®œ¥¿Ü´÷êsÞ6üloþ¨VÞ²oû؃÷Oêsf­¶÷€š{¦|X@ëÀ°pN­úq†­•7ð+,ÂÀWóØ~|t÷5Éwû³yví“íöÇÅÞt÷Ug³ã7oÜÙ_rý˜EöÊìe¿ÝÝ{Ãùú€Éž2ß²¤ø²òZ ¬M´uŸüàú²€#š|T÷Yˆ2ÌXw_C€bÀÎ<‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì½i%×uç—ï½Z{«Þ7t£ûF‚C≒HBâ"È’¿0Â1r„ìÛ¡Û£‰qø‹ƒa°ÃrÌŒÇ<ž‡gÌPP3!’ (Š)z´5@ìÐØè¥z­ª®½^=ÿÿsO¾¬H‰²(Xy«^Þ{Ï=çÜsOfÞsî’™UÕ†V­Z ´h5Ðj`Ëi ³åZÜ6¸ÕÀûXƒÁ +ñ·ë·³Z^ÞYÍ]Ù¾võúŽ•™™íKú-_»61~ôèXwÛÄöÁÚú¶þÚÚX¿ß¬®Ž÷ƒ±NµÞ :Ýõ~¿ÛY¯àUu:ƒõª×¸·ÞétÖ:Ýîj¯×[t:«½ÑÞr¯;²P-,Ÿ9»´Þ_YÞµgÏÂäž=󃩩ùÑÝ»¯W;v̉Íu~¢_…gZ ´Øüh€ÍŽZ ·€dØwV33_yåàÒüü¾Î¾}WŽ®\_Øß¿zyïò•+û—æ÷®­®O­..ìZ]ZÞµ¶²<9X[ѯZë¯Wƒõ¾45¨Vçæ«þêªò‚õûUŸ¸Z¯©x ‹ODÜ©ºŠ š=ÒÝ®nÕíéGÜíU½íÛª‘ñ1ãôz*ëUÞHd|titròúÈØØÜèèèµ±ÉmW'÷ì¾ÜÛ½ûòØî½—G·Mœ]=7}aÛh÷ꎻ޹ Gá 5·¡Õ@«÷NÍÛþ½“¢­¹ÕÀÐÀ`~þÈìã_ß¿ÿèúÊÚ­ËçΜ˜;{þøÒÒò‘¥¹™c+³s{W—–¶­,,VË3³•Œ|Õï¯V«6Ö] ÒeÄûórÛb£eÄ1ä€0Ô$ɧ]6öj$k0”À;.L ê ©uP¬9ƒp$€Q‰â^O±äX—·ÑGadl¢ß½«›œ¬zãã+cÛw\›Üµóìøøø¹‡¾9qó±7ǧö¼Þ™}stß¾·&Nž|»IòÚÐj৬w?å:Zö­¶”®?÷Üáî¶m'Öúý{^|ñ®Ù‹—n_˜›½cñêµcË33û®_¹\-Ï^¯VÖ×d(eD×bä®)wÏŽì§ ¹~]ý°«yŒ¾ ³Ø[~Û]Šý­c´ÍhŸ»ž6Ð#€n\bã4òÀnà‡\]ñ0å&B"`’«& Â&9Ó8Ì8ČĺäïZ¶ž†±m۪ɽ{ªí{öÍNí:·mÇΗwÜ÷òÎ{ï}AZxQ³#¯M}ìc¯‹n(†ei­Z üM5À½Û†V­þ†˜þÔ‘îw-½ôÒý3o¼ñÁëׯ߿pþÂÉë¦Î_½Z­hz¾¿ºâ)ù>óì!w˜>ÇÈcœÒ”írÀeëÒܽçÙGô*‡KhAß¶>fa'@4&«™:_×8E ¢dU0#Ô< ²"×-;“A.Êà‘d˜ŽFh™B³ ý5-Yà hæ@΂4Umß=Uí½ýxZNɳ“G޼ž\Û¸Õ@«ŸL¾U2’»ÕÀÖÔÀW¾ò•Þo|ö³w-¿þúǯ½õÖGç._¾þÌ[÷μ}nßÒâBµ²¤ßâ² dGkçUo$FñR—lšG¾6ƒ¶}1’ô †ŽŽÂ˜Äà0æeÍ€]~à ó²¥Zˆ[›‘wíg`¦ |õÍ7ï[¸6S-ÎÌT+ËËÕúˆÖ¸GFÄPì½Fæ–HôŒÆ#MeQ>äìVç ¥ï4òQIáax“/ò%wjª98 -$T?tR )2 ˜À#X'òrú«š1Р˸f &vMU;¶W{Ž=³ç®»NM>ô§»ïºëÿ=ÿÊ+?8þàƒ‹…´Z ´hh 難M¶غÌ͘yæ™_¾>=ý™™×ÞüÔ¥3oÜ·påj5ùJ¥{v½W‘X£Çp…¹“¾l½7r´èÝöµ:¹ÝÊTxZ¾!$°ÄÇ£á¼3•O“jë\Ì`:)«·éÄšqÄ1ö 4yD5µ—B–ºê† 3 ª ²RìZ6êÖé¸Ñ™:QiÔT8š¡)CRã®kuNù2W ý™¤Yf ØO¡g«É;ªÉ«Ý‡¼µÿƒüÞ®ƒÛ~óÍM?~ºÔÒF­¶¼Ê]µåõÐ*` k`pá­3¯¾úÙko¾õ…égŸùÌÌ…é©Ùé Õ*ÆD#|mm~SGlÞóæ‘ÝñÉ]Uò-ÆLS. …0|1VÖ4C[[Áä™(–†Y4°2ÛRqOÌwƱ4²ÔÒÔÒ!ž}”Â:ŒÂ§TSsM6¥I5“â ÷:Š"ŸÙ4dÍö¸1*D¯ƉҺN%à WOÚ³!¢dã!^qÐÑyܾgoµëȑշÝú§û?|ÿ#»o>ùí±£GO5ùµéV[M¾w¶Z£Ûö¶\¾|üêK/ÿÚ•žÿÍé—OÿâÕ×ßœ\¸6W âÙ5oÔc´iÓ¨Gï6ø& y1\676tX 7Œ½àŒbËØßÅÈ{” O¥!w0ŸÌɘA_ÒEˆá/Æ? ÒøÕù0‹Á/†âªD¸Å(—‚Rq©ËT%Tèo…¤Œó ‘’mä1Ä&g'AÐ.¦¦Èf»ÉÓ6Û¦iâ[)Pì{MÏ>‡p¼Ä“z]CÈ¢ VxÛ!ÐrAGãZ²™ºùxuà®;ŸØsòäïï¹óίo¿ãŽò6j5°e4÷Ì–ipÛЭ­ëñŸŸ9wî·Þ~ü_<ýÒÔÂü¼HWëÈìÎãÆZÝËþ„1ÌØFxX9ê@.ƒ7®ÕЊp±×¾éŠ!¶AÄJ™OÔ7%é0jÆ¿ŒƒuäâÈXì8fÕð¡üLJ\o¬eÈ!¤‚Wð ó2ÞX/ù4ÄÍÖ„$Mš,MìÀ(Äb’Üð¨Ø¨Ci ¥Ö}qX(À <ÒZJpFÍ𢤎ž8Ÿ˜¨öÞvKuàÖÛþðÈÇ?ö¯w<øo;ÇŽ]®åh­~†5÷ÇÏpÛ¦µLOž}íµÿàì©S¿}îégï¿vîœ^®£÷àŽûMwدÕkthÃnC£tÊQ#F›;¦Àãv`‡|  kó(\—›>‰G,·¡8ÃêHQETèÇú á€*Z`9éRòÁgÈ#!Q¦£Yžqð½‘c”] òXF®¯vU„` ªòoÔ¤‘ô5µYŒ½ V|`gÁ \—‡gPäH.8A‡Îë „J{ã"hòÒÆù^×fN^¢´mçÎêàw¼uô#þ<øàÿ1¾oßóÁ¹=¶øÙÔ@Þe?›­k[µ¥50ûç~çÂÅËÿÙ[Ÿúûç_xñÀâu=¦ÇÈ:š¶aòü1æ(Ͷ'ÒĤlg³Ø€˜ÚçÅ8ŒøÃ@¾QÈ’o2(ŒÌÊ©à7ͧK‰|飉›5¥Í[W4C2›¿Ò„¦h®¥aa# i0p¶ò¡.èß)ƒKp^Æ´„m6Fè °‚&Ó+˜ò"ôÛ) P•Þ8€O¶®7i H…@bùÅãeªUg@gt}eEŽW»]?ññý›Ã?÷sÿlÇw~»Qk›l5ð3£ß??3­iÒj@!ºïì#üƒ7ûîoM¿úÚØÒÒRÕ׿Ƈšöm>çFK]¿ìLóf°™MÛ#žaì‡ê5bdžF™r¬‹ã¿&À¼»¬¥0'JØu^‰²¡°Ò XÒ[P1Á '\0F倨K’®ÊC R ˆD"‚\èoÀx^…¿+ "ÚŒ¸1¾Èœí–'Ûcã^t¦‚4ÖÄÀj§ÃR$S8ÙÄQa˜!ç=©°#0}óH×Ê Ú}ôhuüŸû£c¿ðÉ! ýõ(7Š \ÜÃýQVì†ù` ÂnB•·Q0ÁNÃ&ŒÉ°Ø¶YYÇI¢¼+v>‰ ïbl)r‰*MŒp\¨(êjÊjëe¾ÂMR5i(®Ý„hˆy'DÕQsrÈ‚˜.'ÿ KC´ZÁì P¾€‚Af4ÅkÿMd~ɲÆ*EÁ7ªÖSò¹‰:ÄŒBu°XÖ—0ã,(â¨÷ ¬ÊèWn¿µ:ùà/üË›üÄ7qâÄ«”¶¡ÕÀûUq¼_¥oåÞòX½xî—NõkÿËé?úöGçæ®W mì‹^[F# ÍzmpÂä•apØ ÊŽÂ „1+p[—@Z­rÛ¬¬ŽŒ?ì”vmäÓ„p1oª!³!˜“ 1v§Ü)x ;ê(õ™NÜ©£´ êdZ77銜 ¸^,‡ù˜Ò©8DÍqæßÆ·F–6i"Ç&N¦3§™&Kž J¬Ä˜³`¥j½B’l(ððÞÑÀäiœÂ#ÈØK—Yî6RsÔé™+^¡{¿zY|Ö´œ4ª§EnºÿCsüÿþ½ûî»ÿY©±Z ¼ï4À­Ñ†VïK \{âÉüÔÿù/~÷Í_¬*þžÞÒç¯ëɦ]w·N§_‡0¢a98Üx¦| ŒD±–b0“ QIÜBŵ†C&…!`Q[xòyƒ”{·©ö¡!‡¾âÂ* "«°C™¡aÑUEµT$„rex0Î0kBɲQ2L¾+Ͱ˜TRu~#ZCX4ë5-UÈZ‡jMæÑ„ÿu~Á'Psë›8.7YèÓ×î@èÕÔ‚C#fkúdóÔÞ½Õ¿úп=ñðÃÿ鎃ÏCÚ†Vï' øz? ÜÊÚj@þþ·ï÷þõã¿÷ÕÏêýžî·™Q'O·]Ou[Uašö¤€Ëˆ"¬‚ðÙ4 +R ¦ äJÌ‚ò†§|(Ùh¹ n3ú1†8ªm"ÿdéw£FhÜí6ˆ™ÿQ47–7ñ Ï¢ºà¯cªª¨¯†;!³H¾)ßm$úÿ“ƒkôG±Ù€‚ø H2.œ‚þ‚Îò½N¯ZÓL:Üþ™OŸ¿ï7ã·vÜvÛý¨jZx«Í¨.í6´xßh@Æý£/þóÿý÷Ÿzä‘ãKÚÑßÓc}žß¯;z, Íþ4vÄôæ¥?W2q 'À8äß-Ô”u!è?éM´fC¦f;´[?ŠyÊÙ,¿Vx»ýb½ÁX‹.ÛŠA»Q —Á[u%oÜL—xˆ4´Ät‰Wòв,ehÒ›„z m³ì‚»8Z°& ¤o„g>c¡‘Ì€QG@_/áЂœ X_Z©ßsçàç~çwþ£=·ßþ/ßAÛZ lR p‹µ¡ÕÀûBƒÅÅÏ<ûOÿ·óìw¾³sUäév{±Á¯ñ £ÿìúÆÞ–Úâeïßìú]¨Ã0àï’Å»ýHÐ47æ$a£ )Þwp“_#Ýè…ÞÅ$šą̃:’YˆN3‹A†O=Ób¦Àp "ãráÄ|JA(¼Ò^Âq+4mƒ¬®'NYÊ›ZÌ”K´&/ð°á:ƒ žiHÊ’” ¼RŽÂ9Ú /(õàð7X^©öõ6ÌÿøTð„ © ÃÍ•MþY`½k{ËY2•<"ÎçðÌîQh"gË«Õî[o©>òÿö~ìÚ'òD´ñ¦ÔÀ».wmJI[¡¶¤4"œºø_ýÆÓ}gd xäÏsýtâÑ1§b9Šc4YòDM«àÚX$~˜¤R‰ÿnÌ7°0.ãœChb ¹_òYØŠQ"†&fÖ•¥‰—4™O oâ',q‡q¤n,‡6a$‘§!“ŠÐ÷ìÌ•¸Ð„Ô©HøX€Jªw- `⣓”ˆ|ü8¯2±1ãFàg­q­~…¤ÙƒÊvóô ,:c#ÕÕ×_«žýêWÿéÜÅ‹¿u·ÇV›S­°9ÏK+UÑÀò“Oþ‹§¾þ›®¯èëm=u×ú’­¢:Øð¸3(lc)‹ÌÐ\6 “ iÈSþWÑ qèñë){×<’ 0A“#È Ê\`Õ†Ç|š‡Ç²¾¥ ù‹ñkR¿ÄÑmîdH–Ðlk­åÆ*‚Ì<¥¹žn˜Äô@ß2…š4)TÉÓÎY~JÔiµý4N¯P6`×4!wRfÅÞñx¨YK2 ”†ŽUÀH=i¡<8y¶†ç¨~D5˜—LóÎ ¾*yáÙçªg~ÿ÷ÿ¯óçÏo„öØj`ói u6ß9i%*ÌÎ>üê7ù÷/\Õ×YÕ#³Ûƒ-pç›=pÑEG7ȼû?°7ò™ kµQíIP0‡L”y—œa)¹ÒZ|ÏHøuýF/F¨ÁÚ`á×l°L./q]ÀKßhΓ‘qªa”ÄÑibt‹ÑM çFìD‰É7(r¹-¼2ÄŸ¸‘–¹=¥}"Î?à ´ð$3 ¸náº^Ó”2`²MІ¼2™Ï$yB‰-IñJ-]“ùPp•¶s$^ûþ÷oºþê«ÿ£ù´‡V›P­° OJ+Rh`öÏÿâ:sútµªÇýè\3¡Tü f8%‚vÒ]v#f{޹ i …h†0ð ZÄÔ >„•3g×™A_Ó¾1üZ^ª™p7kŠ} ÊbqŒ/ˆ'„s£á®‰4•ƒ¯ K0xP–±Ê©@À‡F€¥JB#ðúáB4M§x›ô6¸˜d’÷ۗϼU­êklá¹»–>—N;Ðzd8º3¶Šn™»6 Jt ݇«ß¶s€1P šºªìàU0ETP“Gš!Ä<@. G&¼ÄÒPaáa3ŒdÍ&Xì@³nÀ Å`š"Ê‚‹“N×\U®´ ’£YåâÚ€'Ôßì0È71f,È'±g1 ñÁÑ/qŠª¢È&z;Îa¥)ŽÜ¥H©è¹è¯4kØD0\^pë|mÂAŠÎbƒo8 Wþ¹†:Ÿ\ºÜxq2 pá7¾1}ù¯[ l ïÃÍ"Q+G«Ë—˜}ûìÔŠ^¬²®õÿ!z—µûÞè\16÷Ä»\™ºß¦7æ=kÜ8Ø|š&G‰‚“7 £Pð Ž@–cAWy¨âb i;ÁÒX²ÄPœ¹ºÂ£ÆSs†DCÚ d’?óЇzÁà¦!¦>WÀ%=™À-•nà›¸SrBϺ‡<†eI2 ·°·£€Ž Bò€wâFQÁ±¬:¸ÑÉu¨ûäCI:\>ÿ¢1y6J±UB¾ð ê*e¹ê>.s98úÉØ÷ÉS§¶Ö_«V×úÕì…éêÚô¹Oš¼=´ØDÙD²´¢´°–_yåÞå™Ùª¯Ñ¿zQ ¢¢;OßvãóºêÌÕ;ÐáòE?“X EÁ¡cç ®pòÈ”¼Òi(ôj!÷ððJœ)N>Ó5ˆqb€1"GŒ¸G˜âSª .bPóÕÖ>Š’§î]VàŠ¦–5)nàeû’ª™·÷/Üø\òB…gVBh²èŒ64rOÇ&ò9ð õ*oÊsP€­ð›²¥!®gvT_³<S^œ×àWãöy]¼£\äÝßæõLVOÉ·Tïë*õ¡µ(×/ǵ¯4/®ZžŸ«f¯\¹§ ·Q«M£ÖØ4§¢$5Ðïv÷öçæ*yUw]c*9tª]zÚŽR6HÛÆ#Òž§snÀŠÍª;m0kdv /´6Œ”ÇÕùƒ§åQã‚X6 Äï`[Š¡ë"h¡m6) Œ¨(«× ”‘AeÓœå±lp.•’WÎÆH 0lÐV‚Û-r¡”°ita# ^I›µi9 U>qꆑjl»™OÁ&Æ›ø9IÞíó˹`v02ºÏšmY± o<¯Ã¥„ LG`È'ôI-Ö‰x¹ý)LÝ^„QžF(Ôu!g€\nQ×ëš~ËÄ¢YZëT3W®íO´6n5°Y4Ð:›åL´rÔP‡º›«tÖdî4’ô5 0‚áÔ劅£#VOí¾X4± ‡;Õ¸Œÿ˜šZÕëª:Z¦[ÇÆÇ5¨’QÐb<Ž Ú¥KϬˆ··lÌJÍZ9ù à.6b]uȾî²Á3³bü•.<È qhM6° ÉP±‚gŒ2«®$ Ÿ¤­Ùí;p’\‚†ÖOòCSÐ, ¾žÂ/Þ‹©³Údk `mƒÞGã(ucœ(R–‹ÄÓäÊ0Ëâ=ÙqUrf$I#†ZAÑÐy /ñd (›LžàË  êUÅv¨ëªJÚð."]fYêeûu®ËÕ•jaiY#ÿ5ÿÖþ×´‘€/XŽŽŽUÝÑ‘ÁÑšy›h5°94Ð:›ã<´R44Ðév×»cc¶ ,šNê·ªŽ}MӪͰÁª¯ßÄ„œ¼€îºžÀ]P‡Þèõ½@9ݺûnb@1u“ï}ì\‡Hpâ C%,ñw¶^”%ŽJKÝ)‚,ˆy¸¡ÁÆd²l6ƒ™7°€é¯,%o¸3N'`…&ñrê!ÁiùÌSHÉÓ5/ØÝYÄž|Öé2•6¸è´Â  mäA5¥œdÍ´†‰›Ò<ŠÈ’燠9"ÕÜŸä èxdRÒrn” ˆ*(„>Eˆeg% âÚ©±£í*ŠiÍÙ(Í;*¸&y[åÂÒ¢vûë¹p¤w~K”ë—3;Ò]_Þ·¦µ¡ÕÀ¦Ñ@ëlšSÑ Rk Ó]ëȰ0rRG:¡ßŠ:Ö¾:TÖYWÙÀHK?œ€ÑÑÑjÀl¼1v ƒB‡î1?V„­Ýî ©IplÓtØxêÖe·£ã·‘TŽ Â¢(Ø(1Ä33,xDQìØÆ3*ýÐÐN©É–¯ Q™G©XJZxÇ€´ÐPgò  X)þk>*oð=ø‘"mMEFä‘§€ *sEvø(Ñ6×íà§œ:Ba‰F`âáNP0,ø„¬ÁÇÅ&'`Ìþ„s@ AcrP ÿl.ü³ŒjBENsP©ˆ²ŠRb¼,ËpJá_ÈlöcÍŸëoYO«0ò_ê¯XGÌ0­‰¯üÓjYñËUº>{½îÚÂÂBë ö6l ´À¦9­ µº==¥e9#ZUÇ;I§ªÎŸ]Õê~ý‚ ¸æ5õ:>¹­nONï À@à°‹›%‡b DéŽ<¬°t82¥PQრd¦×AôF±E10Œùt*œä v"ÆÊl0 Ên(7 Š·5X¿:Žòñ'Ù€5ù©A7W'7 0E[*ºuˆ²a¼‘Fyrᘭ1ªP•ã0àÁ_4 8P‡ü¨†HɳF,ï„ œà¸Vø ‚Ô•§< ±õ #Á¯”I83®_ÎŽ(£þÅ¥¥jQo«\á]BµñÇÐæ¿%]|±nÕÓLVO˺ûÏ=÷܆ \I{h5ðj uÞCå·U¿»´ A”F‰z~º;6ê¤6ÿ«ƒ-ïrÓÖjºæ†Y+ZXXÖ#WÛ'50©Yƒw¸]áÚÀj­?>€ƒS N™–ÆF€úI8L†`ä72€Àø)xAh›XPÂ}`8€ E´üÁđϊLcلѬSs5 yšbÁ,p”N(‘R¥^Œ*CFmSÁ†»Ô£lnª3ð-Ð`à°–@Š|à‚–ù5AoFEPáU”ª u_·¯´&ë®u€ HÂà ”NE5äJ&‚ }Ð!GäcÄ/0û¤~ó‹Ký/ëE?Ò£®5,û*uéš]ÖtT_›Tǹv¹åh `íK_úR뤮ÛxSh u6Åih…Ø nw¥Q§©ÐíéiM£dä'¢Û^gáÖBæKk°Ì¬ðž€ÉåjtÛ¤Ö\Ù0ªÙÀÔ©Ûè`c':O!«³¶©³õV Æ à„À4d©¯”ɦ!øÑéCKLY Ê*©Γ¬aðb"=œ ‚Æ|A~ð³H"W®Á:GƉ“…Á…œ+ÑQ$òT粤,uª4Y2D½È…´”—j¬Z•€ª™ì`R$¤!U]‡²õ+Í p2  Ôá˜0ä M¶È†\Æ_S¥\ý Ñl¿Óë\cL÷//UKùóD .çBsÕ1Æ_KëºîX–êéÔEh`DWjÔÚ[ l ´Àæ9­$E½^G˧íÛjt´†:R 4šZW§;Nß,<æ:š`Y_a‰ÙÌ–«9c“Û«ñ -!tX‚–zN%Yã÷_mÂxP½—\‡peÀË™uÛ]*·ÄFk#€#Œ‡‹ã«¤7xäÁQ¦ž¡PEäö+vÊ ¨§T‘ ÌC ¥‚ڗɤ©4|¯QmA reâ¿æB?§‹#q´%YxZø’/mt8R±%ßÖç§É7鉳±*w3”'vÚåœ1ÉrJJ!º°Û!X/†S.ÃLÆœ¸¯—úp]-è·¸²b×Ý?]«ëêIWØ '`”‘¿Œ‡÷U°¥ë¯;ÒkŸÿç|´aSi u6Õéh…AzòŸÇ§µWLô¶ZßÇ §ô+‚yK ¥?«ײ«ß°ÈS‹ËÕê¸- Œá hF §=ŒÖÜ!«ÃNgÀ†Q<\•§} fJ€*(WŒKÉ)R`‰‡±s–£ =Ä,ià ^Ïv*(©"b2u=QnjÊM×Jh&!å<ãÒQ¾ ¸Ð¢˜"£ÞD×R·Q ´Ç“ã³gÊõN°,X#ÏZ½hÂGÊúÀ-ô¤²1Jû±È‚%†­7€7¹£dMŽ˜Åú7¯ºž€±½Ñÿ‚‡€CÄO£ú•5¯óÏ_Ÿ¯®kÔÏÇ}Fp&ÕnÞ$Éf?FûzÕ¿OÕßkþ9Q›Qýˆc§Û:RJ6™Z`“V ˜˜ÐËS< Pœ¯¥ÊÊ÷ÔÉvÆÕ„6ba{ê¬yaë¯#ê˜×Vôö…ëÕ²¼‚yÍt·m«&wì¨Æ·o«&&'ªQÑw5m`ƒ/‹Ô« i^<<& KQiF‰”`NHúQ@Ò V¼ÓiŒ”íxQŒ}/é‚_xb` A„†7 #©£GÚIACØf^iŒ¶ƒÊmÈéGÉ3QÀ+ÂÆXYY{)°’ÊÂi õ5 9äæYøF5sGULß»n”"› 9ÎSÑiG¡!©·ÔãX9â¨kX† þ+Èn†ê¶{@; Í£}Kšê_\X¬ffg«Yÿ•5úõ†?ÞM±}ûN]ŸÚƒ*><ªÉ‹º0cä/çûýº¶|Ý­ ­6™Z`“VœªÛ¹ó’ßò“ ÃP~¦ôõb•Jo ¨zÚÍS3lÔ~€Éµeuµ‹~kIû–gç«™‰«zŒ`[5¾c»;ð‰íÞ'À¬€—`ÏÚ·ù“ca#ª„²µÅ£Œÿ|èR"˜^y ëä*+4É®&©Bqðb—7òYL\p,ZÒ¼£\t¸! ¯`H.q”—aŒ\ÆAl˜i”WûBW‚Grɜ뀷‰R¬ì€FØH Àè;8z”gÛp‹ Á€\;äm±Þ K†ZåA"Í ¨’ØÙöy…¯Œþœ¾B9{ýºí[¨–Œ×“Åíª–._—“ i~ž<áñ>–º2þ8¦µŒèÇÒÎ×UUmß;5CMmh5°™4Ð:›éllqYúXÊÜÈÈǯ¾øò»^CUß©^5úmõ¢¬ŒÓ‘ÛÐÚ>S²ü­jíµ³VõY9XdL=:È›Ø4š[Ò'Y—®UKW¯V šÑþ€É“ÕäÎ]ž“3á aüUMŒŒÙ¼ECXNŒÊÃK&Ã0}*G4›&p€bù Nò0¬Á³`Á6Fy¡+ø4ËüãpÀÃ]WíDSù£ù™Bå ”F’“¡2·8ѻݺІq.¤¨`U¬4rx} Ð¹d=@¯¨ŸÚœTçk¸ì4…[ª ퟱKšøè«}¼Áov®º67SÍËà//®Ê1X2çî¨tÆ5ͯ™%¹”«ËšèÏWc»§ª1}æ 0þž© Ö¾~ ÉT·£z:eöü¥{žûú×??16ö§·ýʯ´ÎújÃ{®¼NßsAZ¶¦gÏn›žþÔÕ—^~øâK/~öSßsèž;«cG .üÅ_vV¯^«ÖççeÜ—«u½mÏó¹Õ.Ï^kg6#7Oßò4À²Þ 0³T-è‹z&@?€ÅtàÚ¤¥Ô¢Æl|O`µÒ“ÛÇôÔ€–¶É!ðO3ÚÀÅ n1 Çœ¦séÙÙo`ÀÆž—rpÚÙÈ;.F C/HÁhb FVVcƒ™¥£§éK ª+Ã?F®féƒÊš ó‰“qâÀqCû²@qàfé;)A@—¡6…Úå*å”@MûÓàé6ô-êZš_к¾®«Å9]-ù¯­/3¤å%-1é)Tžé×U&Çr´ZÓÎ^D%¯Q#]+“š{Ryì)‰~Q9¤ìÐÒÎë/¨Òþ“‰m;«›ï¹{°wb¬sñégª#·ÝöÆî#G»ý¾¶{jê{‡?ô¡iÄlC«÷B¥—x/ªnëܪ¸|úô®‘ë×aú™g¾òúM¿ðâׯ]ÓKWɨßö±ª[n>Y]<õxµ|ùJÕÇÐÛÖüôìµÞÄR­óª5Çê¬Õ±wêR¼¬™¦sqÒø“"½ª/ ¬ qE»ºuëx~[º:õÞäh5¾mG8“lÔSêØyÉpâøqî¼\`ˬÛÈÿÅ(Øè†‰Â¤Ù‚Œ48‚èß7Ÿø9À8µáï ©ÁMªø£…ÞìFùÚ/0 @Àix“û’²%†  A.Ðß5PåáD€âê“ÆŽK: ¡Š€àfps"¦ ü\‡‘/™ov𳦿¢ûKznŸ>†I×Ó*ñ­à Æl}5NËxl§Rü´ÿ€éýµe¹¼rzBÎáöíÞ3âÚ9or=s¤Y€Ž–º2þáèã?ãÕ˜ö°ÿäø½wW»„óú¿û3ɸîYM¨lÿÑ£nºë®ÇŽÝu××¶íÚõí[>ö±ón^{h5ðw¤ßWGuµÕla ffö^yòɇ¦OŸþÂì›ovúÕWŽ_¿rYÆzISòzÏŸ:PFUËó‹ÕÑ»î¨î¼ó®êÒSOU+—.W+Úˆ5Ð.l½vMjã¿®œX¿vdyô«ÛŒöº2,+šÞå¹í¥E=¿-3/lþ®~ìÆR™RkZ(XS·¿¢G´—ài–@ú@ïèò.9Ú;Àþfx¶›ƒ¼qÐFQ2{ähCÃPŒŠ²9Vµ;ÖRåžà)Žu0¯¤ ‡9†®BÁqBžaP:rðÏš£.Uˆ!x ’‰;™ÅæEC¦…kâÜHè\ü8/ä‡r‚JŠÜTÊ2?Òd~Ш…Ôa~Y¯W^0y ¨àrpbƒ.kOÈ¢ þ¢Før¹ÎÖ4½?àSò»ÚHÚY—ÁÕ#|b,—R›ú´Œ4к¾œÈµŽ®”žœÂÑíͰ)UõàXtí±3¨ëV;ümü»žèkdT×ÃÄN9wÞYMÈ 9÷̳z§…êT}œ¯5œY…S»ª}‡ÏÈxlÿÍÇ¿½ýÈ‘GïýÄ'N»°=´ø)j oåŸb-ë­ªù‹o]zéì箼öòçÞ>õøC3¦÷]¿|YïòïW#ê eEö”΃±¤Qþ#Gª»?ðÁjîôKÕÂ…éjuþº?£ÿuužÿïËã¯.™­ØêP½¹‹§d-Ò𬠾ªÎwe¾¯7´ÑÍ«s×»p´â«ŸvyÛÎA,¨“îi©@F¢Ç«†5 Ó““ZÓåÑÂQ6"⨜G¿hM>f˜{°4£áMïJØwh\ii¿ƒiÒ¸©i…‡‹}Ç‚Y¨ ZÐé˜dR€ ”òRFgeH\ì<Cð7‡È[—5UÔ[ËŠB H1¦(ßX®>ÔJPº°-¹¡0«Ð†´`6„Q¬rdåÓ»TèOðjèª×[–Ñ_”‘_”Áç }ŒúûKrïô@ Áû9ô žÏçDðòžu{¾?ß+'Q—Ò 'gTËlðã[ŒèÙusä\èÇ›&}Råô˜Ðcª/„30Ƶ¢e%ì«£·ÝZu®ÍTW^{Í˨ȡÎ4g]íÀ©Ý¾sgµëÀõ›ïºã»S=²ç–›ýà/>ô´Eh­þ–5àÛîo™gËn k`éÌ™;f^~ñ3W^yý‹çž}þ³Wßxcû¼6ß ÔIòn:J[ :y[ L™èb™šÝ®‘Ó]÷Þ[õ/]ªæÏž«Vµ+ãÏ@_€{juÚ•– b6 èYà=ívt0RQ#.{> ´{˜`_@Ì DšÖ4ée88 @Ù7 rµc½«—¼ÈHÐFz8ã¤õØ!ñ÷ lÔf š¬[MFCY·?n<·ÜÅp¡Ùe­.; d&à›((m:Ô€96ž¢:™\Ð ÃÙ„Ì-\H‚OÒ$Q( 6ˆ ¦t¶+Ê<õóÙÒ~Ž r}òpw³×ÇqM†rY×ÁNâ•=ñ¡Y¡þ"ÎÜ7]T%ßRíÑzþ Ù¡¯Ù!­çÛSÐׄҚ¦ýûÒ›ŸPYgL¯’Ñyä}E¿´ÇzÜ/–¢¥Ù+¢—üÄKä0SÀRÀ(3FrvìÙSí—C»|þ\µtåŠÊxv¥°7sävŠü"µ½ ;ôÔÊžý¡?uòï}ø›»OÿÃÿûßøþ—¿üå j„_Z üM4P.í¿ iKÓj 4pýÅ?tõ•W>wù…¿péµW¼úÆ™±yí¬ö¨H)##_h²4îD‹U°áaxI £÷/Öóo;y²šPÇ:öíjU¼Lÿ3 GûØüÇ™€ŒV‚i]¶m­+Ï×Ú`K/Éþp^D/KGKmL¯1‹°"“ÁO{ Xe{–˜ `¦@Ütäq/FìÇi1RÌ&C…¾†œ¦“G&˜ˆÑãëÀ2cÊòQµç€c|´+¥ÿš‹—…ÐV” æ`3™…4Ó7"·!…kd =$(rP'„ô0$®!djê!N@Ñ{¸ASŽŠ õ P¦q€ÁV} óš^ð„‘ç%<8‚,ᬮjú^Æ~Uç©ý5^ù¼$ü޾¾ÇFP‘³)Ö6ÌoE=«G‰~¼€H»>Ä]°õÕE® ‰1!ÃS::¡s¢óc¯ε(eà™ÑHÙí ©"ÇáaØà<è%¥íjýç¾½Õ6-q-ž;WõpN¡+<ã¤0›@+ÔE>OÊ p}ëÇìÑÞëǎ¿tâ|dç¡ßZÙ»÷±x`Aèmh5ð7Òw|Z üĸöçO<0wéÜC—ž}îáËo¾ùÉ˯¿Þ]Ö:½Ì­ÖWÕ©ªWæâRæNº®ðì³ÜÈ*P§Û×Úí!M…î;t°ZÖ>•«³ZX’ñ—yö€L4#s¶~ €nZŒdHüÅ~ùœØ ý $#c¨’ð1—¾¦“1@|mPQyÕ‘›15̨Æâ ðdyͨw††òp WƒØ\¨/ ¤ µœÀ3壬ã$0RTÌ43i½Y”Ò!±ŒEÚeT3Òo i0òÝË‘!ôM:z ÐºTç$èÂx—3·±"ðõcDnQ )ƒ¹68Ò-†Sî‘·tÌÛôúÒkŸG75Ê­Gõ2ìþñ˰lC«¿®¸ÞÚÐj௥…—^úøôSO=|ñ…—¾píì[½ræmÒ4*—UèiÇ<ó®a è&Õª‹Î.Æ¡Ñ{fUÂ-{@ƒ…'íàß&¾ñîþužÚ``M;üY+å#@qØéÝÑåFn¼ƒcþ®cX YºñÒýz$ŽÁ ïQ¨ÒÌ"àÈFÙAðgˆí`äs†cÉ`1æŸÍdúœîªu½§ØÎ„ÊýŽ"Ê…+ÃÁttG3²$¹â0‚ÁIÐf²ÑBÌ„c ã":¾vè/ ×Ë !ÚT,0Å螬U w; q^… £« *‘ò€lhœÃ@-F]ç‡À.íÓ9ðO#óuëK:!_“ÑêëÜ0š]Õt=† ›Æ0ÁõÅ\Ô÷¤´Ú§Á|GÓŽíEXOçP§Ú'Eû‰ Á0îˆÂëxŽGm}0¡‰Ú¨óË,û5X¾ÑÇ#8ã¥Eu3ÒàZ²:ñxT”/Â1ãœ`¡ÙûÁL3<Ôã—TÉàÑR¾ ° 'Y&´W`—Þ;Á~˜QSÔ¦Ä;ÒQîs)$œô®jk:fHpFUÿ¶©rNœÛwÓñïî?yó×4ãôØßûõ_ÛŒÛC«£æ5øcÐÚ¢­¨¯|å+½Ïßw߃—ŸþáK/¿ò+žÿá‡f®U+ ÑÁö´ÞíC@wÊ|´»VŽê±lc8^ÒÅÔocÝ1#:ÖûG.\ª¦Ô±MlßþéAfÖå ¼þ¯±¹6­² ×ÿÊØÈð4ÀÈ8£< öQSDî<©%¥$v¯¸9% Á£.F¬b°*c]mU{yÊ`UO àv¬ 4z…F?tÁܶ:*¡L;Ì×dˆØa¾.#¿®§úúñJY;6bAÏ\…ö§©@=¾ŒUGÓÓØ †ÑœÉÐô(#/ñVC N„¿?¯<†LþŒ$x¤Ã°XïöÌD €Îò=³’;Ì, òd¼¥{-”@«BÖÞ=“"Ã?P[ü!œ4íÆ0+/¼Ž^šfÜ’Ñ £ÿŽ>ŸÛըܖF¤”¾Úl\Î’¼i A‘Š6)RVעߗñåb”„2Ìxúi½½[vé[nòšT8b©ŸDƒ•x*‹@¤Uà<èM?ÏP¨}£z/9ñ@Å8fš]@Ξ86Žêþàš]œ™©öíÝë ~8—TÊ(?® ÎIÔÉ‹­|u*Ë“,4ѧ e|.Vøø5á\õUϘ–3&õîýÇ]9rûíß;öüÁîþð¦}ðŒÐÚÐjààúiC«ZgOÚ¶m¬ûàÅg^øÂµW_ý•‹/¿üÁ¹‹—ü5´ëج±ªsr'¬þØ=(==ft¥ŽèªJß`_mÑÝy„^ÊMj:ñÅŠi£×àí³Õ„zêí;x÷:0_×Ë~¼cš)bMwdˆmb”Ö ªÉ=ÚÌÅMÆŠà>Ó©8äE_Ä¡1K¯êãîôuŠ^å6tD1Ãð£bʳ­ÇƵ g€2uâ¼aŽÑ.i–èÖq0NÌ£?ÃÕ±óAdd­ßf]Æ{#*ø0}¶f\†<8¦µÊâ»ë|•FpÍsËø)îK0Ö)óëlUA0…C9Yi¾,l¨)šq‘„bŒ6£u9q6FúÎ=^ &´‚"IíëSUE@ÏX™YÞèh´lg€GòôgY¬)¨©ãæ`N“³]@IDAT®kA(<£½ bö] UFó«làc„OCqˆ"NëI­HKÉÅj1].Á©+ rÂÂ×èø •¾®AÏÂ0£ ºp¸¸>yùO¡Àõ‡°¦§t1T‡nºÉK}ÚQ-C÷®K•vXäWž3@(â ÓISÊì”VkÇ…„NËdèf»föí?4ìž»¾»ÿ–“ßÞwäÄ7O~ò£?4ÓöÐj@h^g­B¶¨Î?õÔöñ••‡¦Ÿ{áá˧øÐ•7Μœ•Ñ_UGÂPܱr¥¨ƒÂ84/šÚ£;ŒI)$)€þH#Q@Ù1“%˜ «AÐ0‡©üþ[g«Ñ¹ë^#÷|Ä«# È´?#>↙úUm*cT>¹sB›ñ4úCXýcé_ Y pÒ®•ƒ~žrU‡îÚetðtΔ«k6^޲ïr˜ÚVwË ÄLic‹×ä€ð"å’XSß‘ö4¹ ªñÅG€?ܯ[ÛAÓ”¸¶9è+ˆë= 1†O´Ku@ź2NEµ>¦´xHÖfzc¼i|â»ÁèB?-§G ]øÄÐÒvÒ«MŒâ=cµ¦Ÿø[ Kõ%/ÐÑ…àŽkú‚'1Øû á©T'|Ÿ{¬}ñ›f¹xñÀÀÙŠë@­S=´n aûš¾ô´¤½Ïx¨>Æ‘‡6‹\a]žŠß©¼GÔ¥Ñép‹ ".tÐz¶„DñØ çra^›Qum²¹Ó¹6TV;eF@Ø1a³*›@;f€å³F%Hã0 C†k"NÎ@”ˆà¼pˆƒEÙ+àâ€SH97«÷ͨÎÚS3µo¿Þ±q×÷ö=üèþ;îxäŽüÉÚÖՀ¯“-Ûú-Üð¹'ž80?;ûÐÌëoþêô³ÏüêշϹxÑÆ”©L-rª‰Ž‰¾›à®I½¬º×Òû¸«Š4P÷HyIE×››ÓÌ ĨЙ&¼F0ðeTå‘ïÛçªî•Œ¾Lƒä(²xîY#~:7 ëÿìÀãÓÀ”ñÐÞ¸¦ØÇöl3 ËÔ†±$ôJÕ «…4Ñ¿LP/ú1º:wOõ*Ï”lO#=î¥0yª³U‡¿‚<?dIç@íÆ¨1 ÀR‚М_)3”yŠ]Þxº–üXJ`Ée Ü@K Àù beœ¥Wo~ל8Ž{ hÜò<Ä x„'½¢6kâ ±ž<€Ø³ *’¥^×;Ë 8 ì‡WEذcà}.ŠÃD-²vLrqé ,Ö~M:DÑÈRô‚ôˆ•zµŸc ™ È`?XÓRâ~gBõ(Ïå!4ª÷:¾øðH©Í#ô*FM)®:è-ú*°Ð¨hQˆaçuQÃ8ç…ÎåXÑÈiö²øit?΋«`¤_^#"ò‹uΊÕ^®ŸqMËãLê…RëÒ³…‚´TjNÎXpŽeàå¾A.gÅ€3ë?Ó¡{• !Þ/Ðà#(Ü+8ÍkZ*ئ·î9p°Ú{ìènýèGÝ{âľ6;û½OúÓx`mØBðå³…Ú»¥›:¸üöñ‹/¼þÐôSOÿÚ…_zhîÂù©9}ú—¦Oý]9zr¯‚Æ„€‰ÝÉÔźƒW‡ZʉåŸB_atB‘áÌ#ðE4¨Tƃ7ÐóÿÕ•«ík ,#.3${¢Ÿ:2Ð`ë‘©¦Û;YSëêš»®^Ö3µ]Ó°2,nœIܱS‹EQTìRaFûÔk‹1};iþ Š™Œ~<Ý uì0TItºÊÚ€ÑáR&+ŸË^7—á¯g Ô/%0£¡æØ–J§´Û³ ’-Ï&¨½*aˆK È&‡Bm³sPýfĉD#6žâ ¤aFÛ9 Ø()"ñ’Ógùp P½ŒöÑÆÏ$xQ8ªÀ/Æߎ õâ¸ýа‡ý¢ô$UELõ¯W3±ŸSmÓä…œ+ê >NÓùò0jŒö­oQÓ.i-:˨w Ü|ó+'?tÿ7§ôÂ}‡ÿñÁûîÓÛ·Úð³®.6ü k€ó\}í5Œ¾¦÷Oê⫯î\Òcv¬µÛ ií’à~‡ÎBBt(ÀXÞ#¦úKO’Í«'làUw]‰ŽÒFÕ!Á¥ÿ ¸ä¢®¾f:rºeªŸéü–Re]˨X_gc†›NŽ©úu}·Ïÿt4%=¢Nw‚¶€[êÊúh6 £ŠàŽ[i ——”î2l%vOÊ®oÊ”G??¢?"ÇbбR¯ .ƈŸ¡[?§vx“œŒSËn¯/ÊÉóóX_LlèÅ+Ê9+%­z<³?ñTåCÍëšQè‡UÑ([9|ít‹ ­)•“èl°¤ž(չвƒv˜)¯iwá­ q™²§*o#oÓŒS¸á$ô¥/;•‚®td‡…ó­Ñý@3 ì…HÇ õ#†(KZhá+QáC ŽŸÎ?p2nõñ˜þÏŽB3Ï5oR¡q=¸YJs Ó…Ù”ª«uµ¼äkXW®9C\±á2D`o›3qjÀ¸6úñUÈT™ 3éòSTÒ@‚--Ⱥt9ʼnò²3†ÒDn\ $í®‚©B×éºËµŽ£ªÙ /Mè"Ú¿¿:xˉ³7Ý}÷£{ýúþcÇþ¤ý`‘OÇÏä!®´ŸÉ¦mÝFÍ=ÿüæ.\xèü~ðkW_}ýç/¾þÚäòõw~FŸÑ=eX¢(u°ôî0"¢ËÎÇ×H@Þ=Rt þÆPݱup7M)ïM„ô\êpÝék€FúLãĺ¾ºg k˜l ÖG…]õl‹Îo¢šÐ2€ú`ï±¢.ªPDƒAž½nôŒtŽv=užtèÊ€ñha:á Ï΂ê¥ceÝ™Ý÷ü¬GÑ"Z¹¨‡´ð¨Êæ‘úõÃгT€d À/ÂÑÈÌÆ^˜,qçiQáÛ°A¯?š ó“ÄŒ’ùgÓœåÑÁ<-enÉ”e†"H`l9»1÷r²S·J }lÒC£j=dÆñ¾΃¬8qYÞ€'£n 8N?ÉC€/z‚{ð ýYvÁù:r™ñ¡òs>4ɇA§*t“8Qùp„Éy‡Æ|tn%ã ¯ž½&çiYÛ&µÙoBíKˆ Åq\ \3\,%È×'à0ÀArpyA'l]¿@LÁì#}äNlZ\ŠüãPÒ7Æà#S†Hêš6%íV™Dè;œDàÛv犯<9pà–[¾>65õ{?ûÙ7’G¿ÿ50¼"ÞÿmÙÒ-¸têÔÝ«Wg~ëÉ'ýÒé—~þÚÙ³½=OáÃ6<²D:îrºr‡ÒÀ]–—yý+›]Ó†ÑÍБ(Ù ‰lÐGF(8G‡›}¥k¥Ã*ÕdžjtDTÁ¯èôæ´îåkz©› Iq0ø#¶r’EÕuGl–¨—Q5 Zy­&¦¶Õ˪¢騲ŽuÐD³t‚^Ç-±;y ¯‡¼ÜãÚ8Еȳ û$íGº0úg­^ÓK-Tp–:pl §}ÈC©Í¹Êp€ìøUcôíÈ`ÄCHO»ËaÐÌíß*ªÖ¦ƒ|…'þxÙðQ›UgÍ›¿Ä±cŽ ¨)C;HÐײZrÖ©œýÒ5 õ2rŒæi3K¼.u T_CÊ`ìŽ|´þÔu£@;8£“&¤\ð†gâ “€%´5p9$ø£<4¢ çS`¦•FÇ|Ipmm¶êè ”Áˆ––ôšßäe†8}]¿à³ˆó€C8¡1ÀëY…×$ÎhÀ¢nÏp ‡+,Páî+IõD{,JƒÅ^`»z˜KnS‹0x‹sä| Ò?yˆ3|GcTç“Ofï?~üÚá;îøîÍ÷ßÿµGýáÑ{ï}ƒªÚðþÕ@}m¼›°u%¿ø§§>2wþí/^ÕãzžîS3§; sóê4Ugƒ1£ƒµO5ÑKº)ú`åJ J[ïN)ËA0Nt6É…ÑKvªF*8äÍGuÚ™MépA:¦”ŠèÜe9„³vþ|Õ½tE{˜Ð9ÅG€Á$‹G±GáKˆ5íЫxÄBïä×Ó¼•P¨¦qÈŽ×ÍÑzꑃöèG÷ÉT¾™ÏL(—áQ§îF©Ü“¬´×t,«ˆ¡+> ÀHè‡ñ‚7G¯Å f#)Hlö“Q—°±ôÂè_mò XFZmöSÐ+ϨÞ%*ïѾl4ôÀUcÀ¨‹qº¯`œ,•»C Oh”Œ]d5A|мÄüÓ.· ŠÐ…_¸c”… 씘+ôð_%³܉pR4o#’'PŽˆÄM|‘¹æ ä…é2ËÙ¤§Þh¼8gÄÍ$.+å!9¸nWç=ýï §Ú8¢M}búSì«L@×׆~^ÐhÀ˜®ÅøVAܦ(•û²QXp2_׿ O— oÕFÂI}î˜×½ûî?Ù}üØ·Ürç#·êE{Üì(§v³‹¹uåûã?þã‘<øKWN¿òùs?xâóÚÄ÷k2Ž«šžó›ø´žï“ÈÞQ1²oUßø:ø?:Ž¥; ¥F±Ò00AÀˈù7 M¬4 ŽEŸ£^Û,ÑdçA‡žQ”ìMê:”ȵáåóªÎôe;Dž@F¯ýSò~®˜æy>–È£7º ÔŸ\ÊGïÇèßQ è8±åÞ6…=af´Ûš*1ïËñÌ´úøÚѱ2ø# æË&L²Ù©]1µ/ÓM4Èñ?€V® ®” cnq"tì-^D ºþuo¥8ȃƒçO`CŒ²¥*t>_f 2•cìÉòƒ—¼ÕVÓ)^Hj\x' gʲ)㟼ˆó§dÍË´£.äpž©úà Nâ%ÿЂàÀSœxð² ‰'×:!fæeE¡êÏΪ.iLûeýá 9¾°á§Žè¸^ ‡aI³`Bo´Ô4¡½ST‡n»í‰©ÃG¾yðŽß~úÊì÷¾ô¥/Õ¾!¼Û°y4gsóÈÓJ" h·þ.~?så­3¿zî‰Ç?wùÌ™[g´)κ >¯Í]èîÕÒp2r>nzÜ×-=›pJoP"”žÉäa€2ä36™}W"O‹ˆÎ„˜>V2Ït DU‚QD+ú2²kÓÓr.V#ê\°tžPÒ¦¥ôöét4`Ìæ9›/–0Κ®×‹Œ&¶i„zÊl#Õ’Qm8â8ÍssJظ‹|õßâ-£¯Ñ>¬qÇ,Ž€LºHSœ,O´Gûß ã ŽGþTªìИ†afôîŸqeÕvÎ4±Çu(M^¤ýò!rÀÊå´Á¿’:ð@F¨ÄCxôÊ^:¦Öà®ð (²†Q†>ð©€À£îÀ ˜t§ë~9"‡SâãPFHžYFÌÛÓG—eϱáX‡o”ïˆüÅQ¡§3¸ËËèŸ\ÍË]×ô·½ÍØ<ç<ÁpbS褀}GÅÛ)qR! W¨µ©^ˆþ6OhžóÍ#Õ”dö‡?Üw}zú—æÎ¼õëo?ùäç/½ñúá™éKq[Ëèðžñr¶èä¹Yçþ#KïÎÀiÝÀ.G‘ÂIÙe‘¥óË΃RòÑ!^ ©Bª4¾™`à0C")O×Eèjç7ÊéÎE&mq;ŠT‘½}í¢ëŸŸÖÀŪ§%€‘ꪽâ.9<@¬ãð®Uñºö`f´÷ÚœõÞjt—ÞËîw¸Iõhˆ¶`Ü2v§¬ŒßÃCuÒôí¹æ#À2OÃã€ÅKÔ‘#¼•©Ó æNódCT :¢íi”“Ôœƒ˜¾§32œ>ÿA¨öCÇ{lÜi¯`Þ ,N4ŽúÈ2ZÇ(x“PàZ1_Ä3ˆ Žbê oòà+©,£²ðˆ€¤ú£.Ãã*³üÊVÀ¼ü`¢`J\‡`9°žàž§ùEò‰§Ó—´)© Y“Nú§Ð¼K6 —YÛÑ> 7×,²-kóßêÜ¢vþ3_¡úŒp¥Ç{z Ð'™ ©W'<ê@×GÍKKÛví¬öÞ„ ë‡÷€/R®;ç!óÈšå\V-.1çT‹Î‡SDËT"§”,ÌÌ#êñÞÀ”éèë³\ ä¹ïã Ë+†XÞàYçU8°‰YeL¤ÿ‚³‰°¯%®é]|½ðä‰sGî½÷ÑGŽ|]›"¿{ä#¹¿6¼wð){ïªßÚ5/œ>}ìÊk¯}úÚ›o~ñü‹/}úÒ+/š»¢Ç¸Ôqôôè”oV©ÉÃw™¢7åéÔ¸éÃÀæMª®€3[nò\nLÝ9nTF'ÐñÁÜ¥!ðQ¾ð1ánê§Cu'‚À–¯l v‘0£›†¾t=8 J{d§¶¯]˜®ª «®Ö^Yóg€Ž„ÒÍQ1©'è´¥V·îl%›;Maäq?wæÒkü¨É#}ÚE¹ ¿Ï {–A¡Ò†)PÀÜ)“غ-å !;XhwÄc{Æ>Úg“áW;+²à±AÎ3|'zŠq¢÷ F[à†<£åMK‘‚åÎ'!i¨­*2oã¹XÔEYp žãJÅ'`Á7h(çÎ e¤£Ž(«ëQÝëž®Hš”|þÄ@ÿ¦×¹‡´ä(¼›14‰Çõç™ѯH¯+×çe°—tÉÐ+ýÁëìУ¥£z @¸°t}º.üçkB@ýcŠíh iÛî©j¯¾lɵÃ,Nà ¥š¤mÌš!/5_—\7Xs6ó)Ðrý+ã„Tp掶„5NÐPF€’À³+™„."¸¢'uðýSê Ê‚/Aቼ°°s ˜7 òäܾkW¥Ç §÷¼ùOöÜ|ó×÷ÜvÛwnýÈGÞHÞmüw§ÎUþ5pùÏþìØâÜÜg¦øÃ߸òÆ¿|áô+{¯ÏyT×Ó(¿çóD‡Êˆ/îFEJ q¹Ù¢w¶ôa¨‡ á¦5>g<î<È”tG£ØýÏÄ@Ø#Sêó­8Í8 ¨,±‡4Ñ=ÇèÑ–E]S [4Œ¥ƒbÞü¶ªéÿ¾8¢NߎSãxáõã…str84ì°V×mÓÏst]˜Æìãlä‹qEìRµ;*dŠu~Šå:л1ôWÚ¯’¼ÑÍ´Ë€cü#ÿ ©c Õí+Ý0 è£Ì‚@¤f(Xœ/Î5Á£wbþpÔ^œ Þ+ð0(¼<’ب4u ¿H Õò4œáS)†9p £(x*&xŠ€€>\Odíä ¿ ¤Ó˜C¥I†sF 8qÎ$ x–‰éÀ €Û(¡ÌŸÓ6ð9;È´Ç„á @‡Ç~¾ƒ±:/ /€ÆnDOô´=p'Ï_2¼÷}q}lpމëJ'ZpÜ Ža¡`¸`\[ú”(Â@ÓŽºÂsu“#pª,÷ˆq‘ApJ,“Àä#ÒÁ! Ì„¦¢<ê ”¤¤³f.÷ÛRGP†\ +Ï¿dâ>]ã;#JOlŸ¬ž89³ëà¡ïÞü±þÁãw|çÐýw¾ ÿ6üô5ÀYjÃOY‹gÏÞ|ý7>÷ö3Ï~aúÙg?}ñÌ›»—g¯ûS¶£<£ÏMt_r›ÙH”{Ãà{S>ßÜM§0oêÜ „«*}J ‹·`Î7È6&ƒ.ùg.Y¸ój\A)­¥4¾ù c N”€0è #pe dl×ô1¢fFôÅ?€žhŠ# >ŸêN’!­xtxk zëÒ•+¦3޲‘mú’¡Þ Ès„”‚~ y=O™zJꕦß‘ÒÂð³žK‡/ýzz™… 4¡2jÆx:ÀuMb ™r9¯:ÑJÅT³Ï;EcÌQû5¼¾ xÊô è<ío¸*àƒC\7Àíô«|8fkæ´' }áùº“`iÔÍÖò WpÎ YǦ/ü\†äÉ?LMâÅ9UyÑAÀC§Ð ”ÀÉãg>dEȦ2Å(¾¦OX¡ˆ¼”©HSF¡ùP0.ð:mó«%}aEß$Ðg¯zÕt5®Í{rDý±"½¸72|Pð ꙣ"KDž-R¼mŠ€£6ê:‰4Ã?<‚¤ðåçs÷«qáÍ Œ 9y_®Ê!ðf?PH› ÉëNPšsŽƒ 8ZJÊä.?(2&¸œTMO=d 4äášH¹ˆRð çp|b²ÚyðÀÂM÷ÞûýƒwÜþÈÔÍ7?zò£í× ­¼ŸÒaxfJlU¶zïíW^|ñ‹^<ýù³Ï<ýË×ξ=9mNw¼:žMWÇ`cï;J7 ÷ xžß7n%ñê4žÀ5]tÊ™¥¡ï07ŸÓƒ²& p#ù·°né$U±1eÈFùèäK¹zl(:J”Vo”|Õd‰`¡¯Y;ÚÐc@”ó˜_¬ýËè“F:ÁÝ!²€àýU±©¬ŸR9£cu€zÝìÈ.½Ç];?ɆnȹM‘ÄLÒá0AWJ…çQ™Î›;QÁUªt0 óOç†Ù‚ÜX’)ĆO|™Ÿ@ëì4/Ò[íŒðÑç,~H/ˆ2,¼Ôâ¢_õ,I`ÂÑ?¯öY% ¯ÈQi¹Ö<$XÓÀ‰à|Kp L’8me‰FEà@|×h<òÔ×3-pó ƒùÜà´X ›€Gð†3ËN)æö&|ƒ™óÊBkIðÀšøÈlâ\ƒfU·­-êËz Ò›ÿ¸ø×W•–žÛvT=œvꂉ¯"®‹¼^&÷ì­ö9¬y(ÕSÎ!× ¤ÜWÐ(Cl> X]8Âç6è ü€Cº0ªàQQ.ýù P•8Ö½”y˜)X–[¥ƒK”Eýq.‘}C_`îãĉj¸c†š6 &ñŒ‰®å5Ýï|æ{L/OšÚ¿opøÞ{¾·÷رoí¹ýöoÜùó?ÿdMÐ&þV4çøo…ÙVg2wúô}—_xásZ×ÿâ[O?ói½¯» Gˆ:2ø£LíËxøNÐ…ncï›2On­ì±Š"¹Ù¸¡éÀÀŠ› `ÐpSÇ Yò¼¶dP|þâ¶Ø ÃÿÂ(àÈSO!Väþ¼~Þ$O‘Ò wTD™ò¼ †·¾ ©=A^z úB‹[ó(#AéjõÒem¼ gýµ£X†ž5~fΣUàYŒ¾`îõÞûu}`†NFê×ìpdÜ·k‰Eò|>Ò6 5§Ã£7œ"ýy*‡Y÷>Uˆ6pñåèÒõ'2üÊÂiÐAø‹ÔtV„ô,/ÇñˆJ'VbK^|TùÈ%Ò c@8èÀùœ§Ý2”¦GeœŒ%`Œ ;5Þ®Øu¼"ú £B7?®$yŽàäÕeÃG<#)Ù¢ÛGFð !¦íÀ,›b€tá‹1Šöu¬ðlËB.ê0~ÊÛ( ŒÀquYÈÄk™ûK U_/Ôâ¤ô b–•:¡^.Ù.@ÏósMï OLø÷…P®Ñú:ѵ¶c¯€ÃGÊu‹6Â8¦§-\füp®¯+*QÞ×#eÊ»ã8¦ï•¸§ ®ÊÀƒm“6Óv%õ8ÀKm G1¨¸Ö]AÄЛ'KÄÖ…@q[| ú@L|sP½þ‘b© ¿¼Tê+Š»¨ÞzÛ_î¾éØ£ûïºãÑõÝïþ»/ùËqš ‹6úÉ5àsö““µ©™çŸÿ„Öó?套õÜË/òÚ[gª¥ëz1F ]íÞ÷Æ0!ÓùúnÈ«¿qsp¹Ç"Ä<#pøöáÆˆC)JãVI"Šk*¸fv#Iá2Œ áÆU„Å ‡É`vâT`”‚776ÁM+7/7…À‘Ë \tîÜ»LD¬à»ÿÞ–/_®V40ªÑŸôÅØûƒ@âÎŒ@l K+FtP>¬±otÍÞ‡­|ÇÄ[nÁ®Ñx¢¢Àù­cDN™âgÀN‚b·S`<ÊŽ:v•ñŒ·å-£=§M«©n‹%¸x›Ñr‡¯ç©^Ï0÷ÄׇtO 0Œ,m0Bö Ò<‡±&ÆHv8_äy¡ÓÊ€ ?b΄‹7°RîH× ž“ÖmwÁ¢v– Â’‡$dv•;_……üÃz…Žz’ÞùBŸ0tJ Ÿ2sõEì3dÝG~X§ó–¡0‘B:7E-¥]¡Ÿ¾Þv׿^žû×yÆáÀkÃùõùßQuôh)¡v€%‹¯bN¶Î¿kc¦HùŽ®‘ûä:dÁü$‹0¾P9G»J£àË•R8Ü! h8 ®Î4kž¢5ÁÍ_‡ý‡QŽ{ÅH¥ð{Y¢0ÊQhÉØÑW:Ë@'G¾ yÃ̰hY² 4N™ÜxÁ̼ø>AU¯%÷»vßtôŽ'O~kûÁ½ßÜÿ±¿sË-·0õ׆ŸPq^~B¢­Ž~åñÇ?uùÕ×5µÿÔ®œ9óáËož©Vôf¬®ví÷F5Õ¬a#£’º÷L…ù/W¹`ô-õ]çd”^Š d#¢ï”\ øðkÔG!†B^{ðòŤD|‹Ò`^¿Lè|HdÔ|!5OÁàbÕ€ `G‚€×RHíRщÂU Z%‹cîë@ç‰G ™]ÛupµëÐá7ÝÿÁGvŸ8ñÍɃ»åÃÖGDÚð×Ñ@Qï_uëâ N}{úò§æç¾ð¶ÞÆwíí³¸tæŒ>¢×Îò¸Ïè놧³Ì›Íz$_;¨k£ ä…È¡¾î#kpÞª)”…ˆ®GGÀ7TUŠUPî%§’J\%Èð¦Œ<4Áµ%O3AB¢è )e åMœs‰Âª‘àa‚„[øòî€Öé—®ÍÈ8_õ4"óÈ_–ŒJ=mòcªÀ_D*ИÊ'îûÓµztPŸ¯Åh#Ev´N±c»Ì¶– G›io"Œ~y•V†Q?å™QîѼ™-P¬:&Ï"”rkC4¡ˆAC#„p>°VÃPbxeÔm´Ñ¯ÑcîWËhc¼ãÕ%ý‰ÀŽ4Òc<-Àù6d€2ZžâPÄ&C½3Áíã¼éG³ îÿÇÞ»ýø–\÷}¿K_Ï}Ä™ápLš"u1#°õ‰–,;€%ÇAŒ ï~Iž¿$_ôç $ƒ€1 ËL+ 3‘ ‘#™”`’ÒŒDrfN÷éÓ}úôå÷Ëçó]µöoŸÃq’à!§º{W­[­ªZuݵkOô0U§ åCŸX6—ØM‰Ãõ3}Cy¼2JŽòõÏô€°ãpõÇA€®a=(¾Ù eèc<ÁqÑžä+]ˆcôâÛéÏOFœôÚ†0—þ¯=Þ–ç’•¤­ó}é©Ê^ïð=#ɉ.C/h²:¤`­ð€wà9!æ0±¡ñjª¢é׬_¸aáøò_;ÃÁ‰ß.¬@qb,>På˜HÜ\†¡¢(¸zéR—ô4ü#l¶&kÕYXˆ¾WÎÈþQujâ cÉ™D” £,¹"ÚWPe¦n 8+¬:H¾óèÑâcŸýÌ·ßøôgþÙ?óÙ_g@ð¿|ê/ÿåw”ô‘ûðèþpì1tûõ¯ž^_ÿ·¿üå¿ý§_ýý¿ñ?üß9ùηy.Eã@®¹È{¬0uzX÷¸™uÔã¸"KSM¸³\dùÅ-0…¬¿ø_` ÀÄû“_¶„¹ °À\ýͨEk£cg¢“?‚À*§Ô/xÐŒH%-ˆ<å:l‡^øŠG™j#¾i:žnð«ù‚uݲðìñI¾°o¸pÞ̽ç.§ºT._^tâ¶ð´;ãÚïoœê3Í÷mÌ`ìóâ±±“ß,ÊljÚndà úƒ› œ‰Ø¹¼+2)&,ÜÈjÀP|¨˜¶¢×ŽØf2ÂÕÙ°jƒ]„~±0§Ã$írëÏkvLs{cuöƒ<Ì ÞH s«=FÊjAhàe‘ƒé5¸¶(&YäãÁ‘Å¥ßHƒ¶}…G3©L´FJ›1^yÝG¸`è¤a\^~  ;¹¥ Trô¬@ãà*Jhô W~‡”Kâ,ôD/N{ó1Ë-ÿ3Ž´]¬9ôGåÔïñ?—b§eô\°`eèðzÑž,Oe›?üôמÈxðúë9O¡æP4Õ È=Ò>…Sñ*¿xôŠŽ½Æ%ªÜKF`fäà1åÒT,åß……J<䉆Sßão}"pÐídT4ð ½Â[¦výÌtí'˜¦d Æ-dQÉA„€ åê ½²¤Áe0@X¸  >¼{gñæg>ûþ£O¾ýo}îsÿø.§þÔ_ý«ßõ‘›å@òtþ±önÿìÏîž~ðÁ¿õÎoÿö¯~ç_~í—¾ýûÿ÷çžðA?‰éé_™éci±?tæ & +_ãÛ<›˜p×Ifè‰c‚Q1ÛðKtÅ ^’•T*pfÒU›C“†/º!W´.íM *Ðt}Iµ >y h9ÒF1d߈&É4ÐQ$ËF@ž4êòâæþ-{.NŸ,žó̓U¯0Â÷SÀyÀÁæíx]²Ž¾4ÒÛMíp ®rÐAw»ÀìÄxí耂ømSҌؘàOGNëâ_Î0;ýZ +Egg^U¤ØˆÉWB‰?½òËü/~3Ÿ ûc\rÆ;Û#r'™ä¡)Ò_·ÝlßnßÎÞA@Ñ“~y íM€Ê°ó5ötž¾vý-QøðW¹ !'0&J#¨îæ_:{ÒS±×WeÖ÷‚3¡8æÏÄz›ÿ¦Ž_8ˆ~ `Vä7“Ñ|Âõ{ש[`éQváÂ6ÿ‡k>Ó$Ôp¹zîïÎóvüo|mMnÓùçŽo ­Âã—}°fSo࣌K*¥›^º"ÉjxWïs>þkü,˜h&ê’Â:œûP²aêjT C+Ú‹÷Zâ7P Q*'­ÍÓôòè‚çÞá‘%3u?ѤǪÖ³ü -záT/ E0d!y¡Sby2hwÐÂy YS—üJGóCbžó»áUΛËçù ×_o|ô©?ÿøáŸ{û7Þþüçÿ)ÇyÿÏ?ÿwþÎ7v‚|}#ç~|3à;_ýê½½Íæßy÷7óW¿ýµ¯ýµï~ýêì}ž?ÓéûÝo7ò¥¶k—6–Uo:À°ãuyt4EW6Zv‹_î6ߨ|ð»<îjlZ6ÃsjùG%’ׂ«¨U¬|0a£Ÿ!<.haGnɃ4"&ÙŠý¦[ˆã‡¦a£N'l6qÈåFCZiu‚5çQWÙ4 |4Å·'.ÿ”O{`•9?Κòn tÃRÞa&2ßÙÞ²”k³®Ú>¡×™ç• :æLÚÉd[ð  o؈I¨nÐ@í2·{Þéc­úÈO¼†¹W'/<ìpk¾î´j3 ²:“ðšæ ÛÉô¯`ÉmŽtj  .:™]A0áxt–Zt%v " ^ƒd1¨ó€wôÚ p`“•™Þ‘%¿¾†/á‚ä™ü[¶“\ü ›‡8e8Hh~ïº~¸mã¼7ýNtUgpZvÕ•Aˆ™ü'(„C¾Vbçïæ²í󧬈 EfË^‰7­pgp¤«Ù)R_‘ã#退‹pÕÈå¤tþÙÅÛ„IIÚ±.ÃG¼ÚNžóF˜»?iõ ™ähW;œ"¤ÑþRXxd•|#žÀñËGÆT.U*×húëW´C¤…C¸I¾”k½$4<ã}X0XÍÏÈÐÒZ‡‚XÇ´­ÒWúA‡§B ±ÞÜðMËæèÎÝÅ×?öüíãçþùOüÌO}ñÍŸþéò©Ÿÿù¯+ñÇÑUîþ˜¥ü»ð÷7gg¿üÝßû½¿õÎW~÷?øÖ7>åLß@Övúö1'nnÜRQkäjãSÙוGšÎPlmÇ †%˜LS©À7“OØû•˜€¼ "àÓh×C£CL:þÄ1ÉSNº9ªaPÆäfaéD%Oðxí„x1,mf³aªÆ\’'}Ã9‚|ðälqñ.*nì#@:¼%Âܨd^ä|:Å=î¥Ë´» ì  F<4#•vpÎèm¨{µÏýû”wvö§ƒ¡¢vÿ³™<°zÞ_ü5«à’|Xû@ öÀÔ!Ý8D‰»ÓF;겦4V5*-õb7àóŒÝéX:|Hõ/ äçß7j|}fþvüâ„ÃA¯ª.äZ~ëÀŽk“ÇäSò¢Wq”½Vƨ ;@<øºó7ÑE_qT<Õ¿OÁ»so¾àFÞ4N±&Ž ÔŸ°ÿ 5.q¤žGAwñ´ìÈ‚ú†sùoìüY5Ú^sè«ÿÛù±"q`}·‡<``dJÊóx2™b&û¬?"ÿ—Í„FuÚ„Ç` ᤠéHfŒ@äªhcRŸ1#¬îâœU{bºR¾ ‡%ÏúG0ƒiÕ©”¬¢m^iò#¥"\¼yÌ¥"Ú¢xUF6ĵ®7ìåq¯ÿ†SÿVlBð+”Û•›G=þ×Á2x³Ç¥ÿí £òlé9´ ¯¸Êy–|#¾::Z;Ûót;µaÀyø5Àæ´R2²/‹Qka†´•ÝŽxíñš”¢)X×sÓª‘9ÒÛ<¼tò䦞ñlOè¸:ÀTD3Ñ[”‹ÿCi†Œ&@@Ùm ˜Ë(æB)5T!,¤B1QX§ý-C™ü4ÍÚ`EŒnHÁðú)ãã#io.þä§¿ôñŸú™/~ìs?ûOö~áK¦íGÙMyþ£˜È§¿û»ï[ßúÅ“wÞù•w¾üå¿É+{žðyÞÓã9Ï9È%Æ`#93­²JM {ÖBm¡ª\–×Î Šë¬FÝÁõÖ¤6Bí –˜4Ý¥kž¦xQõƒ¼Qe¾°ªÍ Èê$qá•ULpH§1Ð-VòD§WþQ]Oaª‘Ê @ÓQQmLä1îºÏf .œ³°téætöt`2ëçî#_ Ì@d­0£³aíM€¦Á’–ÌfñÙèçoV¬®ìùÙ>pnâJëfîìfçuí–ç <ÄÄÏ…«"ªÁ1µ¦T.vn`h„º#©Ž½gûâIF¸ì°ëu@dî¬äNW(?~éÓ5:Ó'Ìh»óweà†r1/µ_úü¡O ÔN9 Jžj;(žV¤§ƒ$©„LOí¶¯øà™n;hõ‘ +èI4´Ò Nú¶ ;ÓêP‹FÙ‘?hk 1Ò%-ñˆ×)³êÓ> ·3^¿y·3ÿ —–tìÉCö´ &n™ÎúC´¼Y’ÕЫãû<:r€¤6eoüDàÛá:ÙÅŠÀÿ™¯áÑÛ¼|9Ê:üú“»`´ e“ŽXtÁ‚5^úi JSRôïxÊ‘á“FWWîð¦šDFÑ5ÎÐË8aÁs‘÷…°å€%Þ\3}Ü1D†ôº ){ì6.YØÇ}~3¿‚b+¼–ÓfòXÆM*4l®å5bíÑþ<|‹O¿ýöï¼ùùŸûõGŸùÌ?ÿK¿ô¿ 1?R·Î›™DñLÿ­‹?ùæ/>þ£oüíw÷«¿ôÞ7¾ñÚÓ““4d+Þß]R!»RÅGlÓúh,±¾éó‰åZU4ßëÌ£îÑ%¦Cuÿ…¬VŒxtÕÀŒ@Â9Xÿ•%TâáçÅÚ¶C…úÃ/Í^ñîÄ)»*mÁæQýkyFÕÌd ¸|/ÿDIß„K®¦Ô€é[d´¿?;ÿ<€©O…ܲgà†Æ€Ùd#IÇÎ= ôh!²AO,m{oÖ³£Ûc`ûðyoVìð•Cžvçn’Á€#\¿B§H£“&ynS[V•Æ3™H'I¤ÉŒŽLö8ßXéÊlàg™ZOz9a4Rµ+#tRÕó3Ò]íõ(`Ü!ïÿžN¼y‡vÞˆnÚ¾ùâ¦IÊØ‰P« ”qÞ-?ï “Fñ@hÀg ½.ò˹ C÷"Pi~n¦)PýÁVÞ 3ÏõÛÈo®ùÐ'Gƾ)„KHDì@Ö‹?0ö”F4­ü ŒS¼e_Ù? ¨M䙃JŸÿ?äUÀ-qÇžÄ#¸mK;qmA§E0qåŸb MËW?èðX't%SŸ2šÆpû…¢G®#bòºÄ”®ø[ŽäB:W3‚®¤U\E!¥ S× &ë‚“¦\Å¢Ýu|À¿ÂíDÍÅÆ¯®…æŠþ»zÕÒ!z—'ˆÄD¸÷%%S怛¯n]±ÒSü¹OüÞÛñ/þ“£O|â‹ÿè·~ëýµ‘S§rI޼¢—,ïó›¿ü§_ùê¯~çþð¯}÷¾þú³36õP|õ…=k!©N]l…5*ŠgÒOÓæ†8\y‡áNã7âtƒ4ƼÁ9ÈðRX %xǾ!$þÁ#mƒ4´,”††™b0˜Î¨%sùVе:°ë<™ _rp{8M(]¿íº=ÎàÌïýjö² /0ìÂÓþ|DàÆÏ½ Æ0š h3¡§a·“—ß¾éèA‚HÏdÝ@˜w°@†h‚f–ºØÑšÞ˜ eÄO´wføúTG5üâÌÅtdÐkÏùz ´£Ó¿%¯ä©G %7göC«yÈ›Ç,úSHÊ,¸>õUtd+_¥]a`oHK>“,.Ëä±»JSÉ€œYQ¡¬‹ðàÆ½ýÒuß2ä0t™ñ›øƒ'Î<‡N \ðæ®|RéƒG¸³z:`—Ý8£g‡øvK¯nùå…žù_­‘O ÌÝ–XyŽ×·øøÓ»Z0ð5À­xpÈ6Ò…ì “ƒ€ûY²´üˆã€ȖΟ¼Ôôüi%ΊÍFñ†M…Y_x€ÏÃÒ8@õ^nw3‡+m„G¼5P(ŽŽO\Ù´‰L‘6Ob7Á[Ï’»Ëé Gi[/Œ]þ¸ØËÜñï% Ü¥Ñ"[ŸIauöŽÌŽÃ<³~™§Ú‹áD LÓ§“FR172 ÂI?÷œËÁ«ÈnàTÞ½×9ÓáSþÞþKé|øÖ›_øü¯üÊÿa¯èedÅ«§ýor8ϧ‹_þÖ¿øÿþ·ÿå×þÝ?ûÚ×>ñŒY£¯8í³‘Ïgoé[ Çi(Êœ„˜ô³ä'ëà—sFÒ F ¬a ²¸$¾ï%Üæ2#Pd Äd‘ƒEáƒ.úÆ?hc± /ËœþÅ@E=ÃÏÙFlÓMÜËøÿ¯°O¦”ÁŒ?ðnš4ÐÀ2€iµvðlqúî»œÊÆ{ý”aíøG³ôÏ=~:<»i»tÀ«\Jr ûXiUÄ€'4¦Â³îŸçû´é¸m! Ëò ùŸÎŽÎ}û®ìø<ó×V¤ónCoie žÆŸ´Óþã¸ðo§ž†ÕÄEºÌÇÊK®†s㙳{06XÙüâìè³ÀýÆNÎðcœùãn‡¨lÊ©ÁD„„¦hÅÙø+ êŠßòºÅÆŒyè¹8Êeq‰ƒ{Ø öà¼XÞý3Üø—é¥Ö¿„‚^¶W):ni4}ïƒpÓgù¨¿éÏ ˆYÿíKùhé€ Ü®ìÈMƒ—Â{ÿ‚|æO¦±-¹e+#îð˜ïÄÚ»6”z;òD=¦ÏG3xÄ!@^{Ç îPC³É ÜD¥„ذé¨\ÕD´MÃ8ôˆ_¹RGÆ/”¡åúa¿°âöšÜ+ ˆ ¥í/_qwb2" ´â-ŠÒµdEàÑ$•Pcƒy≠Âã¹%ê…ëPOi;ÞA1ébØ€4ÃJlGÒxiH àØvBài]-Gm&«†Öi’¸bºå±Ñ-+¾>ì7ÞúÜ_øÍ7?÷¹Hü‡ÿößû{ߌÈWèBª^-÷õ_ÿõßú¿~ëûÎß}ÿßü9_s÷þÁñq …2ÓüÏÏÔ¥G¸ýÂS® ÖYñbH!‘)NžI`A^„fβùå%/_Ð[\3ÅõÎyB3ä7™zªC‡?DL8ær†ˆx&þöŒÈ¦ô½ý[Ó°¼„o˜ü¶¯VDÏâ¯05ô+Vž_>[<~ç]ÞÍf¢Ìö¹w§¯Xª7,>;Ë j$gáßÙ*!Nq¥Ñc963=ÂòÈ ;µÁÇlõñdÖ“Þ³¾=V Ö¬¸_$+TütüЧ½…a› Ã,V²‹ÖFY­„tXŒyFë•+™á×üL·æQm¤ƒgç?îY1 c飳 P¬<þäOØ;qÉtDZðÒÏÖ…ïååpžRœPI˜f†\äC/y“È’!ÞßH»r•DqËpãC Šœ[:k<žú‡LLáÌ`Àý%Ž4Ùà×<Õ(%H¼áB>ô†Ðܵd¾öÖ[‹‡œRÇöód…Ùjz¼Ç?`SçK‚¤ÓZ¤Ó6Æo8°!'V•0Hx£VË„& zf2"’Ì‹ O<Ú¯õ#.Ê©€ñÌ]ä@l\Y¾y8ÑNØöHµãiè¿þþÿ‡¶i´‹¤€°¤‚‹éÓ‰o‡¥Rk›‚0H7$Œ`V“]³?éÜóJü^Éññù¿ùþÿí¿÷þÁ>˜^‰›£WÆ=þýßÿÉÿá?þOþÙoÿóÿý3Û}vm~âõÅ]Faw8èÁçžkGè)UÍÖö¿LXp—§EiZ’¢€Ï«l¹h ,2¤ ±·Á¨ÁψÀOàƒxˆ‘br;‰C&€†5}Âhz&'Œpë j€&’&ß\NÒÔ2KÌà"- Ä„fÀßÐ)^[l\ÇgýŒ((]u„6äÕÄ÷’°õÑNP¨—²ÝÐE–_ÁÚ9Z«W<"pã†@;nÈO'V³üRÏŽ0ïù92m`}‰P•l}n¾¥á·S]pE@+É0Äctk£^Ú™WEiS¾Þ©?>Ó©m6^fyõg 6³´‚¹<’äÁ8]îæ²vmò3>`ÊTV‰ô¿éôPó]\f¶Þ#E¤ó y”™0q'ì…öfin Äµ3krÞΑ–rËàHE»Qf2˪KœzÀ[hÆÝp`\âq7Mp`È®Â7¿™!oç+y`9g57Ìê7è¾õy‘¦<´dYCÇÎH+<[[ÂU=÷8Xô9ˆ-4:“ÝÏ‘^ÈX; ÍxjÙºÊZùѹ-‘€rz‡ˆô× `© <úGX¡Y è°Ü’ðË ?‘’ÎÎ#ÐÚ¨à°t†$T8‘Æí 0+eÐHkÒBÎ]~ºÉ?É*xÅ0âiÐKw¬&²£Ë÷=â‰NC*þŽ_OGÝ0ÙÛ™÷F’­´0„n¨¶2ç+?ÀTÒnŒ+KT¶ñyvÄÓó‹Åé“ÓÅÙéo,],.®/îþÎW~ç?ûÇÿÕýôWþþú_Æú[ÚÓz-‡‚óÙ³ÿîK_øG¿àÜïî^ž>_œŸ.ÎÏÏW¼Öc19€·ôküZù·HcP…¸—Ðd\‡Á$$¶ bx•7@áíðK¤s¶ˆŠñE—ïÁ‹jÊ4<‹z›ƒмòµ{ f0ž9j²ùæxë_£¼›­s%ÌÛtä<á#GbFùrm™ÌÜ}V{þôœö·–Mm>eª}6P%ËJmYoF¤žp·dúV0ÇÓùÛ8{°Ï†»Q„4qaÇ "Ô©xs ½:š®,ÉXš—Ãå ^¨Â f饲ñNùRš§IGwBü«Žë¦ÇÍ0W}õGkå»ü.Í»çacÇ”%äbu’_—™<^Óg{fœ…×aâ2a⚎»-¾:lR—ˆ ùµXMü0ç{ÐÅCÉr ´aÕuÇ,>ùl¼÷ünœ8oâÛ 1̰é+¸„–}¸Ðƒd‰Ÿƒ¼’GW €™¿[zù%oÿX˜0ÝŽÆÂ½ý5a3‹·R~ʼÁF2Mâ Ò-óöP롟ýÔ/`.óý€£c-Xvè[š[Þõ3Ü~¼…W¤þqï•Â¥OFŒ°R3 0,w3]¿Áö&“c–…‘s¹™B0Ý##‰ÞwIð'N¼aiÜ€§ªYIËIF„h4ÃÍÉMáŽX=bg×3š˜ºá€'O $ˆ¶ŽGNÍ# ýÛ]œ_.>à#eïò‘²oçÏ'ï}wqÅ ¥çHhV§è|ùþ{?ù¼ûîS±üð_cÚ?üj–†«o~ã/|’BfÁ?'¾?gSÎs åÂÑØûOg÷Gwï/Žîß[ܹw‡Bá0}  õõ, 7Ζä-pÉbA»ð 0 o4˜†KVUùºqŠØŽGñ{I‘ÎLµ¢j¾&%Üz† ñE½`ã½G‘‚ÌÅŠªß_ã!Ð0Yôžá¤‘v"pÃq£á‡ üÚñ iË!,] ÒFƒ¤ÓjÃn#œÎPf\Ç-ÌM}fÌIålØÙW–ÉDd%À6òñØ:ËÚfízVl­ÎÔB\¥ÓÇ ¬)ÿé0Xß2ܰ`Ãîc Gœî’wÉWˆ5rä‘Uq[é€qŒ¿ÊûJ¿°Þ]–ù3«w–œÎ£žï§.8ûªÌn gȃTåÖ¯óÍv4’–¿tăOœ‰Ë&A`ÝI ŸÂH—›å6¤;q98c5 Òhø²iÓe“t6ÈÊ;4Çæ‡éFþ&£ #ê()‹Î¸âMæ•tk{Bu_<¤%¼¤*yÀˆ»6°å½þ-oƒ,ëC>2ú–Ï–CŸb0E"1gý#ˆY¾ü/?ó÷í’Âég“ ÔIÚõ@ǰåiç¯ýFÿ&Ti0™þÄ÷][éN^xÉ)Ã:ir÷’xæxm¿Â¡ ÞÜ/¾²3üÀ-šyJ,´ò„C %+¤À~Ã:î±ëQn!˜áÔ'øAÛ7ã‘67/þ1Àñ¤Ê€Þn§P†ý…ÆÈv €Pxìô7•kÖ1>ÅÛO™ˆœr0ÙÙùãÅ³Ó èØàãAЬ1¾¤]9æäñøúÐ+ä^©ÀÛG/¶‹ãÅSï“Ù<ý_\Ð|ߥ8¯8æâ1K1Ÿ,ÎOÜ]ßc pÿ£ï£<Ç­‚Õb0óa™½‹Q`"e„&ëÀ+¸ǫ¨eu´˜R ¬îŒMæ,­… «Q]x†qL%T”ñC¢ÞoØŒ‘3HKVˆ_”™ÊFd:ÊÒxJbÅN ;Ífjl4b SK ­„¡gäH[¯¥Õ“†Â«u¾C¢0•‰Ç´¨.éä ²±“S­ÊÃòK3úf<°fúÉ.~è³l}ëúíAžçã‰Þ¾ïÛªçwÞ#:6§ì‘ÇÝÎÆ¥sælìSq¸ììò–)òšYáŠM ÙñmçÈ£O’ì7ŒÝ ÑTÄæœMd‰™y^oÃ'ŒŸéö ó(i£Â¬ÃôTgO~ŽA€ýT—ˆl–†]rø”7j "lšRbÉZËż,r¯âòö˜çýÐ.Qþ6_¾Eºq§#¯£~Év_MÐs|$ËÁÑr¹OÞ"ú˜ƒ$ÄÕžãu4¦‹^ÜDB¡žüç§þºÖ=pDÀòlß Äf®ÙÙo™ø¿üž3p×>o˜“•žê®1±ìŸ‚(éd/<ÉÓ<óg•`œè¦Ç ƒŸÿF™ ôÔNÖvú@÷³H•$q×ê “R8Y[hYÓùëhÞåm‚ oºÜ¥Îð 8–mìu BL¸ÄÑÀÒ‡·bêØNò[&Iþ˜Jî\ª³g¥5T ÊIên„‹Rê}Ò[ÆE¸Š)§EH¹Ó-ž9IÄîÈʧòS¼Ä"QG›‡¿lŽºD~Éóý³³'‹“ú“‹s¾éGÆxÌL,9,JÖ[& ›%Î9Dè>gÉDôøÁ£s_÷J –››Ë×G‹×/Þ ÒŸ\.>X<_œRæú =Uuñüùåâò»‹3Ž÷=»ÌŠÀƒÅñÇ츳ØgSNÞbU'sÅ¢5îa[b$W­CÍm,á ¸°(#¶Æ½˜•¤,¨¹EêÌ…X™l¨Ë£NRuXpIP¤(±s˜p¡‘­Ô gëÙø¹«I@V’Ââ$añ$¶êuTGãIƒ5½®i–Ɇ£+’aYš?Áâ&8$%WÝ”™ú3‘ÄO³Òâ¹ý‡äÔ×›<4Õµ4ŽÒt;tVÊqã—‘OðködàvþÎÙÏ—ÝdXƒùÄ™¯ÈnÜnã²ót.¸¢¡H‡nï`›yWVK(Œ‚†¿6ƒ9ˆÁ<妃YZtæ™|GGä8Û¯AŒùX0óгBFT•ãÏ,áÙ7m³À„KkŒøÁY®áõÊ¿ƒœ…Ë댵3S6Ïc@1©6>»Þ[r‰Ý•ά7¤7¯Â-íH©_Ê ƒŽMðJ]6Þ^)tÅ„ÁSuŒÀFÔæH¥«ôTÇ4Òèá#3”‘·ßûß>¿úG5óÇÇúê½tç'¹$½ê꺡ã+ÓËÀfÃ'ƒGOÓ3_,(À al„DaY Ò›|œÕ U±)#.þÅž¡³}Ñ>W[m”Kн34•Ö¥ê0AÉavaÁaÝ…M´ 74Qp–L[ÌÝ‹øá´É Ì<\¥áÁSú ˆŒV˜qgÄW÷ '_"£ä[·Z\ò´Ä ¡C†”J$4¿wAIB0ÍQL ÷â-é5ˆ\ nìÛºb¶qÎÛG<Û?õ[$gعŸË^Òo˜´ t}œÈl ¯-Žéø× Ý3tA|ûîB~eÜ«5¸{|iÓaã{|°·8¦3ÿØíáâ Ÿñ|¼9X<¦i~J F3Í;\yüìlquvγ™Ç‹' Žï?bUàîâˆQÛW•CcágÏ2ŒÇŽÂú¨5w'–ú9ÌÕ ’ªËŠM¥Ð‡MƬˆeA˜šQH h/%_÷^D¬»Q6&*(³<6nV¤Ác\:‚ÃG`4ȲEz zi4ï‰vxlìJ¦­~ÇC •‰·ÂCÆP£äOƒ2cKL Ù54fe[YE£Y½ub-»%hmWNwF–Úð{–}Íš¯Á¹°šSL2Ù(ûE?Û|ã‘?Ä9ÃÄWtA7à†óã9„ûðœúš²ñGyp®.UJf•ñ!G\¤Âog©|B3Q‰Ê!@…mçë¯JB~a½J"\¿µÓBÙ¼ä‘4)Mîöq)ýسšhEAnGNþ-wɱÚagïCqŸ‹/¶µ¥÷¬÷L'ƒeùL]¾güÖ Ë].%VWeìÒ+ŸyïÞ|Hº¸óßñGï\"/úûæ9íë$ò:)v‰Íü./x–¦hÊ'‘©# ÈŒ/©R_$Ecøšƒ™á¹n•Œäm]âc”“ º;Úp!âJÚ’u_Ф|¹ëµ$-ØxLJ‘8Ю û‡¨°–­ hŠ¢ù^ Ë£“¾]Ú˜!3r¸O;4BlÅ)¬y›F½bÄèm±”Ž¥‰ôVµi` `r%×`É´\†tEj±#,T=ˆ"v\T^ÍÔ Yöq ˜ºd \®%c ž°ƒiw#ËßH{…äÄœíóêðÎ9u?ÙÓ'‹«‹:NÜîÀ¯†Jw{‰Ý¸²Ç· x Ô7A|ö »Pû*¶^_(ùUq¯Ô`ïÎÝsGң͠\hz¨à¯ß?Z<Ú-Þb¹÷„×À> æ>޽¿´ 9¾ƒ%VXÆ9ÿ|q~ï`qȪÀ‡÷‡¬ R˜‘Éh/36ŒÍvAs슆©Bš•6Ó”ºB k|aÚxC«0­“{qD@‰i±ry«"Ô•8†áñ.\äsÔIW°!<¡TÀð$ê–-.áªqÁ© g;ñÆ`ã=åHy -¼D–UI¯4Uú;Æ`R9‘O@ö4bt>V»=g‹À‚Sròßô »ÿ˯ҡ³qpœiè3 @¨êØ8¨·'ú‰—O]Ò)#b†‘’GúÕÇN¨RGXÆ ÒY·K¶{´òWÜ«èh8ÒÖ’Õx*­ìK=â¸é3‡@ämüqI#Ã=+°Ë&.Ýšp`™-ãl9ÑJ‹Ð4ÈcéìÛ3Óai´ ƒò×üÎŒsq™ÝKäÌ~T"áé³ËšpùÐ_"í˜uçæ\5à<ŸgúÍD>ƒ„lØ#Ƕ Ö’®±×`»®eV¨‹sd°Ÿ'ib3Ý–w±·Ž@øD7ëõP°òpKüw€ñA(ßZØÚÙ¯ØÂ±/ýiH>ó·ðyC@uýð”q×ÇÐÑÎßgþû®f˜'”¦¶”7àS®2q¦4Ù§QÕ¥ÁðÀÒi`gaÑÖàp¹Û„e¡*–¯˜¶§Ôhŵ\¢#Aq}]4™Ñ$3‹Â«{[¯á*i|ê2ýP@î¾Vk–‰VWýqøÛÛkÛ ð¢S1¥·8í¦øÕ1™M²Ñtè¸)?°x ¦z;,­6 ¯ €s©ŽZÒ^Ý{Ê#ONçù¾yN„öýl ¥m`KžÈqòãÞƒ}ÆÌö™xfR¡^®H)Ul›\]¦ÂôÀ þA¸õýûd.9οƠëBvVwŸwvïQPo0;xrqÃ>,Yà*¶Ñ@38cû ¿ç/Ö|êØ}ltUÀw¾SѬøsƒ×8S‘ôXð)ùÒÇP YvÛUŒ­W¬·t.ú‘Ž4¸Ò4•jH+Kµ2Ñz!šA¾ƒ¼küEì* 6ª_×lhéÚ-™6R&%®Ó`‚l'’Ьì Wúª¦²’Ÿ6¶„CâzÃå½ ®n>9ö÷Ü™ð4Œ0 3]ÂŒ6°¬ò’—ÞmÔ”ºrZHk»¡QÏŒ¨ñ•³x[Ý}êA˜t>:°ø\)ð¬8R†éN6p`ê©xÆag¬~v²>0w7 Y¶ê¦<ù³a‘; ¸:Çä 4…7õ'§e÷5·U–.ä²#·[ìº!Âmd@çÝÎ8l(‘G–‡J ¿²<ñù9\gùN¯·7tÊvþD¸eÜœ°üK1ceúQ4õdÍLê‚0jÆé¨áuæ}$#«ψ¾c˜xé˜Ýy¿ ¬Ž›s§õêŒþ|ËîþlÖ«ç@ ;ç"S·Ï‘­žˆ´¬t[ŸçÄxÄt:Þó(34¾çï†bç¿F¦Ÿ–&^wüçÄPÞJqç¨i,MÕvæ$\ÑÆ´ÓØœv!^cÅ©IKù›2;ña•fàT'ö ¿¸é^gy90Í1ºDNI›x†ô•nF•¸+½F^ò½ÔÓxü¥þ^‰ ¤Å‡kžB,¬Õµyežk‡h‡(Ÿ´òyÏ*Þ„¤×V›Œ{ë(È8ó§†f\å¡yº¸òÙ>ûXœLìѹ»´uë TÃf°¸æÔÇC¾é1á=¨(ãId‰¡.6‹£{÷>ÌråûêÝ»ç\{Óèu­Fg°2±4sôp½xYÁÅÕíâv?¦Iù™3ßž82 k¯ño£.C"pžd:+ý`‰á†78/êÌ ÖÈÅM – &¿Ú°„_àÞcô%¦ë£XQ [A²É-P.5“×@UÒuøEo‡¦xC(SÑv©CDÔço’O q ˜ðàGzG0i¦¡wÜ3kß»·3³Âæ¹8¼#J*8~Ðu'»bEȯ²çÃÖN‚̬å{ƒT|ÀvÌâlØÜ Žù–¯ªÍ=eÁ Èɨ~!>—v9$ ^{£Ìª†uµwI8Ï WѺTX›H0?c…¹éH@š'NE H#mÁ oÓ.ŸÀÌîe4ÈMŸÅ—8.\ðI½ñÒ!¦c¬æÕÞ²vöóì?ËÿJÇ@!§nX¢_ñüŽÙü·óß, [pW”§™L¬éÆVˆ‡zjæ¸Ù.)H篎ð c™3ü+®Å!5ØÙ¿qPpÛ5ë54À5ÐF¨;¾êg:©ò™Å{¾{ì‚…¾a€à³B•dBwþ„Í4÷7¸¢@´[N¬:.š›Úš~Èñs®yÀ+¨’F srR‡,eœ¿€A¢ŒââØ.Þ¹ëCuÊ%+öšÄ–0íµd!xâô¢CYsÙö²".û/†"V@ÿ F.þV`HaAÿ=4 ÄÎi:<˜J‹IÂÔ<}/ªÒEÅJ®6ïž ÜS×r‘úwË!O=Y”çúOÙØ÷ìüŒwùë» ë=6ïa;¾æ'Ý‚AÀúà.«û<"fæ­&VÚ jç+Ú”µÑGPd yt÷îGóåáV÷&s­šsv¥áP”Ca¸Ú£óxt¼ZÜç™á[Ì,ž«0 ¸¿8f™Ñz¬ÆóÈɈ,±zÁà5=:ÀB‰J·ò á« Z2ÓÀca•žAi<‰«ôÀA X3éü%%j7x Ní@㸛‡CÄ:ãOûIÃhÅ“0(/þFz»-H+‚B꺹à†n‡ÝØúÁkZ`;N;ÜÌÃ"ŸXó;^¼Æ^sö œÐ¸iðŒV‚½Ä Ö„øŒ Ñåìø€ !¬ìçUBWŽ9W€Ì0;)[E¦1€©vQÄñ¤£W39(=qjêÿpeÄ#0äÄœ­`„mp’êò@(‘‰úãHc ¸]†ÊYS"o  O2†Ø!º9ŠpÄ rçaÀÔuxg+<úí E%õH††JÀ`18U Pˆnʬ [ÿ”Jo`¸ÄÑQ6ÐûŒFE¬@“éQ 3\½:Õ›HvééF¦”ß µ1JCÁ= 'ÌÎøÍGÚmJd¹¸¤ñ÷U<T9ûç$0mŠmŸ#Óö§ô©ü9²Tõï\²dL !,jh³",Ïóã—×XŠ©‘uCdnK¿ =pÉl¨L_;½þÒ€SaÓa{UƒÄL¤9/ñpy.Ýš?ҙΖEY wâJ»™æ-^.-ð« ò•¾ÐУ‡®åÊ—Î_4§ÕÏnv¿Ù?J+Ìr!G º¢ƒ¼‘†0lÛ¥3p_nœóMËþ›0½cõK#bƒß!‘ëÎ}8§<òˆƒçö+ÚNw»çà‚ßspÌâÝÈo§œƒ;*÷˜IÑŽg¸d6 ><Ò:ipÃ_:àÚ ïq»‰ÐÄdàä—þ±-=YTx£³—€BÕ™O&‹júŸ¼pç{‘à ¡»û‹}7 >älö °ó3 Ñ,¡JmÀòð;C›,gœj¤ ª à?¸„%Ôøv ¥i‹tó Yi˜¾D®’Ž…H„)”xìHBÌÆ¬+A5hÊa$ð'©rpÝ™$`õŸ`Ò3GŒRýv®ü;ˆ>éŠjhÌ2®†Ó2;UE«–Rœigc;¿ép,3Wg†®ÖÐêfžøL«KŦÑxLs© …–|Ë.Kû0ØÕåó·Ümxì¢4æ¥e ^–Ÿp¼¹†Vƒ\”ß©M—Öˆ"*ø‹.‘Reb¾ —/_ü-© Ó!* ×q¹Š “'f:øäÔj }‘M§]¯÷Ñ™Ûùû0Ÿý4i#ÇîU &cž¿²áoË~*í~Ëd~‘Îºç¬ ЧfõÀÎßœÉêñúÌ_¡ ”憿䌇ø8xc5ίô¹F¿=ôNx<ó'aü療Â)Ks„ÁDÎf@³9_õsÅÂWý2¬tæçäÞ"MÛ•ƒô4lmÙ n>#œu¸ö&8 _²PMKïÚÈɲ?Ñ?;wœe[Ú”ÀÌ{Ó©_§F sÕÎôiî-hc6ü€©nœÀ“ pÂJUtá6ãIý¥¡JOô¨ˆ1ãˆÌ¡cŒ™%¶nøÃé…3\$uMºõ‚ˆ™a wi!SȈ?ò” ÚE<Ã`ýÜ3^á³Ó?=õ>vò³ÉÛ40Æ„žÕ*V†2Û§(—Ìö}®ïŒÍÒ`ög8ø¦r»ôŠ«è÷8Aꯎåㆂ~)ôÎ]W©_g›öʸå'?q“ô|og±îQBUT.­Ë@¾¢¨†.~.ÂóšwȲþáƒÃÅCŽ={ƒsN=W€Ù ;\Ldöé^gW<`†rÅ·NÀë„;ü€ß=–‘XÒÜg¯@-K´Zþ³¬ ¿½„3ÜvYPßh3 è.[¹".Šj:5M±»W\†Ã¾`,DêÏ®¡(Ž [·ìtý™_;™ÆÛ‘bªi(|Ä*7’œrèçòêoÕ5_¥¬âëÊ$Ì¢3KBÏÝŽÚ¦<ú8à; µ~Nŵc–G¼¥vÁ§ ѹÛy­lĥ¿¦)¯Óì ËÀÃÆ. ‡qØðE;rWǯ”¦/Q•ÒT¸–‰ ùêç2¼3n»>r™±fÁÚ 8 §;ö—{tÌ”¦Ž‡àÝ8çÉ€L¬Kežù ÅMl¼ÊgmX}—ÀR8ÂÙ3™íô¹ù ƒ:;îtÔö°î+€AÞ,ù<²ØŸ­<~ú7m{Z9-Ûeÿ°Õ…C~Ìðäºl÷|ñ¬G†r0˜ì-;“L[4þ{؉–¢]d€Ahi> Ð64ŽÈÇ+~sãU ýÊ+}’›„,SeqÌ¢ÌCfJ]c,ÆPH\«!}ÈT¤Â#)|'Ä<žÜ (´ÀÍýó|†¿l±òA™s¹øG°mÒ{ý¸0^ðWÌöϱ—ží?áˆÞçÌø¥³Cßcó¶¸aó÷›û°¥½}VmyèïÆ¾|Î[…i?²¸#þÀ͈¡GûÍ]§s*iÝ[òÙÑý»§sÚvÿ+5¸úÒ—Î÷Þ~°Ø¼ë[þ8JÂF;•œžÂŠ”Aœe©!K ÄâeÒXªÓÀŸÒB¥·s¹ÇsÆ;ÊOЀ=½d0À§D}ƒÀMƒ—pqü>6˜ðlÉß9G_ðx`ß ƒ Ž|ƒ€gˆý©YuŒ«¨SY2ãhc\ŠZ1ÕQuƒ·¯çÐêjšÔ^x\nÐ5[Aû*6B ÂiŒ€wƒ+ÒFÆ^='?GD«¥+Z¯ÕUu˜dF±Š¯h” W·ƒ«JCL5Ž©ÈÊæßÍõ • ¢º×éøO炱qúœ5u×Ù$³?? ãûÛ{i¼ p½Ø•“q*WÛˆ¦ÐVÚÍÒÁî,4iìå6¥æ¡ºVV¹-±5~iýWDlÊдÒ!¾t:“WùcÜêTú¨TÇ£~½;0?åå—½²Žp<‘Rz†4qDü|mÏtd“8Ëy<ÁÎÉ3§â>'1f&³«Ô¨XßO>ƒç »@·Àùéà-ËøÖw«S@È4S(¿(¸´âñŒß÷þMÿrƒ‰›7,¯C:m;çkýø:^öŒ8ÍpßRȇ}ãÞ¬bÉRŒEÍüM+8Ÿñ#™W |t€lÄþ‚œ{l©û¢¯ƒÙÙSžµöZ"Hù¡EòJ¨EçÏg§äžìU;Ébm¥êÑ@#ÿ ^ö·£ºtü3z¡òéJN…J–ù |.KXÙQìB«Cˈò±3á*Á°©ÈK¸9”ç¯d•Ôbm ïËfæ>䈼mWâ¦(3i˜ë |hoÌ]0Û?ã`·Së¹`¹ßÏñšëyËÇCó(í[ÊmÉ }Îö÷=´‡6ÝA˜ºkþU>Õ=¨‡4ã®7,\µ#ÐWÄyä A&GdÄkŸøÄG+äÝÄÝ~ûƒ wèß27·oGýs €ÓHsöØ §ã€p×b‡«bä¨Ó৸c„×k4ho08áÁ—h@ϪÀ>çŽ0àyÓµ†‰Ñ9`UÀïc|k:£~(AEp&§nmaÚ;Í`‚6´Á jÖMýôÉ >|\Ð}Êñ­7ް«4³ª÷Bx×ÁWú‹®sgÈÂÌ{õ5šÒ:žä]åma :»NzU£4LÅ1R7ÀTN£NÝSæÊ ½9Ö—ä9ùrEž¤’[Ðt+u°Òy4ouXÄk>8ú'½YéÐG´ùÇô;P³b[Ò¥“D ãtY·yÀüÐö\íqU¡ù²ô¬þ¢zø•§Ç[¼´=eÇfõ`X–žA„žôK“ãyå×?øL‹N¼²ÄQ¿ †…€KÆ)ÑàWºz•-ÔìYÛ-ò¥øÔ­H&ŸÈ‹,éβ¿=µ›d} >4«ÄN=`<€ Ã34á¹;k商§L¯AnX®]0ë·6wYMsÇv:„kâ:´ôU³ônf)ÁQ `âÉ3h¨`9€IÙðÇÁAÁÚ ÿf÷K׊]ö‡ÇU 7Za©Õ‹[÷¯¶ãÁ@ÛçfÆ*yIîÄ}LhGíp(>,Úƒ¶Wh&Û­¤bSð“––Ö*­ÁZAV0‹¢îe'í÷Þ¥~ŒbMüµl›N¼ë=þæ™`¥•º¨PÑGµê¥ØSñ •dü–K¸Ër´½ÉÍ„xð"ëÃ5öœsÆþcÞÛ?c‰ßÝn]ý¡ŒöرoF{\ïm(ËÕѳýñaÛiéP‡™^ѸFpòL]FXoTŠ–¿!}¯r΀ÝXvGÃßøòW?Ú0òíû~ÛÿéOŸc}“ýuÙÖ ±Xœåº"hä¶jÕ ÓNåW®éËæ!dÑ(ø(ñ‘ ±*p…¡óúÒÉí3V€˜­ðۙаӃÑ_EP•€xv©¸dWeêÑq+ß¼×q­£Lo´#P·)Ó ÆÜøG7©ƒWœjÏ]µÕGH9j¶¡¯Â–²Môh²7BÁÅ.•`œ •~0¹K$Âw¤$ŒnR0”"B„U\ñ˜ ;SWª»f¯]^7DWxG µìaž›çýgÐ ÓÍ})ã§îÄ&]¡Î,Ïo7™S¾ãŸ%{žù{:gŽ%öQ8òülæ£ÀÍ›-߈.W§¾Ñç H#ƒgþG2à!™K6Zð–« ‘ák" ‡Çãl4²Jà#Ž‚•Æ|ÓpÚõkÚ¢½ehîišU¤M|ê,|þÛx)£—Üå±ôê­3ü OÉ6 ·É&õB{lWò*΀‡‹7ÿåQO¹ ú+Ÿ÷ 0üa~c)ê¾'sÂ_r ›¾RüRvIã ) m!n)KÚR_á;9=cS›±9¯Åö3ãÂClŒW2ox6“š¬ú¬÷æÀÃZ&é˜])"¶¤E&¿ñѸأ \%öb aZåÐÐ0Üaò÷ÁŸþ1ûê8íö•q«·Þ:[ì¹ èî”ù3ímÜÈUF=+°Ôv¤ì0ÛªhÄSYiΔ=f4p|½xÈ®e?FtÊsJ>ÉIƒ®+÷³*pÍ'NqØÄsïq0±ß¸Ç¦Áœ6èÒîPþùõc‹~…,i‹­ñCç4uÍ ¦•$N]¿)VD%…†7 ·ðÆSÕÏüKXׄbޱ *žíðÕmȦÅíð©æÄ7„ „ù`VØ*ð´–úm4mD•5ÿucº¼âìtçóÂOò߯aÁš¯„{À†<_q&½ÓVe:Ø‘7ek<è¡\avJ‰L1_ ëñˆ`Y/p$€QxüoòDò|d"'Ž0ÿIO >AÈN÷Œi…ˆÒެòNþ*«*Ë;ùeŽßHîñé„*ËõèW_ïR)G¯aï–F–ös‚O–ðÉ›%ùVðîÆg_œ¯ômWv…ÎÂå3>á,Á“÷ºš÷!‹Î¿Â.6tþr˜¿[Ï  h²'ÀÊëþ%ؑޤ‰Ð°ôžà Ä°zÓŠm=½Ï(Óù#"³zh€eÀ€bÛ=ÂÆƒßUüÁÓÅÅ}Þ ¸{qÇC†ò >5š€øPÕ_b•1ƒ„˜•q‹D nú ’KÁ :dµrê?Ò9ñSiä×Å€ `ýÕ@ÈPH|#^=x «†Œ«d!ªFCo‚ƒJÙº\Ó2$X:®ÞÒìd„€¼·lªøÌ'ñª©Ÿ•YdÓ~çù·³+,~蚥ä+üF·wÌ™¢%“êô½xådÖ@,îb79û]ÎÄ1ñǬ`2ý¾ØøÈ9kÖFÊ%ÍxM”Éí(2ÔFöz›Bå ¶§,÷çÓ»ŒÐV”Ë>ã‘ÖúzËò{EÖ°³éÈã cZÀŸäs±ü“ ”R¯ÖM;ÒõñÙ Ûp)ÏÙë/Ñ”TE–Wšjp•®NpŠç…ÿð¢x²1rŠ9ÄãÌû*Ñ +ÜøÂH;7ì"»:Ù¹ç¹:|~»À.mÃ;ý´¶°ÖP¦ž±ËgJœwX>wÙßWé!Û™Ûkjô¤ð¸„Rèt(x6$„U ?HµÇ#À5zqK‡îÓ;zr!6¨Ý2§¦ŸÑCÚÀ¥ÆeÚ[¶te}HÐPˆÝ°œÄ‹iy5½â’\zópt < Ж܊Wnùq Æõ@ºäÂ\¡¥½A-£Áѧ(CÛ:);+]Æî°üÂâê㥾ÂwÂѼOÜHíã!^µM]Ó¦ú Ÿ+37´£ÜØïq‡wú=—Ÿ¶2›G‡&yÐòKפ¯uE^…‡¦g: +`œÂ‚Ó·s‘Ø gØÁ4ß ¸¼ÿèÑG'î²êûìûï?þlqç˜]–SQµU%¢Øt·ê@ÒàÍÂx:P[æu«²Y¬õ/Sþ'ñÔó^ೆîŽõ;Ì’ÔWG¼JXßxÂLã‚a¦— 5æ+ÎK¾Jø”O?}ÀY>pÓà]Π¦ËŒBýP!æE£Ñf½‚ªÊ˜Ê•äTšF§J Ĩ¨¬r]‰«:'Ï@6‰>ýM; Ç´‚á^z4dÏ9{æØ`3 xã¼ÏÃÝñ•(¤C`seQ ³A¬xep»WàÀÁŸçÒd¬h­™,rpg|Ó‘xxÐæ*êŠÃj²ÀHP¾6 Y‰‰˜9“üÆ€2ÿ0¤Y˜:Ù‡¿NÝ2tÅaàšFùêoú4EÙhG‘N¿ª‡S®7€E/ÃFA=ÛPœâ‹5á’1`-sÈQF–+‰Üø@kÃKÒœãŸÐù1U÷«}åH äæÒ†Èq²»ñu\–N*j:Y^õ#Ç7ØrgÙ?¹)TOÝ@¼æ¹ö8û†Ågü:?äãâÖQ»²]~÷fÍLßÑEfì”ËÆçÀà<ÑÏ•7üy`OgÒ©«?ËüÓ‡}\¹ÐPØ0–•–”cƒ>N@Ó¿eóèšïOh8Oh¥Îˆíw瞌e1uzr¾¸âwÂèöìaí¸ã^?Fäs-:•(‚B™MÚàŒgÞêÑ+IFjžðJ7h)BWä|ðJ^»ªQ‹–_>cÐÁ[r… MÈØâš…Kƒ$DZ­Y¼‰)²[%© ËO7ùESU¼^óǦ×f=+Cä°;„mœ=ò†·9n|?ˆ‡.™uº# Î¨Ö8aÙ|¦L~TM'ñT†À£" ÔÒà—ŒhŠÇ<®wK_u¦ø,½—ü¦£¢Ô_Ã?å“2 œe^³-€CPãC|åYঠ1Ó÷–³ðd#ž™æ¬Ü–}.5ª"N:ûf{Ú-¾®³ÉWüLÁ=áOyY‚gö½¹ xl„mÛs:Yñ„·‡¬³r ÇÕ{þU!gAátÒT®-KïÙqÈŒ<ºgµÁ^}Q†núª2ÐO¿yì {@˜ˆÃåœ2mê¶¶þ2èØ·óW†Ï…˜®à1™+ö"Øù ¶C·üUŸÁGgdZùséŒ<›ÿBSåi,–«wåù3Þp!O9í‚0ñE§ÜE3É𥗜Ò”jœ@øOH»!+ñ•gàµ2,¢”<œÁ¦1ÕgÙE_èôû7n™í_Ðñ?yrBǶ¸Àno8°SZ9ÛϳÛ6ðÒ:ʳæ{,´ûwìô¬S§´Û¨h½œ_bÌ“A}Sg&H¥Õp^"$؉mL}pÞZr|S ìŸ}á _ð ð+ã´çWÊ­ŽrPò¿¬>Æ×-fÅR¶=JpFÿ£ÐÓnC`eŒ_Uu`Ê֘ŸzQmzòvõa0TÙsÀTÒ¹œmÅ0äIƒ&^Ñœá·=zî7Þã´Á÷¨ JTß àÄAö xÚ`7.¶«Q—¿t lì"½L»u[)-Ê]@–²îøŠ0 ûü›Èô øÄkþÄ zt°,*÷@ t:,“ÔAÛìʘüvÎ5ÊO’à²c6s=n¶_J3ÿzD šReaçq¢|N̬ÒrYóÜù–çÖ7Bn#Ã6kdÚp›u±"MÃ7tXÒ²Ùgõ'i«†^…U9«6~Ðg0b"•R™ Œ´>(i5%9þnp•#ó_•&#\ùb°ñÄ4 fâ,öHiž†§¡†å"‡ôyß0Sθ“3Àa6–³ô=d…Ù³ùX%ˆ òÕe~uˣ󜼦nÖη7’Ÿd~ŽßMIœöžöh.õ«KžÁ ÛDSÿ|ü‡°vtd¦xë¦@_Ù3ó<6¾¶gï |ã©}a€&Ç3ŠÃ/Žx6éÔ‘ArÖðìñ8`ÍšIÊÊ:Ô`›€×ý!yγP[²ÃѬû†MNü„…7à&À%nR~¥êp…z€nÁ…ª·Rv œÂ+CסÈ$c ¬6Ú§a;èÉ™G8¯òv–PxdL÷¢˜Ð‘ämø)ØÃ«{.󟹓Ÿçür¯x”³—×-±oVp4©lÍ ¨ªñr%e’´¨P~0gŠ‹¾ã^¨Ö-œƒZº ¿H?£y‰-tÀRTH!צø:ÖbÙɰ¾sÌéñk¿6ÏÝI‡VÏ+7X>¿:s1}*}sÖš‡KY&ó"gC<•Oœ¥7•Ýð·ÒsSPe*qEU×bŸW>á./s§È3eˆÒL3“ïq¸È]~¯ßqÀ«,M»Wà)ÊÕC¾Måvž=¹ÊªÀé1›bîð !ï—úx ­p)”ŠœÑÔćŸÒA¸yˆÉßòØ3Á툓WÎܨé^2»«Þè¸fù×Ó¼VtÎú™›D¨™‹ÒÕ—@ëW˜ú§/3œµiu.}£•‡‡Ô¶®€„•Úâ•“P]͸¦IÞ6¤p$æ_å!ÁÀé …EšÀлÅÎóoÃúå¯Ì‹Ë9ÏÚ`½™•óxkË Š—wx®ãÆus¾þ·eévq„ òÔß–ãµSÊîî¿@ºÏÙM¯úe¶í’ô[ŽØÎó{?ì“åwmeìöw‰ŽòpIØÇ¼Úë–qeŸò±¿@æ5E–tÜ#¶Áe¦’þÑ«ó<Ÿ BnýR!{1z,@IDATÜ×°Ç)€+^%³:±Õ 9*sÍÀ‡ž>Qk0'È6ÞØ"z¤“G¶vgþ9!°Ó·“Ö+HCa¨fô±L…É8¹a? /eYŽNRR<ðL\Ú R]0Xªì… '¢¢(wò±vE“X¼DÎà1îÔ ¾‡ÁvÑ~É 4Þ íšöêU¶«g¼ ÃïâñÙâÙ]FÆ>p¿ÀøAÎ@‹t~­ˆw~ä:ÕÔDÏ¥tïwõK3RLƒ‡Êi@ÜUªH§ÞD ;™¡oÂX¢9YÁ‡¤/3zå¤ # ¿ÅÖ…YVÜMAóhµYæ×´—<¯]KÀúïÆídZ7ì:öývw©Ó?pÆ af„~ÏWÎnX¾¾&|MôâqŽÏùïU˜Zm¨|·3 zpÉÁÈ¢ÍøŸ4³Jóbáxƒ÷®K ûéö·xËö¤m™e&Z%v˜WBi<‰Á?i½Z\:ãlõø@*òÈWúj@ t@╽#afòÏSà\Œ³2œõû-+(Ûàƒ 7ÔñùÕÍØ7°¤³ß¸]ùyTÅ!?κí¸ó%OýY—‡†Ì ÃѬ‹fù\¯…*ñž¿Ìsú³@Ù¹›Ã3ÿtԨƧX $^u1¬¾m|Ð ÿn[!|AÆÊ™><ëØ;t§þ²ó|Å¡?K.@–$X1²FzÀÑšåj7öÅöŠrüÉB@›p_¤p–}Ê@ò>Ž2È.8‰uÊÀ4mÏÍÇKÈäÁS0.®;×ôâG´A&‡f€ _úÒ£l*Üß¶CîcJ-ºk:þós>Æsrº8ã~Å€zË1û(œíÓ®e•†ê)«¢ÙÍOÇï[;5¸G^F{¤Éô%µ#͉I؈s¤8é8±ºÐYAGñ4€â«{8”ˆ™ßšZúÖ,¹¦VÇn®¯^©7LÝ+7X¿æÇF­éŠ0+§”µEByµ?hé§³I8pz7¼Õ„«¢JË0ÂÓ #P^pFVFt×"{™5Ïñ!r‡ð}ŒÿøÑþâÍkžÿóì ÏÊNhÍžò»dPpEƒ–U–Ó.YFóÄÁÓý“Åç ç´Á»‹žÉî±™ÉNP r$+ò3c1±I›±4†Q0”É ƒ•b¤£b7›!ÑPTI‹l%늠P¹“Xy;œ¸E”«ê"/ôaxÉÓ-ZÈ·ÐR„аùi¢k<`C4¼¤ÏGNë]&eù`ŒþBG'c¹ùì?å͆L7³‰ßÈÃÃã}–´ã&¯†1 `æËš%B "¯mìu6îæ¨IÈŽúI_#Ú–âŒD¥‡­$‰ð¸º`®©“ù¨v•®Êî}‚4.óMX9‰(¬²Û*;ÿ”Î$ :ÿ’0¶qE¼(fGÇl߇瞜øœ[&z5gé[^Õó•¿%¯añ¼*3½héÌ_½˜õ™Ä…Ïë÷=¨b´®Õ;ú \ê%ó\îMçI ¸îîctþ[À3ÀðNt 7ÝÒ‘/y´@ßN~§›Äò _ÃÈa`±ÉÌ¿l|é@ƒ´í©â׬ØA/ÙðgáfVïnr K^,¶°Ü¿±¤ó_9`ÀÅ4I®[<—î `Ä¢¬_峩OØÄÐï˜ÉA€wñÆb¸ë¾ê£1ðÜ$ªAxÁ-?å˜øJ¢Ú 7SÁ M„ú_r©WƒEºâÙÉ×"tÆ-6ùÎ¥»@´31AHåé{¬^b ç,í?99ák|ÌöE^¥\3³¬7œÜçÉ[7]îÝg¦ï+|´[$26cÃ<òo¨1éÑéW·v# дOÌÈ ½€Å t,Í™|ð†…nv™ëP4\ù¯ +üÎñ½Wê`“ø Õ2K,‡Œ‚01órž‡ËFÙH¥³Äü®Tqœ`©‰…ËÕT˜t©ÉÒ+Æ ¢é6:É©â o6£:©a£äf¿×™á?b)ôÜ ÏLÓløÅ?‘â‹0 l¦¯8Wà_%<ÿà½Å9ƒ€?HäwŽØ)ëhš¸M“í8ž6p]Ç*~¯ê¡º£*Í2°RSÉÔB7°Å<Òi¤;àƒ˜tÂ<­¯ø#-´ó°ôÆ9–ĤI:äŠRf=Ÿ×O#í»à™Ñ²{ÛçÍÑ R&ô@d¢¬É w»Û<ŽF×%nf2¯»g p´£ýýrÜRxEÇaF{0É’%Ët,0e%Zõ‘5ºHY(¤âVÿêbŠFhúeHt5è*_“…ð! ¹¤›Ì4_ '²ò«t`Äs«<ÄCï™îQÅBéà@«`ªéè=„‡Î?—C¥8ÐjÉ;;bŽÄÎÌ] ¶ÏÁÓyÇ)©43ÿ¤I»3:³ÙÒùç÷ió™JgIÚÎ^ð{L¿« `«u^ 4¥!O·tÔᱨŒó»LµtŸÇžû‘ }(°¤|MWìÇ0†HnœKôfÖÒU eOÑ^cC³>¥3‡Â¤êÌýÚ‹rõ[ä&X ,¯ E`gv¡±üC£^ƒ?Ê Âò 7<¶U)'À–³ô¹ákÚÙâÊŸ0ô6S¼XHëæ]eû +c /ü ËüO9©ïòÂü ’Hðžïr¹aEèÖïyóHhÍ*€äY[_HúÜ÷¡‹®C‘ÔÄ9%¢È¸ÎÓ7W¼ü‘£º‘I(à M"fžâI”'rF8å5À©K3=ZœÔî¼öð£G!?¨ûþO¼Î2K5~Ö'0S¹MžŠÝ œ X›Ða°VœÀ‡1örz&Fð§2ƒ KdÑéÛàë×p>â*ú1zG¶Õâl p5Ê áž‰´N@ï±áïÞÃ=¾?p¼8sE€O¦žÐZxÚ s¬C”ö$2_k»|ÂR»jŸ°œö”}w8zø(o0K¥s²&túÒHªŽ‰­DàgZ$4Tá…OaqÒI#¦*c5<SÆN~Á²× ˜3 ’+íŠ0H2àR¬aeG7îimVYÆàll›.Wëô«‹ÏÝ¥m|ÁIÇ#Ÿ-/Ù÷ï+gÙ;ž¬É÷܆ìÄ>ñÒ‘1xØðíZw¯éo]ޤáréß ¤û¼ªæÀÇ:¾Kà³Í Ï©sfZä x— è|e©lF=ͯºã­ô“qFëÌ0¨Ý­Ê,\}$ÒPªFÎU£]™È|ÈÏü%Óõ•6éa#Ï^šœMOè²-û P|ã>÷NøAõ­Ïíé³|†½mÓ³‘ǧٜz¿®wÁL½.‰“gõÙÖí{ÿè–W¼Xɇu¨DKóß÷¼y-ÓgÄ®²d ÁìÝÊå;ú9[ÝÓ—ûq!Ww|kàš5e°´¼öy>…êrù 嗜淺$í./›¹åë'‹—.÷xG¾¹—]èV4x@Ç^ó>G,áÞmOXï ‰=VöRîØ‹~ñÜ-† Ð¥6<(¸6q³_1¬¤j"#Nd€›„m›ÔÃÿºˆiW¾ÉΊ+ÈŽ/ÉŒ¢eh#ÃåÑÑÀÇ~WJ’|ßÍöóéÝËgÁ£Êié«“¾SNê£nl ,9©Ûð5¾|°ËÏ 5‰)5Ô¥ÕÉ-m†Z.T­©÷Rtí„1ÿã’(†¬&5Ò;ÉiÔ`«à;âmÁˆoÇý\ý«å†é¿BJÿ„+1#._Ó±8ÚY&ó°p+Vú’&4]~-rø¸%.Æ¡5p€}fߢ ÚËhpƒCÓ‘†À¥\7»F=R̶ŽxúèÀUb4í¦ÁSºžg,ÜÐT³Ÿ€ö‰ÙÓµo|À÷>x²8ÈòÚ]¾»¸ÃÂO9ƒÎ¦c¤ŽØÔ+™cú«²« ðnÝÔp`ô¾àR’wE#sÑè±Áš;éGŸT`S.$³_ ËݯÕÙ©×sBhZH"U*tò“É6HœÏo·4øñJ‹cåÅŠ¥âÙÑPêÓ¶ÐØ‰°Tl“ç>‚ ÈäDÃkKžN·òÀ¤ñåÆ4h>Ç77¬Õ° ýšÎÑc‡¯Ü>N>ÛÚA¬xO½Ë¹¾5 ÎQ9ñGœ†bQµ3]FØy9¦g•·äô¢U2zVa¢ŸùUBdI#•°þÈ꼓ϒÝr‰§ŽÚõ™?x;Cë3}§Ú9E‘j6 :[&½v†>ïÍ'úsk·é'1~Еgñ©Œö–“Kõ°¤³ô€$ËÕƒ•˜¼ÜÒFùFØ:.i·r`O§!•*ÚI·VÑ{û£p.1½/:Ãâv÷¹Ü`’|””õ €"òþÙØ(z'¯^Š7Ò ƒ¸óŠdÒ_¹ÀòÁk'ë;¨mc’ê¶+AÍ¡û††¶‰Ì =1· ˆ„زœìªÚ†)Ü ªígj°|ÐÛ8Ұѵm‹ iœ¬(§(A/E ?üK8*·D 7ß_ß;Ú_Üg„ýÇŸ^øyb7>_œSŸÑˆ¹hí×Àž>_\rž6›RÎyÐMƒGwï-±Ïˆ¤:ŽÑØôc â­^¥•ˆÓtMµªÀ¡zÉ¢«#d>·d2"d»ÊdgÜ]« 2ªyÙå™aۀęYät±+猹vÿÏsšNÆÃ£‘ÇD…2aé˜eÿõ-³T;2roÉLoÉŒÑYmžIólÙ•ì,½šN(ÛÐ1Å)Ú“é@òR!º¹ÑÐ]çRì“§v˜mÙHè£dåoŽyÛ€¯âIãWð|lr·¼µ‘¬?—xûNmÊä€Pó%y¡.Fâ ˜³Q¤$uòÐ0xóוŠê„‹>4r^ó£ì™Ž›ôm¯Èžq,á7¯ŸÁlºhè·ìO©ý€1@ÊÊwÂQ¾ŠSâeÃ$]†=A/oŒŠW„ Hâ5 ª¶­îb]a…Ÿ4_cÖ¸8nã ÛA`‚5ŸJû`“!žºxõêmc?•ï“ëÿ£ÿä­ï½oÞÓÓÏTÝnvuÅZòµók/Gºè<êÝÄÒTÛꌶ ¦“½+ŸžÒXÛ8âNc4ãNãŒÓ†£¹ˆ–†= Џœ†«9#Þg_n¾¡±½º=Ù¼»;¥3ÀìÖ¦A/Àuv€}·—›Û_³F÷úÍæò‚]"àêáS¦3=ncãå¿ìÐÖfcÏ×ÿõ™ ¸ _"ÞV€Ô¶€mñ´4ß´í–<þ£’âŽ4´ó1i8´VanH zhl´Ô&s%ÀÁ߆¼ˆºINÖ50EQ1t:Š)SÃ(CõN{//Щ hà®K>ÁȵM7œ9–ªÆV…JDÊ‘cjQ'(P°P¸÷^‰‹á!ɧ=í¦¸Æû olÈO×–î]°&°-Ã^e’%tÈK!ávDW¬r€eY¡á6?“ ‘UšpˆŒÙ'A‡¤r@<ê7ò¶Çè\ówaåÿÀ4»Ó‹#Qì–Ù<²Ã•Èîú® ü^êc0ˆîÝtöêÖ`׿¡7“L0ÊÙÖ]ødžISJ”zÐ$¶F%£mâŸxA£63<Æ2ÀÈ¿•¿4þq¼–ˆlHÜr÷†ŒÌÓ±Q^pÅR&Fþ[_ú Žäl¼°¬öZ|4ÈI¤ƒ”ӻʼ‡Þl›Î‚ÍåO`dmÂÀ+~†ç_äøˆÑ?FZò7õiPÙNDq7N¤U.þ Âæçà±tÔ ³Ü¦ƒÆÔ':j×—×\ØÃ¹}Ö÷o>pa•#JßXÓÞrq3]tæ¨DÎÚ2crz~–«Ìë)må¬:‘Ø)Ä'¢¡ððkYƒ³üÌ„W·¶*é‹:î¥9š"•/bÆ,8¸Ù. <š]3˜¬wvPŸ½|ùs`$éoísû'òþà››/ïHï½óÁ §ÑÝ0ÝV>Í å%ð%_±¤RZéøc•‡u% »Ê$ ˆ³Œ12ê@„í¸)€Ã/‰ÞF¤B{-ŒÀ„€l#Ò€±ÑÒž Ð1w¥¿äï{F<ï/==p.x À© Ò'SÇîpJD=Þ¯Þ%%À©®û/rkŽ1 §#‹í1q¿3áÅ×ì‘o9^hYÇìðå„XUÏHþí툉‚ºU\í‹nÏ&™ÅQ>.}¤Äg›Y`tnítYJ¶v\²a“i¦p#ˆ3?DsÖƒŽ?¡1“—ä§&v’)Ò#®KVd T!ŸNŠdý‘¢†¬b¶ÌšÒéàH’ðꇰÌ\ÐÈgÜn&a›ÈË:{p³,K–þ ïã{aBº|ò>6ò½§¸ä ÞOW—°w†…S¦%û?\žÉÙ}{vgnêcv‘=‡ÌÖ(Ù2‹ |"ÓÖËÿ8[¬ÖxÒ-þEfƒ_û4Ö ŸBŒuJi ílÚ9±KÖÎ8ØGvèDdü •Üw\¢úö?úÃ7{äÿàOnàúßþÛ«£¯^PÝC­]aöô·}öas9HvŽŽbºß€©ÈqVÁ?§;{u¸ùšaå•{ص^{|ˆÈ;ð½W ÚÏ[ÖïniÀ?òÑÇçlÎaF Oç"Ö·Q:nªNG…éæ˜rF>U‡f‘C±"[!ÅŽâ#®àBZî²…S¨‚FƒWÑñK”‰+ }ÐJ  º<Óå¦2ÍÈŒ@½»}‹b÷ÎùÈÀˆÒ ¦y®¥u¤¬2Åͧ”­ò¡ÄÙ0"W)827ÎQ'*•î­›/”+?ðö Å‘ A¦¨=R§T %jn¦I2>ÎbÉü¼G‰ºÑòãˆôÁË : F`é(8úÒ8}Ï®ôìȇ…yñ…G¦rW>Ê/^¢•é>¦ ûÜ$YG;ÝîÈ>gíA9Ÿc{n’̹ww™º¹鳯Ÿ¼E£Üب—2ôisx/iH—-·èqÑ;q°AZ%z¹#®( ó*Ë+®½ÓXº/ yÃ:;€<”´gn²lY<8¤™G yÎ~HŒÇP®·Ë ®4Ì`xAQU=4[ïðr Öt£#·å" Ð0O¶e4[Êß Xæàß–£Y‘¡S•cnÄw›Íƒ|ù—û ”mˆÿø ˜ d=¢7)»Q,~xUšê•´ŽÅŒ²oÜ«½8·å´ÔuE iè?ùø®G,½¤ç#Ïî~¼|ÏÚþÛ68ñ@¾qÛ*¼¬/»´.ÐYuCåá7”²”ÈæÌÃ4Pò„Y‹h…¿EOQ"Îð3It+B¢8Ü8üá*{C¤jcš–»ê<ð%Í´W8†dú$¼&ßpÅ£¹¶;Þ;ÔF°}ÖŒ¶#6;oç,³þßÿןþ|@Rê·øsúOþÉÇËÃÅ›Ë÷/+õ+°´»”ÅοÁ-N»ÓðL=m a ;—.QíÚ w”©"J  «È)nMgt‰ÂÌõ´ž•wJpvÍ{ÿyî·ÙѯsɯŹ3äàYëö/Xl„îíP°«Ová;WSÜQ¢öf˜µ°¼ºÃÞs×¹£cLg ²&Î×±JÕCÄÛ?7»ugEPÒ÷ çé ‘‡ÙD7XåàÄJ„6e2š.Ùeh=ɬ…û”]·Ñ´³c¢¨L ȵw.Æ¢K^¹ßeo>Åߘ~ÖÓ f”kÑvˆìD—0X¿Ï§”?á:‘N ¨ì•ÉÔ¾7ÿ 3é l¯Éu_"B¡ƒã%E<~´áD„r:·¡¨þiR–À¯2= F‰øEGÎ…Wüb‚Jªwâ‡=ùƯ݃Lðð*9'T)‡â?Õ1'Oðùä½ü<Àó{ùUþŽþÝ4áFÏ×ò£ð=J§1Žž1 Æ}%´ >°e»²a!›ñ4¼Ñ+ޏq%ü¼| ÚO&õŒ¡<+®RUþZŒb „µ0—D¾ñ~ƒÅB²²,Γ[Þ­ô-GÊ^nLOý•Œú ¬ÏÿîßüÏ•<)ãáI™£?øƒËÓ3ª&€aÌ3~þ/ËÂa³0Ãp¢üÑ’×ÀRYëíŸ~ó¹íÀ0t3pDÀ­8‚ïOÓ`µ@*ë>ßÀ–=pZ¨ÁÈAœÊÀ8¡ž*D$ , å©ÿ³Î |ÍS­—\=ü–÷ØÝ+ð‘nÀþG´úLêÑþÓ`Ýô–#=—¯_o®89p̽çì8;ã¦.§O)ñ6r)+µ :qàWÆ$Б½¬üÚ‰_¾Z©0 ¨àëïà&‚‘Á¨x3ÝŠÓüL€ÊÄÈÃtei€@•›7À$¥hàl¸™ŠŽbÏ‘7ãÅôw¸@î(ÒTqª;¦F\F‡¿0µ,½ Bò¢»Ìm&SQ±¤Ëu”µe7¸emZõ¡#(g TBÑ¡ðs‚ð|ã>ñ3 ip·y̤HƒÄQ7¼Ùñ>Ê@ô\Ò™¸°^;&Ý5%Žv FZçñÓ†5qÃ5…Ù×+#­]Na€ÆæÞÑòV!èt6_ã÷@¸Uœáä’ájÂS  õÚ;@fwØXI9-cèÈ€ò7¹¥Iy@ù?°<·ˆäÙ6Ê_B³ŸÔ%±ˆ‡e“=r,O6¯¹õÁ©±ìµ€Oî‹p¶À’qq«ü-^LžF™^üO=õÁ"k|¥VÃË/y—°¡I±nÝÁ’Y•ð¢*nÉÐ ;zWìúZþG—_tQà&œn;ÁNÝß’–nêûøþÝæÚM}œZ‘Mã¡×cçòµ§ŒøÍÔS?3DíS¦MËšáòŽÐ Y£ÿŽ™œCÜJ;z5—!ìé.Âꕺ†SúâÑŒ4uÈÑ>‚‚½X´¯_óåQ9Rò\”…ÇÊ]*Yz¼üîÿc¦OË<¹À‡‹‹ËíÅ)ã›Á© aï h¦DY4¬ó ÎÄd*î ¾øJ“*ntnÉ„k&+\\þž §ƒßt"‡@œÜaÜ?ƒ  Ûƒáê€x†#ßрȆÁÉòß ú ×]¹>FôËïoØ4HCûíÈ„ã #TZ©²O4r×lþ¹ãnwŒx{àŒÎÀ©×³WÀÝàUkÌSâ*Ǩ–6t†Í¿ÈÑñÚo†ìý©Ä.>MR\dmÅ®’'£¯p Yãˇ¹d¹ÀŒô8˜ëýij¸¨êµ¡ØÉ°(hhŒMnÃKJ ä³tÀ,S¿jÔ©K Þ/ÿ’y¼ûÒaPå²ÑO%aGÁÍ{hóÒÞR•)DgX_ÏÔ°éйòÕ»¬í»VíZª»Þ93çk™%Øpï@Ä2XÌÃgsËŽ‘FQ»„%¤tœÖñtOƒôÃGuPŽ|kËCfCˆÍÔ&GàÈâÔuå äÜuudè#Èôm o_$>™î6“H³ÂMš7Ÿ®á$þÆ!§*E¾ì“ȱK¨œÙÈ2”#Ó¬ó Ù¼´´¬ï[áèdmˆ¯ád'{j/)( {ñ8p/ƒ|íTf| GÝÈ1BߎÎ=Þ]ÿä™G•ÃéÒÆ;äRåÒB;M[õÂéŸ"jª>S6-Ë'AL¸‰ÅŸå—pôгÊó‚*FÈø1›uóWuAŠž¤c‡>³€¯®ÙÐÇ’›ú>¡ø=¾j±¬eÙ~`ÖÊ'²íܳ,uÈ4ÿÉ ›ûÜûJ¤ÈŒP8I!Å&¤‘%e’ZõÔ ÿpšòÙù•.qàÛ8†–ôáú…¢Óp¤×ð×»gðAÚÄj.ÎE¶xÿèg.‡f6¸‘ðt–®N¿ýöçÀÒîïð{ôG×ÿî¿ø¯.Óü©häƒuBe^…/Püç,Œï€¥°Ð_ž–®Q¿tÅ (…n ˜Lèp÷¬B{¥ÂÆ‘KÒ.…锨ºFYÒЄqo#˜!]Úéj³§ ~¾8 0ðõJã5Üϙƻ`ïÛ/\äCŒFkVÀLjX°3€âbC÷æ–M@7ü]¾ý¸¹âÝß 8ç¶ÁSnôÚá/QœÊ86EhUO¥ª i¾[[Bý†1MÚ˜H‘uVËáR86Ìð4Þ½¾Ÿpà!u]胒Ѿé`£mŽÚL¶5»º„³´Õ¤!]~þs`MÑߎÍtÿž=çIà‘c|Fž/•Faþio7ÖWÇ03Ž•¨ëZ*nýg&3Ž^N+qÛîf’Šƒ”Eá·‚ Ü€gÚà8^ 2`#P‰H-³2Dîà`SâÃÇLjNhl_±‹÷{”Ñ{—˜úó ‚+ 2{}Q,!ÐX~b½ùö7¼{¿yË­^Gvø;å‰â#6œ¹¦ZÁ[A‹ª¸¨_5ÕhÚH‹P0‘V¹Ft ¸ü†Ó`òÙùYüJø’!KÃPë%Ñ%!Ø Ç_É\0Tí¦Ê^#´b%ÏðÕ?AÑÙxF •»J]ž Q ' VZ{ýí(t†–l[·­‡/á0G[¦ÑˆqYƒ†aÉ,v“ á˜ÙŒXnèÜÚ²öî쎧`¥bËLy¹õv='1€ j4í.…à4xvÕÁWk¡æÄ ›p\G·5: ®½«S³©NŽ”é{F,ñ!]â`Ö%w˜`l>Ì(ÞÍ•ÒÐ;¨Ù‚îh¡`™9@†ï¸ ÉüÞz:ÑâK§Ã³þŸ 7óŠpoHG¦ðÝÈêŒê“W y´3ñ4é0ÈôeïL€²Ζý¹À% hrêƒM.ˆ?:{–ßd1X¥ñ,:0úñq†¨fÂtµ¯¬c|ËmX¤ž½]ò¢†™¿Êù…ºì%=ßûÈÙýÛ^vEi¢X{FÝÓ,éT‚ç —ÙÔwÌ £lè;¢cÙ?“4f¤:QèYÅÅÇhEŽÂ™ëtãLBnÒT|:U~fzaþÐCÛú®®á¹|*_Â5ô˜Ã²íXò¿ G¬Ÿ6*ÿWniÀÉ/.>þÑ?ûg?ïøédüûó9xù<ç-KTÞ¨ô’™ü˜7é…jùnœäípko?ííç·ñ±¦ÒêNaò ?e,0MÛ°0ÖaÊ*ß.øº†pu‘: e®‡fÐ.‘k7^ê êuñl7¼DŸ "“ì ¼#âÚa¦žAü!O{Ék…`ºê¸êJÇN7Œ$ {Ý…ßJLlSJ·†Q5rï’¢Ï(,SÈÔ­Ùý¤¬ð²¤Ã•ð ÉP¬¶\èG7)Ú Gf¯ªe´EíÈœš¡œ2ˆ"ãÌ=™™©sÊUî9ðC V¯ùßsü/²wþÐ!Lù¤ :Cî¿Î(›Hžt:‡¦_Õã€õ³t¤Zq—d‚»oÆ­Òݸe ®²L@PÐL÷’®ù»"w~P=î羫!ÉŒ¯šÎzCÉE—ãMpp_Ÿ-®Ž‰"\75zzÁ4õQ!x˜göÏ*×Êç¾ ÓÕ´Àªô&N-;ˆË?…ü‘ZŒ‡_\º¡‘Uüø‰cq•Gx ìúZ‚Šœ†]øÈÎÈuËèÞéýï>n®oxFì¶vk&9xj×»§ò¸¿âÞ=§™ 89¡fƒt8«ÔÏ\MØ‹­âa,„b*±Ô1ŒbiÍOËÝE+T(xµU¸ñó¾?f´BJ’Fi.?EGQH3³{߬áÍaÏX»D防æ'°?»xrïCŠûÓ3ÏÞ$Ó¦|1ÍÜùõo.ÓTâá/¬q~Š&þüø]p†[zë‚~rý5º5ûî8hR(²ËS¹¦™h>Ütz‰gã«·mpÐ:àòæ·Ø…ej#¸(J­g(˜Ógg›¯X÷þenôÚáO›(%ç´[16dF÷ëÔ·ïx©ðÝÛÍ»sž,âÁ)oœ³gÀ¾¬˜5 c§Èfßp7,ëÔ¢R!¨²ŠP?õ‰üò°‘Žgü«âÓ¨uüÆWŒXm´ñ°ÃÜ=µîk1ƒÑON`÷˜ þlV3ÝŸiGàÊêè×ezbFHp0e-«ì­ü†è(¾”¹H£4ÕÈ!¥E½¸W;¨KÊ ¥3krŸm躕ÑÜS‹iKÉF+ÉW0 ö6{2ªÃà%;^‰ëÈߎ*{ƒ‘›Ñt)CâäHÞÇ ƒOvÑCcgFP=HÃÇSÖpËLû|ê· 0§Òéi&=œ•°3"=Æ@)¼NÑ{¯ì„évX™NîÌùC£®rÃBb¸*îêQ@¥â&\ÙµìÙ×Ь„D6·<ÜG@|í/¹WÀÙ€Ž¯“ ™ì˜ÃuVBõTvÊXŽÿ±91'% B…ÁÞ¯FÎ&@ÑG,¤x–•ÄK~iÑ—Xó‡=}7ÒüÞ—”ÒhÐ0¿–—`Ü®G(ðUæí3rÑþ;–é8çÃ:¿×];8È«•¾iÀj?3.w–S¶ÌØ9ów#|–g;ü‘%5Á$Üú*kYˆÓ¦D^Ý+æ­q\aÅq&ÜŽ{ƒåeû5£+ :mt‹1SmO&¼¾æå„Þüg˜Þûî‰d„XáΡ+ÕùÙ³'w€q{’€Ïtyó$Ž%Ŷ£s·mÉä4Ž;™ª_Šý̞ݳ=LÆp qóœBÍ·a ÁŒÓ4¶u‘¿y„¹¾«”Ê3ñKÃpDÕBÜE‰úÎøÆÚˆ" ;³ƒYë¤RV]¾d£š}ÂGn¯{Ãî[Zî4ÐîçúfT7œàìð #‹«76×ϹaÐ}üYPÏŸ{Ì­FL¦•fek‘FEåIzÙ¢iáÏf7m;nþ‹„%GÅFž‹#û ›3åéý¿´œµâ¾$ÊÃN€ ÆP1·Õ1":pýÆûÍm³|à¥5ÀX;Λ® ç8²Ò_Öâí`¤Å½™kB;u¬ðHá…*™z7Fèî~/Í£?Â8=›XZ5sŠæ$œ$Œxh¹1ÍÙOìðEIg¤w¨°PÙÈh!`[)LüX÷ÏÈØ ˆpß~f<ëæò$u¹OBÖSt#¡!3$ ÔK{\pï€âÅÍ—W,³cÌ£j_§ôI£ŒÒâçýiœ`‘Æ% ÃE±?àöK–l{J¸ÊA¸)÷ù#«/.±@Ù¥IÇÀpÕz3é´.ËÜN-˜¿M“! («ƒ„ëR‚áŽ}l‡®âkVô>ZŠ “•<´‹h¡ÁÉ1¯AÐv¦,þ¯<ÇBY¬òZ`KcãÓ_QÌqó3¾5˾\ØÃ¹ý«wáãL ¼…n˦Q;¢)”)º5¤ 3(ücf<ÑñÁêѾ"–D~”3€ÅZ׊[òB‚!RÑþüküÄ@ê3ˆ ¿Ð-x…í¯¦¾II\¦˜ÿڔ¾M)FqôÛ\›nÆZa?m[é)9‘#¸$hûœ\ó5}ܧV0MHq§¸³O€4تì3š–÷'”_FÆà¸©ÀåÚtäjàoÓsVEÒÔûþÓð˜˜á:Ÿï¦@@×ïÉ>áf %ûà]ȆK$"ëìYƒ–ÆÎ޲’H™qöÀ¥7ʃQûiýÀfÖ\Ìd¸ÒØÑSø¾m°aÉ"h”5³?„ë²G:kN8Z¶ÐˆãþãEš™¶™9²”–Ò nŒrû#~Ä%|óddŒ¯š…ÉkѳFñécJ«ÁƒVù"w×yý(CíóÏå7zR?3»åÅ‹‡(v‹†³N÷¼eác<÷¾‘pXg÷9ýsì»Ît8ƒPÄ'ØØƒ‚ ™¢Ñˆ&öŠ·å-¦˜,q6@åϯɱ« e oþ{å¥m‡!ò(ÌHóxó#‡jaZP}þ¿˜–j¦±4‘Œ•ĹBã„V¯]‡y‚&Õò©É}ô«ïٳ洒“WÉìV2M5ÀXpÛ¤v1¨ |¤@J4Œ•dÆëJÓþí×îæ=DÅc„ Ð`ˆeÛµSYtÏFwã6\þ5òA³TÂ=ÖòÈÔ‚ ²v6ã¡iòö÷›:†Å&ÔFì%›„ž¿zÆ^f¸vø £1$ryÀk‡·3 jr:òöŠõÈÿÀ#"¯x”ÛŸ{œÝë¾®±ê¨8Ý]kjëÖV²i+‡î/sA3™jnjÀ!³ý·bäë2e/N xöå¡â #Sv¸«”mÜÝÁŸKÏ}z¼ÎG…²›\\; nv“…Q`Z¸•²QÈHQ”’3qGµ(ËL˜ n´‹"Wa€Oç\lPª¼ÂÜÌ€ÆÍë¦FŽ¢€j‡…;;`ΙÒ"I½ÊŒBRK †O:©EèHäZ_ŸÐåšãZ7'¾†í:º£çH€òs:^AdëcH\@”…£iŸßuFuôÜà—pY^¸Vvø „C#倯Í{†™S$³Š={'·:æsJ®ß›ˆ Ž>xC_x8¥O:®óL[»4€²sV&*dÍoj”ÿ£¤#"¯Îá" î¬W áúëÑ…¤74Q(voMcdU[;‹Azf>Æ>‹1/ùglÂϸ ›ùî{ýrRÛ²¯KÅoyÍH{ø àÿ'Žc^qç=p/¹°ç³w> “ñö$Õ­²ÿÓ— 2ÑÁÚ>KC§îæÇ?ÇTÍ'ËsÂKl # b‘*c±út|ãGšÁ@Œ^M+ <µ•žm®Î¦ ®NÅF-êþP‘ÁÖp\>mÖ +ánãì~“£0ŠkóákÙÀ˜ÖÇgOî)`e’€ã¯¿ý)å”<›L厶(ÚXö~TVÉàïùÍÎö¯&·|º µ_ãÛ ká)"üL"QA¹ †ÁÕo?0ÜsåEú&{üÈ#i^>ƒgw*Zþ¯2€Ü¢…~ç´jç/8AÀ4ª÷ ¼ó(!ç{0mûi&£c>óë$d½Løvó–}‡, x”ðŒ‚£LWÊF°Ò /Ó«¶A½?ÙLGFˆWõ­è:Îå2fà6Ð)]Ö»óv|rB@AçØ^0‘ÓþJ¬qœ)g׺™‚÷=GòN»:ÍŸ£`I üCƒn•¯…tä%üÁQ9âÎèÚ)pÝfL:V½ÄJ¦4.B›öéçT‡¡òQ>ºõ–·ÕÙLÖ×u›nðN—Wù—l[¸ûœ-&‰)ëæä“Êß6Þè炸ºFæ*eçzœ*—–YÐa†+kn4n“C¥ëÈŸ»’ô‰&²;[ _ÓÀ‘5<\¿ŸÃÍ݈ìrC_.dPæ}ÓdßD™Ù@q§ÓŽI ò·ãCpÜ'yn\/|2–²pcãöH¡ZÝéag ,2# ›²_tâÇa]”OŒnÓ ¹zh x‹?Fàȧ8 ÓÎ)œå*!”›\Øóqóá’Ù´·—¬lÔ…J\ ÍN°è:ÛdÖøÉÓûÇ9»ÄLLf¤.{ ?˜Rk~KþYîÈWh‰“²Š¯1Îõ3(øh[êšn‚×~ø Ó,핎Óª‰“ŸT\³wÂ8m_TlˆJÚ¦îo‚?ÂäRfÆhè [m¿†Û\ÀYÐLëûͳo¿þyàš`¿]ÛÑ/¾ypæz-•ŠÆÞöÄJ•ÂFÆX׫’u†•<ûÊÆÓ>éÃs{ÓõWð¾=úa¦¥¤uA¶ì¤àÒ·ãÆ1À‹¥+ÓÌ®í‹Ó ŠS¦˜®€ÃA—ðð×î(ßï’¸—ø »BYéÅó~/zAÃó—Ó|̵Ãw\0Ä£"PÒ c;¡¹z ýf¯7Ýr?ýÇ7Œfž1-ùìÅæ‚SNùfú2ÅA`Sk3š up$å#<>Zäl²Óü‰'Í(Lé“JeŸa´ÌPÄ*hµBšU´­¤%tD%OìL§©wÆ@ –cnXŃ‡ë¬¹Ÿ€–Ö‘w&p<°Ô”‹ò‡«kñ*Wâê †C³_…ž± rú¹¸tæÁ)oÅÆä¸`d‡x½ìo5.t½O !ìø.ñúÖroóSƒ8+àDnš<Áî‹…ÁÅ]ƒ,h™-O'û¨NŽ%z‚ÀôcVè€Ç~|"6ilª1âÏZ¼*D˨]} ß›ù¸Ž»ò‡JÒ5xä¢)ó ñ’7j7gP:\–rÁ×ü¼Ûo¾y{À­v÷¯™K£1øw9èà&·ÕÙ 5šÁÆø‘[Æ]°üutâï›–Š Ææ«â\~2êwÎ4&ŽH1±Ã«¦ý¼Ô0*¤°ôgÄÌ5/±3àz•?Oú.K*KvÃç*^pjï|à—Ù†ˆæ]ëŒü ¾™zfMÞ‰…ÄÍ@ÓYA ™¸³–?-ô‘C}nŸ$å´Ÿ¡’rù M2 Ù:îØ'Õ³¬Ì™Ep ‰A‰[˜ †ÓÌò*ˆË'9‰ÀÈ7&a8oÄlt‰•ëèFÙD’yò5á½õŠ`¯Ïeƒ£å'»Ö([ÖïMGé®5äÆB7ýÙ@±çE”rh¢„ ×È€o­×—¯¸M»!«B™·t ÖÐêV y†Àšöï¥&•¿¦z„¼¬ÁΗü7ŽÞ48­x›‘¦ .Ñ×3½\ç˜rìL‘p3<3U*sÞj¸æÕÄísSßÝ¥×óÚ;Ú&M¼{ÒÂöÉœ¼¬;ùé°äy^ùùo…ž¨UX†gDÛÁ\~*M&,Ñ1ÉÞ²V:aO²û>ðºi„·iÿv÷f9\ß•Hœ]Ó~å£ËŽ4ÑÖÖ1Ü%‰«éñ Cî¹gØŠ±'%u8K0_}õó1ÀŸNî¿_ŸÃßÿýw\tBþØú”I„uùŽÜKc×H|õ—FÓövtýyu8«ïOÛšnԶ˧ ZÛ¯Ý3çö¶ooüþþ”ŒK¥žL ¥¯†RàjKõñßé0‘ ¦zÏi¬¾æ!¢Kv}¿e]ó Ü0ÒÜ1b³+pNc}ˎ滷¢‡K¡ŠÚ UÔ:3ªÓˆv¢ûìŒUuŽc@IDAT‰ä²^d³©æx¸Ûo“ls ’®8xȇ©$3ßÁ,£k;”¿ö˜lˆ¨øV‡@»|Eæ 7ôEnyÄåˆþ ûiŽSF秌ޙH=SY“×w7·ÜÒÇc<ÜËï3¼ŸýËÛ “:Î,p‘mŸùO:¹_㘛7©C'Nóó UE¤„¿Jª)+æ òÀÂD¼Sgñ–öoªâ‡ç ë4h:ãh1(¥\Ð wˆÙá5”ÉÚlä{‡;y,ÖĪù-ØZfŽa¡jÎ+ 1šªÝûœš¢R³]~­sùÍ Í!ùtñêÙÏÇç$úmÚïÿ÷?ûxðêâêó¿ý,ᘃäffo±[ gÓîn*Ú-NÛý¶ÿL;ÛWXÚ„áÙtíÿ˜ßÌGû9` âìá]H…‰ÓF{‡7Ó6Î>ÏgfTT…3Û;q#C ‚[þšÇˆ8upʬÀ}™ib;Iî9¿Ë0¶r(dOþ92}È6p6›© U°Ywv×?ÓÇ¡CR[*'Æ2J62¦¸c->÷ ¨8« hñ2Û™/ÈÈ‘Ø0ío«¢È‘´ŒNmF„SºNæˆbž-üUþ9 ãÛ§ ²î.(¦Æ¡ÛÁHCéÚp4k|4 œB§3­Õ%“p +)ß“¶r±RÅ4¨“Ù÷@š¹×À#‡‘ÕŒóì|–  °ú ‘ÓïàdŽÁþ„éÆDå P—5¢Ñ€‘lyôˆÕåž$šzÞ½áÏqC–[L+£Átyf Ì%nHE¢eã((cb\ ×¥¾•_XãØ8æ3IxåÇϽæwxð+«a¢üµS”ýŒQÿ3:¯ŽþUŸY³<¿w´Ï>˜;:Â÷\ìÖ…C—RL˹ÏvV=ºIâˆ[ú|‰ïb:{|¢t**ŠD:ð6íB5+ÚêÎ,„é7"!¿ÆµX…åÏÆ)6\òkÊE¶f´ø” CœÚl–}˜ñªÎ­Xúv\Ë-$y£s‡º"PÚ‡ðàTå_©ô89®TºÊ¥ööpÛ£ç¿øy`%Éoÿ÷ßü¯7/_\’‘Ï’±ü,ÙR¹_B`÷¼lÚW i¯C0ÚÌ=Q-̱ÝiœþŠ?Û÷Ýû~òÐ 1b§áŒŸŽS ÒXÙt‡oÌöÄì+ð°¦áXt_ù´àÁE€Túä@£Ýͧn>6‹¦mdi¤á©3™Eì‚NÀJü[Ö”?ÒxÈè 2ª!œ!0»ÍM»ž­ÂÆžÁuwÜk`@$ª©TÊá8ŠmìO/;„‡'Þv TŒÂJŽ ¹•› ‰·ª=Š“ ²t‘Î fo˜ßÙÈ«aŒ&"…1¢ÓQXâbdV¢æÏDc…“_üŠMì¦GÃ.B,?ÜÂçËOÒI7xè®…Ï‚ˆ_TS±Š^ÖI'™a숫¢–ï ö[¦4¿Fq\2BzË]æoh}¢øš®À- ¿M ¶}F^_ޢ诸ëœ'M¹˜èôå«Íoœ÷§ ®òP‘oÜ#lª©˜ Õ‚Ê„¶qT✗W2²‡èÒÇ ¨§3 "ËhZ#bkm¬Òå1”Q)ÐJð<Ÿ¦Â!\G*ÿ”EÝI”˜è¨ ׎ 8qó›„vé »úåŽë WÆ©©ÈÂL†7ñyOÖC›'Xƹîãˆ<ë÷Êš½éM Ó`í¸¤s£òLJg 3\·§Å#;—«#‰v04Ψì»I1¦Ò»€%¡tËX| éaG#qÖ MŽ5*«D¦ì«ù-H®¶Ð¥c#ôµw¸Ò8…•iº ·eíp«ÃIóWšJ£ä·V;l£ü”¿yÇýthñ¿zù’QûGø®7¿áN~½eSŸ¯ðIÊ4¾ù‘w¸)óÁ_áccâsÒÁK½1j‘¹B"ôÅtšX¢´Ø‰½ØMî ^jƒIÑHrѾo€Åäѯ™imúa×;¦á!(úfm§¿‹M£7Ï„3€e7&mÊ–¸jxêãäR.]ª•®øT:B‰êosúc³b…+w§}SºIóèôüòóÝRŸœéZó¤ÿÿôO¯þû‹Sf¬˜‘§fQ”)_+SÚ‰Îið{ÌT£·ë3ã§-˜¼÷Ý©Àø©‚Ù°þ6¹8C¤Ñð¶ÏÄQ.é-ttb`Áá;ÃtjÄ_h°/ƒŠÉ£ý3m‡tª3rú3ÜØÖ l ®ÎÐð#¿nÿ³<ƒŸ D¦5ñÁ}ϸÀä;ZšIãóÕWxÑlUº+N ô˜¢—¾y4žß5åšÿúm¼]™ Ú9ô¤Èîï`àÇWðOrà±øvZüƒþþÅóßýñ»ÿé_ýÓ£¯^–¢¯Z™—ÌŸslÄæ1%¯—pÍÒ¶”óïôÛMŠÄ“X ¯Ù>bQ¤Î ¶WcZÈmÏ@o/®ÁšY*j3–´‰w·w¼Ámö3Y¤ 2K›ÀîÏÄ2Ò7/-¦E¹9u‚õÚáwï|ƒr{KãÍ3'üº0à^÷´³D€ ˵§Ï6¼ ¹9g–‡N˜I¸cêõ†ƒ/W*]r7Še7;JU%ÚSÛ. ¨ÜQ°ž÷Îñ/w®çX˜)‹TÉ#ÜejœexæôÀˆ £OOØ[J:8{ % rÂËñ¾ì~“MröË€޳.š Y·ÂÇLPEqÀÇå„d"²ŽŽÊpç‚îlDù+ŸÌd Ýøê6Dãå‚‹Sú*NxÅO{¥KÒ){Z±V¼ª# OyÉW¹5òÔ-¾þæª np×nˆª°\âHY]i¤×4¢Ù #yJÒJjhD÷Ç<Gùv»E°àw¤qÂ’¿n㫼þ5 Ö¸ùx,’µyïpÿ#þgÏ.ð8Ø\²®ÿîÃÛÍõFûtXå¶=ówäS–€ÆS<¶uèº~6õ‘&•<àjE&íÑâ.Ëâl¤é[~Åta-pq »4ûŒfц»Ñtú§iØÂw¦Åž ùYðŠlùý)ø‚0,+ž¶Ä®€¦ae/˜]U|KÚx~lšã}þfH…P݉KN2ýá?ýÏÿÿá_ÿëÿ Ê9ð¿™Ñ? Kÿ“4ÛWÏÞ›ñÉ|ëÜ0UV‡î@ù§’A«¿ P÷Ou>8¿íûß gA¦0ŸÌY‹Àßf)˜(ÝPtsÕþS”SìTøû&€} îLÑ–þ6{ºCÞ<ú«<”‘Ås.šþm:<á'¦Òhk_2*zÁå'ßó*á{6z½e¯ÀkìàÝ¢¨—¢ºNxƒ7³·¿ùasù^E{ ”uØ3–ž±Yð3€[:Ÿ?Ø$0ÚVàSv«%B»«ÞÆß6?©¯‚cñÁ‘T7ž¡Êt’’ŽQ²nMÎù3FÑNéOî(V;xO ž^Nã#ËvPh5ÒÇ?üàáûƒ#sÒĨèCË42âÔF.eCe%rg› ù÷À´r.JrÔNZVÜø°t}ŸM‘IÉ®þŽTG|ÂÅQ¿ ãÒéçLÓSZº£’42 ÅG^v°ä3⋽¶xŸ$ª2ZGÞJI‚el·À„; Ò)SKUyu0¦ðk©Á’|¶º-Ojó¢<„õòDW´3 ºZvãam( ›>°ÁqK™9gïÉ+Fûgg¬(}Ù¼~û–c|ìQá1,Gûæå!ëø=“ó%35ð9ÆÒÀ1J?Êä—B§½!4ÍÚ¶(K|&÷ãÞù%XÄÛRWb¬®®ß¡[âlÁ©ÏZfØ„~€W®E¾Ó4ã6ü4¾nímÖØ4t‚и³òžù4´)×™1:„ö]©³ýÍX«T+}ÉžgnNY§#¶¢?[·O@Ô]^þøÜeg™˜Ás®¤PÙ6´§u}r§mi­r*“6뾟îö &¼ç0ùò1¸è,½‹~49 Ž–À`$¾ ¸OÍ|Ä¡iƒ'ážé(î—4H3/ÏN“X: ¶Ó°H3nÓ¯YùõOÓ²; ×Ð^¦‘Ñ­]Ú|¡B)Êmô›«¾åÆÁ_z‚À †Ø@Ç©L¸;¡\'.h´¼¾åµÛ÷ï7uÍX¾Lx~þýæá¥ËÜQøž9ƒÆ›<›<óœ¿W+|Žà!…rá~нŒ(•FÅg £du^Ý D®$@ ˆ1’Š:]geƒƒò¦ˆò÷Wy Ú=O š$û¢Äì$  ·.‚§ûLTÂÊë‚}À°]IÂ#k´ c{÷ ع!t½rªÀ ŽRDÆMßþ«qym´¹#d)7hábçÀS úK'Eb#™CãR ¤qÏ iù IAõMú åñL|d¡,äÜááµ9«Ð²V¡ZhÂ\X5mæLÉ& &<ü±³`Ø™ Çi:Aã†QâºeŸÊó—ß0âÿš+O67ÛûË¿ú«ÍÕ{îåg¹Æv<óïæ½”dýÂ;ó›¼¾ç+|lúcŸ@îÀß2dÈ:Œè1­uqTz0ØU#&\Y‰×Äò–S»‹4HâÄ[ØðÏG’~Å´Ðôn¶5üÚ.æcžiÚ¯\+Ÿöhí½PHW~þ6—}ìÂ*h¥IcïcNü­3Ç–n’kÏûèÙù“<`âT-ù;&ÓÿŸd‡ß|ÃÅ dŠí5;y2ìÊÕÙµZº•Ô©<àwá-hý>kÿ}¿}w‹$~[„)XW¬Å_äg0££é— 5à¯[aLI±ˆÓFK%\Ö¦32w€S„’7°ö¶Æôh\ZygÄ¢cý;̆Yég1mg5†=¹ÀÒ耣Ÿ81-ÀÈ CõCòAÄöÙÀä- ¿l´ÁzÁˆýìÅןr¥ðçÍë«“ÍoP^0Ä%ÃCMxÁj‡Ñ÷Í;.ò¸ ú¡ç³Ù+pNÃþ™û¾°v÷…Æ=oÂ÷ÚX*4zÐ|V„-kï‹òWÖæ—‘¿”Îl¹ñÏÑ5#]§íWEnÙ”1 (#FÖÜqÖ~ƒ±á.Ê_˜”˜ŠQšì+E£;{Å«|q§§_– ¼iÏ΀ j•þà†y"Tp/™£’Ô(ƒ¼0g ´›*T¿ºå_ûÒyjø7Ã7ÓåƒòK ~½!’ENP†¸@MðЭáªÐÝ9ŸHĸnáõ †ôÆËtã#1ýü*»F·¦i°]ƒ ×R«ôî7†ØÉùñŠçè¨!’Yn=š"2³/Þhè}\ØsÈHÿˆ0=»ßáä–¾¡-C•ø%ðŠ«@L>Ý3$%oD¥B¯ßÌC`*Zá„´¨ËqÀÁ—¦Ø,ì&¼-a ?ƒÑ»iú;H:Ôå»ðX ZV첕‚_bÛÊ¿ÊVùy ¡¿<Š6¥hqÞü[\gÈßÞ¾/ýì®pëÁú°9ÿê哼Ðx<ÙÀÇ7ï_æî̪EÔ¼Îöz1òOبÉ?Û€ ÌÂö™<ý«ì….<‹2¿‹ß mãB“Ü~Rt9Úû¦’V«1q¯&O€mý1¬iâÛÊXÜ66o¡ò. î>Œáoð¡ "´I˜&Mé@ЍðJÚuÉ·ã×£~imë]»A¥#cZ…þª #˜kv±¥¢Ëß@‡éöÑ8e[$'gÇy‡à{7 zÁÐÝÑ8Aà’À]T—³ª)/ºãB–»#ÊËË3fh9E@ƒÄÉ{aùò©ø/,¨PiÌkŒRA){î½òšÀÃMÅé(´”î–·o«ñr _…§ÒRq‹árƒ©èŽ›Ü@$Œ;ݳ³?½!ªc”¿èQ“Gå‚s¹j¨›s¬ÏÑ+ÿM“RÔЛn®-±¡ÑÑ{5™^AŒc#[Äaçºû/÷(á6¹n$”áÖ÷eå“B„;úÕi¢bÇôlI¶£(¦ÓÀaÆ£–ÚmœTðâB‘Ì›¸ÖáÖV³»t6Y.-¨¦µ¯áÖ>PçÝq~å&ÍŒ“3;d™žä`cà ¯ ¦LÜ2…ÿæÝëÍ»ú¿p]¯eôÐK}ÜœBàN~÷®Oïq;å1ËTÞùoN‰SéT–‘„=qRTS "[¤0ñÄ‘káiÁPÖÀ–\Ê«¿cáa1Û1³ûâÄ2±ã@ûxò]` ½éû;û— %ï,qÇ hªÖìÈÇ.ÇæÛÜ~Œß»r5Þ,kÃVÌKŸid°ÜzñsÈ;(œ±U»Òû©Q13òÏé‚ð€$ÊÞ V;cĵ¯Yj H`¹Ÿ)ˆÜ`ˆÌU¤=WŽâë>‚¡øLdë€K(÷t¢’™Èâ>HQ]Z€FkmK*6¤$=í Øa0¿(`(ú{ḟÐñ“eÜp ´¦ÿMݘTùO'àî–c|¿ù˼O¡x. 1ÍoeöXæ=×óf¦ŒŽÓ ÿˆ5~ËÝz9¥ÔúG &€²Ê«AŠåßê=dP25þâ˜?qð Ë£–¯44+Óô/¸ÝÖ4¨é7Yjn¾ ø1’x Q&ú¤é+w ¡mk(Å»)ÊåïOCªÖ­œVš²%M ß—KßÇ`kÌÅ(¾†¹s#Q™d"NÙzùîÝ©ž¢±6>IsòË_ò =™1æÆ“7h ¥›OfÜ»š X«.—=K¾ƒÙÐÄ?Bàî¯\&Yï6å?£K²˜ö€GÓê×ÊY»üÚÝ| úQ3.HÚôÅ@vǶŽÚ•S¹ý±×g§ed^‡¢Ÿ]/¿[ÖÁ³9‘T.¹•ÍŠÆÿd9…##rùê¡ðŽ”ÅuŸ€q°ÓQ1K¤â‡#¤p¥A¦„g:kÜ&X³!Õ(‹_¼j©¢ºŽŽ•Íà¥I‡éå82—Ãý¾3áÅ;9½bfè† {>1Úw9çðéΡg†À £ìã¡ð·àûZå;ýí§OKÚšJš’=Ör'þå®â«¬šYú¢3~î²Ô1&I¥®hƒçr_îê H3LÊôlAhD¾À‚30±™}C–ÍW߉ÉÌã*fM´Ëº\+‡û ©Óð¯£/ôVþñŽuÇcÇѲLlÿÁ ¹I>ÿúëŸ7vÚü®¾¿øåû¼/ÎôoîmïüêÜmwµ%«A‹ŒÕº¬Ê{Aåo#§IEþ~ž Œ8K!Äݸ©Ôò3\¾~²¼Û2/>iü¶±Ñ‘ux2ÒPÖ÷aß{?mË@Ê@T†;A´¬#ˆyæ!Ï€ÏÊ_PFKð*%ÉOñ0û;‚œ ñ†O©ŒrÙ±@e«ôLõ«F°šÊ ™N/PÚÏ_m¾cÓà;:on8NÈ—«‚r‚ÀƒhÎ œ3ŠÿÌÉ€kŽ:+ð‰åƒSîxÅ¬Ç ¸að g½¿0ôÿLËsŠ ©è+¬#]#ªªÍ{Ê™fëÁÎ#ð¡üݹŸ„^hì’ÐÙ°{’¤ñGšæ)—:e RKCªÂÍ|>2«®?FÙªüÍ€ÌÀ×i^GÌl…G£¨Íhúþ~@0*¥¡Ë.ø†3 vs"éU›…»`2æ/U¡8ÆÁ!´¥Ç?7 SeÖø.ƒa¹ D%m܉øÕa‡¹Øå¢x$m¼Ò©Pé¥s¿Ç2„ÈRŒŠòž^¨¯†žŸsÍîùsnä;æ ÛÍ»~³¹áR©{:P‡”•oå31ÜOÁ4ÿ.…òôÂ!Šÿ„óûG, ¹Y°f‚Þ•·H‰%öŠ`åŸ‘Ö X9~ü«w¡68“¢KüÚ-h·õ1Þza_¨o†Ìž‘¶išdå'Ò5MÙÛ5“<+:i:ìÕÖø¦‡eF\Ki™þçòYÚݲÊ6¯ÝòêÐ VáµBBcN¡c}ñÍ7?wÖÄúÝØ¶ß}óÎ3¶›4¾:cÎÓæDÁ`MÛhÔ†úuëáîºgçkãò­†xöýáÛƒÆë‚×î…UÓöwñ(Y­¬10ìûa «ãbØ Ë ³-Lüu?fB㦴wîšîé¸rá6þQî“[’6ŠÂwAˆPñ‹}•0/ì­1Q¢JtLªs!Ê_>üÄ4 iùðnµ­iÙ ã”)ðï9ƒý ëµ7ŒèÞÝžm~`„ÿÂÀ¨£Ïœ%¯•iÞ$àˆ×-]„/§¼SøœÑ#Æ#Ö‡¹ið3ß¹\ˆŽÄ–ë[[ù×%?¬ G¨”•Åéc%Õ¡E)§Çdª¬J²¦ôUÎÀQ¤*Ê(ÕLÙÃŒ8$ÒÙ—7ªaòýYgã¡é²¯ýÇ4Æ]›ôy{f„Cæ>”Y–òl2uˆ=_ì ŒÓ ¹‰ÎHߥË1EléX7 å^>–S{ GùIï€6û jú*×l‘f-Tºgホxé¶¼[‘«ëîpIg÷?Ø[MgÀø:ÃP4R?pBĤ>fzÿ ÅÄeQvno?l®ß¿á6I.ìqæÒÃSâÁÒ‘—_¸6šCÝÀñûáR;\âHv+þ?Œ9›º¼‚ ƒA<Å©_‘tíš}hÓ„åÒÀ Ê}µ»ŸX'YvC°ig´ï°é¾Ö8íÝ_QµÏ<‹¼¡úWŠÜß}nÂVü² Û5<©J°H^ ”™ZЂövt>3…òUþéi%%&f„Î~ž0i~·æðû¯ßœ3©ËÝÚ•]üR Ò§òT ¦¡¨l]¤]¯Ìo\é‡IÅh‡ßÆÑ ±ôéX@“B8üÓˆáÙüÑ.¾vp¨äÕ1)À8#Wæ0ñŠiú8¦ø®Û¶8L`=üõë "ÝŽ]Ü!× [d7‹W"–Žþ!°•âV—šiá¡HàØ#øŠ“p0Ë(ƒtPNЦ–iøåC"‚çÄ;²ÔQBYyÎßw¬ 3ðv¿É¬€{¼v؉ê³Í„ŸØGpà ;.ÕùòeÆNﯾåíFÿ3|@‰<Ð)0.[F•iyÑV¾}øTâ2ÍŸ£ÄF™ÜÑžŽˆ•Qå©*Rã¨J´Ã0:‰(áDù›"]TyÂ&#Ry{GÑ%‡SÙµ£Ð³Þï~”£C!,™ˆ“³Ê¿xÄ)/i ÔÔ+|„©]™äÁˆÛIp7ÕEÁg_nsDå3®I' .4¤“'Œrî0ÍÜXhôTäÒZ¡ 9à~|ÃÔl³±‘°]2Iœ¡±r2‹òಠ›y„·"¾Úœ‘_[Öë?1›ñîŠS 7ýäÔÈÖé{’’νÈñyg{ø‚G§˜æ‡îHÙ ¹~ËdD¨íÐ+§_ ÔØýOûéÓÞÄ-†®%]%nƒGaò…w‚`ºÞ4 )¿A“»Ã™¾º€ö:«œúm†…ݨ­x ©A(ߪ ÷À;MÅi+Æn g7”ÿq[åÁ®Ÿ|šûÃU–9†b®0ù…& Ä+Ù}ʇÉÎ^¾üy`7¹û®ûÿø?}÷pz|G#ÄÊ]eоòÞ™¾HTmT2´ýöë×R€Ìxñ‡Yf,ô´3NÂlƃN˜må¾I¸3ºjXf`Å-x(þYäÒÃpªýJû”0šÆø(ÛÀ‰\þÐØV#Ž]ÿ=ùüÆ7?«1œ–Je®^E!Ž ~Ð÷W†ÍsdŒŠ10ú>™†ÀŒˆ~vŠè¾aÀ{ãŽXqx%<å’÷ \³yî KH¯oØ+ð‰{˜L&L÷ x‚àÂ;fî¸dè;¾·Ì^<çW¨Y7¾§ðå¥ü Ånå€Î‚‰©L(¯ÁTÉ §¥Qª#¡ƒÇq²Rö%ûÃÇUä l¦}È5šœðPÙW4M4›óòÛ¢üUà2Á_Ëÿt äé°Ú-ðÚ Â‘{’sQÌy0iÐø6ýV¹ác+™)ÃOÈ$½Æ àQYÈ/¡Ñ“œGñª´ó0Sz‚E’å†f-':Ïã—9w‡cë­zण‚¬(õÜ“€<¹®˜ÎÜ¡›ú<ÕÁÌ2\³©ïêÏKùd4Ë>_lçÀPmèï?súƒð8rÈÿ Ëy©Ïx Þ–=}Ö_å,/pVpÒ:´+…Þþu25ö.Æê’¯õÄÜÖø[Dl2 @ öô?„·™pgøªÔ˜õiQnçñu†GxƶÐ4Ó†–¢Ÿ)ê¢ /KOS„i …P´þ6†ðâÛ°™Óµ¿K›½‚vl+ß5”¶ƒJ¸…Sþ£îÌNÞ Q<"ì²ÒÙÏK» ø»p}ú³?ûpxvñ‘êòM…7²sªm6&Ö>}̳d«þŽ­G¿§ßÈàÒ(X¿}3`]Åiò >FƒGÚ[”7xòè YÁK˜-›² «Ïã—8ÊœöŸ¨ðIyÙgÐľ0Ówašf\.Üå!¸–°ñ?Waxg¶Æâ4›"Ÿ!m÷;L„ÑÍ_ÀP‰¥Ã0¶‘ø?@duLË`#itv³Ñu„Ç –Ž|¢ø;¦}ßæý6¾fŠÞ-½ž Pm¹Òü…΀Å®ùûtÌù6 n9Apt~¾9Vñ¹iðªÞzÒ`´ÛëÚ¥Qù£Œ­–t(`_þsý¼¤"•}âC“} 8²vê<Ëc¤oä’ÌxwüïÕ3ZÎcmPîðwTëÈ;XêGæô&ºZ‹'¶îàÿÖwçw]ïkÊÏÂS>ªªâ«\v ¤!NéP¡m‡ MÄVé«È“3.‰HCœF¸™Í”?ÿÌÖ(;ÞPx ãáQºýêçÀœ,¿ûÝ¿ü—7/Îxðá›®"f^g”ŠSe¨I¦¶ÛZ)Ü/f莀lR)šI¡,xsœ¼býšg*#Ï~‘þ kÙdÒøÊ¡Ð­üãç&øZ: îöï(´;¼Å%îñc8ÚÅ݉·~â&ã3€ï8F¶Š>Óõ d‡v§¿Ò[rëPç¾¶°a:!â|¤óБ©˜ ¨­ Eß¿^Á3 ?œ½Dà†øCx±’”7Ý¿:ã¶ÁO§õD1ï ¸Wà’©îZÅ÷Ž2ª¼ýÄvÂW›O ï΃Q³)På_)W›é°£øM­ÚG ->ÿ¨käoƸ~Àºº{ < à²@*||€OâéLd=±A6º9Qövu,Dðw@vÿ+£pødTžÓʼ÷D w]\I¤†Î Ò´ƒPá2a)Š;³ÕÅŠÒ÷îÂ-e± æ¬]îiP6wðŸ<ãvGÒ]-sÇ®÷¯7Ÿ>Ò #Ü-q?¾5í˜Q°øÝ›æ>·Ëÿ“öu0j³ƒvƒQBÊÎ(ÐÕ–à™Ð î‚A v“J3>åàWav¯äíÏênW@ƒSó“V{Ü8<óYIƒ; Ó0ÚGŸÑÏ h'¨Û¢ð?Í«QåÛö¿ ^ujö¥iÊäF8F¥Aù>Òc°æõãïc²‹5Ëß’nIÛ'ŽËYG'Ç—¯ýkŸ*y’†áÅÓ4þ{¿wýûgg$×/Æz6Z"ˆvüdˆ)Lp ,ñ‹r´ÑÍ¡#rd@°‰“u\™MÆx¥è ˜M†–(t@Œƒ¤ÁB«œ¥¾Né¼`Øwpä…æˆ:qŒü“n¨—#ÂP9K¤nvÄŸ„%Â*Ã\Ò,)J–¸øÂ]ôpFà*Bøø“@%[íp›¡ 4wOÇG›ÖÈß%ãçL‡ÂC™»^o¸îØ7/p×Òø˜CÒÁÂm„}^ØÃlƒ7öŸ¼à1ž3wòŸm>ÑøpÍ«\Øó9éˈßsù,ÁÄ0ðÅ5~edßÇá1ëû~sW‚1ĤñMB¬:‰Ý@ f£„µ?Û(“ç°Ñ28Ä]ö¢Rˆ¸SWŽEX<†h”i\ ÒC>ƒMñˆ —Rn'–{î¦èzfNJ+MÅz¥né«ó4 –ðp[‚:Ô¦mÆi®õm]rŸ©¤Ô4ÎêjY1þ×QTHÅ·ãl–ߢׂdŽî“gÏ>þoüÇÙy’æÉvþèŸÿóOñ_þ×òrXåL*Aš-ÝJà§²H¥ûSfö|¢p_ØŒƒs w¶ïá„|6¢¯ùg朽ø8ÈZpä©'€ß†aµ gP>üÌÊ0ü¬*U|@)øÐÀò“Vª‡bž£º„N´aYøwÃu¶¥,ôQp¾ªêC ÒvŒ”¥ÑXQÅ ’TÖf, ½Gšélcü¬ÆÎ¤²«È@8äç{ιÚõ[.„¹ä‚¡·—'›XO~‡¾bêÀw Ù+ζAöß³{ü&±_Àö pŸü±£Ù}:—næsÍ Íé„<þãíƒNïGiòuY Ê47Ðy3Ÿ×ÓéÈ­‚‚—Ù#hz PQè¹wÎýgÊ»á „W‚ŸÑز!.;öAIÇq™²§‰–FåèŽx;QîÅÃE‘å_‰ ¾eÀéL®E–Æ„Ì^:1vèìý±œŽÁ 1 xH¸tœXŠ‘Ìü8á’•SvòÓ±²ãqÍѽ«÷¿¦Óu•Žƒ ÿðÜš˜<„°6Qæ)W?ûô.K<‡ÙÔW<•1H-–a‘2”ò°€ø)ÚbVhþDZx­–™`…j“¢}û»pY…µà.ƒW»Åç/d ($(~ùÁ Uuà„d 5J“?öqJõÍXKh w„ BB²È¡Ü-]Õ:]ÅÝÜh˜Üç0S?Hó™1¤hÎkH]WI§BoŽ…¹ò-8rÙÅßðvFÙ¤ÿèÏÿœù4Í“í˜Ü™0?RýÒ¨éNa·M ?¶ÅÌ…ÀvÊJ¾TÜ‹™í؇çK÷ÆõJ‡„oÂ0`y*SónùÚ׎iü`9ªpV|¸IJ”5<ÝåßÓŸå1ÿ6c`Íf©»m8íï¨zÞå?³A‡²íÕèÎXeO“œÌ@9€œJ‹þ?§©°3 X¼NÓòZóÝ4Á?³~qV(”R‡e”TÓþ«îPLy¢˜ä÷÷>Q̦ÁË[®>ʦAT;£Í;çèp³wì ð&€Ï/™àr¡cî8|ŽÂD}fÁ—k…âz"”Zvº;Ò‡GD%"¹(ÊŸ€£ØÄSáTºN‘“JFHGÓ˜ììw'¿À¡/Ê1Ê_ZGÞÒ–âÞº  ›S4‰,þÙåÿZ£‡¿}±%ωžëþîIP²‡kö_À’cÐp|›úr„O¾à×} X);*‹†Õ”¬º»x™bþù|혢ªÖ¦í[HÅÖ”»}tÅÄ2á.îò^yëÆ…óXègv ®(`…µ÷‚×4»(¢M&‚5Û >[+]ר K˜3É8v ^˜æSÓYsXyï°›a̰ÙÞ\›\wù7–ŠKŸtT8yr|vþá¿ýÿ¢+H³y2ß§Ýxù2W0ÎEÇÌI‘%Ý$³:S+_z– -2‚¹’ÿdÛó݇éå¥zŒ„»í¡ži´«•33Þcþ3lâcü“¬Ãï4iÓY™ù {Ea¤l´™B¥WB ú¨™Ž*TÍÂ`LwÌ ÓÕ”/É0›¶ø.¯…‡^üpY,º×6ŽÁ~5lŽEÓôÒEb¬ MBËur:cG»÷ xí°O¿þtìÀ6ûõëúÕ GÐPM·¼<˜?7ª©Ðè =ÿjsÍ—KöÐxp ›+‚]ïÏÔ»GùS€"‡w6á1ÂÎM~ƕĮ¥ò°Cù;Uïÿl؃æá3U<;4Ê÷óø"cN$„±ÏhÛ;rï‚á¨Ì»Ã mhø²oàá f&Ò›’.þòæ/4pHáRÙK«Ÿ³¤…ï$á½ o4ú1#ýç̘œœž±Ïðsû×›÷¿a´ï+|PÚÝȽ|é9 :J?ÿá{_»üñ;ÚWró1ËIÁ%ÑŽ”ž˜ÚÜV޹}ŸëÃ@-³%„Jƒá“zݾQ …h†{PÅÕvkÄj„ÎnœA¬Z£u8‹d”sç6z‡–Ø'˜î,£¯;´çAò[hW´šðvà%CÁgÊâ´BVÛ9Î5þkè…ôcʆÈ}jBÖ´þxÈ]Ci¬’;±ä&@f©žìú¿éó¤;ÛW/ßZÝK¡ó%Rñm¿h1ÌtÿRÁih9˜•ÉF Û¤6í&?ñÅ-ž0S†;ôM'혌6ÁéÆ$rìÑDü"ÊïÎòjÒXbïâ—p†;Ê6ù'Ž“\s|µk"Ûp$Ý$jÓHûîN¼!IøÆ^IYºVXÿilp±…n|qØðÅŸ•DFc«7tæjÆ·éñ‘.¤Ëxw:’ç¦UÒ­aLGïð ‡âc1|$§Ý'¨ÇA>2Mw†Æ ^!po¹G _rÕw÷œ ¸s¯³¬MÛp±¬«ê,¸Ž…»›·›ÛíÇͧ\+ËQÂão¾Ý\ 즳?yÛ { 8N¸=Vp÷  #RPðêö<;&£æló¯ÔˆbOB å76 f­ßiÿÄÒù ö¨I‘ÎØÙúdºžðPÊ›Ã1K~’œÑ·£õÔŸVþY@ +òDdd ßMƒü«×ì˜ Cg ûŒ–kütxréL·ìÒ¿àøž·ôy>ÿŽ™…7l¢¼¤sô™€…Ôóü'ÿ$ ¢ÏÜŠ¬¼¢×#X'‡¤2³3æc²Éò4‚N¤_a†‰§ñI2 ÓCx¾X…ip§Ž` Lw<ÆÏ f¼5å¿B–rßùC_DEͯ–0<öq qf´Ê ‰ñ¢'òš°möúîóšÜ+ZÅÁß2W] «×5S~ÿê³Ò–«ýš®ýå×i×a¬ux¥Ò6çgâ¿ëWx Fû!W,*~ú­r6¦ye8-I!.7Y<»x²ï˜8OºpøüyžaL%_È[9¤ùØÊ4Ùhk1ŒîŒB Û¿d:–¡!–ünÑ­`Í×pCÓå¤å±yh>ñÐÚÏï€iBÓ‚é(-a 4Ü _wü'Xèp·‘gŒ8Þ ]ûGž%°I¾ XM«Ê‹"®JWß8ÆFZÀÀq´PÝÎÇZý‡A²ÚXÌÂÚ¸La÷N3+m]',~7)e×ÕIRßÕ]âUs;ü+Ép•gd”d{¯ÀG”Ûk_&ä"!.FUyÅJоÐRå‰â÷Àß_o./­>£3pþ’ééÀæÛo“øi‰I2¹`Yt«÷M„dñ¤ ƒ7Ü©lÒâî•Ò5Üñ—¦qfwùTc©ÿpG¹ãÞ7‘eûÀÛCxÇ‹ï‚ßLÀC&{µšXÃ| )¿MR²'{ŒGŰ ›MUìQ½C¢¿†i9x,üv)ËU8>Ë;÷¼#kðW^åk~2’Å Lê4QÒߟÕV üE*²Ù8þ­Ù ø9Õ×ôÎîè²™/™-xDø_ñtì F²¿D¹¿åý7×¼EÀÔ¸ÔnYãGmefÀ ñ;¢¹æïvËõ´/]àL;· >çuÂ/ìøÄcDŸ?¾'l¢Sç\\äÔwFþ#¿J³š™HŒP¹"X¥‹²¯'~FÙƒÂì„£éì°sÀátúÿ&Vxç²ìÞ ÛLëÓ ˆò€äξÝ||Í%K^ßëÑEÒôÀçw¡0ï¹!׸WÂyø;âi^—kÌ2ï³Ï¯2‹|þâXêoàýS”°¡aàf ¨™‹ aÃ4ÖFg”v¾M gKÓЂ%4ѦrØZÀ+,pjŸËàš`ÖO‡ß á^Bd¿vêî4iXHaÊ­.=‚Ñ!åÛ‘“ßZï Gwói´öÑÝyÖM¹6+¬ »îÇò·`âU®<†3s1ô}éæøV ÆÆÙuþÕW„¶´Oíû¤;Ÿÿâ/ÞoyÉ-ÕÌ\1SFÉY”C²Ê–EqÚ~»sLؾÖüô’g»óÝ 3%CØd:Œ.Ðí-…n„«=n¾a1ÉÓðÆÏ(·ÃP&âÒ~Æ+^>ò˜âO¿˜¥áôí1·AaªG ‹%áŒ8Vc9ƒþJSUW¼CUÔ0ªå Øû€ŸÑcðÀŒ[8Â& ‰q2nx.0Q„ Sáƒ,2ÍéNøÀ»èå>ð ߢ766ù‰ëYÂÄJ½Œ=¬öC¸dsÎ^_pOÀG÷ ð^ÅkFíÎ xÝÏg¾Î ¸”ð™ÙÍ»÷ü½Û| ,>áѢ͹÷ |ó  ?rçw °±°eÜzœ¯7ü)©q´gâf=vÃ-Êú2EïžÝžÝG‘›~Ù©¯?{B*u#kõúËn*ôA!»/™ärS£J5:Nlæ{¸§¢XÆ8yq–¸œ1Õÿ…sɒLJw<ÆÃ¹ý/Üâ—ôbd†‡?ôœ´ˆˆ2æ¦>¯Z>í{ù- 2µÓ¢•wUê*_ªlʱh¬«1‡S*DØáe;¨ÍÅÉOòŸŸ*ÏÍ]_¹—4&e™‚·+iŽ&¿·‹°âÓ8CÃlv³ØÏ,Zö”óx†s~*ôA3üv`ÁÚ#š`â–o¥‰öN×N÷‚I´ÚV*á»!cý »iüjúÛ4@–Œ-X0–ÄT+ú.MÍ.çH7çöÐä ~îTþîîîß°¦úÀYì4ÙdNFË*:2ÉFÀŒµ<$ߨqkE¼(SÚ›ÇLÊ’tò§ †;vœýíÂ$ˈ¨‹±%aÌ#útTôÃà„~ÐD‰ œL¿‚ÛügùÛO^é¬@Óx2_üèWÍ¥ÂÆ‹ŸFÑkµW£H"Ý1¬joµ"þú[Gþ’C;¡ö‡¿j°áß½¬!lmÖZ¹%O;P…ÖiåeðÃ$$•ã,Y2 I`¦—²éÀ#I^‚-l½ŠXPç9ƒÜ*gƒ‘¬ ÎQê‘×s íW\5û+ö ¼áøÝ›+ŽÒ@¥sç wÚ©VOx™É}ö\sdðú‡ãÍÿËÞ›,YwdÙyñwø´YȬbR%ÍhœÖ h¤æ|žz> B2“ÆÔ€4Õd%€™hÖ·Ö^î~n% *3`ðˆ{Ü÷Þk7Þ÷ÓÝs¿xÿÍÝ‹÷t  +/?ú…¾ú\g˟鸾ÏÛöüŽ~úÏõÃ’u­ô ¡ð9æü¹dÁ«ËôÔØºDÏâ®Kù¾¯_¾ _‹?G ¾ç]Žˆ/,ø×÷t`ð½ðûD_wäJ _WäUɯÞÓëyõÀãS=˜÷•žmøÇ·ŸÜýNW<¾Öýn[Ý6x¦¯Xrkƒ³\ŽC¾å€…°5£D@IDAT«z¾â¹ô^èk˜<£@w¬V”i±R¢®È;)VŽc”ŸÉ<°ÃŸ.¤Ø‘³ß;-£)x+‹­P¶åíH#KÊÀ°ö/ôà;öDÂ1W:ä$b3„zLZ¶6*|Ø‹F)d „ܼƒ¦8pù§”(ÊCšht¡·üÆØ²?ífð±Tjk>dmZYÊÔŸÔHBí-âÝvv‰$èÓ±(>ÚÊ’)g z­1þÙ?üÃÏÏì&þ—-½ó?ýõ§¿c/è‚À‚§²ûiB¡³ºcÀ¿ !O–GÌ¥±! 'ˆò ;hc:.ê´ò#¦ªr‰¡Båð‹a"g^ç`ŸÒsýÇoõY?‹o.ËÉÚ»›tCX[6ŹÁ4¾S°!'>^· šÀ}X ³ÐJÇŒ Ö“0< Ó®Qs4k"lŸ‘“¸}pl…gÒþ§q¶qÄ"ŸDä³û mšÙè9Îtsžo£K‚{Ç ð¼ïÝ·~WW~¥KÜouUàÓ/ô¼€~f¸WXF¿ÕBýJW¾Ò™øWŸ¾Õç“»Ï^¾¹{ª[/õœÀë¿úðîÝõ  ©® |󹞢ç`€K;zŽïð¯ïýó Àýè‘Ç9ò?(,(稅£J¬ã+Ü Ðe~_%ÃwêtË€û÷® O>ú«€´™Êœ¶óºa½^÷;ž%ò©~uix£ö¼Ð• .&|þùçwŸý†{ûº”¯¯O>ÕO)?õ/wj‘§=Õ`z/rÿ™®p8,@=Rœ`ˆv%ÂÂ}¯riTWy0Ð|Ú7f‹a:GÚã€48¸`TW *¼k‡èåç>:ˆ,úھėÊ=-1.±ß8ï)Høï> Yò±GŠÉðâ`ƒö¸¦ ÄN# 'ûþÕo®úWÄUöÃT½1&Ì»nõë‹\ia‡†1W~øó@ZéO°ýË?ãGCžè"N¯±µ:L¬)7ï2'˜Qé¢BÎ2£¸´ìx<ÆpËGvú(lÆÉ¶#ìø¾³l¡½taùfÓìaÆ{[Ïü…ˆñ;hÏ©§þ‰±¢bϾ¬ÅŘ¢»©YÒyNÑU±kþŠšÀcQl4%Á‡°d‚`³LõöW»`Ðð£´ãÅ™ÛG1F¢©\‘ËÆ„ÇmÍçõÅçÕe Òt¡eªÃ«”-£Ob—DKåk]àÁÁ_éªÀ7שׂ¿ÕÙöº^ÿ¥]ž§×—Ú´l?Õ¯~q÷å?è8¿ùDWtý½_èÌãý»÷?üPÇé`à­~íî­.§ë­xü¡¿A(?~u¯_Å«…œq?Þ?ÊÃspÁ@뻣å€@¾Xº¸ ðD(þ5?5¤_Ü#:*4gýZÌýÝú§¯t‰_ïäçàDÏ0ð5ƯôjÞüô·wo?ûTÏ9äý(Ü¿ç'výT£|Ç;ýÉ9Âå»û¼—_Ï<ÕNéž‘0÷¾‰¯É’Äht&¢'AIv× Þ‰1Ñþjë "ž“ •»]Ä„öAùv$È2®¡ ýØ&¼•ZâÚ<4ýzm¼ˆí*!&'=»‚ËÅ [ó¸Û4vÈlG¹ÇE‰Á#gLÛÞÁËaÎ0>Å´IŒ›ñq¥°uOëcle·:à%PÚ…”[§çá+[ÖUˆVd·ÛêDõ;sšg4d„ñÉh}÷£í/ROS­G—=ùå/?{ª‡£¾ûJÕ»ê0í í¶‡*soÇïÌQðA{`=`¬;•m1Žõ r“¡Ú›¼Ë64g¨æßàp½tÑ#èrðRúpŸ™ öÀ3o‹v²3•ð3û¨¡ ²-Orqè^އÄ\}ƒ NÕk2ßG‰KµiMˆXi»s6C‘KÌLp$OtÔå¤ k"7öºÉ~¢ŠoJcH>Xü!ÍYq*¢Ô'Âg*Ù<–™¼u‰f])ç ÷}Ýß~ÃU½'à­óúêwŸèÛŸ øåTGñêá×Â~­3ò¯>ýúî =/ð…~ëþ¹oèõ¸¿úÕÝ›?¾û†‡ õ ‚?|®³rý&¯°ÊÛ1×8ü!Þúç·ü‚îùûå‚ZÙ¸eàðxo€oèë‚zXA£ä ‡¾þ÷Lgø/µà¿Ñs /ô¶>^àÃËzÞê9†ß¿ÕÙþ3½ :Ñç6…ªïé‚î4ȧ^çûL·^èªÈ -þîSÚÝ" SÛKê‚“‘&» ŸФ¤s;CVAÄÙž â@’ˆïLЕaqy~0U4W{Œñf0âg–¡ZD;Ö(‘F¥%Ó÷ö,[›ÑµÞ8†ýªa·uP¿»€5%9‰7•´èaµÝëXy*NZl¦6àlc¢”6K›hÁ;[ï¾NñͳOn/‡ÃBîyFPËg¬å߫ߥQGƒ +cï}ôËŸVKÿ žþò—Ÿ>yG_æ\B#Á;ŸfIï°ô#Wc"K–Ï¥‘xlA¶tU@:¯µyýæåÝ/xíð7/ï>ÕÀoÿ\oä¡AÝÐá«„¼vø•¼ÿAgû_ê›|uîs] xùÁwïê,üƒ?ÒCºŠ ÷ |­«ÐÕ¾zÇSú¬˜Oü|9äuÀ~Wt`ðB‹¼~)—ˆž_?ŸK]Uÿ¨ÞyðJ_Û{­WïêÁ[]MøR_ßû»ü{]êÿìîkxðüíðL÷ñŸ°ÐëÈâ;=4¨÷#ê¡AùÑUgú1ž:ÛÎm’êÆøw’.i²¦/{ÁØò”|€é†œ6^ÊÒCÛFÓìTËäÉ[6ƒ¾ûPyñ#]ýò±a_Ê“ª™|ùX‹K~ÕÅïæ0–¦í[‹*¬ñ<æ2îÂ_Õ©ó†T×@çÖŽU$¯½SuÔjÅ1AÄMòÖ`ïÏHOÍ áe/)¥âÊ»¥ÁÜOµZ˜qÝ ≠¾¬U.œ%ºeÑíηsžé)¯>þùÀn«áÒ³>úìûW/§.|ŸîñdÅdBÎÞËÎɬlÙô´±bƒ1«ÐÌIÅ=@Ä3¾ºÊ× ;ʘspX¥6¯·`ùÀD°ø!­rm…:Q–Ú°ñßúÑ|ˉ\3ÛØxt8)U²³à…VϴоÏUý¦ÀgºµõÉçº2 ûü<+ %Ö7¾QÇé—ìõ¬À·w_ë7¾ÐÿúÓ»zpðÍûúªÝ/>º{WŸ?|õÕÝWzÚž7~£wø­€®§]Ù¼û–St|A¯,â×}MPÏèìü‰bäÒü;Šåõ=”¨”o´ }®ç>Õ%þßéÿtÉÿ©ÞÀWûü5DYú^Ï|Ë+~Uµïx‘^äEŸûün] Öª¯h˜µI{˜eXä&fdÜLÉ36°1Cu§Œ+ÇŒÔF»%6¦}LüÆPãÌßa$ЉWœ‰;Ñ?ÜhÁõ8¶Q-Nò§æX%õ[±JgÕC ª’S_<,7bZ>n‹¦®à[oÎ.`kȘ=a é•zGD©<òåeô7§*(:ô•šHÇžlH¼êa¨ü¼‹M‰.ÕÂÙY¥¥„qéïbl ýâÙ‹ï^¿ÖŽ÷ˆÓ£¾ðú¯ÿú­~üs]ž|ŸNòW›= 2HV¿!K_º«\œÄ34ÜNe”Tܬ۹?ëß nyñ:F—¾èiäDÃm-ýÐË¿{>¯£_ÐGVxÔÿÇúO_üÕ›—Ÿ3©®Áå ’É}&öî<ÃëÂfUNžùÕ‡Pò‚ ;žØ§Œ¬É¶¤—T®ò[Þ-](>kÞAÏ\`¤ë¢ÒÅÏ¥RÆ{¦Ñ¦m”ëâÁïŠÔ4ÔÚF\ j3J LÖb7=6ûc,kâ­Ièeò'Hê¢ÛŸrXË¥+RÿÈLj8ÖÇ×Q£„hÇ€ŒD*YŸ”Ǟ˖fS•²n,›½1׉Öñ²"®ïª¸:ûÓFÿ¼`è^0¤‡èþRgàŸégŠ?Ñ×ÿI‹·–bÝ"x¦«¼(X$©Ìët¿ÐÙù—ú†À—¿ýG½ªT—íu{à]]¶£ò‚¾ƒO',7Ô—‡ð8àЏTò ï0ÐsoõÜÁï>ÕÙþ·º·¯gùøŠ#‹{gdAßêèû[}ïÿ©žgx®8_èIþ§:0àê “eÛFIÿRJû¦äJ/­“Û&A¡ã6SÁMvú ­ªÃwR­ÐŸZÒö{àà‘Û¢Åky;ˆà0 r§+SVZ°eŽÃQ¬VvaXµ·Ñr“Ù(Í…¿µŠkî=Í«+µmyl]9Œ¯hTnÙˆG¥È#?£OÄêZ!<{ýêóÿüŸÿó£ý)`*ü¨¨À³÷Þ|Æʾ¯ª™ü™.ï~;3ùm{à«×™<4³uцôL׉¿4ùÁ»7Ș;ff@Åv¥w.ÜÇø»Õi.öŠ] ®Î!#–Þ· 6•Ï8-Ÿ:S_ÇŒ¬IvÛe%ׄkçÒ1ãÆàìæLÂkÇÅ|êK¨®d–ÁþЦ0›„ £Ó{ýÈÁ*8cÙ@ª~KW…Õ>^ ¤…T9<üª[˵¡_DÚÇt…G.¿XàÓ6ŸšÄÄP¯‰x(+l;´KÚ ^î+Wš‹c‡ÐùÏg »˜øQ©]æ%è&½Þúíßþíßò…ÚG›ýÀÝ{ï¾u·h¦xªÅßïm¿·½ãNdf!y‘ìí, ÷ž¾Ê°‘kÈ®rÚÄ×I£7tYM]hÕ§¾Í¿µQ%ê½Ny£cr0Ժ˧ –t‹ÛÒ­Î4cMZÞj<@ƒ¿¦úˆ•ÙZÞZՈܔ6Î;6oõ'pê¶ln3‹·d*b+e_ÛQXé:d«¸,ÞÀ7AU Ýéá«ÙPÙ²ï%ýsZ*H4j„ØØ~Z·åWÏãk9-ý£y#ßËîèñ-€w^¾~Ô—ÿ©Ê£?xúÞ~ ?WÖÈcrçဲ2böÌ@í;KPîbpËÚ;“Ý!÷$'Õsâԇ̉c0ò‘Ìúã ¬c€æ§LeW õÁ’yØetÂç¶ìÀCFˆ®ßÛX&¹vG¯ŽÂ+ù!>Upï¤áï-ãÆ~,À»tìdk† sDVÁöÍO•“°m“?èÁ´M«‚)’Â…M*`nsEãœh_‚qä’û­~᫨¹ZÄV¦ kÛ ñÚšŽ_âA6µKŒ%‰á‘|K^EŽ&)ñ/™Ñn+]û’1ºûÝ·ç»õðÞ_ò^ ü–· ê)ý·Òà'Š9x-ôdà }]ðwz(ðwºÌÿ•~}žêþ¿žlV¼:X/âMz[àw|䥞0Ðýœíó\‚£`Ñ'P‘­“(÷Ù%Ä>¨Ä®ƒQ®—ûYFM ]OÛÏÓ&º€¶!ÚwÔå0ñ†]bÝBÌŒ£‰ô>‘ÀN½å/RméõŒpk Ø®#›}xk¦>é¸ô©SÁ™niÉþàɇï}Bÿ~¯ïóp7÷T¹gÊÄÔgÜÿôÛ *~a%š÷žñlN}ÈÚédˆ@%yÀ k¾ö&Ô\ƾhXø§îÈÆDÖÇì‰kè€7fbñD C´ã«ýKÅ–Õ]‡cñßõÜ;©×8‚1{bê“mtƒ’Tš dG{—)†îˆËVÌÍt©àW]0B{xO¬-ѸtZS†©.Ûêe·w’Ó¶ø¸iw#†w´¶Õ”b+•ˆ?oŒdª ý /!ª|Ž0½ÆŠÇñüŠœÓPSIÚhIe“ç÷Þ}©#Ò®ý±n|þ‡wî~£gxõð':»×ûõ¬À÷ºð½^0¤øè’þgš¾ÑÇ?÷«o|÷¥ö!ý†À÷ºðT/t¶ÿL_åÃ6ƒ”g'ü¬ÂÄLUœˆEe‡”¢Ê®­«‡ÄmX¼(à’ûaÌÕ.⨜³ÿi3¡€Rõ݃©Lý4”ÉqŠ–S¼”"_Œâ¡QÁÈ©7¬½§¤6Ïñ’²•1 ­·Isü\ˆJFi³¾I¦Âs„S†ÝäqpÈÁÙÎðÎ}iõW••¿”¶À66™Ý0QÌvüÔF=tv±Öp4u¹‡oå’ÓJÉAÓ›±åÖÛc³‚ôXAíLâ¦N‰Tb3Lz.Q¬ ‰Ô¿^†¥¶xÜéÑÜ}ðÁ'ÜQå!)Jé @…9ógMëDáAOëã Äøé¼NðäJ¾ß¬2p`,èÏœ›q-@킽]fœ£d½qZˆrFÛ2êrBsàà) øŠs¶»5(Ϙ•à¡z ÷@—tñ˜ mü&,H’Ùñ*4jo¬·6ö¸„¥b;[jtqEéD·S[sk/'.qÍ·åzL»e.õÙ5)9 [ÑæjÍŽ6sÈ0v¼Ña;¼°dô-cúù›wýsôËÄ#,<ú€g¿üKýãî8~Ÿ+éÀôȹhxløî2OÔCf6Õ™•׎zИñ€PΠÀéé÷ÞŒ>ºxÁžã:xðo“12jól&¶…í {²åËÚ'Šè8®Kpµ`„ˆîÐáßB;ñíRÄi·;j-“3‰G íXf[›)W.¾t‚Š m@;“Ün.°©å¶TlBPñ9¦_p-´_œßôMÎzÏ@TFñHú„”ǓNJô—ûͨ½9ÍÚ„ŒqpËÕxieŒ „LïÝ |å¡BPIzŸÏÝ{úöÀ»zhïWzuï—zX𭮘ýƒòÒƒo¾ÖE­· >÷kzu›û¾,–…¿íÅ–];aÓ5"íÆÀRjoUž§j1Š#'ù HŠÙ¶2oÙ‘RõW¥OÜQÞ­R³1\¿•Ÿ£dj¸¼Œ›Ä]9¹÷"ÁÛ6ºâkKíêd,N×aBiKMÎäbîa3¶Œ¸·±ÊÉÐkÙf†wÂvKnGÝÓ'ê}ïõµ}µWªÒØ µ}•ü&°2ûè•iK2Z/`œÊ8è[Öö9:Ëʱá,—*h€¾zÿ½GýSÀÔöÑ|÷ßÿû§wï¿«û§šµù’©*ÆÓ~ Pe:¼}ÇŽA™™Óƒdè5(<ÁŽ&hð$öÒ‘›ž15p *£¦“V™‰£,Í×`V K¾‚’!éédî²øÛ<¶›Æç91x’ùÌ1j«n…º¸¹ò‹TТXyˆ¼hŠL΄ÙŽ^Rëº2…¨·Ö‘õiË?VÖ8*ÆìÅ»ÆZÜ“r€$î\•‹ÑžÊpKê•$ç0V‡@LRz‘Ÿv.›ÜmŠFÀË:±`r”ºìé5q Ï¿Ü¨l“lø(ö.ž=Æ- ñ;ÚI^é à_½y}÷Ñû¯ú®ÿs}à÷ú6Á[}ô[?vÀ{ùÑëé¸)-Ñ’Ù? 'QGňŸÄ6q¨DÌ7m ãEA!fS:¶1jû+¶áÁ´]Ñ15BgŒ¿¡Ç~ö¹GQŠê[V°ñ’FÉf§,AuÈ]Ö†¯À®Ã&3­4ˆôüyÀ±"ÔI—=Ý—úb“4ÂbÌ.ÄÍö^8L¡÷<vb]VÎQ ³Z+ñ~ØÇ2ã‚ÚÈ!LR{¸Ï­1žµnèå™Â˜=´‡µPþ€•EòýÝ»þâѬyäl€ÇTþöíçoŸ¾ÿ:³"ýÙíŒEo¥Ç²ÀLå‹#{àaùì\~ì»:gL¹±¡sI£sÌY®/uöAõ|Ȯ؎SòêÚÆ'NÛXCÆøìTÓáŒL¥%ƒ°(ûóD[1ë„3s½/<*³ì;v‡Édx¯­í Üܱ=øªk&ÜíŽÛ/¼Fð¹Øm@ ω¬iÚ“ÆÆ—•𥂈56ÃCt Å~Z—Šœ£o{W<÷²},»/¥ÄpB—®¡&[ÏôK¯uEà…® ð3¾¼Àïdàþ¾ðM©C©û9=ÖxãéˆÓžÑÁæ´<Æ/qíŒÌ-¤·‘xÁ÷nKÙ:c5qa¸ÙÌ‹‘áx>o`7Ŭèç—âÿÁP;m_ð|ëkä v;WG-f¦,ŠÕú.{VZÔrU;Æ#Vx׺®3g±z齸€×þ®šr?W³› :¼ê7ï-Ÿ­¼û\Æô–Œy­Z—<Á¶|/R¶òÔFζE¿âUÝ¿ù‡Gý`ª½æ„{mðHïü›ÿ‘OãÍ'šsuf©‘O_û2¨rʈéCrhˆ¦¶‚ò%—ì„Úüœ”(Ÿt1ÖgAP²ÜŽewòHövÙ@±1©xŒ¿®õ<tª×K!KcÇØÉ!P3:­û^ËäÙÍcV>éÆs¸KcZ/VðËÙÛÕ\*mFvión+\ˆâŒ¨ ÝúìÈ(Ùhú:‚µµìÎé²Û^4þm6™¾C~ë,ƒÚÿ–gë j€˜àʆÓQ®å]î%¢O X8²xx+Û~EÀÄê®ÃµW( ÉI< ×ýä«zª ûÇs-þà¾Ñ€´õañoߨœ6©‘d*ðÞ‰šèÏ”ÎmÑŽBZ# ShãÛíIY²ŠÍƒ–œÔÜe@â#2ž H4ºpÎbQù?lÔÀÎ÷3±ÉuüÄÞ^ù»vœW„)àL¢Ëj]ÝFÀCeѰ–viaÜ#\òÓÇ”ƒ·…mÛøHº bÇ:½Õ¼”ËA‹1’tê‰ää ?û×=­a0VNÞx<­WÞñ|@dPÒÐC´º‚öÅçŸÿü-€K#ý)ˆ_ÿúÓ§:‹áWÇüu*u~~l¥£!ý¶úŽý í5G³"ýìñ¥Iº‹«-1i#uÏëCï!aSe¢;y͸ýAÚª˜ˆQ~}ÙAqÈ=‹#÷²Ëev%tñO°$êB{Ê0‘XD¡4i|$ÐÙ²“n¹Ù’Žð‡”’îÄGî©ç€‘Ëß]<é3»žNcqD-|SFÞm­Ü—tñ‡œ:©29HhÜjE+ Ê@eäp”#¦µ†e ŒÖÙãi,Ì>غ6\bq\UP_ð2¤X Kìr/pL¨´ËSýðhlcq°6$áH§ÿì7¢ñAÊdOk¿ˆÈqµÝ•îJãú7"ʱ^ Cù¡¥t¶slÆŸøÆ¤>­óx­"ü¶õmýu`V½°°1"ç"O¹ãYŒ8„\*-ˆi˜húÎåÀgß ïì×á ê¢aÞn¥: šTDi$ÔšT^¨jUÃ{›úÙ¨ee Øß~ãæ¶¾ç~rÏEÂYì+YÛñb?bÕ>û0’þõ_>ú÷t¿\ ñØ O~ñ‹Ïït)3S2Ñóu@&µ9S2'Ãnm:wOÊ#0?3}¡Û´8#?íÍêàA߉mÞ<†N,aXLÎØf/ ÒÎ]ÅÎeðræ/F&0•³ø™Œù8´U'S1²”º»•QÌÀ¸b1ƒÊ®H¸h¦³SÓœ7•i}²£?–•±Ø*œÑ !têƒtõ·$46yS¤u4Ð’^Ô±' ÿò¿L†ž’ã$vùißç@BѬŽL‰¥ÉVŽÝöF§fÞ6Pt¥ŒÏè½¶âÛ¶7ÁÁÑ{ü„ÇRSJá¯:…L¾]W[˜%§`ëâ]mÚ0é+&â6s…ĸnÊÁY0+amB9è#0œ41Òv@ÃÒFdŒTNĘuŸWYóhצë§Â¿" Wò85J¹qà)HN¬*ËŽdÇìÊÇÂl±ìAÌÔwšÊw;Ôö¥Ïmîj£¥#³ýðk÷D…·ì»0s"}V×VíÖÌà*>óB›Ÿm2®Òžµ¡ç!Ù—¿øÕÏgCþ)ÊO>þø³ïßyñUV:"àl#Ce]Ÿž…ÛÒ‰zíëÐØ¾Ê ;IgçŽól+³· “ò꺊 Â:lÔȾç†*«}“? ´6|ÀP«TÀvÐß~`¹½ÈÏFMª­PÚ˜;\9 ˆÃñbWi—é" Q‘,<R+åG"y㬟äKéK»è‰zª‘aÚ¨½Å3{³ÄµAoiäõ»Æë@3Kª·Ú‡Ú´Bc »°Aü„ZlÎ ±5‰-ኟšÐó®òâHqÔUPÑ}&£ï¬Aq`FŒ!7¶¾Cpm¬ú´£íŒ¶§þ­Mm$È“Š.íÛ"êÎþ2öV¾1çÞD` — ¹Ç¿ýįu2¦Kþ°¢$A«¸ ßb@ŠW]ôû‰¨3ÝJoå`¯¼¶ï1¸ÔÙfý­Öé“28ì’W‡6»úʘÙ<öa>Ô¯ZUïtkvØÅAÖ"*ÔºŸ4ò à=üæÅ›>xôïÈþO <ÒôôW¯Þ>}ý’Ÿ¾Œ€~€ÛždÕt¡ÄSÎŽ³vžÖ}÷±“¿…Î| ëê xmx°uÀ§Ö­¿Ò3㮘¼cÊóêÛô |;Âfå”I'Ý6öð|0~KâmìˆÅë"$²+]\øºJβ§¾Ën¯¡Mê:¶g¡°ƒcЧ`oÅ® èî´vìèu¢¼Ä)[øYí®2‰lǽý™‘öKëë›5ôO¡;Ks|?Þš2ë4 J:àž0ˆFuUjNI\qÄ–º¬àU¶ŠX”Œ#­±u,itHfÙ(„mÃF{ôV«3ëÀ¨rî'6ŽŽhÂÃFB;óQ(*VGzÅ þxXñ[‚³J´í5…ޏu~z#š12†Æ`¨X­$öO*òŽÌ-™®ô!s?llµï€W)!.Øf©ö7êG7cba– g*ÄyôØR«[+¥;&@m^¬AÇÖ¦)m^43Ó/cÂ6¢aQW>æÃpA9É€ïñG<Ò‹ØFÆßyòìÅWï¾ÿþ£¿ðè¿øw¿þŸß¾|Ã;™¿û˜þ¡é}î:Ýäì<·cÂ8fB°ú0¹¬d¡6Èõá–¶}ºuÀœ¢wRìÌj±èÆ# >¬3<û•Øž¡cË8å†56âÀÒ| Ðþ8€2rÿo1>`2QN+¾áås25­ä‚”ZÒV€zQœÏxmG´M³Š¹¢VOrðL¾ŸI;A°måIöðýå³±áWâb’?‰Ç{Kë£3“éÄ@s;&変¬DŽ¿p<â®Äk{>_ÇëgKdu¾g[øæ¬‡²2M™‡ï@|«¶÷Ãw¦ÀˆO¿i°CŠ#þ)ÌØŠ õ3VׯMØ™v?'ÓeáqµŒ6À#Á´½L›eP Ôóð.*Ãõ o‘+¡çƒyÝ%HÁÛ-£íÄ’M໼€‡¸s,b”Õ$·ÏÅH¯NFjëØà6olqïv†ÛŒñÉ`Ëe¥Ä–rG™b]_Øuv2§~ugQ‰]»¶BÍfwÚ»_¾E•^¯ÉV°µKà–³qÇHRa¡[wnÊâ[ôÎ`fª°[{zãÈÀ¯2Öר9*+­Ìi³Q¼£N}gRÝ~jCœjµu]²À†¦!ï7jV¥b7ͯgÏŸ¾ýÿá?èËç;ÝL?³2OÞï³¹øº*}+_qêYçΕj‰.¾ËÈ)th³îÙš7ή“ ó9Çårùl€,ØþœŠZM=DO»“XèaûÌwâ‚¶tèÛ«'èqƺw88{gmÏañY›ÀaHÀå×¶,¤O˜6ÜfÚäRzŒŸ÷Ô3—“ç8b²i5±Ñ2Ï Z·/Ç¢ iª^ WbÜØf±îíÙCòÍ“±v¸<ðÕ|3Eþ囯úà¦%Ÿ­ƒ'zÔ/N3ÉfA¹i*=³N~Ë5Š?â+_ñP4oìì¸J”Ÿ±!Nþ ¨ÉÔ?Ôz/jø<È5ŽZÓ†Ø=‘'¦åæâ ’œÏRfyKe!Ž6]<HèÅ)ZÆF(ø_…=À(÷r|çŽ{>fñ™ÿ<àøˆ“xGž`1ˆÕøZíÑ@-ˆ ô žãÚ¢óN,–Ûzó.mïeGžÂ0¢P¾YÜ{À ½|ûê@À8v"Lªà×9+Ï¥sñ0­ÉO_h<ÛÄ™¤`>%ÎØI\ି©ílÚ|6=€á@%àúGÆÙzر?ш¡2:ÖVÅŒÏ è˜5‰ŒƒfñÑs\1£m’Çzú Ó„Y'1±ûô¸Çd±Œ^2Acãs `™´C_¶î÷T׿ƒ2ÚÄáš ­°ÈŒ0I£¶hT—ž…µ®ÒðÐçc{£PÛž¤Jƒ>÷ø±ˆÞX6¢NƒFmºú(àåÒm.íh³HjéPBvº öÛlñ{èLqe\0Pj“ðØ’p’¸ê°:i‹&m ¬ŸØ›ZX§c£·=ü]Úc‰[z"̳ Çvº°ù_Ú.ÄD<¶‡wâÛ–[y{jK-ú£ÀþøÝ·ßݽ|óæÑ?Hýö\õXÓ‡¼ípnÚç3Î=X.g¢ (±!(…›–ñAÁ  f<><‰ÖûÎ;Ï×Ýš Üø]þ·º!ø®~ëÍ"Î*†ë§ZY0MLüÈùôJ@ÍZ¯ú2ÛÝ%¡nwÛ#2‰i†œ-zwœé¤3;ÉT+¡®Ù;¡íŠÄ}ÂCiØäÒy¯°H;.U®M ¦‘L« “XËïDe])°0ûž»tQ6À½Ú€}Lz0X¢E? ÄG†íàVÛßÚ#±áçô+Òõ%G¿c¿à¢¥¶Å˜ Â=œˆZ$elð=eìÅÀX´ \|úñ‰°Ê— áÚmmÏ dbC¼ûÜvǤÛæÄaÔ²U°ŠJ‰lsc52 ã¢6  V*›{-…bK7ãÉY÷„áµ á±]´ n³U;0/˜xqyÚm”kÄAas{ŒŽ·cdÉ£ñЈ­@½wŸ‚$“¾` Ý”rÚK-¡µ5‚®Ÿû‡Û¯ýꄦ¿ogMfª©éܤ{ Ém;¸Ûž·ÆEžc³Ìï¼yó“¸9"5}´[ÝÈ;™ééx™e˜¶Âå¸ÒËPÞÁå×ÕÇÀ½A%gNëaȱ…6kÀaœ—Ý=/H¯¡8;ݰûàÁ€ƒá™.² =©¼Aö€^ù=àôšu gǘ€æƒIoÅ´iµ‰y"|6I©¢È²Ø!iDü4a¬`a-ªtÁ·EÑ4£›Rhï³UñI´÷Û{¹ß<ø¦òL x£ZO‚ Öο†W¥¡•iĆÕ[a”àúê…r?ÜVƳÑÇ+{"«–#SÝŽÞ a5xЖ©C&ÜH;Im‹øÎÕKZíNób§¥Lzá¦$ÝS½±ÀM/oé½3âö€eE7‹øÖ‰ïMïR$l³ nz•nÀnzv´3êåU-õß±-».uÛ@¨>䧃‘Ö)†À¬7fsÐ4nC=ŒŸÎÊžâ-¦¼SåÔ똉™Rƒ®í‹×û¥ÿS—s,lŸ?¤R>¤ÆºT*ùšì‚G¡<ЈÝÕ#N£”Ø:7œ ‰>·éÊï×N…V‘ù„ûw^½÷óÀmþ©èg~¤_eÒ¹¤VŒNG3鯸èÀ!:äš3B){«Q•ÐmY9Øë  dC7ŽЙDÛÏÉÇ?zM’­ºÀ †\~9sþžX^è#Ò©‹ŸÍ²èœ³´ô}РºphZ<Ì`•[þú (( >õŽ{l‚CÄÁBÓ„>jÀ½8 ÅÍAŠ(¯|h2*ä—˜°I½}@#Ěñoäö¹(h®(9HÈÅJÐJ+”Uøû€Ñq ‹µ@zk LüãG~{5©9TÂm0f:öí[b=\œ÷öà|â[/j´í$X¶¤åâ9·¯‡ øAÇÌXÃàs,Â¥¯I`pW¤¯•h ¢AíV) š¥mÒ›rŒÐÆþlg|( 0äÃ;c‡—8·‚±à%„ ½yá›#a´‚‹dÛ)}r|(ÁÉc‘èí0t訌OS|? £ÿ‘;«ƒS§¼­µlCÌ'åkߥn lz—b¤¶u¬m:^ÜÖÝèà»§Ñ(±\e’Ú¬/ Ó°ì¸Ú(^­bŒÛ 0·foø÷!QÀ&)!”§\;Ç;ï½yô?DÝ~Ï<ûëý[w"}C­”Ü]̬ê,/L0<«eÒõb2`2ëÁ††kblY"ŸQ²p», Ø5ÐÂö¶;-“«Ï<dz¹Ã(ÞŽÆÎØó•…Á#N0ÒGæ ÌÂή©,:ñžôðXXðý¾ s6;¡Œ{V9^»è³ÃÉ6F°׸oÚÚh.ówÊ”FÑÃ¥‘ðá_¤Ã¬âBÂñùÎTº {Ú²~‚¶’‹ÒL5TÏÄŠO~Ͼ5s •›çMb§s²‹gÿ›e* ©o4P¨ŽTŸê~ƒ»hú‰ÛëGû@IXm„¾%ÚŒoÇÑ[ãÊ´Ç…dÙr«ˆ¶õÕå<+BÛŽyÛ©-WÉ4ä¦aAéÓ P¢Ajñ´Øf"Œ¤ðË ¾¹"*IŽ;\w?³;ûB.J±B.V¸Ýæé™"¬} Ò.ŒTÚ Kyωl€›U™Á^­ˆ“$Loc¥I„À¥²iJ— þh.l’ó‡#Šf<+àÃ…åÒTêYuÑ6œÒäàIÙk»ïvA¬~je"’pK¶rµ1ñWlóØ.ºTraôo †o[^÷Í…½µ«yQ­/~ÒWc}í¯O´³¾óÞ{ÿtOñ2~ßþ×ÿúɓ޽»Óo›³@÷Ì÷<Ëéxd¢ó¥ÛéSúŒÎ<œÁGLG·ßÉGÈdLšÌd‰Åôï©rŒÏŸ†¶>“<`î•_'9C–ÓðÏXlFêÌåñ|µNZèð9|yñ× šՖצmÆÁÓšÛU=˜ø~¨.Ôyhp™Zˆ—© gEÅ£í¤¹O?pF¹²ëŸ øaÊá¥Z‰47z]š@éCÎÆ:‰cÏFwf‹ðŒ Ã.ï:×OqËÖø¸B(C*YE•ÑuبÏ#|C€äìÀ‡weÐÖÓlÖA›åù™†±‡¦Û|™È‰Îº_¯2ARœ kõÇÇ•i`–š‘‰S~$ðU‚‰ôBAÔÍåU°oÜL¶SúìêJ‚Wy8×-öúÁò¶·–g3` ®@†8xˆH«ÝÊ€ùP0âuÛñP­Š]€ÃÎ$ðgÚõ‰t1­mh¨ØNN»…·í…ƒ¥ µ‡"‹ÙÖææaåaÌöt–~Èˉy¨¼½œÒ3ªò‹LdpÛwy®çÉÝûÿ¥®:?þ4SÄã®È×÷woŸÿÅ{ww_äÞv1×ʳì6»$„ž'­¡ žw@ñ.X£Ä{ˆ ¶[°Ê®Zi›ëÌA¹“vÁb1™zB½áA¬²ÑÅ߃¶€:¥²eÂW|d;eè¸Ìtä6e/,`õ© ª°–íH2úgã}Ï, ”Dº •cKÙJÐ9‹_,‚ÉŽÝÑ= ÏF² ”19Yëp'Ç*sÿNyµ^t&R ò)þØš6kŸŸÍ°¨?5À- >crÌ‹t2Jø\ÝÒS\I#Ëotª[LéQr ‰iâö²7;J–Ta ³–,.‡Ëª Ð)˜òô圯~œ@lmL†51.7)tøÅl…cä_ vmñK\^ǶMóÄýû¿ÿIܸÌ;· ôXègÿöß¾egäÌ·‹?/Áq*óeqjštrVÊǰé`Ó‚uñ‡ÍÄaµi ÎB{†:¬¬1C\&íAè.ýNú'ïzÀ“‹|]ìMœõ» ‡ãÅA ½ÂÁ¹‚ÞdZŠ=Hà/þŠ£m6_!Œüº&gÏŽ,¢³„Š98P¡ ™ë§ˆT6ÙÆ}`ñ_jr²#.÷a^¤”ÎIú¡IÛ†÷ó#Ä6‰05-,œÃë¸f ÑgÙ¨¦ ,Rë»Xâ׈òª*š6º7èà‰&åLŸÞ‹<ö&q0‹ÜŒlùQÇpP˜ªŸ0»‡·Ž÷ ‘gòÔíŠÂ=´ì§^dsuølv÷íaoÔQ£Ìõ¨rÍA/Þ&Û6 >sú¹ŠÍ#gQוD^H‚Y¨tвàQÙ¦ï5ôÜR½C°Úûà]ŠËv %Ûæ›Žã°ui†Ï}H2/c¦¶v|”ÆÖnq¸|Š9QåÚœ7Amz—ɦ)Ý¢OLêòÍ…ÆXxõî›»ÏtÒ â±'OϽ/>þøí~©“Î:»”¯Èña!d`³ÐûáµAõx½uP]öav,†‡‚h&>žaBÆíˆŒ‚yõŒ®ré¶øð­ÓòÈü €Êžàð\¢Ü1X!åú-¿5ä®(}L£§Àò•;Õ_«u.ó "_,òÐn+•¡)“öD®Àõ–eÈAM"XêÓú––‹à>~ÞpT\87$²sª8±{¹§ï ƒÝ;¦=uÝiÞ³cÚŽ´OÛ/mÿÚ%Š”˜·‡Â¸tõc;cÌÑ„ãgah«˜\u‡.ÏûÉA+õ《vê¥ý¶Ù󱃗Úì–ɱ”«ô} @yÓR'>1ù”wh¹%l'T¦‰ ­ ´øñ|X˜bú«íYå¨nk€'‚¥7ækr¶0¼jÕªÙ6s;Žôƒ§ñå<Úh$†ZÿÃ¥ÝÕÁ„“ cÎþáÁZòІ 0Ý»1·<gSæƒÝS~S>»xSuƄط-PDøèµ´ubžlŸ® "Ò¶^±GtxµwÅ ˜¾ªf8ÝÖôÿ¿„…Öîa õ¡Ô€ŽÃ¬ÄõÞÿð¯~>x¸áþå¹OõNæ'ï¼ÐÉO&”Õ³ÓË—ŽîL)& _ÏtTÛ@IDAT„ÙIXGÅsî¹³v­œZz‚£ƒÔsŸl‚ñìÌL]Í‘)å […ƒ~´m‰ñÛ8ìgœ‘y1—бվœ÷¬Ÿ÷€Y‰b?, ,ò`.øB›Å}cha/:‚![·Æ¿$T¦~ 5½ØëõÛÆ¥<Å(Ã9ÿÌ®Áò4=﵈['†„‚)·ºgnƒ÷6·Wú¤jë–'¾Ylô1'OŸ=»ûà—¿üùà^«ÿ‰Ï~õ«Ïï^¿óû¬¦÷ƒð>¦ôbÇê£t—Ñb:ØgËÝ Òõ6Ø­Ö;£Æ•Yß™…½r˜ÆDº·°‘ à'@ø½Ø½l ß«^Ä%øŽ  voœ""ê¹ìˆ•—Yê3~š‰‰EÞWO«û %¢ø¡®|Hò‹k܆ݫ.0UF@Âv¾0#,3tJádU_\3&Pb󬂸æŠ>'ëU¶Œ¨0¼ßn,DX츪ãÀ¿ÚÔãgÊÀJ[N¸ Ö963Š”©e§Œ]c/•òì;[6Eeé÷ÓøÞ“½Åö+·Bb°F›Ãš²ü°@¥”ó áh hŠJÅ„ÊYå'¢<ôQl›ÙF…˜£a ¡,! n¥òš/ÁMa;Y㪷}™p\Ž‘ÖrÏ¥B·æ¡oyµ×\òB0I?ÛÏeÉ«Bd!Ü~̘MÐ)“¾†ëÊP8ìV§ûå¦ <ÐÑO;åšØZèí ðy¨Ú®åm¥œÊ·§+b[LÝ k5ùF\ÚÁGG—Þž=þÍë>øùàÚÄ:J+ÿÛï_¾â'½úð´úJê¿ÞwÓŸ#ÕÊôJ€T V·¯Â²h!º‡—U¶iV¾.À‡šÎ.”'¿>¤Ó‰=“W@æQ®- xÿU]W?Qq@€ÙÖ½ñžv‘#fnठ‰ª¡¬·xòœ&¶Ž‚Bv¦0”Ç;ïs vmÚ=²›Å› Ñ€›v ¢¶SPP׺͌⤥¡>܆i&ëš'lq#²v«´ä+ %­N 4*áÁÁù¦ö>|j bÔÞšqos­áŽ,zW‹P÷Úàb`â.?yþâ÷o>~ýóÀ½–ÿ1~ùïÿýçOÞ{ý)çšßkz¶&¨Äb¹.sïñèAçËä’³Pú``äô¬:'¶<ã«Gaû6³Wtާué¿BtÆ¥ËÊ×¢~àRÄ#Þóò>gþðÀø`†¢>®»˜*zWÛ*%ꊌÅ~X¢dS4²ÊÁ’Ü6ö,!Œ3É¢˜,øÑ7âiñ÷Á‚›ÔƒˆÆ¹Mî²ÊÉ‘TÚÜí¡e·­È&èÚX<Ê‹=í/»Â´Œ^ý§Œ¯èÔŽ®|6–ÓH±4 q=”ž¨#“0ó9áÕÍ‚. ~ ¨,SN›¤²[v±õ`,‹¥Dˆlâ‡ý¨ÐŠmyUgãõt~ÚkùFî]üàÕjágnØJ'ÈqtE@-ekÀYD&6Æ5sgnI±nT—±¸òÁ,|À§‚H§“wêWþGò‡Ub´»´Ô°ÓžCDŸîDË·ÖKƒ¾‹ném#Õ­ü‡,ž^«Ëø?õÊ'_ûÆÁÄÆCvbåa)uñòÏ^~Ë/Ð>þôÀüø*¥{\ß?}þâ3-SzIÃut§s­Ô§¦E¬Ž‡7U¾,ÎI=ó] ½xÅ¢Ò3ðQã³EgOZ:ȺwU©˜¹ž¼'&ô¬+bʽRau1zŸ}ñ¿XÁR+t2Y$o›¥Ü |°°³HwÑ_ ½ec÷̨S?ðUŸ„€aYÔŠÎ%âå'ê#ç=@´œ‹JŽïÒÒØÜía8i—½¬D-Ssð™°ëÏ0Ñuw`ËßVñDÐáE=9ÖLlœJCGxÒâlý ÞÑN#we޼øË®ú¢ï1èâï}`2°&8 ŽÚ`HÆRùéo‘8ytb¡ÛÔ,TðムøÇ'1YHž¿1ñ²_E·¶·V”áo;*áúVX€ˆZ!X»:&-¬BåwaCò”.6 ˆÈý·‘»d»Ë*¥EÔ”±c2qMi)ž|ëFŽ¢À‡ÁQM–6o¹QD7£þª¹û¯ÒÍAûê»ÛƒkbW± –¾Ål›×=oócÙÆþÈæŒßå“!ÝúÞÑýÁAŒ>?ôìÕ«Ïþ—ÿø÷C‰ÏTð“Hº,£#2VÿÝ¥7}îaÚʲ8t§FÅgÊ]¨DûÌW^¸jR:-za:º’aSON§uM×ñÑâ<É] b/#G½âÔ&L˜“|€‚ „M’» Ä«>¢BªÝrU9û†_lùäÈìOñ]”„r¿I Ñ#|h·‹äÜØN+'üÛÔÝ¿q^òòz€,í„DšÊ¬¯Ü—pÇR·3 J°‹£Tzà•¹ŠNLb…Ãõ@cùÃêb‘nÇf ï§F1‘ÖY§ P´±?ÄC€Øf»Kœ#àHctÙ†'•ÛvŠem ŒÍ¥Œ™a5¿øÅ¦RµBÚåì¼nÐil–Þ2.FC²µ /°íæ(µÍÀÆ‚… dÔÑ·:–þ@k––q˜Ó¦ËTÞ"ÔÚ7öÀØ› ®Ó© ãJ_©hÜZ¨Øâ¯˜+ULòŽ‰Ø®ìÜ+‘`ájú´ý½­¥pâ凤åg\ާ«U3؉¤6¯±EM<ƒ6º>| ÿüï¸ñPÄãÊåèq~í³?T§ô޾ú﬙º*.­Ûn›Ô—Ï%æÞô:ãGIx¬Rä웜Åß‹áðÐíâé]:¹ß-À%ùmŒL&Þéob^±Ÿ+]„}æ¯ëè7–chUVLlO eÛ×À* $;/ý¡>gⵦ=‹ïª}büµ4µ‹ÛNúµÛ*qkä{N9±«Ïi~º :²Y-œQ¤<&„s ©ØÌÛ~0´1pç˜`c(o;½ÈQ‰lQ?VãÌ_cÄ6±óp6¤øl'ØÄÝf0™‘gUot" NrËÁœ ¹ÒÒ*ŒÉ<œf.B›MtÔ'NWtÌÞj`³­:úÕÛÒ‡Jø!ñ´Ù9sªN¬67>6Bø‰º¥‘æïôrոƴ©³do§‰S8åZÍaH(¶K­r£ûT—.Ÿ<ú“¸üOÕ:?ßTóñ‘O>xï³ï4;ÐÜè"EMnwBcÄwO{áòä¢a ^ÏüYTÑGÎBŸ3îk"ŽÄY®RÆ”'ø{cI˜Û˜è /£g“ra/ÂÇèväÛç¬& ±u‘FÏö¶Šëk ×ün0èS¶#x~‚ê‡Êõ²×•A"U¢žÒôm ©½þØiñìN›<¸•‰¾_¦†AZ#ËŠ+¹Èé`·õ)R¹Mç:óx½úŒ?‰†Åî\8¢Šñ|b£‡“ɨ(’C‹I(ó*[«[Œ/%?ÀWòhYu÷9 }ID<е‰|@¢cõ &•ºGòÙp"GƒRѱªˆ¶öXw6åÚu2÷cO„Ù@ûQ±‰øÝ‡ÐuªžøÛKµ0×–7³¥[…”ÜZrxihaúÒ#¬¢b3+ŽêÆk1¸l®3Dذ‘+/†Ñ¼¦S585Plh¶·’êTÖ0NäÃ>6²6â9èHë1Óq:Èè¥]AFnÛzs‚}x{Z+b{Þ5Ù>ªA®Ïdmœoõ‹]/_ÿ4¤=~¿@Ež~ðá[£µÊˆy3º“éÐILÈ .¸³0/¨° ´Xý³Pöê&{ÐÅÝÒ3=úÞYõàëcs#ÇŽ“ýÄ&4gú>è€ÔËßɇ†eNØ¢¼Û¼ÓuyØX|â•/ø*cgÉT6->Oý#ð=oµ güû6'ÂúJ€p¤‘„cñaEN)1tI2HR¼4•¶E[èO` ;[kø˜±%°6`éÚX&D£@EG>d|MôÊB„xÎb ¦}sÛn’áßfp¢TÚ¾G@m¿ªàª#~°©Ü•íËkM1 *cÀ!¹u‘Ã?”Tž–E–T;†'*  Ðýá(SšØC,$:hU3âX¥\KäNÃ0BTBP6`FõízÎóµ¿VY^°ý>¿p•/'cZô WêA¯Àg¨‰”aC:T0b Nì aÜ÷–޼ÀÁCÚ¥ŒÕ5bE#mº?kp"ªStr¶õT›åm¯Ý‹À]Û­mì!§Ô¾)÷–"ÒméÇJõ{æà·åÄ¿mŠ.Ádb±ÃãÀîwßýI¼˜v`ÚøI¤'ñ‘:E½DŸÍõøî`îCÕ²ýzVøÂ+Q€â1Éúì¿À ¯—ñ9¸9ï3¦1,Ÿ·-~Ko\ðéM \p=+œ}Mª Iò¸-!ú(ZÞMù·9òÕ·ñŒu§º´E&[q×Mn‡.þˆÁó_3ýª´S4+ i§´Ý¶Çô%O¨¶„úªŒ9¡Åk p ¼ÓÞ‰'Â1®Ì¥*æ‘€X'9ûAŽÁ«ï0—ÖÀdžÕ#s}e³MËÙB1æÝW¥Ã©Mx“¬ úÁª2ùŒ«v·}C­“È[ÖÍÚ·quº£\ºfN^eäö|0Öø.Œ˜)´àð uþJ ¤$ì©V‹5\Ù@Ý6•)O[ c²‹í;»ÓÆu)}ó™1R[ð(“•Âsa•‹*—œ1Q ÛbìÔZòSºµNÌCö¯qlÏÕÛ=3µu]6ŽÒ‰Ùô-æJo O·í ï->âçÚŠë¶éÒtÖË÷ßÿùÀMÓüÉÉç} ŸgÔô¥K4í>.ï^;=4ýxI]]Ëç,µxËØÌ\Ï¢ÌÂo'‡AãðÝÙô”‰ßÉÕË@%+S“=õv±êïÎá^ïòg¡y îK¬ã·í°Â@ïÐ…?nWn,ñSW},ŸúPæl¿:Æjc³byͳhñÉ%ÿp—žl4^lX_›N6áÔú-…‚À1™¬j̪À)Ÿ!-:XiËÝæ+Fcl8*¶¡úÙŽˆoì,ÅÖç0c©Bj|¨BQ“W± Ÿ&O}É}¹=b0¹`¡ü*ªþÒ‹…‰ …6Ò RÃ]YÇ@¼¿óØ­¦Çˆ­Ö.r¥(cŠñHRyyR¡^àZeñ6Å Œ¹h!þB@UDC™ÇŠhŸéÃÆ9tѢ݆•!>>Àé§›¾ˆ¥(øõºFAó @D9-£e€Š4ÛNÜ•£pòZ®EòÝÓîp ©Õ؃ò Z¨‰±è@`S„1¤Bk"æ®J‘'…cͲ®ùŒ£2÷’tåÜóR§ÊWL”oèÜmh·tÝù-ä–> S¼Ý³n5néÝ®H•n1·ô}¯p‚bLl+ðB5‡*ç¶¥÷~Òý »,ÝFwÒŒC¼¼P‘”ï}O›'z ð‹7¯~?L»uJþcmøg/ÿî½?áf~óBÍ%éV°éá5ã«<*ç F9<‹µé€È˜Xm@2ΰDû*€”ûð8Oêrìû”¨H‡  'ekñŸàÖ¤N¼ž¼£ƒMìsßÜW$çÌÿ™.÷®Ø±MLøIæ|ÉG€ wžˆ ü@LYO@ ”K[8« ã“Æ;ÈX\ºÀ¬þP£p{ÿ®/Á›|•±+Â~e3¡† 2œjÔjGˆ¶1F&œí² X. ÂÚÞôƒôH‡#Ú hÛ€¸åÕàè@–E^SÛz§·éç‚1 ˆÍ(M¶ìeðmHñ5AL¶>§+"W»í V)¶Ð¡Ä§ú b^º¸žÁWÍö.ZEµ\‹Í;ެ;Ì.ªmæ°µå0؃ÁØ€U?鈴TNÞ²õoh‘1¸ôáp+fÝÆD] 9T\d£qµ1<Ü­ôؤS\3‘üضÚaÒ:As¡éÑ®mQ@bój è BßV)ñ)jÛÁú®y¨‡¶Û^¤Ûê•®.ñä¥^Û¯Ïì¤øÁ¯~¥«Í?”}ô'P—¯ÿÏÿëóýÑÝÝ×^•é= ®©á ïl²Ž5H[˜ÆxDLY<¿â¶2rÉ}5@þX¸Åò¸÷}qñ ÙñÉ} ¯‹§Á‘áØ¤äþŠŸh8ˆØðBHc…qÞâ1 bÃd÷ÇRŸiX˜‰½f,?m ' UÊõqpѶÎYG•Ý—c±£Ü]9~'gþ²å³ì ÀG©qîIúàÌÀïåA?°¥í¦ý|ð"’…ÝvjŨèß”‡¦´‘bö× ÄòÄ Oà­Ë ’9¡Ç÷Ò¡é‘ ¯u8¿oNÝÐIý¡’Àx¯Rn0XFŽ Qa(·­ßf¯Hë.64O“¹ Ô;:Ó&ŠK}±Ë‰†ÛHÆz>EÃÞ)\ø6Èóˆàj“Ø¥[ëa\5D›]}cªØzßÓéæ¼RpØ-ÔRïµ þ‘T ÉUÐñ„@åbS„ØŽ6ø;­_.yR£*­|t—ŽÜ8­0nw@C;öÃ$6­‚\‰rb¿æ5{Áœ:#(Îvlo@.¢E¨ÛmýîÓM”„ÞÎNo0bãj©TÇDuÀ§QÊIΖϱÿ§ö›%¡Ó•Ú¼+q¦ÒÉÏ-(âNìHòí!Ñ£ÔVýNÏ—½~ïÝ»¿ÿoÿíóÓöc.ŸSúc®ÇÝÝ¿þ7ou}ü:sÅ2'Ÿé–®L݉>ÏÄ1ƒhA¡,|fuT@èó-§õÃëwÜ!ͪ4-.Ú“¡„LÔ,:\æu”D÷€â¼½p‚.qFk‚mxßÅv±?[í5±£ÏgÉ z‰”P;²‚2vFõóŽÄƒæM$èŠåµImg»ðûÉö4ÂPÚüî ¸NÂNÑŠoC+N,@ôqŸ†lØÆº†ÉtÀ¶¯³èö×Ô†z?¨NŠUâû”su©ïáÚ*j»{éÓ3¸‹|ÊhðÄèhÄ:M$‡bçNû÷äÒ»×!£w: ëhòxu *Bï§m’ƒ”iÅQéXäØ].6±^¾î¾C'Kc,«“ݲJ/y?7«Þð¬]=Wqê_qÚÄÞÄÍ´ÑbÇÂi‡òI/è*ÜJ±ykw§p+½-¹¶²ÒÆÈž³åµ·íl¥èuæ·¹å=ØFêïÊ—†>ÑNýѯýóÀj˜?““_üù“ï|‘¡;SÑ,Bñ¡ Rwô9v`Ì$ë@Vç›´P&zkŸ=v!Gÿ,jʲ„ÖÖ>˜½ˆ*÷š"°@xÑdž™±¦²1®²áÃs½’í¶)À-“W?µuÊü]þiWó»jžo @ÏâO;Örm+_ .>EA§®]rŠÙ²£‚Ëmœ+ªÊe׌ÛÉaÉÆ{0ýTHˆõcµ‹”œŽÆïɲ5)„7’#ÖU¯̵4ãíd¢n‹¶£ZÑî+Ù?œ·Ø±Xu_9ùþTZtsZT¼ßjTË6Eœtû =lL÷£1_|½‘—çØ´.¯òÐ'Iü°Ž=ÆïXh¬ƒ‚ 쇜D~ë 8Ùúö?fÆfaĶü˜Z6êþd·ÜWÅÕmeä? y"n˵V»·û ø½€‚î‡ÒêO›Ý’­³£¤úŠÝxl¤MÐ¥~,?‘ÛÛÖ¨ßíu¬k¿|úôÙ7ï~üñÏ_ÜÍõçQÒ·>òæ•~8qs TC…1Æ„7óŸ©ìâ«PžÇØÐ‹'»™ìåB…þ(p-ä &lù>¾K¡yµ°¾n8ñõ› Ç|#ÀªÃëXw âyÂFOŸl(LB§eå”K?4ø‰ã¬›éòf±·9âÕ×}›€ ‘«œÅf¼:ŒêŸªà·,_0°±ú|HÖp Ó€%#δ|‚ÐÚZ³)~ÌAÚ¿ ÁlOеœ²ÕGɾîK_0„(õcÜñšf‡ÌÉ6¬eËÖ%m:½Ùê¯Õ~˜š¶“€‡-ýW)` ¨sTôƒ˜£ÿ =nLÂêñœË¢“J’™ŽRz±@ìEm¸©ÖU~•­ƒf”GÁ}©2¹ym“ÒÊSœ‚am $g ²œJ‰ßf— ¨`ÓVS³*ÔùC¼[ù‰QÒ,¹±§‘ãk¥³È{:#;íx’C·úŠÇWãa•§²÷ ô¶‰ý\À ÂAù\‘Jc±o×ùŒÃÝ)NälƦO9å $o¼„H9*Í’ˆ\ÚeC.›šYòêb8é¼,QóÕ/±Xš%'¡ŠC¬–GêmÂd,<”ΧvòLªXã½jÍùžj|Ó„4q]ÒZ•Æ‚ÁÆ/ʽ-_Fʲ–«qpnŠ2âÅ6õ…¦Ø¸TÞcq3s öì˜üäñ½µb»û)Ðv9ò~Z€^´toxòiï”"^ag¬”OºªäÁoNJ··õïØË(ÌÌuÿ›°ÝT½íüPKw´íµ"ß‘a¡]÷#ݱ¢qßËÙפÚ4¶DY±T ÙÔÿd‰ëo…½|çwïôÑÏiÂ?ŸíßüÍßüáé›×zAC{MÝÚEˆ.-{…|±%‡ˆÁQ²“К€* ?Ç£ÖcÄó‹‚Æ2ú¾J0÷`=Ñuq\ÞõU¿.ª§ý#Ž‹X˜ÓõaæR¬©“‰ÞCºÅ¶¾³¶­…¼þ™©­¯Êæ²r¬íÃ9hýXüo­ƒ<Æëj[ÚHLÌæàá÷"=ÁîNDbO"J×´ye,+xkøy.:Œ¯ F™ºÍ »Ø¤tÁ^(¡e<£ütàÖÈU1ÆØæøcѳ©¦€·ûÈ 3å“5뾑)V/±ÚBÛKÂ>–ŽQº‘6¾—Ä3Ä›XDr¨¨ÐG£ÜÜ*÷ ÂØˆ˜E7£‰m«àEHy»d™d¹2ÀVÏ=hð¤æ•‡»¶cváJWmW¡£&ŒÖ øÖnŒW­x)ÚYnî°;Áß·ZÛØm”'èxtO^#iDÍDéæ·üñŒ³IÛohÞjïlE®<ùò³ÿý¿ü—Ÿo´1ÿœò'ïñŽæ ¡Û.ý¡ å¶ãפ³ûÝ;|Iä”û¹Ôæì¯ôYox~¨OeŽ$ýàŸàþ:¡r_€¶eaŽYÆï¬¶WqìŽ ì$;-ñp^ÕæF‰hýk¢´åZ=À[g-p¢ºÈ»q,ÝNÁiñ÷Õt‹…¤ÚÌAB§“ "˜×Ñð¯†Ðú÷@Ùaå@cJd®£éLb̦œeßàmžL`å¢üÛ¤ØTÕÚÏÓ>Z[3 séæà]£ÍNÙiï¶¼ßm†k;}!_"áú‚€rÛlŒ…Aª],c½ —­Ûú" jù-ô“Æ"ÙÔ Æ€c1<Šnzå$äN͇éâ¸>ûÏ6$/ý,FYgrç‚ɽX/ö2Z»Æ´çœ‘Õpó‘íqhd6Õ;Xk¦â˜*ù¦Nåpƒo•Óƒ;T¸ ¯v®ˆŒXMiQ¨«^©íN~§5¬ÖÒ@Wž°‡…RÛå½Ûﲂ3ZˆiÓòÿýj´™¤V¨é?Ǹm'4 G¶ôRv»XŠv-,P>N´©/åÝ:“ŽŸl—ÿMj„f?Ã[áŒ/Ìžï(Xnd as¡Qí±\¶aÆ)'01+S4 ‰º¥´Úºb‹\§«ôsPmãSëäíìÚØÞnO¬xXNÐØo\Žç¤puà¦F© cgeÿ¦[¢"9ê˜Ñ":íÞ²dnÌÕhŸ-KÛÞY<¾R®HbI9ÑÕ+ÛBËE¢ÕÈv)MS­êÔÛöƒ•ú9-R&µuR®‹þY4nk<ôt ú%ÀŸÌ;h–slÿ³šéÏôôõký$p‚:ô¨]î՞џCðìú³ù ªµðŒš‡“ÆOëŠf,u˜±øSî‚oÕY8­/ùíǸƦ~Cg*-à-ö\PV„o=›c.;ëX˜{ß6]£ôñ—-• I¯uŠ,[髆k*ì±P‰¡Q›­ïà ¢œ¢ÞíÔÛ§ ¥=1=Åjƒ ‡O£]!uq“ãà´œôðÁ"MÂnÍ4G©!Þ £~g_¡é:/…h>ã•ü›L[;ñ `cÓõqÚmÿÔ4ØOµ»ÆÚ÷ha€ñNÞ~Ež°3‰VJ+¶[£=ˆI¸ÉÙÞ¦ôB¸£¯l[ɨžqP¦ïa¥¼ëܺ¾UŠ›Ë•+,õtkäUzÒÛ,=–ÇúÙƒklݶÔ5¦Ê·¥‡äÛ/øAyG^kå§Ö}ع¶ËUã!›'¯c&¼›ÑmSOîž¿x~÷Ý·ßÿd.ÿS×c‰<›ãq–Ÿüâ1£hˆh4ðnwshO|³ê^†"ƒ§è¡¡s.x¶/К…+«]h.û÷R?Î×U‚ñÍAo`‡«ü´e¹í–1j­ðÒ“§¶š}T¸Ám#ÕUDol»zö›˜ªÕ‰ÝgúG»û B[‡~÷ lKø3Åã§FW¼Ñ Ü?éQ¹“¤úا(˜8ÞBû]–ŧ|Ö¨åàuÐCÇÔâZz ¤w1öþ_öÞf×·äÈî»ßõÅb³É¦á–dy¨A?‹¦z½F?‡žÀ€fÊM=°†0$@–š,²Ød“¬*¯ßZ±2sïó¿E² Ku*ïÝ;3"V¬ˆÌ;sÿ?Î9fšDT­ñ·Gdò˜hË^˜í§ÂÊøW6yߤŒ%ãì|¥?ýlþj¥€‡‡ä½YMœáéÇ.;',H[ÃRt ›GUJî«zóŽþäÂeËÓÏa__4(˧"¼û¬‚ ›ìl¦=y:Êš«bvžhŸú£¢`Kܨ{¦ºËý"¨3z²#;ˆšu‘¼¹‡ÃU乄ÛѶ!Y„‘¡ìa'Î"Çät8X‡jtfûåÌ7×¢¤F‰æJÅêì@g„£aûæñ—Ö>¢éœY©%İL5:ò‚ç‘ýEwxÃër vvH®>è×õD¡r¹¢Òyû„·†¢!c‚n'³[;‹¢Ãüé³Ç6žYÅ7èæ²ã†±þØ{}Ñ=•ÏÞï>¶wZÝþÕK|ºp_é!ÿÝy‘ù| Ëó³)¯þüǺ8ìL3µ¸ƒ}kÊènt“™s–#ÉÅ„KñÕᇮ ‚g£dÿ‰Þb ¡ŒS±Uׇz}îoÒ¸ù,›„pTö]ÜJ)­Gt…®)œ¹Ÿ¸BYÆ„TF! YpùgÉe³ŠÚà}Û»3öü†CÜ¿Ñï:è÷à`ß÷MBp![CWe쟶×MŸX«´-n'2í¥ù¬äWWêÆUÆ*4nÕÁx¾´.ÉÉVŸr¬¨ã)ûþ±B¸¶ƒymÏ=Û¥ô»2¤/,q †¶ ý< <÷[ Èº ÷€ƒ¼úàš«±<0¯Âü8-ø-¹„K1nÈ$5¥c6·tü—Ï0Z®ÂÄš­3Üüñ!FãØyX€u›^ / YNœTʋɥ˜¥¨:Êc„–KPí_‘ÛçÚªŸ3EáÒ°ÔFëŒY=וƒß¢©>Úx&æŽ[̤pTW ‰”¸†3ù5v)‚Nþ'šv{Dö×r—¯Ö§RÆ ½âî£þàOQ®æ~ï¸=Qæ¯þü‡ú+Mê’Þ7÷`#£GÞü3™ÚAO„¿gï×Í_²©»H”h>Ú(Çá»êCwÚ—ú¡rYßÛ¨ðÚ„QÖ€'m~!‘êµ×3~Zý ËBÉm "_Šc,G«ÖÜÈ3öÆM{½»pæaøû×$[Îò3&U³(ÈåžÄ¦ Ü‚P§²NtòÚfDÔH[ç ‡˜ÍôPl²M ë1ÇâžÞÉž‘l uP 'bU!¸žm »üfJ :BâÊÁÎ]² KÆíV ´­GéLçÛYM¤'©ÄôM AíºáD{ɶ+²̧“Â~& ”ç997çDÊ›õ¢:!õZ)ȵÔ’Í4~›5  öôsû´’õ–ó5½V¶d÷ÈpÁœˆD:ýƒ¿ëwØaØ4æÉ[Ý¥øàî¶îÌ;2éo0ë>qlü)÷ÍþÌ«ˆ3ftÏç8„Ç+’æßÇŸ}þý;í¿¿öõO~ò³¯?ÓŸæMñÛÑÝ€4÷²‰i"èbúʆ²ÞG-ß=aÅÃ<æh9ÛèîòààX&KÀÈˤÆ9õ+oöC—9à:ú»Hìf[Ÿñ¯'Ò²°×oÄë”Éq4ÞÙ}Œ¶nv£…!6a£ÇË’¿· ºh-¬“c ë  í\e¬¾uóp3ºš±h·e= (4éWý’JÏó Å•æ&ð¤wã³£Ã#Ið ݉SÛâÚ-¹h¤ObXƒRö£›ÌgÌ¥œü ¦Ïv-‰«'Ì›6.Ób8ÍÈ1÷$7ö¨F š™(Ñn§Èƒ5 ˜Ø9Ÿ–D‘}øÚ÷è猃ûí0O‰†¸»Õï Ø¡is÷fk¦¬•Ë’º£¿êî½­\ß§QNÿ´·c¸=µÊWŸ²Un^»' Ð üµg™œE‚¢Ü1[oPàþP¹gXn¾Oöòõë¯?ýügˆãC²³T?›òò‡úà#ýdãïu¹ò|æI}sÏÅÏj'&‰T£õœíË ¼ÏpÌ®£ù„Ëî:ÓÚ@ ØÑùGOヸ¨ÎްÙX±î¸Á<9›t"‘“šy7 È~ã_ìñÕXªöƒêü1$|u{c§Hä2œ*ãÏõé²ÂMFÉ`L‰\iôT]´krMQlŠ…° ûkN,w—ÂÃ#¥qË(i6`W…6½ {WpToʉ¼ÊaÀœ8@OÊž³ÎýÌ»ÇN¤2ôù©‚x&UŒ#è?—Æ—ÇøÆÅ®CÅ×8ͪ’Óœ!n—J·q¬zëùúצ˜–7™c’JŽ;çu;ªÛ¤.1Äõo§ÊÒ°è/q7A)Jíz™§±¦€¬V‰¸Ü¾‡7öK¬Ãö´I¦ _f\5EO¶£s„1¾ïÚŒyUáØžåLÔSckЉµ¹ˆí×шf?ˆí¸K¥±®‘žŽÁéW™·o|î#²íÉà”i÷ —¯µ8½zõêÅ»Ï?Õ»Ìϧty~=ú»ÿýûòÍO~øâåoµêêybèõDV£ëuØ>ò‚%źyÅe]I+ÜÆ`›š«]¸ë1¬|$óölý<û$¬ÅRN¸PêSlëXs.æÔÕéPT)‡³;é™ÀàÁ¢cÓá!Kín:ÞÄõa=coj.¸#ɾCìÆ®ÉŸŽ‘ +Ÿ–˲09š•¸ä°ôñ÷[凿÷³YVáí2§3.*9™Ž©0Ÿ1+=¢Í'0ÈøØÐæ¨ ö(äákâ;ZžÄTé Žì¶j‡lø¶‰M´´›G˜"£Cnžñ.èK=|ú£=«žÕ/zùûßÿêŧŸü^߯âöÒß2Óç/¢Í¥UEkͱQ÷¢cj1nÚë—0n¶.=˜Á·ªìÅâ°#×fì![?2y´nü­›6æ•; 1ZW¿”ŸídÉrúÓLT‹^ÑJäŠañ+íbüÄ€?‚Ä‹¸w˜‰ÃŽC‘›Çe}P7Yu«ÇG%èM{:⼈ËÍÙ\±é¡ÄO€Ç½œãGxŠßµPmŒê¯ÁcpG4Õ£B¼ù@ !¿sœ—ßf˜–,J‚Ÿ"1æœj·Ÿ„ÝI‚È<8ð΢¾Bç3ö—¢¥ä’°Œ;:Îã¶2š×Èh„Ñv/¦#ub î¨Z§üšbýrP‡‹´ˆ½à{†˜ñ UšDv?+Ïu4çóAÖy`;úáÅÝe ÷*‡´ë·BUqØP…v·ªAÏÑs܃ë˜bÍ¢]}Ò~ŸŒÇéSŽD½[6g-Áµ§áÊ+ŸÌ€b©É8è‹vçK«ÙÅ§ÒÆÜ5§|¶OðnM³ßšäÄyrfÞè"~üƒ¼øÏÿþßÿj#?üVÖ¿îÁËüO¾|ñæ•.Ð1ÙX]f–­ÜóIJþ:c0P3\L‡æƒEq*á;d|K:ÔƒpÀ.ÂEŸÊ©£½d²Ð´°0ºŒ®‹ÔÒ½°$ÄMs ÅS0'ŒYÄC–^ùÃç·ý5î~Õ}̰õJxSNÝ´wÉ’°+áÙ?ÊôY æW©ÿ^ƒÚ{ý×¢m¿,b¾JP£³~%–†Ãb(hìÖ«}ô­ˆMÒF2GT¡*â>ésmªáeèÉU¯aΤ"4ê4¿_‚ökävÐm›­*]¯e<âs¶Ú“!1b‚–(2Á óAjýÒ5ÆB*U6­„S.G7˜ƒI–u£ÐôƬº>æC04Û8o)BPg{®ûÏ>QEw*Fߪ|»žÜÀ­c_i%Ò„V]Fê²…a[*×^ ò©;þ6¼Nl8¢9ùŠ‹ŽóÆäÚ\Ñg6µ´&çÍ€ô¸œøÇˆ÷kÉîêÏdzo?þèw_þú×ÏæÑÿµN¼0>Ëëô“/_}ò‘ÿ$°³æíi•Ë$]×U ý?Ö踿o7ûÏrµ2Àsú£^%ôKì|êFƒÁ¶à0>/q7ã¥U?° ¿âW{ŸxFÈ— ÆA•s³I7(êÉ«‹¬›?£Ü$ÔñYÝ™^2Üè<sœeËÎ}‰«¡±Rn'¡øÖ—¹D…©_ˆ33®:ì##¼´-›V¯ÂQª,Úˆr›†­mƒâŒª"˜Ê´UêÑ:ÚÆ‘v r#ƒÔ!±ûŒºþ«žñM¤¼µ¿¢ê·õ;úû¤ò÷NfŒ‘®uâV‚€‚\]3«l€OçxNJ{•ýèθè6Ä’S;O‰†¶q—•KÚ.e•ýz3/Å7÷äbÐÕ6Ó&}Ã$ —äE¾ë€£½êƒäLöéóî'OK|¢oŸËz—ë]û)ï¨Ñótä·=˜s­ESùôL&Å7n™ÒÛJÛúmù'ÒÆÒ*þªýS%g©“~ͼ¾øêW?ýÿàû€?uÿ[áÿï?û³/_~òɯú y2ùúVP&ÜÊ…‹º„ëtyßÔYúÃÑÍC>(ßÛ|äóÊûhVÜ÷2ʰ6€Ýø¼Ùéäk.ýUÉ×F:¬Ùãë¸Z˜´‘cãU>±ú„?ÿ÷I¾ƒÉ•H\ó¨¹6iaª üHLѽ‘—¹)çrðØkä»^œŒËÍ) 9EN3Û ˆêî°¼u©7ÅÙ\èÛzë¤!MÃ_Œä¤ÿÜ_û­À¹3øÓÀ‹2‰]åÙ¹ˆ'âò6’ks–G9YwÃáã=Wõéì.ËéV6n·ðïQ8-VA‘V‘>dÍ€Éþ:1·:ŒÇ8ª³T.¤¶Æºöú‹\<º¶7îÛEÕ«¬•±Ÿþw¹øG5áaí9ް6Nü‹éz¼ýÉ"œ[No|⇵–GQNopÅVÿ§Ô§oÚÚÿ_¼~ûæ×ýøÇß?ü)CùßûWõW¿}ñégþ“À\6ÿ\9“º™bÇL£ÙŠ<‘ý‚á(Æ~ÑùnÙ` 6|R¥}àO¾åó q¸˜«óêT»§-ÅšÒJ¿ÁÔ/‰éŒÂ;*·¨ãuòI#ÀZÈh2¿ôÜþ¹þÈ{pÅÇçþ3ØI…€Ýîw%ÃZœƒ‘uú°m(tðy?~p{œ©–}šò÷Õ\y€ÎEx8­AC^Žzòñø èHÇݘð^ÏzÐTÛǠܯØý|UçºPO©ªòâ5Z!ô߬G5+ÃÅU®Û©B=ˆà$­wv–ãD¼¬N`Æd/Ü¡ª™Ú‡j7×1t=®ƒbÙg”u‚;ÑhírØÍ1òçÊò˜Ë÷ˆ‰ñ¹É„œMݰÅLš¦ÅÚ$·0Vûœq.e³Øî´*mXëU{elg©½º“ŽbάžjÃP|{sÕFJÿÊÚÆDßq"ãµyË¿""%«êŠüû×0e>êk½{÷å—¯_ÿð÷Îÿÿ=_ý€€NN]>^ZÏFs‰Þ…€y5åhVõ'×ß©‡ßSü¢v€½%ï¹_£GÄ xƼûÛe0Û¦t¿²bõýeÓ?v¯úíT.¬‹»S™©û»¶ß踦:úeD§bJN“NðX6ê]Îwꇇä™;áxjwßM6A†ØÈQÑî™ö+%“WF5A'Àš²˜qRYºˆOt<Š#¾øl™KáßÞ×D¨íß®èøRHÆü´4,eÞ:ZøÕòˆã‘6;aÔ±0&ŠÄ¹üÀ#]5h׃ôüUeœ#ƒD7Õ©3Óô·ºFzûŽí„œ°€7EåÇ5Q™”ôÙFn”³>Û|à(O±åBÆV}kì”úEÊ9>ÛÒÜ7&ýQT0‘¸2‘aºG{WJìÉ7É4Cx(º‘µÂw|£ë9ØØÎvüΞ}“?àë½R!uŽ* à|n*èâ¯e<²0î—2敲]•«ŒÐ„LÐt¤1^i'øÇ»i-*Y¶ÀDÁîæˆçXm­Œãigè¹Éy°èe¡_}Àꃊs™„̹’K„°‹h±5î–ÃoŠ 1zÑ6™ásNÅ9‚*úÓÍa…¯Ÿ³›|öæQÀŠhE?ÜZÙ@]mC%{ ?l ;:8Ì£*÷§º©«¤´g¹daƒyÔjòŠºJvòi’º$Ìžú¶ë…|êÀ_ù·ôk|Š‹ÿ¶Â]NØhkŽ£^ì•­LùÐÕŸv2ŠGõV$ò5óhðÿöîš[ðè¿Ö:ðöÓOüîò·³|XÖgõ{<ôïÞýâÕ«×^0¿ñÏ—ëò±ØxáRÒöÿ´u梡î´Rs)«§Î‚Œ§Œ“£>èÁ4ëc[un5|Äuì±¹­•ÚÉÓv`ÉÔí¢dãÔ¦Åþ E“?847è^cèОé«ÙˆÇæ/ ,|Þà‰+›e5wn€sEÎlN+÷ɬº`[bÅÉ>ËOÀ`ÅL-ÄÂ8Êëµj›±…{\ÆP§Žý5 þ\½^o›Ï½AçD©-Œoc «_X H¹pÄ5çȪx¶9s.z¾nAi—3B„^ÅÈG%ù>þo×îÕ8ÛW²íòÏxrm$Œ´Àº!´ç ™DâXë ÄŒøÔqnÉ´üææ†¨]\ºY ®{,ùd3ý‘DÛóQò¸¡Ç”IFCÅŠÛ£0ÒêI}ò°û¿œ±Ò¢wm*†žîd=¢rëŠéÕÚÞW<Ò†úb;¥ÄÈy_‡SÆc—ðÆŽ6>ÔÕ¥W‰‘ÜÁÅÚÈEß³ÜÈÝ*ïÖк–ƒ¥2q.ã,Û޾øêw¿{Vˆ>k5{^åõÿðÓŸëqÍâ‚ú6ºÎ˜±É:W<“/ã0ª·sqŬEwpØ‹¹¹^ÄG˜»®1.ާP@“- ö€jGT»‹Ü=ÃLuE—3.=ŒW@àbư*®ãìg-r™Ŧe<>GÙ›Š8 HæÎÆO;¶ÖÒMS<±J"fsŒaÞ0ç1\¶zÑO ’WCX$Ĩz~|Çõk{<°`L0¶ŒP÷ª#W«ZéÊvh×î›9¨ëÚ'x³ylìæmT;“;Ç (ì¯å/Œý¸¼£¶2’E³ËwB?”!%yÕ¤A¡šçD·»_i²ŒËøíùkE2>šò)Éa®ãiÆè‚Pã!¯\0ÊVíV,9£å¾Å-Öƒ£žµQãM]Ýf,z×'¦Ú;>Ù4«“·ÑâYÜɳÑh{ý6âç°ÝYˆ{ÕEjæ™gWüO5úÇ×áàÜhiùEåËWß?üñCùß ùç?ù‚5å>deJð¿«))Eu^_Oœ^n¼бùÓ>e@¤|á5ùõTûIÇÞÔ—}µû•ï€lÚkñ“nñô)Œ1kn@û,¾å•WØ¡7Ñm‹ä¾Ï8‰Ó97Û:´Nvž“sÿåE+¶o‚jH”—ìÃÔ rMƒÃ†_ò3ÜÄÙ;jämséØ& §ò’ ºs’M)[ò±@€`ræö n'¯Ôˆí[Y_s1¯Ëeƒ6íjâ¹i@IDAT´ñ&äÖÒžù ;×$ ðŽè–ñ9(–Fƒ~ÑU ¾%ªÝ…kÅ•·h°q-K¥¦ ú‡Å¤Ú¹J–>þÌœý bümDW§©´Ò5÷3‡êØC\2áœq„B%\%,”&q¯cÍùîS¹>'íÚ£ßq7®(É”3^ ƒN+íbðN©~(¥¬{7öêRg<wß{aÌùµê÷8nM[õzŸœqh$ÉßøèÏ~øì>Xkâu(>\éíOþBH° wñÎ#™ëªâŠ;s®ð¨c|tèÀ—ß‚<‹ku——óãFSlU€©oòÚÔdôöäJë&dŒÉ,…uK4sâ0ví¨dƹ¢ã¹T///ø|üÀ[ÊÝÜý*ÌÆèi‘k5q¥óÛÔËÜç÷ÜΫg<ÁOD*ÄRH>ÒÚzA®¥‚8ÎÕŠäEoÞ H4õçßRĸ ªÃ5ɶáP§€½!%èêÀ¢ÙÌw7ayd'ÅQ Æ7ßYàK²¶¼ÔÛ»ZxºØÓ–$¿àNLlkŽÔÔÚŽ:Un äcP¬–®èv?Й½·Vì×ó±m˜0y7X4g*ç¬\¼RÔî¬a'wó@Û¡GIu/§îÜTÉëèÁ‘Îéruí zÊ)·Ý:ˆë[£f¤7s[Û£‘÷8öê4Fåf‚ží_â¦u™ó¾Z÷c-3,)w¦»þ´ÓëS®ôîóçõ§€ƒsÙê˜|ÐõëŸüèg¯>Þ8 ºt^ÑSìü°tÍɺt‚_ðöÕÉ ðY‹˜„ ÷…¦]NÓò9®VupèVL(¥ðÆLû¶BÅX usd²ÕäXÄÖªë›Aæ|¿Ÿ¯}EO)•lf —ã8úÊ¥Þ&oñçGÿê«´”[xç­ôc#!^ÙC—œ–ûj= ¹¨·ï3“«{Ÿå!°ó,*‰çN;ˆ†9¥¶wßïèzù×÷>J牫‚ÐW÷×TTÅCÆ+mûPͤCzè­ÇmH ¤ÿ´­±Õ<«ã Ó/íÜtÎæ ¸ôÓv5¹{ÌFj=Øpmâõ¤VÊ~ª³°­!þ›Ïàô…؉1ÀÀ¢SŸ¨,¥1icrQÃý‘°tcjuÒœµSÇ÷Î0÷é ¼daõf±Ž/|µ·¶ºÄ=e4ÈAÐnNá»ÊD*æä<ãÏùÌ ^Ø`)Sb“ù â´oÎX"7ãêNŸèÄ©¹Æúä³ÏžÕ¢—u1þ°Ï_ÿàG?ÿê“·úéúᦾ§©YÒ/•yf=ºêêv'Þ#óEwäww”\tÙ'Æ9ÂÄÅc{@÷øJéêõàJ^â”°µy%Tö˜$šUG¢^¤– ¯n/^ñJG›@y'@MfÆy½nSgQoPáת/b¨ø•¤ô˜²QÈæ0ø9‘ô_œþU½½®˜‰?¯jé-†QÉ+ì´¿ýŒÇÄU“¾±ù‘ï²ê¥óþFy´ë]‰ä,.È*È,P0‘êþbä:í‹ÄC-ÀÓⱜXÝ_%‘C ;Ç´jËo5ŒK”êš„®M :£;eY¸ˆî< äˆFሌI¥c44sÍà hÑ›Eeüó`Ìg0·`>¬ÂÅEÚé|k|ºµ ËP—;^€Ò®9]ŒjxjŠEy6Ò‹Ãqy]Q‘šdñÄhêFº×ÅW¹ÚdšÛs¤Î]{ë®íÞ¨aÇiŒh6g¼8·”£¼xß<ÊÒ~ãLó¦nL¬ÊÎîŠm4ûpïëÏ˽ùôóï?x4ˆß%ÝGÿèüâå½Nü5Ye‘î,ðÞµnzM fGgz•û„Yf·W–ß&›‹sdâ´Ô†©¥°SçXg|6¥CîÂsïÏ–o‘* àÏ@5+^W,ÂåãdÝ+ˆºe›tª­V.Ë7 o¿UŽEqVÌôt½*Œ8ç<XÐ.¶?"†] >ú Gv:·ÙìœõÀТmJë´Ï¬mÖ):8™–Êsé.;‡rÏÝA;7Â6ަȉw5rDžw/fœ Õî#Áðžý°]'~ã~@H"1vŸóüþÙIJÀý“8¥ØŸ¦0žR¬‡hôhÚ-覣® ñD Ö±HÙ˜m:i5¢&T†ù$±Ùš¡yhÇ'Wð8 Ÿl+.yêÈÃݤ}Ïš:68¬æDA¦ ŸO‡aÔ •Á“ae<Ó‡2Õ³rkôm“GKÛµ‰ÌñØNØãµÏÑv“&ÆÆ$r°XÂÜÞdìÑ7ƒÖésôÛ§V;ŒÏ7ö ù”j¿Ì‚…(²u²-ƒ2ÒE|ùúÍ‹·Ÿ¼ûþ÷ô|Wëßü›ó«×?üì·úú”/pß2\SNWÙzîVÚûÂw¢l]o ÏஸppT†Éå²Ì ‰À:̵1¾¿àS®; 6ÿ'öQØ·q¨­ :<ôòx™¦–•øÀ{dÃ͆‡Q»PðP9h£;ÑlŠèg_£©Íd;±Ñöá`©£Žmpei¤ÉnÈËüIÑEý1dCPÒŽÕºi.ݾ”%)Xµ:È×y©_!HOhXÉ£p<ŒˆK5ÔÈ;~DYyWðÄTËåLMІDê9ˆ‘È{’I³Ï•ªu}‚ ÿâÜY§ËòÙýÚ}Þ‘..£–ŽR¢m¶È·\¹ßõÀÇ?ýé÷t¿«õoÿóþÕ«Ï?ÓïkÖ%ö«OµzOÒ\ä=mžö$“eOЧMsÊYÜúÚç"Ç#¦Ç: 'œ|+Ó¾—®ÅµyÁ-H޼:uüø €m»Ö‰Õi‚PyÁâ–/8-gaoˆÖêÁw—«1bö†pæØ6Ø´Å¿ò›F x¨˜9³Žå{îŒÚigÔ;ùß(O—¹’´ûý‡ù*? ºÛå1X}GÎö€òP` Xz¼)C*‡sޝ ï=í‹&ž»®Št\okq9Ý µ3×£FrÖ1•ÎÁ6fS,7T–Ñ<Ó<«¡ñ½E{Éj‡)ÛÅé³Ûk+䆓‡6lEwîE{¤*@ïñqI!H{H üì0\È:ê6&W§ŸÊ©÷™V9·ÿ]s2UFlçÌŠ|2ÄʈÕ'1ƒA˘ñ¯öp\#mÆ âAÏ®~õ ¾^§ºæÒÈxul¾S›1<3¤}—ñhÌxsÞ…wÌÞ}òñoÿë¿ûwúSóÏ«ìõâ™ôëõ_ýÕ¯^¼}ç>Ÿ^¯Ò{÷žWZ}F}Sy$ÐÝõLëtêDª|Ç>q~p˜?úäÏÚOâûÕ“¼úÓYÞÚἸuÜ禔ìWÜ•ñƒOÿ^Oüq™DCbãvÃ[ã\ʼª…ÔÑúègëXÌ¡›ÍôÍýC¶²u*|)ÍÏ+ä¦pCcLiŸö~ë½rs»8ÈøšÜˆ£é:2Iì£)¹æà W0R¦óë¡|à^o¢ÔFý¾RLujáÉ3“¿oá$à WB|“*V—µ–Ó†ZÈCÿ» »Fä‚’÷©w@Œ”Ê‘Ì{Á¿™Íh9ú^›"J:d bÜÈÊPO¹äYåY¶.Œmj—·.<7aë8£¯ïnlݲ•@µ9í×Þ¢sD£âS™z{ðà´}Nc9v>X•¼ñDJ‰5ž;nPwùôÙ}ÙQ±÷Zžqwçqfò(òöÝ­fû´ͪÙn„rÑ9½y÷î—?ÿ/ÿåû€Ôwµþ_÷»_¾üôãõ'ó26S Z'¦j]ñ}Ñ÷e_ÿнO*ëk|ŸóŸ¨'Fã8÷“¿«úÁÙ…èP­fµé°´Ý¨3"ö`>7 /‹åâWÇ]Å6¤-×ð‘žs8òì˜÷¶7ó‹g{(¥A‘C¡<μ°÷·óók/°Ò›æÈ!‰ÍƒÀÛ8S;lµ@üÎüf—G€È“Š_QãµRŠÚÏ-‘ƒóØ*Ãýf=Я·Óî‹„#÷òf|¤ÔEñæ§¹†yTӌ a.°‹ªÓQ2âe^¢;0L+Ê¡ŠâÐÜi¸zì+3î‡?ðdµýàr_Ü©ð«¯jç^°c»¨¤£¿˜Æ?ðï)ų¹vëê¶XuuWŸh«cG¹šMÆL¯ÏÙúôa͸ý£ßr"ì8å ¶mkÿÑõ ïLwV›}·ÂSL¢”/¨3Îö£µcÑfn¼~óæË7ù—Ïê/ÒÓÛê·ü³öϾzùé'¿ò²Îg7÷«,Ù“‚“Ú5ŸuÛç( ëdªþ”Y бÅÿ‡‚{)ʡ۫ýê'oÛGI4?/jzI~¹µØ æ¥e½¹Í¨y7¶ß“†  FɛБ‹UÈÖ„)lO®Yݹ >cWõÔ§”pÊyBø­óæ!7?hàSiJÆáúÇ–,|âfÄhë ß³ã3©e€ª¶iÃáÍ~:“[³øì<°: — žp_gìió§o¿Ó0tþî²77D—³²Æ. é4ò-×u]æßË¡öš_ï`Y6bwkñplf°;µótêƒ8q—r ÚZÁ²ùã.8ÁFŸ('Ý­m±º#Ô}J ¯¾7ù÷è0CYZZi·Þת¸XŠzÊ€&e³6B5éõ)f…(ÉÊ'¹5/ ø²ÖåÄÔ«¶SÎ Æ»>›u{¤‚ÇÐ;ƒ;î”ÏÌ’íi¥½\³WïÞýêßþ‡ÿðýÀ}˜¾‹òËOó'sa5-tWûK\RD§ºwât “{ÛgßN]9–] Û„ò­>Ól7¿jˉìv7ð{‚¤ç³o/Â`û#¸ëì‡*ÒÉ>(9Öæ„‹¶ùdåÓÒ§…Ãb•üó¥:êÃH/ø2\l ðâ•3í¸Å6ç‘|¾õjì¸õÈ¿Q¬wÒCwø:LSnªX,ý/‚õî#!}ššsõ‰ð*óV¿Tù“¶µµÊD¨:^­ÇÜþúÚ çï)€ï1øþB¥öÉø ÕÊ™ñ¿~îÿT<éºèJã3 „²oÄ•C_ [ËØ›"ÄÕ%D:¤l\sß"Ðé{2-88æÕDºðÍ}4mC¹ ×ùˆ}txv_+ƒ Íbݢ΃ʴ1ÍÐí‡÷!ìCʬ8þÚïˆD¬S®Á›ôHüâð.éó +§D¸Ê3é®.ä×âZoõã§iŸB=q!51 ka\À~…]¼q÷:ßä F |·„1BIni3wí‡Í>Œ†ò΀±àt‹¯k•éHôö Çå|òŠÅ†Ã¥ÿcžð!A—Ö1…¨ÔðŽ3ãQlĨ ‘å!µþ (ÔÛÔƒµm$óßÈÈv¦°Œ,åv¼ºåÛÓuÜLfð20ÎU´Lb±¥ö*^É g¼(¾">Ç+Ú2nl­àç: Z톭ߙ¢O4ì ’ÕÆ‚ ÄJ«ˆ³s‘rÚÑT.6<1dÎk>üѳû;ô}nKšÏ§¼þóýܓ߫Z¬DºkÙ€¼ªöÔ´]ýÖx^|Ú=:*È(èNü‰il1Õ½¯¾ã§/ÚñcÑ©Ì:Ì•c£qû$–Í /øs6é,ø7ˆšŒÕ% ‡,;µ†­ݨ¬:]ÔöXOœ¼’ÌBn\r]LúäU¾½6âËæ¯F Ð)D“4…Lx? k¾ñãÕ7òJ±ŸüN€J?Ž_ŒÈ*.vHs‘ ŠÖ×f`ƒp•ˆj0@U‹€JÂî1ó§6¦É…Š®5}à¯^R3¯tÔ:ü1]4©üŒ39¶GY‚³, $£çáà(hÕ–”ì79ÚÀÛ.[rÙssBÁ¢#RéºY„#vŸ#g—‚¦‡RäÄ)ÔxN(ª<üíwÈÅ£*ܺÆ9Ü–\ü£Íµ=ªÛšÜÁ»‘²u¯&Q&òáòÉŠ'kFÿÅ8|¢£>·o0'í”íLäZ7.þ‘“[mHÍ]s(G냮rí­ïzzëÞÔ Q_|v¿€þŸËWÇワÿ‹_üâå‹tÅç êöZVåk<=årSÀäÒ§¶rô´ËQýYßmÈt§ÏÙnèê×ÚWIÂ’ë8»–s£«îfòð3€IAÍ£¦_ êêû¦½ ÓAŽM#›@Ȉð_|"mñ"fåRKTù@4]S6'É<ô¿}MÆ= \íŽ~lÝ»§áuþ;;\S o \ µ1!Ê{G²Êµï0yÃMØÔDFÓ‡€‘›;›râÎïê'þ̺t>«ßfMÞγØÖØ1ëÀnõìŠæ\å°eaÄ_Hþϵ3YG¸åO[‡R¢GFE1ކqfDJY¸ÌW|ÀS£©pÏh)Ø{4kÂXd°%’\ï8 Žª†Ö‡®*G“P¹õR41TttËÁšu·M£ö? «s¯ÏéSt0Ä£F*Çæ£uŽG#R'óí/ðå.O½6‚VyËS¦dŸ«nûlL9ÃØsüêÝHÅn}4ÈÕ•áŠÝVZï>ùìû€Ðw¾þæ›/^ýP¿˜ÕŽ…•Gǹ¹øÇϼZ>í œãz^q™ÂÑ¥ ;õg»vê–ú!ŸíÚW­<ïön.õeMã¸Ç´g¯ÆÁD'%›‚œðóM ‡ôðñÇc,2{2 ©[€Åã,¡¿ö§´"¹ %‡7a—M ·m¼d4AŽXO›Ò,¦…‡êÔÒ³¹£C7åsŽ+DØ®öǹ˜í1YÈ['á;1×¢ºâ+×ÇDÇ ;ž;+4ñÚcP‡¢Š©Œ½ºbSw#½yóöÅo÷wÏî—Ñ»÷­%éùz~ý—ùóõ§ÛÃ.„•§o}ÕÖ®ž“ãlgrõ´®ýô¹£ŠAŸx§­ö»ÿyµˆÃþxú¹]Ý‘Èe=……ÁS·“I=Ýfn„tÖÊÛ”Û°¦%1¦àTÚè²é+þ"™Dê²ôr¡­î/]é‹®«7¾GX Õ«Ý) ¦Kh7`‡égðÉÕ!uÊ[ôÁûêÀ’[á™î¹ÚÔŽ·O5P7ÖèŒiö‹‰ËïpÛ¹.«û÷¤Æ1Í’hÕ=yr”‘sŠ—r[cÃ]ÚÌE‰h¬6Ù•×í˜p »@]e/õÙM:"¦¶àö)G;g[6'†¤c”¹ÌálˆNË4tì~l't8f‡È 1¾ï•—áq£”­A5{çi9¾Èw],œñJ2}@ªms»ƺÃÔÚzcª O¥GYô1 ™7rk|wæH4ܾG}/µ5›G˜ú¼zûúÅW¿ÿý÷ßè€|×ë×?ýÉ_ó­­îXÝ,Η$ºâÝpöÔJÏÎÉЉrö¹øÖw|±w}ñØiŸvtw]‹’ ¬Ú³r—Óöƒ }Ó U€}{‹Kp8D·>}.\ÕúÃÊIl¶ ;r¹‘{H·ÖU è/=+І_ûSgÉALìV Ç‚ŠƒMïôeF·r£M©>Ò< lž¨ÙŒ«£–Ü ’°EÄÖ¼¶Ïšª?f7(³†Ùf¶ÄFŸq=7äÚU“»ªŽ=Ïî¯Xvz &ý?¹STß½)ÉA¥s«¹nôl¼PÏDÊ/‹ÚÙ£†¥œöµ对žbÍ»‘÷kð3ÖÌÔ¸pÞ­¥Šz©ˆ‘8“(žÆcªåð a`Itå]è¢C!ŒaVn91ã}¨¢øÎ¥=]ªËøT*â‘\]=:®õɰœR[“V{QÿʧÿÖí^7î‰;¹ëÓ<+Ÿxl{únÝöºg{âß×Nl¿Ÿ ¢O~ø£g÷‡€è¹×Š÷ Á«ÿó¿øÅ ýõ¦oxÏ”­ó¨w°:Æ3§EVÒ)lš *]Û˜ß7™ÙêWä¶ÁSOÝEVg.½JçÛþæ8Ö³ÍèÒÕ  ¿‘æí­&)­?ó—\•ÿX ùáÐä%¼ÔKín<Ä?‹‡±ø‹¡¬;—ÓÜ6¯âÓ¿âeñ«kɽF$ÄÜ䯘¹'%&Ȫ;hP¯Î©Y:ë—C$þÜ0¥˜Ü ê÷(¨ø‚`¿|h°˜NPHQM~î4š’kômȲÓ, ‚yûßMéá£M)Lur‰º†¾!ÁO6l{„WÊÎM –ËÉÉ‚š9ã{æ4‘ N„8ÂVù$FçÀqðy&ogèÉEäö½tæ.Í=hwkôÊ/ßqÙ2|ýÞ YÜ;+¹#Ÿ:;D·ú>:ªµÌŒÝ…†Ï9îæ•îRî2ÆÑ¦¶©ÓÞš´öµ;ù{=ñª­ü#×êñŠTÛæÙ±ÐU:í[GëœëÁÇÎyGÜ‘cÅ’ÒLÖñ“ªú}—ƒ¬¶Rê¹Ä|>4èíg?øþ#€c„¾ÓÍ7þß½úH?áø{.¸¦×Sw¥oL­&ž$ºó¸ù΄ªGm…ÓÂ&dJõõ+þ}u}êo’ó4+wýY½P3öŠðxÑ’>˶Œøb÷ÍT£_NŽp&¸ 1 •7@Ä!]”ƒš€uªYG^9n£)V¼€Ðõ¡Ã×Wbzd6»Àr´Å1;4j¹Ü†Æ:YÖ&B;›:­Wuô>›û¼‚6áŽAá)ÁíB¿T®¯¦W¾xHéáã÷OªRç!¤$àSHј1]Æ`tÅò›€ú yªóPKXyª]·.ÀÎLÊbò@I(sÔ¨æÒÑn&0ÎÓ¶‚ÓÌ»æ!%¸Ò6TZ)3µ¾½™H Áv¢Üë÷1•£ö{Üò`¿Ûêó>Ë/ᾈ»¯€ÔooDÝY‡˜?ä{V2X ÷wb®;™F†D'^ñZ‡|-V›ôª÷ƒˆœteÄÝÔÖB*…Ýqvøn„Þí|i †Êœ¦Ô)j×Ã/Ðõ ã¥$پ͟NæÕ§C ëø7¹é+˜ Ì-ˆQÄÆÙsõ tÚÇ'÷ÝøHg>Ÿ¢+¯i¬Øx·üXBtbo. §†a°¥uìÓaµëÔÃÙÆ³¶29qØ*ƒ¹–ë–|Ú™‹ø1N™vyËyÕmkÊ~Εz>ªƒ×=ôúõ‹·Ÿ}ôýÀ£Aú.ê^ÿãüÅ7oßüæÅWºð\EîÖYI}Q³*&õÑ#tÂ\§Q`™ »]¹>•ƒØç÷é7b·.Xå•7‹²ÛÍ•0µÖJìÆ\Hʱc iÆÁû8)õZ™!Þþþ¥9ØÑéUðùÙôÆé¶Ÿ~a“<1õÞø¨¿s½*;úÙçÎn)žßÔÆÃ2ahŸ¥˜­›Duõï›?9óU’Ù,3&ïœøÏáw`fé’uKa#[TùÈa£/„|ë Z*÷ ³D÷óQV?GÏfF’R²Ñï%2óÊ·Ì´´½k³sn j» ’%,ü¤oÅR‚™ë‹ÎxNÉeWŸ1 Pàl™ÈÍ5\H&57ÍÒ)ÆúÒ®q޽øG”s»cýÈ U¬S•ÍaÁJs8}ÐËÉ÷«jÚ…ݽB)O¤åxr`ª\^ëD¾eÚ•fžŽW´œO Ѥ)g%å²ùFqTÅY¹>íÊLrK6Û'òöÙ^ðÇšìc‰63èd)ö–íFÿuÓ¼zóFÇçß õ]¯¿ø×ÿúW¯~øéüI`eË•ïbEòº¨^@´úÝ?WÇ|hB‘VÎLµò‰kûgmO8ÈË9‘MTí¬à×\«›‡~éܳÉôLÕE–B øEzç¿E±aS.ß–*¿ŒˆvÎ@Ápö+s“v+%£—{0j@LÇÚø$º€£1nK'ý›·!K±}pv$ÆŒ$몗,×n CFÀá0¾¼i|â¥íüëˆjR)'ã<¦¯Å ׯ!,§±5ÏÆ°}x`?Äñ";–S’H;Žù¨<Çs-0Òî鎴ŽÜ¶nÓgËj~\·¶}Ÿ,i£§ê”•4z} 8ãØ+' à[‡ã–êMõÔçõ¹K™ñÝ>»ueÍœ Ó~”¼×¸÷È;÷F Â×s†¥9ÄãÎZkY¨ÛÆvÍnràk>w{ùê7ï~òÃïßè ~×ëŸÿ§ÿôë—Ÿ}úe~b;†׋‹”ŠßWû> b͹ÓöÔíÓ÷Ô?jÿ)XüY\NŸ®YØüÐB?¦/èX€©N;ýíÂì߆xa<ö™ï®Î@ì2$îŒ#±•ÆM¿‰‰K¶-\9NÎûAEv­”—¿(ok[7ùBëoéKÆ×‹ëPCIúèÚÆ4¡hÊ.㔥’- °„‚ñË€d#ÖÃ~äìÑo ßá”0 ŽpæBÂ#'mL—ºª&žcž¨(Òé÷ËŒ—wBÆït§}‘Oax›.â%ˆÄs-¢ é•t¯HSª¦v¬À³iaÔÑá(çÒŒÝú‚JxȨ*6Ñ»¼8ˆ§cù °©!r ƒ¡‚P…µ×ÓÐsâŽöÑçl…[¼¥k¤Gvð}¢=ífYüU®öi'üö 3¶èî¹7Ûíö^6 –CpøÞuÕ óÑ»/þýÏîOÓû¬_´žQù_~ýë_½z÷ñ/¹ˆÞTæ«ÝëZõõÑ„¹N“ ÈÓ‰±ªhÎöFüi-8Ì3+v8u>Wðb†úQ~ñÛ±‘×Ï–ÃÓ[imôãš/EÊÁ„:á{ärPí`gK.ùÀ§òÞ6ùRæ!€ë¶õ¼â_ë›í .Wµ½“©'¸¨Öµö芻>[·ò3À‚¥1»goóUÀÍdªšÜ#Ÿû|K߃;áòì!a0õsÐÁ¸m»[>¸Õ7ï68%¤k²uGjHAëA÷k¿]¡ÛÀ q˜Ü%Ÿ¥1èì×(´ã {jßÚýÚª§È&¶SÙ8à1˜ Ópäû;Bn WW üƒ°+Ë´B©Ñ6u¡ÝK¡Æðœª¿_»‘ÿXoãÃK{§‚.ÿÊöÆYwùôêUÛì»ßÿ)þä$Vãcž“­ÞOëíÏ|yóÑÛ/ÿŸÿó?þú)îÃלkLJߛéÁ_ÿõ_ýòŸø#nÜ—¬þÚ<ÖgËÂùmuõž?†r–Sö4À~Ãÿ¾É„þ}6|OÛÙÆvL=D•hŒ#ß(s>dÖX/R“k7D÷§ dË´z2«\n=£b·>|^—"*‡XvÊ2V¸( ¨‰I¢ºáȃÞó Ð_Óø$AúÙñ¦ÛÛKfÓ@k`ïÞXÆç½àðù3ÏŒ¶èä˜ÛÉóˆqíÃ?Ãú5~Êõ•œ‰ÃïH¾ü>…Èüõ-ð~uïùî?Žžœ_‰ÛŸß—ôg–,ý*ò'àJ•¶të;â£o\Ãy£#ÄM~¦˜º“†ÑÇ›4רv® íÄà$¥¬<ŠÈ9G[ÍžsÍh•pd“b¹Âšà±9W5wB Kÿ­¯ÿô¶Ì9¸Ù´]Ó>dÀ #ý,/&ÁǛ忻|нXÕÖQ«4ö½]?ƒtê8Gçï`ë÷6‰­Ù­Eq&嬣‘öµÛèÜGÛÖ™»±WŒõj«œè·ÖíSl0õØuóÇÖ§•ˆw->:ô#3¯Þ¼ýå§ÿê_}ÿÀ}ˆ¾ËòËÏ~  ¦K;w17Y‹/ø¼$<_œ¬ ÀÖš±&ɬuFÕNÚ§u8JFÕ¸ScäöRl?(\ð)nT…8qöŒœ05»Î8dl®ö=^c»êÐn¢o)mäz²µÉ•ÜN{¶üâ@‡5qâ³cD>ѹnáÌÃ\1Ôm§Î½¼ h÷€{ž^Xž–aÔÀ¾|÷îY¾ú§Ï¼#ù<Ëç?Ð_oÒ×ÂäõUÒ¿™ŽÅНKÏ¢Åd¸¼ºžñ&¤6SÁSgð{í)•é2Ž z„­î¶[ï<¯¹fá•[ñ®$Ýõ·‹¥¦ †Ø¦¡ R$C%Î0D–mmJFÎ ·:œú•¥8e_i8ŒâëbE·òŠ_yô{¶«?v£üMlä•€¡’MÎÞ+ô¼MO?a6§€ŽÂÀcóG,g •Ìôm¾–?áÍÓ%Uõ-rùäÖŽÙW§sSŸç ekpÎùxäló`‡LŽoƒ cû$Ü)ÄCyÑ\u[Jkæþò€¸–*·O4Ãh“È1ª‚äž:½›n™Nyße)ªrsŠþ¼æÍµ±R—©\WDôÁ¨¹¼z÷öYþ #µð>Ï@~õ?þÙeÚiÅôÏ÷Né ¬ètb4x;´r'Bß"]Ãò`Ô:aæïÙ¸LÏ{ÉØ{t–Ûë3¹K°Üþ‘º%çó\Ô”ÜlxLAn(j™ú™|š4›S”¼tC³~tqd¹½½y.ûÄ™øF„¬yY÷”‘ò²ì|dàz:9°3Nÿzy›+sÏvrJ>¼eN±}^NóÍ~rä3yÌAÐZº•¿]z9wœQéõ.‡dYÜaôûX¨ª €l 9÷òÒ&}÷cé¥OÛp³*JÆ:mË:9gwfãp°'Ì ² ´Õ8døjÛ_AŽÎ´å¹ÊƒÐµX4lÃºÈ I]ÚêP‘ä–Ë!”ž_î°‘9íT,›w\a×aÿÑÛEmD§XŽêÌÛ‘ÌÆÛ1 Å+ŽòX’á9DšÅ¥}ƒ4çÓ/Æ&Úž¢¶<lj)G¯7ˆØ{}‰uõÚ׳×<Øpà½hßã6&Ì-ÕÕ; ±žm4;×Wü,ÿ0½dlŸeùê¿üÍ/^}ôÉî[¯¯îrOz~ô¾æ: /\•Ô‡OÕV•Õwþƒ­ÇÒ+ÎeAyñLÎqœN¼7`oRꇜ²!Ç{ç»ØÒÙcÒC«n8Qëèfƒ®íÖB¸ðe¸]á¨Ó…DAMþÞLÔ¶¿Ù„í6}NBÖÈG×Ó Bc‰ü°½”i$ƒ™p‡þõ¡`g‘ƒ_ Žrê¸CvºÏ«7ê§% Ñó@–Íèq «éî{IìfýÐ.:²X‰XR%{JŸãœÓÓxíÅ×¼š˜TáSÑ% (ÚêÎXï·lô‰'Hæe˜‰ŽNül+9!’ŠüWµ×°U5˜äS»äTŸQ­{²±k_qßÑçüäŸÃíÛ› ü>ÔÝŽüÇê¹Æþ}!¬?9ÛNMÿ8î÷[¬ÅžÃ}ŽÙV¾'€o7òb6ß]y#´ Èí£O>ûþ ƒó¡Ô_ýö·¿xùùGÞ ÈÙ‹ôÜyE^æÝÞ«©¦ŽFÿÞô®¨Y‘7“òð~ïðtú€»ßÂ̪Îäs™ºó?w¥vÉÝ8ÏMçrc ’4Ý8­Õ‘ˆlCÌý?ƒU¶•é0E†CŒ+ iòMx5^ÔûóøYŒÌ`À¦¥1å&ö1ù­sµ{ëB·áQâÎÏŸ ¹cá¶Æ‰7ì=B8‹Ôo@>4GVKG¬³äw€ìÛÿ¯J‡š8-íÄè*b^ã®v~ÉÑ©.õÍã!‘ž¼š{ÂŒ8а]ØáîŒ@oPƒõæÜ [—X¸^KGöª½KæYJ|CÊØý<œ¨—I}¶\…eõ¾²¬« µôË4òR4tÈ7L!O|uYŧ\cF>Õ`fAî>5L½Í»uƒâÆÐjz´;Ö™õ‡‹,±Ÿº¶a؜բ‹¶6dÚé]­Á‡ƒ¸äÐ<Ê»å“ýwÇÙœÅc«½º]'®îŸÞ¾ø»ßüí³ü%@ôö\3vïŸAë£ÿéþì+­tßx'ÑãZkÑò%WÍFæp›>×N›bÛ1M s!ü‘å}ø;WßF^´ä%Љ[ Ö€îÈÙ°Ô¿é èló•FîÙObé#ƒÃQ¼]‘â´6ìÐz˜pqɇŽâÓ‚æùèr^NKI.ÉÇQ·~ ËC~æ¿@6ÆÛgÏïÈ`øŠFú³Vå:A-¯Há&—úæÔ©íTà“OrÛ\ÈÀÁÜ)/]89…w¹é,Þt…ž $÷Ä>sq9]­pä_w;ú»î}ן޶Çñªçý …kf)Qv)Ç=ø2n4­Së{OŠ7oß¾àÅäù|¤µ¶<Ÿ.¥'ßüÅ_|ñâít¹ÀÕEÔKÞç•}/8uÛ…V–éaéô¢nàÉuwSf´+æ•1œ*µõ·ïu£ß½OŒ Û“‘&O|ìÇ ˆ6÷“6ªGyU×n…|»¼$(!ï8&¾67œ=zðpLäÂw2¿dƹJå|áR¹ù>Í«Š †. ,ì@Œ“Ýc`!}:qùq@-ÜãC÷é!ýð;øÑ?*ŒÃGÕ‚+ù²¥¯ä¾ù;ŒNð›ƒJds”uòØ¢Zö˜§–ê‘C˜s8Š¢îÕ;=ÐWÞ¬iù¬±¦;ômMÀ™rlœ|øz¶=vëðýâ¨îà\ãxè€ácºá8©ð±­>gݶIŽlUQŸ1ªÇ§óÊ1‡òÄŸú#â4c]|Ö>ö¦ÈÌMàçµÅZ„©kXÏxõDÇQÏÊÁ†gŸ‹ÊuüæÅGŸÿèÙ~ ðùþÀ~ôËWoõ½îßëµÔ»×Y¸µ:ñ7í]|¥í©¡YÎBhsgÀÑuëÏW¤^@»0†ÝSmM¯®.½“Ó ÿ®ûèOz,¦Ü}–LñµÓ€9Š?v £)€`ÆL– jËœ0±[·ì^¬|»}Ê`¤áÏòfq{~™ $}% îñp„´a² 躑‹SÍvä>’“Ô}·ÀfÉØš6¢cA;O^eçsÇÈEÁx—цԿô‡·ÌI>¸M¢®¸V@Œ‘¢`ÇDZáâqÐxuL2~Ñû!@qº‘CÆõX‡8mbœ¼¯q’X®?ñP7ò¦;÷ⱨÒý7錷. -çpÌõ2F£xŒk)Ïš8þÕ¢¡lŸÊîlÝ;NÂÈê$f#›}8p^÷G}[cTYaäs¸qèoaÜ¡'`¹Ä]S+l–3O«¸úX{ç½Ëãº*Û9íŽEÊÈ£EFŠ^ã®Fu\…xÆžû5+7^”zÐ+­D)CëÚ§y`……û1crqÏ ì`6C"ÄÂùQitj<¿b…МyýƒO¾àÑ€}—uo~üã/¾y÷öÅ‹_³*'So^m¥â*·HW‘›¸]º"ÿÌ>¯¾U›ÿòÞb¼BO\›.wvÀOâJ݇Œ>tÔâ<ìaãpGN;ÅñЗÒ7Dz@‘FÉ?cò5ngê*oA³±¶|-‡~Þ}v;›ïƇ»ï60fùø¡WF“LeB- î *Cé·Â£ÉÛëj7>©sdóÈã €÷ˆYéi& ÌÖDc4„`L(?|V¯;x×=…£cå\¤‚·=0sÙTw󝮨ָ¹Ý`ã‹>*Ý?4í[Úppg\jîŸÊö°À Å5A:‡öò\ÍD»ÄBwc·ÝqÕÚqiM–6r“°+ts=É]vð89}ó îæXQA›²4VX™Öòl£u1âsˆ‘m.F5Íe/FŠâve (Ø ¿µØáâeŸûèæ:—‡"ûê$Jä­$œJó8c¡«œz3T¿³}³å¢žza9µm·n^e¸ÖEɹqõk3_~̯•ž¥kâ³ëÝËO?ýâÅ»wÇëIÜ•Uµ¿Ø—K|ù(€ wO ɬªkq¥18ŽnÒjfÂŽ½Síäk»qì〇^\,D¶îkïBÑÁÉÑÂ&e¬_BjZObñŸÛ·Éâ4ÄU™““wCÑ®T\¼IIïÉ4ŽÕá0C²êfX=¸9(l6ëÇìP¬~0Ôä¡]±ñ¥ã«ÂQ†çiÊ|–Ñý¥§n{aMð>˜4?FÑï0Örrh¸Ô8Ç©)5]r>lôyw„&Hò€ÙŒŸÔŒ©Çu£/Ä£?<X@á2Ñ–5þïŸé™ˆ<öò[î‡ý*'½NM <WÓù;ÏB˜¥§3V²½v¢vêØÓâ\[-æ´!Îö±ï`bw›"}"8ÉŒÌBªaxÊ2D¼œE°ãŽ¥á?óéÄåž[ë!/×,¥i2ž&fòKV›dÔ†pªÏèg™ÄÒ ®>æ±ec’Ç–Óz¿¼‰7&ºÌ+´ÉkÛÓâë¾GËvéI•ƒ¯ßV‡¯òŽûêÕ›ï>þøÙ~µ°ý~Fõ«øñêã·zrÓRʬ_xÒWÒ­éÅW^È2앞÷ωq×Ýe¼‹§ÆÎQ]ñ,Ü´|lÈJüêõ1Ü‚œM‘«K ÄB]Œë~R05 á ׆n­Ýt²yK÷ƤýX“ª~GŒ~`«ÒË-§ÕÍ•>ä-ÞêU£t0=PCñˆÉ(6ȯä#딼’M²œd£ÏØ24Þä͹‰H%ã ûYêIRc3NÌÈîHA²y,‘ËSÛÔ‹¿$pb;>˲,…öõ°ßµÀ§1Œœ“7ÃCæÀy\0£›œ @ìd—´Þ–´‘Å-¥Îo÷Ý>¸Çº/²}ÚÞ+ ª­¾vl„¡]ùÄŸºbd?!ÎÝ(ÙüÝF® ³Æ½üv–Þû§®qNjÚ̧àÓA|8W d=xö6‹«L;íª9¥»ÓX¢š´ÑfÛxÚ+£+s9*_=¢^¿øÕÛW÷úÓ×ßÀ0~HåËûoÿö›O>ù% ¨<sø³ËKÇÿ셅´ÓSpµ¯©2˜ rs/÷)xÚm“O9+Ÿ˜Ù¤1&Žo\Ú8Â3ô>¤¦Ó¾QÚgaXïüv9µß€`HL\d ;†õ“ÉÄõCÀ@J‡9C³J9I«m6·¶L÷J*<¸7q£ÃO¥•\Ö7:†ÔÏçúŸ»^ý—‘fú‹ ^ûQ÷XÁ²1¶I/ÈÆ‘ãÃÂ2Ùý{L@[‡®Å~•.À¼ì· ;AZÚVíy^™Î8†Ïj«Ò³Ä: å;kOú4ý ãêô>l?Ç'F'Âÿ §•Òz/ÝWŸùÊ´M §|ùEi0mdŠuÉÃí%«A{«us§½³¿°C{ÑÁ¡2´N×yŽÎ¶‡iNØ‘áq™Æ’QVhŠö!Ÿ0Ú”›yÉäq·uªŸYožœ°Ôš«9c¶-»U;u´ÈÍDœZwœí¹‘wëi9c‚‹Üs£>ì7ÊW¯ùêÍgßÿ`†øÃ9ÿƒúOýòÓO~ÙÏX½ð)ý¼ýÏ…í¥W{ŒçT¹Lˆ:·û#›á[Pì'ñpÈçü)„µ+•_5koóZêÆ=íGÆ Ø½)‹€Hj ¦'ÿdQ=äÚú6z¨³ ƒì+l6b\ò¯aêûpeˆBpW¯ÍéÎfß>17ìJrˆ”ÇÚÈH<É«q+ò«K-É1OòžPçuqÿQ®hŒ”˜Ÿ£šÓø5|v_Ù¼jz„KZ¥´ìõÉ-xïý¾˜‘I i4•ây0p{0öP[ÿ§d,™úý2¦G@2c|Ïdžv_Þƒ ¹Œ·BÑ^-ÝVOp®CÎèw+¨S†í”%6ÀMm_ën>Å·èk‘1À…,³Y8ªeý¥@Wa›ô-ËOŠ…Uƒ66Û±²Ç} öÁT…ü@õPWŸà÷‹Ü˜`ÏMøÊJgÏ“™²u™èa˃•²™‹ºûœ¨Î-°Å›æÂÍF€{ýîí/¿üÿñoãóüÎ]Cž_Ï4w¾ùøÓ_ò *¯¦x•ÅçÛ½ÍÄÏF&ƒF“­«©0Þ%wú£„Cfºz:ÖgVåLÑÒG#\ü@\:riPŒ’»Ñ#ö!æ\Öâ=ù!{ã,ïפv I±p¤ôâ\_~¼´œv‘ø¤«†äÛöX\ý[gó" ‡7v],ÒlßZÃ圴z##ú Ué¤CÕî“[eêk¾}/Õ”cᨳ,‹/›i6T;zå+bcùÈIÛòxåeq³{žF§³9U«/~Õ/6¸ü` ºýpª2ds½üÛMIÚñ zU[a£±‹S žƒòÒÙÃ(•2TùÛ–Û"ãÏ9šÇúò+’žuÄá¢yMœøf›žå3¶‘ó°\bhyAÜm²°ÂBc|Ôž0…[%Õ.²@½V @e]»‘©Ülã§ VM.•;_`)…=9a¥´GybAÚ<ß°^¹1<øàHÙ1¶|úlínÕ‡¨\µ-ÛÖb¹ýYS6ìõ›/ÿú_ü‹ßläójuýx^½šÞ¼þœŠÎ\Lî.]i&¿§‹ï‚±O;xt*ÒUö mÛ?ï #ãî2`ësr–£ºÓ':Gå3t‹C ÛH—]Èé•¶JÉ<¡ÿF;“½¯ü“ÌìÝÅÁ…ÜIMÆ•˜VAo*T:xµÝWÜûf3b@i¯W¨ãNŒ•†g-ùë*Ò¦ùÂ91Éã’[Ã9© NVuÕdÎè¿­·}O,塽Œ#Hr¸ä"Õ®ùó„ÔÃÇÁ4N®Ó7Ò¨Í?ÂEz¸6Ÿµé¯¹xÀɵá îŸK LucšÊ€´WNÛd'ò›‹råØq6;àµåt³>`¢I´»O´œëqj.¾¦9¸È•kU~›Žx#cß^ñY¼2œí؃£«Mb§ê\η‘Úˆ¹&aÄ•a÷*Ïø ëíõåá‡á,øŒl§*ÐK>ET•±“¯21SÒØøS{Å WK5°ì#(ä´¸&‰¿“Å«ùâ-ÇÉÐkÞŸd‰Ü5Žõ!Ük!ˆô×oßð—$òAŸïëÆÝ™{òú“À_zÒtée”ß ͺŸïû3üŽDkaÖgû‡Î1*µ¹î À1GMO8‡Ã“µ|ßäµÉ ×Á"°øG‡Â:¦luðÍæ»ö»Li<¸ùÊV™Ü$‘q3½¿y,Æ­öú,[v^ÅF(Ÿûé—¹DQ!wŠû© 86WÎ=9ô‘Kwpë5?rÊpDÑ ÇP.õ·uå¡QÞŒ»Ç^ EÕ? ù+ˆþç;hâ _ãÁáÕ¢˜(L Ë£6¾CÛ¡sUJÅqîÂPCB=Àƺöãj¨_‘>]TÈÂ'ªåÈ@IDAT·ÉU- R¢—¿þ[…:‚[ëÈÈ„Vÿ!¥õ©«+G}âÙ,âÖ"ë?‰•HÑ6Ç º:B¡²] Ú#slH81ºÿ@g§µ 2\*Û'rÏÝPºi/Ú†6nHRGVÍå©,WÔÖ_üRÕ³-{xŽ]üüÓ/˜~õ´ú7SD=ïd9_¹w"grxÔÊÚ‰Ò•×2BGðĬXã' ¼ø8>ƒ÷†<:µ aV9åÑ{./@³'yÃò¢NÐò«é'`騠bOfpq[ ÈäëŽÚÑ:îùn††ã7nÄn!$…'ëÜ\yJ굃¨.(u¡zóé ‹=&ÇKa®es·{Ná —´¼9BÙX†­où7v“~—ÀÜf,Ê&Yp÷]œ™7“k Wò^ðO®_DŽɢBŸrïU%=9±‰Ê¹‘‚ OÎéýòÒvŽ˜ßë%xûöÙþý½®5gR¿þìó¿ÉDÉaöâþñªïý¶§N›÷t§)löݔٓ8ð†“âÉuQd6#â3ÍËžÝɦÆÁÇ~ÃQ¿ryƒ)ã‘+¢õ‚Q´¬~è¦òŽ¥Ü;ÚSføŽÁ#î!Æc²t«ÉãþÔ‹núº+·þ¬þqº;õ{ú’—»`½,è8*“‡¿Ò Ër’4 æ”E7<kÌ„ÅX DÏJtG¿”WüóoôQ8 ‰LÈSÖX Þ2'2ox¼¤šGéŒÒ5N¢s±© %ï±Ûf;ÆKà ûÄP@]¿·ÄóDpµ“rêµmÔâËå`d·s?ûŠŸeaà§:í’L¯Ž'³Æ´RtpûDÕ”í7ü`쫺v+$Rü‘Š©€¡oԖ݈ÙçbUÀ§b瀊ö­2õDIÓçéÜ¡ &I˜g: @æÍ–6gu­KмãÄÊ9Ç–ƒb*†ÿî™sjÍÀÆg2AR#9õ#€*àgÌ_½{÷l€¾îu°=Fõ7?ýéßx2Ìí] &C6þ¼:ýš 1#áWè3¸órtò¥a6q ö ¿p%˜Ûñª:4>Þ» ®›†Û=Éjðéc Scä LÛ de9uó÷¢l®i{»ˆÎÔdŒÄÕq”—_ËÕ-aÒ€·1Ûpi÷åXÉì¾…}­^zÙëWtÎqãI•±^›{û0 ÍÆÏÉ+…¶ ¤¡c/̇߄ÃÏ;`»©8W(€è d¦P·[cÉzµ_Û™70wÖ$!Ø®RF冒ñb?dJÝúêŸá8A'°:à;hƒW³åÀïr‰ïÁо%rw× Ÿ›Sºè|!~Ë ·.´óðƒI˜Þ AíÀÛ+ çår!§Q;T»´BÄ”Á4µs¨ïï™È0¤0fè` _Í2ù‚Ž– ‚^‰½|ûÑßX~¦§Ùöžgï~ÿ_ÿæ‹?øxM~nš×Ý=ö»<£ÒWú—’ÏÒ)œwë:‰Ø€ú.ÁÂÉÃÍ\äèCÊκ±1¾§´/­FúÜYT"x‘芤ˆç¢a·ìš *\óÀ…ü,;Ñi`g ú¿ÓÐ hû4Ùuc¬¨\ ƒ Ë{Þݹٗ{|x&ÁäþÕ×9@µ;Õíܰ’îtÆmÉ^MD6cäGAšaòj i?"r $sJ>çoÛµ€þ>…GÓŒƒUuˆ}æ¢ýbÁöBô¡BΫ;ù>Æy}݇eo,:·ºëð9M$òQ™*Â2–«5 3!²9Äö¿5»ÕÎXãœ{NµmGŽÇéä°W9Lcaõë|€È—Èb7@ÍÜ7ÉÞÝ?»§öL'Ñ0ί4I=vt:Æ_TåÄVã„4þ𩺵]ùð­õ5Ø–rw 'µ=öÈM·Ô•ã¿Yèi¥³¦Ý=úsÃŽ×=n¢–…Èýòku÷: y¼«­C ð“O¾ØCòaµ¾ùâ‹_¾ø³O5X`Xôô)+WU×EÖ¿Œ…ËÌÝ%‹)?-×ÂÂêCæõ »7–1…xð+{t‡7ñ@ |mmM&Û)ë{u×ãà%&Ť™óétšWœ’óX(J~«øV‰e +. –m†C0–—‹)Ñ«ä·ñEX‹ZLÎàBÊgäþîQC¦ qv9àfh€èèæÈ5s׊+±¥È¦ Œ9ã˜Ãuö#y)7u<ƒÂNÿ‰éM\AûŽR€PXöv*8À•ï'Àƒ¾Q{³¢¶‹ìî—í_M­×|†¹äB=mÏaµ} šÔÀ¨¥«—¹[6ÈÚvå`–ÃÌu,6~3ìÑ‘ˆZúŸ9ŒÏ £^$V›äSHåáh“ÇÄ ‰ë96¾Æ .¶cc×Á/7)Ýã‡L¬º»â¢ú˜ýâ´ìc ñÄ#Æǰ›Îâ"/»–¹ðs&kº-•‡À÷<áàÜ#xØò m¸ãA›«¯XÀD[ßÍ®ZƒÄ×<¡´ò”_½}óâëßüÝ÷d¸>¼óÛÿù}áx^.ùmµY4¸Ð¹Ñ$K±§ŸfçÇç[ú]l^kõd#óCÁ¹ ¿6œßS ŽÎ=tÕãÖÜÖÉ86”iû­æCön12>«p­Ã¨áW}XæÐJÂ4Êäœ 8{Ü.Ž—e }T**×d ³8^1®ùŸÎЗé}êK=…ð€ì:¼®8•ÌmÃPšs]Âñ!Œ›"ìüZ×­\Ì*Ca¥[Ë™~=Ï»pÜ\±Ð“q‰wβŒ1S%”õá:x+—ÂýñuQkTýÈ&}´f¥¹<‘ÇÇœj{|“ÈÂ'¤[å–d_—zŠ}TKG5Ñ ín”atfË÷”¥ì¼üî ;¦ƒåHñ¨îÈNMðXb7ÄEï–0m;ÖÓL³ÈÜŽL»lõ >Js ®›Q<&¯ Ì|øÙ{Ÿ%O’#I¯2³ªºîFcf8B!…¤pû<í#Œ_§y‡=Ì›¬Èò°Wî…Lu@`ÐUÔOÕÔÝ#2»×Î*¯Šp7355s÷øýÉÌý1¹?ÿÿújÿ£s.Yȯª<ýöø _ä¿@Ït:zÜ «OÈ6iòòê‰éÀ†ÒwOÍ8tLHp< øA`VN¾½^;2õ½ {A}LþÃ.ÞÛtÖ}æï=Ô–…kñ}*Á‹ËºiQDf 7RßÖîrãHߦõ89ã¦áLp¹!ë3ÃjcßÜ©ê*¼ð¸ý‚Ønpš2ù6fcÅš· y°`>x‘å¶íV:Õ‡™ºlþÎUµ_õãxŒ‰u ”þdÉÛ£ –þ·¡S¢xZæ\ZûxL u¨ë ›ÆTv OÏu¨Úzì µ9¦UÇäçØÖ#ŒœÖ³ó ¬wµ2îÛ¢,¥-qZ'QFí¶e Ë•‡ù”Ôø„7Z_Ï=²Ž˜Á×;>#É ¹6§h¥ 9çQQ¹g•Ém›sFák'\¯…»°†§¾&`?xË#µƒ £­b ÷ËgÙ¹ésâ’Ó”öãX©ëÞw‘{4£…¹º¹±Û¯ø3‚S²‚«Ä·Ñ™3Žþއ¡¨Í ’1z÷í·_Þ`0~‰åÓß}ÿáÍû·oü7ÓƒÜÆºÐºkø‚X_5r3Ñfzœ¯ÌñêæMÝÍ¿Ëøxé#8 6‹ >áÇçű§®}2„¾­ì;"©ªðÈÚ–Çx—Oÿ2i˜Ÿ­ÀÙÞÑrî5L~;ï`›Yñ̯l&Î8ËÆŸþõ¯¿üàà_VëÓ·ß~xóÕ»?wãsÙ.À½Ûò‡XtÝ{'yndb0›YYdÙÄmšS‘~!°£ÃÃAuøf‘î; ©‹å9E»¨?9É¥g­U>¾£ôª´³“mÊÔ¬Hû×ϵ4%õ`!§42Ž‘é-²óÍ&Á!õ@¬·ÅÕn˜Ô¢1qSßËÐÝçÅPÄð‘‚?^¿ºÐEqjòq^:U&&ï w›0IÒ81®+/÷¢&òÀƒ™*o’ÐNµ ÓèGñÅo|q“ß©u$¬B[±«’OÃô!ŒyºÊ¤‚Ê>ªWÿÈ”>‹‹®>ƒaÎó0%Õ”\SÎ+œ¶oÐêb½¬ª²ÈægóJ:e8¦;‡_˜'²ôxTª‡dh}œŽÎŽl¢[%QL…-šøX‚Ôà*=| ÊÍa6Pd®m õŠ'£õct…Π±Ù+:ô'ÆmÙ½‰ß}À ¸,bæ9—a‚½P•ã~5648éó bùzcvºœ®^™ ðÊ<¢U9qØ 8w¾£ ÒàåqtÈ}ÑÞ}ýõ—2T¿¼óÇ¿ù›O_}¥ßääçï\n73¸Î?-Óâ“! «i=Úk^¥óñ‹gßöÇÿò¥AÑœWü}· èZöCA5ñAÂvÅŽž LI.«£ÝcAïÁPvIo” |k,c¢äÛé`´0jÅil/2攆A¡šEiQHÇîªÞ “>÷·Ác31[–î lCƒM5‰1—¦øP¾µ<ªsÑÎ}ºÑnÍÀ{ʯœ®N )×;Hâ3}žä>c„©ÌeqØ0êøÃSÙ–ÀO³êU¿dÝt1PtgùTûÞ†š‡K.®]^T5,Å®•åe\hÊHÑØ0§àÚª´ýâPÖÍ‘ØG¶I­Ü5Uí\š×®Ãмå¡Á¿ä%?<=þÛÇÇÇ/ït@iõÿõ¿~øøÕ{ý6À¬â™ðL¥L‘Ÿ<¥3ÙX i­©(× RcgªÖ{¤nÚ¼ºÄޱñ{x»W¿ý:¬Ýðý#e²•·­¾“€œ¸´T޼¢ˆ®m§xb2ösï&ñµ° ¹¿ðFþt@Fßpjgl <Èœ¬›¦€…Ø fràË~·8cÔØ$芅Ÿ7Jó#Å9ê jµ^çƒt¼Ù¾îúƒ†æ)çÚ<ðÒv¯#≠È6$ÈÎG}±m&FslÝWö‰¤¤29#Ò7:àÜÝQé-Ø~QWŠ>X„€ód[7Õh2Ä(k4ý8µ ‡,ðŠj.wÓ ×´s_NNŽ+‡S¿¦ÍAλE¨–0ì$Œ 4©Šqš)5R|ã2<öÁ|ðrí,W—Ì+åOtPõ!ØØ8\Ô0v)<öË(l0úz>nê4ª…sÜ%Éà²n:ô‚9Þ2¬ ñ9Å¢ôq±'XF-T»ÆŠÜ ¶£á|r´Û‹«tEÔcc6WZÛ²=ÛÚY}Ò õéíÛôÀ—ï܇ð—"ÿûø‡?½ñ;~Êœ ÃÓ¦Ë~¤½‹tš «¹Â¾È&nÕL¦ËÚDÓÍq&“ïdãÇVŸ½ù¡Åð¸1íê« ó–Ú+ç¤<*»žîU‡—¿`÷Ä[LƺñeL¬ɤè~(¼:ë‹~7@M÷ÏÉ$ÓŨx/ŽŒÇ ü¼Á[ð–ÁÈ©›”Ÿtƒæ³÷؉µxï,¹ªÅ1É-ûGyêÒÏýœ“…WZ@`‘pè¸ú!Ü'Æ© tžqqË^ÑÍ . “ìB²õálÿ†JUÐÎåìLý‰ ÞÍ•‘+×E>,±¹C;Ô¶ÕQ:«‹[°ÌúCm·ô [ÈNÊôÚ°„ðÄåêd&Aå(`ü”«Ç­<7º†99Ü+Ñ„5ľÿ;~â`V$°#p½ a‘ÇY`+Ç=ŠÓçÆ»=ÔÎTç¼¶v;xÿj\˜"Èv7Ó/h(µýœÔyÎZ²Ó˜µå„oë÷¬ŽåsXß<½‹åÃÛüZ~àæÇ›Ž.9õj¯7ýÜŽòc‰Á¿²àmÕè"÷—œ„A¦ôÝ€z²«­ß0;Àúr^\ÖÎGÿmÇÑ]<=½êWÿŒŽ–°×]¾ûF_äRgâpãvaCËâï‹~^yë3.ù–ôLqMŽ.¦žL’=€"Êfjs($:«{&c4÷}íúØAm^ˆç!àðb3‰{’¸_IdoZ9'dëš¡ò]<ÒùÕlÆ#ÜàÔÒÿŽ™ÙÖê"qKç…vd~%î‚Éì°ÆÁ@CgÑóc†>:Ž6®™ßŒ ב ÑS ¯hý9¥l~cÀd%uëÒ\ñÒ}ªqPn¥°a)š#c” Û} ›¸°äG¥ÀyxÏ\‹3×"páÕ‡,ç¦óâñYÙø6%¹Ù)âX\Y-_Ï/ŠÕ%.¬þ»9"ã0E ëFåO5«Mÿú`ƒšÈ-+fb<(ŽöhUñpÐBëÄ£ghÐ-›Çj|dèF –6Q£ªÐ9€q¸jþàÇ;±Cšö’`¡0õå~S9í‘wgÆHUÛáƒ/Ë&Ñy[90§Ü|ªn>§œñ¡Ï:ÃqÝa?th9¸iõ\yû¥…>˜÷n æ~Þ(ZW ¬5:Á»ï®°\äqý¤ þðîí«þ ½gizÝå»o~ðË]Âÿcæ®…€‹>‹îÇÀT¹LuDM èÅ%9‹z¦U¨Ã ’‚K5v?äÚyåß?&L<®:],å–ÍÜzÇ@ìFŽž<Ö;#«:ŠPÏ®¼tŒÎÃçÌ¥öÌAìN аl^øù¦]²¤Áyè—Üè9û À*!ÎeGM³{^e] Á—Σ²ˆHÈ…üÝ]ÉV>(tä][‚³‰Ü N¿“ªTÌ åbw®ÿ’¹ÑOŒaQuÜ–q>Ž„§¥AÃk‰“\(„£x\¤g¾ñu5ïhGÇ€ŽrÄccr=ââkŽéðÙ~i979å ŸJ´h·ì6-ˆÏ\¢™QµS¿ÍtdFrÉæØ|N×ý-˜t²ÒÆÝ<žßÞý0ày5t¦R›ëL»cf³á×¹AÏÏ`Ãa[Oø ×qrt +m’¥ðÃòø`Gçy¨ör0aDsø ¥Ã´Ö:Ô'†vÔñþæ7¿ã‹e™ÐºÀúÏ dYõÒ¬¶—aµ)L@\/dÖeâ,DÂxmßö´({×1 K–¨èmå~>²?»F¡xµµrP;=Œ*gÛŠI¯FQ4©îÈ7ÇA:‘j¿ŠƒX Æî…AÇçÝ4%{£ë©ÈÒû÷Ñ«œâ°TÊI}~;¾ïä'L^ âWýòÍ‚SV]µÈ.’ÁøùöÈk Àsü7 ⌃ÇE#¥qLõ_¦Î«“ÔÙÉæïkËĦ5&e·<Ñ”¼Ç Å÷Û)¨$FÆÖeðOî´4Æ`͵ èp=8r!¥@—|ÍL©“/ï·rUÔèšs›Ö;09$|11¡<÷”°=€ç>˶=˜\odàò½ög6iåŽâçC¦¾Ó?€\¿~G‚\S”§Ë:yî!XÚÙrÔYmÏË⑱Kv †Æ)Ÿvµ1ûäæ@³:C°`‹ã#ú(Gk m×ç&#z ªŸŠ¶Ÿ®WõAÀÿgÅæÁœv«ð¡1*ŽúÔÆ:ØÇ§6Ëè§ToÞѵÅ4žå‰]ž¬k“ÒÄ5çJ¬¤Sc|¡XM®²] UT©ºMÓÈÞJ{é?ÊáX~«QŸ¯_„^”™¹UQn—Z¶&=`V Ò}ÐZ÷ö­öŽ×]XÞ^wùÕW¿ûÈÎçUDWÖ×x]jõ×{0¥èjX–žB»S)Øë"†Í¯JÔð[rã£êRjk±íð^àÉiT~ ]mçEØè Ÿ.=û(Àã ›DöµÈ k§ëÖ,žÓY+’Eé³W©D÷Y|Þ8èé1bvsbT9_ùGcínNËah‹—\²¸pÓ«˜_§¤•ø'Ýe#«?•IC­=¬Û† ÆC0ƒâèhçBxskK¢ 1ø‘IÇI/9Ûp?³ÿ§Ÿlsc¯…”Ï ar•Š8ìóqŠA$$G8§ "*äž4¢C`ØhS*GÚg0–r¶Ï²Žnɽ‘Pø4¨š¯,W‰‹°6{Á}[h@És>,¯ö-ÔéÆ˜è’—êðÒ€Ž¹ç„•:ð'G/%ÆÚëS j|<îãlNàiY¶˜ª^õÂŽÏ\òð€‚sÊÊo)«áNûÒ{ÔµUuú¡³|¡; bTÛpÊÕÎŒ, ÛiwK$=¾ïÞ½ê?Lÿ_ý;?ý—ÿòáéúîͧþtÜUݬuÉçNš{ÇócM ̤ÈY<4tœ½ˆr‘µû£c·å'­²³] wØû%?^a÷K|ÆŸWÜCrVÇÆ„š¾ÅŒ‡Œþªë4—á†[7P"÷b›EŠd@#{ÑãaE‰^1¨8”"‰’\¼BK_ë,ÖáĦ‚¯©‡_ºËG`:Å.j[uè;ç£`u¸ÒÎOˆŸ$.‰4•n(‰Äc¦Úû­N¼µl½øÎ\Vÿ ¦Òw«6†d+2Ý’Žt¢Êت¼¢E H9ïÈŒ’o<£;µïv˜8†ÑÖqä;Ç(:ÿ—9×sT²ogNþƒII”íåÝÞa( ×ÞÕ70*æèEµÏ22'Çàñaþ£§mYµËͧ×fßGîzaª‚¢nëÐaªHÛ宨L’*ÎU:×#£¿À$T^±« ð•Ç7ã “ìÔîþâ RíQm]n€}°)žy±Sˆ/ý‘†Õœ^ˆ4™I±Å㼞ÄxÐÛvŸÁÀZnŒ×X>¾ÓïxûΫ0›¤ç›ÎÌ>ÿ¼'?gì1LNª=mÐd#­ç X‚ö31gúeyê™@ñ]_蓦ïôûÈÕáq~90ÞhwA×Ãý=ä žY–S>fÆ^Då­ÿý¹t/@ ¢^¯”ðSÍ íËF!•9ÎØæ ibk\-N<ù\ú1!Ö‘¦ð^$Ô—~DáÿÐç®H£©ô³éÖ½’E›â|؃r`ž5ÎŒçêëq?°ÄªÛ?fŠÿÁÇøê •ùK[Gçn†§¡›w_ #ë׸˜o÷øbô,5gâpn÷KІvqÚ‹¸9På )WX‘ªD©Üvõ•©[:2é-Ȇj$¨Í2ß8t¾>¹‰ãAÂåz¶‘Én7¥Ìõ'scŽ.œ>¦l0øŒìË1zd‚`Gå±&;PÛHcÊÈÆ£ª1LœÕÕfC$“¿Õ(ùŒÛ>ĸ¶m›ð]'Ì ©@ÝÄÅ×±-LèÏ2¨hRÀã2nÖŸ²A:ùzVšïß¿ùˇ¿üà—_hãýÿö?êO³1éÖç¥ÿuÅóEŸ™*½“­ê”wê¼$Ú—iÕÅ„%%ËJÎýÃ- („Íö‡Cu_Ýgãr`ÿ8!ûf$»û¾+€?Š?ów+xd,õõgϳñ,üÈdâì‹Qíþ"sW(C³ m¢ÒYö¼âžþc0—20GÆÃí31%;m®ÇÊc÷ ÆÊĆG¸ý-'#ÑØÒY&®7Åø@¯_¬ŒYáy—§Ç~ÈKæ!¦_s|" .îù€Äx¸/ðèÂúZÊ•köÀ/"V9&®¿D¨vyHqõo0–§í àÎÜ~VMšp¸«#S%¯ôuÿ˜£4Í\·|Ùí@ˆp…E-Ù‹§Éí– #7Ÿ0èœÆ£ŠF¼ê¶= :‡lEdæFcÊ!ÃDc0 hƒaçZlÌŒ™€ˆçÜ?åŽt«Œr²YËŽ;ªæØö±!þ4óNlŸËåþÊ`5€³T®ÏØVîµK èp5˜å#S7ét Åàǧ2vo§”c©Ž³ìRšFŠ5‡Õ>©Ol9r+íº³ Ïßôvä¿øøæã—€=l¿ÌÖÇïÿîÛwú¤ãOLÝôªúê?-…ÝUÜÅlì¶1RC²O` 1ãŒB½Ì d~­È´ØxÕßEyKá± à£TçÍ66Ìü¡"ÏfU`òÛ ·N-—õJXÒz€8xÖPˆ/Ùj©L‡¥hþNV¯pûˆ#20¬fÃå8õKè$F\Tq,á3þêýècÇ"É¡o|†û7Òc>Ùáè&k6éü¶üj÷SChR? RÀà—N<›v¢k)Éô s#N~7€ßprÐwPú=ˆ0’tðáç¹qáÿŠbŠS–‹}ÉÑÃüX‡‚¤ÒÅ'ÈN•Û¢Ó¶¨åÖë[Ý®'ŽˆÓJ–µoêÝj?ŒA}O1 Ði0—{K>–š‰ ~Âaöü3ÇšÚfîÜŠŸÒy®Žº¡KRR,Y6®“1(ÇP™ºY>(u؆]†³mŽ¥ ‚¬£÷’usj®±Ö±À@t½¾Õ#Ó®ì§ÏJzcʱ°å’G TK>‚8î’'‡äp6›/Àãr{¶d`^ùŸflØ6^uy÷·ûã§woÿòæ#+ítU—`ny_k>dBp—34Šq’ Ù:Ti€K딣M”ØÍ7ضyUÈÆß‡ika(H>g[¢ gq}t ™ÃÅÆ4KUŸ%cöNÜå¼ô"Ò,qß 7$3VóW7³Ç–qžbSp¥˜otþBr­.1˜n<Œ-?%mŠ „XcÕ¼mì:Â_+uÞ^]?M h ¿ä'Eýƒ›þgóÇÂÀTô}”þ[Ê/øx;]š·»Ð3qM-PbêèˆK ÅsZÀt¬·ø‘eóɸyÛ[z¸0¯"ÁP)¢¿JîgÁ ’ÌFÀs :ü÷0… åÎÿÂ6¬õ ~¼Æ'G´.ùo9ü›w[rO›oHËÍdó¿Þ÷¶˜énrÁge5ê0Þ`Ô>p8Ûƒù”­r¢]ãÙÎÞ1#/µö÷9ä…'L}hC›2r®ET>Cp’Ü9ðCWÉ´Wª/àˆSÓKuáæ^ÂÄÇ„ÝqÕâ~ÛÐI„5ïݯ_ýÞ–ž—†ô®ûöÛß¿û‘·<¯“«+–.¿®¾QuuO„Îí™y²í¨H°taÚv)­÷R>œ{’áÍçølìüAê0†‡€]òPDP©ûqÀÕ'è>8\è†È ¶’ÇöÌ>C“Ÿ·Ëc_¡’yxñÔ,ò‚6Üõp=1ì#Åz×á‚=üáRFðŸåÜ8·þ’çZX |NT :Ú¯ö=çšp!§ŽˆÜŸÆEŸÍž¬s{ð©¤÷·ÿµÐ(tCû>aÕ %¯¤³Qõk6 Å€gJDëÚ²c¢›£ö@±xhà*…•6Tc÷Òêˆîï«‘ÏØVU?1Á F£DÚN?§!ÓaܾVˆ XÒÎb&lçPyœOjÚ: óÓÖÁ¸çÚ¨Ñ2>ˆ†IFÆQc€AcS{Ý\},¿ùÜe»ƒcàvùŒ‹}ÉV L™é¾1£wžÏK¦Ë¸‚+fâØÕ‰ )U1´‡Û±ÆÇêÁX¥“a:¡vû¨ÁŸ…{KÐyzÿðå#€s`~‰í?}õÕ¿¼ùÕ¯ô'绿ú`Ë»SM‰™^h»Ì4A¶nËës¨Av9á!c—!•" þ"6Ä¿œE­¢àèÞ;\à ‰¤Fñ+Ìá0ûì,´á2ßè¤r¹l8²Y.Fw‘ofdŽYix›ÛŸw{7}pÜ(Þ5¢Û™9›Ä3Z§ÆèŽÔ2%Œ|¤ËbR¾‰3=¦?±ÓH{ÉD“.c"»exTê‡8&°MáL-߰לpœO'%ä<>`4Ô~Pý<ßñøìŸï ÌwÖ«å>Â%ÚÄS€ü— <R8[§†çеè¤à?ƒ»ƒJ½aÓäU¾ÇÜø! ¿k.qÐy l•qé“UqÔdygí­5ÍÆ„U;ã’—8ƒGgûÁk×»Œò$ÀN1AšSµ!²:(_[»vfÞϼÑ;±O?>¼ÿå€â/µþ_ÿÃøã§_}­?¤ËÌU÷Š53ÀÊåßç¶Ž‰!Õ9QÖ[›ÐÀ¹Š|$WÕe FŽê_8$³ôÝì]XxðR›çÂÌæ ‡þ»Ë… ¡.Š6ÔøÙç\ñð“œlÇß## ?¾ö÷*'á,Â4<Ô¥¿,d ŸW›®š;åÓ´q<ñOû¢»c*˜ó`!°,¹5¿ø&mºúÜ{ûá G]/Xe¿±ç]sÐ;~¸›qïç%\³1™…¶*T²9­“Ô±·¶—ÇP¿ X@g¶ÈËÏsÒØOðv) ‰3ãÕ ½|–`ζ3ökûÖmù¹'ŒÛn‘õarÓ'úÈÎÎù'AõeÆ#0Óúú#ë0l°=6’Æ9yM\¥ü¬Ó ý’h쇜àÂãˆ5E˜VëbÆ/úñ®î¡¢ý‹OâX‡bSØlytQÌ™øÅ±!;‘:>V!ßË]'¹ýp¸±Ó.ôÅØ¶žÉ§ýðþí‡?þøå§îÃþË”ß>ý˜|Ú³¢—¼“ƒW#mS»=³'z-W¹XÕæ”:†êºÈ¾¤¯ÎÃÍËr94{‘¥k->ãÌ·…9Ö+Kr™¬ülLþbž7#&_bJ'‹7Tc0(šV›uã8ÉÈÞP L/zâ\ñhÉ·ï0càI•t÷ò©q0˜ ÇJlȇìÂc’̘±€®ET®I##À»8ÈM­ã’rTñ[üXÃ+ÿØ,ú¹ãbÂ#nÑw·ê÷lÜŒg+3k®Í‘¤çÀ¸Ò©œøóÅJÞ¸¼þà  4:Æ™<‰i5ý'W2*›À®wBJ$Ý.fÛâjý5}‚¾„ð5U¢±eiŸc\oô´cÔ~ \—׀ͱ0“ë’ÁQ†”\*Q¸•„q£ˆ©»{ÙÄGº†ÞªÑûáÔdöH¼ÁY}D:£L¨U‚N{u‹ÀGÉÕ:04 ‰Žf^é{Dǯñ™ªÝóÆ<(·eoÄÒV—É¥ö¡´<èh;N{íaÅ^®1­Ø/Êðèè;ˆ-Î¥ÂY töÑ&_pXªÕ¢3ÐÉ=4k 8僃&‡i¦õ:¹žœÜ|/ó üê2Àr¨yö*ŽSW^+ ðéÕþÏ0|¿ùVl³º°¼J¥×\uÉÖùzGî U,3¯$Ç¡“;ˉt^ÍÇGN°·œKŽ}f,›*¯ÈòçñÈ+P‡ {"¬ýã?8µ/²åÝþèÎÄ—Íœý¢ÚA!9…È2ºÑ{l*@w•=}›îÐLeëp:u0ÀØ(t]M/AáÃé3ŽÚŽÎä¶èa‡º£¸˜”’GS°óäï¡£ªBõPÎÏ[Ç”ô} iï1GªæÍÕRxè+cÄÞÏw(3 qd—šc†`½;Bh'‚ëI3VÞåah}ÐÏòåêâ<†ÈyK;—Âöð?øyŒ,ŽK‚9¯{™N@¸üo8‘!\1@§)N2˜@ÂÓ+[ð%¡}’""¿TðÛ¢ºb;×–·q“ÛÜm’ë?i¬’ÏÌʳÆy20fBsåë3!ìvú ³âŒÜî”`å…Ô»ßÅGF_£öµ-rR¹ø#XaS¨y+b<íVà_*ÄØ5ŸrÝœ›dƨúú\b<–Ã5eÝ‹mõ½cØ¿e¦1 <<=¾úÏÿé=óõÕ—Ço¿Õ—§°²:ªê…÷Só\xª4€5 UFí¦€£ïò냣 ‹¯ >*ù1:ø²ñ@Ü‹CÊ,þ^å3Ñ‘½Èë‡7ÉÞð‹ xR&4朶*¿c6“+)ý1€ yp*z!uŠ_6¿M€-T>“Èäzh­[•%ygI;$3L¶yƒîF—!¡§Y\IzQɏ޾‘VJ÷¯‰EÞ¿1/ƒ­h¢ÄÏ¿®×ƒKÛšJLÂK `~ë<Öœ=Χ"mæÇVîàš–ÎèÈÃPH¥8Œ“«9EÅ9-;p ÑR#Zµ‘/^ØÈ]õ¹°‡ÚÞæˆ{3a.,)x Sù/Ä%Sœ]#ÐtnjêñFƒh½p¼ì35:Û Â¥:§ Xµ‹|·´_òù|ë?Œ¡•Ò1^2‚¨PÛ/øÔd®­4 s ²2¹²½«kÁqñÙàȾm„=TëþôÀ›9çÕ¤€ É}S²¿_6ÕC´6µ1qûxLúÃçÖ+x7?dòÎy’²uè§T7ت3.‘ÝEµ=xƒ8'•Ð?aN¡ö˜&Â~Ʊ'ÏEer¤< Íò!ùä‹û)LÿbÈ:ùwÈV3³vBœ}Å@îN(Hòä?NK¬Ã×r‹áÝ&æaF6.Ó C2Ÿqqæý³…’»¿O‚‰¼(‡™¦çÄè![gŒv•º•&´?Wb[ˆÕ’umV¶R]ãöc"xH°‹Çî:Ñ.më*<®K ƒŠÓ´82<Ü2ˆ=pu[s{d>›òà]C/]Õä §Ô±i¬³ÌɇNmÛçv%°ŠqŠ©­êÒ—‘•Ãøž%Ûg§a+|¦a¢Û¿\*WÑ•‡—¤ˆƒº&×>­™Z´ký€/—ù ¿ûþª“n]}îÌ Ù ñ¼ ¼×éŽ<'¤'ަ^'MñËd® Ò>__€è|düW)ÐE㩾r,Gò†#ÞþŒUíþ" Ú/ú²?b^û7†£?ˆ éP©ÌBä‚âÙÔ×8uÌ4¼?ÿ>õL+{¸’Âæž¸ṼGó ‡É{9çÁ-vYk>APq4fåå˜Fÿà»Z›ëÄöõ‘Ñý@59gÜE*]~{áÑ‹¿À!.}€ï­”•‹ôùLsij(³#$éLº‘s¸å‡kãlïI;7á/,RüªÛ®ÄmìPs]ÜCÀPª² –fàW9÷YLåÌÊ3:ÅG­è« &÷Íi7dEf ØY¡ÒŸíƒ=˜p2ìÈ}Ï~à`Í#€ãƒŸïíÓ™vå³]Âê†#".ð•›F¡qµõÍÃÛ/ït(ñµÞøŸ´³ºæòf¤cºüRæ&e*T»{¢Õ&Ó~±ÙÓҨݭzœTerŸ·c<©›=èö+ÓÈÌT¼»€#§H6¤d£Z ïÛòì/ ò†E2 ±šµ¿¹Nëu÷ÁSŒL.~(W;!ˆ TP©éñ•8Ú4ˆ?9¥4¶ÛÖ>ØçÓµZä8rí’ó–Ú‹Šj¾+A¡+/—!R¾´|èäýÄPN»ÃÁ˜ÞBÆŽ9<Òy\Õžž3úÐ2;‚Gn³y{œWNÆ+2ò Vy!oˆ[•Ã[@bCd»8V:’“PÒÿ%Óõ-˜gàÇ$ªe‚Üm#»Ê8—wùÝ\<æË˜M¸¹VÝMyÉ4à.Ç8d?ŒK¶£ªÊ´}O>¶×Gv;LŽC£lŒzHÔ0WEÉˬ£‚e%kЦüܸbe¢å¿9ðtذúœø;.Ê\ ü‡C%ØiOÕ¹¿£ BgûÇÑóõ´'‘mõy$ŸX_r)Dï‰Çwïþßx¼îó,G¯»“Oßÿ»7_««ZùúmfO,<Ÿ´CæÜ+˜jð?Õ ËÝÜ%9À &LSËËrUê}è& Ì»¸ûˆ§ºíµ’ÿKÞå!qrD+AÁŸ¤Æ¥š.Ž­)³ÇPrsâZt\Ç%~œ¯?Í6:'‘íQF"3JåhBx¢sjHeyàšcC»ü·¬VŠ|ŸùŒ)1·Ý1±Ï’©Ü?C£Æ‡–OSwL!BúX7c$›cagŒ†c\䨓;s[÷d0v`—I2àÒ‡c¨’G¾ÄܸëÚààôM\_O”*ÛnO|B!¼yi«Ø…ãþ³u î¦\ìvø•‘óô¾û{t¯½°½ú¢IúÃã×_iÁÕ"ÍÍ£3Øi¸V“‹¿ä™ ž,#ïE”|§¼<‚Ñù¾ðöd[ˆ«Oì¤7ËÝÐ7š¿$(ßþMöL^å»ÒÛ®Ô v:T^ò¹T·ÿN=X•ú>K^¬×€°¶¸¨‘Ÿã—t™Ybš;ßp=‰øÇææz˜On‹JmçJœÉšìO;èä¸õ›·ÕH‚%r+‘-1²±·[U§€Mú\s“Ef JÞ `žMfzH²…Ïüõ¯ó‡þºÿ HǪ¼ð™-õ0&©§çƒš à8u\è™{Ö+ƒŽ‰ê£yŽRÀgNg¡®/ ˜on£¦ »Â›£•úl’è·Íh·¹×3öò,ŒóÈãÅBLßÍÎI‡ÛèÆ¶ñØÑ³Ï\#@væJ½\ÆlãÙ——ÑÒ ô¢ÊgAPìþq}._°hvlÏ*‡Ï8nåíù× o/@ 2&嘫b:®w¸À£^ÂâpÑG²t;Šåç`ð‹ñQ¹YÔi¨ì‰¹…þ2ÂP$ôÒÍ­;ÑñÀ C͇·ïÞ|üðáËïè þÒë§ÿýùWÄÿɳovÚ~Qæë¯“þ³® Ñ?¥=ù˜,XpÅq³ž2“ªÖ @Ö'“.Ò‰ª=5»C_9¡3¯ôô3¾ àox A²” ‹*òû°«ïIïò‘èxL$6ª‰ªjmþ¨€Ôz'#ÏCöƈÖ[ï°y3$Î$0¯ŒuYX¸£ù`l;ž§Ô¶)œ´ùÙ}&ÌX² £Ã¥‡š^ RÍ—S¨q(QFÖšöWuüuUoüQýèß}àýÊ>Â)7Ë‘Îmõ·QP·MM9¢¥m'‹’PÜ;!— "¿±òÌFs»—Ëê9}fmþ„gª•§c¬èü ùyß Á¯‡»b³{K /œT¨rоb¶ÅÐÛ Îø ÕØ÷õõµDK`Tƪ±®Ýáìæ)«}úX(ÇQ«©rø—d•LbÆ•ãDÎõØc4¨Mfšôwq ޲Ö|­ŒÙ^ˆ½6ÉèêM”sN$Hr ?š«Oõg±ï•TÜNlÛN5IUåÚùÈØ¼Nce¥N><¼}ÔÚøúÿãµÆk.ïþîï~xóîíŸXù£,¾à:q›÷³*¿•¥‰ÓÅrÇL¦xIxQ~¾èëÃÊ “/ï»kòI6nø>‡Ýbc¾7Eõñs Ö—ÕæŸù÷£°üï X‚άð«òÊÔ~ªÓØ-Óf%TMe^©¸É‘vd÷•œ±¯@IDATdŲ¯šþc9Ò!ë°š—¶´ù‡!#2Xäñr5ËË"ŠâReX£2/àƒ˜4t½Šn-8Mò.B:èÏüâM>¸!¬ ýó;¤I\À½i£;ä£ Xeú_·áïÂÏGuõDª†°{«U’g£êQàM {Ö-môSûjH(„|0:æH Ô ÃY¼`FÆ>q’y__0Á…©>á&óLœá´}7‡{<ãØ,’’i¨§QÙÈC—Hq(¦>Æ–CÆØÓŸ`Æyû Žd8¼³e\Ã3€â©M8þ'*Û}õÕü:¤3Œ‰à^é<‡~å?¯hw³¨'BO&ïF‡l¹ÊÙ:–†,²rëÓšS>ã`çòY¶_nZp|æÏ+}ÚímÞ `C`?r¿U³ š%…Lø¼E¯ÖŒŽÇ-Ú8ðÞü„ãF×ÒÚ™•;z^-«uü”`ýO.Ú)ƒvR B¨u”ÏxÉÿŒCÛÔMñÔÑ>ýüq’ˆ×/à#ú!‡Æt½ ±.£X4g™ÜÑ©uò`\¬ö³Åo°¤öÇoJǦuõÌ=P½Œ+·¥ýˆ„‚ƒÅ8[<Lt×r,Þcøë8ŽL&|š×…ßP[—Ú¿Ä©±0©ô³ç¹ÍÍgþéNú;x{®¹)"/]…¥ 2öÝŸŒÐ–—÷飶ſ&©×*T×1ò½Ð‹uò¼¡ÌYAü`…pž8¨ÍÝc¡SåàÒ·/§óšC6q‡wÑ·ÑÜCkM»¿ÍYl¼pÉj¬öaC÷ððø§Ç_?}ù`Æå_ýôÛ?þð¤¿@GÖg Ó+.¸ßŠIÈbÉ|ã±K'ßEÜ7 ³(cR iߥë Uyh]±Ô\0eŠ ý‘Áj—3ˆœ8òä8uÄï8~’ðCÁG-ÞÞøGç'Ѯݑ'Êì¶}Õ{ß½y³6-üš M8&dç9z8òp·#Úײ¾¨´ÔfŸ à ñ1ÙÈín)mVÒò^úÔ¾‰V+þ.FùékûK¯ŽØ§Ž!ÁdÎ\B¸–º‘…‹8ЬߌJMÉ!º;zܧûͱAã*6v–Îò¡ï0H\ÎjNƒÜ]®5–JÃ%ñ®7BJôÛ†"9Ÿ6˘՗¿&“ø OÏ,;NŽíaî3@ª·:Ük­UÝhÆÙ²çû&çCa2P‰‡ç3k°lLú3³eèLUÔ} qw™~td" ÒcÅ%.Û£­kî j™–Ä…ÁäkAœÆp\sãáIaiÂÅ÷8.j£ãþ°~pT‰#®Ç‡?þùÍW_ޱùE7ÿçÿãÿüã£þ$0•‹ì‹ï >‡IÁE/gñ«bÍZáhû-r™;í NCçÔi[åÓÞ¨v«V<ê•v0œó/öD<#„!>ô¨,è‘®Ï×W{cÒ'~1Pt`Br¹¨ù·í/x}úŽB¼N*ßQ,xþøaí>rb\EÆMGqÅÛÚ•x[Üß%Ì¥HçϬٽ”äÝ Ýy 4_4i4Åág Êš_”RÛ÷ŒøžHÁR¶oºNŒŸpò< ÞœàÕ_4}u‰ÀXa÷CF· *ôŒªžÝT&=‰¼½~GôǃöÙd·qŒÛxoì¨G!ÉŠô‘v7Ŷ®9±äã¯èУ®žÉ­’Ì—býÜ›"ßÑÈ“§½cß³X1Ž9q·ö«l”uf34¹Æ¢³ ‰T qhŸ¼µUŽúÉyû„ôMq®$;×åé1:|Ž1Kñi\tm׋þïvÅÜër^ò¶re4\éoðÛë”Ónd¤—|vÿmUB½^x’·]o¾çšDwRœuáß~ÐÚ÷å€A{%åÓ›o¾ÑßÐtè+.Ï ¦&;¥²Ú™ûçD‘©T˜Ç¬Áœ8°v¯läØƒ G¤øÇ'·ßɉ5ÿÒ‚³š'[Nä°¥/oúÞ}ÀjHÜ å‘ÎxŒøˆÀ›¾ìlÒyP0œï²¹9e}é;1æî#$âõ¢"Ño¿Çvá„÷ÏÈÃ)??¨é6®´]håÈÚÚ,+éüNqøO\àq§eׯ@l³ëúˆÄ¿sAŽù>@#hLábPèï”GT¤ #:þï/Hç§…3A0õ§ÏD0J™;®Öˆ³†Zÿ­¹zcmv+iبaU¹ý‡©¼ž= Ÿ‘·Øpô·Ò £Ü‰èöw†Ã¦ÎM3,¸øMz[Eã3†±âŒlàxË6T“Oå03ªÁ­¼'6, aÍa;†#NÄ«®1¨³,#Ðñ_£XŒ|Öà€™¼h¦+ÉRе¾!ËGº¨o㪞’GKÚkñY¹ TŽÎŸú˜è±³=£l¯k ZâcOc§3U?Õh¬Ä^(âº^ãh®>=ýþsøSÀ KõgQ>}úøáñ ß6ÛÝÍœÐäÌî/S4”zòä<ý9úà·ÖsŠ_o¦po][x$* »¾-³€#®6u¥Ø±nÍîîÑmïɾ[Ì;DÓ+ÉÙÌxg½ ƒÑMNm¾¿w–Â–Ž»Š;‘UŽ’§ ËŒÕ%7½€ìW”‡Ÿ?Kñ©¾rHb³Ð§ó´ýV;‰Êè´TïÅ6 üx5žŠWþœRx•Ýaèâòq R0~Ðp×ù€ :Î'§#.ñ{àíM‰L!ú΀öž-ô˜<ü«‡\ý5ºšÖ÷;¬Ði&ØËÛöÁ4Ä3'®[ueÉ¢ *ÎÝb‚Û³³~¹vû¾¹0:p‘fTaüª½°ñ±Ùm0®T¾ç%‰Kî®It€7oŸE0zÁr]$ûV¨ŒAŹbÛÔ1,âˆÚg©VŸÑ{nV\ÇÙ2.' ÉØl¿Þ7èÊqõʵqØg®æpÚVúÍp×ëÛ8ãò3Õæ`ßãžóÓq €Õ/µ¬C‘96,ÒeŽÊ—ÕÏ»ÇýÇã y¥uöºWÚ¹K·ô­ÎŸ4#zÑ{£{ÞhFt’Ðò÷äü£c‡L>|ó±Àþ1:âx#•ý˜J¨—ÜÍãÔmk´Îeù\™2—³H¦l)ù|áÚ›VÙZ‡á<Ó¯ÊiøEë,òµxl¦3 .ãåã­nkÍ…´Fg^ so&CoèáDig%:{ãKþ;riQùZE#)cßë7Üñ¼Ff¼bàZ§›È'˜0ù¾õn»À„ò+;{ÃG3ÑÚAòtúŒÑÁMŸçág-Pðâ4oeò ä:î¯.káqOÇ,ÑÉŽE¹sm:§ðV\ŪƸe³ dRð…@ãwxwկÉpu§W3R{@ÂmOÇã1ñ7ð®ãÉd*×3>‹á 6²s­®:–v»@õåz•ņÊq¤Ä!mËɇ\1¹$5ÏþŽmªp. ¯Cç\Mq^æ¡ìH8‡´ÎŽ—Ö#’à);ÖUNÜD(6ˆëùÎÛœ2–ñ³[‰ÙÀž7ø^ÂiŠ›ˆ[U“j±éžÕ›tŸÅÛÿt¼Kí1¯³ùøý÷úÕŽù¡®=‡Iå¹àÉà–.þžÔl6ƒWÃ˾û&äso¿â“>?‚W)\"W»#œ›Lä…½ØdŠ-šLøä¾Aئ/ ‰åjÛº´‚ؾȼhõ ×Ù(èS?Û?ÿèP|áØPxµMDö}þ8ÐúÅ@€U¼Xêó8³oÝ” ÚþÍî§v”Íj4é/‘(Y¨cÝ£{¾R0¬È­3¿ìSžY¶‘.Ö%(lÉæòN€ßâ×cÄìâŒÇÃGÉ Npyê` í;ÄYÐÁµÓè;Y´Q¤0‡N #S©Ù˳,|ð—ë…Ôï\ ¬ÈùÈbRX‡¨†»<ºX6y]‘…A›Ë*èV?hSV=ƒ¸ú)¹6pÓñ>1›²3âÉ ™kÙÚÁ,FÙo \ŸÖ÷8/ËrÖ#N÷¯²QœÈŽ£ÓŠ·(°˜ÉõÄåã¬A™ãÓïY¿'Rq±n²sl2/ñÉ?/<[ÎCyút͉{%óí›kwÍ©÷D=cQœÇ‡/ïtH^Kýô›oõSº¸ºò|ÎÌ}ÏÄñ?©sã«AÛÞ5 g¾X%³Kê Qð®žû_¾<˜/n&»:®IìÔ-f36Ro‡ ·]¾ó°R]¶€úÁ;Vã“ix㻑}€ºíøÓ—¼KàwÜÛaÖxúÝqî;KŒæ¶w;éH‘ñ¢ÁC Ñߨq{¨9ÑT¼Ö£ÙÖQ%ƹ† ’†~bSV²j. E‘G'(8…úy&~Р¹fâÍêãϰÓ_Hà‚V:³Ð6¹j»MXì. 7c‚qjM˜EÑÍŽ«}–Iµ­Á§s³>\6cN y޼sÛºúÖÅý«ÒQ"ÄÚ=°z¼† ú÷ÆH›ÔHëúWÆAœØ)<ì˜ÎC΄6ž\åˆ;>Ûuz_ARê3=™¼ì'×a»cº•f±MÉÄgç8q?V™«vK7Õ4lkh2WŠ(ñ)ƒ.SZ•6 ÌÎãjO4°AEN$ÞÁ“¼TE-…ûV->Ùê-Y÷‘þð—€ É+:ÿý¿09½ve\ÝÓ”Èk˜.Æªî —‰­õ˜Ù3›¤ÿÐŽuxæÈæy>ÔçÒ0¹ËKdXZÎvý`ãUll°´….íb»5”/õf¥uö«¹ãŸvíBæ¿)°œ×êÒèRkôIT…£y¾"w{xÈ-E­ÅÏêóy}ígØœsýF²~"A±Œïv’y#Mè<ÖèW&šK#Ö{£/‚:¤<¬ùU;/—E懙‡«ïÀ„hâî¾ôYèö•ö«pü[CèKŸ$(Y«LL{v¬êbï°wžÖJr, íõ­›J’ö0$n©+gÒ[µ¡`>×^ýÊ­Šz"[ghOÌÙ®µõc<1¥±NÂEÞ¢ýëwØ\¶šWXVƲÄéïuœÏ+·n¤á©µctÊMíÔ¥/Ö;G‘­s-’ëÍg¹®Æ8ms5HÏã‚{΂¶úç>«¿Ë1cuªÛ¤»¼(xxúò‘}Eç§ï¾ùgþ"àG­”¼àê¯ÁÍô;fV4¦’‹Ô~N tW¿câÈÆjÌÌ&$p{Ð`±¤Á ¨µc\Uòð·Ù¥kVö½a&¤X0è8âÚoð³˜"5—=Ñ“eyχ6ƒŸÚµ …®_ TóVÊréA0æIrlÊy\r]„òƶúSŽôtõw"†‰ó&HªÚPb4²St¸0Ï$wZ¬ÑÙ»§< š}Éÿˆa”óF©|dôÃ'iÌù㞇¤,üÃ}'wrãr¯Hk‚öË‹ÒìËËÇ£Þ>³<’ÚwòÉgº:™TÈîï&;B `WA•äð™frÝz·€;÷­·U2uƒ[íú,]l4`;@½â,Àp2 Nšƒð#uÄ1­ä¥ZÉ çÏÆ%ÿºR»]TG»vj.Ͱ<U*ñ\q£\±VªÒ”!u¥q8ü¶%>È9þÛÅ–us¡ÁŸóЕä×:Qãk€nëÆ£{÷ôÙ¼ðvÆéÕWOß~û;]XÝ õc{ÞçÊóšnfOœÈœkÉ:2¿[?¯„#ãÆ[åÙ둈ßþâ˜è™•‚0uÝ\'XT±³D9 ñ >äqO]ðøtò‡@Ê’2ïí?oûÛV¯$ù8€w><䮜Q‚E£'ˆ•D÷‡N1ý%9{©í§¨‰,âæ˜w:&3¹ùm:xæ µó 6Âúy'ZžîÁݳcøúîȳ¸ŸVÔô‡Ä›vzÈ÷2”à¤ÃQýâ¹ðã•äïh¼D—Ý—r534¨%t–JSúS 'òµŠI§É<Ñ f\Uû`êtÕ›€yEû 8¹ÇI°Ýä2ª2ççkÆ$¤9G^aÄ×0Öu ÇǼÆgò \’ÊÓÏ-XQ£îäD²13oq,^8fìo:o£‰²¬ úÒùçWý-{ñn;-J¯/íŒûïà Z6p»,ÄV9b¯bú“Èš‘ÝÙÄ}Ë×œÊØ>mìö½Ç<¯ýä¶\k†Åßuyzú]˜^ÿy­¯½«ó÷¿ÿ¤Ÿ/¬ñ£|y¡¥)¤+Ïï¥ñô›š‰Å„8Æ :&“)¿'Úb˜]þLœ8ZüKVF[PO\\\‰¾*êsr#[§Ójƒ±2Xš%`Ãm(7\Ì!ÓFÆb–¨èla˜wYèè£7êɺ“ ¤¹ì‰¤Ëãëè Eç{±O¤³M>'Õ¥ ÍØ‰‡­ïb0ÿeô–&WÙr×ݘ¹Û<ヮ±Ý_‡ž>Øo˜8QáQ4yl9\ÒÔÍ=u†!oŸXãYdêôt[âSÏæ ÝîÉ•åÌ5È`3’õj½¹îó3–FKÿ¡‚oobsæA†»€Ï¿°bI¶¼Ñ[wõÙÁv|wnámON<ÑzÝ‹3œæèÌ“#íÜâPãÓû÷úÂøçQ²Î|}ýáÿþOÿúð7ßi#Òê«ÿ,ò¬Ã\p¿ÓÊåù ùÂT¢óú¾š¤î7SÁ wúy:Šá_¤™·®}s^æ¥Ð£P×€½IÄTÆÇÃ!•ˆ$è?9Ò_rjÿˆ2§ÈžEytªóý†¼â7N'øºñ[7./âèð¦:cEXG÷ ûÿ¨3~õ“üÝÆѲå²Vzä¦&'þ‘nUG‹Ì¿àse!¹`x´jæ„ôÞÁdª€J‘nRl÷¬Ï;{N ,mÃëdQxÌ•1„dfnY!a¼=‚+)\Ft¿ðÜEF»èd(èó®róɸhDÌ—Ç®;vtÔ½fð{A¤æ8Ÿ[¿ 6*äp$~æ†p‚;²+i"#™bêD•xÈ™« ƒv|§ "cÕÜé±óŠ0îwËÁ~Ý5üÄà2Ó©l¼r&“ë‡ÁGí*qi&Bòòyì'z³ÆÄñã3¬ÒlDF’ôÂ^L¢m ú¼[…GôÅ4ÖN!vs ×':°ÕàåH¾QÿÔɸÐÑŸ¢wOÌïAÜVÃm–Ã_’€ùýø¤"úl>èzæqxͧÇ?üáLJ_½ÿøæß´u{2¤·läùU¯ºøž¹‘fª”‰Æ¤;ÜâcPô•A|å‘•Ýïø3vd³Á:Ϧ(j›ÐEÞºøl{2sLsÄÇ\æÙ²9VÜ“'ø€I&vvZ¼²çö"õû÷Ø|×ïJ -¬»(¬¹F`’±˜Y‚o`ä º†€/YÌ«Qï°òïÇÉbj‚4W|á¥ÄµRt»ï’Çä·¾íPž`M ±p†&ˆ÷…®å`l@¹Ñ×8çÖ·IÿI$ä„0“À>ëí)ü)Â;VÕm è#á£ÌXÓW‚watð×1)gö]š«[ˆ½Ã…²€H;Aç1×[h§2®Ä EpäèJMíùÒ‡ìy£ \»}êhvƒ}*fÓ$+ŸD&åb\>¶‡xÑ{b5o‡p§–ÝHްÇFÐf^V=ëÓŸÅ#Ýâ,aoó`êë ˜’AÆMº¨§aS®Ã^,ƒj±G[–Z*ãUÆ­ ëfF¦l rt;j7ù¼^˜ä¿Ôe|x÷öÍŸøáG¢|å¾®½Ú>?þ»÷ÃÃÛ§?|ú·ãÂk"ìÉ£W(òJì†L¤==cc>±Xà›ýZ µhcÊ.9Å-¼ŒÚ¯ì„¼.ÛǮݥN6pKXtáp^rÊ“{c/?š´arÞBí.ýÈ ü›6¥û¯PÁa综Ýß·üû–8ÛNüMì< ”TIœ±¼Ã91‡Ê‰]Ãeç*ý£ŒnÕVî“b]PÁ—çÊCºi»†R×Óµª•Âf¾é¦ÏÆêDܶã©^¡Ã§:?!À» >wåòiœæLˆ)ðú!„ñBOâµcœvUíª/ˆì½ŽC7ש’ +ì^ˆ8€LœÄ˜H®t"/@«b.tä¯4º¬G×eshSndZ Sj¹Ì<årryøŒ±šÔø„íä,Æ„ ÚZÆôòP´©ž=1”oǨf-Ö::óÐN†@âö¢ã)váhX¥F#—^ÊÎ4.O\FV•Vt´+ólyõ {p¤R<赨³¦M©ÇUr¬¨†)ww…ÎË«3¾þúËÀŒÝ«©ÞóÍï¿úãO¬TlÔª:Á²¿2va=ãàE)¥ €QÌϤp vÓ˜×WžTç: ¿F÷£öæ(YÁﯬïHÇ“ÎÃVN»¤–IkR[ë.oðCP»Î8RTÌG‘–Îáï¦Aè¶Çìþ´OÄÊæ©m„õè9ì’ýÑ9yL¥ó¸Úß].9ÉÎí}ï Ý-;íÞçúoy ªQ;> ä{@Q½Tºé“2.=žuá4=5ýÄ@Vñf~ŽqÉ}HÌ)¢ÇVõ¸ª5ÅsBN÷œÕ¡`yeÎ3¼„x©Dß$Q^ŒÈsX¥“ÅC‡'·*0ײ5Yª7f(ÜFG]Nô´[Š‹»x[Ý ÷öéƒ-#/¸ÌWÒÁâÁ^6j·¸6‡K9v~WÃo'ñ»bçª:¢1^@âìë=~;£!ٜ֜[7-WÍõŒXŸ¾þ©¼ý¤A©RL¤¥V®¨áÅúÄììÏ>½èvŒ= a‘ÿ'«Þ‹ûÃÛ·o¿|ðò@þrµÿúÛßþðéWù\p¾è›mfäZè±¹›ç´{ÈöÉôâìùV ðKÊÉð² úmW ³øve¬höߤêLl»¿4Y‡3Õ©iºoI-ÊñÃ¥qíErW]Çô©¸Ô• T¯rUÑò RŸy»šw9üN³äöw}ûŸñ€†$uÐdSƒ.œRLYß-¨B‘¶Ž¨=Èä^vî±€ ȉ‹¿ó©Zª5~ÏI¢[ç×ç•?ßCf¾Æuü¨Aë÷ 1@}S`ûôc óŽýÚøÉߘ¹Ø©šèä Ê-«ç]{ñ[o‚=7o¥4æ©#-Ó(ÚÄ» ùY¹‘/¨VvWÿ;cdz›#ÖͽáÜ–KŒE!ûÓÃþôæÍ—w.ô „ÿÿð§‡_­_¤×Wz"æš3<´j±p±Ð{±w»`ÏÆ½&Y#KI§^&Rx³Èwú5V7Güy91ÕΧ#Hî‹CrÂ×ë+¹©Ý²Úl³€c[ú¯·1ÐǦsþKÓÌjDn¡]9ž•‘²¼t¤0dðTÊ‹µ÷3Õ»!}©•û÷y¥Ò?8„èVðmYdpwÜc$Ö‘Q=œWû.ºVÍAJÛ$[ʼnà§ÃÙ.ÉèšuÚ&py_ž> ”€š 9%¯ü…—ºsŒÖ1e„³‡½=XI™qï;±]Ѥò¨9wDì>˜Ó–ÕžölŽÃqäí?¶Õ‘G0ãpá¹^Så?s/þ¥úúQå}Dð€)IL*¦i;q¬Z§ã2=¿Žmçê™oɺÊŠÜ j"Òz)ê³jJíƒÈ˜ÈAÛ×ËfÉW†±Ÿ4'€{èéñÇßÿêW_þ@ðu¿ùî÷]Nøò\Ï/µYMgbäF˜Wj3üH%óE,Ǫ Yü6ÑÖá…<¿¢Ë‚1¼YìEÚEÛ‹º öÇõG"³I²k6v9 <ùÌ‚<)üÐ1Øì¬[`¬#¸ÂJcòWBáÌÄŽ4¡·W<½Q©ãç±tüø&x^ý—7Q¸5G³6>6ÿOó lþB ñbʃ}8ÀžÚŒ-¹´p}zÇó{äÀƒØ*´{¨Î\¿R÷{ø,»Œ\ŠUtTç¹èI€ŽlDrìó0>&uÂñÇÂ÷ÚnÜ¡IÎíäà•Õ„à" È¸Ý ¡XåBn#¸ÒÉã ‡P׃½R•‡«g3>:¡ÛHwûUWßÀ+Õ§òõD KŸ6ÔÆ2L£ Ï9‚q´H*ÓÚ=ʳå"ki}¥ỔµŠHULF Œ#:±% «sQ'7Þ:åt~y@%û¾V\b['T¯ï\,ÇðøÙÓÎ Ks|&`öÁ?y¨žFóH;Ç>—๦©±ŸÅi8ÈX Pmõã»ÿôOÿ¤7>òÙü" .ç§§7¿ïëz>{÷/eA¯ƒ5ŠÛb¿ŽèŒÀ·´ûJÍ@)»¸G&Uõ>oF¾˜Gém^wz”<ˆðE:/ä’ÙÏÙý‹…êüYfãïŽÓ‰ håºôÕ/úÐa+)¹õ±sì(@¬Ç6í¶xËŸ1¬ÞÜ`Ê;+åÈŠâ"}ž®ð™Íß?ì0~›»ß¥ðËÉ´Œåð o(¬ä”¼r^±Ý˜W ¨íÕƒª‡Ç­y æfÔ*5ÓO®ãù@@~(s&ÊÇDuJÜþpÞG?MÅž>ÌÁA=G¨BÌévd'šŸ.ð¡¢#â4Ê3ŽÖÛÍ'Û£^ç^4_;Ѻ†xà?Ø=8øÒ#Ù‡Ù×åÄt2Kg|I†Û>Ö¡8˺G™uÕ “ÀöVMÏCâù2íÉÆvcA |—É£L©Ñtîgæó/xÎ;§H‘Û>ã$÷hÚ¢£-ºÞä4Ã!Uò2Fîsåc¶ò°CÐë0dáΙiB®Qq ˜r»m’ÆaÿŽDºCîœièŠMØ«tÕÝmÈM¨uøNÞ‡·ŸÍï`¼>«€ùéÃïßy"ømf]y¦…m¯&¿oW)Øwº 1H¼|Þ‹­œôß‹­çTäËÔ>lȲª¹¨Ù¤ìή¨€ùn€béã&s ™›ÏÔÁ{«AûA’§*ãapŒ¯º à–œCˆ½}m6“@ÇA"rÎôUܸ̞`.{Â+ÚÄÔosÐamvÙÀä,™w6À´$Éè±cˆƒÁy9ë l3öÞaü]Ôs¹“3¸ë÷¬ñǾ^`t$cnøÔÒ±oÓ¥®§´—qœ¼ñ ç8Ü' ÓŸ| ™1>þ2Ïlõ@¤Y^LãøB‰úË"0æÑ¢P›¾¸GBªPq:’hÜgrgç—0Ð5ÖÄq°CÔ8¸A®Â¸˜f"ø×]£\{DNàñEêÍHkÝq7Lpé„ O“O^™¾13Ñ7În7ƒð‚(6ìû†r㎋O¨çÔЦ43.ú3.¶È“P[WG¬ã~ÜœM‘£0<vÎù[r)[óÊ-5Lw;—ñÔ·‡¬Tž›Ž‚m—Ó«í"êX¯ê6Cµ %ˆîËÏæ €ô¿·þuT^©ôøýoÿÉßJãfáeÎÌΙ 4¯Ÿ±mœ]tÊ"©KGü{Û‹N³xÖ/ÝoЧ»Ê¿ÕM£îPÜeY…s%z×A+Œ:dÑïWÈ“#7uZ© ¥jÚ|‡— Á>}· fÃò¶·›9qÓg‘œ±Â—#Ôfr{§Ø9@ôÁÉ7?c0Þ}UÌ娳0œ[†@8×˹†ô¤šfVÇgu?(áòN@~Ê ±=&“8¿ ÈÝ3§NÓ±Év‘.9僻o€Öà ¥4ŒÔçC§ç ÐÁä^;r3禄8š‘F(” bH:@%5‚ÑñS®ÿJbÁ`Ù¥œ·YBÀŒKxíè¸ !C²Èyó¦Á@TáE°Lû`§eåðZ VsPg²-1Ô;—Ý<¡áåzªšîa²b÷-rr°uň4xç­û"¹éZ‹=‰Y~+¤÷4ىÛõÈôÍãO2räÕÈCtsiô8ÒO «¨ _rCíH:ÅŠflZ£bPó|Õ”/’˘;vS{Èà‘ùV¸LíÓR;+w½Ú:¬å‹<6äU¤c»ý^6LŠ@®û¤½YcÊ„_s`Š¿¿RlòØ‘?•k‡Ë„ZÂ!;.:Ì‘4gr Øç9õ· «¤PE5Žï¦3?bcí‚Òá®;d79­ÆòšpcTeˆÏÊM‚ÇgúËu ’¼'÷8¸=!í5©Ùêárç¾)ˆÛ–oãá1½Û8 ‹ƒ¡}ÊC³+SµmÅM®½¼CŒKÇcTÖ=06ÊÆÄ/Z…~ûö³ú@×öÿU×ßë€wz›G»k*‹ßžmh²Ì-a{@¼NRmbVJo' •[Ñ?³¯Q÷F†Rxûªí·h%{S–ÌÚíC0n|ì65/èÈÇ„Óý2êfƒ÷Œ[ Ÿ#¯ —2j›/C…ÆÆxÐÌètŒâ+géëâÛô/õd–1ãHÀ}Sý$¿~̽s—/@ô}ú¿ù­S+Ř\Ó5n¶ì Ûƒd·µÙI,2×$ý;( èµBïµx`è]Z?VŸÉ£oã—ªŽs¨#ÉiH¢èØ)œ!²Œ;Û}Xx ãÇ™ÿ»¡‘ðœ£;¯vø’Bûî9#l½À8”®Çi««í$ÑÙáÓ¶´#K0`ü/º‘‡£È]LVqÐ> °Å!¡n… ßtƒ@î>7ðð %2sÕˆæ1?äqy^ ̽ÑéÞ•çoljáŠ>¼ü$Ãݲ®gªëSŽÃtu> Gœ>dÔŒ\Nt†’ÇáSìµîL=3Žî‡Åñþý‡«ïë–.kÃëîªÂï¾óŸöï@×EçæÌ¦ª‚L'A&Åž£L¶©lLr’c&Lƾ*e0ýOfB²QË€jOàŽ8˜ÎG03ø %ALJð}E[:@úØ>q­*œˆ;«KõÓ¹â?šª8¹°\.µ7 œo¬&&<ãá;8r{fŒý „†ÌJUB7*B{LÑ!bŒtXnÊzGÄ jÉ¥¥ÑÓ“hÉ”r º«IK^÷8è\¨uX†$D±!·4gãÌEõÅ›÷¼Ë„%Ó@„\dúÚü21LÅÌiÐCE*·urAežG©ó%Ŷn·ì`Z‡¾MÙl–l§ÑbÀpxLÇàqR{ó´Ñ>ÄTvñ)íiÚâ1’bc:rñƶ5Fî¸öÄG ŠëÈUÕ°eZÁÄÆùy‡>˜Î‘æŒL;CaßexQΠÕî!s^è`Wí›#-¯=jžvë.ŠÍaµ8¡=!¤ìwÀ].ð¬…Y×ýø¬8’Q­rF{èhâÊ·c]žÇ‡·¿oûs¨o·þëîòÓßÿý?z¯×”~‰­¾j¥Ìƾ¦•”Ù軈fâè<3ˆÊ_䲿ݯÆ~ˆ°à‡ 6m0}U¯fî”S¸Aüsó€çŠx#—ì›@±P³­ ;ñ©¦i¶.ô½é|Ëy…ƒÃÈœÜ>â¢ÅÇ#¢vcÜÈÆØíÑ1lgc7 ÷)W,ã³´RÐ&}ëÇþަ,Þoçi;ýö[šÒ­·6é—s«Ï º{Ñ[#üƒ‹Àäsxy 3-Ú—ä >³Ò‹ô}œà ] ë|—­¯¾L!{¨Æ×´œÒ¯Fýà£#þN4]s(]äx£Tk$CÝ‚Ùcšoü‡A¤´8š'¾±Z;RÚÑ£¢EÎÅ.§­0x®eº(ÐÉÏã ­ “îqê¨z'!œrH*˜ž-]¶Í¸,ÖPÌ`ãa¯ñ¹pÚ1ÞqjGg{ȇOrÛqͱ.rxÁä;3WŽÞ-»ØõoÒÉ(á9Q÷&À—qcƒ÷Eèê>86£¾z…êä+u¿D½z5f¿0¤}3%q¥Eg¹W^›%ú–ú O*+WnšÞLßȧw<4ªC·_4åÃ-Ûqb“û ¢&}õ&OŽî|83&aòOVx3›Tþ‘ºÕAù©xS_þºæ¡±­ù¸ÏèÅUÝÿÏÞ»Äj¶lÙY¹wæyÜ÷­[öµK€,!!!=Š>¢ƒRAzôéÐAtªAƒM:¶ ‰%\ªB€–LYP–êK¦^På[÷¼Ï©{Î=™ÉøÆ˜#"ÖŸ;ï©¢yvFæZsÎ1Çœ+VÄú{otBvzs¶~q ÚòötÿS(uaô?óGüVúävdG™“ؤ4»’§+ùé ÌøÅw%^•ÕcSµ‡±s~òÕ[`ëËxgw w gŽ@È E$7-«¦Á¾†ML&‹L~¨µl¤Oæ8ÜQžsqÉÅ$ôW`^×·ã…Ú¦ÕØ²Æ:^DTé¹(%®NùÖÇòø˜4`òâpWˆ;râÎ}”2ýmrúi‚ÌѸ¿ö±äôJQäx§®Ï²×X²ÚS¹Ñ‘*$œÕ bp‰& ÇâðN|)Í#R9*UçÐLŽÇá%÷üâÍ@EÈœ5dï¼y`ö׬õ“ßüÍÏî¾ý­Ï_hFø[ÑZ™,ŽL^8FæíhŽØT-ó‡y‚‹/^½ãç"ƒy¤óf,C÷ZÛ ”Ý<’Í5 OT0’©¸¹ÑÁ5ë­i8±‚YŸ“C¨b>|ÚVíûãøÐdsôÇÄÆ2;«žÒþVv Ne*»^5‘NLÑ ƒoýSóh×b§¡ëp¼ÂÃCØs]Ãú§ü„À’7I.‚äóZ0®ptlßø%×<ôðÀ’A‚}bМR_on°pÛ$;N@¦}{]C‰‘C‘('¿•K­NäÚÉÅ›øðÙ?êPõ,{ç*f8«£“UuøÇ]gtŠOyø+^¶ü$Žøp ’reS —fÙ-ç„® ´}¬Ø6ûÌ5Yn›t©Œ[’äîÏ[NŸ#ŽÕ§ Þ#×K˜[Ü«~%/°]úPð…8BçR!Œ÷*g¥dpÅ¢:ÛÈ×À²Ÿ€oäØOe1‡îhÞv®÷^Bw•­r¸‰[Ùw¤3Ó‚\ÜŠÁßýF7m*ÞU³¬öîcÖž'OŸÂ÷¨~ ð\Ÿ¯u¹ÿÁ_þôåÛÏ>yò[ˆ¦8wØ~ÎÙ †4ó’…}ˆE˜_ƒ)Ÿùk!£Ðˆz†h-*6ðs3ao9ÛÁEÈNT8¹á sùÖÎ;Ùfƒ“L<..¸Ë1:^M›“Sß6ÇAr}|“`ç@ICÉõæAµ?ú$Ëü,ö¸¸@@9nvKZ±‹Qä¤áqÓ—Ö÷dE‡œßn7‰ñ0@'•æ¶%ã:ö¾³ÒE´~3tî®3ÊTËôE`®—=H0#åÒzÄä‡RÇÊuŒÈ¼rÎç¶ñ,Æ´îƒ2Ñ ÷-È!A˜dyÐíÇ•£¿Øiõ§Î­‡ÆAÑ/[9§ÿd²´"m¾é`È–»Ä7&Ë ƒŠ¹ Æ>uT}‘Ç—j†{ñL2_Žñ1ÝÒ«ÑvWv€`«r͉ãÄpø,ÞÑ]\$ ¦ÁÈÑrÈØ]]±V àt7énŽ…~‘hTõfä3Ή·þTä…#žçõn§/°Vɾ7Vª¹'kw=˜ážÇPì+K·ÀÂ>{öÅ‹>øìP}훳$~íûéÞÿ3?üøþ·?y¡“ù•”Å6rG¡6ê”ÝÊ|Î[Éý]ÚþÀl0l¼ždÞÆ›Q6©×íÕîFîèp˼ud5ÎÉÏFvd”ÍŸx-ð’—š¼êtÖ`Ùü;±/Gµ)õÁ!”T–þŽŸµFàpq¿y3{0¹7{Sf<Ä(š„ƒï`ä&¦±o®Ž Œd÷mröG+‚$ÒC4ù¬?Ô Ü?âGC8IìY=6—mÇ~0x¾*ïØ‡%ùúšVQÊy“+&Æhp:¹œ /ò;dÎcäÓ§ƒƒªLy àÛëy+‘nœ©ì¥Fùª“ɺꑓ[×Ó¤ête¹øHX÷^M]ñVï2f¾AŠ`í0rÕµ#Ï4Û>Õ§²°Ž!ÙªÖè•;ºæà~YqÕBøÔ?8Œ¡ €2º‡äåã Ÿç¥Æy áDF½x€œ>ÆŸ޷\±J;>¶ëD7 ÚÈi ãXѹhp– †.$×21X™î?þü­·Í_d(º.ÐþÚ—ÿúw÷“'ï¾ûi—.¿ÀäÒ¥gãf"xBÌ]›ù”Í=î6ÌÈ™‘’4’øSØHÌ…NÇÚŽ Ê¢l¾¸øÜW¨~{¾¶!v܃£¼ïc÷ÇÇU¥¹s…XG9Tã³ `äéOqþ¢ ðü†#4Ç–>d¥l+žÎC-ü°Å>þ–ÎC‘§|~'>ßÉHZx‡!ñWˬü SÈ¡_Ôßðxû‹uÊÓ¹ÔM‚åcÜV²bl¦g\9yr=j&ÀêbcŽr‰j˜m(‘òNŒ#ôNYÅ7WCÖ•·%4 ¦¤íwú«‘j!à¬05UUã2r_é'.ɃÍä¡>Ð÷ÉsA,Ó¯Íæ[ÙNRÆš¨ÁlåŠ"¼d_k\ÐÕþ:ȉwŽ+òØ]Mœ¥–lÕ-æ±û™Bºr » Ó8&4é =AÙÍ5qÈÇ¥òø/dn ÔîïØ-Ç3ý˜64¥² Aàê/ã @®zg¨¨nÊÌÑÆ#÷uTJeÞ›…Þ‡e 昭u{.bpaEÕþ1'–ÆÝôgeõÃúý“OÞ~ñâÑü%@Æ{-_÷òK¿ôK/î¾ùýfEoJ&Óræ•K–;‘˜f]H=pwóï:z§Leø|tp‰ !§ rÀ±ÔÇ•±]ÆrâÖE¯ÝLp¦SÄi^Î ¢@ØÁùáeüÜÿ‰íöùîÂx87t4\–fI5"°ÓS_R’J—oÏêȦœ–*ñщ…Ëc)ùyW\óˆKX6Ð~€‡°{õ…ÈÞ;'¾ Î]&‰jòþ¡›RZ㺃9Ùí¡õEÈ@» ‡ä%a]?ò¼»Ý*ODl/uñüÍqSk¬”`3mÔ…F‚¸­rP¡ñy%f òÀU Ô ¶ùK˜éf#âäé÷©Æ‡½å°ŒÖ0Æ ÀUG>Q_‘Ë䃃šÍËUù8Æ!;ÈpT=Cµ¨3$ír€¯¡™FÈËnã¸iÎ0ãš‚CމVò1µÐ$¦ƒX\>¥7¯N¹¼è|Ô8¾§Ä¹Ô4Îø-9÷©7Ðñ?+ß(œÅ"‡Ú¾â9^Œ~Gõ 9ÇMœ®Œ¡¸ñõ»&CŠ®céëϸ€Õõ4½x›R2@Ï?͉/]¤³šš ˆÃ9 † 4'LÕ[‰¡E1Ææ±]NØeÃ݀Ƚù•6:©QXYܸ"R¦Î´ ¶F¾A첯–¡õ#—ù·£nMÉÑ´˜Îò,äRÄ>åY 5iG.CÓV÷kÛVkè–|4péÔ€œKå8j7SLeÜis¦.Gt6¬yYÊÙÿ꬗Ö×E‹”\Ú3GLå5ì"Ä7êN½þhðæ’±O“ƒ\Æ~-äTß•‰ ò”|—¥’0íäàåxöa„ÀH)9¬¿vSòå‹ ¯ïz|œ8¦æ¢ùRsG—ùgÜÓgþrÞDü׿ʽþõïçêáýw¾ý>o+õíw/r²úItPÜ$Ïg¡bŠä‰’É™ÙÙW­kÒ ò«)jû„Ì7œAÑûU¼g›ìª›èªaðèÙŒ¨ôx}ˆ»_j "úåPå°Ÿ7÷ôM·ºç…°Éà/蘒¶i5¢Ýð „úRâP7êÜz¡?¡ŽBð^93f±Ísáò1L•wK´œ–WºV_ºÃ7â;NŽ9a`Fö‰†ms£Ø§µ_wj †ÆjÚ+&cG¾VÂON[N¬CdFµ#–  ŒÌµÌ øÌ:J UtÎáµv»=ز ߉AÖXöùÊŠÞ¸ƒ¹þÛïšï©¿´OúƒsajWÝfȸ0´Ïä³4Çú`»Å¦²xOpÉnHšKyZ/ŽQøòŠ£ú&òJÜSï)ã|#Ÿ)N¨+憣÷xÕ^K%xírí 2‡joÊÒ%VtM (‡óÈfÝÈ4ÃÁ‹¾nïãco¾Äv‘ÞÍr”‡·Î‰S?ìîGËg:ê›BŽò/óRË<Ã3À¼fêøa,Ö4H6òJŸô¢…#}’¬“/ f#£Nv`Ý(¸¦zK€ 3¨¿ë{âr)ïÄ»=ìÉV\kx§í-¤?¨-r:‘mzj°±©o¥9;ÉòÙ™©¿\¯NÕ˜å«Xí3?´wnBmz7yШ}›HXÒV„þFÑë1Uo݉ƒŽü[¶m"o;rÆiëê{×*¶y=$¶¢óØ@ªLì£:2«ßd;¼Ì;çtã_Ëêߊ#çi§ ™ãKa©v –[i§6CW£QåwL¨rlëîï©»LÂ8_õ¤ªJ+u9Ñ1FgÉ «A|O»>ßQ<>¨«¢Î˜¡“Ëå`°†Ãy<{ëÍãúµ.wwú{úyOÝ~' wŸ:½'-MVÀÑgâIÒ ®Î d kó°ÈÉw",)}¥ß….˜É¸ð7ˆldæP!ÕõÝsó’ËÅWtnnÈó3q+&'¯óÊß*M°¼Âްז@ʾ‘øk‚.SEàÌXþÀ€ì¢¦_± Ù\ø <‹.šx{ã—Þéí¯“”¿äHå¬þX@ýõ5q©1 FòÉYâ代Ç{Êe3Ĩ£½…¢ýcn¤s$Yö.’¶› ôÚ±òPÐŒ”è¡Ó1×<Ýà`a!&×ÿêoÛÁSœ»Ã%f“dÍ3œMÞ˜c7]}fìåY>$uDž’Á§Õ`£Ï †Õƒ@–Æu:Œã±Øe*;‘i3nô!9I°œºÙŒ´ËÏÊñ±]§\‰è8Ç'2ãêyáSt—>ã4‰5_dÔ¾‘­;|ÂÌ9ý[~Lk]9†ó•:qÔ ¡ÀÖkиظ0òÛƒ†™ ~–5ìÒQ ÓŸ´Bò\]˜ØM¾^jt\¯<`›NÊÁi<Õ׌_¼xT¿˜!Økcäk^ßÿÅŸÿ Ñ×B•õ=Ó…v¾àè‰ÅZƦ€Ÿ'&mÌSU‡¯¹Pª/ë${±”à¹( œÖ½OÞĆÃÚ¤ææ©FQ7^? 0?¹ÊÞØ h–œg0m»Cƒqþ ǘvÁ^ìêä0ɹ7è(eì¿Õ§áÙ~­Û}è"×6ÿ¥áó{©/‹¦tØýû2 &Jý—ƒ¯éÖf FãêÎ1´µH\r÷â'jN:öwOF­¥€,?略ÁH Àsgò÷O>(éÍ‚îkW¾™À`ì&½û)ÌÛwôdmcÏÕöS}sJ•œ³3Ÿø{•É”áîA[ÛÇ5‚ÄÐc!@몃-öz\]1kžà³ÃÁµ‹ºm9n1ôv®Âás6ñÐñJÜ`fØO·;Ž]†å†g8Æ{åA¬#Q8(½2\ccªŽúŸ“¤.؃©Æ±z?Ú%w„s44©âëÎ<<1{-‚1‹0î×p@Çùlì¬@IDATµðœµ.$œÝ\®KtA67þãú%@Œ—×¥Ü}ï{Ðk&ú—kÅcÃÈì`@˜j™Òé' ¿u çŸCG)ðºI‘ØMÕ›ü ®ßvبf>Ú:®yz`ÕÅÚ‘I|Ší“[±·ï8×!´k‰_ # Ç ëoà«›7ƒú O\m]âÍn0ðxY©ÜA‹³Î%E1‹E<â^ƒîœÅšlè)ü±ŽhzMËÈ‹a®__³Óû ‹9.‚ýò¥ƒõ¢Þ`·H&‰ÔxÃæ*yæÁä´Ó®Œ4–`wŸš×Öf&âòatK¯ir\¸5ý‡ð•<Èþ›ó 3"2ça(±bEC–õÊ=TiùÈVŸ%D–8å!ŸÚ‚ÞÒmk2[Låj¡˜SG;òÖîVè®rú¼u`ÿ,g¿³¸VãâêûèÆ´Ö¢ òF8|œÙ¼9ƒ(:6f«‰ºGü2I5çåÌöAÜï iž¬Ñ¹ðH+¹-kN Ìÿ«ŸÓXLÎd´ ± U ­¶,›MìO3,Ƕøõ/O¿ûÝž<ÓG|p¯ÂÛ«ýV×xoÜØï!owÈ(› sxi§1£—.v]ç“uœ6µ®YÙcõu‰ÔxÎs]ðø“§õÞ˜…\4xòÒ‡Ÿ·\ÒÎr› I©à^Í-‡?zøÇÍI5=H•,äVŸ¥Mâ{e8:3Nد<ÕP—©däÔ'cÐ2QK3À§íØÂR¯Ó†6¥½…’Ã[;—aÇåÔÛ áÕÇÜ•.úí<Šnä«\¯¡<˜OË’ê&ƒãì°–™žÌ``¾ÎåîÛß~ÿå[ÏôyO¦]oÑÔÞ8‘«-&×!˜Ú¸2E'—34E¢çøíÓŒ¨AöØúú7nä=#jß‹å KSù?‘RÌ×q•—û27Æ3|œGájzÛ›M½ñ|„ÀPøŠ±'ˆm#Ãá›<ÂW_°°”Ì«Œq9º±gÜmwŒqŽåãëSÎŒŽ“¨*n> uÖ}µx7âÙãúC@ „_äyDÉéþ‡?Ì—Ÿ¿ð"¸º½3™Ä)þ­qGR1_Ù Fù¥Q|:N¦Yƽ1z3ª~øqñ¡“oVVe€Ãåɘ*›kdÖxÃ9•_ò°Ü/Ű©Ýø­yŽS‡ÚÇg ²§J5xwÀ0dŽrµíÈ7FD|šÿ2«áÕ¹]kaAÈ?8ÄÄ%{8Ç%o}Ã#_éø‚gƒZ–ýiázäË”Â1È6*Ƹá~Žßúâ¥V™\Z¯~—ܹWŒ³>&ÖÒ³ãÊßyQϱ(WÔØHÎ>ÊÛ´ðèò`BÞék£ìœ7ßÙÂ9‰¤Ï•_Í"(|³±Ä1y?ü8W\£ ½žÈSØpÐJ ~oña4½Œ6šÊ׸å‹úï8Í©us‰ŒÏ5<“{Îí’ØåžÍO¢ÔpªT†SÞpË42«ywhò˜Irö/ÓÙ“IA.‹— ²X–^qÝNjÉÃ.ä‰R®úÇÿÜœÑX¦©Ô® —rI܃(z(…꿬EÉ›p9Ü clE+"ÚJ¤ì¸4è›þ•$à –âåÓ§oÞ`,¾ÎåÅǨ? üE®z'“.~ßßžÕÒ÷‰WÉù|Y³Ä¯œf¾2iÜÌJê·îëÃó¤Z ÙX­Œ _|Ø@}¿Ã•Ë÷§ï·ƒÌ݈É'$â =¥÷8¢Ý3ãÆ“ž¸‡:o¶ò! öà¥mån#—“º‰6à>|tÄñG%Gÿg œ|Ñ5&qøèÀ& QªL]U(r5zMÐûíÑaòí¢‡Ý1¥ñw+DbNŠ¡_çÇ>tá^¬þ¢`WÅ€ÖG$p´ÍUª›rfŸ¸öSdjS‹ä‚’`y”TCÿ)îϲ_ý[J×¾H:Ϥ-ú~dãë*Ù±`.8°D‰]µŒOîrÒhJÙøõ0ÿúÄsÎx…—õI{Ÿƒp Q–ÊyK´WŸíkePÄ@n6Õ#Q Þ™vÏã ®‚Ô,ŠV˜Ì€ è\ðËX^hÄc’Í„Â_xm(zr˜õéKѰFkJNÅ T„p‚L—Hx!ÕFîC4¦Œ³ŽÓÇrâ’›ó ÜÎ IŒ}Á‰Å–±#‡Í‘HaäÜ/‡ËºéwRžÞýôåOúèÞx–Áx<çwÿâ·>ýÉÛo}¬?(ÿ¦œ@Í& ËÜ9™–ÒÈÆäÂ^ ëiß0À‡ÉuOF)ºÛ~ÒwÃÆ‡ŸIï¦ÌFêW—ªoìåZÁš >:(ãaÎå^íÃÝ~K'Pó‡‚ÏÇûppÿ¥w<ôò¡Mñ¸ ë }¯ãïa=8ø› +Žô¶OÖ«üB+ì<»£Èî9–„ßà˜%ÒIò ÜbfÈc.2ðð®é;gÀ}-=SOÿtƒúçÜ‹…·Oˆ’2yOVø]:.ÐÆâ1ƒt(ÑX¬n VN7Ógü5öƒ´¹2~wK¾R#­«Šh|ŒÑ%]¶—"IäÚíDN¹iÖ¥¹UL»#S\êr"Õãl—‘ª½>•;ŠW9Ruñ9¯Ôö:‘W|rì¹q#ƒDÓwq^ñ´b|Ô®ÝÞD¬yQ”†rBÛ62táëâmܵ”[ƒsG$£‹×~Pé6Žx'Ãø-ÕäaNÍO^ sèFar°ˆÖ!ss"û¤¸2=ÚŒíÈ­÷ulñ¸{úôãO>þøQý†ýèQ•ßÿýß×_|çã?åU ¢ŠVFo”L~tlÒž Ô7#tÊgûq'ï‰á•(²^nÐÆ pªWâ’ëÜùÉ]²ÔiSc/š¯Ù q3}îæŒ&Juäìlêg7{°Ž®váÕ¦s@騀Ñ1÷±Éí&<:ÚªÖy÷+7ylÛŽŒ%5úsªYüißË(XfþÙüù /WrØ•"“f¾àqÁ…C™ÇÑé7Q‰½QqÄãG»üã:Z^{å²·.ÞƒR¹ž©îAû©¤Ä®C„Ž‚}0“¯Õò±}Â[ù«;8˜sìEQï¼úp-s5M}hƒ«üÏëtWb¶ÿôøêu•ˆ‰¦Çî‹”.¯2D-OBæT"î¸ vœ´*]ÌÎÕ¼sÊ<ªO-Êevî+'v<íÜ­àëÓv­1iµ0a¸·ªÛȽ̋X®½Îþ¥?±gœBΚ¥‡äß¹¿óÐñþºÖ¿øË¿ü\Ÿð…7noÄî,“‹)’ÆüòÀlh¼Î£S›Iè‡ä›ÃÊ!æ^ cü—¯¯–+{S-õ„Ÿ Æ÷€~™?œÄt#>€E7MƯöâºòïƒ@ˆcÄ¿Ü(¥1='»Ù¯±¬Ãày›íÒyó)¦„²Ã%‡ËÁm8Ž4€õǘKa8Roþ` ‰ÇW$þqÀ CJÓÌ™·óä<$àrÇXˆª«ŽgçÒÄf)T IeqTK’ë¦ MÝÆæö -bìýÀzPk,j0KÈÉ=Ü(áoŒ€úYt_ùFÛ³üuÝò²ú…c_“`cm¤b7OãÆ‰Ô½k‹m]{=áŽ.ˆÆ*>öJ©íÔ6·ø/«“Íö*Vµ›ƒÞ·Qî1·ƒïV³bŸÚ7ˆf%Œÿïͱ–\í+G’Dç≘;V®xqFà;Ê [‚­í·Ò±¯{Îø»NBMÌ%‹Ô¹“5‘ÂD¦É#="‡mOvA$;ý" žüÚ¯}éñœ×šýxº¬ ñwý'ÙHÙø¼÷¹&Rö¢(™WL˜ÖŸÑ1ŰõU­ýfW¶Þ`ú¯6N<4Ц8¶„ÄÏæÈO€ápÉ\NÚ:úmó5ï‡p k£%7Låêà ¼`û΃ýÒqL.‹[Fx˜$pUÜ7*v{@»›gxó@FóCǹ` ¥kô¬¹G rSú“Bð_Ý’póWjž}¶u{Óºê¯YúaKÙl­Z;©Á!þÛP‡—­‹8'OœéyJæ‡G¢ÕÉ®¯Ðy½¯æÊ\ûѸÕÞÖ;n87Úf‰O[<^ñ‰ù‘NŸêSgŒGápß5®‰¬³Ã‘ðËÁ9wh½6Þšy2ð;l2%¢˜¹35‰@ï€ä›ž‚â>¡üä±ý%@úÿè¾@§ï¾ñ­÷¨;f6ùÏñú•‘f‹»'Ff¦7ø»À«>ÆÙ9ák¢A|ŸI׸aÒYŸËÏZ840ØÛ7 ½Æ`â›óò±ÉÞr&-ÞZ‹K1ê›Jþ¹‚ç/%'¹~wƒ¾’×£¥®és÷Qa  ÉeeeLl §O&•ŒJÆÎ'‹á:Ž:+o›å³ócŽfžž×Œ˜åÅÉ}I¸p,R7ÄÐÅü”OãØñ» F`:§wõr,ìV­{€ÆíU4”`ŠôUŽá’Cpõ‰_ûvõ©W&žtCkç«OCí\ä9>‰¹-ei¹fiWSÄ®M%¢Ñ1:PfÊ Òþ&îÆ ?u4Éc#‘Ñ7ÿx1×® aŒÊ-âV—FC/'b$ÎŽ@¢&—bv”æßê›9 zà–Gùpÿío½ço…ÏôõÛ¢ºø|û¿›x'*òº¹4{X,­›»!S) ,Ÿuw2—˜l]LY ±!÷Abaªðê7m*äYٯФ³Ÿ|pãp*j ¯Ž…{-ìR"ß®QR-Œ9‘?ˆÜ›=AD¿­þoŸ\6wã9É—¾SÈ…R<ísó7lø±%èª,v\mÀŠ54áñy®'s.UçÒ9ƒpÖåNoÁ°ù“°¿¯šwzÖ<:ü˜+”s쯋[‰è(qH/§mJ–fç¥ÃB=°Œ˜ú%€óXz@*Ë1¢‡¤ºÁ²‘3'êÚ:°«„.w‚ƹ¦P¿ö\ŸÞGx&Ò8ÖÆŽO=64W[»z½ÞñlœöñšÉ¶Ý(Õ§® gpL᳀ʰì<Ê÷άã”Êšš\;0¼Š8ànnDryÕ§<µ·ÍugŸþlÆxžrÚñ<õgV_5Wðã裿¼¸x•ïÌŒ‘‹k[¬œÅuÿÒ/ mzD§®Å¨Ë\ìû^~s½~óbÅ­Ä‚~þ¨Èš0s'øFÓˆeÂhȬ×DòdœÏ„IÇe’ãçÅT 6Õò·†Ï8TÀr“nëä/ÊÈ+d|z842 À*pqœ: ÈN•@-ÅéÎ'Oo ªy¡={çZäá¡ðóD:S"—cø½  *ÎmìîŒì«G…ÑS¡+ÌãK¬¥ØÁ†Á”;œ™å½¾A¸ðz™­ÈÿÌ! í®lþô«?6‰ìMWvÆá÷_v²'rò“è5³m5;+9¡jQÛ×%”‡i8TÁw™rè5Z)ÂÙcjÚù© !eœ’[sŸÜ± Ïa=j+}µ}Îöö[ZÍ¢rü³‚: Ù‘/žWD,›xÁæªÄ Än¥·;£[°;&~ÁƯh¤”ŽeëÄ*‡0ro´x•± ²k.^µxÔ ÜÙ®_úرsrà‘~\kpÉ5㺹oc¤‰–‘?ûXûë¦]ëʤÇ\m|TäVŸk§v>ø÷Š'·Œ_óN]Œ~ ð›€û¯}õü³O>¸ûÖ»žPÞˆgGcó`qæèdáUù’½£É6sIÊÂìLoÉøð³åËO:\:Õôb¼}Ãá4ŒKÌ&Ñ\isxÿò±^ù±!Ñ>‹m£lÿZƒ«š<_)ðËXnoÖEBåñÇŒgò÷;£/gÇyå Œ7É‚§=ãŽÙ …jëÁépÞ:h…íGo²¼•¸·ýð@|Œ}MÑâ2.¹60ó¥A_O©V?¤çÝ•®€~@Pލþü}øaÚöÌ‘ jû^Lã1~æìÑV•þâKÁ²=½˜J$ïÛT´´“S–ßr4Ɖ½òœˆ¶_W׳v䶉,¸»ok72^§_ðdžÒVëQÛ&׳­]׿ø o#Ǻ3K®3Gd\s‘6Wú×­-þ™›q£seëå±&m2/ˆÛü+‡%RÎ{¶7(¬DN;R3‰¿ K âÔ·½Ç¼ÙtsæXØË„Oü@¤ Krc‹f¸Õ̶?øƒ¦•’ùSÀ_¾x\UuÎËÇÓñï|ç^õðzîKÍ”Þ;ž4¨ÏE½ÓI_d ¿T|í‹I]½0ÜlŠkS™6²_!J> |}9õ]¸ùB`sðgåc@ׄ(A“TL_üÊc·¨5(9ØÑyóWíϼG•A`úqEûˆ:dÆB5©®ôàxÝdƒ¸Cã_D¶Î NXµ´¹Ñ¥ ~90ž£ÃE¥4mƒ-"¶|™ïºÀeF€#|8zm»ù§Ÿ™?ŒIÆÏ,Oø´4neêôj4X œþ‡B­ãxŒö‘<Éõ²óÆ>öã4¹‚µ'çr”ÉF¨¦´uÖẎ°Ã_"ìÜËYŽrSw ÿ¶KÝÜʹY´nÿ6­ðä\ =”Z"-yÔy@¬mYãuºª˜üiǶd¡SÕKg÷j‡kØ‘Â{Q[*÷Î$¶ôížÓX¶g"ÝÊ Âå9f¼ä ´gaác1®(Åy.œ|¤n͈ä:Çž9A<ìõ)š:~™ïn t§Szùò¹¿nÂGtz”߸ûÎ÷?øROwìþª=A5á2}2{΅ГIê§Ât2ó/øòe'y°m&œl>,úðta`ó@¦t®ŸrÛA4nxÌ%ÀåfÙ\jóà@A.ÿ ˆA˜ô%œ¨.vDa,u”ÑÜ’ú^î.~`°\øœ2c–U{¬L*ÅÄ©œŽøk¶ÏÈ\¯ÅYŒìS¢‘ñGß+ÐØh£·ƒÚºJCP°ûÚ©5o‡²Ñ—KT%æŸî°#øécBøÌß%ðRŒ™rßYLpG¼ÐÚ/¹¸™“àõ ±¿k  š,ž¯ N/RŽKu, ð¿—QL‰¸â.t-{œm:ì4ëWîb¸6µEç^º¿Û·>›¿åo}ÆÙ<ò#¸“E“é„€@:ä³y0p2¦½>kÜç”å§XŽY5ÆKRsÏJ®O@+×DZo9O^óg}‚ƒâp—®2‡9nË֥Ź´`+£¼ô «þÖ*ÛšG¶ÄK‚eDЬuºmb/©ké†3câÈæðŒr'¥{çÙ›w<†àtÿsßý@øaÿÊ_MÃü˜—:Ÿ™”IãɶŸ|¿dŠÍlä÷MŽÎ3Ü3TRõ[ÎçÃó aDl™ŠVä$5¯/\–ÊÔ]¬©»Éã\ÌnD‰~Ù¦}ÊR™³¼µq_¬¨ÍMänùR‡eÌÚæò»c4%’ñã ¬68@@‡mþº³‘¸å:ű ð„µ®ÆHé¾!¾ÏImÔø2Mº”Ô–t"e9Š?bæ’ 3ÅÒ_é•<ÊÕlö6-_(rdC´R§í·çð¨BÒÁ÷\Ö[Æ3ŽÍ >s5 Ä[+Œ~[wkAþL³7ís¹*¹:²<}®Yroí§­mxà=å´«ckåD½!YòºGÀ„¹Øú­zlÈK7|8ÖO0ÏOøÐ’r‚ƒ Üš¾åÅ@A¦ Æ4j7äêh¸ø¥O¥ª˜UÑ÷ž”«;°û88Î æ?ÜlCÆOë¥ûŠ,…ñÅ©^òèXk:.!Ì£»»wÞ<0F¡Ü}ï{ï?ÑŸfz0Aræ÷Å3%4“X Y©¥“ÆÅ‡‰6ŠL®xRv³‹J¬ð±QGÊâ „ vr80Ä4¥vDÚñ˽€y|Çß錡~ˆèOÎ\xÊQ5>æÔ¸¬)ý%¿î JƯ‚Ù¾’›xjß#§SoоuNà³¶Ÿ9eìâ…ÌQö>Ôˆ}p+©ÊVD‘kY÷úxlŸù-m7Ù>ðÅRNN€" /úEáÀ¿×bÊè+„93Haµ7°õ:‘— íi†Ô³:c$ ïB‘’™ó–ÅBÓÀU9ö`«lýW ü'*÷9oi²±~Ç!ZÐxÔ'v2M„ø&n®N|‚ÛyHF;¯D8cìL³ýQôF6#SqÀÕCMë ‘=Šóz ªÌc0Ý'ÙH A¶y|€Ó̉ÆÄ;•c©áM1É×|ÎK5ð« Áê\IapÕµ7py, C¬Ú¨q½í[7LûP±OÉ'aÄþ<þ¾V†¯Ÿ–p¿£Zã¾tæËµ2ÄÉÐÊÇ:ãæ$' wÐíIˆ±âá®©ÑØ4jaÈ1%òÐП#Ü/NùM€ƒµÁj®þ#‹Z%ÁÁ‡3Z¸È.‘ÂùV°•Ó~Uš^ØL„–m[Nôß:‰ö;äÅ!÷)Œ-f¦ÑÀµ—?;ÆŸ9ÈQ„S^øQz9¡}”b ±iì½¶pûa´yŒ}­9pIþ,ÌM ¨©ÇM­]¬+Hê[Œ×®¯}òššYZæû–3ùŽ`Z,=V¨f6¥ðÀdâ¦í»~²2°zòJ ¬'Ÿ”f†Í-èæŸfzbÊ–ƒå´³l”±÷[æå¿lŽƒ8.éûðLe=±šg¹ðë³sA1_û‰„ɳj/:Ò»> õo©±LF粑ûÛpN¡cvV‰€‡)ctê† õø`£žBQ¬Í¼)—t´}ÕÔÁ´¦ÕqâAâöAÏ “+™¾–re^‘Kû ,yÐÊ|¢µ àñ©n½ NlÌ`(<€¨í9UL•Õnÿѧ7´v—÷UÌ~Æ êu-8Ø‚JÍè—Úg×HÍ–Óï$½å/~BQgÚr°tÌ[LÈ´×<R*ϩʮ̯-ZùØŸ&í‘Oì?³ €ª‡×78Šó }ÇÔý‘j(¬_máÚ††öyÔXsgñâ RÆÇí*°M›Šèî5áü…A霹ÓXçp ŠSÈ=Ú(ÒΣÀö™y7>v?8 ÀÏ}90@6ìÕ‡  ·˜D óû”‰Ñ‡š“7èœ;†§î«ÚÎÐ$ƒìÒ K1zÉÕ!ŸzƃRš Ùʜ싱¼j{® Œý}ŠÒã~#ciü nÎÂãb7‘®¶·sâôô=+ÅÊc89(­Ëé1MÀ`º­{IŽÎyàé:âq(¹ì‹Â½R ë8.¿Õ;ÜÒ¡¾ptá¹úÑŸüñ?º¿ÈÐt ¢ý˜ÊË'ïê}É4Ì«-~‹Ÿ–­Ù“‡IÃæþ¥&L&uþÖÍÄ›7ùˆ!zêl¬öð˜W'AÀÆwç±[¾}wž|5»{sû#‹ãªïƒg×öÐP*(8|ÿ¨A» r‚Ç6Úc£>B¡u±oÁäÖvGÝ€zÁ”_Û\ǸO¹Ãч4`èËaÝM¢< ÔÞ9Tq{‚D¯3cv‚,vN`Ê?³§º1ìì‹„FXU}Ç9ð弿®fŠjÞ &v̰u3µ^Xÿú^é7®Ûk|Š[OMËÓŽvRt 4v wqCõ€Ë¶dÔ¶|‚Ңç£L#žÞ»M_Š ~…7¤‡Cš'nµK$…ÇHP¿’ÀQûˆª–Î>>ØG×f÷#äוº4‡‡­ú³]¡÷¡7{å¼øh?ÐæÉÂ@ªrò¶]LíVѸëù_AØÆjß:wò-õŠ£Fq¦Ô µlB×f]—g÷ü/ø‡ZÈcªo–ÅÇÓu}ð×ZYÏWþLº¬ó,æ3©ÔÊdêÌÑÄÑͲ'h°Œ\}ú=&ºpmç¾¹EàMk>D>'+~Þp˜+ä(ò¹óÆDßlä´åâ<á$¦c¡Ã&»sæTNÕ+îøy3ĉ‚“ÚùÄȨ¤;hŒÁÏÁ¨àBˆ ·G‡Â Àè©(q˜ÐÖÓvîØT\qÙÊ99µÖ×@–Ûé~¶™~· ¿-Úã¼¹ÒâÜ éšH˜üVÿääþ+ê¹ ?wbY§“škl4ˆ«?2aö%Goî¼ëÔiÀeÍ÷KòîÂL­éoò*ŸÝov÷lÞèI®§¯©¯=Õ¥2×Òä1çÒ¥aNbݘݪ }ÞÚÝÂ~JæTîèzœoÞ§@ÆÉÇ›#‚ÊÑýK…ìîáÀïÔê¹f±›ûô™öeŒÑgÛŒ9êKß:ÔíÌ´OŸRUGÝ£6êÚÛ®l¬N®ë0Æ^3Â3÷Š!Otô/s9mÜëã¾>¶ ^Õ*å@ÇQ¤èÖn<ú…½{”ˆñy”¿Èãßx Ç7<3q “‚™é/FÉÈ[µ1³ˆñN€ìÒñjÍ ¯åî©4ËáðÚ*‘Wcg &§_<›¯Ú^¡óËbÖMJ[zôÞ(ˆ¹ŠøÇÎÔ bÙ¢ÚE‚ejÃä‰/Rx)Üpòc0ÎQÁì7<à›;*ã…éßp_„ñÏà©οþšM«Ï-}ž@pÓg•â”â~ƒ©Bµã©–zµ1óû¼Ù!¨tÜÐqàpz%ƒ€‚<¤5Ù¡}އŸ5`jzLTS0­_çœÞôqªQ-u¼iôgû{÷C“ùµÆfÀ+OyŸÑˆI+qÊ`µÓ¦?~¢“`ê/­B¬«¿•hRN\ç+EAÅ ¼òG'¹>èÄ€{'2+oüÐ5¯±ÛdWÅv3J¶J Ï?+Ã﹊Ѫέx¸u ó€Ç|è`ñAùü-µ9Pb“€|;ÆÆñjÌÓäV®ŽglÇ]1õ½µÝÚ+Ÿ5mJ9«r¬¯Úë°p«QÔ¨×z¯vÇÈ/ïïÀ,u×Áz ÒÝw¾õãçÏîµp±€jºuFД̦|/—Wf£ o×{Àg õÍq§Ò¿’wv;ßôšyP{ŠƒÍŸ‰ØiVqÇsâL£)Y!þ✋8ºì³óNÇQí :U曚6ÍÆ]Y Ã÷àq߆Ï>8w³@/¥‚ÈK2˜•3ªÑ©¹$HÆ\`§?CsW'_oLÔî@¸§¹ÆîqÉÞ-¼ËÄæ³ô>|4ns%bà¯ãHn xùðNµ6¶äÆCX³­ƒªƒHº Z%¹ óŒ ¾8“ÇÐxlÉÑj@Ç :‘eTËc!¹3' +Qm""3‰†£.®9¡ã¨Ï´ñ£9,;: ågŽTæ Cqõ©¼€ãgôøÐ^vëÂ×üŒGÅk‰4ˆÙ9ä¸`[šº9æÝäD©š¨9Nó‘å«K9êW^êõà"Áö‚ U»qÏ6r .7n6¡Ã§ö³p+££Ô‡6˜uï¡x €¡œuÛ±äÜü±qÀû³¸‹¡ö’¼VŽ?ÿåÓ·~,ñQ–ÎûG×ùÏ_þøÉ;OgéÕ–f“¤36LØ(×g¶ÈZeø!…AÏf’É(‰ÿ2û;6¿ƒ Ú>ÅŒuŸ… ²u}ö¦TyfÿzžIîÅ_m5u@"ÝpâÊS¯pT An¾Ky3;¦»6›ö°÷¸ÊIS<6ä!ÙXò©ýè/ú¼ S|«Ù/`§iê{Ô瘙N6§>qñw‘¼Ühr ¨=N4&7Ƙ¥‹+gUäm›U{³Ã™ÕGµuc¤‚#Õ_¤xÓUÍd`ÒðVj?ÃEǦÆBï|¿-,t1¼ ƾªÍ3#ëÉ7:ô=ºI¯»XÛtW»ÙªtÎqt¼àXÒ³q¯"PÞÖ‚ŠÞý8xgƒ-þ`îâæO0ü×BŠƒ»Ûï°8Œtø¶/n#…üÏby€îÂ÷xuVJw.`¶‰§y46ß±(ýÐ8—Ò\jF ™£Îg‚%¯'•Œ«È;yÕðê 7¶tÑ%ÅU‚Kë©ÇãxBþð™dî *(8H‰9cj0>l°~—B:(yÁ}£?ÙõߥuàV9ŒGóU³4Ø},àÄXríîÊÇN‹2 éí†} Y¶QÔ_„ñIÍ5q_&ríIô*Ÿ1L©ÓÂ7öpØ®v®û6V¿5·nqç=€Gãú~8ûE»²@õ+ßÙHªoØ—n O ªœ¦[eéP{<ÇÞuzß'ª)ÆŽj£3FmÄŽgkl-õc“o»ã]KÛÎW7\í;ö;÷?øþûL6Ì{VB ™,¬’õŸÞÉ‚ÈoùcÒæ ØÎIŠb-êÄÛÏÖqÒÊÌçãø1©Y¬g=w{ݰÂc·/õÈõ[7”là(üùaóIáWØ“;}¡øPò#Xáf)g) 0æà€2o!˜†„Zœ—GÍ aæûs~ñ.3}OSrRÂÐ>UÛ”Œ‘fGG ó«F°eJÓxÒÔ'ÌëRøû}*süQA„b«\Šâú£žh2¶ä;ãÁɾ6éiËaS:L@NÌDrZ[} w(Éíûxó¯–ÕÕÊ¿ ømµâã;Ü`ÊÓvù| èO¿øòË7ïÜæ×]¾ûÁþä¹VW6ÁN &}6G–o¦Ëèà‹Z¨ÀvóF^“L Ú}W€‰YÝš¤ø›ù¦VÕý–æj‹ÆÙÔÙ¾4Tfvý.ô#1¨ÙZö9(÷9MŸ‘é_¾#Hþ›t|ip ²²Z‹8Ô*yç"q­šm¤ÚÁ¨H…W¨Þ¡U­w4ÀwÓ Lg•?Ã6rŽqõŽ³Ï•©;nÕ°……‡Ã¯¦i¨vB›ÿè1¸9rªO©ºlöHt/×)ãçH3||Uœó¡šÇ°åùT&ýRÍÀðß¾:uåŸ1­x{-—:&lrA÷UåÄ Çr9äÝkãÔ‡ôED®Î¯¤‹HŠE"Èàgì‚yAÆïÜ8Juâ6ÔâCeüÚ®Ïëê[\cw./"€c$W÷H›;ü*ûº>öG6pœo8ìD˜òÙ¯>ð®´WÁ¹ Çü³jr@X¼²Ynp«ÏÈR]J}P.N¸ë@ƒ­švŠî±·ß~´ïËiäqÔϾ÷½÷^¾õ–Ñ›N7ž¼ÚšÉ$ýš¼ ‹äN86 ~w@eÌž€Ò» VFŽÎºó¦¬_ù³HÇ÷Ò¨r‹¯®õÀ½¡uSËw°’Gå놑 ]7ƒa²:ÙùR™¼(_Jg&Sô1¢¹Ivgƒ5Dèþ®DùœutöÛt2Õ :Ë"ÇÅÏ »„#ôZìÉ„¸”ŽiòHΠݘ~×@tb6åøø]3·°Àp¡AÛ‡j#È:¢mhZfD¯vu |l!åÇ?sæ,@ÇÒÆ7±Ä¡Fç5€öÓøÎÝc'äV8Ò—š¨«?u¶þÀ…x˜J$¡z«£õ#_0§¢>£·¨¶!Åíô«©©P—ªí[ýé‡ýÄ`ÿó¸zÿâwË…Ý÷‡µùú#c¤ÈPL:ø<nÿbÌW‚Ú¾ÏÔ\±Î6qpž¸äAÜæ­²mÇ}§ ó´>ÐQºêhs6ï(ðã^¨®<•O?p«5K¾÷wo¾xŽÑ£hßë[ïݽóì‹çú}Àþ Y³…IÈýùœ ÄyMÙ‘ù"__ýããWúƒ÷䢡£ >ÿ9aá=A©¥£­jù‹Œ/>nV?p`ã®G^¥æ“õr¦¾."hRVŽºkÙÆ‘ÓÂoú;+6´›K<$amðþÅ3¨ÅR®{a Ó® Ú€éÊ#­5øåË–‰?&^Y{Œ Qqÿ»“a—cÇ0@Á1º¶UÓ(ü´UE@!Ì*È7åTõ\¼¨aœ÷+i2 ÆSäÑᣃ2æ©eWç¶­9ä€Ï\ µûfúUG<,£SÁçE'ò+oƒ8)FJA•GwŠ çÆœ¸`.‚0¯“«W}^ð6Í€¹íÓt0ž³ØF^±FîØÙ³˜ƒ÷2fý@L7ô—6P_›Ãçg5Op½vô{å>ÆrjQ;þÓ@ïfdÛæäþ®þeîÙ$u¿äL»Ç4Ѽ™ùºò²·}í"ѳÏ5ÉæBcs Ñ×ÑÄáb¿}ÂÞwVíKîR¢gÐ]ëä¼ÑsÈäurÚÈ—K“þîþÅ£ýàÑ~àé÷¿ÿÞÝÛoðåË?|kMœÌB&—îžÙÂ&$…Ô9¤£ÍÌÂLééŸç—ŒÌY#ÇšŒ¼²5mtãèŮóñªyåÚE’Zk¥È‡¦*7Ø”ëä˜Gfd!¶`æÔ‰\ìoŠDä¡;dØ£EV‘3rt²ª‘‡‹ÙÈãÊÞ²¯$p„œ˜ùn†¿£!däÇ».ý8ܸVŽ%}¯Qe?@H@¾äYI¨ rPX(D•>Ó–cu%*Ù›¦ðýübÐ ¢èÈ]ìÈgU¢‹Óz[ÕʦÎ(ƒðæÂJ¨ÂìÔ'Û3ár ¥Ñÿ§Â’Úz“±áíåXʸ­¾6Yø—¥ |Ôf|¬û&^ cùðYvéV^ãsÊàf®œƒ¥ò%lymyžœÎÛ€œl%\§ýÂÏáwÛ|Ð&²ÛAÁÿ }§¹92ƒ;%scäñM æ»–ô¡¿9Ò1CÎl .öóþ…«¼Ãeô‘éL8ЩH&#júd5¦ÞD(lŽ‘ªmæ`¼ÑchqÿÃr¤â´¹ÍŒ ÍÝÝg_<{öæ ã÷Xêý­¿õñó·Þú@3à‡ž.l2žY·™(öë tøá“SxÎñL‚TÆÏ>vŠú´¹=±™²‘jí%«A?ëBí,+÷Sy´/ø!`Þ”ó€~eóä¢]o¥𡘶õVPR/ÖÑ‹ð̘ Ú8ámZD‹¥>±ìd˜Šªcí™qÚáÂZÏzÃë7Ní–FÙð&zùaH7{.¸–ªiZöI g:ßûÆÜ=yïÉçŸ?Ú€µ&í‘z­_üå_~þäoü˜?¶ÃãñgP ¦ÞO–3‹¼áÃ’âÕIÆýéT³HœÒîâ›IçüµAs9îØPP˜¨SN5%¹:¨^†ÑáCNØ8¨àT™j¹rÕŒÜcèJk—žj[²œÊuk+æuõò;8‚­E’šðšÛƦëçˆ]ç3X+ÃÃ\:´XT˜¹·„vë¢Gû¶rÎȩԻÐN¤î¿„js- ]rI_Ñ¢ÏÑ‘§'ü+öšÕž+ÜãöPåq>p¢xöìÇÿÃoüÆ£üC@ŒÔ£ý€Î?ýÎ7ÄwxEŸWr|é-³†EŸ½‚9ÂFͽÈÛû-4™WÝè±ur±1°9â×W£ÅOˆ¼"T ÞÖ^ï2@¢ÎFšìypPüëwE”É/»³Å:Àqw¥¹u7ï¢Øä×þ®c}LÐ1ûà›ŒßÖ“Žñʾ\r2g膜w*cŸÀäm÷_‚ ú=Ð ÐÍÛúVL1;O'Å»8 ŠfNºÉÍvjžìx¡á¡Ët£Ã‚èX–¦]Ór‘ÞïähvA³_bz‚^MV•%äçâk,ñ²äúªöF:9– û††hºSNjlô#…¼Œ”¼˜(s}ÙxÏÕÍ_ÉóÊw]”ÆTíçŽ#8×Õ×vUÓ\5›?z÷q|û ’ë-Ÿ:Ñ ûq ~.Ø=`áí,ðçèçZØO>¾‚‹›~1wtU‡˜¸4éu£ú†žb»NäEŸ—nØ3Î6Åoh‰LgÜ çìi;ä),:Ã+×~àÛ¤^05Ú^öí7º….çw(ñáð<À¨bž4ÿŸ=çíÍÆ˜¤Gº¬1Eìh»¥–0IɯI*€Â®6æ–Û>3Öö±y{…gæ¢æC S7v4i¡‚ÍFÉËŠ]¶1gÃG™Ø¨Ó×kbgœL |„B\/Møe°›Ôý‚£mGœ»gOß<0(±<û¹ïÿ_Þ4AúÙs§ï xÁ¦6k¤mL6µ™ˆ–Õ¦´ÝÚ¼*ïáß&(2ꬻ’¢Ã'ù#DÜq~;¸F&‚ùÕÌ^§ SmnU?°LL>/ß®ñË¢®‡MêÜtŽíŒiåÌyË8qS'<æÖrFœ°Qü®GBí1“Üï€ÉbGkJ±• ÊsÜYÒÐíE.ˆäŽkRâ¦8]ô\×LÖ8¡T1ß8…¡œcTeöb ÀjCÚrú ÷J‚cØ$ÞEãdobî`y°y›ßɹÚz~•r{ï (LÌv˜¼7¶½@q‚ •-|wŽV§Xñ·µ#I¹î5—òŒƒ¡6µ#®ko¹mœSç”ë[|Æeþº­Sf°ïæÄ¼p¿½}T‚T[Ü)¸/!Ú¾u\6.µájÜ=}ë°=ÖÂZõhË‹'÷ðD¿ø¥Vca–>£ÁFÊ"ÍDb ³È3¡–N66ucÑgŠùlœ5LµLrx(ÜlÜÆäÑÕ>¶KfâcëH߀—ú’0…õ?>`ƒP)CÍìsdF;.Hø§?Áà¾K(ÐäAÆayxLêþŽÁìx|ŸÂ‰oÜ–*+yH0dò%‡ÊlB¨É•Ây·Ðd”ñëBCäÙ„…V>VyÐñÛ‰ (y†,ÔΣ§=6?7jÜÏR™kïWÿ Kzî/:Âa//MÏ)òÆx[äà @z½F%ÆA…Ï„=–b3vÛhœÁ´ÆC±¡!GÓ\´)1„JCLR–í—$=­Síy(¡²98µàwGFuª— ;— ¶‡Qµçb1SwœjÜOŠÓFû6µênq¯—3?ã—HÎÝ͹×g#Ò⠾מêÒ îÌ´cÓ9‰Ïm çÖúIé1*¥ÌÆÝÊ£ßÞgkîGù$œ´yÌhúDŽx4×Ô‘Ï‘Ãys¦]6Þùê5ïu¶¼òÿ¤RŸpj§/ùq©§Oýc-ú#€ûï~û·¿|÷'O>úôÉ[ï>Õ[ú™ˆì'ž;š(}EÈa±Aß·×™ÐÌ%Þ=ðæ#Á?ÿŽ~fŸ?6×â¾;W7.<ÙÀh‹Ø †?%ÎÊI0‰m’ -moÊ€Urƒ§?xòçW‚KB –Æ\cõ»Òä;a­}œ§â&ÌÆ»r ßSèf³îx¯Ø5‰Xh¨ÓŽ‘‚Q†#öñ™A¢P2<…Ú¯zæ=zÆÅ×TF»"8ð¡ŽN6t-¶p꽈IázìÕ0ÔÎù@IDATY,'´O®qqåŸYøDi,×:UŽ_BÆ?£$-˜¨¸â}LJùI— ã0’çÌa¢ÉxœñŠ¥nqûÑ.ÚË\ú¥DHé¢}Æe,×u6~wyPP*Ó6ˆÆ¥iX]Pôú.ÆýyN ͈‡%r£ §œó9º æ~bk·O:Æ•NimIÂ9f€°[W ‚´Y;¾Õ­ëê¦M~}ÑÐQ#³úʬÉZ“UÆc·w íæ8ctü`íuYü"€OFÒ£ó;–¾ée?&M¸aS.Â~ùüù“§ßüÆó—ï¾ý?Gû8Ϭõ¶üÍ_ýÕÿ÷ßþWá>ü½ôWžégìôy7a&ÆEsâ{"ÏdÃîÏäGƃÂ"»n(Û3]m„\ºÜ:“:™{O|âì{1v•0ë½éÙtásÚɧz= ðóP0¾þlÙ·×ØVïpI>ÃÑãq¯'™ôIŒâêZÄñÑMnÔãêl8ÑWcÕŸ¹ãëœNKö±Qs¨=¦j°0ðåxȦšN(ëU?²AV_†É¸ȸ[‡¾bÏG2hF' ê¢òÜ*z"ä'5ÚÛ`HXJü*È:œ%a6ÿSŽ#¿M0É˦?…ý©¾ûñ_>ù‰è>ÔJðzñpè¸^΄©mB.Ù@ÂP º…çy3\í(N¿Þ ”y¼û{‚‡{ñlß95ÎéV;¶Ú«ûÙõŠtäÌ]­ñÕù6FåÔI®ºxLßQNçl_r²éx®Éf ¦I¾vä}„‚³x|­;ˆ1 I9·/ÐSbI{Ÿ ¼}’ÈȪ¼Ž‘Ë œEv#%Sû2t‡Ú«æ…Rç©m•Û'1Õ’Y†ò9AÞzû“w¿ÿýëüõ_ÿûå}Œõ£~à‚ÿ{õßø•O^|ñOñþ‡ÿâÛŸ©{D‚Ý[³[¸¯Ê=ѤEÇäò¦ä Z ™±h:­1>œœaÙggâr/z3†ŽõbŒ63éºÔ”˹Møp´xƒb¿› ‹Ã*u@§6ù£r-]û3f»¥¿Ám±Þ >]âŠÌÒB‡áfQ×w ºH0&õðBîÐÙ鋽Èï°”Úp'åQy4×»> ”ëOJçf0§kqœQÑ^§NJç0\^ƒÉIy€?9p³Œ‚K[Ô=4žÌ£A\ÐNDý¦æÐî{ÿôɧ/ž?ùä§_>ù\*?è!Øc¼8Ôh(tj“«c4ìë°ƒ_é Î×_‘ÀóÍ»Ëøœ"mçRåM½|Gÿ:ìëô7tqûìy½u½Í u(ð sðÌ%_ÿiÛìtQ,×[kZiW¹cCa :ABû5¥¦ÎƒSn;œÈ`›€ôkápD>u¸#ƒ¥]Ì´/éÇ䆳 1hñMá0µi³Â¤Lÿ%óÛX¿|úÖ÷ö÷¾óoþíßþíÿm¶ê=ÚhÇÿ“í_ÿ÷Ÿüö?üÏøÙç?|G…?D鯶ÎDÏë½Cm¿’Ô ô‡£ ÷4`¼¾ëÔŸÅï+OßÇUh“ q:±»pHå©Í«Ú§sĆ0d“ݲ´%¨âþêŸM» ¦îôsnÒu‘àÕøù0oÊ܂ʟ³À¿?bÿ$½E­'—œ× œ¨éÞù 2Ñ‹1Á ~5œ—›“E®™î‡_®ÄÇ,äÂODhc™Dòr…tdcH²v£œZUÖŒy¬Á}rÔ8ýq¿Ç®jõ‡³Ÿ¹² ZXä@„™qã cÕ·CÑßé"?}ëÙ“ýô§Oþ賟<ùP™üŸúêxpœÄu~œBéÚ–Tî?uíj»ØI­„`ô·U9Goé\ëd·0‹¦6|®¸ìGÜ’©Û>Ìn¢ÿ³–“£~™qgóÐiÒ¢¦_'ìäÏxRÌPøèЃ}tKÆÀŽ4RÈÇwDõ7÷DCP7 íÞÓuƒ }qÄ]±Bä¾¾ÈíOíÀYK§)îOnÌ€°ÁcÆ2ž§[o?t±nו‹l¼K‹ý³û»÷?ùò?þÿøÿ5‰oŠF ûÛ£Œ¿óû¿÷ÿÔ_ùgÿƇ/_þÜÓÏÿåïèYD5fv±8Ò<æ­L”Ø0z¡“Rt9hŒ ¶zÿ8¢d®󯋘TÉuÆy•yºôÎxXµø§(ïïŸüD_8ø´ïHõ¡úß…›œ:ï×€L †N^+z’§:ÓrêÑò³pËð,šÓбS-L ¦6Ï}Ü^ësC±D¸Ê—˜{–”»‹î]³ª8·e>uíËâ‘ñõØP×0´³øÕŠŸ‘ápÃ3íRª§ýj8jæî%ÑÃvúû>è†ùî”ç†É½—s«,TÇ`)Ô(öSFGAÇQÿ‡0ྪĿÞÌÇ\ÿÎ×ø# fÝ™ù:Kìµ3dÌöë`âPÎ8õ ‚þ‘K"3_(®§mÙZ ĆózeÅÕn‚8 €]z}¼13ïÔ)ÞÊ?9A'fj’Š’]õ Òq v^Ó¬§¯×Oô b«Um511Ïpÿäå“/~|ÿä?ý?ù“÷ÃÏ>{Ô?ê§áxmyóðÚ¡yòäÿøèƒ_}÷çîo¾÷ìÉ_úî‹»áší™”¹ùfkQfRf^®hxÁcgRúU)3•;f&±a’±·àÓÂMVk1Ô¾hŒÒt³Ê‚=ÓÞ<#;tÉÚy×"û΀›®ß?Hó·òe¬WÚNÑ'4*UF’kz—t.î5¶s̳$‹…§TÁ¬äWLì-ýÒrÅ+†ShÆ/Á½¸ÑÌb6W€ÁƒtÆÙ¯¾Ð©øÜÕGËÀc^ÜQµ¶A~¾~2`³]¾Ÿ@ˉzBû‹ªp÷:ãߣ¼Ã³9ý!Öé…DïŸü©>è—?ÐÅä]€õÎ1UˆI>8Ý–Cw‹Á·ålW×ú ¨jÕâ!Ž}œËò Ï"_3ÊR®ˆ™èwm½â©„jsYŠ¥“̵ò¬vòqÀ Ê…VÛ Õ)§´ÚjÐÆë¶ß‹I·©ÕXzÚ8·`@¶n0aw}®) bíìŠ<öÚ¾ ;Ž=ùø‘AòóC·’0Vº~ÁõÌÕý<Ì<,.Ÿ¿|ùßëøÅÿû½÷þ›Dys~ݼyxÝÈŒþ÷?üðýßüøã_yçßýß¿¼»û—¾ûòÉÏ¿£…“ «¯´}×i6z¡`&ªLå· wþfnZf7’›ó…¾å¹|=éGMÕˆW¡ÜÖ©mÈ~ðΫԂåG^ Ð ŸZgÓ¸–d›˜q“£H¸!û<}Ù>¹±‘;u9^¾N;|2ôK;£,ÈÆºGaÑpã_ 4ÂÒí¶1:9¶=dSááÃ"•iCô\`ýOîj0¶Ó/⇿õû¡±™ S®c êÁ‘í%2”“¸cÃAÿ]·iúšÐ†GÉå Xu€ç˜€<ˆÞééÂÏõ€ <ð.€sy„Y}V•“*´{8Nä bÙ—yü©–ÎÀëi`V6Äñ€4NðRNŽhnϯ"êÛ¹ÅL¿¢NiÚªðkì0š*`€{ptdŸ•Ã:ÛœÞp®¨#ã?é—Ós^ûêµAz‡ªÓø¢³ {ù¨+X§^¯ü0t+ß Æ¥#ƒ–Ïï+C”ÐñéÛúaKØ}OKIÌ5‘rH­â{B'¯’Í¥“þ´ëÿó'/_þ‡ÿè½÷þ£Oò“?6øÍégŽÀ›€Ÿ9<Ûø»üžýÜ÷þ«={úòÝ'O~á»/ô{¤4O™ªj&¦7vO`tLÍ]Àäæ×¤õ,ž›ÈEU*x`àÿÃAU:ô´Us"NM^Qôßf *†k÷èƒuu`ìæ84öï èÕ-K@°jÏ.—8yg  ]¦?‡“¡³ª,jéO_Éú9à·ä«·!%¡æ`uš¶ŠU¡ŽuÎ"èØ§ÏÇ8 á¸"`„« ­¸ò…ÆÊ¾äÎí#¹cé.õÞ¶ØËA›ÀŒ,‡!jôaÀ¿fùB J%”EYª¼Ó‡þé€Ïx€ï輯ÉüóÃcwΕÆèW;?[^x)æ6 `JíH£oŸ­Âºtt:(ªºÔ'†r^@¯¸Â-;Òyÿ¢5F§ŒÑé3¾›$C¯Ó˜9‹mÂì/¼­G.áßÄPå954åñ¼NêÓ¹ã‡ÆÚÙÍ`>fÎ8s‰³LÙ¥õêÈÒ*Ɖåûf8é°Ù.|gÙ•ûyæ8Õ™vdÚ¼Kö§:~üâÅñG?ýé¿óã?ü»ÛûMë«FàÍÀWÐaÿÃ>úò~üÑßþöw¿õ+={úO|çå“þÛº³üÝ€¾zÒädb2Ï;irÓbÑÂìVêÞÐKçY¿î¡c1¯[E4~N½þ½nO1 Å%Ç„I.IÍl^¼ÑI@î =*ëê‚ÙE±ü›ehZ]D³\&÷ʼn“°ðÏ>¾õX“‹þ?öÞÅÙ¶ì:ëÛûÜG¿ïKÆ`›eCÅ6!Œm’ÿ"…%¿pœP—S<ŠTLRSW¨rUqÀXؘ,caã&Øq l!Ù’eË’ºÕ­îV«ûÞ{νgïsÏ=÷Þsv¾ß÷±ÖÚçÞ–[¨%õcÍsöšsŽñoÌ9×Zs̽öÚk i3Æž>ªM‡Ôâ ZyÊíÆdæû }¦¥øwF `QrbƯHQbÀ€êe[5¬†Þ í> ¤ä5ƒ~¶¬wN k7*øÝO î¥òI¯º'˜@E7±áÌ21GÇ)9-ïìDŽ=¨Ft;©“¼@©äIDeÚäN)‹‡Ø7vNRz ]™(±q¿Ð•ÓG²ÙÔæ%£]öØ=áã“Éä"rÏ9À«—5Lc{‡B¨ÜønêéÉayµ^Ø0¡¡(3 ŒŸèÜì,Yé$v2n"k›n$]ö±YÙÃçE„ŒQšá=] >ü€žzé¯ê Àmqènéž&T8Šº˜_>ש\tu;Ÿ(±™Tí«ë­›Ö·‰¶kSÿMD¿·ÒPÏAï"òÈI×O·"ãa  BñËùu(ªn“ŨLšÍ´Üâ©ÌÚñÎ!ЋãÌN•mùD0à%³$#ER£ÔÇ8@R ‚éšðà·]8¥ sX÷ñêrÄ[[8†±+÷°°Àß_lö¯žÿùïí}ÇÁáás[†såÀtŽ{ÅF30#ð±ÕÍ_¿wñ‰¿uýüÙÅùÍÉ×ëŠÀÿD°ÐNž¬Ué7'DO6œ\Y,4~ÈGŠa10ˆDÒ'9øÈGÎ>Ÿ‘€C’mJÍQi;9ðcP/S”²uí§mNsÒÀñkyò_dƒ­1Í9GàÏXm Šþ™Hù*à-µ{îˆDJñ×Ñë;•Àí@3©HeeSû·I@ضMã· ƒãH©z?6¨Œè¢Ç£ÉZÿ€Ü’×ÞRóCÂ>Ï”t‚€ê±§b«ö+õ˜ÙÈZÉðßuI‘t­dúŠž9TVâ;-G(ÖiÓçøØ·òS¼¡êؤªŽt<Ìj¥Â~bæqŠÆQŒU «Žìô BŸëèPR¼§sfw¹øå—îÝûÏŸÛÛûkGGºçoNŸíÌ €ÏvËþéƒý—>°^½ksùâ‡4Yÿ¾ËÇ‹ßvN³=ï:}0s@ûÀΑMq8ÈKå‰ÛrMBšÉ8ú$ÆÊŸŸé$ïóƒÉÎ<Ø× ãºöª'BU,Ö¦õÈ™â`ñ|ÎöÈ(ðßS†$-Sn $¿£nDðÁÕñ &E‘r7ÄÈFôåvY7 ªNå·û›É_B ÚŸiÛYy¤,FÒµ‹¶òò_õ×úl<*öD4Ô‘éå~X(†jBËÍ«QUÞÁÚ:©›³ueãÆaAËT$u_]® 0pà)“›—¼Ž3s±h þ—º/*;Ü ‡pàH½Û“‚çxQ·^ŸMÂÍiŽ´d›uŠÁæeÓD¹Å£JŸm›"FÜ‘<dŽ — DÖÇÄàCBc,`39g¨rl A4¶¼º;––6– Ïq г/)qŽg8Í`eôìw•d4r)¡7Æ~4OÉ6ç RÈÆºÂASu ‡ù 27IÅ0øh9Z|Ð7µÊðv¿X3gòbÑù$Ýj±ÙÛ=Yü7Oííþqþ'…˜Ó«4óàUȦyZ߸u°þ›‡—.Þ=³³ü#—îmÎòОcN’:8Ø™h}Y ™^}rQe.ç<ð‰QzU-ð ͉á?NùžÖŒ°KØMSECsJŽÚ'c•=y0YHã²J$pHSëð8 Z§M¹2ðd¢òh û‰°^·jò‰/üOÛ¶EÒ„Ê{Ò@•S¼ ª2œã˜ÕepÛ{ ì*ÈÈÒ÷ÜvO'pì,®FØy+¨zX!êΩí°ÅW9ƧäÝ7;½<Öþl΢,=ÈiíKçL¿Ð7îó[ø=•nÉ»ÍȺ ü4fZGOjüT‡¬å"1V0îw•áóXØ” ž*·?A!F|ÚÞÖ䇯em;öÑ s)èÓÁÕvŒ.¶Xl¥I§\,¥ýMêöë«uV6°/ Tù”ßhG¯Ã9P"ÃJY˺±–Mz®ÜPt꺹$é¼=÷éPp;ÊGe/ àÊ=æ=ÂW²½ÅæÇ^ÜœüÑoìýÓÁv.¼j#0/^µ¡‰®*Þÿúzõÿ_|üÝ·Ïí|éãõmN²œÓ*pòùi©N(Ä”µá¢ì:9BäR0¹â\œxÂGCò ˆ^/Ãj2):ñتC` düU‹"²·H¹¤í ‡IòjR&ê¿ÐWu+T¦9íø¼P²ò‚@b§õLbUAßã$QÏ_EÛðä¡!"FîwÎ8‘'&k‚& t4ªèJeîþïq‰ŒwùŸ b 'íDÇ‚„œƒ€¼¹·®XHÉàäÆ¨Ž r?¾¸|Zœ6A^û°»'¯ ¬~j,¸ p­ßEç×ý5th#¸JæÄ§êö¯ÜåÊ 6dƵÀ4Ç€ÀÇMt½-WÝ}êC¡X1ÑòÎËõ$±'?]r›NÓÕNí+t¡cÔcþ ^PÉGü°è±6×Pçx²d20êú`q>Á¥M‘å·mè©Ø.£€Ì&eFµ/í7¼m†»e”;Ù*çPÖ‡î\µÏc&¾iÛ%Ý”úäµã{âÙ7þòíù¾=¤¯z>/^õ! Ÿ[¯¯ýª>8¹|áÃ';;¿ÿÊ ÒÏQjò~ÏŸƒ?ç›NPü}ŽLÒkR÷IRgïâ8Tî“M°!!k9¶å$2ê%p‘ªê~+AVãڞ̌B>N&ÐoìU5bXHß>ºo@ÂY:0t;éQâ5ŸµcÒ<añ"Q‘”’:xåv¨ÉrmÑ¥ñg…lÜ8r€¤j8UXÙ%*IÆè™Þ7öW>ð£Ar€ Ð1à–g§ËÝnä*÷¸Ògj·Su'd P-í›}¯7jppG íŒ]‘N¿åÊ/u|5kë©·ÌmiÅòÖ7~ Afýi'ªÓV$x€‰FñÆcŽˆx ’&¶F>OÑ%šAl€lì&¾8Hu ¤2ݶ«4Çd-ÖT>.U·N~Ü~)©GZ©x†Ïï#­m;‘MsHã« Fuá#›úpÙà>o·À„§ûÂ*6$aÌ¥m›d_p~V ]î?Ñ»þïÝßÝý–—ŽŽ~%Æóös5óàs5²^},ð¡ÃGþ¡ƒóçˆeÿÉåc…yž¤Áéðg_*øR} ›Š'‹>jKÕ'iN.NSDh)û«jè!°trÎÒÉl®|˜dÍYíÀ´l!6*¥SæDî¾UÝf…i@ÛóüðÓqˆ.íç{ÁLºùé¤.¡Ç {·ÕÕ$GfG…0'†Za,3ð„Éã ƒÓcPæ#‡Þ(“àI«Ž0ÈÒÏô -Ï`!Ç>‡f©é±ðþ— _Öa dß4B²0ʱWÖmC5ÚÅ?d¾‚Á@¿rµÖ“óÀäI€+5×}¼“ ØÓÉ}8-|P½¢k¢’u•Võ;ÑmŠFÄ çÀ”°I[¯:E™aɾ¤ÊøOë.KNb¢e ©y¿Q¬„všÌ×Â) Õ}œªè}®z 2@ç˜"ˆS î÷êàÌ !üâà'¯'¨ Çšý C;ì×.ÓÛë:‚L›öA —m`KÕó—Ê' µ‹nÀhjdN©s<ÞF7¢þÛÍÛ?¹·÷÷n-w5矻˜Ÿ»±Ýb¾zëÖßX¯~þøÊ¥ŸÒ×®¾ôÂbñÖGt¶ø¤ãlqòiSBÊ5ÛÔ©#™þ=a”EƒU»_lj׈г}ŽøœüÂ!ÞT·'Ù+ðødV=˜”ÙØ¾j§/]›€vŒœ=ÙNòV"ØRújI+”{roò²w_S a7ªsáè'&Ó´]ï©ÜD3)2 MÙ N|@ ·3Jj±Xe2Æ»ZW ,R/ ¼˜´2¦ƒ@UÃíβ­,þ „ ÇßùÔà–‚ÉêäÝÿË^¼¾|Á>JÝmë|°êÆI€îA©šgUÆT®†p4¤Ò^)“:ÀD‡¶VOë(Ú¬åªÛ’‰^§Y BžÔÕ©/—µ±¹`Ô[ß;¹µÕ·0Ib²flióÀ0žÃ üqTžÊ‰3Éú×ä6fCÞãFyœ%ŠÊ}èr盫x†!C^|}N´M¼¤ýù¬Ÿœô®gù±—Ž7âٽݿ¨Gøê¹>sú|À¼ø|tùy~ÿŬìÜ¥K¸svñU—N_ÌÇÇVœ>uÆä’'µ*È}ºh¦>‘ûd¶°à ò.A„lGk³ZÒ_ç+zÛ ±‡3׆÷säkNín[ÚzÊSšŸK xŒ‰}»¯‚Ç¢¡ ¬ûvŸ›R2É´ÞetD`W]HÛÂË>ïnSn½)™¢«/S'ü¼°q;!­„å0~õtí’ÈXµÔw9‹!Ïí—!Æ$åÓ~µ¬TC›\§åtbn÷ß%0ÒЋ}ÇàèžÓ{ò™K[ y»§ í§ý£~¹2 tmcªrÀxÒLÒP„¶lh€måadlm?èâ«-¬d3Ø’z(J'Wb;5ìåê-7åhf±«"€Ã»Dö1¦ºy-lòLƒ§µ ~wnˆà´ÌÅ¢˜G¤ÚäLÆ®‡¾ì; sµÑøh¶ä&HKÛŽ¼ÛN_À³å!á·u¼][lþÚÝÝo~éèp¾Ü?´ÏSy^|žú´›­÷?üÞƒõ߸tùâ³ËÍ×\8Y<&—ÅûTÌéâwð!íSl´‘ûD,LÊÅ¡ŒzVöX‘b ‚I¡WãÔ-+Ä8‘Ô$%¥'c@JEй).Sdû)ˆ¾j€n•—-2s¢'¥i)k ýž:{£ârQ«î ¯8¶x_Œzò,Š8R‡©óò¤Å¨½Ã8ˆ—9¤ö#A‹u­e‘¨Æ¿ÈŠÖHð§'_ú`?4Iåd݇¯°Le”ë¥lØ_ÝoŽ%ž°#C®¬u€k­{š ¦_Ä–W7Á‚S›ÖŸÆLë”]Ÿ OñxlJ–€$È´7¶vf{mý˜÷QñÌv ¡|­#FrîEÈ´ažîÊhâ­º@á® à ¬W ±D†ÂGÞ}ãÎþ›roG3€8uŽ£>VÈÝrÔ5¸áÁ ì¿®9& zßP· ‘Ótêø“Ò瘧ÆâøHÇÞÍ?Û»{qóoÏ—ûÇû|—æÀç{Ä·ým>´^ýâѽëðü¹/~ìdñûÓ³|‰0çN–:ýUÏÔP'¢N*N&Ÿ¶èô'L)lЩHûæÃL6áô œÓ9­“ÀÓ'¤ÑÎì”#-ñÃrQÔa ‚­J8hx•›SuO.ÔUFÝiúÕ¸Þ÷ùË—U÷¼í-'›/:§³ˆrçdäÄò$W'1sINÈLZ”û=}òbÞœJЧMî°¸\("oáv“„'ÁR¥´Í[ë(…/UŽ`X¬ <´’ÒÛ‚ "ÉJ¹bÀDg€5\XLsèO:7˜Œõm2,2—`²þ1±%c2$•§cã¾Ùsú©®™ ïòäã‰=Å-¾"GB%ÆHòM݈‘š%iß„À7—Oƒ`Œ­Mí¬(£:¤iÅ|ò¢|çœ&eÿ`} R®øÛÔFDÓj5aKf_SåNOê4Á¢Âw ‹¶ p”[ž¨“DªÂlITÁtРªŽcgJ›£$¢æ!f¼òi²®€`:•ÈÕ.›Ã BJ‘#óT›íi›cw캰²íåHÒêÑz,%0”¡†4Í›¯³;ý5¦u#Lô>ÂÌ×aïq¹¹ùÅ«‹»ßôɽýwê;ýà×yPß0ØH>Mt…ô }x£7P»L.“Uã!Rž{IŠã¾ RZa×Ù |ƒÃ ÷Ж²ÛY :}Ü7}5º«£;+ïò$/ôuè•ep½Þ k;X‚KëÑUt\Y'TĺS— “0G£Fc0ad&Iò¯%“,˜~a:Ú«Œá¤ˆH±i@`H½GøWËÅîÕåò»ŸÞÝý΃Ã;ÏÆjÞ¾–F`^¼–öƤ-ŸÐOÿÚzõ÷Ï^¹øov–ÿÁåÍæKÎ+òû¤ãD®Ù§Ô¡%Ûzt¯²+R¿Ë6‡l|N›¢`ª žb_Žæ2³Ó0Ð$@])ïôS‰]|ÒVꘉvmcC)™|l ¥„¼Hî³ò©¬ûˆ0eù‘qûatè#6ð’gƒ€Š’…)ãÁ¡½Z€¡Ó WÃl¢¶ãÓ“¥ä¾ Ru‚vè« ,,šä].N;Ϙ0à±P±,‘Ggš­zëÈËJ•Z@n>}À×ù@ý»!Ÿ,ºMmöJsÓŸWC›“ýa‘Àtm›ïšò¡7EÂRn\7ZË'3ÖÄÄÊÆÔ-¬S™˜¨–H¥$ï_}XH9=AO'‡vQÖ«÷§/ã é†Å†}Üã€Ä<`† ®}pt°È‡%ʆ†Y˜zx°j?* Wr_T0J‡¾¯lY\f i»]ÀQuðáA«çK¿·³yçõÍá;^ÚÝÿÐÏéµ9ó൹_†V=¹Z}佫¿ñЕ˷Îm6_{Qßàìw€ ìI…‰$w§vì(t¢bÜÉØª G)3Ÿôœèš€3Ñ‘g"`0½»@{´–:…~ uäI)yRë Aµkþ1¼}´?ê=纬z0´N%Ñu(ÆÉÒvˆ: Ûír>©ÃÁ«X ¤ Îïò¤²¦½üþƒñ&„>)WZª¬l Ɉk IÙøJ ðšµ=ªÇ›v\hDX»ÒzÊöÑŽYîœñÀ/Ÿÿ÷M€Í)Ø$k%´è½Û‡ö«ú ¢Üð.cÙB•]œÔ¥\ü$ö„åÃ&°øîò0Jâ5u)Êo¦@Ä}A¢J˨:•l¨š“þ„×-0*¸ÓѱS*kïS•'û;>B°…mûóFóÀˆà˜ÉÍ~i¿5¸Ç®aTT¦šñGÉ9žàÞ6ã˜dœ©m‡Tð˜Ÿy`£‡ùèrÿbó/^Úœ|Û'w÷þ·ÃÃ{ûaŸ·¯Õ˜¯Õ=sª]úÉá÷,/<öãW:óÅË|[€Q¯>‘¨©Ëv2çPÓNéar¶|¨èI¢yȇ #]‚Ҙà [O$.oûÍÄEÏQ±±™o‚„÷_ÇfIÙm„»˜wþUãÀ1hÈP8!nÓ.»§ð`5ÆÆÔû lÅÄ.g Ûö«@èG$©ŒRqmÈ”rŽœÎð~&[îú˜h¸ûIS¢À瘬±_}T†!ð¯)_ïì¼tusòçžÞÛû®[·o?ä¼}­À¼x­ï¡Iû>qp°§ûÞ}îò…÷ïì|ÕÅÍæ·ó±@/8…3±ròrvrrúµ<%NZO üš¸¨IÃL怇&L(Ôú/7ü…c˜l„¡ =¥q5‚ ó£JöexiI°hÁh²‰£´@ƒ ¢¬4õ×mCÎäÔ¾©“0ï¦hÃÍIày•• ²4Vm”]ûBOrÿm¬ÑÁ™8ÝzÊn@ÕSW2Gµ°ñÒc.œZâ-bžA¢ÌkŠñtŒÏ˜¨-ýƒ€à_n£C.ßèÑiTÈoÜÒG·U½©™à†Úß ¿n*˜ô‹úVò8lI v»O‰¨Nˆ2J”Ü™*Ûh @mh}ç6\LÇ„›6ð&¨¥#±?մݬÛ.]w·ùÝ´6 sú?pÙw¤ÑßP}¬·&°®Ù¦-ù  #µqD,„|cU\6Ó)]ËcGXÇã6sfŒhÓvôµÜÝ¿»X¼s÷öíw¼¸Zý¿E;g¯“˜¯“5mæS«ÕoêcX~ÑåÇ7›?|ùÞâ!¾ï`TH˜\Â'y^Òy“ºdUSÆÿ8±TÝvlÄûøÇKך„Ë„€u’™ËÞ:m\ã äù¬ì7i]Op¾MÍZO`¸Ð‹Ëê¤á«ƒ©FF‰Ú.\Ë&æà…˦“ŒÈÄþ$¨¡sÿѽK.÷ØZ¹Ývƒik5¼ÛÜ É‚Q=- »$6,û_"uÉ6$àPÀu3M1‚¢w¿ÅÀƒ€në ÀAßPWš{^EiGi‹ãÎÆ©àr z¿FË* Ö¨£ gJ!¦ wŽG¢Ì¾ë2˜jǸ3ËFÆ5/HM-Ø0¶e’ ”ú7!× `ºÒ«ÜR$#¦Œ¾Ó®t ê‘á„s±™Z~ ÓTP7T9ý±!bó†ØÛèX蛇Ñ÷rl+Ĺ™Åê=µCw÷ÿŠ~ùô?{~w÷¾u÷î Äœ^_#0/^_ûkÚÚÍ“ûûÿòü…ÇìúCg.>±Y¾­¿-௠ÖYî]V™¨rÆ÷Wôúü÷DáÉ¥'²LvÖ<ʇ …aMDÈX ô»vfLHÀzÒ±E½ì[³ Õé» S<ÝÈ‹€è†IMÛJ6ä`$ory¿°GŸv£¥Ö)~™Cbw³ é²-+j,\p¬†Åu|RðUõÕ“ªV; Êè—-h8˜ˆùL•Ô7{e"krìÝ_(Û÷ä…,„D }׃³| š>@þºåjZMÐ…¨’0p™›rË•[Ö00­œ*‹¢Üù”³Æ¹8é¬Ç½x›5!6IÑÑî®·Ѷ§ÂIH[Û¤sì9Î}E«ÊÈÌ‘öTï«ØT §b=üÍvÊIëÅ*Çh„®›‚z±YŠ—lJ«jê[œV½õÍEPââdn•º% ÊFózgyKŸóÿ¥göö¾íàð𣟳×áÌ €×áN›6ùéõúƇV«x÷ò…÷ï,¿êòÉæKVTɯéÀ35ÒÍôÉ Mò‰®™Ò4Éuè9£`Æö%xWàÞwª›SRê]®©8<Ç09>F˜:‘ñneOJ‘ ÙÁ’Mhtùc"l2ÊÈðÛ—Ô±KJ·×_´Kì㇭?f).s¢/Á²%ydÓ¶²§HÍ&ú /Y°u;ÒÞiÂWw`e‹&ÈÚ¾sHS~ÏèÝþRù¡œèk€‡âº¡ø ßÝIÂJ=V8cL5e½=VU7@ù™XXœ Ê©.R$¼H H–5´”ø$õ‘B¹!*—*'×'Â.’»ÙÊý¿òB?dÄøî9Œle©ñ Gl“äR˃©»Ïä#&Æîs Kß8Äè'j_ÔsܰŸ§‰‘‹7ÛV«)ƒãé¡a‡úØH?Õû÷öîÝ{û‹7oþ_RM]L çòëdæÀëdGýVÍ|vµzê}ëwn®\>xx±ø/ÝÛœ;+#®œÛÃÙÚÅh$è¹¹'žà•“¸amz²%GÆáðc‚Ì GlÃAÛŒ¥–:ö¤~Wå²€C(Ë/‚ +9ÿý­¹•Ó¦ŠqD>À¥Ÿ,† ´-Š_åOòæBÝwUl¢zòàiúT2`täQª†¢·oÌ‹^©ÛÚö™‚£ƒÀv´Qgœã2°^›Îm© n þ‹³gô€cpGrnÜz¶w¢Œ¬ê=&TéNË©»< t:-¤Î+£6-o÷7Öí…vÕáfQ3Œ6HF¶Ôâåt[©Û»@µK†þ4¯ÉÔN®T9€š$ûëì Âæ=^Ä"ò1‘i ói v;L8]µUBKðRn9Ö‹¬å”“²ÄÈ8Ábª5Êг(ÎÃ|¿vm³ùãÏííýÕ[GGúØNo„˜o„½8öaóÔjÿ_n{äÇo>tö‹[.¿ú"¿- ½ƒLáºîÏP@8íkÖ¦&¼ØS„¨Ô î*sPq%‰¢'Já†i’²žðT¶ ö$µGë:Å8ÅaQ‘ÉD¡¬l<¥Dïà‰%êL–ÐR¡>M´/ìÝ×'ìyÑÌA,A0ݾôvDÆ¢‹{ÂeñØNö^@Ií{,$ïç+ôMÙ_3Ó$öAC4Fdl»mÔá!ïa58/mN¤¸-ç·´àÑl¼ûÿtÂß«8$dNåÓ ÒÖÒ)pu­Y»Ž²ËOe*7q©]mh,&ðèýÔ¤ËcÊkZï²Ïh4ÎÈÈ©ë/˜Î¥,Iïã:8Þ®ƒ$a_G‡ŽY;‘ =Ó¢$ûU‰¥H8¢èsÜjmÀúVŽ7ÚÕGK$i»qø»ÿj‡}ÐYºZ.o_;Ùüåïíþ1ýTïoX¹wóÝÜÿ)ZèæíëxæÀëxçýVMþæÍ§Þ°zçÉ[.¾¤w0oÓBà Þiö 1±1MœžP2uhV ÔZÂJl˜‹:œmKÞ—Mñ¢‰”IÇsjO6EÐÅ“&n‹|ðAÀ+šž,aëd^Ô"7®ªù¾}Ç >)÷ËvUW *Ñü;(cPí¼äc²´ªAçÝ(‘Ó0 "\UÝF² °H›ÓüÈ«×.9IÈOþvç‚1›í!ã×jp(Õ¾|øA@RNÛAyŽðBC›\H}ŠGíÔÀXHÔ¨2tr^-ÅvŠlßÞ¥¥ ó8¨`†•6Û¶=R—K0Øàl¢8©ª<©QtãÆŽø×í4\ЮËzHÝÖ¯¹£e×]í4s—] ‹cS„­À .êUÎý±“}ªò´¥ˆdŠCæDÁ_óù~±ï;ŸÝÛûÖ‡w®I5§7èÌ €7èŽvK_|ïúÊ¥¾ufçÒ£‹ÅºÄ[oýOdˆ©ÀˆòĤš4‰†û*PSÇ‚Üã‘_¼u—G+øk&ÐOµŽ`—U¥}$LÈTG„QU%åj€7 *ٺʭc;¥Ô-%÷qP —i„,„m»©.6Eë¬OqYð–BºªÙz­|³C¼£ ênÛ.Ê?c]ï†AIr{S|`ÝBÜê•c5­¤m¤é9Ð=ˆ&­ï>€u;¼3uwÿby´·9þž§öö¾E—û?„~Noì˜oìý;ôîêþþᯯWÿèá q}vñ•—7‹/ãcé"À“…&¦OB H=™drAÓ’PX\Ö6®jšuR®™Í&èÅÑø©^&AOj¥g®ƒ6ê*< ",¸ai+u÷D+êEqzvï6 Zd ËÔ_mt[(Y_léodÕŸ)ÀxÑ9À‹—š^X‚¼ Õ•ð=Þ€E³<ä©þ–ãF9îÒdÕ=žpùÇ€ôÀæxqWüþ1 Éý1ê6«¶ÀQ4.à‡¾öþEGšb¨EÞ &[4ÈÇ”Z3µVõ‚æ8*| r²ôMÞÙns6cÇkó²í=6½qËÕIú9àÜ”1töG_Ùá` Ÿ*™s°õ’|¨æÍƒÚg]óQÑ‹þtÿû£†ö_X½—ªi;4àìS$´û®^»›Å?ºº8yû§nÜø A¼.;§7öÌ €7öþ½¯wO¬>þþƒõž¿ra­éák/,>«Ù€‰ß“‚,8û„=UhÂÐDΓ–2®Œ:X´óÉ%HÙhÊ1A&-¨œ¤ï wÝZë8¹§Ï{ðc@mãÉÊ“<}‹ØmzÚö l lãˆ$É=L;[¤œ}ã$šÞOÃçñ¦`ÊlIÙy‘Uåb*Kï,xàGÃÎërÙæVX¯Rµ-x[Àv¥]š ‹À—çÉ­5ƒËmÖ9èhF¥ál$ÓÐ`ƒÜôi>®j}t+E¯c[ƒ£‡õâêfù§ž½qýÏë§z_ bÞ¾YF`^¼Yöô©~~tµzϹK~ô¥sgŸxüdñ.0ë(^ô¤Ã„B€õÜ"\b®& MJÄ•žhàèd™ôÌeÁ«\u ÐïüÅ Î~œGŸ`—€ƒð…´€´ ¥¼[-)Áôñ·±nHÕm£Œ òmžøÁ?,‚Ì¡ “;¤Ý?‚•íEžd‘ŠÉ3†žðeà ŠB:à9ˆµèÔ0ÆÆ/üz€EP æÝ°ítë–MÙ £Qè´8ÏÁ±’ìëm~ß©}Ú&¦îŸêˆšw<,$ à#Àd-Å*eÆpLå •ŠFhãj×Gf•k£,Mi´ò ‡>‰IDAT3oQâ‡b/†Ðy¸ZÑ<âDé½›R•Fx‡”œ²’·æpukCðGŸc©Ë#ĺФÏ]7«Üçe†Ó =ÙÄŒqoOÙSºxOÿXêàÐ×ú¾ïúæø›®ßÜû7c«æÒ›iæÀ›ioŸêë3«Õþ‡Wû?}æÒ?ûÜòw?~²ù]i¶ìɦ'rO˜5¹37ùkKRø]·ä(-?Ó9l:¡u`óåi)˜œ ÄãšóIcEoð*¨¾Ó÷$«ìiÍ  Ô|–ºÖ³©ƒ%xø& UU¸lTGNYA×u{°¡&^„h±QÓ2ýäVÑN@6 X$–•Ø‹rG0P”{°)âKýxcØh‹V4¼Ø¸Ü¨Ë ¾ ê@ö5àI‚Ãi1˜¡ŽÜ¯ fÔ'ýK ¬miC»n†¢i™ÍTê-(ã–wŽ˜r{ïaïßn<尿ùbÙ²œì<Æ”}»3ã·7Sy|åxœÊÃ6"Ç›¡<©·QR|ƒÚÖ*Kð.ÄÃÇ ÏîßÛ,þé{ßüɽ?tttÄúoNoÒ˜oÒ?íöÇ×ëgÞ·^ÿðòÊåçõà?tYß8£™ƒû<9Ø“ ³~þKYe,Ð98”Mi"8`Ä0—Ùˆ3”‘SLT 'ù`'MHÀó%o•h<¼x˜Ps‚Ç¥¿€-}Ä^2\å›eRç¥êðºýr˜ ßÕÁŽ tи0Ô‘›+bw4X+²ÀÀ^/·Ubô^ˆ)g\<†=@4†r'ìôòîC¥'ÿh ×ô&@“ô[©êƒ_x àþmTittÝÏmijC‘š·”)ú¨ðNïÐ@ÁFÇ÷ Úï@dAnäcLÚ ž¨Qj/ÕnÅöÆíD þ©Æ¨õ½¦kZï­”…ÆTÆ1Š_Žóæè_„™¶rÕgLèŸã[ÜÝ¿¿\<}}³ù®Oìí}÷úðèù;—Þ¬#0/Þ¬{þýÖC„Þw÷Ò…¹~vç‘G–˯½pOSŒæ&+&¿˜€( )Áº'Séz*jh瘹Ì̧‚qž3Ýfâ“…f=*ª-²Á¾ƒµùJGz(U3ÞµÈé©Ý ‹»®›CB|t Gq;—e, yJǘ‘šSˆËδa õ†!@ÒÔ2f<"&À '/뵡<^½›¾©•i“¯¢\êI€’x }¾û:¬¶ãØuÑ‘=©å]tº‘^Óûéi«’Èdà@ÑØZÚS×ýzUÚn´–û †°á=Õ*Œ{ U<)›S¨¡=†ƒÓËûª4§ÛÛ8Á†@O™!úXŽmËo8…1xºé1ÉX£ÇÄ‹bþ[ªé&¿ï»¾Ø|ÓÕ½½÷N-çò›{æÀ›{ÿß×ûV«[¿¹^ýãËöö™/|³ùòG5£ñì€~‡Ï äINÖž =AAåZ¹&$=¹ö¤¦¨uzâÎËŸWgÌØö¤‚^O€hIžä”÷Ýr+UÉdê(òhaŠ©³õ<ïÒ9J½èw-ß/$ª­`Üˬ mïD16‘Àsš{'‚ê…Å’vNh‡10éº?8hYŠºò¡+zJä­c]Ó Õy#s—&Ô©Z¤õ(¶R£n#°C2•Žez¨w°%p›¡P‚`šÃí°>›²ZkÒi¹Æ1„ùw_2þxiÆ‘‚Þæm†Ú– Ë׿qg«åU'#õ1kw¡µ¾Ò.× ŒQŒh”ùŠwl»Û¥»ú˜go±øç7Žï}ãó7oünòã¡sšG`y0 Å\˜Ž€îxîWV?rï-—^Ðo |Í•“Íãç43ù¦f&~V>“•ê*gòËÄç›Ò*òÍX—êÈ:Qª0wÛ ¤&÷ô']ìÆ// Šg÷ë8®@¨ mÌ_·©9!)2 ²ÛAÓx”ÒËjŽQõD¸ ¤°®mÉÅ -/â®Ç±Èӻѩ?{6d8UìeWŒ¬€!êä_~$¨ÈÎòVê&@ÿÁ½“<õMœ<x&¬lÔ9¶mßî˸u¸%áA#Úüt`D^!Ô‘cdoçp¸–™°Ü¨ blCŽHmÕ€á£w|ä2‡[1ÝÄ[ í·vÅP·¼ôEk’Æo§‘wûR°Ò²?íϜѴ è|T÷tœÙyéÚæäÏ}bo÷O¯æËýÓ=7—ǘãXÌ¥ŒÀ3ûûÿV?9¬Î<ü>¸ÈÇšq¸"à ‰HÁ…IÉÉUøΓ“#e†¶=¡Ò«?—‡—ÉX"ó

~MÛzº?ñÓç ØøuÉes±!Ñ·Q-q{,t«2""ƒ¨¶ñKŸø‹”_ì»¶³ü?öoß~Ç‹ûû¿Ãœæx¹˜/72³|O¬×·ô¡|÷Ê¥rogùåzˆÐWôÇÖž€<7%€(’kžròÜæI­ê*£DŸ)+rÆ"ç-1¹þüކ2v–9êˆddMU)3;pK̰͌tÇ­$ *—£‡û ÒðÚ¡dašoã·àÌ‹³²Cæª7™ÂÁ$@o‘¤­ípð«Bs„&ýiÎ|FôCrÚ·rÌ“ô€Ÿû.ÌÍSˆÐWeT¤úÊÒidBjÒÊ)K™W¹L¥Iºõ-Ž}×dRßðV`‹leÓ›ä"I[º%á©}74hôC)vc{9ÖRuic¬6¤®‹}ó˜HúØìftmÆ$­†’Ò]­0÷–‹¹{rò­úžï?¸{÷Ýœæøt#0/>Ýè̺­xnÿyý¶Àܽtñã'go»t¼¹t^3¢'2bHß„•I USp†‰œ^„>Tƒ}{”Žîp²½ò!Pg"“4³bQäWL°ÑÂ"m‘fxŸÅʱÐ-rÐŒûû·ÅpáQuŸâ/[‚úÇ?zêûRÕ6¶±>¶éïÛÞȰET™yÉG[­ŠÂ´0àllÛLîàYh±ÁÈùéTM.1}®¶Å‹jØ£·¡<%“Ú‰‡qc×AëXº<Áõ°ì®…å›ËûÙË“ÖO8¼_LL×G|·+#‹<ŸÕ+«x=%Èaä ¤a¹±Puõ—v¢ÇPÇÿÄ4Eéã8ò:Y|7‹kW›ï~zoïO®oß~æ>“Y0ÀËŒÀ¼x™™Å/?O¯W¿zrþܯ}øì¹Íæë/=•¦ a’St™‰O//O`ƒ5ñY^8ñ˜Lù”ƒ+L†È|i]y§\°Æ"䪒u`§ìD0TW*"Ç+S¯[èR¡Ç¬>Ìí¢rm¿…†ƸÊé]ü¥Ÿî~犽ëml›´(,8Ð܈|µ¢‰©¢f ¦:)ç À¡"É­{ǾÀM€Ó{Ú¾ñey_Ö-]ãG‰4êFsË´¯`~Û‰ú–L•Ó²­¶6 óVaJ+Q?MÐþ§ºI¹-ɧ/ ÔO'ó”oÀ $iç‚ñbdÌℾó×àöÙ,‘·ÎC½®ž,~pïÌá;^Ú]ýó8™·ó¼ò˜¯|¬fäd^ÐÅ¿±Úÿg—.ÿÌݳ‹¯¸²X|Åcz8Ïç™NÈL_¼¦Áƒ’æ´~‡ÓîÇëö4H>ÀçD:NžqÞ¶6ìJµ¡²õv9áÑi5w81§m檜>xF¨W÷É´9•Ž2ÅNiw‡DI[©Üc ¼ù°i5eøãƒwèpÐë)bb‹X¯‘f¡¼y<^Áæ#ÌqÓØB¿ýJç”ëD»’0jÃÎGÍ´Ôý1¼ £EJ#o,{ky}œ©Ü»³÷Í4ˆŽm‚a;ÀF÷`O-MžñnY·ÅŒ«=ì¿Æôq=`­ÈÞk¾ºã_ÒØ¡ëVMÛÊ~‚wýÜÝc¹ø7׎¿]w÷ÿ¯‡‡÷VƒŸ¹0Àg0óà3¬zÿ|j½ÿɬþÎòÒ¥ÝÝYþ‡—7›+ü¶@ê¶ ÎôçiL³ØP¶¢”Ò£Aw_2dÔôçôtËò6ó¥]dòìph3¶þ³èGG”jcMÅ~w.Pv.²*[ÅAHõˆ»%§øâT lûH@Ç!nRŸÚÛΜ””ªŒ½o:4k«dYz]ýׂ\8Y¬õ-€;’óîŸ{j&–±gK;H‚)œ-IKƒë-º~Å,¨±ì’!ÚLw\ Þ¶ÍÖÕl”ÈЧíê+§3ôÈèøˆ³UqXqj“ >.'š•¼}ö` Û’7—€¶+?iG¬-o\å‘mÿc10,,Út£æõ«Ëåw?½»ûGGO2Ÿ«ó|F#0/>£ášÁ/7O®÷?øü¥'Þyçìrs^߸|¼9Ë4׿6è²êLptx²S>ýÊ Sk*ôÆ“ƒ·A&_Hü®]2ÄÜå.Éð1„ßýsË&Á!X?L¿ž½‹ÀåpÃÓÁd8AŠÇm—?R‰†À=½d ú´Å~‚F† YPN-%ô}­ŒðÆÂX³å*€Eƒ’‚8±”cH•U%÷9`Ëê¶ ·y Øx¯¶‹Áö¶½6'ïJ»'iy¶Ý6ò¤¶Ðþie«j§n¼bѸFC=.ÄnÑôÏ:O;–«7iÝ´¸À3áÔa¼}ORŠ[m'û&2ÂMݦÕ·+ 0GlT‰™ð“£9 ‹ žþøÌ‹Ãñ™ñàØ>Rð¿¶Øü­ÝÃ÷¿´¿?_îÏÐÍÛÏr†ùí³ä™ÍçX¬V«»¿¹^ÿüíK~âÖ¹åï¼°Y¼•¦LpÌk¼zd^t %G® 5ïԉܞ8)+¡'(—Ø ŒŠ áTZãÌea|KØ"|7Ï ”À÷d 6´Œñ:µµ'8P¹¢MVn•Êí‹€ÉÄNbË«ƒh›6GëétëF¼Cš×Ó0 /isc/ŠBà"Žù€+Ký -¼‰† †¨Ò’þ =ÂèbØ-Mßè ~Ì ÎX¸(]³2ˆìY³´Ì½%7¤”·Ì_ûLIÛZÏ‚Éä>àZÚ¾íR6ÈÛ.5$᪺ô¿i¢=[[³ÁƇ£÷zÛ[æc ëØ4 zÒ1—û‹_Ý].¾ý¹ÝÝï;¼7_îÏÈÌÛWcæÀ«1Š3ÇÖèi‚×>¸^¿kqùÂGŽw–o»|²¹ÌC„‚ýsk"ô„© ‘É“i±‚ÁøN9vŽOB´mÐlÃ(óôÔÍ4ë9yÈQ“¸*^pHÖñ mÍdL¦ umš‹ËÃLòÜ»@šâ™ßŠ”§,ŒGè„-4´µÔL½Ê…wftlÐcC›†öÒäÚ“ÀÑf¾á›ûuÞ?ä`oBvÃ:²PjFXSîG2 ¦0h©›¾}¤Ú°Q*ùVN%i ëY}é¿{ž’‘Ò Ù;:¢­íè3ŽØ§$j¼Ðór= ¦z©­o Ž]·AYãFLc‘$å| /B»oñÉv½XÞ½º9ù±÷mëÃô͜Ï#ðjÀ¼xµFræ¹o>¾ZýÚ‡ÎÿðÝG:~±ø#xTŸþyˆPsRMÒ¹aM*{ÒöÔ %cÂM_E(©ƒló¸R3:s0ó~¶ ®Ô¹Ò,uÞµ˜È|ÅAѲ¦yºƦ¶7yêæm®QiÄÔ¼Un‘ð´3'A¿ â“6„%@Êè5zn qÒqýc•júlc©Yñè1އZrÜÒU€;²ëß  at¡-œ#é>€¢–:#n†€›Ã-냠sˆ+k¬ùªNy8¦ kåÆví²ô õÏ•ˆ$˜øÃOdƒO¦ãÜÁ;ŽƒÛ:Hu“ßß¿zïî7èa>ÿ@â^›™Ó<¯ÚÌ €Wm(g¢€>³<úõÕêg½tá§×;;_òðbñ{§ 07úMœò¼«fEˆF¥ôaQ ø¤O™mí?•`uû»©ØgŠ£žÀ¬À¿»ÜüêµÍæ;žÝÛûïܹnNó|®F`^|®FvæÝ'W«ôÛ?¦o |@ï>ߪú÷ježd õ4Z2R.«]+ w C¥~ç¤â¡'îÄò€2=‘^¼‰F‰ÎŽHª8tZ.€aã µ1¢Ãwß©Žó(7A%ÚJ»š&0n»J]&ˆTÈmyo¦ãÒüÝÛЉÛ"±<Hß8ÔG·5þ€:2.Æ«&°LÛÅ€u}Ú3d¼ðí\›î¹5¨èƒn l7Œ=öˆÕ`r·»eÔ**3BÆÓm+CiZ×äû0V|·h,ÓRð)#2§ Ö«â}A^mi¯öU4wüLÕ}ÌjLö—ËÕîæä/=µ·÷m·oÿf<ÍÛy>·#0/>·ã;³Ÿ¯÷?üË«¿þø¥+g—'_{ádñ0Ï®'×ýìš™—Ù—¿æç‚êŽd£ÂJ‡ãž==ײ©ˆ[s¯q]†¡q˜-(ÀNùÑm ¾1ç_@ü®O†þ£êµÂ.½ƒÁ„6Áïפ禔¾±œv”Q¬„³“ǪˆÉp@|N²¡ý:¨IÇÕ >à¾pK žpS¯ñ#€Øf %˜Ü“ÉhWßð!ýàºÐe–~…¸R;Û¶‘HíóWýÊy™%(«s¹BÕüÍA3/ò¢1Þß°VÒ"n~Ä#Tz±/Hdæ¯22rš¿¯š4Ž|(Gh¥ˆNøœgù‘kÇ÷þä³7n|Ï­££]¸ç4ÀçsæÀçs´g_[#ð‰ƒ›{zˆÐO,ßr郺ï\8Ù¼å!Þù)xr­Y”Éxë342½ˆÍ=±zÒŽ*ö*»@†ÜQÞúÆ;é€u &6:uî‰;4v«MT›üÆ€j¦µ0ÊuúM…éÇEàl:‚‚¯.cY ‹–T / >Ð”Û Xªå_õX¼èM¾7@æ Š‚©£·åü@«š»‚ÞP#÷«œ”1B€ˆð©S›´LåÁÐæÖiCîý‡ iʈn±)AÛXÚ‡gî 1çÔ_¢IZïJ¡J掰ÛW·¼\[iN,Âg|4fÛÓx,™¶©ã¶«íj±<¾¾\ü•'ww¿Y?ÕûØÏÛy>ÿ#0/>ÿc>{<5OïïÿÆæâïÜ?·£uÀòkõ#Cg T\p pôΤM!”"LÒO3ºMÀáœK&ct&r wp),Y»°=$U¬~ŽdÖIßa3ká-§¬~ù(ò®mUt¥åUµxÊ'}öBB x‰o0ìDêö |*¸ÅáqA©º¥Àmå<ম  Ã#`%©§ñ‘1 ÊÐØ ¬d m|óže–D[8H8§šñ,u|Àü£+DUà ™÷q9ERë5}l+PË«)Äi°ŒsÑtW% e ²t™4–ê1ØGf6ïJtïŽV`×w–?õÒ;ßð©›7ß%Ñ=½æ4ÀlæÀlègÇÓгî~xµúù"t~ç‹?Ù|õ#úX€€Û¡sì˜T=Ñ2a£©Y0 ‘Ñ×ü^“2–5ɃÓ+qG¡AÀ“ 樢߽Û~ åÇ2qxQ‚¢òÑ€µ’_B;%à ãŦÛn¢(Ê}é†E@a|嬗6d?å|œaÚN§õnŸ+·¸ PU‚”1‘Èc%AÊÈÌiµ1Ùuû—ØE#š, JgžÂûŠOÛ6pwÐ¥L¢^`Ï?Ùä…R/uøÓ(”Úuj]G G×[[õö‹+%ü¤µ°I õ‰Æúæbùäõåæ;ŸÙÝý‹º»ÿª•óf/ðÌ €/ð˜ÝoÀ³«Õõ¬Vï~èÒ•­ûÞª¾ôa}V}¬àê@›9¹&í OÈ4áæ¿*Ž® €LÇÌÅ53Ÿ'N[ÀþF\î?0B8þ\¤:؇¯Qäz©Y|ÀÙº²ÍJC•4¯ƒÞÜ/äð#y­%ì_YØà?c.Õ0ÅÀ¹ŒG…@réU8£ƒ¤EÖ]µ-÷à‰†º ΋M¶eoL¼¦¸ˆ`p’ÚížÔ»HNÛ ;DQ”ƒ=êv»â±Å6‘ ›JM×õi0žê~ ÃÚ©wm/ ¦\½ —>H«6ÂåÅ 9Mé6Ü䧇ùüµ½½Ýo~éðð}’Îi×ÌÌ €×Ì®˜2­÷Ÿ|ßÁúo>réânZû×N6󱀿-Àä:IYHȤÎKºü¾W”%€#‘1VÓ6ž¸%Jª` ‡{Âcêˆø•ÛÎ$å'a;豑á´i0<íVµ\—î„#ÀS÷»Àpõb¦íœ LÆÇýGÂñƒ@¹ {`ˆ®´wwKµôõÁý3L9¤´+x¶*J‹=¦= '&)·½tCòÛëp/…3œJŒP¼– baRß{‰‚-²Ñ*<“öœû) È©†9XˆÞõwú?ûâ½{ߨËýûPÃ=z˜Kó¼6F`^¼6öÃÜŠ—¬WïY^|âÇΞyËËÍïBW˜s'v&k&`^ýîŒ œ»! Á€‰Z"cF›wÿ™¾ÙrcÛ€Q9áÎZÛD& C¢"+SM8,˜º%Žú`å½Á„Ùš<†ÿÆYåMÇeÜRa¯ Z§Æ×D"NÓì·`n?{Ë< vaš‡¶tû¸'à áN·ªÍŸ†Æ¶í-«÷¿Æ;ô!'y|KÉ3Œ·F6ªðì~}¥òcz×ÿ§>±·÷_}Òêy3ÀkpæÀkp§ÌMÚg×ë›\¯~òÜå ï9:sæ÷>~ròehFgÀÌ|Lê Û•ZÑAÙørÏê%†(( ‚!%PHÛÌr‰,%py€eàØ[? K% hBà"9й¤~‰‚S U‰¿©ˆ1ÀWHL R²¡lˉ…Û™oøA@ó$À6,ZN©›ïUSÖãßíïúÔ¢Û1pã§ )»}‘e¤Fy´®êï®[&âvMµìx5ŒÞ*#s[Vj¿ä£÷Ö¦m–k7?Õý Írq°\Ü»ºØüÕ§vw¿i}ûö|¹¾¹ôyðÝ1s³îý¶ÀSï?XýàC—/Ü<·³üš‹Ç›G¹ówò™ác㠾͙¥Ÿ>V=bâ ‰z'OæEÇß“<úÆÇ; q÷Õð^&g1e‘[ŠDZÚÆQ_yE/^¨H4] t{;Çf“t#¥tû£”Jí”/lìM8®I(:öƒ€VêÀIõ2Ün•ÆzJàRwàÇw¾ªGbdú`ÇÊÆ¤ÚÐ"ðé_qJxbÔ\‘ÄÆ°ßx 9|mcÜ}i9n”—N”xµçm ‹ ékg€áÅÝýúµ¾vmsò /ܸñw%šïî× Ìéµ?óൿæž­×ÿzqåÒ®Ï.ŸxôdñŸèŸŽ9I™äÉ›zÏ莄¿HG4LóÖ·×p¤mñSÞ;püUž.EmQ:dȄϋ7Ãýù;xShçzRDÏåóÂ)'™Ë…ÑÞßN€c‹4mJ¨µ'ÛbÚ~!Ç„äœªŠ•”¼kÁ ±DžÀe Þùèk€GÒðk€kɆÀg*,Ò¿öe1©z\©:P׋6‘º‹n¯7£Ü|…¥1ôWëÔ¶¢Ùâ›qªv©Þ‹„ðœò+¡ÇHþôT9ÍÊ ¾xtýªö¢(ëîþç^Üœü™§÷öþ¬~±ïÙSTsu×ÝÌ €×Ý.›ür#ð‰[·ÖZ¯~fçâ?ïìò÷ècßõ0“y]¯(mï Ÿ3>É€¼ó#¸%d1€nx‹¬~÷J½6ÄævÖ¾ƒ¢ëõN»AÜHȶlùh³ªÀ»O*zó™F)³¾Ü’ùg‘-/¡ \b#û¡¬î ²<˜‡‰Œ­%sð Z†$[f UsS$BJ™W ÁQÝJtß[ÞýñØYhÖ”K{Æ->³Å‚ið\… ¢ke·aªëv€t°#y°A²o5ðWËïáÞÝw\ßßO1ÏÙ<¯û˜¯û]8wàô<³^?óþõú‡ž¸rù¹{;‹ÿè½Íų,5'hÍñ¼+$ø‡˜ó1 .Ë?UÌ;Lê ppô±…"új¦jXW°sYýƒ÷‚ÀrÏHjr%¤ÄEd.“w_$ì@†žW_¹ †ÝTNï”k€$R>ÿ_9øH‹¤¡.|=f4L. í Cé«‚¶ºßÈ*Ð÷;ïˆÂC™ä1× æ‰Ú®‹&ø’S î‘uÚ# ç~ösö>ã]ùÔöü›ON¾å“7ö¾ÿÎ;·0™Ó<o”˜o”=9÷ã¾øðjÿýÇçÏýÐáÃçÏ_,¾þ±z܀ʢ«!Zæw„…CÕ1ºõ‰" 2L0P„!vs0K1A'ê¼³&¿Ú§‚œ¤© Çp˜ ƒ‘ÇBEct[W-E#_r®Fð ß‰Puÿº§Á¾ò,`d!“q!!¹;‡aRteTƒBmë¥ÊØ 8¼#Yäø‚°Ê–ÌH·¿‚™š¼iÚ‘rntubƒ‹^¸PÆ ~`EWF.ì/—/]Ýlþ¼.÷‡îîõœæx£À¼x£íѹ?[#ðÂíÛGúXàgÏ^zâžY~¹~dèw?ªû|©ÛQ"𭘂\Áƒ—ß=8(ºŽá0À³qpAä  L?' °Ó @ˆ@pSÌVFª¤]‘RËR qv›Ť+»¶ eÕZ¨üާ¿ˆ?‚=0ÊæJ#†¾K,…Â& â«Ì*ÃËE8#jfjÜ7)[—NÕ¢êÌÔ¶ÔªMlåhêÁxx$ìýåqîöcÛzŽÔák‹Í_¿~tôŸZ­~î9Í#ðFyðFݳs¿¶Fàéõú…_9XÿÇô±ÀÝ$xùdóÄ9‚®"ñxó.Ã"\0® è Wzdûd*Ó¤zÛ¸P:d†jSñm@| ÑXcÊo}‡ÿ‰”ÆM¸¹9€6µÂ Z OTßà9·ø-åþ ‚" #Û’5¹òn+®\–²Û Ù®Û€Âãf ë=z9V˜ñŽÜW+\FR Gz‘uò¾+¹¹â ÛÓûÌ2S&™?þ¹«+ z˜Ï/];9ùægoÜøßuwÿº}Ìù<oÔ˜oÔ=;÷ë# o ¼ÿÞ…Ç~äðì™ÇZÔ·„äëu&e5¼ÓäŽ9%Þ=4† ¨ZãK„Kè¶Ð¦RÛpùݦÐïJcëÊ/ò!XºµT¶ôPÑ^$~gÀåÒÑ0s(oZÚÁgÿ·ý-y0r­ 0p8‹Ûb|I›0;@gÜmý¼™GàM0óàM°“ç.nÀ§Öë[úXàÿ>ó–KÿdÿÌòw^8YüžGøX€è8Æ‚„ ¹^ ¤^¤¬RtÒü|UaP” H8ؘgã§ÉùójñXÄ:x§a¿íX@4_‚+v¸²ý´¢2U‹´É‚ ~y <lü€| PÂJ½꺿òØmu £iÿý- |!?>A‹ý<Û½¹”·Cð½ÙE´‘®ì•ÙGü÷¾ÈÂmÁ­±8má}Ćۺ rm³x×õã{ßðÉ7~&½™·ó¼yF`^¼yöõÜÓS#ðôþþóX¯~ôìÅ >9³üª '›ß懅‰Jd•wDµ¬ôÁ$`ÛS‚VQøn}Õ 6ðO]¾TÌ»fÈHÆ¥8l%ó;{)Qçf¾±çåwîe@HÈI©æY8ÖO,ë&À“| PJ>؇@ÍGûàqÝo뛩7ÕN娲øÅ¶¸ÃŒ%>$;¥ø„d0Ÿ¶Cªßtë›Íåè“äý™yÎ +Æ&Py!!„£–¬¥±ï0¦bq;ˆá£œT¯`DÂ;i?ë‚1S9%£>刧j¥y¸ÀoäI€{2ZKÞ‹ãµ™.`Â!£aâ "‚ïü)cÁ«zJƒ$ƒsLªOíÃyá¦åæ kØá²ï"åÝ¿ÛcûÜÓÀÝý/-6?²{tôG_œïî‡.½©G`^¼©wÿÜùÓ#ðôúæÕ®W?væò…*.ý¡K'‹Kçõ¹¤ï;êË€äÀ¤HÃd\pö%gŸ„Ùª G:ƒ½r8"‘ul”± Ü1ѱ ›ÂV6Øøj@s¢Ô‹ _,^8Á ŽÜäHü¥më&@ÉxðYô”¦ÇÀj­Ëé“Ì”(;3ÀAÙà”6 0ŸËÕ?—Ù¨ŽŸÁHe“Žý­¶j<Ô¾¤ï\e Èáõw(ì-c ?O6\èîþå‡_Úl¾ýù½½ÿi~v?ã2§y2ó`>æxÀèG†>xþчßùâ#oÎmN¾N7 žñoøðöZÉq*Å!Àôíà —±©˜å«”I½°È r-Î 9ãþD|¶–`Ž€ kª[Ħ!,¬G‡|H²àH€ÛЏ\ `À£€ñÁË©m”W¸WŽ·ª?Xnã¨ØÚ›Q![—¤ oÑÆ®–Ñ §xõ¢¢E’÷gü°ÒÇŒ‡Z¬Ë£kË“¿òÔîÞ·èÙý¿žy;À<=ó GbÎç85ÏÞºuG_ü¹ÅÅÇÿÁ­s;_¬ßøÊÇôm‚ oî+¼ƒ’ÊÄ¥HˆlzùÃ¥ë`§êùx†Ǹò0 £|•á–½TÈ‘aá _€dL%,`ÉTn Ü ÿdî‹@íÓvaª-¤á#àÚˆ©Ø6RÛNäÀŒ+Ù ¨‹“…ƒMÙ ×Ëß#¨†ù£éhÃÔx/l¸»qò®«zvÿ§nîÿ„Ôú0gNóÌ#pzæÀé™ëóœg×ë«X¯ÿþ#o¹ô^}uì«õmßþ°¾gvÌÛr¥lóîÓÁL‚–õå|ê¼N;Ë fQ¡P@uõ²ðÂ@bR_-ˆµ(‘]b£É¤NNflÑ熴²ãQÀ,îÔT|mkû¤AÕ,•ÂL—S¹rã- ÞÅŽä–Ê…6 FÊ€“ÐUmZœñPÉvÖJ Ê5üÞ™ÅõÅâW7ßþìͽï=¼sçšÐsšG`—yð23‹ç8=]­>úÞƒÕ^¸|I\~~rø›'ìu ÂÆï´%'Hù’´¢–—#[½3ŸóƒCüÙµíÄfBðTÐEf½²rè€^ö¾1P[‰Ï¨BcÎØ!Ì€_¼#Wø@w·½4¤RÓÅQ„ÈhÞ)£2ªûa<©–¾p…iœ!m'"ßLØõ¶qš«ÑQAó¹}}³ùžÝØýÖõÑílÎæ˜GàÓŒÀ¼ø4ƒ3«æxÀœüÆzõ‹ËËâ`gùÅ,_ý¸>ðÏñ*9(´ÊœÀ<¼­%"RBd5bÖÖé:"*§¢ÂXÝv<Ø„¥ä¿ø)sS7ÿÝ‘ÓC/–‹áÆ€M CÚm¥ õ{JC›íÇ&MuQ¤b»<­7&7ùÅ/h!ᨶ@ §ÚÊâç¶òk;ËŸ~ñÎÑ7¼°óÝa2§yæx#0/^Á ÍyNÀ'V«ë³ñšÑóV % õËï|%ó{l5¿Ó.%oöüxçÌÃ~:s÷>  ²ñnAñvu\e ‹>û÷Ùø[uScroá„´u•¥Ÿýß lâ~‘¶éÏpU½¯4ëâ~Û™M´,Xîèum¹ùÉk÷îý§Ÿ¼yã§džAÆÑœæ˜Gà3yðÙl0ÀƒGà™Õjÿ×Ö«xþò…uçÌò­/¾ìa…(‚v¿:xÂ@¸äåÀOìs õÒÀ²Ö“byCîˆgA‚eÚŠ·BÆ— âK8¦&<ŽB¦,WUòƒ€„åÇ€’~½8±#¥Á6í0ª|ð=·…€^4ÜôGrUEäü­@¦v`Ì'Ǫþý}­oo±xæúbó_>³·÷æg÷{pæÍ<ŸõÌ €Ïzg‚y¶G@zò}ë¿ùðåK7õþ×\8>y”;ý}‘®_Uì»ÿYôG ˆ C™Iڟ﫞`›¥¶ƒ\z","u•]°ðƒ€ds BCÈÐKÒ<–k¿0‘üÀ»,¢tn;ÚU2 ù}À‚&øA¸Gâ@P¼º\ü//ÓÕ7~©Íç|y>û˜ŸýÎ óº^ýëÅÃÿîÍGvžÐ·þà=—‹Ûò² ˆ/;8B2ÄOl*Ó ÁYφªœ{ªjʘ&ŒâPêøEOâ@ Ìs;´\;hH1DÓà& …èLUað«ì-†ÃryP:ÒÊI_âÿ™›'Çßøì?|ttt»Ñs>À<¯ÎÌ €Wgg–y8Ï®öõµÁŸ~èâ¥_¸ufñ»Û,~×#ý±€,¼ âUüK€M &p†½•¾aHˆòŠÙ’¡q'Klƒ×—YŽ”û&@•³@åVð¬äÏüãÔu0Ã×%Áçx¥ -èöRP2Æ¥ÑOÀ£–ïéÊÄþrçÃ׎7ßùÌÝ¿°::zÁðy3À<¯úÌ €W}HgÂyî§ÖûOÿÊÁú‡Î^¹üœâÿÛ.žl.žS´é›¨<Ì´» šUÑ&ìðCKg¦9ócj'÷n Œìµ*A`[ù[ [úù6Th¤O¦[x1xñû7ö½6S.Ÿâ"Ú†€!ðH0à‘Âk ÕÌÖë«IòS»0þÝr.~z4rÏŒ´A›$zOÖA`VÈ“$ŠB’¸”ñ-òPA¢Ö³ò(ñ²(Ç7õ¤Ë<å@@3µ` ‚@yJÐ+LLòˆe6BPkÖ¶¡ ëdÉ€@þA&SÜ»À= pæ3]̲£Såò;Kõú]mlOCÀXLX”m C` î$ÉìåZzr¸¿ÝÎå^,dnlDÙ»,@b÷„NÊÕY¶;ë„xÙi/ƒ(òuˆE[P%‚ ÷40cuDI+A&ì†ÀH¦å= /”޼l4 /"­}[t¾¿¾ßÎ|`Àîþç;ƒ÷*•ß|7‹ C`0`Á¶¡ µ€7Á‹ñ‘/jÃ;·¹èïà,Ë][¸09Ù–PArÕ”¦¥½À¸,—ýŒñc1åJQ ©:¦é¢ ÍSA.ÇåE œÍ«d•¥†~¤Ñ@IÞ/?hsy²¼ë%<ÑÄîþbä~(bwÿrù3ÛÝߘ% uFÀ€u܆3ÖBànš.aYàì@~ôlu(÷$N ìÝÑɼ=Ð0zz’î2³Ó™?“$d­c‚´ÿß¾½K\à1@½ ›ð0+g!$¨s°;ó^­@L š“sü°W1@¥î `?íc£aôÏ¢£¹¿ônÚhÌh­= C`£0`£·q 5¸•¦3¥é©áÉü•f.z.ï¢Ý<- ;îAÆ$hþzCï’@oOªyž¥^Iðú€Ù‹ÀeâˆK5¶ õÒÇñU®VrfOëå‹r€4ëå‡[3­!†ï~šûù‚¹ÿ÷Pc±!`l,¦l,þ6º!°&ð&xåb-ýxx×Ds(Âiަù^Lîè¡K&û"‡˜eœm£D‚ZÔèÏRÖˬžµHpæ_Gax.ÙéÙ£.Ñ£nel;êðOäQfPXÀ<ÛÓwÿbìÎÛíÃ0÷Ÿ0s¿bcOC`³ ` Àfùö†ÀjÜ$¹ò§«COŒeîùXŒ§5 Ó ó{VVs½ÎÌ»'PObUÀ·g®…_ØXA}¯@òWBû:8ågåSDðó¯9߯B«C5rSó0÷Ãw?ÍýÓèbÁ06¦l²b¯cÜÀt’,bÀéhbâr;Ž÷Cxl»2ºP.“¬Á½HwY^Ȉ%°\ºáÁ%^D€G¹@S=Mè}7Ô’üÑýØ„ä/ІÏS¦T"’Ýý.û T*š«×ÿ 2,6 ͇€)›ï›Øk"p+­^--%Ÿ6'ò­Î@üR¾ã†Á¾Á‰;‘Œeæïuµ: ªV €ºn †¡xf!roO‹GÍÜïá²ÈèLèƒd¯hÜÀlµZÄ%Cg:“ù ˜¹ïŲÀž`}’½’8™~¥Ë™ Ë4õó:àp#`ŠºÈ<(á.‚ Ðì/J¤PŽóG)Rs‘ûh®Õ:¼P©üº2š¥ C 0 ¾’½£!ð?ÜN’©KµäĶÉüb»òY4Ê[õdÖB'mÓÐ]P-¥ôÁ¯vz* {HòÒ±Z8áDz͢:ÒEçÎ-´ã×gÊÅãÍf †€!Ðo˜Ðo_ÌÞ×Xxü£>:r²24¸}(ƒ7A*r^í©„Ù=çðt ,N€Àò\ {Hò${ndšAæþÈ´QŽ;nÜ˲·n–JïÕ˶»_!²§!З˜ЗŸÍ^ÚXÀ½Z­v-M¾ß6^8[pO Çnï(™Ä͵zDJêL O •õ ›Iú²Î8¨´¤Ø"°àܱëÅâI½~Qªía}€)}ýùìå Õà´À .ú2ÛU¸Úß7êÜ$®ÖeQЇ "¹›AðÑ2ë`%?ý§mÄÿõ\«yp¶R9l? †€!°0` |Dû µ¸]­^ní<žv°iï¼  €Øe†®¯£Ò—x†ŸA.íA\Œ¢¿ÛÙ›7ËÅ÷—›Í©´‡!`lLØ2ŸÒþC`5sµZëZ’œpl°:˜‡[áý;àMûhú¯sºñ@?l$Œ’(^šÜ±k‹ GªåK«¥Z‰!`lLØ _ÑþCàLóØ`’|3°«p¾–‹wã?þ³¬#Vº®ärøEJ”û¤7ŽÜš/H3÷?W«6úµùõó_`ïnÀ+{ö¼wÜ«({¼ãâvš¹©r®ñíõÙÅ«-Ì:†€!`†€!`†@ ð/ÚÆ~êÕ›PIEND®B`‚ic11 ͉PNG  IHDR szzô$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+\IDATX ­WKŒG½·ïÍçÍÏÛ²&Šm@#Ø€Í"D²Y YÙ$‡H,l²ð;R ÄG€@bBŠ™(€Hb1Ÿ# d%€D˜Ä±3ƒ™ÌÌûöûtwUqNu÷ØÄ؉šé®êª{ï9÷Ö­ÏSùïJ1û«³gßÙ 5E~Ô»âDf+õ†ÁIœüÉ&Ñyâ‰+SAuï™{–à;'OÆŸ¾xqòÃÓ§?§£ó‰sR#¹µbÑ&†â/ CÿXÀº$9}ê©óOB·ÝBön(ôì­%8wüxtJ$Ä€%8ZÝþÇÒÍM¹1 7Æ£b`r“" ©µvh ÓŒ‹Ít0ÜÚÚ”W:G©SéÜÛdÍþÛËN²G ðS \xì±ýÃí·imm~(ûÝ‹³éý»\Öš‘4 uÀ[„!³VÙÄm†²¾ÝÑ}ï}Ozhyù·¡qÏÍÏ4ýɧŸ¾QÛDËÕÓã ¼î¸xæÌnwNº¢xØYó`+§2Œn_»&K—_uË+ûtz®%½ÑÈÝxs[7cé„ÎÝœ µ=Õ”n¿ïÞ~Hßuÿ™'jQLšü> ‚ sSsÏâ§OýÝ5f„6ü{áàáÃ7—~ðòµc»“$QSÈ0/dØ<"]W 7$ÕQ–¹%Ž…v“Hº­Xúq¨Cc˜gÒ5RuýñØ8S¸9 891è‰n{ã_xÿ±K¯u¶ÏèÕ«Wˆà =¨ÁÛŽ¾¼þÁKñš][^Ì» ³ªIƪqd ÒÍé‹ÐX›¤º°]0ôÒ/2éåcI‡éº@ðdçval©0á4Û´ÆuÆ]s­Ûwív;@ßÑ™ÙÖA˜ºrœ.ûhˆ$q¸1NB92ÈÜ¡­h{vS®/MË -7hÍJìÔ-Ak8ÉVž©i®¤ïé(p±Éõ`H +eÐï¹õ^_úý~HÂIÙ"‰%R³S² ìèÇxAW‰ L Fƒh>‘}ªºcèºë]Û=%W¡l5fÅÂãä2Es.»_(¦Ð`zV†ýôÚ§#L\€å9Ì"—@( ” @p–B§ª½q jÈl‡Eh¦cÇ_9<*äè̼¼”7åJ1‘7m!Aa¼çŒ@⚉„q"ÃA*°#ÍfDAÎÁG˜ä~ÿq&RˆÃ$‘ÌÅ©]ä’6©.åöaá¥EHC­à¹¯‘È3rþ*™¼!Po$úåÄ%…ä‰õÆa‚AB–ˆÂähâ\ŠaOr¾¼E£@4 Mm%_4¹q©$ÃÍyŸÐѸ)6çe.jˆ‰BŽx`êù§ÒCåKE,½oyyÈÚ䤷rbuuªt×}dÇ]Ã+¢ËÝGñÄnå$†d2%gšñºž>zPêÃ2•À(1™°÷WĨW†ø' >l{ݲ‰¾ÒXô9\cz]nÁìT ºÌÊr¾N€„¯1N¡ÌK£|Æ”~¤ìÂRè9/ã¤Ë^ˆ{SþõîÒ»:(º€1À S˜5)×´½|Tß4âåPß*¬ ÀÎÌwØ}¼T)Y<^ ¢¯Mªuá1V(úBµk>p°cÑJH¿éºZld•‰¶®^µ-ÿ‰,o3U,Í5Ú5ußYnuúôª* j:H¢”ãNÝ€Û”¸öí1zSÓ's©Ýþy…´ƒÁo÷·†%À’àÛYúÒÏ&éwMMáÞïœÂ÷ÿ‚‰†©€ë räÏH­.ò 4CÔ‘éãq?Zœ|éö©ŒÇ¯À®OxÔÞÁô­Øïp_vç °Š›Ú/Çéê‘©ÙóñFƒH$8‹ƒ²Àÿ%rº xü@ò^3ÑzÎ>߱桺ghÁ‘¾êV?÷,zÊßÇý“R_YÜýм ¿…iyÎÜ”]þllõººˆ—•®1¯O ÷Ù?<0Ub<ÿ˜ƒÿKáo‡:„úõù½Ÿÿ^kïä¹…ýîÌî½î¥]îùÅ/Ã`Red9×ÿßrî ùÔÔÒÊ׿÷<óÑ¥=¿‘VëðmH5ÑÛºîÞü"`QO´Ó«ËIEND®B`‚ic12;‰PNG  IHDR@@ªiqÞ$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+ÊIDATxÅ[{Œ]ÅyŸ9¯ûØ—×Ø»€C.¯àªÐªJµk%´u”TPÔþS•ªV•*R*¥©¢zÝTT!$M”)ü“VQ‚DZ…*ii À¢µ !% ŽÁl°1ÌÞ»{÷¾Îkúû}sæÞs÷ÞÅÆ˜tì¹óúæ›ï=sΙÕêHËKKÁòÊJêP?zûíWw»ýëú½xJÓK3“.˜ÜÌ*Ï‹ €¼Ü$(×}ßÍøÞ±0 ~277÷Ô¯Üyç!‡c3N×ÿvKývlžF< Íô¹Ï-?üÜÅíÎÍYÜ¿¦Z£²®”ÿM¥²‡n»í7O¿|òkÓJ×Ûq¬z)ŒÁ˜TkÏkpYN0 Jƒ0Æäó+ÚT© câÚâ…¿wÓÝ_¾×­Qžúvê£D¼ LNóÿó¥/]q俾¸×lªÔÓ±VÚ×&÷L‰aj}RrÖÀ1 1À,(•,ÈMT™Qù廯ýí;îxÚ­5 Ç[í£I¤Ø·/$¢þ±ã×g͆j+£™,õRg™qÙ ^Îå~WO0'Ã\ Ê´Š›è 'N\Ï5þØ®u^”w΀4ÍqY©4™<ð@ŸÄ]¼¸Ø]\k©Æ‘¼×[-ÕÎrÃéi’é’Á t\ÎÒ“¡{`’Ià*k­ õìÑcÞÓkM¥{\ãËv-³„µ™a,ç,Œ·4‘ Ø»×W++jY©A”7÷Ý}çÁ©µÖúØl­vÓ¶£Ç.{ýßh^©‡ºµ}Úôçfµ©ÕTÂ@…¾PN„Cd؈JÒLÅq_mtºªÙZW¯¯­©vš™Å÷îÑWì¾ìÅ éß_¯Oû}KKï½õVd¢(µ´¤}ôÑŒ²fßÙ¤3 À1½¦WJLÿà+_©¿üŸßÿåÞFëÆ,‰ ûÙ¥>ênl¨ðð Æ_këºåä°€ÈW_«u0¹n2Õe=DûöÇÝ Ës•!ê'q¢ºýXuQö¢@%ÕªRµŠŒÖÕŠ¹üg/×; zNDaðP½Z½q×®Çnùìg×ôÌ=KKzye…;Æ›î@ó>$aÚŒêñCŸüäÜꫯîM6:7š¸CÕ¨‹aª 8V1¼Úx:;=ßÿï{µ$5õùi]…Ö§§kª ÐÐ|/IÔz§£šµÎ"IU õ±Kv}OmÈNÛ"}*ÁÖÐj·ÆŽpÙµ{ò™úTå¹Wמ?…*„ !ÆœÃà‘Zmúþú® þÝ»îzÍÑŒ’nª÷ƒ0;f“À¾à÷>õ© N½ôò‡óöÆMi¨®õ¨Lu±µ%ˆR°cêÇÇæ®3ÏÓ½~Ϩ§ŸÕS.˜ŽL}vJWkU©W!hç€v&Þë©Ð®>–ëbÑ.,·…’™H!ˆv¯kúI¢õÔ”ºäê«Ì\µ¦+ˆU¬BèȺêyÁtªì禅ác~TùçÙ™úwç«_=t.ðÆÎÍ€}ûöÍî›ýØ\/¾9K“½ÕÜlCÔ±)L5OqZ¦ÁºGûÂÃ6 ÁK­CÃíCÏêù7 ´g¶O«™™ºªÔªÊ CnVÐEî‰ û¡¯ú ¾‹Õ[˜ÓAÙ§;W‡ÛéTM©z]]råUf{ÂD¬€=© è‡(œûˆ´Ü†í5¬ã_/7½J=k}ÿÑ^ç¾»|ð5Z7ÐÌ>HËÖ\ÒÛŽ¼t ñÔm‡aºY½¦ª~†˜>»h[öi0ã%6a^ÓWR`ÚëTŒšÁ`‡ZGÓè÷ÃP‚- ?ß#än§¯D ¼‹¹]`åá©×í¨V‘¬Lù QaŸGÂÜpDƒ)fAèÏMjº2ý$­žn·?Ôï´?´šå{ú‡{AÉD–4"€ýèZF¾4ÍÌ3§ÔœJº/Î…•—wÎñüœªÃ«»ˆfðÊ}¬[$ähOʈm‚ºÀÍB,õ4QõLùž/Ѿ³ïa¬ÁõÀ`°ý¸‡Œ6¤ 3ãJň à ¨ñY–~„µ¡Í rãg© ( d]Õê´}ìzµÙ4y?íOWÂjuq^6–FàF³$Yõ·UÔ‚‰‚…4Óïy®aNú§Õ±…ºzcǼö§§UÚäâd\Ü@&S;FÍîO§aîM¸M rªil`$Šð Ä׳j‰‹Âèy–8 K®f0g3ç!Œ™\€>®OËô Œîrg†Ó†Úh·ù\a`þ*˜‰ü*ž1GšB⦟‰¦«kÞj[e <b­ÍUÕ•˜¸»‘ªÓ¯œT/ÎùêÄŽ9…ý]Ua+nM KœJÍšäц6 MÄëƒ;ÉÖ—!zä), }… 楦€+„à¢Ü‡Ïp΢/€õpœÚ¦+2˜®â¬ÐÀA)ŽSbg¨×ê|"£Ï*Ü@¤‚jíÌ8ÄLA’6Xâ4ô6K ®úêB ¿H[ϯ©ãѪ:º£®NÃ=¼éºš #!,ÂÚpä³DNA4v »ç£ÍýˆV#$Z¶"<5`Têp-Œ!»ÉègÕBÓ÷;šÑÂ7þ ]¥Q.Gñå‚à¥æòªø˜0 ë›À[  lF Êr‰§ aÆ. @.à˜+ÁÙ‚À­PjÈêü)ˆ¶‡Íóœl'–åÊ^—ì¨e¾´„²ð¬n¸“‚jwud&(VÆÖÓ$l²L­¹z!]öÐd\*U]—”—u¼#·–P@ pŽÌ6(—¥·´ˆ«ºr8ËÖ·ÖrZrR- `1èù~ƒ§0~¨ ¦‰H”'-Ïèƒh->L2ݘ…wmW - ƒ…<˜:´ T„67\.qá'Ï6å1WŸä2†Å› XVö gŒBŠPqRä ÏÕÝ›Ûì’ìTÛ²N+Sd¬lRè¥Ó²ßv „ÀžíO¦}çcS&Ñ'@^ä¯òxK/*zFhó®›ÌÑ]0nõL”#À#„pdëÑÐsh³ºÕÄqÞ È\ù —Ø©ÁÒÖIˆ¦1#)¦8æ\)Ý.aåØÈø¤å¾4iL©o®„¤R,Úê˜ ¹à‰Ð’„ °%mvR.è²eÑ[¢Õ!p¥£„mAK‘XjŒƒ·(KˆÝÀ%½ ¦¹e ÀþB/:ðš|U…„G–2X¹>¢Ä C‰B²`*UÒ7ï&Îe¬4E°âÇb·¿fm,Ë9ˆŸÞàÂY.1`ó£0çŽrƒ÷HŒcùzŸOe”Ÿ¼m è8qŒ%‘:z])'FPH††d³]jAJeþËÌofŽ Ú>û äêØö Ìöµ}M|&ž1ŽøHÌ,ª­ãÚ>|àsIãÑ’¥äŽTÃeí 5œ`©ê˜˜ÍKp¬:!”Ká¼b®-F)p¤Âsù(ŒO6©`8K°ÈϘ¾?µñ. Ç3¼¬WÄ©çk–’a»\+$ÅÏÂL"„Þ „ý…c˜}å´U¿›7°1„',ÙÅøFO¹>I2Ž×Ème›æ‹#0ðáYŽh˪ƒoenº(óŠÞÅ–L×t¥›[.Ë‚rý4ÉQ³´øøO–EpH§=;+˜7¶Ä–¸ê†ºx-Õ&Ýd2çcÕ YïÝŒMâÊE€—*I1S ['Éc‹ï dÍbžëçØæ, ›:‰*“”i¯ol >£ÛÞáï˜H;†å‘庳|·§’ÁrrVPî#GÄhÿÙµ ú ožåÆÙïh+—|ÉÌ1ˆbý›ò¶ SyštŒ  €ñšªEÌâûK™mKë ¢éBVcxá1YÕKãcÔIgþqóXnΖkAÄ„K&åGá1ä[= ˆR‘8s/¥/bK[–ç…IY»ã[™^À‘DNXYÜâ/£ô²œŠ™å®¡ ‹^¸yƒÒnE 0î9À5‚mÂ6ÈñB1öšôG\@°>‰H7áègØ‘àÈ>&À,y•}Yú Ã4Ï¢HCO×vÁ¡ hvÒ‹­ÇN$'2ï%ФŽ}å~ˆõÑN7(¥¬)+Û)ì³xå¿ôoù D„[¹€,†í¤‘Àb| !ëóXu|º#®=$Aã—><:Kµ²‹à0ÁqAÀ ±^0ÀÒ¦¢$XÑS.„†$a\´íWhÜÎÜò9€h& àGâÈ[Åí h^¸ÃÛ],…*yáªdŠßÿØãÇÇH©Ë¦F@ÂC-8TÉ$¾ ’c …€~Ζ–’ô£Mp dÙ_ÎlPëì–}hËvêyçnÝT¯ò¾åk¸]+ñu9”UÈ[ì@âÒ«hšÝÔ¶ðL@q N¤ x¸.¦Ù¸€q×&.ÖE¾l ¹¶ƒ‘6zŒó²y9“JHLö¦Ø*ÈI¨@ƒû:¼ó dEF]>t¢Íë+.Ó #ø!„Ÿ¼H[r€m$æ¹1Æ Ö¡qꜱìk|ÊÀ ¥9 ØXš(÷‘t¡Lñøº¨<Œ<Üâ:ÄU5^ÉäW+/HQòî+·¦%›$àÙQ‚ÆI LtT±F<.±:ÌŽmkIöĵíîÄ¥A·@ÆùQØ‹3ûU¸@çÐʉpÀ«sõpMíßåyïëàs1>T§ødT°·ÑÈ<µMóãmf2Žî¡H»,ŽÚ]ñ‚L09KmÉCƳØ!³.¦O¥V'x÷tˆ¯Â^7Ï^{å9€1¹¥l«ø%5 !@™Ý9·¸ÊÓ¾öp›; 0„{A>­ ¸›§CÀÐF¡¸÷þv—`/݈i(ñÃ:ߢ~ÃôÕa¼¶À5Ja†ÄmÇ0K©ãG˜.èB4M³§0ø †>ÜC—&{9î†ióé'VWï">$.O4c‰[&ÌpBPŸž¹øªy/ÿâ‚Ö¿bÀÃæ—5庨ð!rÜÞÂwD¸…ˆ‚VP0ŒUlŸ÷OË¿§îÅg@p+X¤)0¶Z«í¢Æ©eñuÐ…0$®È€‡ Ë«!­¡£Ì?áÑïO¯®/Û’yŽ¿©‚ßÇyáûÉ_ýÕÜÂͳZþ"ã½›×Ú*Æ$‘ç…¸² `` ü¦h݃Ú ÂYÿpD,R¸Ï£1ŸŒ óøý¬ó™D´nû4®Ñ%ðyù;…NnŽôµ¹í©Fã_ÊÄ~÷AT:&ýÐmϘž´´øÛo| ×¾ûýÕŒ@}p ÷_ãœÝ@¸æa Ú"‡øEÝÆz”ߥÈ.ÆŒÓУМæQwà–jV:…¦Õ±µŸc‹Ã»Z/„¹§m“ÿåš[Nõz‡1ÕÅ5ÄÓY  Àb~–±À $ûp¿óÈ{+õ{Aìn\V¾ ã/C2°ERÜ30ùšLQâhضV°J+Ac@ æŽXÃè΋“È)ü,@ˆ÷Úyþ0ÿÑ­­}‹è‘É<¬ŸU²ç”tÙ->3³p㬧>‘ v'¼ö’ç þ("Ä•Ö[ \ËQêüì†x¡þÑOÔs… r9Ìó¨ƒqûð…èÆ!Æ_ÕÉóc°†O<ÙlÞ_POsKŒó„WKeីEÜ>ôoýöÝ?_«áâ‹ù .=„„u þœ„u7†>†9”Ô8ò!8]2®ÑæÎKTr°¡¹gbî€éææŽ'Ö¿õJ¯wMÊ’8ÏÊÜ7–ÞŠ ŒMFGÙ-ÒïõÚ]½múë`ýÝÏ¿–oYƒž%xXS¦©S´ÓCØ)nîŽyhgyº@Š-;­öñ§s¶Óä£O­¯áœ& ÓÜÉøY›;`Ç—>_iÄ-–çw~d.×·¸2…wãÌ€G /àc5Í×opwA«oû‰y—ìè $ƒS¦õÀpYLkøù‰¾Ñ·ÿpm•Œ3³¹Û飿çS³·‹^±>©ÿz~çŸÕ3ÿ‚ö*°† NŒ?šÒ>Ÿ-ùÿ%Ìõó8¼B`<s‡lÂ>, «Ì]O6ļàä¬õœÍ8Æ’C:6ð6:Ì1ôˇ{ÿ¸f*ú˜ñ.š®…Ö=9®BÓ9¶Í#pŒÓÜ# uœfÝ•?d#5¿ñÔzãë ƒÁí¼˜;ðŒ¥wÂÊ‹ŒºÅÜž1Á<6¨Ô$ø´€7q--ÏOÁöÿô Ë8ñœWs/öÓ®{ËV‹²îòö…?ù¶…Ö׿/6·îX4¸`‡ùÀöí_ÀàTA7…wÂ: ôÿOÅRI0½¸ð™í ó;¿ÍÏ_["‰æþSKÿû\j]•½IEND®B`‚ic13ìU‰PNG  IHDR\r¨f$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì½i°mÉu¹Ï9wÞüjP©J¥* –l ¶„ í¶xLh0tGG¨"ˆá mLw¿ˆV)ºÿt4Ýý‚°qà†h° -É˨Œ¶0l4•TRÕ«7Üûîøît†þ¾µ2÷Ù÷¾WB®ºKÖË{÷ÉÌ•+Wf®Ìµrܹ{Í}óÍÌÞd2iš§žê¿ÿÆÞÓÏ<3&³>_×g„ùµÏ}îìÜÖ•ýÖ–÷öæ'/. æ‡ûûs½¦M&ýÁ¨iú3½1©Œfz½Þa³¿¿779<˜»ôð^oqqçB¿¿Õ¼å-·¡9$Ô¯kúO_¹ÒßåË“Þ?hî'¤õŸ‹óu Þ¼w nî›o %ÖGïýÐ×öÉ¿xöÚ¾ðèÞÑÑ#ëŸûÜ«Ž÷?Ú;|õ¸ß»8><ºx´»s~8Å}¶çÇãÑ 7÷¥²Âõ‡„ í‚™ úã™Ą́7ý­ÁìÌæ`qqc0¿°ÖŽ×æ–æ_˜™ýÒùÇ¿:îÜó<òÈsÍ›ß|ë%D*…}lLî+„o–gcû&ÊË·eVµž=üSü`óAzá.ëo|üã]ÿÊWÞ´ù¥/çptô{÷vŸØÛÜy‚^üòh8œEpûãa3Ž›ááa3œŒén{͈¾—øÑõ*qaRÃ.Ò.04ÀÔ1éõCI“áòÚkúúýððÏÎÍ6ýÁ ™ÌÌ6Œ"šQ¿?š[Z\›_Y}vnyåKó3ƒOŸòµŸ~ø oøì™ïýÞ/Cch 3˜¼÷½MóŒ_BatPï;ï%jÓ¸—iܧ}¼÷½ï4'„Áœ¹õѾ髿õ¹·í¬¯ÿáíÝïÞÛØ|ãäðpev4l†‡ÍÁð¨9RØm%¹ßGâCRÑýZŸ9NO×*ìÚUÚeªþ+”@ËX•XPèÛs«0£P/Òë1Â@3ôz*‰9”ÂìÌL3;?ߌ3ÍdvfoáÌê—άþÆò¹s¿òêïþîwéïø èû’)¦2èÝW•ÿeíZÇÿeSý6M ¡‹Þž¹qÛÓOž}öÜ—~ñãßó¹/¾soãÖº½µý¦™ápf|pÐìíïg;fŠÞïèvÚ:%qDÄSØCpS'{‘Í4Ž:¢8¤Øðçi`Fä7GROBí¯Yˆ‚d¢–“G%1W˜DïÍ¡QƒyF ½þdáâùÏ/ž=÷K—{ôçÞø®wýbïá‡oT¬̼ïcÕ"Uø}ûÞqÀš»oî1ü÷¿ãæõíPøË?ó3ïxñsŸÿ“Û7¯½s´¹ûèàè ÙÙCàž1#xeŒáxŸV—YW·•ðÖ'HðÃõÒ‰hx‰c×íA¸ úïf¾«?IšX]®^ª&ý~(ÒGSM³./,6½…¹f²¸|cåK}øµ¯ýG¯û³ö_‚ rÂübrzì¼§¿ÓZ»§É|ûgx;¨=>2±ú[çïüÉ_þÊܾ¹ö¶þÞífÛ^~ìr|o¤ÀOFãÎXa(òªXTgµ[© ìdeNN„¹†µñ¬Ž*èǪå•~›’•j¡Òj’NDg±zX`¾cã;)lÒ “Þhİ¡é³~Ñ_Fô—›¹sg>sæ5¯þ¿ßúÇÿÛ¿ß{Ýë®KÉAWi »oN—µvO—ê}jȦ`L™0Oæ?ý?ñ¯}æ³ÿãøÖ­Çoïì6{áò>âé˜G[ŠxøÖèù À—E¬ <|…Ùµ/rZK¡ÑVOñw;ü6¬8ºz¢º«Ýâ:í DùT2týÕO„pƒos="Ëýyxµ´¼ÔLVW¯_|òuûmõ¯ü_ðïhî^ˆÛU1@î›Óà€õpßœ2x–Òí{›æÙ|àÏ~âßÿÃk×¾k{s«9ìõzÄ€'S.-¼õ-!~ÂÀãψäl¡…1¦@ŠX:¢ð¶ÊgdÒ8°œˆÏVQè3­)} si.µÕœH+hK¢k*­®Mx%¡+²ÛëÀ™™³+«Íäü¹ç_õ–ïýëßó#?ò÷%ç¢é;k'Âî›WÎi=¼rZ÷)ÀnCýµ¿õ·þëŸúÌÿ°yýzsä!š™™>kdENNôîr¯]ÔGÀFHÙ¡íés¨cé"¤1'Ü!|ÆíºM`jZšSÐËwUbJ² æåà†"³`5ig(SÅ%eIDcäü» ã™ñdæÌ¹óÍÊ“OüÌÛßÿ¾?BÝêN§^~fïÇìrà¾èrãºkϽúïþ·¿ñÿ®ý‡Oþáë›[ã™ùy–´Fwè[c7+÷k/Aðñ:Lîn- …§’r>ù€ó£­!nfÿnDå·ó«¢c”4žÏ/-ÎÌ?ùºÏüà_û«ïì]¼øµ®‚ýíо{wœNÍÝö·¡§“rí{²ðÉ¿ù¿ÿâóÿöão»¹p4ÓïͰpŸ[ûz\ªH]%”B¥D; * Špq# cë¬Q kQJܤÆoJcx#™’Ž;zÓ©¦ú)?p—ûOÚ`‚o”ÄÁŽŸÒ‹IÓ”XŒ àêÑòx<»ôæïüÒïÿKÿý\~ì±H£bÕ<Ü·_f^^´û±Nr@é6ùÜßû{?qí×~õm7ö÷gú3s£Inùw¦ÆíÈP€Za,!0å)GpZÁ‹UvˆÚ3‡©Ê@áL@X±ª!qº6B*"T£€@Òè€?ü…®Â¯¹Ã6–´Á«Ø Ä+&™ŸT Nú½þìn¿wÔû­Ï>ñëÿ§ÿ1o‡Õ¥ÂÅß¼tôü+ òmÕ¹),ïþÒ/ýñ¿ù›ê«×oŽfúƒ¹Ñx ^¹ˆ/ŸløÅTyœú3¬Å% dª<ÂK|q"¾~ÿCÈZj-\È4Š qóI¡&rÅÑ)­“qºa?p ­J3ó²ù¡5Õ=µ¯yš¶j-|l8qšÌn>ûåø7?ýÓ?.¹§8>Ý’½ïxÙ¸?xÙ¬›FdŸ?ÖÜžÿôgÿ2{üÍ`a>ÎäWÁ´i‡ðبm×ùVx+)<>²BÛ8&2ÕÒ¹€i¨ Ò©•qÒߦ'šE”ªÀ J.Y•Ê1Û˜„iZ¢é­ nºmHÅýÏÙ5D8lÈ!ÈÙÁÆ‹/6{ÿés?FïÿwÞT&½|û¾}ù¼‹˜6BŽô>¾õÜW¾o}k[_x •‰¶î“m?‚ËO„ñ“xSÌÖ…ÀfX±‹¿,ûwˆ×Tò8„½¦§€E^+Õ’Á½µ‹ÃÈ‚„ŽÃ#°ü¨ÅmP!¡³5¯ÔK&>#>ïAL6®^}ãÇþçÁ«*¨F»oÿ69pðÛdØè9í?ûì“ÃÍ¥á~ìÇq¾‡²{Ƙ6éì8ÓU!¾ëâYà%n¨›)ªêÇž6ÕPE-qî´J ¼Î$Û¦ø˜eÈnx%¬€]§ç‰<ê­µ¯<¯íìœéĺï|¸¯^ó"ê>Â2éÏÎÏ! {“mÏó//ç{ó4tמ/Úwiä ÁTJF k% wõ×8 g1ÔâÏЂC‘§qÂUi:ÕšÆ%Ï*›v.ÌÅ®Cðv®ØCífèx@Çwœz« RƘ]…ð5[{{ÍÖÁÞd‰ÑÕÂòò|‡Ð}ç+àÀ}ð ˜w,êâ?׬ ‡ÍïîoÓS-œ=ÓÌëñVާâìUmãÊeÈ>!¾€£LvåR·FYwŽg˜!!,»äÚE'…HXÀ§¸w†fŽ4އ¤Ïø%n$OJ¹J Ù‘Ö]sVP •°¢òƒ0Ýq‚€££Ãfkg§Ù>6{GÞ<^XXô}s ¸¯N‰’@`F=Þ{_áý 4Ö£Û;ÍÎþasxnµY\\â%8ßå/‚îÉp-™V=+þP,°¥V”ÄNHÚNñ§ô+Œé€nDá§D +© j*väåÍ@-?/²±jú4‹g +Ia™ë8®Ü ,é9Ü᛽ƒýfs{»¹ÍÔêþmróÑ¥……ff0`¡såJÓ<óŒ®ûæerà¾x™Œk£=õT8Ùö?j¸gna¡wîp{22 8Øi¶öo7ûgÎ4ÜŠÃh`Þƒ-H¯ûÛk†BP€]7Ìóû*…”qÇþoØà*ÝöàÚù£×TšZWutl©lª Oi¦Šj5ž ÜÅÔ[M¦o&W‚´ÆòÄèJ+òŸ¯FÁ ow!~ÿ†‡GÍöÎv³É[“‡£Q3DøooÌöêÀµ•ªÚTî;^.î+€—˹ï;¿³çÕ^eh¤}îË›[˜ï]Ø?hzG“f†©ÀöÞæoΞ;×,¯,£¸SÏ]ÅM% 2zùÆ^ xBÄRÐTÙI :6¼Wl¤¦0ñk7>,BJ œ5Lh1-è^äÈžF®ŠÝͽMOz„kzÉ!Éû®ÖÆGÂràˆ‘Ó6B¿±µÙp§šæ>È„Ùùfn~ásÀki ¹o^î+€—Ǽ¸åöégžõž~:nùY}üñ5®°±qöú33“y–ÏÓ çFÍÌ^ìúfó¹šËç›… ç›3Œ ÎÎ PÙŽUš´sº ð õ­¿4!F8OÚ«»½m ¯pc‡ÔÝwŠZ¥YäL¸†U»ÂA²dï}Xˆ§b®XÎãàNmµÄˆaýÊrc{§Y»µÑlÞ\ç¾Ãq3 ú¨°~â=ƒŒ®èùƒWç/]Ú2O?ýô¡‰_¹reð1®L';U1|ß|¨­ê@ýöF¡ýöËuÝʤ­:ÌäŸxôßý쿼2»ºô§ÖÖÿØÚ/ýÊäèö^oĶ98jF{Íöî^s‹ÎmÍ./ÛzV›ÁÅóÍò¹³ÍòÒR³ä½y³3¹X¨dEͤ·#S­J"“¿ë¯Q3ƒS×qÄ—€ýã˜Õ×@d » K7¿(ªt#‹zƒ@u¨zâœnß¾Ýlmm5·Ö×›½íÍ^ÎP7G}†ù«+ÍâÒròd~ŽQÕb3³0?yò{ÞÒ{òÑWÿÊøÖÍŸúŽ·¾íßòÔS_¨yÔ¾Ò43›^'–Éwî»q Öå1à}Or€«ÿ~ºç§y—¿Ë“ç>ò‘'¯þ‡ÿøG·×n¼g÷æÚŒ7·Î-_¾Ô¼úÁ'×åã½áön3aåzD#óp'3bH»³Ã½L v!ç³ ¡iŽ–PgÏ6‹4ú%”ÁCÝ9¦ \kª»íÿ›§Ô¿ÍjÝÙ!+#/ÿ.òSѱÛÐ fnºQ‡á¯÷7‡,äí³¨·{{¯ÙFî0Ì?(B?žaêãã, Nf›Ù%„^ß! G€ãhõ,£¥¹ÅÅæ‰ßûÝ“³ãQïöó/6ý3«»gΟû·«çÏø5¯ýG¿ÿ‡øÓÝpñø€ špT›,¶Ùíâ|»»_ªæ¿]ùâû¼½w ôÏœú¯üóþ/þƧþØæúÚ{v¯ßøƒ3‡GËGÜé·Ç–ßÑh4Z8{®yãc 6?õéæˆ¡ìˆ¹ìáox¸ç¯™ÐëÙƒYÔ:86û·›Ûôy{Ì’°Ü…tžñʹfe`ƒŸ_ZhY<ô`Ñ #„†ÄL2|_¾Èm‘>›·­»VjgÊOëG˜ü¯‰oP,ì·C e"üV“P…ÝÕûö#¶BCàÚ{³ñmzúÛ»;Í!ë `„$ö(Ç!woˆ¤÷æâæàC} àtÊoôQ î œE).°~òèw|GÓßÞïÝ\Ÿ0}ÌÇy”t†«Îþû3«gîñïú®Ÿûþá_g*ÕUÜîàöñûß"¨u§]ÛJömåV^žzï{ûw¹£¿÷…ø3ßsó‹¿õîëkï¹}ký-s‡‡³4æ=–¹¹Ð/®öbÂËu¼ŸÊ\öɇn& g÷_¸ÆÐ¯¡Ëk&ôü\uÕŒQ*B£¤Ú3øpÊmŸgo2 ¥°2ØC)@—‹€Ü±¿ÂV"Û‰\.â"# bÅì,÷ðó (n3èAc“eùø+ÓÓ,©bSâ’~jªÄIc£P‘´Åá¼Þ} ßnVÐUd>.ܰW@9íáxoól«ÞP~qm‚ïðá€Ùl÷ðøäß`1ÔQm÷ÈW\Gfîìž# Ê7ƒ°¸zñbsîÒ¥¦¹u+?TB–ââòC (ÿÊ€ï›5ËçÏ}jõÜùñàkûð;ÿÒõ‰^ï­ê×jú(ƒÞ}e-¡òäÛǶ—¿Û×x€>ÿÿñ[_üìo½{ïæ÷ìÜÚü„žË{w›Vª¹†"…žk½’+ÅñÏ8=¶®.ÐóAH‡kkÍp‡öFï7¦§÷‹= =·×æWãá ÿ ´å¤{l{í›}„‹³ïÍ{Ÿ>Ò祠BP€ìÚ¤4™áŠm!qB¦8m@) èYBÛƒòY/²§rpÔÐ#¤ÇƒoZûEØ®›?û1&Ÿ\VJŠO‹!è¬Ê+ðú÷!er•ùˆ2:>ÐXÆx˜Ã÷]^&}w"¯$7rˆ@ ïûá‘ÉGì>àŽQäÓs¦?°,*¹EGœ±8¾™ lVQó(A(ŠDuX=ì lÍÌŒ?\bÔ0† ++Ÿ_>{æ£?ñćÞùîwÿrïõ¯EDSÇÔÏ–}[~6}{˜*ô¼ºk]È |áÓ?ù“pí‹Ï¾ûöæÆî­ßú}s4²=z±ýh`´_Vö›ñˆ._©ÑT¶ÑÖln4B{ðå¯6+4Ø0 `Ì kÃMŽ,ðŒ•…h´GçëˆÜlï×WP•‚$î¡‚‡Ðí»hFO«½Ïˆáøíüˆî˜È e(’‚fÁªrF( lijìeéZÕFxBc}+Ë(ƒß3±kãYâú„3*é»hiÏ pILe–DØaåჄ›ÂOÙ,x›' Ð;Ü7Èp·GMða”9FUfŒvfèÙå‘ÓªG_û8 EBZª2ŸžP*®GS32˜!“.²2dB™,>·zñÂ3ì$|èÍoû3¯ûÛÛ“ý ; Ï|ƒaÿ[Þȳߵ¦#ô¶OÛ]àg>õw~âûמý&ÍÎs|zx×LSžˆàèh‰…ÀW?ñ¼bdAž…/I7HHKR…¦_Y †ßk›\3ˆÂf¤Ö_d”âèb2;»ÍÃ/3:øÙGž|òç¿ïÏý¹ß½5WT¿ ·åÕïÓÌ¡0¶×0“_ÿõËŸøØ¿¾²uõùÚ¾±öƒ,E?ܰ uûðÀÊ0¡§Epˆ+él‚F¥!#82&}‚I6iwMÌF=úÊW›þ‹k44-‚6@¹·E 0ì±’½ÓÅÊžËËTp‡ÿ1_§±+ø.è9ˆÅ°W˜+ò=(ùôqî~d¬­"@)¨ bÎîÈ„7G¤íUe!¨þ¨$Èò¯BpènþœÄHAÁÇÍ5mm¬˜nàwíÂQ†=½Ê&ÂðÇð<ý¡d°åWÒu„ ßô0¸{”ÙÅý›7šþ ²‡®_ȯŕ•æ‘'QäÇ7‰–J"ÁKì~á<†kB<ÌÑ)C 7âö7Hbqnqe0·¿rñÒÇÏ^¸ðáG¾ã ?ÿþôŸþ¤’¿¿›¶+ºåû–p[—ï¿r¥ïi<2Œ7ÍÍ_ø…G¾ðÉOþá[W¯þÐîõ›ïèíí_ž°]·ƒÐóý?eKgåÓ6u"¶1 ü¯;¶¨Ý°ŒJC$ù1Bqø•çš™PàÙûÐg˜Î Yól³x~%Þtm‹Ù+¥P„ wåBÑDã/ÀÀÔlÙ¦­à)´º£‡GŠ*°+9õ«†r0œÇŽ_¡'{”Ÿøø½£_}ÓlþCÀSp;B-®adñ“WÝ­>mhÞýKG˜t«ÐK§NäʸÙãüÄçúŒ–BÀã(W³üU¯}mð0†ÿÀ›(ìÁËð¥ôüñY¡ “nŸª´5²4F(QÇ`ž¼Ì±øÈ"âhñÜÙ_;{þüG.>þøÏ½ãÇ~ÌíÅ|)£~Ko/Ê‹oCã鿟çiÛoÇ|åCzâ…O}ê­_}у9ßßß?8?då~ŸE-atD4Û‡-°kðwA2¤ëTq0LÓ Wx ¢Žžûj3sõfô6 ½  ÏоÍe‚°›g;oŽ/åO D´ìÁìñièÑû£b_çßcM ñ¢ó6/Ê5{q’4½‰Ø9ÿ¤˜ (ô<¹.`¸Â ®šÀ…ZAÚæ­öäÑ{á†w*€ÄãkG„çœ>pó(Mñk¼b· ¿ÌÇr;ÙçdàdÄ® ß t Б•L²ü¢/9Û<ôøká±Tü«sÿ»)¢F ÚÆz1rÀŽ0 ä{æC¿f€NDáÈ4ì8”Á#ƒ!; gÏ~féâ…ÉõäþÁ+W>Þû½¿w7cÅï·Ü§Î£ :ø¦sÒÀïzïkÿôÃoxö3¿ú®Íëk?´sƒƒ9‡+‡!ôÖžíÑOUóù-jÖêX›ÇʘUox NuÁÊfƒ§:°“8I1æØ4àáWŸof^¸ `€ÐûòâÓ›¸ €a>々óKmƒÎö ]®ÄV -§Óí»:ŽC(IQáרë;Ì7c!ôœ'àmÄìíQGùC1€G7Ͻ|Ú7QRø¥å0^’öìÒo…˜ PÆy< ÿQ ’¯ÜޏWF…g?Ü™P ]ê?`zv´µAðaµ*ø§âs@âK¸zðñÇà£õ™Õ¢àæ“J +¸ÚÃðC!× •°Ù“à/…>ašª8®²»äòdfº lAŽYŸ˜]YýâÒ¹ó}ð‘Wÿô½ÿÝ/÷ž|r3©$©§¡~³î\ž|³™‡4î8˜c&¿ðOÿéw}õ?~ú»k7ß½ãi¼ƒƒÅ†÷®€3¼ŸîÑ[ï¶Ô0±õwuÁ‰\~ ¨¬±¡H!ã¤B ²aÑàÞƒç_hf9Äò‚?lfÈû ¡&“é̞YŒƒ<¬J;ºÆk´Øœÿ» hÏïZ±"˜¾J sÅ <‚yGèéÞ™Þ¤ÀÖïBa®À'±«`ÌâvšsrýR' );Z°|98îV }œ8$óq*QçþéïÄ1¹È{òM¥ˆåé–&ªNœ.9<Å\ߨ (?¸K¼QùÀc¯‰/†:ôwXgÕ8ÔWhsdý*Ø–5š Ôþà&®ôKªÆ)d%=}d‹; Ì£…ŸÐZ÷ŽÇ¨¤BMÂU¸MY`Ün|ÝšÀÃãˆ#pt‡Ë;Ž3Œ ô`&ã©-¶Už7X\¸¾xöÜ3KçÏýìƒo~ó¿ú¯ø‡Ÿ“n1½+è§g «+ðwÊ®eþ/ž¾¼}‰#¸³Ÿú©ŸzëÏ}éÝ›ë7Þ}ûæÚ÷Ì ‡½#È><§' §'ÛEè³JJö ×ß5V¶­5à|=SC«­„„Îî#\r1d¦·ÞåÞú†—TØenæþÏЛ9ßœa 00¸VçyéLôZ1ß·¡çtÀ€=  Á±lUQ–ZÓ¶•’FÎýzÝ5€z@( "Lau# £D®î K—c ­Â®Ôư®Å@pU)üÉ‹˜ µð,îPÀ51J¾ÂÏ!'¶e9åwD„ž\:àcª¡0´((€‹š^ýh(£+Œ leqëŸÂ²ö9­ {}“*Ð[:ºYëØÂ…iˆ#Ž üÇU¶Ñ ¨¶Q}êw4;·¹táü/¯^¸ü‘‡ßô†þ?óg>—Tò÷ÊïðYƒZ¦nžî™›öõRB?÷ÙðÞöµÿô›ïÙ¹¶öC·×Ö¾k–Ó`{ûô JX¿?¤G¤{É#¸ Ð0 ºÓÄ8šãºô“\¤lðFÒk3ÊÁv%š~â¡ÓH·¯ñÀ×®6óàòY f.Öˆ‰P6›e\ 9~¡AŸ1ÇÉÀyÎDƒRÈËžöþù  4l¬Ñ ¢Îpë7S¦_ÎQ IÏü…¡Ï5€Øò£ÛÅ@G à†p£ \t3oE~‚4C¡IÛdVÁÕ_?hŒp‹çSÃr* §½=Á®íª¿S˜NMNxÇ” žãáQì¤á² Df–/]l˜sãf…¼¥ +ÌÙ«k»EX…8á‰GËT!›FøÍ¦*& /¯#÷*Ûpâ(ûa:£^páÇË”ÔÚrG:äUæf8;{{ñÂù/=û¡^ÿúñö¿ø?küj®üœ50ï÷ÔÈ {z¾ín:¶0hÊ…_ÿÉŸü¾ëŸÿ<+÷·Þ¹kýÍŽz0ÇEÏ8³ÆQNù,ïáªÌ•½²û0 ¥pG :/Û¬‰¹'é˜R÷)$Z¡ˆ!®ä¢­k×Q/´S€YvæèVàŸŒöi”<jKÁ~0×o\]ža¨‹, ˜ØàP ~®¤ £‚@|ódÎh!Ç– îØæ ó{ÿÜÀO¸øG„».0椢#a¡<Ü#müòMQ)YÎ*ÜÕvd`ü®QpÅK%q#ÇÒ5óêsì”ü˜Þ߃XÈôäwtG®Xï˼ tù‘G¾T ®\ [þU7ôuŠÏ±õ€†uLÔ8«_£a¦a!0µ÷pZÝ€ksòB§Â w¨ëY^nbGápñâ…¿|î܇Î?ñÄÏ]ùÑý H!ÊgæÉ÷MKQ6Þ3Sóy/èSˆbßúå_ûÛûû¯}ñ‹b÷Æúno½¡Àï!ø‡ä„£°Ãz’•|ÛgͨªîÈtÄHLÕ-^r4 žº’³VðI›žt´Bk"ÕB¡¢f³pÑ«"°Û7n²ø|3‡4Ï `sæ ëNúœCàT{4(›•ßw¿nPÞìS Øë÷ò(°=?n×b À†_wûé.sd»âÇ…½X PøñÇÑßPŽêz€ ‚Å6zÿœ&XváªYúô8ßoY‡¤g¹äM(¹Â§pÜ9-``ÎPa†N óT`(˜hüäcò9ù˜á‡Ôýˆ}¸Cšò•¼Â.TŒƒ@ž† E¬ð›7ÂW.?Ð\~Õ«Ø«ç ô§ À5U¬#l#Ú†ÛÈb´‹ØÇÞ:”pm¼'n}Œ¯ §…[˜©ÌâÓÒǰ8@ЬNÊ aï6÷E§}^bbTðëKçÎ~ä¡×¿þÃ?ðã?þ«ä¯m–*ƒ®E§ôcŽï…‘GQʼø‰¿ù¾ýÚWŸý»7×ß9ÜÚzBaØã¥ uN™ÒÓs£•=ÍO•Â`h'sï–á“'ýmIhÃGà¦òB°t«tª[[C~l¼°#~GhvÀ![³C àÏ"\Ty3àÅ ‡þ¼ß‚ìå }Föò¾ã?ËÙ€æqîåI@‚ʦMn£›£TÑsÃ'§Î2ô§ð§¨ Âü°Æù‰ž_|ã)øD´¢‚]ùÄ×èf}U×ã½Y‰†Ë¯:Ï·ÌáX®TáQC ϸÚᆞc8óuHÏ?rèÏ´gb ‚Š#ð˜Þ‰@*€I³úÀÍ?ÌþBOnGøåã1¥T€ \ÎQÄI…b°˜6˜‰ˆeÜŒ“/•„!f¡¤Ú# 8%Ñ1‰€ÖñˆÈYƒI¼½è;’=ÖçšøÎYƒÿ°xæÌGxÃëÿÙù+år§îlótŠ”CøÿÙ_ûëo<Ø^û4üstkó ¾»ç+¤´¶·PßLê½F³+ô_'Vb-XQÚ2?ªÊ@Í îWP•6Ÿqƒ†I.]I¡R¹›=XâÙ˹àÃoÀ¯ï>÷µfŽÖå·SÐ`x»Ðþß^˳þ ½ ^Šƒ>(½æQñ\¨ d‘£ƒ`´mÀl{FÆd‹2a<íÑ›#`íê?‚2d‘Í£Á1 Ï9bÀ&–Ñ‚!ä(ˆX æ>7uÄ“B©€§pÛä-w ·ð<¬§R¬sþª M£† é݇,莹+aŒð+½Ê@Ìý©œ\pÀ‹SE@4¥…lÎ<ø`óÀCqÈJÿ(|ŽìùüN°£‰T¿‚nðm O%7”ˆðfóR˜Ã.pñ ÷×õ=]0,p5ÅavÂöcçðšjAU9kaÏìS÷G3³¿Ú,¯þÝÿéýß<íT¼¹*u*¤¢Ü6Ëñ¿ø±ûÿð?ûW‡×o.õ—›¥óç'K«+#¶½8ÁêhÌëb49veäyH–UÆÙ@ȯ)¶š¾ Ãm#0'6ÂÖ.þ6j:’„îŒ3à·f;C:i…ð Ö]žp!{H£Duˆl¾ ŠÞ¸{ÝsñU0fá±ÆÏC݃kƒýz^š±gž#ž·ÙBð³\f !?æé¸UhñRôMK¿‚‹ý‘ó|9,'d,{tó”ü‹-BÊlüœ> LTN –£€—ºÍgÙªˆtñב$²ìغƒ/* VùãþÜLõ$ ´Šå1ýIÈ8yp~DyÒà!¶©§èJTªS;Ú~yXþ‡@ažþZ Ç£rЛ±J ÒFÖ‡»ÅHžIj*~–9Ò0Ð4¦HASo$_ÊAÉa,ïOÂÊ9Ù9:š¼°±1¾yýúÌöÕçߺðÚ'Þú¿¾÷½Ûýƒü™Óžœªx©³sŸùÍßÿ¶/¾¸ôéý¼×1»õÜRæÁ 3«ìá.³½ãPÇWîxG3œõl fÁˆù—씜•{šâ·ÑU F¦FXµ+n§&pÖøÒ a "ÆOXÕ¦6k>-B3a}(‡°®eh"/¸yù áš p²§R€§èM:8-P øÞ›ŠÀ¡x½|cf„žä…_ rìà9SËÆ ‡Èd,¨ÍÕ~„L¡ç±§õ•Ý8óm{o6y0^<À£§Fuë©6ÿÄçNÃØR$-”Óµ°?ËwË+M2ø²^>)ðÎçC¹˜i°²?æ†äÀíyÄŽÙa å*„±#lçÈUOmp"ʭл…:Χ’ ˆ0~äTå•ðÌeºŒßâFîñùoâ'¼–$bŠ[áôûc™‹3ìâM`‰+,âë/½ˆŠ O ¡nÝfd´¾±Ù[_»ÙÛÝXgb„î]\<ìoïÌßøÒ—_m NEÒºOܪ¨º87·ýŸÅº0ÌÞúÏo7W¯~­ÙâÙ8s¡Y`+gÅepùcœx“/DŽÞÍòQ«Ö&J›ÜK@÷œiP6¼À—ÉšB7k XÐ,Â\èÛø2‘”i\d.vm A9‰§½“ÿ\׸·/iĆ4\Üc¹ ¼x‡‘–ù¹õ«<ä~µs[uÀÐýŠ÷Œ8,½c `Ð a!oqBØä˜ÓC'^®PFOLú5_¦Âo8 C˜ìË…Á<0!¼hñÐ’ShQF1Ê!?AÏ8Ò04S\ Bž& ¾ CƒE™y“„ÇôøâN{~yª¬äŸøÕ¨ úYÄÄ66Y¾BžªL¡—7)üÆÉö”ê³ ¾Ø¸ ‹x‰£Û ¯tÂ/L4Ó¦;Iâ1<:§íF¨åÓØÛÔ²¶¹»Ý¬­ßj6^¼Îe/žeàÅKO³ ‹lõg¸réÒ…î-FAã4~NU¼ò=M®.î ¾Ø,SñÞÑöªñ|sëh¥¹Ê¼ïyÎz¯o­£ÉšÙ‡/rwÛùfq9GV.M…–aÑ’õ¾Šj˼0€õ·á¸“ïY‘FÝ”6BÄâ§SI %jET#­ QÇ< Ìô2Ýhd´lãlgÚA±öè3¤å*y©ÀD//<ü S¬ h3óF‰¸.>hf¡ j¬x‡è!ìѼZFK\§Ú± ð’Ãsí$°ÂB؇CS¡·˜LÌ\K„_!‡¦ ‚Éxôö±>ÀÜÛ‹D¼éhäb¡‡œØÎ;â`º0Þ+6ŠkºHL&Ønñ©âø¦‡ëöôyôèýbØoÎá!Éš¨?ä¤ó5nP<òÈ<ÆÜFì\PE¥[˜±ü¶¥ÍSᡨ»ªôràd{bHCKSmaÕ茩H…Y?ºÃonÓi\{û}da“ôöÍέµàÿA_˜¿ÈÕ‰,û8úÍ!8¢X¦8üªû4Í©*€š±þÃßžÐ8&GÌ÷gmÔ½æA†ý—83ýÚábsÆsu´×\»ú|çÙZ½ÐÌqGþ Wc/p ®]Qy¾À[8OTnEPx12Yuµ3rTF8!4$&@»i§”4z£Üé·úŠX¤#ž·äYf®À ¡³š”Cý7˜¥÷$G “]̲ÇîC㈚ž!Ì•‚#„!ÖHßQDnæ°7…¤d…pWÖS ¨À¤^¶çwÈ‚n,æ™eˆè攌,Þ$'¶K¼¤LaGã‚Sºïð'†îŠÞ\úмÐÓ³®TðIôüæL Ð ¡ Êôus§)ŒÂ󱲡—BÐl âøJ7éNaÔ?­À&^<ÄM:øHK¸)©`ÓNx'‚™¹‹9&‘UžföDžôr¸mkw·YçâØ Œö"µ:À…y®BWðcšG$â»¶žÓ£³—/Ç¥¦—ƒê]2ñ2A§ªž*™\º¼ãM1œ…r“‡"à„¼FÑœE1œ]j^=^h6†«ÍÕ½ýæêöÎXoÖ=BóÐÅf±|BkΗ,¨Ay™=žBF%á—³Z1î–Ë+3LTBå”XY©F ˜ˆÙÚSŒ oƒZÌ.éVæ€"d/î{ä±ÍÅWárZ=-sh¦<.òÍ Üa¿š+Ùø¡å•^ú½[Ð^;æºÄ‰x”º‘% ã¯Å¶Ç×W{y…7†ù A¡ €© sD=;ysw „,Yª :Ë‘J‹žÞ¹»=yöüØôôÑó32°¡zµ 'aç"r„êã­¨ C‹0±èH€4¤=¿®¥àü0î<Aþ…ÀO…?á¶aÇS•AÔa/8 ´‚ªÛ0¢­é.øÒ“7ŽÈJc ·¦Xò¾¾bÌ0‡«æö›[¼æ¬àï¬ß¤<Ä÷Ûtxs\‡n‡gKÀ)B(!¼Aúá|]¾|y×$NÛœª('—âKÛˆ=튖•%l¤6<Ë<„€_bôñÑbscï°ya²ßÜ|ñùfÇgå|3wéB³Â×uø*L|JY)ØÑÛÊ ‰–Š’v˜ZKá!К/ˆ%§¿Ïš `øý!zÖ©¶‘§=…&g˜Ìdñ!ÀC…î+´øƒÉÔº¯˜»ÿooÊ€@ÃTfqÜ£,öN6r×BØ(€Ù0l¼m>LF?f=l`"´‚Ž_~3@ 70cÇß6.ù Å@^å3“ðPçX˜ˆ¡zŒXÍgâÎv¬¸kç ŒG™Ç³Ùó;þ‰9}߀uGÙMºfaVc¤QòC1cŠ`ˆå5ܨXqË[ÝòK|ÓÆ+¬ºâ&?åW ¦—°.Üð|²®ð’gé‹…ÎVÈ+ÓI“á¢Èófx|à”—ÖÖ¸ÞìÖµ›\ûx3XöÛ¿ßy`Q5hÉ›H3S ] IòÆF#€‡æSSMSeL÷i˜SU5CG_ø'<&|.›œ[BKâc+·þ‹7FiÏ2ôñyd´Ð¬,7W¹êÆÎfskç£ báðü¹fÅðbnDd+ºNÛš´å®Îðت@x×D|EITê!°(â)˜&`éŒÆfÕØ#(¬6Ð9â•ì“·ìqÊ·ÞÆk/Ÿ7pýA‡8Õï{ö†i’2väËüh²ñEîlˆÍ§´µ}¥?sož–åBù‰ppH'u&ÒOŽºÔodÑp‡QÁ5îÔ‘oæ¬1"ØvTÀÂ<[‰+«Œ ØA˜¥Òr‚BŒ¢Vd©Ž¤óé!*X7cºãwú¸/!S@4h#Xiè¶Zm”*¸Y=0ƒqxŸ¿ïÿ;<ôjÚCbOxȹ¿qR)ÀañÇ`z¥­¨H¯6ZÝiÒUÓÓBM¹¬’è}µž4„ÇŠ?Èåì¥3ÜíK®0@¨Ap˜O#óŠ3ïºy`žÙy¼#¤–S¦IÌù½‰‰ø„9p:hz·7MP>V‡‚9æ 2(yÜ|²HÖx–‘b1u–郇dÜ2Õ$Oà+^k[! ·¶py–°i‚Ì}âZo€ù,ôôŠ$ „-äU¦gt@7éíoñ¹³[7׸R>:k¾×ÀíO,‚‡à÷æKÜcB´Ã—ùMO$N›7G„Fë/¼Cˆ‚{ZÖé*€’«ÑCmóÙ¦D`Ù9¬Ì"•Bã‰BËYxáÎjRÈÅÎ9*83Û<ÊZÁ:‹'/r|øEv6yÖé ú²VÀ¨ ΀'墿<„¦&jC‹¦’y0¢eÒ#òƒ­1X“0«;•Ñš  Xå¢=6½Î<‰eÏÞÏûýÉÅñQw G8ô„[Ò3LÌÄ‘AÓžp5ä'Ë‘<ÌFj&,žpAÓ2¨„”Ž®ãÏZLÿNmü$kÏ º†¹Ê¯R˜w ¿´Ä±Çï+ìÀQiæ#·ö å!¢˜RàŽQ‚¥2®ã†‰¯8šVE2‚\Ma—O>ŽªæI+§0R’3ò\csÒé£B p…á·ÖS„á×l⊃ÛühTÕcÛô?áüÚÛÓ&7y‘É-¼­›×¢·÷ú¶šú'¿ÚWÄ׸ ¾ “§¦¯í¤+° Íô¹ùöÃo|ch)¬kÍÎ+2§«JÆ^ýªWí~ninⲘy.ÙìTÆÛÈ4VLýê»8Áp Ž Y4ÁÐCv8Nüâd¯Y»öB³ËSG|ù…{Ê›uвQGv°mX‘vö¥¤gÚÍŸ®»ò_-Ÿ4Àmk)ñ[¯8…Žv KÙCJ˜[_¾Ñ<¤‡ôÇv'³4pæÝj¥á9ÿwô@#¾9Õíh à Øtd™2¬+©ùËÑħöî ¨!üFÜè™ñe<3‹›^š‚ÄŸBï\ßaÿ˜s špɉýx( v©T1.x2ëŠMávÎ1©mðS{~Êi['¦CYb¤BfÜuâ`Wût¯ß’nûiGïO…¸3bþÛs¸ƒ÷r'x”õV‡ÿ¯¬óZŸ­m`52LS,yÞBS~{ÓòNØaáÁ¿ÍTU¬>[x³³|î£Ü®WÙ"¡·nBäYòâ“tä»k'¤d 0øé÷wXýÏ)@d¼¼rût@ÍÏ»Þ5ìýÏÿËv‘íä¾-cE3ݲ~„[g  ƒ‚?Àk”—ØN|œ­Ä›(‚«ÃÃæ:#‚­pÃ; î ðñˆØAˆÔjç±RµJ&ªõ%¦uVwµ#X¸Å‰!9_ÇÁ¥7 ò¦>SCØ!ó@?³uÄ–`¬ôÓÄcjà?Õô¼5"À­ßTr4*³@ú5Ÿá-8!Ü%,æà šÏÌnƉµÆb„E©Cv·rý³?@€ýÊ/ïP>îd!‚‚­J@ …ÛãÇ¢!yU‘¸Ï_„¿â8÷wkˆ…èI,ÐÁ8_“vÕC*…  /C¸;bºòÃ6f¶³­%¿AKÉ „­R…~ã NÃÉ»´u`·wláñÉwNê5›Üû ôÙÂðñÖõàÅ”H¦£›§K__·äÃ!02? îRA|·`ëÊÌŒß=usª €2×`ÌèsßweÇž‹Òºs&zûD •9Q,f ©ù3Œß‚´‚ЬðéG˜Üb­à:;/²ƒàZÁmÎÌr®`™Ó†¾o?뼕È;“ý&„Á_MÖw›‹ žÚ¢ NÍ%¨àÕ¶h‡[?&zXÖ,x!òàˆƒCôªôÃæÌ³ìûsŽxÈëÁÌgP4&ðhSA#VºÉdͲ7Êbz¸ÍMô«:0¥‡+zzeú²x#OŒ@lìòFM½7 {·üJÏϰ%”€ÕSò4á&Ðà:„¹¥GéZr=>-á—¶8™ãrF‚ü bÔ§pöéæû”¿‡Ò±Ýļ_8qã˜4ŠÁƒVÖ¤#óBá'TÍ{áMòÅ”"¹¢ô$´3'%U&a†xïY…]ÞâÜdn¿Î¾ýוGÜ9öìm*ôŒœ¾µñ[¼ ôW@Ä ×Á1ŠÑâ&0•\o§ùó~Øü…¿P0OÏ:UPË=鯮 \*²òÓX9ɈdÉÔ7õƒQ¥Ñ2Œø!Ê1¦¢!ö ¢¼DEÄV";/róÎuÎlòÜò\ÁƒÚs®À:4 Y€h,Bvj«*‡È&á5ÝN¶Í^ôµ–ʼnS£§f£6žùÕØ¬{©óï3ôˆÑí3çwj€$Ðá7ó(ƒÑž‹fìÿ3Ô>¤çõ-¸h6~{˜’9“Sàkƒo>Â+—3– ;óM¯M¦ã¯ÓècÎ/\©Ú·Ç'/ 1qí½cTAÞ]Ä3)«Bxœ*Œ¸Àz²î¨Bö*°–‘ÝAŠC¯ßváÈ&7AÉÑ@ŸI~ƒ}N¹›bò!¾£ƒìýÄÐßlùnˆÂ–ð´A \íŠDŠé¶ü¶3óDž:2Ûæóî·66næÎ:_ûK|¡Ù}{Þ”ô» ‘†‰B#Üü$,M­ºjÛª~ÃZPxÍŸ¸º¥ÜCùÎ./mÓ2¸¢µ‘_™ãž)€fey+·Y–)'Ìo-­/Ū¥«ÁÚEÎu¦1F’†¥f±ò{Í*=æ*;n%n —âØñ5¾ÆãZÁžëg/ÆÂ’;Œ |ß>z+­´Î¼™ ØÃظ£q ©t¤'ªüDf%…F<ÝÐ%‚ñ£'MW͹<€|€Ó5ûÖŸq˜Ý?dŠÀÀá¶/ÉŒÙÄ!¾|ÄÜÒs¾¡çðÙ‘AÐÇmîÍ ?m6˜øµlům3 &Oã“Âp“WOíÑÍfüyG'Á¡ö«ˆ&ìøý?ðRÊi)ÐðÕfË«°÷X'èsÝÙ y÷µÞž7ý:°7-’é3Âè¡ìzK(¸}®[ ŒÝæ €8úË’E¯O®œÊKssý¨7Ë(ÄÒ™êdÎI†‰¶~ÌKÆÂéñÜýfƒ›‰7n­7¼Œìéñrî`ñL|ž|–ÞÞs¦–édÊ´jJ‘ôg %¬þfœ–”U€i¡8‰EÛè/-Æü¿wùÿ~@IDATO {™ö©+^Wô ¿âºí¦ ÎJ“ÕÚÑд1 §<”¹«d¥¬¶¸],ªD¥f»b¹irTPŽߨ?l®l®5[<·8WÐç\_{i¹t"+•ÆD!‚lu¹´ŒÑ,Ãtó˜9,XYÑÄË(Q6E. –dçtˆŽÕú®ÿ„7ä¼3—ÏÀ‹m2ÂITR¹ðæíB^á5žáq[!s¡Óíºø /Á^7¸VÊ`öã)Ù°ÑÆŸ™PpE־ÌÀÇ4 ~ÑU»ˆyw9†..®Í¢@âsÉtçlćž Dá—aNà™BxõY܉HFzŒ|Ü´ÜN+ܹám'Cø”6®ÇÊŸ}¿:E¥©RS¸!?t×…¾*„€ŠÉ2Y¶7³ÃûpeYƒÒˆ@Þž²¨·Ûl8·ç«N‡ã<žëÞLÛ;uë¤`Ô¨gazZÓõTwÙ"…£ ·?A8~ÖÒøXÿš[¨/U¬ãÄ^ïÔ'•‚YýÍ­­þ*ç·¨p»+Ûf-t¶Ó,¨Cf“aÓíÕ¬X­`ˆÈ6(kÞZÕ]iáK „²Vºmì=Ð9zŸÇÜJ2=àŒ°N°Çã¨`–­ÄÅ3«±ƒÚ=ÒµÑglœætš¡)G`6¼D³—2!9 %„“ž_¡’v¬¦Á¡$á1n°sÝQö„Ñ€Ãå ócÄ&9^ÕLØq*á FÎÛÇHÊØ/ó ò1ë zoŽž!„s( zm?HŠM¢¤òPkðÏÑü8ä3A±ô\{€¯/)eÌ÷·£×î;9Ÿ(™øAˆÒÙjvÒã{åØÄÕ¦7¯~Ú8¡P0Îí= Ñ×ï%š'‘[¢îx!joäMǹóH2¹®BÊĨ‡pÀ‡…Ñ'Ç© °õÉLáXòÚµ o¤ÚæxîÃüÛ¼Œcë1 ,­æ¢[xîÚ„1z’«4„/X­mÛM5SW…œ°E¨ykãQÏdxÝÚȃÓ¤Nxù^«òTÍûK&g–oºýÃÕžA¿2A^¦Ié·ÊéˆI%;cQ¥6J#cŸ2 It~»ôkES€Þ<ù0#‚Ë<±V€"xkº×ʨ`³·Øl³VÀUL¼™¸§µ‚ É”m‰5‘NºÕYƒT"Õ3/–!=™#hB*\Z\{:‹UF”9ü`A/.~±b…žEº0FF³ð‰Sd<Á Õ%æž| íÚ8Å@`'®¬E/ BÀYTàôú(è¨'<£”ƒKDzNÜ#pëÒãPQ “åÄu´ Ñ6OÚàö­ðÕöïî=lòæÔÀ õJ/qQ¸‡Ø3ÈqíAeƒ1¼ð/V+Òƒ„‹× ^=^™'ÏGäËwî7éí·Önñ2NY;%t ÏÅGÉ"Z¥T«¿õC«¶1aÕm^l«Y«™³ãù;™_#©ØXµÏöŸ©Ù[t—èþ²­SWï#+OópäÖˆm»Þöa/-us’ÝrGÛ#žÌ®Ùv³?°-å?Â[:Fp×Xé&j¥(¾ˆsžçìÊ ;‹0bT@Op„2*¸}ŽQ§ Y+˜Gax)§‘óÉ©L%~ —y 09Æ¡z ¸eQ¸-‹Âì@Üxl©Іz†á¶¿Õˆ—.š‚~‡7a¾S/eW®¸ñŒ#¯ Ãnw&¦ç}~OØØ¡7̹YÝB;b3‰ý8‹=µý¡‰‡øìñRâ:…éymXã¸_å3‡­-`Û›/BÄŠ4.Z>†ýÕ6G §(^ 2¯É¿ä[¸‰n®Úù7n9•ÔÆÈØÈ0‚îô ?d¸Í[x±o¿ÆÍÍ`z×â láy[ÜÁhV s4?L´£t&KÀ«É×°ZÖ”ÁÕtPtGØ4Û‘á[0 œÕOøÓï¯ù Ï3<§iN]4ï}ï¤á ð™ ¶F1Ì]@ªÿ˜©Œ¨å7PýÕ(0a:EÐXA ¡ŽÀ5’@Œ5þ17ÀXDÅv˰%À2šßFÛœ+¸F#yqÌVâÆZ³Í³5àû}—9z|Ž‹K8äá…µr]?ËV$hâ/&>äY7]Ãud&k>ì§¢ÒÅ+eŒÆŒ;ø4À€PU¥¸A+’â'醚LØÊN<±7\!WŠè¹§žÙ[#ج-Ä){~@ Û‘Ó·‡ï™§;UÉ[\Oþ(Jj"ºvÐCø£ŒÒP¹8´!½ž˜‹Ab.c"ì¹ÈaÏð;:é“Gæ&d~°ýPÛ‹Ô5 d,2ꉡxªl BŸ>iŒDoÏ;÷ÛØ9¨ÇsÙ¾ÌòÐÛÇÝ‹òœhÆ”D¤W`5í’B†éÉdZÅÓŽ¶Ù†´µ{ž ™¤Gä¤SË„–ø¾Åâ¹3ãôO_äýÿå·ýfœ5W+Óìg!§©þjOC¦®hczA y‡nØÖ„½ ÿ!PrÔ‡À<Ówn‘È —©áOF«£.0=Ï ïkX+XcTp•kʯs_Áæ‹_ã\/ô8*`­`—‘yÓ…­¶±˜/2OÌeMÈ˲l´™wÃýKÜøuhO^\íÒ&Ù3†¿ÄnŸÊ®¦n’L6Ü∡<Å•ìS…íÜ;dC?ñ&,:Åörókov˜Ì³ sÂíÛ7æÚQ|Åafñ+°N3ìñYì- ØÑ‹Ûá¿qAY6ðX ® …ÕCÄ:G¤k½˜¢Sl½­Mæó‚T’‰¥µyñ,hÝÂÛØÜhvoÜ€uQXvøÖ /â0ª›q*bÌ*ñ‹·*m¼IW‡¦Ä©q#Íò“µžÄ-ÄMzÓ°ê2épûcåd£-1ÄÌ‘×Á\¬œö]&tê  Þ ÐÍ«·Ý˶hjª&Ø…»ÛOðànÀ‚IØQïxJ;)LË€ŠÓÒ‰FáUSj¹Ð¯¸AØv\—Z/•QÁ£‚xEà¨`—g‡QÁîì ¸VÀ–#ï;İT ¶™I×…¤¸¾ÛÆo©#{™¾õ›=?yRØýsþ.ôÛƒ¥Èe5ŽaÖ”²EáåCÁJý§Ÿ„¢GÄi"å15(€ô…_bv¾AÄ^Ü^Ûa½‚ìÔ@Á¶÷öÞ-‡÷V¡£™ë9*–ìÅC€ËüÝ‘FžÂ¥¦ŽÚ¸ÆA cÄaÏOS”M²pL.ëNáB·\B!áá(­)ZTøð³Æq›-¼-õ6ÛïæGz{œé3ÂëÓÛ{.ßE½àÌóÁè×o†ã¯ð¬?©ÚžÂ¯gPR”¡™ó.F'i´ `Œh9V4¬,ÖEÀš“S³O]Ô÷•_óšíÝAoÔßã=/”¿¦ËTËÜõwÃï°NýuM¨ê–hJàt©dñ ÄQ cO¬¨$j¦‰ 2Ü\dÈžã5Ãùææk=¾>b»èêךý«W›Ûç9mÈôÀµ‚q‚"#‰˜çš°0…Í”TDöl~f§4 ‡ñ´¨o‡å ©ø¥ 1¿7’Cê  «2ˆ¸Ø±pHœðZç¦kqÙ~³~ëîF³5»Òl_bzàV" ϕ乳«ÍðúM„J!86ð4Ó‘ÒU¶P2æBcvù怯Ú)4 èhÍ:Ì=³TÄ6(q€óï(n±9ÌŽ2zi†ð±S®p‘Gy"ŽT1¤ „©ª~)h1^öbú¿nóIømÞÂSð÷x$Œ£1¾%àüÞ•ü¸Z BuT”H¦{wSáɳŠ¥J Ébä´,C}Ü]ëÆ¨-{“þpVš.b5ð‡Â qÖs5äÔìÓW¡Ê(ÕÆÆ6Ux›á079áï”ë·“ûÊÚ“q*9ÛmÅAÙ´¦[ÅÓT[·iNA ÍÆbŸ¡™eÞ™y¬#ƒ×xƒQY+¸qDtu§9¸Ú0*¸ÔÌqÀh]¸Üì¯oðáKnr’&ÂfƒpzÒö蚞Ÿ8` D±Ï-¾OŒ"R 0ô3Öˆc`Ä'h¦-<„ßôù <çÜSç1žãý–¬É´s~® WDz|wìñ¹ß ¸\ÅÖ”üGÊmX ;ĵ–R±dÓȸ¡ÊTJ*Mò6b¡rž_¸Ìå±ÚÚBè7¸agçÆ3Œ<°Ó°@Ûw^Ï™‡_¿5QÊõ…¨üRfžÌWÁÓÙ`É£Á ozã5M×•î ™¦z•¼4ÇţЉú…#“Éáp?FŽ B–NxþÓW…S¾¾¸=7³M'rí:òy7Xa•sß`aD—Ô]È…cähOU0¢­Ù¾hsۻƩnTDk¥Äô¤H‹H ð* tu†cÇ,Þ:Zb­€» xQ~ýÖM•Ül¶yCŒXÎ2Xä’S?}}´Å}ì¹+¨¹–Ãü \{þjÓÄ‹\õ·$¤«`•Bdï™þ:[¨XQ'—ùŸ®LˆÌg™láN/4Y)~Ý銛®9Q ܲէÀ&…\ãg‚S»ª¹„+ôöü)üb¥™¦FZ y7¡os®®rYæÂ›‡Í³Ï}µ¹½î¢,dŽÖ_ð-<_Æñ\¾ŠI“ÊPáË¿FQ2<ýþVÁÖ¹(Å–P «và€$ÛvŒ˜±kd130ËßAÌ¢Šp‡©zxJeŠL[Ù\»–k¥Þî 𠧯jf~ôG?ýÿìxE„»Å4µh2²+ô]e|7¼’íÚ•aÕ>Öúm5©Mÿ„ð‹ë“áÊ¡&¬âÎV„§P(âØ1=Ôì¥?ÁÁ–‡KÍ (ƒ6Ùúê—›^FjX4¬,7s,¹5fxk‹m/”OL!Êyv]—¨‰D.ìéM†Dòh.çÀžÇ÷’¡ÃJ‹¼JBpËKÜüÊçì‰ £ÒÊœÄL¼J¿Ä7¨5•Ái‡‚"•ìÙEMþ¶ H( s‚‘Ë5&l/.œåH¦S~&í€-ĵžoö¹4VÓçnH{ùxýÖa¾í*èd™Ûµ`™š±¦î€e„iQ {Ã6 ËÆ’@Xmü Ú]‚Ó´º®šÙ+íšžð)ÍÂÓ牦È•ÂìœÓ›â6 À%ì4Í©+€N&‡¨ð|!ˆbÒ|*’Ñ2>ëmÚ8KÉ‚I%ì?WX™)Ç:é†G}a'ó ,{wrv,ò´ù‹f“V´[Î\a$nøYÿÎÒ(eT°>bTÀk¤q®àú q¡ûˆ†íÛds]nF(‰ÑÖŠ€·Ì<;ïõÈgòc¿¿ä'Å^1VáIÛ!}¬¨³ÃÇCè㌔RðÙø,¶G+*ˆ©·¹=QÖ`V½–$h±ðM …°–0ý©Ð3‡Û†MÇ“r$ALêEŽ9¿·ŽÆ,ÜYø˜61Ì÷#({ûÍ[͈Z_}áÌíã>½8' "—ß,7^p§y§ßhÆ ¼êÀ޶RüÓº$޵£…’Vr¦ÂO¦xÔe¯¼¿{Û´]ƒúæÊðíwýø›¿ü—»§æ>u@ÎäLëM¾òö?Ì­@êp)ªÒ¤#™rRT¿áÕ]™'옉ԠCÛ¬g¦@!YMíh¤ï¦Ñ'v‰°«GrÅø|jUüy&¡0õÆc]Ýçƒ(4ò››·šíÍõæpqµésܸwñ\Þ°ÃöÕä¶Órè¹{âÇêÐÊ¡: , ¡îú‡pb7[¦Xh†,Y:pÍ[‹ä5K+!s˜ù´¬ ‡V‚ÁÑC~‘ZMd¹V£‹¨0çåa²œY‰Îósš~GÖtµUSÕÉEþx?7 Ýž[àŒV«-<9›¿'cn¦Õ³²9Øš4"Ëe6ä"g6©S™ª)Òs¿÷B˜K«™3's,ÕÂêí”·+´¨2I¾¸ˆ^M”0Ï´á*­ïÒ=æ.H™—l’Ò­iéÖœô Ð—Djî’ù(Oöþ‘7 ±¦rmž—‘œi¡ nð„ÛÍÆÞ6_šo†ÌqÇŒ &,dy®~r{³óØ(UEg\¹Gø=2›«ÿeANf(ìò r€ÃÅ qõ‡bÇr ·¤ijy[u[Ï(ÇÔ€PÆIÞY7¾¬ò%XÀÞ* ±2GÙ˜øÒ]ÁÌ"S"ÊÌø–C‡\±ÅM;û| 2ÍÀ+à¹õi–m<¯ÍV¡Å¨! 8¥‰«s¨©vúîþ+Žé´í @·= ËtAËcìLKWmMYÒª¥ý‘~K¶D›—=<‘—òÛFÀµå9š£á={Øôn°±·ºÂ+Ááj̶M™j5Æ(ȆÌÂî @ÍÈ·’jíä(¸V†M[£+ÓÀ—þ)‘\IéT¾™ œÚì“”´‹ÀÄcššzîÇØF|˜žn‹éÁµ½£æù£½ææÖZãäÎQÁp‘-.v|ç¾ÇËJF!xA°nã™—ä ·}Ól™e˜ÌrÊPJî¨ÁAæJÕ”â^Þš¶œÆ÷î‚nïno.•,UÎó €»'án3fûùjq¹ûk!nÓÙzÅÖ>ÇsGðAÓ礞§ô¼A7®ÍŽ‚I…'ÜŪ„#VT|_ߪB_é‰-¹6³º1%¹ôtÒ«eŸFH^VüjÆ•V$€»¶ã6ÐðâɸS ù@crÇÂòr=$j¥Ö%ñŠÜ÷RØnr|£d°[Ô²qvËd[ªE¤‘Ô†°âM ^œ’ n C¦Ršjí*ü¦U…7ó¿Â; L(*óaz9”@ñKÔ.ꛟ\ªý¤´½×F¬Z_àyíp¡¹1Zn^ØáßPÛÛiöy+q¸:ߌyÝ÷ÑcTÀˆ€·YÈÏB9ÀCÆhјÈCùXÏXˆÚÒb^„?¶;r8ê”ÁŒÊG«; @ÈÇì¾#‚0S.’ ¬àF]ü©¡ákÉ$=³DO¾r0à%ÂI³{´ßî²þÁ¢ip_~\­Å¸HÓ¢" KAÍ®Ï1¦ëÇ<í¯0ëHÓ†ˆr °«¸l¡8¶nx = à¦[ŒðdI˜õÖÀ«HD;L¥šv¢v#{™ô»  F>5ûž(€÷Öö66o6gê1uhhÒ¶µ(\ S޼´¿à…6Æ‚Šíä8ÿ:LªÕ[íiÏÝ&KÑcúÛ‰y7籊½!¨4³S~£Qå¨Ä4ÙÊzl†Q=âç ®²hø½áúÖ-¾„ÐoYø3jh˜'÷Ç(Äüð¦j¼K öÊ¡ùuÎJ N>@‹‰&ád6v z%5 œ¶Üp½¡6ãP§n'š{´w–³–ç¸;W¾ñGð„Æl‡öY™÷M;çöÔ­«ù{Óñ-<ëº7ï)^¿u ϲ˜žÒ…Á—ÿÍ“:ë¸+P¾îÏ4V–§+Û!"tä_†„§K2€ÔŨ<3¬¦PìDÏöˆ»m—ò½¢ù‚hzÇü‰P•9PN:]"½bëž(€÷‘­§y¸Ãn}¼H»Ü)Y8‹Ö±i”wÊ? ϰpçUûlmw„àG£ç]¿‡çÜ~à¹üH‚4Joì ^dÒá'L¦,¬Â«]Z«[}¥mXf>½Eß$A#‚ZI£RJü ®°äCÅÍÚ»›2ȺŽz.QÛtkû-íª¦Zr7Í\GIÎ,.ä›M‰pê¿÷D¼;žæµàþco Õ^©® O‡Þ<–˜ìé-V+•'ÊXà•_âžt{"UVAH«VUU™~¥QÚ~Æõ˜hLýkÝ㯺?&lmwpKwßÅJ7¸µÉˆ®Ûž's „ÌyŽýnȽÄ#ß´ñïÑϽQõ•à +Ü ÐÛ§•›²¢¢,¥çq0ª©üÑ-34•‘á­4WCx:€6 á)`Ò-x¸:)‡¯ý¹а»˜6Ò>6¤‰t¦¦x5Ï5_✠n1*w¬;R±L»–&(É,Ž fDp™¹ö;¾~ÈZ‹‚×ø>ý/ÐðŽÁ» \'XR)°Ä<ýhƒ¯1Kµ&-Á>«øó«|@…)…+ù·¹eÏbí­¯Q?àÒZòj-¿lá!aV·Ä\ɯ4mËVføÃ}gñKQ[˺¶Þƒ–ö ´:°“þ6¨¤Wû¤*,d­ôÈo¦F&‚ eÈL‰Wã·ip´e8o° ¤Ûà/é‡32¿ûƒ£¥‹¿@Ô|Ó¬a}k¶éo±P¼šƒÉGº+n°Î®àWw0O¦óJ­UįUXmïd•DÁ NÉ»ýÔ¸ÝÖSÇèmEC¸«*bM¯“ÍœN€`:šbW±J~Ð8HßhNAtyäØçÕì¬VšÙF¼ÊVáúÍëÍ.Ͼ‡q8i8ïw.²xÇ»öCNãy–/àø¢WP2¬ß —ß&Î!«ù&ï>«ù|¦š¹½×f[òàJ~)ƒ¹È"fÞnÜZðª;Ü0ž4¸Â#M º ~õÄ;¬“á%jKG½$Ž&’À'¬?)ðSEvãWEPÑ»öIÁ?顯m¢Ú¦c­OÒNwæ•QÚÎêâb¬ `Aéd®›ð+pß›@ÉÐëšõý/ÏÏî ¼Rš¢QZ ‘ÉÞ?"veÄe;&ôš«§6™(½Ê¨®»C© Îä#ò·x;¤U¡§- “ù¬éhúÓæõÎð.‹ Ù¦$ÓŽZ: Oa«ü VØ€æY|{!õ;¯G\ãÍﱃpaÞäSÖûñå‚ WñÙE˜gø>dØ¿ÃzÂ&=ýî7™#¦ qµ•ìíãÚlÓí»:̯YÊ|™]ó–vòFo@´Kù#Ð"Fr(ᵾѶ^iU»RD;éÉ›Re‰R£»%Ð hmð1Ô’X­‹âm¹–·Â[;5eë5oÁƒtxó[$ƒØ:ØÙ‰9×½~S½§  yßûFýŸýh|$”åè(¤‰Z^Kè½|U+Þ± ¢Ff‰\MÕÚÁÈ*ô Çm‚¡¬·­âµÌÔüˆ6u‡he¯UÒ¯Ù¨)ÔSj™ž1gµt‰ÏÄQø3ú+åBż•iÙ³fx—F»E ˱q[®XÁ/#1üzŒ]„u>œêmÇ/°K°vã:·ê\oÖ–›#Âö¹§àèÀÕXÊnCÏûôzI|±Çôƒa™ïΚw3@Ä(SºõV.U2UXEq*~–½Fjë)ƒÿįѫ©îc¶YAXØ'ü5À0Ý5®ÞjІגGs» f‘Û©‚ ¢•Ê ÛNA#±$ÞºÎ!sÿÁΟeâöçZàé;:Y8=â03ùêkŒgÏlåÙ +ÝY&V™ýR±Ýµ âŽ,¯¶.Í@F‰ß¥m™¨6ÒJA;2m¼H§¨ ¸¢Ÿ˜Ñd­ùÏFÓ5õáÉÕ“ВV%ž1ê±æJ£ÚDSS×ü!c–tá£~·ßÜßwçU&øe¤GX0ü}L~àâåæûÎ<ÔüžÁ¹æQ—Y8ô‚’ßÂóÕÜå3±0çâž Ša>¼0-~²'2'ò'S÷÷˜»ËŒ&Š®X7i½!5…Çš¨¬±v¬“AÆé&YQ+^×¼ ¨ˆa¶ù(”-o¦s·”È.઎‘ízj#ÇŽöXÛ¶CW>ÃwíØ‰vIœ¶ûž(N42¼Åntt 1D/«g²;O­M‹$Zžà&lYÓa ¡Rå/+® Ä1,™îñºŒMSº*šéeƒ®)Rè‰ã&&ç^¢Öƒèqû°vF‰x—Ÿ*B5•:j‘Š#ó‚§Ð0+Æqç!ïÄcÈuŒ¿qÈ[\•S‹ó|7ð¼7q›ñfïRó™këÍ'ÆÍ¦ß»G‰ zØÒH¯90~H¯$qDü@0ܸz°u§35®yM`ÇÁŒãA¢™_í—ŠbxBâ©€ð;ã%¤Â[Þƒ)¬¶7ãj¢.¨ìOè]~Kã6rU@¤ÚÍ >>áȹJæÿð¿¶E¹ õ— ª"õ² |ˆ–µéïîs'€£í°Ï[e‹”çÙs‘¾•®F¨ñl@ÐÊʘVÉtõz¥qÕFx,étŸcݪèHÏ*¨Õ@½„"°";h'mOàÏx™ÿ“4ŽûKÂ5mㆻl)¶pøB¹2,m˯à{}V}íÆ)ÂÇŽ_Å}–æ¸õ˜ŽÌMTQÉ^ãÊç*xKžÓ®þÖnó‘qïRäÂ?[ÜiýU%Þ -}|5š0ÝÚÇÌB r#~¥3Û…TwÚ¶´ ™â§«4³cà»Áj›:´÷hNx¬«Z_•ˆ ¸ÏÎ÷CÔ€»•ª¢¿"ûžÈUdºwf…{-vÑ  {ÔD–)zQ‹P”€V&N¬ !]wå.v(Gý…ƒm˜ôº&‰N!ú_ÂDÖ",ª WÉ;ÙŠ8”tkó5ž¦ÆÒ´J€ó~WzÛÅ?0R‹8µœ .!Õ‘š@E® §Cõ¢W žŸPÇ¥·ÁWX|ãÑËxW€ßLÌâ˜ÿÐ-å W¤´"=â‹_M8%éÖ”_ñ'qƒ+zM%Úx­#ÀW!müê8Õ_í‚k áa ÄÅO–³›B Nò·æ1Õ‘Œ\Vá=Æ61iSê×QomÏ1¾ .(ÔïÊ¡‹JäômÛÂ=1ï/<¦,ë,MÓðmŽÒÚÛÀ=Áòóx<~ᕹ ¸½|ôôrÞ€ZÒèºõS{aÓ©t#ÝŠTìN;!¦•é…‹Däh/ÍC«+åmÕÏHs¢Ê§Ô¤_ ¹Ì ­š"È"âð¿’E †´©S"7•‚v…ñ1hìš¿eq„^ms›%³d­o˜”nÁXÖÀÕ®M‡¯xMoúNm€ø?òÆq ÖqŠ@Éqçjuk/1qe9!w3ø):v|†Ïùʈ%]yÄ´Ž’¤Žt•бëø&ÎM…éMÀþUÏÔýá8³?…ÓWõèü­ÏÕ‡3nò} òu¾Ü‚»ÅÅ׿^•ŸùêÓ }:M_W{מ¢;Ö:ðm½’k½LÏ¥·=ª¥Ë•îdÓékrrÑ®¶c 0ÜáÊ—\ç¶ú’b—1’.˜……ub§&Þq˜$]Ҫ𾀊ñÂWžҘv>º;ÐiÅouuƒs阆K@;s4ÂRóíËXñ‰—©‹?ëÀ„NÇ×2l9(¡ðñg™NPd‘ƒÙPGÙNb‡ D9SÏ?ŒŠ‡«Ò\YùÖnh“•dLEmM^v¾Ö +ÝêͲ³“×~ê·ù!à—ö€üÑ™»{à—~Éí}ôƃ÷ôµþ"f7yLMuˆVú´W£Ç aV§ÚÈŸ¦tu€«á^ ݾå_l25ðgŸÐ 6ÆÝÆl Q°fŠÖÙ"ê1LðÙªjep‘£ís·C>Ë4mÊË—ø²SU*_Ù˹uñán+ç†Ë YX·¯ÃÚ¿áå?üÊ3´SŸT_ ¢†$}ˆ>}‰ÕÆCÛºÿ¬(m§³ºs"·AW¿Ãwût ‘Ú.{~¤bL¦ÿédr,~jkñÖÕ¡J·Gø‘=&rîM7ã‹Zcä9Øce,'¢vbz Poé/hil_ûÊÏÔw¹ñ}Ge7mn?Ê‹ï|ÿ™æ×%_o>V2ÙÝ ¨'˜±ôˆw¿{§z¨7P!™Ø0ÕŒ4n‰²è7Ñ«Ï+ÚFAÈŠS®´H* O€t*“QßãÖzñ:g3j:Sg2¬rKà]?qdy`énVžkô”+kÒÏ"N‹n†+ùmÖ}Ôaz¡¤&Oñ cׯ°É6Áç8ZQK¹(#!tå;±'ºö-b7Çh'Y©êÓPl JÅ­öeCçc cÕcžaf잺¼¼üð;ïøswõ·iÝ@t;%m>ý…ßñüúÁùÅÙGjeÍÀM€9Ù‡…pÕ#^ÔêÕ‰)ÓúºïÆP‡ 7ØÆóÖ¢j…©ð) ÈZÏ E@Áï„Ô·²ÀC¼V@a·ñ–DâS <"^Û{ 4ü˜¹2!äžO&‡akãò?›>À¦S‹þXœ¡[cwf|"nÖ"=¤ÌŠ)ñÛ>K±ÛèZè¾Zi{–XÛ͈y,äº[²;«fgXÕ}|Õ—æNÞ6ÞÚl$ßuÙé7/>:ýÉ}À­ ÍyñöÛõÝògü 1øÝöÙÕðnþX´y+iÕÖâǵ݋¶—í ²É:|F¸±-Ï™H¡H3Ñ ¡s_e·–­Åo+Ö6­Xä#¾ åfr¼Z—o=MÌ…£/¥\Ϋåx« ýªp•À}ê}Ñkˬ;SÙqÇp)]ß‹0òøä’H»#_<}*v¬Rìü1ôléd/º™tµ Øñø\ñ1ôVss?qcYâÒW䕹T+B–ƒˆÑ’‘€ú+š½ñ»ÆwYK7Æü=­7™öìþ™ÇŸé«¥ïñ£º½®ž]l–fwŒ©² ª{êN`éa[ÈeÏÊAe¿¡~’íð ±–bFl»ÜSO%÷ÐŒ›ä¨ìT#ÖÖ60d‹í|9„° 6ÁoBÛ#)½tà„}/õäÑ&‹¥X÷L¼10õbÕ&`G{F¯x‹ZüÖ¢Ïhâb†‰Ã)Y [‹ºª½w/ó)0|”?ú36\,ÏuÑü£üßéWÉbLñ¤tËÔ½tú¹7Ÿžñ[SGz ÔKúó@Å•>ã@ÂÝsà›.zßî/uLÖB5)I”žÑ‚ò»â}× ü7/‹þÂïÔάï?¢C`X-dÉ2C,]ŠõÂ'pç™ ²ªâ¯‚ísËË 9ĺP§Ôý’˜d“‰Þ O:ýà3z㥮»&uœ„?P¢˜¥R› fƒˆ|jp¹Ö¦—qcÈûâ±Å–¿ -ïò-8}ø©.ž±Ø&¼uð#ÕöóáGrvÄØ­;}xþïå«tCª]îLI¼é¥#};EèÛ¼|É[k÷ré³×dÁŽ‹‹Pû¢êÏ\ùV™aVŠx.ñ©S'dvãÊžt:Z„Lƒ €ß€Ã„–¼i±]àqgÝʹlõ§K°Þ€/ÛŠå³ôµê DcAHìv[1ŸªT 'V®‡U4‡ÐÊTÒS²ÖWÕŸhqծЍ€Õf€S_î§³5èOS˜‹LÕL×lÒ+*†Ïú;§¯Ž_úaBÆé'Ò;ÝôYÀJþÉ“çgü¤•kŽÖÞÍcay#Èjhy0/p¹õçK<¦Ý4`ûº£Ò“({솟ö[™Í\FNÒ{“Gç⻀Ž©º&¾z£XÔƒ­VVÕ¼g‚ê²s=9‹%¹fóºÞFÝçŽ^ÇÆEÆVJ?'°T¥€‡‹;“Z5·0¶;ÅK«mÁ ø”ÈÍùÅ4þ7I7(²Õ÷ÊŒKX.ë<[3 fÛ÷rJ°$Úò˜´Ø _*O§èؤ71cëCYúÉG}yîý÷Ÿ´‹XuõvI¦Ìízmoú—ÓGŸðC’Û)×Ê&Ùý 6õVÝø ;MàP±ûžq]'ÛBo¬ ZWÄÅ!bOÒLø]Á·ïԜܲs³3SU‹PnÝᢾ2ãžPna6l]ÅqÑÀ—LeS}鈒TáfëÄIPÍÍÏÕ¯pKÄOY†Ή˜ãÓÙÛx[·O‹9 *Œq>•¬,­ÑÂ=¾h¹ÝcfŸ´“…¬‰-b±Þ÷¥v¨ó듃òí%FáüËÏWã3»n}ÿ¨µ—N—Õ¹ì¼ö+ýM·Ó[!M%t‡ÒYÒ¡Æ2¬x;k1¦Ô7€ÍꌸòºwF,î,‹ËñÛHüðcû:ªûkçG¡%Uh>»0^Ë˽åJÞWø‘ã`úÊ]ñ6wˆ’Þd ôÃQòB^-Ÿ§ér­•`tE…Îý,yh|FŸú†z3¡ÃØüT•øþÄ [÷`[#c§®— Ã1XŒK*¡ÃCg¡÷æ2nKÓOÓ .-()mê|Pi\Æ+{ƨ 1 ª XOËÏ}Õ×*ÑFÝ>YR¸}çñxúðÁ»Þj e[ Z”žpÒ-­h’…Jç"òD—ùè`›Ê*‚¶“X…kß¶pà;áÌ|”eÜÉшjÎÖ!â>PTD¾Þ\wd=Ú¿¸;‹’ÐÛ&+»ÑÑÄšLž¼ à¿¿2 éöÔÔñý¶¹å-jâ ‰”úKK€IÒ`Y}‚!ê #yèÇÏmq¸Dá2çF `Š®›R¬f™p-ÊõˆAö59lyÎ+ñ3ï¿w¦ï»ãîîË@ÝëW^yvÁe¬Weµ›3S±§ãرP“V=¸ÔóƙèYë6ÛÎä¶#FÅ«Ûþ%€|ø÷ý°Ó|׆ ?¸ Lêá-J‡+ÉêU¾âÒ’.Z™U¼Â Cà\°£4Ý* 3«¾ªHe±cÆÏt…×µ,‹m&.òнMgPâ +IJÖŬ®q­Gà2c”aä¢ò㾎L«Ég.~„í‚ËÕ­ª…`O3òò‹«U»ßRñòÐîi] ¡±Vªõ‘xãÔ¥Ç{¢üt¸ lPv4Ny @’ØpCf¯.ÔŽRñåIÖn ‘Í1€KÆédã¶™Õh¡9ÐîùiAKgEÞýwL㈿CKG;"ö¦€YÊxÈãq÷¯¿òÊ ø.¿ LøýšKJ·EÝÌóŸÿÙ'õGAtÇžÙÅÕgPün=éÊÞ½Ô˜:ôà®@®re¿¶Ió gú‡?®´Ë¨ÀêðK‹El}Ê3ƒ¼gž^ËŸ-+ï«ÅžoÇŽ¥S¥±­Ï%J5_û7tqãê¡(Êw× Ò;äF¦¨ö¤?°[«Ät§¦ÚO ÄkÜllNl Åx_†¦ÏÄ[jS$D¶¦œsëÆ¿bV~ ¦¦ŸfÕ†<ºÊf,ìp³Èã¯|H×Ó”ÏükLN/5±^ûò—ó7nn»’rÛ~7þ®¿ð…ÇꀋÍ]¾*W°úÉÜ þ R³¼Êž ,øuÑS[ë} •[ËÕXøµHÄ Ä·Ø›KØ‹¾wªuúñ—ì{&:‹r–90ëÌ)}&ÐDcÛNǬ’ˆg©+Ù¡|®ù[2^¨NÏpñiY§¶P)¼¿›ÆpF]“Ý©I×"‚ÀP×ájóˆ)Ð ‹ÔªqÊ|Øö™æÉqøòáP ¾¶þí }XZpñU.|MÆETÜÕk?õ%à.¿ L¼;}Àà¸|ûÛÏ/¯¯/žž<ð[ j¡¯¸n3¯¯¹:oË:9=ʨã0´M2È[³V¾1êNF¡~”ãoé»(±}®Ès7P œgLžÐûGBX”rUoÍ <Š­(!×™ºä6´œªI¦¹øÐÕ=ªô×ÚŽÚ<§I²ˆMêиl`–U1¿À2´†»I1\|!ß­…°>äí§äÑBg”º×) 7—ÀÚvK´øè§NdiÎöÒÚK6b¦ê´}vzzqqyò“À- }uýÖ[OO=x~¾~²yiø¸"/»NÎ13z`F}Á²ÓŒKÆ&sd1Šj5[š3ßë6}º=„J’ÉSÊJ¸dâÙ¨à#m1ð†„’T°¡{óøˆü¯;è 3™—žÉ—ëÎâ>Mwɶ¬¤ØTšZ80:ª^tå1Üw_› Ÿ¹ ÚY8,àø.ýf­7b1H—3}PG-~tÑ;Îp5˜r¸ø+ç¤_WêÊ”ñ!.ñÅf{ÆZsìÃËïÿÿ90ÕË¡äwQöãq»1<#NN¾òs?÷ôôá£'§/´{t˜OhÉ9Átôž¾4Ûu°t§Ñ£êA‰¯OL¥“”»Oê¬ 6.=ØmZª&WFOnÅŸ)äú»Ê–Æu?.‹ÒÑt"˜œ®MÏ[•« Ú³Ntl1Ϧ ’*ݤTMK67`B…ƒ}ÝòÎù-€ô[l·49Æ õªÕ+|ÖøLºµXk;Ÿ µBÜ{S€oß2y/9ZÎÀ*!ýLû³Ÿyûíß:ïœ|ý럾öêã3½Pö/§ÜŸ»Nµî˜,FŸDééô6/-êm<Óîñ£ãvà¶sè+ÿpÉBŠû¶É@n¶ìÑù£Êž½šdÔ¥Z[˜Ý•Ít$mÛÈÀm±´GPM·À­Ý¢KXÍ¥¼ó¥êb2”µ?jìÓF­;Š‘‘[´3Î>h´µ}˜ÙEÊËœÒÍs›/c:‘“‹Í”¬Ü.ÉVÅ¿ Ÿ¥<äÍc]‡×åñá£Çè÷ý¾pU­l§w@vSùv#ÐF<ò•` ÈÓós-ÃñbZ k}ÚÞÊ~ð$çåÎWþ}/îëE€ªÎä Út5rôdé¤2qBh3!ÛÆÞ¶×D>tÚEàÊ·¯tmLW˜ÈHP¹*oGtÉÑ!ïUgV#žWà6Þ÷íK¬ýÉðˆß`ÇìýïëÕ‰ùƒ`| þ™æ_šŠâÖK¦Ê­;^Vw½úúÿM€µ÷Ü4N/»é”z³`TYºäl(Ø<³é £Jb‹+cK"©l­“+7 ]gXBká×R´¶å@IDATÕs<ÞÀf㘊¼´±O9buO7‰)>Ø„†ß€Pd ¥…ב8à·‰ )”Ð?(>¹t¤ZPÝÏM†q0nrØòBFnl*m<š³:J»;ûlá›ÝL‰Ðr“å¢IB#ö`ЖÝûw]m}… »i_üXëk¯çõZ¿uz‹µ;߯W‚OOŸœkæÓvç?š³ûÖIç,—T‡-ó7òz½_ÖÈrpAîÎm×1G Ï#¸YúZ˜K£Ü'HD+Y»f`ÃÏðúù¦²’¯Cí Nñ#_¥áIÉMUVmPYJ±ÅÚ0¶z hmAÊ ÝDQb—`‰‡aÝãÒ(· åL«‹aÎÊ|ôS|5M•„f(¸8bùÏúvl…¶iu·µ0¾nG=bn}­µÛµºMª’1Õ¼yŸýÖÙÆW‚Ÿ¼÷ÞÉ[¯êGBû’Ó0 ðští™tcd² jȸ„mìykq}{qýô_Ìéûâ×;$Òh‹öØL,ñÛ‰Rõõ½c`ãªêxÊËLqîü®§´Ä«E AÏÚ\5 ˆÈ¤JM­…"ú®s|„Yë…)|ÎûS1K ïzº“\,ØjoÕ± RØÍb; åÀ9ËÎþlÏi=0L½œ°°,ííÛU¨œ {$ÛDø'QÝ6£¿WtÝ.½ Ÿzá•tÞ>Ÿýÿö=O5æççï\=â+ÁÛÞ› ð´ e>TH³ 5pzˆ=W||Þ¶n匉«‰’«YÑ’FÇó‹íÄáê¼È’JÞ9Ø´§¢æÊ?±ÏU~˜$¨|‚ê°UenD²aU>§‘;åL61·uçH,)1 dx³,ŠQÓ<$GŒ¬êÊà3ãµëEBR3çµ%t륶sÙºãxYÜJÝâÆ,ò=v__ GÙr»U­>Ä;?ÖÆÃ'W/>º—¯“P¦ì6¹;¨¾ñÚ{þ@ýLørA\.ŽôÒÚSáEeà×úÅ:4ÉòQß²©×üÒk”³ð×;€X„®c±¹¼4 ™,Éî4pJò6¾Ü1,÷¢oQöÁƒ‰¸5Q$Èn‘¨Ѽ{Ï ð“.ZìqçØ>±¹´Óî»5ǵ_‡Ú*¶MÑùA¨(¢¨í2pC7˜)C´ˆ'ßB· ´x5ˆŒK%¯þI+¦™¯EÊ´a¡³hgAºÖgÍ^¸Gtïfqá¤ÜOÇ W耸â#Zd ;=qåiáu¢ú‚;±ƒËUI‹Qp:'iÈâ§[Ö*üWŒÚ&ä«%޾‚qšÑ.“lÜ­ÌhpSá]_¨]pêcÞI¶2Iv[ßÔÞŽõ%pÔFöNáÀ¥DZ\me³·J^ÈéRWKmú=*œê£\lèXñT5~…òèѹŸÜõWÉ+Sþ®Š›úè‹_Y¾¬žôlg½ÔTãi>k‡;‚mRUŸw yÚ–ø@Þ½ÚW»qÕ¯7´o¯\êÍFrü ­SéØä@]o²çÚíg7DŸKMW×Ä“ ØÄ]9Ü$òºæFªZ;q ? ¶?uðð ã5$C‡í¡Ô_8C ï;uˆûUÔeB&e;êÍ,u…Úé"ljB["_á’!Ž®š[çV¼‘C\9F¶Ï8ýŒ>%˜Ô›6䦨• °3Tñ˜c$ùõµ.‰gõæÿåõ™ïôMÀ;/YEwèäg¾òôäìüâDßðÑD]ïXþµ¹¨Í€ !ð&X¯õK‹³ñÚß=ìµgøêµßò=!2}É¡vX21¤M*Iî;º]¶íF¿÷ÔÛ¾ÄY¬¬ámÌmÍ Ô¢UîY4È_§ï€Fj´cQ´ÚPçÒÝ}‰.y™Ç[v±#†â3þ­e•㓃mh:ªaÇÄ·øˆn-ìzQè& õ@äÓ¼$;yW·ÖÓft ¸õ‚‘íňjª\}îí·ò6 5ÀîªÜýÐß|ô9¿ùãL¦1«ºe¬‘yû¿]1Ñt«C¶oDÝU7‚áÛŸ´*»ó:%J5‡Ò.fu±¼ilêÊ¿IjYx‹±ø8tNÌzíŒDG¯GÚ=@ç ž­åtV]³mƒqÄÆ¨feY—`HýìÂ5a¥³º1 txhè `yÅ Š”•8ÃîhcíµŸœÕy+Ÿód• x\xÄÌh˽áè"yýúë¿…žô½Ù³_ÿ;O57Ÿž÷Bä2·),ã,åPlOÁH¦=^Ø"¸M¥RCŒ`c¢ÌKaæÄb»giKÚÃ0Ê7wÇR ìͨlbûq™-ˆ-ÆIŒCC+‡d2RZ<Û¬ëÕîíÆ€Ma¤Õ™FÍ@G“á::Lºú07âZ™¡Øîí°ÖÆÖ•OA*~²€ÎL§(½5uv½«V¸ø:üˆÊC6ävøþ+ý£ Ío·"Ê»g/sòÛß~ûùé+žžì[ý# ;¼²gT’è§ë…¯Éšç äYr¢¾µž£7wö ¥ë M&4ÑUª ÆÛp Ó¤PP$±šî¦ÕªÊëùñÔSx³Ú)ŠÑBuE§Ež=Õð%~k*ÙQšˆ–/×#”4,–kYëåuúŠÛ؇Ÿ`©S" ] ™˜ð´þ°$òªçnÂyk5ÑøĈ%fðÃCmšÁÆz_GnY+4-<\º@>~ÿwü·Žå·E·kâ¶¼óï¿ñº~%Xï×3{Ùª³]›&•CZë9›Ç¶+«^²è•ßðÇR²lëN¢êvïÌ7¡80Ü û ïdª.›Ê 2Ô¼šÉû¤æ•?]ãC(%XªuÔæ×Ã:5lóŽSù”=¾ô|bmnë%ŽBíÀJûЏ$7Ÿc¶â‘­Öè_zÈÀm' ýA‘/¶xN]b"=jf,‡£ÏÀT™¶³/#›´ûܶåëèKLe}E™YaãÂØ?|þÕŸú©;ÿUà„ÌjKýÖi&~%øÏ=ö¯W?éÜúÒèµrÖ«<ðõ¹Áþa GØr¼[{%œã^õ6b‚91F¨!Ÿ‚ÔŠì I`×ã ‚ ›Ä‘~Iºë\æ•Ù«»}Lv°­Ð gÝ)‡¡Z‡xpˆ(ˆRZªipy(ò‘½ŒŽfu Ûš×IÿgœØYxgñë¹Z·.ÜÉGw˜²éd+™ÑWü^꜠_¹8êgÁžêWïå«Àäµ›Žkª·Ç«{ÜîÓ>Ö¯룎^]ò?FðH¬Ž4¥Zo æmÀ`Ö·ÿØ0b =ÜjHjGÕM"lQ´K‘ ’’:mݣײ8Û‰¬‹møJ’‚·é%n»nÀ°SÜzó*iú?]|u_‚ŽŒ`ˆ+³MwÛ_“``ÁY[5xt7•u7*f¬Qðãî, Ñ!“žTš¦ŽÌ¥Œº9 žŒ>*²ÂÃ…_ý8аž–Á”uõcòAwÀ˽ÞäôXãuh¹»ƒó:íîÀýpé~8}ý¡¾è9W [&å@†Yg»e‡K—å\O÷q?õãí¿t_¨P‡ ^”ŽÓõ,¤®ºâ©¶Èè:•t4Ç® 2S@HRœiªÂ¤*oþœEQhr ŠÈžËLRy0Õõ&`x쯣´ïddê8¡ÊV/,üvà¡2•ðÿ_M- ÆŠÓl/»MȨ,´=)W†lã[º` ®s˨þ7W–ÈJ^ˆ €ŸH‘Sª^|l«› uõÀšZ®?˜svywF3vÐ[­®‡[u_Îþ…ƒ ýBÐ& 3:¿ÐqÇkvo‚+>õ--u^6ÎAÛiweÏÿ®¤v|¡vyq¹¤,ÃÑjÙM³ˆ°Y³ÆúKA´±-º I¯l+@ÂØ8&°”ÈXÔ–Vî†s¢­³Þ±s}n&“܆¤¼º ÛþF}Q#[«á1¡PÏ‘ú è(›Ê#c,§I}‘Å1cʸ¬ªY‹´ç@’1¶ËQhd”²1kTy®äuN»µåªõ¹>ãÂñ ~ädkpKµƒá¿%¿7ÿh÷öé‹‹ï¼®§¾B²XÔ‘ýûé÷ñß+i¿d÷õ ›yåïwä”Í«é̶žj'¯A"qI¼xª¹Â š¥ñ-k–¯"ºÐ‰†÷UÜÁfpþ£’¸ ¥íêâŒL[g¥ø`…²fÄVÀƒÑÖÔú¸-®Á’§è"*3}Š>ñÊëf§"Jºà°-›PÀæÁ aû@Ö¶âÌ»Zn"›yí.0uþ±‡V)ÎÕdz^b1Ñå•íâxAžùQÞ&o¼½£5‘ÝäfÝw0%nÁç‹o´äìùûß¹xã i4Ž—;›Ê¦‡3cS·OH7ØAkácÅFkæ|øNÍ„A{úÈЂ­²’?ÏËøFÏbË«§C8â»°Óìvðž|Ó¬F5—+¼&¦`9P °‹½¦­üÅ„ÂL?…I=9§]Ð`"£žb[)tºìýGn N·³ýDo8qŽm =V¬ëà<§«½J³Õc=5Å![KÚ‘‚Šœvð÷À®//»¯ÅåêäøcëàÖÃ|³=^|þ'üFà©^ðòV OÊó{t„;C=d^'®ã[½÷É‘Ÿñ£†ƒîÖ¦¹#ȼ7 fµÛðÄgÿ/ê„6˜ýèì2w8[9 ”2Ó(Á@&Ùuµ‹Ø¶ö“,éG+tN àÈLÌl&CMe{“½>È›˜ö`5.R‡†·<•ÕÑ"{iøç~U="×eœþ¶û¡¬`¥«¾ÛÆ™ÀÒÎ:–UãÜ}iZò»ª»¦SY"«BÝ_Ö…C9ûû‘ß½— àÝg¿ôÅç´Ëé~<>xvssÕóÌSz› Çõ¹áå]Ä3®ü)veY$Çh2cî‹§:EÃ`z¢ t ]7æ*7h{§EGluœ­¶ ;°#±î6Õ–^Ó[ù »J¾•"ÇÛ¹@vÅîݧ5ß‚È7?ŸÃ_üC•Xô«súˆœ ZçµÅuåG]Y—$òÐxv¢f”µ‡‚/ïBkzèWßxÍšÚ»å¥þàã×øsÒQÇßíÑLÍÛóøO?ÿøñû×0 nÒl…C>G´8­:)Ó›…šl:}ÀymîäØ×P™©aXfUÖ‚2ã&š½&è®Çë;3¥áÚ á®¦¦Çò>Ô8 }¤êЕÅóšµµ›…dÝuÚ>$-N=ô&yôÐ5oøƨ²ê÷xcÚf´U6±ãDÔ¸¦±'H 샀EoÙÆû‚ÏlÁC¼8¢êeSRbÀ•Nœgž^5¾÷þ‹úM€X;ÜžvÓñ#áú߸<ÓÛ§Óðjbu J:e]wŽa%/¬—²±~™Ý~ðÀÝoóã?74uYôã£Ä8S©Læ„èTJyôÜÃvC(/þu3°nUÇDì‡|ø¡Q²9ær/«¦Ì|í~wZ_ ÓÂÎxCI¥ŽrQHì§~Õì©߇šC Xü®eÝsVØàѹ¾w£…Á`õÈÅÊÎ#6Ñ…îäT³ìéͤP²ê¿š×™·8:ìWìNOÏŸ|ûÛ/@ÜWÙÏ¡;‰«Æ¹Ûô óòäµ×žž]\2£Ç\L¬º°:V£Ö^ŸÉ›úšzYãw}Ô7‘Ë*¬]ÃÆùàÐÖS«|º%Í’é¶t„þ Péª=æ K/á‘צ5³CÆ’ÆúmÁݬ]Ý«“·Êv|›£ú¾»÷6¼šæÊb%'îÉÝŸRíÒ(»ö¡oJäÇh¢¢Û—诶ÁYÆi6?tØRö‘Êœf 8¹; »À©Tu‘[À©4¡Ùr%púðìÙð×ÿºÇýýTÏý5“¹w}õè‘þ&@ºAÅfÔ¢›»)’Y+n? Ó ^vÓ¥{@Ëû‹~›Ë—Éݾ'œ×åÆ)ÊSíÝ=›š-e¹‰pçóN$Ùˆr{ɪ=¿8µA…ñ»Á›úŽý“¢©ˆzb§o ”…±a>%gaÄ’>Tå‘XüÁ¢ã8V¢[L ‹sÝ@;b‘Nc˜Ä×ü)»H@|ºÝ;¿©šÚÙ‘¼ê¸´+ØpPÀ…_êívêŽ5ЦsVñy×s9¼:×Ï‚ÏËÃ>¢Üz¹· @™»oNŸ?röúChLéì†ÕºZàëÐTO¬“|1ƱÕõ…­ÉíwÆ(Éž…éD–UØYøj:f™”'hq]~3Å-7~‚žvž´IxLxÓñV )C1 óȳ`ΛT½ ±˜¯ × ýÙ»Ëti'ÝÒ8®{3µ{ié:ø=~6³s¿UË8þ6ŠÈ‰!à8™6¹c´ÂmDßqp‘áIJálh¶Ìª_ùÕá"7»Ôk`+UœV ã8ÕŽ¯!^p ßfukµ\_nÍáMŽò•à“×^yîÁÊmr&ö0¬—Ž©aÊ9 <Ø‹žˆªÖ‹Z̓CWóÿYµ(ºŸCíq=eá.ÞåÐV¢˜y“_\ k+Ú¿„ƒ#¡Mé @ÊŒLoPµÚ çõbõX(:ñ«ûò·‘¬Žóé#ü¶ï5Äq£OÊÁ149†ÆSð½ÇYœ–X§S(Ê_x„±±ƒdÁKN`7Æ ö&¹ ˜%L,jötÇw•·÷°ÀofšÝºã½Ã|%øüüüû'úî`<È«ÛX‹ú4Û¿^éÛôoQp…enF‡¤©CñSW†hºéži…D2>‚+¾ÊÌ üÈ—O>Ñõj“µË©,ÿÈ®.Ýæì²¸" 9¼è|YÑ `b#êHk^  –†âžǪ̀¯B+¥Q·å­[Ú•vÇæ&jW3Dªöê‘“al£¤>ºc¯·‘Ó©TGÔâòÛ6É¿‰:@«ESHD«þÀÖ–Ã'™ÙNä3øŸ}yz~¿ €T{ÀÞmùF»¿øà£pùêuF-éeé°Ú%™(CÕ`uu_Õj•;zÓ:]ÁÓû=BN¡gPÖù¬ëjò˜A£M Õ]kÖÍ)¾Ã-6üômìê^ú`ô­Ñ*+Fªö¢Ý)ë힨»â˜²Ëbk ~f“¨—Æ!†©ÿ¯mܽÃ>‘K€ÙZÖúÊãc­c“ºi‚£ÿà9(¤6ømä¾ ìjìR -À°‡ óˆoWðÄÕs™ëËëïàãk³ÉTï´d*Ýiœ3ô9€K}!茫ˆ:ÄsQ<´Žêž9GÓ]59o¹¥.\%Ç;Ó‰¼ÇO‚k´¾^ÞÀ¤:¥ððå†z|ˆ"äeŒh» E9T ê#e[ùI\NÎòŦü·¿Æövrµ>'Žnº¬4®z¦Ûëð¶Ó9Ër¥¬ K-%½UPås-ìÀ¦ {:­røý.˜•â7õÉ,2 UÖüJR˜Èã#Ô6 D–ücšø`ðûÕ¯uèƒm°¦ØÅ¥ U ¡÷výI ïZx§{Û¾Qm=yðöO?{¡KíT#1ÌéúCŸáŽÂ Œ¸>mkîW+¹úµ®Öb”Lõ,LC T—à¢RŽ<:RåBí¶uã×€-{ÙÉÑÚ¬ùTáy(§¼—ÉÁ»#·Gõ$¯·Q¸ ˜¹Þ × J蘌IoMÀhå€×ªvÔX«ñÑÌN¼‰ dK½Í7®ñµêS‡†ÇnÅP§ _K0{ùЉî˜ï؃_qÔWÝZš!Cï'©‹JTo=|˜g‹önÙOœC·þú«¿íé =Ð×ܹ"^¦cXq*óO|W=Ý_[×¶Ý:éæõI5³×;æ5Q¾u¸¥õRø¥@á×X§ØP±+°ónð†‹‹ ‹]µÆÏ Ò˜XJŸödg~¤Ó_öaxûŠ)9âÍ}B_ ÚDG_,Ð|V`¦)¸\K\D–úê/º•fØW|äÐÕ—WKƒƒéªI°« þ&ùw¯m×vÄ×M²Ä3.àøQ=vÙ€5ú*°¦£þf&¶ñÓ§ üG*÷¹TWüÔ›ï½ðšåûZz¬€\áÖ¦(³ÌÑ¢=q5Ò§†L¯ÝåÊAÅ¥ÌE†+íÈŒ^Wåb ›m­J)…w †ÔᶔѯÝt¤›‰qôŒomÜäÀ¸¡–¿ ³‚#̦ÄCÒŠ¤’|*§Õ¬ÜÄN—jh Ôs ñ[ŽÌe1¤Ÿcº‰l¨Àú«Àó‚.Ú qWçý<¿«8cßøÙ·Ÿ]Ÿ½`ñÐÊjélo‚×£ÄPJ&ýJc5iqx.³,žvÒC苽|Æ7þ±ô"iaâ £¤£Vyñí[ê«Þ†ûÓþŠl|lŸ`VÒ^lýíÂ5o»ÇG´ Oîyvš&t@|õ¬fð6]˜r!ëÕÏÎhØìäkµü¬’â7¶ñÅ`I#™y»¥Žz´æ;Í`»÷Ì*nOƒ=J•ÐMøSýŒ‹>x~Ôî…Ǧ̈́SÃiûÉ»''O®ÏÏžùãÀþë4Ý)Ý9ûàY¬«|;ßk˜q¾xutÝ›_/ð‡ïíbÒ`Ê¡²ä»óXðbÜ™-òžÎ3€e6¹H^mhR¦}\탅.Ÿvnp!«)/öé—ŽO.8˜I†M´ZhÝ‹«à¦å'sŸÆÆ™Ø4ÕAÆ©Z9¤›;ÉbýŠYù³]åÓâbü˜[­@ÎQ9~ðà‹_¼×¯“Æ2ý¨Þ}ù5~%øáƒ÷êöy®· h:‹L<¹Õ;¡Ç³›éÐPº7÷Ó6xi´Èk—¬U½|àÓ‚A’@Þ&ŒŸýú¥Îƒ9z4:Ëb`ÚqD*V”‰*yœˆµ”D)õIªPßþ Ojm5`[ö‰—E´½ª+ b|”¼ú"5Ǥ²º¬˜%Ù96/ÿL·÷½ÇRçHœ=žúÞæf/‹ßÕþe1‚[íü|JF‘%éùÕé㮯½|’ï}~?JýÞ7€Z¿̯Ÿð;hY tN§¤“ö ˤEÛ=&õm'fš'(,†X¨fõŠ™º±â$ZÖ¦øOo®Ê6Ÿ¹.Á¤›W„ÈCŸ1îDsµ§šƒ0VcÞ¦°åMAQØôtE§Ã×öZ›Ó´dŽuGÌÄdì´úd¿”ä‘zIç9ñoÒOääbƒdµƒ?V_åé+hÍ­òyÕJwzvúäï}üñ½ý*pbßÛ >pñÀóúןž~ì•â5Çg[ÒyéØ=%i:/õ¬øµÄÙÞoÉJš­aÚÖÇL(" ­ûá \G#™#=:EàìÕ–vçT.3S0»¢žª(:÷l‚pd#ÁÊuQ°UHÅÂÖ8ÌDE=3Œµ0mg]çËÐBß|v8©CƒŒ}è^¾ÖWLøøK=øPä{Ý^¶ê£‹lOñ»ÊÂxJ(‹|Oi<ùfcËä0[ÎìµhÆbcñÃU¶qnöÑÑo´&8èžOÝPU\ï 0hdŒsêÃI3™o¾ÄQú}÷ËfnOO«×â1a.Œ?‚Ç{+÷º¤UúÎýw.>8¹ä“À-„žѳ¢AƒØ¦š¶*›a5¶³õjßëÉzM–ïÌ:Ñxè(&%Ûj¼“ØpVV b’N§_Ý-˜Ï;SÛñºš²n:èDs³Dfš@ªT¦ó ³4m¶¶§dœ£mIdX„ ¹¦½«ËÕÁÀÿ .> O¾{̶Þ5š±ÁÎZðЕ§ŠSäTŠúgóÑ[(‡Ü½äkíþ>Ê2…î#\Ÿzå•Ç|!H-÷Ë÷tZo Z!\ÉæÆ ¯Üê¸tϱ ÃέzmdeÙgjÕB­“‰)>:  µ9ná˜Ý=عhËËUî8v°vzR¶Où;"ŠVÒÆ5C·›Ü¥w?$Qe\€¯Û!SðHhSÐ1m’¡ƒSørÞ€Vƒá®Ød‘í¡«~¯[ÌŽ²Áï}ŒYÁåLgÒ þÍkšG[AQÜßÅVÙ±£×ͱØÂÊÖkàäôÁ÷vª{©®sñÎ~£ûñìµ×Ÿ\Ô¼ó|ÏNéŽDÎÞÐWÄ‘TêÒ׺ðr”ºÍ`¬žauÀÐà^W• æåbQ`!<%õ¢ã.ÃÎZ¦×;²«óˆ©êÊ£í÷C äã¾sC±hÜÙP›ùÖ^ýÇlr?.*æ"ä£b³O­ñ‚Ye˜ÍÒή¯õ)(/]÷³z‘Eê¾OÇ—Â ÃßdX_&fm°kW)®¢e¸Ê2_>µ‡qvÁ1é1ìÍ$Ö(åS·ÚbÌ+TaC,baz…]Ídkõ³Á5R¤Ky.§%"Ÿº<#êdc]Ô‹ž°*Õ†òå-²¡±ÈU;¯_Ó®²®sY¯’À˜ñÛ¶§êÉæK“Ñr™Œœâ>ïX$`ሮº‹¦ò_°Írw`%[ç ÝéTuÿ!îüKU‹ Þ}\2ôë\p—HF1¼mÒï´…’?ƒ§<Ý´ë¯øS€VÞã)sÿ^Bþ©î“W¾üÅÇúþÿ¼ªé꼬BvΚٕgøõ“ñ§õn`Ê—fvËón⢩—·«`dzà+cxïoêÅßΩ+ ¾úT=¾Ë?î 7Jâ‚-aïYafo«þ¤Ô’ÂÇñêÀô8´V€uñŠæ·êqHüNtïÃƹ*SÛPçèž?bœ1)ô{{sÅ tD’ÓŽ‹Êq—<¬­”qƒÚC+fï>‹:†ßí¤ "Š67Žyñàá£lQs×§O5o+‰týÕ«Ÿ|y¦¯÷íªý3°ÝyßýѽíA` âL8/¬¦øŠÎþ2JÈ}lû7·ÁØ¥ŒÁ“ lJS–žÎÕEJW¸qvïjŒ$ÉR0ß4Uë}ª>œv#Æ´âqN’¥O&@ÂBb`±ë½(q¦ÒˆªôÙØä8Î#,rǴҼЮvÆjž¾*Öm±5lQ*÷Æ#®FY<ä26@Ü/pU³ ¹`'²=µEtPc[à\:U >£kŸ¶A,F#êÀ®®¯..üÿà]ïxjðGÿàÿ}®mý†çJ—`Þæ[¿|Óý6¶¿OÇõ!²)«œE{@ÖM€ZO ”KYßÊ/^jñΖ/c<ĵ1w|`f>Ð,ˆã)< ûE b7Å›ˆp.nTØäÓº ‘.6ÈG•Ü«„võÖa}#QlõUF¡0%¯à%q{-¢h(^F6zo :¥¯6©Efçášìñã.[`}#ÒIÙ‹FØ´Ü›|Ë3=BÁ&ÄõÙÙ‹‹‹‹ü,8Þî­Üë@ÝÒœ<üéŸ~|ýÀ¿‚¢¡Ô¤gRl{¸åê “jé’Ñqa,‹(ß-ˆªn› v¹PµóŸ*´øõֿ̔lE‹EÑ`¦®¸¼cpl¨‰Äâ)¬'À®¯Qºà7·öùðÐt5ÌT楽­¼œÚhÐ6ݵ=iÂF–~Þѵ?Žå_1K³úµDúÙ)AÛ4cf}tͲIÛ–¨ÆªÕåžŠÊÆ‡‚éÿÓ‹W_ý­ÿ šrò{¿úÕ®_{íÉé¥f`­L/ZúG%Ò]·Ý² ÃX˜ë¢vÇjûJg‚ìþ-£>g¯í½Âò>ÆØå@v ;½ÀéP2Š|1 &3uµÍ¼%%㪳/Ħ„Vm7ã$Äu™s®cugɲÈÊOÝ›oÕÞ_½1ý'ó)9Î1Ö”A«º=ï·vô‰Ï™Xµ‚.²~Ýï+¼0ËŒMB½çÏ à\÷&ؼ‹`ÜZ£N=ƒS’HXKÄ¡èÄû‚Ù²¨zÈÛZµ©Ì#?dóµm4m†{ ÝŽ&C™ š–øóÄÚÄ‹~nD–Їÿ–—`ލs6ûž’ÊjÙž“¸P0©£÷¢'AÛƒézI—³Ñ™ÚÙl 2ûhg­.‹­›O}è8-wÑgC\ýÍ…`$­ä§¾†–1‹Lc,–ù}úøä—~‰©M‰ºjw|®ùtÇAvîóêõמœi5eáƒÉÑ—B¥³üí3] t¼–EB}ÞOUÿ#¢Džº_J0ú@—‚Þ67^G6˜U|`‡ÿþ_ï—ªï›æk!w:š#õ¹Âx*’‚cqŠšØ}‚ÓQdÊJôÜÛ´q•Y~ V2Ç_t¶_êI5¾MJœè©W£EeýؘQ¯~Á«ŽÈ¶‹~ض®>´¥ŠëYôª¤óD³ dưÕÌÇUò› tŸU[ÜaÝkùzõóÉÉ£þ%T]íû%@/FɨºX®¸~P¨óÏ'å®AY38,NvÒÔ [ÊAÁV1^”j‹„K-’E/‘¥+D¼_´Ìzœ«_Cî›Èî'J€,ƒ­vKâbˆ´hro¤Im¼4 †DuÒyë=}`8O7¹NU¶ÙEzHËKlŠâ1^£O7xlú †ôÃ;g*}¬õµ=ÑOoÅ­x$v3œO ¸ƒ#Yt OžOÑ+JÞóF>\—½(ÃF”æ9ÅÕ†žÂس~8w=RùÝåùÞ7}ÈåêÙûï^½¢ß¬©«³ÚNHK'z‚ˆ§SÝY|D–^5&Y=˜׌—Ø©e‹´Pî©÷XŠÛ–Zx%ËÂ¥† £bÛ¦"£tJÒ-ãzITo FGâ½d<øä.Àw ~1ìqJl ^Í®¨T7ÂÝXÒ{DÇ€¶—Œ–nKrßJk{Ëô׊tk+h‰Å¯ý¾b …ñGœ›öiÒÀà1·üX‚è¬#}l"Šmä®gÑcÛ}W›çŒ³Ö·¾jÄã/㯿q‘¿°Ï’wZ²<î4Èêü›îê““‹Ë“w.žkQ_ûWQüEun~!ˆÅ>:ªÇ/œ±ºN³ ƒç‹¥0\ó’›…ãòŒDûʳ¿Xq ðè•2Úÿb0RYª˜…ê°N |½”)ézö²cÁKX“AtYøžèôC9ioåߤé6 †Q¯}%BOAX…ÍmÔİÁzN÷ªB}è° ³Ðc˜Ê¤ã56¸Ð1x ™°Õ±­íg£G5ÚPÎëỡnGl‡ß¶Ý·snúåiú«þð…hiõDA?o%ld³>°2às0úãXþ& K„ÂßõyLõ»tàÿó¯¿wQßôPÑyéßò«+ 8)«sÕÑX.|ÉʳmÙ–@æQtaŽ÷<È4µ÷í»ùnÁƈŠzo·ÑKÝô;¯§¥«ózõE;ü‘¯/ð޵m_ò®¸±ªïRX&QmöT°åŒmƒz“r¢•­u’CSf;"9œ±`b;Q7|x£r¶vñ±ÆŸþ*НÀo‹ÛöSìÖÕ¹¼o7ÒZéõ9AÆ$šq@äˆí€K?ÆK浊·}Æ? ú5‹î÷tïÀ7ª/NNß~ëñGúB>ò«¿ZBúd=花Øw¿S¯øðøóƒ:]‘ÑóÖ1ð › xbéh•‡ÆüºÓ‹¯+AÑBã¯â`Oñ ÌÇUp·ÅRÙT ‘o«náëÊG[ÊÒÍm'Õô®ˆøNA8·G>ÖR9ÎLáÚÒÜÔ¯òòP¸)_äµ\Ú“ÅRÞbìªn™ùâ8GV˜x›òèÓ6r\ãSV…É9ñQ–©A}÷è9 læó ³)¾(ýl;ä«¡JÍ rwþžû—ggù&`îñ|¯ß¤]ú³`.g'ó7õ`O7A ÑrïÛúÌW0u|ÿMkаàÎ¥£0Fà©v_kó(%gìWݸ4*@l1dÀÏ4Š•ªÙº»Ùz˜÷)Ζ%ßöCõM¢­>£™:Ù'Œû2~+Óc¶ŒYŠÇS/ø!Ãâ¶ïNÙuª‡N=¬cªÍÀÝyú@¿“Q¥ëÊ}{ßøF }öñçð7t!g©éçÂ{ñõÞsu=ÁÂôëo‚<öY\lÔùDk2uÛ‹R཰{Ô¬ï‘Î÷çcÃhå$¶c‹ñs……Ú1«‹uò_UÔ@1Çøurx²42ö8ð„·ž8Pl¶˜øê®ÛĞ˒¶ËÚÎxyÐ9©Ž}½–?YuòµÐm$Ó-íC¾/…í€Ã6õ Ëç¬ÍV®äåñtîÓç˜ ¹Ý4‚„D‚ÂkoTR¢¥,‘{Âà3ÚBh¡Ñí{£ÃÓb4Øk¼ë\â:FS]ò4ú}\"Ï·U¹ß²ÎÍ{‰œÉóêÛ_~|y~vÁkzžâWËy¯„= b> ˆÜ% O±^”ªoß±k[d«ÞÍßÒIWVs2 ¯Ü4Xñ#êçÒåsúcfÉ96Ô“”by±®1Èä…y°[ਖ¸œ‘á¼þâ䰀߹궀­É+ÇNÅTq:o( ¿?ÊE¬iâÍÌ‚¼Ù¦°•+g,8’¹¨ÿ/cb§Š"5R§´ÁõM>å ¹MÛ{pPó‹’ù°–`‘¿Ò`ƒƒ’ÏŠ Ï…$w‘¹ÚxWïâêÕWý–x|ß'½÷;v>¾ßýäò•ÇêŒ÷ÕØG¾Š«SØ<ê-…MºJMªsÎÞ‚(~(ØÄ湈Ä2â­ß5hˆFˆŠ.‹¾7³FƒHL2ñj¸+®ãH¿tXâYŠ­dðù#Ô¼‰I‘—6sóÈ”¥"E·\~†³ÒåœH½°Í§-+¸2*´,0Â5¬NU »´ j”Pá±&ÏÔÑl%{¿v5¯¦mè¡EÕÎ8ª¸Þ”ŠëÂ@SŽñégœE íZ_å«ùÈ…J°ÁYo}O@ôôŠç“¾ xzy™ÏðÏ÷¾Ô}›:ï{ïÉåù¹~àô Z¸¼ðáÖÛ:˜»èù¹êzþ^ ¸îÀçó-½œÂ…É„\@3R<,d²žõÀ ˜“·†±]´!Ƴ`Æ ² PàWÿ®3R·ÎfUŒœP%¦}W‰lrÞ,8¼Ùmðm-…Û¯Óô՛𤠢«mÛŠ³Æm—²©…Ž€zMq«ÍÇyFÉ—ÁÜhPË  ;ܲó8ô~i3;~Œ¾Ö²ÖÃCà ¿§^Àí¬fKU&né“1Hø«Þu®¯?}röýᦙû"™»÷ùíòOýÂ/|túÊÃ'Ü[s;Ä‘eÁ'ÿªÓ™\Ù-3FSK+šàs§P]ªs¯J^¯£ãðËa)øó!9óÞ?ü)†Â~LÅÀ(øÐªrÆG`ÔÉ•:Èò'†Ò¦aS­—Õ–ª•öQÉLp’¤aq¦b\WˆYqÑKA€X­ÉI…™MSÖÙ.¬+Q{h`+ d˜RÚ²6_‚¨,òСD@]؈,›ò-G-»Ð|ðœÔc{”–Ml7öŽÚ]·ø^±5Þ«÷Še?Iæ8]ïY,zuvöø7^p'ü™”{ßÔÊê—?öÇ..^Í¿Ì ]8Þè ºª#‹Ù¯­´<‡uâJîÅ.ªÿ=à¢îqu½Z¹êq Ž’õt©!ñ_+Z×—F|Ùw¨j<¿ ±L°õí7cA~ì°hñ%`#;VÒæ‘¤A_¶íw]ýõÑ̨/A’I)Yò…¿©”ZÚÅ×y๳°7bK‡ºë¶r} ;Á¥~[QöÆ€‰2ÿ•DR‚1VcÁ!sFÎ&ži7òñ™ùèñšãÐOe¶ÚSOÁÍÃ…ÂñôjøWõW¹¡ýLÊý¿¨f2\×ú8à{×Îø}¿¦g‘2dÜtž À~Éè<Æšçt"R”:Å:Qnë+ˆôŒB6‹ó<`„ØBÆã?YŠL‡'WëÏ(¦ˆ·)¾ÄãžÅÅ÷Dîe!!òÈ SÂú}—9KÕì´/\ù˜>“Zä©O¯•Ã^?œË b`q€Š;©¤K®Î_boåz<‘gkjVTЙG˜Aã¿•ÎrçUIdÌ<Âó`™v–MÓn‘±år´×£`7*ÅSßËÈ$ÓnÕ1mïwšõ³@Üþg6­P‰ï¾|¦ÀÅéùãW*fÉ‘dû!еn$eDpâOj<pò—+,ŸÕ¿$V£ìΓENÝŽªÕ¹sÎdâ¹G‹¬'cþ;{ç”Ä$ °EÆÊŠ–y}D/™YáÖ|l¯:»h&uÛXχdå°F¼£¥æœÜ³q.†r˜šûÞp,šÎ,‘KJ`æÛwdÐÈmX.2ÖS.ј,õ¡¶Ûiß­Âép>Зiwœ×Ç}ZcäW¾Ëšñí¿z‡ÅO瞈z:Î8ÕX¼,,ßZir‹°n ÜžC¹â#æðEÏ ÇA¦ÃwžèRªdªas)¿.€U´[•!|«,礂%´Í\GvLî¹ï7õp`cÏa¼Tj«Z©u;¨dI•gµï6Ê$ÖXÚ†hØu]¢)²…‹ $6NE·÷9€# ‰Ã‚íE+àÔ”õÈ<þ%®so^CߨÍ"£ŸWl}Ú´Æ€3:æÞ*/YrH¥°5vñ[2>‡áyët¯ÏÇ‚®=YNîáü™Üð¿¤Æ]^|üú‰°« ]uiã Éí:ÅÎäÓ >u±îÀÈèµ¼T€Ï›µ„'dlî `9‡2ùë¥Wé”2*œÍ`½4Ðhr&…”OÉ=ª­/[{f2ðU¤éÅ^™TÕ!RÏ@—ÿrYâ‰î&bqI<ë`³QÙ§0^XȤC—ϵ"‰«ÂV¿2ðYà¸2¿ØvÓ]ij>„éÇf=’NÕÉX¦StdT£]í*ÐÜ8J?Ñp{|´iϨ iÞ}&C%RöxU PãÅ®zD¦ >­ÂÌóöêêïëŒæUõ~ΟÉ0šöèÁ;ë A—|Nƒ¥æu3‹;ÃÂöÕ^?efÑ#£“½ÄÔBî×ù’³øÐÓ»ü nzùL£ nŒê*øz°d:ÕÇ‹måð3JÏvKáNäJ™¾àåOr<ÒÚËÄ ÆöaÛ•…E3Ë¢€Å¨2­Z|Ø7½LˆwÓpÕ ÓbWÀ4ªëíµ fàÀ~3(£:ÏQ‰´œeQFºÒŵ›5:L 9²e±b‘¤>é6ÞK“ àWÓ7_úêwŸýš6@‹ x]…Yõ?U‹¤–añLdlèXoš ØÛYŸÁXÖ—fc¥Ãc6ƒÕ‡Ä¤Rz**þ, ¼pTçc³jÚœ*= µqi”“'«Ú1…Ilp±7NÚJáYî\—ÞHÇX#ƒô] vØ¿¹# ÈâÀ“N'î´(¼ ²$ÊK:ì(¡U;¬¯˜Æ&äPI°º‰~•¬äk+¼èÖNx ºsd}ÜG¼–ÿé#qB;¾ñlêÛlÜjs¤ ‡};t½O< ›O®ÄsŒve F±)Ön€HìSì+K+@ Žß”a'A6ì)äébü¬àè4}V¼¨?‰×bØ_‰Ñdcº—aW q¦WkÃ,ùÆtS‰~Òä‹ñºÒF‹0]³ßãø‰ vÅaHÎd½Êã©ÿ•[䂼e××/œž>Ô·õ7òþM'4Cwõ~H­•û‰µF¡Nþ‹_ù•ïü“?ÿ»¾øÊûïÿA]íùb€þ6‚þ@H_g ò©:žQÌ`Ï¢« " ŒV²‡(«œÎ_À±iߪºPõd [l Þ ªªóĘ âXâ±÷ ›¶µ™ŽÄ@Öf°£x‚µGÙI:'ÀIDATôci>W©ÍÉ8 Öö:Hýgƒ`Áóå ¾Tõ±èw^¼8ù Í‚çê·±q´×O"Ä£@‰C©x[yPµì vSò}¿‰±Ñu@÷1®;ì:ÑØ{¡.þ2®¶Å¹JñœqZwz«>›mdÄ'Ž>ËÚÿÔÙ¼¬ìòZ¿-у󳞜¾{òè•å¿û¿ÿî_ª Iè{-ŸÕ@#=,î7ÿþŸýÇ~ögÿöÇ|øáôô úÛÈzxÅÝ€ç£'sÆ‹ñ :jOnMèܪ{`¤óΫE=olíÞ¸© Êžjl€˜LÌCª¼vÇξ`T†_ÙÖ¾$E¾N|t­ÄlãÃõÖ×ÓC|BL±=L'ë ×^ H½L)K¿ù,Á™<ï¾|WÀ·— w£”ÉarD5°bV[øªsžè¹ØVÙê%v%‹Ï¢Ëص[HÆh`q­£ê¬þÁgù€«\*< õBFÙ¥æ Ø­jå¿æ^x„ÌE×áå^«óK}þDÏ¡OOŸ__ÿ©ï_^üsÿëoþý¿*(ó|˜‹¿×òYn4”Þ?ûï¿ûίüùßù;þäïùðÃG¯®ÿ‰7ô[I__^¾P¿©¿¼†½À{ðè-Š~Ë„¢ ™ÜÞ™ñªÃW;`)`šÏfÀÕ‚‘/3Ì¢ÇǰA%ü˜pØ"0¢¸X›¶ åPÆ¢+ËÒ­çXM_…¬º‘´2q»êºÇE™†‡šÈsFýY벺ÊzNݸ¼ ãùÔ¶¶7ÏU½zkÕ3>Ó~¯®x§úüLåƒë«ÿóÉååþ•ï}ïß~÷ƒø/ÁóÜYìý—Ïz Å×_SG|ëwžÿåçOÿÜçÞ~ëϽr}ý{ß:9û¹s½Ð& ÕpÔZ¬…ãA”!ƒèq`ñvçi²L,k¹ŠÉA= ›…¢RãÎÒŠåÖGÃ<7ê4ŒBlÄDoß’±ˆy¡îºNÄÉ,\3‡@ÏKn÷U½ÔgZt»vöüäê¿ùÍë¾þwß{üŸ ʯÿäª_A$ø,‹šücW¸+ñÎøå/ù+ääü›¿íÅõ/¾¥îúèêÚŸÐ}¨kžæ«ß)`ÚbÀ[†<5€ò9~ž™t,V¿ :xM>ºËƒXŠíf¸yH&#v>^l?ÂÕâ/Âö‰i0ñEŠœ&õP0ù 3<Å1Šgð%_-Kö QjŠÕÔí4JÆÔü<~òלü¦ž ÒØ¤¬üM²¹„’KI»ø ]eŸÈË(vP󽉭òøéµ»±¡bÛ%©,ز«œé&ìUÏY*!Ya¥7®dãªo%óóô\OøOÞ¿¾þö“«ëëï¼÷îŸ(˯…ß9ýxÜ$™¦îë¯i§üÕçÏŸþåçÏþÌ[oþÏ¿z}ò¼u}ús\¨>Öï© Ë®© ‹ñ K|-Z ÅJ‘ §Ô½"<€ð¼®ÖW*IQÔíœä=×–„CìjµBL‹Åo Rñ³Ö^€Vï;ˆæ­ÐÂu lR^YÔ D+²ü+\Õmíu‘2uy8ïê]r9Ú;GÛD^Z (åÒññÄñ²}Ñø¯°Öx–q¨~Ù k",F‘¡Ó2ò£ÄjD†é´À™x¡”H§ˆ —'I,ìx,uÕŽug8Óç/xðÿýO¸ˆ¿ÐrëP£íÊÄ+Ï]P 3)Зɬ ˜‰×â#•Pó·¬,è µ¸)5-pu–0P•z9@ge¡‡Zí ‚u2gÑãEoUÉ®úZø ž]_ýÕï_^þë¿þäÉÿXV¾ês±ú±-Üõý8—k= ¯}wúמ?ûŸþüW¾ôŸþž‹ËÏ¿zrúû?§›þzË×ú„ÛX=Ò2c'GÌ’“›ú¯ªkžTn¼äe\xÏå^8åèZ?dCéEç;{×äe–8¼Ã5£˜<ŠO$\éìã[äuSùÏdåµ>ŽÉ G6Q˹ò³Z4îv$ò7¥ÿ^?X?̪ëq†¤2MŠS‡ŒJ“`BKY𑻟Ë}¹bèì«j›Å@û¡êƒ“l’{`ÑK;ʸm]í`ÛêTñ…A€\qtýá¢tÊèý“Óï<;=ù7þÖ»ïþâ“>⣽ÌWZðcyÕW^£ü¸oIÔ]ÿ5Þ-xï½'ÿÃûÏþÌÛo¾ù^99ùÝožžþü­(mÕ…Þ«©Ó<1´äzqØYOZx³w4pC¡t¾²d &°ÚlH¢}¶Gã¬×)þŒÉò¾0L6¤ž|²–c*±c@7Åè@6;¨Rðy®&—rêwtýÊK€ÂUûÉhµ+{œI*’âþë‹8jSüÄW( Û.:Ë„ŒO⟘Eê: ¨¥_ØZÐñ¥ K¿²ÒŒ›u>O܈Õy\øé>ÈçôüR;쳫«ÿðûøã¯÷ñã_&† kŠ…_© ù1.?)€»ð[µyYpö§Þö­¿øÁ³?ñ Ÿûüoœž^þ/œœ¿uÁŸãsDõ[šDÛ ìffIÞOjhX!5ð¸JøkúµtOŽ—ôö?óþÓÿù/¼õæò{NN?ÿÚééWW—šÚ {ÊÌÀ“+R¨Žš9…ñ„Ó­4ººZPQ±°L<ѨsÈ&+¼&aQ6›2«3y[`¦y©J °å‰’óÀà÷þ4 ‡+A*‡2ì¦OÊî{ú*6~&7”¤Uµ>·Ð.†ï‰8jÓ¾¢sß.î†|‰ˆÿ!of­£7BBäëQš ©Õj,L¶—9ž«m6‡Ø@ѳšõÖ{FŸæ9=ÿèDÄóúêßü›ßÿþyüá‡ßB¬ƒ¬~ìo÷•ãAùIÜÒˆëoŠû/ ž={öWô²à oþ¿}õúúÞ<9ýu®w ´ëŸ&þܲܲMPp_žU¬UCàÒ"<•ƒ­5†ƒºµ Ä[Ny(™í€p)èýN¦í-¶Á$ú¡*Þ|0èö>‘j3Ð^庎é£À§'ᄄ àùØì°k¿$‚:±k7¸ÿÀtYëëâÏ%ÒúöE{ð‹lÅÆ‡åö›+8õƒˆme¹b©PG:åµ!Ïz-p¿solÙ†õtã˳óÓWºš<½¾þÏíúúŸÿõ÷Þû¯Á¨°~~bn÷ñîô“¼¸)ߪ±òË‚_zúô×ô²àOþÜ›oüºÈý·OÎÞúX³D©?êÃGj20aüwáä…ãº&Sý˜ 0/GÝëäI‡€ ‹¬ÞЬ:FÃV~²±shŒeÒn̬AåÜÚ&^ âƒ(~ü±e'bA/ŠÊ…xØ-=6<È@6€´Õ®–¼,—iäÅÍóÞnÅ9_ ‚aÚUõ}üÐØÑN,ë¿}?Í'%ˆ; tl<ÁC—>œo÷õŒOOùÎôžþÿ¢?]õ/ÿí÷¾ÿï~øá‡üˆOýW—ªþd–Ÿø  »}ó²àŸ}ÿ¹_üç'¯>º>ùƒŸ×û4y·@¿Ö“¤YF’+£…YOHf©1¦Ë"/u£GÖ…Éi\m­¯¨ÑÍÉ»È¶à”»¼J*}µ‚PcƒYð¶ –ŠV–öúè—l妵½Ó÷ Ã*É!Å„².þÈJS¹¾™`V;TCÞ|-ð™ÉÔ¯ÏJï=ìÊ[ÞÊÃŽ>3¯Û}>ì§o£œtzúìÉõÕ7t»ÿ‡ßûèƒÿKjÖ N"o÷•÷Aù­²¤a›—õýgö‹_xó¿zÈ»'§¿KT/ ®õnß,ÐKâZ`Y m]uj{R1Pp«àEŸPE3yPÛ¾ÕT±c#€¯“*~sÝ$ÂG»‘)~0'ˆÊŠFîþü›/­ŒCpðÝeèÔv¾*þ‰¹ÆYy\S_eë"® ªÊšóÀÉ9ƒPcRÞæ•›:/zp‰W‹~.tÚ_ºi[õÈ¡ÑAù¯Œôa„—Ûý?ýÿ<¸øúo|ïñÙ®X+?Ñ·ûÊÿ üVÛÜÀoÕØÖ»Ïžýú_úàÙü³Ÿ{Sßz½úýoŸž½ÅWŽõÇEõñþà, H ‚IÁbñÄBÆ”§^¢f$àj­b•혔õÀk¹¯¦øûÿÚ;ÿ K®ªŽw¿™$ìîÌìì¯dw³"†X#&EªÔæË*­’¢L%X©RJ,)KQ´RTb Eª ‚ˆ©UXP ù¡  Qä§ "&!6?HÆ]³»a³óÞ̼yo~½n¿Ÿsîé×3›X–ÍîLß™î{ï¹çœÛ}ßýžû£o߆Ë*&Ì:ÌPÙ¤Mù$•¦»âqqÎæ\…Ë ?®ÙôWœ~ý¤™! Å}?& ÒëÀ"gªçà÷ÂCÿ…èGb¨=Òb¨K]?Ñêô³ß( 'ôKC]O„ÃGVà6A«ûv-Ú‡BC|›ÝïçÙÁNV¾ù`§ý§K½%vëÙ0Ý}+„u§ iÒ=®üR¯ûõ/ïšüÈ¥ƒR˶ʫÆ3-Û´EDà’öPÕÂÎî£ÃêÑj­¨Ji ‹0µ —P•ÛÞnJé°ºSqäL·½»ï“„®+ !b¼Îg€‚fèp]q.+š<)#ËÓ[UÑÄ\MÒPï¡SôlHš¢Ú©Ê'ш¯¥¡C4 '¿ {ÖUZRáq“ÓiÁ›´DftšaMJˆsî[Dá¡qztý‘e ¯ÞÑüžÞØÓòý¹¢¸YÝý_›Y\|TÉØdnmÃt÷u/'¹lâf‡Ã‚ùù…ÿèw¿xîøäç¶æå«'²üUÕ"" ôkf¼²­½ˆ0Î*qj˜œ%»&3²8›ë25»<&t½T`?Pd²®Ö"Ç·kT>Ñ ZÞÁ LÒ%Ä!’áeJ””3z`zDU½šSð…ÿÿçÒ­GT> £`üZS%¥È„ñ yçv>O#Eå!™àåâĦÃrH2(ƒ×¡ïFÂh:ùõh›8Ÿöר5RèÔËŠÏ=3ýåC³3·‰¥»´ú®»¯{:Ém`7=í¿>¥÷‹½ù#w÷»=0>vHï\±3ÏwèWϵ9¹6É4¨¤T:*ŸIë$ØìP€žpª¡ñx0*¥%Ye5EÞž?Êå,òp]©ÈDuØ:‹x¼º&d%HRHšÒåd&tBj˜`À†Z”z1 Ë8‹°üõ®~¯Ö )?þ#ÍékyìúÃÄÖò"ËTn¸2/À¾åŸÐLÄë>¼è7fn_³ûYñôlžýÖ·Ûíwô–z¾»_c-°i @Üó´{ëV¿²w÷‡/Y]néiÁUzZpŽÖø""PCåK(¥òX•*XJP5W’ ÈŠ×x8!“â¨À¹/ÒäG:¤p 9"n:SBè0yåm8ÇOé.9ŠšÒÐÁ† 6C€$dº©ê"°&oçóVw­ŒéoèYã+bBç £6Âõ‰>+»”Æï†¹â…fú†ºH«‡j ¯žék‰¥¹¬|¯ºû¿ªyþ[¬*+² ÝÝ×=žä6H%0t:½û{ _jMLþó–,»x¼•_rŽF<-P'‹@]ƒ 'š‘-*>Ûù»LkxŲ©»ûºÿ“\cÖÉ´×½|ʆsÇîéuoÙ;1þM½;óÚY¾G³D>,`Q Ð*þ°5·VYz1ð[ ÜÀN…® È­¢Ã›˜Ý«$+='éL×Ož´ê–Y%F¿¨¤þC¢CQ¯ØÞœÑv*þ]€µöœKÑ_úH7£ç,FXOæ¤Ìd‚?®ÕtÕí ÈÂãk½¸6èQôµývž=ÓÍ‹ß}t¦}ýìÒߌz—‚𯩢ø›Âxþˆ6µÈØrýâê{å çùy= V[3®í˵ÁÖŸj%µÍú™ Jâ4“lÆ£ˆÅ¡'â– ABΖç·RaB‡|ÛÆL{ÅWd—¯ùƃÑLU2Fu“’EYµï,/eÿ¥MAŸÓ›=2 ?ù XW­¿”C·4"ÀµÖØõ'^Èv=)¾&MBÄ+ƒ Hô‚ÏåásŠñ&9r ¾È~3 èJéChJÇ2h9·ý>»¡¯íÜ}b_÷älûÙòr_,£ïÚ T6îyJ 1ÏS(ëIÓ^‘ò©ôþáÀöm_WŸôò­|¯*k®çÌ|ä¼å{ ¨ª[g¢/+*3ˆ7« ê†B ìuòìm·ov¹X,Ôi”mºgúºçíð"ŠlÚëŸõä_¿°ðØ]‹Ý½jëØªzÒ?=©§úŠ‘žvé`~ i`P&ò;"ô¨ƒ“€3p'vW®&ä¬}'i˜ì`SRÒfÙ*û6 sGGs=ô5)›J2qF·q£Y ðÐÊòOÌÎÞ£dn‘ú¼)–ðê>O‰k À‹/Fž”S ´˜î«ýî]ÅÎí·Ž—Ù…ÛòüÇϲ|ƒRA„~6á  =(ß+· RÇ ±ªLu­š(¤O¨³µðâšcõ|L\¼È'/å`â&Ùé1àQ¦žháà ^®g4Óëë™]$K×Ù}±TçsºÝ_’!\ñš¼ó@äV#Ù}YV­Ý×ì>tdåýZ·{Ýcíöߨ»ûñ…ºÈ¸ñ¿‡h À÷PHÏÇ2]Ü9?ÿ]-"úäþñ±ÿÔ›†—Oä­}’É5Aµª¹Õ[ ªê,ßžõ [»íè£âÛT¾³9ÞÅcCñIãËw•®À€bN2äÅŽt1ðƒÐY[keŽjÄ‚”sI¦7ùˆ„ÎxÔÉ}-¥y^‘'I&…È«zç^”éãF“œ¥s)Îì¾òÖÇò‘Ų<¡oìÝôH§ý–öââ!±Pnºû*„ïÇ5àû)µšÌtmXð†^÷‰;û ºdÛ6=‰*µSqkËŠf©µhŇVÏUå¼h=Qå èYUŸÚ¥Á!’cD!nðÇHìF–¢S°™a‘~ ÀŒ uÁh•\ÌÊ‹.Åô!ìZ hÎó¹ÁY©JÓ ’OPü^L‰i±8… gž'Uišäcž%¼£¶ýv–ýíC£Ko|nfîK&Ôt÷S1ü`^c~°ò é5Âú ÷¶'Ç?±«,/ÐÓ‚Ë_ư@Ÿ‰Ö²baCM¼”M:éî‹xŽ^ÜYÌÊ™ù<{çÃöotŸ’uEMw_…pª\cNUIÖôL{·-É>¾Ð}â. ^91ÖÕ»¯›Ì[[5,†O |-u[ðX“·œ…(0[È(Ÿx•.Rtû-ÑSABòðI€ÃÆ€=ñR½Ef„Ÿuï lRc}y%¤´³ÄŒ¼NzÍ1k _ÇÄÏ Í5& º^‡,ü ùÉvСAp€W@— b{;ÍåJuDòÝý‡ŽçÙ›¶Ûï_í÷ç$Ö¼±§BøaºÆü0KWºÓÇMó)UæûúýÎ}ý…Ïî»[Kq_³£Ì0ˆï27os\C©_q€Ü! ¬f0d(a4#˜þÄ@ad ¥ÃãJ×ß@:ÚZIËc@^»¼Z‰:ÈÑ¡DZõЈ­å·œLM‡ñ î¡Ïì>†dTÝý^–Íé“Ú¤îþ¯wúsûm+„3ðÔ€Óô£L;6lXðÉ^÷)íTüÁß:§'pWnÏ[cìS¥a½¿€16¶×õ„*Ì) @èF@ 6ÆÇOƒG÷€p¢Cr8*Ih§0› @_qXICAË'ŒŽÓ]¯ã~˜m“2ÊFOîÇ €©}Ú~»å_Ûɳ[Ÿ*Wît¾àÚšî>Åzº\cNWI{>õaAñÕÞÂýìÝú±‹V[[õÍ‚×ùw Ë-3“„váøÄÁ‘rp…íÒã¼\`dH/쫳’“¬8ºëÿ*ME™UÊ1ÑÍ|øÕZ~c‚ÏO«¯Ü´vàkí>t|áèêêÕOÍÍÒê/ëhZ}ÂÙàªêp6\lsVÃaÁž=coÍFoº`eðöóõ¹sv*¦Õ¨€æ—Cûš!?8C× ÀaÙGÔ ÌŠÈÄ¢-B’O[Oë¯õ²´öX!£2 1J£[OÏÙMÏÙg¶¸¸ø”ÂYäpýXõKØîLÂ_Üsákb0x÷ùeù 窩çsf`Ü^¨—c@#Ï8 ó|Žƒ>S €Ã>=/kîÙ]A™–‘~Q¬hÝÀûôqÍ÷HmÓÝW!œ­®œ¥¿Ü´÷êsÞ6üloþ¨VÞ²oû؃÷Oêsf­¶÷€š{¦|X@ëÀ°pN­úq†­•7ð+,ÂÀWóØ~|t÷5Éwû³yví“íöÇÅÞt÷Ug³ã7oÜÙ_rý˜EöÊìe¿ÝÝ{Ãùú€Éž2ß²¤ø²òZ ¬M´uŸüàú²€#š|T÷Yˆ2ÌXw_C€bÀÎ<‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì½i%×uç—ï½Z{«Þ7t£ûF‚C≒HBâ"È’¿0Â1r„ìÛ¡Û£‰qø‹ƒa°ÃrÌŒÇ<ž‡gÌPP3!’ (Š)z´5@ìÐØè¥z­ª®½^=ÿÿsO¾¬H‰²(Xy«^Þ{Ï=çÜsOfÞsî’™UÕ†V­Z ´h5Ðj`Ëi ³åZÜ6¸ÕÀûXƒÁ +ñ·ë·³Z^ÞYÍ]Ù¾võúŽ•™™íKú-_»61~ôèXwÛÄöÁÚú¶þÚÚX¿ß¬®Ž÷ƒ±NµÞ :Ýõ~¿ÛY¯àUu:ƒõª×¸·ÞétÖ:Ýîj¯×[t:«½ÑÞr¯;²P-,Ÿ9»´Þ_YÞµgÏÂäž=󃩩ùÑÝ»¯W;v̉Íu~¢_…gZ ´Øüh€ÍŽZ ·€dØwV33_yåàÒüü¾Î¾}WŽ®\_Øß¿zyïò•+û—æ÷®­®O­..ìZ]ZÞµ¶²<9X[ѯZë¯Wƒõ¾45¨Vçæ«þêªò‚õûUŸ¸Z¯©x ‹ODÜ©ºŠ š=ÒÝ®nÕíéGÜíU½íÛª‘ñ1ãôz*ëUÞHd|titròúÈØØÜèèèµ±ÉmW'÷ì¾ÜÛ½ûòØî½—G·Mœ]=7}aÛh÷ꎻ޹ Gá 5·¡Õ@«÷NÍÛþ½“¢­¹ÕÀÐÀ`~þÈìã_ß¿ÿèúÊÚ­ËçΜ˜;{þøÒÒò‘¥¹™c+³s{W—–¶­,,VË3³•Œ|Õï¯V«6Ö] ÒeÄûórÛb£eÄ1ä€0Ô$ɧ]6öj$k0”À;.L ê ©uP¬9ƒp$€Q‰â^O±äX—·ÑGadl¢ß½«›œ¬zãã+cÛw\›Üµóìøøø¹‡¾9qó±7ǧö¼Þ™}stß¾·&Nž|»IòÚÐj৬w?å:Zö­¶”®?÷Üáî¶m'Öúý{^|ñ®Ù‹—n_˜›½cñêµcË33û®_¹\-Ï^¯VÖ×d(eD×bä®)wÏŽì§ ¹~]ý°«yŒ¾ ³Ø[~Û]Šý­c´ÍhŸ»ž6Ð#€n\bã4òÀnà‡\]ñ0å&B"`’«& Â&9Ó8Ì8ČĺäïZ¶ž†±m۪ɽ{ªí{öÍNí:·mÇΗwÜ÷òÎ{ï}AZxQ³#¯M}ìc¯‹n(†ei­Z üM5À½Û†V­þ†˜þÔ‘îw-½ôÒý3o¼ñÁëׯ߿pþÂÉë¦Î_½Z­hz¾¿ºâ)ù>óì!w˜>ÇÈcœÒ”írÀeëÒܽçÙGô*‡KhAß¶>fa'@4&«™:_×8E ¢dU0#Ô< ²"×-;“A.Êà‘d˜ŽFh™B³ ý5-Yà hæ@΂4Umß=Uí½ýxZNɳ“G޼ž\Û¸Õ@«ŸL¾U2’»ÕÀÖÔÀW¾ò•Þo|ö³w-¿þúǯ½õÖGç._¾þÌ[÷μ}nßÒâBµ²¤ßâ² dGkçUo$FñR—lšG¾6ƒ¶}1’ô †ŽŽÂ˜Äà0æeÍ€]~à ó²¥Zˆ[›‘wíg`¦ |õÍ7ï[¸6S-ÎÌT+ËËÕúˆÖ¸GFÄPì½Fæ–HôŒÆ#MeQ>äìVç ¥ï4òQIáax“/ò%wjª98 -$T?tR )2 ˜À#X'òrú«š1Р˸f &vMU;¶W{Ž=³ç®»NM>ô§»ïºëÿ=ÿÊ+?8þàƒ‹…´Z ´hh 難M¶غÌ͘yæ™_¾>=ý™™×ÞüÔ¥3oÜ·påj5ùJ¥{v½W‘X£Çp…¹“¾l½7r´èÝöµ:¹ÝÊTxZ¾!$°ÄÇ£á¼3•O“jë\Ì`:)«·éÄšqÄ1ö 4yD5µ—B–ºê† 3 ª ²RìZ6êÖé¸Ñ™:QiÔT8š¡)CRã®kuNù2W ý™¤Yf ØO¡g«É;ªÉ«Ý‡¼µÿƒüÞ®ƒÛ~óÍM?~ºÔÒF­¶¼Ê]µåõÐ*` k`pá­3¯¾úÙko¾õ…égŸùÌÌ…é©Ùé Õ*ÆD#|mm~SGlÞóæ‘ÝñÉ]Uò-ÆLS. …0|1VÖ4C[[Áä™(–†Y4°2ÛRqOÌwƱ4²ÔÒÔÒ!ž}”Â:ŒÂ§TSsM6¥I5“â ÷:Š"ŸÙ4dÍö¸1*D¯ƉҺN%à WOÚ³!¢dã!^qÐÑyܾgoµëȑշÝú§û?|ÿ#»o>ùí±£GO5ùµéV[M¾w¶Z£Ûö¶\¾|üêK/ÿÚ•žÿÍé—OÿâÕ×ßœ\¸6W âÙ5oÔc´iÓ¨Gï6ø& y1\676tX 7Œ½àŒbËØßÅÈ{” O¥!w0ŸÌɘA_ÒEˆá/Æ? ÒøÕù0‹Á/†âªD¸Å(—‚Rq©ËT%Tèo…¤Œó ‘’mä1Ä&g'AÐ.¦¦Èf»ÉÓ6Û¦iâ[)Pì{MÏ>‡p¼Ä“z]CÈ¢ VxÛ!ÐrAGãZ²™ºùxuà®;ŸØsòäïï¹óίo¿ãŽò6j5°e4÷Ì–ipÛЭ­ëñŸŸ9wî·Þ~ü_<ýÒÔÂü¼HWëÈìÎãÆZÝËþ„1ÌØFxX9ê@.ƒ7®ÕЊp±×¾éŠ!¶AÄJ™OÔ7%é0jÆ¿ŒƒuäâÈXì8fÕð¡üLJ\o¬eÈ!¤‚Wð ó2ÞX/ù4ÄÍÖ„$Mš,MìÀ(Äb’Üð¨Ø¨Ci ¥Ö}qX(À <ÒZJpFÍ𢤎ž8Ÿ˜¨öÞvKuàÖÛþðÈÇ?ö¯w<øo;ÇŽ]®åh­~†5÷ÇÏpÛ¦µLOž}íµÿàì©S¿}îégï¿vîœ^®£÷àŽûMwدÕkthÃnC£tÊQ#F›;¦Àãv`‡|  kó(\—›>‰G,·¡8ÃêHQETèÇú á€*Z`9éRòÁgÈ#!Q¦£Yžqð½‘c”] òXF®¯vU„` ªòoÔ¤‘ô5µYŒ½ V|`gÁ \—‡gPäH.8A‡Îë „J{ã"hòÒÆù^×fN^¢´mçÎêàw¼uô#þ<øàÿ1¾oßóÁ¹=¶øÙÔ@Þe?›­k[µ¥50ûç~çÂÅËÿÙ[Ÿúûç_xñÀâu=¦ÇÈ:š¶aòü1æ(Ͷ'ÒĤlg³Ø€˜ÚçÅ8ŒøÃ@¾QÈ’o2(ŒÌÊ©à7ͧK‰|飉›5¥Í[W4C2›¿Ò„¦h®¥aa# i0p¶ò¡.èß)ƒKp^Æ´„m6Fè °‚&Ó+˜ò"ôÛ) P•Þ8€O¶®7i H…@bùÅãeªUg@gt}eEŽW»]?ññý›Ã?÷sÿlÇw~»Qk›l5ð3£ß??3­iÒj@!ºïì#üƒ7ûîoM¿úÚØÒÒRÕ׿Ƈšöm>çFK]¿ìLóf°™MÛ#žaì‡ê5bdžF™r¬‹ã¿&À¼»¬¥0'JØu^‰²¡°Ò XÒ[P1Á '\0F倨K’®ÊC R ˆD"‚\èoÀx^…¿+ "ÚŒ¸1¾Èœí–'Ûcã^t¦‚4ÖÄÀj§ÃR$S8ÙÄQa˜!ç=©°#0}óH×Ê Ú}ôhuüŸû£c¿ðÉ! ýõ(7Š \ÜÃýQVì†ù` ÂnB•·Q0ÁNÃ&ŒÉ°Ø¶YYÇI¢¼+v>‰ ïbl)r‰*MŒp\¨(êjÊjëe¾ÂMR5i(®Ý„hˆy'DÕQsrÈ‚˜.'ÿ KC´ZÁì P¾€‚Af4ÅkÿMd~ɲÆ*EÁ7ªÖSò¹‰:ÄŒBu°XÖ—0ã,(â¨÷ ¬ÊèWn¿µ:ùà/üË›üÄ7qâÄ«”¶¡ÕÀûUq¼_¥oåÞòX½xî—NõkÿËé?úöGçæ®W mì‹^[F# ÍzmpÂä•apØ ÊŽÂ „1+p[—@Z­rÛ¬¬ŽŒ?ì”vmäÓ„p1oª!³!˜“ 1v§Ü)x ;ê(õ™NÜ©£´ êdZ77銜 ¸^,‡ù˜Ò©8DÍqæßÆ·F–6i"Ç&N¦3§™&Kž J¬Ä˜³`¥j½B’l(ððÞÑÀäiœÂ#ÈØK—Yî6RsÔé™+^¡{¿zY|Ö´œ4ª§EnºÿCsüÿþ½ûî»ÿY©±Z ¼ï4À­Ñ†VïK \{âÉüÔÿù/~÷Í_¬*þžÞÒç¯ëɦ]w·N§_‡0¢a98Üx¦| ŒD±–b0“ QIÜBŵ†C&…!`Q[xòyƒ”{·©ö¡!‡¾âÂ* "«°C™¡aÑUEµT$„rex0Î0kBɲQ2L¾+Ͱ˜TRu~#ZCX4ë5-UÈZ‡jMæÑ„ÿu~Á'Psë›8.7YèÓ×î@èÕÔ‚C#fkúdóÔÞ½Õ¿úп=ñðÃÿ鎃ÏCÚ†Vï' øz? ÜÊÚj@þþ·ï÷þõã¿÷ÕÏêýžî·™Q'O·]Ou[Uašö¤€Ëˆ"¬‚ðÙ4 +R ¦ äJÌ‚ò†§|(Ùh¹ n3ú1†8ªm"ÿdéw£FhÜí6ˆ™ÿQ47–7ñ Ï¢ºà¯cªª¨¯†;!³H¾)ßm$úÿ“ƒkôG±Ù€‚ø H2.œ‚þ‚Îò½N¯ZÓL:Üþ™OŸ¿ï7ã·vÜvÛý¨jZx«Í¨.í6´xßh@Æý£/þóÿý÷Ÿzä‘ãKÚÑßÓc}žß¯;z, Íþ4vÄôæ¥?W2q 'À8äß-Ô”u!è?éM´fC¦f;´[?ŠyÊÙ,¿Vx»ýb½ÁX‹.ÛŠA»Q —Á[u%oÜL—xˆ4´Ät‰Wòв,ehÒ›„z m³ì‚»8Z°& ¤o„g>c¡‘Ì€QG@_/áЂœ X_Z©ßsçàç~çwþ£=·ßþ/ßAÛZ lR p‹µ¡ÕÀûBƒÅÅÏ<ûOÿ·óìw¾³sUäév{±Á¯ñ £ÿìúÆÞ–Úâeïßìú]¨Ã0àï’Å»ýHÐ47æ$a£ )Þwp“_#Ýè…ÞÅ$šą̃:’YˆN3‹A†O=Ób¦Àp "ãráÄ|JA(¼Ò^Âq+4mƒ¬®'NYÊ›ZÌ”K´&/ð°á:ƒ žiHÊ’” ¼RŽÂ9Ú /(õàð7X^©öõ6ÌÿøTð„ © ÃÍ•MþY`½k{ËY2•<"ÎçðÌîQh"gË«Õî[o©>òÿö~ìÚ'òD´ñ¦ÔÀ».wmJI[¡¶¤4"œºø_ýÆÓ}gd xäÏsýtâÑ1§b9Šc4YòDM«àÚX$~˜¤R‰ÿnÌ7°0.ãœChb ¹_òYØŠQ"†&fÖ•¥‰—4™O oâ',q‡q¤n,‡6a$‘§!“ŠÐ÷ìÌ•¸Ð„Ô©HøX€Jªw- `⣓”ˆ|ü8¯2±1ãFàg­q­~…¤ÙƒÊvóô ,:c#ÕÕ×_«žýêWÿéÜÅ‹¿u·ÇV›S­°9ÏK+UÑÀò“Oþ‹§¾þ›®¯èëm=u×ú’­¢:Øð¸3(lc)‹ÌÐ\6 “ iÈSþWÑ qèñë){×<’ 0A“#È Ê\`Õ†Ç|š‡Ç²¾¥ ù‹ñkR¿ÄÑmîdH–Ðlk­åÆ*‚Ì<¥¹žn˜Äô@ß2…š4)TÉÓÎY~JÔiµý4N¯P6`×4!wRfÅÞñx¨YK2 ”†ŽUÀH=i¡<8y¶†ç¨~D5˜—LóÎ ¾*yáÙçªg~ÿ÷ÿ¯óçÏo„öØj`ói u6ß9i%*ÌÎ>üê7ù÷/\Õ×YÕ#³Ûƒ-pç›=pÑEG7ȼû?°7ò™ kµQíIP0‡L”y—œa)¹ÒZ|ÏHøuýF/F¨ÁÚ`á×l°L./q]ÀKßhΓ‘qªa”ÄÑibt‹ÑM çFìD‰É7(r¹-¼2ÄŸ¸‘–¹=¥}"Î?à ´ð$3 ¸náº^Ó”2`²MІ¼2™Ï$yB‰-IñJ-]“ùPp•¶s$^ûþ÷oºþê«ÿ£ù´‡V›P­° OJ+Rh`öÏÿâ:sútµªÇýè\3¡Tü f8%‚vÒ]v#f{޹ i …h†0ð ZÄÔ >„•3g×™A_Ó¾1üZ^ª™p7kŠ} ÊbqŒ/ˆ'„s£á®‰4•ƒ¯ K0xP–±Ê©@À‡F€¥JB#ðúáB4M§x›ô6¸˜d’÷ۗϼU­êklá¹»–>—N;Ðzd8º3¶Šn™»6 Jt ݇«ß¶s€1P šºªìàU0ETP“Gš!Ä<@. G&¼ÄÒPaáa3ŒdÍ&Xì@³nÀ Å`š"Ê‚‹“N×\U®´ ’£YåâÚ€'Ôßì0È71f,È'±g1 ñÁÑ/qŠª¢È&z;Îa¥)ŽÜ¥H©è¹è¯4kØD0\^pë|mÂAŠÎbƒo8 Wþ¹†:Ÿ\ºÜxq2 pá7¾1}ù¯[ l ïÃÍ"Q+G«Ë—˜}ûìÔŠ^¬²®õÿ!z—µûÞè\16÷Ä»\™ºß¦7æ=kÜ8Ø|š&G‰‚“7 £Pð Ž@–cAWy¨âb i;ÁÒX²ÄPœ¹ºÂ£ÆSs†DCÚ d’?óЇzÁà¦!¦>WÀ%=™À-•nà›¸SrBϺ‡<†eI2 ·°·£€Ž Bò€wâFQÁ±¬:¸ÑÉu¨ûäCI:\>ÿ¢1y6J±UB¾ð ê*e¹ê>.s98úÉØ÷ÉS§¶Ö_«V×úÕì…éêÚô¹Oš¼=´ØDÙD²´¢´°–_yåÞå™Ùª¯Ñ¿zQ ¢¢;OßvãóºêÌÕ;ÐáòE?“X EÁ¡cç ®pòÈ”¼Òi(ôj!÷ððJœ)N>Ó5ˆqb€1"GŒ¸G˜âSª .bPóÕÖ>Š’§î]VàŠ¦–5)nàeû’ª™·÷/Üø\òB…gVBh²èŒ64rOÇ&ò9ð õ*oÊsP€­ð›²¥!®gvT_³<S^œ×àWãöy]¼£\äÝßæõLVOÉ·Tïë*õ¡µ(×/ǵ¯4/®ZžŸ«f¯\¹§ ·Q«M£ÖØ4§¢$5Ðïv÷öçæ*yUw]c*9tª]zÚŽR6HÛÆ#Òž§snÀŠÍª;m0kdv /´6Œ”ÇÕùƒ§åQã‚X6 Äï`[Š¡ë"h¡m6) Œ¨(«× ”‘AeÓœå±lp.•’WÎÆH 0lÐV‚Û-r¡”°ita# ^I›µi9 U>qꆑjl»™OÁ&Æ›ø9IÞíó˹`v02ºÏšmY± o<¯Ã¥„ LG`È'ôI-Ö‰x¹ý)LÝ^„QžF(Ôu!g€\nQ×ëš~ËÄ¢YZëT3W®íO´6n5°Y4Ð:›åL´rÔP‡º›«tÖdî4’ô5 0‚áÔ劅£#VOí¾X4± ‡;Õ¸Œÿ˜šZÕëª:Z¦[ÇÆÇ5¨’QÐb<Ž Ú¥KϬˆ··lÌJÍZ9ù à.6b]uȾî²Á3³bü•.<È qhM6° ÉP±‚gŒ2«®$ Ÿ¤­Ùí;p’\‚†ÖOòCSÐ, ¾žÂ/Þ‹©³Údk `mƒÞGã(ucœ(R–‹ÄÓäÊ0Ëâ=ÙqUrf$I#†ZAÑÐy /ñd (›LžàË  êUÅv¨ëªJÚð."]fYêeûu®ËÕ•jaiY#ÿ5ÿÖþ×´‘€/XŽŽŽUÝÑ‘ÁÑšy›h5°94Ð:›ã<´R44Ðév×»cc¶ ,šNê·ªŽ}MӪͰÁª¯ßÄ„œ¼€îºžÀ]P‡Þèõ½@9ݺûnb@1u“ï}ì\‡Hpâ C%,ñw¶^”%ŽJKÝ)‚,ˆy¸¡ÁÆd²l6ƒ™7°€é¯,%o¸3N'`…&ñrê!ÁiùÌSHÉÓ5/ØÝYÄž|Öé2•6¸è´Â  mäA5¥œdÍ´†‰›Ò<ŠÈ’燠9"ÕÜŸä èxdRÒrn” ˆ*(„>Eˆeg% âÚ©±£í*ŠiÍÙ(Í;*¸&y[åÂÒ¢vûë¹p¤w~K”ë—3;Ò]_Þ·¦µ¡ÕÀ¦Ñ@ëlšSÑ Rk Ó]ëȰ0rRG:¡ßŠ:Ö¾:TÖYWÙÀHK?œ€ÑÑÑjÀl¼1v ƒB‡î1?V„­Ýî ©IplÓtØxêÖe·£ã·‘TŽ Â¢(Ø(1Ä33,xDQìØÆ3*ýÐÐN©É–¯ Q™G©XJZxÇ€´ÐPgò  X)þk>*oð=ø‘"mMEFä‘§€ *sEvø(Ñ6×íà§œ:Ba‰F`âáNP0,ø„¬ÁÇÅ&'`Ìþ„s@ AcrP ÿl.ü³ŒjBENsP©ˆ²ŠRb¼,ËpJá_ÈlöcÍŸëoYO«0ò_ê¯XGÌ0­‰¯üÓjYñËUº>{½îÚÂÂBë ö6l ´À¦9­ µº==¥e9#ZUÇ;I§ªÎŸ]Õê~ý‚ ¸æ5õ:>¹­nONï À@à°‹›%‡b DéŽ<¬°t82¥PQრd¦×AôF±E10Œùt*œä v"ÆÊl0 Ên(7 Š·5X¿:Žòñ'Ù€5ù©A7W'7 0E[*ºuˆ²a¼‘Fyrᘭ1ªP•ã0àÁ_4 8P‡ü¨†HɳF,ï„ œà¸Vø ‚Ô•§< ±õ #Á¯”I83®_ÎŽ(£þÅ¥¥jQo«\á]BµñÇÐæ¿%]|±nÕÓLVO˺ûÏ=÷܆ \I{h5ðj uÞCå·U¿»´ A”F‰z~º;6ê¤6ÿ«ƒ-ïrÓÖjºæ†Y+ZXXÖ#WÛ'50©Yƒw¸]áÚÀj­?>€ƒS N™–ÆF€úI8L†`ä72€Àø)xAh›XPÂ}`8€ E´üÁđϊLcلѬSs5 yšbÁ,p”N(‘R¥^Œ*CFmSÁ†»Ô£lnª3ð-Ð`à°–@Š|à‚–ù5AoFEPáU”ª u_·¯´&ë®u€ HÂà ”NE5äJ&‚ }Ð!GäcÄ/0û¤~ó‹Ký/ëE?Ò£®5,û*uéš]ÖtT_›Tǹv¹åh `íK_úR뤮ÛxSh u6Åih…Ø nw¥Q§©ÐíéiM£dä'¢Û^gáÖBæKk°Ì¬ðž€ÉåjtÛ¤Ö\Ù0ªÙÀÔ©Ûè`c':O!«³¶©³õV Æ à„À4d©¯”ɦ!øÑéCKLY Ê*©Γ¬aðb"=œ ‚Æ|A~ð³H"W®Á:GƉ“…Á…œ+ÑQ$òT粤,uª4Y2D½È…´”—j¬Z•€ª™ì`R$¤!U]‡²õ+Í p2  Ôá˜0ä M¶È†\Æ_S¥\ý Ñl¿Óë\cL÷//UKùóD .çBsÕ1Æ_KëºîX–êéÔEh`DWjÔÚ[ l ´Àæ9­$E½^G˧íÛjt´†:R 4šZW§;Nß,<æ:š`Y_a‰ÙÌ–«9c“Û«ñ -!tX‚–zN%Yã÷_mÂxP½—\‡peÀË™uÛ]*·ÄFk#€#Œ‡‹ã«¤7xäÁQ¦ž¡PEäö+vÊ ¨§T‘ ÌC ¥‚ڗɤ©4|¯QmA reâ¿æB?§‹#q´%YxZø’/mt8R±%ßÖç§É7鉳±*w3”'vÚåœ1ÉrJJ!º°Û!X/†S.ÃLÆœ¸¯—úp]-è·¸²b×Ý?]«ëêIWØ '`”‘¿Œ‡÷U°¥ë¯;ÒkŸÿç|´aSi u6Õéh…AzòŸÇ§µWLô¶ZßÇ §ô+‚yK ¥?«ײ«ß°ÈS‹ËÕê¸- Œá hF §=ŒÖÜ!«ÃNgÀ†Q<\•§} fJ€*(WŒKÉ)R`‰‡±s–£ =Ä,ià ^Ïv*(©"b2u=QnjÊM×Jh&!å<ãÒQ¾ ¸Ð¢˜"£ÞD×R·Q ´Ç“ã³gÊõN°,X#ÏZ½hÂGÊúÀ-ô¤²1Jû±È‚%†­7€7¹£dMŽ˜Åú7¯ºž€±½Ñÿ‚‡€CÄO£ú•5¯óÏ_Ÿ¯®kÔÏÇ}Fp&ÕnÞ$Éf?FûzÕ¿OÕßkþ9Q›Qýˆc§Û:RJ6™Z`“V ˜˜ÐËS< Pœ¯¥ÊÊ÷ÔÉvÆÕ„6ba{ê¬yaë¯#ê˜×Vôö…ëÕ²¼‚yÍt·m«&wì¨Æ·o«&&'ªQÑw5m`ƒ/‹Ô« i^<<& KQiF‰”`NHúQ@Ò V¼ÓiŒ”íxQŒ}/é‚_xb` A„†7 #©£GÚIACØf^iŒ¶ƒÊmÈéGÉ3QÀ+ÂÆXYY{)°’ÊÂi õ5 9äæYøF5sGULß»n”"› 9ÎSÑiG¡!©·ÔãX9â¨kX† þ+Èn†ê¶{@; Í£}Kšê_\X¬ffg«Yÿ•5úõ†?ÞM±}ûN]ŸÚƒ*><ªÉ‹º0cä/çûýº¶|Ý­ ­6™Z`“VœªÛ¹ó’ßò“ ÃP~¦ôõb•Jo ¨zÚÍS3lÔ~€Éµeuµ‹~kIû–gç«™‰«zŒ`[5¾c»;ð‰íÞ'À¬€—`ÏÚ·ù“ca#ª„²µÅ£Œÿ|èR"˜^y ëä*+4É®&©Bqðb—7òYL\p,ZÒ¼£\t¸! ¯`H.q”—aŒ\ÆAl˜i”WûBW‚Grɜ뀷‰R¬ì€FØH Àè;8z”gÛp‹ Á€\;äm±Þ K†ZåA"Í ¨’ØÙöy…¯Œþœ¾B9{ýºí[¨–Œ×“Åíª–._—“ i~ž<áñ>–º2þ8¦µŒèÇÒÎ×UUmß;5CMmh5°™4Ð:›éllqYúXÊÜÈÈǯ¾øò»^CUß©^5úmõ¢¬ŒÓ‘ÛÐÚ>S²ü­jíµ³VõY9XdL=:È›Ø4š[Ò'Y—®UKW¯V šÑþ€É“ÕäÎ]ž“3á aüUMŒŒÙ¼ECXNŒÊÃK&Ã0}*G4›&p€bù Nò0¬Á³`Á6Fy¡+ø4ËüãpÀÃ]WíDSù£ù™Bå ”F’“¡2·8ѻݺІq.¤¨`U¬4rx} Ð¹d=@¯¨ŸÚœTçk¸ì4…[ª ퟱKšøè«}¼Áov®º67SÍËà//®Ê1X2çî¨tÆ5ͯ™%¹”«ËšèÏWc»§ª1}æ 0þž© Ö¾~ ÉT·£z:eöü¥{žûú×??16ö§·ýʯ´ÎújÃ{®¼NßsAZ¶¦gÏn›žþÔÕ—^~øâK/~öSßsèž;«cG .üÅ_vV¯^«ÖççeÜ—«u½mÏó¹Õ.Ï^kg6#7Oßò4À²Þ 0³T-è‹z&@?€ÅtàÚ¤¥Ô¢Æl|O`µÒ“ÛÇôÔ€–¶É!ðO3ÚÀÅ n1 Çœ¦séÙÙo`ÀÆž—rpÚÙÈ;.F C/HÁhb FVVcƒ™¥£§éK ª+Ã?F®féƒÊš ó‰“qâÀqCû²@qàfé;)A@—¡6…Úå*å”@MûÓàé6ô-êZš_к¾®«Å9]-ù¯­/3¤å%-1é)Tžé×U&Çr´ZÓÎ^D%¯Q#]+“š{Ryì)‰~Q9¤ìÐÒÎë/¨Òþ“‰m;«›ï¹{°wb¬sñégª#·ÝöÆî#G»ý¾¶{jê{‡?ô¡iÄlC«÷B¥—x/ªnëܪ¸|úô®‘ë×aú™g¾òúM¿ðâׯ]ÓKWɨßö±ª[n>Y]<õxµ|ùJÕÇÐÛÖüôìµÞÄR­óª5Çê¬Õ±wêR¼¬™¦sqÒø“"½ª/ ¬ qE»ºuëx~[º:õÞäh5¾mG8“lÔSêØyÉpâøqî¼\`ˬÛÈÿÅ(Øè†‰Â¤Ù‚Œ48‚èß7Ÿø9À8µáï ©ÁMªø£…ÞìFùÚ/0 @Àix“û’²%†  A.Ðß5PåáD€âê“ÆŽK: ¡Š€àfps"¦ ü\‡‘/™ov𳦿¢ûKznŸ>†I×Ó*ñ­à Æl}5NËxl§Rü´ÿ€éýµe¹¼rzBÎáöíÞ3âÚ9or=s¤Y€Ž–º2þáèã?ãÕ˜ö°ÿäø½wW»„óú¿û3ɸîYM¨lÿÑ£nºë®ÇŽÝu××¶íÚõí[>ö±ón^{h5ðw¤ßWGuµÕla ffö^yòɇ¦OŸþÂì›ovúÕWŽ_¿rYÆzISòzÏŸ:PFUËó‹ÕÑ»î¨î¼ó®êÒSOU+—.W+Úˆ5Ð.l½vMjã¿®œX¿vdyô«ÛŒöº2,+šÞå¹í¥E=¿-3/lþ®~ìÆR™RkZ(XS·¿¢G´—ài–@ú@ïèò.9Ú;Àþfx¶›ƒ¼qÐFQ2{ähCÃPŒŠ²9Vµ;ÖRåžà)Žu0¯¤ ‡9†®BÁqBžaP:rðÏš£.Uˆ!x ’‰;™ÅæEC¦…kâÜHè\ü8/ä‡r‚JŠÜTÊ2?Òd~Ш…Ôa~Y¯W^0y ¨àrpbƒ.kOÈ¢ þ¢Før¹ÎÖ4½?àSò»ÚHÚY—ÁÕ#|b,—R›ú´Œ4к¾œÈµŽ®”žœÂÑíͰ)UõàXtí±3¨ëV;ümü»žèkdT×ÃÄN9wÞYMÈ 9÷̳z§…êT}œ¯5œY…S»ª}‡ÏÈxlÿÍÇ¿½ýÈ‘GïýÄ'N»°=´ø)j oåŸb-ë­ªù‹o]zéì箼öòçÞ>õøC3¦÷]¿|YïòïW#ê eEö”΃±¤Qþ#Gª»?ðÁjîôKÕÂ…éjuþº?£ÿuužÿïËã¯.™­ØêP½¹‹§d-Ò𬠾ªÎwe¾¯7´ÑÍ«s×»p´â«ŸvyÛÎA,¨“îi©@F¢Ç«†5 Ó““ZÓåÑÂQ6"⨜G¿hM>f˜{°4£áMïJØwh\ii¿ƒiÒ¸©i…‡‹}Ç‚Y¨ ZÐé˜dR€ ”òRFgeH\ì<Cð7‡È[—5UÔ[ËŠB H1¦(ßX®>ÔJPº°-¹¡0«Ð†´`6„Q¬rdåÓ»TèOðjèª×[–Ñ_”‘_”Áç }ŒúûKrïô@ Áû9ô žÏçDðòžu{¾?ß+'Q—Ò 'gTËlðã[ŒèÙusä\èÇ›&}Råô˜Ðcª/„30Ƶ¢e%ì«£·ÝZu®ÍTW^{Í˨ȡÎ4g]íÀ©Ý¾sgµëÀõ›ïºã»S=²ç–›ýà/>ô´Eh­þ–5àÛîo™gËn k`éÌ™;f^~ñ3W^yý‹çž}þ³Wßxcû¼6ß ÔIòn:J[ :y[ L™èb™šÝ®‘Ó]÷Þ[õ/]ªæÏž«Vµ+ãÏ@_€{juÚ•– b6 èYà=ívt0RQ#.{> ´{˜`_@Ì DšÖ4ée88 @Ù7 rµc½«—¼ÈHÐFz8ã¤õØ!ñ÷ lÔf š¬[MFCY·?n<·ÜÅp¡Ùe­.; d&à›((m:Ô€96ž¢:™\Ð ÃÙ„Ì-\H‚OÒ$Q( 6ˆ ¦t¶+Ê<õóÙÒ~Ž r}òpw³×ÇqM†rY×ÁNâ•=ñ¡Y¡þ"ÎÜ7]T%ßRíÑzþ Ù¡¯Ù!­çÛSÐׄҚ¦ýûÒ›ŸPYgL¯’Ñyä}E¿´ÇzÜ/–¢¥Ù+¢—üÄKä0SÀRÀ(3FrvìÙSí—C»|þ\µtåŠÊxv¥°7sävŠü"µ½ ;ôÔÊžý¡?uòï}ø›»OÿÃÿûßøþ—¿üå j„_Z üM4P.í¿ iKÓj 4pýÅ?tõ•W>wù…¿péµW¼úÆ™±yí¬ö¨H)##_h²4îD‹U°áaxI £÷/Öóo;y²šPÇ:öíjU¼Lÿ3 GûØüÇ™€ŒV‚i]¶m­+Ï×Ú`K/Éþp^D/KGKmL¯1‹°"“ÁO{ Xe{–˜ `¦@Ütäq/FìÇi1RÌ&C…¾†œ¦“G&˜ˆÑãëÀ2cÊòQµç€c|´+¥ÿš‹—…ÐV” æ`3™…4Ó7"·!…kd =$(rP'„ô0$®!djê!N@Ñ{¸ASŽŠ õ P¦q€ÁV} óš^ð„‘ç%<8‚,ᬮjú^Æ~Uç©ý5^ù¼$ü޾¾ÇFP‘³)Ö6ÌoE=«G‰~¼€H»>Ä]°õÕE® ‰1!ÃS::¡s¢óc¯ε(eà™ÑHÙí ©"ÇáaØà<è%¥íjýç¾½Õ6-q-ž;WõpN¡+<ã¤0›@+ÔE>OÊ p}ëÇìÑÞëǎ¿tâ|dç¡ßZÙ»÷±x`Aèmh5ð7Òw|Z üĸöçO<0wéÜC—ž}îáËo¾ùÉ˯¿Þ]Ö:½Ì­ÖWÕ©ªWæâRæNº®ðì³ÜÈ*P§Û×Úí!M…î;t°ZÖ>•«³ZX’ñ—yö€L4#s¶~ €nZŒdHüÅ~ùœØ ý $#c¨’ð1—¾¦“1@|mPQyÕ‘›15̨Æâ ðdyͨw††òp WƒØ\¨/ ¤ µœÀ3壬ã$0RTÌ43i½Y”Ò!±ŒEÚeT3Òo i0òÝË‘!ôM:z ÐºTç$èÂx—3·±"ðõcDnQ )ƒ¹68Ò-†Sî‘·tÌÛôúÒkŸG75Ê­Gõ2ìþñ˰lC«¿®¸ÞÚÐj௥…—^úøôSO=|ñ…—¾píì[½ræmÒ4*—UèiÇ<ó®a è&Õª‹Î.Æ¡Ñ{fUÂ-{@ƒ…'íàß&¾ñîþužÚ``M;üY+å#@qØéÝÑåFn¼ƒcþ®cX YºñÒýz$ŽÁ ïQ¨ÒÌ"àÈFÙAðgˆí`äs†cÉ`1æŸÍdúœîªu½§ØÎ„ÊýŽ"Ê…+ÃÁttG3²$¹â0‚ÁIÐf²ÑBÌ„c ã":¾vè/ ×Ë !ÚT,0Å螬U w; q^… £« *‘ò€lhœÃ@-F]ç‡À.íÓ9ðO#óuëK:!_“ÑêëÜ0š]Õt=† ›Æ0ÁõÅ\Ô÷¤´Ú§Á|GÓŽíEXOçP§Ú'Eû‰ Á0îˆÂëxŽGm}0¡‰Ú¨óË,û5X¾ÑÇ#8ã¥Eu3ÒàZ²:ñxT”/Â1ãœ`¡ÙûÁL3<Ôã—TÉàÑR¾ ° 'Y&´W`—Þ;Á~˜QSÔ¦Ä;ÒQîs)$œô®jk:fHpFUÿ¶©rNœÛwÓñïî?yó×4ãôØßûõ_ÛŒÛC«£æ5øcÐÚ¢­¨¯|å+½Ïßw߃—ŸþáK/¿ò+žÿá‡f®U+ ÑÁö´ÞíC@wÊ|´»VŽê±lc8^ÒÅÔocÝ1#:ÖûG.\ª¦Ô±MlßþéAfÖå ¼þ¯±¹6­² ×ÿÊØÈð4ÀÈ8£< öQSDî<©%¥$v¯¸9% Á£.F¬b°*c]mU{yÊ`UO àv¬ 4z…F?tÁܶ:*¡L;Ì×dˆØa¾.#¿®§úúñJY;6bAÏ\…ö§©@=¾ŒUGÓÓØ †ÑœÉÐô(#/ñVC N„¿?¯<†LþŒ$x¤Ã°XïöÌD €Îò=³’;Ì, òd¼¥{-”@«BÖÞ=“"Ã?P[ü!œ4íÆ0+/¼Ž^šfÜ’Ñ £ÿŽ>ŸÛըܖF¤”¾Úl\Î’¼i A‘Š6)RVעߗñåb”„2Ìxúi½½[vé[nòšT8b©ŸDƒ•x*‹@¤Uà<èM?ÏP¨}£z/9ñ@Å8fš]@Ξ86Žêþàš]œ™©öíÝë ~8—TÊ(?® ÎIÔÉ‹­|u*Ë“,4ѧ e|.Vøø5á\õUϘ–3&õîýÇ]9rûíß;öüÁîþð¦}ðŒÐÚÐjààúiC«ZgOÚ¶m¬ûàÅg^øÂµW_ý•‹/¿üÁ¹‹—ü5´ëج±ªsr'¬þØ=(==ft¥ŽèªJß`_mÑÝy„^ÊMj:ñÅŠi£×àí³Õ„zêí;x÷:0_×Ë~¼cš)bMwdˆmb”Ö ªÉ=ÚÌÅMÆŠà>Ó©8äE_Ä¡1K¯êãîôuŠ^å6tD1Ãð£bʳ­ÇƵ g€2uâ¼aŽÑ.i–èÖq0NÌ£?ÃÕ±óAdd­ßf]Æ{#*ø0}¶f\†<8¦µÊâ»ë|•FpÍsËø)îK0Ö)óëlUA0…C9Yi¾,l¨)šq‘„bŒ6£u9q6FúÎ=^ &´‚"IíëSUE@ÏX™YÞèh´lg€GòôgY¬)¨©ãæ`N“³]@IDAT®kA(<£½ bö] UFó«làc„OCqˆ"NëI­HKÉÅj1].Á©+ rÂÂ×èø •¾®AÏÂ0£ ºp¸¸>yùO¡Àõ‡°¦§t1T‡nºÉK}ÚQ-C÷®K•vXäWž3@(â ÓISÊì”VkÇ…„NËdèf»föí?4ìž»¾»ÿ–“ßÞwäÄ7O~ò£?4ÓöÐj@h^g­B¶¨Î?õÔöñ••‡¦Ÿ{áá˧øÐ•7Μœ•Ñ_UGÂPܱr¥¨ƒÂ84/šÚ£;ŒI)$)€þH#Q@Ù1“%˜ «AÐ0‡©üþ[g«Ñ¹ë^#÷|Ä«# È´?#>↙úUm*cT>¹sB›ñ4úCXýcé_ Y pÒ®•ƒ~žrU‡îÚetðtΔ«k6^޲ïr˜ÚVwË ÄLic‹×ä€ð"å’XSß‘ö4¹ ªñÅG€?ܯ[ÛAÓ”¸¶9è+ˆë= 1†O´Ku@ź2NEµ>¦´xHÖfzc¼i|â»ÁèB?-§G ]øÄÐÒvÒ«MŒâ=cµ¦Ÿø[ Kõ%/ÐÑ…àŽkú‚'1Øû á©T'|Ÿ{¬}ñ›f¹xñÀÀÙŠë@­S=´n aûš¾ô´¤½Ïx¨>Æ‘‡6‹\a]žŠß©¼GÔ¥Ñép‹ ".tÐz¶„DñØ çra^›Qum²¹Ó¹6TV;eF@Ø1a³*›@;f€å³F%Hã0 C†k"NÎ@”ˆà¼pˆƒEÙ+àâ€SH97«÷ͨÎÚS3µo¿Þ±q×÷ö=üèþ;îxäŽüÉÚÖՀ¯“-Ûú-Üð¹'ž80?;ûÐÌëoþêô³ÏüêշϹxÑÆ”©L-rª‰Ž‰¾›à®I½¬º×Òû¸«Š4P÷HyIE×››ÓÌ ĨЙ&¼F0ðeTå‘ïÛçªî•Œ¾Lƒä(²xîY#~:7 ëÿìÀãÓÀ”ñÐÞ¸¦ØÇöl3 ËÔ†±$ôJÕ «…4Ñ¿LP/ú1º:wOõ*Ï”lO#=î¥0yª³U‡¿‚<?dIç@íÆ¨1 ÀR‚М_)3”yŠ]Þxº–üXJ`Ée Ü@K Àù beœ¥Wo~ל8Ž{ hÜò<Ä x„'½¢6kâ ±ž<€Ø³ *’¥^×;Ë 8 ì‡WEذcà}.ŠÃD-²vLrqé ,Ö~M:DÑÈRô‚ôˆ•zµŸc ™ È`?XÓRâ~gBõ(Ïå!4ª÷:¾øðH©Í#ô*FM)®:è-ú*°Ð¨hQˆaçuQÃ8ç…ÎåXÑÈiö²øit?΋«`¤_^#"ò‹uΊÕ^®ŸqMËãLê…RëÒ³…‚´TjNÎXpŽeàå¾A.gÅ€3ë?Ó¡{• !Þ/Ðà#(Ü+8ÍkZ*ئ·î9p°Ú{ìènýèGÝ{âľ6;û½OúÓx`mØBðå³…Ú»¥›:¸üöñ‹/¼þÐôSOÿÚ…_zhîÂù©9}ú—¦Oý]9zr¯‚Æ„€‰ÝÉÔźƒW‡ZʉåŸB_atB‘áÌ#ðE4¨Tƃ7ÐóÿÕ•«ík ,#.3${¢Ÿ:2Ð`ë‘©¦Û;YSëêš»®^Ö3µ]Ó°2,nœIܱS‹EQTìRaFûÔk‹1};iþ Š™Œ~<Ý uì0TItºÊÚ€ÑáR&+ŸË^7—á¯g Ô/%0£¡æØ–J§´Û³ ’-Ï&¨½*aˆK È&‡Bm³sPýfĉD#6žâ ¤aFÛ9 Ø()"ñ’Ógùp P½ŒöÑÆÏ$xQ8ªÀ/Æߎ õâ¸ýа‡ý¢ô$UELõ¯W3±ŸSmÓä…œ+ê >NÓùò0jŒö­oQÓ.i-:˨w Ü|ó+'?tÿ7§ôÂ}‡ÿñÁûîÓÛ·Úð³®.6ü k€ó\}í5Œ¾¦÷Oê⫯î\Òcv¬µÛ ií’à~‡ÎBBt(ÀXÞ#¦úKO’Í«'làUw]‰ŽÒFÕ!Á¥ÿ ¸ä¢®¾f:rºeªŸéü–Re]˨X_gc†›NŽ©úu}·Ïÿt4%=¢Nw‚¶€[êÊúh6 £ŠàŽ[i ——”î2l%vOÊ®oÊ”G??¢?"ÇbбR¯ .ƈŸ¡[?§vx“œŒSËn¯/ÊÉóóX_LlèÅ+Ê9+%­z<³?ñTåCÍëšQè‡UÑ([9|ít‹ ­)•“èl°¤ž(չвƒv˜)¯iwá­ q™²§*o#oÓŒS¸á$ô¥/;•‚®td‡…ó­Ñý@3 ì…HÇ õ#†(KZhá+QáC ŽŸÎ?p2nõñ˜þÏŽB3Ï5oR¡q=¸YJs Ó…Ù”ª«uµ¼äkXW®9C\±á2D`o›3qjÀ¸6úñUÈT™ 3éòSTÒ@‚--Ⱥt9ʼnò²3†ÒDn\ $í®‚©B×éºËµŽ£ªÙ /Mè"Ú¿¿:xˉ³7Ý}÷£{ýúþcÇþ¤ý`‘OÇÏä!®´ŸÉ¦mÝFÍ=ÿüæ.\xèü~ðkW_}ýç/¾þÚäòõw~FŸÑ=eX¢(u°ôî0"¢ËÎÇ×H@Þ=Rt þÆPݱup7M)ïM„ô\êpÝék€FúLãĺ¾ºg k˜l ÖG…]õl‹Îo¢šÐ2€ú`ï±¢.ªPDƒAž½nôŒtŽv=užtèÊ€ñha:á Ï΂ê¥ceÝ™Ý÷ü¬GÑ"Z¹¨‡´ð¨Êæ‘úõÃгT€d À/ÂÑÈÌÆ^˜,qçiQáÛ°A¯?š ó“ÄŒ’ùgÓœåÑÁ<-enÉ”e†"H`l9»1÷r²S·J }lÒC£j=dÆñ¾΃¬8qYÞ€'£n 8N?ÉC€/z‚{ð ýYvÁù:r™ñ¡òs>4ɇA§*t“8Qùp„Éy‡Æ|tn%ã ¯ž½&çiYÛ&µÙoBíKˆ Åq\ \3\,%È×'à0ÀArpyA'l]¿@LÁì#}äNlZ\ŠüãPÒ7Æà#S†Hêš6%íV™Dè;œDàÛv犯<9pà–[¾>65õ{?ûÙ7’G¿ÿ50¼"ÞÿmÙÒ-¸têÔÝ«Wg~ëÉ'ýÒé—~þÚÙ³½=OáÃ6<²D:îrºr‡ÒÀ]–—yý+›]Ó†ÑÍБ(Ù ‰lÐGF(8G‡›}¥k¥Ã*ÕdžjtDTÁ¯èôæ´îåkz©› Iq0ø#¶r’EÕuGl–¨—Q5 Zy­&¦¶Õ˪¢騲ŽuÐD³t‚^Ç-±;y ¯‡¼ÜãÚ8Еȳ û$íGº0úg­^ÓK-Tp–:pl §}ÈC©Í¹Êp€ìøUcôíÈ`ÄCHO»ËaÐÌíß*ªÖ¦ƒ|…'þxÙðQ›UgÍ›¿Ä±cŽ ¨)C;HÐײZrÖ©œýÒ5 õ2rŒæi3K¼.u T_CÊ`ìŽ|´þÔu£@;8£“&¤\ð†gâ “€%´5p9$ø£<4¢ çS`¦•FÇ|Ipmm¶êè ”Áˆ––ôšßäe†8}]¿à³ˆó€C8¡1ÀëY…×$ÎhÀ¢nÏp ‡+,Páî+IõD{,JƒÅ^`»z˜KnS‹0x‹sä| Ò?yˆ3|GcTç“Ofï?~üÚá;îøîÍ÷ßÿµGýáÑ{ï}ƒªÚðþÕ@}m¼›°u%¿ø§§>2wþí/^ÕãzžîS3§; sóê4Ugƒ1£ƒµO5ÑKº)ú`åJ J[ïN)ËA0Nt6É…ÑKvªF*8äÍGuÚ™MépA:¦”ŠèÜe9„³vþ|Õ½tE{˜Ð9ÅG€Á$‹G±GáKˆ5íЫxÄBïä×Ó¼•P¨¦qÈŽ×ÍÑzꑃöèG÷ÉT¾™ÏL(—áQ§îF©Ü“¬´×t,«ˆ¡+> ÀHè‡ñ‚7G¯Å f#)Hlö“Q—°±ôÂè_mò XFZmöSÐ+ϨÞ%*ïѾl4ôÀUcÀ¨‹qº¯`œ,•»C Oh”Œ]d5A|мÄüÓ.· ŠÐ…_¸c”… 씘+ôð_%³܉pR4o#’'PŽˆÄM|‘¹æ ä…é2ËÙ¤§Þh¼8gÄÍ$.+å!9¸nWç=ýï §Ú8¢M}búSì«L@×׆~^ÐhÀ˜®ÅøVAܦ(•û²QXp2_׿ O— oÕFÂI}î˜×½ûî?Ù}üØ·Ürç#·êE{Üì(§v³‹¹uåûã?þã‘<øKWN¿òùs?xâóÚÄ÷k2Ž«šžó›ø´žï“ÈÞQ1²oUßø:ø?:Ž¥; ¥F±Ò00AÀˈù7 M¬4 ŽEŸ£^Û,ÑdçA‡žQ”ìMê:”ȵáåóªÎôe;Dž@F¯ýSò~®˜æy>–È£7º ÔŸ\ÊGïÇèßQ è8±åÞ6…=af´Ûš*1ïËñÌ´úøÚѱ2ø# æË&L²Ù©]1µ/ÓM4Èñ?€V® ®” cnq"tì-^D ºþuo¥8ȃƒçO`CŒ²¥*t>_f 2•cìÉòƒ—¼ÕVÓ)^Hj\x' gʲ)㟼ˆó§dÍË´£.äpž©úà Nâ%ÿЂàÀSœxð² ‰'×:!fæeE¡êÏΪ.iLûeýá 9¾°á§Žè¸^ ‡aI³`Bo´Ô4¡½ST‡n»í‰©ÃG¾yðŽß~úÊì÷¾ô¥/Õ¾!¼Û°y4gsóÈÓJ" h·þ.~?så­3¿zî‰Ç?wùÌ™[g´)κ >¯Í]èîÕÒp2r>nzÜ×-=›pJoP"”žÉäa€2ä36™}W"O‹ˆÎ„˜>V2Ït DU‚QD+ú2²kÓÓr.V#ê\°tžPÒ¦¥ôöét4`Ìæ9›/–0Κ®×‹Œ&¶i„zÊl#Õ’Qm8â8ÍssJظ‹|õßâ-£¯Ñ>¬qÇ,Ž€LºHSœ,O´Gûß ã ŽGþTªìИ†afôîŸqeÕvÎ4±Çu(M^¤ýò!rÀÊå´Á¿’:ð@F¨ÄCxôÊ^:¦Öà®ð (²†Q†>ð©€À£îÀ ˜t§ë~9"‡SâãPFHžYFÌÛÓG—eϱáX‡o”ïˆüÅQ¡§3¸ËËèŸ\ÍË]×ô·½ÍØ<ç<ÁpbS褀}GÅÛ)qR! W¨µ©^ˆþ6OhžóÍ#Õ”dö‡?Üw}zú—æÎ¼õëo?ùäç/½ñúá™éKq[Ëèðžñr¶èä¹Yçþ#KïÎÀiÝÀ.G‘ÂIÙe‘¥óË΃RòÑ!^ ©Bª4¾™`à0C")O×Eèjç7ÊéÎE&mq;ŠT‘½}í¢ëŸŸÖÀŪ§%€‘ꪽâ.9<@¬ãð®Uñºö`f´÷ÚœõÞjt—ÞËîw¸Iõhˆ¶`Ü2v§¬ŒßÃCuÒôí¹æ#À2OÃã€ÅKÔ‘#¼•©Ó æNódCT :¢íi”“Ôœƒ˜¾§32œ>ÿA¨öCÇ{lÜi¯`Þ ,N4ŽúÈ2ZÇ(x“PàZ1_Ä3ˆ Žbê oòà+©,£²ðˆ€¤ú£.Ãã*³üÊVÀ¼ü`¢`J\‡`9°žàž§ùEò‰§Ó—´)© Y“Nú§Ð¼K6 —YÛÑ> 7×,²-kóßêÜ¢vþ3_¡úŒp¥Ç{z Ð'™ ©W'<ê@×GÍKKÛví¬öÞ„ ë‡÷€/R®;ç!óÈšå\V-.1çT‹Î‡SDËT"§”,ÌÌ#êñÞÀ”éèë³\ ä¹ïã Ë+†XÞàYçU8°‰YeL¤ÿ‚³‰°¯%®é]|½ðä‰sGî½÷ÑGŽ|]›"¿{ä#¹¿6¼wð){ïªßÚ5/œ>}ìÊk¯}úÚ›o~ñü‹/}úÒ+/š»¢Ç¸Ôqôôè”oV©ÉÃw™¢7åéÔ¸éÃÀæMª®€3[nò\nLÝ9nTF'ÐñÁÜ¥!ðQ¾ð1ánê§Cu'‚À–¯l v‘0£›†¾t=8 J{d§¶¯]˜®ª «®Ö^Yóg€Ž„ÒÍQ1©'è´¥V·îl%›;Maäq?wæÒkü¨É#}ÚE¹ ¿Ï {–A¡Ò†)PÀÜ)“غ-å !;XhwÄc{Æ>Úg“áW;+²à±AÎ3|'zŠq¢÷ F[à†<£åMK‘‚åÎ'!i¨­*2oã¹XÔEYp žãJÅ'`Á7h(çÎ e¤£Ž(«ëQÝëž®Hš”|þÄ@ÿ¦×¹‡´ä(¼›14‰Çõç™ѯH¯+×çe°—tÉÐ+ýÁëìУ¥£z @¸°t}º.üçkB@ýcŠíh iÛî©j¯¾lɵÃ,Nà ¥š¤mÌš!/5_—\7Xs6ó)Ðrý+ã„Tp掶„5NÐPF€’À³+™„."¸¢'uðýSê Ê‚/Aቼ°°s ˜7 òäܾkW¥Ç §÷¼ùOöÜ|ó×÷ÜvÛwnýÈGÞHÞmüw§ÎUþ5pùÏþìØâÜÜg¦øÃ߸òÆ¿|áô+{¯ÏyT×Ó(¿çóD‡Êˆ/îFEJ q¹Ù¢w¶ôa¨‡ á¦5>g<î<È”tG£ØýÏÄ@Ø#Sêó­8Í8 ¨,±‡4Ñ=ÇèÑ–E]S [4Œ¥ƒbÞü¶ªéÿ¾8¢NߎSãxáõã…str84ì°V×mÓÏst]˜Æìãlä‹qEìRµ;*dŠu~Šå:л1ôWÚ¯’¼ÑÍ´Ë€cü#ÿ ©c Õí+Ý0 è£Ì‚@¤f(Xœ/Î5Á£wbþpÔ^œ Þ+ð0(¼<’ب4u ¿H Õò4œáS)†9p £(x*&xŠ€€>\Odíä ¿ ¤Ó˜C¥I†sF 8qÎ$ x–‰éÀ €Û(¡ÌŸÓ6ð9;È´Ç„á @‡Ç~¾ƒ±:/ /€ÆnDOô´=p'Ï_2¼÷}q}lpމëJ'ZpÜ Ža¡`¸`\[ú”(Â@ÓŽºÂsu“#pª,÷ˆq‘ApJ,“Àä#ÒÁ! Ì„¦¢<ê ”¤¤³f.÷ÛRGP†\ +Ï¿dâ>]ã;#JOlŸ¬ž89³ëà¡ïÞü±þÁãw|çÐýw¾ ÿ6üô5ÀYjÃOY‹gÏÞ|ý7>÷ö3Ï~aúÙg?}ñÌ›»—g¯ûS¶£<£ÏMt_r›ÙH”{Ãà{S>ßÜM§0oêÜ „«*}J ‹·`Î7È6&ƒ.ùg.Y¸ój\A)­¥4¾ù c N”€0è #pe dl×ô1¢fFôÅ?€žhŠ# >ŸêN’!­xtxk zëÒ•+¦3޲‘mú’¡Þ Ès„”‚~ y=O™zJꕦß‘ÒÂð³žK‡/ýzz™… 4¡2jÆx:ÀuMb ™r9¯:ÑJÅT³Ï;EcÌQû5¼¾ xÊô è<ío¸*àƒC\7Àíô«|8fkæ´' }áùº“`iÔÍÖò WpÎ YǦ/ü\†äÉ?LMâÅ9UyÑAÀC§Ð ”ÀÉãg>dEȦ2Å(¾¦OX¡ˆ¼”©HSF¡ùP0.ð:mó«%}aEß$Ðg¯zÕt5®Í{rDý±"½¸72|Pð ꙣ"KDž-R¼mŠ€£6ê:‰4Ã?<‚¤ðåçs÷«qáÍ Œ 9y_®Ê!ðf?PH› ÉëNPšsŽƒ 8ZJÊä.?(2&¸œTMO=d 4äášH¹ˆRð çp|b²ÚyðÀÂM÷ÞûýƒwÜþÈÔÍ7?zò£í× ­¼ŸÒaxfJlU¶zïíW^|ñ‹^<ýù³Ï<ýË×ξ=9mNw¼:žMWÇ`cï;J7 ÷ xžß7n%ñê4žÀ5]tÊ™¥¡ï07ŸÓƒ²& p#ù·°né$U±1eÈFùèäK¹zl(:J”Vo”|Õd‰`¡¯Y;ÚÐc@”ó˜_¬ýËè“F:ÁÝ!²€àýU±©¬ŸR9£cu€zÝìÈ.½Ç];?ɆnȹM‘ÄLÒá0AWJ…çQ™Î›;QÁUªt0 óOç†Ù‚ÜX’)ĆO|™Ÿ@ëì4/Ò[íŒðÑç,~H/ˆ2,¼Ôâ¢_õ,I`ÂÑ?¯öY% ¯ÈQi¹Ö<$XÓÀ‰à|Kp L’8me‰FEà@|×h<òÔ×3-pó ƒùÜà´X ›€Gð†3ËN)æö&|ƒ™óÊBkIðÀšøÈlâ\ƒfU·­-êËz Ò›ÿ¸ø×W•–žÛvT=œvꂉ¯"®‹¼^&÷ì­ö9¬y(ÕSÎ!× ¤ÜWÐ(Cl> X]8Âç6è ü€Cº0ªàQQ.ýù P•8Ö½”y˜)X–[¥ƒK”Eýq.‘}C_`îãĉj¸c†š6 &ñŒ‰®å5Ýï|æ{L/OšÚ¿opøÞ{¾·÷رoí¹ýöoÜùó?ÿdMÐ&þV4çøo…ÙVg2wúô}—_xásZ×ÿâ[O?ói½¯» Gˆ:2ø£LíËxøNÐ…ncï›2On­ì±Š"¹Ù¸¡éÀÀŠ› `ÐpSÇ Yò¼¶dP|þâ¶Ø ÃÿÂ(àÈSO!Väþ¼~Þ$O‘Ò wTD™ò¼ †·¾ ©=A^z úB‹[ó(#AéjõÒem¼ gýµ£X†ž5~fΣUàYŒ¾`îõÞûu}`†NFê×ìpdÜ·k‰Eò|>Ò6 5§Ã£7œ"ýy*‡Y÷>Uˆ6pñåèÒõ'2üÊÂiÐAø‹ÔtV„ô,/ÇñˆJ'VbK^|TùÈ%Ò c@8èÀùœ§Ý2”¦GeœŒ%`Œ ;5Þ®Øu¼"ú £B7?®$yŽàäÕeÃG<#)Ù¢ÛGFð !¦íÀ,›b€tá‹1Šöu¬ðlËB.ê0~ÊÛ( ŒÀquYÈÄk™ûK U_/Ôâ¤ô b–•:¡^.Ù.@ÏósMï OLø÷…P®Ñú:ѵ¶c¯€ÃGÊu‹6Â8¦§-\füp®¯+*QÞ×#eÊ»ã8¦ï•¸§ ®ÊÀƒm“6Óv%õ8ÀKm G1¨¸Ö]AÄЛ'KÄÖ…@q[| ú@L|sP½þ‘b© ¿¼Tê+Š»¨ÞzÛ_î¾éØ£ûïºãÑõÝïþ»/ùËqš ‹6úÉ5àsö““µ©™çŸÿ„Öó?套õÜË/òÚ[gª¥ëz1F ]íÞ÷Æ0!ÓùúnÈ«¿qsp¹Ç"Ä<#pøöáÆˆC)JãVI"Šk*¸fv#Iá2Œ áÆU„Å ‡É`vâT`”‚776ÁM+7/7…À‘Ë \tîÜ»LD¬à»ÿÞ–/_®V40ªÑŸôÅØûƒ@âÎŒ@l K+FtP>¬±otÍÞ‡­|ÇÄ[nÁ®Ñx¢¢Àù­cDN™âgÀN‚b·S`<ÊŽ:v•ñŒ·å-£=§M«©n‹%¸x›Ñr‡¯ç©^Ï0÷ÄׇtO 0Œ,m0Bö Ò<‡±&ÆHv8_äy¡ÓÊ€ ?b΄‹7°RîH× ž“ÖmwÁ¢v– Â’‡$dv•;_……üÃz…Žz’ÞùBŸ0tJ Ÿ2sõEì3dÝG~X§ó–¡0‘B:7E-¥]¡Ÿ¾Þv׿^žû×yÆáÀkÃùõùßQuôh)¡v€%‹¯bN¶Î¿kc¦HùŽ®‘ûä:dÁü$‹0¾P9G»J£àË•R8Ü! h8 ®Î4kž¢5ÁÍ_‡ý‡QŽ{ÅH¥ð{Y¢0ÊQhÉØÑW:Ë@'G¾ yÃ̰hY² 4N™ÜxÁ̼ø>AU¯%÷»vßtôŽ'O~kûÁ½ßÜÿ±¿sË-·0õ׆ŸPq^~B¢­Ž~åñÇ?uùÕ×5µÿÔ®œ9óáËož©Vôf¬®ví÷F5Õ¬a#£’º÷L…ù/W¹`ô-õ]çd”^Š d#¢ï”\ øðkÔG!†B^{ðòŤD|‹Ò`^¿Lè|HdÔ|!5OÁàbÕ€ `G‚€×RHíRщÂU Z%‹cîë@ç‰G ™]ÛupµëÐá7ÝÿÁGvŸ8ñÍɃ»åÃÖGDÚð×Ñ@Qï_uëâ N}{úò§æç¾ð¶ÞÆwíí³¸tæŒ>¢×Îò¸Ïè놧³Ì›Íz$_;¨k£ ä…È¡¾î#kpÞª)”…ˆ®GGÀ7TUŠUPî%§’J\%Èð¦Œ<4Áµ%O3AB¢è )e åMœs‰Âª‘àa‚„[øòî€Öé—®ÍÈ8_õ4"óÈ_–ŒJ=mòcªÀ_D*ИÊ'îûÓµztPŸ¯Åh#Ev´N±c»Ì¶– G›io"Œ~y•V†Q?å™QîѼ™-P¬:&Ï"”rkC4¡ˆAC#„p>°VÃPbxeÔm´Ñ¯ÑcîWËhc¼ãÕ%ý‰ÀŽ4Òc<-Àù6d€2ZžâPÄ&C½3Áíã¼éG³ îÿÇÞ»ýø–\÷}¿K_Ï}Ä™ápLš"u1#°õ‰–,;€%ÇAŒ ï~Iž¿$_ôç $ƒ€1 ËL+ 3‘ ‘#™”`’ÒŒDrfN÷éÓ}úôå÷Ëçó]µöoŸÃq’à!§º{W­[­ªZuݵkOô0U§ åCŸX6—ØM‰Ãõ3}Cy¼2JŽòõÏô€°ãpõÇA€®a=(¾Ù eèc<ÁqÑžä+]ˆcôâÛéÏOFœôÚ†0—þ¯=Þ–ç’•¤­ó}é©Ê^ïð=#ɉ.C/h²:¤`­ð€wà9!æ0±¡ñjª¢é׬_¸aáøò_;ÃÁ‰ß.¬@qb,>På˜HÜ\†¡¢(¸zéR—ô4ü#l¶&kÕYXˆ¾WÎÈþQujâ cÉ™D” £,¹"ÚWPe¦n 8+¬:H¾óèÑâcŸýÌ·ßøôgþÙ?óÙ_g@ð¿|ê/ÿåw”ô‘ûðèþpì1tûõ¯ž^_ÿ·¿üå¿ý§_ýý¿ñ?üß9ùηy.Eã@®¹È{¬0uzX÷¸™uÔã¸"KSM¸³\dùÅ-0…¬¿ø_` ÀÄû“_¶„¹ °À\ýͨEk£cg¢“?‚À*§Ô/xÐŒH%-ˆ<å:l‡^øŠG™j#¾i:žnð«ù‚uݲðìñI¾°o¸pÞ̽ç.§ºT._^tâ¶ð´;ãÚïoœê3Í÷mÌ`ìóâ±±“ß,ÊljÚndà úƒ› œ‰Ø¹¼+2)&,ÜÈjÀP|¨˜¶¢×ŽØf2ÂÕÙ°jƒ]„~±0§Ã$írëÏkvLs{cuöƒ<Ì ÞH s«=FÊjAhàe‘ƒé5¸¶(&YäãÁ‘Å¥ßHƒ¶}…G3©L´FJ›1^yÝG¸`è¤a\^~  ;¹¥ Trô¬@ãà*Jhô W~‡”Kâ,ôD/N{ó1Ë-ÿ3Ž´]¬9ôGåÔïñ?—b§eô\°`eèðzÑž,Oe›?üôמÈxðúë9O¡æP4Õ È=Ò>…Sñ*¿xôŠŽ½Æ%ªÜKF`fäà1åÒT,åß……J<䉆Sßão}"pÐídT4ð ½Â[¦výÌtí'˜¦d Æ-dQÉA„€ åê ½²¤Áe0@X¸  >¼{gñæg>ûþ£O¾ýo}îsÿø.§þÔ_ý«ßõ‘›å@òtþ±önÿìÏîž~ðÁ¿õÎoÿö¯~ç_~í—¾ýûÿ÷çžðA?‰éé_™éci±?tæ & +_ãÛ<›˜p×Ifè‰c‚Q1ÛðKtÅ ^’•T*pfÒU›C“†/º!W´.íM *Ðt}Iµ >y h9ÒF1d߈&É4ÐQ$ËF@ž4êòâæþ-{.NŸ,žó̓U¯0Â÷SÀyÀÁæíx]²Ž¾4ÒÛMíp ®rÐAw»ÀìÄxí耂ømSҌؘàOGNëâ_Î0;ýZ +Egg^U¤ØˆÉWB‰?½òËü/~3Ÿ ûc\rÆ;Û#r'™ä¡)Ò_·ÝlßnßÎÞA@Ñ“~y íM€Ê°ó5ötž¾vý-QøðW¹ !'0&J#¨îæ_:{ÒS±×WeÖ÷‚3¡8æÏÄz›ÿ¦Ž_8ˆ~ `Vä7“Ñ|Âõ{ש[`éQváÂ6ÿ‡k>Ó$Ôp¹zîïÎóvüo|mMnÓùçŽo ­Âã—}°fSo࣌K*¥›^º"ÉjxWïs>þkü,˜h&ê’Â:œûP²aêjT C+Ú‹÷Zâ7P Q*'­ÍÓôòè‚çÞá‘%3u?ѤǪÖ³ü -záT/ E0d!y¡Sby2hwÐÂy YS—üJGóCbžó»áUΛËçù ×_o|ô©?ÿøáŸ{û7Þþüçÿ)ÇyÿÏ?ÿwþÎ7v‚|}#ç~|3à;_ýê½½Íæßy÷7óW¿ýµ¯ýµï~ýêì}ž?ÓéûÝo7ò¥¶k—6–Uo:À°ãuyt4EW6Zv‹_î6ߨ|ð»<îjlZ6ÃsjùG%’ׂ«¨U¬|0a£Ÿ!<.haGnɃ4"&ÙŠý¦[ˆã‡¦a£N'l6qÈåFCZiu‚5çQWÙ4 |4Å·'.ÿ”O{`•9?Κòn tÃRÞa&2ßÙÞ²”k³®Ú>¡×™ç• :æLÚÉd[ð  o؈I¨nÐ@í2·{Þéc­úÈO¼†¹W'/<ìpk¾î´j3 ²:“ðšæ ÛÉô¯`ÉmŽtj  .:™]A0áxt–Zt%v " ^ƒd1¨ó€wôÚ p`“•™Þ‘%¿¾†/á‚ä™ü[¶“\ü ›‡8e8Hh~ïº~¸mã¼7ýNtUgpZvÕ•Aˆ™ü'(„C¾Vbçïæ²í󧬈 EfË^‰7­pgp¤«Ù)R_‘ã#退‹pÕÈå¤tþÙÅÛ„IIÚ±.ÃG¼ÚNžóF˜»?iõ ™ähW;œ"¤ÑþRXxd•|#žÀñËGÆT.U*×húëW´C¤…C¸I¾”k½$4<ã}X0XÍÏÈÐÒZ‡‚XÇ´­ÒWúA‡§B ±ÞÜðMËæèÎÝÅ×?öüíãçþùOüÌO}ñÍŸþéò©Ÿÿù¯+ñÇÑUîþ˜¥ü»ð÷7gg¿üÝßû½¿õÎW~÷?øÖ7>åLß@Övúö1'nnÜRQkäjãSÙוGšÎPlmÇ †%˜LS©À7“OØû•˜€¼ "àÓh×C£CL:þÄ1ÉSNº9ªaPÆäfaéD%Oðxí„x1,mf³aªÆ\’'}Ã9‚|ðälqñ.*nì#@:¼%Âܨd^ä|:Å=î¥Ë´» ì  F<4#•vpÎèm¨{µÏýû”wvö§ƒ¡¢vÿ³™<°zÞ_ü5«à’|Xû@ öÀÔ!Ý8D‰»ÓF;겦4V5*-õb7àóŒÝéX:|Hõ/ äçß7j|}fþvüâ„ÃA¯ª.äZ~ëÀŽk“ÇäSò¢Wq”½Vƨ ;@<øºó7ÑE_qT<Õ¿OÁ»so¾àFÞ4N±&Ž ÔŸ°ÿ 5.q¤žGAwñ´ìÈ‚ú†sùoìüY5Ú^sè«ÿÛù±"q`}·‡<``dJÊóx2™b&û¬?"ÿ—Í„FuÚ„Ç` ᤠéHfŒ@äªhcRŸ1#¬îâœU{bºR¾ ‡%ÏúG0ƒiÕ©”¬¢m^iò#¥"\¼yÌ¥"Ú¢xUF6ĵ®7ìåq¯ÿ†SÿVlBð+”Û•›G=þ×Á2x³Ç¥ÿí £òlé9´ ¯¸Êy–|#¾::Z;Ûót;µaÀyø5Àæ´R2²/‹Qka†´•ÝŽxíñš”¢)X×sÓª‘9ÒÛ<¼tò䦞ñlOè¸:ÀTD3Ñ[”‹ÿCi†Œ&@@Ùm ˜Ë(æB)5T!,¤B1QX§ý-C™ü4ÍÚ`EŒnHÁðú)ãã#io.þä§¿ôñŸú™/~ìs?ûOö~áK¦íGÙMyþ£˜È§¿û»ï[ßúÅ“wÞù•w¾üå¿É+{žðyÞÓã9Ï9È%Æ`#93­²JM {ÖBm¡ª\–×Î Šë¬FÝÁõÖ¤6Bí –˜4Ý¥kž¦xQõƒ¼Qe¾°ªÍ Èê$qá•ULpH§1Ð-VòD§WþQ]Oaª‘Ê @ÓQQmLä1îºÏf .œ³°téætöt`2ëçî#_ Ì@d­0£³aíM€¦Á’–ÌfñÙèçoV¬®ìùÙ>pnâJëfîìfçuí–ç <ÄÄÏ…«"ªÁ1µ¦T.vn`h„º#©Ž½gûâIF¸ì°ëu@dî¬äNW(?~éÓ5:Ó'Ìh»óweà†r1/µ_úü¡O ÔN9 Jžj;(žV¤§ƒ$©„LOí¶¯øà™n;hõ‘ +èI4´Ò Nú¶ ;ÓêP‹FÙ‘?hk 1Ò%-ñˆ×)³êÓ> ·3^¿y·3ÿ —–tìÉCö´ &n™ÎúC´¼Y’ÕЫãû<:r€¤6eoüDàÛá:ÙÅŠÀÿ™¯áÑÛ¼|9Ê:üú“»`´ e“ŽXtÁ‚5^úi JSRôïxÊ‘á“FWWîð¦šDFÑ5ÎÐË8aÁs‘÷…°å€%Þ\3}Ü1D†ôº ){ì6.YØÇ}~3¿‚b+¼–ÓfòXÆM*4l®å5bíÑþ<|‹O¿ýöï¼ùùŸûõGŸùÌ?ÿK¿ô¿ 1?R·Î›™DñLÿ­‹?ùæ/>þ£oüíw÷«¿ôÞ7¾ñÚÓ““4d+Þß]R!»RÅGlÓúh,±¾éó‰åZU4ßëÌ£îÑ%¦Cuÿ…¬VŒxtÕÀŒ@Â9Xÿ•%TâáçÅÚ¶C…úÃ/Í^ñîÄ)»*mÁæQýkyFÕÌd ¸|/ÿDIß„K®¦Ô€é[d´¿?;ÿ<€©O…ܲgà†Æ€Ùd#IÇÎ= ôh!²AO,m{oÖ³£Ûc`ûðyoVìð•Cžvçn’Á€#\¿B§H£“&ynS[V•Æ3™H'I¤ÉŒŽLö8ßXéÊlàg™ZOz9a4Rµ+#tRÕó3Ò]íõ(`Ü!ïÿžN¼y‡vÞˆnÚ¾ùâ¦IÊØ‰P« ”qÞ-?ï “Fñ@hÀg ½.ò˹ C÷"Pi~n¦)PýÁVÞ 3ÏõÛÈo®ùÐ'Gƾ)„KHDì@Ö‹?0ö”F4­ü ŒS¼e_Ù? ¨M䙃JŸÿ?äUÀ-qÇžÄ#¸mK;qmA§E0qåŸb MËW?èðX't%SŸ2šÆpû…¢G®#bòºÄ”®ø[ŽäB:W3‚®¤U\E!¥ S× &ë‚“¦\Å¢Ýu|À¿ÂíDÍÅÆ¯®…æŠþ»zÕÒ!z—'ˆÄD¸÷%%S怛¯n]±ÒSü¹OüÞÛñ/þ“£O|â‹ÿè·~ëýµ‘S§rI޼¢—,ïó›¿ü§_ùê¯~çþð¯}÷¾þú³36õP|õ…=k!©N]l…5*ŠgÒOÓæ†8\y‡áNã7âtƒ4ƼÁ9ÈðRX %xǾ!$þÁ#mƒ4´,”††™b0˜Î¨%sùVе:°ë<™ _rp{8M(]¿íº=ÎàÌïýjö² /0ìÂÓþ|DàÆÏ½ Æ0š h3¡§a·“—ß¾éèA‚HÏdÝ@˜w°@†h‚f–ºØÑšÞ˜ eÄO´wføúTG5üâÌÅtdÐkÏùz ´£Ó¿%¯ä©G %7göC«yÈ›Ç,úSHÊ,¸>õUtd+_¥]a`oHK>“,.Ëä±»JSÉ€œYQ¡¬‹ðàÆ½ýÒuß2ä0t™ñ›øƒ'Î<‡N \ðæ®|RéƒG¸³z:`—Ý8£g‡øvK¯nùå…žù_­‘O ÌÝ–XyŽ×·øøÓ»Z0ð5À­xpÈ6Ò…ì “ƒ€ûY²´üˆã€ȖΟ¼Ôôüi%ΊÍFñ†M…Y_x€ÏÃÒ8@õ^nw3‡+m„G¼5P(ŽŽO\Ù´‰L‘6Ob7Á[Ï’»Ëé Gi[/Œ]þ¸ØËÜñï% Ü¥Ñ"[ŸIauöŽÌŽÃ<³~™§Ú‹áD LÓ§“FR172 ÂI?÷œËÁ«ÈnàTÞ½×9ÓáSþÞþKé|øÖ›_øü¯üÊÿa¯èedÅ«§ýor8ϧ‹_þÖ¿øÿþ·ÿå×þÝ?ûÚ×>ñŒY£¯8í³‘Ïgoé[ Çi(Êœ„˜ô³ä'ëà—sFÒ F ¬a ²¸$¾ï%Üæ2#Pd Äd‘ƒEáƒ.úÆ?hc± /ËœþÅ@E=ÃÏÙFlÓMÜËøÿ¯°O¦”ÁŒ?ðnš4ÐÀ2€iµvðlqúî»œÊÆ{ý”aíøG³ôÏ=~:<»i»tÀ«\Jr ûXiUÄ€'4¦Â³îŸçû´é¸m! Ëò ùŸÎŽÎ}û®ìø<ó×V¤ónCoie žÆŸ´Óþã¸ðo§ž†ÕÄEºÌÇÊK®†s㙳{06XÙüâìè³ÀýÆNÎðcœùãn‡¨lÊ©ÁD„„¦hÅÙø+ êŠßòºÅÆŒyè¹8Êeq‰ƒ{Ø öà¼XÞý3Üø—é¥Ö¿„‚^¶W):ni4}ïƒpÓgù¨¿éÏ ˆYÿíKùhé€ Ü®ìÈMƒ—Â{ÿ‚|æO¦±-¹e+#îð˜ïÄÚ»6”z;òD=¦ÏG3xÄ!@^{Ç îPC³É ÜD¥„ذé¨\ÕD´MÃ8ôˆ_¹RGÆ/”¡åúa¿°âöšÜ+ ˆ ¥í/_qwb2" ´â-ŠÒµdEàÑ$•Pcƒy≠Âã¹%ê…ëPOi;ÞA1ébØ€4ÃJlGÒxiH àØvBài]-Gm&«†Öi’¸bºå±Ñ-+¾>ì7ÞúÜ_øÍ7?÷¹Hü‡ÿößû{ߌÈWèBª^-÷õ_ÿõßú¿~ëûÎß}ÿßü9_s÷þÁñq …2ÓüÏÏÔ¥G¸ýÂS® ÖYñbH!‘)NžI`A^„fβùå%/_Ð[\3ÅõÎyB3ä7™zªC‡?DL8ær†ˆx&þöŒÈ¦ô½ý[Ó°¼„o˜ü¶¯VDÏâ¯05ô+Vž_>[<~ç]ÞÍf¢Ìö¹w§¯Xª7,>;Ë j$gáßÙ*!Nq¥Ñc963=ÂòÈ ;µÁÇlõñdÖ“Þ³¾=V Ö¬¸_$+TütüЧ½…a› Ã,V²‹ÖFY­„tXŒyFë•+™á×üL·æQm¤ƒgç?îY1 c飳 P¬<þäOØ;qÉtDZðÒÏÖ…ïååpžRœPI˜f†\äC/y“È’!ÞßH»r•DqËpãC Šœ[:k<žú‡LLáÌ`Àý%Ž4Ùà×<Õ(%H¼áB>ô†Ðܵd¾öÖ[‹‡œRÇöód…Ùjz¼Ç?`SçK‚¤ÓZ¤Ó6Æo8°!'V•0Hx£VË„& zf2"’Ì‹ O<Ú¯õ#.Ê©€ñÌ]ä@l\Y¾y8ÑNØöHµãiè¿þþÿ‡¶i´‹¤€°¤‚‹éÓ‰o‡¥Rk›‚0H7$Œ`V“]³?éÜóJü^Éññù¿ùþÿí¿÷þÁ>˜^‰›£WÆ=þýßÿÉÿá?þOþÙoÿóÿý3Û}vm~âõÅ]Faw8èÁçžkGè)UÍÖö¿LXp—§EiZ’¢€Ï«l¹h ,2¤ ±·Á¨ÁψÀOàƒxˆ‘br;‰C&€†5}Âhz&'Œpë j€&’&ß\NÒÔ2KÌà"- Ä„fÀßÐ)^[l\ÇgýŒ((]u„6äÕÄ÷’°õÑNP¨—²ÝÐE–_ÁÚ9Z«W<"pã†@;nÈO'V³üRÏŽ0ïù92m`}‰P•l}n¾¥á·S]pE@+É0Äctk£^Ú™WEiS¾Þ©?>Ó©m6^fyõg 6³´‚¹<’äÁ8]îæ²vmò3>`ÊTV‰ô¿éôPó]\f¶Þ#E¤ó y”™0q'ì…öfin Äµ3krÞΑ–rËàHE»Qf2˪KœzÀ[hÆÝp`\âq7Mp`È®Â7¿™!oç+y`9g57Ìê7è¾õy‘¦<´dYCÇÎH+<[[ÂU=÷8Xô9ˆ-4:“ÝÏ‘^ÈX; ÍxjÙºÊZùѹ-‘€rz‡ˆô× `© <úGX¡Y è°Ü’ðË ?‘’ÎÎ#ÐÚ¨à°t†$T8‘Æí 0+eÐHkÒBÎ]~ºÉ?É*xÅ0âiÐKw¬&²£Ë÷=â‰NC*þŽ_OGÝ0ÙÛ™÷F’­´0„n¨¶2ç+?ÀTÒnŒ+KT¶ñyvÄÓó‹Åé“ÓÅÙéo,],.®/îþÎW~ç?ûÇÿÕýôWþþú_Æú[ÚÓz-‡‚óÙ³ÿîK_øG¿àÜïî^ž>_œŸ.ÎÏÏW¼Öc19€·ôküZù·HcP…¸—Ðd\‡Á$$¶ bx•7@áíðK¤s¶ˆŠñE—ïÁ‹jÊ4<‹z›ƒмòµ{ f0ž9j²ùæxë_£¼›­s%ÌÛtä<á#GbFùrm™ÌÜ}V{þôœö·–Mm>eª}6P%ËJmYoF¤žp·dúV0ÇÓùÛ8{°Ï†»Q„4qaÇ "Ô©xs ½:š®,ÉXš—Ãå ^¨Â f饲ñNùRš§IGwBü«Žë¦ÇÍ0W}õGkå»ü.Í»çacÇ”%äbu’_—™<^Óg{fœ…×aâ2a⚎»-¾:lR—ˆ ùµXMü0ç{ÐÅCÉr ´aÕuÇ,>ùl¼÷ünœ8oâÛ 1̰é+¸„–}¸Ðƒd‰Ÿƒ¼’GW €™¿[zù%oÿX˜0ÝŽÆÂ½ý5a3‹·R~ʼÁF2Mâ Ò-óöP롟ýÔ/`.óý€£c-Xvè[š[Þõ3Ü~¼…W¤þqï•Â¥OFŒ°R3 0,w3]¿Áö&“c–…‘s¹™B0Ý##‰ÞwIð'N¼aiÜ€§ªYIËIF„h4ÃÍÉMáŽX=bg×3š˜ºá€'O $ˆ¶ŽGNÍ# ýÛ]œ_.>à#eïò‘²oçÏ'ï}wqÅ ¥çHhV§è|ùþ{?ù¼ûîS±üð_cÚ?üj–†«o~ã/|’BfÁ?'¾?gSÎs åÂÑØûOg÷Gwï/Žîß[ܹw‡Bá0}  õõ, 7Ζä-pÉbA»ð 0 o4˜†KVUùºqŠØŽGñ{I‘ÎLµ¢j¾&%Üz† ñE½`ã½G‘‚ÌÅŠªß_ã!Ð0Yôžá¤‘v"pÃq£á‡ üÚñ iË!,] ÒFƒ¤ÓjÃn#œÎPf\Ç-ÌM}fÌIålØÙW–ÉDd%À6òñØ:ËÚfízVl­ÎÔB\¥ÓÇ ¬)ÿé0Xß2ܰ`Ãîc Gœî’wÉWˆ5rä‘Uq[é€qŒ¿ÊûJ¿°Þ]–ù3«w–œÎ£žï§.8ûªÌn gȃTåÖ¯óÍv4’–¿tăOœ‰Ë&A`ÝI ŸÂH—›å6¤;q98c5 Òhø²iÓe“t6ÈÊ;4Çæ‡éFþ&£ #ê()‹Î¸âMæ•tk{Bu_<¤%¼¤*yÀˆ»6°å½þ-oƒ,ëC>2ú–Ï–CŸb0E"1gý#ˆY¾ü/?ó÷í’Âég“ ÔIÚõ@ǰåiç¯ýFÿ&Ti0™þÄ÷][éN^xÉ)Ã:ir÷’xæxm¿Â¡ ÞÜ/¾²3üÀ-šyJ,´ò„C %+¤À~Ã:î±ëQn!˜áÔ'øAÛ7ã‘67/þ1Àñ¤Ê€Þn§P†ý…ÆÈv €Pxìô7•kÖ1>ÅÛO™ˆœr0ÙÙùãÅ³Ó èØàãAЬ1¾¤]9æäñøúÐ+ä^©ÀÛG/¶‹ãÅSï“Ù<ý_\Ð|ߥ8¯8æâ1K1Ÿ,ÎOÜ]ßc pÿ£ï£<Ç­‚Õb0óa™½‹Q`"e„&ëÀ+¸ǫ¨eu´˜R ¬îŒMæ,­… «Q]x†qL%T”ñC¢ÞoØŒ‘3HKVˆ_”™ÊFd:ÊÒxJbÅN ;Ífjl4b SK ­„¡gäH[¯¥Õ“†Â«u¾C¢0•‰Ç´¨.éä ²±“S­ÊÃòK3úf<°fúÉ.~è³l}ëúíAžçã‰Þ¾ïÛªçwÞ#:6§ì‘ÇÝÎÆ¥sælìSq¸ììò–)òšYáŠM ÙñmçÈ£O’ì7ŒÝ ÑTÄæœMd‰™y^oÃ'ŒŸéö ó(i£Â¬ÃôTgO~ŽA€ýT—ˆl–†]rø”7j "lšRbÉZËż,r¯âòö˜çýÐ.Qþ6_¾Eºq§#¯£~Év_MÐs|$ËÁÑr¹OÞ"ú˜ƒ$ÄÕžãu4¦‹^ÜDB¡žüç§þºÖ=pDÀòlß Äf®ÙÙo™ø¿üž3p×>o˜“•žê®1±ìŸ‚(éd/<ÉÓ<óg•`œè¦Ç ƒŸÿF™ ôÔNÖvú@÷³H•$q×ê “R8Y[hYÓùëhÞåm‚ oºÜ¥Îð 8–mìu BL¸ÄÑÀÒ‡·bêØNò[&Iþ˜Jî\ª³g¥5T ÊIên„‹Rê}Ò[ÆE¸Š)§EH¹Ó-ž9IÄîÈʧòS¼Ä"QG›‡¿lŽºD~Éóý³³'‹“ú“‹s¾éGÆxÌL,9,JÖ[& ›%Î9Dè>gÉDôøÁ£s_÷J –››Ë×G‹×/Þ ÒŸ\.>X<_œRæú =Uuñüùåâò»‹3Ž÷=»ÌŠÀƒÅñÇ츳ØgSNÞbU'sÅ¢5îa[b$W­CÍm,á ¸°(#¶Æ½˜•¤,¨¹EêÌ…X™l¨Ë£NRuXpIP¤(±s˜p¡‘­Ô gëÙø¹«I@V’Ââ$añ$¶êuTGãIƒ5½®i–Ɇ£+’aYš?Áâ&8$%WÝ”™ú3‘ÄO³Òâ¹ý‡äÔ×›<4Õµ4ŽÒt;tVÊqã—‘OðködàvþÎÙÏ—ÝdXƒùÄ™¯ÈnÜnã²ót.¸¢¡H‡nï`›yWVK(Œ‚†¿6ƒ9ˆÁ<妃YZtæ™|GGä8Û¯AŒùX0óгBFT•ãÏ,áÙ7m³À„KkŒøÁY®áõÊ¿ƒœ…Ë댵3S6Ïc@1©6>»Þ[r‰Ý•ά7¤7¯Â-íH©_Ê ƒŽMðJ]6Þ^)tÅ„ÁSuŒÀFÔæH¥«ôTÇ4Òèá#3”‘·ßûß>¿úG5óÇÇúê½tç'¹$½ê꺡ã+ÓËÀfÃ'ƒGOÓ3_,(À al„DaY Ò›|œÕ U±)#.þÅž¡³}Ñ>W[m”Kн34•Ö¥ê0AÉavaÁaÝ…M´ 74Qp–L[ÌÝ‹øá´É Ì<\¥áÁSú ˆŒV˜qgÄW÷ '_"£ä[·Z\ò´Ä ¡C†”J$4¿wAIB0ÍQL ÷â-é5ˆ\ nìÛºb¶qÎÛG<Û?õ[$gعŸË^Òo˜´ t}œÈl ¯-Žéø× Ý3tA|ûîB~eÜ«5¸{|iÓaã{|°·8¦3ÿØíáâ Ÿñ|¼9X<¦i~J F3Í;\yüìlquvγ™Ç‹' Žï?bUàîâˆQÛW•CcágÏ2ŒÇŽÂú¨5w'–ú9ÌÕ ’ªËŠM¥Ð‡MƬˆeA˜šQH h/%_÷^D¬»Q6&*(³<6nV¤Ác\:‚ÃG`4ȲEz zi4ï‰vxlìJ¦­~ÇC •‰·ÂCÆP£äOƒ2cKL Ù54fe[YE£Y½ub-»%hmWNwF–Úð{–}Íš¯Á¹°šSL2Ù(ûE?Û|ã‘?Ä9ÃÄWtA7à†óã9„ûðœúš²ñGyp®.UJf•ñ!G\¤Âog©|B3Q‰Ê!@…mçë¯JB~a½J"\¿µÓBÙ¼ä‘4)Mîöq)ýسšhEAnGNþ-wɱÚagïCqŸ‹/¶µ¥÷¬÷L'ƒeùL]¾güÖ Ë].%VWeìÒ+ŸyïÞ|Hº¸óßñGï\"/úûæ9íë$ò:)v‰Íü./x–¦hÊ'‘©# ÈŒ/©R_$Ecøšƒ™á¹n•Œäm]âc”“ º;Úp!âJÚ’u_Ф|¹ëµ$-ØxLJ‘8Ю û‡¨°–­ hŠ¢ù^ Ë£“¾]Ú˜!3r¸O;4BlÅ)¬y›F½bÄèm±”Ž¥‰ôVµi` `r%×`É´\†tEj±#,T=ˆ"v\T^ÍÔ Yöq ˜ºd \®%c ž°ƒiw#ËßH{…äÄœíóêðÎ9u?ÙÓ'‹«‹:NÜîÀ¯†Jw{‰Ý¸²Ç· x Ô7A|ö »Pû*¶^_(ùUq¯Ô`ïÎÝsGң͠\hz¨à¯ß?Z<Ú-Þb¹÷„×À> æ>޽¿´ 9¾ƒ%VXÆ9ÿ|q~ï`qȪÀ‡÷‡¬ R˜‘Éh/36ŒÍvAs슆©Bš•6Ó”ºB k|aÚxC«0­“{qD@‰i±ry«"Ô•8†áñ.\äsÔIW°!<¡TÀð$ê–-.áªqÁ© g;ñÆ`ã=åHy -¼D–UI¯4Uú;Æ`R9‘O@ö4bt>V»=g‹À‚Sròßô »ÿ˯ҡ³qpœiè3 @¨êØ8¨·'ú‰—O]Ò)#b†‘’GúÕÇN¨RGXÆ ÒY·K¶{´òWÜ«èh8ÒÖ’Õx*­ìK=â¸é3‡@ämüqI#Ã=+°Ë&.Ýšp`™-ãl9ÑJ‹Ð4ÈcéìÛ3Óai´ ƒò×üÎŒsq™ÝKäÌ~T"áé³ËšpùÐ_"í˜uçæ\5à<ŸgúÍD>ƒ„lØ#Ƕ Ö’®±×`»®eV¨‹sd°Ÿ'ib3Ý–w±·Ž@øD7ëõP°òpKüw€ñA(ßZØÚÙ¯ØÂ±/ýiH>ó·ðyC@uýð”q×ÇÐÑÎßgþû®f˜'”¦¶”7àS®2q¦4Ù§QÕ¥ÁðÀÒi`gaÑÖàp¹Û„e¡*–¯˜¶§Ôhŵ\¢#Aq}]4™Ñ$3‹Â«{[¯á*i|ê2ýP@î¾Vk–‰VWýqøÛÛkÛ ð¢S1¥·8í¦øÕ1™M²Ñtè¸)?°x ¦z;,­6 ¯ €s©ŽZÒ^Ý{Ê#ONçù¾yN„öýl ¥m`KžÈqòãÞƒ}ÆÌö™xfR¡^®H)Ul›\]¦ÂôÀ þA¸õýûd.9οƠëBvVwŸwvïQPo0;xrqÃ>,Yà*¶Ñ@38cû ¿ç/Ö|êØ}ltUÀw¾SѬøsƒ×8S‘ôXð)ùÒÇP YvÛUŒ­W¬·t.ú‘Ž4¸Ò4•jH+Kµ2Ñz!šA¾ƒ¼küEì* 6ª_×lhéÚ-™6R&%®Ó`‚l'’Ьì Wúª¦²’Ÿ6¶„CâzÃå½ ®n>9ö÷Ü™ð4Œ0 3]ÂŒ6°¬ò’—ÞmÔ”ºrZHk»¡QÏŒ¨ñ•³x[Ý}êA˜t>:°ø\)ð¬8R†éN6p`ê©xÆag¬~v²>0w7 Y¶ê¦<ù³a‘; ¸:Çä 4…7õ'§e÷5·U–.ä²#·[ìº!Âmd@çÝÎ8l(‘G–‡J ¿²<ñù9\gùN¯·7tÊvþD¸eÜœ°üK1ceúQ4õdÍLê‚0jÆé¨áuæ}$#«ψ¾c˜xé˜Ýy¿ ¬Ž›s§õêŒþ|ËîþlÖ«ç@ ;ç"S·Ï‘­žˆ´¬t[ŸçÄxÄt:Þó(34¾çï†bç¿F¦Ÿ–&^wüçÄPÞJqç¨i,MÕvæ$\ÑÆ´ÓØœv!^cÅ©IKù›2;ña•fàT'ö ¿¸é^gy90Í1ºDNI›x†ô•nF•¸+½F^ò½ÔÓxü¥þ^‰ ¤Å‡kžB,¬Õµyežk‡h‡(Ÿ´òyÏ*Þ„¤×V›Œ{ë(È8ó§†f\å¡yº¸òÙ>ûXœLìѹ»´uë TÃf°¸æÔÇC¾é1á=¨(ãId‰¡.6‹£{÷>ÌråûêÝ»ç\{Óèu­Fg°2±4sôp½xYÁÅÕíâv?¦Iù™3ßž82 k¯ño£.C"pžd:+ý`‰á†78/êÌ ÖÈÅM – &¿Ú°„_àÞcô%¦ë£XQ [A²É-P.5“×@UÒuøEo‡¦xC(SÑv©CDÔço’O q ˜ðàGzG0i¦¡wÜ3kß»·3³Âæ¹8¼#J*8~Ðu'»bEȯ²çÃÖN‚̬å{ƒT|ÀvÌâlØÜ Žù–¯ªÍ=eÁ Èɨ~!>—v9$ ^{£Ìª†uµwI8Ï WѺTX›H0?c…¹éH@š'NE H#mÁ oÓ.ŸÀÌîe4ÈMŸÅ—8.\ðI½ñÒ!¦c¬æÕÞ²vöóì?ËÿJÇ@!§nX¢_ñüŽÙü·óß, [pW”§™L¬éÆVˆ‡zjæ¸Ù.)H篎ð c™3ü+®Å!5ØÙ¿qPpÛ5ë54À5ÐF¨;¾êg:©ò™Å{¾{ì‚…¾a€à³B•dBwþ„Í4÷7¸¢@´[N¬:.š›Úš~Èñs®yÀ+¨’F srR‡,eœ¿€A¢ŒââØ.Þ¹ëCuÊ%+öšÄ–0íµd!xâô¢CYsÙö²".û/†"V@ÿ F.þV`HaAÿ=4 ÄÎi:<˜J‹IÂÔ<}/ªÒEÅJ®6ïž ÜS×r‘úwË!O=Y”çúOÙØ÷ìüŒwùë» ë=6ïa;¾æ'Ý‚AÀúà.«û<"fæ­&VÚ jç+Ú”µÑGPd yt÷îGóåáV÷&s­šsv¥áP”Ca¸Ú£óxt¼ZÜç™á[Ì,ž«0 ¸¿8f™Ñz¬ÆóÈɈ,±zÁà5=:ÀB‰J·ò á« Z2ÓÀca•žAi<‰«ôÀA X3éü%%j7x Ní@㸛‡CÄ:ãOûIÃhÅ“0(/þFz»-H+‚B꺹à†n‡ÝØúÁkZ`;N;ÜÌÃ"ŸXó;^¼Æ^sö œÐ¸iðŒV‚½Ä Ö„øŒ Ñåìø€ !¬ìçUBWŽ9W€Ì0;)[E¦1€©vQÄñ¤£W39(=qjêÿpeÄ#0äÄœ­`„mp’êò@(‘‰úãHc ¸]†ÊYS"o  O2†Ø!º9ŠpÄ rçaÀÔuxg+<úí E%õH††JÀ`18U Pˆnʬ [ÿ”Jo`¸ÄÑQ6ÐûŒFE¬@“éQ 3\½:Õ›HvééF¦”ß µ1JCÁ= 'ÌÎøÍGÚmJd¹¸¤ñ÷U<T9ûç$0mŠmŸ#Óö§ô©ü9²Tõï\²dL !,jh³",Ïóã—×XŠ©‘uCdnK¿ =pÉl¨L_;½þÒ€SaÓa{UƒÄL¤9/ñpy.Ýš?ҙΖEY wâJ»™æ-^.-ð« ò•¾ÐУ‡®åÊ—Î_4§ÕÏnv¿Ù?J+Ìr!G º¢ƒ¼‘†0lÛ¥3p_nœóMËþ›0½cõK#bƒß!‘ëÎ}8§<òˆƒçö+ÚNw»çà‚ßspÌâÝÈo§œƒ;*÷˜IÑŽg¸d6 ><Ò:ipÃ_:àÚ ïq»‰ÐÄdàä—þ±-=YTx£³—€BÕ™O&‹júŸ¼pç{‘à ¡»û‹}7 >älö °ó3 Ñ,¡JmÀòð;C›,gœj¤ ª à?¸„%Ôøv ¥i‹tó Yi˜¾D®’Ž…H„)”xìHBÌÆ¬+A5hÊa$ð'©rpÝ™$`õŸ`Ò3GŒRýv®ü;ˆ>éŠjhÌ2®†Ó2;UE«–Rœigc;¿ép,3Wg†®ÖÐêfžøL«KŦÑxLs© …–|Ë.Kû0ØÕåó·Ümxì¢4æ¥e ^–Ÿp¼¹†Vƒ\”ß©M—Öˆ"*ø‹.‘Reb¾ —/_ü-© Ó!* ×q¹Š “'f:øäÔj }‘M§]¯÷Ñ™Ûùû0Ÿý4i#ÇîU &cž¿²áoË~*í~Ëd~‘Îºç¬ ЧfõÀÎßœÉêñúÌ_¡ ”憿䌇ø8xc5ίô¹F¿=ôNx<ó'aü療Â)Ks„ÁDÎf@³9_õsÅÂWý2¬tæçäÞ"MÛ•ƒô4lmÙ n>#œu¸ö&8 _²PMKïÚÈɲ?Ñ?;wœe[Ú”ÀÌ{Ó©_§F sÕÎôiî-hc6ü€©nœÀ“ pÂJUtá6ãIý¥¡JOô¨ˆ1ãˆÌ¡cŒ™%¶nøÃé…3\$uMºõ‚ˆ™a wi!SȈ?ò” ÚE<Ã`ýÜ3^á³Ó?=õ>vò³ÉÛ40Æ„žÕ*V†2Û§(—Ìö}®ïŒÍÒ`ög8ø¦r»ôŠ«è÷8Aꯎåㆂ~)ôÎ]W©_g›öʸå'?q“ô|og±îQBUT.­Ë@¾¢¨†.~.ÂóšwȲþáƒÃÅCŽ={ƒsN=W€Ù ;\Ldöé^gW<`†rÅ·NÀë„;ü€ß=–‘XÒÜg¯@-K´Zþ³¬ ¿½„3ÜvYPßh3 è.[¹".Šj:5M±»W\†Ã¾`,DêÏ®¡(Ž [·ìtý™_;™ÆÛ‘bªi(|Ä*7’œrèçòêoÕ5_¥¬âëÊ$Ì¢3KBÏÝŽÚ¦<ú8à; µ~Nŵc–G¼¥vÁ§ ѹÛy­lĥ¿¦)¯Óì ËÀÃÆ. ‡qØðE;rWǯ”¦/Q•ÒT¸–‰ ùêç2¼3n»>r™±fÁÚ 8 §;ö—{tÌ”¦Ž‡àÝ8çÉ€L¬Kežù ÅMl¼ÊgmX}—ÀR8ÂÙ3™íô¹ù ƒ:;îtÔö°î+€AÞ,ù<²ØŸ­<~ú7m{Z9-Ûeÿ°Õ…C~Ìðäºl÷|ñ¬G†r0˜ì-;“L[4þ{؉–¢]d€Ahi> Ð64ŽÈÇ+~sãU ýÊ+}’›„,SeqÌ¢ÌCfJ]c,ÆPH\«!}ÈT¤Â#)|'Ä<žÜ (´ÀÍýó|†¿l±òA™s¹øG°mÒ{ý¸0^ðWÌöϱ—ží?áˆÞçÌø¥³Cßcó¶¸aó÷›û°¥½}VmyèïÆ¾|Î[…i?²¸#þÀ͈¡GûÍ]§s*iÝ[òÙÑý»§sÚvÿ+5¸úÒ—Î÷Þ~°Ø¼ë[þ8JÂF;•œžÂŠ”Aœe©!K ÄâeÒXªÓÀŸÒB¥·s¹ÇsÆ;ÊOЀ=½d0À§D}ƒÀMƒ—pqü>6˜ðlÉß9G_ðx`ß ƒ Ž|ƒ€gˆý©YuŒ«¨SY2ãhc\ŠZ1ÕQuƒ·¯çÐêjšÔ^x\nÐ5[Aû*6B ÂiŒ€wƒ+ÒFÆ^='?GD«¥+Z¯ÕUu˜dF±Š¯h” W·ƒ«JCL5Ž©ÈÊæßÍõ • ¢º×éøO炱qúœ5u×Ù$³?? ãûÛ{i¼ p½Ø•“q*WÛˆ¦ÐVÚÍÒÁî,4iìå6¥æ¡ºVV¹-±5~iýWDlÊдÒ!¾t:“WùcÜêTú¨TÇ£~½;0?åå—½²Žp<‘Rz†4qDü|mÏtd“8Ëy<ÁÎÉ3§â>'1f&³«Ô¨XßO>ƒç »@·Àùéà-ËøÖw«S@È4S(¿(¸´âñŒß÷þMÿrƒ‰›7,¯C:m;çkýø:^öŒ8ÍpßRȇ}ãÞ¬bÉRŒEÍüM+8Ÿñ#™W |t€lÄþ‚œ{l©û¢¯ƒÙÙSžµöZ"Hù¡EòJ¨EçÏg§äžìU;Ébm¥êÑ@#ÿ ^ö·£ºtü3z¡òéJN…J–ù |.KXÙQìB«Cˈò±3á*Á°©ÈK¸9”ç¯d•Ôbm ïËfæ>䈼mWâ¦(3i˜ë |hoÌ]0Û?ã`·Së¹`¹ßÏñšëyËÇCó(í[ÊmÉ }Îö÷=´‡6ÝA˜ºkþU>Õ=¨‡4ã®7,\µ#ÐWÄyä A&GdÄkŸøÄG+äÝÄÝ~ûƒ wèß27·oGýs €ÓHsöØ §ã€p×b‡«bä¨Ó৸c„×k4ho08áÁ—h@ϪÀ>çŽ0àyÓµ†‰Ñ9`UÀïc|k:£~(AEp&§nmaÚ;Í`‚6´Á jÖMýôÉ >|\Ð}Êñ­7ް«4³ª÷Bx×ÁWú‹®sgÈÂÌ{õ5šÒ:žä]åma :»NzU£4LÅ1R7ÀTN£NÝSæÊ ½9Ö—ä9ùrEž¤’[Ðt+u°Òy4ouXÄk>8ú'½YéÐG´ùÇô;P³b[Ò¥“D ãtY·yÀüÐö\íqU¡ù²ô¬þ¢zø•§Ç[¼´=eÇfõ`X–žA„žôK“ãyå×?øL‹N¼²ÄQ¿ †…€KÆ)ÑàWºz•-ÔìYÛ-ò¥øÔ­H&ŸÈ‹,éβ¿=µ›d} >4«ÄN=`<€ Ã34á¹;k商§L¯AnX®]0ë·6wYMsÇv:„kâ:´ôU³ônf)ÁQ `âÉ3h¨`9€IÙðÇÁAÁÚ ÿf÷K׊]ö‡ÇU 7Za©Õ‹[÷¯¶ãÁ@ÛçfÆ*yIîÄ}LhGíp(>,Úƒ¶Wh&Û­¤bSð“––Ö*­ÁZAV0‹¢îe'í÷Þ¥~ŒbMüµl›N¼ë=þæ™`¥•º¨PÑGµê¥ØSñ •dü–K¸Ër´½ÉÍ„xð"ëÃ5öœsÆþcÞÛ?c‰ßÝn]ý¡ŒöرoF{\ïm(ËÕѳýñaÛiéP‡™^ѸFpòL]FXoTŠ–¿!}¯r΀ÝXvGÃßøòW?Ú0òíû~ÛÿéOŸc}“ýuÙÖ ±Xœåº"hä¶jÕ ÓNåW®éËæ!dÑ(ø(ñ‘ ±*p…¡óúÒÉí3V€˜­ðۙаӃÑ_EP•€xv©¸dWeêÑq+ß¼×q­£Lo´#P·)Ó ÆÜøG7©ƒWœjÏ]µÕGH9j¶¡¯Â–²Môh²7BÁÅ.•`œ •~0¹K$Âw¤$ŒnR0”"B„U\ñ˜ ;SWª»f¯]^7DWxG µìaž›çýgÐ ÓÍ})ã§îÄ&]¡Î,Ïo7™S¾ãŸ%{žù{:gŽ%öQ8òülæ£ÀÍ›-߈.W§¾Ñç H#ƒgþG2à!™K6Zð–« ‘ák" ‡Çãl4²Jà#Ž‚•Æ|ÓpÚõkÚ¢½ehîišU¤M|ê,|þÛx)£—Üå±ôê­3ü OÉ6 ·É&õB{lWò*΀‡‹7ÿåQO¹ ú+Ÿ÷ 0üa~c)ê¾'sÂ_r ›¾RüRvIã ) m!n)KÚR_á;9=cS›±9¯Åö3ãÂClŒW2ox6“š¬ú¬÷æÀÃZ&é˜])"¶¤E&¿ñѸأ \%öb aZåÐÐ0Üaò÷ÁŸþ1ûê8íö•q«·Þ:[ì¹ èî”ù3ímÜÈUF=+°Ôv¤ì0ÛªhÄSYiΔ=f4p|½xÈ®e?FtÊsJ>ÉIƒ®+÷³*pÍ'NqØÄsïq0±ß¸Ç¦Áœ6èÒîPþùõc‹~…,i‹­ñCç4uÍ ¦•$N]¿)VD%…†7 ·ðÆSÕÏüKXׄbޱ *žíðÕmȦÅíð©æÄ7„ „ù`VØ*ð´–úm4mD•5ÿucº¼âìtçóÂOò߯aÁš¯„{À†<_q&½ÓVe:Ø‘7ek<è¡\avJ‰L1_ ëñˆ`Y/p$€QxüoòDò|d"'Ž0ÿIO >AÈN÷Œi…ˆÒެòNþ*«*Ë;ùeŽßHîñé„*ËõèW_ïR)G¯aï–F–ös‚O–ðÉ›%ùVðîÆg_œ¯ômWv…ÎÂå3>á,Á“÷ºš÷!‹Î¿Â.6tþr˜¿[Ï  h²'ÀÊëþ%ؑޤ‰Ð°ôžà Ä°zÓŠm=½Ï(Óù#"³zh€eÀ€bÛ=ÂÆƒßUüÁÓÅÅ}Þ ¸{qÇC†ò >5š€øPÕ_b•1ƒ„˜•q‹D nú ’KÁ :dµrê?Ò9ñSiä×Å€ `ýÕ@ÈPH|#^=x «†Œ«d!ªFCo‚ƒJÙº\Ó2$X:®ÞÒìd„€¼·lªøÌ'ñª©Ÿ•YdÓ~çù·³+,~蚥ä+üF·wÌ™¢%“êô½xådÖ@,îb79û]ÎÄ1ñǬ`2ý¾ØøÈ9kÖFÊ%ÍxM”Éí(2ÔFöz›Bå ¶§,÷çÓ»ŒÐV”Ë>ã‘ÖúzËò{EÖ°³éÈã cZÀŸäs±ü“ ”R¯ÖM;ÒõñÙ Ûp)ÏÙë/Ñ”TE–Wšjp•®NpŠç…ÿð¢x²1rŠ9ÄãÌû*Ñ +ÜøÂH;7ì"»:Ù¹ç¹:|~»À.mÃ;ý´¶°ÖP¦ž±ËgJœwX>wÙßWé!Û™Ûkjô¤ð¸„Rèt(x6$„U ?HµÇ#À5zqK‡îÓ;zr!6¨Ý2§¦ŸÑCÚÀ¥ÆeÚ[¶te}HÐPˆÝ°œÄ‹iy5½â’\zópt < Ж܊Wnùq Æõ@ºäÂ\¡¥½A-£Áѧ(CÛ:);+]Æî°üÂâê㥾ÂwÂѼOÜHíã!^µM]Ó¦ú Ÿ+37´£ÜØïq‡wú=—Ÿ¶2›G‡&yÐòKפ¯uE^…‡¦g: +`œÂ‚Ó·s‘Ø gØÁ4ß ¸¼ÿèÑG'î²êûìûï?þlqç˜]–SQµU%¢Øt·ê@ÒàÍÂx:P[æu«²Y¬õ/Sþ'ñÔó^ೆîŽõ;Ì’ÔWG¼JXßxÂLã‚a¦— 5æ+ÎK¾Jø”O?}ÀY>pÓà]Π¦ËŒBýP!æE£Ñf½‚ªÊ˜Ê•äTšF§J Ĩ¨¬r]‰«:'Ï@6‰>ýM; Ç´‚á^z4dÏ9{æØ`3 xã¼ÏÃÝñ•(¤C`seQ ³A¬xep»WàÀÁŸçÒd¬h­™,rpg|Ó‘xxÐæ*êŠÃj²ÀHP¾6 Y‰‰˜9“üÆ€2ÿ0¤Y˜:Ù‡¿NÝ2tÅaàšFùêoú4EÙhG‘N¿ª‡S®7€E/ÃFA=ÛPœâ‹5á’1`-sÈQF–+‰Üø@kÃKÒœãŸÐù1U÷«}åH äæÒ†Èq²»ñu\–N*j:Y^õ#Ç7ØrgÙ?¹)TOÝ@¼æ¹ö8û†Ågü:?äãâÖQ»²]~÷fÍLßÑEfì”ËÆçÀà<ÑÏ•7üy`OgÒ©«?ËüÓ‡}\¹ÐPØ0–•–”cƒ>N@Ó¿eóèšïOh8Oh¥Îˆíw瞌e1uzr¾¸âwÂèöìaí¸ã^?Fäs-:•(‚B™MÚàŒgÞêÑ+IFjžðJ7h)BWä|ðJ^»ªQ‹–_>cÐÁ[r… MÈØâš…Kƒ$DZ­Y¼‰)²[%© ËO7ùESU¼^óǦ×f=+Cä°;„mœ=ò†·9n|?ˆ‡.™uº# Î¨Ö8aÙ|¦L~TM'ñT†À£" ÔÒà—ŒhŠÇ<®wK_u¦ø,½—ü¦£¢Ô_Ã?å“2 œe^³-€CPãC|åYঠ1Ó÷–³ðd#ž™æ¬Ü–}.5ª"N:ûf{Ú-¾®³ÉWüLÁ=áOyY‚gö½¹ xl„mÛs:Yñ„·‡¬³r ÇÕ{þU!gAátÒT®-KïÙqÈŒ<ºgµÁ^}Q†núª2ÐO¿yì {@˜ˆÃåœ2mê¶¶þ2èØ·óW†Ï…˜®à1™+ö"Øù ¶C·üUŸÁGgdZùséŒ<›ÿBSåi,–«wåù3Þp!O9í‚0ñE§ÜE3É𥗜Ò”jœ@øOH»!+ñ•gàµ2,¢”<œÁ¦1ÕgÙE_èôû7n™í_Ðñ?yrBǶ¸Àno8°SZ9ÛϳÛ6ðÒ:ʳæ{,´ûwìô¬S§´Û¨h½œ_bÌ“A}Sg&H¥Õp^"$؉mL}pÞZr|S ìŸ}á _ð ð+ã´çWÊ­ŽrPò¿¬>Æ×-fÅR¶=JpFÿ£ÐÓnC`eŒ_Uu`Ê֘ŸzQmzòvõa0TÙsÀTÒ¹œmÅ0äIƒ&^Ñœá·=zî7Þã´Á÷¨ JTß àÄAö xÚ`7.¶«Q—¿t lì"½L»u[)-Ê]@–²îøŠ0 ûü›Èô øÄkþÄ zt°,*÷@ t:,“ÔAÛìʘüvÎ5ÊO’à²c6s=n¶_J3ÿzD šReaçq¢|N̬ÒrYóÜù–çÖ7Bn#Ã6kdÚp›u±"MÃ7tXÒ²Ùgõ'i«†^…U9«6~Ðg0b"•R™ Œ´>(i5%9þnp•#ó_•&#\ùb°ñÄ4 fâ,öHiž†§¡†å"‡ôyß0Sθ“3Àa6–³ô=d…Ù³ùX%ˆ òÕe~uˣ󜼦nÖη7’Ÿd~ŽßMIœöžöh.õ«KžÁ ÛDSÿ|ü‡°vtd¦xë¦@_Ù3ó<6¾¶gï |ã©}a€&Ç3ŠÃ/Žx6éÔ‘ArÖðìñ8`ÍšIÊÊ:Ô`›€×ý!yγP[²ÃѬû†MNü„…7à&À%nR~¥êp…z€nÁ…ª·Rv œÂ+CסÈ$c ¬6Ú§a;èÉ™G8¯òv–PxdL÷¢˜Ð‘ämø)ØÃ«{.󟹓Ÿçür¯x”³—×-±oVp4©lÍ ¨ªñr%e’´¨P~0gŠ‹¾ã^¨Ö-œƒZº ¿H?£y‰-tÀRTH!צø:ÖbÙɰ¾sÌéñk¿6ÏÝI‡VÏ+7X>¿:s1}*}sÖš‡KY&ó"gC<•Oœ¥7•Ýð·ÒsSPe*qEU×bŸW>á./s§È3eˆÒL3“ïq¸È]~¯ßqÀ«,M»Wà)ÊÕC¾Måvž=¹ÊªÀé1›bîð !ï—úx ­p)”ŠœÑÔćŸÒA¸yˆÉßòØ3Á툓WÎܨé^2»«Þè¸fù×Ó¼VtÎú™›D¨™‹ÒÕ—@ëW˜ú§/3œµiu.}£•‡‡Ô¶®€„•Úâ•“P]͸¦IÞ6¤p$æ_å!ÁÀé …EšÀлÅÎóoÃúå¯Ì‹Ë9ÏÚ`½™•óxkË Š—wx®ãÆus¾þ·eévq„ òÔß–ãµSÊîî¿@ºÏÙM¯úe¶í’ô[ŽØÎó{?ì“åwmeìöw‰ŽòpIØÇ¼Úë–qeŸò±¿@æ5E–tÜ#¶Áe¦’þÑ«ó<Ÿ BnýR!{1z,@IDATÜ×°Ç)€+^%³:±Õ 9*sÍÀ‡ž>Qk0'È6ÞØ"z¤“G¶vgþ9!°Ó·“Ö+HCa¨fô±L…É8¹a? /eYŽNRR<ðL\Ú R]0Xªì… '¢¢(wò±vE“X¼DÎà1îÔ ¾‡ÁvÑ~É 4Þ íšöêU¶«g¼ ÃïâñÙâÙ]FÆ>p¿ÀøAÎ@‹t~­ˆw~ä:ÕÔDÏ¥tïwõK3RLƒ‡Êi@ÜUªH§ÞD ;™¡oÂX¢9YÁ‡¤/3zå¤ # ¿ÅÖ…YVÜMAóhµYæ×´—<¯]KÀúïÆídZ7ì:öývw©Ó?pÆ af„~ÏWÎnX¾¾&|MôâqŽÏùïU˜Zm¨|·3 zpÉÁÈ¢ÍøŸ4³Jóbáxƒ÷®K ûéö·xËö¤m™e&Z%v˜WBi<‰Á?i½Z\:ãlõø@*òÈWúj@ t@╽#afòÏSà\Œ³2œõû-+(Ûàƒ 7ÔñùÕÍØ7°¤³ß¸]ùyTÅ!?κí¸ó%OýY—‡†Ì ÃѬ‹fù\¯…*ñž¿Ìsú³@Ù¹›Ã3ÿtԨƧX $^u1¬¾m|Ð ÿn[!|AÆÊ™><ëØ;t§þ²ó|Å¡?K.@–$X1²FzÀÑšåj7öÅöŠrüÉB@›p_¤p–}Ê@ò>Ž2È.8‰uÊÀ4mÏÍÇKÈäÁS0.®;×ôâG´A&‡f€ _úÒ£l*Üß¶CîcJ-ºk:þós>Æsrº8ã~Å€zË1û(œíÓ®e•†ê)«¢ÙÍOÇï[;5¸G^F{¤Éô%µ#͉I؈s¤8é8±ºÐYAGñ4€â«{8”ˆ™ßšZúÖ,¹¦VÇn®¯^©7LÝ+7X¿æÇF­éŠ0+§”µEByµ?hé§³I8pz7¼Õ„«¢JË0ÂÓ #P^pFVFt×"{™5Ïñ!r‡ð}ŒÿøÑþâÍkžÿóì ÏÊNhÍžò»dPpEƒ–U–Ó.YFóÄÁÓý“Åç ç´Á»‹žÉî±™ÉNP r$+ò3c1±I›±4†Q0”É ƒ•b¤£b7›!ÑPTI‹l%늠P¹“Xy;œ¸E”«ê"/ôaxÉÓ-ZÈ·ÐR„аùi¢k<`C4¼¤ÏGNë]&eù`ŒþBG'c¹ùì?å͆L7³‰ßÈÃÃã}–´ã&¯†1 `æËš%B "¯mìu6îæ¨IÈŽúI_#Ú–âŒD¥‡­$‰ð¸º`®©“ù¨v•®Êî}‚4.óMX9‰(¬²Û*;ÿ”Î$ :ÿ’0¶qE¼(fGÇl߇瞜øœ[&z5gé[^Õó•¿%¯añ¼*3½héÌ_½˜õ™Ä…Ïë÷=¨b´®Õ;ú \ê%ó\îMçI ¸îîctþ[À3ÀðNt 7ÝÒ‘/y´@ßN~§›Äò _ÃÈa`±ÉÌ¿l|é@ƒ´í©â׬ØA/ÙðgáfVïnr K^,¶°Ü¿±¤ó_9`ÀÅ4I®[<—î `Ä¢¬_峩OØÄÐï˜ÉA€wñÆb¸ë¾ê£1ðÜ$ªAxÁ-?å˜øJ¢Ú 7SÁ M„ú_r©WƒEºâÙÉ×"tÆ-6ùÎ¥»@´31AHåé{¬^b ç,í?99ák|ÌöE^¥\3³¬7œÜçÉ[7]îÝg¦ï+|´[$26cÃ<òo¨1éÑéW·v# дOÌÈ ½€Å t,Í™|ð†…nv™ëP4\ù¯ +üÎñ½Wê`“ø Õ2K,‡Œ‚01órž‡ËFÙH¥³Äü®Tqœ`©‰…ËÕT˜t©ÉÒ+Æ ¢é6:É©â o6£:©a£äf¿×™á?b)ôÜ ÏLÓløÅ?‘â‹0 l¦¯8Wà_%<ÿà½Å9ƒ€?HäwŽØ)ëhš¸M“í8ž6p]Ç*~¯ê¡º£*Í2°RSÉÔB7°Å<Òi¤;àƒ˜tÂ<­¯ø#-´ó°ôÆ9–ĤI:äŠRf=Ÿ×O#í»à™Ñ²{ÛçÍÑ R&ô@d¢¬É w»Û<ŽF×%nf2¯»g p´£ýýrÜRxEÇaF{0É’%Ët,0e%Zõ‘5ºHY(¤âVÿêbŠFhúeHt5è*_“…ð! ¹¤›Ì4_ '²ò«t`Äs«<ÄCï™îQÅBéà@«`ªéè=„‡Î?—C¥8ÐjÉ;;bŽÄÎÌ] ¶ÏÁÓyÇ)©43ÿ¤I»3:³ÙÒùç÷ió™JgIÚÎ^ð{L¿« `«u^ 4¥!O·tÔᱨŒó»LµtŸÇžû‘ }(°¤|MWìÇ0†HnœKôfÖÒU eOÑ^cC³>¥3‡Â¤êÌýÚ‹rõ[ä&X ,¯ E`gv¡±üC£^ƒ?Ê Âò 7<¶U)'À–³ô¹ákÚÙâÊŸ0ô6S¼XHëæ]eû +c /ü ËüO9©ïòÂü ’Hðžïr¹aEèÖïyóHhÍ*€äY[_HúÜ÷¡‹®C‘ÔÄ9%¢È¸ÎÓ7W¼ü‘£º‘I(à M"fžâI”'rF8å5À©K3=ZœÔî¼öð£G!?¨ûþO¼Î2K5~Ö'0S¹MžŠÝ œ X›Ða°VœÀ‡1örz&Fð§2ƒ KdÑéÛàë×p>â*ú1zG¶Õâl p5Ê áž‰´N@ï±áïÞÃ=¾?p¼8sE€O¦žÐZxÚ s¬C”ö$2_k»|ÂR»jŸ°œö”}w8zø(o0K¥s²&túÒHªŽ‰­DàgZ$4Tá…OaqÒI#¦*c5<SÆN~Á²× ˜3 ’+íŠ0H2àR¬aeG7îimVYÆàll›.Wëô«‹ÏÝ¥m|ÁIÇ#Ÿ-/Ù÷ï+gÙ;ž¬É÷܆ìÄ>ñÒ‘1xØðíZw¯éo]ޤáréß ¤û¼ªæÀÇ:¾Kà³Í Ï©sfZä x— è|e©lF=ͯºã­ô“qFëÌ0¨Ý­Ê,\}$ÒPªFÎU£]™È|ÈÏü%Óõ•6éa#Ï^šœMOè²-û P|ã>÷NøAõ­Ïíé³|†½mÓ³‘ǧٜz¿®wÁL½.‰“gõÙÖí{ÿè–W¼Xɇu¨DKóß÷¼y-ÓgÄ®²d ÁìÝÊå;ú9[ÝÓ—ûq!Ww|kàš5e°´¼öy>…êrù 嗜淺$í./›¹åë'‹—.÷xG¾¹—]èV4x@Ç^ó>G,áÞmOXï ‰=VöRîØ‹~ñÜ-† Ð¥6<(¸6q³_1¬¤j"#Nd€›„m›ÔÃÿºˆiW¾ÉΊ+ÈŽ/ÉŒ¢eh#ÃåÑÑÀÇ~WJ’|ßÍöóéÝËgÁ£Êié«“¾SNê£nl ,9©Ûð5¾|°ËÏ 5‰)5Ô¥ÕÉ-m†Z.T­©÷Rtí„1ÿã’(†¬&5Ò;ÉiÔ`«à;âmÁˆoÇý\ý«å†é¿BJÿ„+1#._Ó±8ÚY&ó°p+Vú’&4]~-rø¸%.Æ¡5p€}fߢ ÚËhpƒCÓ‘†À¥\7»F=R̶ŽxúèÀUb4í¦ÁSºžg,ÜÐT³Ÿ€ö‰ÙÓµo|À÷>x²8ÈòÚ]¾»¸ÃÂO9ƒÎ¦c¤ŽØÔ+™cú«²« ðnÝÔp`ô¾àR’wE#sÑè±Áš;éGŸT`S.$³_ ËݯÕÙ©×sBhZH"U*tò“É6HœÏo·4øñJ‹cåÅŠ¥âÙÑPêÓ¶ÐØ‰°Tl“ç>‚ ÈäDÃkKžN·òÀ¤ñåÆ4h>Ç77¬Õ° ýšÎÑc‡¯Ü>N>ÛÚA¬xO½Ë¹¾5 ÎQ9ñGœ†bQµ3]FØy9¦g•·äô¢U2zVa¢ŸùUBdI#•°þÈ꼓ϒÝr‰§ŽÚõ™?x;Cë3}§Ú9E‘j6 :[&½v†>ïÍ'úsk·é'1~Еgñ©Œö–“Kõ°¤³ô€$ËÕƒ•˜¼ÜÒFùFØ:.i·r`O§!•*ÚI·VÑ{û£p.1½/:Ãâv÷¹Ü`’|””õ €"òþÙØ(z'¯^Š7Ò ƒ¸óŠdÒ_¹ÀòÁk'ë;¨mc’ê¶+AÍ¡û††¶‰Ì =1· ˆ„زœìªÚ†)Ü ªígj°|ÐÛ8Ұѵm‹ iœ¬(§(A/E ?üK8*·D 7ß_ß;Ú_Üg„ýÇŸ^øyb7>_œSŸÑˆ¹hí×Àž>_\rž6›RÎyÐMƒGwï-±Ïˆ¤:ŽÑØôc â­^¥•ˆÓtMµªÀ¡zÉ¢«#d>·d2"d»ÊdgÜ]« 2ªyÙå™aۀęYät±+猹vÿÏsšNÆÃ£‘ÇD…2aé˜eÿõ-³T;2roÉLoÉŒÑYmžIólÙ•ì,½šN(ÛÐ1Å)Ú“é@òR!º¹ÑÐ]çRì“§v˜mÙHè£dåoŽyÛ€¯âIãWð|lr·¼µ‘¬?—xûNmÊä€Pó%y¡.Fâ ˜³Q¤$uòÐ0xóוŠê„‹>4r^ó£ì™Ž›ôm¯Èžq,á7¯ŸÁlºhè·ìO©ý€1@ÊÊwÂQ¾ŠSâeÃ$]†=A/oŒŠW„ Hâ5 ª¶­îb]a…Ÿ4_cÖ¸8nã ÛA`‚5ŸJû`“!žºxõêmc?•ï“ëÿ£ÿä­ï½oÞÓÓÏTÝnvuÅZòµók/Gºè<êÝÄÒTÛꌶ ¦“½+ŸžÒXÛ8âNc4ãNãŒÓ†£¹ˆ–†= Џœ†«9#Þg_n¾¡±½º=Ù¼»;¥3ÀìÖ¦A/Àuv€}·—›Û_³F÷úÍæò‚]"àêáS¦3=ncãå¿ìÐÖfcÏ×ÿõ™ ¸ _"ÞV€Ô¶€mñ´4ß´í–<þ£’âŽ4´ó1i8´VanH zhl´Ô&s%ÀÁ߆¼ˆºINÖ50EQ1t:Š)SÃ(CõN{//Щ hà®K>ÁȵM7œ9–ªÆV…JDÊ‘cjQ'(P°P¸÷^‰‹á!ɧ=í¦¸Æû olÈO×–î]°&°-Ã^e’%tÈK!ávDW¬r€eY¡á6?“ ‘UšpˆŒÙ'A‡¤r@<ê7ò¶Çè\ówaåÿÀ4»Ó‹#Qì–Ù<²Ã•Èîú® ü^êc0ˆîÝtöêÖ`׿¡7“L0ÊÙÖ]ødžISJ”zÐ$¶F%£mâŸxA£63<Æ2ÀÈ¿•¿4þq¼–ˆlHÜr÷†ŒÌÓ±Q^pÅR&Fþ[_ú Žäl¼°¬öZ|4ÈI¤ƒ”ӻʼ‡Þl›Î‚ÍåO`dmÂÀ+~†ç_äøˆÑ?FZò7õiPÙNDq7N¤U.þ Âæçà±tÔ ³Ü¦ƒÆÔ':j×—×\ØÃ¹}Ö÷o>pa•#JßXÓÞrq3]tæ¨DÎÚ2crz~–«Ìë)må¬:‘Ø)Ä'¢¡ððkYƒ³üÌ„W·¶*é‹:î¥9š"•/bÆ,8¸Ù. <š]3˜¬wvPŸ½|ùs`$éoísû'òþà››/ïHï½óÁ §ÑÝ0ÝV>Í å%ð%_±¤RZéøc•‡u% »Ê$ ˆ³Œ12ê@„í¸)€Ã/‰ÞF¤B{-ŒÀ„€l#Ò€±ÑÒž Ð1w¥¿äï{F<ï/==p.x À© Ò'SÇîpJD=Þ¯Þ%%À©®û/rkŽ1 §#‹í1q¿3áÅ×ì‘o9^hYÇìðå„XUÏHþí툉‚ºU\í‹nÏ&™ÅQ>.}¤Äg›Y`tnítYJ¶v\²a“i¦p#ˆ3?DsÖƒŽ?¡1“—ä§&v’)Ò#®KVd T!ŸNŠdý‘¢†¬b¶ÌšÒéàH’ðꇰÌ\ÐÈgÜn&a›ÈË:{p³,K–þ ïã{aBº|ò>6ò½§¸ä ÞOW—°w†…S¦%û?\žÉÙ}{vgnêcv‘=‡ÌÖ(Ù2‹ |"ÓÖËÿ8[¬ÖxÒ-þEfƒ_û4Ö ŸBŒuJi ílÚ9±KÖÎ8ØGvèDdü •Üw\¢úö?úÃ7{äÿàOnàúßþÛ«£¯^PÝC­]aöô·}öas9HvŽŽbºß€©ÈqVÁ?§;{u¸ùšaå•{ص^{|ˆÈ;ð½W ÚÏ[ÖïniÀ?òÑÇçlÎaF Oç"Ö·Q:nªNG…éæ˜rF>U‡f‘C±"[!ÅŽâ#®àBZî²…S¨‚FƒWÑñK”‰+ }ÐJ  º<Óå¦2ÍÈŒ@½»}‹b÷ÎùÈÀˆÒ ¦y®¥u¤¬2Åͧ”­ò¡ÄÙ0"W)827ÎQ'*•î­›/”+?ðö Å‘ A¦¨=R§T %jn¦I2>ÎbÉü¼G‰ºÑòãˆôÁË : F`é(8úÒ8}Ï®ôìȇ…yñ…G¦rW>Ê/^¢•é>¦ ûÜ$YG;ÝîÈ>gíA9Ÿc{n’̹ww™º¹鳯Ÿ¼E£Üب—2ôisx/iH—-·èqÑ;q°AZ%z¹#®( ó*Ë+®½ÓXº/ yÃ:;€<”´gn²lY<8¤™G yÎ~HŒÇP®·Ë ®4Ì`xAQU=4[ïðr Öt£#·å" Ð0O¶e4[Êß Xæàß–£Y‘¡S•cnÄw›Íƒ|ù—û ”mˆÿø ˜ d=¢7)»Q,~xUšê•´ŽÅŒ²oÜ«½8·å´ÔuE iè?ùø®G,½¤ç#Ïî~¼|ÏÚþÛ68ñ@¾qÛ*¼¬/»´.ÐYuCåá7”²”ÈæÌÃ4Pò„Y‹h…¿EOQ"Îð3It+B¢8Ü8üá*{C¤jcš–»ê<ð%Í´W8†dú$¼&ßpÅ£¹¶;Þ;ÔF°}ÖŒ¶#6;oç,³þßÿןþ|@Rê·øsúOþÉÇËÃÅ›Ë÷/+õ+°´»”ÅοÁ-N»ÓðL=m a ;—.QíÚ w”©"J  «È)nMgt‰ÂÌõ´ž•wJpvÍ{ÿyî·ÙѯsɯŹ3äàYëö/Xl„îíP°«Ová;WSÜQ¢öf˜µ°¼ºÃÞs×¹£cLg ²&Î×±JÕCÄÛ?7»ugEPÒ÷ çé ‘‡ÙD7XåàÄJ„6e2š.Ùeh=ɬ…û”]·Ñ´³c¢¨L ȵw.Æ¢K^¹ßeo>Åߘ~ÖÓ f”kÑvˆìD—0X¿Ï§”?á:‘N ¨ì•ÉÔ¾7ÿ 3é l¯Éu_"B¡ƒã%E<~´áD„r:·¡¨þiR–À¯2= F‰øEGÎ…Wüb‚Jªwâ‡=ùƯ݃Lðð*9'T)‡â?Õ1'Oðùä½ü<Àó{ùUþŽþÝ4áFÏ×ò£ð=J§1Žž1 Æ}%´ >°e»²a!›ñ4¼Ñ+ޏq%ü¼| ÚO&õŒ¡<+®RUþZŒb „µ0—D¾ñ~ƒÅB²²,Γ[Þ­ô-GÊ^nLOý•Œú ¬ÏÿîßüÏ•<)ãáI™£?øƒËÓ3ª&€aÌ3~þ/ËÂa³0Ãp¢üÑ’×ÀRYëíŸ~ó¹íÀ0t3pDÀ­8‚ïOÓ`µ@*ë>ßÀ–=pZ¨ÁÈAœÊÀ8¡ž*D$ , å©ÿ³Î |ÍS­—\=ü–÷ØÝ+ð‘nÀþG´úLêÑþÓ`Ýô–#=—¯_o®89p̽çì8;ã¦.§O)ñ6r)+µ :qàWÆ$Б½¬üÚ‰_¾Z©0 ¨àëïà&‚‘Á¨x3ÝŠÓüL€ÊÄÈÃtei€@•›7À$¥hàl¸™ŠŽbÏ‘7ãÅôw¸@î(ÒTqª;¦F\F‡¿0µ,½ Bò¢»Ìm&SQ±¤Ëu”µe7¸emZõ¡#(g TBÑ¡ðs‚ð|ã>ñ3 ip·y̤HƒÄQ7¼Ùñ>Ê@ô\Ò™¸°^;&Ý5%Žv FZçñÓ†5qÃ5…Ù×+#­]Na€ÆæÞÑòV!èt6_ã÷@¸Uœáä’ájÂS  õÚ;@fwØXI9-cèÈ€ò7¹¥Iy@ù?°<·ˆäÙ6Ê_B³ŸÔ%±ˆ‡e“=r,O6¯¹õÁ©±ìµ€Oî‹p¶À’qq«ü-^LžF™^üO=õÁ"k|¥VÃË/y—°¡I±nÝÁ’Y•ð¢*nÉÐ ;zWìúZþG—_tQà&œn;ÁNÝß’–nêûøþÝæÚM}œZ‘Mã¡×cçòµ§ŒøÍÔS?3DíS¦MËšáòŽÐ Y£ÿŽ™œCÜJ;z5—!ìé.Âꕺ†SúâÑŒ4uÈÑ>‚‚½X´¯_óåQ9Rò\”…ÇÊ]*Yz¼üîÿc¦OË<¹À‡‹‹ËíÅ)ã›Á© aï h¦DY4¬ó ÎÄd*î ¾øJ“*ntnÉ„k&+\\þž §ƒßt"‡@œÜaÜ?ƒ  Ûƒáê€x†#ßрȆÁÉòß ú ×]¹>FôËïoØ4HCûíÈ„ã #TZ©²O4r×lþ¹ãnwŒx{àŒÎÀ©×³WÀÝàUkÌSâ*Ǩ–6t†Í¿ÈÑñÚo†ìý©Ä.>MR\dmÅ®’'£¯p Yãˇ¹d¹ÀŒô8˜ëýij¸¨êµ¡ØÉ°(hhŒMnÃKJ ä³tÀ,S¿jÔ©K Þ/ÿ’y¼ûÒaPå²ÑO%aGÁÍ{hóÒÞR•)DgX_ÏÔ°éйòÕ»¬í»VíZª»Þ93çk™%Øpï@Ä2XÌÃgsËŽ‘FQ»„%¤tœÖñtOƒôÃGuPŽ|kËCfCˆÍÔ&GàÈâÔuå äÜuudè#Èôm o_$>™î6“H³ÂMš7Ÿ®á$þÆ!§*E¾ì“ȱK¨œÙÈ2”#Ó¬ó Ù¼´´¬ï[áèdmˆ¯ád'{j/)( {ñ8p/ƒ|íTf| GÝÈ1BߎÎ=Þ]ÿä™G•ÃéÒÆ;äRåÒB;M[õÂéŸ"jª>S6-Ë'AL¸‰ÅŸå—pôгÊó‚*FÈø1›uóWuAŠž¤c‡>³€¯®ÙÐÇ’›ú>¡ø=¾j±¬eÙ~`ÖÊ'²íܳ,uÈ4ÿÉ ›ûÜûJ¤ÈŒP8I!Å&¤‘%e’ZõÔ ÿpšòÙù•.qàÛ8†–ôáú…¢Óp¤×ð×»gðAÚÄj.ÎE¶xÿèg.‡f6¸‘ðt–®N¿ýöçÀÒîïð{ôG×ÿî¿ø¯.Óü©häƒuBe^…/Püç,Œï€¥°Ð_ž–®Q¿tÅ (…n ˜Lèp÷¬B{¥ÂÆ‘KÒ.…锨ºFYÒЄqo#˜!]Úéj³§ ~¾8 0ðõJã5Üϙƻ`ïÛ/\äCŒFkVÀLjX°3€âbC÷æ–M@7ü]¾ý¸¹âÝß 8ç¶ÁSnôÚá/QœÊ86EhUO¥ª i¾[[Bý†1MÚ˜H‘uVËáR86Ìð4Þ½¾Ÿpà!u]胒Ѿé`£mŽÚL¶5»º„³´Õ¤!]~þs`MÑߎÍtÿž=çIà‘c|Fž/•Faþio7ÖWÇ03Ž•¨ëZ*nýg&3Ž^N+qÛîf’Šƒ”Eá·‚ Ü€gÚà8^ 2`#P‰H-³2Dîà`SâÃÇLjNhl_±‹÷{”Ñ{—˜úó ‚+ 2{}Q,!ÐX~b½ùö7¼{¿yË­^Gvø;å‰â#6œ¹¦ZÁ[A‹ª¸¨_5ÕhÚH‹P0‘V¹Ft ¸ü†Ó`òÙùYüJø’!KÃPë%Ñ%!Ø Ç_É\0Tí¦Ê^#´b%ÏðÕ?AÑÙxF •»J]ž Q ' VZ{ýí(t†–l[·­‡/á0G[¦ÑˆqYƒ†aÉ,v“ á˜ÙŒXnèÜÚ²öî쎧`¥bËLy¹õv='1€ j4í.…à4xvÕÁWk¡æÄ ›p\G·5: ®½«S³©NŽ”é{F,ñ!]â`Ö%w˜`l>Ì(ÞÍ•ÒÐ;¨Ù‚îh¡`™9@†ï¸ ÉüÞz:ÑâK§Ã³þŸ 7óŠpoHG¦ðÝÈêŒê“W y´3ñ4é0ÈôeïL€²Ζý¹À% hrêƒM.ˆ?:{–ßd1X¥ñ,:0úñq†¨fÂtµ¯¬c|ËmX¤ž½]ò¢†™¿Êù…ºì%=ßûÈÙýÛ^vEi¢X{FÝÓ,éT‚ç —ÙÔwÌ £lè;¢cÙ?“4f¤:QèYÅÅÇhEŽÂ™ëtãLBnÒT|:U~fzaþÐCÛú®®á¹|*_Â5ô˜Ã²íXò¿ G¬Ÿ6*ÿWniÀÉ/.>þÑ?ûg?ïøédüûó9xù<ç-KTÞ¨ô’™ü˜7é…jùnœäípko?ííç·ñ±¦ÒêNaò ?e,0MÛ°0ÖaÊ*ß.øº†pu‘: e®‡fÐ.‘k7^ê êuñl7¼DŸ "“ì ¼#âÚa¦žAü!O{Ék…`ºê¸êJÇN7Œ$ {Ý…ßJLlSJ·†Q5rï’¢Ï(,SÈÔ­Ùý¤¬ð²¤Ã•ð ÉP¬¶\èG7)Ú Gf¯ªe´EíÈœš¡œ2ˆ"ãÌ=™™©sÊUî9ðC V¯ùßsü/²wþÐ!Lù¤ :Cî¿Î(›Hžt:‡¦_Õã€õ³t¤Zq—d‚»oÆ­Òݸe ®²L@PÐL÷’®ù»"w~P=î羫!ÉŒ¯šÎzCÉE—ãMpp_Ÿ-®Ž‰"\75zzÁ4õQ!x˜göÏ*×Êç¾ ÓÕ´Àªô&N-;ˆË?…ü‘ZŒ‡_\º¡‘Uüø‰cq•Gx ìúZ‚Šœ†]øÈÎÈuËèÞéýï>n®oxFì¶vk&9xj×»§ò¸¿âÞ=§™ 89¡fƒt8«ÔÏ\MØ‹­âa,„b*±Ô1ŒbiÍOËÝE+T(xµU¸ñó¾?f´BJ’Fi.?EGQH3³{߬áÍaÏX»D防æ'°?»xrïCŠûÓ3ÏÞ$Ó¦|1ÍÜùõo.ÓTâá/¬q~Š&þüø]p†[zë‚~rý5º5ûî8hR(²ËS¹¦™h>Ütz‰gã«·mpÐ:àòæ·Ø…ej#¸(J­g(˜Ógg›¯X÷þenôÚáO›(%ç´[16dF÷ëÔ·ïx©ðÝÛÍ»sž,âÁ)oœ³gÀ¾¬˜5 c§Èfßp7,ëÔ¢R!¨²ŠP?õ‰üò°‘Žgü«âÓ¨uüÆWŒXm´ñ°ÃÜ=µîk1ƒÑON`÷˜ þlV3ÝŸiGàÊêè×ezbFHp0e-«ì­ü†è(¾”¹H£4ÕÈ!¥E½¸W;¨KÊ ¥3krŸm躕ÑÜS‹iKÉF+ÉW0 ö6{2ªÃà%;^‰ëÈߎ*{ƒ‘›Ñt)CâäHÞÇ ƒOvÑCcgFP=HÃÇSÖpËLû|ê· 0§Òéi&=œ•°3"=Æ@)¼NÑ{¯ì„évX™NîÌùC£®rÃBb¸*îêQ@¥â&\ÙµìÙ×Ь„D6·<ÜG@|í/¹WÀÙ€Ž¯“ ™ì˜ÃuVBõTvÊXŽÿ±91'% B…ÁÞ¯FÎ&@ÑG,¤x–•ÄK~iÑ—Xó‡=}7ÒüÞ—”ÒhÐ0¿–—`Ü®G(ðUæí3rÑþ;–é8çÃ:¿×];8È«•¾iÀj?3.w–S¶ÌØ9ów#|–g;ü‘%5Á$Üú*kYˆÓ¦D^Ý+æ­q\aÅq&ÜŽ{ƒåeû5£+ :mt‹1SmO&¼¾æå„Þüg˜Þûî‰d„XáΡ+ÕùÙ³'w€q{’€Ïtyó$Ž%Ŷ£s·mÉä4Ž;™ª_Šý̞ݳ=LÆp qóœBÍ·a ÁŒÓ4¶u‘¿y„¹¾«”Ê3ñKÃpDÕBÜE‰úÎøÆÚˆ" ;³ƒYë¤RV]¾d£š}ÂGn¯{Ãî[Zî4ÐîçúfT7œàìð #‹«76×ϹaÐ}üYPÏŸ{Ì­FL¦•fek‘FEåIzÙ¢iáÏf7m;nþ‹„%GÅFž‹#û ›3åéý¿´œµâ¾$ÊÃN€ ÆP1·Õ1":pýÆûÍm³|à¥5ÀX;Λ® ç8²Ò_Öâí`¤Å½™kB;u¬ðHá…*™z7Fèî~/Í£?Â8=›XZ5sŠæ$œ$Œxh¹1ÍÙOìðEIg¤w¨°PÙÈh!`[)LüX÷ÏÈØ ˆpß~f<ëæò$u¹OBÖSt#¡!3$ ÔK{\pï€âÅÍ—W,³cÌ£j_§ôI£ŒÒâçýiœ`‘Æ% ÃE±?àöK–l{J¸ÊA¸)÷ù#«/.±@Ù¥IÇÀpÕz3é´.ËÜN-˜¿M“! («ƒ„ëR‚áŽ}l‡®âkVô>ZŠ “•<´‹h¡ÁÉ1¯AÐv¦,þ¯<ÇBY¬òZ`KcãÓ_QÌqó3¾5˾\ØÃ¹ý«wáãL ¼…n˦Q;¢)”)º5¤ 3(ücf<ÑñÁêѾ"–D~”3€ÅZ׊[òB‚!RÑþüküÄ@ê3ˆ ¿Ð-x…í¯¦¾II\¦˜ÿڔ¾M)FqôÛ\›nÆZa?m[é)9‘#¸$hûœ\ó5}ܧV0MHq§¸³O€4تì3š–÷'”_FÆà¸©ÀåÚtäjàoÓsVEÒÔûþÓð˜˜á:Ÿï¦@@×ïÉ>áf %ûà]ȆK$"ëìYƒ–ÆÎ޲’H™qöÀ¥7ʃQûiýÀfÖ\Ìd¸ÒØÑSø¾m°aÉ"h”5³?„ë²G:kN8Z¶ÐˆãþãEš™¶™9²”–Ò nŒrû#~Ä%|óddŒ¯š…ÉkѳFñécJ«ÁƒVù"w×yý(CíóÏå7zR?3»åÅ‹‡(v‹†³N÷¼eác<÷¾‘pXg÷9ýsì»Ît8ƒPÄ'ØØƒ‚ ™¢Ñˆ&öŠ·å-¦˜,q6@åϯɱ« e oþ{å¥m‡!ò(ÌHóxó#‡jaZP}þ¿˜–j¦±4‘Œ•ĹBã„V¯]‡y‚&Õò©É}ô«ïٳ洒“WÉìV2M5ÀXpÛ¤v1¨ |¤@J4Œ•dÆëJÓþí×îæ=DÅc„ Ð`ˆeÛµSYtÏFwã6\þ5òA³TÂ=ÖòÈÔ‚ ²v6ã¡iòö÷›:†Å&ÔFì%›„ž¿zÆ^f¸vø £1$ryÀk‡·3 jr:òöŠõÈÿÀ#"¯x”ÛŸ{œÝë¾®±ê¨8Ý]kjëÖV²i+‡î/sA3™jnjÀ!³ý·bäë2e/N xöå¡â #Sv¸«”mÜÝÁŸKÏ}z¼ÎG…²›\\; nv“…Q`Z¸•²QÈHQ”’3qGµ(ËL˜ n´‹"Wa€Oç\lPª¼ÂÜÌ€ÆÍë¦FŽ¢€j‡…;;`ΙÒ"I½ÊŒBRK †O:©EèHäZ_ŸÐåšãZ7'¾†í:º£çH€òs:^AdëcH\@”…£iŸßuFuôÜà—pY^¸Vvø „C#倯Í{†™S$³Š={'·:æsJ®ß›ˆ Ž>xC_x8¥O:®óL[»4€²sV&*dÍoj”ÿ£¤#"¯Îá" î¬W áúëÑ…¤74Q(voMcdU[;‹Azf>Æ>‹1/ùglÂϸ ›ùî{ýrRÛ²¯KÅoyÍH{ø àÿ'Žc^qç=p/¹°ç³w> “ñö$Õ­²ÿÓ— 2ÑÁÚ>KC§îæÇ?ÇTÍ'ËsÂKl # b‘*c±út|ãGšÁ@Œ^M+ <µ•žm®Î¦ ®NÅF-êþP‘ÁÖp\>mÖ +ánãì~“£0ŠkóákÙÀ˜ÖÇgOî)`e’€ã¯¿ý)å”<›L厶(ÚXö~TVÉàïùÍÎö¯&·|º µ_ãÛ ká)"üL"QA¹ †ÁÕo?0ÜsåEú&{üÈ#i^>ƒgw*Zþ¯2€Ü¢…~ç´jç/8AÀ4ª÷ ¼ó(!ç{0mûi&£c>óë$d½Løvó–}‡, x”ðŒ‚£LWÊF°Ò /Ó«¶A½?ÙLGFˆWõ­è:Îå2fà6Ð)]Ö»óv|rB@AçØ^0‘ÓþJ¬qœ)g׺™‚÷=GòN»:ÍŸ£`I üCƒn•¯…tä%üÁQ9âÎèÚ)pÝfL:V½ÄJ¦4.B›öéçT‡¡òQ>ºõ–·ÕÙLÖ×u›nðN—Wù—l[¸ûœ-&‰)ëæä“Êß6Þè炸ºFæ*eçzœ*—–YÐa†+kn4n“C¥ëÈŸ»’ô‰&²;[ _ÓÀ‘5<\¿ŸÃÍ݈ìrC_.dPæ}ÓdßD™Ù@q§ÓŽI ò·ãCpÜ'yn\/|2–²pcãöH¡ZÝéag ,2# ›²_tâÇa]”OŒnÓ ¹zh x‹?Fàȧ8 ÓÎ)œå*!”›\Øóqóá’Ù´·—¬lÔ…J\ ÍN°è:ÛdÖøÉÓûÇ9»ÄLLf¤.{ ?˜Rk~KþYîÈWh‰“²Š¯1Îõ3(øh[êšn‚×~ø Ó,핎Óª‰“ŸT\³wÂ8m_TlˆJÚ¦îo‚?ÂäRfÆhè [m¿†Û\ÀYÐLëûͳo¿þyàš`¿]ÛÑ/¾ypæz-•ŠÆÞöÄJ•ÂFÆX׫’u†•<ûÊÆÓ>éÃs{ÓõWð¾=úa¦¥¤uA¶ì¤àÒ·ãÆ1À‹¥+ÓÌ®í‹Ó ŠS¦˜®€ÃA—ðð×î(ßï’¸—ø »BYéÅó~/zAÃó—Ó|̵Ãw\0Ä£"PÒ c;¡¹z ýf¯7Ýr?ýÇ7Œfž1-ùìÅæ‚SNùfú2ÅA`Sk3š up$å#<>Zäl²Óü‰'Í(Lé“JeŸa´ÌPÄ*hµBšU´­¤%tD%OìL§©wÆ@ –cnXŃ‡ë¬¹Ÿ€–Ö‘w&p<°Ô”‹ò‡«kñ*Wâê †C³_…ž± rú¹¸tæÁ)oÅÆä¸`d‡x½ìo5.t½O !ìø.ñúÖroóSƒ8+àDnš<Áî‹…ÁÅ]ƒ,h™-O'û¨NŽ%z‚ÀôcVè€Ç~|"6ilª1âÏZ¼*D˨]} ß›ù¸Ž»ò‡JÒ5xä¢)ó ñ’7j7gP:\–rÁ×ü¼Ûo¾y{À­v÷¯™K£1øw9èà&·ÕÙ 5šÁÆø‘[Æ]°üutâï›–Š Ææ«â\~2êwÎ4&ŽH1±Ã«¦ý¼Ô0*¤°ôgÄÌ5/±3àz•?Oú.K*KvÃç*^pjï|à—Ù†ˆæ]ëŒü ¾™zfMÞ‰…ÄÍ@ÓYA ™¸³–?-ô‘C}nŸ$å´Ÿ¡’rù M2 Ù:îØ'Õ³¬Ì™Ep ‰A‰[˜ †ÓÌò*ˆË'9‰ÀÈ7&a8oÄlt‰•ëèFÙD’yò5á½õŠ`¯Ïeƒ£å'»Ö([ÖïMGé®5äÆB7ýÙ@±çE”rh¢„ ×È€o­×—¯¸M»!«B™·t ÖÐêV y†Àšöï¥&•¿¦z„¼¬ÁΗü7ŽÞ48­x›‘¦ .Ñ×3½\ç˜rìL‘p3<3U*sÞj¸æÕÄísSßÝ¥×óÚ;Ú&M¼{ÒÂöÉœ¼¬;ùé°äy^ùùo…ž¨UX†gDÛÁ\~*M&,Ñ1ÉÞ²V:aO²û>ðºi„·iÿv÷f9\ß•Hœ]Ó~å£ËŽ4ÑÖÖ1Ü%‰«éñ Cî¹gØŠ±'%u8K0_}õó1ÀŸNî¿_ŸÃßÿýw\tBþØú”I„uùŽÜKc×H|õ—FÓövtýyu8«ïOÛšnԶ˧ ZÛ¯Ý3çö¶ooüþþ”ŒK¥žL ¥¯†RàjKõñßé0‘ ¦zÏi¬¾æ!¢Kv}¿e]ó Ü0ÒÜ1b³+pNc}ˎ滷¢‡K¡ŠÚ UÔ:3ªÓˆv¢ûìŒUuŽc@IDAT‰ä²^d³©æx¸Ûo“ls ’®8xȇ©$3ßÁ,£k;”¿ö˜lˆ¨øV‡@»|Eæ 7ôEnyÄåˆþ ûiŽSF秌ޙH=SY“×w7·ÜÒÇc<ÜËï3¼ŸýËÛ “:Î,p‘mŸùO:¹_㘛7©C'Nóó UE¤„¿Jª)+æ òÀÂD¼Sgñ–öoªâ‡ç ë4h:ãh1(¥\Ð wˆÙá5”ÉÚlä{‡;y,ÖĪù-ØZfŽa¡jÎ+ 1šªÝûœš¢R³]~­sùÍ Í!ùtñêÙÏÇç$úmÚïÿ÷?ûxðêâêó¿ý,ᘃäffo±[ gÓîn*Ú-NÛý¶ÿL;ÛWXÚ„áÙtíÿ˜ßÌGû9` âìá]H…‰ÓF{‡7Ó6Î>ÏgfTT…3Û;q#C ‚[þšÇˆ8upʬÀ}™ib;Iî9¿Ë0¶r(dOþ92}È6p6›© U°Ywv×?ÓÇ¡CR[*'Æ2J62¦¸c->÷ ¨8« hñ2Û™/ÈÈ‘Ø0ío«¢È‘´ŒNmF„SºNæˆbž-üUþ9 ãÛ§ ²î.(¦Æ¡ÛÁHCéÚp4k|4 œB§3­Õ%“p +)ß“¶r±RÅ4¨“Ù÷@š¹×À#‡‘ÕŒóì|–  °ú ‘ÓïàdŽÁþ„éÆDå P—5¢Ñ€‘lyôˆÕåž$šzÞ½áÏqC–[L+£Átyf Ì%nHE¢eã((cb\ ×¥¾•_XãØ8æ3IxåÇϽæwxð+«a¢üµS”ýŒQÿ3:¯ŽþUŸY³<¿w´Ï>˜;:Â÷\ìÖ…C—RL˹ÏvV=ºIâˆ[ú|‰ïb:{|¢t**ŠD:ð6íB5+ÚêÎ,„é7"!¿ÆµX…åÏÆ)6\òkÊE¶f´ø” CœÚl–}˜ñªÎ­Xúv\Ë-$y£s‡º"PÚ‡ðàTå_©ô89®TºÊ¥ööpÛ£ç¿øy`%Éoÿ÷ßü¯7/_\’‘Ï’±ü,ÙR¹_B`÷¼lÚW i¯C0ÚÌ=Q-̱ÝiœþŠ?Û÷Ýû~òÐ 1b§áŒŸŽS ÒXÙt‡oÌöÄì+ð°¦áXt_ù´àÁE€Túä@£Ýͧn>6‹¦mdi¤á©3™Eì‚NÀJü[Ö”?ÒxÈè 2ª!œ!0»ÍM»ž­ÂÆžÁuwÜk`@$ª©TÊá8ŠmìO/;„‡'Þv TŒÂJŽ ¹•› ‰·ª=Š“ ²t‘Î fo˜ßÙÈ«aŒ&"…1¢ÓQXâbdV¢æÏDc…“_üŠMì¦GÃ.B,?ÜÂçËOÒI7xè®…Ï‚ˆ_TS±Š^ÖI'™a숫¢–ï ö[¦4¿Fq\2BzË]æoh}¢øš®À- ¿M ¶}F^_ޢ诸ëœ'M¹˜èôå«Íoœ÷§ ®òP‘oÜ#lª©˜ Õ‚Ê„¶qT✗W2²‡èÒÇ ¨§3 "ËhZ#bkm¬Òå1”Q)ÐJð<Ÿ¦Â!\G*ÿ”EÝI”˜è¨ ׎ 8qó›„vé »úåŽë WÆ©©ÈÂL†7ñyOÖC›'Xƹîãˆ<ë÷Êš½éM Ó`í¸¤s£òLJg 3\·§Å#;—«#‰v04Ψì»I1¦Ò»€%¡tËX| éaG#qÖ MŽ5*«D¦ì«ù-H®¶Ð¥c#ôµw¸Ò8…•iº ·eíp«ÃIóWšJ£ä·V;l£ü”¿yÇýthñ¿zù’QûGø®7¿áN~½eSŸ¯ðIÊ4¾ù‘w¸)óÁ_áccâsÒÁK½1j‘¹B"ôÅtšX¢´Ø‰½ØMî ^jƒIÑHrѾo€Åäѯ™imúa×;¦á!(úfm§¿‹M£7Ï„3€e7&mÊ–¸jxêãäR.]ª•®øT:B‰êosúc³b…+w§}SºIóèôüòóÝRŸœéZó¤ÿÿôO¯þû‹Sf¬˜‘§fQ”)_+SÚ‰Îið{ÌT£·ë3ã§-˜¼÷Ý©Àø©‚Ù°þ6¹8C¤Ñð¶ÏÄQ.é-ttb`Áá;ÃtjÄ_h°/ƒŠÉ£ý3m‡tª3rú3ÜØÖ l ®ÎÐð#¿nÿ³<ƒŸ D¦5ñÁ}ϸÀä;ZšIãóÕWxÑlUº+N ô˜¢—¾y4žß5åšÿúm¼]™ Ú9ô¤Èîï`àÇWðOrà±øvZüƒþþÅóßýñ»ÿé_ýÓ£¯^–¢¯Z™—ÌŸslÄæ1%¯—pÍÒ¶”óïôÛMŠÄ“X ¯Ù>bQ¤Î ¶WcZÈmÏ@o/®ÁšY*j3–´‰w·w¼Ámö3Y¤ 2K›ÀîÏÄ2Ò7/-¦E¹9u‚õÚáwï|ƒr{KãÍ3'üº0à^÷´³D€ ˵§Ï6¼ ¹9g–‡N˜I¸cêõ†ƒ/W*]r7Še7;JU%ÚSÛ. ¨ÜQ°ž÷Îñ/w®çX˜)‹TÉ#ÜejœexæôÀˆ £OOØ[J:8{ % rÂËñ¾ì~“MröË€޳.š Y·ÂÇLPEqÀÇå„d"²ŽŽÊpç‚îlDù+ŸÌd Ýøê6Dãå‚‹Sú*NxÅO{¥KÒ){Z±V¼ª# OyÉW¹5òÔ-¾þæª np×nˆª°\âHY]i¤×4¢Ù #yJÒJjhD÷Ç<Gùv»E°àw¤qÂ’¿n㫼þ5 Ö¸ùx,’µyïpÿ#þgÏ.ð8Ø\²®ÿîÃÛÍõFûtXå¶=ówäS–€ÆS<¶uèº~6õ‘&•<àjE&íÑâ.Ëâl¤é[~Åta-pq »4ûŒfц»Ñtú§iØÂw¦Åž ùYðŠlùý)ø‚0,+ž¶Ä®€¦ae/˜]U|KÚx~lšã}þfH…P݉KN2ýá?ýÏÿÿá_ÿëÿ Ê9ð¿™Ñ? Kÿ“4ÛWÏÞ›ñÉ|ëÜ0UV‡î@ù§’A«¿ P÷Ou>8¿íûß gA¦0ŸÌY‹Àßf)˜(ÝPtsÕþS”SìTøû&€} îLÑ–þ6{ºCÞ<ú«<”‘Ås.šþm:<á'¦Òhk_2*zÁå'ßó*á{6z½e¯ÀkìàÝ¢¨—¢ºNxƒ7³·¿ùasù^E{ ”uØ3–ž±Yð3€[:Ÿ?Ø$0ÚVàSv«%B»«ÞÆß6?©¯‚cñÁ‘T7ž¡Êt’’ŽQ²nMÎù3FÑNéOî(V;xO ž^Nã#ËvPh5ÒÇ?üàáûƒ#sÒĨèCË42âÔF.eCe%rg› ù÷À´r.JrÔNZVÜø°t}ŸM‘IÉ®þŽTG|ÂÅQ¿ ãÒéçLÓSZº£’42 ÅG^v°ä3⋽¶xŸ$ª2ZGÞJI‚el·À„; Ò)SKUyu0¦ðk©Á’|¶º-Ojó¢<„õòDW´3 ºZvãam( ›>°ÁqK™9gïÉ+Fûgg¬(}Ù¼~û–c|ìQá1,Gûæå!ëø=“ó%35ð9ÆÒÀ1J?Êä—B§½!4ÍÚ¶(K|&÷ãÞù%XÄÛRWb¬®®ß¡[âlÁ©ÏZfØ„~€W®E¾Ó4ã6ü4¾nímÖØ4t‚и³òžù4´)×™1:„ö]©³ýÍX«T+}ÉžgnNY§#¶¢?[·O@Ô]^þøÜeg™˜Ás®¤PÙ6´§u}r§mi­r*“6뾟îö &¼ç0ùò1¸è,½‹~49 Ž–À`$¾ ¸OÍ|Ä¡iƒ'ážé(î—4H3/ÏN“X: ¶Ó°H3nÓ¯YùõOÓ²; ×Ð^¦‘Ñ­]Ú|¡B)Êmô›«¾åÆÁ_z‚À †Ø@Ç©L¸;¡\'.h´¼¾åµÛ÷ï7uÍX¾Lx~þýæá¥ËÜQøž9ƒÆ›<›<óœ¿W+|Žà!…rá~нŒ(•FÅg £du^Ý D®$@ ˆ1’Š:]geƒƒò¦ˆò÷Wy Ú=O š$û¢Äì$  ·.‚§ûLTÂÊë‚}À°]IÂ#k´ c{÷ ع!t½rªÀ ŽRDÆMßþ«qym´¹#d)7hábçÀS úK'Eb#™CãR ¤qÏ iù IAõMú åñL|d¡,äÜááµ9«Ð²V¡ZhÂ\X5mæLÉ& &<ü±³`Ø™ Çi:Aã†QâºeŸÊó—ß0âÿš+O67ÛûË¿ú«ÍÕ{îåg¹Æv<óïæ½”dýÂ;ó›¼¾ç+|lúcŸ@îÀß2dÈ:Œè1­uqTz0ØU#&\Y‰×Äò–S»‹4HâÄ[ØðÏG’~Å´Ðôn¶5üÚ.æcžiÚ¯\+Ÿöhí½PHW~þ6—}ìÂ*h¥IcïcNü­3Ç–n’kÏûèÙù“<`âT-ù;&ÓÿŸd‡ß|ÃÅ dŠí5;y2ìÊÕÙµZº•Ô©<àwá-hý>kÿ}¿}w‹$~[„)XW¬Å_äg0££é— 5à¯[aLI±ˆÓFK%\Ö¦32w€S„’7°ö¶Æôh\ZygÄ¢cý;̆Yég1mg5†=¹ÀÒ耣Ÿ81-ÀÈ CõCòAÄöÙÀä- ¿l´ÁzÁˆýìÅןr¥ðçÍë«“ÍoP^0Ä%ÃCMxÁj‡Ñ÷Í;.ò¸ ú¡ç³Ù+pNÃþ™û¾°v÷…Æ=oÂ÷ÚX*4zÐ|V„-kï‹òWÖæ—‘¿”Îl¹ñÏÑ5#]§íWEnÙ”1 (#FÖÜqÖ~ƒ±á.Ê_˜”˜ŠQšì+E£;{Å«|q§§_– ¼iÏ΀ j•þà†y"Tp/™£’Ô(ƒ¼0g ´›*T¿ºå_ûÒyjø7Ã7ÓåƒòK ~½!’ENP†¸@MðЭáªÐÝ9ŸHĸnáõ †ôÆËtã#1ýü*»F·¦i°]ƒ ×R«ôî7†ØÉùñŠçè¨!’Yn=š"2³/Þhè}\ØsÈHÿˆ0=»ßáä–¾¡-C•ø%ðŠ«@L>Ý3$%oD¥B¯ßÌC`*Zá„´¨ËqÀÁ—¦Ø,ì&¼-a ?ƒÑ»iú;H:Ôå»ðX ZV첕‚_bÛÊ¿ÊVùy ¡¿<Š6¥hqÞü[\gÈßÞ¾/ýì®pëÁú°9ÿê哼Ðx<ÙÀÇ7ï_æî̪EÔ¼Îöz1òOبÉ?Û€ ÌÂö™<ý«ì….<‹2¿‹ß mãB“Ü~Rt9Úû¦’V«1q¯&O€mý1¬iâÛÊXÜ66o¡ò. î>Œáoð¡ "´I˜&Mé@ЍðJÚuÉ·ã×£~imë]»A¥#cZ…þª #˜kv±¥¢Ëß@‡éöÑ8e[$'gÇy‡à{7 zÁÐÝÑ8Aà’À]T—³ª)/ºãB–»#ÊËË3fh9E@ƒÄÉ{aùò©ø/,¨PiÌkŒRA){î½òšÀÃMÅé(´”î–·o«ñr _…§ÒRq‹árƒ©èŽ›Ü@$Œ;ݳ³?½!ªc”¿èQ“Gå‚s¹j¨›s¬ÏÑ+ÿM“RÔЛn®-±¡ÑÑ{5™^AŒc#[Äaçºû/÷(á6¹n$”áÖ÷eå“B„;úÕi¢bÇôlI¶£(¦ÓÀaÆ£–ÚmœTðâB‘Ì›¸ÖáÖV³»t6Y.-¨¦µ¯áÖ>PçÝq~å&ÍŒ“3;d™žä`cà ¯ ¦LÜ2…ÿæÝëÍ»ú¿p]¯eôÐK}ÜœBàN~÷®Oïq;å1ËTÞùoN‰SéT–‘„=qRTS "[¤0ñÄ‘káiÁPÖÀ–\Ê«¿cáa1Û1³ûâÄ2±ã@ûxò]` ½éû;û— %ï,qÇ hªÖìÈÇ.ÇæÛÜ~Œß»r5Þ,kÃVÌKŸid°ÜzñsÈ;(œ±U»Òû©Q13òÏé‚ð€$ÊÞ V;cĵ¯Yj H`¹Ÿ)ˆÜ`ˆÌU¤=WŽâë>‚¡øLdë€K(÷t¢’™Èâ>HQ]Z€FkmK*6¤$=í Øa0¿(`(ú{ḟÐñ“eÜp ´¦ÿMݘTùO'àî–c|¿ù˼O¡x. 1ÍoeöXæ=×óf¦ŒŽÓ ÿˆ5~ËÝz9¥ÔúG &€²Ê«AŠåßê=dP25þâ˜?qð Ë£–¯44+Óô/¸ÝÖ4¨é7Yjn¾ ø1’x Q&ú¤é+w ¡mk(Å»)ÊåïOCªÖ­œVš²%M ß—KßÇ`kÌÅ(¾†¹s#Q™d"NÙzùîÝ©ž¢±6>IsòË_ò =™1æÆ“7h ¥›OfÜ»š X«.—=K¾ƒÙÐÄ?Bàî¯\&Yï6å?£K²˜ö€GÓê×ÊY»üÚÝ| úQ3.HÚôÅ@vǶŽÚ•S¹ý±×g§ed^‡¢Ÿ]/¿[ÖÁ³9‘T.¹•ÍŠÆÿd9…##rùê¡ðŽ”ÅuŸ€q°ÓQ1K¤â‡#¤p¥A¦„g:kÜ&X³!Õ(‹_¼j©¢ºŽŽ•Íà¥I‡éå82—Ãý¾3áÅ;9½bfè† {>1Úw9çðéΡg†À £ìã¡ð·àûZå;ýí§OKÚšJš’=Ör'þå®â«¬šYú¢3~î²Ô1&I¥®hƒçr_îê H3LÊôlAhD¾À‚30±™}C–ÍW߉ÉÌã*fM´Ëº\+‡û ©Óð¯£/ôVþñŽuÇcÇѲLlÿÁ ¹I>ÿúëŸ7vÚü®¾¿øåû¼/ÎôoîmïüêÜmwµ%«A‹ŒÕº¬Ê{Aåo#§IEþ~ž Œ8K!Äݸ©Ôò3\¾~²¼Û2/>iü¶±Ñ‘ux2ÒPÖ÷aß{?mË@Ê@T†;A´¬#ˆyæ!Ï€ÏÊ_PFKð*%ÉOñ0û;‚œ ñ†O©ŒrÙ±@e«ôLõ«F°šÊ ™N/PÚÏ_m¾cÓà;:on8NÈ—«‚r‚ÀƒhÎ œ3ŠÿÌÉ€kŽ:+ð‰åƒSîxÅ¬Ç ¸að g½¿0ôÿLËsŠ ©è+¬#]#ªªÍ{Ê™fëÁÎ#ð¡üݹŸ„^hì’ÐÙ°{’¤ñGšæ)—:e RKCªÂÍ|>2«®?FÙªüÍ€ÌÀ×i^GÌl…G£¨Íhúþ~@0*¥¡Ë.ø†3 vs"éU›…»`2æ/U¡8ÆÁ!´¥Ç?7 SeÖø.ƒa¹ D%m܉øÕa‡¹Øå¢x$m¼Ò©Pé¥s¿Ç2„ÈRŒŠòž^¨¯†žŸsÍîùsnä;æ ÛÍ»~³¹áR©{:P‡”•oå31ÜOÁ4ÿ.…òôÂ!Šÿ„óûG, ¹Y°f‚Þ•·H‰%öŠ`åŸ‘Ö X9~ü«w¡68“¢KüÚ-h·õ1Þza_¨o†Ìž‘¶išdå'Ò5MÙÛ5“<+:i:ìÕÖø¦‡eF\Ki™þçòYÚݲÊ6¯ÝòêÐ VáµBBcN¡c}ñÍ7?wÖÄúÝØ¶ß}óÎ3¶›4¾:cÎÓæDÁ`MÛhÔ†úuëáîºgçkãò­†xöýáÛƒÆë‚×î…UÓöwñ(Y­¬10ìûa «ãbØ Ë ³-Lüu?fB㦴wîšîé¸rá6þQî“[’6ŠÂwAˆPñ‹}•0/ì­1Q¢JtLªs!Ê_>üÄ4 iùðnµ­iÙ ã”)ðï9ƒý ëµ7ŒèÞÝžm~`„ÿÂÀ¨£Ïœ%¯•iÞ$àˆ×-]„/§¼SøœÑ#Æ#Ö‡¹ið3ß¹\ˆŽÄ–ë[[ù×%?¬ G¨”•Åéc%Õ¡E)§Çdª¬J²¦ôUÎÀQ¤*Ê(ÕLÙÃŒ8$ÒÙ—7ªaòýYgã¡é²¯ýÇ4Æ]›ôy{f„Cæ>”Y–òl2uˆ=_ì ŒÓ ¹‰ÎHߥË1EléX7 å^>–S{ GùIï€6û jú*×l‘f-Tºgホxé¶¼[‘«ëîpIg÷?Ø[MgÀø:ÃP4R?pBĤ>fzÿ ÅÄeQvno?l®ß¿á6I.ìqæÒÃSâÁÒ‘—_¸6šCÝÀñûáR;\âHv+þ?Œ9›º¼‚ ƒA<Å©_‘tíš}hÓ„åÒÀ Ê}µ»ŸX'YvC°ig´ï°é¾Ö8íÝ_QµÏ<‹¼¡úWŠÜß}nÂVü² Û5<©J°H^ ”™ZЂövt>3…òUþéi%%&f„Î~ž0i~·æðû¯ßœ3©ËÝÚ•]üR Ò§òT ¦¡¨l]¤]¯Ìo\é‡IÅh‡ßÆÑ ±ôéX@“B8üÓˆáÙüÑ.¾vp¨äÕ1)À8#Wæ0ñŠiú8¦ø®Û¶8L`=üõë "ÝŽ]Ü!× [d7‹W"–Žþ!°•âV—šiá¡HàØ#øŠ“p0Ë(ƒtPNЦ–iøåC"‚çÄ;²ÔQBYyÎßw¬ 3ðv¿É¬€{¼v؉ê³Í„ŸØGpà ;.ÕùòeÆNﯾåíFÿ3|@‰<Ð)0.[F•iyÑV¾}øTâ2ÍŸ£ÄF™ÜÑžŽˆ•Qå©*Rã¨J´Ã0:‰(áDù›"]TyÂ&#Ry{GÑ%‡SÙµ£Ð³Þï~”£C!,™ˆ“³Ê¿xÄ)/i ÔÔ+|„©]™äÁˆÛIp7ÕEÁg_nsDå3®I' .4¤“'Œrî0ÍÜXhôTäÒZ¡ 9à~|ÃÔl³±‘°]2Iœ¡±r2‹òಠ›y„·"¾Úœ‘_[Öë?1›ñîŠS 7ýäÔÈÖé{’’νÈñyg{ø‚G§˜æ‡îHÙ ¹~ËdD¨íÐ+§_ ÔØýOûéÓÞÄ-†®%]%nƒGaò…w‚`ºÞ4 )¿A“»Ã™¾º€ö:«œúm†…ݨ­x ©A(ߪ ÷À;MÅi+Æn g7”ÿq[åÁ®Ÿ|šûÃU–9†b®0ù…& Ä+Ù}ʇÉÎ^¾üy`7¹û®ûÿø?}÷pz|G#ÄÊ]eоòÞ™¾HTmT2´ýöë×R€Ìxñ‡Yf,ô´3NÂlƃN˜må¾I¸3ºjXf`Å-x(þYäÒÃpªýJû”0šÆø(ÛÀ‰\þÐØV#Ž]ÿ=ùüÆ7?«1œ–Je®^E!Ž ~Ð÷W†ÍsdŒŠ10ú>™†ÀŒˆ~vŠè¾aÀ{ãŽXqx%<å’÷ \³yî KH¯oØ+ð‰{˜L&L÷ x‚àÂ;fî¸dè;¾·Ì^<çW¨Y7¾§ðå¥ü Ånå€Î‚‰©L(¯ÁTÉ §¥Qª#¡ƒÇq²Rö%ûÃÇUä l¦}È5šœðPÙW4M4›óòÛ¢üUà2Á_Ëÿt äé°Ú-ðÚ Â‘{’sQÌy0iÐø6ýV¹ác+™)ÃOÈ$½Æ àQYÈ/¡Ñ“œGñª´ó0Sz‚E’å†f-':Ïã—9w‡cë­zण‚¬(õÜ“€<¹®˜ÎÜ¡›ú<ÕÁÌ2\³©ïêÏKùd4Ë>_lçÀPmèï?súƒð8rÈÿ Ëy©Ïx Þ–=}Ö_å,/pVpÒ:´+…Þþu25ö.Æê’¯õÄÜÖø[Dl2 @ öô?„·™pgøªÔ˜õiQnçñu†GxƶÐ4Ó†–¢Ÿ)ê¢ /KOS„i …P´þ6†ðâÛ°™Óµ¿K›½‚vl+ß5”¶ƒJ¸…Sþ£îÌNÞ Q<"ì²ÒÙÏK» ø»p}ú³?ûpxvñ‘êòM…7²sªm6&Ö>}̳d«þŽ­G¿§ßÈàÒ(X¿}3`]Åiò >FƒGÚ[”7xòè YÁK˜-›² «Ïã—8ÊœöŸ¨ðIyÙgÐľ0Ówašf\.Üå!¸–°ñ?Waxg¶Æâ4›"Ÿ!m÷;L„ÑÍ_ÀP‰¥Ã0¶‘ø?@duLË`#itv³Ñu„Ç –Ž|¢ø;¦}ßæý6¾fŠÞ-½ž Pm¹Òü…΀Å®ùûtÌù6 n9Apt~¾9Vñ¹iðªÞzÒ`´ÛëÚ¥Qù£Œ­–t(`_þsý¼¤"•}âC“} 8²vê<Ëc¤oä’ÌxwüïÕ3ZÎcmPîðwTëÈ;XêGæô&ºZ‹'¶îàÿÖwçw]ïkÊÏÂS>ªªâ«\v ¤!NéP¡m‡ MÄVé«È“3.‰HCœF¸™Í”?ÿÌÖ(;ÞPx ãáQºýêçÀœ,¿ûÝ¿ü—7/Îxðá›®"f^g”ŠSe¨I¦¶ÛZ)Ü/f莀lR)šI¡,xsœ¼býšg*#Ï~‘þ kÙdÒøÊ¡Ð­üãç&øZ: îöï(´;¼Å%îñc8ÚÅ݉·~â&ã3€ï8F¶Š>Óõ d‡v§¿Ò[rëPç¾¶°a:!â|¤óБ©˜ ¨­ Eß¿^Á3 ?œ½Dà†øCx±’”7Ý¿:ã¶ÁO§õD1ï ¸Wà’©îZÅ÷Ž2ª¼ýÄvÂW›O ï΃Q³)På_)W›é°£øM­ÚG ->ÿ¨käoƸ~Àºº{ < à²@*||€OâéLd=±A6º9Qövu,Dðw@vÿ+£pødTžÓʼ÷D w]\I¤†Î Ò´ƒPá2a)Š;³ÕÅŠÒ÷îÂ-e± æ¬]îiP6wðŸ<ãvGÒ]-sÇ®÷¯7Ÿ>Ò #Ü-q?¾5í˜Q°øÝ›æ>·Ëÿ“öu0j³ƒvƒQBÊÎ(ÐÕ–à™Ð î‚A v“J3>åàWav¯äíÏênW@ƒSó“V{Ü8<óYIƒ; Ó0ÚGŸÑÏ h'¨Û¢ð?Í«QåÛö¿ ^ujö¥iÊäF8F¥Aù>Òc°æõãïc²‹5Ëß’nIÛ'ŽËYG'Ç—¯ýkŸ*y’†áÅÓ4þ{¿wýûgg$×/Æz6Z"ˆvüdˆ)Lp ,ñ‹r´ÑÍ¡#rd@°‰“u\™MÆx¥è ˜M†–(t@Œƒ¤ÁB«œ¥¾Né¼`Øwpä…æˆ:qŒü“n¨—#ÂP9K¤nvÄŸ„%Â*Ã\Ò,)J–¸øÂ]ôpFà*Bøø“@%[íp›¡ 4wOÇG›ÖÈß%ãçL‡ÂC™»^o¸îØ7/p×Òø˜CÒÁÂm„}^ØÃlƒ7öŸ¼à1ž3wòŸm>ÑøpÍ«\Øó9éˈßsù,ÁÄ0ðÅ5~edßÇá1ëû~sW‚1ĤñMB¬:‰Ý@ f£„µ?Û(“ç°Ñ28Ä]ö¢Rˆ¸SWŽEX<†h”i\ ÒC>ƒMñˆ —Rn'–{î¦èzfNJ+MÅz¥né«ó4 –ðp[‚:Ô¦mÆi®õm]rŸ©¤Ô4ÎêjY1þ×QTHÅ·ãl–ߢׂdŽî“gÏ>þoüÇÙy’æÉvþèŸÿóOñ_þ×òrXåL*Aš-ÝJà§²H¥ûSfö|¢p_ØŒƒs w¶ïá„|6¢¯ùg朽ø8ÈZpä©'€ß†aµ gP>üÌÊ0ü¬*U|@)øÐÀò“Vª‡bž£º„N´aYøwÃu¶¥,ôQp¾ªêC ÒvŒ”¥ÑXQÅ ’TÖf, ½Gšélcü¬ÆÎ¤²«È@8äç{ιÚõ[.„¹ä‚¡·—'›XO~‡¾bêÀw Ù+ζAöß³{ü&±_Àö pŸü±£Ù}:—næsÍ Íé„<þãíƒNïGiòuY Ê47Ðy3Ÿ×ÓéÈ­‚‚—Ù#hz PQè¹wÎýgÊ»á „W‚ŸÑز!.;öAIÇq™²§‰–FåèŽx;QîÅÃE‘å_‰ ¾eÀéL®E–Æ„Ì^:1vèìý±œŽÁ 1 xH¸tœXŠ‘Ìü8á’•SvòÓ±²ãqÍѽ«÷¿¦Óu•Žƒ ÿðÜš˜<„°6Qæ)W?ûô.K<‡ÙÔW<•1H-–a‘2”ò°€ø)ÚbVhþDZx­–™`…j“¢}û»pY…µà.ƒW»Åç/d ($(~ùÁ Uuà„d 5J“?öqJõÍXKh w„ BB²È¡Ü-]Õ:]ÅÝÜh˜Üç0S?Hó™1¤hÎkH]WI§BoŽ…¹ò-8rÙÅßðvFÙ¤ÿèÏÿœù4Í“í˜Ü™0?RýÒ¨éNa·M ?¶ÅÌ…ÀvÊJ¾TÜ‹™í؇çK÷ÆõJ‡„oÂ0`y*SónùÚ׎iü`9ªpV|¸IJ”5<ÝåßÓŸå1ÿ6c`Íf©»m8íï¨zÞå?³A‡²íÕèÎXeO“œÌ@9€œJ‹þ?§©°3 X¼NÓòZóÝ4Á?³~qV(”R‡e”TÓþ«îPLy¢˜ä÷÷>Q̦ÁË[®>ʦAT;£Í;çèp³wì ð&€Ï/™àr¡cî8|ŽÂD}fÁ—k…âz"”Zvº;Ò‡GD%"¹(ÊŸ€£ØÄSáTºN‘“JFHGÓ˜ììw'¿À¡/Ê1Ê_ZGÞÒ–âÞº  ›S4‰,þÙåÿZ£‡¿}±%ωžëþîIP²‡kö_À’cÐp|›úr„O¾à×} X);*‹†Õ”¬º»x™bþù|혢ªÖ¦í[HÅÖ”»}tÅÄ2á.îò^yëÆ…óXègv ®(`…µ÷‚×4»(¢M&‚5Û >[+]ר K˜3É8v ^˜æSÓYsXyï°›a̰ÙÞ\›\wù7–ŠKŸtT8yr|vþá¿ýÿ¢+H³y2ß§Ýxù2W0ÎEÇÌI‘%Ý$³:S+_z– -2‚¹’ÿdÛó݇éå¥zŒ„»í¡ži´«•33Þcþ3lâcü“¬Ãï4iÓY™ù {Ea¤l´™B¥WB ú¨™Ž*TÍÂ`LwÌ ÓÕ”/É0›¶ø.¯…‡^üpY,º×6ŽÁ~5lŽEÓôÒEb¬ MBËur:cG»÷ xí°O¿þtìÀ6ûõëúÕ GÐPM·¼<˜?7ª©Ðè =ÿjsÍ—KöÐxp ›+‚]ïÏÔ»GùS€"‡w6á1ÂÎM~ƕĮ¥ò°Cù;Uïÿl؃æá3U<;4Ê÷óø"cN$„±ÏhÛ;rï‚á¨Ì»Ã mhø²oàá f&Ò›’.þòæ/4pHáRÙK«Ÿ³¤…ï$á½ o4ú1#ýç̘œœž±Ïðsû×›÷¿a´ï+|PÚÝȽ|é9 :J?ÿá{_»üñ;ÚWró1ËIÁ%ÑŽ”ž˜ÚÜV޹}ŸëÃ@-³%„Jƒá“zݾQ …h†{PÅÕvkÄj„ÎnœA¬Z£u8‹d”sç6z‡–Ø'˜î,£¯;´çAò[hW´šðvà%CÁgÊâ´BVÛ9Î5þkè…ôcʆÈ}jBÖ´þxÈ]Ci¬’;±ä&@f©žìú¿éó¤;ÛW/ßZÝK¡ó%Rñm¿h1ÌtÿRÁih9˜•ÉF Û¤6í&?ñÅ-ž0S†;ôM'혌6ÁéÆ$rìÑDü"ÊïÎòjÒXbïâ—p†;Ê6ù'Ž“\s|µk"Ûp$Ý$jÓHûîN¼!IøÆ^IYºVXÿilp±…n|qØðÅŸ•DFc«7tæjÆ·éñ‘.¤Ëxw:’ç¦UÒ­aLGïð ‡âc1|$§Ý'¨ÇA>2Mw†Æ ^!po¹G _rÕw÷œ ¸s¯³¬MÛp±¬«ê,¸Ž…»›·›ÛíÇͧ\+ËQÂão¾Ý\ 즳?yÛ { 8N¸=Vp÷  #RPðêö<;&£æló¯ÔˆbOB å76 f­ßiÿÄÒù ö¨I‘ÎØÙúdºžðPÊ›Ã1K~’œÑ·£õÔŸVþY@ +òDdd ßMƒü«×ì˜ Cg ûŒ–kütxréL·ìÒ¿àøž·ôy>ÿŽ™…7l¢¼¤sô™€…Ôóü'ÿ$ ¢ÏÜŠ¬¼¢×#X'‡¤2³3æc²Éò4‚N¤_a†‰§ñI2 ÓCx¾X…ip§Ž` Lw<ÆÏ f¼5å¿B–rßùC_DEͯ–0<öq qf´Ê ‰ñ¢'òš°möúîóšÜ+ZÅÁß2W] «×5S~ÿê³Ò–«ýš®ýå×i×a¬ux¥Ò6çgâ¿ëWx Fû!W,*~ú­r6¦ye8-I!.7Y<»x²ï˜8OºpøüyžaL%_È[9¤ùØÊ4Ùhk1ŒîŒB Û¿d:–¡!–ünÑ­`Í×pCÓå¤å±yh>ñÐÚÏï€iBÓ‚é(-a 4Ü _wü'Xèp·‘gŒ8Þ ]ûGž%°I¾ XM«Ê‹"®JWß8ÆFZÀÀq´PÝÎÇZý‡A²ÚXÌÂÚ¸La÷N3+m]',~7)e×ÕIRßÕ]âUs;ü+Ép•gd”d{¯ÀG”Ûk_&ä"!.FUyÅJоÐRå‰â÷Àß_o./­>£3pþ’ééÀæÛo“øi‰I2¹`Yt«÷M„dñ¤ ƒ7Ü©lÒâî•Ò5Üñ—¦qfwùTc©ÿpG¹ãÞ7‘eûÀÛCxÇ‹ï‚ßLÀC&{µšXÃ| )¿MR²'{ŒGŰ ›MUìQ½C¢¿†i9x,üv)ËU8>Ë;÷¼#kðW^åk~2’Å Lê4QÒߟÕV üE*²Ù8þ­Ù ø9Õ×ôÎîè²™/™-xDø_ñtì F²¿D¹¿åý7×¼EÀÔ¸ÔnYãGmefÀ ñ;¢¹æïvËõ´/]àL;· >çuÂ/ìøÄcDŸ?¾'l¢Sç\\äÔwFþ#¿J³š™HŒP¹"X¥‹²¯'~FÙƒÂì„£éì°sÀátúÿ&Vxç²ìÞ ÛLëÓ ˆò€äξÝ||Í%K^ßëÑEÒôÀçw¡0ï¹!׸WÂyø;âi^—kÌ2ï³Ï¯2‹|þâXêoàýS”°¡aàf ¨™‹ aÃ4ÖFg”v¾M gKÓЂ%4ѦrØZÀ+,pjŸËàš`ÖO‡ß á^Bd¿vêî4iXHaÊ­.=‚Ñ!åÛ‘“ßZï Gwói´öÑÝyÖM¹6+¬ »îÇò·`âU®<†3s1ô}éæøV ÆÆÙuþÕW„¶´Oíû¤;Ÿÿâ/ÞoyÉ-ÕÌ\1SFÉY”C²Ê–EqÚ~»sLؾÖüô’g»óÝ 3%CØd:Œ.Ðí-…n„«=n¾a1ÉÓðÆÏ(·ÃP&âÒ~Æ+^>ò˜âO¿˜¥áôí1·AaªG ‹%áŒ8Vc9ƒþJSUW¼CUÔ0ªå Øû€ŸÑcðÀŒ[8Â& ‰q2nx.0Q„ Sáƒ,2ÍéNøÀ»èå>ð ߢ766ù‰ëYÂÄJ½Œ=¬öC¸dsÎ^_pOÀG÷ ð^ÅkFíÎ xÝÏg¾Î ¸”ð™ÙÍ»÷ü½Û| ,>áѢ͹÷ |ó  ?rçw °±°eÜzœ¯7ü)©q´gâf=vÃ-Êú2EïžÝžÝG‘›~Ù©¯?{B*u#kõúËn*ôA!»/™ärS£J5:Nlæ{¸§¢XÆ8yq–¸œ1Õÿ…sɒLJw<ÆÃ¹ý/Üâ—ôbd†‡?ôœ´ˆˆ2æ¦>¯Z>í{ù- 2µÓ¢•wUê*_ªlʱh¬«1‡S*DØáe;¨ÍÅÉOòŸŸ*ÏÍ]_¹—4&e™‚·+iŽ&¿·‹°âÓ8CÃlv³ØÏ,Zö”óx†s~*ôA3üv`ÁÚ#š`â–o¥‰öN×N÷‚I´ÚV*á»!cý »iüjúÛ4@–Œ-X0–ÄT+ú.MÍ.çH7çöÐä ~îTþîîîß°¦úÀYì4ÙdNFË*:2ÉFÀŒµ<$ߨqkE¼(SÚ›ÇLÊ’tò§ †;vœýíÂ$ˈ¨‹±%aÌ#útTôÃà„~ÐD‰ œL¿‚ÛügùÛO^é¬@Óx2_üèWÍ¥ÂÆ‹ŸFÑkµW£H"Ý1¬joµ"þú[Gþ’C;¡ö‡¿j°áß½¬!lmÖZ¹%O;P…ÖiåeðÃ$$•ã,Y2 I`¦—²éÀ#I^‚-l½ŠXPç9ƒÜ*gƒ‘¬ ÎQê‘×s íW\5û+ö ¼áøÝ›+ŽÒ@¥sç wÚ©VOx™É}ö\sdðú‡ãÍÿËÞ›,YwdÙyñwø´YȬbR%ÍhœÖ h¤æ|žz> B2“ÆÔ€4Õd%€™hÖ·Ö^î~n% *3`ðˆ{Ü÷Þk7Þ÷ÓÝs¿xÿÍÝ‹÷t  +/?ú…¾ú\g˟鸾ÏÛöüŽ~úÏõÃ’u­ô ¡ð9æü¹dÁ«ËôÔØºDÏâ®Kù¾¯_¾ _‹?G ¾ç]Žˆ/,ø×÷t`ð½ðûD_wäJ _WäUɯÞÓëyõÀãS=˜÷•žmøÇ·ŸÜýNW<¾Öýn[Ý6x¦¯Xrkƒ³\ŽC¾å€…°5£D@IDAT«z¾â¹ô^èk˜<£@w¬V”i±R¢®È;)VŽc”ŸÉ<°ÃŸ.¤Ø‘³ß;-£)x+‹­P¶åíH#KÊÀ°ö/ôà;öDÂ1W:ä$b3„zLZ¶6*|Ø‹F)d „ܼƒ¦8pù§”(ÊCšht¡·üÆØ²?ífð±Tjk>dmZYÊÔŸÔHBí-âÝvv‰$èÓ±(>ÚÊ’)g z­1þÙ?üÃÏÏì&þ—-½ó?ýõ§¿c/è‚À‚§²ûiB¡³ºcÀ¿ !O–GÌ¥±! 'ˆò ;hc:.ê´ò#¦ªr‰¡Båð‹a"g^ç`ŸÒsýÇoõY?‹o.ËÉÚ»›tCX[6ŹÁ4¾S°!'>^· šÀ}X ³ÐJÇŒ Ö“0< Ó®Qs4k"lŸ‘“¸}pl…gÒþ§q¶qÄ"ŸDä³û mšÙè9Îtsžo£K‚{Ç ð¼ïÝ·~WW~¥KÜouUàÓ/ô¼€~f¸WXF¿ÕBýJW¾Ò™øWŸ¾Õç“»Ï^¾¹{ª[/õœÀë¿úðîÝõ  ©® |󹞢ç`€K;zŽïð¯ïýó Àýè‘Ç9ò?(,(稅£J¬ã+Ü Ðe~_%ÃwêtË€û÷® O>ú«€´™Êœ¶óºa½^÷;ž%ò©~uix£ö¼Ð• .&|þùçwŸý†{ûº”¯¯O>ÕO)?õ/wj‘§=Õ`z/rÿ™®p8,@=Rœ`ˆv%ÂÂ}¯riTWy0Ð|Ú7f‹a:GÚã€48¸`TW *¼k‡èåç>:ˆ,úھėÊ=-1.±ß8ï)Høï> Yò±GŠÉðâ`ƒö¸¦ ÄN# 'ûþÕo®úWÄUöÃT½1&Ì»nõë‹\ia‡†1W~øó@ZéO°ýË?ãGCžè"N¯±µ:L¬)7ï2'˜Qé¢BÎ2£¸´ìx<ÆpËGvú(lÆÉ¶#ìø¾³l¡½taùfÓìaÆ{[Ïü…ˆñ;hÏ©§þ‰±¢bϾ¬ÅŘ¢»©YÒyNÑU±kþŠšÀcQl4%Á‡°d‚`³LõöW»`Ðð£´ãÅ™ÛG1F¢©\‘ËÆ„ÇmÍçõÅçÕe Òt¡eªÃ«”-£Ob—DKåk]àÁÁ_éªÀ7שׂ¿ÕÙöº^ÿ¥]ž§×—Ú´l?Õ¯~q÷å?è8¿ùDWtý½_èÌãý»÷?üPÇé`à­~íî­.§ë­xü¡¿A(?~u¯_Å«…œq?Þ?ÊÃspÁ@뻣å€@¾Xº¸ ðD(þ5?5¤_Ü#:*4gýZÌýÝú§¯t‰_ïäçàDÏ0ð5ƯôjÞüô·wo?ûTÏ9äý(Ü¿ç'výT£|Ç;ýÉ9Âå»û¼—_Ï<ÕNéž‘0÷¾‰¯É’Äht&¢'AIv× Þ‰1Ñþjë "ž“ •»]Ä„öAùv$È2®¡ ýØ&¼•ZâÚ<4ýzm¼ˆí*!&'=»‚ËÅ [ó¸Û4vÈlG¹ÇE‰Á#gLÛÞÁËaÎ0>Å´IŒ›ñq¥°uOëcle·:à%PÚ…”[§çá+[ÖUˆVd·ÛêDõ;sšg4d„ñÉh}÷£í/ROS­G—=ùå/?{ª‡£¾ûJÕ»ê0í í¶‡*soÇïÌQðA{`=`¬;•m1Žõ r“¡Ú›¼Ë64g¨æßàp½tÑ#èrðRúpŸ™ öÀ3o‹v²3•ð3û¨¡ ²-Orqè^އÄ\}ƒ NÕk2ßG‰KµiMˆXi»s6C‘KÌLp$OtÔå¤ k"7öºÉ~¢ŠoJcH>Xü!ÍYq*¢Ô'Âg*Ù<–™¼u‰f])ç ÷}Ýß~ÃU½'à­óúêwŸèÛŸ øåTGñêá×Â~­3ò¯>ýúî =/ð…~ëþ¹oèõ¸¿úÕÝ›?¾û†‡ õ ‚?|®³rý&¯°ÊÛ1×8ü!Þúç·ü‚îùûå‚ZÙ¸eàðxo€oèë‚zXA£ä ‡¾þ÷Lgø/µà¿Ñs /ô¶>^àÃËzÞê9†ß¿ÕÙþ3½ :Ñç6…ªïé‚î4ȧ^çûL·^èªÈ -þîSÚÝ" SÛKê‚“‘&» ŸФ¤s;CVAÄÙž â@’ˆïLЕaqy~0U4W{Œñf0âg–¡ZD;Ö(‘F¥%Ó÷ö,[›ÑµÞ8†ýªa·uP¿»€5%9‰7•´èaµÝëXy*NZl¦6àlc¢”6K›hÁ;[ï¾NñͳOn/‡ÃBîyFPËg¬å߫ߥQGƒ +cï}ôËŸVKÿ žþò—Ÿ>yG_æ\B#Á;ŸfIï°ô#Wc"K–Ï¥‘xlA¶tU@:¯µyýæåÝ/xíð7/ï>ÕÀoÿ\oä¡AÝÐá«„¼vø•¼ÿAgû_ê›|uîs] xùÁwïê,üƒ?ÒCºŠ ÷ |­«ÐÕ¾zÇSú¬˜Oü|9äuÀ~Wt`ðB‹¼~)—ˆž_?ŸK]Uÿ¨ÞyðJ_Û{­WïêÁ[]MøR_ßû»ü{]êÿìîkxðüíðL÷ñŸ°ÐëÈâ;=4¨÷#ê¡AùÑUgú1ž:ÛÎm’êÆøw’.i²¦/{ÁØò”|€é†œ6^ÊÒCÛFÓìTËäÉ[6ƒ¾ûPyñ#]ýò±a_Ê“ª™|ùX‹K~ÕÅïæ0–¦í[‹*¬ñ<æ2îÂ_Õ©ó†T×@çÖŽU$¯½SuÔjÅ1AÄMòÖ`ïÏHOÍ áe/)¥âÊ»¥ÁÜOµZ˜qÝ ≠¾¬U.œ%ºeÑíηsžé)¯>þùÀn«áÒ³>úìûW/§.|ŸîñdÅdBÎÞËÎɬlÙô´±bƒ1«ÐÌIÅ=@Ä3¾ºÊ× ;ʘspX¥6¯·`ùÀD°ø!­rm…:Q–Ú°ñßúÑ|ˉ\3ÛØxt8)U²³à…VϴоÏUý¦ÀgºµõÉçº2 ûü<+ %Ö7¾QÇé—ìõ¬À·w_ë7¾ÐÿúÓ»zpðÍûúªÝ/>º{WŸ?|õÕÝWzÚž7~£wø­€®§]Ù¼û–St|A¯,â×}MPÏèìü‰bäÒü;Šåõ=”¨”o´ }®ç>Õ%þßéÿtÉÿ©ÞÀWûü5DYú^Ï|Ë+~Uµïx‘^äEŸûün] Öª¯h˜µI{˜eXä&fdÜLÉ36°1Cu§Œ+ÇŒÔF»%6¦}LüÆPãÌßa$ЉWœ‰;Ñ?ÜhÁõ8¶Q-Nò§æX%õ[±JgÕC ª’S_<,7bZ>n‹¦®à[oÎ.`kȘ=a é•zGD©<òåeô7§*(:ô•šHÇžlH¼êa¨ü¼‹M‰.ÕÂÙY¥¥„qéïbl ýâÙ‹ï^¿ÖŽ÷ˆÓ£¾ðú¯ÿú­~üs]ž|ŸNòW›= 2HV¿!K_º«\œÄ34ÜNe”Tܬ۹?ëß nyñ:F—¾èiäDÃm-ýÐË¿{>¯£_ÐGVxÔÿÇúO_üÕ›—Ÿ3©®Áå ’É}&öî<ÃëÂfUNžùÕ‡Pò‚ ;žØ§Œ¬É¶¤—T®ò[Þ-](>kÞAÏ\`¤ë¢ÒÅÏ¥RÆ{¦Ñ¦m”ëâÁïŠÔ4ÔÚF\ j3J LÖb7=6ûc,kâ­Ièeò'Hê¢ÛŸrXË¥+RÿÈLj8ÖÇ×Q£„hÇ€ŒD*YŸ”Ǟ˖fS•²n,›½1׉Öñ²"®ïª¸:ûÓFÿ¼`è^0¤‡èþRgàŸégŠ?Ñ×ÿI‹·–bÝ"x¦«¼(X$©Ìët¿ÐÙù—ú†À—¿ýG½ªT—íu{à]]¶£ò‚¾ƒO',7Ô—‡ð8àЏTò ï0ÐsoõÜÁï>ÕÙþ·º·¯gùøŠ#‹{gdAßêèû[}ïÿ©žgx®8_èIþ§:0àê “eÛFIÿRJû¦äJ/­“Û&A¡ã6SÁMvú ­ªÃwR­ÐŸZÒö{àà‘Û¢Åky;ˆà0 r§+SVZ°eŽÃQ¬VvaXµ·Ñr“Ù(Í…¿µŠkî=Í«+µmyl]9Œ¯hTnÙˆG¥È#?£OÄêZ!<{ýêóÿüŸÿó£ý)`*ü¨¨À³÷Þ|Æʾ¯ª™ü™.ï~;3ùm{à«×™<4³uцôL׉¿4ùÁ»7Ș;ff@Åv¥w.ÜÇø»Õi.öŠ] ®Î!#–Þ· 6•Ï8-Ÿ:S_ÇŒ¬IvÛe%ׄkçÒ1ãÆàìæLÂkÇÅ|êK¨®d–ÁþЦ0›„ £Ó{ýÈÁ*8cÙ@ª~KW…Õ>^ ¤…T9<üª[˵¡_DÚÇt…G.¿XàÓ6ŸšÄÄP¯‰x(+l;´KÚ ^î+Wš‹c‡ÐùÏg »˜øQ©]æ%è&½Þúíßþíßò…ÚG›ýÀÝ{ï¾u·h¦xªÅßïm¿·½ãNdf!y‘ìí, ÷ž¾Ê°‘kÈ®rÚÄ×I£7tYM]hÕ§¾Í¿µQ%ê½Ny£cr0Ժ˧ –t‹ÛÒ­Î4cMZÞj<@ƒ¿¦úˆ•ÙZÞZՈܔ6Î;6oõ'pê¶ln3‹·d*b+e_ÛQXé:d«¸,ÞÀ7AU Ýéá«ÙPÙ²ï%ýsZ*H4j„ØØ~Z·åWÏãk9-ý£y#ßËîèñ-€w^¾~Ô—ÿ©Ê£?xúÞ~ ?WÖÈcrçဲ2böÌ@í;KPîbpËÚ;“Ý!÷$'Õsâԇ̉c0ò‘Ìúã ¬c€æ§LeW õÁ’yØetÂç¶ìÀCFˆ®ßÛX&¹vG¯ŽÂ+ù!>Upï¤áï-ãÆ~,À»tìdk† sDVÁöÍO•“°m“?èÁ´M«‚)’Â…M*`nsEãœh_‚qä’û­~᫨¹ZÄV¦ kÛ ñÚšŽ_âA6µKŒ%‰á‘|K^EŽ&)ñ/™Ñn+]û’1ºûÝ·ç»õðÞ_ò^ ü–· ê)ý·Òà'Š9x-ôdà }]ðwz(ðwºÌÿ•~}žêþ¿žlV¼:X/âMz[àw|䥞0Ðýœíó\‚£`Ñ'P‘­“(÷Ù%Ä>¨Ä®ƒQ®—ûYFM ]OÛÏÓ&º€¶!ÚwÔå0ñ†]bÝBÌŒ£‰ô>‘ÀN½å/RméõŒpk Ø®#›}xk¦>é¸ô©SÁ™niÉþàɇï}Bÿ~¯ïóp7÷T¹gÊÄÔgÜÿôÛ *~a%š÷žñlN}ÈÚédˆ@%yÀ k¾ö&Ô\ƾhXø§îÈÆDÖÇì‰kè€7fbñD C´ã«ýKÅ–Õ]‡cñßõÜ;©×8‚1{bê“mtƒ’Tš dG{—)†îˆËVÌÍt©àW]0B{xO¬-ѸtZS†©.Ûêe·w’Ó¶ø¸iw#†w´¶Õ”b+•ˆ?oŒdª ý /!ª|Ž0½ÆŠÇñüŠœÓPSIÚhIe“ç÷Þ}©#Ò®ý±n|þ‡wî~£gxõð':»×ûõ¬À÷ºð½^0¤øè’þgš¾ÑÇ?÷«o|÷¥ö!ý†À÷ºðT/t¶ÿL_åÃ6ƒ”g'ü¬ÂÄLUœˆEe‡”¢Ê®­«‡ÄmX¼(à’ûaÌÕ.⨜³ÿi3¡€Rõ݃©Lý4”ÉqŠ–S¼”"_Œâ¡QÁÈ©7¬½§¤6Ïñ’²•1 ­·Isü\ˆJFi³¾I¦Âs„S†ÝäqpÈÁÙÎðÎ}iõW••¿”¶À66™Ý0QÌvüÔF=tv±Öp4u¹‡oå’ÓJÉAÓ›±åÖÛc³‚ôXAíLâ¦N‰Tb3Lz.Q¬ ‰Ô¿^†¥¶xÜéÑÜ}ðÁ'ÜQå!)Jé @…9ógMëDáAOëã Äøé¼NðäJ¾ß¬2p`,èÏœ›q-@킽]fœ£d½qZˆrFÛ2êrBsàà) øŠs¶»5(Ϙ•à¡z ÷@—tñ˜ mü&,H’Ùñ*4jo¬·6ö¸„¥b;[jtqEéD·S[sk/'.qÍ·åzL»e.õÙ5)9 [ÑæjÍŽ6sÈ0v¼Ña;¼°dô-cúù›wýsôËÄ#,<ú€g¿üKýãî8~Ÿ+éÀôȹhxløî2OÔCf6Õ™•׎zИñ€PΠÀéé÷ÞŒ>ºxÁžã:xðo“12jól&¶…í {²åËÚ'Šè8®Kpµ`„ˆîÐáßB;ñíRÄi·;j-“3‰G íXf[›)W.¾t‚Š m@;“Ün.°©å¶TlBPñ9¦_p-´_œßôMÎzÏ@TFñHú„”ǓNJô—ûͨ½9ÍÚ„ŒqpËÕxieŒ „LïÝ |å¡BPIzŸÏÝ{úöÀ»zhïWzuï—zX𭮘ýƒòÒƒo¾ÖE­· >÷kzu›û¾,–…¿íÅ–];aÓ5"íÆÀRjoUž§j1Š#'ù HŠÙ¶2oÙ‘RõW¥OÜQÞ­R³1\¿•Ÿ£dj¸¼Œ›Ä]9¹÷"ÁÛ6ºâkKíêd,N×aBiKMÎäbîa3¶Œ¸·±ÊÉÐkÙf†wÂvKnGÝÓ'ê}ïõµ}µWªÒØ µ}•ü&°2ûè•iK2Z/`œÊ8è[Öö9:Ëʱá,—*h€¾zÿ½GýSÀÔöÑ|÷ßÿû§wï¿«û§šµù’©*ÆÓ~ Pe:¼}ÇŽA™™Óƒdè5(<ÁŽ&hð$öÒ‘›ž15p *£¦“V™‰£,Í×`V K¾‚’!éédî²øÛ<¶›Æç91x’ùÌ1j«n…º¸¹ò‹TТXyˆ¼hŠL΄ÙŽ^Rëº2…¨·Ö‘õiË?VÖ8*ÆìÅ»ÆZÜ“r€$î\•‹ÑžÊpKê•$ç0V‡@LRz‘Ÿv.›ÜmŠFÀË:±`r”ºìé5q Ï¿Ü¨l“lø(ö.ž=Æ- ñ;ÚI^é à_½y}÷Ñû¯ú®ÿs}à÷ú6Á[}ô[?vÀ{ùÑëé¸)-Ñ’Ù? 'QGňŸÄ6q¨DÌ7m ãEA!fS:¶1jû+¶áÁ´]Ñ15BgŒ¿¡Ç~ö¹GQŠê[V°ñ’FÉf§,AuÈ]Ö†¯À®Ã&3­4ˆôüyÀ±"ÔI—=Ý—úb“4ÂbÌ.ÄÍö^8L¡÷<vb]VÎQ ³Z+ñ~ØÇ2ã‚ÚÈ!LR{¸Ï­1žµnèå™Â˜=´‡µPþ€•EòýÝ»þâѬyäl€ÇTþöíçoŸ¾ÿ:³"ýÙíŒEo¥Ç²ÀLå‹#{àaùì\~ì»:gL¹±¡sI£sÌY®/uöAõ|Ȯ؎SòêÚÆ'NÛXCÆøìTÓáŒL¥%ƒ°(ûóD[1ë„3s½/<*³ì;v‡Édx¯­í Üܱ=øªk&ÜíŽÛ/¼Fð¹Øm@ ω¬iÚ“ÆÆ—•𥂈56ÃCt Å~Z—Šœ£o{W<÷²},»/¥ÄpB—®¡&[ÏôK¯uEà…® ð3¾¼Àïdàþ¾ðM©C©û9=ÖxãéˆÓžÑÁæ´<Æ/qíŒÌ-¤·‘xÁ÷nKÙ:c5qa¸ÙÌ‹‘áx>o`7Ŭèç—âÿÁP;m_ð|ëkä v;WG-f¦,ŠÕú.{VZÔrU;Æ#Vx׺®3g±z齸€×þ®šr?W³› :¼ê7ï-Ÿ­¼û\Æô–Œy­Z—<Á¶|/R¶òÔFζE¿âUÝ¿ù‡Gý`ª½æ„{mðHïü›ÿ‘OãÍ'šsuf©‘O_û2¨rʈéCrhˆ¦¶‚ò%—ì„Úüœ”(Ÿt1ÖgAP²ÜŽewòHövÙ@±1©xŒ¿®õ<tª×K!KcÇØÉ!P3:­û^ËäÙÍcV>éÆs¸KcZ/VðËÙÛÕ\*mFvión+\ˆâŒ¨ ÝúìÈ(Ùhú:‚µµìÎé²Û^4þm6™¾C~ë,ƒÚÿ–gë j€˜àʆÓQ®å]î%¢O X8²xx+Û~EÀÄê®ÃµW( ÉI< ×ýä«zª ûÇs-þà¾Ñ€´õañoߨœ6©‘d*ðÞ‰šèÏ”ÎmÑŽBZ# ShãÛíIY²ŠÍƒ–œÔÜe@â#2ž H4ºpÎbQù?lÔÀÎ÷3±ÉuüÄÞ^ù»vœW„)àL¢Ëj]ÝFÀCeѰ–viaÜ#\òÓÇ”ƒ·…mÛøHº bÇ:½Õ¼”ËA‹1’tê‰ää ?û×=­a0VNÞx<­WÞñ|@dPÒÐC´º‚öÅçŸÿü-€K#ý)ˆ_ÿúÓ§:‹áWÇüu*u~~l¥£!ý¶úŽý í5G³"ýìñ¥Iº‹«-1i#uÏëCï!aSe¢;y͸ýAÚª˜ˆQ~}ÙAqÈ=‹#÷²Ëev%tñO°$êB{Ê0‘XD¡4i|$ÐÙ²“n¹Ù’Žð‡”’îÄGî©ç€‘Ëß]<é3»žNcqD-|SFÞm­Ü—tñ‡œ:©29HhÜjE+ Ê@eäp”#¦µ†e ŒÖÙãi,Ì>غ6\bq\UP_ð2¤X Kìr/pL¨´ËSýðhlcq°6$áH§ÿì7¢ñAÊdOk¿ˆÈqµÝ•îJãú7"ʱ^ Cù¡¥t¶slÆŸøÆ¤>­óx­"ü¶õmýu`V½°°1"ç"O¹ãYŒ8„\*-ˆi˜húÎåÀgß ïì×á ê¢aÞn¥: šTDi$ÔšT^¨jUÃ{›úÙ¨ee Øß~ãæ¶¾ç~rÏEÂYì+YÛñb?bÕ>û0’þõ_>ú÷t¿\ ñØ O~ñ‹Ïït)3S2Ñóu@&µ9S2'Ãnm:wOÊ#0?3}¡Û´8#?íÍêàA߉mÞ<†N,aXLÎØf/ ÒÎ]ÅÎeðræ/F&0•³ø™Œù8´U'S1²”º»•QÌÀ¸b1ƒÊ®H¸h¦³SÓœ7•i}²£?–•±Ø*œÑ !têƒtõ·$46yS¤u4Ð’^Ô±' ÿò¿L†ž’ã$vùißç@BѬŽL‰¥ÉVŽÝöF§fÞ6Pt¥ŒÏè½¶âÛ¶7ÁÁÑ{ü„ÇRSJá¯:…L¾]W[˜%§`ëâ]mÚ0é+&â6s…ĸnÊÁY0+amB9è#0œ41Òv@ÃÒFdŒTNĘuŸWYóhצë§Â¿" Wò85J¹qà)HN¬*ËŽdÇìÊÇÂl±ìAÌÔwšÊw;Ôö¥Ïmîj£¥#³ýðk÷D…·ì»0s"}V×VíÖÌà*>óB›Ÿm2®Òžµ¡ç!Ù—¿øÕÏgCþ)ÊO>þø³ïßyñUV:"àl#Ce]Ÿž…ÛÒ‰zíëÐØ¾Ê ;IgçŽól+³· “ò꺊 Â:lÔȾç†*«}“? ´6|ÀP«TÀvÐß~`¹½ÈÏFMª­PÚ˜;\9 ˆÃñbWi—é" Q‘,<R+åG"y㬟äKéK»è‰zª‘aÚ¨½Å3{³ÄµAoiäõ»Æë@3Kª·Ú‡Ú´Bc »°Aü„ZlÎ ±5‰-ኟšÐó®òâHqÔUPÑ}&£ï¬Aq`FŒ!7¶¾Cpm¬ú´£íŒ¶§þ­Mm$È“Š.íÛ"êÎþ2öV¾1çÞD` — ¹Ç¿ýįu2¦Kþ°¢$A«¸ ßb@ŠW]ôû‰¨3ÝJoå`¯¼¶ï1¸ÔÙfý­Öé“28ì’W‡6»úʘÙ<öa>Ô¯ZUïtkvØÅAÖ"*ÔºŸ4ò à=üæÅ›>xôïÈþO <ÒôôW¯Þ>}ý’Ÿ¾Œ€~€ÛždÕt¡ÄSÎŽ³vžÖ}÷±“¿…Î| ëê xmx°uÀ§Ö­¿Ò3㮘¼cÊóêÛô |;Âfå”I'Ý6öð|0~KâmìˆÅë"$²+]\øºJβ§¾Ën¯¡Mê:¶g¡°ƒcЧ`oÅ® èî´vìèu¢¼Ä)[øYí®2‰lǽý™‘öKëë›5ôO¡;Ks|?Þš2ë4 J:àž0ˆFuUjNI\qÄ–º¬àU¶ŠX”Œ#­±u,itHfÙ(„mÃF{ôV«3ëÀ¨rî'6ŽŽhÂÃFB;óQ(*VGzÅ þxXñ[‚³J´í5…ޏu~z#š12†Æ`¨X­$öO*òŽÌ-™®ô!s?llµï€W)!.Øf©ö7êG7cba– g*ÄyôØR«[+¥;&@m^¬AÇÖ¦)m^43Ó/cÂ6¢aQW>æÃpA9É€ïñG<Ò‹ØFÆßyòìÅWï¾ÿþ£¿ðè¿øw¿þŸß¾|Ã;™¿û˜þ¡é}î:Ýäì<·cÂ8fB°ú0¹¬d¡6Èõá–¶}ºuÀœ¢wRìÌj±èÆ# >¬3<û•Øž¡cË8å†56âÀÒ| Ðþ8€2rÿo1>`2QN+¾áås25­ä‚”ZÒV€zQœÏxmG´M³Š¹¢VOrðL¾ŸI;A°måIöðýå³±áWâb’?‰Ç{Kë£3“éÄ@s;&変¬DŽ¿p<â®Äk{>_ÇëgKdu¾g[øæ¬‡²2M™‡ï@|«¶÷Ãw¦ÀˆO¿i°CŠ#þ)ÌØŠ õ3VׯMØ™v?'ÓeáqµŒ6À#Á´½L›eP Ôóð.*Ãõ o‘+¡çƒyÝ%HÁÛ-£íÄ’M໼€‡¸s,b”Õ$·ÏÅH¯NFjëØà6olqïv†ÛŒñÉ`Ëe¥Ä–rG™b]_Øuv2§~ugQ‰]»¶BÍfwÚ»_¾E•^¯ÉV°µKà–³qÇHRa¡[wnÊâ[ôÎ`fª°[{zãÈÀ¯2Öר9*+­Ìi³Q¼£N}gRÝ~jCœjµu]²À†¦!ï7jV¥b7ͯgÏŸ¾ýÿá?èËç;ÝL?³2OÞï³¹øº*}+_qêYçΕj‰.¾ËÈ)th³îÙš7ή“ ó9Çårùl€,ØþœŠZM=DO»“XèaûÌwâ‚¶tèÛ«'èqƺw88{gmÏañY›ÀaHÀå×¶,¤O˜6ÜfÚäRzŒŸ÷Ô3—“ç8b²i5±Ñ2Ï Z·/Ç¢ iª^ WbÜØf±îíÙCòÍ“±v¸<ðÕ|3Eþ囯úà¦%Ÿ­ƒ'zÔ/N3ÉfA¹i*=³N~Ë5Š?â+_ñP4oìì¸J”Ÿ±!Nþ ¨ÉÔ?Ôz/jø<È5ŽZÓ†Ø=‘'¦åæâ ’œÏRfyKe!Ž6]<HèÅ)ZÆF(ø_…=À(÷r|çŽ{>fñ™ÿ<àøˆ“xGž`1ˆÕøZíÑ@-ˆ ô žãÚ¢óN,–Ûzó.mïeGžÂ0¢P¾YÜ{À ½|ûê@À8v"Lªà×9+Ï¥sñ0­ÉO_h<ÛÄ™¤`>%ÎØI\ି©ílÚ|6=€á@%àúGÆÙzر?ш¡2:ÖVÅŒÏ è˜5‰ŒƒfñÑs\1£m’Çzú Ó„Y'1±ûô¸Çd±Œ^2Acãs `™´C_¶î÷T׿ƒ2ÚÄáš ­°ÈŒ0I£¶hT—ž…µ®ÒðÐçc{£PÛž¤Jƒ>÷ø±ˆÞX6¢NƒFmºú(àåÒm.íh³HjéPBvº öÛlñ{èLqe\0Pj“ðØ’p’¸ê°:i‹&m ¬ŸØ›ZX§c£·=ü]Úc‰[z"̳ Çvº°ù_Ú.ÄD<¶‡wâÛ–[y{jK-ú£ÀþøÝ·ßݽ|óæÑ?Hýö\õXÓ‡¼ípnÚç3Î=X.g¢ (±!(…›–ñAÁ  f<><‰ÖûÎ;Ï×Ýš Üø]þ·º!ø®~ëÍ"Î*†ë§ZY0MLüÈùôJ@ÍZ¯ú2ÛÝ%¡nwÛ#2‰i†œ-zwœé¤3;ÉT+¡®Ù;¡íŠÄ}ÂCiØäÒy¯°H;.U®M ¦‘L« “XËïDe])°0ûž»tQ6À½Ú€}Lz0X¢E? ÄG†íàVÛßÚ#±áçô+Òõ%G¿c¿à¢¥¶Å˜ Â=œˆZ$elð=eìÅÀX´ \|úñ‰°Ê— áÚmmÏ dbC¼ûÜvǤÛæÄaÔ²U°ŠJ‰lsc52 ã¢6  V*›{-…bK7ãÉY÷„áµ á±]´ n³U;0/˜xqyÚm”kÄAas{ŒŽ·cdÉ£ñЈ­@½wŸ‚$“¾` Ý”rÚK-¡µ5‚®Ÿû‡Û¯ýꄦ¿ogMfª©éܤ{ Ém;¸Ûž·ÆEžc³Ìï¼yó“¸9"5}´[ÝÈ;™ééx™e˜¶Âå¸ÒËPÞÁå×ÕÇÀ½A%gNëaȱ…6kÀaœ—Ý=/H¯¡8;ݰûàÁ€ƒá™.² =©¼Aö€^ù=àôšu gǘ€æƒIoÅ´iµ‰y"|6I©¢È²Ø!iDü4a¬`a-ªtÁ·EÑ4£›Rhï³UñI´÷Û{¹ß<ø¦òL x£ZO‚ Öο†W¥¡•iĆÕ[a”àúê…r?ÜVƳÑÇ+{"«–#SÝŽÞ a5xЖ©C&ÜH;Im‹øÎÕKZíNób§¥Lzá¦$ÝS½±ÀM/oé½3âö€eE7‹øÖ‰ïMïR$l³ nz•nÀnzv´3êåU-õß±-».uÛ@¨>䧃‘Ö)†À¬7fsÐ4nC=ŒŸÎÊžâ-¦¼SåÔ똉™Rƒ®í‹×û¥ÿS—s,lŸ?¤R>¤ÆºT*ùšì‚G¡<ЈÝÕ#N£”Ø:7œ ‰>·éÊï×N…V‘ù„ûw^½÷óÀmþ©èg~¤_eÒ¹¤VŒNG3鯸èÀ!:äš3B){«Q•ÐmY9Øë  dC7ŽЙDÛÏÉÇ?zM’­ºÀ †\~9sþžX^è#Ò©‹ŸÍ²èœ³´ô}РºphZ<Ì`•[þú (( >õŽ{l‚CÄÁBÓ„>jÀ½8 ÅÍAŠ(¯|h2*ä—˜°I½}@#Ěñoäö¹(h®(9HÈÅJÐJ+”Uøû€Ñq ‹µ@zk LüãG~{5©9TÂm0f:öí[b=\œ÷öà|â[/j´í$X¶¤åâ9·¯‡ øAÇÌXÃàs,Â¥¯I`pW¤¯•h ¢AíV) š¥mÒ›rŒÐÆþlg|( 0äÃ;c‡—8·‚±à%„ ½yá›#a´‚‹dÛ)}r|(ÁÉc‘èí0t訌OS|? £ÿ‘;«ƒS§¼­µlCÌ'åkߥn lz—b¤¶u¬m:^ÜÖÝèà»§Ñ(±\e’Ú¬/ Ó°ì¸Ú(^­bŒÛ 0·foø÷!QÀ&)!”§\;Ç;ï½yô?DÝ~Ï<ûëý[w"}C­”Ü]̬ê,/L0<«eÒõb2`2ëÁ††kblY"ŸQ²p», Ø5ÐÂö¶;-“«Ï<dz¹Ã(ÞŽÆÎØó•…Á#N0ÒGæ ÌÂή©,:ñžôðXXðý¾ s6;¡Œ{V9^»è³ÃÉ6F°׸oÚÚh.ówÊ”FÑÃ¥‘ðá_¤Ã¬âBÂñùÎTº {Ú²~‚¶’‹ÒL5TÏÄŠO~Ͼ5s •›çMb§s²‹gÿ›e* ©o4P¨ŽTŸê~ƒ»hú‰ÛëGû@IXm„¾%ÚŒoÇÑ[ãÊ´Ç…dÙr«ˆ¶õÕå<+BÛŽyÛ©-WÉ4ä¦aAéÓ P¢Ajñ´Øf"Œ¤ðË ¾¹"*IŽ;\w?³;ûB.J±B.V¸Ýæé™"¬} Ò.ŒTÚ Kyωl€›U™Á^­ˆ“$Loc¥I„À¥²iJ— þh.l’ó‡#Šf<+àÃ…åÒTêYuÑ6œÒäàIÙk»ïvA¬~je"’pK¶rµ1ñWlóØ.ºTraôo †o[^÷Í…½µ«yQ­/~ÒWc}í¯O´³¾óÞ{ÿtOñ2~ßþ×ÿúɓ޽»Óo›³@÷Ì÷<Ëéxd¢ó¥ÛéSúŒÎ<œÁGLG·ßÉGÈdLšÌd‰Åôï©rŒÏŸ†¶>“<`î•_'9C–ÓðÏXlFêÌåñ|µNZèð9|yñ× šՖצmÆÁÓšÛU=˜ø~¨.Ôyhp™Zˆ—© gEÅ£í¤¹O?pF¹²ëŸ øaÊá¥Z‰47z]š@éCÎÆ:‰cÏFwf‹ðŒ Ã.ï:×OqËÖø¸B(C*YE•ÑuبÏ#|C€äìÀ‡weÐÖÓlÖA›åù™†±‡¦Û|™È‰Îº_¯2ARœ kõÇÇ•i`–š‘‰S~$ðU‚‰ôBAÔÍåU°oÜL¶SúìêJ‚Wy8×-öúÁò¶·–g3` ®@†8xˆH«ÝÊ€ùP0âuÛñP­Š]€ÃÎ$ðgÚõ‰t1­mh¨ØNN»…·í…ƒ¥ µ‡"‹ÙÖææaåaÌöt–~Èˉy¨¼½œÒ3ªò‹LdpÛwy®çÉÝûÿ¥®:?þ4SÄã®È×÷woŸÿÅ{ww_äÞv1×ʳì6»$„ž'­¡ žw@ñ.X£Ä{ˆ ¶[°Ê®Zi›ëÌA¹“vÁb1™zB½áA¬²ÑÅ߃¶€:¥²eÂW|d;eè¸Ìtä6e/,`õ© ª°–íH2úgã}Ï, ”Dº •cKÙJÐ9‹_,‚ÉŽÝÑ= ÏF² ”19Yëp'Ç*sÿNyµ^t&R ò)þØš6kŸŸÍ°¨?5À- >crÌ‹t2Jø\ÝÒS\I#Ëotª[LéQr ‰iâö²7;J–Ta ³–,.‡Ëª Ð)˜òô圯~œ@lmL†51.7)tøÅl…cä_ vmñK\^ǶMóÄýû¿ÿIܸÌ;· ôXègÿöß¾egäÌ·‹?/Áq*óeqjštrVÊǰé`Ó‚uñ‡ÍÄaµi ÎB{†:¬¬1C\&íAè.ýNú'ïzÀ“‹|]ìMœõ» ‡ãÅA ½ÂÁ¹‚ÞdZŠ=Hà/þŠ£m6_!Œüº&gÏŽ,¢³„Š98P¡ ™ë§ˆT6ÙÆ}`ñ_jr²#.÷a^¤”ÎIú¡IÛ†÷ó#Ä6‰05-,œÃë¸f ÑgÙ¨¦ ,Rë»Xâ׈òª*š6º7èà‰&åLŸÞ‹<ö&q0‹ÜŒlùQÇpP˜ªŸ0»‡·Ž÷ ‘gòÔíŠÂ=´ì§^dsuølv÷íaoÔQ£Ìõ¨rÍA/Þ&Û6 >sú¹ŠÍ#gQוD^H‚Y¨tвàQÙ¦ï5ôÜR½C°Úûà]ŠËv %Ûæ›Žã°ui†Ï}H2/c¦¶v|”ÆÖnq¸|Š9QåÚœ7Amz—ɦ)Ý¢OLêòÍ…ÆXxõî›»ÏtÒ â±'OϽ/>þøí~©“Î:»”¯Èña!d`³ÐûáµAõx½uP]öav,†‡‚h&>žaBÆíˆŒ‚yõŒ®ré¶øð­ÓòÈü €Êžàð\¢Ü1X!åú-¿5ä®(}L£§Àò•;Õ_«u.ó "_,òÐn+•¡)“öD®Àõ–eÈAM"XêÓú––‹à>~ÞpT\87$²sª8±{¹§ï ƒÝ;¦=uÝiÞ³cÚŽ´OÛ/mÿÚ%Š”˜·‡Â¸tõc;cÌÑ„ãgah«˜\u‡.ÏûÉA+õ《vê¥ý¶Ù󱃗Úì–ɱ”«ô} @yÓR'>1ù”wh¹%l'T¦‰ ­ ´øñ|X˜bú«íYå¨nk€'‚¥7ækr¶0¼jÕªÙ6s;Žôƒ§ñå<Úh$†ZÿÃ¥ÝÕÁ„“ cÎþáÁZòІ 0Ý»1·<gSæƒÝS~S>»xSuƄط-PDøèµ´ubžlŸ® "Ò¶^±GtxµwÅ ˜¾ªf8ÝÖôÿ¿„…Öîa õ¡Ô€ŽÃ¬ÄõÞÿð¯~>x¸áþå¹OõNæ'ï¼ÐÉO&”Õ³ÓË—ŽîL)& _ÏtTÛ@IDAT„ÙIXGÅsî¹³v­œZz‚£ƒÔsŸl‚ñìÌL]Í‘)å […ƒ~´m‰ñÛ8ìgœ‘y1—бվœ÷¬Ÿ÷€Y‰b?, ,ò`.øB›Å}cha/:‚![·Æ¿$T¦~ 5½ØëõÛÆ¥<Å(Ã9ÿÌ®Áò4=﵈['†„‚)·ºgnƒ÷6·Wú¤jë–'¾Ylô1'OŸ=»ûà—¿üùà^«ÿ‰Ï~õ«Ïï^¿óû¬¦÷ƒð>¦ôbÇê£t—Ñb:ØgËÝ Òõ6Ø­Ö;£Æ•Yß™…½r˜ÆDº·°‘ à'@ø½Ø½l ß«^Ä%øŽ  voœ""ê¹ìˆ•—Yê3~š‰‰EÞWO«û %¢ø¡®|Hò‹k܆ݫ.0UF@Âv¾0#,3tJádU_\3&Pb󬂸æŠ>'ëU¶Œ¨0¼ßn,DX츪ãÀ¿ÚÔãgÊÀJ[N¸ Ö963Š”©e§Œ]c/•òì;[6Eeé÷ÓøÞ“½Åö+·Bb°F›Ãš²ü°@¥”ó áh hŠJÅ„ÊYå'¢<ôQl›ÙF…˜£a ¡,! n¥òš/ÁMa;Y㪷}™p\Ž‘ÖrÏ¥B·æ¡oyµ×\òB0I?ÛÏeÉ«Bd!Ü~̘MÐ)“¾†ëÊP8ìV§ûå¦ <ÐÑO;åšØZèí ðy¨Ú®åm¥œÊ·§+b[LÝ k5ùF\ÚÁGG—Þž=þÍë>øùàÚÄ:J+ÿÛï_¾â'½úð´úJê¿ÞwÓŸ#ÕÊôJ€T V·¯Â²h!º‡—U¶iV¾.À‡šÎ.”'¿>¤Ó‰=“W@æQ®- xÿU]W?Qq@€ÙÖ½ñžv‘#fnठ‰ª¡¬·xòœ&¶Ž‚Bv¦0”Ç;ïs vmÚ=²›Å› Ñ€›v ¢¶SPP׺͌⤥¡>܆i&ëš'lq#²v«´ä+ %­N 4*áÁÁù¦ö>|j bÔÞšqos­áŽ,zW‹P÷Úàb`â.?yþâ÷o>~ýóÀ½–ÿ1~ùïÿýçOÞ{ý)çšßkz¶&¨Äb¹.sïñèAçËä’³Pú``äô¬:'¶<ã«Gaû6³Wtާué¿BtÆ¥ËÊ×¢~àRÄ#Þóò>gþðÀø`†¢>®»˜*zWÛ*%ꊌÅ~X¢dS4²ÊÁ’Ü6ö,!Œ3É¢˜,øÑ7âiñ÷Á‚›ÔƒˆÆ¹Mî²ÊÉ‘TÚÜí¡e·­È&èÚX<Ê‹=í/»Â´Œ^ý§Œ¯èÔŽ®|6–ÓH±4 q=”ž¨#“0ó9áÕÍ‚. ~ ¨,SN›¤²[v±õ`,‹¥Dˆlâ‡ý¨ÐŠmyUgãõt~ÚkùFî]üàÕjágnØJ'ÈqtE@-ekÀYD&6Æ5sgnI±nT—±¸òÁ,|À§‚H§“wêWþGò‡Ub´»´Ô°ÓžCDŸîDË·ÖKƒ¾‹ném#Õ­ü‡,ž^«Ëø?õÊ'_ûÆÁÄÆCvbåa)uñòÏ^~Ë/Ð>þôÀüø*¥{\ß?}þâ3-SzIÃut§s­Ô§¦E¬Ž‡7U¾,ÎI=ó] ½xÅ¢Ò3ðQã³EgOZ:ȺwU©˜¹ž¼'&ô¬+bʽRau1zŸ}ñ¿XÁR+t2Y$o›¥Ü |°°³HwÑ_ ½ec÷̨S?ðUŸ„€aYÔŠÎ%âå'ê#ç=@´œ‹JŽïÒÒØÜía8i—½¬D-Ssð™°ëÏ0Ñuw`ËßVñDÐáE=9ÖLlœJCGxÒâlý ÞÑN#we޼øË®ú¢ï1èâï}`2°&8 ŽÚ`HÆRùéo‘8ytb¡ÛÔ,TðムøÇ'1YHž¿1ñ²_E·¶·V”áo;*áúVX€ˆZ!X»:&-¬BåwaCò”.6 ˆÈý·‘»d»Ë*¥EÔ”±c2qMi)ž|ëFŽ¢À‡ÁQM–6o¹QD7£þª¹û¯ÒÍAûê»ÛƒkbW± –¾Ål›×=oócÙÆþÈæŒßå“!ÝúÞÑýÁAŒ>?ôìÕ«Ïþ—ÿø÷C‰ÏTð“Hº,£#2VÿÝ¥7}îaÚʲ8t§FÅgÊ]¨DûÌW^¸jR:-za:º’aSON§uM×ñÑâ<É] b/#G½âÔ&L˜“|€‚ „M’» Ä«>¢BªÝrU9û†_lùäÈìOñ]”„r¿I Ñ#|h·‹äÜØN+'üÛÔÝ¿q^òòz€,í„DšÊ¬¯Ü—pÇR·3 J°‹£Tzà•¹ŠNLb…Ãõ@cùÃêb‘nÇf ï§F1‘ÖY§ P´±?ÄC€Øf»Kœ#àHctÙ†'•ÛvŠem ŒÍ¥Œ™a5¿øÅ¦RµBÚåì¼nÐil–Þ2.FC²µ /°íæ(µÍÀÆ‚… dÔÑ·:–þ@k––q˜Ó¦ËTÞ"ÔÚ7öÀØ› ®Ó© ãJ_©hÜZ¨Øâ¯˜+ULòŽ‰Ø®ìÜ+‘`ájú´ý½­¥pâ凤åg\ާ«U3؉¤6¯±EM<ƒ6º>| ÿüï¸ñPÄãÊåèq~í³?T§ô޾ú﬙º*.­Ûn›Ô—Ï%æÞô:ãGIx¬Rä웜Åß‹áðÐíâé]:¹ß-À%ùmŒL&Þéob^±Ÿ+]„}æ¯ëè7–chUVLlO eÛ×À* $;/ý¡>gⵦ=‹ïª}büµ4µ‹ÛNúµÛ*qkä{N9±«Ïi~º :²Y-œQ¤<&„s ©ØÌÛ~0´1pç˜`c(o;½ÈQ‰lQ?VãÌ_cÄ6±óp6¤øl'ØÄÝf0™‘gUot" NrËÁœ ¹ÒÒ*ŒÉ<œf.B›MtÔ'NWtÌÞj`³­:úÕÛÒ‡Jø!ñ´Ù9sªN¬67>6Bø‰º¥‘æïôrոƴ©³do§‰S8åZÍaH(¶K­r£ûT—.Ÿ<ú“¸üOÕ:?ßTóñ‘O>xï³ï4;ÐÜè"EMnwBcÄwO{áòä¢a ^ÏüYTÑGÎBŸ3îk"ŽÄY®RÆ”'ø{cI˜Û˜è /£g“ra/ÂÇèväÛç¬& ±u‘FÏö¶Šëk ×ün0èS¶#x~‚ê‡Êõ²×•A"U¢žÒôm ©½þØiñìN›<¸•‰¾_¦†AZ#ËŠ+¹Èé`·õ)R¹Mç:óx½úŒ?‰†Åî\8¢Šñ|b£‡“ɨ(’C‹I(ó*[«[Œ/%?ÀWòhYu÷9 }ID<е‰|@¢cõ &•ºGòÙp"GƒRѱªˆ¶öXw6åÚu2÷cO„Ù@ûQ±‰øÝ‡ÐuªžøÛKµ0×–7³¥[…”ÜZrxihaúÒ#¬¢b3+ŽêÆk1¸l®3Dذ‘+/†Ñ¼¦S585Plh¶·’êTÖ0NäÃ>6²6â9èHë1Óq:Èè¥]AFnÛzs‚}x{Z+b{Þ5Ù>ªA®Ïdmœoõ‹]/_ÿ4¤=~¿@Ež~ðá[£µÊˆy3º“éÐILÈ .¸³0/¨° ´Xý³Pöê&{ÐÅÝÒ3=úÞYõàëcs#ÇŽ“ýÄ&4gú>è€ÔËßɇ†eNØ¢¼Û¼ÓuyØX|â•/ø*cgÉT6->Oý#ð=oµ güû6'ÂúJ€p¤‘„cñaEN)1tI2HR¼4•¶E[èO` ;[kø˜±%°6`éÚX&D£@EG>d|MôÊB„xÎb ¦}sÛn’áßfp¢TÚ¾G@m¿ªàª#~°©Ü•íËkM1 *cÀ!¹u‘Ã?”Tž–E–T;†'*  Ðýá(SšØC,$:hU3âX¥\KäNÃ0BTBP6`FõízÎóµ¿VY^°ý>¿p•/'cZô WêA¯Àg¨‰”aC:T0b Nì aÜ÷–޼ÀÁCÚ¥ŒÕ5bE#mº?kp"ªStr¶õT›åm¯Ý‹À]Û­mì!§Ô¾)÷–"ÒméÇJõ{æà·åÄ¿mŠ.Ádb±ÃãÀîwßýI¼˜v`ÚøI¤'ñ‘:E½DŸÍõøî`îCÕ²ýzVøÂ+Q€â1Éúì¿À ¯—ñ9¸9ï3¦1,Ÿ·-~Ko\ðéM \p=+œ}Mª Iò¸-!ú(ZÞMù·9òÕ·ñŒu§º´E&[q×Mn‡.þˆÁó_3ýª´S4+ i§´Ý¶Çô%O¨¶„úªŒ9¡Åk p ¼ÓÞ‰'Â1®Ì¥*æ‘€X'9ûAŽÁ«ï0—ÖÀdžÕ#s}e³MËÙB1æÝW¥Ã©Mx“¬ úÁª2ùŒ«v·}C­“È[ÖÍÚ·quº£\ºfN^eäö|0Öø.Œ˜)´àð uþJ ¤$ì©V‹5\Ù@Ý6•)O[ c²‹í;»ÓÆu)}ó™1R[ð(“•Âsa•‹*—œ1Q ÛbìÔZòSºµNÌCö¯qlÏÕÛ=3µu]6ŽÒ‰Ùô-æJo O·í ï->âçÚŠë¶éÒtÖË÷ßÿùÀMÓüÉÉç} ŸgÔô¥K4í>.ï^;=4ýxI]]Ëç,µxËØÌ\Ï¢ÌÂo'‡AãðÝÙô”‰ßÉÕË@%+S“=õv±êïÎá^ïòg¡y îK¬ã·í°Â@ïÐ…?nWn,ñSW},ŸúPæl¿:Æjc³byͳhñÉ%ÿp—žl4^lX_›N6áÔú-…‚À1™¬j̪À)Ÿ!-:XiËÝæ+Fcl8*¶¡úÙŽˆoì,ÅÖç0c©Bj|¨BQ“W± Ÿ&O}É}¹=b0¹`¡ü*ªþÒ‹…‰ …6Ò RÃ]YÇ@¼¿óØ­¦Çˆ­Ö.r¥(cŠñHRyyR¡^àZeñ6Å Œ¹h!þB@UDC™ÇŠhŸéÃÆ9tѢ݆•!>>Àé§›¾ˆ¥(øõºFAó @D9-£e€Š4ÛNÜ•£pòZ®EòÝÓîp ©Õ؃ò Z¨‰±è@`S„1¤Bk"æ®J‘'…cͲ®ùŒ£2÷’tåÜóR§ÊWL”oèÜmh·tÝù-ä–> S¼Ý³n5néÝ®H•n1·ô}¯p‚bLl+ðB5‡*ç¶¥÷~Òý »,ÝFwÒŒC¼¼P‘”ï}O›'z ð‹7¯~?L»uJþcmøg/ÿî½?áf~óBÍ%éV°éá5ã«<*ç F9<‹µé€È˜Xm@2ΰDû*€”ûð8Oêrìû”¨H‡  'ekñŸàÖ¤N¼ž¼£ƒMìsßÜW$çÌÿ™.÷®Ø±MLøIæ|ÉG€ wžˆ ü@LYO@ ”K[8« ã“Æ;ÈX\ºÀ¬þP£p{ÿ®/Á›|•±+Â~e3¡† 2œjÔjGˆ¶1F&œí² X. ÂÚÞôƒôH‡#Ú hÛ€¸åÕàè@–E^SÛz§·éç‚1 ˆÍ(M¶ìeðmHñ5AL¶>§+"W»í V)¶Ð¡Ä§ú b^º¸žÁWÍö.ZEµ\‹Í;ެ;Ì.ªmæ°µå0؃ÁØ€U?鈴TNÞ²õoh‘1¸ôáp+fÝÆD] 9T\d£qµ1<Ü­ôؤS\3‘üضÚaÒ:As¡éÑ®mQ@bój è BßV)ñ)jÛÁú®y¨‡¶Û^¤Ûê•®.ñä¥^Û¯Ïì¤øÁ¯~¥«Í?”}ô'P—¯ÿÏÿëóýÑÝÝ×^•é= ®©á ïl²Ž5H[˜ÆxDLY<¿â¶2rÉ}5@þX¸Åò¸÷}qñ ÙñÉ} ¯‹§Á‘áØ¤äþŠŸh8ˆØðBHc…qÞâ1 bÃd÷ÇRŸiX˜‰½f,?m ' UÊõqpѶÎYG•Ý—c±£Ü]9~'gþ²å³ì ÀG©qîIúàÌÀïåA?°¥í¦ý|ð"’…ÝvjŨèß”‡¦´‘bö× ÄòÄ Oà­Ë ’9¡Ç÷Ò¡é‘ ¯u8¿oNÝÐIý¡’Àx¯Rn0XFŽ Qa(·­ßf¯Hë.64O“¹ Ô;:Ó&ŠK}±Ë‰†ÛHÆz>EÃÞ)\ø6Èóˆàj“Ø¥[ëa\5D›]}cªØzßÓéæ¼RpØ-ÔRïµ þ‘T ÉUÐñ„@åbS„ØŽ6ø;­_.yR£*­|t—ŽÜ8­0nw@C;öÃ$6­‚\‰rb¿æ5{Áœ:#(Îvlo@.¢E¨ÛmýîÓM”„ÞÎNo0bãj©TÇDuÀ§QÊIΖϱÿ§ö›%¡Ó•Ú¼+q¦ÒÉÏ-(âNìHòí!Ñ£ÔVýNÏ—½~ïÝ»¿ÿoÿíóÓöc.ŸSúc®ÇÝÝ¿þ7ou}ü:sÅ2'Ÿé–®L݉>ÏÄ1ƒhA¡,|fuT@èó-§õÃëwÜ!ͪ4-.Ú“¡„LÔ,:\æu”D÷€â¼½p‚.qFk‚mxßÅv±?[í5±£ÏgÉ z‰”P;²‚2vFõóŽÄƒæM$èŠåµImg»ðûÉö4ÂPÚüî ¸NÂNÑŠoC+N,@ôqŸ†lØÆº†ÉtÀ¶¯³èö×Ô†z?¨NŠUâû”su©ïáÚ*j»{éÓ3¸‹|ÊhðÄèhÄ:M$‡bçNû÷äÒ»×!£w: ëhòxu *Bï§m’ƒ”iÅQéXäØ].6±^¾î¾C'Kc,«“ݲJ/y?7«Þð¬]=Wqê_qÚÄÞÄÍ´ÑbÇÂi‡òI/è*ÜJ±ykw§p+½-¹¶²ÒÆÈž³åµ·íl¥èuæ·¹å=ØFêïÊ—†>ÑNýѯýóÀj˜?““_üù“ï|‘¡;SÑ,Bñ¡ Rwô9v`Ì$ë@Vç›´P&zkŸ=v!Gÿ,jʲ„ÖÖ>˜½ˆ*÷š"°@xÑdž™±¦²1®²áÃs½’í¶)À-“W?µuÊü]þiWó»jžo @ÏâO;Örm+_ .>EA§®]rŠÙ²£‚Ëmœ+ªÊe׌ÛÉaÉÆ{0ýTHˆõcµ‹”œŽÆïɲ5)„7’#ÖU¯̵4ãíd¢n‹¶£ZÑî+Ù?œ·Ø±Xu_9ùþTZtsZT¼ßjTË6Eœtû =lL÷£1_|½‘—çØ´.¯òÐ'Iü°Ž=ÆïXh¬ƒ‚ 쇜D~ë 8Ùúö?fÆfaĶü˜Z6êþd·ÜWÅÕmeä? y"n˵V»·û ø½€‚î‡ÒêO›Ý’­³£¤úŠÝxl¤MÐ¥~,?‘ÛÛÖ¨ßíu¬k¿|úôÙ7ï~üñÏ_ÜÍõçQÒ·>òæ•~8qs TC…1Æ„7óŸ©ìâ«PžÇØÐ‹'»™ìåB…þ(p-ä &lù>¾K¡yµ°¾n8ñõ› Ç|#ÀªÃëXw âyÂFOŸl(LB§eå”K?4ø‰ã¬›éòf±·9âÕ×}›€ ‘«œÅf¼:ŒêŸªà·,_0°±ú|HÖp Ó€%#δ|‚ÐÚZ³)~ÌAÚ¿ ÁlOеœ²ÕGɾîK_0„(õcÜñšf‡ÌÉ6¬eËÖ%m:½Ùê¯Õ~˜š¶“€‡-ýW)` ¨sTôƒ˜£ÿ =nLÂêñœË¢“J’™ŽRz±@ìEm¸©ÖU~•­ƒf”GÁ}©2¹ym“ÒÊSœ‚am $g ²œJ‰ßf— ¨`ÓVS³*ÔùC¼[ù‰QÒ,¹±§‘ãk¥³È{:#;íx’C·úŠÇWãa•§²÷ ô¶‰ý\À ÂAù\‘Jc±o×ùŒÃÝ)NälƦO9å $o¼„H9*Í’ˆ\ÚeC.›šYòêb8é¼,QóÕ/±Xš%'¡ŠC¬–GêmÂd,<”ΧvòLªXã½jÍùžj|Ó„4q]ÒZ•Æ‚ÁÆ/ʽ-_Fʲ–«qpnŠ2âÅ6õ…¦Ø¸TÞcq3s öì˜üäñ½µb»û)Ðv9ò~Z€^´toxòiï”"^ag¬”OºªäÁoNJ··õïØË(ÌÌuÿ›°ÝT½íüPKw´íµ"ß‘a¡]÷#ݱ¢qßËÙפÚ4¶DY±T ÙÔÿd‰ëo…½|çwïôÑÏiÂ?ŸíßüÍßüáé›×zAC{MÝÚEˆ.-{…|±%‡ˆÁQ²“К€* ?Ç£ÖcÄó‹‚Æ2ú¾J0÷`=Ñuq\ÞõU¿.ª§ý#Ž‹X˜ÓõaæR¬©“‰ÞCºÅ¶¾³¶­…¼þ™©­¯Êæ²r¬íÃ9hýXüo­ƒ<Æëj[ÚHLÌæàá÷"=ÁîNDbO"J×´ye,+xkøy.:Œ¯ F™ºÍ »Ø¤tÁ^(¡e<£ütàÖÈU1ÆØæøcѳ©¦€·ûÈ 3å“5뾑)V/±ÚBÛKÂ>–ŽQº‘6¾—Ä3Ä›XDr¨¨ÐG£ÜÜ*÷ ÂØˆ˜E7£‰m«àEHy»d™d¹2ÀVÏ=hð¤æ•‡»¶cváJWmW¡£&ŒÖ øÖnŒW­x)ÚYnî°;Áß·ZÛØm”'èxtO^#iDÍDéæ·üñŒ³IÛohÞjïlE®<ùò³ÿý¿ü—Ÿo´1ÿœò'ïñŽæ ¡Û.ý¡ å¶ãפ³ûÝ;|Iä”û¹Ôæì¯ôYox~¨OeŽ$ýàŸàþ:¡r_€¶eaŽYÆï¬¶WqìŽ ì$;-ñp^ÕæF‰hýk¢´åZ=À[g-p¢ºÈ»q,ÝNÁiñ÷Õt‹…¤ÚÌAB§“ "˜×Ñð¯†Ðú÷@Ùaå@cJd®£éLb̦œeßàmžL`å¢üÛ¤ØTÕÚÏÓ>Z[3 séæà]£ÍNÙiï¶¼ßm†k;}!_"áú‚€rÛlŒ…Aª],c½ —­Ûú" jù-ô“Æ"ÙÔ Æ€c1<Šnzå$äN͇éâ¸>ûÏ6$/ý,FYgrç‚ɽX/ö2Z»Æ´çœ‘Õpó‘íqhd6Õ;Xk¦â˜*ù¦Nåpƒo•Óƒ;T¸ ¯v®ˆŒXMiQ¨«^©íN~§5¬ÖÒ@Wž°‡…RÛå½Ûﲂ3ZˆiÓòÿýj´™¤V¨é?Ǹm'4 G¶ôRv»XŠv-,P>N´©/åÝ:“ŽŸl—ÿMj„f?Ã[áŒ/Ìžï(Xnd as¡Qí±\¶aÆ)'01+S4 ‰º¥´Úºb‹\§«ôsPmãSëäíìÚØÞnO¬xXNÐØo\Žç¤puà¦F© cgeÿ¦[¢"9ê˜Ñ":íÞ²dnÌÕhŸ-KÛÞY<¾R®HbI9ÑÕ+ÛBËE¢ÕÈv)MS­êÔÛöƒ•ú9-R&µuR®‹þY4nk<ôt ú%ÀŸÌ;h–slÿ³šéÏôôõký$p‚:ô¨]î՞џCðìú³ù ªµðŒš‡“ÆOëŠf,u˜±øSî‚oÕY8­/ùíǸƦ~Cg*-à-ö\PV„o=›c.;ëX˜{ß6]£ôñ—-• I¯uŠ,[髆k*ì±P‰¡Q›­ïà ¢œ¢ÞíÔÛ§ ¥=1=Åjƒ ‡O£]!uq“ãà´œôðÁ"MÂnÍ4G©!Þ £~g_¡é:/…h>ã•ü›L[;ñ `cÓõqÚmÿÔ4ØOµ»ÆÚ÷ha€ñNÞ~Ež°3‰VJ+¶[£=ˆI¸ÉÙÞ¦ôB¸£¯l[ɨžqP¦ïa¥¼ëܺ¾UŠ›Ë•+,õtkäUzÒÛ,=–ÇúÙƒklݶÔ5¦Ê·¥‡äÛ/øAyG^kå§Ö}ع¶ËUã!›'¯c&¼›ÑmSOîž¿x~÷Ý·ßÿd.ÿS×c‰<›ãq–Ÿüâ1£hˆh4ðnwshO|³ê^†"ƒ§è¡¡s.x¶/К…+«]h.û÷R?Î×U‚ñÍAo`‡«ü´e¹í–1j­ðÒ“§¶š}T¸Ám#ÕUDol»zö›˜ªÕ‰ÝgúG»û B[‡~÷ lKø3Åã§FW¼Ñ Ü?éQ¹“¤úا(˜8ÞBû]–ŧ|Ö¨åàuÐCÇÔâZz ¤w1öþ_öÞf×·äÈî»ßõÅb³É¦á–dy¨A?‹¦z½F?‡žÀ€fÊM=°†0$@–š,²Ød“¬*¯ßZ±2sïó¿E² Ku*ïÝ;3"V¬ˆÌ;sÿ?Î9fšDT­ñ·Gdò˜hË^˜í§ÂÊøW6yߤŒ%ãì|¥?ýlþj¥€‡‡ä½YMœáéÇ.;',H[ÃRt ›GUJî«zóŽþäÂeËÓÏa__4(˧"¼û¬‚ ›ìl¦=y:Êš«bvžhŸú£¢`Kܨ{¦ºËý"¨3z²#;ˆšu‘¼¹‡ÃU乄ÛѶ!Y„‘¡ìa'Î"Çät8X‡jtfûåÌ7×¢¤F‰æJÅêì@g„£aûæñ—Ö>¢éœY©%İL5:ò‚ç‘ýEwxÃër vvH®>è×õD¡r¹¢Òyû„·†¢!c‚n'³[;‹¢Ãüé³Ç6žYÅ7èæ²ã†±þØ{}Ñ=•ÏÞï>¶wZÝþÕK|ºp_é!ÿÝy‘ù| Ëó³)¯þüǺ8ìL3µ¸ƒ}kÊènt“™s–#ÉÅ„KñÕᇮ ‚g£dÿ‰Þb ¡ŒS±Uׇz}îoÒ¸ù,›„pTö]ÜJ)­Gt…®)œ¹Ÿ¸BYÆ„TF! YpùgÉe³ŠÚà}Û»3öü†CÜ¿Ñï:è÷à`ß÷MBp![CWe쟶×MŸX«´-n'2í¥ù¬äWWêÆUÆ*4nÕÁx¾´.ÉÉVŸr¬¨ã)ûþ±B¸¶ƒymÏ=Û¥ô»2¤/,q †¶ ý< <÷[ Èº ÷€ƒ¼úàš«±<0¯Âü8-ø-¹„K1nÈ$5¥c6·tü—Ï0Z®ÂÄš­3Üüñ!FãØyX€u›^ / YNœTʋɥ˜¥¨:Êc„–KPí_‘ÛçÚªŸ3EáÒ°ÔFëŒY=וƒß¢©>Úx&æŽ[̤pTW ‰”¸†3ù5v)‚Nþ'šv{Dö×r—¯Ö§RÆ ½âî£þàOQ®æ~ï¸=Qæ¯þü‡ú+Mê’Þ7÷`#£GÞü3™ÚAO„¿gï×Í_²©»H”h>Ú(Çá»êCwÚ—ú¡rYßÛ¨ðÚ„QÖ€'m~!‘êµ×3~Zý ËBÉm "_Šc,G«ÖÜÈ3öÆM{½»pæaøû×$[Îò3&U³(ÈåžÄ¦ Ü‚P§²NtòÚfDÔH[ç ‡˜ÍôPl²M ë1ÇâžÞÉž‘l uP 'bU!¸žm »üfJ :BâÊÁÎ]² KÆíV ´­GéLçÛYM¤'©ÄôM AíºáD{ɶ+²̧“Â~& ”ç997çDÊ›õ¢:!õZ)ȵÔ’Í4~›5  öôsû´’õ–ó5½V¶d÷ÈpÁœˆD:ýƒ¿ëwØaØ4æÉ[Ý¥øàî¶îÌ;2éo0ë>qlü)÷ÍþÌ«ˆ3ftÏç8„Ç+’æßÇŸ}þý;í¿¿öõO~ò³¯?ÓŸæMñÛÑÝ€4÷²‰i"èbúʆ²ÞG-ß=aÅÃ<æh9ÛèîòààX&KÀÈˤÆ9õ+oöC—9à:ú»Hìf[Ÿñ¯'Ò²°×oÄë”Éq4ÞÙ}Œ¶nv£…!6a£ÇË’¿· ºh-¬“c ë  í\e¬¾uóp3ºš±h·e= (4éWý’JÏó Å•æ&ð¤wã³£Ã#Ið ݉SÛâÚ-¹h¤ObXƒRö£›ÌgÌ¥œü ¦Ïv-‰«'Ì›6.Ób8ÍÈ1÷$7ö¨F š™(Ñn§Èƒ5 ˜Ø9Ÿ–D‘}øÚ÷è猃ûí0O‰†¸»Õï Ø¡is÷fk¦¬•Ë’º£¿êî½­\ß§QNÿ´·c¸=µÊWŸ²Un^»' Ð üµg™œE‚¢Ü1[oPàþP¹gXn¾Oöòõë¯?ýügˆãC²³T?›òò‡úà#ýdãïu¹ò|æI}sÏÅÏj'&‰T£õœíË ¼ÏpÌ®£ù„Ëî:ÓÚ@ ØÑùGOヸ¨ÎްÙX±î¸Á<9›t"‘“šy7 È~ã_ìñÕXªöƒêü1$|u{c§Hä2œ*ãÏõé²ÂMFÉ`L‰\iôT]´krMQlŠ…° ûkN,w—ÂÃ#¥qË(i6`W…6½ {WpToʉ¼ÊaÀœ8@OÊž³ÎýÌ»ÇN¤2ôù©‚x&UŒ#è?—Æ—ÇøÆÅ®CÅ×8ͪ’Óœ!n—J·q¬zëùúצ˜–7™c’JŽ;çu;ªÛ¤.1Äõo§ÊÒ°è/q7A)Jíz™§±¦€¬V‰¸Ü¾‡7öK¬Ãö´I¦ _f\5EO¶£s„1¾ïÚŒyUáØžåLÔSckЉµ¹ˆí×шf?ˆí¸K¥±®‘žŽÁéW™·o|î#²íÉà”i÷ —¯µ8½zõêÅ»Ï?Õ»Ìϧty~=ú»ÿýûòÍO~øâåoµêêybèõDV£ëuØ>ò‚%źyÅe]I+ÜÆ`›š«]¸ë1¬|$óölý<û$¬ÅRN¸PêSlëXs.æÔÕéPT)‡³;é™ÀàÁ¢cÓá!Kín:ÞÄõa=coj.¸#ɾCìÆ®ÉŸŽ‘ +Ÿ–˲09š•¸ä°ôñ÷[凿÷³YVáí2§3.*9™Ž©0Ÿ1+=¢Í'0ÈøØÐæ¨ ö(äákâ;ZžÄTé Žì¶j‡lø¶‰M´´›G˜"£Cnžñ.èK=|ú£=«žÕ/zùûßÿêŧŸü^߯âöÒß2Óç/¢Í¥UEkͱQ÷¢cj1nÚë—0n¶.=˜Á·ªìÅâ°#×fì![?2y´nü­›6æ•; 1ZW¿”ŸídÉrúÓLT‹^ÑJäŠañ+íbüÄ€?‚Ä‹¸w˜‰ÃŽC‘›Çe}P7Yu«ÇG%èM{:⼈ËÍÙ\±é¡ÄO€Ç½œãGxŠßµPmŒê¯ÁcpG4Õ£B¼ù@ !¿sœ—ßf˜–,J‚Ÿ"1æœj·Ÿ„ÝI‚È<8ð΢¾Bç3ö—¢¥ä’°Œ;:Îã¶2š×Èh„Ñv/¦#ub î¨Z§üšbýrP‡‹´ˆ½à{†˜ñ UšDv?+Ïu4çóAÖy`;úáÅÝe ÷*‡´ë·BUqØP…v·ªAÏÑs܃ë˜bÍ¢]}Ò~ŸŒÇéSŽD½[6g-Áµ§áÊ+ŸÌ€b©É8è‹vçK«ÙÅ§ÒÆÜ5§|¶OðnM³ßšäÄyrfÞè"~üƒ¼øÏÿþßÿj#?üVÖ¿îÁËüO¾|ñæ•.Ð1ÙX]f–­ÜóIJþ:c0P3\L‡æƒEq*á;d|K:ÔƒpÀ.ÂEŸÊ©£½d²Ð´°0ºŒ®‹ÔÒ½°$ÄMs ÅS0'ŒYÄC–^ùÃç·ý5î~Õ}̰õJxSNÝ´wÉ’°+áÙ?ÊôY æW©ÿ^ƒÚ{ý×¢m¿,b¾JP£³~%–†Ãb(hìÖ«}ô­ˆMÒF2GT¡*â>ésmªáeèÉU¯aΤ"4ê4¿_‚ökävÐm›­*]¯e<âs¶Ú“!1b‚–(2Á óAjýÒ5ÆB*U6­„S.G7˜ƒI–u£ÐôƬº>æC04Û8o)BPg{®ûÏ>QEw*Fߪ|»žÜÀ­c_i%Ò„V]Fê²…a[*×^ ò©;þ6¼Nl8¢9ùŠ‹ŽóÆäÚ\Ñg6µ´&çÍ€ô¸œøÇˆ÷kÉîêÏdzo?þèw_þú×ÏæÑÿµN¼0>Ëëô“/_}ò‘ÿ$°³æíi•Ë$]×U ý?Ö踿o7ûÏrµ2Àsú£^%ôKì|êFƒÁ¶à0>/q7ã¥U?° ¿âW{ŸxFÈ— ÆA•s³I7(êÉ«‹¬›?£Ü$ÔñYÝ™^2Üè<sœeËÎ}‰«¡±Rn'¡øÖ—¹D…©_ˆ33®:ì##¼´-›V¯ÂQª,Úˆr›†­mƒâŒª"˜Ê´UêÑ:ÚÆ‘v r#ƒÔ!±ûŒºþ«žñM¤¼µ¿¢ê·õ;úû¤ò÷NfŒ‘®uâV‚€‚\]3«l€OçxNJ{•ýèθè6Ä’S;O‰†¶q—•KÚ.e•ýz3/Å7÷äbÐÕ6Ó&}Ã$ —äE¾ë€£½êƒäLöéóî'OK|¢oŸËz—ë]û)ï¨Ñótä·=˜s­ESùôL&Å7n™ÒÛJÛúmù'ÒÆÒ*þªýS%g©“~ͼ¾øêW?ýÿàû€?uÿ[áÿï?û³/_~òɯú y2ùúVP&ÜÊ…‹º„ëtyßÔYúÃÑÍC>(ßÛ|äóÊûhVÜ÷2ʰ6€Ýø¼Ùéäk.ýUÉ×F:¬Ùãë¸Z˜´‘cãU>±ú„?ÿ÷I¾ƒÉ•H\ó¨¹6iaª üHLѽ‘—¹)çrðØkä»^œŒËÍ) 9EN3Û ˆêî°¼u©7ÅÙ\èÛzë¤!MÃ_Œä¤ÿÜ_û­À¹3øÓÀ‹2‰]åÙ¹ˆ'âò6’ks–G9YwÃáã=Wõéì.ËéV6n·ðïQ8-VA‘V‘>dÍ€Éþ:1·:ŒÇ8ª³T.¤¶Æºöú‹\<º¶7îÛEÕ«¬•±Ÿþw¹øG5áaí9ް6Nü‹éz¼ýÉ"œ[No|⇵–GQNopÅVÿ§Ô§oÚÚÿ_¼~ûæ×ýøÇß?ü)CùßûWõW¿}ñégþ“À\6ÿ\9“º™bÇL£ÙŠ<‘ý‚á(Æ~ÑùnÙ` 6|R¥}àO¾åó q¸˜«óêT»§-ÅšÒJ¿ÁÔ/‰éŒÂ;*·¨ãuòI#ÀZÈh2¿ôÜþ¹þÈ{pÅÇçþ3ØI…€Ýîw%ÃZœƒ‘uú°m(tðy?~p{œ©–}šò÷Õ\y€ÎEx8­AC^Žzòñø èHÇݘð^ÏzÐTÛǠܯØý|UçºPO©ªòâ5Z!ô߬G5+ÃÅU®Û©B=ˆà$­wv–ãD¼¬N`Æd/Ü¡ª™Ú‡j7×1t=®ƒbÙg”u‚;ÑhírØÍ1òçÊò˜Ë÷ˆ‰ñ¹É„œMݰÅLš¦ÅÚ$·0Vûœq.e³Øî´*mXëU{elg©½º“ŽbάžjÃP|{sÕFJÿÊÚÆDßq"ãµyË¿""%«êŠüû×0e>êk½{÷å—¯_ÿð÷Îÿÿ=_ý€€NN]>^ZÏFs‰Þ…€y5åhVõ'×ß©‡ßSü¢v€½%ï¹_£GÄ xƼûÛe0Û¦t¿²bõýeÓ?v¯úíT.¬‹»S™©û»¶ß踦:úeD§bJN“NðX6ê]Îwꇇä™;áxjwßM6A†ØÈQÑî™ö+%“WF5A'Àš²˜qRYºˆOt<Š#¾øl™KáßÞ×D¨íß®èøRHÆü´4,eÞ:ZøÕòˆã‘6;aÔ±0&ŠÄ¹üÀ#]5h׃ôüUeœ#ƒD7Õ©3Óô·ºFzûŽí„œ°€7EåÇ5Q™”ôÙFn”³>Û|à(O±åBÆV}kì”úEÊ9>ÛÒÜ7&ýQT0‘¸2‘aºG{WJìÉ7É4Cx(º‘µÂw|£ë9ØØÎvüΞ}“?àë½R!uŽ* à|n*èâ¯e<²0î—2敲]•«ŒÐ„LÐt¤1^i'øÇ»i-*Y¶ÀDÁîæˆçXm­Œãigè¹Éy°èe¡_}Àꃊs™„̹’K„°‹h±5î–ÃoŠ 1zÑ6™ásNÅ9‚*úÓÍa…¯Ÿ³›|öæQÀŠhE?ÜZÙ@]mC%{ ?l ;:8Ì£*÷§º©«¤´g¹daƒyÔjòŠºJvòi’º$Ìžú¶ë…|êÀ_ù·ôk|Š‹ÿ¶Â]NØhkŽ£^ì•­LùÐÕŸv2ŠGõV$ò5óhðÿöîš[ðè¿Ö:ðöÓOüîò·³|XÖgõ{<ôïÞýâÕ«×^0¿ñÏ—ëò±ØxáRÒöÿ´u梡î´Rs)«§Î‚Œ§Œ“£>èÁ4ëc[un5|Äuì±¹­•ÚÉÓv`ÉÔí¢dãÔ¦Åþ E“?847è^cèОé«ÙˆÇæ/ ,|Þà‰+›e5wn€sEÎlN+÷ɬº`[bÅÉ>ËOÀ`ÅL-ÄÂ8Êëµj›±…{\ÆP§Žý5 þ\½^o›Ï½AçD©-Œoc «_X H¹pÄ5çȪx¶9s.z¾nAi—3B„^ÅÈG%ù>þo×îÕ8ÛW²íòÏxrm$Œ´Àº!´ç ™DâXë ÄŒøÔqnÉ´üææ†¨]\ºY ®{,ùd3ý‘DÛóQò¸¡Ç”IFCÅŠÛ£0ÒêI}ò°û¿œ±Ò¢wm*†žîd=¢rëŠéÕÚÞW<Ò†úb;¥ÄÈy_‡SÆc—ðÆŽ6>ÔÕ¥W‰‘ÜÁÅÚÈEß³ÜÈÝ*ïÖк–ƒ¥2q.ã,Û޾øêw¿{Vˆ>k5{^åõÿðÓŸëqÍâ‚ú6ºÎ˜±É:W<“/ã0ª·sqŬEwpØ‹¹¹^ÄG˜»®1.ާP@“- ö€jGT»‹Ü=ÃLuE—3.=ŒW@àbư*®ãìg-r™Ŧe<>GÙ›Š8 HæÎÆO;¶ÖÒMS<±J"fsŒaÞ0ç1\¶zÑO ’WCX$Ĩz~|Çõk{<°`L0¶ŒP÷ª#W«ZéÊvh×î›9¨ëÚ'x³ylìæmT;“;Ç (ì¯å/Œý¸¼£¶2’E³ËwB?”!%yÕ¤A¡šçD·»_i²ŒËøíùkE2>šò)Éa®ãiÆè‚Pã!¯\0ÊVíV,9£å¾Å-Öƒ£žµQãM]Ýf,z×'¦Ú;>Ù4«“·ÑâYÜɳÑh{ý6âç°ÝYˆ{ÕEjæ™gWüO5úÇ×áàÜhiùEåËWß?üñCùß ùç?ù‚5å>deJð¿«))Eu^_Oœ^n¼бùÓ>e@¤|á5ùõTûIÇÞÔ—}µû•ï€lÚkñ“nñô)Œ1kn@û,¾å•WØ¡7Ñm‹ä¾Ï8‰Ó97Û:´Nvž“sÿåE+¶o‚jH”—ìÃÔ rMƒÃ†_ò3ÜÄÙ;jämséØ& §ò’ ºs’M)[ò±@€`ræö n'¯Ôˆí[Y_s1¯Ëeƒ6íjâ¹i@IDAT´ñ&äÖÒžù ;×$ ðŽè–ñ9(–Fƒ~ÑU ¾%ªÝ…kÅ•·h°q-K¥¦ ú‡Å¤Ú¹J–>þÌœý bümDW§©´Ò5÷3‡êØC\2áœq„B%\%,”&q¯cÍùîS¹>'íÚ£ßq7®(É”3^ ƒN+íbðN©~(¥¬{7öêRg<wß{aÌùµê÷8nM[õzŸœqh$ÉßøèÏ~øì>Xkâu(>\éíOþBH° wñÎ#™ëªâŠ;s®ð¨c|tèÀ—ß‚<‹ku——óãFSlU€©oòÚÔdôöäJë&dŒÉ,…uK4sâ0ví¨dƹ¢ã¹T///ø|üÀ[ÊÝÜý*ÌÆèi‘k5q¥óÛÔËÜç÷ÜΫg<ÁOD*ÄRH>ÒÚzA®¥‚8ÎÕŠäEoÞ H4õçßRĸ ªÃ5ɶáP§€½!%èêÀ¢ÙÌw7ayd'ÅQ Æ7ßYàK²¶¼ÔÛ»ZxºØÓ–$¿àNLlkŽÔÔÚŽ:Un äcP¬–®èv?Й½·Vì×ó±m˜0y7X4g*ç¬\¼RÔî¬a'wó@Û¡GIu/§îÜTÉëèÁ‘Îéruí zÊ)·Ý:ˆë[£f¤7s[Û£‘÷8öê4Fåf‚ží_â¦u™ó¾Z÷c-3,)w¦»þ´ÓëS®ôîóçõ§€ƒsÙê˜|ÐõëŸüèg¯>Þ8 ºt^ÑSìü°tÍɺt‚_ðöÕÉ ðY‹˜„ ÷…¦]NÓò9®VupèVL(¥ðÆLû¶BÅX usd²ÕäXÄÖªë›Aæ|¿Ÿ¯}EO)•lf —ã8úÊ¥Þ&oñçGÿê«´”[xç­ôc#!^ÙC—œ–ûj= ¹¨·ï3“«{Ÿå!°ó,*‰çN;ˆ†9¥¶wßïèzù×÷>J牫‚ÐW÷×TTÅCÆ+mûPͤCzè­ÇmH ¤ÿ´­±Õ<«ã Ó/íÜtÎæ ¸ôÓv5¹{ÌFj=Øpmâõ¤VÊ~ª³°­!þ›Ïàô…؉1ÀÀ¢SŸ¨,¥1icrQÃý‘°tcjuÒœµSÇ÷Î0÷é ¼daõf±Ž/|µ·¶ºÄ=e4ÈAÐnNá»ÊD*æä<ãÏùÌ ^Ø`)Sb“ù â´oÎX"7ãêNŸèÄ©¹Æúä³ÏžÕ¢—u1þ°Ï_ÿàG?ÿê“·úéúᦾ§©YÒ/•yf=ºêêv'Þ#óEwäww”\tÙ'Æ9ÂÄÅc{@÷øJéêõàJ^â”°µy%Tö˜$šUG¢^¤– ¯n/^ñJG›@y'@MfÆy½nSgQoPáת/b¨ø•¤ô˜²QÈæ0ø9‘ô_œþU½½®˜‰?¯jé-†QÉ+ì´¿ýŒÇÄU“¾±ù‘ï²ê¥óþFy´ë]‰ä,.È*È,P0‘êþbä:í‹ÄC-ÀÓⱜXÝ_%‘C ;Ç´jËo5ŒK”êš„®M :£;eY¸ˆî< äˆFሌI¥c44sÍà hÑ›Eeüó`Ìg0·`>¬ÂÅEÚé|k|ºµ ËP—;^€Ò®9]ŒjxjŠEy6Ò‹Ãqy]Q‘šdñÄhêFº×ÅW¹ÚdšÛs¤Î]{ë®íÞ¨aÇiŒh6g¼8·”£¼xß<ÊÒ~ãLó¦nL¬ÊÎîŠm4ûpïëÏ˽ùôóï?x4ˆß%ÝGÿèüâå½Nü5Ye‘î,ðÞµnzM fGgz•û„Yf·W–ß&›‹sdâ´Ô†©¥°SçXg|6¥CîÂsïÏ–o‘* àÏ@5+^W,ÂåãdÝ+ˆºe›tª­V.Ë7 o¿UŽEqVÌôt½*Œ8ç<XÐ.¶?"†] >ú Gv:·ÙìœõÀТmJë´Ï¬mÖ):8™–Êsé.;‡rÏÝA;7Â6ަȉw5rDžw/fœ Õî#Áðžý°]'~ã~@H"1vŸóüþÙIJÀý“8¥ØŸ¦0žR¬‡hôhÚ-覣® ñD Ö±HÙ˜m:i5¢&T†ù$±Ùš¡yhÇ'Wð8 Ÿl+.yêÈÃݤ}Ïš:68¬æDA¦ ŸO‡aÔ •Á“ae<Ó‡2Õ³rkôm“GKÛµ‰ÌñØNØãµÏÑv“&ÆÆ$r°XÂÜÞdìÑ7ƒÖésôÛ§V;ŒÏ7ö ù”j¿Ì‚…(²u²-ƒ2ÒE|ùúÍ‹·Ÿ¼ûþ÷ô|Wëßü›ó«×?üì·úú”/pß2\SNWÙzîVÚûÂw¢l]o ÏஸppT†Éå²Ì ‰À:̵1¾¿àS®; 6ÿ'öQØ·q¨­ :<ôòx™¦–•øÀ{dÃ͆‡Q»PðP9h£;ÑlŠèg_£©Íd;±Ñöá`©£Žmpei¤ÉnÈËüIÑEý1dCPÒŽÕºi.ݾ”%)Xµ:È×y©_!HOhXÉ£p<ŒˆK5ÔÈ;~DYyWðÄTËåLMІDê9ˆ‘È{’I³Ï•ªu}‚ ÿâÜY§ËòÙýÚ}Þ‘..£–ŽR¢m¶È·\¹ßõÀÇ?ýé÷t¿«õoÿóþÕ«Ï?ÓïkÖ%ö«OµzOÒ\ä=mžö$“eOЧMsÊYÜúÚç"Ç#¦Ç: 'œ|+Ó¾—®ÅµyÁ-H޼:uüø €m»Ö‰Õi‚PyÁâ–/8-gaoˆÖêÁw—«1bö†pæØ6Ø´Å¿ò›F x¨˜9³Žå{îŒÚigÔ;ùß(O—¹’´ûý‡ù*? ºÛå1X}GÎö€òP` Xz¼)C*‡sޝ ï=í‹&ž»®Št\okq9Ý µ3×£FrÖ1•ÎÁ6fS,7T–Ñ<Ó<«¡ñ½E{Éj‡)ÛÅé³Ûk+䆓‡6lEwîE{¤*@ïñqI!H{H üì0\È:ê6&W§ŸÊ©÷™V9·ÿ]s2UFlçÌŠ|2ÄʈÕ'1ƒA˘ñ¯öp\#mÆ âAÏ®~õ ¾^§ºæÒÈxul¾S›1<3¤}—ñhÌxsÞ…wÌÞ}òñoÿë¿ûwúSóÏ«ìõâ™ôëõ_ýÕ¯^¼}ç>Ÿ^¯Ò{÷žWZ}F}Sy$ÐÝõLëtêDª|Ç>q~p˜?úäÏÚOâûÕ“¼úÓYÞÚἸuÜ禔ìWÜ•ñƒOÿ^Oüq™DCbãvÃ[ã\ʼª…ÔÑúègëXÌ¡›ÍôÍýC¶²u*|)ÍÏ+ä¦pCcLiŸö~ë½rs»8ÈøšÜˆ£é:2Iì£)¹æà W0R¦óë¡|à^o¢ÔFý¾RLujáÉ3“¿oá$à WB|“*V—µ–Ó†ZÈCÿ» »Fä‚’÷©w@Œ”Ê‘Ì{Á¿™Íh9ú^›"J:d bÜÈÊPO¹äYåY¶.Œmj—·.<7aë8£¯ïnlݲ•@µ9í×Þ¢sD£âS™z{ðà´}Nc9v>X•¼ñDJ‰5ž;nPwùôÙ}ÙQ±÷Zžqwçqfò(òöÝ­fû´ͪÙn„rÑ9½y÷î—?ÿ/ÿåû€Ôwµþ_÷»_¾üôãõ'ó26S Z'¦j]ñ}Ñ÷e_ÿнO*ëk|ŸóŸ¨'Fã8÷“¿«úÁÙ…èP­fµé°´Ý¨3"ö`>7 /‹åâWÇ]Å6¤-×ð‘žs8òì˜÷¶7ó‹g{(¥A‘C¡<μ°÷·óók/°Ò›æÈ!‰ÍƒÀÛ8S;lµ@üÎüf—G€È“Š_QãµRŠÚÏ-‘ƒóØ*Ãýf=Я·Óî‹„#÷òf|¤ÔEñæ§¹†yTӌ a.°‹ªÓQ2âe^¢;0L+Ê¡ŠâÐÜi¸zì+3î‡?ðdµýàr_Ü©ð«¯jç^°c»¨¤£¿˜Æ?ðï)ų¹vëê¶XuuWŸh«cG¹šMÆL¯ÏÙúôa͸ý£ßr"ì8å ¶mkÿÑõ ïLwV›}·ÂSL¢”/¨3Îö£µcÑfn¼~óæË7ù—Ïê/ÒÓÛê·ü³öϾzùé'¿ò²Îg7÷«,Ù“‚“Ú5ŸuÛç( ëdªþ”Y бÅÿ‡‚{)ʡ۫ýê'oÛGI4?/jzI~¹µØ æ¥e½¹Í¨y7¶ß“†  FɛБ‹UÈÖ„)lO®Yݹ >cWõÔ§”pÊyBø­óæ!7?hàSiJÆáúÇ–,|âfÄhë ß³ã3©e€ª¶iÃáÍ~:“[³øì<°: — žp_gìió§o¿Ó0tþî²77D—³²Æ. é4ò-×u]æßË¡öš_ï`Y6bwkñplf°;µótêƒ8q—r ÚZÁ²ùã.8ÁFŸ('Ý­m±º#Ô}J ¯¾7ù÷è0CYZZi·Þת¸XŠzÊ€&e³6B5éõ)f…(ÉÊ'¹5/ ø²ÖåÄÔ«¶SÎ Æ»>›u{¤‚ÇÐ;ƒ;î”ÏÌ’íi¥½\³WïÞýêßþ‡ÿðýÀ}˜¾‹òËOó'sa5-tWûK\RD§ºwât “{ÛgßN]9–] Û„ò­>Ól7¿jˉìv7ð{‚¤ç³o/Â`û#¸ëì‡*ÒÉ>(9Öæ„‹¶ùdåÓÒ§…Ãb•üó¥:êÃH/ø2\l ðâ•3í¸Å6ç‘|¾õjì¸õÈ¿Q¬wÒCwø:LSnªX,ý/‚õî#!}ššsõ‰ð*óV¿Tù“¶µµÊD¨:^­ÇÜþúÚ çï)€ï1øþB¥öÉø ÕÊ™ñ¿~îÿT<éºèJã3 „²oÄ•C_ [ËØ›"ÄÕ%D:¤l\sß"Ðé{2-88æÕDºðÍ}4mC¹ ×ùˆ}txv_+ƒ Íbݢ΃ʴ1ÍÐí‡÷!ìCʬ8þÚïˆD¬S®Á›ôHüâð.éó +§D¸Ê3é®.ä×âZoõã§iŸB=q!51 ka\À~…]¼q÷:ßä F |·„1BIni3wí‡Í>Œ†ò΀±àt‹¯k•éHôö Çå|òŠÅ†Ã¥ÿcžð!A—Ö1…¨ÔðŽ3ãQlĨ ‘å!µþ (ÔÛÔƒµm$óßÈÈv¦°Œ,åv¼ºåÛÓuÜLfð20ÎU´Lb±¥ö*^É g¼(¾">Ç+Ú2nl­àç: Z톭ߙ¢O4ì ’ÕÆ‚ ÄJ«ˆ³s‘rÚÑT.6<1dÎk>üѳû;ô}nKšÏ§¼þóýܓ߫Z¬DºkÙ€¼ªöÔ´]ýÖx^|Ú=:*È(èNü‰il1Õ½¯¾ã§/ÚñcÑ©Ì:Ì•c£qû$–Í /øs6é,ø7ˆšŒÕ% ‡,;µ†­ݨ¬:]ÔöXOœ¼’ÌBn\r]LúäU¾½6âËæ¯F Ð)D“4…Lx? k¾ñãÕ7òJ±ŸüN€J?Ž_ŒÈ*.vHs‘ ŠÖ×f`ƒp•ˆj0@U‹€JÂî1ó§6¦É…Š®5}à¯^R3¯tÔ:ü1]4©üŒ39¶GY‚³, $£çáà(hÕ–”ì79ÚÀÛ.[rÙssBÁ¢#RéºY„#vŸ#g—‚¦‡RäÄ)ÔxN(ª<üíwÈÅ£*ܺÆ9Ü–\ü£Íµ=ªÛšÜÁ»‘²u¯&Q&òáòÉŠ'kFÿÅ8|¢£>·o0'í”íLäZ7.þ‘“[mHÍ]s(G냮rí­ïzzëÞÔ Q_|v¿€þŸËWÇワÿ‹_üâå‹tÅç êöZVåk<=årSÀäÒ§¶rô´ËQýYßmÈt§ÏÙnèê×ÚWIÂ’ë8»–s£«îfòð3€IAÍ£¦_ êêû¦½ ÓAŽM#›@Ȉð_|"mñ"fåRKTù@4]S6'É<ô¿}MÆ= \íŽ~lÝ»§áuþ;;\S o \ µ1!Ê{G²Êµï0yÃMØÔDFÓ‡€‘›;›râÎïê'þ̺t>«ßfMÞγØÖØ1ëÀnõìŠæ\å°eaÄ_Hþϵ3YG¸åO[‡R¢GFE1ކqfDJY¸ÌW|ÀS£©pÏh)Ø{4kÂXd°%’\ï8 Žª†Ö‡®*G“P¹õR41TttËÁšu·M£ö? «s¯ÏéSt0Ä£F*Çæ£uŽG#R'óí/ðå.O½6‚VyËS¦dŸ«nûlL9ÃØsüêÝHÅn}4ÈÕ•áŠÝVZï>ùìû€Ðw¾þæ›/^ýP¿˜ÕŽ…•Gǹ¹øÇϼZ>í œãz^q™ÂÑ¥ ;õg»vê–ú!ŸíÚW­<ïön.õeMã¸Ç´g¯ÆÁD'%›‚œðóM ‡ôðñÇc,2{2 ©[€Åã,¡¿ö§´"¹ %‡7a—M ·m¼d4AŽXO›Ò,¦…‡êÔÒ³¹£C7åsŽ+DØ®öǹ˜í1YÈ['á;1×¢ºâ+×ÇDÇ ;ž;+4ñÚcP‡¢Š©Œ½ºbSw#½yóöÅo÷wÏî—Ñ»÷­%éùz~ý—ùóõ§ÛÃ.„•§o}ÕÖ®ž“ãlgrõ´®ýô¹£ŠAŸx§­ö»ÿyµˆÃþxú¹]Ý‘Èe=……ÁS·“I=Ýfn„tÖÊÛ”Û°¦%1¦àTÚè²é+þ"™Dê²ôr¡­î/]é‹®«7¾GX Õ«Ý) ¦Kh7`‡égðÉÕ!uÊ[ôÁûêÀ’[á™î¹ÚÔŽ·O5P7ÖèŒiö‹‰ËïpÛ¹.«û÷¤Æ1Í’hÕ=yr”‘sŠ—r[cÃ]ÚÌE‰h¬6Ù•×í˜p »@]e/õÙM:"¦¶àö)G;g[6'†¤c”¹ÌálˆNË4tì~l't8f‡È 1¾ï•—áq£”­A5{çi9¾Èw],œñJ2}@ªms»ƺÃÔÚzcª O¥GYô1 ™7rk|wæH4ܾG}/µ5›G˜ú¼zûúÅW¿ÿý÷ßè€|×ë×?ýÉ_ó­­îXÝ,Η$ºâÝpöÔJÏÎÉЉrö¹øÖw|±w}ñØiŸvtw]‹’ ¬Ú³r—Óöƒ }Ó U€}{‹Kp8D·>}.\ÕúÃÊIl¶ ;r¹‘{H·ÖU è/=+І_ûSgÉALìV Ç‚ŠƒMïôeF·r£M©>Ò< lž¨ÙŒ«£–Ü ’°EÄÖ¼¶Ïšª?f7(³†Ùf¶ÄFŸq=7äÚU“»ªŽ=Ïî¯Xvz &ý?¹STß½)ÉA¥s«¹nôl¼PÏDÊ/‹ÚÙ£†¥œöµ对žbÍ»‘÷kð3ÖÌÔ¸pÞ­¥Šz©ˆ‘8“(žÆcªåð a`Itå]è¢C!ŒaVn91ã}¨¢øÎ¥=]ªËøT*â‘\]=:®õɰœR[“V{QÿʧÿÖí^7î‰;¹ëÓ<+Ÿxl{únÝöºg{âß×Nl¿Ÿ ¢O~ø£g÷‡€è¹×Š÷ Á«ÿó¿øÅ ýõ¦oxÏ”­ó¨w°:Æ3§EVÒ)lš *]Û˜ß7™ÙêWä¶ÁSOÝEVg.½JçÛþæ8Ö³ÍèÒÕ  ¿‘æí­&)­?ó—\•ÿX ùáÐä%¼ÔKín<Ä?‹‡±ø‹¡¬;—ÓÜ6¯âÓ¿âeñ«kɽF$ÄÜ䯘¹'%&Ȫ;hP¯Î©Y:ë—C$þÜ0¥˜Ü ê÷(¨ø‚`¿|h°˜NPHQM~î4š’kômȲÓ, ‚yûßMéá£M)Lur‰º†¾!ÁO6l{„WÊÎM –ËÉÉ‚š9ã{æ4‘ N„8ÂVù$FçÀqðy&ogèÉEäö½tæ.Í=hwkôÊ/ßqÙ2|ýÞ YÜ;+¹#Ÿ:;D·ú>:ªµÌŒÝ…†Ï9îæ•îRî2ÆÑ¦¶©ÓÞš´öµ;ù{=ñª­ü#×êñŠTÛæÙ±ÐU:í[GëœëÁÇÎyGÜ‘cÅ’ÒLÖñ“ªú}—ƒ¬¶Rê¹Ä|>4èíg?øþ#€c„¾ÓÍ7þß½úH?áø{.¸¦×Sw¥oL­&ž$ºó¸ù΄ªGm…ÓÂ&dJõõ+þ}u}êo’ó4+wýY½P3öŠðxÑ’>˶Œøb÷ÍT£_NŽp&¸ 1 •7@Ä!]”ƒš€uªYG^9n£)V¼€Ðõ¡Ã×Wbzd6»Àr´Å1;4j¹Ü†Æ:YÖ&B;›:­Wuô>›û¼‚6áŽAá)ÁíB¿T®¯¦W¾xHéáã÷OªRç!¤$àSHј1]Æ`tÅò›€ú yªóPKXyª]·.ÀÎLÊbò@I(sÔ¨æÒÑn&0ÎÓ¶‚ÓÌ»æ!%¸Ò6TZ)3µ¾½™H Áv¢Üë÷1•£ö{Üò`¿Ûêó>Ë/ᾈ»¯€ÔooDÝY‡˜?ä{V2X ÷wb®;™F†D'^ñZ‡|-V›ôª÷ƒˆœteÄÝÔÖB*…Ýqvøn„Þí|i †Êœ¦Ô)j×Ã/Ðõ ã¥$پ͟NæÕ§C ëø7¹é+˜ Ì-ˆQÄÆÙsõ tÚÇ'÷ÝøHg>Ÿ¢+¯i¬Øx·üXBtbo. §†a°¥uìÓaµëÔÃÙÆ³¶29qØ*ƒ¹–ë–|Ú™‹ø1N™vyËyÕmkÊ~Εz>ªƒ×=ôúõ‹·Ÿ}ôýÀ£Aú.ê^ÿãüÅ7oßüæÅWºð\EîÖYI}Q³*&õÑ#tÂ\§Q`™ »]¹>•ƒØç÷é7b·.Xå•7‹²ÛÍ•0µÖJìÆ\Hʱc iÆÁû8)õZ™!Þþþ¥9ØÑéUðùÙôÆé¶Ÿ~a“<1õÞø¨¿s½*;úÙçÎn)žßÔÆÃ2ahŸ¥˜­›Duõï›?9óU’Ù,3&ïœøÏáw`fé’uKa#[TùÈa£/„|ë Z*÷ ³D÷óQV?GÏfF’R²Ñï%2óÊ·Ì´´½k³sn j» ’%,ü¤oÅR‚™ë‹ÎxNÉeWŸ1 Pàl™ÈÍ5\H&57ÍÒ)ÆúÒ®q޽øG”s»cýÈ U¬S•ÍaÁJs8}ÐËÉ÷«jÚ…ݽB)O¤åxr`ª\^ëD¾eÚ•fžŽW´œO Ѥ)g%å²ùFqTÅY¹>íÊLrK6Û'òöÙ^ðÇšìc‰63èd)ö–íFÿuÓ¼zóFÇçß õ]¯¿ø×ÿúW¯~øéüI`eË•ïbEòº¨^@´úÝ?WÇ|hB‘VÎLµò‰kûgmO8ÈË9‘MTí¬à×\«›‡~éܳÉôLÕE–B øEzç¿E±aS.ß–*¿ŒˆvÎ@Ápö+s“v+%£—{0j@LÇÚø$º€£1nK'ý›·!K±}pv$ÆŒ$몗,×n CFÀá0¾¼i|â¥íüëˆjR)'ã<¦¯Å ׯ!,§±5ÏÆ°}x`?Äñ";–S’H;Žù¨<Çs-0Òî鎴ŽÜ¶nÓgËj~\·¶}Ÿ,i£§ê”•4z} 8ãØ+' à[‡ã–êMõÔçõ¹K™ñÝ>»ueÍœ Ó~”¼×¸÷È;÷F Â×s†¥9ÄãÎZkY¨ÛÆvÍnràk>w{ùê7ï~òÃïßè ~×ëŸÿ§ÿôë—Ÿ}úe~b;†׋‹”ŠßWû> b͹ÓöÔíÓ÷Ô?jÿ)XüY\NŸ®YØüÐB?¦/èX€©N;ýíÂì߆xa<ö™ï®Î@ì2$îŒ#±•ÆM¿‰‰K¶-\9NÎûAEv­”—¿(ok[7ùBëoéKÆ×‹ëPCIúèÚÆ4¡hÊ.㔥’- °„‚ñË€d#ÖÃ~äìÑo ßá”0 ŽpæBÂ#'mL—ºª&žcž¨(Òé÷ËŒ—wBÆït§}‘Oax›.â%ˆÄs-¢ é•t¯HSª¦v¬À³iaÔÑá(çÒŒÝú‚JxȨ*6Ñ»¼8ˆ§cù °©!r ƒ¡‚P…µ×ÓÐsâŽöÑçl…[¼¥k¤Gvð}¢=ífYüU®öi'üö 3¶èî¹7Ûíö^6 –CpøÞuÕ óÑ»/þýÏîOÓû¬_´žQù_~ýë_½z÷ñ/¹ˆÞTæ«ÝëZõõÑ„¹N“ ÈÓ‰±ªhÎöFüi-8Ì3+v8u>Wðb†úQ~ñÛ±‘×Ï–ÃÓ[imôãš/EÊÁ„:á{ärPí`gK.ùÀ§òÞ6ùRæ!€ë¶õ¼â_ë›í .Wµ½“©'¸¨Öµö芻>[·ò3À‚¥1»goóUÀÍdªšÜ#Ÿû|K߃;áòì!a0õsÐÁ¸m»[>¸Õ7ï68%¤k²uGjHAëA÷k¿]¡ÛÀ q˜Ü%Ÿ¥1èì×(´ã {jßÚýÚª§È&¶SÙ8à1˜ Ópäû;Bn WW üƒ°+Ë´B©Ñ6u¡ÝK¡Æðœª¿_»‘ÿXoãÃK{§‚.ÿÊöÆYwùôêUÛì»ßÿ)þä$Vãcž“­ÞOëíÏ|yóÑÛ/ÿŸÿó?þú)îÃלkLJߛéÁ_ÿõ_ýòŸø#nÜ—¬þÚ<ÖgËÂùmuõž?†r–Sö4À~Ãÿ¾É„þ}6|OÛÙÆvL=D•hŒ#ß(s>dÖX/R“k7D÷§ dË´z2«\n=£b·>|^—"*‡XvÊ2V¸( ¨‰I¢ºáȃÞó Ð_Óø$AúÙñ¦ÛÛKfÓ@k`ïÞXÆç½àðù3ÏŒ¶èä˜ÛÉóˆqíÃ?Ãú5~Êõ•œ‰ÃïH¾ü>…Èüõ-ð~uïùî?Žžœ_‰ÛŸß—ôg–,ý*ò'àJ•¶të;â£o\Ãy£#ÄM~¦˜º“†ÑÇ›4רv® íÄà$¥¬<ŠÈ9G[ÍžsÍh•pd“b¹Âšà±9W5wB Kÿ­¯ÿô¶Ì9¸Ù´]Ó>dÀ #ý,/&ÁǛ忻|нXÕÖQ«4ö½]?ƒtê8Gçï`ë÷6‰­Ù­Eq&嬣‘öµÛèÜGÛÖ™»±WŒõj«œè·ÖíSl0õØuóÇÖ§•ˆw->:ô#3¯Þ¼ýå§ÿê_}ÿÀ}ˆ¾ËòËÏ~  ¦K;w17Y‹/ø¼$<_œ¬ ÀÖš±&ɬuFÕNÚ§u8JFÕ¸ScäöRl?(\ð)nT…8qöŒœ05»Î8dl®ö=^c»êÐn¢o)mäz²µÉ•ÜN{¶üâ@‡5qâ³cD>ѹnáÌÃ\1Ôm§Î½¼ h÷€{ž^Xž–aÔÀ¾|÷îY¾ú§Ï¼#ù<Ëç?Ð_oÒ×ÂäõUÒ¿™ŽÅНKÏ¢Åd¸¼ºžñ&¤6SÁSgð{í)•é2Ž z„­î¶[ï<¯¹fá•[ñ®$Ýõ·‹¥¦ †Ø¦¡ R$C%Î0D–mmJFÎ ·:œú•¥8e_i8ŒâëbE·òŠ_yô{¶«?v£üMlä•€¡’MÎÞ+ô¼MO?a6§€ŽÂÀcóG,g •Ìôm¾–?áÍÓ%Uõ-rùäÖŽÙW§sSŸç ekpÎùxäló`‡LŽoƒ cû$Ü)ÄCyÑ\u[Jkæþò€¸–*·O4Ãh“È1ª‚äž:½›n™Nyße)ªrsŠþ¼æÍµ±R—©\WDôÁ¨¹¼z÷öYþ #µð>Ï@~õ?þÙeÚiÅôÏ÷Né ¬ètb4x;´r'Bß"]Ãò`Ô:aæïÙ¸LÏ{ÉØ{t–Ûë3¹K°Üþ‘º%çó\Ô”ÜlxLAn(j™ú™|š4›S”¼tC³~tqd¹½½y.ûÄ™øF„¬yY÷”‘ò²ì|dàz:9°3Nÿzy›+sÏvrJ>¼eN±}^NóÍ~rä3yÌAÐZº•¿]z9wœQéõ.‡dYÜaôûX¨ª €l 9÷òÒ&}÷cé¥OÛp³*JÆ:mË:9gwfãp°'Ì ² ´Õ8døjÛ_AŽÎ´å¹ÊƒÐµX4lÃºÈ I]ÚêP‘ä–Ë!”ž_î°‘9íT,›w\a×aÿÑÛEmD§XŽêÌÛ‘ÌÆÛ1 Å+ŽòX’á9DšÅ¥}ƒ4çÓ/Æ&Úž¢¶<lj)G¯7ˆØ{}‰uõÚ׳×<Øpà½hßã6&Ì-ÕÕ; ±žm4;×Wü,ÿ0½dlŸeùê¿üÍ/^}ôÉî[¯¯îrOz~ô¾æ: /\•Ô‡OÕV•Õwþƒ­ÇÒ+ÎeAyñLÎqœN¼7`oRꇜ²!Ç{ç»ØÒÙcÒC«n8Qëèfƒ®íÖB¸ðe¸]á¨Ó…DAMþÞLÔ¶¿Ù„í6}NBÖÈG×Ó Bc‰ü°½”i$ƒ™p‡þõ¡`g‘ƒ_ Žrê¸CvºÏ«7ê§% Ñó@–Íèq «éî{IìfýÐ.:²X‰XR%{JŸãœÓÓxíÅ×¼š˜TáSÑ% (ÚêÎXï·lô‰'Hæe˜‰ŽNül+9!’ŠüWµ×°U5˜äS»äTŸQ­{²±k_qßÑçüäŸÃíÛ› ü>ÔÝŽüÇê¹Æþ}!¬?9ÛNMÿ8î÷[¬ÅžÃ}ŽÙV¾'€o7òb6ß]y#´ Èí£O>ûþ ƒó¡Ô_ýö·¿xùùGÞ ÈÙ‹ôÜyE^æÝÞ«©¦ŽFÿÞô®¨Y‘7“òð~ïðtú€»ßÂ̪Îäs™ºó?w¥vÉÝ8ÏMçrc ’4Ý8­Õ‘ˆlCÌý?ƒU¶•é0E†CŒ+ iòMx5^ÔûóøYŒÌ`À¦¥1å&ö1ù­sµ{ëB·áQâÎÏŸ ¹cá¶Æ‰7ì=B8‹Ôo@>4GVKG¬³äw€ìÛÿ¯J‡š8-íÄè*b^ã®v~ÉÑ©.õÍã!‘ž¼š{ÂŒ8а]ØáîŒ@oPƒõæÜ [—X¸^KGöª½KæYJ|CÊØý<œ¨—I}¶\…eõ¾²¬« µôË4òR4tÈ7L!O|uYŧ\cF>Õ`fAî>5L½Í»uƒâÆÐjz´;Ö™õ‡‹,±Ÿº¶a؜բ‹¶6dÚé]­Á‡ƒ¸äÐ<Ê»å“ýwÇÙœÅc«½º]'®îŸÞ¾ø»ßüí³ü%@ôö\3vïŸAë£ÿéþì+­tßx'ÑãZkÑò%WÍFæp›>×N›bÛ1M s!ü‘å}ø;WßF^´ä%Љ[ Ö€îÈÙ°Ô¿é èló•FîÙObé#ƒÃQ¼]‘â´6ìÐz˜pqɇŽâÓ‚æùèr^NKI.ÉÇQ·~ ËC~æ¿@6ÆÛgÏïÈ`øŠFú³Vå:A-¯Há&—úæÔ©íTà“OrÛ\ÈÀÁÜ)/]89…w¹é,Þt…ž $÷Ä>sq9]­pä_w;ú»î}ן޶Çñªçý …kf)Qv)Ç=ø2n4­Së{OŠ7oß¾àÅäù|¤µ¶<Ÿ.¥'ßüÅ_|ñâít¹ÀÕEÔKÞç•}/8uÛ…V–éaéô¢nàÉuwSf´+æ•1œ*µõ·ïu£ß½OŒ Û“‘&O|ìÇ ˆ6÷“6ªGyU×n…|»¼$(!ï8&¾67œ=zðpLäÂw2¿dƹJå|áR¹ù>Í«Š †. ,ì@Œ“Ýc`!}:qùq@-ÜãC÷é!ýð;øÑ?*ŒÃGÕ‚+ù²¥¯ä¾ù;ŒNð›ƒJds”uòØ¢Zö˜§–ê‘C˜s8Š¢îÕ;=ÐWÞ¬iù¬±¦;ômMÀ™rlœ|øz¶=vëðýâ¨îà\ãxè€ácºá8©ð±­>gݶIŽlUQŸ1ªÇ§óÊ1‡òÄŸú#â4c]|Ö>ö¦ÈÌMàçµÅZ„©kXÏxõDÇQÏÊÁ†gŸ‹ÊuüæÅGŸÿèÙ~ ðùþÀ~ôËWoõ½îßëµÔ»×Y¸µ:ñ7í]|¥í©¡YÎBhsgÀÑuëÏW¤^@»0†ÝSmM¯®.½“Ó ÿ®ûèOz,¦Ü}–LñµÓ€9Š?v £)€`ÆL– jËœ0±[·ì^¬|»}Ê`¤áÏòfq{~™ $}% îñp„´a² 躑‹SÍvä>’“Ô}·ÀfÉØš6¢cA;O^eçsÇÈEÁx—цԿô‡·ÌI>¸M¢®¸V@Œ‘¢`ÇDZáâqÐxuL2~Ñû!@qº‘CÆõX‡8mbœ¼¯q’X®?ñP7ò¦;÷ⱨÒý7錷. -çpÌõ2F£xŒk)Ïš8þÕ¢¡lŸÊîlÝ;NÂÈê$f#›}8p^÷G}[cTYaäs¸qèoaÜ¡'`¹Ä]S+l–3O«¸úX{ç½Ëãº*Û9íŽEÊÈ£EFŠ^ã®Fu\…xÆžû5+7^”zÐ+­D)CëÚ§y`……û1crqÏ ì`6C"ÄÂùQitj<¿b…МyýƒO¾àÑ€}—uo~üã/¾y÷öÅ‹_³*'So^m¥â*·HW‘›¸]º"ÿÌ>¯¾U›ÿòÞb¼BO\›.wvÀOâJ݇Œ>tÔâ<ìaãpGN;ÅñЗÒ7Dz@‘FÉ?cò5ngê*oA³±¶|-‡~Þ}v;›ïƇ»ï60fùø¡WF“LeB- î *Cé·Â£ÉÛëj7>©sdóÈã €÷ˆYéi& ÌÖDc4„`L(?|V¯;x×=…£cå\¤‚·=0sÙTw󝮨ָ¹Ý`ã‹>*Ý?4í[Úppg\jîŸÊö°À Å5A:‡öò\ÍD»ÄBwc·ÝqÕÚqiM–6r“°+ts=É]vð89}ó îæXQA›²4VX™Öòl£u1âsˆ‘m.F5Íe/FŠâve (Ø ¿µØáâeŸûèæ:—‡"ûê$Jä­$œJó8c¡«œz3T¿³}³å¢žza9µm·n^e¸ÖEɹqõk3_~̯•ž¥kâ³ëÝËO?ýâÅ»wÇëIÜ•Uµ¿Ø—K|ù(€ wO ɬªkq¥18ŽnÒjfÂŽ½Síäk»qì〇^\,D¶îkïBÑÁÉÑÂ&e¬_BjZObñŸÛ·Éâ4ÄU™““wCÑ®T\¼IIïÉ4ŽÕá0C²êfX=¸9(l6ëÇìP¬~0Ôä¡]±ñ¥ã«ÂQ†çiÊ|–Ñý¥§n{aMð>˜4?FÑï0Örrh¸Ô8Ç©)5]r>lôyw„&Hò€ÙŒŸÔŒ©Çu£/Ä£?<X@á2Ñ–5þïŸé™ˆ<öò[î‡ý*'½NM <WÓù;ÏB˜¥§3V²½v¢vêØÓâ\[-æ´!Îö±ï`bw›"}"8ÉŒÌBªaxÊ2D¼œE°ãŽ¥á?óéÄåž[ë!/×,¥i2ž&fòKV›dÔ†pªÏèg™ÄÒ ®>æ±ec’Ç–Óz¿¼‰7&ºÌ+´ÉkÛÓâë¾GËvéI•ƒ¯ßV‡¯òŽûêÕ›ï>þøÙ~µ°ý~Fõ«øñêã·zrÓRʬ_xÒWÒ­éÅW^È2앞÷ωq×Ýe¼‹§ÆÎQ]ñ,Ü´|lÈJüêõ1Ü‚œM‘«K ÄB]Œë~R05 á ׆n­Ýt²yK÷ƤýX“ª~GŒ~`«ÒË-§ÕÍ•>ä-ÞêU£t0=PCñˆÉ(6ȯä#딼’M²œd£ÏØ24Þä͹‰H%ã ûYêIRc3NÌÈîHA²y,‘ËSÛÔ‹¿$pb;>˲,…öõ°ßµÀ§1Œœ“7ÃCæÀy\0£›œ @ìd—´Þ–´‘Å-¥Îo÷Ý>¸Çº/²}ÚÞ+ ª­¾vl„¡]ùÄŸºbd?!ÎÝ(ÙüÝF® ³Æ½üv–Þû§®qNjÚ̧àÓA|8W d=xö6‹«L;íª9¥»ÓX¢š´ÑfÛxÚ+£+s9*_=¢^¿øÕÛW÷úÓ×ßÀ0~HåËûoÿö›O>ù% ¨<sø³ËKÇÿ셅´ÓSpµ¯©2˜ rs/÷)xÚm“O9+Ÿ˜Ù¤1&Žo\Ú8Â3ô>¤¦Ó¾QÚgaXïüv9µß€`HL\d ;†õ“ÉÄõCÀ@J‡9C³J9I«m6·¶L÷J*<¸7q£ÃO¥•\Ö7:†ÔÏçúŸ»^ý—‘fú‹ ^ûQ÷XÁ²1¶I/ÈÆ‘ãÃÂ2Ùý{L@[‡®Å~•.À¼ì· ;AZÚVíy^™Î8†Ïj«Ò³Ä: å;kOú4ý ãêô>l?Ç'F'Âÿ §•Òz/ÝWŸùÊ´M §|ùEi0mdŠuÉÃí%«A{«us§½³¿°C{ÑÁ¡2´N×yŽÎ¶‡iNØ‘áq™Æ’QVhŠö!Ÿ0Ú”›yÉäq·uªŸYožœ°Ôš«9c¶-»U;u´ÈÍDœZwœí¹‘wëi9c‚‹Üs£>ì7ÊW¯ùêÍgßÿ`†øÃ9ÿƒúOýòÓO~ÙÏX½ð)ý¼ýÏ…í¥W{ŒçT¹Lˆ:·û#›á[Pì'ñpÈçü)„µ+•_5koóZêÆ=íGÆ Ø½)‹€Hj ¦'ÿdQ=äÚú6z¨³ ƒì+l6b\ò¯aêûpeˆBpW¯ÍéÎfß>17ìJrˆ”ÇÚÈH<É«q+ò«K-É1OòžPçuqÿQ®hŒ”˜Ÿ£šÓø5|v_Ù¼jz„KZ¥´ìõÉ-xïý¾˜‘I i4•ây0p{0öP[ÿ§d,™úý2¦G@2c|Ïdžv_Þƒ ¹Œ·BÑ^-ÝVOp®CÎèw+¨S†í”%6ÀMm_ën>Å·èk‘1À…,³Y8ªeý¥@Wa›ô-ËOŠ…Uƒ66Û±²Ç} öÁT…ü@õPWŸà÷‹Ü˜`ÏMøÊJgÏ“™²u™èa˃•²™‹ºûœ¨Î-°Å›æÂÍF€{ýîí/¿üÿñoãóüÎ]Cž_Ï4w¾ùøÓ_ò *¯¦x•ÅçÛ½ÍÄÏF&ƒF“­«©0Þ%wú£„Cfºz:ÖgVåLÑÒG#\ü@\:riPŒ’»Ñ#ö!æ\Öâ=ù!{ã,ïפv I±p¤ôâ\_~¼´œv‘ø¤«†äÛöX\ý[gó" ‡7v],ÒlßZÃ圴z##ú Ué¤CÕî“[eêk¾}/Õ”cᨳ,‹/›i6T;zå+bcùÈIÛòxåeq³{žF§³9U«/~Õ/6¸ü` ºýpª2ds½üÛMIÚñ zU[a£±‹S žƒòÒÙÃ(•2TùÛ–Û"ãÏ9šÇúò+’žuÄá¢yMœøf›žå3¶‘ó°\bhyAÜm²°ÂBc|Ôž0…[%Õ.²@½V @e]»‘©Ülã§ VM.•;_`)…=9a¥´GybAÚ<ß°^¹1<øàHÙ1¶|úlínÕ‡¨\µ-ÛÖb¹ýYS6ìõ›/ÿú_ü‹ßläójuýx^½šÞ¼þœŠÎ\Lî.]i&¿§‹ï‚±O;xt*ÒUö mÛ?ï #ãî2`ësr–£ºÓ':Gå3t‹C ÛH—]Èé•¶JÉ<¡ÿF;“½¯ü“ÌìÝÅÁ…ÜIMÆ•˜VAo*T:xµÝWÜûf3b@i¯W¨ãNŒ•†g-ùë*Ò¦ùÂ91Éã’[Ã9© NVuÕdÎè¿­·}O,塽Œ#Hr¸ä"Õ®ùó„ÔÃÇÁ4N®Ó7Ò¨Í?ÂEz¸6Ÿµé¯¹xÀɵá îŸK LucšÊ€´WNÛd'ò›‹råØq6;àµåt³>`¢I´»O´œëqj.¾¦9¸È•kU~›Žx#cß^ñY¼2œí؃£«Mb§ê\η‘Úˆ¹&aÄ•a÷*Ïø ëíõåá‡á,øŒl§*ÐK>ET•±“¯21SÒØøS{Å WK5°ì#(ä´¸&‰¿“Å«ùâ-ÇÉÐkÞŸd‰Ü5Žõ!Ük!ˆô×oßð—$òAŸïëÆÝ™{òú“À_zÒtée”ß ͺŸïû3üŽDkaÖgû‡Î1*µ¹î À1GMO8‡Ã“µ|ßäµÉ ×Á"°øG‡Â:¦luðÍæ»ö»Li<¸ùÊV™Ü$‘q3½¿y,Æ­öú,[v^ÅF(Ÿûé—¹DQ!wŠû© 86WÎ=9ô‘Kwpë5?rÊpDÑ ÇP.õ·uå¡QÞŒ»Ç^ EÕ? ù+ˆþç;hâ _ãÁáÕ¢˜(L Ë£6¾CÛ¡sUJÅqîÂPCB=Àƺöãj¨_‘>]TÈÂ'ªåÈ@IDAT·ÉU- R¢—¿þ[…:‚[ëÈÈ„Vÿ!¥õ©«+G}âÙ,âÖ"ë?‰•HÑ6Ç º:B¡²] Ú#slH81ºÿ@g§µ 2\*Û'rÏÝPºi/Ú†6nHRGVÍå©,WÔÖ_üRÕ³-{xŽ]üüÓ/˜~õ´ú7SD=ïd9_¹w"grxÔÊÚ‰Ò•×2BGðĬXã' ¼ø8>ƒ÷†<:µ aV9åÑ{./@³'yÃò¢NÐò«é'`騠bOfpq[ ÈäëŽÚÑ:îùn††ã7nÄn!$…'ëÜ\yJ굃¨.(u¡zóé ‹=&ÇKa®es·{Ná —´¼9BÙX†­où7v“~—ÀÜf,Ê&Yp÷]œ™7“k Wò^ðO®_DŽɢBŸrïU%=9±‰Ê¹‘‚ OÎéýòÒvŽ˜ßë%xûöÙþý½®5gR¿þìó¿ÉDÉaöâþñªïý¶§N›÷t§)löݔٓ8ð†“âÉuQd6#â3ÍËžÝɦÆÁÇ~ÃQ¿ryƒ)ã‘+¢õ‚Q´¬~è¦òŽ¥Ü;ÚSføŽÁ#î!Æc²t«ÉãþÔ‹núº+·þ¬þqº;õ{ú’—»`½,è8*“‡¿Ò Ër’4 æ”E7<kÌ„ÅX DÏJtG¿”WüóoôQ8 ‰LÈSÖX Þ2'2ox¼¤šGéŒÒ5N¢s±© %ï±Ûf;ÆKà ûÄP@]¿·ÄóDpµ“rêµmÔâËå`d·s?ûŠŸeaà§:í’L¯Ž'³Æ´RtpûDÕ”í7ü`쫺v+$Rü‘Š©€¡oԖ݈ÙçbUÀ§b瀊ö­2õDIÓçéÜ¡ &I˜g: @æÍ–6gu­KмãÄÊ9Ç–ƒb*†ÿî™sjÍÀÆg2AR#9õ#€*àgÌ_½{÷l€¾îu°=Fõ7?ýéßx2Ìí] &C6þ¼:ýš 1#áWè3¸órtò¥a6q ö ¿p%˜Ûñª:4>Þ» ®›†Û=Éjðéc Scä LÛ de9uó÷¢l®i{»ˆÎÔdŒÄÕq”—_ËÕ-aÒ€·1Ûpi÷åXÉì¾…}­^zÙëWtÎqãI•±^›{û0 ÍÆÏÉ+…¶ ¤¡c/̇߄ÃÏ;`»©8W(€è d¦P·[cÉzµ_Û™70wÖ$!Ø®RF冒ñb?dJÝúêŸá8A'°:à;hƒW³åÀïr‰ïÁо%rw× Ÿ›Sºè|!~Ë ·.´óðƒI˜Þ AíÀÛ+ çår!§Q;T»´BÄ”Á4µs¨ïï™È0¤0fè` _Í2ù‚Ž– ‚^‰½|ûÑßX~¦§Ùöžgï~ÿ_ÿæ‹?øxM~nš×Ý=ö»<£ÒWú—’ÏÒ)œwë:‰Ø€ú.ÁÂÉÃÍ\äèCÊκ±1¾§´/­FúÜYT"x‘芤ˆç¢a·ìš *\óÀ…ü,;Ñi`g ú¿ÓÐ hû4Ùuc¬¨\ ƒ Ë{Þݹٗ{|x&ÁäþÕ×9@µ;Õíܰ’îtÆmÉ^MD6cäGAšaòj i?"r $sJ>çoÛµ€þ>…GÓŒƒUuˆ}æ¢ýbÁöBô¡BΫ;ù>Æy}݇eo,:·ºëð9M$òQ™*Â2–«5 3!²9Äö¿5»ÕÎXãœ{NµmGŽÇéä°W9Lcaõë|€È—Èb7@ÍÜ7ÉÞÝ?»§öL'Ñ0ί4I=vt:Æ_TåÄVã„4þ𩺵]ùð­õ5Ø–rw 'µ=öÈM·Ô•ã¿Yèi¥³¦Ý=úsÃŽ×=n¢–…Èýòku÷: y¼«­C ð“O¾ØCòaµ¾ùâ‹_¾ø³O5X`Xôô)+WU×EÖ¿Œ…ËÌÝ%‹)?-×ÂÂêCæõ »7–1…xð+{t‡7ñ@ |mmM&Û)ë{u×ãà%&Ť™óétšWœ’óX(J~«øV‰e +. –m†C0–—‹)Ñ«ä·ñEX‹ZLÎàBÊgäþîQC¦ qv9àfh€èèæÈ5s׊+±¥È¦ Œ9ã˜Ãuö#y)7u<ƒÂNÿ‰éM\AûŽR€PXöv*8À•ï'Àƒ¾Q{³¢¶‹ìî—í_M­×|†¹äB=mÏaµ} šÔÀ¨¥«—¹[6ÈÚvå`–ÃÌu,6~3ìÑ‘ˆZúŸ9ŒÏ £^$V›äSHåáh“ÇÄ ‰ë96¾Æ .¶cc×Á/7)Ýã‡L¬º»â¢ú˜ýâ´ìc ñÄ#Æǰ›Îâ"/»–¹ðs&kº-•‡À÷<áàÜ#xØò m¸ãA›«¯XÀD[ßÍ®ZƒÄ×<¡´ò”_½}óâëßüÝ÷d¸>¼óÛÿù}áx^.ùmµY4¸Ð¹Ñ$K±§ŸfçÇç[ú]l^kõd#óCÁ¹ ¿6œßS ŽÎ=tÕãÖÜÖÉ86”iû­æCön12>«p­Ã¨áW}XæÐJÂ4Êäœ 8{Ü.Ž—e }T**×d ³8^1®ùŸÎЗé}êK=…ð€ì:¼®8•ÌmÃPšs]Âñ!Œ›"ìüZ×­\Ì*Ca¥[Ë™~=Ï»pÜ\±Ð“q‰wβŒ1S%”õá:x+—ÂýñuQkTýÈ&}´f¥¹<‘ÇÇœj{|“ÈÂ'¤[å–d_—zŠ}TKG5Ñ ín”atfË÷”¥ì¼üî ;¦ƒåHñ¨îÈNMðXb7ÄEï–0m;ÖÓL³ÈÜŽL»lõ >Js ®›Q<&¯ Ì|øÙ{Ÿ%O’#I¯2³ªºîFcf8B!…¤pû<í#Œ_§y‡=Ì›¬Èò°Wî…Lu@`ÐUÔOÕÔÝ#2»×Î*¯Šp7355s÷øýÉÌý1¹?ÿÿújÿ£s.Yȯª<ýöø _ä¿@Ït:zÜ «OÈ6iòòê‰éÀ†ÒwOÍ8tLHp< øA`VN¾½^;2õ½ {A}LþÃ.ÞÛtÖ}æï=Ô–…kñ}*Á‹ËºiQDf 7RßÖîrãHߦõ89ã¦áLp¹!ë3ÃjcßÜ©ê*¼ð¸ý‚Ønpš2ù6fcÅš· y°`>x‘å¶íV:Õ‡™ºlþÎUµ_õãxŒ‰u ”þdÉÛ£ –þ·¡S¢xZæ\ZûxL u¨ë ›ÆTv OÏu¨Úzì µ9¦UÇäçØÖ#ŒœÖ³ó ¬wµ2îÛ¢,¥-qZ'QFí¶e Ë•‡ù”Ôø„7Z_Ï=²Ž˜Á×;>#É ¹6§h¥ 9çQQ¹g•Ém›sFák'\¯…»°†§¾&`?xË#µƒ £­b ÷ËgÙ¹ésâ’Ó”öãX©ëÞw‘{4£…¹º¹±Û¯ø3‚S²‚«Ä·Ñ™3Žþއ¡¨Í ’1z÷í·_Þ`0~‰åÓß}ÿáÍû·oü7ÓƒÜÆºÐºkø‚X_5r3Ñfzœ¯ÌñêæMÝÍ¿Ëøxé#8 6‹ >áÇçű§®}2„¾­ì;"©ªðÈÚ–Çx—Oÿ2i˜Ÿ­ÀÙÞÑrî5L~;ï`›Yñ̯l&Î8ËÆŸþõ¯¿üàà_VëÓ·ß~xóÕ»?wãsÙ.À½Ûò‡XtÝ{'yndb0›YYdÙÄmšS‘~!°£ÃÃAuøf‘î; ©‹å9E»¨?9É¥g­U>¾£ôª´³“mÊÔ¬Hû×ϵ4%õ`!§42Ž‘é-²óÍ&Á!õ@¬·ÅÕn˜Ô¢1qSßËÐÝçÅPÄð‘‚?^¿ºÐEqjòq^:U&&ï w›0IÒ81®+/÷¢&òÀƒ™*o’ÐNµ ÓèGñÅo|q“ß©u$¬B[±«’OÃô!ŒyºÊ¤‚Ê>ªWÿÈ”>‹‹®>ƒaÎó0%Õ”\SÎ+œ¶oÐêb½¬ª²ÈægóJ:e8¦;‡_˜'²ôxTª‡dh}œŽÎŽl¢[%QL…-šøX‚Ôà*=| ÊÍa6Pd®m õŠ'£õct…Π±Ù+:ô'ÆmÙ½‰ß}À ¸,bæ9—a‚½P•ã~5648éó bùzcvºœ®^™ ðÊ<¢U9qØ 8w¾£ ÒàåqtÈ}ÑÞ}ýõ—2T¿¼óÇ¿ù›O_}¥ßääçï\n73¸Î?-Óâ“! «i=Úk^¥óñ‹gßöÇÿò¥AÑœWü}· èZöCA5ñAÂvÅŽž LI.«£ÝcAïÁPvIo” |k,c¢äÛé`´0jÅil/2攆A¡šEiQHÇîªÞ “>÷·Ác31[–î lCƒM5‰1—¦øP¾µ<ªsÑÎ}ºÑnÍÀ{ʯœ®N )×;Hâ3}žä>c„©ÌeqØ0êøÃSÙ–ÀO³êU¿dÝt1PtgùTûÞ†š‡K.®]^T5,Å®•åe\hÊHÑØ0§àÚª´ýâPÖÍ‘ØG¶I­Ü5Uí\š×®Ãмå¡Á¿ä%?<=þÛÇÇÇ/ït@iõÿõ¿~øøÕ{ý6À¬â™ðL¥L‘Ÿ<¥3ÙX i­©(× RcgªÖ{¤nÚ¼ºÄޱñ{x»W¿ý:¬Ýðý#e²•·­¾“€œ¸´T޼¢ˆ®m§xb2ösï&ñµ° ¹¿ðFþt@Fßpjgl <Èœ¬›¦€…Ø fràË~·8cÔØ$芅Ÿ7Jó#Å9ê jµ^çƒt¼Ù¾îúƒ†æ)çÚ<ðÒv¯#≠È6$ÈÎG}±m&FslÝWö‰¤¤29#Ò7:àÜÝQé-Ø~QWŠ>X„€ód[7Õh2Ä(k4ý8µ ‡,ðŠj.wÓ ×´s_NNŽ+‡S¿¦ÍAλE¨–0ì$Œ 4©Šqš)5R|ã2<öÁ|ðrí,W—Ì+åOtPõ!ØØ8\Ô0v)<öË(l0úz>nê4ª…sÜ%Éà²n:ô‚9Þ2¬ ñ9Å¢ôq±'XF-T»ÆŠÜ ¶£á|r´Û‹«tEÔcc6WZÛ²=ÛÚY}Ò õéíÛôÀ—ï܇ð—"ÿûø‡?½ñ;~Êœ ÃÓ¦Ë~¤½‹tš «¹Â¾È&nÕL¦ËÚDÓÍq&“ïdãÇVŸ½ù¡Åð¸1íê« ó–Ú+ç¤<*»žîU‡—¿`÷Ä[LƺñeL¬ɤè~(¼:ë‹~7@M÷ÏÉ$ÓŨx/ŽŒÇ ü¼Á[ð–ÁÈ©›”Ÿtƒæ³÷؉µxï,¹ªÅ1É-ûGyêÒÏýœ“…WZ@`‘pè¸ú!Ü'Æ© tžqqË^ÑÍ . “ìB²õálÿ†JUÐÎåìLý‰ ÞÍ•‘+×E>,±¹C;Ô¶ÕQ:«‹[°ÌúCm·ô [ÈNÊôÚ°„ðÄåêd&Aå(`ü”«Ç­<7º†99Ü+Ñ„5ľÿ;~â`V$°#p½ a‘ÇY`+Ç=ŠÓçÆ»=ÔÎTç¼¶v;xÿj\˜"Èv7Ó/h(µýœÔyÎZ²Ó˜µå„oë÷¬ŽåsXß<½‹åÃÛüZ~àæÇ›Ž.9õj¯7ýÜŽòc‰Á¿²àmÕè"÷—œ„A¦ôÝ€z²«­ß0;Àúr^\ÖÎGÿmÇÑ]<=½êWÿŒŽ–°×]¾ûF_äRgâpãvaCËâï‹~^yë3.ù–ôLqMŽ.¦žL’=€"Êfjs($:«{&c4÷}íúØAm^ˆç!àðb3‰{’¸_IdoZ9'dëš¡ò]<ÒùÕlÆ#ÜàÔÒÿŽ™ÙÖê"qKç…vd~%î‚Éì°ÆÁ@CgÑóc†>:Ž6®™ßŒ ב ÑS ¯hý9¥l~cÀd%uëÒ\ñÒ}ªqPn¥°a)š#c” Û} ›¸°äG¥ÀyxÏ\‹3×"páÕ‡,ç¦óâñYÙø6%¹Ù)âX\Y-_Ï/ŠÕ%.¬þ»9"ã0E ëFåO5«Mÿú`ƒšÈ-+fb<(ŽöhUñpÐBëÄ£ghÐ-›Çj|dèF –6Q£ªÐ9€q¸jþàÇ;±Cšö’`¡0õå~S9í‘wgÆHUÛáƒ/Ë&Ñy[90§Ü|ªn>§œñ¡Ï:ÃqÝa?th9¸iõ\yû¥…>˜÷n æ~Þ(ZW ¬5:Á»ï®°\äqý¤ þðîí«þ ½gizÝå»o~ðË]Âÿcæ®…€‹>‹îÇÀT¹LuDM èÅ%9‹z¦U¨Ã ’‚K5v?äÚyåß?&L<®:],å–ÍÜzÇ@ìFŽž<Ö;#«:ŠPÏ®¼tŒÎÃçÌ¥öÌAìN аl^øù¦]²¤Áyè—Üè9û À*!ÎeGM³{^e] Á—Σ²ˆHÈ…üÝ]ÉV>(tä][‚³‰Ü N¿“ªTÌ åbw®ÿ’¹ÑOŒaQuÜ–q>Ž„§¥AÃk‰“\(„£x\¤g¾ñu5ïhGÇ€ŽrÄccr=ââkŽéðÙ~i979å ŸJ´h·ì6-ˆÏ\¢™QµS¿ÍtdFrÉæØ|N×ý-˜t²ÒÆÝ<žßÞý0ày5t¦R›ëL»cf³á×¹AÏÏ`Ãa[Oø ×qrt +m’¥ðÃòø`Gçy¨ör0aDsø ¥Ã´Ö:Ô'†vÔñþæ7¿ã‹e™ÐºÀúÏ dYõÒ¬¶—aµ)L@\/dÖeâ,DÂxmßö´({×1 K–¨èmå~>²?»F¡xµµrP;=Œ*gÛŠI¯FQ4©îÈ7ÇA:‘j¿ŠƒX Æî…AÇçÝ4%{£ë©ÈÒû÷Ñ«œâ°TÊI}~;¾ïä'L^ âWýòÍ‚SV]µÈ.’ÁøùöÈk Àsü7 ⌃ÇE#¥qLõ_¦Î«“ÔÙÉæïkËĦ5&e·<Ñ”¼Ç Å÷Û)¨$FÆÖeðOî´4Æ`͵ èp=8r!¥@—|ÍL©“/ï·rUÔèšs›Ö;09$|11¡<÷”°=€ç>˶=˜\odàò½ög6iåŽâçC¦¾Ó?€\¿~G‚\S”§Ë:yî!XÚÙrÔYmÏË⑱Kv †Æ)Ÿvµ1ûäæ@³:C°`‹ã#ú(Gk m×ç&#z ªŸŠ¶Ÿ®WõAÀÿgÅæÁœv«ð¡1*ŽúÔÆ:ØÇ§6Ëè§ToÞѵÅ4žå‰]ž¬k“ÒÄ5çJ¬¤Sc|¡XM®²] UT©ºMÓÈÞJ{é?ÊáX~«QŸ¯_„^”™¹UQn—Z¶&=`V Ò}ÐZ÷ö­öŽ×]XÞ^wùÕW¿ûÈÎçUDWÖ×x]jõ×{0¥èjX–žB»S)Øë"†Í¯JÔð[rã£êRjk±íð^àÉiT~ ]mçEØè Ÿ.=û(Àã ›DöµÈ k§ëÖ,žÓY+’Eé³W©D÷Y|Þ8èé1bvsbT9_ùGcínNËah‹—\²¸pÓ«˜_§¤•ø'Ýe#«?•IC­=¬Û† ÆC0ƒâèhçBxskK¢ 1ø‘IÇI/9Ûp?³ÿ§Ÿlsc¯…”Ï ar•Š8ìóqŠA$$G8§ "*äž4¢C`ØhS*GÚg0–r¶Ï²Žnɽ‘Pø4¨š¯,W‰‹°6{Á}[h@És>,¯ö-ÔéÆ˜è’—êðÒ€Ž¹ç„•:ð'G/%ÆÚëS j|<îãlNàiY¶˜ª^õÂŽÏ\òð€‚sÊÊo)«áNûÒ{ÔµUuú¡³|¡; bTÛpÊÕÎŒ, ÛiwK$=¾ïÞ½ê?Lÿ_ý;?ý—ÿòáéúîͧþtÜUݬuÉçNš{ÇócM ̤ÈY<4tœ½ˆr‘µû£c·å'­²³] wØû%?^a÷K|ÆŸWÜCrVÇÆ„š¾ÅŒ‡Œþªë4—á†[7P"÷b›EŠd@#{ÑãaE‰^1¨8”"‰’\¼BK_ë,ÖáĦ‚¯©‡_ºËG`:Å.j[uè;ç£`u¸ÒÎOˆŸ$.‰4•n(‰Äc¦Úû­N¼µl½øÎ\Vÿ ¦Òw«6†d+2Ý’Žt¢Êت¼¢E H9ïÈŒ’o<£;µïv˜8†ÑÖqä;Ç(:ÿ—9×sT²ogNþƒII”íåÝÞa( ×ÞÕ70*æèEµÏ22'Çàñaþ£§mYµËͧ×fßGîzaª‚¢nëÐaªHÛ宨L’*ÎU:×#£¿À$T^±« ð•Ç7ã “ìÔîþâ RíQm]n€}°)žy±Sˆ/ý‘†Õœ^ˆ4™I±Å㼞ÄxÐÛvŸÁÀZnŒ×X>¾ÓïxûΫ0›¤ç›ÎÌ>ÿ¼'?gì1LNª=mÐd#­ç X‚ö31gúeyê™@ñ]_蓦ïôûÈÕáq~90ÞhwA×Ãý=ä žY–S>fÆ^Då­ÿý¹t/@ ¢^¯”ðSÍ íËF!•9ÎØæ ibk\-N<ù\ú1!Ö‘¦ð^$Ô—~DáÿÐç®H£©ô³éÖ½’E›â|؃r`ž5ÎŒçêëq?°ÄªÛ?fŠÿÁÇøê •ùK[Gçn†§¡›w_ #ë׸˜o÷øbô,5gâpn÷KІvqÚ‹¸9På )WX‘ªD©Üvõ•©[:2é-Ȇj$¨Í2ß8t¾>¹‰ãAÂåz¶‘Én7¥Ìõ'scŽ.œ>¦l0øŒìË1zd‚`Gå±&;PÛHcÊÈÆ£ª1LœÕÕfC$“¿Õ(ùŒÛ>ĸ¶m›ð]'Ì ©@ÝÄÅ×±-LèÏ2¨hRÀã2nÖŸ²A:ùzVšïß¿ùˇ¿üà—_hãýÿö?êO³1éÖç¥ÿuÅóEŸ™*½“­ê”wê¼$Ú—iÕÅ„%%ËJÎýÃ- („Íö‡Cu_Ýgãr`ÿ8!ûf$»û¾+€?Š?ów+xd,õõgϳñ,üÈdâì‹Qíþ"sW(C³ m¢ÒYö¼âžþc0—20GÆÃí31%;m®ÇÊc÷ ÆÊĆG¸ý-'#ÑØÒY&®7Åø@¯_¬ŒYáy—§Ç~ÈKæ!¦_s|" .îù€Äx¸/ðèÂúZÊ•köÀ/"V9&®¿D¨vyHqõo0–§í àÎÜ~VMšp¸«#S%¯ôuÿ˜£4Í\·|Ùí@ˆp…E-Ù‹§Éí– #7Ÿ0èœÆ£ŠF¼ê¶= :‡lEdæFcÊ!ÃDc0 hƒaçZlÌŒ™€ˆçÜ?åŽt«Œr²YËŽ;ªæØö±!þ4óNlŸËåþÊ`5€³T®ÏØVîµK èp5˜å#S7ét Åàǧ2vo§”c©Ž³ìRšFŠ5‡Õ>©Ol9r+íº³ Ïßôvä¿øøæã—€=l¿ÌÖÇïÿîÛwú¤ãOLÝôªúê?-…ÝUÜÅlì¶1RC²O` 1ãŒB½Ì d~­È´ØxÕßEyKá± à£TçÍ66Ìü¡"ÏfU`òÛ ·N-—õJXÒz€8xÖPˆ/Ùj©L‡¥hþNV¯pûˆ#20¬fÃå8õKè$F\Tq,á3þêýècÇ"É¡o|†û7Òc>Ùáè&k6éü¶üj÷SChR? RÀà—N<›v¢k)Éô s#N~7€ßprÐwPú=ˆ0’tðáç¹qáÿŠbŠS–‹}ÉÑÃüX‡‚¤ÒÅ'ÈN•Û¢Ó¶¨åÖë[Ý®'ŽˆÓJ–µoêÝj?ŒA}O1 Ði0—{K>–š‰ ~Âaöü3ÇšÚfîÜŠŸÒy®Žº¡KRR,Y6®“1(ÇP™ºY>(u؆]†³mŽ¥ ‚¬£÷’usj®±Ö±À@t½¾Õ#Ó®ì§ÏJzcʱ°å’G TK>‚8î’'‡äp6›/Àãr{¶d`^ùŸflØ6^uy÷·ûã§woÿòæ#+ítU—`ny_k>dBp—34Šq’ Ù:Ti€K딣M”ØÍ7ضyUÈÆß‡ika(H>g[¢ gq}t ™ÃÅÆ4KUŸ%cöNÜå¼ô"Ò,qß 7$3VóW7³Ç–qžbSp¥˜otþBr­.1˜n<Œ-?%mŠ „XcÕ¼mì:Â_+uÞ^]?M h ¿ä'Eýƒ›þgóÇÂÀTô}”þ[Ê/øx;]š·»Ð3qM-PbêèˆK ÅsZÀt¬·ø‘eóɸyÛ[z¸0¯"ÁP)¢¿JîgÁ ’ÌFÀs :ü÷0… åÎÿÂ6¬õ ~¼Æ'G´.ùo9ü›w[rO›oHËÍdó¿Þ÷¶˜énrÁge5ê0Þ`Ô>p8Ûƒù”­r¢]ãÙÎÞ1#/µö÷9ä…'L}hC›2r®ET>Cp’Ü9ðCWÉ´Wª/àˆSÓKuáæ^ÂÄÇ„ÝqÕâ~ÛÐI„5ïݯ_ýÞ–ž—†ô®ûöÛß¿û‘·<¯“«+–.¿®¾QuuO„Îí™y²í¨H°taÚv)­÷R>œ{’áÍçølìüAê0†‡€]òPDP©ûqÀÕ'è>8\è†È ¶’ÇöÌ>C“Ÿ·Ëc_¡’yxñÔ,ò‚6Üõp=1ì#Åz×á‚=üáRFðŸåÜ8·þ’çZX |NT :Ú¯ö=çšp!§ŽˆÜŸÆEŸÍž¬s{ð©¤÷·ÿµÐ(tCû>aÕ %¯¤³Qõk6 Å€gJDëÚ²c¢›£ö@±xhà*…•6Tc÷Òêˆîï«‘ÏØVU?1Á F£DÚN?§!ÓaܾVˆ XÒÎb&lçPyœOjÚ: óÓÖÁ¸çÚ¨Ñ2>ˆ†IFÆQc€AcS{Ý\},¿ùÜe»ƒcàvùŒ‹}ÉV L™é¾1£wžÏK¦Ë¸‚+fâØÕ‰ )U1´‡Û±ÆÇêÁX¥“a:¡vû¨ÁŸ…{KÐyzÿðå#€s`~‰í?}õÕ¿¼ùÕ¯ô'绿ú`Ë»SM‰™^h»Ì4A¶nËës¨Av9á!c—!•" þ"6Ä¿œE­¢àèÞ;\à ‰¤Fñ+Ìá0ûì,´á2ßè¤r¹l8²Y.Fw‘ofdŽYix›ÛŸw{7}pÜ(Þ5¢Û™9›Ä3Z§ÆèŽÔ2%Œ|¤ËbR¾‰3=¦?±ÓH{ÉD“.c"»exTê‡8&°MáL-߰לpœO'%ä<>`4Ô~Pý<ßñøìŸï ÌwÖ«å>Â%ÚÄS€ü— <R8[§†çеè¤à?ƒ»ƒJ½aÓäU¾ÇÜø! ¿k.qÐy l•qé“UqÔdygí­5ÍÆ„U;ã’—8ƒGgûÁk×»Œò$ÀN1AšSµ!²:(_[»vfÞϼÑ;±O?>¼ÿå€â/µþ_ÿÃøã§_}­?¤ËÌU÷Š53ÀÊåßç¶Ž‰!Õ9QÖ[›ÐÀ¹Š|$WÕe FŽê_8$³ôÝì]XxðR›çÂÌæ ‡þ»Ë… ¡.Š6ÔøÙç\ñð“œlÇß## ?¾ö÷*'á,Â4<Ô¥¿,d ŸW›®š;åÓ´q<ñOû¢»c*˜ó`!°,¹5¿ø&mºúÜ{ûá G]/Xe¿±ç]sÐ;~¸›qïç%\³1™…¶*T²9­“Ô±·¶—ÇP¿ X@g¶ÈËÏsÒØOðv) ‰3ãÕ ½|–`ζ3ökûÖmù¹'ŒÛn‘õarÓ'úÈÎÎù'AõeÆ#0Óúú#ë0l°=6’Æ9yM\¥ü¬Ó ý’h쇜àÂãˆ5E˜VëbÆ/úñ®î¡¢ý‹OâX‡bSØlytQÌ™øÅ±!;‘:>V!ßË]'¹ýp¸±Ó.ôÅØ¶žÉ§ýðþí‡?þøå§îÃþË”ß>ý˜|Ú³¢—¼“ƒW#mS»=³'z-W¹XÕæ”:†êºÈ¾¤¯ÎÃÍËr94{‘¥k->ãÌ·…9Ö+Kr™¬ülLþbž7#&_bJ'‹7Tc0(šV›uã8ÉÈÞP L/zâ\ñhÉ·ï0càI•t÷ò©q0˜ ÇJlȇìÂc’̘±€®ET®I##À»8ÈM­ã’rTñ[üXÃ+ÿØ,ú¹ãbÂ#nÑw·ê÷lÜŒg+3k®Í‘¤çÀ¸Ò©œøóÅJÞ¸¼þà  4:Æ™<‰i5ý'W2*›À®wBJ$Ý.fÛâjý5}‚¾„ð5U¢±eiŸc\oô´cÔ~ \—׀ͱ0“ë’ÁQ†”\*Q¸•„q£ˆ©»{ÙÄGº†ÞªÑûáÔdöH¼ÁY}D:£L¨U‚N{u‹ÀGÉÕ:04 ‰Žf^é{Dǯñ™ªÝóÆ<(·eoÄÒV—É¥ö¡´<èh;N{íaÅ^®1­Ø/Êðèè;ˆ-Î¥ÂY töÑ&_pXªÕ¢3ÐÉ=4k 8僃&‡i¦õ:¹žœÜ|/ó üê2Àr¨yö*ŽSW^+ ðéÕþÏ0|¿ùVl³º°¼J¥×\uÉÖùzGî U,3¯$Ç¡“;ˉt^ÍÇGN°·œKŽ}f,›*¯ÈòçñÈ+P‡ {"¬ýã?8µ/²åÝþèÎÄ—Íœý¢ÚA!9…È2ºÑ{l*@w•=}›îÐLeëp:u0ÀØ(t]M/AáÃé3ŽÚŽÎä¶èa‡º£¸˜”’GS°óäï¡£ªBõPÎÏ[Ç”ô} iï1GªæÍÕRxè+cÄÞÏw(3 qd—šc†`½;Bh'‚ëI3VÞåah}ÐÏòåêâ<†ÈyK;—Âöð?øyŒ,ŽK‚9¯{™N@¸üo8‘!\1@§)N2˜@ÂÓ+[ð%¡}’""¿TðÛ¢ºb;×–·q“ÛÜm’ë?i¬’ÏÌʳÆy20fBsåë3!ìvú ³âŒÜî”`å…Ô»ßÅGF_£öµ-rR¹ø#XaS¨y+b<íVà_*ÄØ5ŸrÝœ›dƨúú\b<–Ã5eÝ‹mõ½cØ¿e¦1 <<=¾úÏÿé=óõÕ—Ço¿Õ—§°²:ªê…÷Só\xª4€5 UFí¦€£ïò냣 ‹¯ >*ù1:ø²ñ@Ü‹CÊ,þ^å3Ñ‘½Èë‡7ÉÞð‹ xR&4朶*¿c6“+)ý1€ yp*z!uŠ_6¿M€-T>“Èäzh­[•%ygI;$3L¶yƒîF—!¡§Y\IzQɏ޾‘VJ÷¯‰EÞ¿1/ƒ­h¢ÄÏ¿®×ƒKÛšJLÂK `~ë<Öœ=Χ"mæÇVîàš–ÎèÈÃPH¥8Œ“«9EÅ9-;p ÑR#Zµ‘/^ØÈ]õ¹°‡ÚÞæˆ{3a.,)x Sù/Ä%Sœ]#ÐtnjêñFƒh½p¼ì35:Û Â¥:§ Xµ‹|·´_òù|ë?Œ¡•Ò1^2‚¨PÛ/øÔd®­4 s ²2¹²½«kÁqñÙàȾm„=TëþôÀ›9çÕ¤€ É}S²¿_6ÕC´6µ1qûxLúÃçÖ+x7?dòÎy’²uè§T7ت3.‘ÝEµ=xƒ8'•Ð?aN¡ö˜&Â~Ʊ'ÏEer¤< Íò!ùä‹û)LÿbÈ:ùwÈV3³vBœ}Å@îN(Hòä?NK¬Ã×r‹áÝ&æaF6.Ó C2Ÿqqæý³…’»¿O‚‰¼(‡™¦çÄè![gŒv•º•&´?Wb[ˆÕ’umV¶R]ãöc"xH°‹Çî:Ñ.më*<®K ƒŠÓ´82<Ü2ˆ=pu[s{d>›òà]C/]Õä §Ô±i¬³ÌɇNmÛçv%°ŠqŠ©­êÒ—‘•Ãøž%Ûg§a+|¦a¢Û¿\*WÑ•‡—¤ˆƒº&×>­™Z´ký€/—ù ¿ûþª“n]}îÌ Ù ñ¼ ¼×éŽ<'¤'ަ^'MñËd® Ò>__€è|düW)ÐE㩾r,Gò†#ÞþŒUíþ" Ú/ú²?b^û7†£?ˆ éP©ÌBä‚âÙÔ×8uÌ4¼?ÿ>õL+{¸’Âæž¸ṼGó ‡É{9çÁ-vYk>APq4fåå˜Fÿà»Z›ëÄöõ‘Ñý@59gÜE*]~{áÑ‹¿À!.}€ï­”•‹ôùLsij(³#$éLº‘s¸å‡kãlïI;7á/,RüªÛ®ÄmìPs]ÜCÀPª² –fàW9÷YLåÌÊ3:ÅG­è« &÷Íi7dEf ØY¡ÒŸíƒ=˜p2ìÈ}Ï~à`Í#€ãƒŸïíÓ™vå³]Âê†#".ð•›F¡qµõÍÃÛ/ït(ñµÞøŸ´³ºæòf¤cºüRæ&e*T»{¢Õ&Ó~±ÙÓҨݭzœTerŸ·c<©›=èö+ÓÈÌT¼»€#§H6¤d£Z ïÛòì/ ò†E2 ±šµ¿¹Nëu÷ÁSŒL.~(W;!ˆ TP©éñ•8Ú4ˆ?9¥4¶ÛÖ>ØçÓµZä8rí’ó–Ú‹Šj¾+A¡+/—!R¾´|èäýÄPN»ÃÁ˜ÞBÆŽ9<Òy\Õžž3úÐ2;‚Gn³y{œWNÆ+2ò Vy!oˆ[•Ã[@bCd»8V:’“PÒÿ%Óõ-˜gàÇ$ªe‚Üm#»Ê8—wùÝ\<æË˜M¸¹VÝMyÉ4à.Ç8d?ŒK¶£ªÊ´}O>¶×Gv;LŽC£lŒzHÔ0WEÉˬ£‚e%kЦüܸbe¢å¿9ðtذúœø;.Ê\ ü‡C%ØiOÕ¹¿£ BgûÇÑóõ´'‘mõy$ŸX_r)Dï‰Çwïþßx¼îó,G¯»“Oßÿ»7_««ZùúmfO,<Ÿ´CæÜ+˜jð?Õ ËÝÜ%9À &LSËËrUê}è& Ì»¸ûˆ§ºíµ’ÿKÞå!qrD+AÁŸ¤Æ¥š.Ž­)³ÇPrsâZt\Ç%~œ¯?Í6:'‘íQF"3JåhBx¢sjHeyàšcC»ü·¬VŠ|ŸùŒ)1·Ý1±Ï’©Ü?C£Æ‡–OSwL!BúX7c$›cagŒ†c\䨓;s[÷d0v`—I2àÒ‡c¨’G¾ÄܸëÚààôM\_O”*ÛnO|B!¼yi«Ø…ãþ³u î¦\ìvø•‘óô¾û{t¯½°½ú¢IúÃã×_iÁÕ"ÍÍ£3Øi¸V“‹¿ä™ ž,#ïE”|§¼<‚Ñù¾ðöd[ˆ«Oì¤7ËÝÐ7š¿$(ßþMöL^å»ÒÛ®Ô v:T^ò¹T·ÿN=X•ú>K^¬×€°¶¸¨‘Ÿã—t™Ybš;ßp=‰øÇææz˜On‹JmçJœÉšìO;èä¸õ›·ÕH‚%r+‘-1²±·[U§€Mú\s“Ef JÞ `žMfzH²…Ïüõ¯ó‡þºÿ HǪ¼ð™-õ0&©§çƒš à8u\è™{Ö+ƒŽ‰ê£yŽRÀgNg¡®/ ˜on£¦ »Â›£•úl’è·Íh·¹×3öò,ŒóÈãÅBLßÍÎI‡ÛèÆ¶ñØÑ³Ï\#@væJ½\ÆlãÙ——ÑÒ ô¢ÊgAPìþq}._°hvlÏ*‡Ï8nåíù× o/@ 2&嘫b:®w¸À£^ÂâpÑG²t;Šåç`ð‹ñQ¹YÔi¨ì‰¹…þ2ÂP$ôÒÍ­;ÑñÀ C͇·ïÞ|üðáËïè þÒë§ÿýùWÄÿɳovÚ~Qæë¯“þ³® Ñ?¥=ù˜,XpÅq³ž2“ªÖ @Ö'“.Ò‰ª=5»C_9¡3¯ôô3¾ àox A²” ‹*òû°«ïIïò‘èxL$6ª‰ªjmþ¨€Ôz'#ÏCöƈÖ[ï°y3$Î$0¯ŒuYX¸£ù`l;ž§Ô¶)œ´ùÙ}&ÌX² £Ã¥‡š^ RÍ—S¨q(QFÖšöWuüuUoüQýèß}àýÊ>Â)7Ë‘Îmõ·QP·MM9¢¥m'‹’PÜ;!— "¿±òÌFs»—Ëê9}fmþ„gª•§c¬èü ùyß Á¯‡»b³{K /œT¨rоb¶ÅÐÛ Îø ÕØ÷õõµDK`Tƪ±®Ýáìæ)«}úX(ÇQ«©rø—d•LbÆ•ãDÎõØc4¨Mfšôwq ޲Ö|­ŒÙ^ˆ½6ÉèêM”sN$Hr ?š«Oõg±ï•TÜNlÛN5IUåÚùÈØ¼Nce¥N><¼}ÔÚøúÿãµÆk.ïþîï~xóîíŸXù£,¾à:q›÷³*¿•¥‰ÓÅrÇL¦xIxQ~¾èëÃÊ “/ï»kòI6nø>‡Ýbc¾7Eõñs Ö—ÕæŸù÷£°üï X‚άð«òÊÔ~ªÓØ-Óf%TMe^©¸É‘vd÷•œ±¯@IDATdŲ¯šþc9Ò!ë°š—¶´ù‡!#2Xäñr5ËË"ŠâReX£2/àƒ˜4t½Šn-8Mò.B:èÏüâM>¸!¬ ýó;¤I\À½i£;ä£ Xeú_·áïÂÏGuõDª†°{«U’g£êQàM {Ö-môSûjH(„|0:æH Ô ÃY¼`FÆ>q’y__0Á…©>á&óLœá´}7‡{<ãØ,’’i¨§QÙÈC—Hq(¦>Æ–CÆØÓŸ`Æyû Žd8¼³e\Ã3€â©M8þ'*Û}õÕü:¤3Œ‰à^é<‡~å?¯hw³¨'BO&ïF‡l¹ÊÙ:–†,²rëÓšS>ã`çòY¶_nZp|æÏ+}ÚímÞ `C`?r¿U³ š%…Lø¼E¯ÖŒŽÇ-Ú8ðÞü„ãF×ÒÚ™•;z^-«uü”`ýO.Ú)ƒvR B¨u”ÏxÉÿŒCÛÔMñÔÑ>ýüq’ˆ×/à#ú!‡Æt½ ±.£X4g™ÜÑ©uò`\¬ö³Åo°¤öÇoJǦuõÌ=P½Œ+·¥ýˆ„‚ƒÅ8[<Lt×r,Þcøë8ŽL&|š×…ßP[—Ú¿Ä©±0©ô³ç¹ÍÍgþéNú;x{®¹)"/]…¥ 2öÝŸŒÐ–—÷飶ſ&©×*T×1ò½Ð‹uò¼¡ÌYAü`…pž8¨ÍÝc¡SåàÒ·/§óšC6q‡wÑ·ÑÜCkM»¿ÍYl¼pÉj¬öaC÷ððø§Ç_?}ù`Æå_ýôÛ?þð¤¿@GÖg Ó+.¸ßŠIÈbÉ|ã±K'ßEÜ7 ³(cR iߥë Uyh]±Ô\0eŠ ý‘Áj—3ˆœ8òä8uÄï8~’ðCÁG-ÞÞøGç'Ѯݑ'Êì¶}Õ{ß½y³6-üš M8&dç9z8òp·#Úײ¾¨´ÔfŸ à ñ1ÙÈín)mVÒò^úÔ¾‰V+þ.FùékûK¯ŽØ§Ž!ÁdÎ\B¸–º‘…‹8ЬߌJMÉ!º;zܧûͱAã*6v–Îò¡ï0H\ÎjNƒÜ]®5–JÃ%ñ®7BJôÛ†"9Ÿ6˘՗¿&“ø OÏ,;NŽíaî3@ª·:Ük­UÝhÆÙ²çû&çCa2P‰‡ç3k°lLú3³eèLUÔ} qw™~td" ÒcÅ%.Û£­kî j™–Ä…ÁäkAœÆp\sãáIaiÂÅ÷8.j£ãþ°~pT‰#®Ç‡?þùÍW_ޱùE7ÿçÿãÿüã£þ$0•‹ì‹ï >‡IÁE/gñ«bÍZáhû-r™;í NCçÔi[åÓÞ¨v«V<ê•v0œó/öD<#„!>ô¨,è‘®Ï×W{cÒ'~1Pt`Br¹¨ù·í/x}úŽB¼N*ßQ,xþøaí>rb\EÆMGqÅÛÚ•x[Üß%Ì¥HçϬٽ”äÝ Ýy 4_4i4Åág Êš_”RÛ÷ŒøžHÁR¶oºNŒŸpò< ÞœàÕ_4}u‰ÀXa÷CF· *ôŒªžÝT&=‰¼½~GôǃöÙd·qŒÛxoì¨G!ÉŠô‘v7Ŷ®9±äã¯èУ®žÉ­’Ì—býÜ›"ßÑÈ“§½cß³X1Ž9q·ö«l”uf34¹Æ¢³ ‰T qhŸ¼µUŽúÉyû„ôMq®$;×åé1:|Ž1Kñi\tm׋þïvÅÜër^ò¶re4\éoðÛë”Ónd¤—|vÿmUB½^x’·]o¾çšDwRœuáß~ÐÚ÷å€A{%åÓ›o¾ÑßÐtè+.Ï ¦&;¥²Ú™ûçD‘©T˜Ç¬Áœ8°v¯läØƒ G¤øÇ'·ßɉ5ÿÒ‚³š'[Nä°¥/oúÞ}ÀjHÜ å‘ÎxŒøˆÀ›¾ìlÒyP0œï²¹9e}é;1æî#$âõ¢"Ño¿Çvá„÷ÏÈÃ)??¨é6®´]håÈÚÚ,+éüNqøO\àq§eׯ@l³ëúˆÄ¿sAŽù>@#hLábPèï”GT¤ #:þï/Hç§…3A0õ§ÏD0J™;®Öˆ³†Zÿ­¹zcmv+iبaU¹ý‡©¼ž= Ÿ‘·Øpô·Ò £Ü‰èöw†Ã¦ÎM3,¸øMz[Eã3†±âŒlàxË6T“Oå03ªÁ­¼'6, aÍa;†#NÄ«®1¨³,#Ðñ_£XŒ|Öà€™¼h¦+ÉRе¾!ËGº¨o㪞’GKÚkñY¹ TŽÎŸú˜è±³=£l¯k ZâcOc§3U?Õh¬Ä^(âº^ãh®>=ýþsøSÀ KõgQ>}úøáñ ß6ÛÝÍœÐäÌî/S4”zòä<ý9úà·ÖsŠ_o¦po][x$* »¾-³€#®6u¥Ø±nÍîîÑmïɾ[Ì;DÓ+ÉÙÌxg½ ƒÑMNm¾¿w–Â–Ž»Š;‘UŽ’§ ËŒÕ%7½€ìW”‡Ÿ?Kñ©¾rHb³Ð§ó´ýV;‰Êè´TïÅ6 üx5žŠWþœRx•Ýaèâòq R0~Ðp×ù€ :Î'§#.ñ{àíM‰L!ú΀öž-ô˜<ü«‡\ý5ºšÖ÷;¬Ði&ØËÛöÁ4Ä3'®[ueÉ¢ *ÎÝb‚Û³³~¹vû¾¹0:p‘fTaüª½°ñ±Ùm0®T¾ç%‰Kî®It€7oŸE0zÁr]$ûV¨ŒAŹbÛÔ1,âˆÚg©VŸÑ{nV\ÇÙ2.' ÉØl¿Þ7èÊqõʵqØg®æpÚVúÍp×ëÛ8ãò3Õæ`ßãžóÓq €Õ/µ¬C‘96,ÒeŽÊ—ÕÏ»ÇýÇã y¥uöºWÚ¹K·ô­ÎŸ4#zÑ{£{ÞhFt’Ðò÷äü£c‡L>|ó±Àþ1:âx#•ý˜J¨—ÜÍãÔmk´Îeù\™2—³H¦l)ù|áÚ›VÙZ‡á<Ó¯ÊiøEë,òµxl¦3 .ãåã­nkÍ…´Fg^ so&CoèáDig%:{ãKþ;riQùZE#)cßë7Üñ¼Ff¼bàZ§›È'˜0ù¾õn»À„ò+;{ÃG3ÑÚAòtúŒÑÁMŸçág-Pðâ4oeò ä:î¯.káqOÇ,ÑÉŽE¹sm:§ðV\ŪƸe³ dRð…@ãwxwկÉpu§W3R{@ÂmOÇã1ñ7ð®ãÉd*×3>‹á 6²s­®:–v»@õåz•ņÊq¤Ä!mËɇ\1¹$5ÏþŽmªp. ¯Cç\Mq^æ¡ìH8‡´ÎŽ—Ö#’à);ÖUNÜD(6ˆëùÎÛœ2–ñ³[‰ÙÀž7ø^ÂiŠ›ˆ[U“j±éžÕ›tŸÅÛÿt¼Kí1¯³ùøý÷úÕŽù¡®=‡Iå¹àÉà–.þžÔl6ƒWÃ˾û&äso¿â“>?‚W)\"W»#œ›Lä…½ØdŠ-šLøä¾Aئ/ ‰åjÛº´‚ؾȼhõ ×Ù(èS?Û?ÿèP|áØPxµMDö}þ8ÐúÅ@€U¼Xêó8³oÝ” ÚþÍî§v”Íj4é/‘(Y¨cÝ£{¾R0¬È­3¿ìSžY¶‘.Ö%(lÉæòN€ßâ×cÄìâŒÇÃGÉ Npyê` í;ÄYÐÁµÓè;Y´Q¤0‡N #S©Ù˳,|ð—ë…Ôï\ ¬ÈùÈbRX‡¨†»<ºX6y]‘…A›Ë*èV?hSV=ƒ¸ú)¹6pÓñ>1›²3âÉ ™kÙÚÁ,FÙo \ŸÖ÷8/ËrÖ#N÷¯²QœÈŽ£ÓŠ·(°˜ÉõÄåã¬A™ãÓïY¿'Rq±n²sl2/ñÉ?/<[ÎCyút͉{%óí›kwÍ©÷D=cQœÇ‡/ïtH^Kýô›oõSº¸ºò|ÎÌ}ÏÄñ?©sã«AÛÞ5 g¾X%³Kê Qð®žû_¾<˜/n&»:®IìÔ-f36Ro‡ ·]¾ó°R]¶€úÁ;Vã“ix㻑}€ºíøÓ—¼KàwÜÛaÖxúÝqî;KŒæ¶w;éH‘ñ¢ÁC Ñߨq{¨9ÑT¼Ö£ÙÖQ%ƹ† ’†~bSV²j. E‘G'(8…úy&~Р¹fâÍêãϰÓ_Hà‚V:³Ð6¹j»MXì. 7c‚qjM˜EÑÍŽ«}–Iµ­Á§s³>\6cN y޼sÛºúÖÅý«ÒQ"ÄÚ=°z¼† ú÷ÆH›ÔHëúWÆAœØ)<ì˜ÎC΄6ž\åˆ;>Ûuz_ARê3=™¼ì'×a»cº•f±MÉÄgç8q?V™«vK7Õ4lkh2WŠ(ñ)ƒ.SZ•6 ÌÎãjO4°AEN$ÞÁ“¼TE-…ûV->Ùê-Y÷‘þð—€ É+:ÿý¿09½ve\ÝÓ”Èk˜.Æªî —‰­õ˜Ù3›¤ÿÐŽuxæÈæy>ÔçÒ0¹ËKdXZÎvý`ãUll°´….íb»5”/õf¥uö«¹ãŸvíBæ¿)°œ×êÒèRkôIT…£y¾"w{xÈ-E­ÅÏêóy}ígØœsýF²~"A±Œïv’y#Mè<ÖèW&šK#Ö{£/‚:¤<¬ùU;/—E懙‡«ïÀ„hâî¾ôYèö•ö«pü[CèKŸ$(Y«LL{v¬êbï°wžÖJr, íõ­›J’ö0$n©+gÒ[µ¡`>×^ýÊ­Šz"[ghOÌÙ®µõc<1¥±NÂEÞ¢ýëwØ\¶šWXVƲÄéïuœÏ+·n¤á©µctÊMíÔ¥/Ö;G‘­s-’ëÍg¹®Æ8ms5HÏã‚{΂¶úç>«¿Ë1cuªÛ¤»¼(xxúò‘}Eç§ï¾ùgþ"àG­”¼àê¯ÁÍô;fV4¦’‹Ô~N tW¿câÈÆjÌÌ&$p{Ð`±¤Á ¨µc\Uòð·Ù¥kVö½a&¤X0è8âÚoð³˜"5—=Ñ“eyχ6ƒŸÚµ …®_ TóVÊréA0æIrlÊy\r]„òƶúSŽôtõw"†‰ó&HªÚPb4²St¸0Ï$wZ¬ÑÙ»§< š}Éÿˆa”óF©|dôÃ'iÌù㞇¤,üÃ}'wrãr¯Hk‚öË‹ÒìËËÇ£Þ>³<’ÚwòÉgº:™TÈîï&;B `WA•äð™frÝz·€;÷­·U2uƒ[íú,]l4`;@½â,Àp2 Nšƒð#uÄ1­ä¥ZÉ çÏÆ%ÿºR»]TG»vj.Ͱ<U*ñ\q£\±VªÒ”!u¥q8ü¶%>È9þÛÅ–us¡ÁŸóЕä×:Qãk€nëÆ£{÷ôÙ¼ðvÆéÕWOß~û;]XÝ õc{ÞçÊóšnfOœÈœkÉ:2¿[?¯„#ãÆ[åÙ둈ßþâ˜è™•‚0uÝ\'XT±³D9 ñ >äqO]ðøtò‡@Ê’2ïí?oûÛV¯$ù8€w><䮜Q‚E£'ˆ•D÷‡N1ý%9{©í§¨‰,âæ˜w:&3¹ùm:xæ µó 6Âúy'ZžîÁݳcøúîȳ¸ŸVÔô‡Ä›vzÈ÷2”à¤ÃQýâ¹ðã•äïh¼D—Ý—r534¨%t–JSúS 'òµŠI§É<Ñ f\Uû`êtÕ›€yEû 8¹ÇI°Ýä2ª2ççkÆ$¤9G^aÄ×0Öu ÇǼÆgò \’ÊÓÏ-XQ£îäD²13oq,^8fìo:o£‰²¬ úÒùçWý-{ñn;-J¯/íŒûïà Z6p»,ÄV9b¯bú“Èš‘ÝÙÄ}Ë×œÊØ>mìö½Ç<¯ýä¶\k†Åßuyzú]˜^ÿy­¯½«ó÷¿ÿ¤Ÿ/¬ñ£|y¡¥)¤+Ïï¥ñô›š‰Å„8Æ :&“)¿'Úb˜]þLœ8ZüKVF[PO\\\‰¾*êsr#[§Ójƒ±2Xš%`Ãm(7\Ì!ÓFÆb–¨èla˜wYèè£7êɺ“ ¤¹ì‰¤Ëãëè Eç{±O¤³M>'Õ¥ ÍØ‰‡­ïb0ÿeô–&WÙr×ݘ¹Û<ヮ±Ý_‡ž>Øo˜8QáQ4yl9\ÒÔÍ=u†!oŸXãYdêôt[âSÏæ ÝîÉ•åÌ5È`3’õj½¹îó3–FKÿ¡‚oobsæA†»€Ï¿°bI¶¼Ñ[wõÙÁv|wnámON<ÑzÝ‹3œæèÌ“#íÜâPãÓû÷úÂøçQ²Î|}ýáÿþOÿúð7ßi#Òê«ÿ,ò¬Ã\p¿ÓÊåù ùÂT¢óú¾š¤î7SÁ wúy:Šá_¤™·®}s^æ¥Ð£P×€½IÄTÆÇÃ!•ˆ$è?9Ò_rjÿˆ2§ÈžEytªóý†¼â7N'øºñ[7./âèð¦:cEXG÷ ûÿ¨3~õ“üÝÆѲå²Vzä¦&'þ‘nUG‹Ì¿àse!¹`x´jæ„ôÞÁdª€J‘nRl÷¬Ï;{N ,mÃëdQxÌ•1„dfnY!a¼=‚+)\Ft¿ðÜEF»èd(èó®róɸhDÌ—Ç®;vtÔ½fð{A¤æ8Ÿ[¿ 6*äp$~æ†p‚;²+i"#™bêD•xÈ™« ƒv|§ "cÕÜé±óŠ0îwËÁ~Ý5üÄà2Ó©l¼r&“ë‡ÁGí*qi&Bòòyì'z³ÆÄñã3¬ÒlDF’ôÂ^L¢m ú¼[…GôÅ4ÖN!vs ×':°ÕàåH¾QÿÔɸÐÑŸ¢wOÌïAÜVÃm–Ã_’€ùýø¤"úl>èzæqxͧÇ?üáLJ_½ÿøæß´u{2¤·läùU¯ºøž¹‘fª”‰Æ¤;ÜâcPô•A|å‘•Ýïø3vd³Á:Ϧ(j›ÐEÞºøl{2sLsÄÇ\æÙ²9VÜ“'ø€I&vvZ¼²çö"õû÷Ø|×ïJ -¬»(¬¹F`’±˜Y‚o`ä º†€/YÌ«Qï°òïÇÉbj‚4W|á¥ÄµRt»ï’Çä·¾íPž`M ±p†&ˆ÷…®å`l@¹Ñ×8çÖ·IÿI$ä„0“À>ëí)ü)Â;VÕm è#á£ÌXÓW‚watð×1)gö]š«[ˆ½Ã…²€H;Aç1×[h§2®Ä EpäèJMíùÒ‡ìy£ \»}êhvƒ}*fÓ$+ŸD&åb\>¶‡xÑ{b5o‡p§–ÝHްÇFÐf^V=ëÓŸÅ#Ýâ,aoó`êë ˜’AÆMº¨§aS®Ã^,ƒj±G[–Z*ãUÆ­ ëfF¦l rt;j7ù¼^˜ä¿Ôe|x÷öÍŸøáG¢|å¾®½Ú>?þ»÷ÃÃÛ§?|ú·ãÂk"ìÉ£W(òJì†L¤==cc>±Xà›ýZ µhcÊ.9Å-¼ŒÚ¯ì„¼.ÛǮݥN6pKXtáp^rÊ“{c/?š´arÞBí.ýÈ ü›6¥û¯PÁa综Ýß·üû–8ÛNüMì< ”TIœ±¼Ã91‡Ê‰]Ãeç*ý£ŒnÕVî“b]PÁ—çÊCºi»†R×Óµª•Âf¾é¦ÏÆêDܶã©^¡Ã§:?!À» >wåòiœæLˆ)ðú!„ñBOâµcœvUíª/ˆì½ŽC7ש’ +ì^ˆ8€LœÄ˜H®t"/@«b.tä¯4º¬G×eshSndZ Sj¹Ì<årryøŒ±šÔø„íä,Æ„ ÚZÆôòP´©ž=1”oǨf-Ö::óÐN†@âö¢ã)váhX¥F#—^ÊÎ4.O\FV•Vt´+ólyõ {p¤R<赨³¦M©ÇUr¬¨†)ww…ÎË«3¾þúËÀŒÝ«©ÞóÍï¿úãO¬TlÔª:Á²¿2va=ãàE)¥ €QÌϤp vÓ˜×WžTç: ¿F÷£öæ(YÁﯬïHÇ“ÎÃVN»¤–IkR[ë.oðCP»Î8RTÌG‘–Îáï¦Aè¶Çìþ´OÄÊæ©m„õè9ì’ýÑ9yL¥ó¸Úß].9ÉÎí}ï Ý-;íÞçúoy ªQ;> ä{@Q½Tºé“2.=žuá4=5ýÄ@Vñf~ŽqÉ}HÌ)¢ÇVõ¸ª5ÅsBN÷œÕ¡`yeÎ3¼„x©Dß$Q^ŒÈsX¥“ÅC‡'·*0ײ5Yª7f(ÜFG]Nô´[Š‹»x[Ý ÷öéƒ-#/¸ÌWÒÁâÁ^6j·¸6‡K9v~WÃo'ñ»bçª:¢1^@âìë=~;£!ٜ֜[7-WÍõŒXŸ¾þ©¼ý¤A©RL¤¥V®¨áÅúÄììÏ>½èvŒ= a‘ÿ'«Þ‹ûÃÛ·o¿|ðò@þrµÿúÛßþðéWù\p¾è›mfäZè±¹›ç´{ÈöÉôâìùV ðKÊÉð² úmW ³øve¬höߤêLl»¿4Y‡3Õ©iºoI-ÊñÃ¥qíErW]Çô©¸Ô• T¯rUÑò RŸy»šw9üN³äöw}ûŸñ€†$uÐdSƒ.œRLYß-¨B‘¶Ž¨=Èä^vî±€ ȉ‹¿ó©Zª5~ÏI¢[ç×ç•?ßCf¾Æuü¨Aë÷ 1@}S`ûôc óŽýÚøÉߘ¹Ø©šèä Ê-«ç]{ñ[o‚=7o¥4æ©#-Ó(ÚÄ» ùY¹‘/¨VvWÿ;cdz›#ÖͽáÜ–KŒE!ûÓÃþôæÍ—w.ô „ÿÿð§‡_­_¤×Wz"æš3<´j±p±Ð{±w»`ÏÆ½&Y#KI§^&Rx³Èwú5V7Güy91ÕΧ#Hî‹CrÂ×ë+¹©Ý²Úl³€c[ú¯·1ÐǦsþKÓÌjDn¡]9ž•‘²¼t¤0dðTÊ‹µ÷3Õ»!}©•û÷y¥Ò?8„èVðmYdpwÜc$Ö‘Q=œWû.ºVÍAJÛ$[ʼnà§ÃÙ.ÉèšuÚ&py_ž> ”€š 9%¯ü…—ºsŒÖ1e„³‡½=XI™qï;±]Ѥò¨9wDì>˜Ó–ÕžölŽÃqäí?¶Õ‘G0ãpá¹^Så?s/þ¥úúQå}Dð€)IL*¦i;q¬Z§ã2=¿Žmçê™oɺÊŠÜ j"Òz)ê³jJíƒÈ˜ÈAÛ×ËfÉW†±Ÿ4'€{èéñÇßÿêW_þ@ðu¿ùî÷]Nøò\Ï/µYMgbäF˜Wj3üH%óE,Ǫ Yü6ÑÖá…<¿¢Ë‚1¼YìEÚEÛ‹º öÇõG"³I²k6v9 <ùÌ‚<)üÐ1Øì¬[`¬#¸ÂJcòWBáÌÄŽ4¡·W<½Q©ãç±tüø&x^ý—7Q¸5G³6>6ÿOó lþB ñbʃ}8ÀžÚŒ-¹´p}zÇó{äÀƒØ*´{¨Î\¿R÷{ø,»Œ\ŠUtTç¹èI€ŽlDrìó0>&uÂñÇÂ÷ÚnÜ¡IÎíäà•Õ„à" È¸Ý ¡XåBn#¸ÒÉã ‡P׃½R•‡«g3>:¡ÛHwûUWßÀ+Õ§òõD KŸ6ÔÆ2L£ Ï9‚q´H*ÓÚ=ʳå"ki}¥ỔµŠHULF Œ#:±% «sQ'7Þ:åt~y@%û¾V\b['T¯ï\,ÇðøÙÓÎ Ks|&`öÁ?y¨žFóH;Ç>—๦©±ŸÅi8ÈX Pmõã»ÿôOÿ¤7>òÙü" .ç§§7¿ïëz>{÷/eA¯ƒ5ŠÛb¿ŽèŒÀ·´ûJÍ@)»¸G&Uõ>oF¾˜Gém^wz”<ˆðE:/ä’ÙÏÙý‹…êüYfãïŽÓ‰ håºôÕ/úÐa+)¹õ±sì(@¬Ç6í¶xËŸ1¬ÞÜ`Ê;+åÈŠâ"}ž®ð™Íß?ì0~›»ß¥ðËÉ´Œåð o(¬ä”¼r^±Ý˜W ¨íÕƒª‡Ç­y æfÔ*5ÓO®ãù@@~(s&ÊÇDuJÜþpÞG?MÅž>ÌÁA=G¨BÌévd'šŸ.ð¡¢#â4Ê3ŽÖÛÍ'Û£^ç^4_;Ѻ†xà?Ø=8øÒ#Ù‡Ù×åÄt2Kg|I†Û>Ö¡8˺G™uÕ “ÀöVMÏCâù2íÉÆvcA |—É£L©Ñtîgæó/xÎ;§H‘Û>ã$÷hÚ¢£-ºÞä4Ã!Uò2Fîsåc¶ò°CÐë0dáΙiB®Qq ˜r»m’ÆaÿŽDºCîœièŠMØ«tÕÝmÈM¨uøNÞ‡·ŸÍï`¼>«€ùéÃïßy"ømf]y¦…m¯&¿oW)Øwº 1H¼|Þ‹­œôß‹­çTäËÔ>lȲª¹¨Ù¤ìή¨€ùn€béã&s ™›ÏÔÁ{«AûA’§*ãapŒ¯º à–œCˆ½}m6“@ÇA"rÎôUܸ̞`.{Â+ÚÄÔosÐamvÙÀä,™w6À´$Éè±cˆƒÁy9ë l3öÞaü]Ôs¹“3¸ë÷¬ñǾ^`t$cnøÔÒ±oÓ¥®§´—qœ¼ñ ç8Ü' ÓŸ| ™1>þ2Ïlõ@¤Y^LãøB‰úË"0æÑ¢P›¾¸GBªPq:’hÜgrgç—0Ð5ÖÄq°CÔ8¸A®Â¸˜f"ø×]£\{DNàñEêÍHkÝq7Lpé„ O“O^™¾13Ñ7În7ƒð‚(6ìû†r㎋O¨çÔЦ43.ú3.¶È“P[WG¬ã~ÜœM‘£0<vÎù[r)[óÊ-5Lw;—ñÔ·‡¬Tž›Ž‚m—Ó«í"êX¯ê6Cµ %ˆîËÏæ €ô¿·þuT^©ôøýoÿÉßJãfáeÎÌΙ 4¯Ÿ±mœ]tÊ"©KGü{Û‹N³xÖ/ÝoЧ»Ê¿ÕM£îPÜeY…s%z×A+Œ:dÑïWÈ“#7uZ© ¥jÚ|‡— Á>}· fÃò¶·›9qÓg‘œ±Â—#Ôfr{§Ø9@ôÁÉ7?c0Þ}UÌ娳0œ[†@8×˹†ô¤šfVÇgu?(áòN@~Ê ±=&“8¿ ÈÝ3§NÓ±Év‘.9僻o€Öà ¥4ŒÔçC§ç ÐÁä^;r3禄8š‘F(” bH:@%5‚ÑñS®ÿJbÁ`Ù¥œ·YBÀŒKxíè¸ !C²Èyó¦Á@TáE°Lû`§eåðZ VsPg²-1Ô;—Ý<¡áåzªšîa²b÷-rr°uň4xç­û"¹éZ‹=‰Y~+¤÷4ىÛõÈôÍãO2räÕÈCtsiô8ÒO «¨ _rCíH:ÅŠflZ£bPó|Õ”/’˘;vS{Èà‘ùV¸LíÓR;+w½Ú:¬å‹<6äU¤c»ý^6LŠ@®û¤½YcÊ„_s`Š¿¿RlòØ‘?•k‡Ë„ZÂ!;.:Ì‘4gr Øç9õ· «¤PE5Žï¦3?bcí‚Òá®;d79­ÆòšpcTeˆÏÊM‚ÇgúËu ’¼'÷8¸=!í5©Ùêárç¾)ˆÛ–oãá1½Û8 ‹ƒ¡}ÊC³+SµmÅM®½¼CŒKÇcTÖ=06ÊÆÄ/Z…~ûö³ú@×öÿU×ßë€wz›G»k*‹ßžmh²Ì-a{@¼NRmbVJo' •[Ñ?³¯Q÷F†Rxûªí·h%{S–ÌÚíC0n|ì65/èÈÇ„Óý2êfƒ÷Œ[ Ÿ#¯ —2j›/C…ÆÆxÐÌètŒâ+géëâÛô/õd–1ãHÀ}Sý$¿~̽s—/@ô}ú¿ù­S+Ř\Ó5n¶ì Ûƒd·µÙI,2×$ý;( èµBïµx`è]Z?VŸÉ£oã—ªŽs¨#ÉiH¢èØ)œ!²Œ;Û}Xx ãÇ™ÿ»¡‘ðœ£;¯vø’Bûî9#l½À8”®Çi««í$ÑÙáÓ¶´#K0`ü/º‘‡£È]LVqÐ> °Å!¡n… ßtƒ@î>7ðð %2sÕˆæ1?äqy^ ̽ÑéÞ•çoljáŠ>¼ü$Ãݲ®gªëSŽÃtu> Gœ>dÔŒ\Nt†’ÇáSìµîL=3Žî‡Åñþý‡«ïë–.kÃëîªÂï¾óŸöï@×EçæÌ¦ª‚L'A&Åž£L¶©lLr’c&Lƾ*e0ýOfB²QË€jOàŽ8˜ÎG03ø %ALJð}E[:@úØ>q­*œˆ;«KõÓ¹â?šª8¹°\.µ7 œo¬&&<ãá;8r{fŒý „†ÌJUB7*B{LÑ!bŒtXnÊzGÄ jÉ¥¥ÑÓ“hÉ”r º«IK^÷8è\¨uX†$D±!·4gãÌEõÅ›÷¼Ë„%Ó@„\dúÚü21LÅÌiÐCE*·urAežG©ó%Ŷn·ì`Z‡¾MÙl–l§ÑbÀpxLÇàqR{ó´Ñ>ÄTvñ)íiÚâ1’bc:rñƶ5Fî¸öÄG ŠëÈUÕ°eZÁÄÆùy‡>˜Î‘æŒL;CaßexQΠÕî!s^è`Wí›#-¯=jžvë.ŠÍaµ8¡=!¤ìwÀ].ð¬…Y×ýø¬8’Q­rF{èhâÊ·c]žÇ‡·¿oûs¨o·þëîòÓßÿý?z¯×”~‰­¾j¥Ìƾ¦•”Ù軈fâè<3ˆÊ_䲿ݯÆ~ˆ°à‡ 6m0}U¯fî”S¸Aüsó€çŠx#—ì›@±P³­ ;ñ©¦i¶.ô½é|Ëy…ƒÃÈœÜ>â¢ÅÇ#¢vcÜÈÆØíÑ1lgc7 ÷)W,ã³´RÐ&}ëÇþަ,Þoçi;ýö[šÒ­·6é—s«Ï º{Ñ[#üƒ‹Àäsxy 3-Ú—ä >³Ò‹ô}œà ] ë|—­¯¾L!{¨Æ×´œÒ¯Fýà£#þN4]s(]äx£Tk$CÝ‚Ùcšoü‡A¤´8š'¾±Z;RÚÑ£¢EÎÅ.§­0x®eº(ÐÉÏã ­ “îqê¨z'!œrH*˜ž-]¶Í¸,ÖPÌ`ãa¯ñ¹pÚ1ÞqjGg{ȇOrÛqͱ.rxÁä;3WŽÞ-»ØõoÒÉ(á9Q÷&À—qcƒ÷Eèê>86£¾z…êä+u¿D½z5f¿0¤}3%q¥Eg¹W^›%ú–ú O*+WnšÞLßȧw<4ªC·_4åÃ-Ûqb“û ¢&}õ&OŽî|83&aòOVx3›Tþ‘ºÕAù©xS_þºæ¡±­ù¸ÏèÅUÝÿÏÞ»Äj¶lÙY¹wæyÜ÷­[öµK€,!!!=Š>¢ƒRAzôéÐAtªAƒM:¶ ‰%\ªB€–LYP–êK¦^På[÷¼Ï©{Î=™ÉøÆ˜#"ÖŸ;ï©¢yvFæZsÎ1Çœ+VÄú{otBvzs¶~q ÚòötÿS(uaô?óGüVúävdG™“ؤ4»’§+ùé ÌøÅw%^•ÕcSµ‡±s~òÕ[`ëËxgw w gŽ@È E$7-«¦Á¾†ML&‹L~¨µl¤Oæ8ÜQžsqÉÅ$ôW`^×·ã…Ú¦ÕØ²Æ:^DTé¹(%®NùÖÇòø˜4`òâpWˆ;râÎ}”2ýmrúi‚ÌѸ¿ö±äôJQäx§®Ï²×X²ÚS¹Ñ‘*$œÕ bp‰& ÇâðN|)Í#R9*UçÐLŽÇá%÷üâÍ@EÈœ5dï¼y`ö׬õ“ßüÍÏî¾ý­Ï_hFø[ÑZ™,ŽL^8FæíhŽØT-ó‡y‚‹/^½ãç"ƒy¤óf,C÷ZÛ ”Ý<’Í5 OT0’©¸¹ÑÁ5ë­i8±‚YŸ“C¨b>|ÚVíûãøÐdsôÇÄÆ2;«žÒþVv Ne*»^5‘NLÑ ƒoýSóh×b§¡ëp¼ÂÃCØs]Ãú§ü„À’7I.‚äóZ0®ptlßø%×<ôðÀ’A‚}bМR_on°pÛ$;N@¦}{]C‰‘C‘('¿•K­NäÚÉÅ›øðÙ?êPõ,{ç*f8«£“UuøÇ]gtŠOyø+^¶ü$Žøp ’reS —fÙ-ç„® ´}¬Ø6ûÌ5Yn›t©Œ[’äîÏ[NŸ#ŽÕ§ Þ#×K˜[Ü«~%/°]úPð…8BçR!Œ÷*g¥dpÅ¢:ÛÈ×À²Ÿ€oäØOe1‡îhÞv®÷^Bw•­r¸‰[Ùw¤3Ó‚\ÜŠÁßýF7m*ÞU³¬öîcÖž'OŸÂ÷¨~ ð\Ÿ¯u¹ÿÁ_þôåÛÏ>yò[ˆ¦8wØ~ÎÙ †4ó’…}ˆE˜_ƒ)Ÿùk!£Ðˆz†h-*6ðs3ao9ÛÁEÈNT8¹á sùÖÎ;Ùfƒ“L<..¸Ë1:^M›“Sß6ÇAr}|“`ç@ICÉõæAµ?ú$Ëü,ö¸¸@@9nvKZ±‹Qä¤áqÓ—Ö÷dE‡œßn7‰ñ0@'•æ¶%ã:ö¾³ÒE´~3tî®3ÊTËôE`®—=H0#åÒzÄä‡RÇÊuŒÈ¼rÎç¶ñ,Æ´îƒ2Ñ ÷-È!A˜dyÐíÇ•£¿Øiõ§Î­‡ÆAÑ/[9§ÿd²´"m¾é`È–»Ä7&Ë ƒŠ¹ Æ>uT}‘Ç—j†{ñL2_Žñ1ÝÒ«ÑvWv€`«r͉ãÄpø,ÞÑ]\$ ¦ÁÈÑrÈØ]]±V àt7énŽ…~‘hTõfä3Ή·þTä…#žçõn§/°Vɾ7Vª¹'kw=˜ážÇPì+K·ÀÂ>{öÅ‹>øìP}훳$~íûéÞÿ3?üøþ·?y¡“ù•”Å6rG¡6ê”ÝÊ|Î[Éý]ÚþÀl0l¼ždÞÆ›Q6©×íÕîFîèp˼ud5ÎÉÏFvd”ÍŸx-ð’—š¼êtÖ`Ùü;±/Gµ)õÁ!”T–þŽŸµFàpq¿y3{0¹7{Sf<Ä(š„ƒï`ä&¦±o®Ž Œd÷mröG+‚$ÒC4ù¬?Ô Ü?âGC8IìY=6—mÇ~0x¾*ïØ‡%ùúšVQÊy“+&Æhp:¹œ /ò;dÎcäÓ§ƒƒªLy àÛëy+‘nœ©ì¥Fùª“ɺꑓ[×Ó¤ête¹øHX÷^M]ñVï2f¾AŠ`í0rÕµ#Ï4Û>Õ§²°Ž!ÙªÖè•;ºæà~YqÕBøÔ?8Œ¡ €2º‡äåã Ÿç¥Æy áDF½x€œ>ÆŸ޷\±J;>¶ëD7 ÚÈi ãXѹhp– †.$×21X™î?þü­·Í_d(º.ÐþÚ—ÿúw÷“'ï¾ûi—.¿ÀäÒ¥gãf"xBÌ]›ù”Í=î6ÌÈ™‘’4’øSØHÌ…NÇÚŽ Ê¢l¾¸øÜW¨~{¾¶!v܃£¼ïc÷ÇÇU¥¹s…XG9Tã³ `äéOqþ¢ ðü†#4Ç–>d¥l+žÎC-ü°Å>þ–ÎC‘§|~'>ßÉHZx‡!ñWˬü SÈ¡_Ôßðxû‹uÊÓ¹ÔM‚åcÜV²bl¦g\9yr=j&ÀêbcŽr‰j˜m(‘òNŒ#ôNYÅ7WCÖ•·%4 ¦¤íwú«‘j!à¬05UUã2r_é'.ɃÍä¡>Ð÷ÉsA,Ó¯Íæ[ÙNRÆš¨ÁlåŠ"¼d_k\ÐÕþ:ȉwŽ+òØ]Mœ¥–lÕ-æ±û™Bºr » Ó8&4é =AÙÍ5qÈÇ¥òø/dn ÔîïØ-Ç3ý˜64¥² Aàê/ã @®zg¨¨nÊÌÑÆ#÷uTJeÞ›…Þ‡e 昭u{.bpaEÕþ1'–ÆÝôgeõÃúý“OÞ~ñâÑü%@Æ{-_÷òK¿ôK/î¾ùýfEoJ&Óræ•K–;‘˜f]H=pwóï:z§Leø|tp‰ !§ rÀ±ÔÇ•±]ÆrâÖE¯ÝLp¦SÄi^Î ¢@ØÁùáeüÜÿ‰íöùîÂx87t4\–fI5"°ÓS_R’J—oÏêȦœ–*ñщ…Ëc)ùyW\óˆKX6Ð~€‡°{õ…ÈÞ;'¾ Î]&‰jòþ¡›RZ㺃9Ùí¡õEÈ@» ‡ä%a]?ò¼»Ý*ODl/uñüÍqSk¬”`3mÔ…F‚¸­rP¡ñy%f òÀU Ô ¶ùK˜éf#âäé÷©Æ‡½å°ŒÖ0Æ ÀUG>Q_‘Ë䃃šÍËUù8Æ!;ÈpT=Cµ¨3$ír€¯¡™FÈËnã¸iÎ0ãš‚CމVò1µÐ$¦ƒX\>¥7¯N¹¼è|Ô8¾§Ä¹Ô4Îø-9÷©7Ðñ?+ß(œÅ"‡Ú¾â9^Œ~Gõ 9ÇMœ®Œ¡¸ñõ»&CŠ®céëϸ€Õõ4½x›R2@Ï?͉/]¤³šš ˆÃ9 † 4'LÕ[‰¡E1Ææ±]NØeÃ݀Ƚù•6:©QXYܸ"R¦Î´ ¶F¾A첯–¡õ#—ù·£nMÉÑ´˜Îò,äRÄ>åY 5iG.CÓV÷kÛVkè–|4péÔ€œKå8j7SLeÜis¦.Gt6¬yYÊÙÿ꬗Ö×E‹”\Ú3GLå5ì"Ä7êN½þhðæ’±O“ƒ\Æ~-äTß•‰ ò”|—¥’0íäàåxöa„ÀH)9¬¿vSòå‹ ¯ïz|œ8¦æ¢ùRsG—ùgÜÓgþrÞDü׿ʽþõïçêáýw¾ý>o+õíw/r²úItPÜ$Ïg¡bŠä‰’É™ÙÙW­kÒ ò«)jû„Ì7œAÑûU¼g›ìª›èªaðèÙŒ¨ôx}ˆ»_j "úåPå°Ÿ7÷ôM·ºç…°Éà/蘒¶i5¢Ýð „úRâP7êÜz¡?¡ŽBð^93f±Ísáò1L•wK´œ–WºV_ºÃ7â;NŽ9a`Fö‰†ms£Ø§µ_wj †ÆjÚ+&cG¾VÂON[N¬CdFµ#–  ŒÌµÌ øÌ:J UtÎáµv»=ز ߉AÖXöùÊŠÞ¸ƒ¹þÛïšï©¿´OúƒsajWÝfȸ0´Ïä³4Çú`»Å¦²xOpÉnHšKyZ/ŽQøòŠ£ú&òJÜSï)ã|#Ÿ)N¨+憣÷xÕ^K%xírí 2‡joÊÒ%VtM (‡óÈfÝÈ4ÃÁ‹¾nïãco¾Äv‘ÞÍr”‡·Î‰S?ìîGËg:ê›BŽò/óRË<Ã3À¼fêøa,Ö4H6òJŸô¢…#}’¬“/ f#£Nv`Ý(¸¦zK€ 3¨¿ë{âr)ïÄ»=ìÉV\kx§í-¤?¨-r:‘mzj°±©o¥9;ÉòÙ™©¿\¯NÕ˜å«Xí3?´wnBmz7yШ}›HXÒV„þFÑë1Uo݉ƒŽü[¶m"o;rÆiëê{×*¶y=$¶¢óØ@ªLì£:2«ßd;¼Ì;çtã_Ëêߊ#çi§ ™ãKa©v –[i§6CW£QåwL¨rlëîï©»LÂ8_õ¤ªJ+u9Ñ1FgÉ «A|O»>ßQ<>¨«¢Î˜¡“Ëå`°†Ãy<{ëÍãúµ.wwú{úyOÝ~' wŸ:½'-MVÀÑgâIÒ ®Î d kó°ÈÉw",)}¥ß….˜É¸ð7ˆldæP!ÕõÝsó’ËÅWtnnÈó3q+&'¯óÊß*M°¼Âްז@ʾ‘øk‚.SEàÌXþÀ€ì¢¦_± Ù\ø <‹.šx{ã—Þéí¯“”¿äHå¬þX@ýõ5q©1 FòÉYâ代Ç{Êe3Ĩ£½…¢ýcn¤s$Yö.’¶› ôÚ±òPÐŒ”è¡Ó1×<Ýà`a!&×ÿêoÛÁSœ»Ã%f“dÍ3œMÞ˜c7]}fìåY>$uDž’Á§Õ`£Ï †Õƒ@–Æu:Œã±Øe*;‘i3nô!9I°œºÙŒ´ËÏÊñ±]§\‰è8Ç'2ãêyáSt—>ã4‰5_dÔ¾‘­;|ÂÌ9ý[~Lk]9†ó•:qÔ ¡ÀÖkиظ0òÛƒ†™ ~–5ìÒQ ÓŸ´Bò\]˜ØM¾^jt\¯<`›NÊÁi<Õ׌_¼xT¿˜!Økcäk^ßÿÅŸÿ Ñ×B•õ=Ó…v¾àè‰ÅZƦ€Ÿ'&mÌSU‡¯¹Pª/ë${±”à¹( œÖ½OÞĆÃÚ¤ææ©FQ7^? 0?¹ÊÞØ h–œg0m»Cƒqþ ǘvÁ^ìêä0ɹ7è(eì¿Õ§áÙ~­Û}è"×6ÿ¥áó{©/‹¦tØýû2 &Jý—ƒ¯éÖf FãêÎ1´µH\r÷â'jN:öwOF­¥€,?略ÁH Àsgò÷O>(éÍ‚îkW¾™À`ì&½û)ÌÛwôdmcÏÕöS}sJ•œ³3Ÿø{•É”áîA[ÛÇ5‚ÄÐc!@몃-öz\]1kžà³ÃÁµ‹ºm9n1ôv®Âás6ñÐñJÜ`fØO·;Ž]†å†g8Æ{åA¬#Q8(½2\ccªŽúŸ“¤.؃©Æ±z?Ú%w„s44©âëÎ<<1{-‚1‹0î×p@Çùlì¬@IDATµðœµ.$œÝ\®KtA67þãú%@Œ—×¥Ü}ï{Ðk&ú—kÅcÃÈì`@˜j™Òé' ¿u çŸCG)ðºI‘ØMÕ›ü ®ßvبf>Ú:®yz`ÕÅÚ‘I|Ší“[±·ï8×!´k‰_ # Ç ëoà«›7ƒú O\m]âÍn0ðxY©ÜA‹³Î%E1‹E<â^ƒîœÅšlè)ü±ŽhzMËÈ‹a®__³Óû ‹9.‚ýò¥ƒõ¢Þ`·H&‰ÔxÃæ*yæÁä´Ó®Œ4–`wŸš×Öf&âòatK¯ir\¸5ý‡ð•<Èþ›ó 3"2ça(±bEC–õÊ=TiùÈVŸ%D–8å!ŸÚ‚ÞÒmk2[Låj¡˜SG;òÖîVè®rú¼u`ÿ,g¿³¸VãâêûèÆ´Ö¢ òF8|œÙ¼9ƒ(:6f«‰ºGü2I5çåÌöAÜï iž¬Ñ¹ðH+¹-kN Ìÿ«ŸÓXLÎd´ ± U ­¶,›MìO3,Ƕøõ/O¿ûÝž<ÓG|p¯ÂÛ«ýV×xoÜØï!owÈ(› sxi§1£—.v]ç“uœ6µ®YÙcõu‰ÔxÎs]ðø“§õÞ˜…\4xòÒ‡Ÿ·\ÒÎr› I©à^Í-‡?zøÇÍI5=H•,äVŸ¥Mâ{e8:3Nد<ÕP—©däÔ'cÐ2QK3À§íØÂR¯Ó†6¥½…’Ã[;—aÇåÔÛ áÕÇÜ•.úí<Šnä«\¯¡<˜OË’ê&ƒãì°–™žÌ``¾ÎåîÛß~ÿå[ÏôyO¦]oÑÔÞ8‘«-&×!˜Ú¸2E'—34E¢çøíÓŒ¨AöØúú7nä=#jß‹å KSù?‘RÌ×q•—û27Æ3|œGájzÛ›M½ñ|„ÀPøŠ±'ˆm#Ãá›<ÂW_°°”Ì«Œq9º±gÜmwŒqŽåãëSÎŒŽ“¨*n> uÖ}µx7âÙãúC@ „_äyDÉéþ‡?Ì—Ÿ¿ð"¸º½3™Ä)þ­qGR1_Ù Fù¥Q|:N¦Yƽ1z3ª~øqñ¡“oVVe€Ãåɘ*›kdÖxÃ9•_ò°Ü/Ű©Ýø­yŽS‡ÚÇg ²§J5xwÀ0dŽrµíÈ7FD|šÿ2«áÕ¹]kaAÈ?8ÄÄ%{8Ç%o}Ã#_éø‚gƒZ–ýiázäË”Â1È6*Ƹá~Žßúâ¥V™\Z¯~—ܹWŒ³>&ÖÒ³ãÊßyQϱ(WÔØHÎ>ÊÛ´ðèò`BÞék£ìœ7ßÙÂ9‰¤Ï•_Í"(|³±Ä1y?ü8W\£ ½žÈSØpÐJ ~oña4½Œ6šÊ׸å‹úï8Í©us‰ŒÏ5<“{Îí’ØåžÍO¢ÔpªT†SÞpË42«ywhò˜Irö/ÓÙ“IA.‹— ²X–^qÝNjÉÃ.ä‰R®úÇÿÜœÑX¦©Ô® —rI܃(z(…꿬EÉ›p9Ü clE+"ÚJ¤ì¸4è›þ•$à –âåÓ§oÞ`,¾ÎåÅǨ? üE®z'“.~ßßžÕÒ÷‰WÉù|Y³Ä¯œf¾2iÜÌJê·îëÃó¤Z ÙX­Œ _|Ø@}¿Ã•Ë÷§ï·ƒÌ݈É'$â =¥÷8¢Ý3ãÆ“ž¸‡:o¶ò! öà¥mån#—“º‰6à>|tÄñG%Gÿg œ|Ñ5&qøèÀ& QªL]U(r5zMÐûíÑaòí¢‡Ý1¥ñw+DbNŠ¡_çÇ>tá^¬þ¢`WÅ€ÖG$p´ÍUª›rfŸ¸öSdjS‹ä‚’`y”TCÿ)îϲ_ý[J×¾H:Ϥ-ú~dãë*Ù±`.8°D‰]µŒOîrÒhJÙøõ0ÿúÄsÎx…—õI{Ÿƒp Q–ÊyK´WŸíkePÄ@n6Õ#Q Þ™vÏã ®‚Ô,ŠV˜Ì€ è\ðËX^hÄc’Í„Â_xm(zr˜õéKѰFkJNÅ T„p‚L—Hx!ÕFîC4¦Œ³ŽÓÇrâ’›ó ÜÎ IŒ}Á‰Å–±#‡Í‘HaäÜ/‡ËºéwRžÞýôåOúèÞx–Áx<çwÿâ·>ýÉÛo}¬?(ÿ¦œ@Í& ËÜ9™–ÒÈÆäÂ^ ëiß0À‡ÉuOF)ºÛ~ÒwÃÆ‡ŸIï¦ÌFêW—ªoìåZÁš >:(ãaÎå^íÃÝ~K'Pó‡‚ÏÇûppÿ¥w<ôò¡Mñ¸ ë }¯ãïa=8ø› +Žô¶OÖ«üB+ì<»£Èî9–„ßà˜%ÒIò ÜbfÈc.2ðð®é;gÀ}-=SOÿtƒúçÜ‹…·Oˆ’2yOVø]:.ÐÆâ1ƒt(ÑX¬n VN7Ógü5öƒ´¹2~wK¾R#­«Šh|ŒÑ%]¶—"IäÚíDN¹iÖ¥¹UL»#S\êr"Õãl—‘ª½>•;ŠW9Ruñ9¯Ôö:‘W|rì¹q#ƒDÓwq^ñ´b|Ô®ÝÞD¬yQ”†rBÛ62táëâmܵ”[ƒsG$£‹×~Pé6Žx'Ãø-ÕäaNÍO^ sèFar°ˆÖ!ss"û¤¸2=ÚŒíÈ­÷ulñ¸{úôãO>þøQý†ýèQ•ßÿýß×_|çã?åU ¢ŠVFo”L~tlÒž Ô7#tÊgûq'ï‰á•(²^nÐÆ pªWâ’ëÜùÉ]²ÔiSc/š¯Ù q3}îæŒ&Juäìlêg7{°Ž®váÕ¦s@騀Ñ1÷±Éí&<:ÚªÖy÷+7ylÛŽŒ%5úsªYüißË(XfþÙüù /WrØ•"“f¾àqÁ…C™ÇÑé7Q‰½QqÄãG»üã:Z^{å²·.ÞƒR¹ž©îAû©¤Ä®C„Ž‚}0“¯Õò±}Â[ù«;8˜sìEQï¼úp-s5M}hƒ«üÏëtWb¶ÿôøêu•ˆ‰¦Çî‹”.¯2D-OBæT"î¸ vœ´*]ÌÎÕ¼sÊ<ªO-Êevî+'v<íÜ­àëÓv­1iµ0a¸·ªÛȽ̋X®½Îþ¥?±gœBΚ¥‡äß¹¿óÐñþºÖ¿øË¿ü\Ÿð…7noÄî,“‹)’ÆüòÀlh¼Î£S›Iè‡ä›ÃÊ!æ^ cü—¯¯–+{S-õ„Ÿ Æ÷€~™?œÄt#>€E7MƯöâºòïƒ@ˆcÄ¿Ü(¥1='»Ù¯±¬Ãày›íÒyó)¦„²Ã%‡ËÁm8Ž4€õǘKa8Roþ` ‰ÇW$þqÀ CJÓÌ™·óä<$àrÇXˆª«ŽgçÒÄf)T IeqTK’ë¦ MÝÆæö -bìýÀzPk,j0KÈÉ=Ü(áoŒ€úYt_ùFÛ³üuÝò²ú…c_“`cm¤b7OãÆ‰Ô½k‹m]{=áŽ.ˆÆ*>öJ©íÔ6·ø/«“Íö*Vµ›ƒÞ·Qî1·ƒïV³bŸÚ7ˆf%Œÿïͱ–\í+G’Dç≘;V®xqFà;Ê [‚­í·Ò±¯{Îø»NBMÌ%‹Ô¹“5‘ÂD¦É#="‡mOvA$;ý" žüÚ¯}éñœ×šýxº¬ ñwý'ÙHÙø¼÷¹&Rö¢(™WL˜ÖŸÑ1ŰõU­ýfW¶Þ`ú¯6N<4Ц8¶„ÄÏæÈO€ápÉ\NÚ:úmó5ï‡p k£%7Låêà ¼`û΃ýÒqL.‹[Fx˜$pUÜ7*v{@»›gxó@FóCǹ` ¥kô¬¹G rSú“Bð_Ý’póWjž}¶u{Óºê¯YúaKÙl­Z;©Á!þÛP‡—­‹8'OœéyJæ‡G¢ÕÉ®¯Ðy½¯æÊ\ûѸÕÞÖ;n87Úf‰O[<^ñ‰ù‘NŸêSgŒGápß5®‰¬³Ã‘ðËÁ9wh½6Þšy2ð;l2%¢˜¹35‰@ï€ä›ž‚â>¡üä±ý%@úÿè¾@§ï¾ñ­÷¨;f6ùÏñú•‘f‹»'Ff¦7ø»À«>ÆÙ9ák¢A|ŸI׸aÒYŸËÏZ840ØÛ7 ½Æ`â›óò±ÉÞr&-ÞZ‹K1ê›Jþ¹‚ç/%'¹~wƒ¾’×£¥®és÷Qa  ÉeeeLl §O&•ŒJÆÎ'‹á:Ž:+o›å³ócŽfžž×Œ˜åÅÉ}I¸p,R7ÄÐÅü”OãØñ» F`:§wõr,ìV­{€ÆíU4”`ŠôUŽá’Cpõ‰_ûvõ©W&žtCkç«OCí\ä9>‰¹-ei¹fiWSÄ®M%¢Ñ1:PfÊ Òþ&îÆ ?u4Éc#‘Ñ7ÿx1×® aŒÊ-âV—FC/'b$ÎŽ@¢&—bv”æßê›9 zà–Gùpÿío½ço…ÏôõÛ¢ºø|û¿›x'*òº¹4{X,­›»!S) ,Ÿuw2—˜l]LY ±!÷Abaªðê7m*äYٯФ³Ÿ|pãp*j ¯Ž…{-ìR"ß®QR-Œ9‘?ˆÜ›=AD¿­þoŸ\6wã9É—¾SÈ…R<ísó7lø±%èª,v\mÀŠ54áñy®'s.UçÒ9ƒpÖåNoÁ°ù“°¿¯šwzÖ<:ü˜+”s쯋[‰è(qH/§mJ–fç¥ÃB=°Œ˜ú%€óXz@*Ë1¢‡¤ºÁ²‘3'êÚ:°«„.w‚ƹ¦P¿ö\ŸÞGx&Ò8ÖÆŽO=64W[»z½ÞñlœöñšÉ¶Ý(Õ§® gpL᳀ʰì<Ê÷άã”Êšš\;0¼Š8ànnDryÕ§<µ·ÍugŸþlÆxžrÚñ<õgV_5Wðã裿¼¸x•ïÌŒ‘‹k[¬œÅuÿÒ/ mzD§®Å¨Ë\ìû^~s½~óbÅ­Ä‚~þ¨Èš0s'øFÓˆeÂhȬ×DòdœÏ„IÇe’ãçÅT 6Õò·†Ï8TÀr“nëä/ÊÈ+d|z842 À*pqœ: ÈN•@-ÅéÎ'Oo ªy¡={çZäá¡ðóD:S"—cø½  *ÎmìîŒì«G…ÑS¡+ÌãK¬¥ØÁ†Á”;œ™å½¾A¸ðz™­ÈÿÌ! í®lþô«?6‰ìMWvÆá÷_v²'rò“è5³m5;+9¡jQÛ×%”‡i8TÁw™rè5Z)ÂÙcjÚù© !eœ’[sŸÜ± Ïa=j+}µ}Îöö[ZÍ¢rü³‚: Ù‘/žWD,›xÁæªÄ Än¥·;£[°;&~ÁƯh¤”ŽeëÄ*‡0ro´x•± ²k.^µxÔ ÜÙ®_úرsrà‘~\kpÉ5㺹oc¤‰–‘?ûXûë¦]ëʤÇ\m|TäVŸk§v>ø÷Š'·Œ_óN]Œ~ ð›€û¯}õü³O>¸ûÖ»žPÞˆgGcó`qæèdáUù’½£É6sIÊÂìLoÉøð³åËO:\:Õôb¼}Ãá4ŒKÌ&Ñ\isxÿò±^ù±!Ñ>‹m£lÿZƒ«š<_)ðËXnoÖEBåñÇŒgò÷;£/gÇyå Œ7É‚§=ãŽÙ …jëÁépÞ:h…íGo²¼•¸·ýð@|Œ}MÑâ2.¹60ó¥A_O©V?¤çÝ•®€~@Pލþü}øaÚöÌ‘ jû^Lã1~æìÑV•þâKÁ²=½˜J$ïÛT´´“S–ßr4Ɖ½òœˆ¶_W׳v䶉,¸»ok72^§_ðdžÒVëQÛ&׳­]׿ø o#Ǻ3K®3Gd\s‘6Wú×­-þ™›q£seëå±&m2/ˆÛü+‡%RÎ{¶7(¬DN;R3‰¿ K âÔ·½Ç¼ÙtsæXØË„Oü@¤ Krc‹f¸Õ̶?øƒ¦•’ùSÀ_¾x\UuÎËÇÓñï|ç^õðzîKÍ”Þ;ž4¨ÏE½ÓI_d ¿T|í‹I]½0ÜlŠkS™6²_!J> |}9õ]¸ùB`sðgåc@ׄ(A“TL_üÊc·¨5(9ØÑyóWíϼG•A`úqEûˆ:dÆB5©®ôàxÝdƒ¸Cã_D¶Î NXµ´¹Ñ¥ ~90ž£ÃE¥4mƒ-"¶|™ïºÀeF€#|8zm»ù§Ÿ™?ŒIÆÏ,Oø´4neêôj4X œþ‡B­ãxŒö‘<Éõ²óÆ>öã4¹‚µ'çr”ÉF¨¦´uÖẎ°Ã_"ìÜËYŽrSw ÿ¶KÝÜʹY´nÿ6­ðä\ =”Z"-yÔy@¬mYãuºª˜üiǶd¡SÕKg÷j‡kØ‘Â{Q[*÷Î$¶ôížÓX¶g"ÝÊ Âå9f¼ä ´gaác1®(Åy.œ|¤n͈ä:Çž9A<ìõ)š:~™ïn t§Szùò¹¿nÂGtz”߸ûÎ÷?øROwìþª=A5á2}2{΅ГIê§Ât2ó/øòe'y°m&œl>,úðta`ó@¦t®ŸrÛA4nxÌ%ÀåfÙ\jóà@A.ÿ ˆA˜ô%œ¨.vDa,u”ÑÜ’ú^î.~`°\øœ2c–U{¬L*ÅÄ©œŽøk¶ÏÈ\¯ÅYŒìS¢‘ñGß+ÐØh£·ƒÚºJCP°ûÚ©5o‡²Ñ—KT%æŸî°#øécBøÌß%ðRŒ™rßYLpG¼ÐÚ/¹¸™“àõ ±¿k  š,ž¯ N/RŽKu, ð¿—QL‰¸â.t-{œm:ì4ëWîb¸6µEç^º¿Û·>›¿åo}ÆÙ<ò#¸“E“é„€@:ä³y0p2¦½>kÜç”å§XŽY5ÆKRsÏJ®O@+×DZo9O^óg}‚ƒâp—®2‡9nË֥Ź´`+£¼ô «þÖ*ÛšG¶ÄK‚eDЬuºmb/©ké†3câÈæðŒr'¥{çÙ›w<†àtÿsßý@øaÿÊ_MÃü˜—:Ÿ™”IãɶŸ|¿dŠÍlä÷MŽÎ3Ü3TRõ[ÎçÃó aDl™ŠVä$5¯/\–ÊÔ]¬©»Éã\ÌnD‰~Ù¦}ÊR™³¼µq_¬¨ÍMänùR‡eÌÚæò»c4%’ñã ¬68@@‡mþº³‘¸å:ű ð„µ®ÆHé¾!¾ÏImÔø2Mº”Ô–t"e9Š?bæ’ 3ÅÒ_é•<ÊÕlö6-_(rdC´R§í·çð¨BÒÁ÷\Ö[Æ3ŽÍ >s5 Ä[+Œ~[wkAþL³7ís¹*¹:²<}®Yroí§­mxà=å´«ckåD½!YòºGÀ„¹Øú­zlÈK7|8ÖO0ÏOøÐ’r‚ƒ Üš¾åÅ@A¦ Æ4j7äêh¸ø¥O¥ª˜UÑ÷ž”«;°û88Î æ?ÜlCÆOë¥ûŠ,…ñÅ©^òèXk:.!Ì£»»wÞ<0F¡Ü}ï{ï?ÑŸfz0Aræ÷Å3%4“X Y©¥“ÆÅ‡‰6ŠL®xRv³‹J¬ð±QGÊâ „ vr80Ä4¥vDÚñ˽€y|Çß錡~ˆèOÎ\xÊQ5>æÔ¸¬)ý%¿î JƯ‚Ù¾’›xjß#§SoоuNà³¶Ÿ9eìâ…ÌQö>Ôˆ}p+©ÊVD‘kY÷úxlŸù-m7Ù>ðÅRNN€" /úEáÀ¿×bÊè+„93Haµ7°õ:‘— íi†Ô³:c$ ïB‘’™ó–ÅBÓÀU9ö`«lýW ü'*÷9oi²±~Ç!ZÐxÔ'v2M„ø&n®N|‚ÛyHF;¯D8cìL³ýQôF6#SqÀÕCMë ‘=Šóz ªÌc0Ý'ÙH A¶y|€Ó̉ÆÄ;•c©áM1É×|ÎK5ð« Áê\IapÕµ7py, C¬Ú¨q½í[7LûP±OÉ'aÄþ<þ¾V†¯Ÿ–p¿£Zã¾tæËµ2ÄÉÐÊÇ:ãæ$' wÐíIˆ±âá®©ÑØ4jaÈ1%òÐП#Ü/NùM€ƒµÁj®þ#‹Z%ÁÁ‡3Z¸È.‘ÂùV°•Ó~Uš^ØL„–m[Nôß:‰ö;äÅ!÷)Œ-f¦ÑÀµ—?;ÆŸ9ÈQ„S^øQz9¡}”b ±iì½¶pûa´yŒ}­9pIþ,ÌM ¨©ÇM­]¬+Hê[Œ×®¯}òššYZæû–3ùŽ`Z,=V¨f6¥ðÀdâ¦í»~²2°zòJ ¬'Ÿ”f†Í-èæŸfzbÊ–ƒå´³l”±÷[æå¿lŽƒ8.éûðLe=±šg¹ðë³sA1_û‰„ɳj/:Ò»> õo©±LF粑ûÛpN¡cvV‰€‡)ctê† õø`£žBQ¬Í¼)—t´}ÕÔÁ´¦ÕqâAâöAÏ “+™¾–re^‘Kû ,yÐÊ|¢µ àñ©n½ NlÌ`(<€¨í9UL•Õnÿѧ7´v—÷UÌ~Æ êu-8Ø‚JÍè—Úg×HÍ–Óï$½å/~BQgÚr°tÌ[LÈ´×<R*ϩʮ̯-ZùØŸ&í‘Oì?³ €ª‡×78Šó }ÇÔý‘j(¬_máÚ††öyÔXsgñâ RÆÇí*°M›Šèî5áü…A霹ÓXçp ŠSÈ=Ú(ÒΣÀö™y7>v?8 ÀÏ}90@6ìÕ‡  ·˜D óû”‰Ñ‡š“7èœ;†§î«ÚÎÐ$ƒìÒ K1zÉÕ!ŸzƃRš Ùʜ싱¼j{® Œý}ŠÒã~#ciü nÎÂãb7‘®¶·sâôô=+ÅÊc89(­Ëé1MÀ`º­{IŽÎyàé:âq(¹ì‹Â½R ë8.¿Õ;ÜÒ¡¾ptá¹úÑŸüñ?º¿ÈÐt ¢ý˜ÊË'ïê}É4Ì«-~‹Ÿ–­Ù“‡IÃæþ¥&L&uþÖÍÄ›7ùˆ!zêl¬öð˜W'AÀÆwç±[¾}wž|5»{sû#‹ãªïƒg×öÐP*(8|ÿ¨A» r‚Ç6Úc£>B¡u±oÁäÖvGÝ€zÁ”_Û\ǸO¹Ãч4`èËaÝM¢< ÔÞ9Tq{‚D¯3cv‚,vN`Ê?³§º1ìì‹„FXU}Ç9ð弿®fŠjÞ &v̰u3µ^Xÿú^é7®Ûk|Š[OMËÓŽvRt 4v wqCõ€Ë¶dÔ¶|‚Ңç£L#žÞ»M_Š ~…7¤‡Cš'nµK$…ÇHP¿’ÀQûˆª–Î>>ØG×f÷#äוº4‡‡­ú³]¡÷¡7{å¼øh?ÐæÉÂ@ªrò¶]LíVѸëù_AØÆjß:wò-õŠ£Fq¦Ô µlB×f]—g÷ü/ø‡ZÈcªo–ÅÇÓu}ð×ZYÏWþLº¬ó,æ3©ÔÊdêÌÑÄÑͲ'h°Œ\}ú=&ºpmç¾¹EàMk>D>'+~Þp˜+ä(ò¹óÆDßlä´åâ<á$¦c¡Ã&»sæTNÕ+îøy3ĉ‚“ÚùÄȨ¤;hŒÁÏÁ¨àBˆ ·G‡Â Àè©(q˜ÐÖÓvîØT\qÙÊ99µÖ×@–Ûé~¶™~· ¿-Úã¼¹ÒâÜ éšH˜üVÿääþ+ê¹ ?wbY§“škl4ˆ«?2aö%Goî¼ëÔiÀeÍ÷KòîÂL­éoò*ŸÝov÷lÞèI®§¯©¯=Õ¥2×Òä1çÒ¥aNbݘݪ }ÞÚÝÂ~JæTîèzœoÞ§@ÆÉÇ›#‚ÊÑýK…ìîáÀïÔê¹f±›ûô™öeŒÑgÛŒ9êKß:ÔíÌ´OŸRUGÝ£6êÚÛ®l¬N®ë0Æ^3Â3÷Š!Otô/s9mÜëã¾>¶ ^Õ*å@ÇQ¤èÖn<ú…½{”ˆñy”¿Èãßx Ç7<3q “‚™é/FÉÈ[µ1³ˆñN€ìÒñjÍ ¯åî©4ËáðÚ*‘Wcg &§_<›¯Ú^¡óËbÖMJ[zôÞ(ˆ¹ŠøÇÎÔ bÙ¢ÚE‚ejÃä‰/Rx)Üpòc0ÎQÁì7<à›;*ã…éßp_„ñÏà©οþšM«Ï-}ž@pÓg•â”â~ƒ©Bµã©–zµ1óû¼Ù!¨tÜÐqàpz%ƒ€‚<¤5Ù¡}އŸ5`jzLTS0­_çœÞôqªQ-u¼iôgû{÷C“ùµÆfÀ+OyŸÑˆI+qÊ`µÓ¦?~¢“`ê/­B¬«¿•hRN\ç+EAÅ ¼òG'¹>èÄ€{'2+oüÐ5¯±ÛdWÅv3J¶J Ï?+Ã﹊Ѫέx¸u ó€Ç|è`ñAùü-µ9Pb“€|;ÆÆñjÌÓäV®ŽglÇ]1õ½µÝÚ+Ÿ5mJ9«r¬¯Úë°p«QÔ¨×z¯vÇÈ/ïïÀ,u×Áz ÒÝw¾õãçÏîµp±€jºuFД̦|/—Wf£ o×{Àg õÍq§Ò¿’wv;ßôšyP{ŠƒÍŸ‰ØiVqÇsâL£)Y!þ✋8ºì³óNÇQí :U曚6ÍÆ]Y Ã÷àq߆Ï>8w³@/¥‚ÈK2˜•3ªÑ©¹$HÆ\`§?CsW'_oLÔî@¸§¹ÆîqÉÞ-¼ËÄæ³ô>|4ns%bà¯ãHn xùðNµ6¶äÆCX³­ƒªƒHº Z%¹ óŒ ¾8“ÇÐxlÉÑj@Ç :‘eTËc!¹3' +Qm""3‰†£.®9¡ã¨Ï´ñ£9,;: ågŽTæ Cqõ©¼€ãgôøÐ^vëÂ×üŒGÅk‰4ˆÙ9ä¸`[šº9æÝäD©š¨9Nó‘å«K9êW^êõà"Áö‚ U»qÏ6r .7n6¡Ã§ö³p+££Ô‡6˜uï¡x €¡œuÛ±äÜü±qÀû³¸‹¡ö’¼VŽ?ÿåÓ·~,ñQ–ÎûG×ùÏ_þøÉ;OgéÕ–f“¤36LØ(×g¶ÈZeø!…AÏf’É(‰ÿ2û;6¿ƒ Ú>ÅŒuŸ… ²u}ö¦TyfÿzžIîÅ_m5u@"ÝpâÊS¯pT An¾Ky3;¦»6›ö°÷¸ÊIS<6ä!ÙXò©ýè/ú¼ S|«Ù/`§iê{Ô瘙N6§>qñw‘¼Ühr ¨=N4&7Ƙ¥‹+gUäm›U{³Ã™ÕGµuc¤‚#Õ_¤xÓUÍd`ÒðVj?ÃEǦÆBï|¿-,t1¼ ƾªÍ3#ëÉ7:ô=ºI¯»XÛtW»ÙªtÎqt¼àXÒ³q¯"PÞÖ‚ŠÞý8xgƒ-þ`îâæO0ü×BŠƒ»Ûï°8Œtø¶/n#…üÏby€îÂ÷xuVJw.`¶‰§y46ß±(ýÐ8—Ò\jF ™£Îg‚%¯'•Œ«È;yÕðê 7¶tÑ%ÅU‚Kë©ÇãxBþð™dî *(8H‰9cj0>l°~—B:(yÁ}£?ÙõߥuàV9ŒGóU³4Ø},àÄXríîÊÇN‹2 éí†} Y¶QÔ_„ñIÍ5q_&ríIô*Ÿ1L©ÓÂ7öpØ®v®û6V¿5·nqç=€Gãú~8ûE»²@õ+ßÙHªoØ—n O ªœ¦[eéP{<ÇÞuzß'ª)ÆŽj£3FmÄŽgkl-õc“o»ã]KÛÎW7\í;ö;÷?øþûL6Ì{VB ™,¬’õŸÞÉ‚ÈoùcÒæ ØÎIŠb-êÄÛÏÖqÒÊÌçãø1©Y¬g=w{ݰÂc·/õÈõ[7”là(üùaóIáWØ“;}¡øPò#Xáf)g) 0æà€2o!˜†„Zœ—GÍ aæûs~ñ.3}OSrRÂÐ>UÛ”Œ‘fGG ó«F°eJÓxÒÔ'ÌëRøû}*süQA„b«\Šâú£žh2¶ä;ãÁɾ6éiËaS:L@NÌDrZ[} w(Éíûxó¯–ÕÕÊ¿ ømµâã;Ü`ÊÓvù| èO¿øòË7ïÜæ×]¾ûÁþä¹VW6ÁN &}6G–o¦Ëèà‹Z¨ÀvóF^“L Ú}W€‰YÝš¤ø›ù¦VÕý–æj‹ÆÙÔÙ¾4Tfvý.ô#1¨ÙZö9(÷9MŸ‘é_¾#Hþ›t|ip ²²Z‹8Ô*yç"q­šm¤ÚÁ¨H…W¨Þ¡U­w4ÀwÓ Lg•?Ã6rŽqõŽ³Ï•©;nÕ°……‡Ã¯¦i¨vB›ÿè1¸9rªO©ºlöHt/×)ãçH3||Uœó¡šÇ°åùT&ýRÍÀðß¾:uåŸ1­x{-—:&lrA÷UåÄ Çr9äÝkãÔ‡ôED®Î¯¤‹HŠE"Èàgì‚yAÆïÜ8Juâ6ÔâCeüÚ®Ïëê[\cw./"€c$W÷H›;ü*ûº>öG6pœo8ìD˜òÙ¯>ð®´WÁ¹ Çü³jr@X¼²Ynp«ÏÈR]J}P.N¸ë@ƒ­švŠî±·ß~´ïËiäqÔϾ÷½÷^¾õ–Ñ›N7ž¼ÚšÉ$ýš¼ ‹äN86 ~w@eÌž€Ò» VFŽÎºó¦¬_ù³HÇ÷Ò¨r‹¯®õÀ½¡uSËw°’Gå놑 ]7ƒa²:ÙùR™¼(_Jg&Sô1¢¹Ivgƒ5Dèþ®DùœutöÛt2Õ :Ë"ÇÅÏ »„#ôZìÉ„¸”ŽiòHΠݘ~×@tb6åøø]3·°Àp¡AÛ‡j#È:¢mhZfD¯vu |l!åÇ?sæ,@ÇÒÆ7±Ä¡Fç5€öÓøÎÝc'äV8Ò—š¨«?u¶þÀ…x˜J$¡z«£õ#_0§¢>£·¨¶!Åíô«©©P—ªí[ýé‡ýÄ`ÿó¸zÿâwË…Ý÷‡µùú#c¤ÈPL:ø<nÿbÌW‚Ú¾ÏÔ\±Î6qpž¸äAÜæ­²mÇ}§ ó´>ÐQºêhs6ï(ðã^¨®<•O?p«5K¾÷wo¾xŽÑ£hßë[ïݽóì‹çú}Àþ Y³…IÈýùœ ÄyMÙ‘ù"__ýããWúƒ÷䢡£ >ÿ9aá=A©¥£­jù‹Œ/>nV?p`ã®G^¥æ“õr¦¾."hRVŽºkÙÆ‘ÓÂoú;+6´›K<$amðþÅ3¨ÅR®{a Ó® Ú€éÊ#­5øåË–‰?&^Y{Œ Qqÿ»“a—cÇ0@Á1º¶UÓ(ü´UE@!Ì*È7åTõ\¼¨aœ÷+i2 ÆSäÑᣃ2æ©eWç¶­9ä€Ï\ µûfúUG<,£SÁçE'ò+oƒ8)FJA•GwŠ çÆœ¸`.‚0¯“«W}^ð6Í€¹íÓt0ž³ØF^±FîØÙ³˜ƒ÷2fý@L7ô—6P_›Ãçg5Op½vô{å>ÆrjQ;þÓ@ïfdÛæäþ®þeîÙ$u¿äL»Ç4Ѽ™ùºò²·}í"ѳÏ5ÉæBcs Ñ×ÑÄáb¿}ÂÞwVíKîR¢gÐ]ëä¼ÑsÈäurÚÈ—K“þîþÅ£ýàÑ~àé÷¿ÿÞÝÛoðåË?|kMœÌB&—îžÙÂ&$…Ô9¤£ÍÌÂLééŸç—ŒÌY#ÇšŒ¼²5mtãèŮóñªyåÚE’Zk¥È‡¦*7Ø”ëä˜Gfd!¶`æÔ‰\ìoŠDä¡;dØ£EV‘3rt²ª‘‡‹ÙÈãÊÞ²¯$p„œ˜ùn†¿£!däÇ».ý8ܸVŽ%}¯Qe?@H@¾äYI¨ rPX(D•>Ó–cu%*Ù›¦ðýübÐ ¢èÈ]ìÈgU¢‹Óz[ÕʦÎ(ƒðæÂJ¨ÂìÔ'Û3ár ¥Ñÿ§Â’Úz“±áíåXʸ­¾6Yø—¥ |Ôf|¬û&^ cùðYvéV^ãsÊàf®œƒ¥ò%lymyžœÎÛ€œl%\§ýÂÏáwÛ|Ð&²ÛAÁÿ }§¹92ƒ;%scäñM æ»–ô¡¿9Ò1CÎl .öóþ…«¼Ãeô‘éL8ЩH&#júd5¦ÞD(lŽ‘ªmæ`¼ÑchqÿÃr¤â´¹ÍŒ ÍÝÝg_<{öæ ã÷Xêý­¿õñó·Þú@3à‡ž.l2žY·™(öë tøá“SxÎñL‚TÆÏ>vŠú´¹=±™²‘jí%«A?ëBí,+÷Sy´/ø!`Þ”ó€~eóä¢]o¥𡘶õVPR/ÖÑ‹ð̘ Ú8ámZD‹¥>±ìd˜Šªcí™qÚáÂZÏzÃë7Ní–FÙð&zùaH7{.¸–ªiZöI g:ßûÆÜ=yïÉçŸ?Ú€µ&í‘z­_üå_~þäoü˜?¶ÃãñgP ¦ÞO–3‹¼áÃ’âÕIÆýéT³HœÒîâ›IçüµAs9îØPP˜¨SN5%¹:¨^†ÑáCNØ8¨àT™j¹rÕŒÜcèJk—žj[²œÊuk+æuõò;8‚­E’šðšÛƦëçˆ]ç3X+ÃÃ\:´XT˜¹·„vë¢Gû¶rÎȩԻÐN¤î¿„js- ]rI_Ñ¢ÏÑ‘§'ü+öšÕž+ÜãöPåq>p¢xöìÇÿÃoüÆ£üC@ŒÔ£ý€Î?ýÎ7ÄwxEŸWr|é-³†EŸ½‚9ÂFͽÈÛû-4™WÝè±ur±1°9â×W£ÅOˆ¼"T ÞÖ^ï2@¢ÎFšìypPüëwE”É/»³Å:Àqw¥¹u7ï¢Øä×þ®c}LÐ1ûà›ŒßÖ“Žñʾ\r2g膜w*cŸÀäm÷_‚ ú=Ð ÐÍÛúVL1;O'Å»8 ŠfNºÉÍvjžìx¡á¡Ët£Ã‚èX–¦]Ór‘ÞïähvA³_bz‚^MV•%äçâk,ñ²äúªöF:9– û††hºSNjlô#…¼Œ”¼˜(s}ÙxÏÕÍ_ÉóÊw]”ÆTíçŽ#8×Õ×vUÓ\5›?z÷q|û ’ë-Ÿ:Ñ ûq ~.Ø=`áí,ðçèçZØO>¾‚‹›~1wtU‡˜¸4éu£ú†žb»NäEŸ—nØ3Î6Åoh‰LgÜ çìi;ä),:Ã+×~àÛ¤^05Ú^öí7º….çw(ñáð<À¨bž4ÿŸ=çíÍÆ˜¤Gº¬1Eìh»¥–0IɯI*€Â®6æ–Û>3Öö±y{…gæ¢æC S7v4i¡‚ÍFÉËŠ]¶1gÃG™Ø¨Ó×kbgœL |„B\/Møe°›Ôý‚£mGœ»gOß<0(±<û¹ïÿ_Þ4AúÙs§ï xÁ¦6k¤mL6µ™ˆ–Õ¦´ÝÚ¼*ïáß&(2ꬻ’¢Ã'ù#DÜq~;¸F&‚ùÕÌ^§ SmnU?°LL>/ß®ñË¢®‡MêÜtŽíŒiåÌyË8qS'<æÖrFœ°Qü®GBí1“Üï€ÉbGkJ±• ÊsÜYÒÐíE.ˆäŽkRâ¦8]ô\×LÖ8¡T1ß8…¡œcTeöb ÀjCÚrú ÷J‚cØ$ÞEãdobî`y°y›ßɹÚz~•r{ï (LÌv˜¼7¶½@q‚ •-|wŽV§Xñ·µ#I¹î5—òŒƒ¡6µ#®ko¹mœSç”ë[|Æeþº­Sf°ïæÄ¼p¿½}T‚T[Ü)¸/!Ú¾u\6.µájÜ=}ë°=ÖÂZõhË‹'÷ðD¿ø¥Vca–>£ÁFÊ"ÍDb ³È3¡–N66ucÑgŠùlœ5LµLrx(ÜlÜÆäÑÕ>¶KfâcëH߀—ú’0…õ?>`ƒP)CÍìsdF;.Hø§?Áà¾K(ÐäAÆayxLêþŽÁìx|ŸÂ‰oÜ–*+yH0dò%‡ÊlB¨É•Ây·Ðd”ñëBCäÙ„…V>VyÐñÛ‰ (y†,ÔΣ§=6?7jÜÏR™kïWÿ Kzî/:Âa//MÏ)òÆx[äà @z½F%ÆA…Ï„=–b3vÛhœÁ´ÆC±¡!GÓ\´)1„JCLR–í—$=­Síy(¡²98µàwGFuª— ;— ¶‡Qµçb1SwœjÜOŠÓFû6µênq¯—3?ã—HÎÝ͹×g#Ò⠾מêÒ îÌ´cÓ9‰Ïm çÖúIé1*¥ÌÆÝÊ£ßÞgkîGù$œ´yÌhúDŽx4×Ô‘Ï‘Ãys¦]6Þùê5ïu¶¼òÿ¤RŸpj§/ùq©§Oýc-ú#€ûï~û·¿|÷'O>úôÉ[ï>Õ[ú™ˆì'ž;š(}EÈa±Aß·×™ÐÌ%Þ=ðæ#Á?ÿŽ~fŸ?6×â¾;W7.<ÙÀh‹Ø †?%ÎÊI0‰m’ -moÊ€Urƒ§?xòçW‚KB –Æ\cõ»Òä;a­}œ§â&ÌÆ»r ßSèf³îx¯Ø5‰Xh¨ÓŽ‘‚Q†#öñ™A¢P2<…Ú¯zæ=zÆÅ×TF»"8ð¡ŽN6t-¶p꽈IázìÕ0ÔÎù@IDATY,'´O®qqåŸYøDi,×:UŽ_BÆ?£$-˜¨¸â}LJùI— ã0’çÌa¢ÉxœñŠ¥nqûÑ.ÚË\ú¥DHé¢}Æe,×u6~wyPP*Ó6ˆÆ¥iX]Pôú.ÆýyN ͈‡%r£ §œó9º æ~bk·O:Æ•NimIÂ9f€°[W ‚´Y;¾Õ­ëê¦M~}ÑÐQ#³úʬÉZ“UÆc·w íæ8ctü`íuYü"€OFÒ£ó;–¾ée?&M¸aS.Â~ùüù“§ßüÆó—ï¾ý?Gû8Ϭõ¶üÍ_ýÕÿ÷ßþWá>ü½ôWžégìôy7a&ÆEsâ{"ÏdÃîÏäGƃÂ"»n(Û3]m„\ºÜ:“:™{O|âì{1v•0ë½éÙtásÚɧz= ðóP0¾þlÙ·×ØVïpI>ÃÑãq¯'™ôIŒâêZÄñÑMnÔãêl8ÑWcÕŸ¹ãëœNKö±Qs¨=¦j°0ðåxȦšN(ëU?²AV_†É¸ȸ[‡¾bÏG2hF' ê¢òÜ*z"ä'5ÚÛ`HXJü*È:œ%a6ÿSŽ#¿M0É˦?…ý©¾ûñ_>ù‰è>ÔJðzñpè¸^΄©mB.Ù@ÂP º…çy3\í(N¿Þ ”y¼û{‚‡{ñlß95ÎéV;¶Ú«ûÙõŠtäÌ]­ñÕù6FåÔI®ºxLßQNçl_r²éx®Éf ¦I¾vä}„‚³x|­;ˆ1 I9·/ÐSbI{Ÿ ¼}’ÈȪ¼Ž‘Ë œEv#%Sû2t‡Ú«æ…Rç©m•Û'1Õ’Y†ò9AÞzû“w¿ÿýëüõ_ÿûå}Œõ£~à‚ÿ{õßø•O^|ñOñþ‡ÿâÛŸ©{D‚Ý[³[¸¯Ê=ѤEÇäò¦ä Z ™±h:­1>œœaÙggâr/z3†ŽõbŒ63éºÔ”˹Møp´xƒb¿› ‹Ã*u@§6ù£r-]û3f»¥¿Ám±Þ >]âŠÌÒB‡áfQ×w ºH0&õðBîÐÙ鋽Èï°”Úp'åQy4×»> ”ëOJçf0§kqœQÑ^§NJç0\^ƒÉIy€?9p³Œ‚K[Ô=4žÌ£A\ÐNDý¦æÐî{ÿôɧ/ž?ùä§_>ù\*?è!Øc¼8Ôh(tj“«c4ìë°ƒ_é Î×_‘ÀóÍ»Ëøœ"mçRåM½|Gÿ:ìëô7tqûìy½u½Í u(ð sðÌ%_ÿiÛìtQ,×[kZiW¹cCa :ABû5¥¦ÎƒSn;œÈ`›€ôkápD>u¸#ƒ¥]Ì´/éÇ䆳 1hñMá0µi³Â¤Lÿ%óÛX¿|úÖ÷ö÷¾óoþíßþíÿm¶ê=ÚhÇÿ“í_ÿ÷Ÿüö?üÏøÙç?|G…?D鯶ÎDÏë½Cm¿’Ô ô‡£ ÷4`¼¾ëÔŸÅï+OßÇUh“ q:±»pHå©Í«Ú§sĆ0d“ݲ´%¨âþêŸM» ¦îôsnÒu‘àÕøù0oÊ܂ʟ³À¿?bÿ$½E­'—œ× œ¨éÞù 2Ñ‹1Á ~5œ—›“E®™î‡_®ÄÇ,äÂODhc™Dòr…tdcH²v£œZUÖŒy¬Á}rÔ8ýq¿Ç®jõ‡³Ÿ¹² ZXä@„™qã cÕ·CÑßé"?}ëÙ“ýô§Oþ賟<ùP™üŸúêxpœÄu~œBéÚ–Tî?uíj»ØI­„`ô·U9Goé\ëd·0‹¦6|®¸ìGÜ’©Û>Ìn¢ÿ³–“£~™qgóÐiÒ¢¦_'ìäÏxRÌPøèЃ}tKÆÀŽ4RÈÇwDõ7÷DCP7 íÞÓuƒ }qÄ]±Bä¾¾ÈíOíÀYK§)îOnÌ€°ÁcÆ2ž§[o?t±nו‹l¼K‹ý³û»÷?ùò?þÿøÿ5‰oŠF ûÛ£Œ¿óû¿÷ÿÔ_ùgÿƇ/_þÜÓÏÿåïèYD5fv±8Ò<æ­L”Ø0z¡“Rt9hŒ ¶zÿ8¢d®󯋘TÉuÆy•yºôÎxXµø§(ïïŸüD_8ø´ïHõ¡úß…›œ:ï×€L †N^+z’§:ÓrêÑò³pËð,šÓбS-L ¦6Ï}Ü^ësC±D¸Ê—˜{–”»‹î]³ª8·e>uíËâ‘ñõØP×0´³øÕŠŸ‘ápÃ3íRª§ýj8jæî%ÑÃvúû>è†ùî”ç†É½—s«,TÇ`)Ô(öSFGAÇQÿ‡0ྪĿÞÌÇ\ÿÎ×ø# fÝ™ù:Kìµ3dÌöë`âPÎ8õ ‚þ‘K"3_(®§mÙZ ĆózeÅÕn‚8 €]z}¼13ïÔ)ÞÊ?9A'fj’Š’]õ Òq v^Ó¬§¯×Oô b«Um511Ïpÿäå“/~|ÿä?ý?ù“÷ÃÏ>{Ô?ê§áxmyóðÚ¡yòäÿøèƒ_}÷çîo¾÷ìÉ_úî‹»áší™”¹ùfkQfRf^®hxÁcgRúU)3•;f&±a’±·àÓÂMVk1Ô¾hŒÒt³Ê‚=ÓÞ<#;tÉÚy×"û΀›®ß?Hó·òe¬WÚNÑ'4*UF’kz—t.î5¶s̳$‹…§TÁ¬äWLì-ýÒrÅ+†ShÆ/Á½¸ÑÌb6W€ÁƒtÆÙ¯¾Ð©øÜÕGËÀc^ÜQµ¶A~¾~2`³]¾Ÿ@ˉzBû‹ªp÷:ãߣ¼Ã³9ý!Öé…DïŸü©>è—?ÐÅä]€õÎ1UˆI>8Ý–Cw‹Á·ålW×ú ¨jÕâ!Ž}œËò Ï"_3ÊR®ˆ™èwm½â©„jsYŠ¥“̵ò¬vòqÀ Ê…VÛ Õ)§´ÚjÐÆë¶ß‹I·©ÕXzÚ8·`@¶n0aw}®) bíìŠ<öÚ¾ ;Ž=ùø‘AòóC·’0Vº~ÁõÌÕý<Ì<,.Ÿ¿|ùßëøÅÿû½÷þ›Dys~ݼyxÝÈŒþ÷?üðýßüøã_yçßýß¿¼»û—¾ûòÉÏ¿£…“ «¯´}×i6z¡`&ªLå· wþfnZf7’›ó…¾å¹|=éGMÕˆW¡ÜÖ©mÈ~ðΫԂåG^ Ð ŸZgÓ¸–d›˜q“£H¸!û<}Ù>¹±‘;u9^¾N;|2ôK;£,ÈÆºGaÑpã_ 4ÂÒí¶1:9¶=dSááÃ"•iCô\`ýOîj0¶Ó/⇿õû¡±™ S®c êÁ‘í%2”“¸cÃAÿ]·iúšÐ†GÉå Xu€ç˜€<ˆÞééÂÏõ€ <ð.€sy„Y}V•“*´{8Nä bÙ—yü©–ÎÀëi`V6Äñ€4NðRNŽhnϯ"êÛ¹ÅL¿¢NiÚªðkì0š*`€{ptdŸ•Ã:ÛœÞp®¨#ã?é—Ós^ûêµAz‡ªÓø¢³ {ù¨+X§^¯ü0t+ß Æ¥#ƒ–Ïï+C”ÐñéÛúaKØ}OKIÌ5‘rH­â{B'¯’Í¥“þ´ëÿó'/_þ‡ÿè½÷þ£Oò“?6øÍégŽÀ›€Ÿ9<Ûø»üžýÜ÷þ«={úòÝ'O~á»/ô{¤4O™ªj&¦7vO`tLÍ]Àäæ×¤õ,ž›ÈEU*x`àÿÃAU:ô´Us"NM^Qôßf *†k÷èƒuu`ìæ84öï èÕ-K@°jÏ.—8yg  ]¦?‡“¡³ª,jéO_Éú9à·ä«·!%¡æ`uš¶ŠU¡ŽuÎ"èØ§ÏÇ8 á¸"`„« ­¸ò…ÆÊ¾äÎí#¹cé.õÞ¶ØËA›ÀŒ,‡!jôaÀ¿fùB J%”EYª¼Ó‡þé€Ïx€ï輯ÉüóÃcwΕÆèW;?[^x)æ6 `JíH£oŸ­Âºtt:(ªºÔ'†r^@¯¸Â-;Òyÿ¢5F§ŒÑé3¾›$C¯Ó˜9‹mÂì/¼­G.áßÄPå954åñ¼NêÓ¹ã‡ÆÚÙÍ`>fÎ8s‰³LÙ¥õêÈÒ*Ɖåûf8é°Ù.|gÙ•ûyæ8Õ™vdÚ¼Kö§:~üâÅñG?ýé¿óã?ü»ÛûMë«FàÍÀWÐaÿÃ>úò~üÑßþöw¿õ+={úO|çå“þÛº³üÝ€¾zÒädb2Ï;irÓbÑÂìVêÞÐKçY¿î¡c1¯[E4~N½þ½nO1 Å%Ç„I.IÍl^¼ÑI@î =*ëê‚ÙE±ü›ehZ]D³\&÷ʼn“°ðÏ>¾õX“‹þ?öÞÅÙ¶ì:ëÛûÜG¿ïKÆ`›eCÅ6!Œm’ÿ"…%¿pœP—S<ŠTLRSW¨rUqÀXؘ,caã&Øq l!Ù’eË’ºÕ­îV«ûÞ{νgïsÏ=÷Þsv¾ß÷±ÖÚçÞ–[¨%õcÍsöšsŽñoÌ9×Zs̽öÚk i3Æž>ªM‡Ôâ ZyÊíÆdæû }¦¥øwF `QrbƯHQbÀ€êe[5¬†Þ í> ¤ä5ƒ~¶¬wN k7*øÝO î¥òI¯º'˜@E7±áÌ21GÇ)9-ïìDŽ=¨Ft;©“¼@©äIDeÚäN)‹‡Ø7vNRz ]™(±q¿Ð•ÓG²ÙÔæ%£]öØ=áã“Éä"rÏ9À«—5Lc{‡B¨ÜønêéÉayµ^Ø0¡¡(3 ŒŸèÜì,Yé$v2n"k›n$]ö±YÙÃçE„ŒQšá=] >ü€žzé¯ê Àmqènéž&T8Šº˜_>ש\tu;Ÿ(±™Tí«ë­›Ö·‰¶kSÿMD¿·ÒPÏAï"òÈI×O·"ãa  BñËùu(ªn“ŨLšÍ´Üâ©ÌÚñÎ!ЋãÌN•mùD0à%³$#ER£ÔÇ8@R ‚éšðà·]8¥ sX÷ñêrÄ[[8†±+÷°°Àß_lö¯žÿùïí}ÇÁáás[†såÀtŽ{ÅF30#ð±ÕÍ_¿wñ‰¿uýüÙÅùÍÉ×ëŠÀÿD°ÐNž¬Ué7'DO6œ\Y,4~ÈGŠa10ˆDÒ'9øÈGÎ>Ÿ‘€C’mJÍQi;9ðcP/S”²uí§mNsÒÀñkyò_dƒ­1Í9GàÏXm Šþ™Hù*à-µ{îˆDJñ×Ñë;•Àí@3©HeeSû·I@ضMã· ƒãH©z?6¨Œè¢Ç£ÉZÿ€Ü’×ÞRóCÂ>Ï”t‚€ê±§b«ö+õ˜ÙÈZÉðßuI‘t­dúŠž9TVâ;-G(ÖiÓçøØ·òS¼¡êؤªŽt<Ìj¥Â~bæqŠÆQŒU «Žìô BŸëèPR¼§sfw¹øå—îÝûÏŸÛÛûkGGºçoNŸíÌ €ÏvËþéƒý—>°^½ksùâ‡4Yÿ¾ËÇ‹ßvN³=ï:}0s@ûÀΑMq8ÈKå‰ÛrMBšÉ8ú$ÆÊŸŸé$ïóƒÉÎ<Ø× ãºöª'BU,Ö¦õÈ™â`ñ|ÎöÈ(ðßS†$-Sn $¿£nDðÁÕñ &E‘r7ÄÈFôåvY7 ªNå·û›É_B ÚŸiÛYy¤,FÒµ‹¶òò_õ×úl<*öD4Ô‘éå~X(†jBËÍ«QUÞÁÚ:©›³ueãÆaAËT$u_]® 0pà)“›—¼Ž3s±h þ—º/*;Ü ‡pàH½Û“‚çxQ·^ŸMÂÍiŽ´d›uŠÁæeÓD¹Å£JŸm›"FÜ‘<dŽ — DÖÇÄàCBc,`39g¨rl A4¶¼º;––6– Ïq г/)qŽg8Í`eôìw•d4r)¡7Æ~4OÉ6ç RÈÆºÂASu ‡ù 27IÅ0øh9Z|Ð7µÊðv¿X3gòbÑù$Ýj±ÙÛ=Yü7Oííþqþ'…˜Ó«4óàUȦyZ߸u°þ›‡—.Þ=³³ü#—îmÎòОcN’:8Ø™h}Y ™^}rQe.ç<ð‰QzU-ð ͉á?NùžÖŒ°KØMSECsJŽÚ'c•=y0YHã²J$pHSëð8 Z§M¹2ðd¢òh û‰°^·jò‰/üOÛ¶EÒ„Ê{Ò@•S¼ ª2œã˜ÕepÛ{ ì*ÈÈÒ÷ÜvO'pì,®FØy+¨zX!êΩí°ÅW9ƧäÝ7;½<Öþl΢,=ÈiíKçL¿Ð7îó[ø=•nÉ»ÍȺ ü4fZGOjüT‡¬å"1V0îw•áóXØ” ž*·?A!F|ÚÞÖ䇯em;öÑ s)èÓÁÕvŒ.¶Xl¥I§\,¥ýMêöë«uV6°/ Tù”ßhG¯Ã9P"ÃJY˺±–Mz®ÜPt꺹$é¼=÷éPp;ÊGe/ àÊ=æ=ÂW²½ÅæÇ^ÜœüÑoìýÓÁv.¼j#0/^µ¡‰®*Þÿúzõÿ_|üÝ·Ïí|éãõmN²œÓ*pòùi©N(Ä”µá¢ì:9BäR0¹â\œxÂGCò ˆ^/Ãj2):ñتC` düU‹"²·H¹¤í ‡IòjR&ê¿ÐWu+T¦9íø¼P²ò‚@b§õLbUAßã$QÏ_EÛðä¡!"FîwÎ8‘'&k‚& t4ªèJeîþïq‰ŒwùŸ b 'íDÇ‚„œƒ€¼¹·®XHÉàäÆ¨Ž r?¾¸|Zœ6A^û°»'¯ ¬~j,¸ p­ßEç×ý5th#¸JæÄ§êö¯ÜåÊ 6dƵÀ4Ç€ÀÇMt½-WÝ}êC¡X1ÑòÎËõ$±'?]r›NÓÕNí+t¡cÔcþ ^PÉGü°è±6×Pçx²d20êú`q>Á¥M‘å·mè©Ø.£€Ì&eFµ/í7¼m†»e”;Ù*çPÖ‡î\µÏc&¾iÛ%Ý”úäµã{âÙ7þòíù¾=¤¯z>/^õ! Ÿ[¯¯ýª>8¹|áÃ';;¿ÿÊ ÒÏQjò~ÏŸƒ?ç›NPü}ŽLÒkR÷IRgïâ8Tî“M°!!k9¶å$2ê%p‘ªê~+AVãڞ̌B>N&ÐoìU5bXHß>ºo@ÂY:0t;éQâ5ŸµcÒ<añ"Q‘”’:xåv¨ÉrmÑ¥ñg…lÜ8r€¤j8UXÙ%*IÆè™Þ7öW>ð£Ar€ Ð1à–g§ËÝnä*÷¸Ògj·Su'd P-í›}¯7jppG íŒ]‘N¿åÊ/u|5kë©·ÌmiÅòÖ7~ Afýi'ªÓV$x€‰FñÆcŽˆx ’&¶F>OÑ%šAl€lì&¾8Hu ¤2ݶ«4Çd-ÖT>.U·N~Ü~)©GZ©x†Ïï#­m;‘MsHã« Fuá#›úpÙà>o·À„§ûÂ*6$aÌ¥m›d_p~V ]î?Ñ»þïÝßÝý–—ŽŽ~%Æóös5óàs5²^},ð¡ÃGþ¡ƒóçˆeÿÉåc…yž¤Áéðg_*øR} ›Š'‹>jKÕ'iN.NSDh)û«jè!°trÎÒÉl®|˜dÍYíÀ´l!6*¥SæDî¾UÝf…i@ÛóüðÓqˆ.íç{ÁLºùé¤.¡Ç {·ÕÕ$GfG…0'†Za,3ð„Éã ƒÓcPæ#‡Þ(“àI«Ž0ÈÒÏô -Ï`!Ç>‡f©é±ðþ— _Öa dß4B²0ʱWÖmC5ÚÅ?d¾‚Á@¿rµÖ“óÀäI€+5×}¼“ ØÓÉ}8-|P½¢k¢’u•Võ;ÑmŠFÄ çÀ”°I[¯:E™aɾ¤ÊøOë.KNb¢e ©y¿Q¬„všÌ×Â) Õ}œªè}®z 2@ç˜"ˆS î÷êàÌ !üâà'¯'¨ Çšý C;ì×.ÓÛë:‚L›öA —m`KÕó—Ê' µ‹nÀhjdN©s<ÞF7¢þÛÍÛ?¹·÷÷n-w5矻˜Ÿ»±Ýb¾zëÖßX¯~þøÊ¥ŸÒ×®¾ôÂbñÖGt¶ø¤ãlqòiSBÊ5ÛÔ©#™þ=a”EƒU»_lj׈г}ŽøœüÂ!ÞT·'Ù+ðødV=˜”ÙØ¾j§/]›€vŒœ=ÙNòV"ØRújI+”{roò²w_S a7ªsáè'&Ó´]ï©ÜD3)2 MÙ N|@ ·3Jj±Xe2Æ»ZW ,R/ ¼˜´2¦ƒ@UÃíβ­,þ „ ÇßùÔà–‚ÉêäÝÿË^¼¾|Á>JÝmë|°êÆI€îA©šgUÆT®†p4¤Ò^)“:ÀD‡¶VOë(Ú¬åªÛ’‰^§Y BžÔÕ©/—µ±¹`Ô[ß;¹µÕ·0Ib²flióÀ0žÃ üqTžÊ‰3Éú×ä6fCÞãFyœ%ŠÊ}èr盫x†!C^|}N´M¼¤ýù¬Ÿœô®gù±—Ž7âٽݿ¨Gøê¹>sú|À¼ø|tùy~ÿŬìÜ¥K¸svñU—N_ÌÇÇVœ>uÆä’'µ*È}ºh¦>‘ûd¶°à ò.A„lGk³ZÒ_ç+zÛ ±‡3׆÷säkNín[ÚzÊSšŸK xŒ‰}»¯‚Ç¢¡ ¬ûvŸ›R2É´ÞetD`W]HÛÂË>ïnSn½)™¢«/S'ü¼°q;!­„å0~õtí’ÈXµÔw9‹!Ïí—!Æ$åÓ~µ¬TC›\§åtbn÷ß%0ÒЋ}ÇàèžÓ{ò™K[ y»§ í§ý£~¹2 tmcªrÀxÒLÒP„¶lh€måadlm?èâ«-¬d3Ø’z(J'Wb;5ìåê-7åhf±«"€Ã»Dö1¦ºy-lòLƒ§µ ~wnˆà´ÌÅ¢˜G¤ÚäLÆ®‡¾ì; sµÑøh¶ä&HKÛŽ¼ÛN_À³å!á·u¼][lþÚÝÝo~éèp¾Ü?´ÏSy^|žú´›­÷?üÞƒõ߸tùâ³ËÍ×\8Y<&—ÅûTÌéâwð!íSl´‘ûD,LÊÅ¡ŒzVöX‘b ‚I¡WãÔ-+Ä8‘Ô$%¥'c@JEй).Sdû)ˆ¾j€n•—-2s¢'¥i)k ýž:{£ârQ«î ¯8¶x_Œzò,Š8R‡©óò¤Å¨½Ã8ˆ—9¤ö#A‹u­e‘¨Æ¿ÈŠÖHð§'_ú`?4Iåd݇¯°Le”ë¥lØ_ÝoŽ%ž°#C®¬u€k­{š ¦_Ä–W7Á‚S›ÖŸÆLë”]Ÿ OñxlJ–€$È´7¶vf{mý˜÷QñÌv ¡|­#FrîEÈ´ažîÊhâ­º@á® à ¬W ±D†ÂGÞ}ãÎþ›roG3€8uŽ£>VÈÝrÔ5¸áÁ ì¿®9& zßP· ‘Ótêø“Ò瘧ÆâøHÇÞÍ?Û»{qóoÏ—ûÇû|—æÀç{Ä·ým>´^ýâѽëðü¹/~ìdñûÓ³|‰0çN–:ýUÏÔP'¢N*N&Ÿ¶èô'L)lЩHûæÃL6áô œÓ9­“ÀÓ'¤ÑÎì”#-ñÃrQÔa ‚­J8hx•›SuO.ÔUFÝiúÕ¸Þ÷ùË—U÷¼í-'›/:§³ˆrçdäÄò$W'1sINÈLZ”û=}òbÞœJЧMî°¸\("oáv“„'ÁR¥´Í[ë(…/UŽ`X¬ <´’ÒÛ‚ "ÉJ¹bÀDg€5\XLsèO:7˜Œõm2,2—`²þ1±%c2$•§cã¾Ùsú©®™ ïòäã‰=Å-¾"GB%ÆHòM݈‘š%iß„À7—Oƒ`Œ­Mí¬(£:¤iÅ|ò¢|çœ&eÿ`} R®øÛÔFDÓj5aKf_SåNOê4Á¢Âw ‹¶ p”[ž¨“DªÂlITÁtРªŽcgJ›£$¢æ!f¼òi²®€`:•ÈÕ.›Ã BJ‘#óT›íi›cw캰²íåHÒêÑz,%0”¡†4Í›¯³;ý5¦u#Lô>ÂÌ×aïq¹¹ùÅ«‹»ßôɽýwê;ýà×yPß0ØH>Mt…ô }x£7P»L.“Uã!Rž{IŠã¾ RZa×Ù |ƒÃ ÷Ж²ÛY :}Ü7}5º«£;+ïò$/ôuè•ep½Þ k;X‚KëÑUt\Y'TĺS— “0G£Fc0ad&Iò¯%“,˜~a:Ú«Œá¤ˆH±i@`H½GøWËÅîÕåò»ŸÞÝý΃Ã;ÏÆjÞ¾–F`^¼–öƤ-ŸÐOÿÚzõ÷Ï^¹øov–ÿÁåÍæKÎ+òû¤ãD®Ù§Ô¡%Ûzt¯²+R¿Ë6‡l|N›¢`ª žb_Žæ2³Ó0Ð$@])ïôS‰]|ÒVꘉvmcC)™|l ¥„¼Hî³ò©¬ûˆ0eù‘qûatè#6ð’gƒ€Š’…)ãÁ¡½Z€¡Ó WÃl¢¶ãÓ“¥ä¾ Ru‚vè« ,,šä].N;Ϙ0à±P±,‘Ggš­zëÈËJ•Z@n>}À×ù@ý»!Ÿ,ºMmöJsÓŸWC›“ýa‘Àtm›ïšò¡7EÂRn\7ZË'3ÖÄÄÊÆÔ-¬S™˜¨–H¥$ï_}XH9=AO'‡vQÖ«÷§/ã é†Å†}Üã€Ä<`† ®}pt°È‡%ʆ†Y˜zx°j?* Wr_T0J‡¾¯lY\f i»]ÀQuðáA«çK¿·³yçõÍá;^ÚÝÿÐÏéµ9ó൹_†V=¹Z}佫¿ñЕ˷Îm6_{Qßàìw€ ìI…‰$w§vì(t¢bÜÉØª G)3Ÿôœèš€3Ñ‘g"`0½»@{´–:…~ uäI)yRë Aµkþ1¼}´?ê=纬z0´N%Ñu(ÆÉÒvˆ: Ûír>©ÃÁ«X ¤ Îïò¤²¦½üþƒñ&„>)WZª¬l Ɉk IÙøJ ðšµ=ªÇ›v\hDX»ÒzÊöÑŽYîœñÀ/Ÿÿ÷M€Í)Ø$k%´è½Û‡ö«ú ¢Üð.cÙB•]œÔ¥\ü$ö„åÃ&°øîò0Jâ5u)Êo¦@Ä}A¢J˨:•l¨š“þ„×-0*¸ÓѱS*kïS•'û;>B°…mûóFóÀˆà˜ÉÍ~i¿5¸Ç®aTT¦šñGÉ9žàÞ6ã˜dœ©m‡Tð˜Ÿy`£‡ùèrÿbó/^Úœ|Û'w÷þ·ÃÃ{ûaŸ·¯Õ˜¯Õ=sª]úÉá÷,/<öãW:óÅË|[€Q¯>‘¨©Ëv2çPÓNéar¶|¨èI¢yȇ #]‚Ҙà [O$.oûÍÄEÏQ±±™o‚„÷_ÇfIÙm„»˜wþUãÀ1hÈP8!nÓ.»§ð`5ÆÆÔû lÅÄ.g Ûö«@èG$©ŒRqmÈ”rŽœÎð~&[îú˜h¸ûIS¢À瘬±_}T†!ð¯)_ïì¼tusòçžÞÛû®[·o?ä¼}­À¼x­ï¡Iû>qp°§ûÞ}îò…÷ïì|ÕÅÍæ·ó±@/8…3±ròrvrrúµ<%NZO üš¸¨IÃL怇&L(Ôú/7ü…c˜l„¡ =¥q5‚ ó£JöexiI°hÁh²‰£´@ƒ ¢¬4õ×mCÎäÔ¾©“0ï¦hÃÍIày•• ²4Vm”]ûBOrÿm¬ÑÁ™8ÝzÊn@ÕSW2Gµ°ñÒc.œZâ-bžA¢ÌkŠñtŒÏ˜¨-ýƒ€à_n£C.ßèÑiTÈoÜÒG·U½©™à†Úß ¿n*˜ô‹úVò8lI v»O‰¨Nˆ2J”Ü™*Ûh @mh}ç6\LÇ„›6ð&¨¥#±?մݬÛ.]w·ùÝ´6 sú?pÙw¤ÑßP}¬·&°®Ù¦-ù  #µqD,„|cU\6Ó)]ËcGXÇã6sfŒhÓvôµÜÝ¿»X¼s÷öíw¼¸Zý¿E;g¯“˜¯“5mæS«ÕoêcX~ÑåÇ7›?|ùÞâ!¾ï`TH˜\Â'y^Òy“ºdUSÆÿ8±TÝvlÄûøÇKך„Ë„€u’™ËÞ:m\ã äù¬ì7i]Op¾MÍZO`¸Ð‹Ëê¤á«ƒ©FF‰Ú.\Ë&æà…˦“ŒÈÄþ$¨¡sÿѽK.÷ØZ¹Ývƒik5¼ÛÜ É‚Q=- »$6,û_"uÉ6$àPÀu3M1‚¢w¿ÅÀƒ€në ÀAßPWš{^EiGi‹ãÎÆ©àr z¿FË* Ö¨£ gJ!¦ wŽG¢Ì¾ë2˜jǸ3ËFÆ5/HM-Ø0¶e’ ”ú7!× `ºÒ«ÜR$#¦Œ¾Ó®t ê‘á„s±™Z~ ÓTP7T9ý±!bó†ØÛèX蛇Ñ÷rl+Ĺ™Åê=µCw÷ÿŠ~ùô?{~w÷¾u÷î Äœ^_#0/^_ûkÚÚÍ“ûûÿòü…ÇìúCg.>±Y¾­¿-௠ÖYî]V™¨rÆ÷Wôúü÷DáÉ¥'²LvÖ<ʇ …aMDÈX ô»vfLHÀzÒ±E½ì[³ Õé» S<ÝÈ‹€è†IMÛJ6ä`$ory¿°GŸv£¥Ö)~™Cbw³ é²-+j,\p¬†Åu|RðUõÕ“ªV; Êè—-h8˜ˆùL•Ô7{e"krìÝ_(Û÷ä…,„D }׃³| š>@þºåjZMÐ…¨’0p™›rË•[Ö00­œ*‹¢Üù”³Æ¹8é¬Ç½x›5!6IÑÑî®·Ѷ§ÂIH[Û¤sì9Î}E«ÊÈÌ‘öTï«ØT §b=üÍvÊIëÅ*Çh„®›‚z±YŠ—lJ«jê[œV½õÍEPââdn•º% ÊFózgyKŸóÿ¥göö¾íàð𣟳×áÌ €×áN›6ùéõúƇV«x÷ò…÷ï,¿êòÉæKVTɯéÀ35ÒÍôÉ Mò‰®™Ò4Éuè9£`Æö%xWàÞwª›SRê]®©8<Ç09>F˜:‘ñneOJ‘ ÙÁ’Mhtùc"l2ÊÈðÛ—Ô±KJ·×_´Kì㇭?f).s¢/Á²%ydÓ¶²§HÍ&ú /Y°u;ÒÞiÂWw`e‹&ÈÚ¾sHS~ÏèÝþRù¡œèk€‡âº¡ø ßÝIÂJ=V8cL5e½=VU7@ù™XXœ Ê©.R$¼H H–5´”ø$õ‘B¹!*—*'×'Â.’»ÙÊý¿òB?dÄøî9Œle©ñ Gl“äR˃©»Ïä#&Æîs Kß8Äè'j_ÔsܰŸ§‰‘‹7ÛV«)ƒãé¡a‡úØH?Õû÷öîÝ{û‹7oþ_RM]L çòëdæÀëdGýVÍ|vµzê}ëwn®\>xx±ø/ÝÛœ;+#®œÛÃÙÚÅh$è¹¹'žà•“¸amz²%GÆáðc‚Ì GlÃAÛŒ¥–:ö¤~Wå²€C(Ë/‚ +9ÿý­¹•Ó¦ŠqD>À¥Ÿ,† ´-Š_åOòæBÝwUl¢zòàiúT2`täQª†¢·oÌ‹^©ÛÚö™‚£ƒÀv´Qgœã2°^›Îm© n þ‹³gô€cpGrnÜz¶w¢Œ¬ê=&TéNË©»< t:-¤Î+£6-o÷7Öí…vÕáfQ3Œ6HF¶Ôâåt[©Û»@µK†þ4¯ÉÔN®T9€š$ûëì Âæ=^Ä"ò1‘i ói v;L8]µUBKðRn9Ö‹¬å”“²ÄÈ8Ábª5Êг(ÎÃ|¿vm³ùãÏííýÕ[GGúØNo„˜o„½8öaóÔjÿ_n{äÇo>tö‹[.¿ú"¿- ½ƒLáºîÏP@8íkÖ¦&¼ØS„¨Ô î*sPq%‰¢'Já†i’²žðT¶ ö$µGë:Å8ÅaQ‘ÉD¡¬l<¥Dïà‰%êL–ÐR¡>M´/ìÝ×'ìyÑÌA,A0ݾôvDÆ¢‹{ÂeñØNö^@Ií{,$ïç+ôMÙ_3Ó$öAC4Fdl»mÔá!ïa58/mN¤¸-ç·´àÑl¼ûÿtÂß«8$dNåÓ ÒÖÒ)pu­Y»Ž²ËOe*7q©]mh,&ðèýÔ¤ËcÊkZï²Ïh4ÎÈÈ©ë/˜Î¥,Iïã:8Þ®ƒ$a_G‡ŽY;‘ =Ó¢$ûU‰¥H8¢èsÜjmÀúVŽ7ÚÕGK$i»qø»ÿj‡}ÐYºZ.o_;Ùüåïíþ1ýTïoX¹wóÝÜÿ)ZèæíëxæÀëxçýVMþæÍ§Þ°zçÉ[.¾¤w0oÓBà Þiö 1±1MœžP2uhV ÔZÂJl˜‹:œmKÞ—Mñ¢‰”IÇsjO6EÐÅ“&n‹|ðAÀ+šž,aëd^Ô"7®ªù¾}Ç >)÷ËvUW *Ñü;(cPí¼äc²´ªAçÝ(‘Ó0 "\UÝF² °H›ÓüÈ«×.9IÈOþvç‚1›í!ã×jp(Õ¾|øA@RNÛAyŽðBC›\H}ŠGíÔÀXHÔ¨2tr^-ÅvŠlßÞ¥¥ ó8¨`†•6Û¶=R—K0Øàl¢8©ª<©QtãÆŽø×í4\ЮËzHÝÖ¯¹£e×]í4s—] ‹cS„­À .êUÎý±“}ªò´¥ˆdŠCæDÁ_óù~±ï;ŸÝÛûÖ‡w®I5§7èÌ €7èŽvK_|ïúÊ¥¾ufçÒ£‹ÅºÄ[oýOdˆ©ÀˆòĤš4‰†û*PSÇ‚Üã‘_¼u—G+øk&ÐOµŽ`—U¥}$LÈTG„QU%åj€7 *ٺʭc;¥Ô-%÷qP —i„,„m»©.6Eë¬OqYð–BºªÙz­|³C¼£ ênÛ.Ê?c]ï†AIr{S|`ÝBÜê•c5­¤m¤é9Ð=ˆ&­ï>€u;¼3uwÿby´·9þž§öö¾E—û?„~Noì˜oìý;ôîêþþᯯWÿèá q}vñ•—7‹/ãcé"À“…&¦OB H=™drAÓ’PX\Ö6®jšuR®™Í&èÅÑø©^&AOj¥g®ƒ6ê*< ",¸ai+u÷D+êEqzvï6 Zd ËÔ_mt[(Y_léodÕŸ)ÀxÑ9À‹—š^X‚¼ Õ•ð=Þ€E³<ä©þ–ãF9îÒdÕ=žpùÇ€ôÀæxqWüþ1 Éý1ê6«¶ÀQ4.à‡¾öþEGšb¨EÞ &[4ÈÇ”Z3µVõ‚æ8*| r²ôMÞÙns6cÇkó²í=6½qËÕIú9àÜ”1töG_Ùá` Ÿ*™s°õ’|¨æÍƒÚg]óQÑ‹þtÿû£†ö_X½—ªi;4àìS$´û®^»›Å?ºº8yû§nÜø A¼.;§7öÌ €7öþ½¯wO¬>þþƒõž¿ra­éák/,>«Ù€‰ß“‚,8û„=UhÂÐDΓ–2®Œ:X´óÉ%HÙhÊ1A&-¨œ¤ï wÝZë8¹§Ï{ðc@mãÉÊ“<}‹ØmzÚö l lãˆ$É=L;[¤œ}ã$šÞOÃçñ¦`ÊlIÙy‘Uåb*Kï,xàGÃÎërÙæVX¯Rµ-x[Àv¥]š ‹À—çÉ­5ƒËmÖ9èhF¥ál$ÓÐ`ƒÜôi>®j}t+E¯c[ƒ£‡õâêfù§ž½qýÏë§z_ bÞ¾YF`^¼Yöô©~~tµzϹK~ô¥sgŸxüdñ.0ë(^ô¤Ã„B€õÜ"\b®& MJÄ•žhàèd™ôÌeÁ«\u ÐïüÅ Î~œGŸ`—€ƒð…´€´ ¥¼[-)Áôñ·±nHÕm£Œ òmžøÁ?,‚Ì¡ “;¤Ý?‚•íEžd‘ŠÉ3†žðeà ŠB:à9ˆµèÔ0ÆÆ/üz€EP æÝ°ítë–MÙ £Qè´8ÏÁ±’ìëm~ß©}Ú&¦îŸêˆšw<,$ à#Àd-Å*eÆpLå •ŠFhãj×Gf•k£,Mi´ò ‡>‰IDAT3oQâ‡b/†Ðy¸ZÑ<âDé½›R•Fx‡”œ²’·æpukCðGŸc©Ë#ĺФÏ]7«Üçe†Ó =ÙÄŒqoOÙSºxOÿXêàÐ×ú¾ïúæø›®ßÜû7c«æÒ›iæÀ›ioŸêë3«Õþ‡Wû?}æÒ?ûÜòw?~²ù]i¶ìɦ'rO˜5¹37ùkKRø]·ä(-?Ó9l:¡u`óåi)˜œ ÄãšóIcEoð*¨¾Ó÷$«ìiÍ  Ô|–ºÖ³©ƒ%xø& UU¸lTGNYA×u{°¡&^„h±QÓ2ýäVÑN@6 X$–•Ø‹rG0P”{°)âKýxcØh‹V4¼Ø¸Ü¨Ë ¾ ê@ö5àI‚Ãi1˜¡ŽÜ¯ fÔ'ýK ¬miC»n†¢i™ÍTê-(ã–wŽ˜r{ïaïßn<尿ùbÙ²œì<Æ”}»3ã·7Sy|åxœÊÃ6"Ç›¡<©·QR|ƒÚÖ*Kð.ÄÃÇ ÏîßÛ,þé{ßüɽ?tttÄúoNoÒ˜oÒ?íöÇ×ëgÞ·^ÿðòÊåçõà?tYß8£™ƒû<9Ø“ ³~þKYe,Ð98”Mi"8`Ä0—Ùˆ3”‘SLT 'ù`'MHÀó%o•h<¼x˜Ps‚Ç¥¿€-}Ä^2\å›eRç¥êðºýr˜ ßÕÁŽ tи0Ô‘›+bw4X+²ÀÀ^/·Ubô^ˆ)g\<†=@4†r'ìôòîC¥'ÿh ×ô&@“ô[©êƒ_x àþmTittÝÏmijC‘š·”)ú¨ðNïÐ@ÁFÇ÷ Úï@dAnäcLÚ ž¨Qj/ÕnÅöÆíD þ©Æ¨õ½¦kZï­”…ÆTÆ1Š_Žóæè_„™¶rÕgLèŸã[ÜÝ¿¿\<}}³ù®Oìí}÷úðèù;—Þ¬#0/Þ¬{þýÖC„Þw÷Ò…¹~vç‘G–˯½pOSŒæ&+&¿˜€( )Áº'Séz*jh瘹Ì̧‚qž3Ýfâ“…f=*ª-²Á¾ƒµùJGz(U3ÞµÈé©Ý ‹»®›CB|t Gq;—e, yJǘ‘šSˆËδa õ†!@ÒÔ2f<"&À '/뵡<^½›¾©•i“¯¢\êI€’x }¾û:¬¶ãØuÑ‘=©å]tº‘^Óûéi«’Èdà@ÑØZÚS×ýzUÚn´–û †°á=Õ*Œ{ U<)›S¨¡=†ƒÓËûª4§ÛÛ8Á†@O™!úXŽmËo8…1xºé1ÉX£ÇÄ‹bþ[ªé&¿ï»¾Ø|ÓÕ½½÷N-çò›{æÀ›{ÿß×ûV«[¿¹^ýãËöö™/|³ùòG5£ñì€~‡Ï äINÖž =AAåZ¹&$=¹ö¤¦¨uzâÎËŸWgÌØö¤‚^O€hIžä”÷Ýr+UÉdê(òhaŠ©³õ<ïÒ9J½èw-ß/$ª­`Üˬ mïD16‘Àsš{'‚ê…Å’vNh‡10éº?8hYŠºò¡+zJä­c]Ó Õy#s—&Ô©Z¤õ(¶R£n#°C2•Žez¨w°%p›¡P‚`šÃí°>›²ZkÒi¹Æ1„ùw_2þxiÆ‘‚Þæm†Ú– Ë׿qg«åU'#õ1kw¡µ¾Ò.× ŒQŒh”ùŠwl»Û¥»ú˜go±øç7Žï}ãó7oünòã¡sšG`y0 Å\˜Ž€îxîWV?rï-—^Ðo |Í•“Íãç43ù¦f&~V>“•ê*gòËÄç›Ò*òÍX—êÈ:Qª0wÛ ¤&÷ô']ìÆ// Šg÷ë8®@¨ mÌ_·©9!)2 ²ÛAÓx”ÒËjŽQõD¸ ¤°®mÉÅ -/â®Ç±Èӻѩ?{6d8UìeWŒ¬€!êä_~$¨ÈÎòVê&@ÿÁ½“<õMœ<x&¬lÔ9¶mßî˸u¸%áA#Úüt`D^!Ô‘cdoçp¸–™°Ü¨ blCŽHmÕ€á£w|ä2‡[1ÝÄ[ í·vÅP·¼ôEk’Æo§‘wûR°Ò²?íϜѴ è|T÷tœÙyéÚæäÏ}bo÷O¯æËýÓ=7—ǘãXÌ¥ŒÀ3ûûÿV?9¬Î<ü>¸ÈÇšq¸"à ‰HÁ…IÉÉUøΓ“#e†¶=¡Ò«?—‡—ÉX"ó

~MÛzº?ñÓç ØøuÉes±!Ñ·Q-q{,t«2""ƒ¨¶ñKŸø‹”_ì»¶³ü?öoß~Ç‹ûû¿Ãœæx¹˜/72³|O¬×·ô¡|÷Ê¥rogùåzˆÐWôÇÖž€<7%€(’kžròÜæI­ê*£DŸ)+rÆ"ç-1¹þüކ2v–9êˆddMU)3;pK̰͌tÇ­$ *—£‡û ÒðÚ¡dašoã·àÌ‹³²Cæª7™ÂÁ$@o‘¤­ípð«Bs„&ýiÎ|FôCrÚ·rÌ“ô€Ÿû.ÌÍSˆÐWeT¤úÊÒidBjÒÊ)K™W¹L¥Iºõ-Ž}×dRßðV`‹leÓ›ä"I[º%á©}74hôC)vc{9ÖRuic¬6¤®‹}ó˜HúØìftmÆ$­†’Ò]­0÷–‹¹{rò­úžï?¸{÷Ýœæøt#0/>Ýè̺­xnÿyý¶Àܽtñã'go»t¼¹t^3¢'2bHß„•I USp†‰œ^„>Tƒ}{”Žîp²½ò!Pg"“4³bQäWL°ÑÂ"m‘fxŸÅʱÐ-rÐŒûû·ÅpáQuŸâ/[‚úÇ?zêûRÕ6¶±>¶éïÛÞȰET™yÉG[­ŠÂ´0àllÛLîàYh±ÁÈùéTM.1}®¶Å‹jØ£·¡<%“Ú‰‡qc×AëXº<Áõ°ì®…å›ËûÙË“ÖO8¼_LL×G|·+#‹<ŸÕ+«x=%Èaä ¤a¹±Puõ—v¢ÇPÇÿÄ4Eéã8ò:Y|7‹kW›ï~zoïO®oß~æ>“Y0ÀËŒÀ¼x™™Å/?O¯W¿zrþܯ}øì¹Íæë/=•¦ a’St™‰O//O`ƒ5ñY^8ñ˜Lù”ƒ+L†È|i]y§\°Æ"䪒u`§ìD0TW*"Ç+S¯[èR¡Ç¬>Ìí¢rm¿…†ƸÊé]ü¥Ÿî~犽ëml›´(,8Ð܈|µ¢‰©¢f ¦:)ç À¡"É­{ǾÀM€Ó{Ú¾ñey_Ö-]ãG‰4êFsË´¯`~Û‰ú–L•Ó²­¶6 óVaJ+Q?MÐþ§ºI¹-ɧ/ ÔO'ó”oÀ $iç‚ñbdÌℾó×àöÙ,‘·ÎC½®ž,~pïÌá;^Ú]ýó8™·ó¼ò˜¯|¬fäd^ÐÅ¿±Úÿg—.ÿÌݳ‹¯¸²X|Åcz8Ïç™NÈL_¼¦Áƒ’æ´~‡ÓîÇëö4H>ÀçD:NžqÞ¶6ìJµ¡²õv9áÑi5w81§m檜>xF¨W÷É´9•Ž2ÅNiw‡DI[©Üc ¼ù°i5eøãƒwèpÐë)bb‹X¯‘f¡¼y<^Áæ#ÌqÓØB¿ýJç”ëD»’0jÃÎGÍ´Ôý1¼ £EJ#o,{ky}œ©Ü»³÷Í4ˆŽm‚a;ÀF÷`O-MžñnY·ÅŒ«=ì¿Æôq=`­ÈÞk¾ºã_ÒØ¡ëVMÛÊ~‚wýÜÝc¹ø7׎¿]w÷ÿ¯‡‡÷VƒŸ¹0Àg0óà3¬zÿ|j½ÿɬþÎòÒ¥ÝÝYþ‡—7›+ü¶@ê¶ ÎôçiL³ØP¶¢”Ò£Aw_2dÔôçôtËò6ó¥]dòìph3¶þ³èGG”jcMÅ~w.Pv.²*[ÅAHõˆ»%§øâT lûH@Ç!nRŸÚÛΜ””ªŒ½o:4k«dYz]ýׂ\8Y¬õ-€;’óîŸ{j&–±gK;H‚)œ-IKƒë-º~Å,¨±ì’!ÚLw\ Þ¶ÍÖÕl”ÈЧíê+§3ôÈèøˆ³UqXqj“ >.'š•¼}ö` Û’7—€¶+?iG¬-o\å‘mÿc10,,Út£æõ«Ëåw?½»ûGGO2Ÿ«ó|F#0/>£ášÁ/7O®÷?øü¥'Þyçìrs^߸|¼9Ë4׿6è²êLptx²S>ýÊ Sk*ôÆ“ƒ·A&_Hü®]2ÄÜå.Éð1„ßýsË&Á!X?L¿ž½‹ÀåpÃÓÁd8AŠÇm—?R‰†À=½d ú´Å~‚F† YPN-%ô}­ŒðÆÂX³å*€Eƒ’‚8±”cH•U%÷9`Ëê¶ ·y Øx¯¶‹Áö¶½6'ïJ»'iy¶Ý6ò¤¶Ðþie«j§n¼bѸFC=.ÄnÑôÏ:O;–«7iÝ´¸À3áÔa¼}ORŠ[m'û&2ÂMݦÕ·+ 0GlT‰™ð“£9 ‹ žþøÌ‹Ãñ™ñàØ>Rð¿¶Øü­ÝÃ÷¿´¿?_îÏÐÍÛÏr†ùí³ä™ÍçX¬V«»¿¹^ÿüíK~âÖ¹åï¼°Y¼•¦LpÌk¼zd^t %G® 5ïԉܞ8)+¡'(—Ø ŒŠ áTZãÌea|KØ"|7Ï ”À÷d 6´Œñ:µµ'8P¹¢MVn•Êí‹€ÉÄNbË«ƒh›6GëétëF¼Cš×Ó0 /isc/ŠBà"Žù€+Ký -¼‰† †¨Ò’þ =ÂèbØ-Mßè ~Ì ÎX¸(]³2ˆìY³´Ì½%7¤”·Ì_ûLIÛZÏ‚Éä>àZÚ¾íR6ÈÛ.5$᪺ô¿i¢=[[³ÁƇ£÷zÛ[æc ëØ4 zÒ1—û‹_Ý].¾ý¹ÝÝï;¼7_îÏÈÌÛWcæÀ«1Š3ÇÖèi‚×>¸^¿kqùÂGŽw–o»|²¹ÌC„‚ýsk"ô„© ‘É“i±‚ÁøN9vŽOB´mÐlÃ(óôÔÍ4ë9yÈQ“¸*^pHÖñ mÍdL¦ umš‹ËÃLòÜ»@šâ™ßŠ”§,ŒGè„-4´µÔL½Ê…wftlÐcC›†öÒäÚ“ÀÑf¾á›ûuÞ?ä`oBvÃ:²PjFXSîG2 ¦0h©›¾}¤Ú°Q*ùVN%i ëY}é¿{ž’‘Ò Ù;:¢­íè3ŽØ§$j¼Ðór= ¦z©­o Ž]·AYãFLc‘$å| /B»oñÉv½XÞ½º9ù±÷mëÃô͜Ï#ðjÀ¼xµFræ¹o>¾ZýÚ‡ÎÿðÝG:~±ø#xTŸþyˆPsRMÒ¹aM*{ÒöÔ %cÂM_E(©ƒló¸R3:s0ó~¶ ®Ô¹Ò,uÞµ˜È|ÅAѲ¦yºƦ¶7yêæm®QiÄÔ¼Un‘ð´3'A¿ â“6„%@Êè5zn qÒqýc•júlc©Yñè1އZrÜÒU€;²ëß  at¡-œ#é>€¢–:#n†€›Ã-냠sˆ+k¬ùªNy8¦ kåÆví²ô õÏ•ˆ$˜øÃOdƒO¦ãÜÁ;ŽƒÛ:Hu“ßß¿zïî7èa>ÿ@â^›™Ó<¯ÚÌ €Wm(g¢€>³<úõÕêg½tá§×;;_òðbñ{§ 07úMœò¼«fEˆF¥ôaQ ø¤O™mí?•`uû»©ØgŠ£žÀ¬À¿»ÜüêµÍæ;žÝÛûïܹnNó|®F`^|®FvæÝ'W«ôÛ?¦o |@ï>ߪú÷ježd õ4Z2R.«]+ w C¥~ç¤â¡'îÄò€2=‘^¼‰F‰ÎŽHª8tZ.€aã µ1¢Ãwß©Žó(7A%ÚJ»š&0n»J]&ˆTÈmyo¦ãÒüÝÛЉÛ"±<Hß8ÔG·5þ€:2.Æ«&°LÛÅ€u}Ú3d¼ðí\›î¹5¨èƒn l7Œ=öˆÕ`r·»eÔ**3BÆÓm+CiZ×äû0V|·h,ÓRð)#2§ Ö«â}A^mi¯öU4wüLÕ}ÌjLö—ËÕîæä/=µ·÷m·oÿf<ÍÛy>·#0/>·ã;³Ÿ¯÷?üË«¿þø¥+g—'_{ádñ0Ï®'×ýìš™—Ù—¿æç‚êŽd£ÂJ‡ãž==ײ©ˆ[s¯q]†¡q˜-(ÀNùÑm ¾1ç_@ü®O†þ£êµÂ.½ƒÁ„6Áïפ禔¾±œv”Q¬„³“ǪˆÉp@|N²¡ý:¨IÇÕ >à¾pK žpS¯ñ#€Øf %˜Ü“ÉhWßð!ýàºÐe–~…¸R;Û¶‘HíóWýÊy™%(«s¹BÕüÍA3/ò¢1Þß°VÒ"n~Ä#Tz±/Hdæ¯22rš¿¯š4Ž|(Gh¥ˆNøœgù‘kÇ÷þä³7n|Ï­££]¸ç4ÀçsæÀçs´g_[#ð‰ƒ›{zˆÐO,ßr郺ï\8Ù¼å!Þù)xr­Y”Éxë342½ˆÍ=±zÒŽ*ö*»@†ÜQÞúÆ;é€u &6:uî‰;4v«MT›üÆ€j¦µ0ÊuúM…éÇEàl:‚‚¯.cY ‹–T / >Ð”Û Xªå_õX¼èM¾7@æ Š‚©£·åü@«š»‚ÞP#÷«œ”1B€ˆð©S›´LåÁÐæÖiCîý‡ iʈn±)AÛXÚ‡gî 1çÔ_¢IZïJ¡J掰ÛW·¼\[iN,Âg|4fÛÓx,™¶©ã¶«íj±<¾¾\ü•'ww¿Y?ÕûØÏÛy>ÿ#0/>ÿc>{<5OïïÿÆæâïÜ?·£uÀòkõ#Cg T\p pôΤM!”"LÒO3ºMÀáœK&ct&r wp),Y»°=$U¬~ŽdÖIßa3ká-§¬~ù(ò®mUt¥åUµxÊ'}öBB x‰o0ìDêö |*¸ÅáqA©º¥Àmå<ম  Ã#`%©§ñ‘1 ÊÐØ ¬d m|óže–D[8H8§šñ,u|Àü£+DUà ™÷q9ERë5}l+PË«)Äi°ŒsÑtW% e ²t™4–ê1ØGf6ïJtïŽV`×w–?õÒ;ßð©›7ß%Ñ=½æ4ÀlæÀlègÇÓгî~xµúù"t~ç‹?Ù|õ#úX€€Û¡sì˜T=Ñ2a£©Y0 ‘Ñ×ü^“2–5ɃÓ+qG¡AÀ“ 樢߽Û~ åÇ2qxQ‚¢òÑ€µ’_B;%à ãŦÛn¢(Ê}é†E@a|嬗6d?å|œaÚN§õnŸ+·¸ PU‚”1‘Èc%AÊÈÌiµ1Ùuû—ØE#š, JgžÂûŠOÛ6pwÐ¥L¢^`Ï?Ùä…R/uøÓ(”Úuj]G G×[[õö‹+%ü¤µ°I õ‰Æúæbùäõåæ;ŸÙÝý‹º»ÿª•óf/ðÌ €/ð˜ÝoÀ³«Õõ¬Vï~èÒ•­ûÞª¾ôa}V}¬àê@›9¹&í OÈ4áæ¿*Ž® €LÇÌÅ53Ÿ'N[ÀþF\î?0B8þ\¤:؇¯Qäz©Y|ÀÙº²ÍJC•4¯ƒÞÜ/äð#y­%ì_YØà?c.Õ0ÅÀ¹ŒG…@réU8£ƒ¤EÖ]µ-÷à‰†º ΋M¶eoL¼¦¸ˆ`p’ÚížÔ»HNÛ ;DQ”ƒ=êv»â±Å6‘ ›JM×õi0žê~ ÃÚ©wm/ ¦\½ —>H«6ÂåÅ 9Mé6Ü䧇ùüµ½½Ýo~éðð}’Îi×ÌÌ €×Ì®˜2­÷Ÿ|ßÁúo>réânZû×N6󱀿-Àä:IYHȤÎKºü¾W”%€#‘1VÓ6ž¸%Jª` ‡{Âcêˆø•ÛÎ$å'a;豑á´i0<íVµ\—î„#ÀS÷»Àpõb¦íœ LÆÇýGÂñƒ@¹ {`ˆ®´wwKµôõÁý3L9¤´+x¶*J‹=¦= '&)·½tCòÛëp/…3œJŒP¼– baRß{‰‚-²Ñ*<“öœû) È©†9XˆÞõwú?ûâ½{ߨËýûPÃ=z˜Kó¼6F`^¼6öÃÜŠ—¬WïY^|âÇΞyËËÍïBW˜s'v&k&`^ýîŒ œ»! Á€‰Z"cF›wÿ™¾ÙrcÛ€Q9áÎZÛD& C¢"+SM8,˜º%Žú`å½Á„Ùš<†ÿÆYåMÇeÜRa¯ Z§Æ×D"NÓì·`n?{Ë< vaš‡¶tû¸'à áN·ªÍŸ†Æ¶í-«÷¿Æ;ô!'y|KÉ3Œ·F6ªðì~}¥òcz×ÿ§>±·÷_}Òêy3ÀkpæÀkp§ÌMÚg×ë›\¯~òÜå ï9:sæ÷>~ròehFgÀÌ|Lê Û•ZÑAÙørÏê%†(( ‚!%PHÛÌr‰,%py€eàØ[? K% hBà"9й¤~‰‚S U‰¿©ˆ1ÀWHL R²¡lˉ…Û™oøA@ó$À6,ZN©›ïUSÖãßíïúÔ¢Û1pã§ )»}‘e¤Fy´®êï®[&âvMµìx5ŒÞ*#s[Vj¿ä£÷Ö¦m–k7?Õý Írq°\Ü»ºØüÕ§vw¿i}ûö|¹¾¹ôyðÝ1s³îý¶ÀSï?XýàC—/Ü<·³üš‹Ç›G¹ówò™ác㠾͙¥Ÿ>V=bâ ‰z'OæEÇß“<úÆÇ; q÷Õð^&g1e‘[ŠDZÚÆQ_yE/^¨H4] t{;Çf“t#¥tû£”Jí”/lìM8®I(:öƒ€VêÀIõ2Ün•ÆzJàRwàÇw¾ªGbdú`ÇÊÆ¤ÚÐ"ðé_qJxbÔ\‘ÄÆ°ßx 9|mcÜ}i9n”—N”xµçm ‹ ékg€áÅÝýúµ¾vmsò /ܸñw%šïî× Ìéµ?óൿæž­×ÿzqåÒ®Ï.ŸxôdñŸèŸŽ9I™äÉ›zÏ莄¿HG4LóÖ·×p¤mñSÞ;püUž.EmQ:dȄϋ7Ãýù;xShçzRDÏåóÂ)'™Ë…ÑÞßN€c‹4mJ¨µ'ÛbÚ~!Ç„äœªŠ•”¼kÁ ±DžÀe Þùèk€GÒðk€kɆÀg*,Ò¿öe1©z\©:P׋6‘º‹n¯7£Ü|…¥1ôWëÔ¶¢Ùâ›qªv©Þ‹„ðœò+¡ÇHþôT9ÍÊ ¾xtýªö¢(ëîþç^Üœü™§÷öþ¬~±ïÙSTsu×ÝÌ €×Ý.›ür#ð‰[·ÖZ¯~fçâ?ïìò÷ècßõ0“y]¯(mï Ÿ3>É€¼ó#¸%d1€nx‹¬~÷J½6ÄævÖ¾ƒ¢ëõN»AÜHȶlùh³ªÀ»O*zó™F)³¾Ü’ùg‘-/¡ \b#û¡¬î ²<˜‡‰Œ­%sð Z†$[f UsS$BJ™W ÁQÝJtß[ÞýñØYhÖ”K{Æ->³Å‚ið\… ¢ke·aªëv€t°#y°A²o5ðWËïáÞÝw\ßßO1ÏÙ<¯û˜¯û]8wàô<³^?óþõú‡ž¸rù¹{;‹ÿè½Íų,5'hÍñ¼+$ø‡˜ó1 .Ë?UÌ;Lê ppô±…"új¦jXW°sYýƒ÷‚ÀrÏHjr%¤ÄEd.“w_$ì@†žW_¹ †ÝTNï”k€$R>ÿ_9øH‹¤¡.|=f4L. í Cé«‚¶ºßÈ*Ð÷;ïˆÂC™ä1× æ‰Ú®‹&ø’S î‘uÚ# ç~ösö>ã]ùÔöü›ON¾å“7ö¾ÿÎ;·0™Ó<o”˜o”=9÷ã¾øðjÿýÇçÏýÐáÃçÏ_,¾þ±z܀ʢ«!Zæw„…CÕ1ºõ‰" 2L0P„!vs0K1A'ê¼³&¿Ú§‚œ¤© Çp˜ ƒ‘ÇBEct[W-E#_r®Fð ß‰Puÿº§Á¾ò,`d!“q!!¹;‡aRteTƒBmë¥ÊØ 8¼#Yäø‚°Ê–ÌH·¿‚™š¼iÚ‘rntubƒ‹^¸PÆ ~`EWF.ì/—/]Ýlþ¼.÷‡îîõœæx£À¼x£íѹ?[#ðÂíÛGúXàgÏ^zâžY~¹~dèw?ªû|©ÛQ"𭘂\Áƒ—ß=8(ºŽá0À³qpAä  L?' °Ó @ˆ@pSÌVFª¤]‘RËR qv›Ť+»¶ eÕZ¨üާ¿ˆ?‚=0ÊæJ#†¾K,…Â& â«Ì*ÃËE8#jfjÜ7)[—NÕ¢êÌÔ¶ÔªMlåhêÁxx$ìýåqîöcÛzŽÔák‹Í_¿~tôŸZ­~î9Í#ðFyðFݳs¿¶Fàéõú…_9XÿÇô±ÀÝ$xùdóÄ9‚®"ñxó.Ã"\0® è Wzdûd*Ó¤zÛ¸P:d†jSñm@| ÑXcÊo}‡ÿ‰”ÆM¸¹9€6µÂ Z OTßà9·ø-åþ ‚" #Û’5¹òn+®\–²Û Ù®Û€Âãf ë=z9V˜ñŽÜW+\FR Gz‘uò¾+¹¹â ÛÓûÌ2S&™?þ¹«+ z˜Ï/];9ùægoÜøßuwÿº}Ìù<oÔ˜oÔ=;÷ë# o ¼ÿÞ…Ç~äðì™ÇZÔ·„äëu&e5¼ÓäŽ9%Þ=4† ¨ZãK„Kè¶Ð¦RÛpùݦÐïJcëÊ/ò!XºµT¶ôPÑ^$~gÀåÒÑ0s(oZÚÁgÿ·ý-y0r­ 0p8‹Ûb|I›0;@gÜmý¼™GàM0óàM°“ç.nÀ§Öë[úXàÿ>ó–KÿdÿÌòw^8YüžGøX€è8Æ‚„ ¹^ ¤^¤¬RtÒü|UaP” H8ؘgã§ÉùójñXÄ:x§a¿íX@4_‚+v¸²ý´¢2U‹´É‚ ~y <lü€| PÂJ½꺿òØmu £iÿý- |!?>A‹ý<Û½¹”·Cð½ÙE´‘®ì•ÙGü÷¾ÈÂmÁ­±8má}Ćۺ rm³x×õã{ßðÉ7~&½™·ó¼yF`^¼yöõÜÓS#ðôþþóX¯~ôìÅ >9³üª '›ß懅‰Jd•wDµ¬ôÁ$`ÛS‚VQøn}Õ 6ðO]¾TÌ»fÈHÆ¥8l%ó;{)Qçf¾±çåwîe@HÈI©æY8ÖO,ë&À“| PJ>؇@ÍGûàqÝo뛩7ÕN娲øÅ¶¸ÃŒ%>$;¥ø„d0Ÿ¶Cªßtë›Íåè“äý™yÎ +Æ&Py!!„£–¬¥±ï0¦bq;ˆá£œT¯`DÂ;i?ë‚1S9%£>刧j¥y¸ÀoäI€{2ZKÞ‹ãµ™.`Â!£aâ "‚ïü)cÁ«zJƒ$ƒsLªOíÃyá¦åæ kØá²ï"åÝ¿ÛcûÜÓÀÝý/-6?²{tôG_œïî‡.½©G`^¼©wÿÜùÓ#ðôúæÕ®W?væò…*.ý¡K'‹Kçõ¹¤ï;êË€äÀ¤HÃd\pö%gŸ„Ùª G:ƒ½r8"‘ul”± Ü1ѱ ›ÂV6Øøj@s¢Ô‹ _,^8Á ŽÜäHü¥më&@ÉxðYô”¦ÇÀj­Ëé“Ì”(;3ÀAÙà”6 0ŸËÕ?—Ù¨ŽŸÁHe“Žý­¶j<Ô¾¤ï\e Èáõw(ì-c ?O6\èîþå‡_Úl¾ýù½½ÿi~v?ã2§y2ó`>æxÀèG†>xþчßùâ#oÎmN¾N7 žñoøðöZÉq*Å!Àôíà —±©˜å«”I½°È r-Î 9ãþD|¶–`Ž€ kª[Ħ!,¬G‡|H²àH€ÛЏ\ `À£€ñÁË©m”W¸WŽ·ª?Xnã¨ØÚ›Q![—¤ oÑÆ®–Ñ §xõ¢¢E’÷gü°ÒÇŒ‡Z¬Ë£kË“¿òÔîÞ·èÙý¿žy;À<=ó GbÎç85ÏÞºuG_ü¹ÅÅÇÿÁ­s;_¬ßøÊÇôm‚ oî+¼ƒ’ÊÄ¥HˆlzùÃ¥ë`§êùx†Ǹò0 £|•á–½TÈ‘aá _€dL%,`ÉTn Ü ÿdî‹@íÓvaª-¤á#àÚˆ©Ø6RÛNäÀŒ+Ù ¨‹“…ƒMÙ ×Ëß#¨†ù£éhÃÔx/l¸»qò®«zvÿ§nîÿ„Ôú0gNóÌ#pzæÀé™ëóœg×ë«X¯ÿþ#o¹ô^}uì«õmßþ°¾gvÌÛr¥lóîÓÁL‚–õå|ê¼N;Ë fQ¡P@uõ²ðÂ@bR_-ˆµ(‘]b£É¤NNflÑ熴²ãQÀ,îÔT|mkû¤AÕ,•ÂL—S¹rã- ÞÅŽä–Ê…6 FÊ€“ÐUmZœñPÉvÖJ Ê5üÞ™ÅõÅâW7ßþìͽï=¼sçšÐsšG`—yð23‹ç8=]­>úÞƒÕ^¸|I\~~rø›'ìu ÂÆï´%'Hù’´¢–—#[½3ŸóƒCüÙµíÄfBðTÐEf½²rè€^ö¾1P[‰Ï¨BcÎØ!Ì€_¼#Wø@w·½4¤RÓÅQ„ÈhÞ)£2ªûa<©–¾p…iœ!m'"ßLØõ¶qš«ÑQAó¹}}³ùžÝØýÖõÑílÎæ˜GàÓŒÀ¼ø4ƒ3«æxÀœüÆzõ‹ËËâ`gùÅ,_ý¸>ðÏñ*9(´ÊœÀ<¼­%"RBd5bÖÖé:"*§¢ÂXÝv<Ø„¥ä¿ø)sS7ÿÝ‘ÓC/–‹áÆ€M CÚm¥ õ{JC›íÇ&MuQ¤b»<­7&7ùÅ/h!ᨶ@ §ÚÊâç¶òk;ËŸ~ñÎÑ7¼°óÝa2§yæx#0/^Á ÍyNÀ'V«ë³ñšÑóV % õËï|%ó{l5¿Ó.%oöüxçÌÃ~:s÷>  ²ñnAñvu\e ‹>û÷Ùø[uScroá„´u•¥Ÿýß lâ~‘¶éÏpU½¯4ëâ~Û™M´,Xîèum¹ùÉk÷îý§Ÿ¼yã§džAÆÑœæ˜Gà3yðÙl0ÀƒGà™Õjÿ×Ö«xþò…uçÌò­/¾ìa…(‚v¿:xÂ@¸äåÀOìs õÒÀ²Ö“byCîˆgA‚eÚŠ·BÆ— âK8¦&<ŽB¦,WUòƒ€„åÇ€’~½8±#¥Á6í0ª|ð=·…€^4ÜôGrUEäü­@¦v`Ì'Ǫþý}­oo±xæúbó_>³·÷æg÷{pæÍ<ŸõÌ €Ïzg‚y¶G@zò}ë¿ùðåK7õþ×\8>y”;ý}‘®_Uì»ÿYôG ˆ C™Iڟ﫞`›¥¶ƒ\z","u•]°ðƒ€ds BCÈÐKÒ<–k¿0‘üÀ»,¢tn;ÚU2 ù}À‚&øA¸Gâ@P¼º\ü//ÓÕ7~©Íç|y>û˜ŸýÎ óº^ýëÅÃÿîÍGvžÐ·þà=—‹Ûò² ˆ/;8B2ÄOl*Ó ÁYφªœ{ªjʘ&ŒâPêøEOâ@ Ìs;´\;hH1DÓà& …èLUað«ì-†ÃryP:ÒÊI_âÿ™›'Çßøì?|ttt»Ñs>À<¯ÎÌ €Wgg–y8Ï®öõµÁŸ~èâ¥_¸ufñ»Û,~×#ý±€,¼ âUüK€M &p†½•¾aHˆòŠÙ’¡q'Klƒ×—YŽ”û&@•³@åVð¬äÏüãÔu0Ã×%Áçx¥ -èöRP2Æ¥ÑOÀ£–ïéÊÄþrçÃ׎7ßùÌÝ¿°::zÁðy3À<¯úÌ €W}HgÂyî§ÖûOÿÊÁú‡Î^¹üœâÿÛ.žl.žS´é›¨<Ì´» šUÑ&ìðCKg¦9ócj'÷n Œìµ*A`[ù[ [úù6Th¤O¦[x1xñû7ö½6S.Ÿâ"Ú†€!ðH0à‘Âk ÕÌÖë«IòS»0þÝr.~z4rÏŒ´A›$zOÖA`VÈ“$ŠB’¸”ñ-òPA¢Ö³ò(ñ²(Ç7õ¤Ë<å@@3µ` ‚@yJÐ+LLòˆe6BPkÖ¶¡ ëdÉ€@þA&SÜ»À= pæ3]̲£Såò;Kõú]mlOCÀXLX”m C` î$ÉìåZzr¸¿ÝÎå^,dnlDÙ»,@b÷„NÊÕY¶;ë„xÙi/ƒ(òuˆE[P%‚ ÷40cuDI+A&ì†ÀH¦å= /”޼l4 /"­}[t¾¿¾ßÎ|`Àîþç;ƒ÷*•ß|7‹ C`0`Á¶¡ µ€7Á‹ñ‘/jÃ;·¹èïà,Ë][¸09Ù–PArÕ”¦¥½À¸,—ýŒñc1åJQ ©:¦é¢ ÍSA.ÇåE œÍ«d•¥†~¤Ñ@IÞ/?hsy²¼ë%<ÑÄîþbä~(bwÿrù3ÛÝߘ% uFÀ€u܆3ÖBànš.aYàì@~ôlu(÷$N ìÝÑɼ=Ð0zz’î2³Ó™?“$d­c‚´ÿß¾½K\à1@½ ›ð0+g!$¨s°;ó^­@L š“sü°W1@¥î `?íc£aôÏ¢£¹¿ônÚhÌh­= C`£0`£·q 5¸•¦3¥é©áÉü•f.z.ï¢Ý<- ;îAÆ$hþzCï’@oOªyž¥^Iðú€Ù‹ÀeâˆK5¶ õÒÇñU®VrfOëå‹r€4ëå‡[3­!†ï~šûù‚¹ÿ÷Pc±!`l,¦l,þ6º!°&ð&xåb-ýxx×Ds(Âiަù^Lîè¡K&û"‡˜eœm£D‚ZÔèÏRÖˬžµHpæ_Gax.ÙéÙ£.Ñ£nel;êðOäQfPXÀ<ÛÓwÿbìÎÛíÃ0÷Ÿ0s¿bcOC`³ ` Àfùö†ÀjÜ$¹ò§«COŒeîùXŒ§5 Ó ó{VVs½ÎÌ»'PObUÀ·g®…_ØXA}¯@òWBû:8ågåSDðó¯9߯B«C5rSó0÷Ãw?ÍýÓèbÁ06¦l²b¯cÜÀt’,bÀéhbâr;Ž÷Cxl»2ºP.“¬Á½HwY^Ȉ%°\ºáÁ%^D€G¹@S=Mè}7Ô’üÑýØ„ä/ІÏS¦T"’Ýý.û T*š«×ÿ 2,6 ͇€)›ï›Øk"p+­^--%Ÿ6'ò­Î@üR¾ã†Á¾Á‰;‘Œeæïuµ: ªV €ºn †¡xf!roO‹GÍÜïá²ÈèLèƒd¯hÜÀlµZÄ%Cg:“ù ˜¹ïŲÀž`}’½’8™~¥Ë™ Ë4õó:àp#`ŠºÈ<(á.‚ Ðì/J¤PŽóG)Rs‘ûh®Õ:¼P©üº2š¥ C 0 ¾’½£!ð?ÜN’©KµäĶÉüb»òY4Ê[õdÖB'mÓÐ]P-¥ôÁ¯vz* {HòÒ±Z8áDz͢:ÒEçÎ-´ã×gÊÅãÍf †€!Ðo˜Ðo_ÌÞ×Xxü£>:r²24¸}(ƒ7A*r^í©„Ù=çðt ,N€Àò\ {Hò${ndšAæþÈ´QŽ;nÜ˲·n–JïÕ˶»_!²§!З˜ЗŸÍ^ÚXÀ½Z­v-M¾ß6^8[pO Çnï(™Ä͵zDJêL O •õ ›Iú²Î8¨´¤Ø"°àܱëÅâI½~Qªía}€)}ýùìå Õà´À .ú2ÛU¸Úß7êÜ$®ÖeQЇ "¹›AðÑ2ë`%?ý§mÄÿõ\«yp¶R9l? †€!°0` |Dû µ¸]­^ní<žv°iï¼  €Øe†®¯£Ò—x†ŸA.íA\Œ¢¿ÛÙ›7ËÅ÷—›Í©´‡!`lLØ2ŸÒþC`5sµZëZ’œpl°:˜‡[áý;àMûhú¯sºñ@?l$Œ’(^šÜ±k‹ GªåK«¥Z‰!`lLØ _ÑþCàLóØ`’|3°«p¾–‹wã?þ³¬#Vº®ärøEJ”û¤7ŽÜš/H3÷?W«6úµùõó_`ïnÀ+{ö¼wÜ«({¼ãâvš¹©r®ñíõÙÅ«-Ì:†€!`†€!`†@ ð/ÚÆ~êÕ›PIEND®B`‚leocad-23.03/resources/leocad.ico000066400000000000000000002172611440571307300167220ustar00rootroot00000000000000 è¶(ž00¨Æ ¨nÈhÞ"00 ¨%F(  ¨îM ˆ –^ hh +²†l( @€€€€€€€€€ÀÀÀ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ ™™ ™™™™™ ™™™ ™™™™ ™™™™™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™™ ™™™™™ ™™™™™ ™™™™™ ™™™™ ™™™™ ™™™ ™™ ™™™ ™™ ™™™™ ™™ ™™™™™ ™ ™™ ™™ ™ ™™™™™™™ ™™™™™™™™ ™™™™ ™™™™™™™™™™™™™™ÿþÿÿðÿÿÀÿþ?ðÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀðüÿÿ€ÿÿÀÿÿðÿ( À€€€€€€€€ÀÀÀ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ ™ ™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™ ™™™ ™ ™™ ™™™™þÿø?à€€€€€€€€€€àøü?(0`€ ™UTSR»¹¬¨§¤›™‰`J¹®··²°®¬ª¢ž–’‘Ž‹‡…}{yvusqomkhfec^][XVSQNMI¼µ¯¡”³UÿÿÿFFFFFFFFFFFFFFFFFFFFFFFB*FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC*9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACC*DDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC#DDDD9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC>>>#DDDDDD9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC>>>>>BD*DDDDD9FFFFFFFFFFFFFFFFFFFFFFFFFFFFAC>>>>>>B***DDDDDD9FFFFFFFFFFFFFFFFFFFFFFFFA>>>>>>>>>B****DDDDDD99FFFFFFFFFFFFFFFFFFFFF>>>>>>>>>>B******DDDDDD9FFFFFFFFFFFFFFFFFFAC>>>>>>>>>>>>B*******DDDDDDD9FFFFFFFFFFFFFFFC>>>>>>>>>>>>>>B*********DDDDDDDFFFFFFFFFFFFFC>>>>>>>>>>>>>>>>>B***********DDDDDDFFFFFFFFFFFF>>>>>>>>>>>>>>>>>B*'***********DDDDFFFFFFFFFFFF>>>>>>>>>>>>>>>>>>B*'***************FFFFFFFFFFFF>>>>>>>>>>>>>>>>>>B*'***************FFFFFFFFFFFF>>>>>>>>>>>>>>>>>>B*'***************FFFFFFFFFFFF>>>>>>>>>>>>>>>>>>A*&***************FFFFFFFFFFF>>>>>>>>>>>>>>>>>>>A*#***'*'********'*FFFFFFFFFF>>>>>>>>>>>>>>>>>>>A*#**'''''*******#*FFFFFFFFFF>>>>>>>>>>>>>>>>>>>A*#'*''''''******#*FFFFFFFFFF>>>>>>>>>>>>>>>>>>>A*#'''''''''*****#*FFFFFFFFFF>>>>>>>>>>>>>>>>>>>A*#'&&'''''''***'#*FFFFFFFFFF>>>>>>>>>>>>>>>>>>>A*#''''**''''**''#'FFFFFFFFFF>>>>>>>>>>>>>>>>>>>A*#'''''''''''*''#'FFFFFFFFFF>>>>>>>>>>>>>>>>>>>A*#''**'''&&&*'&'##FFFFFFFFFF>>>>>>>>>>>>>>>>>>>B*&''***'&&&&&'&'#&FFFFFFFFFF>>>>>>>>>>>>>>>>>>>B*&*'**''&&&&&'&'#&FFFFFFFFFF>>>>>>>>>>>>>>>>>>>B*'***''''&&&&'&'#'FFFFFFFFFF>>>>>>>>>>>>>>>>>>>B*'***'&&&&&'''&&##FFFFFFFFFF>>>>>>>>>>>>>>>>>>>B*****'&&&'''''&#'#FFFFFFFFFF>>>>>>>>>>>>>>>>>>>B****''''&&'*'''###FFFFFFFFFF>>>>>>>>>>>>>>>>>>#********'''*'*&''#FFFFFFFFF>>>>>>>>>>>>>>>>>CB*'********'''*'*''##&FFFFFFFF>>>>>>>>>>>>>>>A#**'*********'''***&&'##FFFFFFFF>>>>>>>>>>>>CB***'*************'****&'##FFFFFFFF>>>>>>>>>>CA&*&&*****//////*B#******'*#&FFFFFFFF>>>>>>>CABAA#'*/16662*AAB#****'*#'FFFFFFFF>>>>>CAAAAAA*D**1DD9====DBAAAAB&***#*FFFFFFFF>>AAAA AAB/*BBBB#*/D====*BBAAAAA#***FFFFFFFFCCCCCCC AAB%BACCCABB%*1D9==D*#BAAAAC A&FFFFFFFFFFCCCCCCC AAA@CCABB#*DD9=D*#BAACAACFFFFFFFFFFFFFFFCCCCCCC@C>>CABB**DD=*#AAAAAFFFFFFFFFFFFFFFFFFFFFFCCC>CCAAABBB#*DDD#AAAFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAA CCCC AA#*BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACCCCCCCCCCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCCCCCCCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCCCCCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCCCFFFFFFFFFFFFFFFFFFFFÿÿþÿÿÿÿüÿÿÿÿðÿÿÿÿÀÿÿÿÿ€ÿÿÿþÿÿøÿÿàÿÿÀÿÿÿþü?ü?ü?ü?ü?ü?øøøøøøøøøøøøøøøððððððððü?ÿ€ÿÿøÿÿþÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿðÿÿ( @€º·¶³²­«©¨¦¥£¢¡ Ÿžœš™˜—–•”“’‘ދЉˆ‡€utsronmlkihed]\[XWVUTSRQº¹¸··µ³²²¬««ª©©¨¨§§¦¥¤¤££¢¢¡¡  ŸŸžžœœ››šš™™˜˜——––••””““’’‘‘ŽŽŒ‰‡„„ƒ‚€~|zyxwwutsrrqqpponnmlkjjiihggfeedccb`_^]\[ZZYXXWWVVUUTTSSRRQQ»¸¸¶²°¬ª©¨¦¥¤£¢¡ Ÿžœ›š™˜—–”“‘ŒŠ…~wZYVUTSRÿÿÿöööööööööööööööÝ2öööööööööööööööööööööööööööööÑÌíôôöööööööööööööööööööööööööÓÌÌÊí¯¯ôööööööööööööööööööööööÓÌÊÊÊÊí¯¯¯ïôöööööööööööööööööö×ÎÊÊÊÊÊÊí§/¯¯¯ôôöööööööööööööööÑÊÊÊÊÊÊÊÊí.í¦©¯¯¯ôööööööööööööÓÌÊÊÊÊÊÊÊÊÊíííí¤¤¯¯¯ïôöööööööööÎÊÊÊÊÊÊÊÊÊÊÊíííííí¤¦­¯¯ôööööööööÊÊÊÊÊÊÊÊÊÊÊÊííííííí¡¡¬2¯ööööööööÊÊÊÊÊÊÊÊÊÊÊÊííííííííí¡¡¡ööööööööÊÊÊÊÊÊÊÊÊÊÊÊííííííííííííööööööööÊÊÊÊÊÊÊÊÊÊÊÊííííííííííííööööööööÊÊÊÊÊÊÊÊÊÊÊÊííííííííííííööööööööÊÊÊÊÊÊÊÊÊÊÊÊííííííííííííöööööööÊÊÊÊÊÊÊÊÊÊÊÊÊíííííííííííííööööööÊÊÊÊÊÊÊÊÊÊÊÊÊíííííííííííííööööööÊÊÊÊÊÊÊÊÊÊÊÊÊíííííííííííííööööööÊÊÊÊÊÊÊÊÊÊÊÊÊíííííííííííííööööööÊÊÊÊÊÊÊÊÊÊÊÊÊíííííííííííííööööööÊÊÊÊÊÊÊÊÊÊÊÊÊíííííííííííííööööööÊÊÊÊÊÊÊÊÊÊÊÊÊíííííííííííííööööööÊÊÊÊÊÊÊÊÊÊÊÌãíííííííííííííööööööÊÊÊÊÊÊÊÊÊÎëíííííííííííííííööööööÊÊÊÊÊÊÌ×ííííퟟŸŸŸííííííííööööööÊÊÊÊÌíí퓟¯¯¯¯ïïï¯ííííííííööööööÊÌÑííííí¯íííퟯÉÉÉ©íííííííööööööÑííÎíííí{ÎÌÎÝíí¬óÉôíííííííöööööööööííÌÌÔÌÌÊÌÑáëí¯ô¯ííííöööööööööööööööíÌÌÎÎíííííí¯ííöööööööööööööööööööÌíííííííííííöööööööööööööööööööööíÌÌííííÌÌÌöööööööööööööööööööööööííííííííööööööööööööÿþÿÿüÿÿðÿÿÀÿÿÿþøðððððððàààààààààààààü?ÿ€ÿÿÀÿÿàÿÿðÿ(0 ºª¨§¦£¡ Ÿž›™˜—–•”“Šƒ€~yusqomlihfecZYXWVUTSR¸¶µ´±±°¬ª©¨§¦¥¤£¢¢¡  Ÿžžœ››šš™™˜˜—––••””““’’‘‘Œˆ‡…„ƒ}{zywutqmkjhggfdba`^\[YYXWWVVUUTTSSRRQ¸´¯©¨¦¥¤£¢Ÿžš™˜—–”“’‘‡„oljgdcWVURÿÿÿ´´´´´´´´´´´¦ª´´´´´´´´´´´´´´´´´´´´´4¨²²´´´´´´´´´´´´´´´´´‘¨¯¯²´´´´´´´´´´´´´´’¦­«®¯²´´´´´´´´´´”4¦«©¬®¯²´´´´´´´´¦ª©©ª¬­¯²´´´´´´¦©¨©©©ª«¯´´´´´´¦©¨©¨©©©ª´´´´´´¦©¨¨¨¨©©©´´´´´´¦©¨¨¨¨¨©¨´´´´´´¦©¨¨¨¨¨¨¨´´´´´´¦©¨¨¨¨¨¨§´´´´´¦©¨¨¨¨¨¨§¨´´´´¦©¨¨¨¨¨¨§¨´´´´¦©¨¨¨¨¨¨§¨´´´´§©¨¨¨¨¨¨§¨´´´´’§¨©©©©¨¨¨§¨´´´´¦o««©ªª©¨©©©§¨´´´´¦¦¦«®«®¯°Ž®¦¦¦©©¨´´´´¦¦¦¦¦¨¦¦¦¨­²Ž©¦¦¦¦¨´´´´´´¦¦¦¦‘‘¡¨¯²©¦¦¦´´´´´´´´´´´¦¦¦¦¦¦¦©¦´´´´´´´´´´´´´´´¦¦¦¦¦¦¦¦´´´´´´´´´´´´´´´´´¦¦¦¦¦¦´´´´´´´´´ÿçÿÿÁÿÿÿü?ðàààààààÀÀÀÀÀÀÀÀðþÿÿÿÿ( @µ¥£¢¡Ÿœš™—•”’‘Ž|njeb_]VTSR´²¯ª§¤£¡  ŸŸœœ›š™˜—–••””“’‘ŽŒŠ‰…‚~~}zwvsqmkihggffdda`_\ZWVVUUTTSRR¢Ÿ›—•”‹‰…nc\Xÿÿÿppppppplpppppppppppppnnpppppppppllnppppppllllnppppllllpppplllppppppppgpppppppppppppppgkkppcll`lpppaajWnlcapppppppapppppppppppppppppþüðÀÀÀÀÀÀÀÀ€€Àøü?(0` €%f‡ ˜£i´03@ÿ˜w¤ï""¸ÿ xÿGùL‰ U•M¤Ð""·ÿ "¼ÿ !¹ùzùTÿ\ÿKÝGZf'¡¨!°ÿ !½ÿ¼û!Âû!$Ãÿ€ÿYü^úYÿSÿI³ =.@9 }¨ó!"Àÿ!»ÿ Âú!Åþ!$Ëÿ "Ìþ…þ^ÿdþ\ûYýZÿMøG… UU›R¤Õ !»ÿ !¾ÿ Âù!Æý!#Éÿ #Îþ "Ôþ #Òþˆþbþjþeÿ]þZùZÿXÿIÙAVf’*£® ³ÿ !¿ÿ¿ûÃü #Éÿ!Ïþ "Ñþ "Õþ$%×ÿ!$×þŒþgÿnþgþcþbÿ]üYûYÿQÿI¯ 7*@U Ÿ‚©õ!"Âÿ¾þ Åú Èþ!#Ìÿ "Ñþ"$Ôÿ #×þ$$Ùÿ%&Üÿ%'Úÿ Žÿgþtÿlþkÿeþdÿ_þ[ûVþXÿJõB€ ÿUœU¨Ø !½ÿ !¾ÿÃù Éý!#Ìÿ "Ñþ"Õþ #Öþ!#Úþ!$Üþ##Þþ$&ßÿ#&Þþþjÿsþnþlþiþgþdþcÿ^ýZùXÿTÿHÕ AOÿŽ+£± "´ÿ!"Âÿ!Áû!Åü!#Ëÿ"Ðþ"Õþ"$Öÿ!#Úþ$%Úÿ%%Þÿ$&ßÿ$(àÿ%)ãÿ&*ßÿ !‘ÿkÿ wÿ rÿqÿoÿkþjÿeþbþbÿ]üWûXÿPÿG©3#ÿ"&¢y ¬ù"$Âÿ!Àþ"Çú!Ëþ"$Ïÿ "Õþ #×þ$$Úÿ!#Üþ%%Þÿ!%àþ$'áÿ#&äþ%)äÿ&*çÿ(+ãÿ !“ÿlÿ xÿsþ sÿoþpÿlþlÿgþeþdÿ]þ\úXÿXÿKóHnU07¬%')·ÿ%&Çÿ!#Å÷!#Ëþ #Ðþ!#Õþ!#×þ!$Ûþ%&Üÿ!#ßþ$&ßÿ!%ãþ%(ãÿ%)äÿ&)åÿ&*åÿ(+éÿ),äÿ "”ÿ mÿ!!zÿ wÿ vÿ uÿpþqÿmþmÿiþgþeþ cÿ`ý]÷!]ÿTÿ""L%€49½6')Äú!%Êþ!%Ïþ!%Ôþ#%×þ#%Úþ!%Þþ!%ßþ!%áþ%'áÿ#&äþ%)äÿ&)åÿ&*çÿ&*èÿ(+èÿ(,êÿ)-çÿ #•ÿ nÿ! {ÿ!xÿ!xÿ wÿ uÿqþ rÿnþ!oÿlþ lÿgþdþbþ`þ\û[8™58ËD*+Ðÿ$(Òÿ#&Öý%(Úÿ!%Þþ%(ßÿ%(àÿ%)ãÿ%)äÿ%)äÿ&)åÿ&*çÿ&*èÿ(+éÿ(+éÿ(,éÿ),ìÿ+-éÿ #–ÿ!nÿ! |ÿ!!yÿ!!yÿ!!xÿ!!wÿ!!vÿ!vÿ!sÿpþ!qÿmþkþ kÿiý hÿ!"fÿ!!_F3™17ÑT),Ûÿ#&×þ#&Ûþ#(ßþ%)ßÿ#(äþ%)äÿ$'åþ&)åÿ&*çÿ&*èÿ(*éÿ(+éÿ(,êÿ(,êÿ),êÿ+-íÿ,-éÿ""—ÿ!oÿ!"|ÿ!!yÿ!!yÿ!!yÿ!!xÿ!!xÿ!!xÿ!!wÿ!!uÿqþ!!rÿnþ!nÿjþiþ"#nÿ!!eV3™36Öd+.äÿ#&Üý#(ßþ#'áþ#(äþ%)äÿ&)åÿ&*çÿ&*çÿ(*éÿ(+éÿ(+éÿ(,êÿ(,ìÿ),ìÿ)-ìÿ,.îÿ,/éÿ"#˜ÿ!oÿ""|ÿ!!yÿ!!zÿ!!yÿ!!yÿ!!yÿ!!yÿ!"xÿ!"wÿ!"vÿ!"uÿpþoþmþoý"$sÿ##if3™29Úu)-êÿ#'àü#'ãþ#'äþ&)åÿ&)åÿ&*çÿ&*èÿ(*éÿ(+éÿ(*êÿ(,êÿ(,ìÿ)+íÿ+-íÿ+-íÿ,/îÿ-0êÿ"#™ÿ!oÿ""}ÿ""zÿ""zÿ""zÿ""zÿ""zÿ""zÿ""yÿ""xÿ""wÿ!"vÿ!"uÿ qþ pþ oü#%yÿ%%pv3ÿ44Þ…)-ðÿ$(äû$(åþ$(çþ$(èþ&*èÿ&*éÿ(*éÿ&*êÿ&*êÿ(,êÿ),ìÿ)-íÿ+,îÿ+.îÿ,.íÿ,/îÿ-1êÿ##™ÿ!pÿ!#~ÿ""zÿ""zÿ""zÿ"#{ÿ""zÿ"#{ÿ""zÿ""zÿ""yÿ""xÿ uþ tþ !rþ!sû%%|ÿ$$p†@ÿ23â•),ôÿ$(çû$(çþ$(éþ$(éþ(*éÿ(*éÿ&*êÿ&*êÿ(*êÿ(,êÿ),ìÿ+-íÿ+,îÿ,-îÿ,.îÿ-/îÿ/1êÿ##šÿ!qÿ!#~ÿ""zÿ""zÿ"#{ÿ"#{ÿ"#{ÿ"#{ÿ"#{ÿ""zÿ""zÿ""yÿ vþ vþ uþ!!vû%'~ÿ$$r–ÿ03ã¤)-õÿ%(èû$(éþ$(éþ(*éÿ(*éÿ&*êÿ&+ìÿ&+ìÿ(,ìÿ(,ìÿ),ìÿ+-íÿ+,îÿ,-îÿ,/îÿ-0îÿ.2ìÿ#$šÿ!qÿ!#~ÿ"#{ÿ""zÿ"#{ÿ"#|ÿ"#{ÿ"#{ÿ"#{ÿ"#{ÿ""zÿ""zÿ wþ wþ wþ!!xû%&€ÿ"%u¥ÿ,2å³)-öÿ%(éû$(éþ$(éþ"(êþ(*êÿ&*êÿ&+ìÿ(+íÿ(+íÿ(,ìÿ)+íÿ+-íÿ+,îÿ,-îÿ,/îÿ-0îÿ02ìÿ#$šÿ!qÿ!#~ÿ"#|ÿ"#|ÿ"#|ÿ"#|ÿ"#{ÿ"#|ÿ"#|ÿ"#|ÿ"#{ÿ""zÿ !xþ !xþ !xþ!!zû%&ÿ%%w´ÿ,1èÀ(+öÿ%(éû(*éÿ%(êþ%(êþ&*êÿ&+ìÿ&+ìÿ(+íÿ(+íÿ)+íÿ)-íÿ+,îÿ+.îÿ,.îÿ,/íÿ-0îÿ02ìÿ#$šÿ!rÿ"#ÿ"#|ÿ"#}ÿ"#}ÿ"#|ÿ"#{ÿ"#{ÿ"#|ÿ"#|ÿ"#|ÿ"${ÿ !xþ !xþ !yþ!"{û%%‚ÿ%%yÂÿÿ@@ÿ,/ëÍ(+öÿ#)êû$(ìþ(*êÿ$(ìþ&*êÿ&+ìÿ(+íÿ(+íÿ(+íÿ),ìÿ)-íÿ+,îÿ,-îÿ,.îÿ,/íÿ-0îÿ03ìÿ#$šÿ!rÿ!#ÿ"#|ÿ"#|ÿ"#|ÿ"#{ÿ""zÿ""zÿ"#{ÿ"#|ÿ"$|ÿ"$|ÿ !xþ"$zÿ#${ÿ!"{û%%‚ÿ%&|Î33fU;NØ -0ëÙ(*ôÿ#)ìû%*êÿ$(ìþ$(ìþ&+ìÿ&+ìÿ(+íÿ(+íÿ(,ìÿ)+íÿ)-íÿ+,îÿ,.îÿ,.íÿ,/íÿ-1îÿ13êÿ#$šÿ rÿ!#ÿ"#|ÿ"#|ÿ"#{ÿ"#{ÿ"#{ÿ"#{ÿ"#|ÿ"$|ÿ"$|ÿ#$|ÿ#$|ÿ!!yþ#$|ÿ!#|û%$ÿ%'|Ú;;‰ ÿNNÞ,.ëä&*òÿ#)íû"(ìþ%*êÿ$(ìþ&+ìÿ&+íÿ(+íÿ(+íÿ(+íÿ)+íÿ)-íÿ+-íÿ+-íÿ,.íÿ,/íÿ-1îÿ13êÿ#$™ÿqÿ""~ÿ""{ÿ"#{ÿ""zÿ""zÿ"#{ÿ"#{ÿ"$|ÿ"$}ÿ#$}ÿ#$}ÿ!"zþ!"{þ#$}ÿ"#|û%$ÿ&'~å77zU€KKé"+-ëî&)òÿ"'ìü%*êÿ"(ìþ(*êÿ&+ìÿ&+ìÿ(+ìÿ(,ìÿ(,ìÿ)+íÿ)+íÿ+-íÿ+-ìÿ,.ìÿ,/ìÿ-1îÿ13êÿ#$˜ÿ!oÿ""}ÿ!"{ÿ"#{ÿ""zÿ""zÿ""zÿ"#|ÿ"$}ÿ#$}ÿ#$}ÿ#$}ÿ#$}ÿ!"{þ#$}ÿ!"{ü##€ÿ$$}ï,,u#@ÿCCé.(+è÷%*ðÿ"'ìü%*êÿ"(êþ"(ìþ&*ìÿ&+ìÿ&+ìÿ(*êÿ(,ìÿ(,ìÿ),ìÿ+-ìÿ+-ìÿ,.ìÿ,/ìÿ.1îÿ14êÿ#$˜ÿ nÿ""}ÿ!!zÿ"#{ÿ""zÿ""zÿ"#{ÿ"$|ÿ"$}ÿ#$}ÿ#$}ÿ#$}ÿ#$}ÿ!"{þ#$}ÿ!"{ü##ÿ$$}÷61w/@ÿA=å;(,êþ%)îÿ"'êü&)éÿ$(éþ&*éÿ%*êÿ(*êÿ&*êÿ&*êÿ(,êÿ(,êÿ),êÿ)-êÿ+-êÿ,.ìÿ,/ìÿ-1íÿ15éÿ#$—ÿnÿ""|ÿ!!zÿ""zÿ""zÿ"#{ÿ"#|ÿ"#|ÿ"$|ÿ"$}ÿ#$}ÿ#$}ÿ#$}ÿ!"{þ#$}ÿ!"{ü##ÿ$$|þ33{<3™<<êH+.îÿ#)ìÿ$'éý&(èÿ$'éþ"'êþ%*êÿ&*éÿ(*éÿ(+éÿ(,éÿ(,êÿ),êÿ)-êÿ+-êÿ,.ìÿ,/êÿ-0íÿ15éÿ#$–ÿlÿ!"{ÿ!!zÿ!!zÿ""zÿ"#{ÿ"#}ÿ"#}ÿ"#}ÿ"$}ÿ"$}ÿ#$|ÿ"$|ÿ!"{þ#$}ÿ!"}ý##~ÿ&(ÿ14~I3ÿ8;èW+-òÿ%(éÿ#'éý%)çÿ#'èþ&(éÿ&)éÿ&*éÿ&*éÿ(+éÿ(+éÿ(,éÿ),éÿ)-éÿ+-êÿ,.êÿ,-éÿ-0éÿ13çÿ#$–ÿkÿ!!zÿ!!yÿ!!zÿ""zÿ"#|ÿ"#}ÿ"#}ÿ"#}ÿ"$|ÿ"$|ÿ#${ÿ#$|ÿ!"{þ#$}ÿ!!~ý!!|þ((ƒÿ..}X@ÿ8:èe)-õÿ!&èý#'åþ#'èþ#'éþ$'éþ&(éÿ&*èÿ&*èÿ(+éÿ(+éÿ(+èÿ(+èÿ),éÿ)-éÿ+-èÿ+.åÿ-1éÿ15éÿ"$”ÿ jÿ!!zÿ!!xÿ!!yÿ"#{ÿ"#{ÿ"#{ÿ"#|ÿ"#}ÿ"#}ÿ"${ÿ"$zÿ#$|ÿ!"{þ!"{þ!!~ý!!~ý('…ÿ02}f@ÿ57çt)+öÿ!%çü#%åþ%)çÿ%)çÿ$'èþ&)çÿ&*çÿ&*çÿ&*èÿ(+èÿ(+çÿ),çÿ),çÿ)-èÿ,-éÿ,/éÿ+.Þÿ*+Ãÿ"‚ÿjÿ!!sÿ""uÿ!"xÿ!!zÿ""zÿ""yÿ""zÿ"#|ÿ"#|ÿ"#{ÿ"$zÿ"${ÿ!"zþ#$}ÿ!!|þ "|ü((…ÿ00uUU58êƒ)+öÿ"&çû#%åþ#&çþ#'çþ%)åÿ&)çÿ&*çÿ&*çÿ&*åÿ&*äÿ(*åÿ(+èÿ)-éÿ+,äÿ%(Ôÿ"´ÿÿyÿ|ÿyÿrÿoÿ!rÿ"!xÿ"!yÿ""yÿ""zÿ"#{ÿ"#|ÿ"#{ÿ"$zÿ"${ÿ!"zþ!"{þ!"{þ!#~û&'…ÿ,,}…ÿ13ç’)+öÿ$&çú#&çþ%'åÿ#'çþ#'çþ%)åÿ%)äÿ&*äÿ(+äÿ(+éÿ(+éÿ%)ßÿ $Çÿ¤ÿ ƒÿ uÿwÿ{ÿ zÿzÿ yÿ uÿqÿqÿ uÿ!"wÿ"$zÿ#%{ÿ"#{ÿ"#{ÿ"$zÿ"$zÿ !yþ#$}ÿ#$}ÿ!#|ú&'…ÿ+/“ÿÿ34æ¡(*õÿ$&äú%(äÿ#%åþ%(äÿ%)äÿ&)äÿ(*äÿ&)çÿ!$ãÿ #Õÿ"$¹ÿ”ÿyÿtÿ zÿ {ÿyÿvÿtÿrÿpÿpÿpÿoÿoÿuÿrÿtÿ""yÿ#%{ÿ#$zÿ"$yÿ""zÿ "zþ#$}ÿ!#{ú&'…ÿ,,~¢ÿÿ/2ã¯&*òÿ$&ãú%(äÿ#&ãþ$'äþ$'åþ #åþ!Ûÿ"Æÿ./¬ÿ89•ÿ }ÿ wÿ}ÿ }ÿxÿtÿpÿnÿmÿlÿkÿjÿjÿkÿ kÿ!xÿ99ˆÿ./ÿsÿrÿ uÿ!!uþ"#xþ!!xþ"${ÿ!"zú%&…ÿ--}°ÿÿ/0á¾%(ðÿ$(ßú&)ãÿ#%äþ!àÿÔÿ$&»ÿ25¢þAB“þNN—ÿEF˜þ„ÿ |ÿtÿ kÿ fÿ cÿ `ÿ ^ÿ \ÿ \ÿ \ÿ ]ÿ ^ÿ bÿ eÿoÿCD•þOOœÿAB“þ23…þ!#vþoÿoþ !uþ%&{ÿ"#zú%&‚ÿ,+{¾ÿ@@€-/ãÇ%)îÿ!#âúÚÿÈþ+-±þ<>œþHJ˜þPQœÿPR¢ÿOP¤þFE˜ÿwÿ bþ aÿdÿhÿjÿgÿbÿ ]ÿ XÿQÿIÿCÿCÿGþ[ÿEF‡ÿPP˜þPQšÿPRžÿKL›ÿ<=þ+,}þqÿpÿ!!vú%&€ÿ+-zÈ@@€U;NÄ (*Þà ßÿ##¼ö68¥ûFG™ýPRžÿRS¥ÿPQ§þNO¦þNP¤þRT£ÿEDþdþ jÿzþ Šÿ"#“þ"$‘ÿˆÿÿ uÿ kÿ bÿTþJÿ?þ6ÿ4þBDnþSTˆÿNOþOO–þPRþRT¡ÿPR ÿFG–ý67…û !töxÿ'(wß;;‰ @@ÿ99¸¸IK¬ÿVW¨ÿYZ®ÿTU«ÿQSªúQSªúQS¦ýQR§þPQ¥þST£þEEŒþ~ÿ ’þ¢ÿ.1²ÿ7:¸ÿ34³ÿ&'¤ÿ”ÿ‡ÿ~ÿtÿfÿZÿ NÿAþ6þED\þTTzþQR…þRRŽþQS”ýQT™úRUŸùTV£ÿXY«ÿTV§ÿHJ˜ÿ55}À33M ÿqq nr±Add±Š\]®ÐZ\®ÿ^_¸ÿZ[µÿWW­ÿST«ûRS§ûXX¥üFH™þ žþ¬þ%(¹þ8:Ãÿ>BÉþ=?Ãÿ/1µÿ""¥ÿ™ÿ ÿ!…ÿqþ! eÿYþ Jþ BþEE_þXXxüTT‚ûRSŒûVV”ÿZZ¢ÿ\^«ÿ[[¤ÿZZ¤×``©”ii±Kffª’’¶lh±;cc³ƒ^a±Ë[]°ü_`»ÿ[\·ÿ[]¯ÿEE¨þ­þ »þ)+Çþ8;Ðÿ=@Ôþ68Êþ')¸ÿ¨ÿÿ“ÿ‰þwþiÿ`þYþJþDDhþZ\„ÿ\]‘ÿ__›ÿYZ™þ\\Ð^`¡Šdh¦Bjjª 33fÿÿÿosÀ5ff¸}bdµÅ`a³øXY½ÿ&)ÂýÀþ!¼þ,.¶ÿ/3®þ35¢ÿ46šÿ67–ÿ46“ÿ24Žÿ-/‰ÿ"&~þrÿbþWþ!"YýVV‚ÿ^`ù_`–Çcešjj£:€€ªÿ33fUÿUUy€³(qsέ<>Åÿ/1¡üHIÿNPžþRU¢þVW¤þXX§þYY¨þXY©þXX©þWW¨þUU¦þOQ¢þHK˜ÿ13‚ü78uÿhhбyyª*ÿÿÿUÿÿÿÿ@@€33fquÈx[\¸ÿ[[¤ô^`­ý\^°þ]`°ÿ]_¯ÿ\^®ÿ\^®ÿ\^®ÿ\^­ÿ\^®ÿ]_®ÿ\^®þ^`­ý[\­ôY\¯ÿecš~f@@€ÿÿÿ33f||¿Hjj¸ÿee½ÿ^`°ÿ[]¯û]^¯ù]_®ú^_®ú^_®ú^_®ú^_®ú]_­ú]^®ù]_®ú]`¯ÿce¼ÿij»ÿuuµL33fwzÂKlk¹Éee·þklÁÿjkÁÿhi¾ÿgg¼ÿff»ÿff»ÿfg¼ÿhi½ÿij¿ÿkl¿ÿde¶þii¸Ìqt¸Oÿÿÿ}}Ç7tt¼nnn»™llº¶llºÇlm»ÎjlµÏll·Çll¹¶mm¸šssºoyyÀ9ÿÿÿÿÿÌ3ÿÿÿÿ ÿÿÿþ`ÿÿù€ŸÿÿöoÿÿÌ3ÿÿ0 ÿþÀù€Ÿöoè7èèèèèèèèèØØÐ Ð Ð Ð Ð Ð Ð Ð Ð Ð Ð ° ° °    Ð þñÀþ<?ÿÂcÿÿú_ÿÿÿÿÿÿþ€ÿÿ( @ €€€®e» '€ž{ªù!#ÀÿuÿMÿL†f™K¨Ú!"Âÿ "Âÿ"Æúzû[ÿ^ÿMàDR€‡"§° "¼ÿ!"Åÿ"Èù#Ïý"$Ïÿ ÿaþcù^ÿYÿIµ2$U£€®ü!"Æÿ!Åû!Ìü"$Ñÿ #×þ$&×ÿ†þhþkÿcü]û]ÿNýF€œP«Þ!"Åÿ "Åÿ!Ìú"$Ðÿ "Öþ!#Úþ%%Þÿ%(Üÿ ‡ÿlÿoþiþgÿbú]ÿZÿJÜ@LÿŽ$!§´""¿ÿ!#Çÿ "Ìù "Ñþ"$Õÿ!#Úþ$&Üÿ!%àþ%(ãÿ&*áÿ ‰ÿoÿ uÿpÿkþiÿcþ`ù]ÿVÿH®<ÿ-–'$´î%&Îÿ!#Ëú "Ðü$%Öÿ!$Ûþ!#ßþ$&àÿ#&äþ%)äÿ&*çÿ)+äÿ "‹ÿpÿ xÿsþqÿoÿjþiÿdü^ú!^ÿQë 0ÿ82´)'*Èÿ!%Îû#%Öþ%'Úÿ!&ßþ%(àÿ%(ãÿ%)åÿ&*çÿ(*èÿ(+éÿ)-èÿ"!Œÿ rÿ!!zÿ!wÿ vÿ sÿqÿmþ lÿfþeú!!aÿ[*U5:Ê5)+×ÿ#&Úý#&ßþ#'áþ%)äÿ&)äÿ&*çÿ&*èÿ(+éÿ(,êÿ),ìÿ+.éÿ""Žÿ!sÿ! {ÿ!!yÿ!!xÿ!!wÿ!!vÿqþoþlþlý!"lÿh6ÿ44ÖE)-åÿ!&ßü#(äþ%)äÿ&)åÿ&*èÿ(+éÿ(*êÿ(,êÿ),ìÿ+-íÿ,/êÿ""ÿ!!sÿ""{ÿ""zÿ"!yÿ"!yÿ"!xÿ!"wÿ!"uÿ pþnü"$tÿ!!jF€/2ÛV+-îÿ$(äû$(çþ&*çÿ&*éÿ(+éÿ(*êÿ(,êÿ)-íÿ+,îÿ,.îÿ-0ìÿ"#ÿ!"uÿ"#{ÿ""zÿ""zÿ""zÿ""zÿ""yÿ""wÿ""vÿ!sû%%{ÿ #oW@ÿ25äf).õÿ%)èú$(éþ(*éÿ&*êÿ&+ìÿ(,ìÿ),ìÿ+,îÿ,.îÿ,/îÿ-1ìÿ"#ÿ!"vÿ"#|ÿ""zÿ"#{ÿ"#{ÿ"#{ÿ""zÿ""yÿ wþ! wú%&ÿ""qh@ÿ/1çw)-øÿ%)éú&*éÿ(*éÿ&*êÿ(+ìÿ(,ìÿ)+íÿ+,îÿ,-îÿ,/îÿ.1ìÿ"$‘ÿ!"vÿ"#}ÿ"#|ÿ"#|ÿ"#|ÿ"#|ÿ"#{ÿ""zÿ""zÿ!!yú%&‚ÿ$$wx@ÿ/3éˆ),ûÿ&)êú%(êþ(*êÿ&+ìÿ(+íÿ(+íÿ)+íÿ+,îÿ,.îÿ,/îÿ.2ìÿ"$‘ÿ!"wÿ!#~ÿ"#}ÿ"#{ÿ"#{ÿ"#|ÿ"$|ÿ"${ÿ"$zÿ!"zú%&„ÿ%){‰@ÿ-2í™(-ûÿ%)ìú(*êÿ&*êÿ&+íÿ(+íÿ(,ìÿ)+íÿ+,îÿ,.îÿ,/îÿ02ìÿ"$‘ÿ!"wÿ"#}ÿ"#|ÿ"#{ÿ""zÿ"#|ÿ"$}ÿ#$|ÿ#${ÿ!"zú%&…ÿ$(|š@€-3ìª(+úÿ%)ìú(*êÿ&+ìÿ&+íÿ(+íÿ(+íÿ)+íÿ+-íÿ,.ìÿ,/îÿ02êÿ"#ÿ!vÿ"#}ÿ"#{ÿ""zÿ"#{ÿ"$}ÿ#$}ÿ#$}ÿ!"{þ!#|û%&„ÿ%(|«@U,0ìº&,øÿ#(ìû%*êÿ&*ìÿ&+ìÿ(+ìÿ(,ìÿ),ìÿ+-ìÿ,.ìÿ-/íÿ03êÿ"#Žÿ!sÿ"#|ÿ""zÿ""zÿ"#{ÿ#$}ÿ#$}ÿ#$}ÿ#$}ÿ!#|û%&„ÿ((}»ÿ+/ëÉ&*õÿ"'éü&(éÿ%*êÿ(*êÿ&*êÿ(,êÿ),êÿ+-êÿ,.ìÿ,/íÿ03éÿ"#ÿ rÿ""{ÿ""zÿ"#{ÿ"#|ÿ"$}ÿ#$}ÿ#$}ÿ!"{þ "zü%%ƒÿ''}Êÿ+-ìÖ%*ñÿ#'èü&(èÿ&)éÿ&*éÿ(+éÿ(,éÿ(,éÿ)-êÿ+.êÿ,/éÿ02éÿ"#ÿpÿ!"{ÿ""zÿ"#|ÿ"#}ÿ"#}ÿ"$|ÿ#$|ÿ!"zþ!"{ü%%‚ÿ&'~×ÿ@@¿'+èâ#)ìÿ#'çý&(èÿ&(èÿ&*èÿ(*éÿ(+èÿ),çÿ)+èÿ,-éÿ-0ìÿ/1äÿ""†ÿ!oÿ"!yÿ!!zÿ"#{ÿ"#{ÿ"#}ÿ"#|ÿ"${ÿ!"zþ!!~ý#$ÿ%'ã@@€ÿKKá(+çí%(éÿ#&çý%)çÿ&)çÿ&*åÿ(*åÿ(+çÿ(,éÿ+-êÿ(+Þÿ#%¿ÿ —ÿyÿrÿ rÿ"!xÿ""yÿ"$zÿ"$|ÿ"#{ÿ"$zÿ!"zþ!!~ý##€ÿ&'}î+9qÿ@@ä'*ä÷$(çÿ#%åþ%)äÿ&*äÿ(+çÿ%(éÿ$(äÿ"'Òÿ®ÿ ‡ÿrÿ tÿyÿwÿ sÿqÿuÿvÿ!xÿ%%|ÿ#%{ÿ"${ÿ!"zþ##~ÿ$&~÷55{ÿ3@æ()+äÿ!%äþ$'äþ&)åÿ#çþ Úÿ*+Ãÿ.0£ÿ |ÿ sÿxÿwÿrÿnÿmÿmÿ mÿ oÿ-.ÿ()|ÿtÿuÿ!!vþ"#zþ#$}ÿ&'~ÿ88ƒ)U6;â4),çÿ #çüàþ!Ñþ-/·þ=?þLM—þ;;Žþ tþkþ cÿ aÿ ]ÿ Zÿ Xÿ Vÿ Xþ^ÿ<>‰ÿOO›ÿ=?þ-.~þqþpþ wü((~ÿ05}5€47ÝJ%)îÿ#%Äý:8ªúHJœûOQžþQS£ÿQR¦þ;=‰ÿbÿwÿ !†ÿ†ÿyÿ jÿ ^ÿNÿ@ÿ1þ99gþQQþRR˜ÿOQ þHK—û98ˆú"$vü%&‚ÿ33wK@..¾'GHªÃUU¢ù]^´ÿY[µÿTU¬ÿQR¦úUU£û;<Šþ‘ÿ%&®þ8:¾þ67µÿ !ÿŠÿ}ÿfþSþ=ÿ:;RþUU}ûQS‰úST–ÿZZ¦ÿ]_¯ÿUU£üEDÊ+1m*ÿpp¿ aa¯i^^¯¹Y[­ö^_»ÿ_`¶ÿ;=¦ÿ¶þ.0Èÿ>@Ñÿ24Åþ«ÿ ™ÿ ‰þqÿ`ÿ Nþ:;`ÿ^^Šÿ^_˜ÿYZ—øZ[ ¾\\¡ogg¬%ÿÿUlvºebµ`ee´±QR¿ó»ÿ.0²þ<>¬þAC¢ÿBD›ÿ@Ašþ>@•ÿ57‰þ(+vþ\ÿJKtôdd–³b_˜cjj§ÿ@@€UcfÀ²SU°ÿ[Z¤õZ[¨û\_¬ü]_«ý]_«ý\_¬ü[]­û[\¬õSU«ÿ\^–¶@@€II’ps³[iiºÿhi¿ÿee¼ÿcc·ÿab¶ÿ`b¶ÿab¶ÿeeºÿhi½ÿii¼ÿmm¸^II’syÆ(nn¹€jj·µhh¶Ñhh´Ýhh´ÝhhµÑjj¶µoo¼ss¶*ÿÿì7ÿÿ ÿþ`ý€¿òOì7Ð             à@@@@@@@° ÎsñÀþ@ÿ ÿ(0 ` ™˜%Ÿ¬l´,3€9 £}²ò"$Âÿ zÿL÷Rƒ @Uª¡Q¯Õ!$Äÿ"$Íÿ!$Íù€ù^ÿaÿPØFTU€˜*¬­ "½ÿ!$Íÿ!$Îû"%×û$%Õÿ †ÿeüiûcÿYÿM­>)€N §€³õ"$Íÿ #Ïþ"$Õú#$Úþ%&àÿ$'Ýþ‰þjÿoþhúcþaÿPôI} €$$¤$$µÇ%'Íÿ"$Ïÿ"%Öù#%Üý$&ßÿ$&âþ%(èþ%*âþ!Œþlþuþpÿmýhùdÿ_ÿRÃ7¿55¾+&)Êþ%(×ÿ%(Ûú%(àÿ$(äþ$(æþ%)çþ(+ëÿ(+æþ!!Žþ!pÿ yþtþrþ!pÿ lú! iÿ!!cÿ#],@@¿/4Õ6&*Ùú%)ßÿ$(äý%(æþ&*çÿ%*éþ(+éÿ(,îþ+-çÿ"#ÿ!pÿ!"{ÿ wþ!!xÿ !uþ sý!"oÿ!"lú %k7@3Ì40ÞE),äÿ%)äÿ%(çý&*èÿ'*êþ(,ëÿ(+íþ+-ïÿ+.éþ!#‘þ!"qÿ!"{þ""zÿ!!yþ""xÿ !wý!"uÿ"$tÿ$$qFf3Ì14äT),ìÿ%(èþ%)éþ%*ëþ'*ìþ(+ìþ+-íÿ,.ðÿ-0éÿ#$’ÿ!"rÿ"#}ÿ!"zþ!"zþ!!yþ!!xþ!!wþ%%{ÿ''rUf3Ì14èc)-òÿ%)êü%)êþ'*ìþ'*íþ),íÿ+-íÿ,/ðÿ-1éÿ#%“ÿ!"sÿ"#~ÿ"#{ÿ"#{ÿ!"zþ!#yþ!#yü%&€ÿ&)zdfÌ/1és)-õÿ%)ëü%*ëþ'*íþ'*íþ),íÿ+-îÿ,/ïÿ-1éÿ#%’ÿ!"sÿ"#~ÿ""zÿ!"zþ"#{þ"#zþ!"zü&'‚ÿ(({tfÿ/3ìƒ),÷ÿ%*ìû%*ìþ'*íþ(+ìÿ),íÿ+-ìÿ,/îÿ/2èÿ#%‘ÿ!rÿ"#}ÿ""zÿ"#{þ"#|þ"#{þ#$|û&'ƒÿ))}ƒ€ÿ-1ì’),÷ÿ%*êû%)ëþ%*ìþ'*ìþ),ìÿ+-êÿ,/îÿ/2çÿ#$ÿ!qÿ"#|ÿ""zÿ"#{þ"#|þ"#|þ"#|û&'„ÿ(*“Uÿ+.é¢(+ôÿ%(èû%)êþ%)êþ'*êþ),éÿ),éÿ,/íÿ/2éÿ#$ÿ!oÿ!#|ÿ"#{ÿ!"|þ"#{þ"#{þ"#|û&'„ÿ))~¢€*-è°(+òÿ%(çû%)çÿ%)èþ'*èþ(+éþ*-íþ,.ëÿ*-×þ !„þ!!nÿ!"zþ!!yþ"#{þ#$|ÿ"#yþ"#|ú&&„ÿ'(±+.æ¾&)ïÿ%)æû%)çþ%(éþ"'êþ&*ãÿ"&Îÿªÿ…ÿxÿuÿtÿ!wÿvþ""zÿ$$zþ#$|û%&ƒÿ'(}¿€€ÿ+.äÈ(*îÿ#%çü#äÿ#&Ùþ-.Áþœþ wþ iÿ kþ nþmþ lþtþ+,~þ wþtÿ wü&'‚ÿ)*~É€€€@Uê %(ãÝ!äÿ&'Îö68µüFG¢þGG“þkþcþiÿ cþ Yþ VÿOþaþGG‘þFG–þ67†ü$$vöwÿ#$xÝ;;‰ ';ë 79ÈÏJK¼ÿSUªÿTV¤ÿTV¤ýJL˜ü{ÿ!#˜þ01§þ‘þzÿdþ Iþ<ÿJJrüVV’ýVV ÿSU¤ÿIJ›ÿ54Ó$$mhh„ce¥]]^¯¨ZZ¯æ]_µÿQRªÿ­ü,/Èÿ:=Éÿ"$­ÿ”ÿ}ÿ]ÿGüPQtÿ]^’ÿXY˜è[^£«dd«aZZ¥fp¸jg´R^^½¹78»ÿ;=°øHJ©úHI¢ûGHûCE˜ú69†ø35sÿYY†ºhh Shh—ª@@€€yÎ*`b±ÿfg·ÿcd³ÿcdµÿcd¶ÿde¶ÿgg¾ÿ`a¯ÿllª-@@€UUUª33™pp½Ijj»¤ffµËfg´Úfg´Úff´Ëhi¶¥mp»K33fUUªüÃ?ûßægØ @@@@@@@@@@@À€€€ÀøÎsùŸ(  @€Œ§³i¹#U¨~»û"$Ðÿ |ÿRýONµÜ"%Ôÿ"$Õÿ$$×ú‚ûfÿgÿRÝCL #µ¨"$Ïÿ$$Úÿ"%Ýù!$äý&)áÿ !†ÿlþoùiÿaÿR¥(0¿ (+Ôÿ!%ßý$'äû&)åÿ$)êþ),çÿ"#ˆÿqþ!!wÿrûný!!hÿU!).Ö,%)àþ#'åþ$(éþ$)êþ'*îþ(,êþ!Šþ rþ yþ vþ rþ pþ#h,,5å:),îÿ$'éü$)ìþ%*íþ+-îÿ,/êÿ"#‹ÿ""wÿ !{þ yþ wü%%}ÿ#p;*1êI)-öÿ#)ìû$)íþ'*îþ(,ðþ-0éÿ"$Œÿ vþ !zþ !zþ!!zû%&‚ÿ""yJ-0èZ)-úÿ%)íú&+ìÿ'*íþ+-íÿ-0èÿ#$Šÿ!"vÿ !zþ!"{þ!"{ú&'…ÿ(%}Z.0ìj(-ùÿ%(éú$)êþ%*éþ+-íÿ.1ìÿ#$‰ÿ!!uÿ !{þ!"{þ!"zú&'…ÿ))|k',è{)+öÿ&)èú"(êþ%*íþ'+èþ'*Éÿ}ÿ!!vÿ xþ"#{ÿ"$zú'(†ÿ''}|+-ç‰#&õÿ!åø$(Úþ"%½þ ‹ÿ fþ mþlþ xþ"#zþsø!"ÿ%)}‰++Ú§58éÿ@?´ÿLLžû)*qýmÿvþ _þMÿ)*hýLM’û??Œÿ46‘ÿ)){¨?C®9WW¢¢XX©ä]^±ÿ)+¢ÿ(+Âú(*¯ý†ýXú)*Fÿ]^ÿXXžåSS¡¦@<„<ÿUUÆ jfºFKM¸óPQ¼ÿRS¬ÿPR¦ÿNP¤ÿHI‰ôeeGMM€ ÿÿ€io³Zff³Ðcd²âcd³âff·Ðgiº\@ì7 `€€€€€€€€€€€`˜‰PNG  IHDR\r¨f pHYsÄÄ•+±ÝIDATxÚì½û³dÙUø­µ÷9'÷YÏî®~¨%DÓ’< $ƒKæB†®ŽÀ=1Ævx<À8hýè˜_&ˆñDLf"çì“™·ZZ¦ZºQ•÷æãdÞ̳ÖúÖ·¾µáìò _HUgžáooÓ³Ï='䵞¤ª€b÷ùç×óéÑŠß:̪ªÐÍÕžVUQMªœ#" Ì, xä —¨ªIá&3Z¿0¡••ãs³Ù¾ïûÆék¼-xx75nü“ÆÃ‚DT¡P‘xb™1°™EVc¡Ì“|míFouåóƒõµ?¼üÔÓÿiý~àKD4MÑ^»FgÎàÌ|ÛD{º~½5ú[·6^ùó/½÷àöKïŸþ­ÉáÑÓ™x+³¦Ó)œ(¼÷ Ãl P"®q»2SjßZGwjÍ·¶u­!燮ý7H`þæÎIC!€ñÑï”I*İ¡œ½^.28æçÏ}µ7\ýýÍGýÄãïyÏgèᇷëã>{õªýåOÚŸ9‚3ð-gø~ßû̳Ï=×@áÛŸøèûön½ôs“í÷ûÑÉc¦šád ê‰IÄ$BP…SrÀ62w 5‰ÛÕS7àSé¸~Œ€±üúTʯÁ“ŠD*aV‚ŠŠ&#Å ?z9$l÷/ŸÿäÅÇû?ÿéŸýD4‹oÍ@õ œ9€oã¿vÍÔ_UW_üÍÿãçö_¾ý Ó½½wódŒ“É•eË^@ /¤L¤)r¯#ùÂMmh×%_¦2@‚åÑ|©a  îÜÁhéAT_ˆ¹{, !`…úᨨ£,"åàA¿úCصÕ/­>úÈÿþôß¼úôß±U#‚Ôiž]ÎÀ*êðªZܼ~ý¿Ýzþ+ÿ=¼ir|‚iY)ãAÄ¢Ê ðÖÔÈÐ^4tÎ[ð2k?íz.õ¿_ Oo?Äã´…“'¨q"Ñ%P<ñ‡äE•{ÌÜ[@WV·ÖßôäÿòŽô~…ˆöp|ërvV9€7Šñ3 |í{ÿÏÿùÿè¶¶ÞqrpˆäÁ L“¯Ïçï ¹÷’s_O}ñ$ÿÏ&+5ƛ©ŸÃK8%$qL ÑÚ˜©{Ö̽Ÿv†Í;¡Î‰Ç±IÂâ… vuu º¾þÊ…ïþžÿáéŸýÙߨIÓë wrv9sä%=Q¿ü¿ýúÿ´ÿå¯üóÑÖ=8¨ƒÉª\›žÎCjí€í…È Ò6_WC!J‘2!üÏM>=²×ú`Ô¾7¨‚‰ M)Q!ñýÔ¼„Ô‡ Ê,$NŒÀ®nžCÿÉ'~ó{ÿÙ?ÿE":JÓ©³Ë™x`#¿ª®~á×~íß}ñÏÿööþØ¢§Po$ ÛqpEõ~aý›õ†O9šÛk®?^kí„Ú³'¼}zÝüH“ ªRÖW†6Ów|é~á¿y??û œ9€9çWUíýåoüëÏlýñŸ¼{w2©2"ë—|Îúõ|ø tNœD4Ì $¥•ëéð»yê²òà<_?6áø–þNDPÕ%× A€jíT’cE #ý#˜TCÕ¬ø®wÜü®Ÿ{æ‡/>þø«iŠuvy=œîÙå÷¤1 ¾ü[ÿ÷¯íþÙÿ÷î““Ò²Í|”«vÿAO¿ õϱЧu¾Ý§vÚ”[‹Ï«å½ZÿNZÖ€ÛÊBÔùÔÿÞGxúxˆ¯àòëøúÍë$¿#¢ ’xL•æ¹"Vd'„ª|þKo~þ·û߯ÏZTõ,x9€$ú_»fÈÉŸþéßÙþùŸõΖϬͽ8DÅ\{Â'¥íùS¸1’ô1Ñ@š:ò%$—” ;¡y‰C Öa4ÑÆ·tÿÅ¿£¹ÉcIþµïU—0—‰ÛIÞ»¢¾ÖXFTøÀ‘dGUYù—^úáÏýÖoý3xæ™gÎÎÝ×ábÏ>‚×!ú_¿.°óÕ¯þw{/½îp*‰¦Q;1Ëú 4îÜŸ#ÿк@ÓÿjÏ2ïs´ë4a5ùÁ€é>¥DmsõS¨ {Ýûø€å×Iþ¡¢`¶æèîŒoÜú§ªú«DTÖi×Ùx†þZsª·n½éä•WÞspxR媷1°…ëzºÝ µoíôð“ sœú÷†Ò×:¤7é\Do½IARBAO9^ªPêx ]ú·4©Èò·Ö}lÊ‘¦ÏU@ \V¥Ž¶î<õgôû߯a!€ã ¨Ÿno¿E޾,ʃg%š;CõÔ@x:Ø}$͉y’ªà}Œuñõ—¿°.1_ÂýŸ¤ ¯[¿§ÅCS'ÝXîP—¼ZtNã²RœœÐÑ­ÛßàÿýðûÞ÷ºV3ÏÀÙå@n-«*ÐäDgL”ƒ¨îð'Ðë¬T¡KJnº¾±”þíd¦58"t0~êa¨{Óü[:”Ïw&.±þ…´" WzŒ'SåY‰½ããµ³3îÌ<—| ‚ç¬ÈˆOgzì•tE‘å9˜Äm$§p¥E{Š\·£¾[f·ºÄÐH—ë èô¼½~1R]p,ÔH“ÓÈOã}_à>nk)’ˆ‚"W–Ç8ë€ ÅpXœxgàÁºä9lžc¥*qRUÍfèmn Ï 0˜©í³Oêùr4g64õ”ˆ­KÛ€Úü`ŒWZšd," ]î :B XïO‰ÂSß™.¹=ÞQW EBIÐU3ŒŽŽ0*&eEYž£ßëgà»y* ­ÁÆÌ£:9ÄÉdŠòÜzƒ!Œ± '@Äén]Ã× h‹£cÇý\w~z-‰Xòá©z¯Ñé’âöZ—sYìn†.2º$Îw¤Î ‘Åä_Uƒ|Ø{L§b\–¨ŒÅw8ßëˆ*ÀÕ«ÀsÏ{gà¯ñòÌ3¶¶[ØÞ€Ö¦ê¼'b4a¶qý äE&Q3á˜[=Ýǯ ¦Oÿnþ’F¢%%6¸£5tJ^/û û…í¥Öãò\8O ›`ÐÚÍ|’št„Pø²ÂñÑ!Py‡ÊXŒH¯€Ér°1ÕÙ‰wæŒËÛßN¸~žÄ{8Ï‘ ´1›‚¦;+q<~û{ÈÎ_Ä`uE‘˜:á(8ƒº¯®¡S0æZK0ÇÀÍc„†‚§$w¯#u{ÜÃ^÷ÛJ,^+On—Ht†_´3€Ä§iEã„4¹V¨ W:F8Øßƒ›Îà˜²ÁŒ÷‘õ CPkÓ>©³Ë™ø/~ágÃä^OÏ>ë`õÊû»DPk‰Ñ¼×£õ²BîLYÁíÝÃÑˉÃsWP\ºŒÕÍMôû}k@dbAÉuÀ>’xB7GX,$†nÀEâ/ÜžBó¹ç¦þâ4ãŸ'&I s7eÎLÚ°~Ýy‰0T â0›Lqxx„½­mܽ §Ùæ%ð`g ØfÈLDJÄXÝÜ<€gŸ}¶@W¯^5Ÿ~î99›ðWÈ\Ï>‚¯ï¢Çqݾ@¿ð…Ç>ÿ™Ï\-V†?ß;Øÿ‰ƒßÿu“ ù£`VB&œp0ÞÁÈÏ0ÁH€™Yƒ¹ôÎc¸²‚~уÉm4~n ~ƒô©îÆ£×üâZ»ý:Â÷|ŽN÷Ïû;åR‚°NF$¡ZÙ¡B!Îc6áøø£ý}ìÝ}“Ñ>€gBIhã<k0yî÷÷‡0ýBßò® Ç¯<ò‡z°û¯Ÿüî·æíïÿéÒ÷y°Ÿnlj‘…gà0zUþ0? tÆR½ü{¿÷–ƒç_ø±ÉÁÎÇ;»?¬£ÑÆàÂ\¾|I÷>ûYòGÇÐã#Èt ™NA"ð³)Æã1Nª Æ2ÅXFâ1ö@U¬Áœ»ŒÞÆ++(z}äEkDºèOi¹%ú+|I'òýu÷qº0GtáA¿ãá½ ,K̦œŸàøà£Ý{˜£„-Jfh±|u6ÏÃ[À úÈ}äƒ!žüžïÖ5š¼r¼¶z2ÜØøìpcãc—Ÿxâ“ßÿ¡}1}׃k×ð‘ë×ålÁ™øº>U¥÷ñssFçSŸzûö_üÅOœ|ðd{ûóªºÉ ¦Î¡tÎë›xËO˜Ñ¿·· ³)0B½@] ½s˜U%f³ &ê1•c)q"f Hÿ<ìÆ9dÃ+ô‹²¼€Í2XË`b›„Ô¥Ó¾SEž‚‚0)iËýzˆ¾:/P0’™BÉ ÉJ¨ ¼TU…ª¬0L019áäpåÑ.DÃTb‚gg•ZP ¶_ÀØ< !°µà¬€ôõúè­­âÑ·½ 4ÉlkGmnMÎŒ¢×GeŒ[9·ö'ÕO\yê©O¼ëg~æssû̵k×ð‘³ñãg`. Ñ3×®ñ’ýôÒG?úΣ[7>p´»ÿÁÙÞÞ÷e®ÊÊ“LE OÌ VbqxâáG {»˜½r29&hY‚¼ƒTÔûµˆ`æýÇôÈ»Æ)‡síÚ5:sߦà´m<ªj^üøÇßµÿÕ¯~`¶»ûÁ“ƒÃwæUÉÓ“c”¢B0zóø£ñ0Á•6\…ÕÁng~t LÇ“)|9`2Pi‡Ù0sÈò9c^¥÷˜–.87ÃLì`¶:™â±§¾Öf€x#¡®Š’5J^„DLf Š4Ë`û½—WÎ{nõü…>þŽw<÷Öù‘íôϼzõªyîë\ÂzæÞ8F¯éªªkÏÿæo¾÷è囜îýXy4zʺãñ%¬ä”™Y„Ô„3Vha¦í(,(ôù0Û÷B´ª*@<àK‚áê…&§FˆÁÁø‰A†ÀdBÔŽ¥/6&†Ä¨¬Þ£t®*Q:Ê…kWßóG/^/>£Tð”´«ƒ€A$åVÈÜ=9(6ÜiÒx'‚¸ ^Ž <1ÔÀäð†!x ™‹†ÏQ"jÔ@BÕC‰6ìUÛB Ã" ‚¢·¾Š'Þö4,YœhDײ"€EU +‰‹ÃDƒ,=˜"ßœ»ðÿ¬\Øüø•§ßþ{oûÑ}i¡¢ßò™x}ÜÂÓñâúqþù?ýÓÙ¿}û§&;;?*''OP5Ãl2E)^™Ø‹af/$œ&Ïá¬m'ú$[=ì#jáõ…à{÷À°V ïÁ¢€VP=AÑ6Ï•{CäccÀlÀ†AÆÀ²O|6 ‘;:ïµÉÅ}åPU¼s¨*'Þ œJØ4¤ =â\Dª¾Ù ÍÏq»WTæ)†*A‰!l l!ÆÂ³7$l‚F^© þ|\5¢Ñ’êÏ+üÌð5G`â£{·aòL¯& [0ƒ‰0ÜXÇ£ßõ4Œ1€8./­/kPó¤Ôø´Ø¢ò g÷ÙÀôúÌŽVÎ_øƒá¹õÿpþ±7ýî»þÞßûÊ·Cyñ[Å4œôËÑÏ}îâ>ÿù«ã{wêx{çÇi2y˜ÆcLÊœŠ²a/ÄÌâIˆ›8ªzê.yx¬I=Îß¼ ¾srXÿ­Z^|Ã:€Ó„9;ø‡WnùË{´u罹[;ïãÙì¢NNpRÎà b@bVϳÝi§ÚiF¿x_½V›QÞ¼ûꬽ À+H<#ꣷrÌÔð3GÈo Ø2l­|3Ü:2áõ8¼/AF«̼…÷Þ D<¼sð¢ð^‚cðÀ©‡HÔá $ð ºþL|m¸Æ‘ùß%>NžSÅ(.ˆ×*C¸nL(h&þy ™…ÖËAˆ1>ØCu´^Ý€ Y0Ü<+O=fJ¢~Ø“dRÃW „¤¶Ñ¿N R>£Nx8V V˜‚Ù 1Æ÷66þtecóãkW®|âÿÁ?ø\ÓŒô-P^¤7œÑ œ—>ùÉ7½ðÂOìom}p²³ó^3+7Ýø3qpÁÒ€™ë[íðx]s>Åò—¦á>Ç wëÌ+¯ÀÀÞ½(Pƒ`‘ÈzTBºÍŒ83 ‘ÌÀÆÂ b 2Š)@舀µU%À|QxçáÕA\àx'pâî>>84ŽC±ÄÄ’Ÿ`Ë(Ë “»Pqàá8ëA™€ú30I‘èmÕùïNSãÝþä'¿sû/¿ô“£ÝýŸomÿ -«•j|Œ©„j5)TÖÅp}!™û§|RɬL3ìµ6&Ãð/½{û6˜ãŒw!J‰0!£@±²NÀØ0 ÇHÏcóX ½™À …"I´õ¢ÁÈ¡€w¯¾ò8ïõ®gžy¹£5Ìs­ýöt÷1úì…ë×ßµûâË8ÞßýÀlgçÆ;r“ fabFÇè;é¹.Ž·¢$jG¼üZï«s-éø+`q´w ™ÁøÕÛÀK/"ƒAá¬w UñENCÓ¢èõƒ †d²&Ê3kƒ€C 9´ÂjÓ)XW(ÚŸý5À~ï >}óOâ<*Ô[wÎWøÁ@€‹9ê<‚¦2:Irý*–ú\tIîèïÐ%µì—³Y‰jê<,´ºÊó¹™ \;€‡Âå7½º‰Þ`јøý£Ô†5˜‡þuá%Ñ?5–ºÚ@HF2 ‰·p¿È@EoóÃþ¹Í?ž»ôñso~Ó'¿çCzþAÒÐbôùÍßú­wß{ñæO¶w~j¶»÷[–˜N'p¢‘#ËD>HpÓ•Ýe81”‹žÊèéÍýÞ@\k0zõü‹7Ð#ëKd•G¦ # •#0™HbÏXƒ¢?„µˆÑáØØ˜æ& ƒz’PÝs/±èU›n<ñ>–CI0D{×@þÊyTÎA«€D°ˆ†tI©KÊ\äFêþU$%-Ö|AR¨S'•€^éÉäèž, ¾I+ìêzPã®àÒO€£0u¾Oõ5µ€¦¨@[rð5ÀÂísœÇêCK.‡#¥Ã"UE,/BÅ6ƒíåplËâ¹?é¯m~tý‰'>ñýÿï>% ¯æ#­vê éø@s‘~ø•óoÞ»óÒ­¿;ÝÝÿñr4úNžN0™NQ`À®Vã)"hq\ü²dŸÚ)Õé L,WÙ1öe›%4eû£ 6äüõ-À×µøº|f,ŽïÞCuãäl`½C.Ö Œx°âˆ0ÓÉ&Ë}Ø–ûD¨6 ,#ŠDatrIä—hü  AÅÁø&ÏçP–¬€ :Ð(òPÌNFðG‡Aeç#;f¨÷0kç@™ jˆX=V¯<†K?#&æãÁð&ö¤B “æø ˜¸~¢x¨Ñ ÜG#Ь`\@Ý (¤é(J Aœ¶(Òt/‚Èì ‡)³ô×7>7X_ÿøæ“oþØ»þá?üÏéöãk€™'ÄtÐØ•ªö¿ôë¿þ#;¯¾üwÇ;ï—£Ã7s9Ãt:ƒWQ5Ö+6ÞSè°›³Â9Fþµþ=å÷y‡!ÞöÚÈ%œ¹ñÇA­ñ+€ o²ànÞ€%‚õ¬ €E`Ü1 12ÊÂÉG6~ÆdE¦(`Øm€±Q`‚!M¨vá¹#›/Å@Qö+.D|ñNàͪT®jÒ†úþ@:ˆԘжk²NÔW¼r[þ‹ª¿´ Ø”#!Ø1üDè¼Çìøîä8( )Š™@ñ3UÐêzpFØ€T°þØc¸üèc`ïa à¨ö‹“£K¡n€ m‰P©%‰À*AtI”„ϧX±iDܵhL¢B³›ÜÏÀÀW…aw ‚µ ä½¥1(Ö7þ¬XYýøÆ“Oþû÷üãüÇo4ÀäSÿò_>UŒ~Áÿ´ß?øNL§˜ÎfpªJÆx5–Ù; B÷¯ï ˆ_Ps½0 Bî/ß«³‡æ‰¯éäûË Á”ýF p 8Q¨Í0ÚÚÂø…‚qŒ÷È$žpå,bX2°Æ‚‰b›nÐdY޼WÀØ ÆF`cô¯S¨€S¦hü±LéNÜ—Zñçc¯@YÂUAèºþ\|œ¨¢ U| 6´íªå9ñ‡H]WRÑO}ßÏ¿P•%ÜèRÎàaŽŠF¦æZ¼¯m4h& (@6—¯< ã=,Œ Õ4òSjøÁtkò£)5èÖ$UZFrt]ƒ§e¼a鄎zQ5V •ŠÂf ôú=L™Q™ì?c°ú«ÿõ¿ú•ÿõ›á^ס Ñ±ÊgÿÅ¿øÏýû÷©ò¢þ‚Ö×<±aV%µÐ ž(ˆdhÙÔ}×võHçšc,¯ßA­ø’ôˆ)¦¢—ÖðS]@lúYºp/¿ÎWÚÚAO"¤ÕÐú˺֜VÈMŒI rXÕÆVÎA§ ›),Î-ŒD‚°ÙЖ55Btõm¢# J|(º² ©€*<à¤UýÕõÿÚøEñ¼« œ6tø©1ºSÛäS%aSâS,D~+Ül ?9†z‡œ_OïE‚. ö#ÔFY£,“~§ÉPÑð™HsÊP4jM8$ÕB24Y˲ï¤QAXߌL´2ãF/‚$ýL¢Ç²íŠu‰: J%Heˆ,^+§wvvdïÕWìÑ+7ÞÕ{ëßx׿ú¥_ýÓ_ýÕß|½Ó×Õ|8Fÿµ¯|ùûßyûÅÁ_œÜ™íî ½ØcsùQ»zé2kkq˜C°Ujg`6C0)~hfœâY…æ ‡¶›iVZÓ"*¨ÉÅîðJílôíŽÙî2õI%ª"Ì(ÍB £‚rcK&Œú†ÀªQ d!"U9Cæ*X¶ qfCnkLsR!^Ïà5©;« uu~î£1úºÌ§I”&‚×àN}Ý­'HYAA8‡š Â0!¢ Ϭ _‚ ö¢$' ©*T¾‚”SHåã§gãVbŠ‘?hÄ €6ÏO ˜Ðï­àroˆÃj†­Ù î–[Ø»¹…Í`zË—Ñ[ ¨€ëÈ/mä³*:Ê^ÒÖç¶^Ûqõ¤Ë§Ô6P¾»·JuX´¿Ë¢N „Pþadl ÌbÎlA°B‚!†ÃBá)èðY`Ud8H,²¨>`8°¹¨hWx…† @ª×.BL§­ªÏE‡ã#ëêô>”A¢PD [CãÈÀ“ÀCÔA”Bo ¤ˆåàx¬…LÄØ@.5UUåð~…94#15¿>°wR?Ž’®¾adñÛ4 @ÖÃ?’¦ Vé§17¥ÖQDGÀ1XiÂîk'e@2:q^4¿m:ê©Èí¹WŸ3Î f“)ööv±w÷ïÞ ÝjEŽÞà!äy,Ëé[– •§¼¨/桇ÆUf¡êITa‰p¡×ÃfÑÃcÕvË ¶ÊlmßÀñ½õ/!»üVÎG1ì#³Y+•®ò­™;OŠ9;N®)MºE…fv½.elðŸîá¸_» µUŠŒÑŠ, …*6Ã0ê`Œ…†!/¡ìçÅA +€e§&”­¼R‹•Åó#¾pÞÇ™~µÎ¿ŽèAæ+„`øu¾.!y^80 x­âcÂïAç rAlDª«˜P>ĈI¼ØKÄDâ æ Àã‡$1ò×åÖð $áZ½E8 EDÑøDD²ý­bÍì€1˜dRùcy°>wH—É÷Q¦'Z½ EÇRÎJŒF#ìoÝÃþ—0+ËÐ2XA¯¿[ÈŒiù ¼ c°vùò.¾Î¡×Õ(IÙ`íá‡G©=Ð)€{ñűzõæ^·Q4Η7‰:Œ‰°šXÍ <äWpPN±UN°ëv°ÿâöoåàË¡wñ"†kë(²lÂ2ÍV22Äfsn'lG» ÂÑœœsA5à ¤30%ÿ>ÞQKM- v•€qÉ0‘xx50‡a¨Dn 0Ù, E.ä=ˆ† n¢ %.¨í[±Í,?-½õt¿¢«!QÓ¦«±jmËy(3µq´—0„4ÌT†T o"¹ÇB1ö›HæQ3tœ„Fqùe ÃXª+ e ™QèA‘s@QÐð™Ìÿ2ÐΤ  ö ‹v¿;L$½Lm:8Zž;mt)h¶:³¦Ó ±ï·nY»aصMdÅY^ ãæûNPjep±jA>¼¼xç;þfw^_ÄúÐ^ï„2S’ [¶1ãhxBÁ¬ cñð`ˆ Åc¿†é[ÕövnàxëN—_z+(†CdÖÖE84#ý"wÐ|ñPm3|¢n7ÍoÌ]Hýtmij i#nS‚!ç‘«PJÌat·– Æ”î3ƒ%ä¤6’ZÌ&ÃÃÇù¡R‚k^àœjD((ì$pÚÚ°Ñ¡\„a¨F5C„ýUÀpðÂ6hÈÞ‡’¡h‹„ ä¡>ÃEi¯Æî@EùÀKHjÕ%I,*œ†JŽxA O@Á@®@Æ‚œ-r²èì9úiK/'¹~ÓýWWj“ÎíÍ‚cÕÎl$cÅÐ,=MV¹+ ®ÂÑè{»Ø»s“q ì©è#®"+úÈŒ…©hqA ¸s•T›¥½£êoß¿aH@éÒÈX{Ì$C7ÏŸ$Tjƒ´>XÄU.°’x8¢‚írŒ­Ù_ܾږ+X_G‘e ˜ÀÂR4ÿšA"éð»Ú!kYðébnõ`9óC”Nœ¶£Šè˜ &ÎaAE6ž@V–‚À©‡‰UHø™p"OARºê¾‰'t-ÝÑ&¿D@5–è8ç(¡‘hv@£HË_’H>Ç€Š…’%šðc… A # ¦@R[³ŠƒGê¡£P%ô-a`€‚‹€zäÉIK˜kãÕîî‚”îi'ÿhGÙ—j9êcHZÞõµí·ä€xLgq«ñ½{8Üz9To0à ØÁYH=ª +ïëÍ)íJcÔѽì(ùøÒ[Þ2Š1V‰èuñ=º²ròµAod—=QÄËÓöo¥XGÂú„ÂX\î¯àb1Ä£u¡:ÀÞÎMŒ·nâdPÁðÜ9ôú½0L ñÔ,ÎÔèÂCéŒç`Ü’÷•®ºoE‚]£Gwˆh ã"™Gªj#ñ0†àœ¢ô@å<ÔzXãaµÓƒ˜bCKßúPÚ"´#°¢ÜUµéû“h؈/Ú0ì ÛŽvø‡6Ñ¿nnù;˜ ÎC¬ CÈ@œ‡²ºÀ/xV¨ ì~æ£ñDz#B¡ùÔ‡5:û8LÈX‘A£ÁÇ™Gþ$‹$_N„Œ¶^È”2ûÑáÖl?­ù)-éÑ-¼jGv*É:óÚÙ8ïprr‚ýÝìݽƒññ~x/EެX‡ía][H}¨v„ P]ÞXRZ\Òž¦ÆÆããZ?ðÀ#üäO:úŸeÄKþ¦…Öû%{§I5¢‚º$ä{çc)ñQ·Š½r‚­r‚ÙŽ^ÜÂþ­ |ùqôÎ_Ä`uyQÀÔ…$©ÉÀ¨Hán €º= 3ïîýé‚è³Û`PÃO¥*¥ZPH52ÞW0#S…£t%* ƒ4 v0jaàéçÄ>Ô±)è (¾_B;ª§#6‰ 3ÂÄßhüT„µb/LVå@ö‰‹«º‰S‹Õ˜p fh©£Ⳅ¾ž#Џ#  $£0A% ßißÇA ‰¢Ç@ ‹Áf„ŒYTe`X2ÎÀF4%;º5ü:-hÔ$Ær£1~Y¤†¥îtÈ A9«0::ÀþöJCsV`z+°EÖYc~—jcü´Lù>‡X ¼ª åÅà誵³>h‘ùg~æ˜àz§FmÒ¶øž*¡¤–44˜ß1 2ƒA¶Š‡z+8tkØM°Uboû&[70é_‚½ü†›çP z 颳gÁ\ݰ&aïSb]pÌ­X˜Ò2Ñ\OyæÈC-ƒ$0ë‚Ì)Ü´‚³UEp™ÈÃdì-˜cß»FãONÞz¯ iËeè\¿jRÏ×âSßT!þ 2€óý¯šE¦žã톣7TbÔ°5v.iµÞßÇ¿×7‘/”Ks(,Ç~~Ø*ØdSŸÕº 25ÈÈÀD]E]Š£8œ•¢"Œ’4 [ãoóýT-j5ùáiîñŸLq¸sûãýp_–ÃöWƒÑçyð€âœ âS­{¹ñ'§£ÎhD bãÑá—~é Á嵕cFÕ,•nIíØÞ¼#蘡¢Û(T—c³Ž5ÀÓÃfÞã~{³ ¶Êì”ÜÊÀ— ¨`mYü²¤!w¸ãZþ·ûºŠ®ñ‹¶r¾Í€‰›š³Æ“;ˆ€,XÊ ´ãP–…a!ÆrD)mYÂÑ ®2(­8 sÈ„9±›±Ég=šö§tx¡vÊT!çiŠÝ ñWWÜÛ•aññ3À›Xˆ(L4Du4’áv6 5G‘(yQ2ÐcB.%ÎH×Q<2gÁÉ1 ²X1a¬†ÈšÈ"Ì7šÖèµiÏíäôÚmÉïªC’Ú±´íc…›•p°³ƒ;_C%U8_Š>LY¯N5ã‘$žoaæxýåÆß)RµÍLU®JdÃá(¢o€áêcÆöy}-Ú`AŽÛ©ÅÏ#ƒú›Q›AZƒ¡]ÅåÞ Žª lÍN°íް·sÓ­›¯\F~é! 66Q z0l Š^œbãk›¯!F4ß K!G:vb¹V¨׉‡Ù–ÀHF ØËNa,#«j_Î &lù©2ºïl! câ„[Š#Ã2,íiHæNÆ> ‘Ý5©‘FÔé«öŒÐÌD'» Ù@ÅÅÉ=ui/¨•—aˆÃ°N&S˜ÜÀ:Æ™Áã~?àœ@3õ-hV‚‹ä@Ì@'þBUÅȘÛšŽëj”ŸÔaxuáÿvl0~߸}Ál2ÁÁþjロð 3܀ɇȊx N‚N§#¦TµM½#.«ˆ©%ZRGN:uD¿Î9„h˹.p+;Þ+'Ø®FØ™ÞÃèÖ=hÔœ¿€þÊ*lžIÛ®B›hb¾Š¨×_TÎïªÅ#mNš–Cú#í1œ€™¡ÎÓ<‚F±ŽJè ¹xп/õØ/FPÜ‚nŸ ¤ž‘-qãÍ2M%Àr ]ñœ‡ºP’“JbØ â¡Ú· „œ=XBg¥°zK$ƒ†p­d) ¬^À†ï ü†¯š± ¢,è Ðöö‡J GŸ6N`Y¿G] i[n©!?4iÛ…*¤r8ápg·_B)AžKy¶Îís›‰ Ôºpš(XÓcþBbÀ …Ø|pô†q©Ùã£#Î×béÃtÇ.'EVŽ£§êëF‹Ò£ÒÑ`ç8ÿÕSÛøD"Àj‘a5Ëðˆ qPUØ®QÁö LïÝÀxå2ìÅËèol 7zÃËûÕÐÀ±¶™–¨‡“!¥ZR˜|@HøxÖ„[<.›†ÁÖ˜. SóV@³ ±P1ÐÌCŀ؇J‘¤¬‚ȦrÌ¥Œ L~j÷P%ñá}Ô~€läI¬ ‘Ø0H˜s@˸•(F]ƒ0­0@å€Ü†ë~|ÝÜ‚|P<3”õ P*(7€S°ÉÂ& ¶ ã¡fŠo­×çHx2£A;ÝoB6FäXCêæ;ªƒ‹÷˜Ngíïáp{ '{wC¦cf°ÓÂæ=C-YÈ5ï27‹†—›x‚)_[¼“¶¦'JUÝXƒßß}½‡úkwŽoÒ;Êäü)C½Ú/’ë¼¼†ÛÍïÚæn²dv?NIÒèx±èá\Ñ‹²ãÜ+±7½‡Ñ‹÷p„Ç—Cqîú«+a>_3"¢Ñ–¿>§ã¡(²õMw[ÜG# Åaí` F²HSÛÍÃ5¢ìã³(ÔpˆlâŸÍmµ¢î4q€ ulØÐ¥§&¦&&z[Ž0F˜*<‡ð1‰wÁ©ÃÏÂè㪼Í|p".¢HJ’TÁè¹ M¬à83±®Î¡›:DmݱïHš0~¤ÁIŽÇcíìàð•YçL±ÛÂfy(ßJœ8üù©dœR®.qÂ5ì_žóŸÎþ§zôx³(ÈZ°êþÆü2€g8cömÞfc™Q6¯´kÓV¥×¦ sï6UP]Z.=}§_üB +Öl†Õl—ý*˶gl»"*˜¬^†½ô0úë¡EÙ†i´å½-OZË7M³H‚(I”ÁÔ.ÄHæÊ¶Y,µ?G@ -”¶¨iO.Ѷ·\ M)Om({ª ì³ï”EOûPï‡m4yPûEÑ ÚyÿZψè€j«]àÂ0˜ð1[Ö‹ ëy†+~ˆƒ2 .Ùq#n“{ÀÞêC°/¡·¶Ž~oÊhÑ$Š3¶Ôû™£Èœ:Yaµë£ÔQ–(ûh¹£LÏÅ&Û©óã¸2GPSc"°‘g eF±ÃÐ,b"¾Z›VØÄtÀÆÏ“ãƒðhÊ+@-ÈÖ×1E±&ŽE Ï%Ž¿³8Žëb ³÷"ÄUƒù‘Þפµu{­>)ºY‰Ñáw·q¼õµˆ Ô[ç}Ø^Ðå7^ÒBğׂ$¿FI´´Û´EX h‡äHuvGŒÌôFÀë? à›âꙸòÈȱ ŸJ¬üÕëŠ)ÊãÅš]iÓfÀ¦7@—/)%@Ï7þHé~mk:/NIH¬ZöÛ´‹Swdyã掫Ô" PR&«Ë`õÀh ‹€5Âz3¸’)Ì>: ñ1Ù`+¨ ‘?¤®}®ÏÏ ÄešT§2mié3Jx”背5mI3Ýõè“É8zwî`:ÞhÌ‚ó¸7D–÷`ëÔ§þÒ”ÝÜ¿&+@§0\±)Œ—¤©§NŠ]’õäj³Ò½a@ݯ<¸òĨ4ð$bÝÌ7&0 î5ïD»åºæ^¥¹¡¡ÔU+éæK{–¢Àz^à‘j€ýjŠír‚ê÷¾ŠÙÝ0Y{öÂyô×7Ðë÷)1åq‘eB˜º:pX¼¡¾;`&v›Õ›r ‘˜£. ¥0 FQͧõs tºéc@R¨­bÔˆÃ$p „г™\ÛØCÇQǪˆ‰ph)† cȇB7ÇhK’AØTL”i2ë-"8+Ï@‰.ƒ¢Ö‚*Ë@ªð³ £ã޶w0Ú¹ çªÃ{}p¾S]>×¹z]޼?¿x?·F¯œ€£éè¼ÒÜ‚›ù|Uë!¥ñE¼&ò]}ä‘\# €úrÒï ‘³óÍXi’zîVcòsÎ[[b±v JólmW@B r‹A¾‚Ëý•ˆ &¸Waÿ䜌^Áˆ‡8¾øŠÍMôWBÝ8?· ÷ÊšòIŒ˜{ÍÇÖ)šßS¨&”+® %•jÛ–ZYVCẉ1t&%%¼KpH$ ]ã4gŒÆ=^Úæ/ø¾%tá³´G¼=ÂBt¦lÆÕÆOa%:hU¢wþ<úýHããcâp{ 㣭ðyÖ`Š!lžù7ÁNSŽ} ãÇ)œRjüÔ1þùäl1ÿ甇Â)2Î} ¼P±q½~ÿè ƒê™ØÙxLà‚ˆ¾i›ë ±H®±Ä“7-£EÁ´”oè:ƒˆ aÓô°QxÄEÙñlŒ]w„Ã{_Ey˜¬=ŒìÂEôÖÏ¡åQL·¶QD…`luI?‹ùS; ŠN ¾n ?™ø~, "Û¾Còœ²N-L¢c¤BÝN”0ª5P«c#pŒÞõ@%EP<ƒ¨C‘×ÏiæîP,vRë®hA¡…Ê‹s…ícóÊe WÖptŒ~tïTQ°ƒ<÷†°ù6+`f¾&Pha·ß¼¡Ïçø)òª¿®Ltëþ‹2òS]Í}–[ugL‡Û‡•rêý7¥ø›ãâ¼8¿š››o|Ù ¯óœ£yGÝe5ã¹Ò„$J bÖömkC„af0ÌVq¹¿‚£Ùz˜UP±|“ÑÛ!ø¡'ÛDoew°êð0–Ê4°ââÛ¿Y‘DHÍÖ7bØ ´k³C³l¸V¸ØZã­Æ)8QÛ¾¥n! ZH ’€´µædáº.©¹j$=Ó–õ7C@ ùç¸ Ý~Lª–…ì›æZôXˆýiøÜçÎ^HЋ0ê WtûÎqÀ€ÛfXWNy56z1tuýʦlŽ Ó\NÌkFY­ÇGnm-pk±ÀÛ»·p´¼ƒGgx¸<ÆÓ§ˆË'À°ÿ&­;ØÚý"†ó3 'O Ãe„”Û±X)|y£§—Xd#+v¹°ƒ€e Ä~”$¨…&sŽ((† Ù i--FA&3£Û»›—:†!ª?ê ²K»·`÷ö]„¾Çùùsœ¼÷!V—WcÏýÎÂÖ-,¶w°è{ÕgaGvy#æÈaòò–&õâïA…ÅìO§¨Ç’î’KÙ›¢ß¥¼TÞМüù/}i…¿ö×^`Òßù 'mÅñö¢z›½D¡™ÝË «Ðî¬,Û’u‘‡WÌd'Àlõ„·ú|fgß¾¼Gøèê O/âäùC,ûÛ·ï¼ ¾º‚œŸB.c‘JÇ`G(OAcEå $Ë@ºi8J"©}a+a6rÓq¹?]—8³2D£t9“Ó°ÉG"‹$Àxu…°ØÂÞ·°ØÝƒprz„ó£G`–\—ßïîc±ØvPhøþ–æ6~‹ðkpäqæs¨Šý'ä33XÛYöÂ*Ò躭#J±Ý«’HN!,vNòxåt²Åªrª¦S° JÄá êð«ééÉÌÚ\HÅX9rÉåªéÝÇY{ã'l-pkkÏ ·pxy€‡çÏñÑêG‡'¸’«½à[w ûÀÕ9äüX]B¨MJ(@´‘+l±2‘ èTŠ)A«„´EŽ©Dü‚”\Œb= 5‚è15­…(û>ýnv—ruÃj±Ø¾­{ °…•¬prøgǧã,vö±ØÚÇ¢£Ô£ºQ² §˜¬ZG ö+àc „:;ÇÃÕŽONp);XíÝïÝáîˆ ®ž« P؉eÅSþŸ*·ÖÇ“Hd`üNiBÏÈ1`Fìt¼aRLªÍŸ+ÄöÕ ~Ïê|ËÕ8,ewýí; ÅËãôòW§GfPߣ»}ýöú~ }¡C*/K);cŒìœZz¤‹&‚2 úÝ‚]£¥;)øOåãŠß2*1e.‘“ºE÷ÂZ_˜H-ÁÝáácl€xe¬¤Ô;­šºZè`ê„QÖ˜m‰l;K"aÊ)KqבÍåɤ¼ît¢ `gÑás‹}¼±³‹“åm<9Áv°Ú=ßzcôÃWóÈp ÛqNàV$þ¶@±å0… „©¨HœšØBÒ’ŠÍBú’¢WDµ ´2´æ¨ ûi6ל/§Wá.le&ÙÝÁpvöx1­À/Œÿî=8BHj ®çøÂëF±ù]ƒ)s×/>U\×]Úö² TÔ&Ìds˜ª7¿þÙËhls€½EÅoíïàøê>ŸŸá£«#<»xˆ³3àjûxû6pïMt,ócðùsÎnwª)Á (Ø_i/:#ÒËLLæ ²âÆ¿u¶ ßÝÅ€Wg8?|„åùÙø‹-tûw±ØÞE×oÆO&oO:}'uÃìÔN;ï Ü—vªX¤mø}©7»^M ¶iæ¦&Ÿe>—Ë û„ÆŽÉÅþþ^࿃ÞyG~ô«_>ÿöñªïAÂɶ›ÁŠœ<=a€z<¨aægÄñUéÒ%©þ¼¼D²@¢ #Ìï˜:ìÖBÏÄ ›"·ÐŒlQ$eÁ ‰¸» ìt¸·³Ï¯nãÙÅ>:ŽÇËC_á ;XîÞnßGwç àê«“§åÙXLÒï`*'™8€ï*ûRU$MH‰c€‰¡i:á!ÃøÅÞ],nÝú-\ žžàòù3 «Ð÷»èv÷°è·G5ã2¶WB¬ÙÐ6¸Ùío…€Rû”}Ó/U™¯Ghd$dÊù““Ū×ùôIÈ'hèö¼y ¼˜Vàf~0jô :¾$¨#âQfEH;Öž¾dùSE¹ù3‡ˆèÅõH§¤0%«2•Å™ÃÅYÛÐTײOöîs{㻬r ãP•¹Øë{ìÝ:À›{»8¹¼ƒ‡gxxyˆ§çàü XnßߺîoGàÃÙ†ãÇ™Á§n;z È¬óªÊL"ú{ÚPxu[ú·°{ÿ è÷ö0PÀÙÅž?|W—gcH°½…°wýbýÖbÔË[ã†/7)‰N©„àæx+ƒ@óÜFÂc¤Œ¿¦øÊ‘0>&t3Tl›¿¦B$U€­êŒY" èîßyõ@j ^]§˜c*×@­´iC€1ÆR75Ðô„ôZ]‚ ÌÔF%òЏ3xá[Ñ8T¡6õ<–Ñ´ù­ rDS{žy/.Q*ž`ôÑd1‹Ðá3{ ÜÛÝÁ·­ðäüÏOðhuŒ“'G¸¤- ·ßݾÅÝÏ€.–X<ÅêüIôü[c3õjË’‘†¨ð ¼µþ¶n¿‰ÅÁ`±«åžœžàüð#0óX¿{€°½‡~kôö‰òç©Î%dí½¹IœË.ú´qqGé”m×^¨T7¶ìM©`r©AU:!u`²ZT/¨ñùyóK ‚0VÇǧÀ‹i~‘iÀñ¤¾ó;OÐ÷1‡Q‘ÆZÐró—–JeqŸ¤¼cïpP÷C{þß‹¸t¾žK%¯Eˆ¼'{=&ÃÈÒµ¤ eqbHhL‚›Øw6iÍ.‰í²·[Ø_láí[û8¾¼3ÇxvòÎŽ€åîƒ1<øìç±ÏÏŽqõô!†8£žºE,hêÔc\?\B>;ØûÌ·£¿µ•§g§8yô.–çIHs a{ÝöB¿5J{‹Œrß4Í0q5©äi6(±¨AäÞ"7ÕG3È€¤˜­C€"×où€þ7×»¨c÷2™4éÊ£ˆOaØ}ë­“Wä–àÝÝc¡î‚Æ™v F:6¤@Úa€T­¼E5Õž¿Õ¥Õt™º6˜ªó·ögRƨ^ÑAÍlR`œÒÓÙtJy:¼±·‹{»»ø¶åm<¹¸ÀGg'x´|Š“GOpÉ–÷ßF¸s»wß–—Xaùì xuZ·Lo`ûî=lݾê8¿¼Ä“ÇpþôƒQ|´C”ÖÚC·½ƒ¾ïAiþ`â7”pgª.¤µ,ª“ªkôƒÐ†q¹DÄyM. ÒË ëDØAª±iiö²ÌÄ“ElÈŒÐõËÝû÷_A¯ðÓ÷Þ;>Žû€ÛW-Ú¶eIÉæRíž'ó2WëOíM¯[17X ÓǨÕÓJC´F£‘ÛJY ‡ö&-]Dã‘QÓ€ ¸µµ…[[[øìÞ>—÷ñèù >º<Á³£oàìé7p¹{ôà-l½ñ&vÞúÀWX]\A†¡ï±ØÚu=®VŽŽqüä]\=?=kß#lÝFØÙgá%e ¦òÖ,|û¼"œ¢×ƒª],¦m›h½Í(k4‚HDf¹ ´t<…¶…!%Ý`¦Ø×ßøÍºƒ¢ö%ÁýüÑhÒéþööQô©ßr-€|÷Ó§noŸŽsÛIDˆ@jˆÆTËW×þ¯)õµƒ¢(¨Uùi.gP Èç?æZ`Ø$»µ?Ç#ŠÔÔ ¢ˆ¤R3*Œ MEäH!,c·ÝVßã­~7vvñÅÕ}<9?ÃgÏñxù Çï?Ü?øw?ƒƒlw ¬†+xÿX‡;ûèCÔäé\Çq\fFrìá ÐÑUÃNó[g²Ó•”Ç%l¾ù+0؈”½qËú« –>¡¢4Øç«f7êhåɉsã Kt{ûGD´® úéÎÎN»S´ËÊH9˯™ŠŒâÕ–²Z;ò—Íé»·p_î[>‰s×ÜlúºL‚e™®”,¡0¢úÆ7$¶éÓ"¨êCcgk»»{xxtˆýãÓ@¼<³oÊ/në+­aç¥&a,Ç^›m¢šôk&fJîw )àI›ùðm@ 5ïÒ{Of„] §Ï_h+ð Ì>ºup¨ÀÜ4-!*$[C]L(á`V"û­a? mv–¡ør7¿m> /ÎÝ]Û}g7Õ¤‰ø¸£¼<1Ü ýãäb“ ˆˆŠ´ä¤÷—Ä*²Ô6ta5¬€Ñ‰Ä9 Q/LŸ?þÄYËE‡æÜŽÄuû#@AKx­Õm³†Ñmý.‰wlÅÊÍM®f0UÉ?SPhY’l`ôµª0«wï©42]ןâÿ{aà+9“!Ocʨ´²YËNrÑC°åE–í¿Ú¢án‰í-¦9ëÛ‚!2Æü©Â-õÂÓ:µW¬û»4ì;WÙ5þnB:{ ¾Ø9!‚ ‚Ç¡ 9Ùä¶X-X¯Y.úÆôËêÚ¤î¿4 IÖ‡e-¯}nh—~÷:ÛKÁ(HU‰HÎ"ÙH¼–'¯/Š„–ÖÀAagñBµ^¨ør:ò“çek2Ä—ÓSÙg‰Æ\xìׯ-+… pm:*ˆúyÊë&Ï_@du¢HY“+^—úSêE…3ˆ.Ôjz‹¨^˜Hå¾ý{& N}~(¶ýdä}Å£b'Û¤ õ”÷OÓ›\ ¡È8Ô„¼ƒ´Éœ:­hƒ§èïÌ,¨¬”¸Ù¥9âÏXç _`DAÀb ÃùðüÀ«hRKð°¿8ú®ðå€ì’ÎSâŠî)s-EþEHr±†Ôž]„dÕQ°ÿ“`£!%•–T›7ÐçF›B ©ƒFwÝ*ÅÝ8(PUq§ƒ“9 ãõ9;«F.£Ï $OZËÌ6öÀ¦ìeŽù+ôõ ¢ò>Y¹/Qê‘ö¸KpCrƒo*×]õ|ûBæÐ/Ð#‹¼z!À—ãµêÞüŽÓU×ÁtÖS¬%¯®‚ÜÔŽÒ/Úó¸‹È9!!†ú»•“~›Ñ)€q?ÕÞŒ(M™™°wn…Á”姨8Þàœ‡ÇPñ÷ô˜NìM³„bÀ&ÔØ ×GíÍ5ùPC݉à¿hÔ[é¦#JƒUË Áj l³ï|CÒlÁ¬ÇOKF*¢ÔÖ€¸ XÜ9xþʼóÎx’ŸýìɪëˆÜŠž¶[4—¥ŒùÕ•'çÛð8܈/BPA[Ó¼¯Ë?Ùðwò$Eu‘´‰TÈLщÀ–D‹­´3á…â"YR‚ é«Z&bãm*bnò*´óûK¼¦2‹œôui„ïÒˆšæ„@ÔÿtAŠ˜ÿ¦GÚÙkÆÿ\syʳ4ÀZQÀîƒ/T x‘iÀ¯~u”5ÛY^ B È  ÞŒ—™‘~Ø&Î3~(L­•°òôÂmŒÚ"«|“Ý‚ ŽýôrRî$"²;Nà(ÓhÕ‚*Q€iôV”ójõ*Ç,‰¡ÍÍuž² A‹ûÍõ4”mQ—ùV§žu>Ëq5Zª à„9Þñ4<‰-jÑjÏVáÇ æt¹ú8%â£GË•5ÿRŒ£,ÁÎù<™ ‡€­Ï|îðÕEñßêéÓS4êå…JÆUL15eW#7>eRÔ&N>F—Ï‚׫oxyÖòŽY*½§ú|ªŠÅõ%PÕiÀÖ ¨¡ 2­±Ø Ýáîññ‘Îܼ’¾ô¥UØÚ9%ÑšjñËÐÖ (=úÛZ8ël@MXÑHša,Èu,Mb¯º<ÜØû<»@ \Ç«H(¶fhÔP ƒ ´C¡œ”Jv%ÊŒ™2Xﬥužl 8ÇÐÉ̆¥ìY§T`ûo´°6¼A5øÄ &¤:î*ØIž4éCÀ¾@¨öüi^©¹¡ïNž½ÿþå+Ø–à['VÁ¤Þ²æTCk×Ó ¬à>ù.˜2¡˜6Ì;rc[ÔÀ ·”?¸ä³'x¥mÄçÃ,ªî ` _ëV×ÓjËC Ù|ãêíµ¶<ÚGø›‡fe8æ@-ªb|ªRÔ@k%æÊ¨¾èô"p4‚~w÷ô‡~â'†WÖPûÎIÀJ‘€]“n6ÏYA:'Æ3Ã#Òðüœ+Êrºþ8Ai޼ä(بóãÔ(h s QYgRS~Ê‘sNŸš×%F/HYÔËðÌ@(Ê_¼óI"¥S©ö5¼õÇ\4„k o@›"ô;kËä¹ÀQ‘˜›óas2ƒÁÃÚÛ;¡©ÛL^i€¾; Æo †Õ|™íàœ¥‹‡ä©Pró:ãà ÊÑ0Ozõºö?©¶&‹-þÝáÙà¼ÆÎ­Äb‰¸ùnj¹ÏˆX¿ Õ6ÀÌÃIÒTñL{)˜˜_®»ù¥Ló*„×q D$í{ ÕŪKív—ë…(Nô¦ÅmÛSâ' hgï/ÖξxðN:øã£ç¡»e¥:LC´E‘øTój#ŒéÀ±8ÄŽåÖ¿WÖ_Š÷1¡G§ÐH§^n9w’bãH4„fWa¯ç•€ö<‚ PB–ÚEŠCxêa&Rc¯5A…××D WÁ9‹HסëÃàŶß„O©§§ÃÖàÙþ .´Ky{ƒ°‚ É™¬S~ö¾ . Hc¬ôÀ9Mg¶SI?ËEdÇHóÑĪ÷ˆw8N†8‹,ºŠºJ5H•¯‹ý§äÞô‚T­ªu ›xþõAy û ‹Se¼>¯µBë âä,Z(A*†¿½Dy}“òäblx~õøË0I×Cnbo¾h0žööî銦bÓÒÊw³u´‰¨âxgó§t™˜lB¡ž¸1n{õp 6ú»¡ÕKÜìt;]4f’q¡°Kž¿¶®ßÈ}å•Y2غn6¬ J_)s¡u ä]o²_³žÀqÄ2ë¤[3¹ ò[zÂöµ$XkàhF=HÈ®˜‘¥BGèvö_0n»ûoœp×ç€>˜M94F„üßµ;pnàœç¯è‹_†ˆ•R1ûnÞÙø3n±JQ‡DÈÓŽ©ðü-T Î^4¯’Š/©Žù[‹V~™+ô)K\ÝÚËÌøè 8­½ó¾¼õn2иÅ@ÔÐ*Ò.Þµ$ÿºYþhº÷ƒÛ{ý ðb[o|á Ç£(QHuͤ¦ÓÆ Ê•gñ3¦¨Ç!=Ï?zŽ`+T./P›Î¢1°ž?„M6~é¹[ó®B£ß î^ìªSƒDM?W£¡rôE¸ÖêO0 î”PÁ$#¨=K8š©*«›ÎÖ£’´ñÅi. ÖØ8ÙëìÀ ]4t»o¾}‚øw#w÷^ÙâN}ï61#Î#4vž¯´áö± 5ÎkÑ×+ f¡e–Úò×8•Z]¤Xj‰ïRç?}—–QC=ÚëÌï‘"f—5ý¼q|å Ù·éªßðÏE§Qa«+î_}ÚåöíÚꞇ†”tð$‘×!€õ̃2&ÏéltÛ"j‘ž[sÅò HÖaÔ™ù…Þæ×­²ã‚¢˜¦i6¡úŒöèIÌŒÀ-¼^H»@%4lHÍô‡Ùë4iéµít3 ×¢Aõè¸ùñí¥µ¤Ù{D¥r­öÞ{Êúç¤A2&M펛zNB·8Ý}ðàõÉàw®°·wD Ä5ës]µÖó۴ߘߧ\ì#×¹4qæÜ|h»ÑaXãɳˆÀåÐÏ™%[í_iˆ¦ rÓKIõ1$4p€Ûœƒ°æZ‹4dÀÙ kÅLi–kh……¥¨ô&}e­ Pû5¤¥ÏÈ"ÌĬKÒ–Û;Gñí·Ï¿ÙðÒ €n Œ“Ž:‹âdÞ§|üƒ¬çßÐ¾è¡ ™ø“†Y»€üx‡6Vh'%Õ-ÄÒòœžL®´‡.‰ÇZîkãPÏÏ¼Ë à)ÿ–`~U”º T™’õ$ŸÐõIÀë8«µ‰ñbQU›…Š‚sîxòêT|/8컉‹íï×ø9åZ¤Aé’ ‡¬2®éßõ191èøüÓ …Gª½%|µóŠx6„‘ázp»•m»­nÀ‰?»cktòZSÉÂ5[H4›ÔeRZORf¡?ÍH¯}<–t wGÍCØZ€//o¤ø¦ Àøoÿpèz``Ò(ÜŒ•%çD‘ ˆó-`óÐ2X¼A›Žåœû×dúE © ›ºG¼ôBk‹ãQíC:ÿ®øixN pÏNâ”ÔoêïZ©%ýQ:*ƒËÓ1ô‘“LòÖR䚨ù®ŸëÝqãoâ_T f&¡Ôo=¹©my`Ôìxëí±!HÆñSà|•Oj™:ãZ¬ÿô=dÁžêÿ‰×Ü‹P|Í/~7ëT<‚-G%ØÉ5I(‚$Lž_ǶsV6¹LÞ·œ^«æÚPQ¢ëŽ+¿Y(´ø’8'´èÙÏZǙؾ£ T‚Ðòî¯å—Ö<>ïÞi–µüظØ,ò ;'¯“ýópy²v‰Å2ó¬jc˼}=v½ÅúÉ÷ƒïÜ{Á˜Ÿ½³ædêáåzÓµ«Ø8Gq.õ›}¼µ¦E-)³ßMíÛªX®“£2—ˆPx]AUn@(gðú1þµ’Ôè,–V]„Ì" ;)tàC0Q6ºPœÍK1¶¶º#àÅ·ß(è¼u¼êSKpÜ)4mVFé7rUé5Ã?þ<é ¤ßC¡Ã“½>]ç„æfhú†P`º¨÷•|w1†¯ñyÁä¨ é‰¦9 S‘4e \!JEXÜOI}ZS‚ ~ŽªËNm¿¹þŸy²™kgTÂÊ¿…‚9Ü‘ Ú®Y(Ùˆ ”XHW='$ëèˆVµÌ+ } Ñ„4ôõAxë­P·©ÎÔ y#K6­ÂÝ1ÖŸ…&Ë`Nª•ÿ¯ih¯qî p\¶.²L^‘—ûù$V4½®è­¹‡Æ,ø‚*Ž®†×¥DSås1|E¯[5gA鮵èIꟉÚÜ‚ Í ‹Ìj›¸G"­ªÂÏ–ˆ‰_—As.Ðû2@‘¢X¬ðÎ[Çß¶ø„€ØH·n äªÕaÆþîß|òÏÛ¾‰´i@nÖwpóéZÔîÄÆ—…u²±ñ™ºÆ¦BÄV6Á/uóŰây ºäpDm®¶BÍE¶AŠðCh]ȆBC h óÏQ÷iÕ¨žšçᾟä•>Þí.=z÷ÝÓog|B9€/}inÝ:%ÀTvÅðŒ‡ïÒàäHø±³ùEý¬¾»@ów&lòæ³'"é8|O¦>è`¿Iëþz’–ÓK krƒLä`tk2I(dh6D¾Fůk4\Ï.k¾hÌ$Á¥³²füL W§2ç®´¨¹æê{ýZ©$CçAÒ/ž¿}ïÞåMmËnÌ”àýƒ£@BfWÂ5c0DŸ&oP’¹>§ø>oꯣ0sÞÞ/äŸV³±&•FŽ7Ë/ˆ öçtYÚB>eFx½uz.s™ÿ;‘‰‚ÔÄ'6¦Ç¿OW̦nûrʯœëom©ß 4 Û['?ô?±zm €¦tqq°5éëÍzgnð6D¹„Øiþ‰iÆ æìqÃ㈗¤Qà 35&¤Á$ŶÎf›«2*à A€¢Z2©9×<·´Ò®ø¦[Š^¿Ï&Ô]ûŽAˆýeš…Ñ€)éÏ2Á'˜æLcÃõqjB7Rõža.C“ª:A !¤ G7Õ |“!Àxö¶ã°JYÿñ¡àpŽýUSߣ“õâÆïíBi0{ÓÄ—†^|UgÄSE ;K·ìbIÉñ¿ˆD#PšRxÊü] æÖwJA©¯5bjqŸ%Ùçpº%XhATåÕ4¸‚#Í^\j5aQÜ‚wXÊâëÚ°xôâº*b€®CXñÉ7—jø€LêÿÛÛ§%€ÏóLL_ò­,-ýµóýê•ÈÒ¾ Ó‚h¦çÖ¸0­:;êÀ³¿RŽ]ªß›Ló½üz–-%%ÞÂSOÍ9ëZ[ÑôgÆÑL¬?7›Gš!87AfN€6>J_‰Úþ4È¡éèE}‘âPà*‹ŽüOCCÞ1I`-ú×Ï|o¢–«'èzp ‰ó¦ÞÐ@- ª %hÎ_MýÑÏñŒ«uîoþv‘‹ÀÅä¶§Ùpio¹±9ÇâÈ×x{AOQV­Ã( dÈy½ÌK™)Ï¿~¢^;Úž[Dbà  ‡U—2þ;šj Óäõ©€b(EKõIã]fKÄ_Ou#˜Âñkg¾œÎèùó‡Ãö.„u3+Ö™Õ¦ì.ð5 Ó€ÜPøMR`ßüUm46qÙ,šX 4õ5p:¥¥*Ö£Ú¹›Æàé ƒ(°ÆÛ7Ùýw"ðŽi¶`Hµ×¥ÈÓgN`“¡žÅYPM ¦ª|¸œÅØnB̈ÒuàÜL+ð€¯$ÿ}°zâ®*šÙxD5ê:€awذ9h Ì›„¯ç@‘-\g@Cõ‚ü86µ«Ò¬úð†1¶ T囨ôhræíXø›b™É‰µ•Pœ¡$¶i»¤ñ|aBÝHÔαTãØCA»Ûû§¯ÈôÍ·—]—W´PÈ~ºü…>½Øø|Ó†“„8mc/À(qµ}²¦5؉îT OpÊ<Æ*@Id!·€¨Þ*çýélÂÌ(ó~RÄĨkpóCä²å³°v­a\ã½7å æ@Pã@Df>DÊhyÚ¤¸;°|AõÆ>ZF†þÎb"t{·Ž›i¾I °:99Vƒ tYʾzjfɹ˜fWë‰Ë\Ëí9—書<Á‰|fžÀh‚Ëð› ¡.N #“½cj÷ó·ÀʛҬ—´‹Z®µ(¨ýñÍ«§5ïùIæ´Pm„ÈÉa›¿ UHM†¨'ÔiC±ð_B7æ°VÝv úú!€îÁƒéÂP[â°†f.7þì(Ñ O+ÌÄÕ– X‡È‹êØñ¡žS½·V@qø®€“ —ÆN+?¯ªS µk\ï@?6Œ7viÆëKËã£A¨nï\œJBïŒ%·|· 1œAY*RÖ\ñо`ž,ñ¦ñ{S!§x¬.H‡©„;yàc]ëMQ7ç·ä3é:­ˆYhê6j%®oÓ„J¨qì­ [èº0lߺõúqÉ_‡ wD±)0e˜A 0Üþñ60Ûh/×|¼ewªp6#Í–ó —ÊbªÿNŠdY?®¶Õ:,*©è+Ûz\{*` :||ttôÍÕO¬À—¿<„Û{§#掗qó+¯žZW˜.›lÀˆ# Òº¥rð4#pSOGóW5´y­·¹TÎK]÷ãé.W\z«ly5 ¶øªVß,åê¡qÿ°›…F„ù™äZ;EÚKaVÆ=“/J4ÄÖ Jöúä¶åè~qŠ÷ß_¾v!€n ÆöÞIejGÏ?O®Q¬¿$\Öˆÿ©‰&1RºèCñܲ”Xß`}l¼f{uÆ:=è¤ ì.4=A‰Öä:¤WhÝàšúìK‰‰ï™Je©©K€™äÙúçÎÕxÐ|0ùtH5•…ža•ZÖg‚K=HEôôç¥ SÀZ„Óÿæ·{¸IÐßÔ¥y¼½}È.º²à&yv=ºKì^×vjëú;õ7Va€ÝJc«0;î:¨×ùδ1Mª ÐŽ´!ç­È/-{’ø? 0Ï:õòãããB1£Â4±6ÁX‘çÎè9Ö È3xy®½V6Yý #¤.} Ü‚[hDu°:½–jY©TìÍ …A¸Ž8UØœ#€› €uK!"€ùߢËú‰3©%¸ Ý3„nbÞáÍí+ÊáÏ~- Á| +lÆàŒÖê¹l&—}‚’Þe#䨼<ÈYH¤Æà’l¶ØædÆòJwæžÏ Åº ™j†¥¡Ù/3^¸&XÑl5¦bÞ@¹ûIÅü!˜ˆÊÆÜÁ&„Wß[“*Ý×–ïœ[ÁJÇíÔ‰|LýÍjܨH-ÁÃÅŇÃÖ˜9òûayÝÄ4‡ëè=‡U¢Øü#~͉:¤=ij°ÇF‘ØÃMmÁ ?Ž,ÁBA#O0¯Q›äÍã#SÀBSØ¢ç–ä\Á'ÈLWÍ|sDºÅ—Pë hT`Î'ØÐ‹³%³eÍ/ ž!N‘eh÷x‡À͵ß(Z‚¥ï޹ "hнíÃÍ7bqÆWоê¥ÙVéÇ4· 3¬´b0* d:JOPÓ4ðIú=’ƒBÙLŸm ?ÎÈü˜}oÄpâShµ¿ÈóŽdùì\¾ÀÊx·ÆK«ÙJÊ1^þ&,\%—Ðâ+Óƒ0ƒPd†/õ¥œnœKzœ×O‡b’P·zŒþw“`ôuo|þtEÝ4€&^É ~fØòŠ`âýDîåQÂÓ|+{ªÞÌyƒý‚•ä‚ 5¡°¡­¦‚ÞVoaœÜ¢9Šî•0¢€µ7OæÁ¤”Urý¨5ÊjynQZžüÏjmþ²­É çÈ1 -ú£õ¹XC™¬‹œ¬`}ÊÂ/?áC,õ[§¯­ÈÿÞ|p²ê:”<ŸˆÊÌç¼7þ>˜Œ€¨>I‚|åy º\Š–ÁµÛRo@Ý#à”¯Kz—Yè…I5üÌ6•Ux4Õpüò¹GiS‹ˆ–¯QˆÉÐ\ëW‘¬1&ªY¿ù6Þ”4_‚,Øìø°§oõ<ÈTK抜åW"‰ €°»{ ÿë enÚ {‡+ûø 1v}s¥¤=·èÇ× ~´ØŸ†æ l°z7Ø "®¥ŒRàª*0´^¬õf• o©ãæÎÐÇ(üßDßß#TEq,n'`úÍŒ£™MÚ†C®Á«æõ|¯ãi|ö0°t!Ђìî¾ö€ß{~"‚(ì|Ýâ)nXÅÎ+¦ I(²u£ÐôÖSféÊMæ"‚ˆ0xm2|:AIxâ,Xr‡ãr]ƒÄÎr%qÀæîE×Ö§J@Y×$íLÀÚŒ€·ãœº&í’›çrö‘–°Iso”¢¯åk[¬ê½æa ÅM¾qnââówN¥ï–6í |è ÎÎ÷vMÍDT ?ÃàXx!w“GZÜh 6Ó¢B²‹'CE2‡0¤­ÜJKé e;]`Cö5¡´èMºF$dƒeëUV+¾Acš'[†d£·ÑˆslVú\î¶ÖóCž>m@2ÖOE޹ëNGa°°BSÀ‡¨ëŃSfn”ú[™¯k2¸jO) Å3;À(‚‡ áO·Š ʦù0wÕ¼NuÊ5êTàlÑÏÁ4†œJ6ý㬠^DŽKvÙFZÜ5âúk#£ëƾ¨ë®4^[:¿ºwïF[_Jðõ¾Þm-“$«Ì,ŽÍ¬+Ï<ŸgZ‹­~ÝñõV6 ¥¯‘GËä}‚^ RMâqŽ£U ìáV. Q«7 þ.*M)Nkk©ˆŸŸÕ à6&Øhýó?®©ÞôsÜÃÇ2\˜“:ûšôü!Œ\Aùx—¢„>=9==¾&Íòê€?ÿ¥/­¸ïO‘Y·t;nS±éÅÙèóå\íÇmÀö-Ù%;G%3|C u<~C6X3e(*‰…õõõ󜒓Ì`dûns~lt)›˜ymÞù×´B€9g•ÈA9âªHÃdÛCÀñ]]]Þô~¼I`š¼·RYæß7‰¥ª‹Üز2óš‰/ðÂTLDHÊÅñ;…yãЈÅCc æj4.SŒaHÖãeÖâØâ5FOÖnQms#\•ªø: U#°¶|¸€õ×Ùø²æ±¹õ2§~ì½7»ùõw‰¥#é9ŸÑüú¯ÿúðÚ€´ €vwI†jžÛu…·\ÿ,.‘œ ˆ4è ÂⲸšøñuÔ(_þŵrƒ90<@ÂPiJ1u"…ôi¸vi»oR„Ÿ.F/^¨â“Ýä-/ïntj õ¦.?kSèOΚðཬYwëžÃ¡m$<{Í)¾êéä&§§ý  C×Å>Ii±R³6xK8+¾ŠiwM¯¬%øŠ*رҖíÈ=ÀûY¶p;M1ûÑ9O6ª€b{[R%¡,Á3‘ «‘€Á±Œª"‡‹“-kg+v¯, F–ø©½3ç6O!¶áˆÈæ|€8zýÍâ¢×eõÕs¤A“¬«ðká =çOŠw’äÍyz\XLãºXKEd9/·îp>| @j –çg§´½ Ö#‚f"ñØj*±$êï⋇KXÏÞHÿ¨¦ôÌÔj¥Uƒ~6WºÍ¿˜¶>¦Ð›_<ô Û«>4°UXm:iúß"?5K nÐÛ/k§«(34‰;U=)J„¢³0n|‰²¬JM$U~";?¸ì¿DBÀÃpã­À7¤–`ZÐÓ¡ëÌ«â.¥ÖÂ2JxˆW4xˆÔZð7}ã¶c„$– ËÔ_¤& 5Z…Mm“dc0Éw¡Ïð7˜4IX¢FžþÖX€ëˆ×ɬ•0Oׇ¤šúgf=ñ¥p´·$ Ž‹.•Q‹8—N“¤°/á%ü /ãC™ñû˜™š³!= ¢É*»äØôšdKÝd_Áž·çSz)D¿§SÔÄÓx6É3(ñ䣄d Zw¯œW_N­­šš|J_WeÀä ó¿ðqžOA|L™ 畞1¶–Öàt"G[Â7R Ã#àf[_švvŽV¡ƒÈBUs)bɬ.°5¿n*M­càrò ßË"tð«k ‚+_6ô°rûð:$º rÒRÔ“Ž¨@!5êÆoµâvŠ-ù5×ìÇëm6ïz¢éXÃÌìb›êg©ž` ¹ ÿ¤)>‚Z44;ªû¨Ü¯\ò-ö«¼Ô2â?îwŸ¼ö µw{»Ç+š’S¬‰Z.â~Î|îü sA*zS³ÐT) 5­œªsHf½¾/‚a˜,4)húDvz#¸ u£×2ƒY0³9‚ ¿YI»o&š>÷ ÂÇ6BMÃÒà‹šÜ¾ÔºÎˆr´ÊšÉF@¡Õ p³€/ƒÞƒ7OVÔù$fá&é “õ2(`ÌL£÷"Ah9uA9…•œÍÇŠª„wU'ÃJ²b±«¥dÍ)€8!‚0mäBѦZIb‘¹sOìç[é@¨I·Õ祬‹H®É¥Á6¾ h²Êp4÷Vñ"’C¤úPÔ0@JÌ} ³:×ñ`БÚôZ!]Pë²æêHQmŽ‹¾V LÝ*L `µØ=~íÀÏ$ð™;GlyÕ :Ñ´¹-°ý¬éùƒ !‹±ÜÞH{Ò‰åÖ‘RT µèÀ¦CÎõ3Ô¹­ÙaZYØ÷ÆÚØØŒBÓ5ª“5ǶEÌ­ù¨—Pñ9J(um?|®ÝüssöÄ2øfÇÎËyHáñ¹ÅÃ` ¹Ê·=˜t¦¸ GyÌB¡#Ð/n¾ðÆ @¾;·VD++K/9¦V™Aõæ­ûeÁ¼&êô<Ë<Éä ‘Š &Bû–EoMRgL¡@³HeÈz©G`¤Æ¥Slj7¥4œðºÊ¼¹7/s V‚4<¿äzG©ß :”ÉsSI$¥x¾¨‰håˆ4b|… JÍ‚RNMœÚa-Ÿžß‘„‡Õ*ðëŸHU?«>xNÎA !Š…%]m!ã×Úâ’â5ÒyU‚g£݆„Z£PuâpB"šµò¬"òCƒ”—îY.Zªà˜ /*/ÐØKêˆDª-‘bŽ¡ âw)R¢ÒBb=´K ÂÏ]ÆëATyEZ¤ 0DsÏ =èðÙp8„ê4X&,———'¯½HrµXñ¢?0 ƒÑRµ)ÅÙÔë<’î-°·zs‰dÓlyùF¢éËï¬AB•iЙ²¦•ç. ̯U¡Ê B| Û$ÅMlåíÝÇŠ”¯P“Jq‰g¹%v +Ëñ µXÊ„’ÐHŒé÷ N®nß~ýC€ôï{Þ~û»ûÇ4 #í­<½ÄâpÑ 3Þ”Á±ØëRGìr²öJ—aÅ|­@.›<²~›&× EfGV¶kÍ¿ÇQÏÌkP`Ä×O¿ðiIQµé¯auJ¢¯,â¸ùÅù»4ÊN̶mÞLúV£‚ô6©˜z:ÃðüeìÅ—ÂÐÿðRºÅ…„± 8zòGêò¦‰w3oÁÔM4¦&­w Ådc‡£0»°Ë±Uåä)›‹ [ú žíu—6ùyaà5ÝœÞôzFŠ·Ù¥±&xj¶_êY…šà+ Ô@ÐJ†`B‡L0j1RQ@ÝñßyãåkoŠû~ "Sdþ§ʃÐXo³Zi#QA±âŠ‚ÖÜŒ eó•*¶¼ØJ‘)nÀ¼¶n*š]ì0ÀÎJP³Š\Ä@¡|4^+Q‰•*ЂM¡Iø–ÜàÖ¥”™M®á¶fß5Sß®Q(P‚X¤ôì\)zJ¤ÑG<Ò<~exâã±ù?ŠÔº-ÓcCLBKGøêW‡OK0ÚÂýýã\KmØÒhâ˜.I+‚ «NÅFo¨Þê=˜ŒÀ°!¡X½Y´úܘt+ÐÈž˜l+±›±›1š$d4HC²æÂh„H=>˼ˆÚ’ßÞKÃé ù—Ê!«¨‰·Ê¨hèåßU˜h„\$`ºÉç"ô›iÓcRü±b4}ÈPj.ToB›¼àt’[ã$ÔUZöq„ŠÄ9%˜c¡1iÛ) Œ’"%¤†Ø²Nv7º41eÅꋇI ÿ©IBù=ü‘1i€i†-M`®©G)ÐÀ0ˆY°jІ|S6 ¼ƒã(ŠQš‰Óõq \æç5D‚·Ö½^3™i,Sã}2QÀÄ“§Ï›À‘Èåèlx"…³ÁÐwL"ð©1?“~8=Ê[ †¸‘ƒ½!ŽõL¢æ|Y LÄsºbr^3M3ÚPWM<­×8HaVˆô1…¨ù ÚÌ¿— FEIªb$¢ÃOøJ<É«q¿†ÆÔ cOðœmÊ'§iZ9"%I'ë_ó7:q ƒ— »JÄI(šé³ºÙH<2’•ìT#aËS¨8¬›fÒŽÊû«êVez…FåTàØ€$Á,R`]G]û9´Iü¯ê&*x¬6yèB¸JÃê¯!GÛŠ™ûÚò5 _À;{‡«ÐM=öEŒÎ¤Ò2ªƒEL:Ð 9‹e}º‰×^}j^=™ÁÄ5YŠ"1ÝošÄ ²§‘5!u’ú¸Áì‹ÂœëB…|æ®52#³~8 Š«¸žäå/[6Ó ¤ø;»ÇÊ*Ô …n¸£%ã¨TûT÷#•N{ó ¼lD\Ó£ø<ÉcøOA`ê¼ÿè*0@;ÞU,Y#R’1Òl'²G–*5¤ãHï•hÀV–Ï}M^u€E$FxÄ‰É ”®¼G+Žmå1XgŠx—5•ù ¿HŠz©~fÇ:žÈ@÷8§2jV™=ó‘Í ˜Ïœ²’ÏL×02±õöêHÅ“ˆ 9%¥ÃÃÒ Þƒ‹u$áhÖ¬A«y” 0u©ðÆÿÝ´&`î¤GK$t!‹P V_¢ÊÇÍrQ ˜ ˆ=Ø9¨†áP>G¹*Í”çÏrŠMšÝ¡4ÏÜ»ØØx9ޱ6G%ÌÔ æ17m&sòg{ƒXêw(?—´§S£¼QÊ̆"¡ò⨫®œùüRâÕó¸–_U 9®ŽGœ$I¾78ÅU Ó¿lBL'ü$§ÈˆãPÐa;ëÊko~&^׋Û;Ça‡‘Y ¼uzC&¦( ïÒT¢p7x''ŸAÕô³PEÀê.*n¬úN†ÕgŸ×à¾TÄ•ÐK\ðÉP»ˆÙ¹=ó$hÉ4‰„'ƒªOU @TÖß©„ØÍËΦ ìBñœXHCI.Klç#E”(îD²÷ ùdý@á€ÄÔÃ;QÖë³™è+{ée0&äŒ\àaê±Xºã—en<È3ï¿u4„n%"ybJ´¹2¡@ŒQY]@ku[ðºa CÜ­–aR¬xú ¦þ8†Ã[Rj[ïÀ¾ã­º‘ѯMÁµÇ ’Y¨n”KúÇ ¼|ë{ÙiyŽÖwM¬ÙÁ­ëkŠ”%õ¸%Ïh‡DD©hëBÀõ¯tnü‚ëІ©Á £ZcˆÇ·Y ÛÛ/¥ð¥ "™È‘œ`kìI™ W c!èeòh:Ôa›Ð! ù“^D|¯!Ä„P´Å’úiü©H…¥6¡Q¢*ªú†ÔV†öP1ÜtÈÁ•qJ ’TÈ @ƒÅ4m¨ÔÔc¡üzêê”ÿ±"—8{APJ°ÔJåÁŽÞ"¢Š …{µéÈPÅãs™‚µ{±è¬¤u“ªdJ]‚ÚËÙI.¤.åš5×cÙ „ ñÅ´Àø8KiE2Gb*¡TËP]fxZ?x6……ׯWB:è¶ža^vâõ5ËÐmÑ8¬šÁÑ“SÔÇÏ5ø‘BfYŒ© QäUÐ`9ÿ\ªÅ "qCB"£¢l¢Ì†øY&.ÀSÁ6ú—¬½ûäÁ‘Ñ𔋿èÙ×X°JKVSŽE×ÈÃQl<‚ˆÃ1›"©b¸ ª7®÷5Êâf†¤ÖmÐVŽÉ–I )OP R4bÄ~‘dù-£1Ô­ÝNsWYâ… \ô Ò6ã±1Ðõà•¼”™€/3Ȳ½xšã~Ž|¢Òo*~ã}a À$X%8•bcµ˜9ónܯ+©1ÝÈ14Ð.Jt/r£EU発pcP* k©…M*9ò‰±§Ùt¤2`Î,¼RC“¦^?½”è¨ÜhÚc’ïùÍÓ‘{eD(~ͳò™³)XÚëÈŒ•ОãØ6QY(Vù¨† Ybœþ›&äh.—Ñž ýËkzià{ú*€ayùÞ°Ø/¯ 0jé ”„¾L)½)Ö ZJH=ú§ÖbRÖ¸Ó,µê¤:HÎéy°Óv4ÖŽ¤™\J^;•ƒbyòr±‡¸+ËÁÐB–Ü"MÉEJY'Hï„ ˆÔq´V!í"È›$LÖh´†eT^–()\Ë©FT†\\¾'ÙüMÕR¶{Ûç{ZP›‘ÿI—ÇC¢¤í d…Z•š ð©3ùº-¶]…€3ê jc#֚ȵ½)ÉXÀ‘Œƒäª0Å$á ™ ìÎ^0H0tš_€ÎCNã&å*DzaUr#bõÈÄãóÖ”ãE·Ú¯qÞ ¨É²ó„B›0• AÈãö‹ \p ÇÃü ä¨Ï¿&ùÜñÅQ!Zf¹ƒò˜t‚µ…~<ò¯µùµuCq2Jâô¯(C÷µ ĉ@=Þ{™{𥀯%þÖÛÏÞý:D@]†úŒNîHŒú!On%…8Ç÷¥˜BÚ[Ie,+©ÒZQÆu­~jAâc €%m^SOÅLÅ|.¥ÅÆäS|Oµ‚ÙàzŒ%M¯CY rì¤äÁâæÏ‹;X²Œ›×2z%j)øÒÒ`øÒçŠÉoÌ7lnjAAz Ü­yâ©y}I«óo[×ËbÉ7pÌ}‡nñôe€/Í|5žì°»ûîÐucÂfà¡ ¡Kž¬g”LÊ…H”Mý”t *±æã-[å0"¨æUqÃ@j'MœLŠ1ˆŽýu_€ZàTªPÕ~eC‘±7mbG‹šŽ¿*O°F-øð!”¸óz4‡QJHÓóÝä°à5®’f?Ô|ºþ$xzì½´É½Öæ—¢ Ù—TÎò}™DB”±Yö]X ¡wÝ?y™ {Yè~ú7óá¿÷=ßó`ûìôÏ ¬Y 3 ÕbTID2*HFÁXò çÂ%JÒÜ¡"¹ä/j¤êÂøÚqƒëHÜߎnüXÞ8ß=èWö’©iw»Én^Í“L2T^CeƘK"<¹¸Äž]›¦}GÍ_]œ,²¶·8ƒÜTÈ&RßKÒ2tq¹¨Y’µËhõ9¯!@—ýäÿ¢¾%ëIÀ4MµV«3‹,]6ÈÓa{ï¯üüï}í`³¦Î×Êäõó?½ûî/~ßw}÷,ÏÎþ­»Ý]4ðj„Œ¨™›ìˆtæ¾ÿãêôb¯´è¨g j/†>2…±–;Ât&åiË M–i§ÜY@¶ mC0ñdÒÕë‹&`~B9}x<ø+ž]^âC΢ÖÇüñ~¾[`û5òfÚxãOßÉMIVœ4ÃñuœÇ¢‰ÑAÌC:39Êz«§,@z­ÅE¢ô'âAhÈÏV<X†¾ë:ÃÏ<Ä»;Ð$ÀâggqÏø&«…E†…Nºއ՝¼{uøÎ?yrüßXF¯?¼LØÿI ZFi€7ß|ó­¿qkï+X~ø€€«Õ0Ô…ÆE`"á=†#T2Áý à}.ñU |Pþš@¹_d_G¹7\ä~“ìŒkZ!v'ëïa2€(˜H èá‚:üáÑt˜™ ÖxŒ+‹%u˜ íØ~íÏž q; `Ç`HÉ åà–Ù/‡{ÆðCnòÉŸ¦¦0-d+Ô…nA„ÓÕðþã•üÈ?zúè'ÜÿÄlüOðÖØýמ??ùŸŸþÜ›÷ïüÚð¯P÷ˆ–¼\íìÀ‰D‚MÅÝ¢áñD*QUÁ¥šìÛ´¹Üšz7):Œœfý*t/3Á·¹ùH(÷5äÿ P‘rL$ EAûJÃÑ3–"쌕’›Î`( >42F м¾Š¸4Ü•šˆ<ËQè–lbð$Òʰ¥À&ïÏcùj`†EßõW1ÿíp~þ}tôìÿ€¾¢œÚ'íß'‡öÎX6<À~ñÛþêgE¾òVèÞ¼\-E8t]× ££0z|»ýÒœwŠÍ5D4•Ó4>¡"q À¢\WAå±#Ñ2yä0ùahÉ8Ë%” RÏ—+¶F‚âÞ(Ø¿ Ÿ¢ŒW×a‰€~|Œßà£лÞXొ\Ä+©ãRKlÍyþ¦×oMZjÔ( da•r,7~,Œ œ[sÇ÷‘X}2%ø¸Jc2D(ëU,¨ï{8Z-ã½Ëå_÷øøÿú¤|¯º¨Â|ñ‹Ÿý1à+oA~è@€K^‚@]×…>ÒtI-(nÈ  ?0UÜ%C@¹‡2̧ éI… Vö‹Š0 3cm´n^ÛÈc6x<öP¨d&c@Zˆˆ#2ÛyZ`|m:,CÀã·bÐÃN¬ièWàrXB]:á\@”`}*$ 41öACýˆ‚Ú!s vcçÐÚPÔ¡y¹=™ŒËh¿%£8ŠÔD¡ÞmA›Ÿ©iA„ÐaI„qzŠßaà£@³+8ÍÄŒs2få´+f~ ¹g&;ß´,ÓDëW!PL‚’™ÏOºlˆ=¶ORs< ТïÂÙ0­V_ù­§‡ûUƒû¯<(ÌWRXpzzú«‡‡?÷Ùw~uù»ö»þO,(ÄlAtm-º”Þˆ I6“òªf2­ýãT³O–'³à)WVÒ]Q Õãêô!4¡©¾€¼ü"Ö 0€pxyUôbå­Á"g¬·†ý³%½Îléò]QqGmHÄzoV3%t…¡š')ªeX×vd±Žœ÷Ÿòý<Â}Á C¿èzáþOÿãåê?üÃg‡¿ô*Âý×ÍTaÁO=;úú/ÿ?}çö7z‘ï»Û÷w–d˜ú1,H-„2éý'N æÍ ¶\òÊ“ %~]†c+UvƒI~ŽÅ-£ð²‡@¦7‚@à”PMP•ØŽ†‘8\^á}™ @9lÃ0ò½ý:¦_ÉqR*Îù}‹?5øX¯ùOs"5o¢â}.:Wù©ø?9‡ <¬u]Xtáx~÷ý üÇ¿ûìÑ_\\½ªpÿµ4éþþ^ þí£ãßù¹Ý½Ÿú3]·³Eøs·©+^+K|R±!c“Œí{µ¼nQ±xçšI±DEu¡-7ö ~ªÚ“è*ߨ܄’'ð8ÌBÝ4!€£å>ÄØ=Ól½>m8z›¿êÑ/åÔdÎhÌ¿p4#•Žªß'C²Jç1Ù?ËÃñÀ""¡ï»s‘Ó'¼úòÿùèÉ_~|ùüŸÅýò‰(áýc°AXðkGG¿ø…w~a!ôÝ·B÷ -yµu”Ùf¥i%±º¤§ÎÄ¢×Ô{ÐbQ¨\¨dtøt-°FÁk5ÖdX*w%±¥ÈNÜŒ ã)Š+fJ ðì*†±î ~/Ëð¯kßõ`ÿ$g.fóWe»9hDzL¹zŽÙ¶ÓŸ“X¹Àhó•^_`;õ,‡U‚û]×1ut8 ÿÃ?Âå;ï>:üû˜æÌ¼ÒpÿÓ`êlÁ³ãoüÒÑÑßýÓ÷ßï1ü›wûþÎJ@,«A¨*wæÌ{"ÅHO€Á…A«øÀ9ÎgbHèûîÃÙÑ0üøo=~úãÎag•¿¾›ãS`¦°àääù¯ÿÊíÛ~öÉŸºÝußÕ£‹ˆ@”RáZQhê+ít =¦7 yA²ÓƒÑiQJ2A©¸cÚ€)T'6wÐ@I9†0v.—øPFЕ†îa~vg¢¯m• O™€Q¸PhŠë¡GljïñY¦t kôŸtŃ@dèBßq V?û{çôþÙ³'ÿ#ÆÒÝOdã΀o>, úŸ=9|ÿ—Ž~êOÞ=ø—ãÏÞ[t÷V <¬€>P" S+q¬'fžv³ô¸g0')¶ÚÁõdÐ@ ÈÄFôÖcæŠBBQDè¦ KpEàp–dÅdúJÆ`Óê¾Òs‹j½6q¾"ì²Ð‡~ž¸.EXa•y¹`ùET›®"]SN?±û}ß…cþÅG,õ·>þ‘³Ë³×îª @a:ðïÿî/Ü¿÷“CX¾ÿ ëËa9,A#PÜ{ó µd·âLÑœJ½I1C£/, 2³àp¢F˜§ßFœˆì Ÿœ$`ÂáÕ€Ip{ ’äºP»¸Çóü"Žê.‰Ïðçß­$·ùñù•ae±$Ìã\¤ý¦‚ž%,ƒp¿èú áËÇ<üØo<|ü—žý>Aln:,8<<ûµÃã_ݽõàïß"ü‰Û}ø“=…1[ 1,P†ÀŽ·%ÄV¾ U8DßänÈ$‘1mÍÿ›4ÈI ‚*ÒQŹX)fŽ–Wø#ÐÀ¦0ß“ÿ–|LÅj>z¨§¹.¹•xÚü𵩇yŽì¿Rø)¼þŠá‡Ðõ„. òKßX­ÞùÚ“§? àòÓ÷ÿØÌ„?røÁ/þ½?uÿî?íyõoÜë÷Wq R/zâªv©2ªBƒ5®×1h ŒõËÍßboI+õö¦´ajsÄ/—øb°U¤!è“|é”ÙŒäJEU,÷`Î(†‰MÉn.Õ}}dšmuÙ«Õj ®}™ ÿòÑÀÿéo>~ô7ž]\<ü4Âý?6›„ÏŽþߟï?ùg[è ß§ë·.yÉ,$cí@ §B¢©V€œî¶©HЏ\àk†‹CúµøqP¾Ä¶ÈŠ@Ô…I4Î=<–ø£@éý2^­\B#)Ž7aMuü¬_KdTxSX“=½ãõÿ¿½«‹±ëªÎßZ{ÛãñŒñ$vbRhƒBþ©­T)<”çÈ€üPÔñÔUˆ&D-$R()}j+QA[‘¦…¦. A“8B°âÐÈ8$!MÒ*ÁÄcß{gî¹wæÞ™{÷^«gŸsö9sÄ;ÞûÁ–åñߌ÷Úk}ëû)‚]êˆ.j0ùœxQ/b·Y³á½äžþæ‘éôÈòÊÊã—r»?ëPú4Ï€}8˜8|àà[®û ÞüÌ~2ïËT0ñÞ1Á0eÄ$ÁЬåTÙ™¨'ø@¹:¬= šF$1hGÑÌÎ3 ·+yK¹ˆ84-û3&L˜qz}„S t0ÛŸú|[vï$[‚:ãì?…nI™aØ("Úù4 ©-¸¤õê×Ü}x¶Æ*rqõ6¦ölžŸ ìoБ:€ i,¬.?î¹z÷ÂÓòÎEk—<ˆDk’ˆŠEAåÖV€G%4ÒX8´Õh–zp–Y|)™ÚdÓ¸ñ±¥h:Å2ë4[T¨3Æ”ÊÞ›šÜûrŽoˆ3ùP¡•k¡õòׯ>дó4kÖ/.¿sÞ3æÌðHüË«äÿø{g{ínnž‰þŸKúž:€ŸåÔd¶ßɸe‰pó™ËFn*LP2™1 *xxÇüÒWwbò¦&»fOÅ.$dŠÌ]ªC6kµa[v¼Õ­ç¼W¹-éåú÷øiA£küz¢¦¢Çƒ»¢Ñùýÿã¿ógŸxÏØBk+V QHG­› †\7^@5‹H˜÷½÷ª*žÙd†sç9³á<¹Úû&“1{ûù¢ ÒIà †ÿzÍž¹“p|ýBföig攘¥ Õp¡Ú§QæX¥MW‹ƒÔÊ@ä|Üt¾UbU³P/¾‚ПºÀ䈭H[Ò¶$ç†äáY ¹ív¾œÛ›4am t"'g-•{1ÊO›Ï;ïEA6³fMd¹çåOëvÿ¤;ÿ¯CÅ^*V!`轫Ãçîä_xÇÜngHsží¶©8Š(Yކ5—#/êÕµå ¤qšT‹ñxÚýT.úìÊéFÀ><÷¿vhnîKtÝÛD¥%™`©–ÓRƒTçÛ‡x3ªW‹1¤[ðÊfDŸ—&¡Aî¥Ð Jß’”Sƒs¥ˆ‡ª{)%¡Gcßš£?ëâ—辊 ³Æ ½ rÕ¿øn§û{Ýõ×§ýv*i,¨Æ‚_¸?|þ׿Vä=ó&› "#¯\ˆ4ØW›˜ HhØfǺá1‡iKÀ&"lÀ)0¢Œ8",j¬Ìã`6ZÃx•iG FV!›µ xÑ_¿@áõ^|–YëÙP_åè©Éô¦ÿ[Yý^ÇöÛ©¤Ó äÛùðÄ÷ö¼áî·I¶#c½a1;#@‰I•*ƒ²І6€¢B@ ÖaÙ~SI:âP,~½„`¬1x'­­Â¨C4D€Ç­½µ¢÷¶¤Á!Ÿ B÷C»¿¬úûw:wnnnöS»Ÿ À%9<Ó ¾9Èÿkß¾µÍËÛwgÙA†!ç²!Ž">¯nÉþB³P36ùÔ &ôr/8‹à ˆ&‰¨¡Ø 1êZ2û„ü_r¨¶Ú}!µ™5k*ã¾øÛwº:7=dБ @ Àw¯æ§ ?ÿ¶ÝóÝLåÝ lç K²"ÀD#·¡¶9©5V…Tb·b-׆ÔJ" ¼Ç90FhT®õå—‹ïEµ¸üµ¶¯¸¹—?(ö¦^¡â³ÌÇ–r‘¯<­‡Ÿïö¿^úKÚïB8‰ xaãâÜ·oé.›}bÁ-ØôÖ²a"† lÂÊc rú-â½(\zƒ©pÝáðãÂùWa˜‚ñÊd?P ÂP*å8$ê¾ü"R]þ²å/ŸmU‰’xŠvßdÖ2¹—g{ê?öƒîê×Ǥ‹Ÿ:€tÚø@9ühmmíÁÁà¾ý ‹Ç ä­»Œ½Ú‘sâž„l öHpªµŠ°ºV¬•ÒPµxÅ:Á…`™€qk¨hºe*O¸üÂ%¿?6ì¬1ƒ©¯šeÖ¬‹ŒzSýÔñ^÷wÏŽ6~˜ÚýTÒùÆ‚/æùKÇòÁ?_³sþ´Þ°ÛÚGD*Î+ W(I jèy)šá9LèT[vS±‡/¶E 4mÊK_U÷¿ý$Žæ ÜBï‹´kŒeÊÅõiÜô|oõ(€izõÓÎÏQ «\Ãö|ÊП/zùÈ^Ã\ŒD3q!2  \¢SPrXñ‘#¡ðœ‚ðÊtO °B £€§âÙD"ž¿/½{ÉðJPñŽØX&B.þÅâæ“Î½©ÝO _¹1r*þÃý‡Þsm¦Ÿ¾‚ù½FçœcVÃ&£òò³¦r.¾ÄL1VÀ0/O¦x ŠUÔ€@ Ò4îP).­äSˆ÷@­a3œþõ‰•î]†¸DÂ5ÓΫ2(@Ïæ_Öò—ÈwÿÚ®Åg &ïž·Ù…(˜¡`º5 ,\æÚi„@ð ÅcY *]x¥È@ Yˆ…ôW™|Nœªí¾7†ê¿ñâxó¦§óþ½&éÕO@:¯ÆX°´4wÛÎí·^îýÇ–Œµ#çdÆr‰¶YE4Ï 1¼¯¸ žR O…£±' í¾†h-X!a(â‡v¿ïý‹ý©Þzjµû¥Ôî§Îk4¹êÍï|»;— ½o›^Å`Œ)¶FË0`>¢€aÀãÌ´.•ªOŠËïE ò(¼s@µfݹéô®G;½O§v?é¼Fc: ˜/ûg îù•ŹS¤ôŽÝÆ^!òÞ;0³––^‘ÕXa ®zAÀ˜ ·€úò 7õ*ê½1Æ8c8wîþÿS½•Kí~êÒ¹0NmIöf¼árèæ½"7_nÍö ïÄÊÆ޾èTàå©Ãô©ð€(¿ŸzÇÌ ¼!WÜ’ÐýTÒ¹Ƃ߹úêk~ÛOïØÇ榜wNAla`©XùqÏ*°Š‚!èðΉBaØðº›ºuègwzw¤v?é\cÁ€ýf¿ßy(üû•»ËȽ}žíU &/ÎÙc†<CtàœWQñlÙ˜V¿ÿ…éôýO®¬Þ“ÚýÔ¤s±Ž€ùøÁƒ¹òñýÖî@ê½|Bÿ3Í Þ±  ï¦Ï­N'·~¿×ÿÏè¡H¾û©¤s±Ã€¹·äÞïÝ»ÿ/çænÛ ÿáEb¬)pv²)Ï“á‘5N¦ãÜû¿zôܹϧv?é\ä'öøÑh4x¨ßÿúŒÍAQy눘ΨJú§Ã>±ºzŽÚýÔ¤óz Tv|Ë›~KÇrè%l Action File.New Soubor.Nový File.Open Soubor.Otevřít File.Merge Soubor.SlouÄit File.Save Soubor.Uložit File.SaveAs Soubor.Uložit jako File.SaveImage Soubor.Uložit obrázek File.Import.LDD Soubor.Import.LDD File.Import.Inventory Soubor.Import.Inventory File.Export.3DS Soubor.Export.3DS File.Export.COLLADA Soubor.Export.COLLADA File.Export.HTML Soubor.Export.HTML File.Export.BrickLink Soubor.Export.BrickLink File.Export.CSV Soubor.Export.CSV File.Export.POVRay Soubor.Export.POVRay File.Export.Wavefront Soubor.Export.Wavefront File.Render Soubor.Vykreslit File.Instructions Soubor.Pokyny File.Print Soubor.Tisk File.PrintPreview Soubor.Náhled tisku File.PrintBOM Soubor.Tisk soupisu File.Recent1 TODO - poslední, nedávné, historie Soubor.Poslední1 File.Recent2 Soubor.Poslední2 File.Recent3 Soubor.Poslední3 File.Recent4 Soubor.Poslední4 File.Exit Soubor.UkonÄit Edit.Undo Upravit.ZpÄ›t Edit.Redo Upravit.Znovu Edit.Cut Upravit.Vyjmout Edit.Copy Upravit.Kopírovat Edit.Paste Upravit.Vložit Edit.PasteSteps Edit.Find Upravit.Najít Edit.FindNext Upravit.Najít Další Edit.FindPrevious Upravit.Najít PÅ™edchozí Edit.FindAll Edit.Replace Edit.ReplaceNext Edit.ReplaceAll Edit.SelectAll Upravit.Vybrat VÅ¡e Edit.SelectNone Upravit.Nevybrat nic Edit.SelectInvert Upravit.Vybrat opak Edit.SelectByName Upravit.Vybrat dle názvu Edit.SelectByColor Upravit.Vybrat dle barvy Edit.SelectSingle Upravit.Vybrat jeden Edit.SelectPiece Upravit.Vybrat díl Edit.SelectColor Upravit.Vybrat barvu Edit.SelectPieceColor TODO Upravit.Vybrat barvu dílu Edit.TransformRelative Upravit.Relativní transformace Edit.TransformAbsolute Edit.TransformToggleRelative Edit.TransformSeparately Edit.TransformTogether Edit.TransformToggleSeparate Edit.Snap.Toggle Upravit.PÅ™ichytit.PÅ™epnout Edit.SnapMove.XY0 Upravit.PÅ™ichytit pÅ™esunout.XY0 Edit.SnapMove.XY1 Upravit.PÅ™ichytit pÅ™esunout.XY1 Edit.SnapMove.XY2 Upravit.PÅ™ichytit pÅ™esunout.XY2 Edit.SnapMove.XY3 Upravit.PÅ™ichytit pÅ™esunout.XY3 Edit.SnapMove.XY4 Upravit.PÅ™ichytit pÅ™esunout.XY4 Edit.SnapMove.XY5 Upravit.PÅ™ichytit pÅ™esunout.XY5 Edit.SnapMove.XY6 Upravit.PÅ™ichytit pÅ™esunout.XY6 Edit.SnapMove.XY7 Upravit.PÅ™ichytit pÅ™esunout.XY7 Edit.SnapMove.XY8 Upravit.PÅ™ichytit pÅ™esunout.XY8 Edit.SnapMove.XY9 Upravit.PÅ™ichytit pÅ™esunout.XY9 Edit.SnapMove.Z0 Upravit.PÅ™ichytit pÅ™esunout.Z0 Edit.SnapMove.Z1 Upravit.PÅ™ichytit pÅ™esunout.Z1 Edit.SnapMove.Z2 Upravit.PÅ™ichytit pÅ™esunout.Z2 Edit.SnapMove.Z3 Upravit.PÅ™ichytit pÅ™esunout.Z3 Edit.SnapMove.Z4 Upravit.PÅ™ichytit pÅ™esunout.Z4 Edit.SnapMove.Z5 Upravit.PÅ™ichytit pÅ™esunout.Z5 Edit.SnapMove.Z6 Upravit.PÅ™ichytit pÅ™esunout.Z6 Edit.SnapMove.Z7 Upravit.PÅ™ichytit pÅ™esunout.Z7 Edit.SnapMove.Z8 Upravit.PÅ™ichytit pÅ™esunout.Z8 Edit.SnapMove.Z9 Upravit.PÅ™ichytit pÅ™esunout.Z9 Edit.SnapAngle.Toggle Upravit.PÅ™ichytit úhel.PÅ™epnout Edit.SnapAngle.Angle0 Upravit.PÅ™ichytit úhel.Úhel0 Edit.SnapAngle.Angle1 Upravit.PÅ™ichytit úhel.Úhel1 Edit.SnapAngle.Angle2 Upravit.PÅ™ichytit úhel.Úhel2 Edit.SnapAngle.Angle3 Upravit.PÅ™ichytit úhel.Úhel3 Edit.SnapAngle.Angle4 Upravit.PÅ™ichytit úhel.Úhel4 Edit.SnapAngle.Angle5 Upravit.PÅ™ichytit úhel.Úhel5 Edit.SnapAngle.Angle6 Upravit.PÅ™ichytit úhel.Úhel6 Edit.SnapAngle.Angle7 Upravit.PÅ™ichytit úhel.Úhel7 Edit.SnapAngle.Angle8 Upravit.PÅ™ichytit úhel.Úhel8 Edit.SnapAngle.Angle9 Upravit.PÅ™ichytit úhel.Úhel9 Edit.Transform Upravit.Transformace Edit.TransformAbsoluteTranslation TODO - zjistit co dÄ›lá Upravit.Transformovat absolutní posun Edit.TransformRelativeTranslation Upravit.Transformovat relativní posun Edit.TransformAbsoluteRotation Upravit.Transformovat absolutní otáÄení Edit.TransformRelativeRotation Upravit.Transformovat relativní otáÄení Edit.Tool.Insert Upravit.Nástroj.Vložení Edit.Tool.Light Upravit.Nástroj.OsvÄ›tlení Edit.Tool.Spotlight Upravit.Nástroj.Zdroj osvÄ›tlení Edit.Tool.Camera Upravit.Nástroj.Kamera Edit.Tool.Select Upravit.Nástroj.Výbírání Edit.Tool.Move Upravit.Nástroj.PÅ™esouvání Edit.Tool.Rotate Upravit.Nástroj.OtáÄení Edit.Tool.Delete Upravit.Nástroj.Mazání Edit.Tool.Paint Upravit.Nástroj.Malování Edit.Tool.ColorPicker TODO - výbÄ›r barvy, kapátko Upravit.Nástroj.Kapátko Edit.Tool.Zoom Upravit.Nástroj.ZvÄ›tÅ¡ování Edit.Tool.Pan Upravit.Nástroj.Posouvání Edit.Tool.RotateView Upravit.Nástroj.OtáÄení pohledu Edit.Tool.Roll Upravit.Nástroj.PÅ™etoÄení Edit.Tool.ZoomRegion Upravit.Nástroj.ZvÄ›tÅ¡ení oblasti Edit.Cancel Upravit.ZruÅ¡ení View.Preferences Zobrazit.PÅ™edvolby View.ZoomIn Zobrazit.PÅ™iblížit View.ZoomOut Zobrazit.Oddálit View.ZoomExtents Zobrazit.Rozsah zvÄ›tÅ¡ení View.LookAt Zobrazit.Prohledávat View.MoveForward Zobrazit.Posunout dopÅ™edu View.MoveBackward Zobrazit.Posunout zpÄ›t View.MoveLeft Zobrazit.Posunout vlevo View.MoveRight Zobrazit.Posunout vravo View.MoveUp Zobrazit.Posunout nahoru View.MoveDown Zobrazit.Posunout dolu View.Viewpoint.Front Zobrazit.Pohled.PÅ™ední View.Viewpoint.Back Zobrazit.Pohled.Zadní View.Viewpoint.Top Zobrazit.Pohled.Horní View.Viewpoint.Bottom Zobrazit.Pohled.Spodní View.Viewpoint.Left Zobrazit.Pohled.Levý View.Viewpoint.Right Zobrazit.Pohled.Pravý View.Viewpoint.Home Zobrazit.Pohled.Výchozí View.Cameras.None Zobrazit.Kamery.Žádné View.Cameras.Camera01 Zobrazit.Kamery.Kamera01 View.Cameras.Camera02 Zobrazit.Kamery.Kamera02 View.Cameras.Camera03 Zobrazit.Kamery.Kamera03 View.Cameras.Camera04 Zobrazit.Kamery.Kamera04 View.Cameras.Camera05 Zobrazit.Kamery.Kamera05 View.Cameras.Camera06 Zobrazit.Kamery.Kamera06 View.Cameras.Camera07 Zobrazit.Kamery.Kamera07 View.Cameras.Camera08 Zobrazit.Kamery.Kamera08 View.Cameras.Camera09 Zobrazit.Kamery.Kamera09 View.Cameras.Camera10 Zobrazit.Kamery.Kamera10 View.Cameras.Camera11 Zobrazit.Kamery.Kamera11 View.Cameras.Camera12 Zobrazit.Kamery.Kamera12 View.Cameras.Camera13 Zobrazit.Kamery.Kamera13 View.Cameras.Camera14 Zobrazit.Kamery.Kamera14 View.Cameras.Camera15 Zobrazit.Kamery.Kamera15 View.Cameras.Camera16 Zobrazit.Kamery.Kamera16 View.Cameras.Reset TODO - pÅ™enastavit, obnovit, resetovat, vynulovat, obnovit tovární nastavení Zobrazit.Kamery.PÅ™enastavit View.Time.First Zobrazit.ÄŒas.První View.Time.Previous Zobrazit.ÄŒas.PÅ™edchozí View.Time.Next Zobrazit.ÄŒas.Další View.Time.Last Zobrazit.ÄŒas.Poslední View.Time.InsertBefore View.Time.InsertAfter View.Time.Insert Zobrazit.ÄŒas.Vložit View.Time.Delete ÄŒas.Zobrazit.Vymazat View.Time.AddKeys Zobrazit.ÄŒas.PÅ™idat klíÄe View.SplitHorizontal Zobrazit.RozdÄ›lit vodorovnÄ› View.SplitVertical Zobrazit.RozdÄ›lit svisle View.RemoveView Zobrazit.Odstranit zobrazení View.ResetViews Zobrazit.Obnovit zobrazení View.Toolbars.Standard Zobrazit.Panely nástrojů.Standard View.Toolbars.Tools Zobrazit.Panely nástrojů.Nástroje View.Toolbars.Time Zobrazit.Panely nástrojů.ÄŒas View.Toolbars.Parts Zobrazit.Panely nástrojů.Části View.Toolbars.Colors Zobrazit.Panely nástrojů.Barvy View.Toolbars.Properties Zobrazit.Panely nástrojů.Vlastnosti View.Toolbars.Timeline Zobrazit.Panely nástrojů.ÄŒasová osa View.Toolbars.Preview View.FullScreen Zobrazit.Celá obrazovka View.CloseCurrentTab Zobrazit.Zavřít aktuální kartu View.Shade.Wireframe Zobrazit.Stín.Schéma View.Shade.Flat Zobrazit.Stín.Plochý View.Shade.DefaultLights Zobrazit.Stín.Výchozí osvÄ›tlení View.Projection.Perspective Zobrazit.Projekce.Perspektivní View.Projection.Orthographic Zobrazit.Projekce.Pravoúhlá View.ToggleViewSphere TODO - space betwen words? Zobrazit.PÅ™epnout sférické zobrazení View.ToggleAxisIcon View.ToggleGrid View.FadePreviousSteps Zobrazit.Zeslabit pÅ™edchozí kroky Piece.Insert TODO - kousek, kus, Äást Dílek.Vložit Piece.Delete Dílek.Odstranit Piece.Duplicate Dílek.Duplikovat Piece.PaintSelected Piece.ResetPivotPoint Dílek.Vynulovat bod otáÄení Piece.RemoveKeyFrames Dílek.Odstranit klíÄový snímek Piece.ControlPoint.Insert Dílek.Kontrolní bod.Vložit Piece.ControlPoint.Remove Dílek.Kontrolní bod.Odstranit Piece.Move.PlusX Dílek.Posuny.PlusX Piece.Move.MinusX Dílek.Posuny.MinusX Piece.Move.PlusY Dílek.Posuny.PlusY Piece.Move.MinusY Dílek.Posuny.MinusY Piece.Move.PlusZ Dílek.Posuny.PlusZ Piece.Move.MinusZ Dílek.Posuny.MinusZ Piece.Rotate.PlusX Dílek.OtoÄení.PlusX Piece.Rotate.MinusX Dílek.OtoÄení.MinusX Piece.Rotate.PlusY Dílek.OtoÄení.PlusY Piece.Rotate.MinusY Dílek.OtoÄení.MinusY Piece.Rotate.PlusZ Dílek.OtoÄení.PlusZ Piece.Rotate.MinusZ Dílek.OtoÄení.MinusZ Piece.MinifigWizard Dílek.Průvodce Minifig Piece.Array Dílek.Pole Piece.ViewSelectedModel Dílek.Zobrazit vybraný model Piece.MoveSelectionToModel Dílek.PÅ™esunout výbÄ›r do modelu Piece.InlineSelectedModels Dílek.Vložené vybrané modely Piece.EditSelectedSubmodel Dílek.Upravit vybraný podmodel Piece.EditEndSubmodel Dílek.Upravit koncový podmodel Piece.Group Dílek.Seskupit Piece.Ungroup Dílek.RozdÄ›lit Piece.GroupAdd Dílek.PÅ™idat skupinu Piece.GroupRemove Dílek.Odstranit skupinu Piece.GroupEdit Dílek.Upravit skupinu Piece.HideSelected Dílek.Skrýt vybrané Piece.HideUnselected Dílek.Skrýt nevybrané Piece.UnhideSelected Dílek.Zobrazit vybrané Piece.UnhideAll Dílek.Zobrazit vÅ¡e Piece.ShowEarlier Dílek.Zobrazit dříve Piece.ShowLater Dílek.Zobrazit pozdÄ›ji Model.New Model.Nový Model.Properties Model.Vlastnosti Model.List Model.Seznam Model.Model01 Model.Model01 Model.Model02 Model.Model02 Model.Model03 Model.Model03 Model.Model04 Model.Model04 Model.Model05 Model.Model05 Model.Model06 Model.Model06 Model.Model07 Model.Model07 Model.Model08 Model.Model08 Model.Model09 Model.Model09 Model.Model10 Model.Model10 Model.Model11 Model.Model11 Model.Model12 Model.Model12 Model.Model13 Model.Model13 Model.Model14 Model.Model14 Model.Model15 Model.Model15 Model.Model16 Model.Model16 Model.Model17 Model.Model17 Model.Model18 Model.Model18 Model.Model19 Model.Model19 Model.Model20 Model.Model20 Model.Model21 Model.Model21 Model.Model22 Model.Model22 Model.Model23 Model.Model23 Model.Model24 Model.Model24 Model.Model25 Model.Model25 Model.Model26 Model.Model26 Model.Model27 Model.Model27 Model.Model28 Model.Model28 Model.Model29 Model.Model29 Model.Model30 Model.Model30 Model.Model31 Model.Model31 Model.Model32 Model.Model32 Model.Model33 Model.Model33 Model.Model34 Model.Model34 Model.Model35 Model.Model35 Model.Model36 Model.Model36 Model.Model37 Model.Model37 Model.Model38 Model.Model38 Model.Model39 Model.Model39 Model.Model40 Model.Model40 Help.HomePage NápovÄ›da.Domovská stránka Help.BugReport NápovÄ›da.Náhlásit chyby Help.Updates NápovÄ›da.Aktualizace Help.About NápovÄ›da.O Menu &New &Nový &Open... &Otevřít... &Merge... &SlouÄit... &Save &Uložit Save &As... Uložit j&ako... Save &Image... Ulož&it obrázek... &LEGO Digital Designer... TODO &LEGO Digital Designer... Set &Inventory... TODO Nastavte &hodnotu zásob... 3D &Studio... TODO 3D &Studio... &COLLADA... TODO &COLLADA... &HTML... &HTML... &BrickLink... &BrickLink... &CSV... &CSV... &POV-Ray... &POV-Ray... &Wavefront... &Wavefront... &Render... &Vykreslit... &Instructions... Pok&yny... &Print... &Tisk... Print Pre&view... Ná&hled tisku... Print &Bill of Materials... Tisk &kusovníku... &Recent1 TODO - Naposledy otevÅ™ené, Nedávné, Naposledy použité, Poslední, Poslední hledané &Nedávné1 &Recent2 &Nedávné2 &Recent3 &Nedávné3 &Recent4 &Nedávné4 &Recent 1 &Nedávné 1 &Recent 2 &Nedávné 2 &Recent 3 &Nedávné 3 &Recent 4 &Nedávné 4 E&xit U&konÄit &Undo &ZpÄ›t &Redo &Znovu Cu&t Vyjmou&t &Copy &Kopírovat &Paste &Vložit &Find... &Najít... Find Ne&xt Najít d&alší Find Pre&vious Najít pÅ™e&dchozí Select &All Vybrat &vÅ¡e Select &None Nevybrat &nic Select &Invert PÅ™evrát&it výbÄ›r Select by Na&me... VýbÄ›r podle j&ména... Select by Col&or... VýbÄ›r p&odle barvy... Single Selection Jeden výbÄ›r Piece Selection VýbÄ›r dílu Color Selection VýbÄ›r barev Piece and Color Selection VýbÄ›r dílků a barev Relative Transforms Relativní transformace Local Transforms Lokální transformace Move Snap Enabled Povolit pÅ™ichycení posunů None Žádné 1/20 Stud TODO - výstupek, cvoÄek, znaÄka, Äep, kolíÄek, spoj 1/20 výstupku 1/4 Stud 1/4 výstupku 1 Flat TODO - plochý, konstatní, jednoduchý 1 plocha 1/2 Stud 1/2 výstupku 1 Stud 1 výstupek 2 Studs 2 výstupky 3 Studs 3 výstupky 4 Studs 4 výstupky 8 Studs 8 výstupků 1 Brick TODO - cihla, kostiÄka 1 kostiÄka 2 Bricks 2 kostiÄky 4 Bricks 4 kostiÄky 8 Bricks 8 kostiÄek Rotation Snap Enabled Povolit pÅ™ichycení otáÄení 1 Degree 1 stupeň 5 Degrees 5 stupňů 15 Degrees 15 stupňů 22.5 Degrees 22,5 stupňů 30 Degrees 30 stupňů 45 Degrees 45 stupňů 60 Degrees 60 stupňů 90 Degrees 90 stupňů 180 Degrees 180 stupňů Transform Transformace Absolute Translation TODO - pÅ™evod, pÅ™eklad -> pravdÄ›podobnÄ› myÅ¡len posun Absolutní posun Relative Translation Relativní posun Absolute Rotation Absolutní otáÄení Relative Rotation Relativní otáÄení Insert Vložit Light OsvÄ›tlení Spotlight TODO - novinky, doporuÄené, odkazy, zdroj sústredeného svetla, standardní svÄ›tla, zdroj osvÄ›tlení, Zdroj osvÄ›tlení Camera Kamera Select Vybrat Move PÅ™esunout Rotate OtoÄit Delete Odstranit Paint Malování Color Picker VýbÄ›r barvy Zoom ZvÄ›tÅ¡it Pan Posouvat Rotate View OtoÄit zobrazení Roll PÅ™etoÄit Zoom Region Oblast zvÄ›tÅ¡ení Cancel Action ZruÅ¡it akci P&references... P&Å™edvolby... Zoom In PÅ™iblížit Zoom Out Oddálit Zoom E&xtents Rozsah &zvÄ›tÅ¡ení Look At Prohledávat Move Forward Posunout dopÅ™edu Move Backward Posunout zpÄ›t Move Left PÅ™esunout doleva Move Right PÅ™esunout doprava Move Up TODO pÅ™esunout, posunout PÅ™esunout nahoru Move Down PÅ™esunout dolů &Front V&pÅ™edu &Back V&zadu &Top &NahoÅ™e B&ottom &Dole &Left V&levo &Right Vp&ravo &Home &Domů Camera 1 Kamera 1 Camera 2 Kamera 2 Camera 3 Kamera 3 Camera 4 Kamera 4 Camera 5 Kamera 5 Camera 6 Kamera 6 Camera 7 Kamera 7 Camera 8 Kamera 8 Camera 9 Kamera 9 Camera 10 Kamera 10 Camera 11 Kamera 11 Camera 12 Kamera 12 Camera 13 Kamera 13 Camera 14 Kamera 14 Camera 15 Kamera 15 Camera 16 Kamera 16 Reset Obnovit First První Previous PÅ™edchozí Next Další Last TODO - posledn, další, následující Poslední Insert Before Vložit pÅ™ed Insert After Vložit za Insert Step Vložit krok Paste with Steps &Find Find All &Replace Replace Next Replace All Absolute Transforms Toggle Relative Transforms Rotate Separately Rotate Together Toggle Separate Transforms Remove Step Odebrat krok Add Keys PÅ™idat klíÄe Split &Horizontal RozdÄ›lit &vodorovnÄ› Split &Vertical RozdÄ›lit &svisle Re&move View Ode&brat zobrazení Rese&t Views Obnovi&t zobrazení Standard Standard Tools Nástroje Time ÄŒas Parts Části Colors Barvy Properties Vlastnosti Timeline ÄŒasová osa Preview &Full Screen &Celá obrazovka Close &Tab Zavří&t záložku &Wireframe &Drátový model &Flat Shading &Ploché stínování &Default Lights &Výchozí osvÄ›tlení &Perspective TODO - Perspektiva, PerspektivnÄ› &PerspektivnÄ› &Orthographic TODO - Pravoúhle, Ortograficky Prav&oúhle View Sphere TODO - sphere? Zobrazit sféru Axis Icon Base Grid Základní mřížka Fade Previous Steps Zeslabit pÅ™edchozí kroky &Insert Vlož&it &Delete &Odstranit &Duplicate &Duplikovat &Paint Selected Reset &Pivot Point Vynulovat &bod otáÄení Remove &Key Frames Odstranit &klíÄové snímky Insert Control Point Vložit kontrolní bod Remove Control Point Odstranit kontrolní bod Move +X PÅ™esunout +X Move -X PÅ™esunout -X Move +Y PÅ™esunout +Y Move -Y PÅ™esunout -Y Move +Z PÅ™esunout +Z Move -Z PÅ™esunout -Z Rotate +X OtoÄit +X Rotate -X OtoÄit -X Rotate +Y OtoÄit +Y Rotate -Y OtoÄit -Y Rotate +Z OtoÄit +Z Rotate -Z OtoÄit -Z Minifig &Wizard... Průvodce &Minifig... A&rray... Po&le... Open Selected Model Otevřít vybraný model Move to New Model... PÅ™esunout na nový model... Inline Selected Models Vložit vybrané modely Edit Selected Submodel Upravit vybrané podmodely End Submodel Editing UkonÄit úpravy podmodelu &Group... TODO - možná seskupit &Skupina... &Ungroup &RozdÄ›lit &Add to Group &PÅ™idat do skupiny Re&move from Group &Odebrat ze skupiny &Edit Groups... &Upravit skupiny... &Hide Selected &Skrýt vybrané Hide &Unselected Skrýt &nevybrané &Unhide Selected &Zobrazit vybrané U&nhide All Zobrazit &vÅ¡e Show Earlier Zobrazit starší Show Later Zobrazit pozdÄ›ji New Submodel... Nový podmodel... Prope&rties... Vlastno&sti... Submodels... Podmodely... Model 1 Model 1 Model 2 Model 2 Model 3 Model 3 Model 4 Model 4 Model 5 Model 5 Model 6 Model 6 Model 7 Model 7 Model 8 Model 8 Model 9 Model 9 Model 10 Model 10 Model 11 Model 11 Model 12 Model 12 Model 13 Model 13 Model 14 Model 14 Model 15 Model 15 Model 16 Model 16 Model 17 Model 17 Model 18 Model 18 Model 19 Model 19 Model 20 Model 20 Model 21 Model 21 Model 22 Model 22 Model 23 Model 23 Model 24 Model 24 Model 25 Model 25 Model 26 Model 26 Model 27 Model 27 Model 28 Model 28 Model 29 Model 29 Model 30 Model 30 Model 31 Model 31 Model 32 Model 32 Model 33 Model 33 Model 34 Model 34 Model 35 Model 35 Model 36 Model 36 Model 37 Model 37 Model 38 Model 38 Model 39 Model 39 Model 40 Model 40 LeoCAD &Home Page LeoCAD &domovská stránka Report a Bug TODO - Oznámit chybu Nahlásit chybu Check for &Updates... Zkontrolovat akt&ualizace... &About... &O... Insert Step Before Vložit krok pÅ™ed Insert Step After Vložit krok za Move Selection Here PÅ™esunout výbÄ›r sem Set Current Step Nastavit aktuální krok Mouse NewPiece TODO Nový díl NewPointLight TODO Nové bodové svÄ›tlo NewSpotLight TODO Nový zdroj osvÄ›tlení NewCamera TODO Nová kamera Select Vybrat Move PÅ™esunout Rotate OtoÄit Delete Odstranit Paint Malování ColorPicker VýbÄ›r barvy Zoom Lupa ZvÄ›tÅ¡it Pan Posouvat Orbit OtáÄení Roll PÅ™etoÄení ZoomRegion TODO Oblast zvÄ›tÅ¡ení Project New Model.ldr Nový Model.ldr New Model.mpd Nový Model.mpd Submodel # Podmodel # Submodel Name: Název podmodelu: Empty Name Prázdný název The submodel name cannot be empty. Název podmodelu nesmí být prázdný. Duplicate Submodel Duplikovat podmodel A submodel named '%1' already exists, please enter a unique name. Podmodel s názvem '%1' již existuje, zadejte jedineÄný název. New Submodel Nový podmodel Error Chyba Error reading file '%1': %2 Chyba pÅ™i Ätení souboru '%1': %2 Error loading file '%1': File format is not recognized. Chyba pÅ™i naÄítání souboru '%1': Formát souboru není rozpoznán. Error writing to file '%1': %2 Chyba zápisu do souboru '%1': %2 Merged SlouÄeno LeoCAD LeoCAD Nothing to export. Není co exportovat. Export 3D Studio Exportovat 3D Studio 3DS Files (*.3ds);;All Files (*.*) 3DS soubory (*.3ds);;vÅ¡echny soubory (*.*) Could not open file '%1' for writing. Nelze otevřít soubor '%1' pro zápis. Export BrickLink Exportovat BrickLink XML Files (*.xml);;All Files (*.*) XML soubory (*.xml);;vÅ¡echny soubory (*.*) Export COLLADA Exportovat COLLADA COLLADA Files (*.dae);;All Files (*.*) COLLADA soubory (*.dae);;vÅ¡echny soubory (*.*) Export CSV Exportovat CSV CSV Files (*.csv);;All Files (*.*) CSV soubory (*.csv);;vÅ¡echny soubory (*.*) Error creating images. PÅ™i vytváření obrázků doÅ¡lo k chybÄ›. Export POV-Ray Exportovat POV-Ray POV-Ray Files (*.pov);;All Files (*.*) POV-Ray soubory (*.pov);;vÅ¡echny soubory (*.*) Could not find LGEO files in folder '%1'. Nelze najít soubory LGEO ve složce '%1'. Export Wavefront Exportovat Wavefront Wavefront Files (*.obj);;All Files (*.*) Wavefront soubory (*.obj);;vÅ¡echny soubory (*.*) QApplication Group # Skupina # Solid Colors Colors Barvy Plné barvy Translucent Colors Colors Barvy Průsvitné barvy Special Colors Colors Barvy Zvláštní barvy Solid Colors Plné Translucent Colors Průsvitné Special Colors Zvláštní QMessageBox Error Chyba QObject LeoCAD LeoCAD Could not open file '%1' for writing. Nelze otevřít soubor '%1' pro zápis. Status Create a new model VytvoÅ™it nový model Open an existing model Otevřít existující model Merge the contents of another file with the current one SlouÄit obsah jiného souboru s aktuálním Save the current model Uložit aktuální model Save the current model with a new name Uložit aktuální model s novým názvem Save a picture of the current view Uložit obrázek aktuálního zobrazení Import a file in LEGO Digital Designer LXF format Importovat soubor ve formátu LEGO Digital Designer LXF Import all parts from an official set Importovat vÅ¡echny souÄásti z oficiální sady Export the current model in 3D Studio 3DS format Exportovat aktuální model ve formátu 3D Studio 3DS Export the current model in COLLADA DAE format Exportovat aktuální model ve formátu COLLADA DAE Create an HTML page for the current model VytvoÅ™te pro aktuální model HTML stránku Export a list of parts used in BrickLink XML format Exportovat seznam použitých souÄástí ve formátu BrickLink XML Export a list of parts used in comma delimited file format Exportovat seznam použitých souÄástí ve formátu CSV Export the current model in POV-Ray format Exportovat aktuální model ve formátu POV-Ray Export the current model in Wavefront OBJ format Exportovat aktuální model ve formátu Wavefront OBJ Render the current model using POV-Ray Vykreslit aktuální model pomocí POV-Ray Configure instructions layout Konfigurace rozložení pokynů Print the current model Vytisknout aktuální model Display how the model would look if printed Zobrazit, jak by model vypadal, kdyby byl vytiÅ¡tÄ›n Print a list of parts used Vytisknout seznam použitých dílů Open this model Otevřít tento model Quit the application; prompts to save model Undo the last action ZruÅ¡it poslední akci Redo the previously undone action Opakujte dříve vrácenou akci Cut the selection and put it on the Clipboard VyjmÄ›te výbÄ›r a vložte jej do schránky Copy the selection and put it on the Clipboard Copy the selection and put it on the Clipboard Insert Clipboard contents Vložit obsah schránky Find object Najít objekt Find next object Najít další objekt Select all pieces in the model Vybrat vÅ¡echny Äásti modelu De-select everything ZruÅ¡te vÅ¡echny výbÄ›ry Invert the current selection set PÅ™evrátit aktuální výbÄ›r Select objects by name Vybrat objekty podle názvu Select pieces by color Vybrat Äásti podle barvy Select one piece at a time Vybrat vždy jeden dílek Select all pieces of the same type Vybrat vÅ¡echny dílky stejného typu Select all pieces of the same color Vybrat vÅ¡echny kusy stejné barvy Select all pieces of the same type and color Vybrat vÅ¡echny kusy stejného typu a barvy Move and rotate objects relative to the one that has focus PÅ™esun a otáÄení objektů vzhledem k tomu, který je vybrán Rotate pieces around their individual pivot point OtoÄit dílky kolem svého vlastnho otoÄného bodu Insert Clipboard contents in the current step Insert Clipboard contents in their original steps Find piece Find next piece Find previous piece Find all pieces that match the search criteria Replace piece Replace next piece Replace all pieces that match the search criteria Move and rotate objects in absolute coordinates Toggle moving and rotating objects relative to the one that has focus Rotate selected pieces separately Rotate selected pieces together Toggle rotating selected pieces separately Toggle snap axes PÅ™epnout osy pÅ™ichycení Do not snap movement along the XY plane NepÅ™ichytávat pohyb podél roviny XY Snap movement along the XY plane to 1/20 stud PÅ™ichytit pohyb podél roviny XY na 1/20 Äepu Snap movement along the XY plane to 1/4 stud PÅ™ichytit pohyb podél roviny XY na 1/4 Äepu Snap movement along the XY plane to 1 flat PÅ™ichytit pohyb podél roviny XY na 1 plochu Snap movement along the XY plane to 1/2 stud PÅ™ichytit pohyb podél roviny XY na 1/2 Äepu Snap movement along the XY plane to 1 stud PÅ™ichytit pohyb podél roviny XY na 1 Äep Snap movement along the XY plane to 2 studs PÅ™ichytit pohyb podél roviny XY na 2 Äepy Snap movement along the XY plane to 3 studs PÅ™ichytit pohyb podél roviny XY na 3 Äepy Snap movement along the XY plane to 4 studs PÅ™ichytit pohyb podél roviny XY na 4 Äepy Snap movement along the XY plane to 8 studs PÅ™ichytit pohyb podél roviny XY na 8 Äepů Do not snap movement along the Z axis NepÅ™ichytávat pohyb podél osy Z Snap movement along the Z axis to 1/20 stud PÅ™ichytit pohyb podél osy Z na 1/20 Äepu Snap movement along the Z axis to 1/4 stud PÅ™ichytit pohyb podél osy Z na 1/4 Äepu Snap movement along the Z axis to 1 flat PÅ™ichytit pohyb podél osy Z na 1 plochu Snap movement along the Z axis to 1/2 stud PÅ™ichytit pohyb podél osy Z na 1/2 Äepu Snap movement along the Z axis to 1 stud PÅ™ichytit pohyb podél osy Z na 1 Äep Snap movement along the Z axis to 1 brick PÅ™ichytit pohyb podél osy Z na 1 kostiÄku Snap movement along the Z axis to 2 bricks PÅ™ichytit pohyb podél osy Z na 2 kostiÄky Snap movement along the Z axis to 4 bricks PÅ™ichytit pohyb podél osy Z na 4 kostiÄky Snap movement along the Z axis to 8 bricks PÅ™ichytit pohyb podél osy Z na 8 kostiÄek Snap rotations to fixed intervals PÅ™ichycení otáÄení po pevných intervalech Do not snap rotations NepÅ™ichytávat otáÄení Snap rotations to 1 degree OtáÄení pÅ™ichyceného o 1 stupeň Snap rotations to 5 degrees OtáÄení pÅ™ichyceného o 5 stupňů Snap rotations to 15 degrees OtáÄení pÅ™ichyceného o 15 stupňů Snap rotations to 22.5 degrees OtáÄení pÅ™ichyceného o 22,5 stupňů Snap rotations to 30 degrees OtáÄení pÅ™ichyceného o 30 stupňů Snap rotations to 45 degrees OtáÄení pÅ™ichyceného o 45 stupňů Snap rotations to 60 degrees OtáÄení pÅ™ichyceného o 60 stupňů Snap rotations to 90 degrees OtáÄení pÅ™ichyceného o 90 stupňů Snap rotations to 180 degrees OtáÄení pÅ™ichyceného o 180 stupňů Apply transform to selected objects Použít transformaci na vybrané objekty Switch to absolute translation mode when applying transforms PÅ™i použití transformací pÅ™epnout do režimu absolutního posunu Switch to relative translation mode when applying transforms PÅ™i použití transformací pÅ™epnout do režimu relativního posunu Switch to absolute rotation mode when applying transforms PÅ™i použití transformací pÅ™epnout do režimu absolutního otáÄení Switch to relative rotation mode when applying transforms PÅ™i použití transformací pÅ™epnout do režimu relativního otáÄení Add new pieces to the model PÅ™idejte do modelu nové dílky Add new omni light sources to the model PÅ™idat do modelu nové zdroje omni svÄ›tla Add new spotlights to the model PÅ™idat do modelu nové zdroje osvÄ›tlení Create a new camera VytvoÅ™it novou kameru Select objects (hold the CTRL key down or drag the mouse to select multiple objects) Vybrat objekty (stiknutím klávesy CTRL nebo pÅ™etažením myÅ¡i vyberte více objektů) Move selected objects PÅ™esunout vybrané objekty Rotate selected pieces OtoÄit vybrané dílky Delete objects Odstranit objekty Change piece color ZmÄ›ni barvu dílků Get piece color Získat barvu dílku Zoom in or out PÅ™iblížení nebo oddálení Pan the current view Posunout aktuální zobrazení Rotate the current view OtoÄit aktuální zobrazení Roll the current view PÅ™etoÄit aktuální zobrazení Zoom into a region of the screen PÅ™ibližit oblast obrazovky Cancel current mouse action ZruÅ¡it aktuální akci myÅ¡i Change program settings ZmÄ›nit nastavení programu Zoom in PÅ™iblížit Zoom out Oddálit Fit all pieces in current the view (hold the CTRL key down to zoom all views) PÅ™izpůsobit vÅ¡echny dílky v aktuálním pohledu (stisknutím klávesy CTRL zvÄ›tšíte vÅ¡echna zobrazení) Rotate view so selected pieces are at center OtoÄit pohled tak, aby vybrané dílky byly ve stÅ™edu Move the current view forward Posunout aktuální pohled dopÅ™edu Move the current view backward Posunout aktuální pohled dozadu Move the current view to the left Posunout aktuální pohled doleva Move the current view to the right Posunout aktuální pohled doprava Move the current view up Posunout aktuální pohled nahoru Move the current view down Posunout aktuální pohled dolu View model from the front Prohlédnout model zepÅ™edu View model from the back Prohlédnout model zezadu View model from the top Prohlédnout model zezhora View model from the bottom Prohlédnout model zezdola View model from the left Prohlédnout model zleva View model from the right Prohlédnout model zprava View model from the default position Zobrazit model z výchozí polohy Do not use a camera Nepoužívat kameru Use this camera Použít tuto kameru Reset views to their default positions Obnovit výchozí pozici Go to the first step of the model PÅ™ejít na první krok modelu Go to the previous step PÅ™ejít na pÅ™edchozí krok Go to the next step PÅ™ejít na další krok Go to the last step of the model PÅ™ejít na poslední krok modelu Insert a new step before the current step Vložit nový krok pÅ™ed aktuální krok Insert a new step after the current step Vložit nový krok za aktuální krok Insert new step Vložit nový krok Remove current step Odebrat aktuální krok Toggle adding new animation keys PÅ™epnout pÅ™idávání nových animaÄních klíÄů Split the current view horizontally RozdÄ›lit aktuální pohled vodorovnÄ› Split the current view vertically RozdÄ›lit aktuální pohled svisle Remove the current view Odebrat aktuální zobrazení Reset all views Obnovit vÅ¡echny pohledy Toggle the Standard Toolbar PÅ™epnout panel standardních nástrojů Toggle the Tools Toolbar PÅ™epnout panel nástrojů Toggle the Time Toolbar PÅ™epnout panel nástrojů Äasu Toggle the Parts Toolbar PÅ™epnout panel Äástí Toggle the Colors Toolbar PÅ™epnout panel nástrojů barev Toggle the Properties Toolbar PÅ™epnout panel vlastností Toggle the Timeline Toolbar PÅ™epnout panel Äasové osy Toggle the Preview Toolbar Toggle fullscreen mode PÅ™epnout režim celé obrazovky Close current tab Zavřít aktuální záložku Display the scene as wireframe TODO Zobrazit scénu jako drátový model Display the scene without any shading or lights Zobrazit scénu bez stínování nebo osvÄ›tlení Display the scene with the default lights Zobrazit scénu s výchozími svÄ›tly Set the current camera to use a perspective projection Nastavte aktuální kameru tak, aby použila perspektivní projekci Set the current camera to use an orthographic projection Nastavte aktuální kameru tak, aby použila pravoúhlou projekci Toggle the view sphere PÅ™epnout sférické zobrazení Toggle axis icon Toggle grid Toggle fading previous model steps PÅ™epnout zeslabování pÅ™edchozích kroků modelu Add a new piece to the model PÅ™idat nový dílek do modelu Delete selected objects Odstranit vybrané objekty Create a copy of the selected pieces VytvoÅ™te kopii vybraných dílků Change the color of the selected pieces Reset the pivot point of the selected pieces to their origin TODO - původ, zdroj, poÄátek, vznik Obnovte bod otáÄení vybraných dílků dle jejich původu Remove all key frames from the selected pieces Odstraňte vÅ¡echny klíÄové snímky z vybraných dílků Insert a new control point Vložit nový kontrolní bod Remove the selected control point Odstranit vybraný kontrolní bod Move selected objects along the X axis PÅ™esunout vybrané objekty podél osy X Move selected objects along the Y axis PÅ™esunout vybrané objekty podél osy Y Move selected objects along the Z axis PÅ™esunout vybrané objekty podél osy Z Rotate selected objects along the X axis OtoÄit vybrané objekty podél osy X Rotate selected objects along the Y axis OtoÄit vybrané objekty podél osy Y Rotate selected objects along the Z axis OtoÄit vybrané objekty podél osy Z Add a new minifig to the model PÅ™idat k modelu nový minifig Make copies of the selected pieces VytvoÅ™it kopie vybraných dílků Open the model referenced by the selected piece in a new tab TODO OtevÅ™ete model, na který odkazuje vybraný dílek, na nové kartÄ› Move the selected pieces to a new model and replace them with a reference to the model PÅ™esuňte vybrané dílky do nového modelu a nahraÄte je odkazem na model Insert the contents of the selected model references into the current model Vložte obsah vybraných referencí modelu do aktuálního modelu Edit the currently selected submodel in-place TODO - in-place -> vložený, na místÄ›, v místÄ› Upravte aktuálnÄ› vybraný vložený podmodel End in-place submodel editing UkonÄit místní úpravy podmodelu Group selected pieces together Seskupit vybrané dílky dohromady Ungroup selected group OddÄ›lit vybranou skupinu Add focused piece to selected group Remove focused piece from group Odstranit vybraný kousek ze skupiny Edit groups Upravit skupiny Hide selected objects Skrýt vybrané objekty Hide objects that are not selected Skrýt objekty, které nejsou vybrány Show hidden objects that are selected Zobrazit skryté vybrané objekty Show all hidden objects Zobrazit vÅ¡echny skryté objekty Show selected pieces one step earlier Zobrazit vybrané dílky o krok dříve Show selected pieces one step later Zobrazit vybrané dílky o krok pozdÄ›ji Create a new submodel VytvoÅ™it nový podmodel Display the properties of the current submodel Zobrazit vlastnosti aktuálního podmodelu Show a list of all submodels Zobrazit seznam vÅ¡ech podmodelů Switch to this submodel PÅ™epnout na tento podmodel Open LeoCAD's home page on the internet using your default web browser Otevřít domovskou stránku LeoCADu na internetu výchozím webovím prohlížeÄem Open LeoCAD's bug report form on your default web browser Otevřít formulář hlášení chyb LeoCADu ve výchozím webovém prohlížeÄi Check if a newer LeoCAD version or parts library has been released Zkontrolovat, zda nebyla vydána novÄ›jší verze LeoCADu nebo knihovny souÄástí Display program version number and system information Zobrazit verzi programu a systémové informace Move the selected parts into this step PÅ™esunout vybrané Äásti do tohoto kroku View the model at this point in the timeline Zobrazit model v tomto okamžiku na Äasové ose ViewName Left Vlevo Right Vpravo Back Vzadu Front VpÅ™edu Top NahoÅ™e Bottom Dole lcApplication Not enough parameters for the '%1' option. Invalid parameter value specified for the '%1' option: '%2'. The file '%1' is not readable. Invalid parameter value(s) specified for the '%1' option: limits are +/- 360. Invalid parameter value(s) specified for the '%1' option. Invalid parameter value(s) specified for the '%1' option: requirements are: 1 <= <near> < <far>. High contrast stud style is required for the '%1' option but is not enabled. Automate edge color is required for the '%1' option but is not enabled. LeoCAD Continuous Build %1 LeoCAD průběžné sestavení %1 LeoCAD Version %1 LeoCAD verze %1 Compiled %1 Usage: leocad [options] [file] [options] can be: -l, --libpath <path>: Set the Parts Library location to path. -i, --image <outfile.ext>: Save a picture in the format specified by ext and exit. -w, --width <width>: Set the picture width. -h, --height <height>: Set the picture height. -f, --from <step>: Set the first step to save pictures. -t, --to <step>: Set the last step to save pictures. -s, --submodel <submodel>: Set the active submodel. -c, --camera <camera>: Set the active camera. -ss, --stud-style <id>: Set the stud style 0=No style, 1=LDraw single wire, 2=LDraw double wire, 3=LDraw raised floating, 4=LDraw raised rounded, 5=LDraw subtle rounded, 6=LEGO no logo, 7=LEGO single wire. --viewpoint <front|back|left|right|top|bottom|home>: Set the viewpoint. --camera-angles <latitude> <longitude>: Set the camera angles in degrees around the model. --camera-position <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector. --camera-position-ldraw <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector using LDraw coordinates. --orthographic: Render images using an orthographic projection. --fov <degrees>: Set the vertical field of view used to render images (< 180). --zplanes <near> <far>: Set the near and far clipping planes used to render images (1 <= <near> < <far>). --fade-steps: Render parts from prior steps faded. --no-fade-steps: Do not render parts from prior steps faded. --fade-steps-color <rgba>: Renderinng color for prior step parts (#AARRGGBB). --highlight: Highlight parts in the steps they appear. --no-highlight: Do not highlight parts in the steps they appear. --highlight-color: Renderinng color for highlighted parts (#AARRGGBB). --shading <wireframe|flat|default|full>: Select shading mode for rendering. --line-width <width>: Set the width of the edge lines. --aa-samples <count>: AntiAliasing sample size (1, 2, 4, or 8). -scc, --stud-cylinder-color <#AARRGGBB>: High contrast stud cylinder color. -ec, --edge-color <#AARRGGBB>: High contrast edge color. -bec, --black-edge-color <#AARRGGBB>: High contrast edge color for black parts. -dec, --dark-edge-color <#AARRGGBB>: High contrast edge color for dark color parts. -aec, --automate-edge-color: Enable automatically adjusted edge colors. -cc, --color-contrast <float>: Color contrast value between 0.0 and 1.0. -ldv, --light-dark-value <float>: Light/Dark color value between 0.0 and 1.0. -obj, --export-wavefront <outfile.obj>: Export the model to Wavefront OBJ format. -3ds, --export-3ds <outfile.3ds>: Export the model to 3D Studio 3DS format. -dae, --export-collada <outfile.dae>: Export the model to COLLADA DAE format. -html, --export-html <folder>: Create an HTML page for the model. -v, --version: Output version information and exit. -?, --help: Display this help message and exit. Unknown option: '%1'. High contrast stud and edge color settings are ignored when -aec or --automate-edge-color is set. --viewpoint is ignored when --camera is set. --orthographic is ignored when --camera is set. --camera-angles is ignored when --camera is set. --camera-position is ignored when --camera is set. --camera-angles is ignored when --viewpoint is set. --camera-position is ignored when --viewpoint is set. --camera-position is ignored when --camera-angles is set. No file name specified. Error creating OpenGL context. LeoCAD could not find a compatible Parts Library so only a small number of parts will be available. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD nemohl najít kompatibilní knihovnu dílů, takže bude k dispozici pouze malé množství dílů. Informace o tom, jak stáhnout a nainstalovat knihovnu, naleznete na adrese https://www.leocad.org. LeoCAD could not load Parts Library. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD nemohl naÄíst knihovnu souÄástí. Informace o tom, jak stáhnout a nainstalovat knihovnu, naleznete na adrese https://www.leocad.org. LeoCAD LeoCAD Error: model '%1' does not exist. Saved '%1'. Some changes will only take effect the next time you start LeoCAD. NÄ›které zmÄ›ny se projeví až pÅ™i příštím spuÅ¡tÄ›ní LeoCADu. lcAutomateEdgeColorDialog Color Preferences Edge Colors Contrast: Set the amount of contrast - 0.50 is midway. Reset Obnovit Light/Dark Value: Saturation: Set to classify where color values are light or dark - e.g. Dark Bluish Gray (72) is light at 0.39. Set to specify amount of edge color tint or shade from the saturation adjusted part color High Contrast Stud Cylinder Color: Parts Edge Color: Black Parts Edge Color: Dark Parts Edge Color: Select Stud Cylinder Color Select Part Edge Color Automate edge color appears to be enabled.<br>Black parts edge color will not be accessible.<br>Do you want to continue? Select Black Edge Color Automate edge color appears to be enabled.<br>Dark parts edge color will not be accessible.<br>Do you want to continue? Select Dark Edge Color lcFindReplaceWidget Find: Replace: lcInstructions Show Step Number Show Parts List Font: Text Color: Barva textu: Background Color: Border Color: lcInstructionsDialog Instructions Pokyny Page Settings Print Vertical Horizontal Page %1 lcInstructionsPageListWidget Pages Page Setup lcInstructionsPropertiesWidget Properties Vlastnosti Default Výchozí Current Model Current Step Only Current Step Forward Scope: Preset: Select Step Number Color Select Step Background Color Select Parts List Background Color Select Parts List Border Color Select Parts List Text Color Select Step Number Font Select Parts List Font Step Properties Step Number Properties Parts List Properties lcMainWindow New Model Nový model Open Model Otevřít model Save Model Uložit model Transform Transformace C&ameras K&amery &Viewpoints TODO - pohled, hledisko, vyhlídka, zorný úhel, &Pohledy Projection Projekce Sh&ading Stínov&ání Tools Nástroje &File &Soubor &Import &Importovat &Export &Exportovat &Edit &Upravit &View TODO - Zobrazit, pohled, &Zobrazit Ste&p Kro&k T&oolbars Panely nástr&ojů &Piece TODO - dílek, kus &Dílek Sub&model Pod&model &Help &NápovÄ›da Selection Mode Režim výbÄ›ru Change selection mode ZmÄ›na režimu výbÄ›ru Transform Options Snap XY TODO - PÅ™ichytit, Lusknutí, PÅ™ichycení PÅ™ichycení XY Snap Z PÅ™ichycení Z Snap Menu Nabídka pÅ™ichycení Movement Snap TODO - pohyb, pÅ™esun PÅ™esun pÅ™ichycení Snap translations to fixed intervals PÅ™ichycení posunů k pevným bodům Snap Angle Menu Nabídka úhlů pÅ™ichycení Rotation Snap OtoÄení pÅ™ichycení Snap rotations to fixed intervals PÅ™ychycení otáÄení k pevným bodům Standard Standard Time ÄŒas Parts Části Colors Barvy Properties Vlastnosti Timeline ÄŒasová osa Preview Close Other Tabs Zavřít ostatní záložky Reset Views Obnovit zobrazení The file '%1' has been modified by another application, do you want to reload it? Soubor '%1' byl upraven jinou aplikací, chcete jej znovu naÄíst? File Changed Soubor byl zmÄ›nÄ›n %1 (ID: %2) %1 (ID: %2) %n Object(s) selected %n vybraný objekt %n vybrané objekty %n vybraných objektů - %1 (ID: %2) - %1 (ID: %2) in group '%1' ve skupinÄ› '%1' Step %1 Krok %1 M: %1 %2 R: %3 M: %1 %2 R: %3 &Undo %1 &ZpÄ›t %1 &Undo &ZpÄ›t &Redo %1 &Znovu %1 &Redo &Znovu Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*) Podporované soubory (*.lcd *.ldr *.dat *.mpd);;vÅ¡echny soubory (*.*) Merge Model SlouÄit model LeoCAD LeoCAD Merged 1 submodel. SlouÄit 1 podmodel. Merged %1 submodels. SlouÄit %1 podmodelů. Import Importovat LEGO Diginal Designer Files (*.lxf);;All Files (*.*) LEGO Diginal Designer soubory (*.lxf);;vÅ¡echny soubory (*.*) Supported Files (*.mpd);;All Files (*.*) Podporované soubory (*.mpd);;vÅ¡echny soubory (*.*) Supported Files (*.ldr *.dat *.mpd);;All Files (*.*) Podporované soubory (*.ldr *.dat *.mpd);;vÅ¡echny soubory (*.*) Error Chyba Rel Abs M: %1 %2 R: %3 %4 M: %1 %2 R: %3 {1 %2 ?} {3 %4 ?} Saving files in LCD format is no longer supported, please use the LDR or MPD formats instead. Ukládání souborů ve formátu LCD již není podporováno, místo toho použijte formáty LDR nebo MPD. Save changes to '%1'? Chcete uložit zmÄ›ny v '%1'? 0 0 1/20S 1/20S 1/4S 1/4S 1F 1F 1/2S 1/2S 1S 1S 2S 2S 3S 3S 4S 4S 8S 8S None Žádné 1B 1B 2B 2B 4B 4B 8B 8B lcMinifigDialog Minifig Wizard Průvodce Minifig Templates Å ablony Save... Uložit... Delete... Odstranit... Import... Importovat... Export... Save Template Uložit Å¡ablonu Template Name: Název Å¡ablony: Template name cannot be empty. Název Å¡ablony nesmí být prázdný. Are you sure you want to overwrite the template '%1'? Opravdu chcete pÅ™epsat tuto Å¡ablonu '%1'? Overwrite Template PÅ™epsat Å¡ablonu Are you sure you want to delete the template '%1'? Opravdu chcete odstranit tuto Å¡ablonu '%1'? Delete Template Odstranit Å¡ablonu Import Templates Importovat Å¡ablony Minifig Template Files (*.minifig);;All Files (*.*) Å ablona Minifig souborů (*.minifig);;vÅ¡echny soubory (*.*) Error Chyba Error reading file '%1': %2 Chyba pÅ™i Ätení souboru '%1': %2 Export Templates Exportovat Å¡ablony Error writing to file '%1': %2 Chyba zápisu do souboru '%1': %2 lcModel Group # Skupina # Cutting TODO - Vyjmutí, Řezání Vyjmutí Pasting Vkládání Duplicating Pieces Duplikování dílků LeoCAD LeoCAD Error creating images. PÅ™i vytváření obrázků doÅ¡lo k chybÄ›. Error Chyba Error writing to file '%1': %2 Chyba zápisu do souboru '%1': %2 Inserting Step Vložen krok Removing Step Odebrání kroku No pieces selected. Nejsou vybrány žádné dílky. Grouping Seskupení Ungrouping RozdÄ›lení Editing Groups Úpravy skupin Adding Piece PÅ™idání dílku Resetting Cameras Resetování kamer Deleting Odstraňování Removing Key Frames OdstranÄ›ní klíÄových snímků Modifying Úprava New Model Nový model No models selected. Nebyly vybrány žádné modely. Inlining TODO Inlining Moving PÅ™esouvání Rotating OtáÄení Scaling ZmÄ›na velikosti Painting Malování Setting Part Nastavení Äásti Showing Pieces Zobrazení dílků Hiding Pieces Skrytí dílků Editing Camera Úpravy kamery Changing FOV ZmÄ›na FOV Renaming Camera PÅ™ejmenovávání kamery Hide Skrýt Unhide Zobrazit Replacing Part New SpotLight Nový zdroj osvÄ›tlení New Camera Nová kamera Move PÅ™esunout Rotate OtoÄit Zoom ZvÄ›tÅ¡it Pan Posouvat Orbit OtoÄení Roll PÅ™etoÄení Insert Vložit New Light Nové osvÄ›tlení Look At Prohledávat Moving Camera PÅ™esunití kamery Changing Properties ZmÄ›na vlastností Nothing to select. Není nic vybráno. Array only has 1 element or less, no pieces added. Pole obsahuje pouze 1 prvek nebo ménÄ›, nejsou pÅ™idávány žádné dílky. Array Pole Minifig # Minifig # Minifig Minifig lcPageSetupDialog Page Setup Size Width: Šířka: Height: Výška: Preset: Units: Margins Left: Right: Top: Bottom: lcPartPaletteDialog Part Palettes Část palet New... Nová... Delete... Odstranit... Rename... PÅ™ejmenovat... Import... Importovat... Move Up Nahoru Move Down Dolu New Part Palette Nová paleta Äástí Palette Name: Název palety: Are you sure you want to delete the palette '%1'? Opravdu chcete odstranit paletu '%1'? Delete Part Palette Odstranit paletu Äástí Rename Part Palette PÅ™ejmenovat paletu Äástí lcPartSelectionListView Add to Palette PÅ™idat do palety None Žádné Remove from Palette Odebrat z palety lcPartSelectionWidget Search Parts Prohledat Äásti Options Možnosti Edit Palettes... No Icons Žádné ikony Small Icons Malé ikony Medium Icons StÅ™ední ikony Large Icons Velké ikony Extra Large Icons NejvÄ›tší ikony Show Part Names Otázka je zda nepojmenovat parts -> díly, (Äásti) Zobrazit názvy Äástí Show Decorated Parts Otázka co znamená zdobené? Zobrazit zdobené souÄásti Show Part Aliases Allises -> popis, pÅ™ezdívka, oznaÄení Zobrazit pÅ™ezdívny Äástí List Mode Režim seznamu Lock Preview Color Uzamknutí barevného náhledu Favorites Oblíbené All Parts VÅ¡echny Äásti In Use Využíváno Parts In Use Používané Äásti Submodels Podmodely lcPiecesLibrary Initializing Zahajuji naÄítání Loading Parts Library NaÄítání knihovny dílů lcPreviewDockWidget Lock Preview Ctrl+L Toolbar Preview Toolbar Loading... Unlock the preview display to enable updates Lock the preview display to disable updates Unlock Preview lcQAboutDialog About LeoCAD O LeoCADu LeoCAD Version 0.00.0 LeoCAD verze 0.00.0 LeoCAD is a free application for creating virtual LEGO models. LeoCAD je bezplatná aplikace pro vytváření návrhů LEGO modelů. System Information Systémové informace LeoCAD Continuous Build %1 LeoCAD průběžné sestavení %1 LeoCAD Version %1 LeoCAD verze %1 Qt Version %1 (compiled with %2) Qt verze %1 (kompilováno s %2) OpenGL Version %1 (GLSL %2) %3 - %4 OpenGL verze %1 (GLSL %2) %3 - %4 Color Buffer: %1 bits Depth Buffer: %2 bits Stencil Buffer: %3 bits Buffers: %1 Shaders: %2 Framebuffers: %3 BlendFuncSeparate: %4 Anisotropic: %5 Color Buffer: %1 bits %2 %3 Depth Buffer: %4 bits Stencil Buffer: %5 bits Vyrovnávací paměť barev: %1 bits %2 %3 Vyrovnávací paměť hloubek: %4 bits Vyrovnávací paměť Å¡ablon: %5 bits indexed indexovaný double buffered dvojitá vyrovnávací pamÄ›t GL_ARB_vertex_buffer_object extension: %1 GL_ARB_framebuffer_object extension: %2 GL_EXT_framebuffer_object extension: %3 GL_EXT_blend_func_separate: %4 GL_EXT_texture_filter_anisotropic extension: %5 GL_ARB_vertex_buffer_object rozšíření: %1 GL_ARB_framebuffer_object rozšíření: %2 GL_EXT_framebuffer_object rozšíření: %3 GL_EXT_blend_func_separate: %4 GL_EXT_texture_filter_anisotropic rozšíření: %5 Supported Podporováno Not supported Není podporováno Supported (max %1) Podporováno (max %1) lcQArrayDialog Array Pole Dimensions RozmÄ›ry Offsets Posuny Rotations OtoÄení Array is empty. Pole je prázdné. lcQCategoryDialog Category Kategorie Name: Název: Keywords: KlíÄová slova: Edit Category Upravit kategorii New Category Nová kategorie Name cannot be empty. Název nesmí být prázdný. Keywords cannot be empty. KlíÄové slovo nesmí být prázdné. lcQEditGroupsDialog Edit Groups Upravit skupiny New Group Nová skupina Group # Skupina # lcQFindDialog Find Najít Name Název Part ID ID Äásti Color Barva lcQGroupDialog Group Skupina Name Název Name cannot be empty. Název nesmí být prázdný. lcQHTMLDialog HTML Options Možnosti formátu HTML General Obecné Output folder: Výstupní složka: ... ... Transparent image background Průhledné pozadí obrázku Models Modely All Models VÅ¡echny modely Current Model and Submodels Aktuální model a podmodel Current Model Only Pouze aktuální model Steps Kroky Single Page Jedna stránka One Step per Page Jeden krok na stránku Index page PoÄáteÄní stránka Width: Šířka: Height: Výška: Highlight new parts ZvýraznÄ›te nové Äásti Parts List Seznam Äástí Color: Barva: After each step Po každém kroku Create images Vytvářejte obrázky At the end Na konci Output folder cannot be empty. Výstupní složka nesmí být prázdná. Select Output Folder Vyberte výstupní složku lcQImageDialog Save Image Uložit obrázek File name: Název souboru: ... ... Dimensions RozmÄ›ry Width: Šířka: Height: Výška: Step Range Krokový rozsah All Steps VÅ¡echny kroky Current Step Aktuální krok Custom Range Vlastní rozsah From: Od: To: Do: Error Chyba Output File cannot be empty. Výstupní soubor nesmí být prázdný. Please enter a width between 1 and 32768. Prosím zadejte šířku mezi 1 a 32768. Please enter a height between 1 and 32768. Prosím zadejte výšku mezi 1 a 32768. First step must be between 1 and %1. První krok musí být mezi 1 a %1. Last step must be between 1 and %1. Poslední krok musí být mezi 1 a %1. Last step must be greater than first step. Poslední krok musí být vÄ›tší než první krok. Save Image File Uložit soubor obrázku Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) Podporované typy obrázků (*.bmp *.png *.jpg);;BMP soubory (*.bmp);;PNG soubory (*.png);;JPEG soubory (*.jpg);;vÅ¡echny soubory (*.*) lcQMinifigDialog Minifig Wizard Průvodce Minifig Templates Å ablony Save... Uložit... Delete... Odstranit... Import... Importovat... Export... Exportovat... Save Template Uložit Å¡ablonu Template Name: Název Å¡ablony: Template name cannot be empty. Název Å¡ablony nesmí být prázdný. Are you sure you want to overwrite the template '%1'? Opravdu chcete pÅ™epsat tuto Å¡ablonu '%1'? Overwrite Template PÅ™epsat Å¡ablonu Are you sure you want to delete the template '%1'? Opravdu chcete odstranit tuto Å¡ablonu '%1'? Delete Template Odstranit Å¡ablonu Import Templates Importovat Å¡ablony Minifig Template Files (*.minifig);;All Files (*.*) Å ablona Minifig souborů (*.minifig);;vÅ¡echny soubory (*.*) Error Chyba Error reading file '%1': %2 Chyba pÅ™i Ätení souboru '%1': %2 Export Templates Exportovat Å¡ablony Error writing to file '%1': %2 Chyba zápisu do souboru '%1': %2 lcQModelListDialog Submodels Podmodely &New... &Nový... D&elete... O&dstranit... &Rename... &PÅ™ejmenovat... Export... Export... Duplicate... Move &Up Nahor&u Move &Down &Dolu Set Active Nastavit aktivní Nastavit jako aktivní New Submodel Nový podmodel Error Chyba The model cannot be empty. Model nesmí být prázdný. Are you sure you want to delete the submodel '%1'? Opravdu chcete odstranit podmodel '%1'? Delete Submodel Odstranit podmodel No submodel selected. Nebyly vybrány žádné podmodely. Are you sure you want to delete %1 submodels? Opravdu chcete odstranit %1 podmodel? Rename Submodel PÅ™ejmenovat podmodel Export Submodel Exportovat podmodel LeoCAD LeoCAD Nothing to export. Není co exportovat. Export Model Exportovat model Select Export Folder Duplicate Submodel Duplikovat podmodel Copy of Select Parts Library Folder Vyberte složku knihovny Äástí Save Model Uložit model Supported Files (*.ldr *.dat);;All Files (*.*) Podporované soubory (*.ldr *.dat);;vÅ¡echny soubory (*.*) lcQPreferencesDialog Preferences PÅ™edvolby General Obecné Application Aplikace Language: Jazyk: Check for updates: Zkontrolovat aktualizace: Default Výchozí Deutsch Deutsch English English Français Français Português Português Never Nikdy Once a day Jednou dennÄ› Once a week Jednou týdnÄ› Default author name: Výchozí jméno autora: Fixed direction keys TODO Klávesy fixního smÄ›ru Open most recent file on startup Otevírat nejnovÄ›jší soubor pÅ™i spuÅ¡tÄ›ní Custom Paths Vlastní cesty Parts Library: Knihovna souÄástí: Color Configuration: Barevná konfigurace: ... ... Minifig Settings: Nastavení Minifig: PO&V-Ray Executable: Spustitelný soubor PO&V-Ray: &LGEO Library: Knihovna &LGEO: Rendering Vykreslování Axis icon TODO Ikona osy Shading Mode: TODO Režim stínování: 2x 2x 4x 4x 8x 8x width šířka Anti-aliasing Antialiasing Stud Logo TODO Stud Logo Logo1 Logo1 Logo2 Logo2 Logo3 Logo3 Logo4 Logo4 Logo5 Logo5 Edge lines TODO Okrajové Äáry Wireframe Drátový model Flat Shading Ploché stínování Default Lights Výchozí osvÄ›tlení Mesh LOD Síť LOD Czech ÄŒesky Español Å panÄ›lsky Color Theme: Barevný motiv: Dark Tmavé System Systém Restore tab layout Obnovit rozvržení karty Highlight new parts ZvýraznÄ›te nové Äásti Fade previous steps Zeslabit pÅ™edchozí kroky Interface Rozhraní Overlays PÅ™ekrývání Overlay Color: Barva pÅ™ekrytí: Active View: Aktivní zobrazení: Base Grid Základní mřížka Draw studs TODO Nakreslete cvoÄky studs TODO cvoÄky Draw lines every TODO Nakreslí vÄechny Äáry View Sphere TODO Zobrazit sféru Disabled Zakázáno Small Malé Medium StÅ™ední Large Velké Highlight Color: Barva zvýraznÄ›ní: Size: Velikost: Color: Barva: Text Color: Barva textu: Location: TODO - poloha, umístÄ›ní , místo UmístÄ›ní: Stud Style Plain Thin Lines Logo Outline Logo Sharp Top Logo Rounded Top Logo Flattened Logo High Contrast High Contrast with Logo Settings... Contrast Settings... Views Model Views Axis Icon View Sphere: Top Left Vlevo nahoÅ™e Top Right Vpravo nahoÅ™e Bottom Left Vlevo dole Bottom Right Vpravo dole Draw origin lines Part Preview Colors Barvy Background Pozadí Top Color: Bottom Color: So&lid Color P&lná barva &Gradient PÅ™&echod Inactive View Border: Active View Border: Camera Name: Axis Icon Labels: Marquee Border: Highlight New Parts Fade Previous Steps Zeslabit pÅ™edchozí kroky Lines Conditional Lines Line Width: Edge Lines Automate Edge Color Marquee Fill: Grid Lines: Studs: Objects Light: Focused: Control Point Focused: Control Point: Selected: Camera: Categories Kategorie Parts Library Categories TODO Kategorie knihoven souÄástí Name Název Number Číslo Import... Importovat... Export... Exportovat... Reset... TODO - Vynulovat, obnovit, zruÅ¡it, pÅ™enastavit, resetovat Obnovit... Category Kategorie New... Nová... Edit... Upravit... Delete... Odstranit... Keyboard TODO Klávesnice Keyboard Shortcuts Klávesové zkratky Command Příkaz Shortcut Zkratka Search shortcuts Hledání zkratky Key se&quence: Kom&binace kláves: Assign PÅ™iÅ™adit Remove Odebrat Mouse MyÅ¡ Mouse Shortcuts Zkratky myší Action Akce Shortcut 1 Zkratka 1 Shortcut 2 Zkratka 2 Button: TlaÄítko: None Žádné Left Levé Middle StÅ™ední Right Pravé Modifiers: Modifikátory: Control Control Alt Alt Shift Shift Mouse sensitivity: Citlivost myÅ¡i: Grid spacing must be greater than 0. RozteÄ mřížky musí být vÄ›tší než 0. Select Parts Library Folder Vyberte složku knihovny Äástí Select Parts Library Archive Vyberte archiv knihovny Äástí Supported Archives (*.zip *.bin);;All Files (*.*) Podporované archivy (*.zip *.bin);;vÅ¡echny soubory (*.*) Select Color Configuration File Vyberte konfiguraÄní soubor barev Settings Files (*.ldr);;All Files (*.*) Soubory nastavení (*.ldr);;vÅ¡echny soubory (*.*) Select Minifig Settings File Vyberte soubor nastavení Minifig Settings Files (*.ini);;All Files (*.*) Soubory nastavení (*.ini);;vÅ¡echny soubory (*.*) Executable Files (*.exe);;All Files (*.*) Spustitelné soubory (*.exe);;vÅ¡echny soubory (*.*) All Files (*.*) VÅ¡echny soubory (*.*) Select POV-Ray Executable Vyberte spustitelný soubor POV-Ray Open LGEO Folder OtevÅ™ete složku LGEO Reset Colors Obnovit barvy Would you like to also reset the interface colors to match the color theme? Chcete také resetovat barvy rozhraní tak, aby odpovídaly barevnému motivu? Select Background Color Vybrat barvu pozadí Select Gradient Top Color Select Gradient Bottom Color Select Axes Color Vybrat barvu os Select Text Color Select Marquee Border Color Select Marquee Fill Color Select Overlay Color Select Active View Color Vybrat barvu aktivního pohledu Select Inactive View Color Select Fade Color Výbrat barvu slábnutí Select Highlight Color Vybrat barvu zvýraznÄ›ní Select Grid Stud Color TODO Vyberte barevnou mřížku Stud Select Grid Line Color TODO Vyberte barevnou mřížku Line Select View Sphere Color TODO Vyberte pohled dle barvy Sphere Select View Sphere Text Color TODO Vyberte pohled dle barvy textu Sphere Select View Sphere Highlight Color TODO Vyberte pohled dle barvy zvíraznÄ›ní Sphere Select Object Selected Color Select Object Focused Color Select Camera Color Select Light Color Select Control Point Color Select Control Point Focused Color Unassigned NepÅ™iÅ™azeno Are you sure you want to delete the category '%1'? Opravdu chcete smazat kategorii '%1'? Import Categories Importovat kategorie Text Files (*.txt);;All Files (*.*) Textové soubory (*.txt);;vÅ¡echny soubory (*.*) Error loading categories file. PÅ™i naÄítání souboru kategorií doÅ¡lo k chybÄ›. Export Categories Exportovat kategorie Error saving categories file. Chyba pÅ™i ukládání souboru kategorií. Are you sure you want to load the default categories? Opravdu chcete naÄíst výchozí kategorie? The shortcut '%1' is already assigned to '%2'. Do you want to replace it? Import shortcuts Importovat zkratky Error loading keyboard shortcuts file. Chyba pÅ™i Ätení souboru klávesových zkratek. Export shortcuts Exportovat zkratky Error saving keyboard shortcuts file. Chyba pÅ™i ukládání souboru klávesových zkratek. Are you sure you want to load the default keyboard shortcuts? Opravdu chcete naÄíst výchozí klávesové zkratky? Left Button Levé tlaÄítko Middle Button StÅ™ední tlaÄítko Right Button Pravé tlaÄítko Override Shortcut PÅ™epsat zkratky This shortcut is already assigned to '%1', do you want to replace it? Tato zkratka je již pÅ™iÅ™azena k '%1', chcete ji nahradit? Import Shortcuts Importovat zkratky Error loading mouse shortcuts file. Chyba pÅ™i Ätení souboru zkratek myÅ¡i. Export Shortcuts Exportovat zkratky Error saving mouse shortcuts file. PÅ™i ukládání souboru klávesových zkratek doÅ¡lo k chybÄ›. Are you sure you want to load the default mouse shortcuts? Opravdu chcete naÄíst výchozí zkratky pro myÅ¡? lcQPropertiesDialog Properties Vlastnosti Summary Souhrn Author: Autor: Description: Popis: Comments: Komentáře: Measurements: Scene Scéna Background Pozadí So&lid Color P&lná barva Image Obrázek &Gradient TODO PÅ™&echod ... ... Tile Dlaždice Set default options for new projects Nastavit jako výchozí možnosti pro nové projekty Parts Used Použité díly %1 Properties %1 Vlastnosti %1 x %2 x %3 cm %4 x %5 x %6 inches %7 x %8 x %9 LDU Part Část Total Celkem Select Background Color Vybrat barvu pozadí Select Background Top Color Vyberte horní barvu pozadí Select Background Bottom Color Vyberte spodní barvu pozadí Select Background Image Vyberte obrázek na pozadí All Image Files (*.png *.jpg *.gif *.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;GIF Files (*.gif);;BMP Files (*.bmp);;All Files (*.*) VÅ¡echny typy obrázků (*.bmp *.png *.jpg);;BMP soubory (*.bmp);;PNG soubory (*.png);;JPEG soubory (*.jpg);;vÅ¡echny soubory (*.*) lcQPropertiesTree Property Vlastnost Value Hodnota Position Pozice X X Y Y Z Z Rotation Rotace Visibility Viditelnost Visible Steps Viditelné kroky Show Zobrazit Hide Skrýt Appearance Vzhled Color Barva Part Část Target Cíl Up Nahoru Orthographic Pravoúhle FOV FOV Near Blízko Far Daleko Name Název Multiple Objects Selected Bylo vybráno nÄ›kolik objektů lcQSelectDialog Select Objects Vybrat objekty All VÅ¡e None Žádné Invert Invertovat lcQUpdateDialog LeoCAD Updates Aktualizace LeoCADu Connecting to update server... PÅ™ipojuji se k aktualizaÄnímu serveru ... <p>There's a newer version of LeoCAD available for download (%1.%2.%3).</p> <p>K dispozici je novÄ›jší verze LeoCADu ke stažení (%1.%2.%3).</p> <p>You are using the latest LeoCAD version.</p> <p>Používáte nejnovÄ›jší verzi LeoCADu.</p> <p>There are new parts available.</p> <p>K dispozici jsou nové aktualizace.</p> <p>There are no new parts available at this time.</p> <p>MomentálnÄ› nejsou k dispozici žádné nové aktualizace.</p> <p>Visit <a href="https://github.com/leozide/leocad/releases">https://github.com/leozide/leocad/releases</a> to download.</p> <p>NavÅ¡tivte <a href="https://github.com/leozide/leocad/releases">https://github.com/leozide/leocad/releases</a> pro stažení.</p> Error parsing update information. PÅ™i analýze informací o aktualizaci doÅ¡lo k chybÄ›. Error connecting to the update server. PÅ™i pÅ™ipojování k aktualizaÄnímu serveru doÅ¡lo k chybÄ›. lcRenderDialog Render Vykreslit Settings Nastavení Width: Šířka: Height: Výška: Quality: Kvalita: High Nejvyšší Medium StÅ™ední Low Nízká Output: Výstup: ... ... Cancel Render UkonÄit vykreslení Are you sure you want to cancel the current render? Opravdu chcete zruÅ¡it tvorbu aktuálního vykreslení? Cancel UkonÄit Error Chyba Error starting POV-Ray. Chyba spuÅ¡tÄ›ní POV-Ray. An error occurred while rendering. Check details or try again. PÅ™i vykreslování doÅ¡lo k chybÄ›. Zkontrolujte podrobnosti nebo to zkuste znovu. Error writing to file '%1': %2 Chyba zápisu do souboru '%1': %2 Error writing to %1 file '%2': %3 Chyba pÅ™i zápisu %1 do souboru '%2': %3 Select Output File Vyberte výstupní soubor Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) Podporované typy obrázků (*.bmp *.png *.jpg);;BMP soubory (*.bmp);;PNG soubory (*.png);;JPEG soubory (*.jpg);;vÅ¡echny soubory (*.*) lcSelectByColorDialog Select By Color VýbÄ›r dle barvy Color: Barva: lcSetsDatabaseDialog Sets Database Nastav databázi Set Name or Number Nastavit název nebo Äíslo Search Vyhledat Number Číslo Name Název Year Rok Parts Části Sets Database provided by <a href="https://www.rebrickable.com">Rebrickable</a> Nastaví databázi poskytovanou <a href="https://www.rebrickable.com">Rebrickable</a> Please select a set from the list. Vyberte sadu ze seznamu. Downloading Stahování Downloading set inventory Stahování inventáře Keyword cannot be empty. KlíÄové slovo nemůže být prázdné. Searching Vyhledávání Connecting to server PÅ™ipojování k serveru Error connecting to server. PÅ™i pÅ™ipojování k serveru doÅ¡lo k chybÄ›. Error downloading set inventory. PÅ™i stahování inventáře doÅ¡lo k chybÄ›. lcTimelineWidget Step %1 Krok %1 lcView LeoCAD LeoCAD Error creating images. PÅ™i vytváření obrázků doÅ¡lo k chybÄ›. Error Chyba Error writing to file '%1': %2 Chyba zápisu do souboru '%1': %2 leocad-23.03/resources/leocad_de.ts000066400000000000000000012077301440571307300172470ustar00rootroot00000000000000 Action File.New File.Open File.Merge File.Save File.SaveAs File.SaveImage File.Import.LDD File.Import.Inventory File.Export.3DS File.Export.COLLADA File.Export.HTML File.Export.BrickLink File.Export.CSV File.Export.POVRay File.Export.Wavefront File.Render File.Instructions File.Print File.PrintPreview File.Recent1 File.Recent2 File.Recent3 File.Recent4 File.Exit Edit.Undo Edit.Redo Edit.Cut Edit.Copy Edit.Paste Edit.PasteSteps Edit.Find Edit.FindNext Edit.FindPrevious Edit.FindAll Edit.Replace Edit.ReplaceNext Edit.ReplaceAll Edit.SelectAll Edit.SelectNone Edit.SelectInvert Edit.SelectByName Edit.SelectSingle Edit.SelectPiece Edit.SelectColor Edit.SelectPieceColor Edit.TransformRelative Edit.TransformAbsolute Edit.TransformToggleRelative Edit.TransformSeparately Edit.TransformTogether Edit.TransformToggleSeparate Edit.Snap.Toggle Edit.SnapMove.XY0 Edit.SnapMove.XY1 Edit.SnapMove.XY2 Edit.SnapMove.XY3 Edit.SnapMove.XY4 Edit.SnapMove.XY5 Edit.SnapMove.XY6 Edit.SnapMove.XY7 Edit.SnapMove.XY8 Edit.SnapMove.XY9 Edit.SnapMove.Z0 Edit.SnapMove.Z1 Edit.SnapMove.Z2 Edit.SnapMove.Z3 Edit.SnapMove.Z4 Edit.SnapMove.Z5 Edit.SnapMove.Z6 Edit.SnapMove.Z7 Edit.SnapMove.Z8 Edit.SnapMove.Z9 Edit.SnapAngle.Toggle Edit.SnapAngle.Angle0 Edit.SnapAngle.Angle1 Edit.SnapAngle.Angle2 Edit.SnapAngle.Angle3 Edit.SnapAngle.Angle4 Edit.SnapAngle.Angle5 Edit.SnapAngle.Angle6 Edit.SnapAngle.Angle7 Edit.SnapAngle.Angle8 Edit.SnapAngle.Angle9 Edit.Transform Edit.TransformAbsoluteTranslation Edit.TransformRelativeTranslation Edit.TransformAbsoluteRotation Edit.TransformRelativeRotation Edit.Tool.Insert Edit.Tool.Light Edit.Tool.Spotlight Edit.Tool.Camera Edit.Tool.Select Edit.Tool.Move Edit.Tool.Rotate Edit.Tool.Delete Edit.Tool.Paint Edit.Tool.ColorPicker Edit.Tool.Zoom Edit.Tool.Pan Edit.Tool.RotateView Edit.Tool.Roll Edit.Tool.ZoomRegion Edit.Cancel View.Preferences View.ZoomIn View.ZoomOut View.ZoomExtents View.LookAt View.MoveForward View.MoveBackward View.MoveLeft View.MoveRight View.MoveUp View.MoveDown View.Viewpoint.Front View.Viewpoint.Back View.Viewpoint.Top View.Viewpoint.Bottom View.Viewpoint.Left View.Viewpoint.Right View.Viewpoint.Home View.Cameras.None View.Cameras.Camera01 View.Cameras.Camera02 View.Cameras.Camera03 View.Cameras.Camera04 View.Cameras.Camera05 View.Cameras.Camera06 View.Cameras.Camera07 View.Cameras.Camera08 View.Cameras.Camera09 View.Cameras.Camera10 View.Cameras.Camera11 View.Cameras.Camera12 View.Cameras.Camera13 View.Cameras.Camera14 View.Cameras.Camera15 View.Cameras.Camera16 View.Time.First View.Time.Previous View.Time.Next View.Time.Last View.Time.InsertBefore View.Time.InsertAfter View.Time.Delete View.Time.AddKeys View.SplitHorizontal View.SplitVertical View.RemoveView View.ResetViews View.Toolbars.Standard View.Toolbars.Tools View.Toolbars.Time View.Toolbars.Parts View.Toolbars.Colors View.Toolbars.Properties View.Toolbars.Timeline View.Toolbars.Preview View.FullScreen View.CloseCurrentTab View.Shade.Wireframe View.Shade.Flat View.Shade.DefaultLights View.Projection.Perspective View.Projection.Orthographic View.ToggleViewSphere View.ToggleAxisIcon View.ToggleGrid View.FadePreviousSteps Piece.Insert Piece.Delete Piece.Duplicate Piece.PaintSelected Piece.ResetPivotPoint Piece.RemoveKeyFrames Piece.ControlPoint.Insert Piece.ControlPoint.Remove Piece.Move.PlusX Piece.Move.MinusX Piece.Move.PlusY Piece.Move.MinusY Piece.Move.PlusZ Piece.Move.MinusZ Piece.Rotate.PlusX Piece.Rotate.MinusX Piece.Rotate.PlusY Piece.Rotate.MinusY Piece.Rotate.PlusZ Piece.Rotate.MinusZ Piece.MinifigWizard Piece.Array Piece.ViewSelectedModel Piece.MoveSelectionToModel Piece.InlineSelectedModels Piece.EditSelectedSubmodel Piece.EditEndSubmodel Piece.Group Piece.Ungroup Piece.GroupAdd Piece.GroupRemove Piece.GroupEdit Piece.HideSelected Piece.HideUnselected Piece.UnhideSelected Piece.UnhideAll Piece.ShowEarlier Piece.ShowLater Model.New Model.Properties Model.List Model.Model01 Model.Model02 Model.Model03 Model.Model04 Model.Model05 Model.Model06 Model.Model07 Model.Model08 Model.Model09 Model.Model10 Model.Model11 Model.Model12 Model.Model13 Model.Model14 Model.Model15 Model.Model16 Model.Model17 Model.Model18 Model.Model19 Model.Model20 Model.Model21 Model.Model22 Model.Model23 Model.Model24 Model.Model25 Model.Model26 Model.Model27 Model.Model28 Model.Model29 Model.Model30 Model.Model31 Model.Model32 Model.Model33 Model.Model34 Model.Model35 Model.Model36 Model.Model37 Model.Model38 Model.Model39 Model.Model40 Help.HomePage Help.BugReport Help.Updates Help.About Menu &New &Neu &Open... &Öffnen... &Merge... &Vereinen... &Save &Speichern Save &As... Speichern &unter... Save &Image... &Bild speichern... 3D &Studio... 3D &Studio… &HTML... &HTML… &BrickLink... &BrickLink… &CSV... &CSV… &POV-Ray... &POV-Ray… &Wavefront... &Wavefront… Select by Col&or... Auswahl nach &Farbe... Single Selection Einzelauswahl Piece Selection Teilauswahl Color Selection Farbauswahl Piece and Color Selection Teil und Farbauswahl Relative Transforms Relative Umwandlung Move Snap Enabled Einrasten eingeschaltet Insert Before Insert After Open Selected Model Öffne Ausgewähltes Modell Edit Selected Submodel Bearbeite Ausgewähltes Untermodell End Submodel Editing Beende Untermodell Bearbeitung New Submodel... Neues Untermodell... Prope&rties... &Eigenschaften… &Print... &Drucken... &LEGO Digital Designer... &LEGO Digital Designer... Set &Inventory... Bausatz-&Inventar... &COLLADA... &COLLADA... &Render... &Rendern... &Instructions... Print Pre&view... Druck&vorschau... Print &Bill of Materials... Teileliste d&rucken… &Recent1 &Letzte1 &Recent2 &Letzte2 &Recent3 &Letzte3 &Recent4 &Letzte4 E&xit &Verlassen &Undo R&ückgängig &Redo &Wiederherstellen Cu&t &Ausschneiden &Copy Ko&pieren &Paste Ein&fügen &Find... &Suchen... Find Ne&xt Weiter suche&n Find Pre&vious Rückwärts s&uchen Find All &Replace Replace Next Replace All Select &All Alles &auswählen Select &None N&ichts auswählen Select &Invert &Auswahl umkehren Select by Na&me... Auswahl per Na&men… Absolute Transforms Toggle Relative Transforms Rotate Separately Rotate Together Toggle Separate Transforms None Keine 1/20 Stud 1/20 Noppen 1/4 Stud 1/4 Noppen 1 Flat 1 Flach 1/2 Stud 1/2 Noppen 1 Stud 1 Noppen 2 Studs 2 Noppen 3 Studs 3 Noppen 4 Studs 4 Noppen 8 Studs 8 Noppen 1 Brick 1 Stein 2 Bricks 2 Steine 4 Bricks 4 Steine 8 Bricks 8 Steine Rotation Snap Enabled Drehrastung eingeschaltet 1 Degree 1 Grad 5 Degrees 5 Grad 15 Degrees 15 Grad 22.5 Degrees 22.5 Grad 30 Degrees 30 Grad 45 Degrees 45 Grad 60 Degrees 60 Grad 90 Degrees 90 Grad 180 Degrees 180 Grad Transform Verändern Absolute Translation Absolute Verschiebung Relative Translation Relative Verschiebung Absolute Rotation Absolute Drehung Relative Rotation Relative Drehung Insert Einfügen Light Licht Spotlight Punktstrahler Camera Kamera Select Wählen Move Bewegen Rotate Drehen Delete Löschen Paint Anmalen Color Picker Zoom Zoomen Pan Schwenken Rotate View Ansicht drehen Roll Rollen Zoom Region Bereich zoomen Cancel Action Aktion abbrechen P&references... E&instellungen… Zoom In Vergrößern Zoom Out Verkleinern Zoom E&xtents &Alles sehen Look At Zentriert Move Forward Vorwärts bewegen Move Backward Rückwärts bewegen Move Left Nach links bewegen Move Right Nach rechts bewegen Move Up Nach oben bewegen Move Down Nach unten bewegen &Front &Vorderansicht &Back &Rückansicht &Top Dr&aufsicht B&ottom Ansicht &von Unten &Left &Links &Right &Rechts &Home &Ursprungsansicht Camera 1 Camera 2 Camera 3 Camera 4 Camera 5 Camera 6 Camera 7 Camera 8 Camera 9 Camera 10 Camera 11 Camera 12 Camera 13 Camera 14 Camera 15 Camera 16 Reset Zurücksetzen First Erster Previous Vorheriger Next Nächster Last Letzter Insert Step Schritt einfügen Remove Step Schritt entfernen Add Keys Schlüssel hinzufügen Split &Horizontal &Horizontal teilen Split &Vertical &Vertikal teilen Re&move View Ansicht &entfernen Rese&t Views Ansicht z&urücksetzen Standard Standard Tools Werkzeuge Time Zeit Parts Teile Colors Farben Properties Eigenschaften Timeline Zeitachse Preview &Full Screen &Vollbildansicht Close &Tab Schließe &Tab &Wireframe &Drahtrahmen &Flat Shading &Einfache Schattierung &Default Lights &Default Beleuchtung &Perspective &Perspektive &Orthographic &Rechtwinklig View Sphere Ansichtskugel Axis Icon Base Grid Grundraster Fade Previous Steps &Insert &Einfügen &Delete &Löschen &Duplicate &Duplizieren &Paint Selected Reset &Pivot Point &Ursprungspunkt zurücksetzen Remove &Key Frames &Keyframes entfernen Insert Control Point Steuerpunkt setzen Remove Control Point Steuerpunkt entfernen Move +X Bewege +X Move -X Bewege -X Move +Y Bewege +Y Move -Y Bewege -Y Move +Z Bewege +Z Move -Z Bewege -Z Rotate +X Drehe +X Rotate -X Drehe -X Rotate +Y Drehe +Y Rotate -Y Drehe -Y Rotate +Z Drehe +Z Rotate -Z Drehe -Z Minifig &Wizard... Minifig &Assistent… A&rray... &Vervielfachen… Move to New Model... In Neues Modell verschieben… Inline Selected Models Ausgewählte Modelle integrieren &Group... &Gruppieren... &Ungroup &Gruppierung aufheben &Add to Group Zur Gru&ppe hinzufügen Re&move from Group A&us der Gruppe entfernen &Edit Groups... Grup&pen Bearbeiten… &Hide Selected Auswahl &ausblenden Hide &Unselected Nichtausgewähltes aus&blenden &Unhide Selected Auswahl einb&lenden U&nhide All Alles einbl&enden Show Earlier Früheres zeigen Show Later Späteres zeigen Submodels... Untermodelle... Model 1 Model 2 Model 3 Model 4 Model 5 Model 6 Model 7 Model 8 Model 9 Model 10 Model 11 Model 12 Model 13 Model 14 Model 15 Model 16 Model 17 Model 18 Model 19 Model 20 Model 21 Model 22 Model 23 Model 24 Model 25 Model 26 Model 27 Model 28 Model 29 Model 30 Model 31 Model 32 Model 33 Model 34 Model 35 Model 36 Model 37 Model 38 Model 39 Model 40 Insert Step Before Insert Step After Move Selection Here Bewege die Auswahl hierher Set Current Step Aktuelle Schrittweite festlegen LeoCAD &Home Page &Homepage von LeoCAD &Recent 1 &Recent 2 &Recent 3 &Recent 4 Paste with Steps &Find Check for &Updates... Auf Aktualisierungen prü&fen… &About... &Über… Report a Bug Einen Fehler melden Mouse NewPiece Neues Teil NewPointLight Neues Punktlicht NewSpotLight Neues Spotlicht NewCamera Neue Kamera Select Auswählen Move Bewegen Rotate Drehen Delete Löschen Paint Anmalen ColorPicker Zoom Zoomen Pan Verschieben Orbit Umkreisen Roll Rollen ZoomRegion Bereich zoomen Project Empty Name Leerer Name Error Fehler Error reading file '%1': %2 Error loading file '%1': File format is not recognized. Merged Vereint LeoCAD LeoCAD Nothing to export. Nichts zu exportieren. Export 3D Studio Ins 3D Studio exportieren 3DS Files (*.3ds);;All Files (*.*) 3DS Datei (*.3ds);;Alle Dateien (*.*) Could not open file '%1' for writing. Konnte Datei » %1 « nicht zum Schreiben öffnen. Export BrickLink Nach BrickLink exportieren XML Files (*.xml);;All Files (*.*) XML Dateien (*.xml);;Alle Dateien (*.*) Export COLLADA COLLADA exportieren COLLADA Files (*.dae);;All Files (*.*) COLLADA Dateien (*.dae);;Alle Dateien (*.*) Export CSV Nach CSV exportieren CSV Files (*.csv);;All Files (*.*) CSV Datei (*.csv);;Alle Dateien (*.*) Error creating images. Fehler beim Erzeugen der Bilder. Export POV-Ray POV-Ray exportieren POV-Ray Files (*.pov);;All Files (*.*) POV-Ray Datei (*.pov);;Alle Dateien (*.*) Could not find LGEO files in folder '%1'. Konnte keine LGEO Dateien im Verzeichnis » %1 « finden. Export Wavefront Nach Wavefront exportieren Wavefront Files (*.obj);;All Files (*.*) Wavefront Dateien (*.obj);;Alle Dateien (*.*) Error writing to file '%1': %2 Fehler beim Schreiben der Datei » %1 « : %2 New Model.ldr Neues Modell.ldr New Model.mpd Neues Modell.mpd Submodel # Untermodell # Submodel Name: Untermodellname: The submodel name cannot be empty. Das Untermodell kann nicht leer sein. Duplicate Submodel Untermodell duplizieren A submodel named '%1' already exists, please enter a unique name. Ein Untermodell names '%1' existiert bereits, bitte geben sie einen eindeutigen Namen ein. New Submodel Neues Untermodell QApplication Group # Gruppe # Solid Colors Colors Farben Translucent Colors Colors Durchscheinende Farben Special Colors Colors Spezialfarben Solid Colors Translucent Colors Special Colors QMessageBox Error Fehler QObject LeoCAD LeoCAD Could not open file '%1' for writing. Konnte Datei » %1 « nicht zum Schreiben öffnen. Status Save a picture of the current view Aktuelle Ansicht als Bild speichern Export a list of parts used in BrickLink XML format Eine Teileliste im XML Format vom BrickLink exportieren Export a list of parts used in comma delimited file format Liste der verwendeten Teile in eine CSV getrennte Datei exportieren Print a list of parts used Liste der verwendeten Teile drucken Undo the last action Vorangehende Aktion rückgängig machen Redo the previously undone action Rückgängig gemachte Aktion wiederherstellen Cut the selection and put it on the Clipboard Auswahl ausschneiden und in die Zwischenablage legen Copy the selection and put it on the Clipboard Auswahl in die Zwischenablage kopieren Insert Clipboard contents Aus Zwischenablage einfügen Find object Objekt finden Find next object Nächstes Objekt finden De-select everything Auswahl aufheben Invert the current selection set Auswahl invertieren Select objects by name Objekte per Namen auswählen Toggle snap axes Einrasten an Achsen umschalten Snap rotations to fixed intervals Drehung in festen Intervallen Do not snap movement along the XY plane Bewegung in der XY-Eben kontinuierlich Snap movement along the XY plane to 1/20 stud Bewegung mit Einrasten entlang der XY-Ebene in 1/20 Noppen Snap movement along the XY plane to 1/4 stud Bewegung mit Einrasten entlang der XY-Ebene in 1/4 Noppen Snap movement along the XY plane to 1 flat Bewegung mit Einrasten entlang der XY-Ebene in 1 Fläche Snap movement along the XY plane to 1/2 stud Bewegung mit Einrasten entlang der XY-Ebene in 1/2 Noppen Snap movement along the XY plane to 1 stud Bewegung mit Einrasten entlang der XY-Ebene in 1 Noppen Snap movement along the XY plane to 2 studs Bewegung mit Einrasten entlang der XY-Ebene in 2 Noppen Snap movement along the XY plane to 3 studs Bewegung mit Einrasten entlang der XY-Ebene in 3 Noppen Snap movement along the XY plane to 4 studs Bewegung mit Einrasten entlang der XY-Ebene in 4 Noppen Snap movement along the XY plane to 8 studs Bewegung mit Einrasten entlang der XY-Ebene in 8 Noppen Do not snap movement along the Z axis Bewegung entlang der Z-Achse kontinuierlich Snap movement along the Z axis to 1/20 stud Bewegung mit Einrasten entlang der Z-Achse in 1/20 Noppen Snap movement along the Z axis to 1/4 stud Bewegung mit Einrasten entlang der Z-Achse in 1/4 Noppen Snap movement along the Z axis to 1 flat Bewegung mit Einrasten entlang der Z-Achse in 1 Fläche Snap movement along the Z axis to 1/2 stud Bewegung mit Einrasten entlang der Z-Achse in 1/2 Noppen Snap movement along the Z axis to 1 stud Bewegung mit Einrasten entlang der Z-Achse in 1 Noppen Snap movement along the Z axis to 1 brick Bewegung mit Einrasten entlang der Z-Achse in 1 Stein Snap movement along the Z axis to 2 bricks Bewegung mit Einrasten entlang der Z-Achse in 2 Steinen Snap movement along the Z axis to 4 bricks Bewegung mit Einrasten entlang der Z-Achse in 4 Steinen Snap movement along the Z axis to 8 bricks Bewegung mit Einrasten entlang der Z-Achse in 8 Steinen Do not snap rotations Drehung kontinuierlich Snap rotations to 1 degree Drehungen in 1 Grad Schritten Snap rotations to 5 degrees Drehungen in 5 Grad Schritten Create a new model Ein neues Modell anlegen Open an existing model Ein existierendes Modell öffnen Merge the contents of another file with the current one Die Inhalte einer anderen Datei mit der bestehenden vereinen Save the current model Aktuelles Modell speichern Save the current model with a new name Aktuelles Modell mit neuem Namen speichern Import a file in LEGO Digital Designer LXF format Import aus einer LEGO Digital Designer LXF Datei Import all parts from an official set Import aller Teile eines offiziellen Bausatzes Export the current model in 3D Studio 3DS format Export des aktuellen Modells in 3D Studio 3DS Format Export the current model in COLLADA DAE format Export des aktuellen Modells in COLLADA DAE Format Create an HTML page for the current model Erzeuge eine HTML Seite des aktuellen Modells Export the current model in POV-Ray format Export des aktuellen Modells in POV-Ray Format Export the current model in Wavefront OBJ format Export des aktuellen Modells in Wavefront OBJ Format Render the current model using POV-Ray Aktuelles Modell in POV-Ray rendern Print the current model Drucken des aktuellen Modells Display how the model would look if printed Druckvorschau des Modells Open this model Öffne dieses Modell Quit the application; prompts to save model Die Anwendung verlassen; fordert zum Speichern des Modells auf Select all pieces in the model Auswahl aller Teile des Modells Select pieces by color Teileauswahl nach Farbe Select one piece at a time Teile-Einzelauswahl Select all pieces of the same type Auswahl aller Teile gleichen Typs Select all pieces of the same color Auswahl aller Teile gleicher Farbe Select all pieces of the same type and color Auswahl aller Teile gleichen Typs und gleicher Farbe Move and rotate objects relative to the one that has focus Bewege und drehe Objekte relativ zu dem welches den Fokus hat Move and rotate objects in absolute coordinates Toggle moving and rotating objects relative to the one that has focus Rotate selected pieces separately Rotate selected pieces together Toggle rotating selected pieces separately Snap rotations to 15 degrees Drehungen in 15 Grad Schritten Snap rotations to 22.5 degrees Drehungen in 22,5 Grad Schritten Snap rotations to 30 degrees Drehungen in 30 Grad Schritten Snap rotations to 45 degrees Drehungen in 45 Grad Schritten Snap rotations to 60 degrees Drehungen in 60 Grad Schritten Snap rotations to 90 degrees Drehungen in 90 Grad Schritten Snap rotations to 180 degrees Drehungen in 180 Grad Schritten Apply transform to selected objects Transformation auf ausgewählte Objekte anwenden Switch to absolute translation mode when applying transforms Mit Anwendung der Transformation zum absoluten Bewegungsmodus wechseln Switch to relative translation mode when applying transforms Mit Anwendung der Transformation zum relativen Bewegungsmodus wechseln Switch to absolute rotation mode when applying transforms Mit Anwendung der Transformation zum absoluten Drehmodus wechseln Switch to relative rotation mode when applying transforms Mit Anwendung der Transformation zum relativen Drehmodus wechseln Add new pieces to the model Neue Teile zum Modell hinzufügen Add new omni light sources to the model Neue Punktlichtquelle zum Modell hinzufügen Add new spotlights to the model Neue Scheinwerferlichtquelle zum Modell hinzufügen Create a new camera Neue Kamera erzeugen Select objects (hold the CTRL key down or drag the mouse to select multiple objects) Objekte auswählen (Strg gedrückt halten oder mit der Maus mehrere Objekte auswählen) Move selected objects Ausgewählte Objekte bewegen Rotate selected pieces Ausgewählte Objekte drehen Delete objects Ausgewählte Objekte löschen Change piece color Farbe des Teils ändern Get piece color Zoom in or out Vergrößern oder verkleinern Pan the current view Ansicht verschieben Rotate the current view Ansicht drehen Roll the current view Ansicht rollen Zoom into a region of the screen In Teilbereich zoomen Cancel current mouse action Derzeitige Mausaktion abbrechen Change program settings Programmeinstellungen ändern Zoom in Vergrößern Zoom out Verkleinern Fit all pieces in current the view (hold the CTRL key down to zoom all views) Ansicht für alle Teile anpassen Rotate view so selected pieces are at center Ansicht durch Drehen um die selektierten Teile zentrieren Move the current view forward Ansicht vorwärts bewegen Move the current view backward Ansicht rückwärts bewegen Move the current view to the left Ansicht nach links bewegen Move the current view to the right Ansicht nach rechts bewegen Move the current view up Ansicht nach oben bewegen Move the current view down Ansicht nach unten bewegen View model from the front Vorderansicht des Modells View model from the back Rückansicht des Modells View model from the top Draufsicht des Modells zeigen View model from the bottom Ansicht von Unten zeigen View model from the left Linke Seitenansicht des Modells zeigen View model from the right Rechte Seitenansicht des Modells zeigen View model from the default position Modell in der voreingestellten Ansicht zeigen Do not use a camera Kamera nicht benutzen Use this camera Diese Kamera benutzen Reset views to their default positions Alle Ansichten auf Voreinstellung zurücksetzen Go to the first step of the model Gehe zum ersten Schritt des Modells Go to the previous step Gehe zum vorangehenden Schritt Go to the next step Gehe zum folgenden Schritt Go to the last step of the model Gehe zum letzten Schritt des Modells Insert new step Einen neuen Schritt einfügen Remove current step Aktuellen Schritt entfernen Close current tab Aktuellen Tab schließen Remove the selected control point Ausgewählten Steuerungspunkt entfernen Move the selected pieces to a new model and replace them with a reference to the model Bewege die ausgewählten Teile in ein neues Modell und ersetze diese durch eine Referenz auf das Modell Create a new submodel Erzeuge ein neues Untermodell Display the properties of the current submodel Eigenschaften des aktuellen Untermodells anzeigen Show a list of all submodels Liste aller Untermodell anzeigen Switch to this submodel Wechsel zu diesem Untermodell Open LeoCAD's bug report form on your default web browser LeoCADs Fehlerreportformular im voreingestellten Browser zeigen Move the selected parts into this step Bewege die ausgewählten Teile in diesen Schritt View the model at this point in the timeline Zeige das Modell an diesem Punkt der Zeitachse Toggle adding new animation keys Hinzufügen neuer Animationsschlüssel umschalten Configure instructions layout Insert Clipboard contents in the current step Insert Clipboard contents in their original steps Find piece Find next piece Find previous piece Find all pieces that match the search criteria Replace piece Replace next piece Replace all pieces that match the search criteria Insert a new step before the current step Insert a new step after the current step Split the current view horizontally Ansicht horizontal teilen Split the current view vertically Ansicht vertikal teilen Remove the current view Aktuelle Ansicht entfernen Reset all views Alle Ansichten zurücksetzen Toggle the Standard Toolbar Toggle the Tools Toolbar Toggle the Time Toolbar Toggle the Parts Toolbar Toggle the Colors Toolbar Toggle the Properties Toolbar Toggle the Timeline Toolbar Toggle the Preview Toolbar Toggle fullscreen mode Vollbildmodus umschalten Display the scene as wireframe Anzeige der Szene als Drahtgittermodell Display the scene without any shading or lights Anzeige der Szene ohne Schatten und Beleuchtung Display the scene with the default lights Anzeige der Szene mit voreingestellter Beleuchtung Set the current camera to use a perspective projection Aktuelle Kamera auf perspektivische Projektion umstellen Set the current camera to use an orthographic projection Aktuelle Kamera auf orthografische Projektion umstellen Toggle the view sphere Toggle axis icon Toggle grid Toggle fading previous model steps Add a new piece to the model Ein neues Teil zum Modell hinzufügen Delete selected objects Ausgewählte Objekte entfernen Create a copy of the selected pieces Erzeuge eine Kopie der ausgewählten Teile Change the color of the selected pieces Reset the pivot point of the selected pieces to their origin Drehpunkt der ausgewählten Teile auf deren Ursprung zurücksetzen Remove all key frames from the selected pieces Entferne alle Keyframes aus den ausgewählten Teilen Insert a new control point Einen neuen Steuerungspunkt einfügen Move selected objects along the X axis Ausgewählte Teile entlang der X-Achse bewegen Move selected objects along the Y axis Ausgewählte Teile entlang der Y-Achse bewegen Move selected objects along the Z axis Ausgewählte Teile entlang der Z-Achse bewegen Rotate selected objects along the X axis Ausgewählte Teile entlang der X-Achse drehen Rotate selected objects along the Y axis Ausgewählte Teile entlang der Y-Achse drehen Rotate selected objects along the Z axis Ausgewählte Teile entlang der Z-Achse drehen Add a new minifig to the model Ein neues minifig zum Modell hinzufügen Make copies of the selected pieces Erstelle Kopien der ausgewählten Teile Open the model referenced by the selected piece in a new tab Öffne das vom ausgewählten Teil referenzierte Modell in einem neuen Tab Insert the contents of the selected model references into the current model Inhalte der ausgewählten Modellreferenzen in ein neues Modell einfügen Edit the currently selected submodel in-place Bearbeite das ausgewählte Untermodell an Ort und Stelle End in-place submodel editing Beende Untermodellbearbeitung an Ort und Stelle Group selected pieces together Ausgewählte Teile gruppieren Ungroup selected group Ausgewählte Gruppe auflösen Add focused piece to selected group Füge Teil mit Fokus zur ausgewählten Gruppe hinzu Remove focused piece from group Entferne Teil mit Fokus aus der Gruppe Edit groups Gruppe bearbeiten Hide selected objects Ausgewählte Teile ausblenden Hide objects that are not selected Nicht ausgewählte Teile ausblenden Show hidden objects that are selected Zeige ausgeblendete Objekte die ausgewählt sind Show all hidden objects Zeige alle ausgeblendeten Objekte Show selected pieces one step earlier Zeige ausgewählte Teile einen Schritt vorher Show selected pieces one step later Zeige ausgewählte Teile einen Schritt danach Open LeoCAD's home page on the internet using your default web browser LeoCAD's Homepage im Standardbrowsers öffnen Check if a newer LeoCAD version or parts library has been released Prüfe ob eine aktualisierte Version von LeoCAD oder der Teilebibliothek verfügbar ist Display program version number and system information Zeige die Programmversion und Systemversion ViewName Left Links Right Rechts Back Hinten Front Vorne Top Oben Bottom Unten lcApplication LeoCAD LeoCAD LeoCAD could not find a compatible Parts Library so only a small number of parts will be available. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD konnte keine Teilebibliothek finden, es wird nur eine kleine Anzahl an Teilen verfügbar sein. Bitte lesen sie unter https://www.leocad.org nach wie man eine Bibliothek herunterläd und installiert. Not enough parameters for the '%1' option. Invalid parameter value specified for the '%1' option: '%2'. The file '%1' is not readable. Invalid parameter value(s) specified for the '%1' option: limits are +/- 360. Invalid parameter value(s) specified for the '%1' option. Invalid parameter value(s) specified for the '%1' option: requirements are: 1 <= <near> < <far>. High contrast stud style is required for the '%1' option but is not enabled. Automate edge color is required for the '%1' option but is not enabled. LeoCAD Continuous Build %1 LeoCAD Version %1 LeoCAD Version %1 Compiled %1 Usage: leocad [options] [file] [options] can be: -l, --libpath <path>: Set the Parts Library location to path. -i, --image <outfile.ext>: Save a picture in the format specified by ext and exit. -w, --width <width>: Set the picture width. -h, --height <height>: Set the picture height. -f, --from <step>: Set the first step to save pictures. -t, --to <step>: Set the last step to save pictures. -s, --submodel <submodel>: Set the active submodel. -c, --camera <camera>: Set the active camera. -ss, --stud-style <id>: Set the stud style 0=No style, 1=LDraw single wire, 2=LDraw double wire, 3=LDraw raised floating, 4=LDraw raised rounded, 5=LDraw subtle rounded, 6=LEGO no logo, 7=LEGO single wire. --viewpoint <front|back|left|right|top|bottom|home>: Set the viewpoint. --camera-angles <latitude> <longitude>: Set the camera angles in degrees around the model. --camera-position <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector. --camera-position-ldraw <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector using LDraw coordinates. --orthographic: Render images using an orthographic projection. --fov <degrees>: Set the vertical field of view used to render images (< 180). --zplanes <near> <far>: Set the near and far clipping planes used to render images (1 <= <near> < <far>). --fade-steps: Render parts from prior steps faded. --no-fade-steps: Do not render parts from prior steps faded. --fade-steps-color <rgba>: Renderinng color for prior step parts (#AARRGGBB). --highlight: Highlight parts in the steps they appear. --no-highlight: Do not highlight parts in the steps they appear. --highlight-color: Renderinng color for highlighted parts (#AARRGGBB). --shading <wireframe|flat|default|full>: Select shading mode for rendering. --line-width <width>: Set the width of the edge lines. --aa-samples <count>: AntiAliasing sample size (1, 2, 4, or 8). -scc, --stud-cylinder-color <#AARRGGBB>: High contrast stud cylinder color. -ec, --edge-color <#AARRGGBB>: High contrast edge color. -bec, --black-edge-color <#AARRGGBB>: High contrast edge color for black parts. -dec, --dark-edge-color <#AARRGGBB>: High contrast edge color for dark color parts. -aec, --automate-edge-color: Enable automatically adjusted edge colors. -cc, --color-contrast <float>: Color contrast value between 0.0 and 1.0. -ldv, --light-dark-value <float>: Light/Dark color value between 0.0 and 1.0. -obj, --export-wavefront <outfile.obj>: Export the model to Wavefront OBJ format. -3ds, --export-3ds <outfile.3ds>: Export the model to 3D Studio 3DS format. -dae, --export-collada <outfile.dae>: Export the model to COLLADA DAE format. -html, --export-html <folder>: Create an HTML page for the model. -v, --version: Output version information and exit. -?, --help: Display this help message and exit. Unknown option: '%1'. High contrast stud and edge color settings are ignored when -aec or --automate-edge-color is set. --viewpoint is ignored when --camera is set. --orthographic is ignored when --camera is set. --camera-angles is ignored when --camera is set. --camera-position is ignored when --camera is set. --camera-angles is ignored when --viewpoint is set. --camera-position is ignored when --viewpoint is set. --camera-position is ignored when --camera-angles is set. No file name specified. Error creating OpenGL context. LeoCAD could not load Parts Library. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD konnte die Teilebibliothek nicht laden. Bitte lesen sie unter https://www.leocad.org nach wie man eine Bibliothek herunterläd und installiert. Error: model '%1' does not exist. Saved '%1'. Some changes will only take effect the next time you start LeoCAD. Parts library and Anti-aliasing changes will only take effect the next time you start LeoCAD. Die Teilebibliothek und Einstellungen zu Aliasing werden erst nach Neustart von LeoCAD wirksam. Parts library changes will only take effect the next time you start LeoCAD. Die Teilebibliothek werden erst nach Neustart von LeoCAD wirksam. Anti-aliasing changes will only take effect the next time you start LeoCAD. Einstellungen zu Aliasing werden erst nach Neustart von LeoCAD wirksam. lcAutomateEdgeColorDialog Color Preferences Edge Colors Contrast: Set the amount of contrast - 0.50 is midway. Reset Zurücksetzen Light/Dark Value: Saturation: Set to classify where color values are light or dark - e.g. Dark Bluish Gray (72) is light at 0.39. Set to specify amount of edge color tint or shade from the saturation adjusted part color High Contrast Stud Cylinder Color: Parts Edge Color: Black Parts Edge Color: Dark Parts Edge Color: Select Stud Cylinder Color Select Part Edge Color Automate edge color appears to be enabled.<br>Black parts edge color will not be accessible.<br>Do you want to continue? Select Black Edge Color Automate edge color appears to be enabled.<br>Dark parts edge color will not be accessible.<br>Do you want to continue? Select Dark Edge Color lcFindReplaceWidget Find: Replace: lcInstructions Show Step Number Show Parts List Font: Text Color: Textfarbe: Background Color: Border Color: lcInstructionsDialog Instructions Page Settings Print Vertical Horizontal Page %1 lcInstructionsPageListWidget Pages Page Setup lcInstructionsPropertiesWidget Properties Eigenschaften Default Current Model Current Step Only Current Step Forward Scope: Preset: Select Step Number Color Select Step Background Color Select Parts List Background Color Select Parts List Border Color Select Parts List Text Color Select Step Number Font Select Parts List Font Step Properties Step Number Properties Parts List Properties lcMainWindow Transform Transformation C&ameras K&ameras &File &Datei &Export &Exportieren &Edit &Bearbeiten &View &Ansicht &Viewpoints &Ansichten New Model Neues Modell Open Model Modell öffnen Save Model Modell speichern Projection Projektion Sh&ading Sch&atten &Import &Import Ste&p Schrit&te T&oolbars Werkz&euge &Piece &Teil Transform Options Preview %n Object(s) selected Rel Abs M: %1 %2 R: %3 %4 M : %1 %2 R : %3 {1 %2 ?} {3 %4 ?} Merge Model Modell zusammenführen Merged 1 submodel. Ein Untermodell zusammenführen. Merged %1 submodels. %1 Untermodelle zusammengefügt. Import Import LEGO Diginal Designer Files (*.lxf);;All Files (*.*) LEGO Diginal Designer Dateien (*.lxf);;Alle Dateien (*.*) &Help &Hilfe Snap XY Einrasten XY Snap Z Einrasten Z Snap Menu Schritte Menü Movement Snap Einrasten für Bewegung Snap translations to fixed intervals Einrasten der Bewegung in festen Intervallen Snap Angle Menu Winkelschritte Menü Rotation Snap Einrasten für Drehung Snap rotations to fixed intervals Einrasten der Drehung in festen Intervallen Standard Standard Tools Werkzeuge Sub&model Unter&modell Selection Mode Auswahlmodus Time Zeit Parts Teile Colors Farben Properties Eigenschaften Timeline Zeitachse %1 (ID: %2) %1 (ID : %2) - %1 (ID: %2) - %1 (ID : %2) in group '%1' in der Gruppe » %1 « Step %1 Schritt %1 M: %1 %2 R: %3 M : %1 %2 R : %3 &Undo %1 %1 rück&gängig machen &Undo Rückg&ängig machen &Redo %1 %1 &wiederherstellen &Redo &Wiederherstellen Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*) Unterstützte Dateien (*.lcd *.ldr *.dat *.mpd);;Alle Dateien (*.*) LeoCAD LeoCAD Change selection mode Auswahlmodus wechseln Close Other Tabs Andere Tabs schliessen Reset Views Ansicht zurücksetzten The file '%1' has been modified by another application, do you want to reload it? Die Datei '%1' wurde von einer anderen Anwwendung verändert, erneut laden? File Changed Datei verändert Error loading '%1'. Fehler beim Laden von » %1 «. Supported Files (*.mpd);;All Files (*.*) Unterstützte Dateien (*.mpd);;Alle Dateien (*.*) Supported Files (*.ldr *.dat *.mpd);;All Files (*.*) Unterstützte Dateien (*.ldr *.dat *.mpd);;Alle Dateien (*.*) Error Fehler Saving files in LCD format is no longer supported, please use the LDR or MPD formats instead. Speichern als LCD Format wird nicht mehr unterstützt, bitte LDR oder MPD Format verwenden. Save changes to '%1'? Änderungen an » %1 « speichern? 0 0 1/20S 1/20T 1/4S 1/4T 1F 1P 1/2S 1/2T 1S 1T 2S 2T 3S 3T 4S 4T 8S 8T None Keine 1B 1B 2B 2B 4B 4B 8B 8B lcMinifigDialog Minifig Wizard Minifig Assistent Templates Vorlagen Save... Speichern... Delete... Löschen… Import... Importieren… Export... Save Template Vorlage Speichern Template Name: Vorlagenname: Template name cannot be empty. Vorlagenname darf nicht leer sein. Are you sure you want to overwrite the template '%1'? Sind sie sicher das sie die Vorlage '%1' überschreiben wollen? Overwrite Template Vorlage Überschreiben Are you sure you want to delete the template '%1'? Sind sie sicher das sie die Vorlage '%1' löschen wollen? Delete Template Vorlage Löschen Import Templates Minifig Template Files (*.minifig);;All Files (*.*) Error Fehler Error reading file '%1': %2 Export Templates Error writing to file '%1': %2 Fehler beim Schreiben der Datei » %1 « : %2 lcModel Pasting Pasting LeoCAD LeoCAD Error creating images. Fehler beim Bilder Erstellen. Inserting Step Schritt einfügen Removing Step Schritt löschen No pieces selected. Kein Teil ausgewählt. Group # Gruppe # Cutting Schneiden Duplicating Pieces Teile duplizieren Error Fehler Error writing to file '%1': %2 Fehler beim Schreiben der Datei » %1 « : %2 Grouping Gruppieren Ungrouping Gruppierung aufheben Editing Groups Gruppen bearbeiten Adding Piece Teil hinzufügen Resetting Cameras Kameras zurücksetzen Removing Key Frames Keyframes entfernen Modifying Verändernd New Model Neues Modell Inlining In eine Reihe Moving Bewegen Rotating Drehen Scaling Skalieren Setting Part Teil setzen Hide Ausblenden Unhide Einblenden Replacing Part New SpotLight Neues Scheinwerferlicht New Camera Neue Kamera Move Bewegen Rotate Drehen Zoom Zoomen Pan Verschieben Orbit Umkreisen Roll Rollen Insert Einfügen New Light Neues Licht Deleting Löschen Painting Farbgebung No models selected. Kein Modell ausgewählt. Showing Pieces Zeige Teile Hiding Pieces Teile ausblenden Editing Camera Kamera bearbeiten Changing FOV FOV ändern Renaming Camera Kamera umbenennen Look At Modell betrachten Moving Camera Kamera bewegen Changing Properties Eigenschaften ändern Nothing to select. Nichts auszuwählen. Array only has 1 element or less, no pieces added. Das Array hat nur 1 Element oder weniger, keine Teile zugefügt. Array Array Minifig # Minifig # Minifig Minifig lcPageSetupDialog Page Setup Size Width: Breite: Height: Höhe: Preset: Units: Margins Left: Right: Top: Bottom: lcPartPaletteDialog Part Palettes New... Neu… Delete... Löschen… Rename... Import... Importieren… Move Up Nach oben bewegen Move Down Nach unten bewegen New Part Palette Palette Name: Are you sure you want to delete the palette '%1'? Delete Part Palette Rename Part Palette lcPartSelectionListView No Icons Keine Symbole Small Icons Kleine Symbole Medium Icons Mittelgroße Symbole Large Icons Große Symbole Extra Large Icons Extragroße Symbole Show Part Names Zeige Teilenamen Show Decorated Parts Zeige verzierte Teile List Mode Listenmodus Lock Preview Color Vorschaufarbe sperren Add to Palette None Keine Remove from Palette lcPartSelectionWidget Search Parts Teile suchen Options Edit Palettes... No Icons Keine Symbole Small Icons Kleine Symbole Medium Icons Mittelgroße Symbole Large Icons Große Symbole Extra Large Icons Extragroße Symbole Show Part Names Zeige Teilenamen Show Decorated Parts Zeige verzierte Teile Show Part Aliases List Mode Listenmodus Lock Preview Color Vorschaufarbe sperren Favorites All Parts Alle Teile In Use Parts In Use Teile in Verwendung Submodels Untermodelle lcPiecesLibrary Initializing Initialisiere Loading Parts Library Lade Teile Bibliothek lcPreviewDockWidget Lock Preview Ctrl+L Toolbar Preview Toolbar Loading... Unlock the preview display to enable updates Lock the preview display to disable updates Unlock Preview lcQAboutDialog About LeoCAD Über LeoCAD LeoCAD Version 0.00.0 LeoCAD Version 0.00.0 LeoCAD is a free application for creating virtual LEGO models. LeoCAD ist eine freie Anwendung zur Gestaltung virtueller LEGO Modelle. System Information Systeminformationen LeoCAD Version %1 LeoCAD Version %1 OpenGL Version %1 (GLSL %2) %3 - %4 OpenGL Version %1 (GLSL %2) %3 - %4 Color Buffer: %1 bits %2 %3 Depth Buffer: %4 bits Stencil Buffer: %5 bits Farbpuffer: %1 bits %2 %3 Tiefenpuffer: %4 bits Schablonenpuffer: %5 bits indexed indiziert double buffered doppelt gepuffert GL_ARB_vertex_buffer_object extension: %1 GL_ARB_framebuffer_object extension: %2 GL_EXT_framebuffer_object extension: %3 GL_EXT_blend_func_separate: %4 GL_EXT_texture_filter_anisotropic extension: %5 GL_ARB_vertex_buffer_object extension: %1 GL_ARB_framebuffer_object extension: %2 GL_EXT_framebuffer_object extension: %3 GL_EXT_blend_func_separate: %4 GL_EXT_texture_filter_anisotropic extension: %5 LeoCAD Continuous Build %1 Qt Version %1 (compiled with %2) Color Buffer: %1 bits Depth Buffer: %2 bits Stencil Buffer: %3 bits Buffers: %1 Shaders: %2 Framebuffers: %3 BlendFuncSeparate: %4 Anisotropic: %5 Supported Unterstützt Not supported Nicht unterstützt Supported (max %1) Unterstützt (maximal %1) lcQArrayDialog Array Array Dimensions Abmessungen Offsets Versatz Rotations Drehungen Array is empty. Array ist leer. lcQCategoryDialog Category Kategorie Name: Name: Keywords: Schlüsselwörter: Edit Category Kategorie bearbeiten New Category Neue Kategorie Name cannot be empty. Der Name kann nicht leer sein. Keywords cannot be empty. Schlüsselwörter müssen vorhanden sein. lcQEditGroupsDialog Edit Groups Gruppen bearbeiten New Group Neue Gruppe Group # Gruppe # lcQFindDialog Find Suchen Name Name Part ID ID des Teils Color Farbe lcQGroupDialog Group Gruppe Name Name Name cannot be empty. Der Name muss vorhanden sein. lcQHTMLDialog HTML Options HTML Optionen General Allgemein Output folder: Ausgangsordner: ... ... Transparent image background Transparentes Hintergrundbild Width: Breite: Height: Höhe: Index page Indexseite Models Modell All Models Alle Modelle Current Model and Submodels Aktives Modell und Untermodelle Current Model Only Nur aktives Modell Steps Schritte Single Page Einzelseite One Step per Page Ein Schritt pro Seite Highlight new parts Neue Teile Markieren Parts List Teileliste At the end Am Ende After each step Nach jedem Schritt Color: Farbe: Create images Bilder erzeugen Output folder cannot be empty. Das Ausgangsverzeichnis darf nicht leer sein. Select Output Folder Ausgangsordner auswählen lcQImageDialog Save Image Bild speichern File name: Dateiname: Dimensions Abmessungen Step Range Schrittweite All Steps Alle Schritte Current Step Aktiver Schritt Custom Range Individualisierte Schrittweite From: Von: To: An: Width: Breite: Height: Höhe: ... ... Output File cannot be empty. Ausgabedatei darf nicht leer sein. Error Fehler First step must be between 1 and %1. Der erste Schritt muss zwischen 1 und %1 sein. Last step must be between 1 and %1. Der letzte Schritt muss zwischen 1 und %1 sein. Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) Unterstützte Bilddateien (*.bmp *.png *.jpg);;BMP Dateien (*.bmp);;PNG Dateien (*.png);;JPEG Dateien (*.jpg);;Alle Dateien (*.*) Last step must be greater than first step. Der letzte Schritt muss grösser sein als der erste. Please enter a width between 1 and 32768. Bitte die Breite zwischen 1 und 32768 eingeben. Please enter a height between 1 and 32768. Bitte die Höhe zwischen 1 und 32768 eingeben. Save Image File Bilddatei speichern lcQMinifigDialog Minifig Wizard Minifig Assistent Templates Vorlagen Save... Speichern... Delete... Löschen… Save Template Vorlage Speichern Template Name: Vorlagenname: Template name cannot be empty. Vorlagenname darf nicht leer sein. Are you sure you want to overwrite the template '%1'? Sind sie sicher das sie die Vorlage '%1' überschreiben wollen? Overwrite Template Vorlage Überschreiben Are you sure you want to delete the template '%1'? Sind sie sicher das sie die Vorlage '%1' löschen wollen? Delete Template Vorlage Löschen lcQModelListDialog Submodels Untermodelle &New... &Neu... D&elete... L&öschen… &Rename... &Umbenennen… Export... Exportieren... Duplicate... Move &Up &nach oben Move &Down &nach unten Set Active New Submodel Neues Untermodell Error Fehler The model cannot be empty. Das Modell darf nicht leer sein. Are you sure you want to delete the submodel '%1'? Sind sie sicher dass sie dieses Untermodell '%1' löschen wollen? Delete Submodel Untermodell löschen No submodel selected. Are you sure you want to delete %1 submodels? Rename Submodel Untermodell umbenennen Export Submodel LeoCAD LeoCAD Nothing to export. Nichts zu exportieren. Export Model Select Export Folder Duplicate Submodel Untermodell duplizieren Copy of Save Model Modell speichern Supported Files (*.ldr *.dat);;All Files (*.*) Unterstützte Dateien (*.ldr *.dat);;Alle Dateien (*.*) lcQPreferencesDialog Preferences Einstellungen General Allgemein Default author name: Voreinstellung für Autor: ... ... Custom parts library: Eigene Teilebibliothek: Open most recent file on startup Öffne die zuletzt verwendete Datei beim Start Mouse Maus Mouse Shortcuts Maus-Kurzbefehle Action Aktion Shortcut 1 Tastenkürzel 1 Shortcut 2 Tastenkürzel 2 Button: Maustaste: None Keine Left Links Middle Mitte Right Rechts Modifiers: Sondertaste: Control Strg Alt Alt Shift Shift Mouse sensitivity: Mausempfindlichkeit: Check for updates: Auf Aktualisierungen prüfen: PO&V-Ray Executable: PO&V-Ray Executable: &LGEO Path: &LGEO Pfad: Never Nie Once a day Einmal am Tag Once a week Einmal pro Woche Fixed direction keys Feste Richtungstasten Rendering Rendern Edge lines Randlinien Axis icon Achsenbeschriftung width Breite Anti-aliasing Anti-aliasing 2x 2x 4x 4x 8x 8x Shading Mode: Schattenmodus: Wireframe Drahtmodell Flat Shading Einfache Schatten Default Lights Voreingestellte Beleuchtung Base Grid Grundraster Draw studs Noppen darstellen studs Noppen Draw lines every Linien zeichnen alle View Sphere Ansichtskugel Disabled Deaktiviert Small Klein Medium Mittel Large Groß Highlight Color: Hervorhebungsfarbe: Size: Größe: Color: Farbe: Text Color: Textfarbe: Location: Position: Application Language: Default Czech Deutsch English Français Português Español Color Theme: Dark System Custom Paths Parts Library: Color Configuration: Minifig Settings: &LGEO Library: Restore tab layout Stud Style Mesh LOD Highlight new parts Neue Teile Markieren Plain Thin Lines Logo Outline Logo Sharp Top Logo Rounded Top Logo Flattened Logo High Contrast High Contrast with Logo Settings... Contrast Settings... Views Model Views Axis Icon View Sphere: Top Left Oben links Top Right Oben rechts Bottom Left Unten links Bottom Right Oben rechts Draw origin lines Part Preview Colors Farben Background Hintergrund Top Color: Bottom Color: So&lid Color F&lächenfarbe &Gradient &Gradient Interface Inactive View Border: Overlay Color: Active View Border: Camera Name: Axis Icon Labels: Marquee Border: Highlight New Parts Fade Previous Steps Lines Conditional Lines Line Width: Edge Lines Automate Edge Color Marquee Fill: Grid Lines: Studs: Objects Light: Focused: Control Point Focused: Control Point: Selected: Camera: Categories Kategorie Parts Library Categories Kategorie der Teilebibliothek Name Name Number Nummer Import... Importieren… Export... Exportieren… Reset... Zurücksetzen… Category Kategorie New... Neu… Edit... Bearbeiten… Delete... Löschen… Keyboard Tastatur Keyboard Shortcuts Tastenkürzel Command Befehl Shortcut Kürzel Search shortcuts Key se&quence: Tasten&folge: Assign Zuweisen Remove Entfernen Grid spacing must be greater than 0. Rasterweite muss grösser als 0 sein. Select Parts Library Folder Wähle Teilebibliothek Ordner Supported Archives (*.zip *.bin);;All Files (*.*) Unterstütze Bibliotheken (*.zip *.bin);;Alle Dateien (*.*) Select Parts Library Archive Wähle Teilebibliothek Archiv Select Color Configuration File Settings Files (*.ldr);;All Files (*.*) Select Minifig Settings File Settings Files (*.ini);;All Files (*.*) Executable Files (*.exe);;All Files (*.*) Asuführbare Dateien (*.exe);;Alle Dateien (*.*) All Files (*.*) Alle Dateien (*.*) Open POV-Ray Executable Asuführbares POV-Ray öffnen Open LGEO Folder LGEO Ordner öffnen Reset Colors Would you like to also reset the interface colors to match the color theme? Select Background Color Hintergrundfarbe wählen Select Gradient Top Color Select Gradient Bottom Color Select Axes Color Select Text Color Select Marquee Border Color Select Marquee Fill Color Select Overlay Color Select Active View Color Select Inactive View Color Select Fade Color Select Highlight Color Select Grid Stud Color Farbe der Noppen im Gitter wählen Select Grid Line Color Farbe der Gitterlinien wählen Select View Sphere Color Wähle Ansichtskugelfarbe Select View Sphere Text Color Wähle Ansichtskugel Textfarbe Select View Sphere Highlight Color Wähle Ansichtskugel Hervorhebungsfarbe Select Object Selected Color Select Object Focused Color Select Camera Color Select Light Color Select Control Point Color Select Control Point Focused Color Unassigned Unbestimmt Are you sure you want to delete the category '%1'? Sind sie sicher dass sie die Kategorie » %1 « löschen möchten? Import Categories Kategorien importieren Text Files (*.txt);;All Files (*.*) Textdateien (*.txt);;Alle Dateien (*.*) Error loading categories file. Fehler beim Laden der Kategoriedatei. Export Categories Kategorien exportieren Error saving categories file. Fehler beim Speichern der Kategoriendatei. Are you sure you want to load the default categories? Sind sie sicher dass sie die voreingestellten Kategorien laden möchten? The shortcut '%1' is already assigned to '%2'. Do you want to replace it? Import shortcuts Tastenkürzel laden Error loading keyboard shortcuts file. Fehler beim Laden der Tastaturkürzel-Datei. Export shortcuts Tastaturkürzel exportieren Error saving keyboard shortcuts file. Fehler beim Speichern der Tastaturkürzel-Datei. Are you sure you want to load the default keyboard shortcuts? Sind sie sicher dass sie die voreingestellten Tastaturkürzel laden möchten? Left Button Linke Maustaste Middle Button Mittlere Maustaste Right Button Rechte Maustaste Override Shortcut Tastaturkürzel ändern Select POV-Ray Executable This shortcut is already assigned to '%1', do you want to replace it? Dieses Tastaturkürzel ist bereits » %1 « zugewiesen, möchten sie es ersetzen? Import Shortcuts Error loading mouse shortcuts file. Export Shortcuts Error saving mouse shortcuts file. Are you sure you want to load the default mouse shortcuts? Sind sie sicher dass sie die voreingestellten Mauskürzel laden möchten? lcQPropertiesDialog Properties Eigenschaften Summary Zusammenfassung Author: Autor: Description: Beschreibung : Comments: Kommentare: Measurements: Scene Szene Background Hintergrund So&lid Color F&lächenfarbe &Gradient &Gradient Image Bild ... ... Tile Kachel Set default options for new projects Voreinstellungen der Optionen für neue Projekte Parts Used Verwendete Teile %1 Properties %1 Eigenschaften %1 x %2 x %3 cm %4 x %5 x %6 inches %7 x %8 x %9 LDU Part Teil Total Gesamt Select Background Color Hintergrundfarbe wählen Select Background Top Color Hintergrundfarbe oben wählen Select Background Bottom Color Hintergrundfarbe unten wählen Select Background Image Hintergrundbicl wählen All Image Files (*.png *.jpg *.gif *.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;GIF Files (*.gif);;BMP Files (*.bmp);;All Files (*.*) Alle Bilddateien (*.png *.jpg *.gif *.bmp);;PNG Dateien (*.png);;JPEG Datein (*.jpg);;GIF Dateien(*.gif);;BMP Dateien (*.bmp);;Alle Dateien (*.*) lcQPropertiesTree Property Eigenschaft Value Wert Position Position X X Y Y Z Z Rotation Drehung Visibility Sichtbarkeit Visible Steps Show Zeige Hide Ausblenden Appearance Erscheinungsbild Color Farbe Part Teil Target Ziel Up Hoch Orthographic Orhografisch FOV FOV Near Nah Far Fern Name Name Multiple Objects Selected Mehrere Objekre ausgewählt lcQSelectDialog Select Objects Objekte auswählen All Alle None Keine Invert Umkehren lcQUpdateDialog LeoCAD Updates Aktualisierungen für LeoCAD Connecting to update server... Verbinde zum Server für Aktualisierungen… <p>There's a newer version of LeoCAD available for download (%1.%2.%3).</p> <p>Es ist einen neue Version von LeoCAD zum herunterladen verfügbar (%1.%2.%3).</p> <p>You are using the latest LeoCAD version.</p> <p>Sie benutzen die aktuelle Version von LeoCAD.</p> <p>There are new parts available.</p> <p>Es sind neue Teile verfügbar.</p> <p>There are no new parts available at this time.</p> <p>Im Moment gibt es keine neuen Teile.</p> <p>Visit <a href="https://github.com/leozide/leocad/releases">https://github.com/leozide/leocad/releases</a> to download.</p> <p>Besuchen sie <a href="https://github.com/leozide/leocad/releases">https://github.com/leozide/leocad/releases</a> zum downloaden.</p> Error parsing update information. Fehler bei der Analyse der Aktualisierungsinformation. Error connecting to the update server. Fehler bein Verbinden mit dem Aktualisierungsserver. lcRenderDialog Render Render Settings Einstellungen Width: Breite: Height: Höhe: High Hoch Medium Mittel Low Niedrig Quality: Qualität: Output: Ausgabe: ... ... Cancel Render Rendern abbrechen Are you sure you want to cancel the current render? Sind sie sicher dass sie das aktuelle Rendern abbrechen wollen? Cancel Abbrechen Error Fehler Error starting POV-Ray. Fehler beim Start von POV-Ray. An error occurred while rendering. Check details or try again. Beim Rendern ist ein Fehler aufgetreten. Siehe Details oder versuchen Sie es erneut. Error writing to file '%1': %2 Fehler beim Schreiben der Datei » %1 « : %2 Error writing to %1 file '%2': %3 Select Output File Wahl der Ausgabedatei Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) Unterstützte Bilddateien (*.bmp *.png *.jpg);;BMP Dateien (*.bmp);;PNG Dateien (*.png);;JPEG Dateien (*.jpg);;Alle Dateien (*.*) lcSelectByColorDialog Select By Color Auswahl nach Farbe Color: Farbe: lcSetsDatabaseDialog Sets Database Bausatz-Datenbank Set Name or Number Bausatz-Name oder -Nummer Search Suchen Number Nummer Name Name Year Jahr Parts Teile Sets Database provided by <a href="https://www.rebrickable.com">Rebrickable</a> Bausatz-Datenbank bereitgestellt von <a href="https://www.rebrickable.com">Rebrickable</a> Please select a set from the list. Bitte wählen Sie einen Bausatz aus der Liste. Downloading Downloaden Downloading set inventory Downloaden des Bausatz-Inventars Keyword cannot be empty. Schlüsselword darf nicht leer sein. Searching Suche Connecting to server Verbindungsaufnahme zum Server Error connecting to server. Fehler beim Verbinden zum Server. Error downloading set inventory. Fehler beim Downloaden des Bausatz-Inventars. lcTimelineWidget Step %1 Schritt %1 lcView LeoCAD LeoCAD Error creating images. Error Fehler Error writing to file '%1': %2 Fehler beim Schreiben der Datei » %1 « : %2 leocad-23.03/resources/leocad_document.icns000066400000000000000000010540011440571307300207720ustar00rootroot00000000000000icnsXTOC `ic08{ ic13{ ic09{‡ic12¨ic071Wil32il8mkic11˜is32cs8mkic14{‡ic08{ ‰PNG  IHDR\r¨f AiCCPICC ProfileH –wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû2:Y~ pHYs  šœ@IDATxì½ ¸fIYçw¿7×Ê¥²ö(¤ ŠÅ†–Ae´×GÐnGí±AmÚ§Ÿî(‘Qp¤}\[»µe(aÐyTd+”¢ö…¬\ª2+·»~óÿýßx¿ïܯ¾›yofÞ¼_fž¸÷œˆxã7âÄÿ7Þˆ眑N§SZ×¶@Ûg ŒoôeŒŒ ªB“Ø âmiÃÑý#I|8j9dµØèxÃ@ã÷H Š6¦ƒºáã2-ý ¶çlž _ªaâ„ñäI_I­–°ó NÛuìÐ1Õ gºH­‚茗ÑÑÑ΂ÜÒÒÒ‚ê4§c¶ú„9PM…P4ê]tÊ`KWM³±nX­Àý'uìzàþblll‹Â­;‡-6ûñÙ§:¢áæOÌÏÏž}øÄ‰ûåî¸çž{¾ô[¿õ[ûñ|¿Xè8®#•Á’À€°ù­ÛÀѯ°Å õ±ðÓô߬ðõ_ýêW?©ÑezC+w‘>¨/ ¢Ñ,ЛG6Uå_<~üøƒR wÞ{ï½·þÂ/üÂùÔ§>õ xŽêÀB˜×AÇcº`M€!»•,€•Ú÷\µÅ0(€ù™ïslÕñ¸|ð#²P­;G-0¨3®DKºLÿní q@Ëtý†EVÂÞ‡~øÓ·ÜrË/½ç=ïùGexTŠ€Ìbßà‘H•XO×*€ZW ƒÈE¿ …Q7Hü©:Ϧ²µä³Üƒð·-éø¦:¿ ~h¿y&&&ÊÔÔÔá;ï¼óŸóœçü;%ÐÁÔ€µ[’µ±æ¨*²^nXf÷0¸\àC †imbÚg(ëÐÄ+á<²²Më@ÓräÈ‘mOxÂ^sÇwü?7ÝtÓ5âCÙ³æã)` 2{럃øqîòÓðúš³=Î]ø—¨§þvOÀCÏp“Ÿ°Ömr]gYüX(333OúЇ>ô‘W¿úÕO ½­XÖZç.2 €«M €ú¤HÅpîZã"-© fÀ}*×䇗xÒ2ÜôÓÈ)¾}ûЦw»ù—ùƒ¯yÍkž*­8U£¯Sú°(.ž×´Öé’[±§jAJ`ÀSNìÉGZ?=ã(‚½{÷–ÉÉÉmoûÛÿËþà>Mì­È=‡þ°(€´R œz:‡t±ÕñJמJb%Þ{¦g<­¦÷ßÙ*÷Ó?ýÓøÚ×¾¶µVjìu¤‹è¿ÄVô·ÈÅO¶Õì>ôTø(u·§ìرcË[ßúÖV dãC@ þsØV[Tþf8ó7• thIO+€¸öXlÙ²eë[Þò–TíÝlØuö‡Q¬ó%·âÏF ä`5²øMÞ¦B¸ï¾û¸3À„­o~ó›Q7‹·UÍ[§p«Ö©a/4±§|?ÈûãƒÚ#•À±cÇÊáÇ˶mÛ`³ÐÝV j´³LÚ 7t¸Suº³Ü­¸F ôøT¿éÍ<Éß SDÒ’N>=üUn¼ñÆÂ†z¸ÐJ@¬¯|ßûÞ÷yùlæa"ò.‰ÿ‚Ý1È5žK×Z粵ϓ²˜ƒª»R˜l¦5Ãä@kò`h§`Ù´iSÒ·¾éMoúÃÖX©õνUg§/ )MÀæCkÐ3~²0iý9{êZ@Êh• µŽ®UëØ¸ç‹è•€½Rý“?ýA|©VòÉ“i>xð · kƒ;½­Xi­ Öɵ `ö|{*p¯æúRF½?ŽŒfÁ#<âiÏp ä¶¾ñol§´ÄYv­8Ë z!‰KÀ6¯)iM¿ b@›.éÇÏôxò¤Ïs<:ÜL¯yZ%ÐlȳîýZgI`+æül¸Z—`MþfÞL[­Œä%Ìí@6 1 ø9HKà'~â'ZK€†:K®Ug©!/D1M`º>ÒÓ5y›t@œiý>y30速»zyÈ@K@<[[%@k×*€³ÓŽ„ØïÑ’§™Ö&ž´þp‚¾é#“8Ç¡C‡l0ê³/¿µ²ÕÏ®ß*€³Ûžç½´móBNF°éš@ï§Ã-yðÔM|(€LG¤ ?ùäZK€V8C×ûõÎPP›ýÂmèJWH:.ýäË|M?ùš "|Gõ~«²EϾß*€³ß¦ç½Ä~ sA'£%p“/yÓOzú>ó¤"HkÞÀ£ÂÜ €ÎÑTÉ‹/×Z´ÂiºVœfÃ]èÙšàÍkM°f?ùš~‚»ßoòg8yˆãÜl îWÄÓ*€/ek•€[oí§öa µ·ÙE“pöo×E ôÓ²A$«øäËgþáOéŒî z|Ò9úÃú°ˆéž4= dðgYøÔ™ø’k% ÞWþÆoüFûQ³¡Nn-€“4N›ôØŒM׌g¸é^é@Π´T9ʧBHK •C¦Ilýñÿñö}ÍçáVœ¢.öär³Ñšé„›< ð¤gH @k•@kŸ<>´‹€'¯v›: -hiºfœpº¤ã'=ÃéÛa|äæâaSIÀÈ›®Y‡&]ùm ˆÖ. 6¦^Þ’„6ض@ Ì~8ûHCv±(V êU-mU- [ óÉxÓ*€'dÊÕ¸”>ù'¨ñ9VRi$ÏÅd ¬®…Wó+´ò°0x¡*Vä/Ýúç¤ÔÉ\3=?ÖÊAùÉ×ñ›ñ 7­ ¬ŽæÞ€•Ê€§æ» •@«õ¦–vV[ A½È( žäËøÃ?\þâ/þ¢ðŠp^ÂA˜7q`®dæï€•ÏŠONNúؾ}{Ù²eKÙ¼y³éø333Ý'±¨²RnÿÅ_ÈJ Uý¿v?k-#o¿ÀzÓo*‡\ O—<éC'Ì„ùá#GŽØ'Ìx3œr(wzzºìÙ³§\vÙeöwïÞ]¶mÛfå@ ¹(Ü JàsJ:¢cÉ]RY½·¤Br×*€!ÿ.Äê%ðû¯­ŸžŠzƒò€¹Loâ¯_yQ(ðì»ï¾ÛGÒXعsgyžP®»îº²k×.+”ü(„julý©Ÿú©?T¾W¾ÿýïG <ªÃ/0T™ç•h½¢uëÖ€À5IaIÇçHZÎÓ“N<<Ͱ3é”ù›ñ,þt=yñ“àgýýéO{ZqõÕW—›nº©\yå•V(MG¶¾å-où}ÄôÛï÷~ïK*ã¼T­ÈÞÑúëÚ ¸,¤ D@ÚNÒOv¤œôS^3ž N ÷—o“'ó&™÷ß¹÷Þ{­ ° žüä'ÛJ`ÍAVÁ¶·½ím$…ñ­ýèGoW>¦ç•%0’ мøsV#£¢'tLé˜Ñ±KÇzè¡ßV#oÝ·@³ÿ4ÃT™xóäÐðs~Ž_Mk/Äe<åêˆë‘7Ã,’'e¤²Èò²Éšñ ã7y30.ãÉ—õ¦<¬g<ãž"PGÕeß+^ñŠ—~ùË_¾WüGu X¼èNR®hË\]–%žƒÈÐ*€}ûöµ àt€3-¢Ù…Hé§èW+Ÿ>èd]À|œ´¦Xé:(—²pÍú5ù“ŽŸ@MZæKtêtÅW”g>ó™¾Ó :ÝuóÍ7¿LüûtÓ±L ¤\ä5]ÊkÒÎe¸Uç²µ/À²šxPZÒ›à‡–JÀÐé'ÀáùÓ‡žŠ"›™£¿ÜfœpÓe>hýiIËüy ÇgZÀ:ö-ü,ƒïQ”Àq|þˆƒ—*nPy‘rnÎíÀ¹iç‹®”aóœMá¤ã3Oçh†‰çýz˜yPÍ<'4N .ò4Û`étÊÌ<ÉÓŸ/e5Á—¾ô%/>ûÙÏþÚ[o½õŸ÷¼çý”òSQî!ü¨ô J@éæZ°aMæ 긣ñàÊ2#êôó˜ÊÇŽê8Væ-‹ÇŽ—Å¹Ù²$³º³¨ùx'û¥€7®'æ$g\iÆ6m*“Ú@36³©ŒËŸ­3 Œ%ÜônŠ '4Nð4ù2ÞÌ ™€/N˜ŸM>é’'A™ôô›à%ŒK?yš~Zæ‡'ËHZZ-ÄIcÓÒÇ>ö±ò ßð ßñû¿ÿû_|õ«_ý«Ê@ŒBhìV@$o̹UÓîgT*À@x›×˜ã=TŽjÕúø–cûö•,câ׺–v´«ûi„c4¤.ùÜ«Gæè(ÌZ•WÇž‡ml´LnßQf.½´l¹êвåÊ«ËÌå—•‰­[»Š'AЬOOðcC×ôû² }VÞq(Ò!å§ËpÓ'Ü<’7}Ò(?ó4éIËü¤QŸæApLU¸}øœç<ç­¯{Ýë>yË-·ü­Èܤ‚\x¯²Šl´Ú5€ýû÷·‹€}½ƒN×ʬîW?ò¥Ûʡ۾T½çž25¦N¬Î87¯²y­¬/jN­.—ÀìŒèywÉì,ÍKNè~m‚m\êAŸá`꟭_IYPžŒqå“l^¥¥¯ìÈR˜UÚ¦«®*—ÜxcÙñ¤›Êôe—vk ºåUà‘˜B&¾&ˆHÏ5Òš|Í9?iMÞiÊv:õÓ³™ŽŸ<Íp“–¼™7ë =¯!ÓðIg«ñÓŸþôµð±íÕÁT€ïœ=f=`PYâ;g®U笩Ϭ Fý4õjÛWo½µ»ãö2²0¯2íT›×‡41›U °UÏV@@×ß’€ý/ ôkhŒy¨€_'Ç=\™¨)ÂV„þÕɧF'ÔÑ55Ð^úÉk¯-W>ïËÖn0 J A)ÙÑIK   CO@e˜xð¥È|Í´,¾< áˆ7ý“…¥¥¼ô©¿yd9ÐØb,Kå}ßò-ßòoÅúˆŽY(2‡2‚âÚ)À†4ûÚ Mð/j.ÇÿQ9ñ·•GN”ã‹sR <Ì"ytü¥`–àPµœ£< ‡¯{ª‰ò8Í ä|ª¾RD”ÁÝ£*™!mVk ”9óÅ/–»îº«Œ_w}y«^]&¶m-YgK«$œ¦v*À’VMÎ÷3ž<äìLHƒNœpæI !×oÒ2L~ø’·ŸN—÷¹ÏýQ±Ô€"@€…¤LÅ7ĵÀ†4û øÕƒË?|àåÄ}÷–…)­‚kä¢ô$Ò´ Ø­Ã “Îé°â:=Ö€D»Â&^‹Ò‰ôÈyµÜ(¢3 €UŒ [ —52~ð@ùܯÿzyÖßXFµX— ÈÑÖ™ë)Gs¢M äÈßL‡‡8JO?POYn‚r–1¨.™7y2ž>òRV¿ßŸ–q|M¾þå/ù•üÇÌb`‚ß-®8þ†ºVlhóŸ¼ð4£ßþå²øÕûËì„ñ´°G¯ÑøiüuÁ,0FçUjôm¦GiQ°¸ûÙ¨à'Ýà·âp!¦¤ñZèØД Á_÷FU·­ LËZ¹ï³Ÿ+×>뙈4pX€Gœp hè©àDéRFòBOÞ~>è¸Ì“>´fˆ¯ä2~ÿAž¤Q6Gòg˜ø£>ºíû¾ïû^$p·²ðØ0¬wQŠl¤kÀF¶þ©ÊVÂÍ>ð@9²ÿáÒ‘³´+A·ëÔú³%Ù6˜Kšø­7o$¢ 01ËI•4•Û³$¨%ãëFD9ôèá2¯5Tðã^‚$ÃM@ZÒÀ‘sù9ùüÄ3¼œ3bÉßt”•.ÓÒO:~*ÒòD”&¾Ñk®¹æ%æ:Ø"Œ@ÁѨ l¤kÀF¶þ©Ê®TË|eò‘ƒeïÔtÙ²y“@¢Ž¨1$æßË…D—f€ {Pû}¯ÿsˆÑ#¬hÝ!›æ|ÉC9"¸¥*O²N(« SŽ9Vyäp¹2­²õ¹€! xT‚>ÁÅèI#<pYié…³,ä6Ó³ìfÞä…–efüÌ3¨NäQþk䱃‰ jÞ’QtcÝÐ*~˜‹ÞÕN<:1Uö$÷ùÊË®(›wìЊ8›adOêF¿Wüsn65]vP­òF3’PÃAAAÈt5èű‚åÒuª$êô[¡PP ðçgçËa™þ´p\w®Õ.Bƒ Ðjõ>“ró÷Íz2hy$°r 0sx’nÙy=|øše4Ãýu Þ//ëEZ†ñûÃýñTM^Õ{§Ä¤`n 9ÑòŠnŒZ°1ͱñ¥z§ž:÷üG5ŸÆLO•™-›ÊuZmào+lÞRƯ¸²lÝ~I™žÔSÔÚ­§ÛâÅF2ÙºŽäì¨æ²ÐI‘¥¸ï×å]èŽñðª€G†ã¢-Î/‡4â?¤Ý‡GØz¼}kÙ²iK™ÒfÜxݽ;Mêžt&‰1-Óóvñk‚,¯-ý”u2ÞT §âËô”OçAz†³¾Mš7)ÎÉèøiB7£ü u­ØÐæÂŽ<>‹väÁËÝccõ¿£ÝxZU¿f˶²éÀeïÞ/—ý“;ËÒåW•M»w•é™-efš[LZdçÆ_X|u7õÙÚí"@§õ ªë¨î b0:\»)‹ÜAXÔæ¢Ùóåı#å ö¿xàÞrðàþ²85S6]qµzùh™×uÜwÛˤÂU7?¥ì²jZ^ɧ2* ëé"uJðS·t .x9ˆ'›<„3_úÐR&áA®¿ͼÍ0y)·)¯ øf2¾øiÅ~ð×–T£sGkÀ¹kënI'èI\Ò^ò£zûÌ/|¡Ô*zçÑC¥£—]nÙ¹£Lj;î¢ú·Öö캢ì˜ÝUŽŸÐ|ûþ/–C÷,–G§Êþ»ËÒVñnÙZ&7M—)YcÚ±79¡y2|;Ï÷ìRLýpÉ7Qêà¢W€ÍkŸÁ‚6ÍÍΩ¬åÄÑGËq™ùGìuÜÏ È ™¸òqeJÛ„G°XTNGõ|X —_ÔÝ‹/ìãe\VÁ5zdöª›žRv^w­8J€4•Ñ`ƒ^X>/oòÒN©gá&›ô~€Ã;Èõ— OSqÀƒÎÑ”iÍô¦±É؆«žzs¹BÊ`÷õוI½¦[¨ @a Q9ê ðsdÍi@‚2Aè :ÁŸiI;›~–—>²©SSñ@Ë:$½úý¦kÐX'sMíz2¾¡Mk‚žÎ\+º¤Qý@½ÿï?[öþóerîDY:q\ûùõŠ+¬E”ƒ Àk«íü ½ö3Ÿ)ã“3Ô#er|ZëÛ4ïŸ÷ð1>>Y¶l*;5PÔbþˆ÷ÍÏ ÈǤLŽ×!åpâè±2»x´Ì ìó2åÙ Ì­; Wa§y~U VZ|\ز«Ìiƒ÷÷ç$[zÆ«W‘—¥æäZÈpÚÃ÷?X¦žù =M(f-TS•9zLVŧ>Yüëÿ¯,JîåO¾±\yóSË¥zï´^ËÝQ;áÑ¢êO´òo¦zj²ŸÞŒŸN˜òÐäÏpúIkƳœT\Uðó7dÛP¿µÎvó(:½:'•Øü‘£åÐ_‘iÿÙòÐç>_¦ev/ ôóÚø7S~쥲[VÁåO¹¹\úÄ'–Mšö°n€£=e™Pò¦´lãä­ÉgÝK7ýþò›uÈߟ‡˜ä¨~ćµ à,ü ÍE¼>bç4_~øöÛËCÿ™òˆÙ^¼ê'6:ó’·å ]t ;FMEÀŽN˜Þ' ]€ÁxïtôuzlRÑζáë ³ šÈ¨:°XU/õàqá@¢BÓÝ)+ŸQ-ð!C€ZR^EcMÀ“ÆãÄ* =£÷Tšâ º®Åc–QMG¨3ÕGUÍ«¾*Ú4®/;ÛüB¼£e0«2æµÆÀ=Æýÿ÷åÑ/}¡|Q¶=îq力o.»¿æIe«ž¬ëÞM¨Ê€ºÓ~ý® Îþ´“Å3<'S(¤5ySfå%#夓¼Qic‚ù›lLéçq©=?²@ØÒ8øpyäÿ¡|Uæý¡Û¾P6é§fmV|–E2Ðc' Fu(\G€Ñ àø[ÒêðxG&;`-SBºÖ”ª‘2;w\·ukqâQ‚Â: PX ì÷õ-ʨP~™ÞäÒ@õ¤°_À .>,€%¬]5Cì¢î@,ŒˆGuÅ@iqc¡cÅ"¥u‰Ѹ€sñÁ3Jù?¾õòÔ\•V$ôžÕOû ¤ÝÊ!½fk^;ß!‹fÓåW”=O{Z¹ôÆ›ÊÖ+.·2Hцiëo «E ôÀMÞ¤‘¡nò¤°fz†›Ê(iƒò¦Œañ[°–_Bà÷ƒþ¸ýÝzP¾­ÑÙÕˆ±ƒù¯¥;·“·%éÚ˜°ÁDÌùhj%«Gg¦A8T‘b°¨°FË1-¨{ôX9rÇå‹ù°Úi¢¼æ?ÿvÙ}õÕ1h¬ÏXÈžúB3ε7ãYTs0iÃâ­ !5æ¹n8@„9?.àü3<=ú`¹ûþå>¶ájëë–];Ëí{gu;z2½Þ=»w ôd\ôe˜r2kM0“'êîZ“HöòV²`./y±m^æþœ?%PNÉ„ŸÐTcòÑ£eBfý„½áG²–„ðyn9ê>< ‘‹ Ï P³Ò* ’» t›ýR, X Gr½F\£ø"÷÷U7Ö¸]9/+aA+øà‘9>>·™Ât„pC–4s\é“bSöÀ˜Â@ŸeGÚ 03=@í©ž¶¸qÐ4’þY#¨1¥£‰‹¢ÿŽêøÑG˾•}÷Ý©·"/S<qÉ.ËÍ•÷†ù][vmÞ Ñ{ ©+õוèk«Éúp­XŸË]»T:'ndÛ–¢Ý6årlϦñr£FÁîù\¹÷ö±rÿeW•é=W”­[6kû­Þ‚£Ú½5H¥?»³#Èâ Ë%®´eޏé˜ba{íaM´§Q1§¸IrA@=.PNjNŽ50!ÄŽ è#l¼QFO¬f$¬%poÀzå_r±ºV€Š¿¦K¹>‡²@ ¨:K’É:@ÞI@å±p‰LªÌrá„ê´Y¼<ÆLã&«üZi0øQã’`€ö”Eq‚©KX ¢+=Á Òº‡Úÿð¡ÃeÿW(ß·FO_²»l¹ä2½ UêHS±©­Ú#¡:þS)€”¯ÂºAà])Ï ú ÚÀ‚6ˆØ*€Õ6¼vÛLj[­@»UÛjŸ4uMyœâÞ_îÝ{y`jwé\yuÙª¹yÓŒ;!f°úµFH:¸œ;uí좑ìXM®,îø †b׀Ѳ]+õû~DyÆUþÔè‚Ö´ñFàžX”/ä0 áVܘÁ´à‘U•Ð4A|‹RXX*€~Iæ;;;Zi·2ÀÔÄÍ¥80ñç± TFwÖ5X3ì¤Y.tÉdÔ'ç¸älÓIÓ2[¦ÆzÁ  £i£0Ê€kËŠµÊP²¨MÑÅ`… ´*{Tû ö8Xö ôǵö0¹}·n ^#eÒø]FuŒ±Jïâà ¯§Õð4ØO$ 0ˆ~RAç0±U§jl†(œÌl 7ÚFÏâX8LÒIõð«·î*Wuv•CÚ?ÿÀÝ_,÷Ü>Rî»ìš2³{OÙªí­<Ň ^wÇÖ¸¼Ê¦Rp×ÌlOˆu[e8*žP|R°dqpjb®L-h`gBõ„R-XˆTÑV4‚GlÚÊùã ë ±@à–bñmCÕ‹| <ƒ°èýÑ<òK( ¹>Û}±T‚€?Z¶è{[Õd›$wZHf³WÌèÏ øxGÁ˜®eT  ŠÎNyT­¨·hs'ôœ„öØ«§"¸[åéUä;ö”×ìô´ŒEQÍjf]³4†§?úp뼵ȅ÷TVH½€ ñ†VÐpkièuk=УºŒ Ä#šcŽ=pæ¿Ìbåœ&É]¢—`\²isy¼¦öÚ_îÙ'«`ZVÁWée¹;Ë&ݳgDÄ12+¯QÂJϩʠ+ÓÅQ<“"l¦.’Áž3³ºO>.ãB‹~“ì°cÔ„0±I—0eÏßã®>@÷®ASF}x¹EÇhÏâ뙌ðXsªdô¢ Êb–bR}¦TÐf•;£ò7‹iFô)â°€¦~¸dø¾p%ŠÁ·Nµ qüÄQ=büpÙ§{ÿGÞ§Û}ú2Ñžk nÚœ;d‹µeÔ?×ÌüaB —/¹]aR{Ìeû÷ó¤éž~úZâ+•±ëÅ;´ `½.ø´åjaml×%µx¼Û‚è[êcúwG§WÒa¦ÖkôÍÕ#;e/÷Ýó…rææ÷_v­¬‚Ë´”°ÕVcIÞ¨Â64@ÉV_Vɱt÷´xF59fkð´âóíœ,¹ymÊÓˆžÓJþ˜@ˆ®1ȺB`êÈ~ÉÉ]xÜs§hÞ„ ð(/†yYÜ‘àK@('o'}Buÿ¤„O*ìÑ]£?[ž0¾§¥µ¦Å7‰b”Oh*꣫Ô9èJ2è1²¸»pH‹zöî-¼ËVÅÔöK˶k¯òTšH‹*ÌÀ—¹P¢("ïA¼í Çâr*ø§¼µ»Ì—þ©Á©Ò×^ƒs“£U§jgu ~\:¨ný1Ÿ¥Cw@u:ú´;6=šˆ{¶ÇDzCVÁŽéëË×h¤Ý{è@¹{ßWdèSZ² ¶jïü”,æìÞGv¢~G5üÛ„Ö\|Tsöqr±Ž¾àµq)ƒØÍ¯“^™ÑSÀ’7tÊ$·¡,Äøíy¸«”Lh¹ïÏš—HݶRXñ`…pû iÔ Vüy¿À¤’Ö"Ë&™â“ò±^ÜvòiÊ÷-?Äi:Á¼dV·ù°æÁ¯ÞWÕŠþèÌö2¹ûŠ2£ÇŽ#¿”“÷A¹ÂÙ¿‰"žRp­£RÓÛõèsu ÞŒŸ‰*Y™~¾)‚V¬¢Wø½zêä¼¢‹/ñ0RÛœ•&Pöˆ/ØPœÎ `¢Ö¾Ê§´ÆËãµpuÍÒÎòˆ6ÑÜsÏçË=s#eïžëÊÄžKËVYº‡‹þ‰RDô =ÆxôVr1Ã1)‚‘ÏuF9ÁË(¼¤“ºÉxwý0óIdÔ²¦€‹¨2‘¬8Ov%Åõà p)…XÛ@ ÊiþMIŸLŒ¦¹ŒŒeÄGtËò‘ýí™RÍÍ—IÍí·\ý8Iöº")3üÒav£\œe§³bq£ˆW‹´|¿ç-ŘçØ¥"h;ˆÖLßÈp«VÓú Dn„GTé|t,”Þ ¢ÞXWÄ@‡Õhn(a6“/,@ƒ¹w²V°ùºòDX{Ë*Є7]V–t+q‹6MëM>㘽–¤²„äQ@¥Q“ûçÌwÙ˜‹Lœ-•mŠêã~Òjÿw-T.ÕaÙEÞ@á…ð…¿RCIPR‚=¸CTñŠÄÔˆ"G½2/YìT‰%! zùðáCåÐC–Ã{ïÓ»õéñíþÔ\­jÂj¾dQm ØÁ7háLt0-öAÏh&—~æ8ÿ|ÙW{­­XEKÅØ¥ÑvYç"c펽^iRŽT9TyDÇäPoöÜ^ØØ$‹âñÚ¸rýÒŽr@VÁ½÷}¾Üý•Ñòwôi­-ºŸ=.e¬F˜ß+# £8Ä>õË*P ÔŒA4)•J:ƒ'Ò¼@)–ôE°”žjˆTeªÂI!( ùÈÓõ„" )Šh^éÔÕb‚ÐÇôªðCÚ²{ðÁ»Ë¼^N2¾uwÙtåã|mÖJ(ÓZ: Gá¸LhGƒ˜In¥rÓÄ6&ócÓI>ûn5Êä|T­XK_Ñ»íx¼u¹SœaªAfz‹c# t¯8v:8s6uòKõ¾ÿÝ›µV ;Xwî¿£<´éòÒ‘"ت׀Oju{öàA踔€nÇi´´‰4¶6 † O×3î¿SXÚ ðR߀“߃^­ U Ç`À]G‘‹Šéàó &U¢=¼ƒpóv½­H‘ÖûÑCS2Úë©ÈIíØ´KO0¨F{v÷á8Ç|_•íëR"›ª„Ë0Ü&䘯šöG虀r+)‰•èUÏf¹­h¶Æ áŠgubíý×Ss]ä™ß½¯æŒÎ™C˜;¯Ntn»ŠØ)4®÷bÒ.¤S¶h»MóáëwÉ*8Vî¾÷ å®ÛõÌU+£zÇÞ¸€´ ÅDæÈ<ÆkÈôÍ©°á?`ڟׄˆ‹±ÒØ®¥äô,ƒÊàË´2@Pu}½Ž?«ó#Ó3zGá6½ÖkK9røÑr×—>[æôlÁÄÖeúò«µSQo,–òáÖ}ÚÒ!kÁ8÷jD]5gœ|×Eµ¨u@Ù2cVÆ«Ô'§¹?Ѻն@«VÛRðíÐ ³6yË)=²k 4»,Œ'Œkôt%5G„Táà\ÐR>ú ÝuØ£íÇ7éAžt?üù{7_R7o×®D)#½‡¯£·ñ0ûîÃI¾-Âøg_Ÿ>Ì1Âd@ª µIvãIq|6çÄ=,Š Fý¤ÌŸ $Ši\#þ·Þt7ƒg¹çN¿tJ/ ½dÛoGö""õOËTìF+!Ë.@mÅÅ5ˆFüT:ÚL± 4h0¨õ$Ië&3»¤´îä-0´ €¼ ”“_Æú¦z @õÕ9=§W‘–ãqê­12‰–”^îÎ]{xe b7ù£W‡,Š÷ðË÷<ÉÙ.°oŸÚSnÐH»Oû î9q¸Ü¥ÔÛʒ^:!%ÐÑ{}¯\»óu`”ÂÖ`,*‰BÈy=õd:5aŒM¸E}Qð2Êã8››!\nlT·éô¦ašÓCDGêÞÄŒÈÙ)u£\\?®jÆq$x³!S[FõUXUü™ú°¦àšA$éœTyß ±ÖfJ×\hZ Ó}GéÝ:(¼‘nXê1¨ †V ªìFÓFô°¯êb˜ô‹7Á™þI¯$N÷dvÇ%JBº•Ââ—Ë®†½ó*ŸÝ~WMn+WÚ*8QÔIwêm¿{U§Ù)½ª[…èe›<;Eª‚zzPÿ‹Mio°KÕG<5¢Úär©°J<òëâP#£aǦ4ÇÖíJ^0r\/!ßèÔ¦²Eë¬Eà\¶5!(žê¦Ëd¢^ܤ.8òÐC-Yi$o2ÁðUj©% );íEÐZJëVß­XE[å¨Å{õy‰FÜ £›ÊÕNuÆJfD3Âè aGƒwîd K"Gß”ÐèáI"Ÿz{ŒšJWÛõÔÛvÍw?¿¥ìÓrw?ZîÖ‹IŽLlŽÝ€Zë  d5èã^8ìh#QÜš `RJð\U'+ñJÑ&¡1EFõÆ¡‘‰i¿² ÐÏÍê#·z8j‚9¿ÖE|yÊGþT\ŽHmG½i§‹Çy”M¹ø8Òiç!î<ä—lEœ.n¨† S¶‚iòéúI²n=HnÝŠ-0´ `˜~@ïŠSŽi/ÿ ½ƒndQ¯Ñc¿9„fóÒ“Õ£ÃGôn<‘ÝaéѸDA:r¥ÓÑq¯Â*Dꊀ ?©ú\¥ 0—«nOÑÁ}ºKp×ìѲO ˜ÓAÆ47‘•дr#¼þKŠ€}ó”Î?æ>*€‘[œÝ,6Žè+C±I=¬—nðÖ €¦'íf¶hK4Ö€.‡œTŠªGõ+@!S‚üæ‰,äôa>…q\;t¦T=EPi•N›Q[\¼HUõæ½æRŠ“Z‹ˆ„HÈÆžó÷ÝØZ .}hÀàên µûò˜)÷ãënÀòäÕ¦²ã§Ó› i3#)q– õÔ]5rÆí9âì¿wç—ßSJP&lœM^‡(â‡ä^23].Ñ&¢',l-ûõò’;.÷)í°6mÝ^Fµã®=¤úè•Zr,ê©)ƒL„–‰™^Ñç ÁZW8"þŽFûq-<ÎÈ÷S|Ô‰ú*kU΋Lˆ€\¢¨zøA®×E‚®_ àü:¼†‚ï?µt»ÂÒFQ&I8¯(7J±YŸDÃu3ÇÚÓJ-Ð*€•Z¦IwoVg“`õΉcŸ<ã(=™ìNKšÁ¡QËH×h:«‹zub÷nd(AÉMåÙBL¯'çFiXd‡Zˆ­½$‹h“DÄèFÿµ['ËZ¤;¤·ß§éÁ]zsïCš¿/íÖ‡:UȈ¬„E”Çd)Œës_Kõç?|äˆÎÕˆ:¡r¸½Æüškô½ûZ¾µ˜.Ä×®Êù!©¸_Hm6*GíºgXÒ*0¹—ä(ª~Žlk·©º,Ú7ö@kz¥v¦aT¿1B¿OëVß­X}[i¬æ’©Mßã•XîtB¤ºrÆèÝ$ãÜÓANÒä‚IVGnŒv¡MÈ';AYHü¸4!2"סR{ ¬ŽjV=˜£†»4ÊïÒÂØõ@Í^)»´Éè>=hs\ÁØ¥WøÁÞxäÈa=Œ³×–ȸ¶èNMoöã·¶Lô4"7ÙK@q\/‘:ëâ,O(FˆT1v@A¹&…pº.À“`_’’‰2¡} þåaRùQ`…'Uç|°µ u’`«NÒ8ýIìfÕ÷÷Æ´1GOßVàÉëvÖš#1™è¼ús‡Måá]ø ü!.´ èJ>û‘×¼†R¦ fµp€dá¸~Vù€×N^l;ÞY®Ö³õÈ"¸ïð#å+ºu÷€îã?¢©Â¨>a?!K`JvØ®ÌË:–´—Ÿ‡s‚_‚-]u¥º®¶¯% E p%yPkâQ3T×´L!]B| ]^_KÈs^tfSÕ¾ÜäœÖ> >¦ÚºÕ·@ÛZ«o«àÔ*ó(Oå±Àw¢²Ð¶(z„rï­Bé´îÈáõFõ`b'`ŽšÑÑ“?Æú I–ä8‡åEÜr °õt†ló“¡û˜1€$›À¢;‰åÒ-ÛÊ¥²ný£{¿Zþfç~‡#í¨F{—%u‚ŽÜÜFä20ñu¡õbä)ÕêÞ)QØÕ$C$Ûož"E|ÊL½’“¶Àº1MBBáE΀>²I%o(ÓU/ís*SÛ´UÛ»##O{>u ¤Uyj΋œ#;^™Ö‚«qîåj”Ú‚ô÷œów›J|tîì¼ð°jÝï ô¬:x˜òd&ÍG {í@‚¼WekdÓ‘eØg$WnçAu…8Õ“Ö4¶LI¡‰Ä‹F|C_•±Kµ*®Ñ·¬s*Âê%vFJ§êÌŒ£&ÁÁ+×ȨR`æ0h&×4²à²HÎ$…¬ü%å›_|se!‹”–!s™8Fwb:•Vˆ³Xì¬ÄxJPä,Ÿâ3/LÄÉÕ­Äê “ž<ãúëYB³DTÁ2SAµw]A×6à;ÍßžVßC½`Soõײ®œî´tPÝZóèí®ªî*Ѐì„ì½÷Ws©{s*ƒèÚžávÑ#©¶O)@'»xúUVh”ŠÑš%@âqIWZít f«@4nú– lŠûéD•íëqÖ(ß°dÁ2$[O)Ù18ô¤ÆÁËѬZäŠ/ $ÈY %ÑiÖ­˜`‘]]‘™ú=¢ÃÔwT¡uý¿ÑÐVt£+Öí{ÚTÃ×¢D €tw÷Ñè–ÍúÒyé¤!#%59vï· Ñ—ÐÍØ£»œž@uéR‚Ð-³KïV-Ì}W©¢»x²C¸¾:Y0uaÙ€?ÂÕyF{ù”Ö-Oá7 ŒÃÙ› ɃèÝüŠ{Î/Š}ÅS! #ꢊY°ž•rnÝÚZ ïµåºˆ¹Ç4Êtô’ºøÎ%`EýPçŒÖV¢;£jïöîlĤ?&!ê ^ª``›w —@¶:P« ‚?¤™[Áîâ`¦ÀO8«F¹a.ÜA­lÎC˜ƒ¤ÇøÊä,™1sB§3RG’-\üaYAyÍÓ!+4‘ÖM6é!©Ö­­Z°¶ö*eçvm¡‡OÜQ݉Õ}­ܽ݉E°d7ð2ðÓYI « "(‘#›óÆ© »åÉÉŠ2p]t²_…¦|FqäµÜAp½”–ûÅKSnw­ÂTg@'>\^–ÃÄud^h¸¤…_Så²e$?ë’ü&½;êׂ’f>nG6V§Úw4[dUá¡]ÈUWq˜x­—ïuk—\v½Ÿº¦W¥•ÑXÀe4Óèd>z/œÕï!%ÌqËl"AÜXqo1.ÐY#¨ì½åR”« ±f+~êÊ?/Î!¡6aUO 8VüS5c³R(z-¶Hª€ã3åA•ˆåå;µžÄ@]¢ hÕ@ç%¼YY…sôw;Šž> ƒú¦ãÎæ´׆'LÛhŸú «ëërÃZͯWntÑÇ?ù.ž7ÄhÝßÚ]—îÛsþÉÝi“&ŠòeÿƧñáKð~gVnéíûyÈŸâj>ÃGÄ 9º<žå1J£3òl”žï,(è½ü$¡´ä[y¹†5ìÑ€‰G®ëÖáë¨~·5.¯ë$½ÖW¹$„:e{ôâx§)gø’Zù),cù)´UY¢&ô0”]V¬[bX©úzØJl-\àFô¸é ïÔñkö5üG' t‹˜ö·‚Î_}߇0ò¾ÆN›ÄU •x›@òª½8™ÛóÃa¾q#%€Xÿ˜Í ¢áHËz46ûøv‰æ×© x¥KJ±Ðc„‘J¥WÛ†„eµ­é¢»l§ØÍ'¢•–…qçëoJ1?eõÊ¡„Z¸y}7– RX|µx:6c{ZM ¸Ï¬†ñbçɆÙ8‰är@Ÿ×@B.²`J€’ívDœˆUJ÷ºÍCbð䨎œt]PHHÔLg’%Äâ*#yìËS‚aL#?†Ø”^6¡ß×ý­‚¥=Ÿ¤z¿÷I˜Ú¤^ ð}À޾>£Os¤…·²˜"b€(#´4¸4úÑkõŸ;rhj Û±”e`#õ œÞQ¡U™Á?Aé‘Ñ”j×›#˜‚¢Ì²é½M~ñz-@Áu¤œZ„ãкt\0 U%š ÈmuDJ´ˆRŠ0]IDAT)ÕU!\EÔ3èÉ—Ê‚tœyjãZŠNz)é8ol’kHv¼=­Ü­X¹m–§Ô§w{éaz'@Qô±œS}ytÖ¨ÞÁ”);.¨‰?dUp*‘®îå*»Zãæm—%áxªìʉˆy¬?»êI:‹‹]à;©™K µ>ª%5iqÝMJB–ºE™¾ÖÚ–Á/áÄkx>Òݸa$Í~* ¥çºÇ¤>®šïH…á ¶§“¶@«NÚ<Ëó)³ŽnŽjõøÐûðn 6iˈ#&Òù£Ÿ»¤ §›'+ø´Œ`´£XlØ3‚ë/‹©\aR{ôu—!Pjð{“Mp8h½< +’GÊ#[;«¡ÚÈÏ:Y¶RB*aó‘ùUšóÀ—q…ƒWY݆²„”ejS|,iÎОNÙ­8eõ–=¬Iz4^vçŸA}ÖDúo7šOÖN½\{p{®çÈ“V@)G÷^™Æ@zá.å*o A)˜Å#À” ¼]ó]“Ú‰2J#ާ!F‘f¹QNð’ŒKÉÞU)öœ(^É·L—ƒdœüZ mÈ_¸ÊÍô`«9ülÆô–x •tÍØz§hf;k›œ-0²k§€™ÝS/U?­Æ»YܹEKuÜö ·ì€ ˆ±K[‚ž´.4F ‡¨¯Áˆ`xN¾›'8uv1N‘êº) é<ÁH=Ì ?4­àÓ©øÜ·&{¤“ƒH×Õˆ2"oæoòui}ù(— n›FÓSV-oŠÏ¶µnÍ-Ð*€54Yä[·©KÆM@Þ—G_ÅußÁ§0´¤g'¯lôj¥U *1:uWz/Ÿø2/ò#œiĺ &¹,§ÉŸàN)f„Aõà»t„ì ~@ŽN°2Ýy³êǵ’3¾ó)`_q”MÄ__DbJpäÕÒ´†Û%k}R<5¬$;_{ Íèg­[{ ,ûMמýâÊ‘5¢7è6 ËõÑuë–`uÐ|FÅÀá¤Û~éˆq,U»8@ÉÈ+: rôñ %ÎÁð Öš¡2“‚"D¨k—[K(›*™ý ð* HŒ<¢©"È¢>I«¹, fÊá =òÄ“/36yœÆ‚„\*%ê–ù¡üÝt®e¤RäŽúCNtÕTû$`´ÇÏy_jÙÖŸŽº¬³®‘§.žG‡Sgëèmºe‰/ó†ZH>7Ñ_†?ťLJ#f/FÖvϱJíØÝ$ 0²Øe H60ˆq»ÁH›u=ƒn~ f%„|sU%)ë‡Ä›#?åÂÙ“¢Q.=Ä8Òà³S FpÅLŒ2jª<åV^’¬ ê5çï ·KÊò«‰Ÿ·ÀH×)|Z}Ó¿ $¯ËÕ²SjCV­!¯Îö­îtôÓ5Ž®Ùñ¡Y‘Õ4ö°qÈ[h>Ê‚!âKiëSn_7¨¥QrÚQk]`AUþª.| ‘)FW×Ãé5¿¼&„›ÏU¤švxn—èÝÐòèÖ=Ø£D¤Œ*B­¤°†_i‡Z[ ³<|]ÛÔ¶x`ål½U¶@«VÙP°u÷¾ë­@˜ñ‹•Xì‰â!Š€ƒoê„Óc?V=«¡æƒçÄ dôËDIä^€Ä€ÇO ”@õ)Œ£º”Ã"_¸ð‰ÖP¥ûÛ?nÔBÈ ä %=ÂIôOê Òpˆápƒä0Íe#;€Œ®HZP'ïb«„깎‘¾iMËZ·öÚ)ÀÚ/eýsäÓQ)€ù (:wöQõî녣“öâ‚]„ñ=¿m•Š «"È RšËóÃÓ¢ó%hk¾*Å^ämJȵ‹nÕ»ì j]ó¼ÊF€Œ+êfqšÓuÊ’ÅèL¼{iËÒCF>rõV"¸¾ZO%¥u”åôÚ Ëˆ5€PÙ^!¹=Ÿª†ÖÆ2æ êŒ[fÊ‹€úŠnìÞ‹ÎKçô¡Sâ™xÓ™“ljåœV‡HÂ.¯» ƒ(PÈ)G¾.èŽyE¤qî/8S¨YÓµZ^c%¹>É àÇ -#’kzHO=Ë#˜R^¨•”LZ*©š_×JÛ$aÚhqnAíÆ“€õ}€Ù&µÃàåo: ué¯ÃÐ*€þŠC<È1= ´89©>ªNj¤ª'F?U5sâ«`öÖ¾Ê'™·Ø8ևƿŠ|x8j´'¾!«[d2‘–ÄZ{$ÚþŽDÞÈ.@Ý‹-=ëC=3^3?ƃ‡ÏÂbÆS¾•@7©DSÁ5)H!ît]gfË8_]fóÏ”¬2\þFŽ´§S¶@«NÙD=†ì|ú­ Ž ôÙ½+ïöëîéçÍ>›2ºÃª+‡¯x-ë},(ùz¥Ó¹ãè1À%— DAû…šuPŸ æ* ‰Ë\ŠÊÑšÄ.­É™ÄFzr·Œä!ô`Mi(³åõø•./ ÊÏø˜,²±)ý&­[s ´ ` M–£Ëˆ:[G&çø8ÍW›0AOÇv'V·˜vÜoGD'‡:¢[ƒ”xüü?y2_dêž³\°XªNЉÎ_³PLU òœ‰h PȺiyèÁ¹üLy*ÇE"J®+Vá¬[3=ª#w·J5“ù& ØMî¶Y\BoÌL¨ÐéÝ ¬:꟯Oòžä4ò›ÐžNÚËý“²¶‰Ýà ºÚz:²ÀXı¨ƒ?Æ2Å£‡šâD‡fhue;g¦N·ž_“íY0!"Cm¹>U[x$F®þ Gˆ&W”M¨GËpKø"ðEpV*Ãň‘ë4ø@\‡7 VŸ¼)‹ü+ïTâ¸~‹|8ÒÛój[€îÒº5´@ÎÝG6ó‰°º‚n F÷§³F—¯Ã/½»;>:1’+›­Fƒr‡+/ì×,é.\óõÙÝá”Ì‘œìõI·àdZá<¥h:fˆÍø®Y-CxÍÚ9¾œ/r¸©Ä¥.§Ñ¶)×Í•è*¥Â ƒ²pÔyJ¿EëN¯Z°ÆvËG‚Gô%Ú|É…ÇëD‘äu!e?›X :0C\ågOÎÏÐÛ³'RœÚ;¥lß®ƒ¾D ™õˆ\ BWfƒÖ͈¬üv}T¥+ޤn²x7aRÓ졺 ×³¼¨3‰Aëòq¤ë/•e9H†Îa ÁG˦KâA öQàlÉÕûÙ;WŸ£åŒÐ#Á ">²¡UõJæ¦8À#T¬™¦Nà+¬žBäB⢞$ÊÝ…½; Hì9àЃ €1ÖU55™x:)ËÂÏpO¤HAÌ4¶“#ÙÍ”Yóºh…ãZC *‹ÁïV«æ¼¶4R0ô*×ùt¢ô”í:)ÝibÅwZãšg¶µOÒŒ§ã†z'`vÈÓ¹°õÊ‚¶È°ž›–2ƒ·°¨—º³ˆz‡ÀÐ@.Á¤¸eBJ´Ð¹ÍÀF#¶è 3kÖ,f­A.ÒCE²Œ¦Ÿa±Q?ø´±ñ&HaÀê8~ øD¨‰)Bòʧ]‰Ý”¾®JfG6A(Ь#¹{Îû'ºWÊä¶­n;Êí¶a½ ¤†Zœ¤Þ–”~Dï _ÒÜö/‹ÜGºGDl^‰à/ºa¬xw]Ý™•`ž|¯ !W3”0^äÝ¿ÓÄáB`PF5¡ð*#EÁ’òL£–X(DªHDÂ:À™ñr°zï¿ÂÍ"j²yºô("ÚÅ)‘?yIŽeÏ §Èê0eØÄݶU0—Î,‹O‚µîôZ Û}N/ûÅ›kD¢LðG+Dw栊ΚóêŹ7GX÷rªu€ :xòG\|Z#É‘“ƒ!@R9\8Då—ßÍ A5l: d9‚öqvÅè´ùÍò˜iŒØ)†Ìï°N軤äµ¾´…ó‹§÷Ö%Ñêu/TúæKv ªu§Ñ­Xc£u;²€¿¨N^.(ø”¦@¼)(Æ}”C¤‘‹ž®„î ·c‹1`4 Y(¬©Ðu>àw4’;Y:2Œà^†¨ eÁ#çÛ˜òaáHåã¢ÄRk§”žë‰CFĺ´›âã²2«Ò‚/ø`åp „YÌ”Ÿ€'Ý/'QOEávdv`·td»’7¥7·îôZ`h§ÝÎz×µn¹X}§n£Ú xð«³2_Ø@»û½hôäøù¶Â1Ó®—4!—5å8×n·ýýAÑ+háêMd%¡x¸Ç…Q¶eIaÄBâÀ99ʪ¨¥†¨õî™-Ò™C@(ŒPh)–<]>…©ÒÓ*êù=>ÀO@ïšDq¾dä¢@ic+]ž[Á S÷i­Çd±Âm˜Ü0Ö)Û§µ²%Véç#ÁcZ˜g4Z!ªÎ檶õ*Òhpš=óø=¢yÈV'¦‹f”,Ð̂ӱÙJôÏœp19PL¬ŒØ:e¨e×ÛµÎ' – Ë!’£&õ¯# à¨c-¶›; íK‚Õ‹°ÏÕêAˆŽ´4Hr•åò\S »•*@ØUU>x0†¸húÒ‚ùºkYaåiÝêZ U«k§.WÅM|%XCÐb"ˆÎJUÏÄgdŽŽÞí–xNÜ> ±±WA"’E6”@N X@5pPËÁ×á<%ï÷€ üi®@²ëg.ɨvv¤@ ñYðàMªóÖ|ÉG”:Ôb ®nœâ]~ddë.,¼¾<Ú)èžÇÐ&J„?ë“$®!•€÷(³­µÑœÞk8£€­;½hÀÛ-lTÀâ”î¨3ÆbTFtX S‹êèX½12 E¥Yž;xW—¨ÇçFŸnõÒÐ0ÈBÁ (C€‘Ñ1´ƒ8P‚ G{'‘‘SÇ÷^Þä°õ Ìž ;Ž9€kKAxSÑÝñÊ”æQdêo “æ+¨5Ýù)Þt$HA(Þ»¦Mþ¸z™˜‰O‚YL{ZS íÀš®â\2çÊÙÄTéè+ÁØ­`ÀT—Sϵi éüòÁ¯ó¢‡#GÄ€‹Óá:9o¼ìj~.•”`Nde:i²X¼¤T æ­uËâñkÍ£Ì8û»…¢ãÅÙÍ×Ý@äîÝ`RfÖqÈþ0©¦XL=Ø"gºx ñy.¾ ‰H¥ƒ–U½,Ùød1a“óÈ-°7” é8ùúnYY]ĈB1È•ËÈ1ÓŽÛ’‘Ñe;«F|5F¨7ñ‘¬DÓ |Ñ)ò•¾iG» X­tÚ®U§ÑtŒhtëÎö-eA#Ï‚ÉÝ9uîöòÇÔK½ nk“\q àÀ=™<¸Ø§|,"àvŠ€f&À+Š’`ñ¬°Æ¹¡,€’_Y,‡JAÐáèNP\Ùùz™} ï)‚a9ˆ2-É’KFj#Gš¦(KŠ£Ð–¬5åcÖÎ%X¸È€{cOÕ””O¥h_|}ÓSwëS™¹ 8ÚH ­[S ­ ƒëœ.ë6®ÏQ`$üývú TOˆõ3°àEŸf „ýÕqçE^4UeÁ˜ÇhF—gc‘ïÛÓûåº`÷}sÄÇB¢GhE0Ðjæ•d!ÛÚɾNÔ ÕÃU&™Š6qm Âxö;ø\!ÄæR%O/*£Êɯþ†UOÑ™ê"¢<ÑEp˜¨Œ”‚¤ÖY•*V4±ø ­ KŽMªÜ¥²ù’KÜOò7wØÜ°öcÚihÀ°ýˆƒê3ª[Póýgʸ:#0ŒøÜ¶âSG§óó²Ž4€÷ ÐÉ…ßPoµÙ[sàÎE.GGÓ‰µc´#ð±rúн¯®aK¢#”9 ¨‰ Îe!>©Î¢3ˆ3º/ikm~ɇ{-Ø$@éðZ—"\…ùê²â˜â dNÊW%¹×C˜ö0-âˆEIÍiG$b6ëe ­;ýhÀé·]ß¶E±”ù„ÐÌ|–N9JX°êf¡•ÁÝZž?B()…G«ÉM˜ÎŽ0FØt£1\Z˜lÒu(EHœïDÈgnî[Ba * ! „:×ŒÔ ®Á’LÂU¬DΠ€ëÊh…à5_¨ÈJÄJ‰2ô(>Dg=ëåTë@<( +ÕÑñé°‚%ïnÝÚ[ Uko³nŽ1MŽ À@Ÿp‡ÃüÖ†+Ñ€;>Ky,|Aà3 3œî®Ñ\žç áú÷¨“åU…jÃìbQš³jü—lêë)£Î9º›¢[ ¶ (@ÂðÁí,Gù®lâJåú4êÃGe'yL‡ÜP ÃKR5\îg Ìcqβ$ÞJÂqh"l­/5c{Zs ­ Ó»ã¯ù’Ö?ß nS;w–¹qôø|éèÃ#z4x ð« þ8+óê¶Ä2s[¼ÿˆEŽ´ PŒiñN·½ÒŸÁ>ç"C¼" —ðÄ£""¯‡oÒ•×YIKÀIbD@uË0à‡(v#ÖÅo»*b±yn¾à #õÊü®14Q’ŸXP”¦ªqÍȦe¢Žä èð.H0YœŸÓÃVceç¥{\gö m¡‡ÔÑwZ·Æð†õÐÍ»/-׿õß”#ê|-Îéw>¡ž,uPæÔsç„RVüçQïßS°¸c° 0ѹ11qÝñůn­½‚Šè>ÄÄüÜ/‰¡=ЭsŒÖ|^¬;²&ªÄø¸³à2Tæ¢ê‡e‹èo@] î°ÑiÉo^ê+uv½äã.#1ù bx©¿þ s—¯xÈëÕ×m „y)(ÀÏîÖF‰k®?·8_æå³º¤Ê/üS;v•7ÿÚ{ËîË/W}´üʪgëÖÜm«­¹Éj†ªÕoþîï*/üЇKùƺsÒQó€VÀŸSç¤c³E°  ³`^iÑá ¥óxæC,jÃŽy5 B¹0eàÈõeP*¸áë:‡EƒGv'˜<- £ÊÄ“HI¶€>ÔpÈ õ¤îrXò>i‘?|ø½¶!0/é: lq,Ik`­°{oAa6I-ŽªNªæ¢ÚfIó©EEP¢L­P¬a,-IHÊ ~è‡Ê-ÿXùºç³¯iXG~šgØÝÐN†½á²~¼h×µ×–—üê»ÊíúPùÌÛ¡Ì|õ¿.lRó 0‡Ê¤d°jšP#¢a¦> ÑÌÂ>åß%¨·õ*f¥¦é†ä„F²È ¡7Â,V·#É >9WÃ÷¼>¨7uT•á¿Tqa4æJÏéBSéDñiÞC]É…¥@m]ž|bÈÜÍ{–4Â/±A´ŽÖ#P~ÜAÐ7¿l”Źrí³ž]~øío+7=íi–° ¶o»°ã4OmëfÃe¶Qu@ÌTVÜoxñ‹ËUÏ{^ù쯾§|åÿø¥2¡^?'à©óûy:& ~7Çø9[w†-à§ÑÔ!±fô‚Šgÿøÿ\^ôç.ã/x‘;;&îœ@0'`Òò¸pú€×f®à· dÀK:€Ãˆ)Ð ¨Žyòäô(/€ô:àÉaVa­$ƒŠ“ÍlÑMnˆ&Y)•ñ IüdPo!5À/…#e+ÐËÅ(®‚àc ÔJ)„ÉÎ K)IwŠ>â© àgJБ¶äÚ™î<÷û¿¿ü_Ÿ¼µ ~”-Àoçünü3>µÀ7aOÖˆ¢“îyÂãËK~íWËíùhùÛû¶²åÁûˬÒ&"FÙQÙº4þ’ÌÝq‚^Èb(z€Àd‡_Xˆe„ë€{ æ"Ÿ†w¦NQ–ÚÀí[‹ã±e憵§dËtš’Ðiæ+¦}öª'¨åT>êëb-‘2•®<ùT"ÏüžrPØeF>N~hž(óȸžë‘éÀåO{zù‘·½½<ýëþ©¸¤Üª¹ŸþšØžÎ¸Z àŒ›°O€@ɧªéÄ 7¼ðåŸøÏËž7¾±…UHâNÀ¼4§ÑÑaÖ ƒE,(°Q€:Ãb!b@­þ‘'-ðt 1T Jô桌ûó=4Š¯Ê „ÞIGÐò­=‚꿎þð'ø {qsžËUfêè…¼.øcÔǪaƒÒ[èäz#_ÑÞþÅù…²°iªü‹_xGyç?hð|,‡ÖÜßâlŸ[p¶[´ÊeÒߘ<ëG´¼ä£+ã/~iŒ–â›Ï<ëêàóB¨•€èÐÓƒ&€ã;GNÑsjÐSšBxZóotŽ…ÂeQ¢¡4|’ï‘Ûú$¡0È$P üép¹çµÒÑÔ§‚¹9ê{…_œ\ u潘ü(‰9…­$¼3!s_%ÍÉø§šãÿÚ­Ÿ,¯zÍH)ézê¨ßšûjÄurí`6Å6§»¯¿¾¼ä–wjZð‘ò™ŸG™¹÷.[˜ò‚À2„š1)ƒÀ 4ž è– µyØD'Æ”ÀšÜ¼™`ÇÝv$Z¨Â˜Ë3•€×ÓNY|ÄuÔÇ‚€N9< ˆ0òÍO>I`÷ ˜]:#>i€ZåDYÕj!?eë« adBVÒ¼î3h/õ®'?¹¼îío/Ïzî7HB˜û˜úí¨ïæX×Sk¬kóVáuZÀÚSƒ^øÂòíþ§åÒŸ|c9X¬Í™cjÀ~- 0s†¹ßÏèÍÁ.8‡p …`‹A`ÅÏQ3Ûûô ‹r¸BaEÄhl‚NÒ7V €oÂâÒ1x+ø™Šˆ‡ 9°²ÈG%ŵÁ z¹¾¢aê]™xŸ¢6FÌI)}×Û~¶ÜòßÿÌàwûH8Àoïíó+¬¿Zp!vF5¦err²|Ýÿô£å¥ŸøË2ñÒ— @ZëãžÌ l$ò G„[FT+õ @ À}ÇÀq@ÎhË4 ÒP˜ëŒ¶Î+>Ã"`Õ $:qÌ~鞪&"N9{®C Çà—lJµõ íãï (Ñi:!¥ÆÊ>œIå¨Ó?yÕw”÷þ¿Ÿ.ßû#?bÀ~·šèsÃÜ—/¼Ö>:ψ”Λˆ®¹¦¼ø¿Rn~ïûÊìãžè½Þé'ðÏ 6sZ`! ! rM­ \¾u¨pZÀbóæ'|Ó7–—ÿ÷–Kßü¿è Ãx h^£ùœ¶È²ÀÓ)ƒX"˜·W cAÄ €¦Ãcà‰°VÓaÏöb+Â*‹ÑðÃkþôs±Ï — äH '¿þeeH–hž (ò©Sa®/ÅÁ{^ù3?]Þý‘—öüçûºÛÕ}5Ô»Vlô “—§ ™?3÷}ÖÿËòÒ[o-“ßöÏ=ÂòV¦¬œÏëž? g?¼çÔ·Ö|Ç@È#ŒÉÎ.B8ò4@ü©<ÍxŒÞäã ^NPylçÑbŸçüÄu`ÚcS -83ê³™‡p<÷ &_zB{"–ÊS¿íÛÊ-ùÉò}oøQO}0÷YÙoW÷Õ`ìZ°Á?@ïÛ†Š0-Øyå•åE¿üKåkëeþ†˸hÜ럛ð3±sP`Óm?Àí‘^0¶Ù-@{ô•Àå4N‡õˆååcÆGZNð(ðTùÐt0êÇ6Þ |ñ±ÆŠG ÚÌÿ£×mÖ3oú÷—·¿ç=åÚÇ?®5÷iì!s­¶DV£1Ó‚Ç=çëËË?ø_ËU?û³å˜žÓF™9¡–Õsî,jdözÐÚÝZljk­dØ"ÐõñX2Ê!Flè( ,º<ß W8|FuüLQÄàGFlèQºbXL¨‡§4z,z^s‰oý©7—÷|ìcå¹z>ÂÖ…ä´·õÔ`CæZ0d?ÕaÕ¸9-øÚ×¼¦|ë_|¼lzÕwê˜ù#eV/ØÓê:‹ƒ^imt/ rï_м¬ÌkNŠ AO:w¬T6f?À‡Wžè„¥¿˜=ÖC”§ÕûÉXÝŸ—‚zÒ‹¾¥¼óÖ¿,¯ùÉŸ(Óz.sŸëiÍýhëa;õF a¾}r.~H¶Ûˆv\qEyáüå®ïzUù›Ÿûù2yÛýFâ¥q½EhN3~©rÀ*½àûù¼rœ§Ñð£R¬Çi=QÀ¸cÿhB3ðÔž*H£> !Ö ¤D`Nïéƒ|K—… Í<‹Ú̳éÊ«üÄÞ7½ìenV÷ÛÍ<碗œY­pfí·î¹=z¦"0¯ÿºg—Wþ·ÿV®}ÛÏ—#ÚK0¦¹¶0¨)Ì~­ ø DhÜJ w7‰Q›…9æí Œë^¼ÃªÈ4Æú¼Û i‚xü&ž ~/8¢MXäÓ¼cNÁ—üøO”wÉÜüMsÿbWàëÞ9ÎB­8 x.D¦œ~ú÷ÿ‹òò[?Q6}ï÷z±LÎŽŽ{ž;Þ7 ´£0ÿÙ+Às÷lŠ©AÐ}KOéŒþXzÛ€r+ÍÊ º,¦¼Š{drÂÖÁ¢¬Ž'¾àå—>öÑò/ßú–²e‹¾’¤Qß ëÜÌs.~ã(£UÑêgP¦wÊçnÁö={Ê Þñïʳï÷ËÒÍO×&¢¸+ÀÝF}n²8ÈF"vΩ\æŠ{þN<­J@> dQü(,¶$ë'¢jÐÜ\™¾ô²ò†[n)ÿ^w)n¸ñ&ÏóùÛE¾3øa7(k«6¨áϤX²9-Ш|í3ŸY^ñ_ÿ¨\ÿŽ_,G7oÓûýÉ2ýX¡ç..ÌÞPdk´®áEVZ,~—„~æýðóà/øÀzx±žj¼å“·–½üå]sŸ¹>ujÝù×­8ÿ~³nÛŠýîQŸú=ßU^ñ‰O”­ÿÃÿèi/˜Ó6\€ËÜùºçðêm!èEÔ[×z1-ÿàð-:Ý-ð´@VÁM/}i¹þ›¿¹|ö¿]fﺳ|÷÷~O¹Q |8V÷ÛWr nÇ ‘Ú*€ ñW]áš<-¨iþ€É½¶<»·ÝÌÓ× x´\à?p{ym œ¬†Öðj¶ÌÕÖµ-p¾·€§`Cz­0¤?L[­¶ÎE ´ à\´r[FÛCÚC;ÒöZ—j½ûÝï.Ÿÿüç—Éþf­Òçw~ç2ÚÙŠ|Lƒpò'RŽõ ÏÓÍ7ß\nºé¦²sçÎò´§=-ÉýAuÈØGÌ2®¾úêrà 7ô¥¶ÑsÕ­8W-½ÁåÜÿýåÃþpùë¿þëSÖeÔTH/Ó‹>žñŒg”«®ºê”yWËÐ,cóæÍåU¯zUyö³ûïI¬VZËwº-ÐNN·åΣ|Ô—vßñŽw¬ üƒ. Ká½ï}ï ¤³Bà ùÍßüÍ‚5qüøñ³"³²ºh-€ÕµÓyËu2‘ý}§ßÌÿìg?[ÓSÊ|Îsžc«â¡‡Z&òŽ;î(¿û»¿[~à~`½¬O ´S€õi× —úWõWM~Àÿ¦7½iEðª8 =Û€d=áÇ~ìÇ óÿ~Ç:VHëÖ¿Z°þm¼!%ü™çíw€‘Xw˜† rúЇ‘[ÚYnVœåqŒþý¦5õl€n˜ÖÅ +€©w.Z·¾-Ð*€õmß ‘þ¥/}i`¹9·˜¸Äoú¦oXú—¿üåô–xöZ Ug¯-‡FÒ¾ð…ÇÔ…¹ÿ°þYÉ'=éI\柭…ÇeBÛȲhÀ²æ8ÿ#ܾ´»ïZ}©wXÝJŒöïß?¬U¾`êÕ*€ æ§Œ A r—^zé òPиç?hàÈ‘#CQ¿ ¹­¸À~Ý ¼¢aßX3H ¼–xV[ Ugµ9[am œ_-Ð*€óë÷jkÛ¶ÀYmVœÕæÜxa»víX‰aÈfÐÂ%_nÝú¶@«Ö·}Ϲô•nõñΰ:”Ó °{÷îa­òS¯V\0?e\ `ЂÚ=÷Ü3´WºÒ‹ë®»nhë|¡T¬UÊ/Ù¸Ž§<å)X‡ykíJ;þžøÄ'>æ:ZÂÙmVœÝö i7ê @ƒÜ§>õ©Aä §}üãLöìÙsVß@ô˜Z‚[ U`GàÕZ¨ßñ\ÿ°=`³ÒƒK/Õ׋Z·þ-Ð*€õoã )á;¾ã;–Ë«½Všs̰ŽDêñð)åÕ¾ð1Ͳ.„V¬K³n¼PžüË·ï4kÃc¿ø‹¿Xn¿ýö&ù¤axy»ÐÙTÈü•_ù•«ÿÿ{ç’ÓFDQHd'ŠEʲ 0eÈÈò„ŰŒ ØW¦QHâ8uH.z²LdäO¼[RÑ_u¿w^Õín›.F£ÿ¶Ç·GÀ%Á¶Ç²Ü‘(+Î 5m…_ÉWn———*ͽJ(T³¯-~zzºqU^ì±êÄççç~öߘòú°¬Ïj¯{’(JÂuNL⬺m¦8'UIäeSiî«««åM-sÜ‹‹‹'ƒ¯.Çã±#àIÔ6ßÙ°9ÃòG8>>¾¯ë¿îï,wˆ;…£££ÕàäääÄ•€—ÁïaÙ°ÈNÁ;÷ö<;;;à“wì±+?©JϪǃmôG¿z´«ão£=ãp±X¤ö3~9•"áoÂ)Ï?³šN§_ƒ‹Ã Ûó&0›Í~ ‡ÃÏÑ‹¯á9à×O&á³È¿»˜¦™¿HCï›@> @þ¸&FÀ†Þ'6|€ü1p L € ½Olù,ùcà˜@ @zŸØò XòÇÀ-04€4ô>± ä°ä[`i,iè}bÈ'PQr_NÈ·àå(Û€á/ê寤{¶'%cºŠG~ów¯Âö40> ì”À¿X¾ë8‘⼄ Tª^œ‡_O&“ñ:ð]¼.y˲v^ë<5j’;^w_Ìçó›h ¯ÿßøÃö˜Oµ*õ^…a85Þ…ÿþ>œš¬g;ûùÎ ØÊ Á¹ÚOÃIúŸá×áß¿‡«Ûo³ëT¸J¹‰À·áEC,ÁVš€`­$~‡“ôLõÀ>˜bÿïRÂß  ÀàhÀ0©)ëü(låÊc.dÄ2Wzb™yœxÖ~1›k•UZ›à,så§x»-m&PŽ€’›Ø•øÖëì—n@À€B‚c=ó(¨nýõüï;€€b+G@IM,ã\íuW‹(ù%Ú?6åX ç­´ËÀ#éåN|èØª ž%‚rÉÄ*@[MbÀh$¿ný-ÃVž@úÚK´­D'ªP0¦$9S€)á—§±Éfe ´ñL#Yn]똦ZB M Ïúvže› <'ŠkÚÜΗèCú?• àF˜@§ô©z§Ýw·M o€¾Ç߽ óp÷û&`è{üÝûÎ X:w¿o€¾Çß½ïœÀj`ªN&ÜIEND®B`‚ic13{ ‰PNG  IHDR\r¨f AiCCPICC ProfileH –wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû2:Y~ pHYs%%IR$ð@IDATxì½ ¸fIYçw¿7×Ê¥²ö(¤ ŠÅ†–Ae´×GÐnGí±AmÚ§Ÿî(‘Qp¤}\[»µe(aÐyTd+”¢ö…¬\ª2+·»~óÿýßx¿ïܯ¾›yofÞ¼_fž¸÷œˆxã7âÄÿ7Þˆ眑N§SZ×¶@Ûg ŒoôeŒŒ ªB“Ø âmiÃÑý#I|8j9dµØèxÃ@ã÷H Š6¦ƒºáã2-ý ¶çlž _ªaâ„ñäI_I­–°ó NÛuìÐ1Õ gºH­‚茗ÑÑÑ΂ÜÒÒÒ‚ê4§c¶ú„9PM…P4ê]tÊ`KWM³±nX­Àý'uìzàþblll‹Â­;‡-6ûñÙ§:¢áæOÌÏÏž}øÄ‰ûåî¸çž{¾ô[¿õ[ûñ|¿Xè8®#•Á’À€°ù­ÛÀѯ°Å õ±ðÓô߬ðõ_ýêW?©ÑezC+w‘>¨/ ¢Ñ,ЛG6Uå_<~üøƒR wÞ{ï½·þÂ/üÂùÔ§>õ xŽêÀB˜×AÇcº`M€!»•,€•Ú÷\µÅ0(€ù™ïslÕñ¸|ð#²P­;G-0¨3®DKºLÿní q@Ëtý†EVÂÞ‡~øÓ·ÜrË/½ç=ïùGexTŠ€Ìbßà‘H•XO×*€ZW ƒÈE¿ …Q7Hü©:Ϧ²µä³Üƒð·-éø¦:¿ ~h¿y&&&ÊÔÔÔá;ï¼óŸóœçü;%ÐÁÔ€µ[’µ±æ¨*²^nXf÷0¸\àC †imbÚg(ëÐÄ+á<²²Më@ÓräÈ‘mOxÂ^sÇwü?7ÝtÓ5âCÙ³æã)` 2{럃øqîòÓðúš³=Î]ø—¨§þvOÀCÏp“Ÿ°Ömr]gYüX(333OúЇ>ô‘W¿úÕO ½­XÖZç.2 €«M €ú¤HÅpîZã"-© fÀ}*×䇗xÒ2ÜôÓÈ)¾}ûЦw»ù—ùƒ¯yÍkž*­8U£¯Sú°(.ž×´Öé’[±§jAJ`ÀSNìÉGZ?=ã(‚½{÷–ÉÉÉmoûÛÿËþà>Mì­È=‡þ°(€´R œz:‡t±ÕñJמJb%Þ{¦g<­¦÷ßÙ*÷Ó?ýÓøÚ×¾¶µVjìu¤‹è¿ÄVô·ÈÅO¶Õì>ôTø(u·§ìرcË[ßúÖV dãC@ þsØV[Tþf8ó7• thIO+€¸öXlÙ²eë[Þò–TíÝlØuö‡Q¬ó%·âÏF ä`5²øMÞ¦B¸ï¾û¸3À„­o~ó›Q7‹·UÍ[§p«Ö©a/4±§|?ÈûãƒÚ#•À±cÇÊáÇ˶mÛ`³ÐÝV j´³LÚ 7t¸Suº³Ü­¸F ôøT¿éÍ<Éß SDÒ’N>=üUn¼ñÆÂ†z¸ÐJ@¬¯|ßûÞ÷yùlæa"ò.‰ÿ‚Ý1È5žK×Z粵ϓ²˜ƒª»R˜l¦5Ãä@kò`h§`Ù´iSÒ·¾éMoúÃÖX©õνUg§/ )MÀæCkÐ3~²0iý9{êZ@Êh• µŽ®UëØ¸ç‹è•€½Rý“?ýA|©VòÉ“i>xð · kƒ;½­Xi­ Öɵ `ö|{*p¯æúRF½?ŽŒfÁ#<âiÏp ä¶¾ñol§´ÄYv­8Ë z!‰KÀ6¯)iM¿ b@›.éÇÏôxò¤Ïs<:ÜL¯yZ%ÐlȳîýZgI`+æül¸Z—`MþfÞL[­Œä%Ìí@6 1 ø9HKà'~â'ZK€†:K®Ug©!/D1M`º>ÒÓ5y›t@œiý>y30速»zyÈ@K@<[[%@k×*€³ÓŽ„ØïÑ’§™Ö&ž´þp‚¾é#“8Ç¡C‡l0ê³/¿µ²ÕÏ®ß*€³Ûžç½´móBNF°éš@ï§Ã-yðÔM|(€LG¤ ?ùäZK€V8C×ûõÎPP›ýÂmèJWH:.ýäË|M?ùš "|Gõ~«²EϾß*€³ß¦ç½Ä~ sA'£%p“/yÓOzú>ó¤"HkÞÀ£ÂÜ €ÎÑTÉ‹/×Z´ÂiºVœfÃ]èÙšàÍkM°f?ùš~‚»ßoòg8yˆãÜl îWÄÓ*€/ek•€[oí§öa µ·ÙE“pöo×E ôÓ²A$«øäËgþáOéŒî z|Ò9úÃú°ˆéž4= dðgYøÔ™ø’k% ÞWþÆoüFûQ³¡Nn-€“4N›ôØŒM׌g¸é^é@Π´T9ʧBHK •C¦Ilýñÿñö}ÍçáVœ¢.öär³Ñšé„›< ð¤gH @k•@kŸ<>´‹€'¯v›: -hiºfœpº¤ã'=ÃéÛa|äæâaSIÀÈ›®Y‡&]ùm ˆÖ. 6¦^Þ’„6ض@ Ì~8ûHCv±(V êU-mU- [ óÉxÓ*€'dÊÕ¸”>ù'¨ñ9VRi$ÏÅd ¬®…Wó+´ò°0x¡*Vä/Ýúç¤ÔÉ\3=?ÖÊAùÉ×ñ›ñ 7­ ¬ŽæÞ€•Ê€§æ» •@«õ¦–vV[ A½È( žäËøÃ?\þâ/þ¢ðŠp^ÂA˜7q`®dæï€•ÏŠONNúؾ}{Ù²eKÙ¼y³éø333Ý'±¨²RnÿÅ_ÈJ Uý¿v?k-#o¿ÀzÓo*‡\ O—<éC'Ì„ùá#GŽØ'Ìx3œr(wzzºìÙ³§\vÙeöwïÞ]¶mÛfå@ ¹(Ü JàsJ:¢cÉ]RY½·¤Br×*€!ÿ.Äê%ðû¯­ŸžŠzƒò€¹Loâ¯_yQ(ðì»ï¾ÛGÒXعsgyžP®»îº²k×.+”ü(„julý©Ÿú©?T¾W¾ÿýïG <ªÃ/0T™ç•h½¢uëÖ€À5IaIÇçHZÎÓ“N<<Ͱ3é”ù›ñ,þt=yñ“àgýýéO{ZqõÕW—›nº©\yå•V(MG¶¾å-où}ÄôÛï÷~ïK*ã¼T­ÈÞÑúëÚ ¸,¤ D@ÚNÒOv¤œôS^3ž N ÷—o“'ó&™÷ß¹÷Þ{­ ° žüä'ÛJ`ÍAVÁ¶·½ím$…ñ­ýèGoW>¦ç•%0’ мøsV#£¢'tLé˜Ñ±KÇzè¡ßV#oÝ·@³ÿ4ÃT™xóäÐðs~Ž_Mk/Äe<åêˆë‘7Ã,’'e¤²Èò²Éšñ ã7y30.ãÉ—õ¦<¬g<ãž"PGÕeß+^ñŠ—~ùË_¾WüGu X¼èNR®hË\]–%žƒÈÐ*€}ûöµ àt€3-¢Ù…Hé§èW+Ÿ>èd]À|œ´¦Xé:(—²pÍú5ù“ŽŸ@MZæKtêtÅW”g>ó™¾Ó :ÝuóÍ7¿LüûtÓ±L ¤\ä5]ÊkÒÎe¸Uç²µ/À²šxPZÒ›à‡–JÀÐé'ÀáùÓ‡žŠ"›™£¿ÜfœpÓe>hýiIËüy ÇgZÀ:ö-ü,ƒïQ”Àq|þˆƒ—*nPy‘rnÎíÀ¹iç‹®”aóœMá¤ã3Oçh†‰çýz˜yPÍ<'4N .ò4Û`étÊÌ<ÉÓŸ/e5Á—¾ô%/>ûÙÏþÚ[o½õŸ÷¼çý”òSQî!ü¨ô J@éæZ°aMæ 긣ñàÊ2#êôó˜ÊÇŽê8Væ-‹ÇŽ—Å¹Ù²$³º³¨ùx'û¥€7®'æ$g\iÆ6m*“Ú@36³©ŒËŸ­3 Œ%ÜônŠ '4Nð4ù2ÞÌ ™€/N˜ŸM>é’'A™ôô›à%ŒK?yš~Zæ‡'ËHZZ-ÄIcÓÒÇ>ö±ò ßð ßñû¿ÿû_|õ«_ý«Ê@ŒBhìV@$o̹UÓîgT*À@x›×˜ã=TŽjÕúø–cûö•,câ׺–v´«ûi„c4¤.ùÜ«Gæè(ÌZ•WÇž‡ml´LnßQf.½´l¹êвåÊ«ËÌå—•‰­[»Š'AЬOOðcC×ôû² }VÞq(Ò!å§ËpÓ'Ü<’7}Ò(?ó4éIËü¤QŸæApLU¸}øœç<ç­¯{Ýë>yË-·ü­Èܤ‚\x¯²Šl´Ú5€ýû÷·‹€}½ƒN×ʬîW?ò¥Ûʡ۾T½çž25¦N¬Î87¯²y­¬/jN­.—ÀìŒèywÉì,ÍKNè~m‚m\êAŸá`꟭_IYPžŒqå“l^¥¥¯ìÈR˜UÚ¦«®*—ÜxcÙñ¤›Êôe—vk ºåUà‘˜B&¾&ˆHÏ5Òš|Í9?iMÞiÊv:õÓ³™ŽŸ<Íp“–¼™7ë =¯!ÓðIg«ñÓŸþôµð±íÕÁT€ïœ=f=`PYâ;g®U笩Ϭ Fý4õjÛWo½µ»ãö2²0¯2íT›×‡41›U °UÏV@@×ß’€ý/ ôkhŒy¨€_'Ç=\™¨)ÂV„þÕɧF'ÔÑ55Ð^úÉk¯-W>ïËÖn0 J A)ÙÑIK   CO@e˜xð¥È|Í´,¾< áˆ7ý“…¥¥¼ô©¿yd9ÐØb,Kå}ßò-ßòoÅúˆŽY(2‡2‚âÚ)À†4ûÚ Mð/j.ÇÿQ9ñ·•GN”ã‹sR <Ì"ytü¥`–àPµœ£< ‡¯{ª‰ò8Í ä|ª¾RD”ÁÝ£*™!mVk ”9óÅ/–»îº«Œ_w}y«^]&¶m-YgK«$œ¦v*À’VMÎ÷3ž<äìLHƒNœpæI !×oÒ2L~ø’·ŸN—÷¹ÏýQ±Ô€"@€…¤LÅ7ĵÀ†4û øÕƒË?|àåÄ}÷–…)­‚kä¢ô$Ò´ Ø­Ã “Îé°â:=Ö€D»Â&^‹Ò‰ôÈyµÜ(¢3 €UŒ [ —52~ð@ùܯÿzyÖßXFµX— ÈÑÖ™ë)Gs¢M äÈßL‡‡8JO?POYn‚r–1¨.™7y2ž>òRV¿ßŸ–q|M¾þå/ù•üÇÌb`‚ß-®8þ†ºVlhóŸ¼ð4£ßþå²øÕûËì„ñ´°G¯ÑøiüuÁ,0FçUjôm¦GiQ°¸ûÙ¨à'Ýà·âp!¦¤ñZèØД Á_÷FU·­ LËZ¹ï³Ÿ+×>뙈4pX€Gœp hè©àDéRFòBOÞ~>è¸Ì“>´fˆ¯ä2~ÿAž¤Q6Gòg˜ø£>ºíû¾ïû^$p·²ðØ0¬wQŠl¤kÀF¶þ©ÊVÂÍ>ð@9²ÿáÒ‘³´+A·ëÔú³%Ù6˜Kšø­7o$¢ 01ËI•4•Û³$¨%ãëFD9ôèá2¯5Tðã^‚$ÃM@ZÒÀ‘sù9ùüÄ3¼œ3bÉßt”•.ÓÒO:~*ÒòD”&¾Ñk®¹æ%æ:Ø"Œ@ÁѨ l¤kÀF¶þ©Ê®TË|eò‘ƒeïÔtÙ²y“@¢Ž¨1$æßË…D—f€ {Pû}¯ÿsˆÑ#¬hÝ!›æ|ÉC9"¸¥*O²N(« SŽ9Vyäp¹2­²õ¹€! xT‚>ÁÅèI#<pYié…³,ä6Ó³ìfÞä…–efüÌ3¨NäQþk䱃‰ jÞ’QtcÝÐ*~˜‹ÞÕN<:1Uö$÷ùÊË®(›wìЊ8›adOêF¿Wüsn65]vP­òF3’PÃAAAÈt5èű‚åÒuª$êô[¡PP ðçgçËa™þ´p\w®Õ.Bƒ Ðjõ>“ró÷Íz2hy$°r 0sx’nÙy=|øše4Ãýu Þ//ëEZ†ñûÃýñTM^Õ{§Ä¤`n 9ÑòŠnŒZ°1ͱñ¥z§ž:÷üG5ŸÆLO•™-›ÊuZmào+lÞRƯ¸²lÝ~I™žÔSÔÚ­§ÛâÅF2ÙºŽäì¨æ²ÐI‘¥¸ï×å]èŽñðª€G†ã¢-Î/‡4â?¤Ý‡GØz¼}kÙ²iK™ÒfÜxݽ;Mêžt&‰1-Óóvñk‚,¯-ý”u2ÞT §âËô”OçAz†³¾Mš7)ÎÉèøiB7£ü u­ØÐæÂŽ<>‹väÁËÝccõ¿£ÝxZU¿f˶²éÀeïÞ/—ý“;ËÒåW•M»w•é™-efš[LZdçÆ_X|u7õÙÚí"@§õ ªë¨î b0:\»)‹ÜAXÔæ¢Ùóåı#å ö¿xàÞrðàþ²85S6]qµzùh™×uÜwÛˤÂU7?¥ì²jZ^ɧ2* ëé"uJðS·t .x9ˆ'›<„3_úÐR&áA®¿ͼÍ0y)·)¯ øf2¾øiÅ~ð×–T£sGkÀ¹kënI'èI\Ò^ò£zûÌ/|¡Ô*zçÑC¥£—]nÙ¹£Lj;î¢ú·Öö캢ì˜ÝUŽŸÐ|ûþ/–C÷,–G§Êþ»ËÒVñnÙZ&7M—)YcÚ±79¡y2|;Ï÷ìRLýpÉ7Qêà¢W€ÍkŸÁ‚6ÍÍΩ¬åÄÑGËq™ùGìuÜÏ È ™¸òqeJÛ„G°XTNGõ|X —_ÔÝ‹/ìãe\VÁ5zdöª›žRv^w­8J€4•Ñ`ƒ^X>/oòÒN©gá&›ô~€Ã;Èõ— OSqÀƒÎÑ”iÍô¦±É؆«žzs¹BÊ`÷õוI½¦[¨ @a Q9ê ðsdÍi@‚2Aè :ÁŸiI;›~–—>²©SSñ@Ë:$½úý¦kÐX'sMíz2¾¡Mk‚žÎ\+º¤Qý@½ÿï?[öþóerîDY:q\ûùõŠ+¬E”ƒ Àk«íü ½ö3Ÿ)ã“3Ô#er|ZëÛ4ïŸ÷ð1>>Y¶l*;5PÔbþˆ÷ÍÏ ÈǤLŽ×!åpâè±2»x´Ì ìó2åÙ Ì­; Wa§y~U VZ|\ز«Ìiƒ÷÷ç$[zÆ«W‘—¥æäZÈpÚÃ÷?X¦žù =M(f-TS•9zLVŧ>Yüëÿ¯,JîåO¾±\yóSË¥zï´^ËÝQ;áÑ¢êO´òo¦zj²ŸÞŒŸN˜òÐäÏpúIkƳœT\Uðó7dÛP¿µÎvó(:½:'•Øü‘£åÐ_‘iÿÙòÐç>_¦ev/ ôóÚø7S~쥲[VÁåO¹¹\úÄ'–Mšö°n€£=e™Pò¦´lãä­ÉgÝK7ýþò›uÈߟ‡˜ä¨~ćµ à,ü ÍE¼>bç4_~øöÛËCÿ™òˆÙ^¼ê'6:ó’·å ]t ;FMEÀŽN˜Þ' ]€ÁxïtôuzlRÑζáë ³ šÈ¨:°XU/õàqá@¢BÓÝ)+ŸQ-ð!C€ZR^EcMÀ“ÆãÄ* =£÷Tšâ º®Åc–QMG¨3ÕGUÍ«¾*Ú4®/;ÛüB¼£e0«2æµÆÀ=Æýÿ÷åÑ/}¡|Q¶=îq力o.»¿æIe«ž¬ëÞM¨Ê€ºÓ~ý® Îþ´“Å3<'S(¤5ySfå%#夓¼Qic‚ù›lLéçq©=?²@ØÒ8øpyäÿ¡|Uæý¡Û¾P6é§fmV|–E2Ðc' Fu(\G€Ñ àø[ÒêðxG&;`-SBºÖ”ª‘2;w\·ukqâQ‚Â: PX ì÷õ-ʨP~™ÞäÒ@õ¤°_À .>,€%¬]5Cì¢î@,ŒˆGuÅ@iqc¡cÅ"¥u‰Ѹ€sñÁ3Jù?¾õòÔ\•V$ôžÕOû ¤ÝÊ!½fk^;ß!‹fÓåW”=O{Z¹ôÆ›ÊÖ+.·2Hцiëo «E ôÀMÞ¤‘¡nò¤°fz†›Ê(iƒò¦Œañ[°–_Bà÷ƒþ¸ýÝzP¾­ÑÙÕˆ±ƒù¯¥;·“·%éÚ˜°ÁDÌùhj%«Gg¦A8T‘b°¨°FË1-¨{ôX9rÇå‹ù°Úi¢¼æ?ÿvÙ}õÕ1h¬ÏXÈžúB3ε7ãYTs0iÃâ­ !5æ¹n8@„9?.àü3<=ú`¹ûþå>¶ájëë–];Ëí{gu;z2½Þ=»w ôd\ôe˜r2kM0“'êîZ“HöòV²`./y±m^æþœ?%PNÉ„ŸÐTcòÑ£eBfý„½áG²–„ðyn9ê>< ‘‹ Ï P³Ò* ’» t›ýR, X Gr½F\£ø"÷÷U7Ö¸]9/+aA+øà‘9>>·™Ât„pC–4s\é“bSöÀ˜Â@ŸeGÚ 03=@í©ž¶¸qÐ4’þY#¨1¥£‰‹¢ÿŽêøÑG˾•}÷Ý©·"/S<qÉ.ËÍ•÷†ù][vmÞ Ñ{ ©+õוèk«Éúp­XŸË]»T:'ndÛ–¢Ý6årlϦñr£FÁîù\¹÷ö±rÿeW•é=W”­[6kû­Þ‚£Ú½5H¥?»³#Èâ Ë%®´eޏé˜ba{íaM´§Q1§¸IrA@=.PNjNŽ50!ÄŽ è#l¼QFO¬f$¬%poÀzå_r±ºV€Š¿¦K¹>‡²@ ¨:K’É:@ÞI@å±p‰LªÌrá„ê´Y¼<ÆLã&«üZi0øQã’`€ö”Eq‚©KX ¢+=Á Òº‡Úÿð¡ÃeÿW(ß·FO_²»l¹ä2½ UêHS±©­Ú#¡:þS)€”¯ÂºAà])Ï ú ÚÀ‚6ˆØ*€Õ6¼vÛLj[­@»UÛjŸ4uMyœâÞ_îÝ{y`jwé\yuÙª¹yÓŒ;!f°úµFH:¸œ;uí좑ìXM®,îø †b׀Ѳ]+õû~DyÆUþÔè‚Ö´ñFàžX”/ä0 áVܘÁ´à‘U•Ð4A|‹RXX*€~Iæ;;;Zi·2ÀÔÄÍ¥80ñç± TFwÖ5X3ì¤Y.tÉdÔ'ç¸älÓIÓ2[¦ÆzÁ  £i£0Ê€kËŠµÊP²¨MÑÅ`… ´*{Tû ö8Xö ôǵö0¹}·n ^#eÒø]FuŒ±Jïâà ¯§Õð4ØO$ 0ˆ~RAç0±U§jl†(œÌl 7ÚFÏâX8LÒIõð«·î*Wuv•CÚ?ÿÀÝ_,÷Ü>Rî»ìš2³{OÙªí­<Ň ^wÇÖ¸¼Ê¦Rp×ÌlOˆu[e8*žP|R°dqpjb®L-h`gBõ„R-XˆTÑV4‚GlÚÊùã ë ±@à–bñmCÕ‹| <ƒ°èýÑ<òK( ¹>Û}±T‚€?Z¶è{[Õd›$wZHf³WÌèÏ øxGÁ˜®eT  ŠÎNyT­¨·hs'ôœ„öØ«§"¸[åéUä;ö”×ìô´ŒEQÍjf]³4†§?úp뼵ȅ÷TVH½€ ñ†VÐpkièuk=УºŒ Ä#šcŽ=pæ¿Ìbåœ&É]¢—`\²isy¼¦öÚ_îÙ'«`ZVÁWée¹;Ë&ݳgDÄ12+¯QÂJϩʠ+ÓÅQ<“"l¦.’Áž3³ºO>.ãB‹~“ì°cÔ„0±I—0eÏßã®>@÷®ASF}x¹EÇhÏâ뙌ðXsªdô¢ Êb–bR}¦TÐf•;£ò7‹iFô)â°€¦~¸dø¾p%ŠÁ·Nµ qüÄQ=büpÙ§{ÿGÞ§Û}ú2Ñžk nÚœ;d‹µeÔ?×ÌüaB —/¹]aR{Ìeû÷ó¤éž~úZâ+•±ëÅ;´ `½.ø´åjaml×%µx¼Û‚è[êcúwG§WÒa¦ÖkôÍÕ#;e/÷Ýó…rææ÷_v­¬‚Ë´”°ÕVcIÞ¨Â64@ÉV_Vɱt÷´xF59fkð´âóíœ,¹ymÊÓˆžÓJþ˜@ˆ®1ȺB`êÈ~ÉÉ]xÜs§hÞ„ ð(/†yYÜ‘àK@('o'}Buÿ¤„O*ìÑ]£?[ž0¾§¥µ¦Å7‰b”Oh*꣫Ô9èJ2è1²¸»pH‹zöî-¼ËVÅÔöK˶k¯òTšH‹*ÌÀ—¹P¢("ïA¼í Çâr*ø§¼µ»Ì—þ©Á©Ò×^ƒs“£U§jgu ~\:¨ný1Ÿ¥Cw@u:ú´;6=šˆ{¶ÇDzCVÁŽéëË×h¤Ý{è@¹{ßWdèSZ² ¶jïü”,æìÞGv¢~G5üÛ„Ö\|Tsöqr±Ž¾àµq)ƒØÍ¯“^™ÑSÀ’7tÊ$·¡,Äøíy¸«”Lh¹ïÏš—HݶRXñ`…pû iÔ Vüy¿À¤’Ö"Ë&™â“ò±^ÜvòiÊ÷-?Äi:Á¼dV·ù°æÁ¯ÞWÕŠþèÌö2¹ûŠ2£ÇŽ#¿”“÷A¹ÂÙ¿‰"žRp­£RÓÛõèsu ÞŒŸ‰*Y™~¾)‚V¬¢Wø½zêä¼¢‹/ñ0RÛœ•&Pöˆ/ØPœÎ `¢Ö¾Ê§´ÆËãµpuÍÒÎòˆ6ÑÜsÏçË=s#eïžëÊÄžKËVYº‡‹þ‰RDô =ÆxôVr1Ã1)‚‘ÏuF9ÁË(¼¤“ºÉxwý0óIdÔ²¦€‹¨2‘¬8Ov%Åõà p)…XÛ@ ÊiþMIŸLŒ¦¹ŒŒeÄGtËò‘ýí™RÍÍ—IÍí·\ý8Iöº")3üÒav£\œe§³bq£ˆW‹´|¿ç-ŘçØ¥"h;ˆÖLßÈp«VÓú Dn„GTé|t,”Þ ¢ÞXWÄ@‡Õhn(a6“/,@ƒ¹w²V°ùºòDX{Ë*Є7]V–t+q‹6MëM>㘽–¤²„äQ@¥Q“ûçÌwÙ˜‹Lœ-•mŠêã~Òjÿw-T.ÕaÙEÞ@á…ð…¿RCIPR‚=¸CTñŠÄÔˆ"G½2/YìT‰%! zùðáCåÐC–Ã{ïÓ»õéñíþÔ\­jÂj¾dQm ØÁ7háLt0-öAÏh&—~æ8ÿ|ÙW{­­XEKÅØ¥ÑvYç"c펽^iRŽT9TyDÇäPoöÜ^ØØ$‹âñÚ¸rýÒŽr@VÁ½÷}¾Üý•Ñòwôi­-ºŸ=.e¬F˜ß+# £8Ä>õË*P ÔŒA4)•J:ƒ'Ò¼@)–ôE°”žjˆTeªÂI!( ùÈÓõ„" )Šh^éÔÕb‚ÐÇôªðCÚ²{ðÁ»Ë¼^N2¾uwÙtåã|mÖJ(ÓZ: Gá¸LhGƒ˜In¥rÓÄ6&ócÓI>ûn5Êä|T­XK_Ñ»íx¼u¹SœaªAfz‹c# t¯8v:8s6uòKõ¾ÿÝ›µV ;Xwî¿£<´éòÒ‘"ت׀Oju{öàA踔€nÇi´´‰4¶6 † O×3î¿SXÚ ðR߀“߃^­ U Ç`À]G‘‹Šéàó &U¢=¼ƒpóv½­H‘ÖûÑCS2Úë©ÈIíØ´KO0¨F{v÷á8Ç|_•íëR"›ª„Ë0Ü&䘯šöG虀r+)‰•èUÏf¹­h¶Æ áŠgubíý×Ss]ä™ß½¯æŒÎ™C˜;¯Ntn»ŠØ)4®÷bÒ.¤S¶h»MóáëwÉ*8Vî¾÷ å®ÛõÌU+£zÇÞ¸€´ ÅDæÈ<ÆkÈôÍ©°á?`ڟׄˆ‹±ÒØ®¥äô,ƒÊàË´2@Pu}½Ž?«ó#Ó3zGá6½ÖkK9røÑr×—>[æôlÁÄÖeúò«µSQo,–òáÖ}ÚÒ!kÁ8÷jD]5gœ|×Eµ¨u@Ù2cVÆ«Ô'§¹?Ѻն@«VÛRðíÐ ³6yË)=²k 4»,Œ'Œkôt%5G„Táà\ÐR>ú ÝuØ£íÇ7éAžt?üù{7_R7o×®D)#½‡¯£·ñ0ûîÃI¾-Âøg_Ÿ>Ì1Âd@ª µIvãIq|6çÄ=,Š Fý¤ÌŸ $Ši\#þ·Þt7ƒg¹çN¿tJ/ ½dÛoGö""õOËTìF+!Ë.@mÅÅ5ˆFüT:ÚL± 4h0¨õ$Ië&3»¤´îä-0´ €¼ ”“_Æú¦z @õÕ9=§W‘–ãqê­12‰–”^îÎ]{xe b7ù£W‡,Š÷ðË÷<ÉÙ.°oŸÚSnÐH»Oû î9q¸Ü¥ÔÛʒ^:!%ÐÑ{}¯\»óu`”ÂÖ`,*‰BÈy=õd:5aŒM¸E}Qð2Êã8››!\nlT·éô¦ašÓCDGêÞÄŒÈÙ)u£\\?®jÆq$x³!S[FõUXUü™ú°¦àšA$éœTyß ±ÖfJ×\hZ Ó}GéÝ:(¼‘nXê1¨ †V ªìFÓFô°¯êb˜ô‹7Á™þI¯$N÷dvÇ%JBº•Ââ—Ë®†½ó*ŸÝ~WMn+WÚ*8QÔIwêm¿{U§Ù)½ª[…èe›<;Eª‚zzPÿ‹Mio°KÕG<5¢Úär©°J<òëâP#£aǦ4ÇÖíJ^0r\/!ßèÔ¦²Eë¬Eà\¶5!(žê¦Ëd¢^ܤ.8òÐC-Yi$o2ÁðUj©% );íEÐZJëVß­XE[å¨Å{õy‰FÜ £›ÊÕNuÆJfD3Âè aGƒwîd K"Gß”ÐèáI"Ÿz{ŒšJWÛõÔÛvÍw?¿¥ìÓrw?ZîÖ‹IŽLlŽÝ€Zë  d5èã^8ìh#QÜš `RJð\U'+ñJÑ&¡1EFõÆ¡‘‰i¿² ÐÏÍê#·z8j‚9¿ÖE|yÊGþT\ŽHmG½i§‹Çy”M¹ø8Òiç!î<ä—lEœ.n¨† S¶‚iòéúI²n=HnÝŠ-0´ `˜~@ïŠSŽi/ÿ ½ƒndQ¯Ñc¿9„fóÒ“Õ£ÃGôn<‘ÝaéѸDA:r¥ÓÑq¯Â*Dꊀ ?©ú\¥ 0—«nOÑÁ}ºKp×ìѲO ˜ÓAÆ47‘•дr#¼þKŠ€}ó”Î?æ>*€‘[œÝ,6Žè+C±I=¬—nðÖ €¦'íf¶hK4Ö€.‡œTŠªGõ+@!S‚üæ‰,äôa>…q\;t¦T=EPi•N›Q[\¼HUõæ½æRŠ“Z‹ˆ„HÈÆžó÷ÝØZ .}hÀàên µûò˜)÷ãënÀòäÕ¦²ã§Ó› i3#)q– õÔ]5rÆí9âì¿wç—ßSJP&lœM^‡(â‡ä^23].Ñ&¢',l-ûõò’;.÷)í°6mÝ^Fµã®=¤úè•Zr,ê©)ƒL„–‰™^Ñç ÁZW8"þŽFûq-<ÎÈ÷S|Ô‰ú*kU΋Lˆ€\¢¨zøA®×E‚®_ àü:¼†‚ï?µt»ÂÒFQ&I8¯(7J±YŸDÃu3ÇÚÓJ-Ð*€•Z¦IwoVg“`õΉcŸ<ã(=™ìNKšÁ¡QËH×h:«‹zub÷nd(AÉMåÙBL¯'çFiXd‡Zˆ­½$‹h“DÄèFÿµ['ËZ¤;¤·ß§éÁ]zsïCš¿/íÖ‡:UȈ¬„E”Çd)Œës_Kõç?|äˆÎÕˆ:¡r¸½Æüškô½ûZ¾µ˜.Ä×®Êù!©¸_Hm6*GíºgXÒ*0¹—ä(ª~Žlk·©º,Ú7ö@kz¥v¦aT¿1B¿OëVß­X}[i¬æ’©Mßã•XîtB¤ºrÆèÝ$ãÜÓANÒä‚IVGnŒv¡MÈ';AYHü¸4!2"סR{ ¬ŽjV=˜£†»4ÊïÒÂØõ@Í^)»´Éè>=hs\ÁØ¥WøÁÞxäÈa=Œ³×–ȸ¶èNMoöã·¶Lô4"7ÙK@q\/‘:ëâ,O(FˆT1v@A¹&…pº.À“`_’’‰2¡} þåaRùQ`…'Uç|°µ u’`«NÒ8ýIìfÕ÷÷Æ´1GOßVàÉëvÖš#1™è¼ús‡Måá]ø ü!.´ èJ>û‘×¼†R¦ fµp€dá¸~Vù€×N^l;ÞY®Ö³õÈ"¸ïð#å+ºu÷€îã?¢©Â¨>a?!K`JvØ®ÌË:–´—Ÿ‡s‚_‚-]u¥º®¶¯% E p%yPkâQ3T×´L!]B| ]^_KÈs^tfSÕ¾ÜäœÖ> >¦ÚºÕ·@ÛZ«o«àÔ*ó(Oå±Àw¢²Ð¶(z„rï­Bé´îÈáõFõ`b'`ŽšÑÑ“?Æú I–ä8‡åEÜr °õt†ló“¡û˜1€$›À¢;‰åÒ-ÛÊ¥²ný£{¿Zþfç~‡#í¨F{—%u‚ŽÜÜFä20ñu¡õbä)ÕêÞ)QØÕ$C$Ûož"E|ÊL½’“¶Àº1MBBáE΀>²I%o(ÓU/ís*SÛ´UÛ»##O{>u ¤Uyj΋œ#;^™Ö‚«qîåj”Ú‚ô÷œów›J|tîì¼ð°jÝï ô¬:x˜òd&ÍG {í@‚¼WekdÓ‘eØg$WnçAu…8Õ“Ö4¶LI¡‰Ä‹F|C_•±Kµ*®Ñ·¬s*Âê%vFJ§êÌŒ£&ÁÁ+×ȨR`æ0h&×4²à²HÎ$…¬ü%å›_|se!‹”–!s™8Fwb:•Vˆ³Xì¬ÄxJPä,Ÿâ3/LÄÉÕ­Äê “ž<ãúëYB³DTÁ2SAµw]A×6à;ÍßžVßC½`Soõײ®œî´tPÝZóèí®ªî*Ѐì„ì½÷Ws©{s*ƒèÚžávÑ#©¶O)@'»xúUVh”ŠÑš%@âqIWZít f«@4nú– lŠûéD•íëqÖ(ß°dÁ2$[O)Ù18ô¤ÆÁËѬZäŠ/ $ÈY %ÑiÖ­˜`‘]]‘™ú=¢ÃÔwT¡uý¿ÑÐVt£+Öí{ÚTÃ×¢D €tw÷Ñè–ÍúÒyé¤!#%59vï· Ñ—ÐÍØ£»œž@uéR‚Ð-³KïV-Ì}W©¢»x²C¸¾:Y0uaÙ€?ÂÕyF{ù”Ö-Oá7 ŒÃÙ› ɃèÝüŠ{Î/Š}ÅS! #ꢊY°ž•rnÝÚZ ïµåºˆ¹Ç4Êtô’ºøÎ%`EýPçŒÖV¢;£jïöîlĤ?&!ê ^ª``›w —@¶:P« ‚?¤™[Áîâ`¦ÀO8«F¹a.ÜA­lÎC˜ƒ¤ÇøÊä,™1sB§3RG’-\üaYAyÍÓ!+4‘ÖM6é!©Ö­­Z°¶ö*eçvm¡‡OÜQ݉Õ}­ܽ݉E°d7ð2ðÓYI « "(‘#›óÆ© »åÉÉŠ2p]t²_…¦|FqäµÜAp½”–ûÅKSnw­ÂTg@'>\^–ÃÄud^h¸¤…_Så²e$?ë’ü&½;êׂ’f>nG6V§Úw4[dUá¡]ÈUWq˜x­—ïuk—\v½Ÿº¦W¥•ÑXÀe4Óèd>z/œÕï!%ÌqËl"AÜXqo1.ÐY#¨ì½åR”« ±f+~êÊ?/Î!¡6aUO 8VüS5c³R(z-¶Hª€ã3åA•ˆåå;µžÄ@]¢ hÕ@ç%¼YY…sôw;Šž> ƒú¦ãÎæ´׆'LÛhŸú «ëërÃZͯWntÑÇ?ù.ž7ÄhÝßÚ]—îÛsþÉÝi“&ŠòeÿƧñáKð~gVnéíûyÈŸâj>ÃGÄ 9º<žå1J£3òl”žï,(è½ü$¡´ä[y¹†5ìÑ€‰G®ëÖáë¨~·5.¯ë$½ÖW¹$„:e{ôâx§)gø’Zù),cù)´UY¢&ô0”]V¬[bX©úzØJl-\àFô¸é ïÔñkö5üG' t‹˜ö·‚Î_}߇0ò¾ÆN›ÄU •x›@òª½8™ÛóÃa¾q#%€Xÿ˜Í ¢áHËz46ûøv‰æ×© x¥KJ±Ðc„‘J¥WÛ†„eµ­é¢»l§ØÍ'¢•–…qçëoJ1?eõÊ¡„Z¸y}7– RX|µx:6c{ZM ¸Ï¬†ñbçɆÙ8‰är@Ÿ×@B.²`J€’ívDœˆUJ÷ºÍCbð䨎œt]PHHÔLg’%Äâ*#yìËS‚aL#?†Ø”^6¡ß×ý­‚¥=Ÿ¤z¿÷I˜Ú¤^ ð}À޾>£Os¤…·²˜"b€(#´4¸4úÑkõŸ;rhj Û±”e`#õ œÞQ¡U™Á?Aé‘Ñ”j×›#˜‚¢Ì²é½M~ñz-@Áu¤œZ„ãкt\0 U%š ÈmuDJ´ˆRŠ0]IDAT)ÕU!\EÔ3èÉ—Ê‚tœyjãZŠNz)é8ol’kHv¼=­Ü­X¹m–§Ô§w{éaz'@Qô±œS}ytÖ¨ÞÁ”);.¨‰?dUp*‘®îå*»Zãæm—%áxªìʉˆy¬?»êI:‹‹]à;©™K µ>ª%5iqÝMJB–ºE™¾ÖÚ–Á/áÄkx>Òݸa$Í~* ¥çºÇ¤>®šïH…á ¶§“¶@«NÚ<Ëó)³ŽnŽjõøÐûðn 6iˈ#&Òù£Ÿ»¤ §›'+ø´Œ`´£XlØ3‚ë/‹©\aR{ôu—!Pjð{“Mp8h½< +’GÊ#[;«¡ÚÈÏ:Y¶RB*aó‘ùUšóÀ—q…ƒWY݆²„”ejS|,iÎОNÙ­8eõ–=¬Iz4^vçŸA}ÖDúo7šOÖN½\{p{®çÈ“V@)G÷^™Æ@zá.å*o A)˜Å#À” ¼]ó]“Ú‰2J#ާ!F‘f¹QNð’ŒKÉÞU)öœ(^É·L—ƒdœüZ mÈ_¸ÊÍô`«9ülÆô–x •tÍØz§hf;k›œ-0²k§€™ÝS/U?­Æ»YܹEKuÜö ·ì€ ˆ±K[‚ž´.4F ‡¨¯Áˆ`xN¾›'8uv1N‘êº) é<ÁH=Ì ?4­àÓ©øÜ·&{¤“ƒH×Õˆ2"oæoòui}ù(— n›FÓSV-oŠÏ¶µnÍ-Ð*€54Yä[·©KÆM@Þ—G_ÅußÁ§0´¤g'¯lôj¥U *1:uWz/Ÿø2/ò#œiĺ &¹,§ÉŸàN)f„Aõà»t„ì ~@ŽN°2Ýy³êǵ’3¾ó)`_q”MÄ__DbJpäÕÒ´†Û%k}R<5¬$;_{ Íèg­[{ ,ûMמýâÊ‘5¢7è6 ËõÑuë–`uÐ|FÅÀá¤Û~éˆq,U»8@ÉÈ+: rôñ %ÎÁð Öš¡2“‚"D¨k—[K(›*™ý ð* HŒ<¢©"È¢>I«¹, fÊá =òÄ“/36yœÆ‚„\*%ê–ù¡üÝt®e¤RäŽúCNtÕTû$`´ÇÏy_jÙÖŸŽº¬³®‘§.žG‡Sgëèmºe‰/ó†ZH>7Ñ_†?ťLJ#f/FÖvϱJíØÝ$ 0²Øe H60ˆq»ÁH›u=ƒn~ f%„|sU%)ë‡Ä›#?åÂÙ“¢Q.=Ä8Òà³S FpÅLŒ2jª<åV^’¬ ê5çï ·KÊò«‰Ÿ·ÀH×)|Z}Ó¿ $¯ËÕ²SjCV­!¯Îö­îtôÓ5Ž®Ùñ¡Y‘Õ4ö°qÈ[h>Ê‚!âKiëSn_7¨¥QrÚQk]`AUþª.| ‘)FW×Ãé5¿¼&„›ÏU¤švxn—èÝÐòèÖ=Ø£D¤Œ*B­¤°†_i‡Z[ ³<|]ÛÔ¶x`ål½U¶@«VÙP°u÷¾ë­@˜ñ‹•Xì‰â!Š€ƒoê„Óc?V=«¡æƒçÄ dôËDIä^€Ä€ÇO ”@õ)Œ£º”Ã"_¸ð‰ÖP¥ûÛ?nÔBÈ ä %=ÂIôOê Òpˆápƒä0Íe#;€Œ®HZP'ïb«„깎‘¾iMËZ·öÚ)ÀÚ/eýsäÓQ)€ù (:wöQõî녣“öâ‚]„ñ=¿m•Š «"È RšËóÃÓ¢ó%hk¾*Å^ämJȵ‹nÕ»ì j]ó¼ÊF€Œ+êfqšÓuÊ’ÅèL¼{iËÒCF>rõV"¸¾ZO%¥u”åôÚ Ëˆ5€PÙ^!¹=Ÿª†ÖÆ2æ êŒ[fÊ‹€úŠnìÞ‹ÎKçô¡Sâ™xÓ™“ljåœV‡HÂ.¯» ƒ(PÈ)G¾.èŽyE¤qî/8S¨YÓµZ^c%¹>É àÇ -#’kzHO=Ë#˜R^¨•”LZ*©š_×JÛ$aÚhqnAíÆ“€õ}€Ù&µÃàåo: ué¯ÃÐ*€þŠC<È1= ´89©>ªNj¤ª'F?U5sâ«`öÖ¾Ê'™·Ø8ևƿŠ|x8j´'¾!«[d2‘–ÄZ{$ÚþŽDÞÈ.@Ý‹-=ëC=3^3?ƃ‡ÏÂbÆS¾•@7©DSÁ5)H!ît]gfË8_]fóÏ”¬2\þFŽ´§S¶@«NÙD=†ì|ú­ Ž ôÙ½+ïöëîéçÍ>›2ºÃª+‡¯x-ë},(ùz¥Ó¹ãè1À%— DAû…šuPŸ æ* ‰Ë\ŠÊÑšÄ.­É™ÄFzr·Œä!ô`Mi(³åõø•./ ÊÏø˜,²±)ý&­[s ´ ` M–£Ëˆ:[G&çø8ÍW›0AOÇv'V·˜vÜoGD'‡:¢[ƒ”xüü?y2_dêž³\°XªNЉÎ_³PLU òœ‰h PȺiyèÁ¹üLy*ÇE"J®+Vá¬[3=ª#w·J5“ù& ØMî¶Y\BoÌL¨ÐéÝ ¬:꟯Oòžä4ò›ÐžNÚËý“²¶‰Ýà ºÚz:²ÀXı¨ƒ?Æ2Å£‡šâD‡fhue;g¦N·ž_“íY0!"Cm¹>U[x$F®þ Gˆ&W”M¨GËpKø"ðEpV*Ãň‘ë4ø@\‡7 VŸ¼)‹ü+ïTâ¸~‹|8ÒÛój[€îÒº5´@ÎÝG6ó‰°º‚n F÷§³F—¯Ã/½»;>:1’+›­Fƒr‡+/ì×,é.\óõÙÝá”Ì‘œìõI·àdZá<¥h:fˆÍø®Y-CxÍÚ9¾œ/r¸©Ä¥.§Ñ¶)×Í•è*¥Â ƒ²pÔyJ¿EëN¯Z°ÆvËG‚Gô%Ú|É…ÇëD‘äu!e?›X :0C\ågOÎÏÐÛ³'RœÚ;¥lß®ƒ¾D ™õˆ\ BWfƒÖ͈¬üv}T¥+ޤn²x7aRÓ졺 ×³¼¨3‰Aëòq¤ë/•e9H†Îa ÁG˦KâA öQàlÉÕûÙ;WŸ£åŒÐ#Á ">²¡UõJæ¦8À#T¬™¦Nà+¬žBäB⢞$ÊÝ…½; Hì9àЃ €1ÖU55™x:)ËÂÏpO¤HAÌ4¶“#ÙÍ”Yóºh…ãZC *‹ÁïV«æ¼¶4R0ô*×ùt¢ô”í:)ÝibÅwZãšg¶µOÒŒ§ã†z'`vÈÓ¹°õÊ‚¶È°ž›–2ƒ·°¨—º³ˆz‡ÀÐ@.Á¤¸eBJ´Ð¹ÍÀF#¶è 3kÖ,f­A.ÒCE²Œ¦Ÿa±Q?ø´±ñ&HaÀê8~ øD¨‰)Bòʧ]‰Ý”¾®JfG6A(Ь#¹{Îû'ºWÊä¶­n;Êí¶a½ ¤†Zœ¤Þ–”~Dï _ÒÜö/‹ÜGºGDl^‰à/ºa¬xw]Ý™•`ž|¯ !W3”0^äÝ¿ÓÄáB`PF5¡ð*#EÁ’òL£–X(DªHDÂ:À™ñr°zï¿ÂÍ"j²yºô("ÚÅ)‘?yIŽeÏ §Èê0eØÄݶU0—Î,‹O‚µîôZ Û}N/ûÅ›kD¢LðG+Dw栊ΚóêŹ7GX÷rªu€ :xòG\|Z#É‘“ƒ!@R9\8Då—ßÍ A5l: d9‚öqvÅè´ùÍò˜iŒØ)†Ìï°N軤äµ¾´…ó‹§÷Ö%Ñêu/TúæKv ªu§Ñ­Xc£u;²€¿¨N^.(ø”¦@¼)(Æ}”C¤‘‹ž®„î ·c‹1`4 Y(¬©Ðu>àw4’;Y:2Œà^†¨ eÁ#çÛ˜òaáHåã¢ÄRk§”žë‰CFĺ´›âã²2«Ò‚/ø`åp „YÌ”Ÿ€'Ý/'QOEávdv`·td»’7¥7·îôZ`h§ÝÎz×µn¹X}§n£Ú xð«³2_Ø@»û½hôäøù¶Â1Ó®—4!—5å8×n·ýýAÑ+háêMd%¡x¸Ç…Q¶eIaÄBâÀ99ʪ¨¥†¨õî™-Ò™C@(ŒPh)–<]>…©ÒÓ*êù=>ÀO@ïšDq¾dä¢@ic+]ž[Á S÷i­Çd±Âm˜Ü0Ö)Û§µ²%Véç#ÁcZ˜g4Z!ªÎ檶õ*Òhpš=óø=¢yÈV'¦‹f”,Ð̂ӱÙJôÏœp19PL¬ŒØ:e¨e×ÛµÎ' – Ë!’£&õ¯# à¨c-¶›; íK‚Õ‹°ÏÕêAˆŽ´4Hr•åò\S »•*@ØUU>x0†¸húÒ‚ùºkYaåiÝêZ U«k§.WÅM|%XCÐb"ˆÎJUÏÄgdŽŽÞí–xNÜ> ±±WA"’E6”@N X@5pPËÁ×á<%ï÷€ üi®@²ëg.ɨvv¤@ ñYðàMªóÖ|ÉG”:Ôb ®nœâ]~ddë.,¼¾<Ú)èžÇÐ&J„?ë“$®!•€÷(³­µÑœÞk8£€­;½hÀÛ-lTÀâ”î¨3ÆbTFtX S‹êèX½12 E¥Yž;xW—¨ÇçFŸnõÒÐ0ÈBÁ (C€‘Ñ1´ƒ8P‚ G{'‘‘SÇ÷^Þä°õ Ìž ;Ž9€kKAxSÑÝñÊ”æQdêo “æ+¨5Ýù)Þt$HA(Þ»¦Mþ¸z™˜‰O‚YL{ZS íÀš®â\2çÊÙÄTéè+ÁØ­`ÀT—Sϵi éüòÁ¯ó¢‡#GÄ€‹Óá:9o¼ìj~.•”`Nde:i²X¼¤T æ­uËâñkÍ£Ì8û»…¢ãÅÙÍ×Ý@äîÝ`RfÖqÈþ0©¦XL=Ø"gºx ñy.¾ ‰H¥ƒ–U½,Ùød1a“óÈ-°7” é8ùúnYY]ĈB1È•ËÈ1ÓŽÛ’‘Ñe;«F|5F¨7ñ‘¬DÓ |Ñ)ò•¾iG» X­tÚ®U§ÑtŒhtëÎö-eA#Ï‚ÉÝ9uîöòÇÔK½ nk“\q àÀ=™<¸Ø§|,"àvŠ€f&À+Š’`ñ¬°Æ¹¡,€’_Y,‡JAÐáèNP\Ùùz™} ï)‚a9ˆ2-É’KFj#Gš¦(KŠ£Ð–¬5åcÖÎ%X¸È€{cOÕ””O¥h_|}ÓSwëS™¹ 8ÚH ­[S ­ ƒëœ.ë6®ÏQ`$üývú TOˆõ3°àEŸf „ýÕqçE^4UeÁ˜ÇhF—gc‘ïÛÓûåº`÷}sÄÇB¢GhE0Ðjæ•d!ÛÚɾNÔ ÕÃU&™Š6qm Âxö;ø\!ÄæR%O/*£Êɯþ†UOÑ™ê"¢<ÑEp˜¨Œ”‚¤ÖY•*V4±ø ­ KŽMªÜ¥²ù’KÜOò7wØÜ°öcÚihÀ°ýˆƒê3ª[Póýgʸ:#0ŒøÜ¶âSG§óó²Ž4€÷ ÐÉ…ßPoµÙ[sàÎE.GGÓ‰µc´#ð±rúн¯®aK¢#”9 ¨‰ Îe!>©Î¢3ˆ3º/ikm~ɇ{-Ø$@éðZ—"\…ùê²â˜â dNÊW%¹×C˜ö0-âˆEIÍiG$b6ëe ­;ýhÀé·]ß¶E±”ù„ÐÌ|–N9JX°êf¡•ÁÝZž?B()…G«ÉM˜ÎŽ0FØt£1\Z˜lÒu(EHœïDÈgnî[Ba * ! „:×ŒÔ ®Á’LÂU¬DΠ€ëÊh…à5_¨ÈJÄJ‰2ô(>Dg=ëåTë@<( +ÕÑñé°‚%ïnÝÚ[ Uko³nŽ1MŽ À@Ÿp‡ÃüÖ†+Ñ€;>Ky,|Aà3 3œî®Ñ\žç áú÷¨“åU…jÃìbQš³jü—lêë)£Î9º›¢[ ¶ (@ÂðÁí,Gù®lâJåú4êÃGe'yL‡ÜP ÃKR5\îg Ìcqβ$ÞJÂqh"l­/5c{Zs ­ Ó»ã¯ù’Ö?ß nS;w–¹qôø|éèÃ#z4x ð« þ8+óê¶Ä2s[¼ÿˆEŽ´ PŒiñN·½ÒŸÁ>ç"C¼" —ðÄ£""¯‡oÒ•×YIKÀIbD@uË0à‡(v#ÖÅo»*b±yn¾à #õÊü®14Q’ŸXP”¦ªqÍȦe¢Žä èð.H0YœŸÓÃVceç¥{\gö m¡‡ÔÑwZ·Æð†õÐÍ»/-׿õß”#ê|-Îéw>¡ž,uPæÔsç„RVüçQïßS°¸c° 0ѹ11qÝñůn­½‚Šè>ÄÄüÜ/‰¡=ЭsŒÖ|^¬;²&ªÄø¸³à2Tæ¢ê‡e‹èo@] î°ÑiÉo^ê+uv½äã.#1ù bx©¿þ s—¯xÈëÕ×m „y)(ÀÏîÖF‰k®?·8_æå³º¤Ê/üS;v•7ÿÚ{ËîË/W}´üʪgëÖÜm«­¹Éj†ªÕoþîï*/üЇKùƺsÒQó€VÀŸSç¤c³E°  ³`^iÑá ¥óxæC,jÃŽy5 B¹0eàÈõeP*¸áë:‡EƒGv'˜<- £ÊÄ“HI¶€>ÔpÈ õ¤îrXò>i‘?|ø½¶!0/é: lq,Ik`­°{oAa6I-ŽªNªæ¢ÚfIó©EEP¢L­P¬a,-IHÊ ~è‡Ê-ÿXùºç³¯iXG~šgØÝÐN†½á²~¼h×µ×–—üê»ÊíúPùÌÛ¡Ì|õ¿.lRó 0‡Ê¤d°jšP#¢a¦> ÑÌÂ>åß%¨·õ*f¥¦é†ä„F²È ¡7Â,V·#É >9WÃ÷¼>¨7uT•á¿Tqa4æJÏéBSéDñiÞC]É…¥@m]ž|bÈÜÍ{–4Â/±A´ŽÖ#P~ÜAÐ7¿l”Źrí³ž]~øío+7=íi–° ¶o»°ã4OmëfÃe¶Qu@ÌTVÜoxñ‹ËUÏ{^ù쯾§|åÿø¥2¡^?'à©óûy:& ~7Çø9[w†-à§ÑÔ!±fô‚Šgÿøÿ\^ôç.ã/x‘;;&îœ@0'`Òò¸pú€×f®à· dÀK:€Ãˆ)Ð ¨Žyòäô(/€ô:àÉaVa­$ƒŠ“ÍlÑMnˆ&Y)•ñ IüdPo!5À/…#e+ÐËÅ(®‚àc ÔJ)„ÉÎ K)IwŠ>â© àgJБ¶äÚ™î<÷û¿¿ü_Ÿ¼µ ~”-Àoçünü3>µÀ7aOÖˆ¢“îyÂãËK~íWËíùhùÛû¶²åÁûˬÒ&"FÙQÙº4þ’ÌÝq‚^Èb(z€Àd‡_Xˆe„ë€{ æ"Ÿ†w¦NQ–ÚÀí[‹ã±e憵§dËtš’Ðiæ+¦}öª'¨åT>êëb-‘2•®<ùT"ÏüžrPØeF>N~hž(óȸžë‘éÀåO{zù‘·½½<ýëþ©¸¤Üª¹ŸþšØžÎ¸Z àŒ›°O€@ɧªéÄ 7¼ðåŸøÏËž7¾±…UHâNÀ¼4§ÑÑaÖ ƒE,(°Q€:Ãb!b@­þ‘'-ðt 1T Jô桌ûó=4Š¯Ê „ÞIGÐò­=‚꿎þð'ø {qsžËUfêè…¼.øcÔǪaƒÒ[èäz#_ÑÞþÅù…²°iªü‹_xGyç?hð|,‡ÖÜßâlŸ[p¶[´ÊeÒߘ<ëG´¼ä£+ã/~iŒ–â›Ï<ëêàóB¨•€èÐÓƒ&€ã;GNÑsjÐSšBxZóotŽ…ÂeQ¢¡4|’ï‘Ûú$¡0È$P üép¹çµÒÑÔ§‚¹9ê{…_œ\ u潘ü(‰9…­$¼3!s_%ÍÉø§šãÿÚ­Ÿ,¯zÍH)ézê¨ßšûjÄurí`6Å6§»¯¿¾¼ä–wjZð‘ò™ŸG™¹÷.[˜ò‚À2„š1)ƒÀ 4ž è– µyØD'Æ”ÀšÜ¼™`ÇÝv$Z¨Â˜Ë3•€×ÓNY|ÄuÔÇ‚€N9< ˆ0òÍO>I`÷ ˜]:#>i€ZåDYÕj!?eë« adBVÒ¼î3h/õ®'?¹¼îío/Ïzî7HB˜û˜úí¨ïæX×Sk¬kóVáuZÀÚSƒ^øÂòíþ§åÒŸ|c9X¬Í™cjÀ~- 0s†¹ßÏèÍÁ.8‡p …`‹A`ÅÏQ3Ûûô ‹r¸BaEÄhl‚NÒ7V €oÂâÒ1x+ø™Šˆ‡ 9°²ÈG%ŵÁ z¹¾¢aê]™xŸ¢6FÌI)}×Û~¶ÜòßÿÌàwûH8Àoïíó+¬¿Zp!vF5¦err²|Ýÿô£å¥ŸøË2ñÒ— @ZëãžÌ l$ò G„[FT+õ @ À}ÇÀq@ÎhË4 ÒP˜ëŒ¶Î+>Ã"`Õ $:qÌ~鞪&"N9{®C Çà—lJµõ íãï (Ñi:!¥ÆÊ>œIå¨Ó?yÕw”÷þ¿Ÿ.ßû#?bÀ~·šèsÃÜ—/¼Ö>:ψ”Λˆ®¹¦¼ø¿Rn~ïûÊìãžè½Þé'ðÏ 6sZ`! ! rM­ \¾u¨pZÀbóæ'|Ó7–—ÿ÷–Kßü¿è Ãx h^£ùœ¶È²ÀÓ)ƒX"˜·W cAÄ €¦Ãcà‰°VÓaÏöb+Â*‹ÑðÃkþôs±Ï — äH '¿þeeH–hž (ò©Sa®/ÅÁ{^ù3?]Þý‘—öüçûºÛÕ}5Ô»Vlô “—§ ™?3÷}ÖÿËòÒ[o-“ßöÏ=ÂòV¦¬œÏëž? g?¼çÔ·Ö|Ç@È#ŒÉÎ.B8ò4@ü©<ÍxŒÞäã ^NPylçÑbŸçüÄu`ÚcS -83ê³™‡p<÷ &_zB{"–ÊS¿íÛÊ-ùÉò}oøQO}0÷YÙoW÷Õ`ìZ°Á?@ïÛ†Š0-Øyå•åE¿üKåkëeþ†˸hÜ럛ð3±sP`Óm?Àí‘^0¶Ù-@{ô•Àå4N‡õˆååcÆGZNð(ðTùÐt0êÇ6Þ |ñ±ÆŠG ÚÌÿ£×mÖ3oú÷—·¿ç=åÚÇ?®5÷iì!s­¶DV£1Ó‚Ç=çëËË?ø_ËU?û³å˜žÓF™9¡–Õsî,jdözÐÚÝZljk­dØ"ÐõñX2Ê!Flè( ,º<ß W8|FuüLQÄàGFlèQºbXL¨‡§4z,z^s‰oý©7—÷|ìcå¹z>ÂÖ…ä´·õÔ`CæZ0d?ÕaÕ¸9-øÚ×¼¦|ë_|¼lzÕwê˜ù#eV/ØÓê:‹ƒ^imt/ rï_м¬ÌkNŠ AO:w¬T6f?À‡Wžè„¥¿˜=ÖC”§ÕûÉXÝŸ—‚zÒ‹¾¥¼óÖ¿,¯ùÉŸ(Óz.sŸëiÍýhëa;õF a¾}r.~H¶Ûˆv\qEyáüå®ïzUù›Ÿûù2yÛýFâ¥q½EhN3~©rÀ*½àûù¼rœ§Ñð£R¬Çi=QÀ¸cÿhB3ðÔž*H£> !Ö ¤D`Nïéƒ|K—… Í<‹Ú̳éÊ«üÄÞ7½ìenV÷ÛÍ<碗œY­pfí·î¹=z¦"0¯ÿºg—Wþ·ÿV®}ÛÏ—#ÚK0¦¹¶0¨)Ì~­ ø DhÜJ w7‰Q›…9æí Œë^¼ÃªÈ4Æú¼Û i‚xü&ž ~/8¢MXäÓ¼cNÁ—üøO”wÉÜüMsÿbWàëÞ9ÎB­8 x.D¦œ~ú÷ÿ‹òò[?Q6}ï÷z±LÎŽŽ{ž;Þ7 ´£0ÿÙ+Às÷lŠ©AÐ}KOéŒþXzÛ€r+ÍÊ º,¦¼Š{drÂÖÁ¢¬Ž'¾àå—>öÑò/ßú–²e‹¾’¤Qß ëÜÌs.~ã(£UÑêgP¦wÊçnÁö={Ê Þñïʳï÷ËÒÍO×&¢¸+ÀÝF}n²8ÈF"vΩ\æŠ{þN<­J@> dQü(,¶$ë'¢jÐÜ\™¾ô²ò†[n)ÿ^w)n¸ñ&ÏóùÛE¾3øa7(k«6¨áϤX²9-Ш|í3ŸY^ñ_ÿ¨\ÿŽ_,G7oÓûýÉ2ýX¡ç..ÌÞPdk´®áEVZ,~—„~æýðóà/øÀzx±žj¼å“·–½üå]sŸ¹>ujÝù×­8ÿ~³nÛŠýîQŸú=ßU^ñ‰O”­ÿÃÿèi/˜Ó6\€ËÜùºçðêm!èEÔ[×z1-ÿàð-:Ý-ð´@VÁM/}i¹þ›¿¹|ö¿]fﺳ|÷÷~O¹Q |8V÷ÛWr nÇ ‘Ú*€ ñW]áš<-¨iþ€É½¶<»·ÝÌÓ× x´\à?p{ym œ¬†Öðj¶ÌÕÖµ-p¾·€§`Cz­0¤?L[­¶ÎE ´ à\´r[FÛCÚC;ÒöZ—j½ûÝï.Ÿÿüç—Éþf­Òçw~ç2ÚÙŠ|Lƒpò'RŽõ ÏÓÍ7ß\nºé¦²sçÎò´§=-ÉýAuÈØGÌ2®¾úêrà 7ô¥¶ÑsÕ­8W-½ÁåÜÿýåÃþpùë¿þëSÖeÔTH/Ó‹>žñŒg”«®ºê”yWËÐ,cóæÍåU¯zUyö³ûïI¬VZËwº-ÐNN·åΣ|Ô—vßñŽw¬ üƒ. Ká½ï}ï ¤³Bà ùÍßüÍ‚5qüøñ³"³²ºh-€ÕµÓyËu2‘ý}§ßÌÿìg?[ÓSÊ|Îsžc«â¡‡Z&òŽ;î(¿û»¿[~à~`½¬O ´S€õi× —úWõWM~Àÿ¦7½iEðª8 =Û€d=áÇ~ìÇ óÿ~Ç:VHëÖ¿Z°þm¼!%ü™çíw€‘Xw˜† rúЇ‘[ÚYnVœåqŒþý¦5õl€n˜ÖÅ +€©w.Z·¾-Ð*€õmß ‘þ¥/}i`¹9·˜¸Äoú¦oXú—¿üåô–xöZ Ug¯-‡FÒ¾ð…ÇÔ…¹ÿ°þYÉ'=éI\柭…ÇeBÛȲhÀ²æ8ÿ#ܾ´»ïZ}©wXÝJŒöïß?¬U¾`êÕ*€ æ§Œ A r—^zé òPиç?hàÈ‘#CQ¿ ¹­¸À~Ý ¼¢aßX3H ¼–xV[ Ugµ9[am œ_-Ð*€óë÷jkÛ¶ÀYmVœÕæÜxa»víX‰aÈfÐÂ%_nÝú¶@«Ö·}Ϲô•nõñΰ:”Ó °{÷îa­òS¯V\0?e\ `ЂÚ=÷Ü3´WºÒ‹ë®»nhë|¡T¬UÊ/Ù¸Ž§<å)X‡ykíJ;þžøÄ'>æ:ZÂÙmVœÝö i7ê @ƒÜ§>õ©Aä §}üãLöìÙsVß@ô˜Z‚[ U`GàÕZ¨ßñ\ÿ°=`³ÒƒK/Õ׋Z·þ-Ð*€õoã )á;¾ã;–Ë«½Všs̰ŽDêñð)åÕ¾ð1Ͳ.„V¬K³n¼PžüË·ï4kÃc¿ø‹¿Xn¿ýö&ù¤axy»ÐÙTÈü•_ù•«ÿÿ{ç’ÓFDQHd'ŠEʲ 0eÈÈò„ŰŒ ØW¦QHâ8uH.z²LdäO¼[RÑ_u¿w^Õín›.F£ÿ¶Ç·GÀ%Á¶Ç²Ü‘(+Î 5m…_ÉWn———*ͽJ(T³¯-~zzºqU^ì±êÄççç~öߘòú°¬Ïj¯{’(JÂuNL⬺m¦8'UIäeSiî«««åM-sÜ‹‹‹'ƒ¯.Çã±#àIÔ6ßÙ°9ÃòG8>>¾¯ë¿îï,wˆ;…£££ÕàäääÄ•€—ÁïaÙ°ÈNÁ;÷ö<;;;à“wì±+?©JϪǃmôG¿z´«ão£=ãp±X¤ö3~9•"áoÂ)Ï?³šN§_ƒ‹Ã Ûó&0›Í~ ‡ÃÏÑ‹¯á9à×O&á³È¿»˜¦™¿HCï›@> @þ¸&FÀ†Þ'6|€ü1p L € ½Olù,ùcà˜@ @zŸØò XòÇÀ-04€4ô>± ä°ä[`i,iè}bÈ'PQr_NÈ·àå(Û€á/ê寤{¶'%cºŠG~ów¯Âö40> ì”À¿X¾ë8‘⼄ Tª^œ‡_O&“ñ:ð]¼.y˲v^ë<5j’;^w_Ìçó›h ¯ÿßøÃö˜Oµ*õ^…a85Þ…ÿþ>œš¬g;ûùÎ ØÊ Á¹ÚOÃIúŸá×áß¿‡«Ûo³ëT¸J¹‰À·áEC,ÁVš€`­$~‡“ôLõÀ>˜bÿïRÂß  ÀàhÀ0©)ëü(låÊc.dÄ2Wzb™yœxÖ~1›k•UZ›à,så§x»-m&PŽ€’›Ø•øÖëì—n@À€B‚c=ó(¨nýõüï;€€b+G@IM,ã\íuW‹(ù%Ú?6åX ç­´ËÀ#éåN|èØª ž%‚rÉÄ*@[MbÀh$¿ný-ÃVž@úÚK´­D'ªP0¦$9S€)á—§±Éfe ´ñL#Yn]똦ZB M Ïúvže› <'ŠkÚÜΗèCú?• àF˜@§ô©z§Ýw·M o€¾Ç߽ óp÷û&`è{üÝûÎ X:w¿o€¾Çß½ïœÀj`ªN&ÜIEND®B`‚ic09{‡‰PNG  IHDRôxÔú AiCCPICC ProfileH –wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû2:Y~ pHYs  šœ@IDATxì½y°oÙUß·ïðæ~=¼Ô­n¡­–ÔBh`Ž$’²œŠ+ÄD±¡*Ç¦Š U .œ8T*lƒ)þ€($pÀåJà"L.À‚6²@BÝjIÝ­–Z=½yºó½ù~Ö9ß{×Û}~¿û»Ã{ï¾{÷~ïüÖÚkÚû¬sî^ëì³Ï9Skkkå –©©©ë½ë×½ë½Í~óÀ6s_Ûæã–Œös=ˆåzƱP×G[mœææÚC>ÓøûÊuëÑÌk°y y`´àÕÊÁÜø(hmóGÕMo°yà {`TТ›ôߘiC~Ç’o´æí–\{ø=È ÁLÂmÉ<×lh¸Ö£u¦ù[3ÿÚFÓk¹Vo8°h ÀÆ¡wàÎÜõiá3Ú€ ù–1 öÓ<Ð<0Òî¼W{IÓ3„åúnp¨äv†øÖ

þü‹/¼ðŸ|òÉ~æg~æsòð¢6’€ùºN¢P'üJìUIûuÓÓ§OÓ·VšnЦöÀßÀMÙqM/ªƒ>u Sþwj{@ ÀŸ¶Ò

áÂ…Ï;wîiýí}áW~åWÿÍßüÍWÔ)’…´‘ äd€àNçs"à€ošØpƒQ»±?;Mî¹çžÛáÖÚ¾ò@Kº+*Þ‰€ƒ¿ý1ý—¶^~ùå?l¥y`ß{`+qqRYËâDð\·c3Ddzzº\½zõ š%ø´àç?úÑ~äû¾ïûþBòWµÍi#)`v€™ÏŒJr2pÓ’%5êêö˽÷Þ»}å¦yà=Ѐ ï«~ ?-'¿wàÏšæ€á€Çíðvä¬4^·az†àÌܱé¶Á9Ý>xZ Á3¿üË¿ü«?ýÓ?ýiÙp2Àì@^;°'–ÔG½Õo¤Z°‘x þ¬“àþ¿gþí<@­­æ›åÞqíO"ƒ~–Ëø¸[ ÈYÖ°–gV€myyùmÏ?þøã¿þþ÷¿ÿ·Õäem$N6»= Ñnq Úòì´ëZZp]ÝÛŒoâ‚^+ð-ÏàÏ´E“¾jØ>öÀõŠÙnƇ\i~ ³ìÊÊJÑ,¤Ž9òžoú¦oúágžyæ_þê¯þêÿ óã¬Ý9®GxùûÍ ¾oõ9ùçïžÙ…€à­4ìg´ ;º9ðCñ€àÂI°•ææyÀy3gXÎyãC±žù†\ùw{–êê¿,,,°FàøáÇýæoþæôéOúÃ?ù“?ù ’¿[ð2“çwxøoÛë׌- §ZÙ÷àäoåZx ð‘¯Zp­¯Zmz ´;ÙÅÍlâC7¯žö¯ûc9è$W®\)/^??_Ξ=KBpü±Çû[O=õÔÿý ßð o”̨$À‰¾ÿæ1GŶlØOh‹¯ ò¾Gdcº«®xà–÷üª`+ÍûÒ9˜f|;;‹~m#×G]Ù[˜eL§/àCuÓÍ›™™)'OžŒMï¸ôOþÉ?ùî_ø…_ø¤L\ÒæÇY è· ú݆b]¿Åí=¸·•›å6ÐyÞWþÔŒûÊß_µ[¿Úïð€.}·½—Ä£ 8@×|Ó­OÜÃ!ZÏ2ÜЛ‹‚¹ë®»NþÓúOå~à¾J|žêñí'þü{À8¦ÂjûÁJ+Í{Ìœä­ {€?v6Ƈ¥µy`z`7cÞ¨ m·m—o½z¡ t6èz›`$·ß~ûìýÐýüþèþ§j÷”¶Úê'œä¿yðö„Nheßx %¯>”ü¡m^­Ñ(ÍûØ»‘8H㦌¹-óÁ½YÖ| oÔÁßíXÈLSîº%0õÁ~ðÿüÙŸýÙ÷IŽÇpËϳÌöyð8Ù’9¥•ýãNöV6<àÕÀ<=T"­Úð¯ûöxqP]X@áoŸuŒkj‹õS7ì…Aj³•æ]÷@ h.­ƒüßÐhXóÀòv§e(fš4N;u=Ó,—eL«ƒ?uÓ€Ì\¾|™5Sz2àþÅ_üÅ¿#Û¬ ðL€gÛLŽoe_z %ǵéœ K7jó@ó@xÀA8»Ã4àn$ØÎvÀsæCËtê, ÔG½ od&àk¾ækþÑ/ýÒ/ýwb{k Ç™1F¨íz¬ ™Všn ød¾%:{:¹ÙoͯëסKÍdóÀÞô€ƒì$½';*ffŒ×íÁóϲC´QºúÌpyþùç‹ÞIÀW~åWþ’ÏŒzu0ÿl7c¨ÓWëp^ëXβÔ-g^¦Ñ·Ü6¸ëÆ-c:už xá…øN@áÝÜ `[eêÝï~7I@ùÎïüÎaD™øB´ÝJóÀÍò@›¸Yžoí6 Ô®®Oâ t¬gh½\Âûnñ±Y6 ̶z%'mMÀX/6æ­à–Ü G©õ±y`x` î^MÖ…Üw'†XÈ8k˜Л# `¦}oŸz×»ÞÕnLæú&µ‡=Ѐ=|pZךŠr€ö>OJ’§[órð·-Öð^ž XÇIÀ‡>ô¡6j?·¢Zp+µÖçæ=î(׃ç¤]F7룗ë£ðÚ~–«y¹>$Gðç퀼€/"ã™CºÕ’€ìɆßjh À­vÄZ›®“†aÝÔ$2µŽëµ.õšfÙQpHÞv kÝLÒG¾¦S?{ölYYYY_ eÀûúŽ’€{î¹§­¬X«ß0´à†¹º5Ô7lÓ™ÍÊ$2£lŒÓÍ<ð\Çõ`Íϲ™†N–·,“uI:x-0:Ð m‡º“ã–£žålúN“ÙÝü Dëí§yàZ´àZ´Zó@óÀ& xmVð6“«m90Z¯®×ôZß|ÃÌ7nˆÌn°Æ¹ À ¼€ýdC.CÓÇÍdù–øˆ5x#=ЀéíÖVóÀò€ƒçVw¹Ö£nšáMË“ÉzYÞ:5ÍtôÀ½À^wø™f[™FЧäàõ–„kÚÏ ô@Kn ³[SÍûÅ­ÍŠà$rµÌýšfû5ݶÌw=ìã` ßtCh™ÏÞ à nhôLf:<êlÙn–! øò/ÿòm? »›˜h½ý4”2Ûœ°5äakšMºy`y€¿¬ï6ê¿+Û¶}×Ç5f;TpëºÎÔ=…:8peeåUuÚòf]×Yȧ]ÇÞvhÛ¦]¡Ø¦û -ÛÝI@ùÀ>ð¯à(A™Ÿ#øs@ …¶Ò<0Úm`´o§y y`‡Èm”)d†Ê½¶çúìÍšVëÕö\·Áß3ró ôÆM7 Íuä2^ëQWqðíÂïÒv\Ûam\´‘U0vfóXngŠÕJóÀ°|Ò sµy y y`Œú`5FBÑ©¿¢'4ÊN¦g|È–ùÀ¼YÖ4ê–â™fh= Wí|À4{ê9¨›np\`yCì©´$À¡Áëâ–\·6£ÍÇ}°»Ã“È Òƒ–éu½¶c~­“å̳,<Ó²8OxúÞò†ørsÓZP{²Õo¶Zp³@k¿y`x`T°Ì»¶™Ì(~¦g<Û‡7ÄÏ´Z&ó²½L·Ži,ô=tèÁ‘!ÐSZnh?{Ø-ØÃ§u­yàVò€ä¨>oÆß‰^m›zM«í×ü\¯õͲÀ‹Mw°§ hÔ)¦CÛÉL€ôÛí€ðhûÙM´`7½Ùl54Œõp\ÅÏtpoÙÖ(2æšf}è5Í TËSgËA œbÜ2–#˜Rð ‘g†!Û€NŠ·£$àë¾îëÆ¤héÕ?C³;C´¬¹?Ë‚{?‡è£xµl«÷@KÆû§q›švàêq›ƒàŒy¹yäL¯uÛŒ6$S븎쨶X@@CÖ6 ­oˆ 6ŠqxwЯ!r³³ÝZÛC&ÛS?nx@_ê2D«eÆÕ·š Œ³Õx“y %“ù©I54\8¨mÇô¨€“éµýšG»µŒiî“ut¡{@Öµœi:Ø£k~ÆëàOÝŸmZÏöv# Àv.›Õ-ëÀmhz mϰæoµ¾[v¶Úî~’o À~:šm_šnQŒ̇x™–qï~M£žiwà’±œ¡í; žõ,gZ†uЦßtð: àê:eT`;M¾ök¿öÚ ZÝø±Ÿ6(æþÖüIë[ÕÕŸIÛkrJF›šššö‚†À-÷Õ|Ã!^¦ áèé#;ăÆê}¯ê¯ål˺:Ø£c~Ƈ’óͳMèßÍ$`\€Çcß¶[Ø—IËVd'µyÐäZpÐŽxÛßæ=æìxDÀ2ôD무ßÝð@KvËÍFó@óÀŽ=@ðWFñ x›•¬›ñÍôFñIêE€ÈÙ†æÍ2®:ðÃ7o(ЛfXËQÏIuÒ]Iè_]¤ig\ÙŒ?Nwˆçv‡x6™6ÿË™ÌN“jhhØUl'`dŒu ¾e24=Ó²>ô|,g™ºš·ºnº?|ãð†½i†µu'†»™`ß%㦠Áì³!þ¤´Ý²3i{ûY®%ûùè¶}kØ'˜4Èìdwǵ‘y ϸ½Ì‡V×Mƒnžñ ø‘7(ЛfXËQwð7ÜiðÕ_ýÕ‘ŸNª8 vÔÿ޲Ç~µ²;h Àîø±Yih¸‰ ІèÛí¦í²YÓë:íÖ6rݸ?òÆá zÓ k9Ûîf0*8Ó硲›òØÚª½¡>5šÎ¯æ„ææææ ,sqÍ4³uÒ’É6gèÀ®qøC2C¼l|7“ïv7+“ÈdCò-ègíÞ€Ýñc³Ò<Ð<°G=0L&íê(ÝQ vkºnèæÏÐyãð‡ýÍH¾ê«¾*"ÿvó8½Q¼Qt|ÔÊÖ=Ѐ­û¬i44\'8 ™wpǧ?¤—i£ìÛfæƒ FÖ±ýºÝöÌËuãüȇW'ð'I°¾¡öaGO8  ý¡bÕYúáb>õŒ›ßàõñ@K®_›Õææ]öÀvC2uwÆñŇN_FñÝNͯënºyÆ3tàGÞ8üí$¶¾“Ñ®k@›.´ë2éñ’¢Ùnƒ“{ %“ûªI64Ü`䀑ñ¡nŒâ¢gÈTF–!£dk»ãêð°í­®›îÀß8¼í$è9øû²£$à+¿ò+7"»-@ṵ̂E¯å¨oEvH¿Ñt.5'444ì'àF•šGÝ´Œ×ú6Y¦~`­ãºíªC·]Ëæºq~äÃÛJà€x†tc'o $ °ŸèãN ¶†ì ÑvÚÖAÕo ÀA=òm¿› & źԴº^Ë×õZ¾®#Í[]7ݾqxN ñÕ@ 4êæ!—u\·m ÊŽ“Œ\¯2Éñ»^mïG»Ý™²÷ì:íSÿGr¬7³ÍÇ£óúoŒúlMCŽ·Ùãy¶_¿ÊºyØÁ>+ýÌó²¬ë›AäsŸë:úÙ&²¹nûô‰Bÿ3N ÷¾“,//Gð·žg,б¼º®v# øÐ‡>T¾ë»¾ë_Y®ô4:Ä3‘dkï}ï{§üñµž7ä}…c ólZ+;ó@›Ø™ÿšvó@óÀ ðÀP ܬÙID¶ îz†Æi3ã›õ¡æ×ºuÝö¡›g¸Û²l®wàGÞ8<qðQI:›%òÛ®%´çâãahú(XËQ¯i£t}¼Z0Þ?Û<ÐB¼‘·à–lÁYM´y yàæz`Òà ¹ÝÞf}ã†ØwàÜnY/Û¶ýÌ7 9o™F€¦#7`~ÖwÖ·-ù×’€èð&?“ïMÌ4ö´`„c¹y yà`x€àVƒ`æ™6¤“嶃×6ë:6sûæ›æÀ¬7ºã’äÐ é›$ àÁíÞx÷»ßý*‡ç@oܾƒçºiÀV¶ï–lßwM³y yà{ÀAï7»x¯w»õþÕuÚwÀ7Ì44ÅÛ2™nZ¾ ™œX.CÛU0Þµ$ ì±c~¶*?ÆÔgµàÀŸÍÍ·–H“”Z.×3^x™ŸÛ2}œL–ßî6¬[ס»}ÃLËÁÜ2Æ ¡o7 @w§IÀ»Þõ®kd>£pû¤ÁÝñ@{ðýȉßJó@óÀõõ@¹¥íüýe>p­EÚ1vÀ³<4&rlà~î¨>¢³Ó’û„­ºnû¹¯Þxî'â>gºi$~m0¯ ¶ŽqìZ6ŒéÇvÄóL@ùÎïüÎ-¿6˜$à£ýèÈwúæ}§Øy߃Ñ~¶ì6°e—5…ææ½èˆÜ·qA"óŒÁ„°m™ÜÎõÀëvFÕ¡{sÿr`Ífš×dZž °¼o —emÇròÏ”ù¶× »ìÓÌÏx–iøÖ=Ѐ­û¬i44ìCØrÉ.ÓÁüjúnׇú”ÛÈ|÷>¸ƒ6u÷×òã’Ë-—í¹Cä4C°ã$€~æànÜ~.£èY¦áã=ЀñþiÜææàL$ëÝvÀ:HÖ2×£^÷g¨n0ãôÓu÷Ùuwèèž °¬!<6êÆ3„.î( Г×f`ÎÌÇi€ÝH[ô@K¶è°&Þ<ÐðüšÌž×6ñÂ@Ùºf}ßi©LîÔÜ-¥ß€–ÜR'lëìþòÀ¸Áw3žùC0ÓÀ]wðÅ‹Ð\· uÓ‡v¦'è9øÕ82™æör;î›û”°ûeõ:`×2¶3Êî¼uÜN†Ùt·ûí·—7¼á 1KÀšÖ Àgÿ<+077æÜ.P ÃÚŸüÉŸüïÿïÿý_“§ZÐÆÕÿا¤¿ž´@ÞÚAi @Kvpú4Õæy å¯2´ÏübˆD纰yu ÎuËı‘ë‡ïd€{ãðúlN² tÛº/èÇ4×ͯéãêð¼ÙN-Ÿé™—qËl¹ðæ7¿¹¼ño,<¦Èí‚3>aá ³¶H~ÿ÷ÿýÞïýÞß’}fÆ%P~™é׀͎Ìx~KZ0þ iÜæëè„¡&&á!“åŒ`(æ›$›‡´Zzæ;ØwG§üN,cl3:Ó÷u7 Hlu©iYÎÐ6¼¡´ 컀ç Vó,—¡e€Æá×uëdÓjˆ ýȲ¦ Éš†LÖyýë__Þò–·¬¿Ì›ø…nà’€ŸÿùŸÿ?õS?õç²ã™'¼0ˆÀïàoh§º [†¹¿[V¾ÅÚS·ølÝo¸•=P™îËNì¡K@æ2Tw;潡« ¶^Ïv³ŽƒªƒPæå>€›gYó¡Û4óÏò–³MCË[¶†æ·.¸÷Óüçž{®|îsŸ+¯}íkËc=¶~{€'¸MÐ/œúà?øsŸýìg¿ý×ýן”‚º»a˜×Ÿ  ƒ•e ·2¡Ú ÀgΟ?ÿ¡ }ÛÄšväÑ\¹Z®J–IŒ¢·ª+­©UÍ .uW¬ •Ø„ÎéA:Úoj¦»o‹\<½=«©[îåªÁ5-d¸LÓ¾€ô{\q?j™IèÈÔrÑ3z–ËuÓM‡ç«uã@ø¦gÎV_ù»Ž.¸u°CÎFÉÁ4ú1ÏÐtà8<ó ³®q·™eŒ›gYө³¬e€lö±çDf&€Ež ð­œÆ†Ã¼ Ý~à>bä •–èoN}âÇ[pÐþDnàþ´mìõG[VÊÏ^Ÿ?W/]*‹/•eM«®Î]- çΗ…«seíò岪X+ËKejYSÙÚNv‡c×!¬RQ‰$ûk³3åÐìá2uèp9tBWk't/÷¶ÛËìí·ýÐ'Ëá“·—ÃwÞQ¦+3zÝìš®t‡J:ÙœfÀ¬‚Qð$tËÒ>¸7ê9 ×uË-G€¦Nq°¦n:r¦Mwp³6¼ECÛøÉ}GÝ}®M¢×r®Û.u€!ýL7?CãµMèl$ïxÇ;âÅ$ø†D@¼Å¿ñ7þÆuúôé—¤{AÛ¼¶%m^À) ÎÊ›ªÛKê¾bè ”–tãaKÊ¿÷“` A1dÝ?]1.]¾Tæ_:­`¦ÌŸ>].ñŲxîLYÖ€yHÁ{jUWøK«ei¡»§º6¥—ÔȦGljú \«­õ2%â§?¢K—¢pX¦ÖÄ›Ò3ÞªÏHO¡ f Ö¬€„µ™CeY™ÃŠðã÷Ü]NhP?z÷½åè©»Ê1á‡õ˜˜æyÃ^þa°ÇžŒyÔ< Ý2†÷溃{]·Ð290ÏYöÍ8|~èÆkèvA‡º7ú–K²Ð©Sw©q× ‡äLÛ¬íb#ÓÀ½Ács1ÏÅ‚ÌðvAö$@>»¨Ï ÿ×ÂI.kãéÖäaاx†"o­Ð—ƒZZÐ|1Æé$`NŠkä×Û ÀAýSÙÝýŽQOô׿ËÂË òÏAAÿ¥rþÙÏ•µ«—Ë¡M+À/./(ÀÄØ§>D‰ ‡>xnÝT2à˜óFA÷}H§nË6µ^-S×Ñɶ͇î-Û2 èb*à—‡z(L|¥µÏk†àïH–o._ÒÆí€z&ÀI@òÆÉ½Ñ€&)¹O“Èï'™–Äp×]äèÀ¶`?Ý{q_žiªœà·¤)ûËÏ<].=ýt¹ðÌ3eVSö«šâŸŸ›/Ë+ : ¶³ ¾ÓºêfŸ4@vC[mªŒßˆ­Ì]ƒ­%i ñ¤ˆtÁö6LÀÑ»åC²ûÃèFÓu-IwÍ)’ÍÆNk–i&âž¿öqM‰ ³‡eüèÑ#eúˆf ”@œøÒ7•;ßø¦rû—>\ëyqúȂ9Ó]7Ìtã†ÈzÃöšy@ Ð4ë”À Áì-Ÿƒ¼ñ¡À¶3Œ†Gü80æݺ˜†= uÓ\Æ6²-L¸?5Ýu`›fˆ,C· ¾óï,|½}¹páÂxï{ßû½bÕÆL·|+È{Ã1vŽ¡H›÷csÉý'Ñ€nœcÔak Àþ;Ç÷Ä­*€ä«ý•‹Êŧž*ç>ññ2¯ÏÀÎ(à_¹ª¯¬­èþòL·ØÀ¯‘ÞlÖ 8ƒÊÔ<£`Ü-{-]Òka@RèE|ŦV¦ëß”.dMÄÐ:¥«xfþË´~V•6H~M}šréw¥FÀîÔ=éþ Â(Uø]eoYSkkåØñeêèá2}×½åÔ;Þ^N=ú–rH·ÖbYôëÚÃxÿcÙZz½9@"ãà›e2ÍÞ²ðò†žƒ¼qø¦wàz†¹mðQ%ÜŒ[Þv¨g;¦gšu†à(9èCíÚÆ4ÓÙgpó áY–÷|õWu|¥Ú³Ï>ûkßò-ßò! ¸¢EùV€×ÐN´# E_Üöx©ýÉm @7<1,¶`žã7w¯ü‚* ¢óŸ®œþ‹¿(žx¢LkÁÞ]å/i.}æ>½ªouyÄ.˜®gBb y}d"“¢3¨vøúΪ¾¦`Ît=òX®H¸Ú_ˆÚŒþtµ»NäÏ‚Â8+|MO¬'ÁP0«€ñ·¯ÇŒ@×í²) é­˜f?ÕçC‚ÇŽi¡á±åÄ›ÞXî~Ï{ËíšXíýE°pàé,oüæA<×£¹D«ƒüšf¦Ù²¬iY†€ŸéàuÐÏIe¡Ñ&uÊPÿ½ïæ¹>$ošekßžmYÎ<àÍüš—ëàu=ë™?Ý.<|×»ÞÒÏßú­ßú_¾ïû¾ï·%S¿(ˆDzã¤ó&4pàØ’û%~~2ÇóÇÀ†2'`½‰4¾¸ã¥ö'·%1 ŘÖföç9~S÷jYé=ÿ{¿W®<ñ×åÊÙóeI‹ãx\nJÓê1ð´ò ”É> õ}ß×w†@/-¦Ýñºq[Â`¥²ªú´ˆXá$רºO9c _Q}AÙ F¼EŠÅ~Ó"À kè[Ä÷ð»>hCXWPîqTTí»Û“»~cgŠ5·$7Jt˜XÓ¢ÂÛ︣Ì>øºò%óo–£ú -_9H¹ŒžWâÔ3àRË ܶŸuàYh9ãæ9ðÃËr–5µ´é}6Ì…ºiϲ[Á'ÕÏrÆÞܦëÞç!YËd7½éMåÑGÅ‹Zð­W¯^}Qü¼(ÐI§72ê“t¸¸/ÃÜýMm @7$µ€ý}žß°½c€óB¶ ŸøDù¿ù7åÒË/Å}}0Y[ë ãáàË Ã:¾þ!±q• Þ¥(Yi×GÔ¸‹¯ú´(Aº ÖÝ2>l€uwúÙý€L-â9HZOüè ŒD9ÿdºðè,‘žMu¢½ö…þÄFѽÀH$Ä\ Yl²R¢ý×£…SÜfЭ“w*÷~Ó7–û¾þ?邜lFH‚÷Ÿ¡é xÔ3 º7d-cyó\·ÁÝX>ó3-Ói/·é:Ð>´÷€ßnöÒþayù÷~·¼rþ|9tôx\ÙêI}í=c‘"£®¦™ÖÖ‘Ö`] ˜qÕ O¥»"—^ câ÷ÃY§­U—t"t0­zØÕ8ÈHA3tø1G8šà £‚ôƒº‚3ÿÇ:vHB¯‡‰…N·ç °¦!z ßIôýA–ý-*¹»„U=A§ô¢óš=Yý»\Õc‘oúÛÿü ¿(X8ÁòÀ=ô7 9dØ 9ÈÔzֱݬÏ^¹]lúå5¶$¸×zÝìC3ÝýA×m×¸ëØ³Ì(ˆl.–Ë4ãð²MÓ 7Ó­å,Ÿ¡qï/¾ƒÆÍ~ÍrÆÏ?ÿ|< Ûoøµ_ûµ¿ûmßöm?¯vô9ãŒì!§ªO,¡ë<ðV*´ rH«6ìÔ§ÿð÷Ë‹¿óoË9^Ô£M+˺PÑ@Ö•nl"¸vAªÇ0(ÚBT?ˆE"²kàzì>x®_A£ >"’E4lô0ÂoÔ¡såͽýèƒMõºÒì”Õ]FŠÒ/A»ÑÈÚ¼!Û§z ðÓñä€÷S’j#º$áÎF#QГ+zä1hœ„szñÒÿ»²¸´RÞüm{=XÐÅ"*?9¸eŒ[ͲÖrÔM³úàN.r@3Ž Á9CxàìÃÐ~LB³Ì(H»æåþšb•-üض!ªà®Ú?æ9ø»´o2 ›|O€'ôn€ïùÆoüÆßûƒ?ø¿ ?ãD5Þ픺‚® uãAh?ZÐ΄æ]ð€³«ŸüDyñ~¯œÕc}3kZOßOùklë†!Æ¡~(2ÁŽ+å.$÷bwpUˆè®¾¡q}ÓËj”+ênðîíj¨Ã<[<§O’@Ý÷ðÅŽMFEÌ­¯Að°‰|$£á²} ÍŽ,"»J´ÙVúd¦ƒ@#¹X̨ôƒ¹ xÐxÔpý¥Ea«óÄŠú0#ÿ]ám‚ÿiùÜÝw•7üçÿY´µúà>Z?>ó Õ²ÖÖš–!6|. NÉ6-lݲÐÝËÔtêu±6)n»–«ën+ÓÝnæeܲ¦š„æ­®×ò–sß-ô~|úÓŸ.'Nœ(?÷s?÷¡Gyä¿‹$ ž èN×þÔF_Å´®Ö~×=ЀuW4¤y`›Ð Ï >¥Õý/ýÑ•^<]Ž;Z–×5À3Ên¹.²òÒvÂ`7`ûy}‚õ··½ (1eÏ2*Ú"¾óÓ‰v£3|èèDârXíÎ=Š~ vñC­ÑN/ ÆŒºí®.rtbC;ä]¿»@û‚­ØWCù€ä n‡t¶;¶øÑk௕Ëòñ¡Çÿ¼\|ë£åv}YŽ ƒEh«A–¡Àj™!^¦»^kl˜fœ©Óâ<¾i¶E=O}CÏûà~cÓ¸a¦»À'C[-¶g8¤_ó\‚¦Ùuoì@ËÕ=|jú“O>YÞýîwŸüßùÿé[¿õ[ÿ™Ø¬ Ëb‹ÓX³§ÿ ¶Qú³jƒpб–ô3 íÿŽ=Э„×ÒäO>QÎêÕ½SÇŽè²DCP?uÁµ«t÷Æ»jýJ˜^ˆM·lŒßTPÓ÷əРY<ðnpD³+Ý•?|××Ma]_5dÉG¥_”.lôÁ#•hªF{š—"º`P‹}…&º…ŒAïûÎØhƒÎvýèg#Ä—ÕèOg_|¨MûÌÛ .¾øByö#VÞ¡õ ô¡Ûÿ ­Œ ñ‡hèxb?e×r¦#Só 9ø[Îzpð)è:è#ã}€î-{ÙIqt‡Ê}ˆf]xôËûaYCä¼oYǸaè¦aƒÍûÝûŸýc9ÃZŸDê3ŸùLyÛÛÞöß~ó7ó/ëÑ@^ì'pDÞú“8h˜Š³¤•Î-hgBóÀ=ƒ¦¦‹ý‰rþâÅ2¥åp9Âx£a¯’\gqˆKîsw,hYäÖU,«3¬I@È*3aCºªÇƒpÙ-û¥‰´»ö‘î®ô;Lb ¬ô;’lЮ fô/dƒ„.0ÈnØìe»æèWä¬ñïôº. ×íT?éÑ5Ô'aB"´ƒ/EÂîD ™¢7êk:`¹¼ô©'ÊÂÜ¡–ãc‚ߴ¦t ­NÀ©å\7DÖz@ãÐ bøØòbPÓìÐ1 Y—ôL7D&ó­cz®›†|ÝF-—ë¹­LÏx-“ëàlÞw×ö<ö?ójû5:Å~Ó+‚‹¾8õ?ñÿBþ]±ü9u€Þ„êëJg¨¯4Ð}ø¦ù¡y y`»Ð`¦Ñ¿LÍëS¼úBߊþ±zmZoá‹a§¼úJ´’Chà1,1xvˆ (<N‘qdaÓãÐbŒƒ 4¦Ò ¶’ô€¹®ÏUto-ì‡ ÑÜVm;˜0Üãa9Z¥/Á—±) ©@ã„p¤3 ÑB²EB¢Z[ö¾¢»÷íw&c¿ÂD¿¯Wõ1¤¢Û,Wõí€Ø¿è8V¶Vì—¬í  t`·¼å|Õê ݲàØ%Ø¡—<ÛGÆ›éÀܧ̇Gâg›ÈÔý…6®d›ÈÕu۷̇ÃË|ô ÙwæS¯ÛÉíe[ŸÿüçùnÀìÇ~ìkÿñ?þÇÿŸäXÀ ëÈÔ fpÚù¬Ê¸È»´€ƒ}üÛÞï–´Xmvq©L-\-óbŽáó¦}€íƒ4MEôkÜ"NYÄØ š~{=^Ü£HwôÞP7¨özqe-¾ìv!6ÉFÒ õh³·F gÚºçum£¯> ס1¼º¯¢®ÞÑ+d ö‘ @‰& %|À•aW[߯Ø%|qn^k*”ÌÍÍ•»z½äbÜ~t É:æAƒoêæZß2ÀôÑÉuä©[žÇŸ:жnëš–eáç’m@·n–ɸÛÊÐüÜNnÛüºmèY7ÓÍó>g? G}”.:îv¨ëñÀ©÷½ï}?øÏÿù?ÿ3}¥•å$'÷g+ë§TwŠ©ý´ Í;ñÀú`®oH+ ™[(——4Æè?ŸÅeŠ¿»H^½i("Ø#d®WÈÇ(ÅO cB"BÒQ‚Eg×;ÄÒ°$< AÉxv¯KPb…6zÙn* ˆ]¼ã’u¡÷ëit:É5Vô«´x§××ÖÎ,Í«tõÀƒ¾.(V—D’ cËšU¹tõj¹¤O%U25¥¯"æ²Y Ë²à$›Qº™ny”ƒ—iØ3œR×;ªÖ1ô39ÈAsèbÜ0·—qËgˆŽe¬=ëf<ëfºqøYƸ!rC2î›ùöi¶kžõñi¦ë6@¹ÿþûOýøÿø7þÃøC$¯@Ø N­gDj´ Í»á P³ ø'ô"›Ë X¬ŽŸºSï8¢·Ûñ¶>E9m¬#pÒhTÅ¢¬þ®ÚLd)ä#"hÐEQÈ4A‰@â"Èhwµ-jèvò½` ÐëvÈ8Üç÷½C/šÑ+aa½ÎžtrÂ4ô2åïĤ—\ÞºkÈ`oZÔu•·¼4_.]¸X.é}óËZI¯oÇÏÎn$“Wp©s@IDATpÖéó 3ß4`]l3ó¢²èÖA?ßëζs #ðQ°ëö²¬ù¦YÆp=÷yÜv¶ ÝCôÁ]Ÿâ“,;„ÙfßΜ93óž÷¼çÛõ¶À?zî¹ç®J.Ïp²®ÿµ Ó+A¡»´à`ÿ¶÷»èé£GˉÙér×ÜJYºr¡\Ö—þf•ðùÛi}1qµ¿š覴xÐa¨øÜ>ˆ7ú9"Š¡·ÿ‰ ®+ü>dÊPü×Þtvºd"„Eë™j/&¬%rX%ðÐÈŽÈÅ>ŠC)unçm”ʵ6DÒ¾ J ù¾4պɂQü¡—… ´ào^_K¼¨E•W—Ë¢üwqu¥œRà º¡|-F`pÉœLw`DÎ8²ãê9È×r¶‘ƒ¶4ø†îÓÐÕî÷¨ýÌ2¶­¦»î¾åý3ÏúCt³l]G/Û§nyCÓ†ê¦3nCó-rîܹé‡~øõüàý‘ù¾Èc< ³)N% §œÏ¶þÌ¥•6ÐÎæy€«8"¹®òפfž('çΕ%E·µy]¹^½\K»óÎxi™Öµ^ VÌK5Â5±O›á‘ l¡¯v¢3‚y$[¿´VÄ%°jìDºÛ R°z˜£¾€i€—6À7xÑ5ArDc!E¨6‘¡Sz‰_W¨«è;Gë…VCpHØ%KQa?ãi½ÿ?þ-.—Ë/” ºò_Ô—ô–õ©ä«ºè_;vLŸM>¬6ñÄFqZ÷×ëlTðBÏ<ÃkU1H©ëØpÀÏ}q"ùa$Ù©u܆å2̶»_Yn«¸mM¢gYCtœüÔ¾‡\–5ÍžõMRxôoÔþ¡§5!‡´ ðë%úQmÌ0EÄYèƒæ­?KEi¥%íhØ 0ª,k0šV€:¤@uçÂ\™ÒLÀì‚Öèþõ9=!pøîûÊñ“·kàl,²“´¾‰ù¥?\%Ò™A"§ A\Ï0@Š@Ràt‚ÐMïwAŸx ‡ßîryZaf#aèìvÁ_Œ2€ëûËL7ù¡ï¼Ÿ@Š$ ©˜âË® õfûk|µ×÷vUÿ‘À’¦ù/_¼TΟ;[–´–bUŸSRµ0­ :ùôˆ¾© †ï°7®8!3‡ïÀD€ÎAeˆï ž¯ê‘³ ·i>Ë—¹ À©Ç©Ïg¶ NîOTaÝiÈAýi·ê‘oû½mÄ@ÆÀ¤€«åeiFÓÿDë5î÷ka×áÃGˇ—Êáùå2£5Ëg_*Ÿ{ª\8õ`9rßkô¥;Í (¨Ý2Зo4*98÷`-»ñz|!«KݸEäÙÿ±k#Xpa¼qµ½AÇPwnš!vT°Ç0IÑ~-–íá*—ûqE¾¡ýS¢Axç7í`w2]Â%¸ª/ÿÍ_/øÏ½ôr9÷ââ™ÿÙ;î-3zíë²|9­ÍjædJ÷þ§µð~SqŽ 1¶ÓÌ:PRÏ4›QÇ|[t¨ÃãÜ0ͲZÔÁmÛô:0ZÏm³žéÖ·¼¡ùCÐmײ¶eºnú´¬!2§Î>ºMó€ÆÍ³ïÌ3´M˹œŸŸŸ¹çž{Ô›Òk‚Ï@ÒÆÍÆŽ7¡oœ¬Ppi À>øm×·à `1M­`Ç å2¥{Õ—ôLòÂ_(S‡xÎ$@ŸýÕ`HI`Sº‡==»ZŽéüÕóŸ+—Ï>W^œ¹­Ì¾æ¡rìîSåÄm·•c’ÑT7ÃÓÔÐÉÖÑH6 D$—O5qMñ=u.òcAZVâ*Yô(vQX•¾À3’÷rëâ¢Ç{ûIvèKØõã{ê³f:ûj\lLn Èéú_‹ù˜¹t©\Ô3ýç^|¾Ì]:»¶2;U§ø$ðj9®`?ƒ¯IhO{¢tª<ó-÷>ø@¹ûõ¯/³ñ¸% Iè– ƒ`‘ŒqŽ_º*ÖÁ”eÌëÌw6Á‡ ú`ðsÜö3Žœûi¾u¹ gYè¹oYn;ø([ôi³’eŒ¢ î¿™L·]h>æ×ýîÍz¶ }ii‰Û_&Ú'µñgÇ:€¡Y€ÍwHŠ¥à¨VššFx`•€ÂÇhü½ÌŠ^úsUŸ(½ðé'ËÙ¢,éÊõĽ÷”û^soY•,W¾-’€U®Lû‹>¯ç×//Í•««senõj¹ð“eî ¥\8r[™9u9¢u$GŽ‹õ³J(Ö¸E  WÚÄ9ÅU™íÊú”>=ëC­@ð»K~Ñ&0whw z¨µœc° éN¾3D(¸ƒ§DˆýâF´¨>Ä[!ã¶0HÓ+qwQ÷õæ¯(èëE>z“Û…Ó/—Å+ ú2›’ŸEùjõÈåèíw(ÒZ íVÜÀдǚLi¦„1ýó}¼|êß¼PßsOyP߉à-o)wÉëtëåx Ep\e†p?}¨ä`C0¡¾²ÍzØpPƒî6àç %ó;Jg˸¡í»n⾃›îâvêú¬e6ƒµMlÙžûcšéÙ&´œ dÙ,_·cÈ(˜Öm€GDã$a 'ò¸­s˜„rÁY­44È $ 2\EÎôU"ø ®Î+x?û\9÷Ô§Êé¿úx™½z¥,kß¼‚Ì’‚ââ…Ãå.®µHe}tŒ§géKf3åèʱ² ­¸CÁqau^ ãKŸ)ó/êÙf)­;UfïÔvBÉÀmÇË ]åÎèÃCL…âå3¼aNýc–€ÀË¢Bµ#bìƒ"²Ú–!ãKtFRV”0<ôöGË_öÖrß›ÞXŽœ<¹ž °Ï^Hæ âÀ»È^Æ~«pÂF>´<#@y6yÛƒç-ϸ Û·¬¡íÔrÔ)ÈQlÃõ Žø¡–7Ü̆û1Ê~¦×8ºCíЦelu;¦ÉB£dêØX\\œ9uêÔ—ªªU¢ñgGÀŸ§©7¡­Ø-°'<°`@Ѩ²q?¿þ+—/—+Ï>S^ùë'ÊùOþµôÍëñ¾+ºz×Õ/A8nµPí¹rõ¸V©>¤'4¸1Ê£«\ÁOw«Û£é ÿ˜ÖÜ® dzíKzwÀ½­.ȶà’l½t¶,ª[—Ô¯ ¾«G5KpâN%Çc‘áaµuHAï°Þ30­u³ºíÀ"*žÁ'¸2o ‘1‚iØHì+=DÙõnx„&jô50x"ª_ì…b|ÌF,«N0^ÑÛçõéãù¹Å²´p¥,(1š¿¢­)}^ Ü™V¥;ºÊçÑÆeá«J`–fŽ”CÚÃ3GµôuZ×÷òÚŠ¨äÌ ¨c3J„æ.\*SgÏvY][Ô/Ìká÷¥•òÌŸ~¤¼ôÑ¿*,—xÍ#ÄìÀ}i9~—üÖS©D2Ìšý%˜–<6?¶ç o@Ëdhº!¼\¨Ó›‹ejXó‡t,SCö©.Y¿æåºûÍýÍ´Q²–·¬¡Ûu½–³=øÞ,ƒ®i@Ûêu¦Ž?~ŸpbÁ§ÖÁZÞTSx KKäao;­‘¤Ð48Æ@ÒÂý‹Ÿýl9¯ûœùä§Ê¡%7´E]Ùv ü4¦H7Æ -` T$®òÏ)Y8ÉGjtU ]Z¼GœÓH¤´]>³ ·éŠ·LmU³êÌh[ÔFB°<¯újYXS–Õ‡óËÒYV8­•+ ¤jR3š*?¢÷ 9/ÉáE9S¢‘LÉ>/͙֕ô ‹ú5CôŸþô»¬¾ÈE@»"Ã\¯¨íeõŸ+û%ùa…+{%A«šÁ˜S _Y¼´P›] '!:¬™ Eü°¥‡ØuÅ?}¤¬)ñQ§ôŸ…}4Émí ÏÿkÄ”’˜èÃò‚z¨aF‰‡ú#ÊAVË™Ï?WNÊÆQ¾¸¨úô´2u€$aI3õ*æ5Ýžøüü‹rö¯?·dN½ñ å~Ý&¸ÿ‘·”“ºU“bóÐï^Fã 2`ÔLtÐwà d= y¸4óÑ÷–yà.YÞ4 zÛ)CzîkmÏô!Ó€–«õ³ ¼,Ï|ë¹>Šg:0'fè[×¶Ô–N-¬é‚¿¯þ9mHØÀ[©<ЀÊ!­º= „à@5ÛâÙ3åÂgž.çŸÔ•þO–C+ p—¯ê \² *ÜÏgMQ\dzê]:‚"ð„·„2=}ùÙçà—é­iÚ{USà+šê_Ó#mØ8¦)ý˜¶W`e8ŠEtšˆ…nÅ©#市5wÞ Š+«K ÀšJ×cy‹$ÜG×U÷ÂÚ’fŒ•€ ,/\(Ëóçãé=ty1ïD]¡jH@ ¢ÚHxÄHA.®Õã¾>]ÙÀ¢»ë#©R‰¢ô¢ÕW§ôH#Ûò¦l©?‚Sžüß)'¸¿<øö·—{~¸œ¼ÿ~ÍJp<úbœó‚þs1ÍÉõ,“y™n»èåzTô3dϼqÐvk™ºÿ5?×-k["ç>gQtûѲÖ5´^½¿æ3N_j›¶á6$Ã'"9©èLÐÉØ ·žÔ@KÚ9°¿=À@¢=d!JÄ»ùç_y¥\ÐýüóšÞ¿øôÓevy±\½¢ O@Öô4«èYíNxšÒÕ)w¿5"a „šP©…¶"¹ËÏ=×]më šÕÿµÄÒ=t]Ñ®éþ?}è†!®tÉ t5IЬ ‹ÝfE›Rðœ™=Ö]ùHp‰†uË`YSî‹Âã֮йZ_€Î•:}Õ•ôŠÚ$Wé2ÝP]mp/î¯)y’,8vCIˆ¢´÷®9cw‘d¨/PW{È£¹ª+ø%é`cU3S ¨‡¦5«¡Ë{yRûBR€lç+ ÖèÖX@H‰n…œ’—¹+Êbô`ŸT[Ë:6S/Óµrìö“š)èf)èD—NèXÉ?ÓáGÙ•±)Í¢ ÏñfÁE½R¸è½ s—ô†Ægž)OÑm˜Sw•ÞþX¹÷ËÞ\îxíñOóÓ§x¢@ú~ÔÓAhTЊs Eð¡ 6ijlæS³íŽsí/ülçZîæµÚ¾ë†Xe?˸¿øÑ¥öthCö¬o™¬‰»&hñsðçTÚÐ4½;ù’­ƒ†¶à ñ°¿L§kt‰& ö™1ÿòËå쓟ÒÊý¿*óZůH£ûÇ ¦ŠŠq%¨ûÐÓºA½Â´2…a‚(­eꨨu‚!¬k¦èŃCœ^SPžVžR?H"P[[Sr±|{| ¹³ê㊦±gi±›®d™¢‡×] *It…«~ÖN‘–p/^ö—5°¢`©EPºZfª^÷æ4W"!ЇtÔ>IÀšxqïÀ*<¯_Œ‰£ªåŒ"‘TP¥?ðº-ìõLþš¶iûe¹³ºº_%àéÒ›`ß=‚Ȥ¿ìxVCYN Ö’í]¨>ÌÄóZì´5õ{åê%­¥Ðç~©+‹Y•Ý5-@$À#Cªˆ© /‚ÜÖùçSH¨¦uÜØWæTàp–Ÿ,ÿ¬^Ñ+†Ù¾ðùòìéé­­xícï(÷=òeåŽ_WféNÝFqÂ×µìhÊAÌr¦)™OÝÁÊ< e”~–ï$¯ý…O¹_›é\k¡«eý!¾mz†d  ñ‡hØó–mešûä¶ ³v£F jð$ ŒN$’$SÝk\n¯—"ýÓŒ âѾUµ?Í 7u™ÀÍKnh­¸M!³äìÉ9ø¡Àk„§u¤F©lê©-,$p/ë6A$ º}@r `Çët_Ö½÷ÕÕEášúŽhM ìÐWÍ~,ë¾;á^-¾…KNL’4Æ:öO|ÔÉK"H Ò_ök…ùÿ^FÖqd8t} b»¯cß–˜)‘ŸVõhd¨É.k¦å¡êŸÚ•¯aRÇgØáÈ«{§/Ñ‚ ©¯ZFž™A@”Äçªé¹ËzÜ¥òÜ+¿_¾ø‘?·>ð¶w”{u«á®‡*3ǵ¾¢¿¢å*”' (]û‚êƒûèýtË<ã†a¨ÿ±|¦Û^S÷톬 îzÖE~¨XžåkÚMd¡[Çв®[.ۯۀ悎7·‘å-—¡ø’Ͷ¬ràñ–øSàu@?@ìãï>þöµ/ vWôRž3O=YÎüÇ¿,+gÎè¾ñe=¯+[{ÃéGWÜ — 2ÃH¤…½ªŠÈ-c‰½#»"~ÜÃg¼AT?\SÏb#A´ :¼Ô†ëÐ¥•«âkÁžt¹*æ‚–ÀÛ% l@7B2½ Y˜ÑP„lùx­à4™ Y-úÃŒÖ2ý>Å=r®ÔµsË<ÞÈìÀê1=اi|º%m­³ÓU6· º: °¿Zãsk#ZŽJ$º"§ÿà\ñ»w$'$¶DRÂL|`Ì$Ò_uH6I7hS÷ÿˆéW·ß"°3*èa) R‘-í ú IoKŽþ/¦zuí;M!3Ý Q瓼ÐÌBLÿ¯ËSïm`(vñZEkðÍ ôæøê$È÷2ÂèñÆ €Žmô™h,ZF†„¨ëK˜’….ȱHD‚ žt9O¸MÒQ»' –´ˆsUO…,äÏÊùLëC•SZ¤S˸>ʆù@÷Õ4ïƒuëºå¬ë:rµ-l˜f;†Öw;®g¾m×2=#ÊF©aGíèqäM8ˆ°%[<êù„Û¢jŸÀëä ”ŒÀ*<ÏNYÑ÷á/<ó¬ò=Y^ùØ_–Y½”gA÷o°Y=ÏԾ添ÁœÚ™öÙ¿ý.:‡ÝøÑ€ÔþŽ­Ñ©ãõ@(^Ž[â!‹«ã%l(pÒUï oÍ#€Ðñ×â6LÏk¡žîÁ:¤'˜Íqa ™cRœ@‡aL̲样ª`&óêG´»ºÑ÷§âj[}‰~I†8ÈÔ~LåýdS$]ñÓ9ŠüÇ-BþtWÈ Ü¨ÎâRÆfgE@ûÈBEÚeJŸv°B$ÈK,nôm,Ó!í‹í q{bY‹òŠž XÖÅYžÄ 5ˆmšÄ?¸‘Ä &s1£3„» é«úX7!F—( Óùƒ½\‘Ñ™˜ù@•¤AÖÄÇ3rvyM>–eµ§¾h-c–+ åüÅ'Êüg?S>wøH9úàýå¾G+wéÅC'îчŒR2ç46å_èëç8¶é“Ûë!m×ÅãŽeGñ¡[†$x'ÅmÚÆfu·‹|- ™èY:õšfºíd¾ñö²B—ŒC«ë–;°°%öÐï¡g ;‚ú –”eMåóŒþ]u½ü±¿*‡t½¨+Åø p@ó¸lµ°‡®, œÂ´ xà@Rã¾dÔ.j°ƒ®Áž€¥‚| ´%;kñøòÂÅ$˜-3ÞŠMk‡$KG·#«´Í¯Þ 0¥Y€5:­(C®À=x…Éë šˆ§àÔ›CIA0”¨ÔžúKpŠGù\š%€O›ê³]à"˜ “,±Ÿ}‹àû$&Ù7Õ)Ý~°oâÉ:ÈÓβ¯NYOà Ù™Ì.`‘[‚‰L´ÞÙ¡?¸‘ kŠâKz±Ð*/ÒK„ rgiŸEò„§ðYˆí«Ái%qqoÛôYz$K!£:IÉLÜçTÓq\é¹"vqÐZ(uþ'Qu,\'¡Nž° Fœ7:ÿæôTïy˜¿p±,|ö™òy½ˆéfî~ôíåÔ›¿´ÜöÚµ`“Ç#7f½nߺd|ˆæ€/ËfzÆmãzCú2ª]÷3fåäÐCÆrÙŽi9™ñ-—ìä’^wP»oe„Z0Â1|=Àt¦¼Ì©3c€=Þ¹ñХϲOWèˆ`§/"tU‚¯ 2^¡¶QðÖ¾ÈÉÂzÛâÅŒ€t(ܶÀÓæ¼øgY/NŠ~H7‚±øra×o‰Ñ•°E?¥Ρc✾umásáÚø1®ÝÔŽ.ùþ¬‹¾ðä'·W03•HW„³^"êú¡ïqŒä¯))â‡9uhU;š¹x¥,}ñ‹å¥?Ö1>yG¹çmºMðez ჯÏF§@OÄ‹ 8¸*†]ÃÝo–ÏtÇL»‘xݯº?®[ŽúÐþÑç,“÷ÁôLc%'YSIÖ¸aˆ&þG[pàOè 13TAYAÿÌgôÿòcåÜ'Ÿ(³|LFo~ãµ´‰)=+?¥çëÕ»Wݸº×Ÿ6žWõ\Êñ403@³(ò] N‡ºì†ÁþªžD˜Âgàïþ ¸¶$šõA•ft ‚©ô)®&{Y¦¨;Ý.Èó:^^©;¥«Ý©#<Þ¦PD›úß]'ªÛñ”0(¸0•y‹v$¥äÙ5vž1 *E€†,ýå¥@¸ óqï_TzÏ{üyg³á_Ýfé,©­ÞO¶sï²Ƀl£/s‘ H;1íL¬ß:Pû¾ÇÞï\%bg' hߢµò_Óêø/n!(“a÷Q¡°›Ýò:-êä¸S'¢ãkýc"ÿàvö!ÎÉÐÏ.A _"@CÎçÓ\Á)CƒTÕÃ"JãÔ%’‹ %Ý}­Q|tµÍ‘…]™Ó Œ®”—ô(êé?ý“¢ÏB–S, |ó#z¢àKÊŒ^]£À³(uCÓ¨×4ëÝè¶Ý–ë¹Æ-DnˆnpÅmBÛL™¾èµ‚ZÐ΃ëë‚‚Zà37Zë®y=¢wæSO•³ŸøD<«ß½˜g.î%wÏè+8²r ‹ d ¸üéF4ìÿ iÄîZ‘é¹û:A‹ÖÀu•ÛÉ0øh¡¦˜nï ìÂbŸdÅ‹{Ò=V¿Ëp×~4 š,«/ñV:š¾¤ŸH_SzûŸZ×Óx ê´…LLl ¯GÞôià)=HH ʪ~è?øŒv{…÷éSNá?ÕUèŽ`?"XË\­CÇ5$<âZvº¨Û{¼÷Û‰v RðV—x…®ôu›¡Ñ?‘ǹÂí<¤v…°öŸ"‘NÈR7õ¯>AÇ'„Éxc WÇâ#N÷‰Ìñí-Ü\ÓG„ø2 vTÿya¯îºòà1…¾u·´»ÑgŽ4·PXEºô“Ä€`?ØÑ#ñ¢DB(ª"°ñ!mbŸd&³F÷#‹=®cçX—}ôtqIN©é\ZÄÚœ^c¬GWΜ.çÿ3Û#åîÇÞ¦G ßZN¾þ åð‰×$$tÑe7ÝyÇñŽèÐw­GúÓ€–Ëü‰»/´™û“éî£!²ϲðrA.ßȼÇAµ“êú€ÚÁ#µààó²ÇñǬ?T_éóÍ6÷ò+ ú¬Üÿx¹ø™§Ë´ÞÆ7§éý%˜x£œ–Ä3¤Æ*j挺±Óÿ=·ü—CµF{¦Œ,#F¢Röâ€`ô>è¯ö'(·ãq¸0Š2¡L…ÈH”„ÏÕt¿=®TUãÁ1V²/‹°¢¶–ø¹²Uéa¦Ùg1 B³šÆ§;CæVµô#½ŸÕB2’ á*PvV · ¨xùæ¯ñÜ@K¢ÚÓ?8÷ßÕýLX¢×qõ.~åª[Q¿k€!k+¼€G/š"QcË <+ÚxþôeÃâ·û‘›ð!­u|ö›>’PÀ»ï‡qfv._Ô”ùE|é«NÀåM}(á×xAõ¾D*Á¾aM?׉8šj¬ó¾@®;¢(ЄŽýQϘ6èΫ`…^ȇ?º¾ðhj(ÚC³+ÝOÐCΙ¨Kûœ¯q{€ã³ÂC¢Hé]ª/jáÚÚ|9ýïþ¸œÿQ”xÝýÈ[õxá[µˆðárøöî]´…ïpÀ‹¿+cʵ~ÙœDwCzk˜Û¤ ·cÚ¥š—õ¬o=êÈšÞàÎ=Ѐû°Y¨<°þ‡ÊÀ©mNS ¯<ùI-âûËråé§Ë ŸÕc|š€Ö3ß 8Z7KÀPÀa°!-a5"p· 4«9ý•)­þ×›û¦¸dFhfþ|Qþ ½i- £$%L§ÇTs ~’—ú(DJW~Õ½ÿ.¸2àÒ?…6big•è2a,ë+AKákYGö\$®öõþ|EýXc±¢gÞãJ^û ¿ ïÝk{±+)m„|®ú±GF:’U‚²ÂëÕ—è—d9~ì#òËrÔâå „z •üÉ’ ãgìGŸ9pEº+26BN²d:G²`%LoBI¿U²Ø2ptnè7ÎרáGžÆTB¹ÈÂLí¸’WÐA“7ÑSŽsÌÑí]ØîxN¢T¥ÃÌŒé‹úvŠR2væÏÿ¬\â]ºÝuê‘G˽*Ð× èÅC~”0,pîõ¥;']†u E*Ó&±1l¹÷Ljc~ï$³ýº½l d ­7Ξe¬‡½Ü¶ªê«ëµý†ZÐN„]õ€ÿ˜çuOÿe½”ç´^Á{é©§ôš5}ÍNW»ñ”7W™< ¯+#Eµ¯ÇÐÎü©2âN$#ÌP®àõW‰È#ÜMå+p+¸A‰ÑØ— … aDI 4ï.”@ÊÖY œC½íúC;A…¯‡]MA+¼N‚+åE D@#Àv³¬agÿô½?퉮‹ãvDÄG t´æát§ôµ\^ãÇq'Ì1« ¨iúÖMmÓêÚâ­‚ÚOîÃÇ €Öxm¯‚ZÑWò˜ö÷úì¬D] }[ÑìĪ µÕ…‹•ÖfËM¼*9vHvõh#‡„¨®vþô#D@Œ†>8"K²Æì@ð9¬àœ+ú +þcÕtaÖ‚£ˆã–ͪ_)ì?OP?ŽÖÂáÒuº£Xø'6¥;ªTDÃn¿M“ˆ…CÕ ÈA×܃nOD ¡NRH3Ý~9^ê‹:ö%ozļðîÜA‘ªZ¦AdÀAùúê$4‚eùzßèý§¼\Ö ŸO|éÃåu_÷õåÁw<¦6C«ë[´ ;=­¯ŽžYÈ4 ¶¶cÏ66Ó­ùÖ3¤_ÈPÏ4÷×ú[™ ±nƒÃh À°_u;èÿx¹âÿþÁÿXæžy¦LŸ¼­ÕsÑ·Ýug âÜË]æž3&è Ä ’¾Úí„xýÀ†ÅÁÐô¸Ì•þ´bBAétC9Éšpú·§­ò\·t¡vÓµh©¦ÿñ½.ÊFSV48ØCLTýI„¸Õ ›Ö„{‚%uˆàÇ5>8„lÎêA‡gÄþŠö{FïÝŸÑŽi}cô{IAzmNoß?¬Mö§õ)]ÖÀŒ•âB þ àìû *XÄšµÉ=ûU½P‡+íe%\Ô3åN §Ï<‡O"‚iV „Ž4öOW©++•8hôEÂ5ufM·fâv3ÈhHæ¢}µ -ATg#‡S=r;íGÜ"YЭ‡E-êÔ{X¼Éú=‚¿ö(úzôY>Ô‹EEWû¬ê]ACŒÈtæ8KÀ7yÞ! œ™”î(svE+huþÒyÀ«#¢È~,Þä¼Àæ‘Õ~Æ«ákßðmD-ìwrR »(錞íB§õ®÷ƒ/Z÷&FííèsÏ4ª^•+ZœùÒùóåôçž-þõ¿,G~¬ü÷ÿ×Ï”‡}T}–4ë‹Ï×w±5Î^œïc¨ukùÍø˜®ursµ~]ϲ ŸÌ-˜ÌOMj08ñ¼óŠö}ùgž,OΟ)§Ï.•KÏ.gî{°ÜþšûËqÝß<¢Çßxmw|Š–Vƒp?¤ÆPÙ p„ðnئi0~× ¨Ú‹çÍ!2àk#…˜ê¤ÎhK ž«—,WŸa½Wë¸ Öˆ¹Öµß½ëœvæY´Å­ 6´¡ÅÆ"@‚ëx}Vr|¡—Íj6€'xdP!Qý×U»n R’4{T·Fô ùôa}•Nrš¨¨(Éî„}Ú ŠË+|î—«|mñE@]õãn%(œ‡_¦±Z_b€`OاOh܇—TîS¯ò¹a]sK€/ò%@¢3_ YÙg yEj¼Èž’dÅâA=¹¨™žUlÑùøÀú:ö\Ñã¾$HbÀzni,«Cø£Kä$=,sÌèœî‹‹6­}œVŸ’n|ðGá Œ¬ $œv/ê‚·öRŠ %<@•]ŽR´ÆŽÐ7‰F3½£W8ÏØ‡XQ… Õvj]a´JÐôË9Æt»dfgdIÙÒÜÕ‹åÌ™såÜ _(Wν½=ªÏ/ž?[Î?ÿByÖ„'À„e\@ÐĺØVn–êGœ7ø³/ÈdÓ£ô³üL¶1ïíæ~'·`¿á›°GŽ+oºóîrû…#å졹òÂâ¹òòé§Ë¥—Ÿ.çß[ŽÞÿ fî*ÇŽŸè>…Ë ¨?Ãõg{5šú>i ×1Þ¥BÃ`—tWy\QÅÕ©†L®õbäÄ TB+™®Ž;l)ôhŒi"êü"Dq!‰J,d£¨>Ó\¦ÿŸ½7o³ã¸ñ5óœÚ‹«HmV·ýô÷ÿ:÷™éçÞ¶§Û¶$RÜwÖ6ïûC Ïa5¥¶4U²-f'#È, ¶Œ|¯ó!g‚X;Ãùïâ”Ñ{`Ð.ŽÔQ¾NaG¨ã·3²ƒÕÏ»þ~Âè}‡Ñøg¾ÍçHY£§ÃV7éxH…Y;ùÀžÝ/*Š£~|df¨(Ovºì8CQ³àÑ@ÁÈl]÷\pz¡ï÷ËÕ…“ >|Fç¥7J϶žØr_rÛ¦S_5´=:{ë)#²;kbçÍY OqÌi¨hñ¾ë–C5Ê·S jùþ¡rˆÎ*¹aÏ©7`êÈ]¹ˆó‡÷Å™"Ÿ¥ K›m‹¼T€ÙË!˜±\+[ÁQU¨÷À$Í™‹ "@HûLZGxš >BC}Pôž½0ÏYyô݃éé_ÿ”/7úêâÞÍ;ÓîñmfŒv§#Þ8ºsKÂSØvŠ]¡a­ß†ÿÒøçÒiþ—ùmÃ}–·óÛ<¶áM£a7|‰ÿv ,€¿]W æÿ þC\ñ~ó Îá{tãæôÕáÍék¾xÝë»÷§ÇÿñÃô›Ýv¿þÃt㋯¦CgاqÇDÎÎ_éôïÆ&—žVXV\™bbŒª£ÏбòV(·&}ÈAÀÒ¢£Ó‘E é@˜Ê¯"Ê…ê²È¿8œ‰firÇš~@7´µ8vfEô.g2j­ d:Ýu^w;¡nÞ€8cìŒÌ9s–´<è@ÏO»gbŧûÜe_n\A)äíCÐùÒRœœ4e:tù ?±Ý:`´U•RsvÓHev¿:‹O$­ó¯ Q†‡:çÆ3GíŒ\}ûá”ÿ9ç\°‘ðœöÆ¡»oÞŒ|.ðÞ9Åevtþ™ƒç&ºÁO‰Ä•»gxëí„X’£z9­ç˜óî•S'¿žÓø®Û»×ÂVXO Y/ÝiÐ.GÞ⫳_³ž+aýæHêF¦âJèùÀIYçÄÿrX$Ôg–gÄnˆK½Â,ÝS:kï^¿=ùazúí_¦@Ù˜ñ9¼ýU^ Ý?`3È;®ßöxšÔ7÷o{ ¼ÿæ‚ô‘ËåòËy«l;Úø(èÇèüZÍàc4»l;¾Œw9¿»¤ZKà§õ³”þ ¬nÞ˜.X¿öuµs6fíâx>?<œ>èýþäöôèý›éÁû§Óf^~ÏÌÀÑÓÞ×_O·>»?íÆV_Ãi@«IÐ;’Œ#N¢jÇâ•sÓÔ(KaG¡è`À5ì:ò ŠLM~›§†^ª‰‹yá€+mw£_8$7ñÆ÷pRdב ÿücsª~7ïÛÓÀ™»âÉf§ÀwV{9IPÇ|é ÐIRVeF´89ß(×\ræÊÅ¿ÎAl[IÛÉPg¸TäÈh¬£ï_]RèBYœ/Óõ©/=ò²'a§©–9XÆÈ¡ÿŒþ!’M‡àxŸ¬—:P³“á Û }¾PGøª'%³½Ð§\Ÿû% êgy…Ó Þ;î/ðl«ÄÑRîýUru+Ügâü‘×çÅŽ„ÞNHç¥^  NœˆuíÐosV~$ܲØ@Ëð?‚‚úSŠ•#0ï™+¼ûžÑþóéÙÃÓã¿þ‰ ‘î…á¹8¾É²Øíi×c„y6ÂÒ èœ0“â²ÚÁÍ›Áµ#>r¤î¶Ãm8E?+\®·Móçº,O×½Lïr¾ñ.˱ÿ±:]w‰™–À/ÓÛRë#(3HÁñ1£BF¬°Lc´t"ã[t níßž¾>»1=gûÁÛÓƒ“‡Ó“?úãqüòÓÑ_°WàδÏÛ;z>þÇ1hÚuÜ2â§+‰AÆÐ ÒºkƒEÐìë8FÖÒ8D·hÍ ‚T,—ˆ„Ð%–ž89 FÐɈ¤ÑvÓß>íÖhŸàŒºÍ˜pþ•ÊÌNo‡Ít;8:¹wq,Žv×\NY*ØÅèï"‡¾Ö“OÙ^ÔÈH5í€)ŽTCI¹]›Ñõwùg„Ÿs6 :s%xªG? ä™ÁÍ› Σ0o™?yQÁ{Z³'à2Šu&à^ùÓfñÎX×ÈëznÔÍRQ‡ï5‡'éü¥çìÄ•ÃSýâš««ÜàÎbx/é> ‹5[&WÓ!mõ‘°®ºT'ˆŽàFY9|`À!œº{âÖ=ô^åF¥³R_‚êĺü¬œ˜d`¡¯Ì´È6(<\ä#Båi÷Óý–¹,ñúõëéÉÖö¿ÿvzñè»*çõ×ý»÷¦½ƒ›¼ »=¥‚25kÚ9•„"9Ó²ÇßÔǶ“üXù/ý­4ý;ÙÆ½œoÞÓN¼ó–7¬q—ø×ÕÀÒøuõý›æÖØk¿w¯‹y‰!‹aã¢ÝÃÚ~y´3}Æ8ÿzz{zÌ@ߟ°úð?¦WÌ ¼:¼Ï¬À7Ó­Ï?›öé^1²ØT㼦‚^Á4&õ‹7Æ8cC±ó\ð\á[ÆZ9H¯<×1\+0/A¯ ²q1ö‡7Œ¤¯¡æërï0èïòšYÁJÇIQæt9/AV§¼:¡Ò.CNÏ6p€#äõW}ýC:TŒÑ} ­är–Cçî”:âàxì ¨§Ñkw?yèâŸChg•óJ²ê¸CÃÙ· Rq}[íê'èGµ¥ÎÂŽj æí:©C|± ¦ä¦é4xsœö§vü­È„ì Hlª¦L**wä~4[ø?uÄïÞ;QÞ…Q|š˜Šr– †‘öÁðYõ¾‰ï­~IÊ)Y^|$Ô÷X™Ò£Èzâ’DXZ0èIÓý¯øDõãíÿùÿÞ²±Ó°sãéü;Œøx¦ËüúC^+ŒÄÈkcê)1ÁCöËj™,É¿û¥ÿÞ[Ëù†wl¹úêXøvºñ¶ãºÞSµº„«ÖÀÒ¸j.ô2í«u¬w·Uˆ&R£KÌÿ ´HøÕ; Ú-Fúþ¾:u¯€Ëo¦G§¦'z4=þ#»à¿úýt8fýŠÞNo¡ÑÖ©ÅŒk,¡Ÿé}Ù ‹c''ªx$5ÞƒhXZ ²qË"Cä aàUG:ÇÑ8Ú“–é4ÜnÓ;L§c‡“zÅ”wœäìÂX®St==Ÿ¼…\¦­qÒç®óSæ”|f¨³C;(Ge¹A7î…zqBèÔm#,Qô<³Äõ%;bõFA^«FéÀQ¨NÛŽC¦±i˜&Ä Í¤­‹wvvÁÅ÷3>8·çƒ%q›Ýyü©)=âW©$;**­6êžáY7„¶RN±3êÃßú=¾}þ#NaøKÀ3ò§®(Ñ™¬’æùƒ“a³Vo‡aÀQWÊ‘OüH]*„´ XÏú5/mÒ5âÅ¿}ûfzÊŽöŸ=ø í€ïyîÞùŒ)~œ>GïáÐ î)銸*¨Té-ŒQ†Nr=: °K»¬ÿÏl‹¡ãËéŽKw¶a¦»Sp¾MórÙ’ÿ¸–ÀÇõ²@‰úÛÏŸÖ*°üÁjÕ·‚fÀQ™Ð8)‡¹ã½›ÓçL‹¾>»3=Ę>ïøz!36î%P’t«ÖÿÍÑ6fÎù;ŒÏÞdÔ±{ï]J€$|á‚Øº½ªX– Àsú?BFŽBÈ&RGý¦÷xXöÙd¸ð{Þ”,‡8pÊuêv&¡¬~ƒÆ… •Ååƒ]“å§œ´7}YCQ;´óàÔÉL å#ŠGý>ñbzú˜gõÛÿâu>O8D‹8ü}vòï±ÿÅ ¢»Þ7eWßÈâÛåM šêÈŸ_0Sàk£Á1æž[–¿)ËÃaÛ¡o·wþnþ¯Ò´¥ð3Õ¼<|ƒÂر¼s›ƒ‘f÷ǪàDAÙÐÀ逜²×‘ÞZïO7-}svszÊŒÀCïNOÿÄÏ!©{îÁëQw¦CÖSmFœžÎoÅk4<Ü…«ö8ÆPұŠÓú’QP”Q&glnhÏ…z±|&t0†]øºÁ.ëÿHÄbHÖwuòopÚïi¥ï¸;ͯý稟´_cïëvž¸osô/;ß)àßà;h\ëØÉ;âÔŸ´_‘Fq¦ïÁqÓ]¦á)TvHNœ=±=”¹9ðüŒ ›Òôd:xùxþ¬uÎ ©ºLáãÍ/˜qš ú0È‚›µ>íuœ‡¯Þ!î'}õdjvñ¡æ¼'v'¼óÖ¬®›ÎôI ¤Óÿ}CðöÍó³ªzWDõJÂÈ ógÚË Î¾¨á) ´ÒêÃR;{Ê)BÖñÇ,ÈÎAàD¦·o_OÏø’á“ïy…ïÁfÖÂNÄÎ _ốѾ{9ò "ô.ÜÇás‰p%¹qubB2½ePz\ùðÙiïè(οàuÍóàí;¿séæ÷shÿ’:Ûô»»­«K/€«ÓåBixJw-¯îÝÅ0»ILËWGÅ{¬q‹¥Y?Ô"†Å:Ã#§¯ŽnM_0+ð1çá3 °Ë›{¼‰Óµ ãˆÕ³ß ë"ù¯9Ž6#Why"`Í €§\Ê ;ÚwIÀ©}ݪþê”Fdä­¼¢Æ‰éìŸSÇàҳЙÀÓÛè ðP¡S…ŠôlêÀ$|(rO€x¿ÎqpÉâähNuàcé¨Où’ÇV…†6Žžú:z÷F¸¢p@Þ‘¿!÷è-9 Þ§{xØùW—N@ËÏ»Š8tš †P»ÏD„û#™Q;±y/›µCœ{F øÀ—Ç ',¾~ÍÕ¼ÎúÝ_¦7|Ð(Ú¡ºwˆãÏ3Ȧ>YøY;¹:(—´J«J¨ÌÆ\Ó;@ÏÖõ!´Ý·xC`,l;ùvŠGØ_áòKøYçr'àrþW}aqIKà’B–ìh@'…ÑÒÈÅÀšÐYu>ÀÊè\4vbhóˆt|ÚÀ8:ÔûãUÂlÌ«„o¦˜xî¬o¬¾úÃtȬÀ1¯!îóJÕÍêø-…ˆ‰¨Ù’+¶Ê#UyÁФ 3Î;Ë íIôÀ"u€Ž³ŽÓƒ ’¥_ñ;eø¼ƒ§óýþSêyBž_‡s~ÍÈ[’¼–/ÖÅ™!ïÃéK™ÞÇéc_Us¤§oõÕzT”œ=ýéH,C:~10÷žÙ˜‡ŒqìÙ¬è^û 6©×ø©.#{ÎýÍZ¿÷‘Õ™N^º0ðÉ(Þ< Î>bÒq  3é;k Ð‡¤ÕÇ@;9:Çݬó¯qø¹UéØ1ÚC&À…?ЬGÿ.¼g §¤ÕUušdIZÂØ21òAW¶¹ï]ø õû·§Ó‹O§§ùœï·JÍçhÍ+|;‡|Ê—é~¾{7<ÁÞWÞ*ÀóGÊ!bSMBKcuèr„÷Éîí°¿à'“o~ö9ÏúJãŒJï—qÃÿ× ÛŽü§dø˜¼ÊÙ÷r›NÃÍv|м–À§xׯ«ÍÃ@…<Ì—ž|ZeN˜?t ¦V4¢ >ùã7a(@¦¶u„ÂíJÇlªr¯À×9`ÈsƬo¼ã ‚7œ+°Ë¹7xÍêÀstüü22¦s¢ˆ¡’×f„¨‘N*b!ïÔn;Yó¡FŒ×À±y™õ ¼wkëP4èÙ7ÏHÖêºwü+—'þò>øéSçèé½ç'¸0\_|c ". øÁåñÇ¿è #zõ ¸Pfaktî1»*_œ"…Ÿñz`UÂÅÒ¹¤;øët>\¨àæ¾8qçÇŸ7 ,_÷[ä5D ü|GÁˆè¾˜Á1‚¼Ÿ=êª3Gô+.+øzܱoKä,àŽüs‚¢çIرDGÓê0›ùúFyOáÛkúéÀƒÿÑ•÷–âJõÀó^¦ Zj9a3~ýòíôô)R¿ý3£ý§u¿}=•Y©εØe™*›¡ :¤¥¯î œR—¿÷Ëöö ŽùÊí3c'Íû"žo{ØiõlŒLEk'Úq×ïøÇà]þÿ7¾ì¤¥w™çå¼8«'ÜÐøt¹þX:¿†–?!qˆ²{Ÿá›Nbì{‡wÔpXD œö¯7éùǯc‰nˬažÁ'«ƒÁÑÑòç;uÀпžñ*¡³œ6ø§ >ç\§8õ—¿Ÿî}>Ý೪{¼oÍ0«‘èÕ㤭óP¨$ër•ŒÓ€ø‹¤7ò"VBΧ'Õ>Eç ô\¿Ç醊Ð×ÈÑÀ; ñ}DýG¾ ÈéùÓÙÉš¥^ãÈÝ÷:>q™Ñ(Ç S”üËg')l0ŒåC3qÄü2Âw6@çRMÎA=`U“G§€:‘['ÏîþS=­Bå ³inž÷ÌŽK–FÏð—«÷Ö¿77(Æ.Í!4öaî+|éÐÁˆf¥S¬©÷5Ã{(ÇéAO?ê:ü.³%T÷Ê@IDATÞ1>–ŒžÀI~äÛ±„&¼ólÁ3nׯ £ÍªË2ÞKïÜfs'¹ùåxO9ž÷¯ð=cšÿÉ·ÿņLº8Ð\ïâøyŽŽØÉï7Ô í°jT„À>ÅGŠŸÏv=ûÊQPSH‚rXß–r¸ì£Æøg£8Aó˜c³ÿQÂ/qÒm®« ý \ýß2Ý¥ð[¾»‡¶ÍìlÎãMxFÎ:]¿76M¨‘4n#\.kƒ£‰ÞXSÒüOÌ\†—ÕøÞ 7pc÷ÖôUö ܾ·#Àí=ü#³ì`¯À¾#³;ì(Ï4·;²1¹:˜Ðl Ž×Xcµ³)X^„ÑÇÌèšî³èíW¸yÎ5`{ç¡Æ°ƒë_?yæ.7+ƒ»f¼C¼Ç>ú.é ¸!ïœãußï»/ØR¢ã’a;:"iÓ‚¼ wƒ·ê*mÀŒ‘b_°ÿ€lÁ©“N‰Á*8ã:¸‡´Œ™Ï¾@–ÿ ¨´|¯?•!æa6¡Ó†í ó.ûh,ªe¿ƒKð±Êš¥¯F¬Ž(cêíѕÊò™ðPeZ ºWõÇÒ 2èH%Ñl-¢^}L¥Œ´‡y®å†°GðÜfFøBs¯€½gmÿÉ“§Ó‹ïÿ:½xÊÇxD–ç1ûYöÙÔçÇ™ìUIÓÆ+®9,ò$:Ç:}H¸Ùφëüm–;ÚãèÙÈ ™ep3"MÈæG½µî6sü´~EG'Î’Ê«ÌÝã¨E†n¾nÈÇ‚TÇ ¹è#ðÁ#ôLçÌ.™~UùŒ÷‘)kìÈR£Ú yuÜ’¡·Ý¡ìWCEL'œÆÃhI‘ƒé}Fû;Ï{@'eè0›(©îó!OÔ~’Œ ðAÚX°Jø”Ùb€%xÒ}òŸ½ çL¼]~ÿá‚{}x£:sçºÉýFâ¾w¿‘æüS5céüSÝ®|a5\§q×ù»r„­®Ù3¡AÏ4>,Î^0ÖÓyƒ‘ƒ¾ÆwøÔ8œZ³-ƒ;ÛÖØTj¸à¤.¦[î[Ì üŽ“ŸðE½‡ïkVà±³ßÿqz}ƒÍUÌ qìðáÍc‹£O °þA3mIƈW™Êfƒ¡g2…uåÀ§uC†:·xèdí‘Æ#`“‡épüC´³€X¥(¢¾¢çÉú8î’ÍfŽÂ9/Àã9' Ô¼Êçy0â>Û…Žuí,NÝïþA™úP:O}ÄÔáÚ‘ðMµ‚]0“²rÔ<‡ùV…ûhWÍÖ P³µý@…ãFω͡—ÞiŒu|ZôbÜØ—ž”Ûý™áX¹ÃNÆšÙ½èšÌtX¸6ß¾‚÷ìê\˜j=)ºl¸I]|B"s$òŸvƒœç‹gòí¾ÂÇÚþ Îåùøûl`t—þîNÿhlꓟ(bå!o6*z‹Ùì ÈöµJ,e)×.ûXùÛ† é%é=¯ÇDð¥a"9ïƒ(Ü«»ÈClø­vÒ¸åòwÑï~ŽÚAýœ:ŸnJX²»wqÚ:ÝZ7ãŒÚ0o1z求1ué¢4‚¸)­¡f‚1\²IŠak•Prö¼£tf'ÀØû&q’«=øàø|Ï?|íLØa€ŸÎi:{(¬cÓÔôêyœE`m¨cô4HÓí©>A «ùãÇê ô9ž¢g 鋆?Øúq)¡‹ $†5sܦÁ€·ƒÐÛìI¸}óîô%Ç?gƒÕÃwo§‡§Ïy½ëÓ[fÞÜúbÚùò>Ft—óÚÙ…c ‡1×kZ™"(W öw(¨HÂGó*¦È |N×[n+R@EG¤ T0©£Ê¬ÀÀ­/è©¥ª’Î’8:Å´YŸ¬Ã8K $-+]ðæ™=ˆâµãÌVÄ5"'ö”!:ÙdÀ7x_¡™öæõCërèC=Oäx>»GܦN6Ä1@ ÞfànR‡Ø¶7_p=’Ùƒ™W½ÒXRå]óÎ>Õ²âÀÍwtﺿº5†ŠÌ¬Ã4YðÌâ8¥fãÓ^bŸ#ÿ©£}Žç}ö€ߣ?ç9syeÇê+|;|b‡ý n*Å·çYsy&ú‚a9©#jça| Ùr哯Ø>9ÊoÚ' y?…À=·öl§/bM·ê;©gÝŸþ=m;æþûú‰*?«¨iK×_–ˆ~…ùIKàénüdÑŠVŒ¤ýZœ£FŒÑ¡W‘–­Ó"ò#oÐxj–€ü°xæs° ±#,€±Nª9Ôv¡œÜLÊ­« nxk¬34ç˜Ù;¼ËgŠoL`¯Àïßò〡×§—ÿñpzÁ>‚—_ü~Ú¿oºq'Áé†%¬$eP§Fx|½*ÿõg´wŨßÑ\xùÂ×÷æ#µÝ`§£ˆÐäÓÒ Œ4Q9 âÀh@»¸äme¾&—-yfÒQ:CRŽÞ]npÔ>fd.pÔµx#¦²ž7ÃWÚ¡ãq“ =2GúndL£2›£#§ÜÞJ{Hp³J5QÁÏP'Ë"v ìÈÉCƒäʺð[3U¡,qš¬ixïm‡úMz»ÊMÞ¥ Çÿ>/Õ‰‚÷$øÀ\Ÿ?ç¦W¯_MÏ`†ç£ý7/¢/>&À4¿¯ð³üÂá=2‚¿³ï‚ú":ë‡M¬Ä>KH_“MÜÔB?·Ææ +“©ê¸&.-oÌQ!ÏjÝåtdìsʆÚv¸‹Cÿ[p ü‹ÂeÚ—?ÒÓ„#þ?•ÿX½~=X:×£×O—jœ#ÍSu `êRˆ£SmªG2 Ì£…øà$1Òƒl}´Ûe´ _ߪocÒãLjßÀ(ÐG^q\u ÓtçpoºÃHë_ÎŽ§g|µÍW xöðÿ0+ð¦ÇÌ ¬¿ø’½w§cöÔú½Ž†ÊðìÖ(ãÚ·²-ü=å¬É»SÞåÚ«ŽN˺զ-v›u"§\Ê#ÔÁ1#M:(Ý…0ú ã|¹'hmeuìADzSà1Ÿ¹uu$c¯ÊržÒ×!¶Ã ë›Ê|y .ŒÝX¹Ç2³ :tÛïH¿êX—töFeäoUå±S-½¼Aò§L÷Æ {õ•}%Š4zˆ¶0m‘‘,Àõ¾çOŸMÏÿ0½xðçK‡‚3#Öû8}–‚pªŠEŽö˜UÌÒaÍ4ØÏu~)¤CëdOn%˼€Þu5W°´††8»Qaè7úhœÂ_¡3ºÊ !‰*àwÆLŒo|ÐYI臤rÿ×Ë„ËBZn' ãËåKá²F®7¿t®W¿Ÿuíc #§ñd8¬ÑÓ’bÑ4|1•ƒ¸m4KY3TWö14¤ä'tIãP^›Õ ÆÐ:B..£Vû›js‡A>døp÷˜§ß3+ððÝ;fžN^=à@˜Ó+f^3+ppï{˜–õÕµx¦ø‡L®Ùæu¿ÐmŽ%UF½è¡dî¸Ê¢¥a•7^…F8šÕßõ’‡Óüp M¥W§ÉÓ7ìÍŽöÀ!3 :ù*fq”¢cb·£÷8t|wßwô>foJX*(À½§¾ŒžW»'ůèì\¸œ°Ë´|f ¯µ® Nº,¼®àÞ 2i§úðÉfKp}Ë eD³¿°vŽž'ïÒ#x¾zórzùäÉôô¯™Þ½y¼ÕšÚeöæèæ´ï;ü©5ï ?Åoíx”0"ƒKHÀâØl•ÖÜl¡UÒx…[pïÿlS®Ð²•.žuOš†µ}nÂ;Ë›Ï>ú …î$t¼Ý´Ë°¾/Û8Kúê4°t®N— %4Pëãø7.1ݪÓÐVè¸UE^Ð\.| 'eÜÎÓxg`J¬ÑÐVÎo`EcX‡uwƒVȱPŸ$·ò)šjrþð_”ÝeãkÃÿrÂîà ‚G¼NøøÁÿžÞ¿šÞÞþÝ´ûùýzƒà˜Z¼FßÝíxšù\dœvœYœÚYFÔz‚Ž=$‰¶ÁÆIG‘u‚tòÀMpvÁÃb@ˆÚ âÎt °¶yÓ3 ‘49@¶_6ehèÈ3šÝM‚‹:AòW®Ì|M‚;jwé@n-3 B&èîòW3ðµM™ H'À6³!ÐCþ#DÉ\ãÊ’ÚÊ>7¼?øË{—Í™†¡•錵ý/_M/˜æöð?1³ä…GF¯÷9¢×“ú˜‘Égƒei§„`gB]ê>”CÖwÓf„›x47yîÅÜ!³8A‰à+yÙQbTåÆÁâs§ anÍÑöA¨:õ€~}¾E;` êS õœþtë—NÂOëç§J—ÀOig)ûÅ8ggõ#0_å*gkª Ü fYß l;eyë¿1Æ#¯]×XºÉ,Âøõ-^eØu¤…:ަÈk Öldæˆì˜ìÇ󯆽<¹ÃŒÀz>=yù×éÕ ŒY±Wà_øbÛgœ+p“õåãéàþgÓë?ÿ¥ÖÝ5æÈ¦¿Ô5œç5Ãá0ÂU‡Œ çng!_ @ÿ<žÓ>]ž'çòW_káú^×°Å)Ù†ÍÌ€]x g]ydNµÚ:,Üz¨DF÷.è°3­bgÀ½ ¶.è8ÎJJ·g·?´Ó9ÃÀ¾#¥¼ö O¶ š‘0[ú‘dÜÀ,Øt„¶}ò•µNÐ×Âãýthg‹™ù½f´ÿÂiþ‡ßM¯Ÿ?‡@¯mÍH‡©þ: t¶Ô»3ašõ@øÈ…=Õæ´2wÒ*›$ •rZ¡pÊ'Œæ(ŸaDI[´¡©>o:¥ý¢á}È …g,¡Ì• £ÿz&1Úe#êÑ%ü¸|––NÀëç§J–ÀOig)ûùÃ*ߟ_aŒuÅù•’FN‹«,s;ÒDsÞôf6² :Ƭb@}gÜò¹™qÖ!6xÐmc zŒ³£¸²è%cD4Èf¸nDÅCü3޾ËfÀo8þ1o¸WàÑ)ßÿþO'ßMÓ›Û_3+à'ŠqVÿò¯ÓÛ§“gO‹žå£‘¥›v)HÄüÐ6gÄéëÂOøáÈBA‘l…®š¨ë°}ß4^„ÖÝ´ƒ2¢š{°}þÛ²SÏ©÷ìOœ"<ÿ¢dÛÔÎm©íùêj!Wšž]_îƒ<„W,š!t)P_K‰!xÊë…»èüw|×áæíéùsœ>Çó>ÿžãy}Õœ•¯lÒ9Ûa}ßsùékØ/ñ^Ö[áùŠç3² ;2D:ÙŽ š´å:ÝŸ@”8â‚Ó^?â¥"š|ë/M§;©ÂýŸÈ> >ÈAÙ[M /«˜õÚõÝ[e45’™7…§ž+¡c µN@Ϭ'HÐ2nç~98’J]/f0ÀF $ê5›Õ‘Û™ë•CÕ‡¼VËæ3ä<敹㽚xþ޽|Œèû“×Ì |7½{ñýô’ŽÂêwÿ6íñIäöBœ=}:½öç‚Ór¸Çètå®xhµƒÐd#nzÅ ÀŠ…ùìSv@w«“÷OÖ2g è0¯× )gtÝjô6tE•¬Ã†„ÕŒL©,ËÀ²l@%ëWpÖYä ,ªÈ^ôâüCy®®4¹ŸTkÃ[9ª¥í<åQóƒRf?8坨ÁÈ ·Økqp|kzòfúÓ¿ÿûôêÑ_#»' º©oçðˆ¦ùé\y/ÓC­á¡Ã$p¿ H‚¯Û Jd$î÷9ÌþEpœð°Ž’Ûþômí\ŒF”cDA-Ì¢9·¿‹‡ƒŒ`¦®< éŒ+£3Ež pð=ºu—Ï!ó<¤= ÜZ?J®/ÿ¹%M¯ãŸªßíû)œë*û[ä».Þÿ¬t—À?ëû—û‘˽ûŒ_ùF‚ÄWøÿgzû’i~y°¬´ÇHí¹üÌÄìv¦}Ì›Ê:Ó7©|Š\\º’6D64àäK\*ŒºúyL}*W+Õ$©4ÅK…Î+‚|¬cžfž'k*—½;<íÜ×G' K0Ô9 ½æoÉ —Æ àðâ}þ[ƒ:XÂßWKàï«ÿß÷m#µf:ÜqüΖñ jjíéV}ß–-HÇ ‡ãÚ“­2r#?8uyÛ ãÙd΀øðÒ•+Ž8:FŒYfHÆO"od·ˆ_;íØ-G¬LÕþŽéègîxÇ^ÎxüäÓûÇLæß›V7?ãÓ®ÿÆ«j¯§óç?0#À×ÑÅÊ#s!è1¿Ù¾â‚äJ'‚óéW¶ãâôëÁoqT]ìLî|å,צRu*NZ„^MßÇ¥Hç_ÿ„)…qµ²èŒ[šÕ1ôx;++xò‘IÇlŽ–!C|JôŸÀç8º¾qësŽcæRèðÍ[6ö}ûzâ¤Aê®ÙW±æÝ}×Â÷ìXB·:M:Ò¢&’,N[¨gYZµ-*õ¾¥y dæ ˜÷5RŠÒ5n¢àwpZ¨~Ò1 ®NSé¼ø†1%ÆTöt!¢â[÷£öL·ƒÍì›HL¹¡óéÈ¿¡z}AÖ¿©ðS…¥sðëÜê¥ðëèù“á²ýGíˆmçæJrÜö.ax“Ø8 ¯FÙ²áI2˜¥03¸Jkj*;Œthz!"ÂG¾Q“—@ÃSi.ÝNÕ2Ò‡Hq:íüÃÆBÈøžÔÁ³JuŸ]ð_³n}ßc‡OnNßÒ` ûñ;Îýx:á5Ãõ­ûÓúóo¦³wt8 fz÷’º~ºcy@ÝÔ;#~—ÒTgàâÜŽ•ŽÛNN‘œSêµÐŽAÉSÚ(‡hà!3:Þ<_ .qÜ‘³4¶¦è«3 \nþ·oV½7\7Ëïõ1yLz›8£XQßìÑp}ûœ}kâ9挅=ÞQ”篞MoŸý™+Þ9¾Íy8—ŸóìW/JÕ®º/HE=ÒiÊÝÝ!cç½_¥Ï-˜ˆƒ¦É*Ø °™î'ÝugZ*Ê:}7‘šRwvŠZ¶`äB-Êò71h ¦ ¸`Û1 ­óÿ ÷$G>¾µùàößÖø¿Á̧ÔÖ¿çí[:OíÿVy«¹æ8à6œzF-pbµ¶ÛaøM¢Ó²E€zZf+;„Ý6Ü‚må­´Å£2á XòAá6÷­´8N·[UCMlv»¶£å|”E9É>‹òßæ5È›|\æ›Ó[ÓSö |ÿ†oœr$íÓÿœÞ»æÍ¬À9£ÞÉß;f|Çè1¼5-åd€3V™`¶À/çå½¼À_eÚD|7ë9[À†C„ín@½ñ ´n4DP~5éoã`‰N³mãâü7#Ṳ̂ívÜK ÕvZÒ´«’ŠQUI]å¹…q¡ÊÜeÿÄþ]O·Û§ûrÊÁ=i> xxââîÁÑ´Ïg}…O}ç´Ã8yªÃGXRÄÖñ òg¾ƒx5’¤m®c·Æ>_É ›+3ºÄM4L‹O¡‚`%;à4šOù 3o«Ó¡ðÁ?'. ä—À²o-€8/@Ü©ÿ]^E5„^dHv¹,¸ ,€+QãBä ”UžVŸ1¥ëk_XĬw‚¤ ›ƒ×²’£v,%i «É™&»±3ekAãÎbSW¦zÛÕ[š Už3–hÔ·° ­ÃÒŒ’«LŠM\ª„)Žp«ŠÏÝÿ†QîÇGÓ«÷,0+ðÝ;Ž~ËC¯×Ó)‡ÕœðéÙõÝßÑÀ©3+pΦB; ®ë‚wˆË¦Ç$Ø¥‚8j½†‚û ‚ƒSU]ü§).c%ΈÞt° A=e™@˜jàŒ‘:ãp v„Šº(²s~@Wî­u]¥µÇ ÈÉóü=ç0µtã.SùŒöàäíÛéÕ«ïi§ôØÔ·{¤ãçƒ<:ôIç m2™}fzìÞGŽÞ®ù™šó$’¶~¥ãìIçy*PÚ’‹„FPïVñÖçDwÕæB)ùŠ˜N¢ ^ Ê”YÓt€s Sž§sÏ-±WgU² „~Ò­b£è_4l·/€å²hà 40Û«+ µX4P÷œYœnÓ™5SG@1”5ŠÊTŽX§®mÕZ­æšk¶£?‚…ÆÃ Jår$Á8ßZŽ£ Ñ*lžU,3 àÌ(&$äoš6¯¹¼ñŒË#aú3=.éœgÌž†XËþW–sìð÷o^gVà9Ú¼çË='tÎîL;8Ë ö\¼c‰€½«}(;íÌä3âEj/RdzÕGYÊõÖd}”E©›käwä”KÚ©ŠŽD€)}DNÊin9éüÕ§·$Nv–Šì%Òƒ~Oû‡Ÿ\*˜ÚΕlãþyÅ:UmŒÀ+#šŽZgoÇ4*G;*RuÔ:qž%ξã~†"sÃËN§µíhÈ£žDðŸH¨åqñ];¤Ò>:}t¢—°hàº4°t®K³Ÿ0Ý6è«ÇÓ9kº¯ßâÊѪ–6pŽT=†Ö“ÖÜ!Þf]G^_Ï+%¦ÇQþ Ó¨­gåk{TK'`8ît„¶ƒ§Íþ* <\‹ƒVºH•—+0g&Ä‚`ÑDªÒF q5OŒñ¶åñ*…?»6³eØñ8upQ‰^v¦Ïødî6 þᄆø˜Íƒ·/¦‡;üìåk¾§À¬ÀáíéüŸ)¾N"\qÞÅé;fP\vzþ9p®kò¾Cù{¶oíð"[8zÀ Ûm-=¤=”Ì:0Í¿ÜÓjzœ½j©®Œ‘ý9ôwéìíÝeß›ûN¹¿`7ÿ{Î@ðK„¼»¿Ãh‡WøöÙ±¦ÝõEÀ¡g©¡?ï§N›¬B”'íÝK'CøÞŠÂ`&U¬:)%>ìS6`:fu2?ÖãÇÿ㎊•þé-ßLxͦ¾“7oÒ&vüM;|EÑ{œæ·¯çIGå‚Y‹:ˆHýV§²ž ؘŒè…‘=0ƒò${+Ìwç!UF±ÄkF¤è έ³¾eÉ´v*ÞTEÛ+Á2²§N-ŒŒr Å|=WéLŒª5ʇRJxذÿÌÂ%Íèݾù¤Ýr¦ÂrY4pX:W Ä…ć˜,½C€)Þ•›ÉxUM˘qΰ¾š>ÏðÏÀH¿9Œã°Çe‰­ -”VÐéïù€kdz.i¬mpÀ5a”TÃKä¼ýÁ_~:þšul`ª£k§"-—ʨ“!tºqÚ‘VÁØî5ìz}Ð…:–ØDç‘·PááÌÈ@FÂ÷÷™ØŸþ…7ž°aÎ7<ž¾|‰;g=ýè³i¥ã½ûåtÁI„§/ž°¡Ž=ê‡×+ôÚ?ÔË aF1‘ºôô½œ±˜,-Ø‘Þí,}C ¸›ö”{ïÆmÖöïNç,óœ0íÿøåóé¯ñ¹‰‘NÌšã’}ŸýÎrØ´&(m[¬*’†mœ%Œ”¥' ÂY`u•©ïÿFFï[éQÙ aQIû*èÔv'ÇòÆ5ÞÀ ƒ®Ük±¡ás`7`ÄTWšó$ÉÚŸ·|C`Ⱦ>ð08æýÿì Èï-È]­9çãð¦Ó>äKiI/—EW¥¥pUš\èÌБjÜ×LÿŸdè…1#w`knuÐÚ´3?&3Œ›uÞܧ±Ô‚ç@Ö=îý V·H•¡uùYÇn™î&>=Â$ |ƒãq¸~QïoÒ߈ÉG^ù(#ÜCOùä¥ÌÛa–Ü4asœ/UcÄ•gT")¹Ú·0606ê\"£mP%:¬#9æü/ùâà‹wwX`Óà»'Óã7§7¯L'ût²nÝ›vùL±#ÓóWO§SrR>Óì,ÈGZ&òö@5-œÃ+E À´O^3|Åðô-£“i‡Ñüágÿ‚ó?æ¾®¦×¼ÍðÂsùÙÌz}™Ñþo5챤㱆z͉Á/èUOþBl$ù8ûªJ0{?Ìp4àY¾<¨êžàW×é>qÈRŸØ ÆrY4p5X:W£Ç…ÊÇ4À¨•ÃÛ³6Ÿ†‘ÕPjÿŒËùWnv¼Ž”,×3i±õGíùб´Ž•ãü%2òÃth§O!F3p ΜM4¨åA*Ï5£uÀyC@#>PdaÈòCIߥÃLY öÀ"ŠSOÒ[²:ë M;!µ· x ´Œ%ƒ{ „(¦3*AK)L§ßâw½þîÖ 6ÚÝËßs®Àc>OüöÇÝ›NÝ…ÿÕ7ÓáÅ7¼AÀôü£ïÙ…ÿ"ð3RÕFi#µÝ7 œÙå½üã{˜vááu/9¨çùÿҡx%2½NxäC=;‡8÷w¨/ïï©2Bžö0ÂÕf&†„ýŸLtúi– óýpòxzñãé¯@œÞÿÝ´¾}o:Ê^¦òY«ÿäkù¯ð¹:6[hW½yÞþ{Ó>/òÞ½†Þ¿ŸÞ>a´/{­õˆ·ãÚ>£}•pAÇ!â#œj-÷–„Ÿ7N‡§0¢âÜ÷qÿ[YNÁ»þŸ–‹CŠl•%†zçåf$j)CgèxfD(”Èg(üéZb(ç/®´[×éÀ¦\ùWKA©bœ;™ð6Ž’ˆIgÉKDiJC†¶Ç]0³ý©ßz°70:zvŒ.xer‡¿ýå5@”µ„ëÒÀÒ¸.Í~Êt‡…¾`úrç΃桵=ÍÕˆ£UÔHÆÃ“%S¬ßÓX:½ÜéàNìi,5Ä ¸LtˆÄÚ •LjbŒO=Sê›—©¦½ yäI=àF{‚3hÚÍ(k.’V½‰˜ƒ­%ZâÈ4í‡bDr@ÛcÙÙì-O7á ”SÃx IœØ-ŽŒõ÷5 ==¹?=dšþ»wϧ§Oÿ:½~ô—é' ®î3íñåtë+Ndùä Sü¼{ïxöpø+ŽÞ}wr6=ÁfÃÿúãt¨?â²ÓÍ^ƒµëúNó󯜚›;È:rç_mõcÄlÙW–ƒ}Ul§¥›ž6ã,ëøatRTì}Áf&\•IÂf 2m<ÔGÊŒpïÝ…Ä^@ŽŽÄ¡TœÌ,˜„t‘gৃtð6%ÑT„"wv­W·¦  8)ÛÚ$é8Ù0o?ÂYŒ£[tÈзaÞX›ÜrY4p5X:W£Ç…ʶ´¨×/Ï9ó}O¨ÃëÂm1ƒ³!בèF‡M-Ç™ÙNif_[<õ!+oÙhK‡• ¦ˆòSFID¶iÈ `Jùj’ßÑY£ŽJñhîm„–¿óáá%Õ3 Í–Û®9CÅúÁ¤%†œ.=øZá˜Û  ÷0œ‰6º#/ȃu¾bŠÿ Ùù·Ó{ìx=}ûú³O§çý¿3+ðöóßñjÞçÓoið¡¡Óó÷Ó+ÎxöÝwÓËþ‚Îi9·kÅèsµï=Ü3FöÙ°,vê"°%¸V”¶ÎbmHu85²”XÑpg½ÌÛLÇ@œéâbáÂéMȉà-ÈêÙúXðK¾Â0êò4#(¼Â.°’G¸E^ O– b‰S$¨•†HÊ—Ñ4¸vBì¹'ÊÀLJœ?ia܇ocÚX¢kÔÀößÎ5²YHrЊ|mOßÄ)À7g“5»yøDû‘§0ÑW¦Ê#`C!5óÊYŒ5Í2â%™¤Ù´?.™ÐÀj¨¡•O´ºþ<( ò”5͆@DmvxwèëüSUZãƇa›„%:aþlw8qÂÆ|èH:B„·í‰s ~uŠ e£9Ó°ÃAcV§.mrÿ—wîLwyÍìˆÑÖå3Ïä>utÔÞ:Ž‚SqÖ!)ɦ ò—¶ðvÄ‘ðCG(= ÔËqΕ ^¥LºIp¢êîH5rÓ•¯²T&~n{Ú*¥/+‚Ô|įNž…W]‰ÊlŸš(Ÿ~®ZÏácE‚ü”¢d%ß2XÖ?ÛÓiðÆ"ˆüò”qOÇA€©›$3Wã³Èáaý%,¸ ,3× Ô…$Æ.†Óˆ“Ñ/é@Ë+”1+C‡<úQ[|FÒ)è3Ná ½8ÕhjÜÉkq)Ëá2FÉIß:²1MÐÎ4²óÔ«øÂRF:›¯Ä)¸e1æ&ÊtI§ìâiÅk¯»_òìöx6ªvàoÑÊ(OZÀà­üNöÎ!òljV¦Ëí8A7Å•n&¬ê.zuWÎIŸrO9ÔuWýâÑÇÛÚPï'gëËh\u”³—€ëÜkßzžðogÇ9€jpfƦÔHØ´ˆ·B–:_b¤s¡¬ÊÐê(9?D̽Ü®;b¹Ôs5“àV舫 Å‘¢UòŒufÀê9°Ô§„º)÷ZLìHéü{I&øÀ²ioLG(õ¨“ªÆÜkñºQÄê·ßð0ö™Æ¥ÙI…€,.)Qtp´œP:Y®×¥ÿ—°hàÊ5àÔpÇÆ²› ƒ¦;Òj–Ás«•-¡èûè!0ŽBó¡4¦ÎÂk4íKh(ý¯ÓŒ¥Žÿb|¡-Ýž†Î4mp¡!«ëË ’hµ¾‚ì´…Óý‰A‚oƿʻä+]òψP¢e$½•˜¢\,ŒW£v¦I¶ˆëDÌŠntvüK Õ’ù¼J(ú ²à§FÑ é&³Ä¥kcÝA'Ì” ªê8£f‰l5"í£‚X àe&‚L§:ð^+­›û\û6;ÃS«ôeQ~à‰#O¢¨¤Ðr¼Áß‚§Žy+‘ñ_g“^$74QX:úƯ::âjƒyõ¦S®6É¢h[6Ϙ~tlåÄõÌßÕœ8 –÷pü Ô†•T/¹¨¾Ï!L†È:ÒÑÚÅ”j/㽈(wt(´H[k¬ßåÜÄ![ïÒj¤!ãÜ!hxâA 9lZš |Ž©+ÉnGÉÛ¶Úa£‘¯švTyb%^õ §Òñó³^Нâæ~@CGo½´‘v›­Q¿`ù€÷*GÕ•ÝàL@Š Õz°‰œ¶>¢ÿJ•\*À&ä™nðH I=දg€D³NêÍéÒqÓ§ÆÏÂ#Hóý$­o-TíÒ°é–‰48@ȧÍÊ- ËmŒµ‚[iq‚XÉÕ¸;pˆzÉ rß¼N*]pé5xŠæ>¯m.aÑÀuj@Û°„EW®^/^ݺɧcÙÉwvRÆ-œbAËÊÎ@u­$ÓÍIš#~z;ëÌc,5˜]WÕ«hØg2"hUGèŽèemcì‹ËÀ Ñqw¦×îŠMÈøc0À² }q: ¡°ñK;|€gÆ0R^ʱ¤Õà¢%ªaÐlZq¦ý—Ý$A[ãýJWd†Jªª[þÙÉò(_óO¥-õö@óiÇo Nw¶æ5`:ðn‡4ªsQ±<{‘Z̨$íM³)CªÔˆÙdFªhÚ‚M(Ù+Ÿv&Þµ~ŽŒ{T_wDZkÏ®5ŸúƳl&”µ$°<)ˆ¦>êŒî#HÕóÛ ãÙjžN:¹ïõ€³ M3™å²hà 5Ðfâ I.¤ li€óãO&ñ¤ù­ù šF`ü¯ýNÓKG°IcYÍûsG»{ò㥬Ip cm03#}1Í1¿ædg`:¿íB#ïHwÀ;_ÓsI%ÆŸÕ ¡[ɤ›E@8„zDT'‚²ïƒw¹8•‚l;žøRŸØt‡À‡NE4¯Â½‡blù‹¾]jɨ¼Úý¯S·,ˆ$‰–Ö+í y×ó¡‘åpe¨Nµ*¤‹–&‚ Ȥ"u,LõÔ¯p<*’€”rpŒ ÆÑÁÈÌú @šæçÛ-2@÷@D^²Îø¦Š±—c¾IºCu–|ö¤hL™eS ð¹Ì¦>â0Oâiõ,@?RÞOõê’ïŹ×ä¤ý[c@(,—EW¯ñx^=á…â¢hÀ¡ºÃAâ2µ[ÆH¹ëÒUŒ¸I«O&F50½ËÀ´ áOƒ‘xé€ÒþŠâ )³@‚ $6’^ ÆÅ“zbá AØ®[¯Mf4 ânaÌÕÁM!1C“Î(OïGÇéö&Y¬×´gáƒZ\†˜[,)¤’ô¶C²˜Þ–ú¯úÉè–=à5K#Yk’x²Êý²€êóÈÖl{yp¬Ó´~K$|¬OÙö/Mu„òPI[a/}*Å¡ƒúÆó=Ha,ógÝêhJ0,dSp™P7%\»3ÍÆÑùê\AUaìÑŒ~°…üy4}ŸWÐ}»5^@—°hàÊ5ð1ÓqåL‚Ÿžbm63§®ñez5¯„lçMÑb=-­-KÚ•bCËÞÎ\j]wàÅ®kà)ÎÆ«°h\c—ù *þaÔh×Õ;¤­ U·)vf†%ÑDmä•3¢ÛXQt΄`ƒ`¬CòÕŸzI°î¨o>iV(¤CEhÁ­ hÍ9)‰R9c]µA×reDóìƒA.p;äu€Žø…C03äÛ9[Ö²ÏÎdñ%;H‹– »˜gXaÙ°Ãù{¼BkØ~NX.‹®HóŸçÑ[È,ø@4³sç³yI´lá0–f´u!ðf‚àŒ¦¯9ÄjÐÁ!:áRCh¦˜rpÉÇøO^†§:ÖÜ¿ŒÈ½à|ä"KÀ%•þ 3í”o;äv$Ôa0@Ü#AÞv„mб¹B¯Ö¬v:M2øÆÖÔ™÷VÐ„Ò µ¢“ ÍõÍE]j¢á„°8r=®õˆZ%Ù(fñ¶Ó³NuÔòA²fUÜ\JH7nç@øv™uº ]Æ1‰skÍ|ÛRú‚fP@xÑ(N¥+KŠ€)KJúJ•C®öµsîg®ž.+å)#QAºîoQ7y\óf ú$öñº`†LÝõ÷ŽïÞã(€ý®¾Ä‹®EÛväZ,D?m 8½¹ºu£Œ•#”Y¯8ïò0öv $*³‹ÅÔ4°."Ôhª`uÕPcl´ü1ð£QXF*&Û"pÊÖ8–³Šå5³Çhjb5šLM98òmá-7˜'Ý$uGÄô`F7X˜VMËËǘ›á•®Å ÙPn‹%Ù09êȉ)˜I˜f˜2¥¢0Š|h¨ò²¬PBY7).i*€Ð#ŸÎ@¡Õå/0n¸Ó Vº[(ïTuÚÕþá@IDAT|8#‹ý S²ò‹¾FßG÷$‹1™­Àض&ýd“·è£o™‰†ì ³rN Ê|_(AÀÚ&‚ÉÕ]> *_•Šgë©îÙ\?µ«,÷‘|ilî/©°ÚÔL¹‚‚•´:êïIHÄeÚ…üp¾Ä¸;.¢-aÑÀUjàÒŸêU’^h}êÐpV÷îaÛpüù2 †}X:Ë4ÏË-coVýXø˜qÀ¡9\.évn©bY{{EÒmÐGõ&“Ø2ü)Ôl ¤Û{øR6i¿ePÓ ap€ 7Þú ï?*á%o^’Ü´¤ÈDä´¿FþiH¶O´®0C+åd -Ž_äv¾j8³)W"˜Á¨e€ æ‹¸W;XÆQ±yÊËWÓÒ‡°_^§É,¤zþKOŽDËCÍ„¦]¤¼lQ·*,æŽTálƒ¡Œ¥›T©)¥3@¦0d-˜+šØâì›ÎLa_ìÒ Ð!es0¦¬Ò §ÜÓ*‰¼åóÚ8¡I'À¼òÚ‘Ê3Æ3wÀG´:lw„¶Ä‹®B؃« ¸ÐX4pY«7gÇS6sÞ…Å;?.!Y»4ñ m\Ñ+ÔH5K 1¶mœÁOv/3ÄÍo*Îæ¾Œ«î²}Žÿ³,)ºÓ’†Y-Å‘äLvÈ·Õ:ª•Lâ¤U-¢±¤(hP¶ …†¯áYP%…F~°¦V‚ª™A¤¥¥Q0³~w§ü°ôØ‹ï˜âÐ.ÕŠYPkeM:žö¬isèúédy(ñpð‡›ín”I·Ë«%Å+d˜‹cܺwâ ÷¾T àÁ©ÊS …2—ŽMÌéQ/y s<ÚWxM-e£¬:†Bºl£ïYîÁ?ÒvÚö Új%K$ܨîÈuÿ7ºöF_õÔ¤#À,Ù!{ y’Z.‹®^³ý¸zÒ ÅO^Ãæõ©[1t5ú¯€ÝÇÀƒß»œF8F• #§ücø™µtik¤clc~Q·tˆSûâ *ZEO€Pß·/YŒS5EüYdÝ[oJp`+¸ŸÁiúÐ(V¡cÚ?. ¸i¹ÔA¤,#>JýŸ¶¸ùζTlûÆàšJH'!C ÙK+!m"ÁêÃ=Ž/m™Ê0œŒà‡Ü X†ÍÌ €»^ª:Hƒ0ð¤¶ü6ãõÁ^èò-Ñ@Ý Üì¡pëê¢HT ÃðŒ^¶1ª~:1Ò’¦ñS¡p“€zJêª{O%ËfajtžY‘УõY¾tÑ@Ï]Ø)¿Rä:J~Èྔ|ÙázIß/":÷âú¿aå×2™‹Þ¡µ><œöz#G0–Ë¢ëÑ@=×C{¡ú‰k`Ø@6Þˆë÷Û·ÕÛÓ‰CÂŽúK'  ÈK`;Ž–sjj©ÜZ‡×H‹T4Å$‰‹W޽§²´¬ºS7½íÿþç¡ówà‚-Ý‘µX”'– L‘äƒP´qëèŒõl6CùâŽRAG‡ˆ”íƒÚ¢—ÓšgCÂÜžðioÚ-C˜èl`Ê sBu¬‘ÝŒ?éñËÛÎr„>¸Â”ŸÎiHòC=âl~ñµ~ñÏ :å,UÑ T‘uÂ:u·=rz¦ƒL^”¦«ìÁ³|„ð^ÔAkñß²º×«L<;5}1Ë*ë4á/ß§¾2—žÿÄ©”©ì-¨µ~)‘ }ž'uî¨ÌìîÑ 0t»’Y.‹®XÿÝÂ]1ƒ…Ü'¬aWizÎ'óºÓY×ÈÛ‘.ú™G›±m‡+“!H…Å5K½a óá)L,]Ù—eØ›ÏÞ¬|“j`=>øSΟ™TÄõFÞâÓް?wĆñæ/(ԉÞzR,ª×:;#AeRDpýÃSlãQ‘Dºd3>¬2ñªVÃ#—AhµQ22ð‡SžWŽÆòÍ ƒsõõîÊ–ú¡‰lP«Q«Î¿|¡ƒÕÓ:;ùt^Y†¬E‹2]mB:αå’7!÷ªRrOH¿Tš3`–õãPorPñ´eÈ`W ‚n¼ž‡jKË`å¹½òr×# Uo°:²Lf>=¡Rôª~-°ƒ ¾žy|{ù°ÚXÂõjÀÇs ‹®W7óIà Ö65ºÎnÆ Â5x8ÙYˆíÂXU.§ŒK¬;‘Opy¯¹º45ÚfÇ=[ÞK±³k{&ü7=­å]ƒÑN«é…a•ó‘ ¡þ6ËŽÇ–¯Ø©cœéhC÷Wªbut@ÅÁ+Ï—ºƒpE›ŒÆòæSuiõ ^:Ø ±Ë•!ú CéœM~ŽÐ Ñg¼º¹‚Y”… ‚‡ÛèôÛñ;Ú¹¯ÀuúVÊ͵ÆFC‘‹KÅUÒÊ+n “"a»Ì8ÎÕûÏóa#¿‘.]$›ç­óc+N]!PqÚa…thgž³ŠS&Ë‹XîZ=_!4ÓJg£þ1‘|ÔÓ©‰~ù8VãÙ<;åYa9à°;U¼\ \‹Æãw-´¢Ÿº4ž†Ãc>¤¬ì™Fq8}÷äìûQVuµJ~d?XÃY*è ´¦>Å¡/‘ú9Vëú=×Õnx‰H#í0>d$ÇTùŽ•8wTrbØ0Ç.Ll9wQéÍ·\`šì ðñ³Çë¼Ð3Ô&± Šl¨h3ºé8A.™øe—?t^ðTš7¹!uÄ¡2ù³Z¬Qw;2W}ìGúª.8!"oXZw”Í:åL^Á7¥¡P²Ž¼d‚G,Å8Ð&m,üƒYˆªXüÕ™µ«ntaÚöùët¥‚= ¸5Åì!3JY;r…©A³¨’µn`t2޼ùb&út¾'wÞ[…/è@.ŸF'K¸n ,çüL WoÿgVúTчAܹuk:ÙáQÃé_ð~ûîœ)ô Î‡Ú ÐñèŒ j¾Öÿõ*ÃØêÜâô’ÖTÛi˜ ¬/eá+½‚ùxÝ9;Þ™òÎ'p·˧ðe6‡sÇäb'g°ù“ì‰Û¡µ ɧqd ”½ÎB@¬ñC”>+G»jø °*W ?Éa;˶ê1F¨úÕ±pMÝö:~ëðUêòôÏë³ñ62ÒÉ?×äË#Z—ýþÅÄANtaJ0ÝÕÙ轘.¨”ZžA+=•¤æ†¦sp 6˜ECñÚÁ kÏ¡xÁ¤fcÂìÙÌF«…W(šiF%«ÓàL ŒË)¾8$ë™Û8kxŒöŽê”‘âÁ©¡n­ð7Ì#Bß*õ¿]Vm´Ò¨C½Ð’>…ù®žŒ›IØŠ¼‡ÝÿÐévðé‹R· @h‹«NK›Å#ÏuB‹Ø°þ%Ákf[䥜¦*ÿùF;ÛB°>ŠÞ;>n K¼hàÚ4°±¼×Æb!ü©j@Sz5òyÓ=-Ü0ˆqc­cn;¨“ÑÀ·“ÓF„™ÞÎ L㼊WC¬Á íx¯á¹ÛÏC±ªNíÐëzÒ&sOÃkºµ‰qãDIÇÀÄVhçQ¢qEUv‡AÒv‚[NÆJ‘2¼¢›“ï“wÅ­dpFZjÒÞ–ãWn:Bìµ(=X;­"r%‰,§¨hãèAÅ!Ù6µð*C¾Þl(y" K6N8´¨ƒ4NX]Wä ÔK»ªztòÒ+çJÁ]߬åq²ÒøÅ ôVeUQgo]Ã*εi׳1ÓXy$¼P©ì2öžO[3‚,Ëý½ˆÐ¶` Õ›0înu–ú‘ÉÿÎ ìîL»û|Es ‹®Y± ×Ìc!ÿ‰j ?f²â«f+öô’sÔëZ–±GäÀv>˜ØØTí¼°Æé¸Ëth:CüIÄ0c`3,¤,ÅÃ=„€¥Ý… §†Nm¦ÃIŽ¿˜m<ÑÚ¨×"AÞDJ‡žÆY@ˆ †'2e$ßÃÑ– :³HH¶F”’í ê8úWÎZ&˜_X‡ãÈœ;1Ò•ã,/gŒv‡†ŽTZí¼ävËÖÍ3ÞN[ÿºâJ?q3"ßÁ&w¹Ì¬+ qÒð3Óu­$¢U· «ÌG®ÃŘÙX+m¥ÐmƹG€û÷mwXôs•ÆAP²Eº:²e¡,b†xNJ¹/"‡ù\õîàsà{ÇGóA@ÙŒI•%,¸ lýY_ù…æ'­6‚tÖ|8'èùÎ<Ö.–Q ™ØD•)g±ý€¶AîrãÚŠKHöôa;E|žåòí¸ª(×H€q‡hè8Ië+fäN0NËøÁè„ìø–hh—ƒ-2nür‰!`‰•IàI‡² U¿øéð,K gV´9ÚØ°"—Р|½!VŒº9ÿ´’Ë  Pƒ_m¤µQKä“p‹ÖŽV”f=~3lD%Ày0†5ζ25P޹+Taß«G'Äb8 "ÒÙ±C(]šç?H½YÐ<*WÊ(ÍWi0RØòxßí4®v‡ݹ;bËeÑÀ5i`Y¸&Å.d·4€\ÝÿóÉZ¼V/OkÎp$[Ø$5–à X祡4´ó3-¬Ûp¤j9­íŽ„Aò°þ‡ò ¡‘7ß±´âIN! ¿ 4_CºMsäSmfV@åØžªó·-Ç+Œ¶4ÊÒ /‹° ]å·h§ªiÛòù#Ц¼–š‰8ÔóÞDOܳ̔X^ŽÒ”£äžÊéåË·õDA£7¢¤…ÃF©eaœkCJ@Ó‰ª’Ñf0Åñ”m§+Ñn)O‹ƒN¡¡wL%KÔY‰C(m±ŠA°åV0r<=s¹rlëÂY/—URA†Öƒ õ¼§É ö-…f`ÿþ½iwwì‘ 6—%,¸ øÈ-aÑÀõh -ÔwAãg˜–±ÍŸ–±B7¼`ýjX»ºv>†tTmû_Ùý‹âlëiw8ŠÕ´ óC£ê-+nIÄi Zxåj›E9`Ë„è¦Lcø=Keƒ¢‰Ô =QÁÕÉw£C¡úLs“Àï`çªpå#eȦ<¨ÑJ&<¹ç”DΘ8-­7½œ»Ž¿œ¿ù‚mꔣ¶nñ‘œ?u!ÛY4×Úþä»|CD’mþ (ÄSšJH%Òè@ˆiÝŽ+e¢ òK­gN2Ì A²ô®Î 1* XÇòh¦Å¯Z&¾r›P³ã~ì{‰žC·¹]tì—{­)T–Ë¢ëÑÀe»u=\ªŸ¬Úxž3ªqʹ7÷E!±ç[f”$( ¸£å J£§]uäïOzyë‹yUÎØ~Êçt1Óà Òï•k­Ýò¾Ÿk˜e¹1ëâH¡îÕ_Ö‘†Xe ‘á\ãÔ=p£e'­Ó“—Î[Gç!Lš[!8àE¨`“6OPÆ8ñbY4ªˆÂÑ1’›œþâ~î×Ò_ÌÔ¸úH°S`gÀõsäM§C~àzo$ozã~gñҾܿ´‰K!é³-¾£x.3?”ä®"$‰,êT¼zÖ¶îp×þ 6;úq*XÐå¹ ‚%¥Ûè7Ù‘eè°ÔC·Pª>iå^û`Èuå#OîÇé– öŽºvêÌ™%±hàŠ5°,üL…ÆØýÌ:Ÿ2zÇõí»Ç÷º›C=“^øaü:³ÑÏrÃq×Yý…!í¦úµ¥u² tx¤QkŠ ×þwÆ2À`ÎFÄkä­A~sB!e1ìÀ)†$e!rU¡>Æ_˜´H˜Öëêüò¬˜O Ãè÷H:EÈÛ.Êö”ÌÄÒp˜O»Ë‘Is°•Nhš— Á¨a”–¥Ö"ZÚßù™ Ðü‘y£ƒØàÿ;-·ðÀðfÒ£¢ oyJZµPA46)u’WßUîµáÞjÁ)ë •Í› !€ISxÚe!0ÞR ÌûNÿ”ר­Ö´Aú#b° ÷ý-p &5a"ÏÚ¿ß{$ q¸Áù®„ד‹éè.ûeýk£+XdÀ/mïdT6]'=féC?ÔV{ßœ†í Ñ"¬ãç|à=‹P4ûHÉŽÄC—ŒõfñH÷Pwä7¿"7W*y%Ò‡Ïr÷(„º-m(aR¶ÎT@Š­0ËÐrTõáÈÒùZtTí¶®’:3²ºañF[o8è¥ ŽðuôÆÙÈ6äÈÈ_r”¥S3dN¥¤KoÉK]ÚKJ· Q`eöÁ¥rã«{õœ0ʻ؈+ˆj#„[QÈ­|x­X¥Çª Ž´Z0âⱩkYß3eØFP¢ð–Ú9d´§±ä©ëïã|Úãà,ÃÌw wI.¸J ä±¼J‚ ­EÛ˜0G–û·xÍÉihÌöp2eÐ5«,lUŒÍÝXwJjúZ[ZF·‘ÝäWi×û T7ÿåhߤ^Dê:² cË0&Ô € ¦Å:¢WyÈFË¡Ü|üh ßÄòÞ¹õAJýÈ^„¤ÙUJ „Y@WÚ*Ð aÕ(z®yAˆÂ¥š©7*Å-y¨Ùñ Ø*õ˜ØÜ Sí/ ¥«óWÛd§ ò€F%iöf‘®jCw:Æ™gOZ¿EfÐGz bh…gh6O9â¶w[ŸÒqŸ„ÙŠNßÓàßÁ.ƒ·u‡O[,kž³¬òQGãš>œæ-Û*wú?ÿÐ¥Ï崳ǧ3–O«³%\¿fû|ý¬Ÿ²V|Ýì|o?F° ªæ²Æ¥­—Þõ]ùmsªÑ#}âª_£ûL ý—øœ¾m˜jŒô|Ö€\É4ÄîY•káÛa@"ëjäAv*>Sü–çGðÚ‘€¿¦Ðß›ñ¢Î M§<ë%¤¾y+åv*Ê]”à ~. ÿì½[ÏmÝ–×5׳Ö{>ì÷Ý{—HŠÃ–ˆA ($J Ô è e*1/T 8T¼UÐD9ƒ€`qH¸€¯` Üyç¡¢I%&&Z{üýþÿÖÆœÏÚ›Äìçywí5úZsôÞÛ¹·1žÖzïcÌ1¿\:#ÈbBÁQÑu‹ßIN²}Èr«DC9ë}¬fbW¢__S|TH;IÌä?«.ôÔ˳õXWÝ#O\ÆçÔ^›ú;·Å‡Zµñ; âgxÁ6 ­Õ&}ýïùh".ø”oœåôÀ#xàœ<‚“O¤ž/}Êù€^@²¡¶)É`ª— |lOÎʼÁÔ‚nVþÜ÷A³üÅåé}`nkï[ŸúÝv‹„‘ÕP™9H¯6Wý÷ÿ,¤TOŸà¦A)7*$Û¹°öiz9v\c{A£ŸO~÷W÷®rúDx“P’Šâ#y)êÕÜ®|Ó ¬hûÑšúKˆ~‘¢S¤ëð€…È1“ÀÌÌŠ˜á s5nÉÃk •ruèê š¤]»”ÐvvSh6¨s ÍÛ®`ù'%_…- µÍt9Ä6í¥¡-E(EŠ=ZvµÊÓ—±ƒ—êÚ·]:±;²é>Py}¯µ%“€¶†¿“¢•ÔíA¥”'wÏøV“0þDΪOÎãÃ{à~¤{x}§†·Ô¯ù-€¹NR&{õç€ý²:¿˜¢^xýÏÇ´Ý{ûu³D•Ø{Ø×Ý€‰û‰Í¯H¬Rg[UR;YiRKÈÿH£m`Ö _Ô›éÝYXm ŽÒ§ñÛ}ŸdÝeí¬¼I(»DF[@†+§Ÿt¨3âÔ!W†6N±•„µ ÑÀÚ]Yô_är1¶êEí™?wÙ„ˆŒˆ™-Ìš6ÇnÅz2pw&#âø”Wºùºó)©5éFpLR¦Zt;•2,©BÒc{›Ë;ˆƒqùÏ 5ª²…)·àhÙý–;=oÒë³;P²/d’·ç…k(hz‘«3„´öÜ—gl¹¡Ú]¦—/”ñäò>?l¹ÊH÷<œø¶{àœ|Û]z ¼çD]ÇG]^ð#'Fâ¬GýªWŸ/Á5йR7Žzïå+Ç$åsgO7yA׋¶«}'Û¿Þõïn> ’e¥Zø…-GƨMG¢C~V„c·¤rZ’dél¿@z7EÊÑÔ˜ËD'ëÍð,—õ¶• ³}&-sPF r‹Mª¤•Ž9sÊ &6ÀuÌRnpÈŽh„¥7ÉFøÁØÀÉ€ÙÞ °Àã Zº\@4€Õ]@A g]#é@T·EÞû+~‘|Ê:þ˜nt.çÔúiXÉfwL›t—C\¼ªRi(ÙݰKß2êùâóPRMË9¯´÷½ʳ¤¾‘½Eå:Šà8©ÄǵÁùªÿ%V>׬¯ æÿ³÷æ!À‘sV§Ê %ü”{zàð€/7yÆC€&2©_ë{ÉëO-ÆcïÕû[èö¼êdÀDwPé¦4îJÝ´¿påõ¶‚2wÿ $Ѻ´]ý ƒÛñ€”'Ÿ|'Þw ø"¡e¹Ê“†AµOBè‘“D:²À –#ÇëÁGë‡ì`Á1Кü×*ŠJhjr£€4‹!$ œuK·þà –c«ÿ0ðKÞ¯ø n¸7H„¢œ¿ÁUE0=_÷lй9(]Z)·V„í˜øT¨C9èâ0¨Àå¯R\N×ÈJ%j‘~”UîÁ$óœ;iª£“š´=€XIa;þÕT¦×@ùC5ׄ8h,ç.;Ô)€ëm€f†ðþdz›†î¬N<€öoûDŸ"Oà}¥)?tá6À®³âú’<² JtUûŒ•¹-úÝö‡NFÊ,ÛáØ]é&ʬ³ÃÐ{ ´ Ò#À_³¹ò®K]D˜0bSŇ/Á¿kчFÍ$þ²í¦?eŒÑ‡}™|Töd‘ =vVö­¬áV$ÚšTÆvWøKº5cˆM(ËR¦!YË#F9!Qï¨ð½›œ…ù)u'_’-ly„Y"‹Ú\¸m[+géµ×aWnXö5hA Ã-QIñ9o'iCsúúG1žëƒ–¦=áG¡s$x Ì„@Â0—jy"kdD˜hèÄÆ)Cà ÈWw|SæÙ{çO릳<¼®K¯ëÔð6z A•;à'wÿ}±Obüâ}ׇù–mRxè Û—W.­ò\Á›öK]™Â¶45ør°›t¤ðÝÿ þövâàŸFÿ<”—ÏùÌ 2ÈkQ ²@£”V-ùykáô¥ñ£0“1ÿ-V²M·£°Â‚°üKy£S‘ýy`ù,"˜É#{åíl ^w.ôhôÞ*ó‘1ƪêõçøX÷*[;G[h…{Ü {†ÖI†“Šâ¯M1gÔöÓ¥é§0pá·8ÛIÞÖ'¯Rb+ã_9½ïßô:A‚r½7•n} Wdê¿…)+'à:ƽÞòuJT]Ox Ð'—wùÝ Ë>€™Îy8=ðh„{Á§ÈÓ·¸ã×ÍžðŠÓ§Üë¼ã]ó–†Û ~À-3ÓÉMç¦á|•-«å„׃Ölâ7MìÓ"û ½¼__ž±o¾›ÑkPŽõ«Û ­~}W„±å¾AáÆ7nø¿†oZf-¥™#ì[ȹ†ªn ¾XG"’9k øÒ›¹Aå`KYÀ2]ÙÝÿØU] |fº6ö>É[cjMl;?0 [6‘j˜d~Ä­í7ýÓ D”Ç62ž Sä[Ûvê áXZܲR>~’>üW|d!|ùkÉØ§R,%úbHû¥Õ¯7“QË­_ÛË«{Ç-Ù–k£²ùÈœ¶·¤yÆÅiýþçŸÝû%À•sÖ§Â!Bö)óôÀÕ¼àéW¿B~âûÎ ~_C&Å |‡ʬÜgkÜ]Öd¨“؇”ª‰¾|ßà{ÿ ¶¾¸_ Ü)a–xÜ1!ÀˆÝ?‰áif f]½Ô ™êè ÝÔRZê "Çì[nu˜y7Ã+X_™h4kYå¥5]F €MžŠ*^f,b«;«÷ðó0d÷ß>ÏcضªŽ úoÆ, ‘}cÊaÞâk9äµ›ãÒˆ;ð5ÁúÞ'ã«#µm˜´)æÌyS{Æ”kªô!wÅi{lšèsìØRd+ºò™–wRо„Åy«ª;^Á3ñ×àC'78hsÕ7ü‡/í¬,;ü0»dOç§€œåôÀƒz`þTÇ)ümöÀݸàóï!·ù°ß$ù„~ã£Ûÿ® ¼×™Øf' >°¼uj”ª? $§_ŒÉIR¸Ú’4B9ØÉR7€tûÆ<Ù¥[BÚ$~E3¶ß–íWlu+=y2°ê¢7¬[K0í5XzÛ‚mûI¹á¡/x!ׯ©5KŠÞ 72êÏ•¹2VUF~tÚØdkîâDz¼£‚~[Ò­Òn°±¾å¥[y¬æ\­P‰nJÀƒsÒr;¾è§¸Š¼âwB¦Êv¡*l;´Î>¶ Mu\é•X½v$lÎmé!ø¯ÂîDà ¯É~ŸŸ¾ó…Yg9=ðØ¿ÉGPuªxk=°Á’Àvwy—ú|‚ß@Ûmÿû~Ùzl“ô\Ëáî@~@… jÛ‡÷ ¶}éQ••´ÿÝa¿þ,ðËd¥ö#‹É‡µ!\›ŽUáô©€çØlB¤_`Âåè‘䓈—¯Ò ò +«myìQû—8~j¦&zI$“F— ]å`OþŠ©•·2¨ í%Í„¨>-Ÿrø(Ÿâ¦ÃÊ+>Y]ƒQJ’”´|”$ë°‡7fº¢å»¥[=Ëë» o| ÌûQ©vz+ga‘EÇ~ËÈ›~ds=;©{ñWÚØÊ¹Tøº8ÐâÈåp½N„èá–r ±Ô.aú.—^´u¼«?ÆÓcpïñ¬-;yÜþYŸøv{`¯Ûo·ÜSÞé«Iyà“p0 n³Í/aÃh£Ùð¼„ößœ,ÀÁÂûþ>þg»t&ù¹¬‰¸Âh•I Ž"à@f7µÀ­rÛÝÄ?‚0´’5I€®ÅPÔb O‡mêé x+Ã,ñ ÈhÆev¨Ú6”¡˜-¶¥qhMô .'0Ê•@°‘;;#/ú眄 ¢µ]>eH˜¢T¸"W†`Êš-ÚU²eƒÊ²“.2©…ûiñì´Ô¿‹K*ÎHà£728,O8Gði]d¿s.üïÆ r…ø6)#+ü½%qÇ2gûPÖíþèäp\ ”Ñc[í·ßÉ.- *ÌZ|-§mWþïï;v0žåôÀy`ÿVHü)öô€·!ïõGg>KV¢É[Å6€z¿ [Üíª¿+ü†WÛ„ÒÁû€ÏäÞ>i‰HßàªïÇŠä@Ldu³ 84þI(Ï/eIZ š‘eݲ‰«v óUÁ›H“dEm¶ Å"ít,îs %Ì œ¦]‹C³ÀZŠÚQ}ò§– Ø2«Ì-!Ú¦¨ì„PGÎèOã»Ç¾¾”¾c¢²ü8BëÛbĹ´¾9ñ í nÙŽ¶(¯©µÃ¾%“;$/šï³Òíé¼ò–YÛsj@†ŽÉÛJjØ•~¦(µÃc$¡@OÛ;äÐÏV¿ô¿Œ1F¾ì0€ómÕ>PT¹Ó9§ÈûäÕ‰ÿî{¬æ¾û†ö`#20ê·;~åì5ï<ùj‘ãY²xõ÷ø:³5ï긓”ûý ‘nóH½÷¯ íAØÇ¼0¹å!Cž #¸…Œ $ •Ã1ɱ¹ÒÛ}`­* Çêˆçp$Éh.T{L"‘„j>mò{Ñ›oˀ㠡€Ø¾ÔÉ^!Ä`h!ÔS6ÍÄOI}Ò‡ˬýX7ÂòŠßYù®è%I²¤¿P¢Â© r¤wŬ÷õûò§Û¿qÑÜ­o'MÒY›m—.ó¡{š=ª­A©Ô1ºãƒ.M­C`]*:;˜½n,Öao9üºíÀ÷ü,OHCÞ‘¢íê?ŽLÁôú¥þ‰v.…÷xcæúkëj9§¾ýÈßË·_ì)ñôÀÕ]™‘?üðòÒï8ó0^0$YKMp•£)dàIþ·)…'ׯbÓÚØÚzSÉu÷%Ùö)ß×¾»ð ‚Fß&ÿ\ùp™MLF~¢ž >%Íé›p Ì~¤(ýK¶°²([žeäÒÕ”Iþ²Šñš9:›P.É?_a¬`‰Z–ÞªŸä82Ìë‹Éä)ôË<õ´¯Ô-ý ÆW)óó9VD&7}“ÿuRÔQD ò÷ Þ›$7”-\ZeÇá´-®¼¯‰Pª[¡½ÁÏé AðCãDCÚ}KòÊŽ´éXÙ÷\­8[‘¥ âýXvš)¥íþ3-Ø"C½uÇÂ^åTò^s+û%â÷—{ñ(ô,§Ì·“¦äüv{ Û§àO>æ'y€+y‚]^A›ð_ÿ4ÀÎÖ; éöKiM¢î\ñ‘õÐËyÙ"yt÷ÀÕ¾ÅÕÿÒØO±qSÜ*÷Í€)7ÛæÚ–t@#“—›½Sy29 ÎXFA+‚?Âv“] b ¨s?!RbrÆ:ynK ª>dt1ï¤âͼÊ @=~椬2A¢cé1[°É¹eÛ;Nûc¥ƒ?hÇåa[én?ÛÙDÙl"·¯}šœýùPu(ÓW®8õÚNÒ`-\Xô…!88â¼rB#­«$p«èb:•‡,JÝç„;ª%ãÉŽ#bfA)Ø>r^ø7ñäòÁ¼8¤çáôÀ{àœ<°ƒOñƵFл?b@Àó»{SvÅO œ²©ÃK“>Á7ÈÝ;§s×›}Á~`ߨ îp[ Ñž°»AXûæóZc¯oÜ"(:BÚ >d!‰¬»!êe!¾Y/<ŽéЃí°—€ÿYeÚ·ˆÞöÕ¤ÒŽŽ$Mi2ÉQˆ‘›dteLrZ㇤©»J²Vµ Í é\Ëšr£!tKkö©åTûÂÒ!©Ðc½ònåÒo W)¾ Â¥ÝFvŸ(\ú[â¼Úħ`h´(š×i†VúðpÜgEÙL{Bº[PN¯ŒRx¬ŒÖpb€7ÆÞãM€g9=ðX¸F…ÇÒxêy{=ðɧ—çìÌcëä*Wû½ ΆģO/w\I^›§û Àº¯Atè½›X@û‚oäèÈTå¿`’Ý€*ÀHCQtŽîmG6¼®ï%ŠÀ´@ “ò5"‰>\@h¨‚ƒC•Ǿ» AÌ„g™…ñ¿71±‰\‹äû‘V5–­e¶¤h= @;îQE²Ûà7òf»ä„F‘š¬º+Îö­ýÔî¶ß¤¸Ë½C¶õàµh»p?ãªÔñ"„åYÕxVó`Å”é7E&GÉ2®½[}Å+­‚zå^'(…·>®¬±a¬ Ö+ó•·Åø{ð‹×ÚYN<´z ?´–SþÛí f|Íé%/;Iɪ”VâávãQ‘Oû^ž|H– šÝÒï×ç€À“p,½B§vWÁ¾"­ƒ£²jÒ=’à-Mùú ƒ ñ¡†¨’²e=B7 Ý—«¢ou' ¿‘Ió ⛯BV ÆH Ïë…á —­ã–fr‰Õb½…þÑöÞÎȹ¸ÝY>ðäéM›¥dÕYo¹Õx —hïwGd9¨Áí¤"¦Í5qÿ–\zú’…>"ðk€…i—8i¶½ÄG8‡!KÛõš³CÉ$â)”™ ªC.K¸ÓR´W™8ê·8~qÚ¹I<8û`Äm±­ ÿü]—4Þù°€[º¥?ëÓßnìuûí–{Ê;=ð ¸ã'_ókgßPÜ7ã'j‚5Î6©x›<^<èyXM>Y½uкýmßOJì ÜFÙFì0$ÁûüÁ&MôšC$¿É%Ñä¡òÜm'ðgŽòÚœ¿¶ õ0Êg>ÆX†ÀÅçJW„‡~ÐWšf6…)Ûæþ©¯>`‘AíóA£HG"$ª©-C1cm¿˜ëq}$d“ßÊg‰œkA9ú2ÍØS[=`LñgN}Ñɾ„¿‰÷’sÞ G¢nydL÷ø=ñ$´yØÏ(¬hCìˆ oÛ× mp]˜×íC‚Šï=Ù»ÍØÔÊ5ˆÇtñµjäWš´BÔÕa¬I¿¸Ì –Wî > Ä Om»Íc@ö¶õ¤ZS¶>pž?–"£Fî2,*8ú’rQ Û›|Žùô,GRÿ­ùÖÊÙ²AÉZ¸xun_Fõâïùuø‚›A*ÃÏ*JŸƒwXtpŸœ[ÚÎs”PÙ“V[²Ú§³É~¹rõMÇg¤_®@ª¼"äwž¿üy8=ðÀØ¿µVsŠ›=p—ï°0ßeuÃCNÏøæÒ3"š ÔGtœ­~ÃìÛK•P*­!5‰Óíl—Ä®lÅ §Ëg*D>˜44I YŽŠXªÊh78#+Åú’RƒeTfÀöú‰}´³²Q §‰íµÎ»°•Šö³—oPG½… ng‰iZ²ÛRØ&òìAçi¹’„ç–ò$ÊE#¨:ÏLLÀæÔݵ±¼~)µL7)ÓZz?{k!ý±Ç¡Ù—G×,­ØD}œ3hŽ"%.ÿxƺҷDî2Ó–ÀÅë»”H-ýnÿÛá €×”Ÿþ“ly½dž~ðþå>–ý›Iç<œx lT} ñ§ØÓWäGN>ÿrc"ô"¼&Ø69'‰8ƒçDea‰ÚŽéggš$] æ’$Ú­|C3®!\ô«†Rob÷¡ÀW¯œL¬,mò¿·TKЕœ¢O¾š´ ók6„å ›ä×2Ï(+c[¦Ò!·mÙþÖ…þ#ŽEzñ7;)×}Œ«?V¸\™,ëº5:¯‰þ0úøÒºšrŒßùŒ¯¨Þޤ4çñôÀCyà¼Úʳ§Üoî/}Ævísr:A’è× H˜L&!lú ZVí²óô•I’p›dÒ]iš*f×àž6'Ê’Æ€Õ³Á[¸*7„÷ÏàåîÈ`Ñ>ä4ˆ{l+(p•QÙ%gbƒÌþPåï0xìäÀZf3“ôY•_eK[Uàùß.ýk8”³ehËCçÞR"õD/홈È"Y¾èûÂÓ„K£ÃDµ6ÙPŒvDõ¶­ýXâ“6Vé-ÖÝ7é«\š[µåY )M¸ÕUG˜Öô¸ÐQQw(Dø¹Õ/†íDaÈ©JÓ#g¾[K"FçØ««ü½ *£m¯ªµÍËúõ‹×—÷ø±¬'çàêê³õà8 àÁ]|*¸çO?ÍjÇÕ¥ÅʇíÚ`04pζhÂ+‘8_´Êìä%Þè©pÊ>høºí¿ä¦uÍ3&9!×—½RþýÐ3!q‘]åš°×võ»Í³N1|ñQÒ2„Ty,ÀI€ Äí ‡ö`¦•ÈøÑô ŠÚNY¯ðH \¢ÐYC q÷fVë­Ž¼ñ0³0üÀo48¿ˆÇâDXa7‰Yh2öÔ¼ÉQ‘+n?4'½>­œNðò¿’ü[2Ïæ8 –öZV§¶¨uÏC̽AÍ!xáôÓÖ7†Éw(’†Ï=˜vcœ×gžÐPˆB3õ!B¹¢åIëZ+÷zÍ3•Eè;w/.ï~ü1²–z˜ÎêôÀzàœ< sOÑ7H4gCý õί:]]ר ·Àû(•?”#ÄÛ1ZK³`¯2ä3z—Ç$嵐=+WÙN"A¶ Û½À#„tº¡+T¹ê“;Ôëä@èimÙ¤Ú®íFM“%²ù¯õÉ;¢(±-þ!1«Þ"‘¡IQ €$Ía°Úþ­‚À8¬Üd0':¾’ùúÌCv%0*Vb‹I.¬µ"®íª*ǾbX°ƒwLʹ¡SfÀbèÜNÄYÔŽS*; =»JËŠý°¬z2Üàäí‡*EY¾9þV¬”èâp<ôg{p ‰ÍösŠ ¼Às'\XBÓÉdš —v& * -°Ö×£z½?8߈wÎò˜ðò<Ëé÷À®š/¬rújà ‡“Ì»òÖôé±³ZOH€^¶ ¿šÞ]‚½¤¯+}ƒ¹)$ÉÚˆî Ø[ šôm¤—t#½mŸP'<¦¤,¦ËëÜ’8ñ”똤`<ÐÇü!<ø2yÁ¦ ÃÚŒgÓ,/<Ùv9èoÓŒ#~û4#Î:°ºøtõ‘¶›©Pg^Lt—ä©äüí‘¥9ŠTÒhJâÛÒ¿-ÖÛÐȼÂWŽ\Êß3)ýâl/w®\Ý`©§/[ºÂl§›ŒØÀõCèoù‘fJ›6ƒª‹nõ«çj§º×éSO.ïòž ËÚ•Îy8=ð€Ø¿¥TqŠ>=€&ØÞ}Ä»Îù! “ŽÁÏDÿÊÕøàMи¡g°Ìg£'ý¦‚ë%,>üeÛ€­ûÒ«yuni4ÅÜ+Dú딤‚£¡}H]£¬ŒîÚ?1쎤SœGÅ6£,û²hžm3‹—²ê榄eûí'Þ’šÃöáLº2Öd»EÏ@䋚 öØÉÌÚ]yŠT†ø>Ö`¸} Qž[6AŸ&­¡f9dÎ9/Tx¯ÚÑ3]è›VF÷à["wNްôuƒ;š ,ptO_a⬠j=0iP}á+\·zïC ÊBOÝ­ná˺} ðñ· ïYN< ü»9Ëé÷À^hO>ùäò’÷øF;ƒ-ß ¸‰„F\)›Ùí»&œIAÃîMÐÖô•n›2{H ‹\q†Þ¡ÏÄ£º’ücwüó0\ÃsžzO–gn!ÐJ>1øù†Â^„ŸZ^¢1J¸ jÅ&¯Ç7cXD@ª@~>øíxNL—,¨m†>ÛòY@òÿÈZod/_V“y4S´+*©Å&¯˜–CEúÂ$I-&ùÕñ‘§ &ÚˆØa+ —U~qõÛa¿4޳8ŒöÓ·²´aKÎ/ˆ˜Vd‡&W02ƒ–1ÙTù¥92—³ j½pgv MÁ9:Ší°A9pšN¢K0–òc@‡.ൎ²¤«Ô¶*vUÙ¿- p·ëÅ÷ýØ<ç`ÏeT‚ÇýØX«…m[vÏ””ÂÊzûžÏ!8Ü4íR÷(¿×fôŠW¨ˆo 2Í•¿xµ´v½É;óʑ݌ÿ!ÊÔ÷îý! ƒølœx`ÌåøÀZNñ§ÆO>ùèò‚€×ó«€®ìÍ0ýf>Áp"îË$æFƒ}²ṫ5Ó‡†\“ÿpo÷`Áe©|³D^vl{õ“Ä»Îퟂ«;ƒqß ž"©/쉭щþÈZ¤T÷Ë5ÀChV°„‡„AÝ• ðd‘Ú5e³‰ô²Ê`{©Rl\–È~”@ …ù$¼WPÇîm–À°)·_è¨Vàž—'œ+iB'Ž’¶4í Úýø¬ÄâbtúÇsYÍå]™Õ¹½ÚÚ¤»<ëŽ[kt‰œ~”Óë¥çTW煮Û!Úº<Ú¹×\Tí`·‚#[ùúªúlˆÞZ¸G«ÓkËþN†ö”»ñâDáÝ>”ûÊÐÞy<=ð`Ø¿¥Sp >= ²B§öoåOL‚ÎËw¸ Y*R¹Ñdâ$Y/‘Ô$å¿&î7‰'˲يæ}m':«ëºrï$B&“º“ÛÚâ´€‡è°¢QòÅõ¤‚Ð’$g îrܳ1\Ueø—™ï®2¡f7ø³Š–|uo-MÊòPw__¾-]ÙÄ•ëò6°3+uý>4G3P>k}ȆVó-óô#LùÕºÿÚÎyƒ_¹~¤Õ$'Âw²E³ýÁ9IZ [¹>„©pŠ°È¢ßIIÊMQ4êŠ8€•[xx‘gmÉ­.¤ÜòFçžg3VŸr½¶x'Vþ&Þç2g9=ð˜¸ùSxLµ§®·ÕÙFÏÖ9IØ0é}üIlØÝ6ö{éûÐÕ&㉼L m˜L µ³ 8…‘à“€÷V@wùe‘Å"©Ù€Hl¹™<<Ͷÿê )À`­É0÷5¾<µ`p>E»¶;ÊUæH)Ô‘!pˆìb&ÉxºH`ßtB2C«X‰ù8–ð!Ë 6e§TAÉÀvÄags°j#AUEŒ^‰¨ñÒÔ¾J\®NJëW='ϤÌÌìXÄ‘¯7X…VŸÛa¯Æð-b$ÞV¹ à=l¶ AYj‰íQÑšNæc#HÜQV•­éž:kËÞe²ÿ„óøÌgµ9^ üùàþ ”û<žx8ìßÔÃi8%ŸÀ /O>xïòšO¢¢QWÄFM:vC; Å(m@4HZ'0A³m*%í#™ºµ~' 鑵7^“J6ZCx["ÊCòÞ’V¢µÁ?’ŽäéYöé±JvÁRjdÄŽk½yØ´¾þØeéÒ:æCBÚ¢¡–LÔÖ4STüÍþ’£뱿æ(«–ÆŠù€·%êÍú9‰(2:¶µ* ƒšÞOzªë"õiOí=wy—?®|?Ö;ñÐ.‡ž!´mse-O&dʈ(ëÆ[sj#ä€C«éÅ/Mú¿Åídlévr³ú`9ŠóQõ(_ÃsMg—˳wÞ½¼ûÌdåôÀãyà›…ÇÓ~jzk<°‰€=¿¼þäSî6ÝŠ§¶d¿xÚ…ä(¤«ä+Î[OÃ'Ì„k‚²½‰ «úèÚ"ì6ا£˜|Ø9˜HnN4«Öî{ÄQÚ,Ò…@–I¢½}!¸¼­iÃãWçŽùüFíÑÎñ—YžÐ wÜÉPÕ©êЂº–d-bø¬m:Ød¡®ìC‚¾¼ù; ˆ­ÅMj%í<⪫ð ÅCwûY:ÅÈ¿^j)8@IDATžKÆ^ÓÐJŽð„°g5r¤å£‹b+ÀÀ—í¦ÿôcWxä£Àt‹´ýØ$€"ŸEXw¦Ú¿ÂËUž{m2Ië«eèÑæ”Õ+òÙûÏ+K~Ö§ÈG˜y ù§ØÓ÷<ð„ À;_ýJ¢iІÜËÅ+q£f2ÑSlƒêÒ”¨Ú˜ M鲡˜«Üî DG„Ïî€û²î<t#„II%;‡g$úN4Áž,ß Ô~C@N'¯ØÞÅ4®X˜Æbçª H[äèª< e\†þ˜qˆ_˜l5:¬é„ÏDÒ¥oÃtÿáMmfâ^칈ëúSf}1Ò"Lö?EÞp¶*|~"³‡m[_åØ[Ý«+Bó¾‚"È󬄕ŸÉVTì’‚þâT¼$K0/ýÐÖ¯9}0¼ƒ ¯£÷¾zþ°¾>Ëãzàœ<®¿ßzmùµ3Þyî6°yË@hPíúÎ`zSŒ´àR¦m°4À&°Â•œTòû.+ÿì©¥PÃòðψ_9¥õ˜"8œrÇÒêžä;òMƒP“H`Uçµ–ó&µ‡8‡Ðç"b×q«DZSKçG&ÿb·¦ya~jfÛAÂØ™ÖÖ>Íïd"zå£d Í9ïÍ ÉU‡ÜìÓö£ÎlÞØ`:Ç©kzp¾€giT»r´ãÍ•ïN¤ÛO•®D¡”èÄÖíÒˆc`tÖ•"v×F}ÂK[Q·ÇànÚÝ1 ?{ jÙÊλ+§‡³cÂ/­¤ÆqO‹ó ,;ÑìyAÖ³gçO³Üúÿl?¼Î ÀÃûøÔð¦¾üe¢$+q^ l 56ú%;ƒ©ÇÄÕÍ[Á¬7Q·ÁÖ€[&‰ü˜:š>ŽãQ7DìúüÞª[â¦9‰S^»# =K{?›4F!42u‚aòï­ƒb#ìæl“ÜÕ¾iÁó_hG_6¤b–ŠQOзL[¸bµuhnàÛO-Ï®?Ì-®a ÛÛÐ'áW³ÐÀç?)•´¶-;Þ˜'üV—xlÐ;a(ßrC?>0Ùž¸Ê÷ë„›¼¹Fû41q£bß䳿´Ú»ø´a0Áæå¨+p -ö©ö×-#—<þ2‚¬Áâ´ôuQö_?ë$˜îå]n‹Ý]·åôÀƒ{àœr~‹.~s•ò-²¿ÝäFNÀ—¾D>êÖü®:}:Ú‰À½;ôG´a”5rìÍó`p¯ICúÏ´ÛÔû*LòAiIíÊ»ÝÀÒ7X«ÓràHôŽŸÎ½¼âËŒÑ# û5eÉ¡]~,½ßK#cñ&E9›o48ÉH†Y:õÑ^[B+Žeëö®}éÇ‹JmöAÕ™lŒãŸð]4s•S°¬ö9è?‹ãÔ¤ø“º \ÜUù­Éa kñŽÏ®¿ÊwàhÚ˘AÞÄkÃD¬¾Ú‚¤1ÕÈ-ì’aks\m?úÇb:ëÒC/ŽQÞ¶µ5myºêo»~À ¦lâÌlâ5y¾tìŸ[DtwÎÅø‘ʵôþ§çOë—³<®Î ÀãúûÔ†^s ÀT™˜¹Ù1¡œX8ÔàjÐ>ʉ²P“ì¡KžÕa‚»Ñ\"½ò¾ í›îÎfáG1JS„]³ LQ®ò ÖüÏäÅÝ w1ÂdMcÇÒ·;"˜oð»Z@ËþðçõÆ ¼Š« ÒFž4*Qe‡cÿ€/pñô»‡ÍeÉŠï¨ó`%räÜp¦¯Š&rpñí*VÔRvte¢D(áΆºpÒ&Ré*Ë ƒv„¤|ô¥«eâ[–F€CÑ-q´Z«®Ô%*ð°ç†æj@"O^>ûFËì&)=£ª× ½†¹ò ×Õ£BaÒfÌÔ¹>rŠŸ0øÕ͵Þy8=ð°ðš<ËéGñÀ& ·:Ÿ¼Ço$©NP ÈFw²1NMÐÑ%êP^ƒxƒl“‚:\¥uá*ôµo[á¢pÀv¶˜nÔ3™[]†êi#Í•Ú-Ëqï¿D;¶½/Ô?®Û±Þ~‹¤Ô¨Û³êë£8º2ö O²ä¶kR{ Û9°¸PŽaü¨“‡ô¡à€Ù˜Î8)·ÈJ&üÛU1„Õ‰gÓf,y^À•u˜@ŸÛ_˜µeÇöCU1{ Tæ¬oá…>,Ó&…ŸÛ²~“^Ü!“vh—ÂàJ{ÁÕÒ)—wJR¨3‡ƒ(°U"kG™Ö²1™òü¿Y–=‹Ñ­œO>û¬¤Kð&ãÙ?=ðø&áé´œ"OÜz€¯<½pÍò¸AÒG¤5èNôΪ @³Á—Àè§?lÜnØnÒ²æj¡5b›+]¯k3ï2.ÚàØÄOvf@‹òn€ØâžVI ›$6!ŒQ±É¼c­løÓÁ‡Ÿ´»óµ>bëÈWAܤ![Ö' opW¢Ì‰á0÷A<³ IÜ£B•¿© ÛÝA~RFlú².xàvc£ˆOãMüàB;2–WÒ•kíÞ^Éy9êôóŠkÅ+ëƒ/Í jÎãéGñÀ9x7ŸJôÀÚ§üêÙs¡Ñ`üÂiÙÆ{ð…p¹4“ͨø·1:79•y{ „„ùoÚ"@£Ký®Îó,‰ŒÔd?êHÃÚ®roåù@@¾?À¨¾jC¢TÀØâçIÞ1°ÜZïtâZæ&AŠtäcj¡&íxS;QQ dIþض¾‹Í óCJ™1I«ØpŽrA\å%QˆÝtâri½0Üî ¤½Ù5ôW»4X²õEiÇãÄ"s.êЊ/Á’ãAðsPö4Wþ¢U±8aö3~;  0Ú+Ãk"¾ ²RÄ¥ÐHsûiï¹ìi9×ÌЋïY×èQ®ù)÷jôzƒç½ù€«BzN<¨6Œ=¨’Søé=°ï ÷;_šŠ‰ÆGìòA4~V'«·jÃè†Ú&·`Ű]Ñw5f¨½-öú mzW yÂh¥gG!Ë·Þ«5ñeµÆÝr¹¾3xËiªæ“I@º,µäj/’KLa0ÏÌžreaƒy¾ý±q+ǺIׯ >,îÐ@¯£Ï†ÀŒá)ŽŽ•'Ÿ,Èõk†ñ;ÝN>D¨kjð›ø¯i)œ d’0ß…“ÆñhËë…QÃ=£N4ciá;äú 8D¶r’É•M?¼òÓŠ|)Äå_iV_$Š‹È2ÎNš®’"NÉòôì“|RÅ»àÒæp—Ë£‰Û‰WèÇÙ¶£ÈŠü-^ÇÒsn…óqLÝïžÏ¬“Îú=p~ ð[tö®b¿E¶“ÄwÔ§xyå;t·¬Í’Þl&›™”ŸP7’)ö–©&Þ^^ÐwKÿ9,™Ý7‹7 KªLÞÊ6k¢•Ó‡á U˜ºƒ1”ß2ªy®ü͚ݨXÜØlÊd!¶’(œ&(%zÉ‘£;h’(Ú&ì®V•òËŠJUGÆœvZBæá¶0¦$¡ÀœÜÜ ] )ÉÚW$tÛõ· FÉ$Àwì.…ÀuhHÐ@?߉§édÏ H½ qíDxÚ²Ôÿ1E†ô?èñ{v‡GR¸!¬mÔ£å56cЉp ¿b šç02!ž!8^hý¯¾<‹Bˉ‚ý¸Ë†Š<±³,…m+mômw°œ|ðÑG´±s>¡=§Øó§ýÀZNñ§ð€ÛâW_úÚSrW¢®D'É›$‰<÷Ü yìÓ´o¼]*7+8ᴯŞŸ‰ÐÔYÁ‡ AÜ m0–"¼(H"±\“@ñò»Í¯DìÏãß¾‹Ü=Àœ Á }_€e.-èü4¬ä©§¶jÁ–$'‰²Ú™$â”B%N¨LK¨í|<e;Ý6„mTxwůÀMþkó›É_ÕI¬úÌ$¿cC°ó¹&âÑ¢£·Äöí8æµÕ†¼È¢Ù!q´À]G³¶g|ŠAWÄÇP÷ ”;÷œJ®Ÿ„»i±&+ËäŸëh•Cº:<ç± À4{jW>ÀAm3ƒ°¦£È|l¯P´ {Â7bÞûè)ÏrzàQ=`ô8ËéGñÀ¾êÔUÏϘ@sÿYíûÒBbÿ%­5@%o‹ýYq ž¸Š´Óꡬ ³¶6‘[ ÓMš}qaûÀ`úPjSþXö&{Öó³òW̾ ™MY•ÃÁÃŽ}&ÚÉ6›(“ÜÉâv³òMéo–XhÒPO²M«¨Ý$Vt˜ø7‰ ,š{nr¡ï9W°W¾ÙÕ½ç‹âXB§|;SføéÝÊ;l“ùŠrà3§úB¢øÍs ;üï¹±)ä3ι#P¿(Omc†y…¡´ÝÔ%né‚U§t‚ cx¡Š^|X›äëõëYÜ"òäñwîæ‡¤Ö§ÃßäÏü1Ôž:ÞF$`ÎÀŸ~øÑ-_b¢AþÜ€èçe¾ƒÏ¥é.@>‰¿á|N0íN@Ã툻(3q›„Ò`í\Âûú ÔaP‹EÈBÛN‚\”5ü†ø&e#ö®*ÁÀf²õ©üÒ: £D4æOlÕì³ ýÒÝŒƒ¦¼B2FÑS”¢Xë¦ýPýT)I€áÖ¿V B™T}Ý0d&xa>Àèr—¶‰1iл”ׯÐ2cÐK“;cç9+VßÝå}^t}>FÃÏrzàq<0‚£ìÔrzàÕfˆ/–çkpM´Nü6‚ ó[î¤ÓhÞö$rãë&Él{%¯3ÜÄQeùrKÁ»ÏãÄ¡¸öÒ7]Ãü½¢L>ùm÷D¦À¥ŽZÓétE„Ú)ÞÞ°ìr´½¹a 9®‘ŽÕ!*¥Ÿ¾ÔÈÕm8¢¯¼¡DŸ½ª¡S§2åüÐNá(1QÛÞ(eåÖ; Р¥³öt9_+?zȪ‡OÒ¢Íúx¥*ßœŸAèé»wêµàJÜvh_¬ >­Ø«¼èñzçdɧü«}ÀòN6hRÀGpj›+Ñ:Ÿñkó-j}ë/MR¬ýÙiÏwö^¼-d{ Õ.}°>EÉ÷w:‹˜ópzàQ<àßÀYN<º|á–7vÕ×­#ÑÑÕ©aÔò‚çò ÙmR¨,ö“õT¢}:ÅCº+ÏÒ’$–ä6“b˜·TZÛöìË7ŒV|6ç^±ÙBØ!Óu´¡ÝŒ`ÐoRH] #?“À•cÕLRÖo8Œ UY]R;©XsèÇk`‘u¿ö 'ôeJâ±Lª–?³-­ÃpWGŽ•{ÔñpϪÅA¹óŒÀû´7h^?óšÕjäÖ÷ÐÂÜ+£“[ådbÈLI¹ðãX–ãZKï<œxxäOöáÕœNÔ{Á=õç€ß} Á3A¸ÉÝP™¨(¡‰"¯Æ%dZ¿0‹0p6$ûbo$9tmÙm³˜X »MCW”X>.qe/|o j²0ŵ6ÐG¦ƒXþH\B;j ‹LIùÚcwfG@ !/ÊCâ+c%uP¶˜~Ä]¿¶ÿ“k‡·”ËI ÃöŠƒž„uç}ÿØ·Pº ìnw,0}“~kUQàzc§+™@Ÿd˜‰BG'ü¡oÉ÷ú1FyIâkÛèDH¸eébw.ÊM=œrdzîõ°â‹Ò¢ ‹Œšü36j'rR‹·ÙO¹"WôMqrÚDŒ¬îåè9 bྷ´¶ñyŤï˜Ä‹Ÿ\>ä·1Îrzà‹ð€/g9=ðh8¶\?öÙB}ÁSëß—û|°l0¦NP%ÑgÅdÖ1øö»Òð“ˆÅÉI€Qÿù=Ö]az έü&Qx€ù‰lynJþJ)2OQ¿Üx×B© ²?6S 7ñ»Jt?«Ëˆ”œûç[°Â¢€ŽãìçYt9©¡çX)‘B·‰múãÌR“;N ωÌ $[ÕïÒRì·•dÖÑÝÀÀéÿEO Í“#ñ-ý‚$Fí—Š‰@tÓí$£6Ý ¯»Ž¢5ª>ñtô|ö,¸.÷áá3°¦¹:§)_ïsbËEƒ‚· z­_”US©IZñã3ä$Ás(YûR¹Õà˜„{*ó<ÝþÁç|%–rÿ: è<œxPô/ìAUœÂO|£ž~öÉ幫ˬœ‰„$0“·Éìx#[¢3A“¨iHuÅdI7ÒŠOéZJº^“$è´©]I›+.ÿ€‡@Ù-çq?ƒHˆd§Ð‹Z´FØáåš^61f¼c…$¦ìöO±–L¢Pýköúì¤Ø4µª¥×YJÊtÄýÌHRµâJô§?–´Èx´#s–>ç$!ãÇŸì*^Û™\I+¿–u{!â@>ñÜ£ íœX#.ðiSÇÚ2ç±=«H?¨::£ª[ëê×›Žm½rµžä-Íz°”>Ô§¾è¤ÖòÌÎ'¾´*dP{Nô‹ õ\ú¡Òz=z†zy£gëã/}IÂÑ•æy8=ð(˜§XEשäô@^Æ¢žòÕ§çd“½=ÛØ" ¨=$9¼û ŸiT<µ<Ô„á)‰ÆÅyA`5öfWº$§_è’ÐîÓ+$I’Z™opÖœh¥e¹moÿjϦןr÷gGBvn?$sôÖB(­aZíôÆ·*ß‚NÕF5@÷ÀédÞ˜4@L(Ö|´Ã1g¢D_Q6[ý³ÒO2r Ê ­$$!Œ É‹CjÏB½-N®ŽPÉÔD ´®à}žãµ ~†Ô¡­Eà••É Ôg!2Xäd’"ž‚蘇ü( N ׎Un`Í‚SÇh(°!jÎnFb` ¸ûâý¯T65:¿=QO¦›±çùu;Cz‘Aû²TuNgt#ð8W(îµQ_Êò‡½÷A_Ïrzà‘<0—ë#i;Õ¼õ0'Xžñâ“ç$œlUgkÔbi0µ$ErØ÷„åcPåŸ±× ›¸.k @xÜbõ‡‚L/ñËl„·på+#Á9me•ÞÆÊ´æ>²-Üv‹ú¶ÝF“Žùà†ÓfŠ4~nS©Vú§H2Ê=w9õÔ!˜¶!Êŧ[Ö´!«DÚí¦–Ô”æDHénõ„&¯8Éзšrßo @s;ÕrÏÚ¸vîJ\=&ù$ÿÈlò[õ/ŽóAÃWØÐÝ'9ÂgLòMB-U§0ûö„!SZõVv,œDð" ''>y/©ž3ñ;:?^Âr¿ž¾²v¬¾ )·a䘛Ét Ÿ]í+ÛO&ÊCu^GŒ|9þ˜:m{™ày-–QHd*×·^1 þ`žþ,§Óýk{L§®·ÚÇÇŸ¼â©~Béå%³€ñü}(+7ÇLW¨ÆH›²¼—ßß­¹3™€Ç—ød²€,ƒûÌ.ÂdðV¦¶¬•íä# @Â2uèÒ ù"¢’OöÖÎ*5TG^ÌcB»iEJúØ’Ä BZKir„gL@nëX”î¿—d&Ok< MS,]S­¾Oʚɚ%¾pf¾€æà$Æ&㑚ú·ðLZ€¿"ƒF’´;5¦8Ò'µñ<º~ŽéÖlÛgâ„<­©_cºòëC„cDÞúÇ·JLÜ~J4ãE®2£AÅÛ¯,ý ;¦^¹¡—oy·ïË/®Ÿ|=pŸ]Q~rªòÞ¼Ö³œxTñøQµžÊÞZöRž}ðÑåÕ;ï6ÀòÓÀ&(a?+{CªYŒop}aЖsLS\VûP%g† aSš-‹‰$“…ä¹(´#ü •ª…‡‰ 6øÆâ¼µ\)hKËA¦‘9²I[c{iìü­ZÚØ¡)ª«kIÜ¢^ŒÔÓðNâ²7J¥XýN*2ñ Ô] #Sÿ’ôC‡Mw³*–üÉ]ï&õŠ¡@gBà½ý&uˆv‡ ”"҇Õö«W$íL@œ„U)zȉÌx*0Òt5ïL”Zé9GÙQšÂ%jRF]†Qý°‹µ¤Ö7´€×EƼxåÄ^bü¤x]æÚ,\O.þZ;'Vî8 kXó-ü½ï’xÅk±ßã§€Ïrzà‹ðÀñgûE(?u¾}Ø7žÝ½Ë»Ïç'P@ùNõk²H/ÑÒI€[øGØ¥-ÎÇ´š2D€¡óa*·©R\_Ù+pQÀ+˜&Êrk KKQ! ÑZ›"iÊVW®>¯ÐÉ@ÓTìƒvH)ñTÖ|Fjdæ!G$VV“qà]s2º¬ÂMwh8VŒŒldWÃGÉàœ ÅhÕÓt,±lÌSk›þéËÞ j)NÖÃ#4«øiËcr„6;$pÜÙ—•âdÂÒs’VèãøIöÇV÷ÐJu<à9£(%Éž~Oãj01÷ 5áÛïÉT+_>LÃa¢WVŽÔ9¹Ë]ÐÕ¥ ~ª¯ÒÒ&ÙË­rª:äÄßâ(é['ñ»»UútùuËÚá-‹ËÅ·ZúwðÁçO㎳|8'_€Óßj•àïÞáKl_þÊÉ ÜDàl¹²‡œ J`wƒ÷¸Môl2x’çLp ±G`žàM`î.BpUšúòÀh ~ÑK–b•9²¡C;ÐæUºüµ¤V_t7$A3ªK­ ñ~F-šv?~8ä Ÿ¶ÑP^rÒ6ÙX“:2ý ß²5½È¨|iÃ>%ñ½ç nØâÚ]}—¥É˜ÝÐ#†”I€¿°IÒU²>H_UK+Œ¾ïÈo ØaÅ®éB2ܹ—uVÜ’úQ†0l7©;ñnýŒ‚Vmš)Ø–¸Ÿf΃÷ nЉ?ç¹®êµA3')¥>¿€ïqÚÔ·»Ö݃ϳ Iü†Ôë¹ÚÓzà!‡eÎ åÇŸ}éòþG}Ð11~–Óá¯Ö³œx44¤ÐyÀ³Ï>3ª&àû⻬®ÙØ•R“ÝÝå9«¹®I'@';°’'ºz+·e‚µÁÝÛáqÕÈ»´uÛ&1*ß—F€TT“ƒ!I:É0ÐÍ»ú´‰mÀÐAi“æM¡aYù׿¨ÈØ•¡è|<`O’|9ì›”ãlH7ƒ¬±òYVp{ôpTxRy»|·`:AHò„Ö„œmr¾ÏßjÇ*‡D÷Õï!Š ªyòœ(œDø÷7U|Ój_˜CŸ„åÛü|ËäðÄ,@ß l’7«ÐuÁš¢'Þ›6}|M=⥛2iÓ7qÛK£à'qPE 0ê$4PɡЙ`ÜÍ6ID¯¬ÓŽÊ²Hk;§ëLôZ"§_}”vxH*IB* -IÅï£'Ù°>ÎÀGÑêƒ÷(¶¬8œüzŸB·hSÎKpe6QfU“Yý[¯Øð9aÛ¯ò™#2'.²®l¥†F5Ýc¦6ÀØ©éWוI|†öF„úÐûû}2¼¶äÉHŠ´ã/Ƹ;+²æ¼BjQòJoM Ï8ì­UÛ޾ɩy ÒUõúób(ˆ¼O¸–Þç{[ ²³œxTœ€Gu÷©Ld+šàøìý.¯Ÿ=%§š$6à.‰þ¶Jb¶Ñ›(þ$·äžon“D³- ¯yms*©'²|ެÊ0 +ßbÏî0u`êw5r6ÊÍÀÊNNFóM´ ^üØšDͲ\‰zo<ÑžJ1-ÊžphcY¿ìÊwq¹›cKèDÁV¥d4ôQÇae_õƒ2!ŽŒQ]y% tïpŸäa½ v&ĪPfAùꢴ(Ã:ÆmSÙ·¶jãö•¢ToöH¥I]ÕC\ϧÔ-Ý!qä:DBx¼r7/2’>„gb‰t¡Í6‚­µ¯ò³k°:s>B]yW)m»bmWžcQ‹çìá3´¿òP·ŒÎƒ_+x †€È{–Óésð-zûü#ýöMÈ7Ñ=ùÄ{Ÿ†u¶ê¹OÜ$˜žˆmþô‹îø=vSEÞ—œÜàÙ÷U­>7`ñ˜ ùŒÏ¬LZ&6'µpØi`&R'EÁ÷T$óMZÔâ2I`¢±LÆ´i']3(å)ñ«ŽÖ0fRX¶ EP|c3}–®$miÏj‘?ÛÍëo%ÌôFÒŽ+­êwÚcs-)Î&÷Úåî†xWü;™Yÿebõñà£É_1øP.¯÷P:¡«?M˜•ëDMâ½ýP[zÔË®¦mçœVKv/ôµ~wÈY͇ ˜Q®“ðé:^uD|mPTÔÈï¹YkMä:ø”á9 \òú¯Åó,Ê'KhéÛ‰iã åk°~ôidú£K;ãy8=ð8'àäSÅH$d•ôùgÄqRAÑ@¾‰ÀDÙàß$ܤh Í7©È]™:)â8/¹QI4ÿºk ( C;hŒN7Gà]eïä.á܈M° te˜\¤Ç~aÉJf&i­” bò~ÀÒíWƒ×鬑92§QA›hÒ2¯¡‚Fg×ÅN‰\GûtÿàW¨uE*!¶ErrkäMÜŽoi©Mþ±epG?ÚÀ€s/]E¦¿ n»#£×4É•¾»7ÝRwh5¸g®FgÌЊµx=DGü‡$²Å¯NJñ>u…ÙÈë™8¯¯Š»É™ó ¢RÊ-Lw;c„ 2€Šr¢ã¹0ç÷œv Š,‰øìXzú†ã,}ðÙ§ÉŽ´ÏÃéÇòÀ9x,OŸz¾Áï|ö9ïà…@DR÷‚¢?ƒk ïj˜ÞÈÉÿM†×;:YýwÑU)Óͬp2‚É%¯¦&ä^mP1× ž0†æ¾¾—Î& 34ä52+\xcƒ¶Ù¼)·qÜ1Y6iÈã-û VBþ»rŸÿ¡2ª[€íŠb,`òBøwb“—÷@ôd”»ºô>¸_!Ô†¨Ê1ÙtÛ»cSOX«¤ºzc3Ý}ü6:òОçb|š–ñËy‡! Ô:ÿªÝ€ê™©‡à”Z&´VN êò]©£àšëö¾4úƆ¬ãø-™d“,ˆþ¶Ô‹ÛdWK€%i(·ø…;È»2òƒH’L²‹In’[Vº’Ë pBn裡˗ç&ae %šÅK#>Y¿Ö¹ò>ô—4¶u´XŽÈ-8}Ѳ£µË£:eíÖ2¦,ÚD%Þ²+þt[n9Œñ ݤôË«»rŠj;ŽT:F9>KŽ1ri¦Æ/£L(¼œ¤Í¬¡ø\ËO[¦¯=+×zÇ"™Å9J` u¿ô/ùš‹×àGóK€!<§Ùçà‘~ªÃ“„ÞÿÊW./üñ·ýy-°YÏØüó„ÓgIüŸ¬6>û ”q9"Œ¶|x“p‚©x©ÜI0 Êÿ‰OXâ{k âœbÀdG~Ò¹}žÄ’u»¼4l÷þ:ZʲÑÝìßΔa’x:ËÁبüµæ¿ú´<}°ûüÅåïÂøÞ¯}MQ¸‚³œxd4Þ<²ÒSÝÛí}Úù“_ô_~é¿÷/OÞå­€$Þwïð†?¶F œ®ú¿NûQ9)›Àkœ6Iú`ž¿ëþr^Šã;äIÀ5ð&lûrS8‰‘«\îù&ý8¿É ’¬¤ME“€ÐF¯¸>ŸØ\©Â‚ ‘Ä!€ºL4þðNžIìo88ÊÐJ¯>ÓK@&î ø¼‚_CÌXEÞã#Ì‘`Õf¦'½•Љ€ö¸Â|iÆ‘Z¹mÄ>:.}öÿ9Úq±lû[‡]Yùx´=õ$°z­4·;!†V2ŸÌ/zu°¨Mþ´Ói­»Õ=zágñãµÏAxÚÂPw´CSÏû›iq},~ý-ÿ ¯x=SŽ«ÿ ™^I#Âüßü÷ú}Ï_0©ÍñÂßW¶ù¼|áËÑõâ»__½ü¡¿ø—/¿è{¿7çfÿ&@ŸåôÀ£yàœ<š«OE·Ø­ìßð~ÿåŸþ éòÿâ_vyöêëIš>`õõ$_Ì›ÉàÞ/}é}íÜÛ6¸”YYù  Þnß›Ì:0áš‘ÓËÈ믚d¯–„7IÉcB2ÜSÌQ4LBÂ_°#PýÅí–°¤KFyø˜@`Ò*=…n‘ˆöA»Tòdnƒ Íñµ»ˆhòËøè;Ö¦úêP‚ÙV?;Ø!hB–Àµ®õø!r†\‘öa.½¾Î[ïóS#È}z¢¥ êWþÐ]~Ñßü—ðSõòsö¿¼|ÎÓëÿ/‰ÞÕ;S·×Mt> H*Ë}ý×dÆ'l`ÝÂW¦Á™Kæ0Ý‘ LÔw`ürÆûö†þ¦û¡¶½ŸoÛ¡®É¥È÷Êf†Ê» \e{Ë@¸Ykx ð#¬²ÀI¡¬RÚh¢¦u“ŽxÇè„%÷ÎÇ.1£%¼C}•ÛI >ÀƘâ´ìdXSôå!5-ýàÈ5¶­&`µ×›|}aÛCk¦Ä*šûM Ïã“yXBœ¥0jõd,‡®< ¸ñ£&G®ô¶Óéy“Æn´ Xî¯0AtVâØ½5Â}¥¿æšÊý$F×ÓÉõÿ󘉙ݑÃîãªîÄtK^a­´6yÕæZbà{¾ïW_þÀOþÇ—ö7ý¦°¼ö”wœåôÀåëÕûEYpê}k=à$À­Oá§|ù¡ÿ^~è§ÿÖåùoþ͆ÍË3f/YÕ¿ ~β«+YWøÀ´/gUž­n§D]CtVÍ4²o°FmSCW×ÀÈî˜,Ì Øs& #yìõ$—¡K‚1 ªIÇK’I䇑ý‹.Ã/heg÷!vC"|ôÝ«ü‹Ä^È‚(Ú‡ÝÁHÃgKÚ ˆÆÁ,Œ.2ûCKE9òPBR;šÄm˵0Û•¢ê«&ÿÚèN€&ã q9Ô •~l ¡O6L‡Dzɿ=õ–7ãŽ@´=ĵ«¶]ÛöÝÛ‰uíTÜœ_çgù¥IŒ,ÎÀ&õ’f‚@3WË"Åx]HgšïŽpo-uÂà-('VÙb Yù3[sÂædÊI‚_k}έ­ÿ‰?zù/þúßHòwçÀÏ™üëûóøÅyàÜø}n×}‹ûÿAþŒ‡¡Ì’ůýê_}ùÚ_û«—Ÿù?}ù‡ÿùvùÒÿñ¿ç›&q¬ ´§eÓ„Ù¾Áú)K6·m³•"«]èLPYôAÓtdM &wd–ßk?¯¦ªIqGC\ñ¿ú—A¥È z@¶6“0 ýQÆÎ˜d[|ú¢­ÈÖÞõ¸­î´¬–¥#áîøâ$ûSп8¯£'>LÊLÑs–•¿5¶h¦I[Fy_»³c-ø<Œª3üùj¾b"x_E,½ßÌxê/]~'ø É÷ÿŽ»ü[ø]~Å?ù+ÃdöÅ%×{zçáôÀësðÅúÿÔ¾ ÑܱºÛ¢¿þ_þñË/ÿ­?|ù<(õsñÏ_>%‘<‡&ÛáYâ²ßxAÍ-Ò"h‚1ÁÝ[´ý Ÿ)B¸)Îm;?(dbBŽ0Kx©}øÐ”ׯÄU&Hw:™pŽIb@Üâök…¾„ÇÉŠßD°„ˉ†š”#‚Šœçò‰ž’¯†hÐË©2žAUÃt¬ÌQ$©k 'L(È“Aß# j1y˜#ÛUX0JԮЋí„d){¿ÿI¦½•"-µq‹†#x‡QÑÔó¡©–ÈòÛ‹ Œóëô§|Ò!Ðç?dîeûFFlQ±IߌMyžëdlðzÙ¹&¸V”!:oûäü«y¸”íòéü¦\—wÐ}ôµ_~ù}?ù“—áwüŽè3ñ»â?“Üq¾C¨å3Ö®è Ì&¾½X¾ÎÇÊϤa4I¸J¶ŸÓhä»ûw·ädøàxš9de?m' [Ôão„`kúèHRtå˜äÛùt’’«×dp £Æl”¼»`lq@IðT½!\V»ØUà^a¤rua"ÂêÍ“fa»y²‘Ôʪ±ÝD™= ÌÙIS,Q°èÖÿLÎúN|¨ l”3…¶Ä;fùÒ íÝI€ˆƒ–cܾÝ–×Þ‹ßñ“œss_U¶K©žž;€~nr'\ øÍí~ÒüL´À'K+ އ-ýás(Ïž>K‚wÂõ+~øG.ÿöŸø—_õ}ßžÝîßIm€çáôÀwÎ ÀwÐÉ8M¹ïýnôq[àÇüòKø‡/?Ã×ÿ¯¿ü.Ÿrÿ9±ü9™Æ@íÅœít¢¾AÚ o²Ý×úÅ}¤ë5 ‚ØÝçL†,’¶fH@q;?/Òà󓱂wšà7»›Ž:“d68X;áÐ'[î^»dU I'D¥)ÉfC2ZÞû¯1$n‰¥2=MI–ƒF=€¢&üt&ßI©*w&=ЗvGP~“›ª MvŽÕôèæ»I³¿; B}þN÷þEÂ{´ÉÉ„™XS4P{ Ö&ç&p‘€wŒ¼«zš€SœL ?j ª Þ C]|b¯ò¦¸~WΫdw&>ÞÏ—™Yãsàõxè•ca*Ð">™Ý0p¾øÁ/þÞËïû‰?rù±õw†ÖëU?ŸÛýqÇyøöÀ^ëßÁ&ž¦½íØ”·¾ÂmßöÇþÈå‡þÛŸ¾ÜýÈÆ5> à¢Ï—å%,@}…ì >>¡ý•8YÀŸ~E6v`ÎtG؇¶LÌæy ø¹5`‚Fq{؇ٞÇÁdn·ÙMͶC@ßäg²1)ÿ|°€ñŠÌÚW™Ä nQ¯69ÁÈ.Âmv\¢%WtùºœºÒ£¦‘DJ_ñÁ\»Õ§MÅ8v-kò·–?õPlûI'@ôKóŠÛ€ì[â"mÉG<é)Å~>‚K_Kä¡s$ðÂsH•w>È“D ¨“KF!ŽO¿Ïß3cê>Ω÷h²l)÷ùÑéubmÈ5àäç:yš×ì@ý¶çß½üy¶ûo“¿×ëN^!?ËéïXœ;ß±§æ4ìMÜ»-ðk½-ðW.ÿýßþÛÜøS—öÍm [²®Ð¦Md÷¼†I€»Þ£ö+†¯Yíe»JZØääûLOÈYµ‡Ã¾É@SK‹‰=¿3 xRüÙþ¶–”a2ùQ\šLì™\ÒЇ•cv*2uXÍSŸYp—ÂÛ’æhC|ó^¤ÛrP,út>½Ó€k›ú³èu$Ú\Hì&j¨2¯!¦ÖöøeíPŠÆ2ž}±“Žˆ_…ÒÜÊL_C„WôûPŸãôœ¥ZmÖ†N´=òÁ™Ø÷VMìá5‘o>`Sï8ß `>ó‘¢~š±vkh^`ÒÓw˜°ñ _Ë?ñƒ?tù7ÿÈO\¾ÿ7ü†ô÷!¿¬xN|‡{àœ|‡Ÿ Ó¼ûØ•Un ¥ÝýØå—þà^þ»ÿú/]þ7¿-@ôv¥þód nG“¤IM|E0)ÌI€žÏLþa"@Ǭ œÉÆ  ÜÄæÔá©+pþ[ä7Aä­vôw»ÜÌ1$IaIpкq¬ØIOÊül¯pŒ»&R“OŸAÿÆNåõ™dfy ±™Î™ŒE%65Þff4 i" ŽAšþ’6ƒÌêW&J&PqÔu<‘ .s%r /ÊQ‹dY-k罂µ&íõ t›Šä‘ž®6|eò,|À<’(T:‘A¸1œãÝáÈ„+Z˜xy"ÇO½M€`Ωãµ<¹¥àXÔ¦Ûýï}ùóËïý?yùñßý»?·ûëžóø Ó½ÒaÚ~Zý{ +-™ßàg…›ßø›ór÷£?š¤ámŸ¨N¢Ì-&y⟠æjÎm_3ìcÞ0ñøîw“™‰ÅÄ“š¦‰*¼¶…Ccî¿ö„VxK)Må˜düÀü®¨“„!æ¹²g«enQJ®ýJ³ŸI‚ì÷¯:xjJhÎ+"ɾ]q—<ÿ›§KëÑ]”¬è©^:£¡tŽPšÔ»šN¶(o{kjŒÛÆQ¯=IáOLúNˆÁ˜b¢WG?z×WõöFðp*B?9™‹t©¡É§Cx©Sv ó|Üñà‡šåùÍ¿ç÷^þÜßûû÷’ÿ¹ÝïI9Ë/Tœ;¿PÏÜiwïØ >¯ýØàmĨÈ C{„å<1Jª}1r0¸h‚@‰ç÷9²ÜyjòöÏÿ®ßuù¯þþß»üÎß÷oÉÿÜîÇ]gù®òÀ¹ð]u:ÏÁèÛÛ¿äŸúU—_òÿÂågþÖß¾üÃ?ù§z[šlŸ3 xšÕ ‰ÄÄC.óËþff¦‡×Ó¼°|C@ZÚIðVôà wlú‚K v0¨IDAT´LÄÁƒƒÙïõ[¦B^7Ä» ]Z°À¡ƒ1É[úBňà}Ä `&>å— SLе£õ®‡MŽÝyÈ@"^ø¹ý]ÜŒA­€ïõ›ìýʤu #U %úÇ,±±?Lv¤P‡R»úhĤ½I]ÍWñåƒçUžÞD6.Ò´ß"ôê3:ävv8qÒé Ï´/ØÎ`_¨öÓþž_÷ý—?ÀC~?À’å|º?n8ߥ8'ߥ'ömÖ›·~ý¿ôc—¯ñûëÿÃ_ûk—ÿùÏü™Ëglñü}uëS¾þÌ·¹úäÆvWÞŹà­oÐ7éû>yL& yÊÄ'½‹Y1ûT}ú LJÊ®Ð6QÉ ã”Nn ‘߉AvL€Ú…MêL)è¹Üùj_dw‡#ö'CC¡MY¾#AÛµƒL‹®ðqÅñ•;Û-á³&ð&ýð–϶:,ˆH±/( XÿÚw{%¥uX†N2HŸgð¨“&§h>9 ÿ¿öÎ=X²ÎóÏÉK$dM0‚ 7ec‚J4ˆH¹Èed`²Ãº”SŠ Bmm© º\Œ²²µ#LFeµjE."Œ°hÁ‚(‹ Eiµ;¢TÍ,לKöûù=ýœtç$§眼o¿ß'é·»Ÿ[?ýé>ýý=—~:"è7j÷ˆ²FVÙ0‰‘ŸÒT‘ÿ8´š¢!A™õÅõUsÿnsÓYýÙtÚG?švÞygc>OæM»¶(‰m=?ŸW¨w ¼n·ÝôÉáóÓ±·ån„fó¾«[ _BI€‰?(ÑA¼óg‡ÕäŒP诅ùcô!šÂ=©'Zˆ€fñÒŠ}Ø“bûù}óØ' ÏÊ7ÄW^僆?Q‡ßÕWžñÆ‚Ö8r©6óAÉ,ùÉjýňŒùÇZHÀ--¼¨>¥W [ šÅUó_¸d¿èøõm·¥‡/ûjÚíéß§—¥€Ìà¦&™š–wÔãS¯¼ †èHñgP‹>€ê½}ÅA8³æZ*Нè!¢Ä~,GÄÿ\(å ŸÊ?") YÃA¤ÈŸ}DŸ¼ÆGc*Ž‚„‡¢³q`ŽŠSl…#b&™(H¹âÉÿxW~&'ƒ´’!PeŸ[Šê’Û‘ž¼É'·px ¨’iC°ËTÍ „c'áØŽ7”Y¤ÃOäÍq‰Ç쎹̙i´‚È¿…s"1+Z8åhmïBNkE`¼ÇL ?ƒ@èªyÝû§O\|Iz÷Ê÷)¶¼%üŒ®õÿô=p‘}Š™B‚!P&zÛ?˜¿ûÝéÁ—ž¸úê4O°Iú0¨)zg©Š?CF‚Ú 8ÑêOÕ_ÿ‘}ú²ód>Ú ?„KJ£$¢ƒÖÅ„A4G$W"³è‘FeRôˆŒØo%ŽdRÄŽ´¨ô°£ÕA¢HZ9ŽàøîÑH›ƒ´ÉŽœ"D<Ž£´QCÎ!º¼uˆQÞó‘'çSòÒ:÷ý—\s9òõ[›³ÊsPë3Ì¥¨Ô6!×ÚgÑ8m‚­ŽIAT F"â´&9' <ó&À7Þ¾Øu§tºšûOUsÿk^ó7÷Dÿô"ü—Ù‹gîsîYõn×JÞ³þߦcoU·ÀôívýEð]¼Y3c|À ÆÄ3!©Hž@(×LUÅŽÑæJç‡IÎ[bOÍÒÑ¥ ÏðWXiJG¸¨ûÒMcw4aÇU!¦„¯ 'ŒnJþ´FÈ?ê¾YHiÞŽ&p­£ "(jd)ƒøä‹1@V4ÑW¹2»àL>¡5ñW"9Ò`<„ÐÇ~äROeÍýT&ºXy©;1É:šþµ…ÔàåwíæEaœkUÀ*]./qd åsÐ&»ñéf1ž¨Ž×ÏG d¹¸‡žtJÚðÓ»ÒG×­ ñws¿ Øõ,·ôì¥÷‰oÕ-°ßâ´ðš é7w’úò—ÓÜß?¡I„Tsœ¡o  !’$Zh!ïCÔ¡1íGkxª«`ní#—1x ‰+ÄÊ5ýÜ\?Nr˜×RÄÙdØqþ‘*;rÏrZ|²?åÁ§Ô¸‹¸ÒÕPBH$Vˆ8û1@çÆ×ñÂÈT-„ç$ “­ ‘–ôÄSf¹tÅ_¾ae¨„W‰Äìò¯ÄÙ*Z¤¸Êƒ8Š_eJdÕÌ•s1 "@ñ”w BŒ¨ÙtÉe"õ2Á Êü¾þ-KÒ_jtÿŠãŽ‹¼ÝÜüÓãlôø Ðë§?²[àà•+Ó¢#LmüvúÝÕW¤×÷÷§—Ô¾˜ÓÏŽØÌÐ>Û ÖC ¨43b=† XÚG¢ùÆ@4ðã'ÐYÄ+Y’"R Gœ¢I='Ò~ž§€ë· ¨%SFyàb,ƒÖ!y ‹W#+G ªÆMJºôæˆ`"rT­QeD^ñ#·ØV¨Ê‹ ‘ÎÊÛJ¦óWÇÐ?ʉK‚p•¸3~BûQóÇr@ôõ«9ˆK¸æc@ý#7òÑ¿(ŽŽ·²1À?eŽ˜Éò¨ìˆ|>~.-.1ÄO†ktªšûÏXû‰DkG÷Wà½2¨þÔÍÂz›@½[à5sç¦£Ö—Ž»í'©ï„%8¼)΀;„G¯JÜò§©êÛBÇÛÈXt H¹ÝèPº‰cà*„ EüÑ6jÉÑôŸ,öÙ$fnÊÏñðɾ A€•®ÔÖ«1{Y˜QȈ©£EÞ9e)eÄ€ 0¿ HY˜QOåPòQò:ç£_ŽyfñôÚ¯‹ÔÌ©G< ²”;¶IX tCûlÃ2ÆQp¡äÇS)jÿ”G– þåø¬ã½~­±[6ë•ü8Ö&¶ô5HÜ€ò8ðø¦¯ÝuWúø¿ÿtˆ¿›ûL`˜€[†QxÃÐ-o ¼qß7§7nøZzäž§__vYÚåwè»z- Q’ðó‚ß–ÖH<%>ÀhœW Á úUˆZ KUV~ˆ25Ø;„UÈõبb‡Z6é*AÇ$„“ôúUPþG{'Çc`ԇɯRŽ5›²)¯| å£Ý˜yXaQ뎲Åa"/ qµÁ!¶”_ÛQÅÅQóÏYçŒ"ä(;a*i†'EŠ“ÊQ([FE¦*W¥Œ¦–È&ÊDyOAX3Àw{ó¢ôñK.Iï“€cÐ'¯ôytàð °0ŒÂ& ”nRÓ}«&ZüÎ#Ó/7þ}úݾ<½~Ó@zfk½2ÍëR Ù~? åct?r‡,¡åÑôÎà‰S¼ª‡"~Zˆ‡"uÄ‹7åØQ>?Œ.FzE&/ŒÒOwv•¡ jÆÙœ¨ò§Šù ›%I”ÑT¶á8ØV|ŽÉk~´…¹A¬ÊFÉ~ñB•V'10"oí«Y¢ÉCe”G—†"F\¬œqR Ê‘8æÁ–tU çKþUt´`Œ½¨r~èüO§|êSiwÍù€£É?ZwbÏ?&`u<ƒìLÀF!€P±ða˜æÌIïT?òq·Ý‘úNŠ«¦·÷þtåw¤uŸýlˆ?µ~œ'ó þ1Q lù 5Øž&`3TÓÇaü+5/¯ºúª´ô;ßIý‡-S­^*Å A‰ã6I¡™¼f±—Øõ+<ö³0”þê†TåÆ@ˆ I.¢‹t²û•1@xô‰†X¢¸rògr›ÒRß° c33aŒ`[- LnDmœ"ç42#â`øgƒC+Å(Íü9ÇðSDŒ‚œVqðÒç¿Ä?L²Œ-Õ¾IƒÇk%=Ç"¿\šˆ?¤ÄqžŠKú2›-ˆ=}ýœO”AéÑwŒš.Hÿî¿|3]¦)žßzÈ!Qã'o×úÑζCÀÀv9Ø  N ÌþzSàôܘÞxÑ%é¹9»¤9R-j÷4a3*`¯ â§}j¬Ì ¯×ò›_yS·:N8b'­ŒôˆÝñf¿Â#ÛNq´Š–vœ¸¥E€PŽ™ãQ&f¿Xáic.€È‡š{®ñ—¬e7„?Æÿq9§²Î¾% Ó!7ÍcãG3¾Ê|¢\ÚÎ;[jÿ5c‚\á̱òñ”§â3Ð’ÖL•!½ryÜúóÓ5ªõ¿ÿ¤“(Zˆ?5þèbÿ˜€ l‹€þ¤ìLÀÆK Ä…µª  *;ò㙎—ítÚ‡UËåÕ? ¢ÿè Pk€±ÒI ¨G V¢F5Mãè!KUaò7¥¡æË1µ£¡Š[D}Ï5m \¥Ö•„"Ë¥5 OL¤|rU:w)DmšÜ¨™“^ÇÔ/ »Ùè©¶•55<2’“R3Füª›CÁ”#Z "$›ô*Ÿ2V íǶò‹c‘&ZE4í8ŽüÂxÒ>-}²†0¯X‘¾rÇOÒº‹>ŸöØcä§ìÜÜ;h@@Nv&`M Ô»öÞgŸôÁ¯\–ޏñÆ4ø¶ÃUFŒ²XÇë‚2 èÒŒ<ˆ^´("‰ÀÑ·=H—/7£k]m£„'5fúÿÃÐ>5þYjÊK\Ötu Hœ c,BväÀ?ŽG·€¶"mÎ’À–}%a±­0Zˆ3Üì_…Eó<þˆ6N+Î!»ìÇoä£XæŠA©2yˆC„k3ΟµøµÙ{¿!{ÅUé«ê~9èÐCÃxrsÀñ Lˆ€ß˜6'2L t  yû-;"-úþ÷ÒƒßýnúÍW¤×ýó?§—äxÆ8u©Ú, ½Ú *¡Ô6­ÆÒt®ª¬-).§(r’ÆÐSÔ6÷Ñ#–ôíç7ðǧJ£µ´<Œ€<‚¡Êƒ•\e„8ÄÅ8ˆ.m‡«».)ærCê‰÷)göf”>Ó&3oB :Tšó9É")ùTF Ó,GŸ‰öóAN4ÚÐ&Ð:2#½Ý_¥3×›æÏ›A´œx€_ ð L˜@ü°ÂL ›_eFy%Ü”—à¯/(Ëå<ÃÈ'e¥|¹ŒÊ( âqþù\ÂxÀ‡|"DæƒiÎÞ{¥Õ_¹<]ñý›Ò¡‡®óáXÝ/:v&0ilLJgd™@é I|ɲ¥éÔïݘÞôÅ/¥çö˜§ø$~¤4q“•i…$H=¯÷ "®ˆ3ñ¤¦,ˆl¿ÒDÍ_aè$-,!²JéBð倇+LÛ!ά#\µlò##åFKÿÙ ÿªŸž}ĉ&NDÔþ¦4‘3ˆ cxÝ¡ŠKyÂhÐ*¦L®Žøçæ~ÆGp\E›Ó&“x÷ÚsÓ×î¸3rο‰×ùJs¿G÷ ‘ L"˜D˜ÎÊ ò¶Fï¤/?ûì´ÿ±+Óƒ×\›ž»þ[i®p@oð áY2¢V. œ!ñ$-’‹¶Ò ΘÐÙMyÊH(j¤6DeÆSê­l³Š×Âè®W¶!îd†‘Á¨Bƒäa °Orļʘ}YúÉõ9O€L€âbPŸ r':yqmæ:~Þæxj.‰VŒ™š»f´HlN –-Ok.º(¾l™"(+u©ÀÎ}ýÃ?&0éò_ô¤gë MÀ Ðj,”˜Í›¿gZyÉÅéèþ0 .;*iöàøf¯¶åI4>@ƒcL@ˆª ‰%ZŠ`GÓ9ÝÙ¨“‡k[qBdùÑâ›ßÈi£Õ@q#/©ožTHâZËÅ+† T”ȇl"+½ÓH>œCLôCŠJü£Ù^ÂM9(_ÄgèkMfoPFIt;È+Ê!¿8ÊHD5÷kê¾´ZßZ¸ê?ñws?íL`ê Ø˜zÆ>‚ Äø€\«Jû¾ýíéôoH‹¾üåôÒüùê Æ¯EÕùè_—È«ê".úû‹h²ÎBšà…#¶ÅŸ|*‘g A˜€ªŸpL 0ctì"ÞøÅRU㬘gÄhÀ©l b®ùSûWÅ#Ï0TäC­?÷ïWeUâ|^´hÈ0Pú¥ç|$}ýΈæ~júnîÀþ1i!à.€iÁ샘€*ż'a¥V½ô¬³Òâ—~ý_¿•~ÿÍ iwMÐch`—˜J0gðÚ „|&ÞK¸i- [€Ú3_”ŽÒšN{ò——p©±6C”阂]•Cy#æ¹é^±hU üø‡è󯀬‚r& r,mç ëqŠ¢cP.º38¶)<ÝC*ë î7•zá‘ËÓÇ>÷¹´tù‘ÒÍýAÁ?&0½l4äíH 9ú+ôUS 3>`ž¾÷s~¿êøô¿¾øå4㾟K-õªà Iqók„®úÃ%¦}®„¶O†5vñ¡—8‡!/K‰³ñ£v¯Ö+(æ"Ð?&" ‰Ÿ<Ø-‚.Û# yéøÊ> yÒb€qëø*‡þåÏ!ŸÂdñçCI1›¡’EÛÖƒswM«/¾8¶zuôïc€àü©ÞÀà˜V•Í?­ÇôÁL ç `HÖßx³>dsÆwoH‹¿zEzyï7¦9šÏ³ôó¦À }hHЍVýñŠC«@ÌÔ'Ío Ò,ÙÁfBöµŠšyä,1Ïò››¢¦N8­ʈ|lˆ1›ùàþZbm Ý#qlŒ¤¾:ÎЀÚT럥òõkr eqvºæîŸ¥3Ö¬ ñglTÃÔΦŸ€ €égî#šÀ0@ÕìéûÆ-=õÔ´êö[ÓšùîyUÉËG†bú`É7“ú ÐÄNs;†€ÒC`@Í;¯nV“û`ÌÈWÊ+â*~¬%Ö4ËSíÐ@ƒ±%§Û ÖÚfÑ­ÚV¢ê0;èÀKOƒqåßO3€ÜòÄÚüf55 1øOþ´ ð©ã¨íë'Öá¯<"¡ÒÍ›N»ä?¤«ô?Ò²£ŽŠó+ÂïZ?ìL`ǰ°cùûè&0LQ¬w ¼é ·¦ÓþÛߦ7\“^Z¸ošMs»Ÿ™ÿ˜}/ÞPÄ8FùÓ= Üb[šŽ!À²Y# 9b®=º ¨Å#ó,xÿ¼Ï· hÎgì!­CŒK "3ö€–Ò‡ÑBªé3…ïL•¡OãÞqöYé÷ÜÎ9ïÜ´óÎ;G­?Z;T^;0Î àA€q\ &µc e¼§õÛN8>íûî£Ó¯¾õ­ô»«®Jó$È›TÓǘ-ù.y+qŸ)L 꿳„ú•ñ€xS‹ÏÝ ×ýø|Êx@k>.Fr Ä€ÐOÄc¯¦íêäïãÝ?53ìþÖÒÚ/\’Ž~ï{IÂO놛û‡L £¸ £.‡ c[Ä xêØíµ¯Mïùô§Óñ?¹#ÍøÀª¨…c½öÍ–Ó- A‚o„|€4,ȶt[­÷!ÔCRx&blƒs«]ÊHB^Ö!þ4ý'뾂™ÃŸ_奸òŽ…Ú~Ÿâ2ºÿôK/Mßøñ-!þ´ ¸¹_ìL ƒ Øèà‹ã¢™â#CªÔ|á[öO§|óšô¶¿½.õ￟êé“Gìµ(œ¾~„š/FÿÔøå¯ª:¢OmƒA¹†qÝ´ýc8„ ³€ˆjúGì‰9 „ >јEp€Wx§_~ýZÞ~úi隟ýC:çSç¥]wÝÕÍýbbgÝ@À]Ýp•\FPž®Ò-pÐ{W¤}5™Î}·1ýö+—¥×Kœ_%LY÷¤š9çáÕý™ÔÒ¥Ö4ñb0è÷ùŸ%ÞÛg%ïØ¯½•€ø÷é)Í€ø÷ÍÖ R}jý»p`Zsñߤ÷{,¹¸¹?(øÇº‡€[ºçZ¹¤&?Œƒ! aÞe—]Ò1ªu¯ºã§iÖ êP­¯ 2ÂÍGzx50Z¤ìj Bü©É뇩xÃPËkÞû§[€}ÒúÔOÿÁ,Ž¥$ò K¢ODÿ¬YéÔ/|!}ãÖ[BüÝÜïÓº“€ €î¼n.u¨¿-°`¿ýÒ‡¾¾!-ÿûï¤þC߃é§РÀè`›EB®ÿa°fþ4^ZKt  ÕðyÛ``“"hæBÜË 8䤓ӆ»ïN]¿ÞÍýAÅ?&нÜн×Î%ïqåmjàÒ÷tÀQG§}pSºoã éáËÕ-ÐÿrzI5úY2yUàU³ÏqIƒù´Î Iù‰€ ›ãÉ0[½›Ôü?˜^§W?qñ<º¿Çï9Ÿ~»¸ ]×ÓgÓƒŠ!@·ÀœÙsÒ»>±&r×i§Ÿ©Á{곑ï‹×iÚÏ"¯.)~?a¥%@a1¡ÿ²úúÓ& ö;õóŸO_¿ùÇÝ߃÷–O¹Ýl´ûúúìzˆ@éÀØ{áÂt²ZŽþþMipé;DÏ÷¨Ö¯|fdÁ  ÕHÍ›ÔìÏd>8Þ*8øä¥¯Ýó?ÓGÿê|7÷ÿ˜@»¸  ]×ÓgÓãh (_Tå>½eÙ;Ò’ï}/Ý'Cà_yEÚýOL›xK€¦~ d áÍêçgîþøBáÁ‡¤5]”ÞyÌ1A“7ÈדùôøÍåÓo·´î’ú„L€Wú¤ðZtFï©©yO½í¶´Ç'×¥ô àl {@+ÅÓL}Z é­‚_riÚð£…ø—Ñý1úŸüìLÀZEÀ@«.§Oƶ&µz©<ÝóçÍKï¿ð³é¸ßžfbz.Æô¥Õì¿ôì³ÓÕwþ4½vmÚi§¢u Z,ü[õž ´ˆ€¦ý¦ ЛN8ª5,BT‚Xèáuj–´ÌÑ2WË|- Ôz½Öv&Ðuâo]ïñ™^•þ‰üÇôìÿù¿éõ‹öIû.Ù?·n×ø»îÒºÀÝ»§kóŸ´ü‹–—´lÒò²&­d‰¯VhC_´ÖŸEÇè°3^ Pºʹ.>è ÄRwîç¯Óð¶ ´›€»Ú}}}v&`&`&0*£b±§ ˜€ ˜€ ´›€ €v__Ÿ ˜€ ˜€ ŒJÀÀ¨Xìi&`&`í&` Ý××gg&`&`£°0*{š€ ˜€ ˜@» Øh÷õõÙ™€ ˜€ ˜À¨lŒŠÅž&`&`&Ðn6Ú}}}v&`&`&0*£b±§ ˜€ ˜€ ´›€§nx}óç&rtè/¾øbº÷Þ{‡Krë­·¦çŸ~x´¹sç¦N8a8háÂ…iÉ’%ÃûÞ0è^6º÷Ú¹ä“Dàî»ïN7ÝtÓ¸r[½zuZ¾|ù¸âvB$Îí™gžI¬'â0FcS7 V¬XÑ8ë&Ìg>"ÁG‘-Z¾6`FÀñnO°ÐÓ—ß'ßFO?ýtúÕ¯~•¨áO•«‹/NK—. ãh—]v™ªÃN(ßûî»/±Ô]1 &b¼Ôóñ¶ t3Ý|õ\v¨xöÙgÓÍ7ßü ±«E™²Í'žx"±ÜsÏ=éÒK/²ãLVÆÅ(Àx¡‹ã}ï{_ê4Ãe²ÎÕù˜ÀXlŒEÆþ&ÐE¦³I½‹°Œ«¨´”°`¬Zµj\iÉÚ@À@®¢Ï¡g 0°ïúë¯O?üpÏ2˜¬Ç¸ÿþûÓÚµkÓ‚ &+[çcKÀ¯vì¥qÁL`Ûhò¿üòË-þÛÆÔ(ôücúÒ—¾”zè¡FéÙº‘€[ºñª¹Ì=Oñß°aCB°&ê·çž{¦mŒŸÈ«ƒ-O'¥»öÚkS·½ñÑIü\–î ` ;®“KiÃ削?£õßõ®wûUFÆÕGÊ—íÇ<=õÔSé‘G™òˆ&BÌ=öX°zµeÛ¸qc <ì°Ã†Ù{ÃÚDÀ@›®¦Ï¥'\sÍ5ªù7Òíd2 –bÐdN«Ä<°½¤SNß}é¿/ec€$o'L¤µäÛßþvºð Ӽyó¦´ÜÎÜv;‚ºi$€˜ñº]G­Íš5S*b¥–\D·Iù¦:.eb™È›ÌwpÝu×¥Ï|æ3S]LçoÓNÀƒ§¹h#@ {´Yù¶•â¿~ýú)ÿm¿“Â0.¸à‚ÆEÂàÂx°3¶°ж+êói-»îº«Ñ¹íµ×^Qó÷7[°ÑmqÞyçmñç¯2öÂÎÚDÀ@›®¦Ï¥µ¨ý7­…žsÎ9®ùrGÐ]QÿÀÑ(Q^áEW@ýCJ¯ˆ`èB6ºð¢¹È½Gà¿øE£“¦¹Û_í3þÑBÒÄ1ÐÎÚDÀ@›®¦Ï¥µšŠÏÊ•+[Ëb²NŒ’&Ž·xýÑÎÚBÀ@[®¤Ï£µxÅŽ&èñ:jÿ~mmû´h!9äC¶±ã·¿ýmmÏ›&ÐÝlt÷õsé{€À“O>Ùè,:ê¨Fñ{9òÑGÝèô}ôÑFñÙ:™€ €N¾:.› ˆ@Ñ™;wîðD8†·} „Ùx¯úm€ñÒr¼N'` Ó¯Ë×Ó›&ÿsÌ1=Ík"'ðÁ7JÆtÃv&Ð6Úp}­%ÐTlæÏŸßZSubx`£¬ù‚ ´€ €6\EŸCk üùÏntn|ÙÏ®¦Ìš ÈlVÇ6é%``zyûh&Ј@Óþfþo„7"—7åŸþô§ñFu<èh6:úò¸p½Nà™gž7³yÚßqãÚ*b“I^xá…­ÒzǺ•€ €n½r.wOh"6MF³÷¼'i ,Gm ­¹”>‘6hb4±6²z5ç´ë®»Ž;ùsÏ=7hLÀ@'_—ÍL`Z41¦¥@>ˆ LÓÙ‡000N#` Ó®ˆËc&ÐÑÜÕÒÑ—Ç…k@À@XŽjÓM IÓ4_«³›¿Ú71nNÕÝlt÷õsé[N ‰à j¦çfðl‹ÓÃÙG™z6¦ž±`&°çž{Ž;-@Ó‰ƒÆyË#6i=ib”µ›O¯Ë Øèò èâ·›@Ó‰}ž}öÙv™¢³kbx¾…)ºÎvÚ Ø˜vä>  ŒŸ@Óyê{ì±ñgî˜A é—<ݲoœ¶°Ж+éóh%¦bó‡?ü¡•¦ò¤š~piÿý÷ŸÊâ8o˜66¦ µdÍ Ð°xñâq'üÍo~ãq㦕#>ùä“ãNÁµhÚ-3îÌѦ™€ €iîÙ@SM¾WÏ@À‡z¨é!z:þý÷ß?îóor-Æ©#šÀ"``÷aM`¼8à€ñFx¿üå/ÅïåÈôÿ7¸Ï>ûô2.Ÿ{ËØhÙõé´À’%KR“‘ç?üpzüñÇÛb Îèç?ÿù¸så¸ÿܸ± Øè‚‹ä"šÀ 'œÐ 7ÜÐ(~/Fæ•É»ï¾{ܧ¾lÙ2÷ÿ›–#vÝp•\Æž'pØa‡5b@³ö-·ÜÒ(M¯E¾ùæ›òÊ•+Åwdèt6:ý ¹|& ¼¸bÅŠF,n½õÖtï½÷6JÓ+‘(yß}÷ût9ä¸ãNàˆ&ÐltÁErM'žxb£±¤Ù¸q£@Ôã#®½öÚšÏö7Ï:ë¬íGr è26ºì‚¹¸½K€÷ÏO?ýôÆ0šôu7>@•€ïÐíÐÉ­ˆÿ•W^ÙèÑtB¦FpdØAfí ãú°&` °|ùòôè£6j¾æ07ÝtSzä‘GÒÉ'Ÿœ,X0#Q}ðÁ‡ŒÕ«Wy†À ©!´×^{¥U«VíÀRûÐ&0ulL[çlSBàÌ3ÏL|¿þ‰'žh”?¯²0–àðÃO¼^8Q‡è?õÔS‰qþbD"å䵿µk×N‘Ó™@ǰÐñ—Èì$4§³L…c Ùºuë¶›5]kÖ¬I6lh4‰MÉA,5á3Î8#¼y¿}¬–^—+³ ò­&ƒçÊ1§s]Îíhl$ÕËyî¹çŽÉ¤ÏÛ&Эltë•s¹{š}ÒçŸ~ºîºë^•ÈÑ,Þén*®±Îý‚ .xU-$cåkè$ØIWÃe10Ö¯_Ÿh9°›4û[ü'‡¥sé|6:ÿ¹„&0&ºè6(MùcFtÀv `H]xá…®ùo—”#´…€»Úr%}=M€}ÌÈìv;ªžÚ3¯Ìñ¦B79ÊÍë•ÝVînbì²v&y]\*hL€.}ìcéØcM|ä¦ †kœQÃGqDâ3¹Ý& Å`i:ÃbC<ŽnKÀ@Ç^Ì&F€Ñüt °`LÅÈ}júh7Š'eæËM¿¯0±«áT&йú6oÞܹ¥›â’õÉé,Œ…˜Y-E³«e'­çh™«e¾–âu½Öv&Ðuž~úéôØcE¹Ÿyæ™qµP»_´hÑð¹N–àc˜LÇõò#øžÑoøR¶rCt¦Êü'-ÿ¢å%-›´¼¬¥¿Z´¬–!­õHï]´`@v&`&Ðýl4»†~  /Ç600V°ЊËè“000fl4ãåØ&`&`&Ð 6Zq}&`&`&ÐŒ€ €f¼ÛLÀLÀZAÀ@+.£OÂLÀLÀš°ÐŒ—c›€ ˜€ ˜@+ØhÅeôI˜€ ˜€ ˜@36šñrl00h­¸Œ> 00hFÀ@3^Žm&`&`­ ` —Ñ'a&`&`ÍØhÆË±MÀLÀL l´â2ú$LÀLÀL Íx9¶ ˜€ ˜€ ´‚€ €V\FŸ„ ˜€ ˜€ 4#` /Ç600V°ЊËè“000fl4ãåØ&`&`&Ð 6Zq}&`&`&ÐŒ€ €f¼ÛLÀLÀZAÀ@+.£OÂLÀLÀš°ÐŒ—c›€ ˜€ ˜@+ØhÅeôI˜€ ˜€ ˜@36šñrl00h­¸Œ> 00hFÀ@3^Žm&`&`­ ` —Ñ'a&`&`ÍØhÆË±MÀLÀL l´â2ú$LÀLÀL Íx9¶ ˜€ ˜€ ´‚@¯›·sG†ÜßNr›€ ˜€ L#‘Ïè‘û#‹²½ð‘ñ[µßëÀXsäMÁþH¿±ÒÚßLÀL`Çíyíç÷(×ÃÀ(#or\oIá-00N"0òy]öëeÄÏNll}Œvc”hHQ·Žî=00"À3º<³ÇzžwPqwlQl¼’ýæ©o(jÿ+£ÛÇLÀL CðœiÔŸãRÌÎ(† €±¯C¹iJÍ“¢>?vt‡˜€ ˜€ ì`/ëø<·YÊs\›v# ÌéÑ£ûõ›¤l³.7%Àÿëëë;Aë]´ì¤~³µÌ¬-U}µE›v&`&`$0ò™Ìó¸,´Ê²¼¤å-/j!¬<»Ëºä¡ @ÀÙÈ7‚+7I}Í T n0°2çhAüaÈ‚€ø—¥ò²30˜ ò<æY\žÉÔôY¨œ#€íÑZJ¬‹«o¿žZÛØúr×o¶‹õX7HQn¾"þc[çî=00‰(ÏãÑ ñgÙV @Ï‹¾ø ;Ã(†7ŠP¿Ñ¨ÕÑ/Mü$¨ß”ø—V€Rû/- ĵ30hN <“Ëó¶<Â_žËì?üK¼R‘#½]€ € £~ƒáà ƒ ×n¬"ìÚDŸ­ˆÝ@°);0˜8"ÜÅà¹\žuþ‘F@y~—t”`䳿žu6¶¾ôõ›ƒ›ç+Â_½ÜPÄ©×üÙ¶ v&`&0IxÞâêÏÝb°.@}] ÂYêÏvíÚAÀÀ–û€çf©¯¹‘ê®ÜH寫×ü‹øƒ¡žÎÛ&`&`#Pž»¬‹¨³æù\Öu€íFxI§ÍØfÝóÎ@¾¸9mÖ8n~#]¹‘F ÿHñ-íȼ¼o&`&°}Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû2:Y~ pHYs%%IR$ðIDATxÝ[kŒUÕ^çœûœ;wfxžj©‚mZ‰P‘i•?&mlš˜†m6 MLùÓ±&ÅÄ?˜-h蟶Öÿ˜´‰F¶Ò&ÒALµ3Ã0ÌãÞ;÷yνý¾}ÏÓ9÷‡s)º†}ö>û¹Ö·Ö^ûq.F­V?2 ÃDYaB·›FÔRª ÷q„Ke„ªÍŒÉHáš‘ÕÛÛûó-[¶lkVq&ådN‡jµ*ŽãäGGGϼýöÛo<ýôÓ¿¾|ùò0ú¥–ü55“Ý6Ôp#²PØæ†Fõ®©l m {Ö¯_¿óÀo­]»v):§¢Œkħq38hÌ >]„›M0`R*•$‰,öÙgß\³fÍ"ŒBe„B3(ë„>0;Ö_£““1°m[{öíÛwtÕªU Q:A˜dª• ‚À`š¦X–Eí«4óžóÒK/oÐ †S`ö«gF%‹©x``@ÚÛÛçÀB!0­Ô>ûÖ 0¦ö½ ŒIGG‡¤Óé9{÷î „À„­yo^á™Ö–@ h ÌK¥RÒÙÙI Bᆀ`PH€ÚÄãq- „5‚Ð’MÈtÓŠ`¼ ðàø‚ÉéA -§©Âó]ÁeÑ §}Wl–f¼D@3Óê˜Bê1˜Öþ€y$ v‹Ê'puسgÏŒA @ËÕï@Mka™Å4…Æù@†‡‡UÈd2ª6A O Ï?ÿüñuëÖõ àSm–‚†Ô`^¦TF‹z ­-€ñk¯½&/^”\.§vˆÜ%& ™={¶ˆ•+W*¶nݺêðáÃÁžÐÔwÝpPXž µæõRÈeD+qOŽ’ÍfU 8bîÎ;ÿzîܹ¯á}UVg? €_AòÉ,+\‘áS§%÷ñÇRÆæ¦RæqG=ìøâ]]ÒÑÓ#wÞ)qh•3žm5MSç!)ŸÏ«˜}2 –U*9qâDÏ3Ï<³Ó¦MßCY‚àKAhˆ¢_ïd\Š !†ß;-çÿøŠD¡Ç³ŠyÞuÔ¤q+Ð`álŸ ¾ù¦,xäé¼ë®ú) >€Ë<¾rˆ<%N^ÀiQ¨bÓO>ùÀ®]»þ„êƒø0€«“O_*[ èÁñPéü?ÿ!ùá!)¤:Ät*Ь Í©"ô gW¶Åp"bg3’9~LÖÞ}·D!x¬€D‹ 5°j›DÁ9U4,sA0ûúú¾‹*è |­ <À PBcDR%—•±•+gÞ“Êñ¿KêÈ_ļy¾”aΦDæ«°€ª#¹bQ® ~ÿÀ ô8°šxBn½c¹tßq›šû<% aš¹Z‰š‡Çg9c¬QÇò-€ª„¦,ÎsÌíá3gdøäIy¿OÚQT³c>–®Ú„t£nï9,eý8åä³’«UeЊÉh[Z²bàÒ%yíß=)êß²d‰tßµBæ._.Iø «Ì‡2í×@$“Iš~Ýüt…iâÀ0M[•ÅAé¬JçÏË»û÷ËÐÐtE#0g[œrEx¡ç˜–ôCo—‹é)¥+U‘ò2јŒÇ“’‹D%9r¥‚Œ N‚M`®5GR°Ü¹ÄùèCùàÕW¥ÚÙ%_ÙüC™»p‘Ò4ÇÖDáu€ß ÖYxµ©èÊn€š^Ÿ§´WRKÖ¥A¹ç?Ëà>0ïÉÌJ‹“\ÂXÔ þNDúÇǤ“Þ‚e!ðxP)ɘmH¼NÔ ™‡².˜rƒ%àÃ2¹q¹0’‘+C’B/~çÛ»ív±QÇÂT"y-ï8Eúš=Ë5À× Ðˆ`é*YYf—dÁ…ËxDú1×ûa²åŽN‰B°ÙXÀ)æ¥ ½Ø†+<‡$`¬)”/4lYÙG71>*ý£c’Q¾"‹Izö,euÞës¼ x-C ;]€é3Ï„ð$#™‡Ó¯‘DRæ"¿š[66"—àù?´‰¥¤f祆ɩË68˜œÅp†fª]òcã’Åmx1“«H$“ˆ Kâ@ðñ6Øú§^ËdZƒ€ôd·læGðäí¬JFŒ$viÒÂW… ×À­Ãú7¥yKœ²|©»[>(äål~B.ÃìMœ´ÛÀ‡^$–”Âø8„3$-.|»B‹‚a‰`Œ(òÉ^~üøôÖñ¦àmäMbI‰$“bÀ‹+×ÃJÐökR…ó`7!Ü ¿œî’ÿÀAöU rÞÆÒEÝF,‰È%üEïU@˜9ªŸ¨n=Ù&ÑW·O¬O½ÌðÁq‘FÛ/Æ ¦š–QpN#¤ÙeʾòÜ)3"+Smòð¬y’޵‰­Rxl`Mlë·"E'Žmq SLiÚcSùÒmšÅ-@ 8]oä da×I¥±„™b»³Ï-RÒ3 íÖ%¤¿ˆ"ç+üµiq ‘«êªO¾0‡%Òú¦ùs‡Hòå©Þ:Ð3(¾Ë …¶c+–¹á%°8.e×È£qÃu©V>EÄ„õI.vª»z­z óY# '©×c²Ñ5Pà)Ðh n†Hîë,ôÈ¡aœÁ²‰)aBsHUeH<´µP®:,©ýŒ”X'ŽCÉqǬטù3ÔšŒNtjèNOiž‚1ŸR©€4‰†Í,cmU‡IªÃÀ×*Qq)ž®ß è1uþLã S nv>£XT ‚ÙŽÝŸR¬†Êû³½ù$® Ê"TÓz#•‡¶N!úöMÊòDÆÀ»>,Î2ÈPÃŽ’ro ØÇ ®ãdœÂÿ/Õ§ó•Eè'€Ø„0fãÆÐÂ+_€<švÄ©uC@Ò¸µ¡ìdÕ‚V œÞ'A kZ"$ùJMëlͤ²f‚hAÜ>ÇÛ;‚PoØäé1Ø&5ƒ㮾*{æ-w$ ¡HÇYW£œ‹ñdpßéX§›˜ëU?!ü°ò%lÃÏaÚÛOí»Ù{PÀZ­‡eºƒÓ‚–q÷¶m²_€OôöÊ-Ùœüà—OÉn¿]µÐæîiÞÒd`ˆøµ’…/Eš:çÏ— /¾(t†ów!Q ix „ÄÔ ×M` ˜ ç/BÇ’—_~ùªæT¿ùá‡TMÏ=÷œlß¾]¿ªxÅŠ²cÇŽÉŸÆ\UÒËu·€S§N ~Û'ÝøJD`tÐò<úè£*¿õ‘Ó§OËîÝ»uQKâëÀÑ£G• Ôl#¯¾äÞ{ïU LLL4ªzMe×möú_¸×u>WÐôIˆFPp‚ Û4ª;Ó²ën«W¯V¼Òé5Ò,å±cÇÔ4˜©pAÚµtРбi¢ÓÛ¼y³rtŒ5’×)Ò<öØcºJkbµMŶsº#òŒÍïííÝòÏçß’wÊÆ§•ù×} €¡Š‚À*†Ïâ?Ãóß2cÿÏy„ų‚€†jÿ7¢àcº!yêž–š9AÞPñ:ïB¿L¸öS:i!Q£¼c! %JšY…¥Æ Ã.çÿ„A“P+IEND®B`‚ic071W‰PNG  IHDR€€Ã>aË AiCCPICC ProfileH –wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû2:Y~ pHYs  šœ&´IDATxí ^åyߟï¶WÝ%ÄE Ùj„¸§M0I)F·$Ï0Θ‰Û™†Úã8Æ-®ÇÁwâ8¥c&ÆÄã8´!™xÀ13¸Æu±c |Á"‰ ­¤•´—o¿{ÿ¿çœgu´¬n»‡Õ·«}¥÷{ßóÞÏóÿ¿Ï{9ç¼[èt:6SS(Èê?r‹©?®Ã%Í|6! ܬåž"î˜Þßl0,Ï²å€ ðØ~ÙU²ƒ²Yâæ; ¸-Û”‘•mÈŽÅt’¦Ýïl @m€O9+†††^$`¾4Y»`9¥7)¸]mµZ;«Õê³?üá¿ë®»žxüñÇ_Ò=î‘­É:”oÎHjÞ\Ä\˜M»Õ’Zø½²§ŠÏåÒª9.L•C„A ü"AdlïÞ½ß|óÍw?öØc?VSÑ-Ù¶ÒÍ ¦`6ÕÒ{gcPñ O–!`Á„à‡ËÍ5›ÍÁþþþ«ï»ï¾‡?úÑþ[-—E%3<€è‘×ÈbøÓYˆ€EŒŒŒ¬¸ñÆ¿tÇwlÖ½Cä0ïH0[èž'ç óÎL§>³aYhÂð÷½ûÝïþ‡?üáKuãA‚â|Ò³%*K9³-KE;“:ÛŠ¬f <ÀwçνïÿûÿøÖ[o½DÑ1ÌäÚ¼&@. O5#éÆÇÇ­^¯—Þ÷¾÷}å–[nùE-“eN0/Ht¯ ˦ºÜ%a×ZýXOOOIs‚?ýЇ>t±Âç  ŠSL䬿X,:øá’xíøÐP’II0o4ª*7“í¹:‡Ñ~&w@Æp?†a`~,ñ£££¶lÙ2âJ7ÜpÃ×”õwß}÷·äî“mªì9Û'P}Gl5€D•%îT\G¯Ïº>®6‡Lû V.—K×_ý×4t½&X$@ÚWèp Æà:×Ù°ˆÃsmÐÛÛë$¨T*¥ë®»ü‚ŠêÚ9Á"RdÍš,ðá"„ =௯ÏD,$ø³~ðƒ]« ç¤5ÆzH€? :q̤îÝ’¾ÑhØÒ¥KR”LJ¹ïüìg?Ûus‚©žÆñêpL¸!®±þ¬ ) Z€¡M€MÀœ Õ]µY”§˜“'aÈëé,=°éå\c²n€á\£ @¤ mâ™SM ¸k´:ø¶ÂöÊóÕAžHïsa8b ÜUøƒ\ÓóÃjGÐý‘7$‘!‚Ï Þ5$X$@ t7À ¹Ž0\Ha0Nå»ú3ŸùÌJwL5AžX0CÀ!À;ü>Òg‡‹Ã‘@O©®ÑFÇt8È“!‡évh©7ˆÀÅ™Jâ('5“šàÓŸþô1Ó‹8ŽÐ^ŸÒsFxñSIᤓ¿„&÷êcE‚Eb‡q³ÀER²6ÂØÜ|ÜЀ‹E#`>\ÊÁB }[àdùñÌ'þ† ìÍo~³­^½šáà!…ÿ;M ŸT~H€ÆhÉÉy ƒ²¸°t\Ô<àQïøqɃƒ2dÃB^„a¶oßn/¿ü²—sá…–ÞûÞ÷þ…´É¯ÜsÏ=O)FåB‚<  6-|àN!AÖfIÀëa€ ²&; èáF:#£!¾÷½ï™>H-ßtÓM¾e˖˾ñoüPiÆdùZ9ÌöãP> ["»Jö {öìù¦ÜcnÚ^1íu4¦¾gï²1½¾ÝÞm5©Þ–Þäm«yo¤÷ëÙýÒeVY¹Â4.žx¢õ¬Xáñ”A™êò~MBm£æÃåaP­V3\¾À%ŽôY$ \³†kâ£|òc/ºè¢—.»ì²Ízç९ÊB2+Ëe(ìˆMžØ ^C >d+ ˆft]#@|CXV(¥"õ=Ø×+[´³®¿ÞVœy¦µÉöR@ 2<`Å5q” ØSA‹ëHÀg]-!«_ýêW7?ðÀÿ –2€³zÝý÷ÖÙ5¤žW²Ú舕¶üÔʽ+l}©Ç:Õ k7¶[uwÉFUƈÔrUxO¨œ¦øÃªÀmS“·ª–pµq­iâ(p›ˬ5¸Äж ½ü’½¤eâèÖmöü7ÿÚúW®¶ÓÎ9ÛÖ½ÉV®_o="€v¢úõm8³³ÉÍ ÂÆd¼¸"= vðwjݨ÷t ÑÇZÆ[ÝiKK¬}/½hCÏ\ßfÍ];lëã[AeŸrÎ&;åÜólņ7XV€E¯…Œ/EMB§£@€«Û{!.kI áQÐ pS(ß M®`†m8 7Œ&‰žÞÔšzÏO·ØÐÓOÙN=h)Z§Ù²šÛjI¤½+ ZšèÕ%æN_¿Æ÷YGj\]S(j™¦™¼JÕ‹øJ#Bµ4ŽÓó›’eKa  uÕ_£|‰·®²Ç´ª¨“·w¹kŽžFÓú”Æ%?¡ïTo6|¶?ñÛõÿþ¯5+}vÒÙgÛ‰çžk+O“õ,áØDF©éà?àÖ_“.ò@¤ð3ÄÈä>u|vÐvýä'6üÔl÷³ÏZI_Ü]_ÏûpÍ8+冕z×L»-2¼@Õ\òY©Ž××Ñwûuí—ôk(Ð\¬Xà¡.Ž+_UõT‰º¯kH`{­ !ÊúÈCþ íV÷î±FŸæ\"eMeèqœÊÐl\åøôN³FUecÒ=SÊãuÛý½'mïSßÑÊvÂÆ¶jÓ¹v¦MÖ¿T›¦AeMgä©.“Ê0)ârú‚"öÜ< pd?T£Œ9Ûû•¯Úί}Ŷ Xk`‰õ©·2èµ@£‰šƒ//•2yÓ“(¢%Yiþ¯Þª¼N)Qaš¿k^ЫI^êãU1FDªª–zÕšz¹†Öj¥_(ظÚQ•æ©NŒùv›ªsÌJwYqeUªABsH¨¶(¢ %…vÕj­v'D†ŠíèhBÔð‘ÄÝ"dÐuQ“¹~i‘"m±š­ší±}z¼<¢ÞÞQe=-QYtTå¤U ÊDÇèÕðåDþÃu”þpéÔ´Y›< 0ëÆDÉ<ˆ‰öì8ƒUBU•…è›ïz­û‡_ú©½¤5ü++×XMÏó›ŠclfÄ׋tî–UžO˜â°@­ÒD bƒ~=TØ¡ˆdžâÙk`‹¹¡güCz·`ïŽzÚ7.õ>`}Ú(b*z¡úQÛé½$Âñ‰H¾ðÒÿ3ø Ä”œ^Å”°£¾Ì•S~´­d$_èXòzU/EÝÊä2Æ'FÐ)¾¬ ãZõüµ"Ëøð.Û¶s»½ØÓo?Ó¤k|¬©ñ·­‰cEåi ¨bÀ Í’h€dØ`UßبmªLjÃÅ'¢çãÚSþ‡ºîXŸÚ×Û§sÔ&Ÿäñ&*9ƒ\X€kK´Ú*£À{>;„G+§£M¯ªØäJ€#®õ ]Ä©7$¨N[0R¯Žè„I½êX2Ê…VP¯\oTÈÛwJà/jÖýBUs´ô++1èôv-à¤5 áàT¢Ð€(Ý!Ñq„œÒJ©Ì~Í7”z¤ÆOS™ëd/Ð6ðÏ´Gð‚òlUšÑñšµUMIš£WZм,H¤Þï}YåPdZ¥—Mð äiD"”2„Û·T“Eí¸IÛ•\ûß×±oI¦Íè ÚôIa¿@(Ð1 «\„-téwÜDšì´¥)}«–8_(0&~+z+vžVW.[j«ô¸!-1 GÇìî•Ä4öP Ô«‚}‚¸QvX÷èÚCRðýR?>›€LJ\éŠÚ¸êF$í®¶IÚ%ͼÙl©;´’.–M:Z¢’Ó®æm÷¸ é·”ƒ§ËÏä9½ðÕÇ(k¸Ñ® Ç‘Eeøú=E™¼&{?•Ñ IÂO_®‘A"œ|L>ûôá‘nþPî\š\ Ë'ÚÁ¥¦[õ|!¢±Úle}y8UJ "LfAŒ¤¼R)ì2—è_ÆÙ*.îͯºã'O Ë·`Ao*j|F-#BïòtpÐaDj’@ª!æY䦨yü¾“(w:ÆCêô'Š”‘Œhr//ÊÂu“VB{’D‰;•‘¼Wó âÈæäˆ.p§“Ç1mV4¨¨÷ï‚§j'x·0Ÿ-Å©Ûb1å?¿"–°>ü‰!|IÊ„q ˆSãxÖPoRTRRØÐ4i±É¦2ôéyE·š<5@¾÷¨^£cz •¸*-Ðtv‡Ò^-·Õf w  BeC!?@Q@òÐ&!I‘i»þGï'«‡”N&iGâÏ4ì“—ð‡­än5Óɧ+ÚÊ3ßÒL²¦àà+ÄUu*nmñüHp¦c/ÚrÄ-&…¤©^Òµ}>Â2>ö ù7ñxõ¿_ $á$JXê¤ðR§Fe¥¥zu²$¬ùŒ®)(E•y¸!—<ÊÊ¥Œh/…ð¢è#+WËT ‡¶.ÔdRÇãÖ`CÚi,>ŒCDïä?žÆ£äçBVìqè=qG ˜ÅØO:O­ÏƵê>¸¨$L¾éÓúÜ*Âtƒôy+'À/ôà ¤óÙw$ŸìÉi@$æ’ü€%èbŒ§.>ÃÅbH×T ×c³‘òû<€ª»¬-í)ŸsyþnùéZÐ ±»v ‹#— ›Ü®•Ð÷ÆÉlüAj%±èŠ Khð&’&)“_Â\óÈC“’4iͺ†¼€J=KôP+ù 3ÉÜe¿ÝI€Túm¾ÍgÊ È3=ávü°L|_ªVé9¦¥ÇÆ“dðXòÊJaÈ–^\b’1<2Â`IºŸTIˆž,ùäÑ‚´ƒ*¬ˆèÑÛ@˜&©2«ŸýMŸU1Ý8 Ô ù9r;Ë™${à„ X.ÂNÆ^DÑTQ+†d–Í[¿ żq‘9Kw¼ 8Úsø×²F¬§¡!xd“¥ŠN›áiž|»À@o*/ã›"•C¾.4]·€ŒÂ-ê9z[Rô7ƒº ‘½¶ƒÀÄäOû"‹?”ª(êa<=”ñ˜ãuÝPL*˜C¸›IpÀ8ùµ~¼Zª‘/YY$Ú‚<êÀcçf%¬èÑ3 î…r‚’¡{L¶OtM«Z[!(¶„9‡C¡Ž/0yó}”®!¤ˆ^ ô¤ƒ‚)½GùAX?ôRÐá2ù¨ý–¸¸&aÔ‹ª,¦ †(è¨ T4wôM`÷> ¦ý¹j ÌÕhÀ§] !ȹzÚ›&à¢áŒµ<ÎõÍ>õô‚v 6Ü8ðäsx ª ã»y¼^¤!ÂcÑŠw¶P¨*‘Nþ¤HØ pÏ bÊÅKRX’l'õÕ…ÒöÆD–4]hB޹4-/7ù@H€9èQ à|’í†%l„®ôÎ!$ P(¦„gÈCÊ¢â h+žp èèë`h¼‚K™¢ª"7“+rkUZPaÉR«©‡²±‚xÑ¢¯¶m Pñ{?Eò2ŠB×Õ<,P##µÌ°Qöxm$)Ê–*áå#jJ‹òº(ƒŠP3<ŽxüIÍn¨R×î*?ƒ iúõz{7›< à"Éãfãy@qÙö¡?Å¢GÂÇ ¼)LçFcÓxb¨p®½“K-0,0yôw~X2&ÝØÓàÅÓÂC‹e™/pÌ DÃ@Wç¾ó¨x/_õ‹\”í¤ øÑ^†(Š6Q˜£BÑ0ñ2HR²"»ÌäI€ÜTœä¦,°—,±‰´¤õ=Ïx=¼¥M¡²f`|»ï»ƒJ\è›|¨YO«|ÉEd„p½›+/@*ýSP2~køðq?5é÷žÍë¢|Àí¨¾”+"O:=ž½µ¡Íž„êÐNàâ Á ÀWÂ|X’ 9›Ó;8¤ 5^Ñ8Ëa¼òäaNÀÀË.œp""@Ëxx˜GeŸ ø „¢ î€' u-b¤dðu½Â)Þ‡˜E!ó ×:j‡Ñ‘ÒÏTÝœ`‚éÆñŸv¹ÖÄÓUDdúמhõ³ÏÕá MW¯ŸPkuð›ÎóÑ!N’|CbçÈ·ºÀã<†_. ËêZ.K6p§·“4àfÉæ *Ì]Õ©d®9Pçôæ¦Eáû—y‰ŸÉ)+”º*©7ä’FÛ¾ãz ) pú¿ú[{òÉ Í4)Ó½ðËúžî’?þ’õÿ§Ùnõ¦†Î â§QÝ>d¨IÈ !Í™~-×:Ff€Jãûê² xAes`D"Åt5Š  gqèã½êSq 1(“:DHê¨ëüŸºŽž¡^ާã‹dŽ—kèËâw}â¿Ù½ï>«è©&ÚdQ¤>b'ÑËþ·õ.øÀMvé£cvéf œ^­£ÛôawM€pîo]ÃÄ„_Âh4CS“?wÍ *€§}®Âå—Wð%šÀá‡E¹ñt$2©<òªL%Ñ™Cú;šxÔUfSCÊ§Ž‰ o¹æ»÷;ß±+¯½Öoµ›Á§Ý©\tú  §y­XšýÒ~Î6ÞûE«nxƒöoê6Àú–¿¦‰¡þ:Ÿ,€ºV¸N©{ù˜/_ç£ÞÑ–ƒŠ£Ç31li5 äºb€ Ãj çÜ`Žåx9“º§Ì†N 9A'ˆÿîŸ=h·Þu—­^»ÖŒV1]Ûói¦»  ú¬^‚æl?þ$̆·]loäa[uË­¶‡)¤'48Wµ6äÐdžÀ©³Z€hˆ”Azccÿ•Nï€úŒ·%ýΪ²pÄŒ«¥BQݹ-5ηC%ù}/A ‡a)è¤P¤ACÄ<²¼§£tôLKc¿fvÁ¯þªýÆG>b'é/b8&>Úéóà§ë5ÀT¥ bXXyê©ö¶Ïÿ¾óÅ/YõôÓý1ÎúõÞ‰6PO¬û8œÄd5î“6Ô;Va‰Š?AšAqô|&šu¥©žî« ¿ôŒ3춯<`ýüçüøÓ0ó |d;ï@£cX𿢡޹þm¿h›5,¬¹í#¶Wkwþ¦OM³ÿªnaµ9Cƒƒ*p²Ìæ™ ò´QXû¯áLföÌ%¤ÞÃfS['–´8B^e]õ;¿cÿã›ÚÏ]|ñê~Žgù493/ wÎK–èİ@ï;ÿý¿aoÿÖ·­ôŽ/°PáZ*jƒB½ðØ?H¬H ð!ŠÏêU « Ÿ7h.À|•†!”a¹×°¿ò»G³ûkÿÃô• ½žÃŸ»ñEÏÏ‘¸y 7VIói²ÃÂrm¼üÒ¿ÛÎý“?±ê™gùÄMÀÉß5ÉÃ¥¦´gÿ3$°Èr1_ZAG~6E,–˜MÍîOÛ`¼ÿËvûþ§­ÓvžÏê>+³ðçI€(ó˜¸1,0?`Ò¶þçÞÞñÈ×íÄÿ®í­ôøja\cyµ]щàìÚI y>>ièš^ÏQq-õú¦Æyv 7ÿöoÛ>ö7öÖóËZJ²œLf÷s¬î_Wy.„”LJ‘sÎu×Ûßú[ë½úŸÌm]ÏyÆ0¡´¨x_êéÀfý5û¾ñòËí÷¿ýìºßú-ýÍ¡äAùpêb™…wG)@ñG˜,у¾øÎOÙ[øš56' 5Híó7xÝÌ·¥î{N:ÅnÖŠâö?ú#;íotuOqŒõ Õ,X`1?àϽžòsÿ®üË?·S?ñ Û§³„›ZøQò"ÃÛÿó-v4Å¿~ûe¾Ì uå,TWo`Ï|î&uË釜~ÀŸ?Y»uÛÍ‚bnšalx}ÿsŸ³ç¶ÿ“]¦]Å7iÃŽc·÷xµï5u›ìnYý9Ä"gdr%€zMW`FêÂLš\¢fåB€bÞßb“æP‹˜CawcU¹> šëÖŸŽýØÇ>æÕ^}õÕvÉ%—¶ äyúé§íᇶ1þ ejN×à /´‹.ºÈúÓϹï¸ãÛ±ƒ¿òZ3¨S?6oÞl矾­\¹òµ æIȼ&ÀÑÊø±Ç³|pÚl[¶l1ìóÏ?oøÀ¦M“ „<”…½ùæ›í = šæ¸!À3ú»ÃYð§ÓdH lªÙ´iӤئ?Uÿè£Ú“O>éIï½÷^»í¶Ûæ¥&8nðÐCMâz“þ„ëyç7yž#BH»NÏÿo¸áÏ ÐO<ñ„]qÅQÔ¼q‹I =6ÆrzótàϱK/½t2Û~ô£Iÿ|òغuë$&õ×¼ó2h‚0Û·oï¼r d‰~6l6þµz“]Q̦¼¹Î›'f¾§<‡w]­Vs­-†– B®…ÏAay`š;³*NÕ»ƒaXæåe˜[„Ù —Eæ£9.ÀX=ô¹çž³ï~÷»¹`ÅR0ÌYgÞyå‘«®ºj˜/ùËöõ¯ÝØ ÃÐÀ>Àý÷ßAuéù¤‹}vÙAœ&ϧ'éià·æRÙ­àƒÕ›Ýð9ÔN`äGSÜ~ûí~y¨­àHø7Þxãœnåù4ð¸Ù06zØ»ŸîYÀ_¬W½Ï<óÌÀön<;8ÒÍ£Cvô‘¹M¸çµ8z¹-ŒÒoÓ¼";ëBrÕ émÙ…A•ÃßÅq3 <¼(ŽÏ‹8>qŸ¼ëELŠâøô,àøÄ}ò®ó K½YïÙN¼èy]%€¼s‘ùl øA¾µ\4s#d@þ36y,iGðèS»ÂerùH„óQûe+²‹fö@¾<ÆÜ'ËÚŸO Cö³2³%ìã+L¾L—Ý+‹¡ü­´…ûQw9w#Ó1¯3#s© rïýrc8¡¡ú‹OÞû#L—‹f §£ök²`T6´À1% ‹ÆÑ0ü4 Íø‹r0!g:=Ç<€¸›ÙTLb< Uð:nÁ­œE3K Ð˱ȇ¼g¾ÊñžŠ;S¢!€Nãnrµø;[ „ªÏ’2#|FåÏêiàŒj\ÌÔUX£» ޹oÌÿÏh*1üAO€IEND®B`‚il32iÿÿ‡íëèÞÓk……ÿí…âáàÞÔÁéf„…ÿî†ãáàÙºÝédƒ…ÿï†äãáÞÂÅüäa‚…ÿï‡äãáÌ·ýùß`…ÿð‡åäãÕ´þû÷Û_€…ÿð‡æ åäÛ¶ÿþúõÖ\…ÿñçåççÕ½¸¹ÀÔÄsq~›²V…ÿñ‚èçܺ¼¬¦¤ŽÇʰ¢˜—¢…ÿò€éݾ°±¢Ã°ˆ[G¥·ÆÏÀ³±…ÿò€êà鳟rlw`Ni”‹‘ŸÛÔËÇ…ÿô€ìéõåÚ½‹gnmz{x€°àÜ×Ö…ÿô€íëöéêîèÉ}uy{}†·æáÞß…ÿõîùéêéíí‰u|}}„Àêçäç…ÿõ€ïíúíìíîéŠw||~†Éíêéì…ÿö€ñïöìîîðé‹x€|ƒÑñïíð…ÿ÷€òïîéìíîê‹w}zz}×òñðó…ÿø€óîàäéêîêŠrzxtpÝóóòö…ÿù€õ ïÔßäåéç‡rxtnhâ€õø…ÿù€õ óËÏÚÞäá‡mtib’ô€õù…ÿú÷÷ö÷÷Ý¿ÔÔØ„fglÇ÷÷ö÷÷ú…ÿû€ø ÷öøõÒ¼Ð|S©õøõ÷€øû…ÿü‚ù øùùíÁ•Þùùö‚ùü…ÿü€úÍ“€ú§}}»€}»úü…ÿý€û Å~ûû¨“àéàhàÎs×€ûý…ÿý€ü Å~üü~Åüüêiêü~Å€üý…ÿý Æýý”¨ýýáiëëtÙý…ÿþ€ý Çt⋾i¾ýþ…ÿ‚þ€íþþííþííõƒþ…ÿ•…ÿ•ÿÿÿ‡íëèÞÓk……ÿí…âáàÞÔÁéf„…ÿî†ãáàÙºÝédƒ…ÿï†äãáÞÂÅüäa‚…ÿï‡äãáÌ·ýùß`…ÿð‡åäãÕ´þû÷Û_€…ÿð‡æ åäÛ¶ÿþúõÖ\…ÿñ€çåäçç¿tu€¸Ärq~›²V…ÿñèèçèèãÇUQSRQQ½Ã¹°¡˜—¢…ÿò€éÈ’i^+0, *^iˆ¸ÏÀ³±…ÿò€ês8>O,-P>5pÛÔËÇ…ÿô€ìŒ&#)& "$""ŠàÜ×Ö…ÿô€í–+-)+,*! #)'”æáÞß…ÿõ€î¥-+*+,2$!"#'&¤êçäç…ÿõ€ï²-,,+-0$"##''°íêéì…ÿö€ñ¿-,**,0# ##$&½ñïíð…ÿ÷€òË,)*+-.#!#"$$Éòñðó…ÿø€óÕ*')**-#! "!Ôóóòö…ÿù€õß+'€)+#! Þ€õø…ÿù€õ ót$#)%)"#uô€õù…ÿú÷÷ö÷÷½?%$)$ ?¾÷÷ö÷÷ú…ÿû€ø ÷õøõ–"$”õøõ÷€øû…ÿü‚ù öùùâjdÞùùö‚ùü…ÿü€úÍ“€ú§}}»€}»úü…ÿý€û Å~ûû¨“àéàhàÎs×€ûý…ÿý€ü Å~üü~Åüüêiêü~Å€üý…ÿý Æýý”¨ýýáiëëtÙý…ÿþ€ý Çt⋾i¾ýþ…ÿ‚þ€íþþííþííõƒþ…ÿ•…ÿ•ÿÿÿ‡íëèÞÓk……ÿí…âáàÞÔÁéf„…ÿî†ãáàÙºÝédƒ…ÿï†äãáÞÂÅüäa‚…ÿï‡äãáÌ·ýùß`…ÿð‡åäãÕ´þû÷Û_€…ÿð‡æ åäÛ¶ÿþúõÖ\…ÿñ€çåäçç¾€st€¸Ärq~›²V…ÿñèèçèèãÈTPRPOP½Ã¹°¡˜—¢…ÿò€éÈ‘j]).* )]hˆ¹ÏÀ³±…ÿò€êx4@O,  ,O?3qÛÔËÇ…ÿô€ì"%%$ "#"!ŠàÜ×Ö…ÿô€í™),$&((!!"&&•æáÞß…ÿõ€î§'+%&+/#!!"&&¥êçäç…ÿõ€ï³)+&),-#!""&&±íêéì…ÿö€ñ¿)(&()-"%%¾ñïíð…ÿ÷€òË)&%&,,€"!%%Éòñðó…ÿø€óÕ&$%%()!!"!Õóóòö…ÿù€õ ß($(&%("!!!Ý€õø…ÿù€õ óv"$*$%!#uô€õù…ÿú÷÷ö÷÷¾D""*"=¾÷÷ö÷÷ú…ÿû€ø ÷õøõ™ !“õøõ÷€øû…ÿü‚ù öùùãleÞùùö‚ùü…ÿü€úÍ“€ú§}}»€}»úü…ÿý€û Å~ûû¨“àéàhàÎs×€ûý…ÿý€ü Å~üü~Åüüêiêü~Å€üý…ÿý Æýý”¨ýýáiëëtÙý…ÿþ€ý Çt⋾i¾ýþ…ÿ‚þ€íþþííþííõƒþ…ÿ•…ÿ•ÿl8mk-MMMMMMMMMMMMM?Mÿÿÿÿÿÿÿÿÿÿÿÿÿém Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿør Tÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûr Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûs Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûs Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüs Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüs Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóm Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè@VÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿPVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿSVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿUVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿV8dmmmmmmmmmmmmmmmmmmmmd8 !!!!!!!!!!!!!!!!!!!! ic11˜‰PNG  IHDR szzô AiCCPICC ProfileH –wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû2:Y~ pHYs%%IR$ðõIDATX ­W[h\U]÷1“É<Ò¤I§m’šT"‚Õbó!µJ þÄ5úURC)øøðÇD %6~4(B¡µÒ@û‘HÄEÄ)¶`RS…>òh5m^Ì#óº÷ºöÍÜéÍÌmè;÷œ}öÙ{íµ÷9÷ŒbYÜMQ”§8nvËÖÙ_¤Þ8íM¬SßVÓ=”›çææ¾ñ—‰LÓ„aH¥RH&“÷NŸ>ý1ø–ŠãeÊAiÀ^TÑ¥Á‡Ù°åbH!æçç£ÇŽû$—ËùΜ9ó%•ÆW5P˜ôàcgµ&óâ\UUø|>d2$‰ŠÞÞÞ>‘÷÷÷¯ „m‰#Õ°Ö[œ‹Ž˜žžFmm­ÞÓÓÓwèСWh·¹ÄvÙÐ @™ÒÃâ\@hš†`0ˆÅÅEЖ-[t¦ãDGGÇš ¼R`ãëm¢²²Ò.HÔ¶mÛô£GöI ŽÐÖ¸—=O¢¸¢ï÷ûm6d0"Žëëëµ®®®>Ù)çÎóá @Œ¬À¢2iP¥aió^ÃôÅ‹ÈÅã¶^E(Œº½{QUU…“'ObjrÒÖD"رc‡ÖÞÞÞ“e.Û¢Š u7:nÅbCKKKËb™/¤ÃÊå¼}7?ûj>û¤>k-ƒ»Ͼó.L2‘à¶”õ‹±R|‹P(t÷àÁƒo°ÿ“ÛßÚ ÐyâÖ-L\ù‹×þ‚’Œ#6öv²òu‚¸~{£Ù,f›ƒ2xÑP››š}zšššÀ`'SÜš[é¸Úí\úždÂ틯°ëÒ¸âc¶fF W&n" á® Äsy<Êôø¸ þŸÄìo¿¢jú.žû-{‹2zä –m9‡Ò+4ORÕò8­rûV„ççÑjÄœ¹ƒG ¿+&®/Ì JW úI¦ðÏÕ«0L Xhªßn;—@œ¢¤½FW snTîqÅW½BCu>:ŸŠ]õ`‚Ñ—ˆ#­ùaѱ”НB‡Ÿò ²#;CìH0{e{Û“QvÐ6UASiÕdœË l¶t„³9¤ “óœ䢯º­¬®†®ë¶ن‚Wó Šnf$Lã*tz°œ¥Ùó9nOqªÊ岟„cW†ÃE§ÂÀ†ˆsw €¤„,"¤§Zߌ[L1é± Éú0ˆ"À3@;òqÚ07`4i†gjzd°Üû ó+\ ú û̲Tó‡C6KNþÿK>4¦‘¿B¶nMzk‚2lIHYä-~žŽ„l Ž¾Û†Û¹ô×ÀmHúÑhSSSEÎíIæì?*uܺîu¥ŽñCSྪ‰!ù§tœÛKšP?44T;ù>uê”=ßÖÖ¶‚~Š ¯æy'äÇc¨TY"sZMÍrñ92;}ùƒ"Wt¯Æmù:vÏy10IÅÃTò¶â^½±¾Ür'K—x1¤R„¼ÿÏ–¢±8w±ý ç^AâÌ4IEND®B`‚is32cÿÿ‰ÿƒæªÿç‚ߥï€ÿé‚â¨÷ïÿë‚ä©ý÷ïÿî‚竉‰ÿ ñêл¯‡”º×Þÿ ôëÜ­}_v‰Ìóÿ ÷ðòîÙ€v~Ó÷ÿ úôòïê‰v‚Ýúÿ ûõéîè†uzãûÿ ýòÏèâƒpwíýÿ ÿþíÅÎuŽãþÿÿ ÿþþøØ¬õþþÿÿ‡ÿÿ‰ÿÿÿÿ‰ÿƒæªÿç‚ߥï€ÿé‚â¨÷ïÿë‚ä©ý÷ïÿî‚竉‰ÿ ñܱs<.n¤ËÞÿ ô±1- ,3¯óÿ ÷¿*(*!$½÷ÿ úÏ2*.% +Ëúÿ ûÚ.),"&×ûÿ ýìD'(" >ëýÿ ÿþâw%ráþÿÿ ÿþþõ•Œôþþÿÿ‡ÿÿ‰ÿÿÿÿ‰ÿƒæªÿç‚ߥï€ÿé‚â¨÷ïÿë‚ä©ý÷ïÿî‚竉‰ÿ ñÛ±r;-m¥ÊÞÿ ô°3-,1®óÿ ÷¾%"'#½÷ÿ úÎ.',$*Ëúÿ ûÙ+$*"%×ûÿ ýìD%% >ëýÿ ÿþáv"qáþÿÿ ÿþþõ“‹ôþþÿÿ‡ÿÿ‰ÿÿs8mk+88888888ÿÿÿÿÿÿÿ89ÿÿÿÿÿÿÿÿ99ÿÿÿÿÿÿÿÿÿ9:ÿÿÿÿÿÿÿÿÿÿ:;ÿÿÿÿÿÿÿÿÿÿ;=ÿÿÿÿÿÿÿÿÿÿ=>ÿÿÿÿÿÿÿÿÿÿ>?ÿÿÿÿÿÿÿÿÿÿ?@ÿÿÿÿÿÿÿÿÿÿ@AÿÿÿÿÿÿÿÿÿÿACÿÿÿÿÿÿÿÿÿÿCDÿÿÿÿÿÿÿÿÿÿDEÿÿÿÿÿÿÿÿÿÿEEÿÿÿÿÿÿÿÿÿÿE6OXdknnkdXO6ic14{‡‰PNG  IHDRôxÔú AiCCPICC ProfileH –wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû2:Y~ pHYs%%IR$ð@IDATxì½y°oÙUß·ïðæ~=¼Ô­n¡­–ÔBh`Ž$’²œŠ+ÄD±¡*Ç¦Š U .œ8T*lƒ)þ€($pÀåJà"L.À‚6²@BÝjIÝ­–Z=½yºó½ù~Ö9ß{×Û}~¿û»Ã{ï¾{÷~ïüÖÚkÚû¬sî^ëì³Ï9Skkkå –©©©ë½ë×½ë½Í~óÀ6s_Ûæã–Œös=ˆåzƱP×G[mœææÚC>ÓøûÊuëÑÌk°y y`´àÕÊÁÜø(hmóGÕMo°yà {`TТ›ôߘiC~Ç’o´æí–\{ø=È ÁLÂmÉ<×lh¸Ö£u¦ù[3ÿÚFÓk¹Vo8°h ÀÆ¡wàÎÜõiá3Ú€ ù–1 öÓ<Ð<0Òî¼W{IÓ3„åúnp¨äv†øÖ

þü‹/¼ðŸ|òÉ~æg~æsòð¢6’€ùºN¢P'üJìUIûuÓÓ§OÓ·VšnЦöÀßÀMÙqM/ªƒ>u Sþwj{@ ÀŸ¶Ò

áÂ…Ï;wîiýí}áW~åWÿÍßüÍWÔ)’…´‘ äd€àNçs"à€ošØpƒQ»±?;Mî¹çžÛáÖÚ¾ò@Kº+*Þ‰€ƒ¿ý1ý—¶^~ùå?l¥y`ß{`+qqRYËâDð\·c3Ddzzº\½zõ š%ø´àç?úÑ~äû¾ïûþBòWµÍi#)`v€™ÏŒJr2pÓ’%5êêö˽÷Þ»}å¦yà=Ѐ ï«~ ?-'¿wàÏšæ€á€Çíðvä¬4^·az†àÌܱé¶Á9Ý>xZ Á3¿üË¿ü«?ýÓ?ýiÙp2Àì@^;°'–ÔG½Õo¤Z°‘x þ¬“àþ¿gþí<@­­æ›åÞqíO"ƒ~–Ëø¸[ ÈYÖ°–gV€myyùmÏ?þøã¿þþ÷¿ÿ·Õäem$N6»= Ñnq Úòì´ëZZp]ÝÛŒoâ‚^+ð-ÏàÏ´E“¾jØ>öÀõŠÙnƇ\i~ ³ìÊÊJÑ,¤Ž9òžoú¦oúágžyæ_þê¯þêÿ óã¬Ý9®GxùûÍ ¾oõ9ùçïžÙ…€à­4ìg´ ;º9ðCñ€àÂI°•ææyÀy3gXÎyãC±žù†\ùw{–êê¿,,,°FàøáÇýæoþæôéOúÃ?ù“?ù ’¿[ð2“çwxøoÛë׌- §ZÙ÷àäoåZx ð‘¯Zp­¯Zmz ´;ÙÅÍlâC7¯žö¯ûc9è$W®\)/^??_Ξ=KBpü±Çû[O=õÔÿý ßð o”̨$À‰¾ÿæ1GŶlØOh‹¯ ò¾Gdcº«®xà–÷üª`+ÍûÒ9˜f|;;‹~m#×G]Ù[˜eL§/àCuÓÍ›™™)'OžŒMï¸ôOþÉ?ùî_ø…_ø¤L\ÒæÇY è· ú݆b]¿Åí=¸·•›å6ÐyÞWþÔŒûÊß_µ[¿Úïð€.}·½—Ä£ 8@×|Ó­OÜÃ!ZÏ2ÜЛ‹‚¹ë®»NþÓúOå~à¾J|žêñí'þü{À8¦ÂjûÁJ+Í{Ìœä­ {€?v6Ƈ¥µy`z`7cÞ¨ m·m—o½z¡ t6èz›`$·ß~ûìýÐýüþèþ§j÷”¶Úê'œä¿yðö„Nheßx %¯>”ü¡m^­Ñ(ÍûØ»‘8H㦌¹-óÁ½YÖ| oÔÁßíXÈLSîº%0õÁ~ðÿüÙŸýÙ÷IŽÇpËϳÌöyð8Ù’9¥•ýãNöV6<àÕÀ<=T"­Úð¯ûöxqP]X@áoŸuŒkj‹õS7ì…Aj³•æ]÷@ h.­ƒüßÐhXóÀòv§e(fš4N;u=Ó,—eL«ƒ?uÓ€Ì\¾|™5Sz2àþÅ_üÅ¿#Û¬ ðL€gÛLŽoe_z %ǵéœ K7jó@ó@xÀA8»Ã4àn$ØÎvÀsæCËtê, ÔG½ od&àk¾ækþÑ/ýÒ/ýwb{k Ç™1F¨íz¬ ™Všn ød¾%:{:¹ÙoͯëסKÍdóÀÞô€ƒì$½';*ffŒ×íÁóϲC´QºúÌpyþùç‹ÞIÀW~åWþ’ÏŒzu0ÿl7c¨ÓWëp^ëXβÔ-g^¦Ñ·Ü6¸ëÆ-c:už xá…øN@áÝÜ `[eêÝï~7I@ùÎïüÎaD™øB´ÝJóÀÍò@›¸Yžoí6 Ô®®Oâ t¬gh½\Âûnñ±Y6 ̶z%'mMÀX/6æ­à–Ü G©õ±y`x` î^MÖ…Üw'†XÈ8k˜Л# `¦}oŸz×»ÞÕnLæú&µ‡=Ѐ=|pZךŠr€ö>OJ’§[órð·-Öð^ž XÇIÀ‡>ô¡6j?·¢Zp+µÖçæ=î(׃ç¤]F7룗ë£ðÚ~–«y¹>$Gðç퀼€/"ã™CºÕ’€ìɆßjh À­vÄZ›®“†aÝÔ$2µŽëµ.õšfÙQpHÞv kÝLÒG¾¦S?{ölYYYY_ eÀûúŽ’€{î¹§­¬X«ß0´à†¹º5Ô7lÓ™ÍÊ$2£lŒÓÍ<ð\Çõ`Íϲ™†N–·,“uI:x-0:Ð m‡º“ã–£žålúN“ÙÝü Dëí§yàZ´àZ´Zó@óÀ& xmVð6“«m90Z¯®×ôZß|ÃÌ7nˆÌn°Æ¹ À ¼€ýdC.CÓÇÍdù–øˆ5x#=ЀéíÖVóÀò€ƒçVw¹Ö£nšáMË“ÉzYÞ:5ÍtôÀ½À^wø™f[™FЧäàõ–„kÚÏ ô@Kn ³[SÍûÅ­ÍŠà$rµÌýšfû5ݶÌw=ìã` ßtCh™ÏÞ à nhôLf:<êlÙn–! øò/ÿòm? »›˜h½ý4”2Ûœ°5äakšMºy`y€¿¬ï6ê¿+Û¶}×Ç5f;TpëºÎÔ=…:8peeåUuÚòf]×Yȧ]ÇÞvhÛ¦]¡Ø¦û -ÛÝI@ùÀ>ð¯à(A™Ÿ#øs@ …¶Ò<0Úm`´o§y y`‡Èm”)d†Ê½¶çúìÍšVëÕö\·Áß3ró ôÆM7 Íuä2^ëQWqðíÂïÒv\Ûam\´‘U0vfóXngŠÕJóÀ°|Ò sµy y y`Œú`5FBÑ©¿¢'4ÊN¦g|È–ùÀ¼YÖ4ê–â™fh= Wí|À4{ê9¨›np\`yCì©´$À¡Áëâ–\·6£ÍÇ}°»Ã“È Òƒ–éu½¶c~­“å̳,<Ó²8OxúÞò†ørsÓZP{²Õo¶Zp³@k¿y`x`T°Ì»¶™Ì(~¦g<Û‡7ÄÏ´Z&ó²½L·Ži,ô=tèÁ‘!ÐSZnh?{Ø-ØÃ§u­yàVò€ä¨>oÆß‰^m›zM«í×ü\¯õͲÀ‹Mw°§ hÔ)¦CÛÉL€ôÛí€ðhûÙM´`7½Ùl54Œõp\ÅÏtpoÙÖ(2æšf}è5Í TËSgËA œbÜ2–#˜Rð ‘g†!Û€NŠ·£$àë¾îëÆ¤héÕ?C³;C´¬¹?Ë‚{?‡è£xµl«÷@KÆû§q›švàêq›ƒàŒy¹yäL¯uÛŒ6$S븎쨶X@@CÖ6 ­oˆ 6ŠqxwЯ!r³³ÝZÛC&ÛS?nx@_ê2D«eÆÕ·š Œ³Õx“y %“ù©I54\8¨mÇô¨€“éµýšG»µŒiî“ut¡{@Öµœi:Ø£k~ÆëàOÝŸmZÏöv# Àv.›Õ-ëÀmhz mϰæoµ¾[v¶Úî~’o À~:šm_šnQŒ̇x™–qï~M£žiwà’±œ¡í; žõ,gZ†uЦßtð: àê:eT`;M¾ök¿öÚ ZÝø±Ÿ6(æþÖüIë[ÕÕŸIÛkrJF›šššö‚†À-÷Õ|Ã!^¦ áèé#;ăÆê}¯ê¯ål˺:Ø£c~Ƈ’óͳMèßÍ$`\€Çcß¶[Ø—IËVd'µyÐäZpÐŽxÛßæ=æìxDÀ2ôD무ßÝð@KvËÍFó@óÀŽ=@ðWFñ x›•¬›ñÍôFñIêE€ÈÙ†æÍ2®:ðÃ7o(ЛfXËQÏIuÒ]Iè_]¤ig\ÙŒ?Nwˆçv‡x6™6ÿË™ÌN“jhhØUl'`dŒu ¾e24=Ó²>ô|,g™ºš·ºnº?|ãð†½i†µu'†»™`ß%㦠Áì³!þ¤´Ý²3i{ûY®%ûùè¶}kØ'˜4Èìdwǵ‘y ϸ½Ì‡V×Mƒnžñ ø‘7(ЛfXËQwð7ÜiðÕ_ýÕ‘ŸNª8 vÔÿ޲Ç~µ²;h Àîø±Yih¸‰ ІèÛí¦í²YÓë:íÖ6rݸ?òÆá zÓ k9Ûîf0*8Ó硲›òØÚª½¡>5šÎ¯æ„ææææ ,sqÍ4³uÒ’É6gèÀ®qøC2C¼l|7“ïv7+“ÈdCò-ègíÞ€Ýñc³Ò<Ð<°G=0L&íê(ÝQ vkºnèæÏÐyãð‡ýÍH¾ê«¾*"ÿvó8½Q¼Qt|ÔÊÖ=Ѐ­û¬i44\'8 ™wpǧ?¤—i£ìÛfæƒ FÖ±ýºÝöÌËuãüȇW'ð'I°¾¡öaGO8  ý¡bÕYúáb>õŒ›ßàõñ@K®_›Õææ]öÀvC2uwÆñŇN_FñÝNͯënºyÆ3tàGÞ8üí$¶¾“Ñ®k@›.´ë2éñ’¢Ùnƒ“{ %“ûªI64Ü`䀑ñ¡nŒâ¢gÈTF–!£dk»ãêð°í­®›îÀß8¼í$è9øû²£$à+¿ò+7"»-@ṵ̂E¯å¨oEvH¿Ñt.5'444ì'àF•šGÝ´Œ×ú6Y¦~`­ãºíªC·]Ëæºq~äÃÛJà€x†tc'o $ °ŸèãN ¶†ì ÑvÚÖAÕo ÀA=òm¿› & źԴº^Ë×õZ¾®#Í[]7ݾqxN ñÕ@ 4êæ!—u\·m ÊŽ“Œ\¯2Éñ»^mïG»Ý™²÷ì:íSÿGr¬7³ÍÇ£óúoŒúlMCŽ·Ùãy¶_¿ÊºyØÁ>+ýÌó²¬ë›AäsŸë:úÙ&²¹nûô‰Bÿ3N ÷¾“,//Gð·žg,б¼º®v# øÐ‡>T¾ë»¾ë_Y®ô4:Ä3‘dkï}ï{§üñµž7ä}…c ólZ+;ó@›Ø™ÿšvó@óÀ ðÀP ܬÙID¶ îz†Æi3ã›õ¡æ×ºuÝö¡›g¸Û²l®wàGÞ8<qðQI:›%òÛ®%´çâãahú(XËQ¯i£t}¼Z0Þ?Û<ÐB¼‘·à–lÁYM´y yàæz`Òà ¹ÝÞf}ã†ØwàÜnY/Û¶ýÌ7 9o™F€¦#7`~ÖwÖ·-ù×’€èð&?“ïMÌ4ö´`„c¹y yà`x€àVƒ`æ™6¤“嶃×6ë:6sûæ›æÀ¬7ºã’äÐ é›$ àÁíÞx÷»ßý*‡ç@oܾƒçºiÀV¶ï–lßwM³y yà{ÀAï7»x¯w»õþÕuÚwÀ7Ì44ÅÛ2™nZ¾ ™œX.CÛU0Þµ$ ì±c~¶*?ÆÔgµàÀŸÍÍ·–H“”Z.×3^x™ŸÛ2}œL–ßî6¬[ס»}ÃLËÁÜ2Æ ¡o7 @w§IÀ»Þõ®kd>£pû¤ÁÝñ@{ðýȉßJó@óÀõõ@¹¥íüýe>p­EÚ1vÀ³<4&rlà~î¨>¢³Ó’û„­ºnû¹¯Þxî'â>gºi$~m0¯ ¶ŽqìZ6ŒéÇvÄóL@ùÎïüÎ-¿6˜$à£ýèÈwúæ}§Øy߃Ñ~¶ì6°e—5…ææ½èˆÜ·qA"óŒÁ„°m™ÜÎõÀëvFÕ¡{sÿr`Ífš×dZž °¼o —emÇròÏ”ù¶× »ìÓÌÏx–iøÖ=Ѐ­û¬i44ìCØrÉ.ÓÁüjúnׇú”ÛÈ|÷>¸ƒ6u÷×òã’Ë-—í¹Cä4C°ã$€~æànÜ~.£èY¦áã=ЀñþiÜææàL$ëÝvÀ:HÖ2×£^÷g¨n0ãôÓu÷Ùuwèèž °¬!<6êÆ3„.î( Г×f`ÎÌÇi€ÝH[ô@K¶è°&Þ<ÐðüšÌž×6ñÂ@Ùºf}ßi©LîÔÜ-¥ß€–ÜR'lëìþòÀ¸Áw3žùC0ÓÀ]wðÅ‹Ð\· uÓ‡v¦'è9øÕ82™æör;î›û”°ûeõ:`×2¶3Êî¼uÜN†Ùt·ûí·—7¼á 1KÀšÖ Àgÿ<+077æÜ.P ÃÚŸüÉŸüïÿïÿý_“§ZÐÆÕÿا¤¿ž´@ÞÚAi @Kvpú4Õæy å¯2´ÏübˆD纰yu ÎuËı‘ë‡ïd€{ãðúlN² tÛº/èÇ4×ͯéãêð¼ÙN-Ÿé™—qËl¹ðæ7¿¹¼ño,<¦Èí‚3>aá ³¶H~ÿ÷ÿýÞïýÞß’}fÆ%P~™é׀͎Ìx~KZ0þ iÜæëè„¡&&á!“åŒ`(æ›$›‡´Zzæ;ØwG§üN,cl3:Ó÷u7 Hlu©iYÎÐ6¼¡´ 컀ç Vó,—¡e€Æá×uëdÓjˆ ýȲ¦ Éš†LÖyýë__Þò–·¬¿Ì›ø…nà’€ŸÿùŸÿ?õS?õç²ã™'¼0ˆÀïàoh§º [†¹¿[V¾ÅÚS·ølÝo¸•=P™îËNì¡K@æ2Tw;潡« ¶^Ïv³ŽƒªƒPæå>€›gYó¡Û4óÏò–³MCË[¶†æ·.¸÷Óüçž{®|îsŸ+¯}íkËc=¶~{€'¸MÐ/œúà?øsŸýìg¿ý×ýן”‚º»a˜×Ÿ  ƒ•e ·2¡Ú ÀgΟ?ÿ¡ }ÛÄšväÑ\¹Z®J–IŒ¢·ª+­©UÍ .uW¬ •Ø„ÎéA:Úoj¦»o‹\<½=«©[îåªÁ5-d¸LÓ¾€ô{\q?j™IèÈÔrÑ3z–ËuÓM‡ç«uã@ø¦gÎV_ù»Ž.¸u°CÎFÉÁ4ú1ÏÐtà8<ó ³®q·™eŒ›gYө³¬e€lö±çDf&€Ež ð­œÆ†Ã¼ Ý~à>bä •–èoN}âÇ[pÐþDnàþ´mìõG[VÊÏ^Ÿ?W/]*‹/•eM«®Î]- çΗ…«seíò岪X+ËKejYSÙÚNv‡c×!¬RQ‰$ûk³3åÐìá2uèp9tBWk't/÷¶ÛËìí·ýÐ'Ëá“·—ÃwÞQ¦+3zÝìš®t‡J:ÙœfÀ¬‚Qð$tËÒ>¸7ê9 ×uË-G€¦Nq°¦n:r¦Mwp³6¼ECÛøÉ}GÝ}®M¢×r®Û.u€!ýL7?CãµMèl$ïxÇ;âÅ$ø†D@¼Å¿ñ7þÆuúôé—¤{AÛ¼¶%m^À) ÎÊ›ªÛKê¾bè ”–tãaKÊ¿÷“` A1dÝ?]1.]¾Tæ_:­`¦ÌŸ>].ñŲxîLYÖ€yHÁ{jUWøK«ei¡»§º6¥—ÔȦGljú \«­õ2%â§?¢K—¢pX¦ÖÄ›Ò3ÞªÏHO¡ f Ö¬€„µ™CeY™ÃŠðã÷Ü]NhP?z÷½åè©»Ê1á‡õ˜˜æyÃ^þa°ÇžŒyÔ< Ý2†÷溃{]·Ð290ÏYöÍ8|~èÆkèvA‡º7ú–K²Ð©Sw©q× ‡äLÛ¬íb#ÓÀ½Ács1ÏÅ‚ÌðvAö$@>»¨Ï ÿ×ÂI.kãéÖäaاx†"o­Ð—ƒZZÐ|1Æé$`NŠkä×Û ÀAýSÙÝýŽQOô׿ËÂË òÏAAÿ¥rþÙÏ•µ«—Ë¡M+À/./(ÀÄØ§>D‰ ‡>xnÝT2à˜óFA÷}H§nË6µ^-S×Ñɶ͇î-Û2 èb*à—‡z(L|¥µÏk†àïH–o._ÒÆí€z&ÀI@òÆÉ½Ñ€&)¹O“Èï'™–Äp×]äèÀ¶`?Ý{q_žiªœà·¤)ûËÏ<].=ýt¹ðÌ3eVSö«šâŸŸ›/Ë+ : ¶³ ¾ÓºêfŸ4@vC[mªŒßˆ­Ì]ƒ­%i ñ¤ˆtÁö6LÀÑ»åC²ûÃèFÓu-IwÍ)’ÍÆNk–i&âž¿öqM‰ ³‡eüèÑ#eúˆf ”@œøÒ7•;ßø¦rû—>\ëyqúȂ9Ó]7Ìtã†ÈzÃöšy@ Ð4ë”À Áì-Ÿƒ¼ñ¡À¶3Œ†Gü80æݺ˜†= uÓ\Æ6²-L¸?5Ýu`›fˆ,C· ¾óï,|½}¹páÂxï{ßû½bÕÆL·|+È{Ã1vŽ¡H›÷csÉý'Ñ€nœcÔak Àþ;Ç÷Ä­*€ä«ý•‹Êŧž*ç>ññ2¯ÏÀÎ(à_¹ª¯¬­èþòL·ØÀ¯‘ÞlÖ 8ƒÊÔ<£`Ü-{-]Òka@RèE|ŦV¦ëß”.dMÄÐ:¥«xfþË´~V•6H~M}šréw¥FÀîÔ=éþ Â(Uø]eoYSkkåØñeêèá2}×½åÔ;Þ^N=ú–rH·ÖbYôëÚÃxÿcÙZz½9@"ãà›e2ÍÞ²ðò†žƒ¼qø¦wàz†¹mðQ%ÜŒ[Þv¨g;¦gšu†à(9èCíÚÆ4ÓÙgpó áY–÷|õWu|¥Ú³Ï>ûkßò-ßò! ¸¢EùV€×ÐN´# E_Üöx©ýÉm @7<1,¶`žã7w¯ü‚* ¢óŸ®œþ‹¿(žx¢LkÁÞ]å/i.}æ>½ªouyÄ.˜®gBb y}d"“¢3¨vøúΪ¾¦`Ît=òX®H¸Ú_ˆÚŒþtµ»NäÏ‚Â8+|MO¬'ÁP0«€ñ·¯ÇŒ@×í²) é­˜f?ÕçC‚ÇŽi¡á±åÄ›ÞXî~Ï{ËíšXíýE°pàé,oüæA<×£¹D«ƒüšf¦Ù²¬iY†€ŸéàuÐÏIe¡Ñ&uÊPÿ½ïæ¹>$ošekßžmYÎ<àÍüš—ëàu=ë™?Ý.<|×»ÞÒÏßú­ßú_¾ïû¾ï·%S¿(ˆDzã¤ó&4pàØ’û%~~2ÇóÇÀ†2'`½‰4¾¸ã¥ö'·%1 ŘÖföç9~S÷jYé=ÿ{¿W®<ñ×åÊÙóeI‹ãx\nJÓê1ð´ò ”É> õ}ß×w†@/-¦Ýñºq[Â`¥²ªú´ˆXá$רºO9c _Q}AÙ F¼EŠÅ~Ó"À kè[Ä÷ð»>hCXWPîqTTí»Û“»~cgŠ5·$7Jt˜XÓ¢ÂÛ︣Ì>øºò%óo–£ú -_9H¹ŒžWâÔ3àRË ܶŸuàYh9ãæ9ðÃËr–5µ´é}6Ì…ºiϲ[Á'ÕÏrÆÞܦëÞç!YËd7½éMåÑGÅ‹Zð­W¯^}Qü¼(ÐI§72ê“t¸¸/ÃÜýMm @7$µ€ý}žß°½c€óB¶ ŸøDù¿ù7åÒË/Å}}0Y[ë ãáàË Ã:¾þ!±q• Þ¥(Yi×GÔ¸‹¯ú´(Aº ÖÝ2>l€uwúÙý€L-â9HZOüè ŒD9ÿdºðè,‘žMu¢½ö…þÄFѽÀH$Ä\ Yl²R¢ý×£…SÜfЭ“w*÷~Ó7–û¾þ?邜lFH‚÷Ÿ¡é xÔ3 º7d-cyó\·ÁÝX>ó3-Ói/·é:Ð>´÷€ßnöÒþayù÷~·¼rþ|9tôx\ÙêI}í=c‘"£®¦™ÖÖ‘Ö`] ˜qÕ O¥»"—^ câ÷ÃY§­U—t"t0­zØÕ8ÈHA3tø1G8šà £‚ôƒº‚3ÿÇ:vHB¯‡‰…N·ç °¦!z ßIôýA–ý-*¹»„U=A§ô¢óš=Yý»\Õc‘oúÛÿü ¿(X8ÁòÀ=ô7 9dØ 9ÈÔzֱݬÏ^¹]lúå5¶$¸×zÝìC3ÝýA×m×¸ëØ³Ì(ˆl.–Ë4ãð²MÓ 7Ó­å,Ÿ¡qï/¾ƒÆÍ~ÍrÆÏ?ÿ|< Ûoøµ_ûµ¿ûmßöm?¯vô9ãŒì!§ªO,¡ë<ðV*´ rH«6ìÔ§ÿð÷Ë‹¿óoË9^Ô£M+˺PÑ@Ö•nl"¸vAªÇ0(ÚBT?ˆE"²kàzì>x®_A£ >"’E4lô0ÂoÔ¡såͽýèƒMõºÒì”Õ]FŠÒ/A»ÑÈÚ¼!Û§z ðÓñä€÷S’j#º$áÎF#QГ+zä1hœ„szñÒÿ»²¸´RÞüm{=XÐÅ"*?9¸eŒ[ͲÖrÔM³úàN.r@3Ž Á9CxàìÃÐ~LB³Ì(H»æåþšb•-üض!ªà®Ú?æ9ø»´o2 ›|O€'ôn€ïùÆoüÆßûƒ?ø¿ ?ãD5Þ픺‚® uãAh?ZÐ΄æ]ð€³«ŸüDyñ~¯œÕc}3kZOßOùklë†!Æ¡~(2ÁŽ+å.$÷bwpUˆè®¾¡q}ÓËj”+ênðîíj¨Ã<[<§O’@Ý÷ðÅŽMFEÌ­¯Að°‰|$£á²} ÍŽ,"»J´ÙVúd¦ƒ@#¹X̨ôƒ¹ xÐxÔpý¥Ea«óÄŠú0#ÿ]ám‚ÿiùÜÝw•7üçÿY´µúà>Z?>ó Õ²ÖÖš–!6|. NÉ6-lݲÐÝËÔtêu±6)n»–«ën+ÓÝnæeܲ¦š„æ­®×ò–sß-ô~|úÓŸ.'Nœ(?÷s?÷¡Gyä¿‹$ ž èN×þÔF_Å´®Ö~×=ЀuW4¤y`›Ð Ï >¥Õý/ýÑ•^<]Ž;Z–×5À3Ên¹.²òÒvÂ`7`ûy}‚õ··½ (1eÏ2*Ú"¾óÓ‰v£3|èèDârXíÎ=Š~ vñC­ÑN/ ÆŒºí®.rtbC;ä]¿»@û‚­ØWCù€ä n‡t¶;¶øÑk௕Ëòñ¡Çÿ¼\|ë£åv}YŽ ƒEh«A–¡Àj™!^¦»^kl˜fœ©Óâ<¾i¶E=O}CÏûà~cÓ¸a¦»À'C[-¶g8¤_ó\‚¦Ùuoì@ËÕ=|jú“O>YÞýîwŸüßùÿé[¿õ[ÿ™Ø¬ Ëb‹ÓX³§ÿ ¶Qú³jƒpб–ô3 íÿŽ=Э„×ÒäO>QÎêÕ½SÇŽè²DCP?uÁµ«t÷Æ»jýJ˜^ˆM·lŒßTPÓ÷əРY<ðnpD³+Ý•?|××Ma]_5dÉG¥_”.lôÁ#•hªF{š—"º`P‹}…&º…ŒAïûÎØhƒÎvýèg#Ä—ÕèOg_|¨MûÌÛ .¾øByö#VÞ¡õ ô¡Ûÿ ­Œ ñ‡hèxb?e×r¦#Só 9ø[Îzpð)è:è#ã}€î-{ÙIqt‡Ê}ˆf]xôËûaYCä¼oYǸaè¦aƒÍûÝûŸýc9ÃZŸDê3ŸùLyÛÛÞöß~ó7ó/ëÑ@^ì'pDÞú“8h˜Š³¤•Î-hgBóÀ=ƒ¦¦‹ý‰rþâÅ2¥åp9Âx£a¯’\gqˆKîsw,hYäÖU,«3¬I@È*3aCºªÇƒpÙ-û¥‰´»ö‘î®ô;Lb ¬ô;’lЮ fô/dƒ„.0ÈnØìe»æèWä¬ñïôº. ×íT?éÑ5Ô'aB"´ƒ/EÂîD ™¢7êk:`¹¼ô©'ÊÂÜ¡–ãc‚ߴ¦t ­NÀ©å\7DÖz@ãÐ bøØòbPÓìÐ1 Y—ôL7D&ó­cz®›†|ÝF-—ë¹­LÏx-“ëàlÞw×ö<ö?ójû5:Å~Ó+‚‹¾8õ?ñÿBþ]±ü9u€Þ„êëJg¨¯4Ð}ø¦ù¡y y`»Ð`¦Ñ¿LÍëS¼úBߊþ±zmZoá‹a§¼úJ´’Chà1,1xvˆ (<N‘qdaÓãÐbŒƒ 4¦Ò ¶’ô€¹®ÏUto-ì‡ ÑÜVm;˜0Üãa9Z¥/Á—±) ©@ã„p¤3 ÑB²EB¢Z[ö¾¢»÷íw&c¿ÂD¿¯Wõ1¤¢Û,Wõí€Ø¿è8V¶Vì—¬í  t`·¼å|Õê ݲàØ%Ø¡—<ÛGÆ›éÀܧ̇Gâg›ÈÔý…6®d›ÈÕu۷̇ÃË|ô ÙwæS¯ÛÉíe[ŸÿüçùnÀìÇ~ìkÿñ?þÇÿŸäXÀ ëÈÔ fpÚù¬Ê¸È»´€ƒ}üÛÞï–´Xmvq©L-\-óbŽáó¦}€íƒ4MEôkÜ"NYÄØ š~{=^Ü£HwôÞP7¨özqe-¾ìv!6ÉFÒ õh³·F gÚºçum£¯> ס1¼º¯¢®ÞÑ+d ö‘ @‰& %|À•aW[߯Ø%|qn^k*”ÌÍÍ•»z½äbÜ~t É:æAƒoêæZß2ÀôÑÉuä©[žÇŸ:жnëš–eáç’m@·n–ɸÛÊÐüÜNnÛüºmèY7ÓÍó>g? G}”.:îv¨ëñÀ©÷½ï}?øÏÿù?ÿ3}¥•å$'÷g+ë§TwŠ©ý´ Í;ñÀú`®oH+ ™[(——4Æè?ŸÅeŠ¿»H^½i("Ø#d®WÈÇ(ÅO cB"BÒQ‚Eg×;ÄÒ°$< AÉxv¯KPb…6zÙn* ˆ]¼ã’u¡÷ëit:É5Vô«´x§××ÖÎ,Í«tõÀƒ¾.(V—D’ cËšU¹tõj¹¤O%U25¥¯"æ²Y Ë²à$›Qº™ny”ƒ—iØ3œR×;ªÖ1ô39ÈAsèbÜ0·—qËgˆŽe¬=ëf<ëfºqøYƸ!rC2î›ùöi¶kžõñi¦ë6@¹ÿþûOýøÿø7þÃøC$¯@Ø N­gDj´ Í»á P³ ø'ô"›Ë X¬ŽŸºSï8¢·Ûñ¶>E9m¬#pÒhTÅ¢¬þ®ÚLd)ä#"hÐEQÈ4A‰@â"Èhwµ-jèvò½` ÐëvÈ8Üç÷½C/šÑ+aa½ÎžtrÂ4ô2åïĤ—\ÞºkÈ`oZÔu•·¼4_.]¸X.é}óËZI¯oÇÏÎn$“Wp©s@IDATpÖéó 3ß4`]l3ó¢²èÖA?ßëζs #ðQ°ëö²¬ù¦YÆp=÷yÜv¶ ÝCôÁ]Ÿâ“,;„ÙfßΜ93óž÷¼çÛõ¶À?zî¹ç®J.Ïp²®ÿµ Ó+A¡»´à`ÿ¶÷»èé£GˉÙér×ÜJYºr¡\Ö—þf•ðùÛi}1qµ¿š覴xÐa¨øÜ>ˆ7ú9"Š¡·ÿ‰ ®+ü>dÊPü×Þtvºd"„Eë™j/&¬%rX%ðÐÈŽÈÅ>ŠC)unçm”ʵ6DÒ¾ J ù¾4պɂQü¡—… ´ào^_K¼¨E•W—Ë¢üwqu¥œRà º¡|-F`pÉœLw`DÎ8²ãê9È×r¶‘ƒ¶4ø†îÓÐÕî÷¨ýÌ2¶­¦»î¾åý3ÏúCt³l]G/Û§nyCÓ†ê¦3nCó-rîܹé‡~øõüàý‘ù¾Èc< ³)N% §œÏ¶þÌ¥•6ÐÎæy€«8"¹®òפfž('çΕ%E·µy]¹^½\K»óÎxi™Öµ^ VÌK5Â5±O›á‘ l¡¯v¢3‚y$[¿´VÄ%°jìDºÛ R°z˜£¾€i€—6À7xÑ5ArDc!E¨6‘¡Sz‰_W¨«è;Gë…VCpHØ%KQa?ãi½ÿ?þ-.—Ë/” ºò_Ô—ô–õ©ä«ºè_;vLŸM>¬6ñÄFqZ÷×ëlTðBÏ<ÃkU1H©ëØpÀÏ}q"ùa$Ù©u܆å2̶»_Yn«¸mM¢gYCtœüÔ¾‡\–5ÍžõMRxôoÔþ¡§5!‡´ ðë%úQmÌ0EÄYèƒæ­?KEi¥%íhØ 0ª,k0šV€:¤@uçÂ\™ÒLÀì‚Öèþõ9=!pøîûÊñ“·kàl,²“´¾‰ù¥?\%Ò™A"§ A\Ï0@Š@Ràt‚ÐMïwAŸx ‡ßîryZaf#aèìvÁ_Œ2€ëûËL7ù¡ï¼Ÿ@Š$ ©˜âË® õfûk|µ×÷vUÿ‘À’¦ù/_¼TΟ;[–´–bUŸSRµ0­ :ùôˆ¾© †ï°7®8!3‡ïÀD€ÎAeˆï ž¯ê‘³ ·i>Ë—¹ À©Ç©Ïg¶ NîOTaÝiÈAýi·ê‘oû½mÄ@ÆÀ¤€«åeiFÓÿDë5î÷ka×áÃGˇ—Êáùå2£5Ëg_*Ÿ{ª\8õ`9rßkô¥;Í (¨Ý2Зo4*98÷`-»ñz|!«KݸEäÙÿ±k#Xpa¼qµ½AÇPwnš!vT°Ç0IÑ~-–íá*—ûqE¾¡ýS¢Axç7í`w2]Â%¸ª/ÿÍ_/øÏ½ôr9÷ââ™ÿÙ;î-3zíë²|9­ÍjædJ÷þ§µð~SqŽ 1¶ÓÌ:PRÏ4›QÇ|[t¨ÃãÜ0ͲZÔÁmÛô:0ZÏm³žéÖ·¼¡ùCÐmײ¶eºnú´¬!2§Î>ºMó€ÆÍ³ïÌ3´M˹œŸŸŸ¹çž{Ô›Òk‚Ï@ÒÆÍÆŽ7¡oœ¬Ppi À>øm×·à `1M­`Ç å2¥{Õ—ôLòÂ_(S‡xÎ$@ŸýÕ`HI`Sº‡==»ZŽéüÕóŸ+—Ï>W^œ¹­Ì¾æ¡rìîSåÄm·•c’ÑT7ÃÓÔÐÉÖÑH6 D$—O5qMñ=u.òcAZVâ*Yô(vQX•¾À3’÷rëâ¢Ç{ûIvèKØõã{ê³f:ûj\lLn Èéú_‹ù˜¹t©\Ô3ýç^|¾Ì]:»¶2;U§ø$ðj9®`?ƒ¯IhO{¢tª<ó-÷>ø@¹ûõ¯/³ñ¸% Iè– ƒ`‘ŒqŽ_º*ÖÁ”eÌëÌw6Á‡ ú`ðsÜö3Žœûi¾u¹ gYè¹oYn;ø([ôi³’eŒ¢ î¿™L·]h>æ×ýîÍz¶ }ii‰Û_&Ú'µñgÇ:€¡Y€ÍwHŠ¥à¨VššFx`•€ÂÇhü½ÌŠ^úsUŸ(½ðé'ËÙ¢,éÊõĽ÷”û^soY•,W¾-’€U®Lû‹>¯ç×//Í•««senõj¹ð“eî ¥\8r[™9u9¢u$GŽ‹õ³J(Ö¸E  WÚÄ9ÅU™íÊú”>=ëC­@ð»K~Ñ&0whw z¨µœc° éN¾3D(¸ƒ§DˆýâF´¨>Ä[!ã¶0HÓ+qwQ÷õæ¯(èëE>z“Û…Ó/—Å+ ú2›’ŸEùjõÈåèíw(ÒZ íVÜÀдǚLi¦„1ýó}¼|êß¼PßsOyP߉à-o)wÉëtëåx Ep\e†p?}¨ä`C0¡¾²ÍzØpPƒî6àç %ó;Jg˸¡í»n⾃›îâvêú¬e6ƒµMlÙžûcšéÙ&´œ dÙ,_·cÈ(˜Öm€GDã$a 'ò¸­s˜„rÁY­44È $ 2\EÎôU"ø ®Î+x?û\9÷Ô§Êé¿úx™½z¥,kß¼‚Ì’‚ââ…Ãå.®µHe}tŒ§géKf3åèʱ² ­¸CÁqau^ ãKŸ)ó/êÙf)­;UfïÔvBÉÀmÇË ]åÎèÃCL…âå3¼aNýc–€ÀË¢Bµ#bìƒ"²Ú–!ãKtFRV”0<ôöGË_öÖrß›ÞXŽœ<¹ž °Ï^Hæ âÀ»È^Æ~«pÂF>´<#@y6yÛƒç-ϸ Û·¬¡íÔrÔ)ÈQlÃõ Žø¡–7Ü̆û1Ê~¦×8ºCíЦelu;¦ÉB£dêØX\\œ9uêÔ—ªªU¢ñgGÀŸ§©7¡­Ø-°'<°`@Ѩ²q?¿þ+—/—+Ï>S^ùë'ÊùOþµôÍëñ¾+ºz×Õ/A8nµPí¹rõ¸V©>¤'4¸1Ê£«\ÁOw«Û£é ÿ˜ÖÜ® dzíKzwÀ½­.ȶà’l½t¶,ª[—Ô¯ ¾«G5KpâN%Çc‘áaµuHAï°Þ30­u³ºíÀ"*žÁ'¸2o ‘1‚iØHì+=DÙõnx„&jô50x"ª_ì…b|ÌF,«N0^ÑÛçõéãù¹Å²´p¥,(1š¿¢­)}^ Ü™V¥;ºÊçÑÆeá«J`–fŽ”CÚÃ3GµôuZ×÷òÚŠ¨äÌ ¨c3J„æ.\*SgÏvY][Ô/Ìká÷¥•òÌŸ~¤¼ôÑ¿*,—xÍ#ÄìÀ}i9~—üÖS©D2Ìšý%˜–<6?¶ç o@Ëdhº!¼\¨Ó›‹ejXó‡t,SCö©.Y¿æåºûÍýÍ´Q²–·¬¡Ûu½–³=øÞ,ƒ®i@Ûêu¦Ž?~ŸpbÁ§ÖÁZÞTSx KKäao;­‘¤Ð48Æ@ÒÂý‹Ÿýl9¯ûœùä§Ê¡%7´E]Ùv ü4¦H7Æ -` T$®òÏ)Y8ÉGjtU ]Z¼GœÓH¤´]>³ ·éŠ·LmU³êÌh[ÔFB°<¯újYXS–Õ‡óËÒYV8­•+ ¤jR3š*?¢÷ 9/ÉáE9S¢‘LÉ>/͙֕ô ‹ú5CôŸþô»¬¾ÈE@»"Ã\¯¨íeõŸ+û%ùa…+{%A«šÁ˜S _Y¼´P›] '!:¬™ Eü°¥‡ØuÅ?}¤¬)ñQ§ôŸ…}4Émí ÏÿkÄ”’˜èÃò‚z¨aF‰‡ú#ÊAVË™Ï?WNÊÆQ¾¸¨úô´2u€$aI3õ*æ5Ýžøüü‹rö¯?·dN½ñ å~Ý&¸ÿ‘·”“ºU“bóÐï^Fã 2`ÔLtÐwà d= y¸4óÑ÷–yà.YÞ4 zÛ)CzîkmÏô!Ó€–«õ³ ¼,Ï|ë¹>Šg:0'fè[×¶Ô–N-¬é‚¿¯þ9mHØÀ[©<ЀÊ!­º= „à@5ÛâÙ3åÂgž.çŸÔ•þO–C+ p—¯ê \² *ÜÏgMQ\dzê]:‚"ð„·„2=}ùÙçà—é­iÚ{USà+šê_Ó#mØ8¦)ý˜¶W`e8ŠEtšˆ…nÅ©#市5wÞ Š+«K ÀšJ×cy‹$ÜG×U÷ÂÚ’fŒ•€ ,/\(Ëóçãé=ty1ïD]¡jH@ ¢ÚHxÄHA.®Õã¾>]ÙÀ¢»ë#©R‰¢ô¢ÕW§ôH#Ûò¦l©?‚Sžüß)'¸¿<øö·—{~¸œ¼ÿ~ÍJp<úbœó‚þs1ÍÉõ,“y™n»èåzTô3dϼqÐvk™ºÿ5?×-k["ç>gQtûѲÖ5´^½¿æ3N_j›¶á6$Ã'"9©èLÐÉØ ·žÔ@KÚ9°¿=À@¢=d!JÄ»ùç_y¥\ÐýüóšÞ¿øôÓevy±\½¢ O@Öô4«èYíNxšÒÕ)w¿5"a „šP©…¶"¹ËÏ=×]më šÕÿµÄÒ=t]Ñ®éþ?}è†!®tÉ t5IЬ ‹ÝfE›Rðœ™=Ö]ùHp‰†uË`YSî‹Âã֮йZ_€Î•:}Õ•ôŠÚ$Wé2ÝP]mp/î¯)y’,8vCIˆ¢´÷®9cw‘d¨/PW{È£¹ª+ø%é`cU3S ¨‡¦5«¡Ë{yRûBR€lç+ ÖèÖX@H‰n…œ’—¹+Êbô`ŸT[Ë:6S/Óµrìö“š)èf)èD—NèXÉ?ÓáGÙ•±)Í¢ ÏñfÁE½R¸è½ s—ô†Ægž)OÑm˜Sw•ÞþX¹÷ËÞ\îxíñOóÓ§x¢@ú~ÔÓAhTЊs Eð¡ 6ijlæS³íŽsí/ülçZîæµÚ¾ë†Xe?˸¿øÑ¥öthCö¬o™¬‰»&hñsðçTÚÐ4½;ù’­ƒ†¶à ñ°¿L§kt‰& ö™1ÿòËå쓟ÒÊý¿*óZůH£ûÇ ¦ŠŠq%¨ûÐÓºA½Â´2…a‚(­eꨨu‚!¬k¦èŃCœ^SPžVžR?H"P[[Sr±|{| ¹³ê㊦±gi±›®d™¢‡×] *It…«~ÖN‘–p/^ö—5°¢`©EPºZfª^÷æ4W"!ЇtÔ>IÀšxqïÀ*<¯_Œ‰£ªåŒ"‘TP¥?ðº-ìõLþš¶iûe¹³ºº_%àéÒ›`ß=‚Ȥ¿ìxVCYN Ö’í]¨>ÌÄóZì´5õ{åê%­¥Ðç~©+‹Y•Ý5-@$À#Cªˆ© /‚ÜÖùçSH¨¦uÜØWæTàp–Ÿ,ÿ¬^Ñ+†Ù¾ðùòìéé­­xícï(÷=òeåŽ_WféNÝFqÂ×µìhÊAÌr¦)™OÝÁÊ< e”~–ï$¯ý…O¹_›é\k¡«eý!¾mz†d  ñ‡hØó–mešûä¶ ³v£F jð$ ŒN$’$SÝk\n¯—"ýÓŒ âѾUµ?Í 7u™ÀÍKnh­¸M!³äìÉ9ø¡Àk„§u¤F©lê©-,$p/ë6A$ º}@r `Çët_Ö½÷ÕÕEášúŽhM ìÐWÍ~,ë¾;á^-¾…KNL’4Æ:öO|ÔÉK"H Ò_ök…ùÿ^FÖqd8t} b»¯cß–˜)‘ŸVõhd¨É.k¦å¡êŸÚ•¯aRÇgØáÈ«{§/Ñ‚ ©¯ZFž™A@”Äçªé¹ËzÜ¥òÜ+¿_¾ø‘?·>ð¶w”{u«á®‡*3ǵ¾¢¿¢å*”' (]û‚êƒûèýtË<ã†a¨ÿ±|¦Û^S÷톬 îzÖE~¨XžåkÚMd¡[Çв®[.ۯۀ悎7·‘å-—¡ø’Ͷ¬ràñ–øSàu@?@ìãï>þöµ/ vWôRž3O=YÎüÇ¿,+gÎè¾ñe=¯+[{ÃéGWÜ — 2ÃH¤…½ªŠÈ-c‰½#»"~ÜÃg¼AT?\SÏb#A´ :¼Ô†ëÐ¥•«âkÁžt¹*æ‚–ÀÛ% l@7B2½ Y˜ÑP„lùx­à4™ Y-úÃŒÖ2ý>Å=r®ÔµsË<ÞÈìÀê1=اi|º%m­³ÓU6· º: °¿Zãsk#ZŽJ$º"§ÿà\ñ»w$'$¶DRÂL|`Ì$Ò_uH6I7hS÷ÿˆéW·ß"°3*èa) R‘-í ú IoKŽþ/¦zuí;M!3Ý Q瓼ÐÌBLÿ¯ËSïm`(vñZEkðÍ ôæøê$È÷2ÂèñÆ €Žmô™h,ZF†„¨ëK˜’….ȱHD‚ žt9O¸MÒQ»' –´ˆsUO…,äÏÊùLëC•SZ¤S˸>ʆù@÷Õ4ïƒuëºå¬ë:rµ-l˜f;†Öw;®g¾m×2=#ÊF©aGíèqäM8ˆ°%[<êù„Û¢jŸÀëä ”ŒÀ*<ÏNYÑ÷á/<ó¬ò=Y^ùØ_–Y½”gA÷o°Y=ÏԾ添ÁœÚ™öÙ¿ý.:‡ÝøÑ€ÔþŽ­Ñ©ãõ@(^Ž[â!‹«ã%l(pÒUï oÍ#€Ðñ×â6LÏk¡žîÁ:¤'˜Íqa ™cRœ@‡aL̲样ª`&óêG´»ºÑ÷§âj[}‰~I†8ÈÔ~LåýdS$]ñÓ9ŠüÇ-BþtWÈ Ü¨ÎâRÆfgE@ûÈBEÚeJŸv°B$ÈK,nôm,Ó!í‹í q{bY‹òŠž XÖÅYžÄ 5ˆmšÄ?¸‘Ä &s1£3„» é«úX7!F—( Óùƒ½\‘Ñ™˜ù@•¤AÖÄÇ3rvyM>–eµ§¾h-c–+ åüÅ'Êüg?S>wøH9úàýå¾G+wéÅC'îчŒR2ç46å_èëç8¶é“Ûë!m×ÅãŽeGñ¡[†$x'ÅmÚÆfu·‹|- ™èY:õšfºíd¾ñö²B—ŒC«ë–;°°%öÐï¡g ;‚ú –”eMåóŒþ]u½ü±¿*‡t½¨+Åø p@ó¸lµ°‡®, œÂ´ xà@Rã¾dÔ.j°ƒ®Áž€¥‚| ´%;kñøòÂÅ$˜-3ÞŠMk‡$KG·#«´Í¯Þ 0¥Y€5:­(C®À=x…Éë šˆ§àÔ›CIA0”¨ÔžúKpŠGù\š%€O›ê³]à"˜ “,±Ÿ}‹àû$&Ù7Õ)Ý~°oâÉ:ÈÓβ¯NYOà Ù™Ì.`‘[‚‰L´ÞÙ¡?¸‘ kŠâKz±Ð*/ÒK„ rgiŸEò„§ðYˆí«Ái%qqoÛôYz$K!£:IÉLÜçTÓq\é¹"vqÐZ(uþ'Qu,\'¡Nž° Fœ7:ÿæôTïy˜¿p±,|ö™òy½ˆéfî~ôíåÔ›¿´ÜöÚµ`“Ç#7f½nߺd|ˆæ€/ËfzÆmãzCú2ª]÷3fåäÐCÆrÙŽi9™ñ-—ìä’^wP»oe„Z0Â1|=Àt¦¼Ì©3c€=Þ¹ñХϲOWèˆ`§/"tU‚¯ 2^¡¶QðÖ¾ÈÉÂzÛâÅŒ€t(ܶÀÓæ¼øgY/NŠ~H7‚±øra×o‰Ñ•°E?¥Ρc✾umásáÚø1®ÝÔŽ.ùþ¬‹¾ðä'·W03•HW„³^"êú¡ïqŒä¯))â‡9uhU;š¹x¥,}ñ‹å¥?Ö1>yG¹çmºMðez ჯÏF§@OÄ‹ 8¸*†]ÃÝo–ÏtÇL»‘xݯº?®[ŽúÐþÑç,“÷ÁôLc%'YSIÖ¸aˆ&þG[pàOè 13TAYAÿÌgôÿòcåÜ'Ÿ(³|LFo~ãµ´‰)=+?¥çëÕ»Wݸº×Ÿ6žWõ\Êñ403@³(ò] N‡ºì†ÁþªžD˜Âgàïþ ¸¶$šõA•ft ‚©ô)®&{Y¦¨;Ý.Èó:^^©;¥«Ý©#<Þ¦PD›úß]'ªÛñ”0(¸0•y‹v$¥äÙ5vž1 *E€†,ýå¥@¸ óqï_TzÏ{üyg³á_Ýfé,©­ÞO¶sï²Ƀl£/s‘ H;1íL¬ß:Pû¾ÇÞï\%bg' hߢµò_Óêø/n!(“a÷Q¡°›Ýò:-êä¸S'¢ãkýc"ÿàvö!ÎÉÐÏ.A _"@CÎçÓ\Á)CƒTÕÃ"JãÔ%’‹ %Ý}­Q|tµÍ‘…]™Ó Œ®”—ô(êé?ý“¢ÏB–S, |ó#z¢àKÊŒ^]£À³(uCÓ¨×4ëÝè¶Ý–ë¹Æ-DnˆnpÅmBÛL™¾èµ‚ZÐ΃ëë‚‚Zà37Zë®y=¢wæSO•³ŸøD<«ß½˜g.î%wÏè+8²r ‹ d ¸üéF4ìÿ iÄîZ‘é¹û:A‹ÖÀu•ÛÉ0øh¡¦˜nï ìÂbŸdÅ‹{Ò=V¿Ëp×~4 š,«/ñV:š¾¤ŸH_SzûŸZ×Óx ê´…LLl ¯GÞôià)=HH ʪ~è?øŒv{…÷éSNá?ÕUèŽ`?"XË\­CÇ5$<âZvº¨Û{¼÷Û‰v RðV—x…®ôu›¡Ñ?‘ǹÂí<¤v…°öŸ"‘NÈR7õ¯>AÇ'„Éxc WÇâ#N÷‰Ìñí-Ü\ÓG„ø2 vTÿya¯îºòà1…¾u·´»ÑgŽ4·PXEºô“Ä€`?ØÑ#ñ¢DB(ª"°ñ!mbŸd&³F÷#‹=®cçX—}ôtqIN©é\ZÄÚœ^c¬GWΜ.çÿ3Û#åîÇÞ¦G ßZN¾þ åð‰×$$tÑe7ÝyÇñŽèÐw­GúÓ€–Ëü‰»/´™û“éî£!²ϲðrA.ßȼÇAµ“êú€ÚÁ#µààó²ÇñǬ?T_éóÍ6÷ò+ ú¬Üÿx¹ø™§Ë´ÞÆ7§éý%˜x£œ–Ä3¤Æ*j挺±Óÿ=·ü—CµF{¦Œ,#F¢Röâ€`ô>è¯ö'(·ãq¸0Š2¡L…ÈH”„ÏÕt¿=®TUãÁ1V²/‹°¢¶–ø¹²Uéa¦Ùg1 B³šÆ§;CæVµô#½ŸÕB2’ á*PvV · ¨xùæ¯ñÜ@K¢ÚÓ?8÷ßÕýLX¢×qõ.~åª[Q¿k€!k+¼€G/š"QcË <+ÚxþôeÃâ·û‘›ð!­u|ö›>’PÀ»ï‡qfv._Ô”ùE|é«NÀåM}(á×xAõ¾D*Á¾aM?׉8šj¬ó¾@®;¢(ЄŽýQϘ6èΫ`…^ȇ?º¾ðhj(ÚC³+ÝOÐCΙ¨Kûœ¯q{€ã³ÂC¢Hé]ª/jáÚÚ|9ýïþ¸œÿQ”xÝýÈ[õxá[µˆðárøöî]´…ïpÀ‹¿+cʵ~ÙœDwCzk˜Û¤ ·cÚ¥š—õ¬o=êÈšÞàÎ=Ѐû°Y¨<°þ‡ÊÀ©mNS ¯<ùI-âûËråé§Ë ŸÕc|š€Ö3ß 8Z7KÀPÀa°!-a5"p· 4«9ý•)­þ×›û¦¸dFhfþ|Qþ ½i- £$%L§ÇTs ~’—ú(DJW~Õ½ÿ.¸2àÒ?…6big•è2a,ë+AKákYGö\$®öõþ|EýXc±¢gÞãJ^û ¿ ïÝk{±+)m„|®ú±GF:’U‚²ÂëÕ—è—d9~ì#òËrÔâå „z •üÉ’ ãgìGŸ9pEº+26BN²d:G²`%LoBI¿U²Ø2ptnè7ÎרáGžÆTB¹ÈÂLí¸’WÐA“7ÑSŽsÌÑí]ØîxN¢T¥ÃÌŒé‹úvŠR2væÏÿ¬\â]ºÝuê‘G˽*Ð× èÅC~”0,pîõ¥;']†u E*Ó&±1l¹÷Ljc~ï$³ýº½l d ­7Ξe¬‡½Ü¶ªê«ëµý†ZÐN„]õ€ÿ˜çuOÿe½”ç´^Á{é©§ôš5}ÍNW»ñ”7W™< ¯+#Eµ¯ÇÐÎü©2âN$#ÌP®àõW‰È#ÜMå+p+¸A‰ÑØ— … aDI 4ï.”@ÊÖY œC½íúC;A…¯‡]MA+¼N‚+åE D@#Àv³¬agÿô½?퉮‹ãvDÄG t´æát§ôµ\^ãÇq'Ì1« ¨iúÖMmÓêÚâ­‚ÚOîÃÇ €Öxm¯‚ZÑWò˜ö÷úì¬D] }[ÑìĪ µÕ…‹•ÖfËM¼*9vHvõh#‡„¨®vþô#D@Œ†>8"K²Æì@ð9¬àœ+ú +þcÕtaÖ‚£ˆã–ͪ_)ì?OP?ŽÖÂáÒuº£Xø'6¥;ªTDÃn¿M“ˆ…CÕ ÈA×܃nOD ¡NRH3Ý~9^ê‹:ö%ozļðîÜA‘ªZ¦AdÀAùúê$4‚eùzßèý§¼\Ö ŸO|éÃåu_÷õåÁw<¦6C«ë[´ ;=­¯ŽžYÈ4 ¶¶cÏ66Ó­ùÖ3¤_ÈPÏ4÷×ú[™ ±nƒÃh À°_u;èÿx¹âÿþÁÿXæžy¦LŸ¼­ÕsÑ·Ýug âÜË]æž3&è Ä ’¾Úí„xýÀ†ÅÁÐô¸Ì•þ´bBAétC9Éšpú·§­ò\·t¡vÓµh©¦ÿñ½.ÊFSV48ØCLTýI„¸Õ ›Ö„{‚%uˆàÇ5>8„lÎêA‡gÄþŠö{FïÝŸÑŽi}cô{IAzmNoß?¬Mö§õ)]ÖÀŒ•âB þ àìû *XÄšµÉ=ûU½P‡+íe%\Ô3åN §Ï<‡O"‚iV „Ž4öOW©++•8hôEÂ5ufM·fâv3ÈhHæ¢}µ -ATg#‡S=r;íGÜ"YЭ‡E-êÔ{X¼Éú=‚¿ö(úzôY>Ô‹EEWû¬ê]ACŒÈtæ8KÀ7yÞ! œ™”î(svE+huþÒyÀ«#¢È~,Þä¼Àæ‘Õ~Æ«ákßðmD-ìwrR »(錞íB§õ®÷ƒ/Z÷&FííèsÏ4ª^•+ZœùÒùóåôçž-þõ¿,G~¬ü÷ÿ×Ï”‡}T}–4ë‹Ï×w±5Î^œïc¨ukùÍø˜®ursµ~]ϲ ŸÌ-˜ÌOMj08ñ¼óŠö}ùgž,OΟ)§Ï.•KÏ.gî{°ÜþšûËqÝß<¢Çßxmw|Š–Vƒp?¤ÆPÙ p„ðnئi0~× ¨Ú‹çÍ!2àk#…˜ê¤ÎhK ž«—,WŸa½Wë¸ Öˆ¹Öµß½ëœvæY´Å­ 6´¡ÅÆ"@‚ëx}Vr|¡—Íj6€'xdP!Qý×U»n R’4{T·Fô ùôa}•Nrš¨¨(Éî„}Ú ŠË+|î—«|mñE@]õãn%(œ‡_¦±Z_b€`OاOh܇—TîS¯ò¹a]sK€/ò%@¢3_ YÙg yEj¼Èž’dÅâA=¹¨™žUlÑùøÀú:ö\Ñã¾$HbÀzni,«Cø£Kä$=,sÌèœî‹‹6­}œVŸ’n|ðGá Œ¬ $œv/ê‚·öRŠ %<@•]ŽR´ÆŽÐ7‰F3½£W8ÏØ‡XQ… Õvj]a´JÐôË9Æt»dfgdIÙÒÜÕ‹åÌ™såÜ _(Wν½=ªÏ/ž?[Î?ÿByÖ„'À„e\@ÐĺØVn–êGœ7ø³/ÈdÓ£ô³üL¶1ïíæ~'·`¿á›°GŽ+oºóîrû…#å졹òÂâ¹òòé§Ë¥—Ÿ.çß[ŽÞÿ fî*ÇŽŸè>…Ë ¨?Ãõg{5šú>i ×1Þ¥BÃ`—tWy\QÅÕ©†L®õbäÄ TB+™®Ž;l)ôhŒi"êü"Dq!‰J,d£¨>Ó\¦ÿŸ½7o³ã¸ñ5óœÚ‹«HmV·ýô÷ÿ:÷™éçÞ¶§Û¶$RÜwÖ6ïûC Ïa5¥¶4U²-f'#È, ¶Œ|¯ó!g‚X;Ãùïâ”Ñ{`Ð.ŽÔQ¾NaG¨ã·3²ƒÕÏ»þ~Âè}‡Ñøg¾ÍçHY£§ÃV7éxH…Y;ùÀžÝ/*Š£~|df¨(Ovºì8CQ³àÑ@ÁÈl]÷\pz¡ï÷ËÕ…“ >|Fç¥7J϶žØr_rÛ¦S_5´=:{ë)#²;kbçÍY OqÌi¨hñ¾ë–C5Ê·S jùþ¡rˆÎ*¹aÏ©7`êÈ]¹ˆó‡÷Å™"Ÿ¥ K›m‹¼T€ÙË!˜±\+[ÁQU¨÷À$Í™‹ "@HûLZGxš >BC}Pôž½0ÏYyô݃éé_ÿ”/7úêâÞÍ;ÓîñmfŒv§#Þ8ºsKÂSØvŠ]¡a­ß†ÿÒøçÒiþ—ùmÃ}–·óÛ<¶áM£a7|‰ÿv ,€¿]W æÿ þC\ñ~ó Îá{tãæôÕáÍék¾xÝë»÷§ÇÿñÃô›Ýv¿þÃt㋯¦CgاqÇDÎÎ_éôïÆ&—žVXV\™bbŒª£ÏбòV(·&}ÈAÀÒ¢£Ó‘E é@˜Ê¯"Ê…ê²È¿8œ‰firÇš~@7´µ8vfEô.g2j­ d:Ýu^w;¡nÞ€8cìŒÌ9s–´<è@ÏO»gbŧûÜe_n\A)äíCÐùÒRœœ4e:tù ?±Ý:`´U•RsvÓHev¿:‹O$­ó¯ Q†‡:çÆ3GíŒ\}ûá”ÿ9ç\°‘ðœöÆ¡»oÞŒ|.ðÞ9Åevtþ™ƒç&ºÁO‰Ä•»gxëí„X’£z9­ç˜óî•S'¿žÓø®Û»×ÂVXO Y/ÝiÐ.GÞ⫳_³ž+aýæHêF¦âJèùÀIYçÄÿrX$Ôg–gÄnˆK½Â,ÝS:kï^¿=ùazúí_¦@Ù˜ñ9¼ýU^ Ý?`3È;®ßöxšÔ7÷o{ ¼ÿæ‚ô‘ËåòËy«l;Úø(èÇèüZÍàc4»l;¾Œw9¿»¤ZKà§õ³”þ ¬nÞ˜.X¿öuµs6fíâx>?<œ>èýþäöôèý›éÁû§Óf^~ÏÌÀÑÓÞ×_O·>»?íÆV_Ãi@«IÐ;’Œ#N¢jÇâ•sÓÔ(KaG¡è`À5ì:ò ŠLM~›§†^ª‰‹yá€+mw£_8$7ñÆ÷pRdב ÿücsª~7ïÛÓÀ™»âÉf§ÀwV{9IPÇ|é ÐIRVeF´89ß(×\ræÊÅ¿ÎAl[IÛÉPg¸TäÈh¬£ï_]RèBYœ/Óõ©/=ò²'a§©–9XÆÈ¡ÿŒþ!’M‡àxŸ¬—:P³“á Û }¾PGøª'%³½Ð§\Ÿû% êgy…Ó Þ;î/ðl«ÄÑRîýUru+Ügâü‘×çÅŽ„ÞNHç¥^  NœˆuíÐosV~$ܲØ@Ëð?‚‚úSŠ•#0ï™+¼ûžÑþóéÙÃÓã¿þ‰ ‘î…á¹8¾É²Øíi×c„y6ÂÒ èœ0“â²ÚÁÍ›Áµ#>r¤î¶Ãm8E?+\®·Móçº,O×½Lïr¾ñ.˱ÿ±:]w‰™–À/ÓÛRë#(3HÁñ1£BF¬°Lc´t"ã[t níßž¾>»1=gûÁÛÓƒ“‡Ó“?úãqüòÓÑ_°WàδÏÛ;z>þÇ1hÚuÜ2â§+‰AÆÐ ÒºkƒEÐìë8FÖÒ8D·hÍ ‚T,—ˆ„Ð%–ž89 FÐɈ¤ÑvÓß>íÖhŸàŒºÍ˜pþ•ÊÌNo‡Ít;8:¹wq,Žv×\NY*ØÅèï"‡¾Ö“OÙ^ÔÈH5í€)ŽTCI¹]›Ñõwùg„Ÿs6 :s%xªG? ä™ÁÍ› Σ0o™?yQÁ{Z³'à2Šu&à^ùÓfñÎX×ÈëznÔÍRQ‡ï5‡'éü¥çìÄ•ÃSýâš««ÜàÎbx/é> ‹5[&WÓ!mõ‘°®ºT'ˆŽàFY9|`À!œº{âÖ=ô^åF¥³R_‚êĺü¬œ˜d`¡¯Ì´È6(<\ä#Båi÷Óý–¹,ñúõëéÉÖö¿ÿvzñè»*çõ×ý»÷¦½ƒ›¼ »=¥‚25kÚ9•„"9Ó²ÇßÔǶ“üXù/ý­4ý;ÙÆ½œoÞÓN¼ó–7¬q—ø×ÕÀÒøuõý›æÖØk¿w¯‹y‰!‹aã¢ÝÃÚ~y´3}Æ8ÿzz{zÌ@ߟ°úð?¦WÌ ¼:¼Ï¬À7Ó­Ï?›öé^1²ØT㼦‚^Á4&õ‹7Æ8cC±ó\ð\á[ÆZ9H¯<×1\+0/A¯ ²q1ö‡7Œ¤¯¡æërï0èïòšYÁJÇIQæt9/AV§¼:¡Ò.CNÏ6p€#äõW}ýC:TŒÑ} ­är–Cçî”:âàxì ¨§Ñkw?yèâŸChg•óJ²ê¸CÃÙ· Rq}[íê'èGµ¥ÎÂŽj æí:©C|± ¦ä¦é4xsœö§vü­È„ì Hlª¦L**wä~4[ø?uÄïÞ;QÞ…Q|š˜Šr– †‘öÁðYõ¾‰ï­~IÊ)Y^|$Ô÷X™Ò£Èzâ’DXZ0èIÓý¯øDõãíÿùÿÞ²±Ó°sãéü;Œøx¦ËüúC^+ŒÄÈkcê)1ÁCöËj™,É¿û¥ÿÞ[Ëù†wl¹úêXøvºñ¶ãºÞSµº„«ÖÀÒ¸j.ô2í«u¬w·Uˆ&R£KÌÿ ´HøÕ; Ú-Fúþ¾:u¯€Ëo¦G§¦'z4=þ#»à¿úýt8fýŠÞNo¡ÑÖ©ÅŒk,¡Ÿé}Ù ‹c''ªx$5ÞƒhXZ ²qË"Cä aàUG:ÇÑ8Ú“–é4ÜnÓ;L§c‡“zÅ”wœäìÂX®St==Ÿ¼…\¦­qÒç®óSæ”|f¨³C;(Ge¹A7î…zqBèÔm#,Qô<³Äõ%;bõFA^«FéÀQ¨NÛŽC¦±i˜&Ä Í¤­‹wvvÁÅ÷3>8·çƒ%q›Ýyü©)=âW©$;**­6êžáY7„¶RN±3êÃßú=¾}þ#NaøKÀ3ò§®(Ñ™¬’æùƒ“a³Vo‡aÀQWÊ‘OüH]*„´ XÏú5/mÒ5âÅ¿}ûfzÊŽöŸ=ø í€ïyîÞùŒ)~œ>GïáÐ î)銸*¨Té-ŒQ†Nr=: °K»¬ÿÏl‹¡ãËéŽKw¶a¦»Sp¾MórÙ’ÿ¸–ÀÇõ²@‰úÛÏŸÖ*°üÁjÕ·‚fÀQ™Ð8)‡¹ã½›ÓçL‹¾>»3=Ę>ïøz!36î%P’t«ÖÿÍÑ6fÎù;ŒÏÞdÔ±{ï]J€$|á‚Øº½ªX– Àsú?BFŽBÈ&RGý¦÷xXöÙd¸ð{Þ”,‡8pÊuêv&¡¬~ƒÆ… •Ååƒ]“å§œ´7}YCQ;´óàÔÉL å#ŠGý>ñbzú˜gõÛÿâu>O8D‹8ü}vòï±ÿÅ ¢»Þ7eWßÈâÛåM šêÈŸ_0Sàk£Á1æž[–¿)ËÃaÛ¡o·wþnþ¯Ò´¥ð3Õ¼<|ƒÂر¼s›ƒ‘f÷ǪàDAÙÐÀ逜²×‘ÞZïO7-}svszÊŒÀCïNOÿÄÏ!©{îÁëQw¦CÖSmFœžÎoÅk4<Ü…«ö8ÆPұŠÓú’QP”Q&glnhÏ…z±|&t0†]øºÁ.ëÿHÄbHÖwuòopÚïi¥ï¸;ͯý稟´_cïëvž¸osô/;ß)àßà;h\ëØÉ;âÔŸ´_‘Fq¦ïÁqÓ]¦á)TvHNœ=±=”¹9ðüŒ ›Òôd:xùxþ¬uÎ ©ºLáãÍ/˜qš ú0È‚›µ>íuœ‡¯Þ!î'}õdjvñ¡æ¼'v'¼óÖ¬®›ÎôI ¤Óÿ}CðöÍó³ªzWDõJÂÈ ógÚË Î¾¨á) ´ÒêÃR;{Ê)BÖñÇ,ÈÎAàD¦·o_OÏø’á“ïy…ïÁfÖÂNÄÎ _ốѾ{9ò "ô.ÜÇás‰p%¹qubB2½ePz\ùðÙiïè(οàuÍóàí;¿séæ÷shÿ’:Ûô»»­«K/€«ÓåBixJw-¯îÝÅ0»ILËWGÅ{¬q‹¥Y?Ô"†Å:Ã#§¯ŽnM_0+ð1çá3 °Ë›{¼‰Óµ ãˆÕ³ß ë"ù¯9Ž6#Why"`Í €§\Ê ;ÚwIÀ©}ݪþê”Fdä­¼¢Æ‰éìŸSÇàҳЙÀÓÛè ðP¡S…ŠôlêÀ$|(rO€x¿ÎqpÉâähNuàcé¨Où’ÇV…†6Žžú:z÷F¸¢p@Þ‘¿!÷è-9 Þ§{xØùW—N@ËÏ»Š8tš †P»ÏD„û#™Q;±y/›µCœ{F øÀ—Ç ',¾~ÍÕ¼ÎúÝ_¦7|Ð(Ú¡ºwˆãÏ3Ȧ>YøY;¹:(—´J«J¨ÌÆ\Ó;@ÏÖõ!´Ý·xC`,l;ùvŠGØ_áòKøYçr'àrþW}aqIKà’B–ìh@'…ÑÒÈÅÀšÐYu>ÀÊè\4vbhóˆt|ÚÀ8:ÔûãUÂlÌ«„o¦˜xî¬o¬¾úÃtȬÀ1¯!îóJÕÍêø-…ˆ‰¨Ù’+¶Ê#UyÁФ 3Î;Ë íIôÀ"u€Ž³ŽÓƒ ’¥_ñ;eø¼ƒ§óýþSêyBž_‡s~ÍÈ[’¼–/ÖÅ™!ïÃéK™ÞÇéc_Us¤§oõÕzT”œ=ýéH,C:~10÷žÙ˜‡ŒqìÙ¬è^û 6©×ø©.#{ÎýÍZ¿÷‘Õ™N^º0ðÉ(Þ< Î>bÒq  3é;k Ð‡¤ÕÇ@;9:Çݬó¯qø¹UéØ1ÚC&À…?ЬGÿ.¼g §¤ÕUušdIZÂØ21òAW¶¹ï]ø õû·§Ó‹O§§ùœï·JÍçhÍ+|;‡|Ê—é~¾{7<ÁÞWÞ*ÀóGÊ!bSMBKcuèr„÷Éîí°¿à'“o~ö9ÏúJãŒJï—qÃÿ× ÛŽü§dø˜¼ÊÙ÷r›NÃÍv|м–À§xׯ«ÍÃ@…<Ì—ž|ZeN˜?t ¦V4¢ >ùã7a(@¦¶u„ÂíJÇlªr¯À×9`ÈsƬo¼ã ‚7œ+°Ë¹7xÍêÀstüü22¦s¢ˆ¡’×f„¨‘N*b!ïÔn;Yó¡FŒ×À±y™õ ¼wkëP4èÙ7ÏHÖêºwü+—'þò>øéSçèé½ç'¸0\_|c ". øÁåñÇ¿è #zõ ¸Pfaktî1»*_œ"…Ÿñz`UÂÅÒ¹¤;øët>\¨àæ¾8qçÇŸ7 ,_÷[ä5D ü|GÁˆè¾˜Á1‚¼Ÿ=êª3Gô+.+øzܱoKä,àŽüs‚¢çIرDGÓê0›ùúFyOáÛkúéÀƒÿÑ•÷–âJõÀó^¦ Zj9a3~ýòíôô)R¿ý3£ý§u¿}=•Y©εØe™*›¡ :¤¥¯î œR—¿÷Ëöö ŽùÊí3c'Íû"žo{ØiõlŒLEk'Úq×ïøÇà]þÿ7¾ì¤¥w™çå¼8«'ÜÐøt¹þX:¿†–?!qˆ²{Ÿá›Nbì{‡wÔpXD œö¯7éùǯc‰nˬažÁ'«ƒÁÑÑòç;uÀпžñ*¡³œ6ø§ >ç\§8õ—¿Ÿî}>Ý೪{¼oÍ0«‘èÕ㤭óP¨$ër•ŒÓ€ø‹¤7ò"VBΧ'Õ>Eç ô\¿Ç醊Ð×ÈÑÀ; ñ}DýG¾ ÈéùÓÙÉš¥^ãÈÝ÷:>q™Ñ(Ç S”üËg')l0ŒåC3qÄü2Âw6@çRMÎA=`U“G§€:‘['ÏîþS=­Bå ³inž÷ÌŽK–FÏð—«÷Ö¿77(Æ.Í!4öaî+|éÐÁˆf¥S¬©÷5Ã{(ÇéAO?ê:ü.³%T÷Ê@IDATÞ1>–ŒžÀI~äÛ±„&¼ólÁ3nׯ £ÍªË2ÞKïÜfs'¹ùåxO9ž÷¯ð=cšÿÉ·ÿņLº8Ð\ïâøyŽŽØÉï7Ô í°jT„À>ÅGŠŸÏv=ûÊQPSH‚rXß–r¸ì£Æøg£8Aó˜c³ÿQÂ/qÒm®« ý \ýß2Ý¥ð[¾»‡¶ÍìlÎãMxFÎ:]¿76M¨‘4n#\.kƒ£‰ÞXSÒüOÌ\†—ÕøÞ 7pc÷ÖôUö ܾ·#Àí=ü#³ì`¯À¾#³;ì(Ï4·;²1¹:˜Ðl Ž×Xcµ³)X^„ÑÇÌèšî³èíW¸yÎ5`{ç¡Æ°ƒë_?yæ.7+ƒ»f¼C¼Ç>ú.é ¸!ïœãußï»/ØR¢ã’a;:"iÓ‚¼ wƒ·ê*mÀŒ‘b_°ÿ€lÁ©“N‰Á*8ã:¸‡´Œ™Ï¾@–ÿ ¨´|¯?•!æa6¡Ó†í ó.ûh,ªe¿ƒKð±Êš¥¯F¬Ž(cêíѕÊò™ðPeZ ºWõÇÒ 2èH%Ñl-¢^}L¥Œ´‡y®å†°GðÜfFøBs¯€½gmÿÉ“§Ó‹ïÿ:½xÊÇxD–ç1ûYöÙÔçÇ™ìUIÓÆ+®9,ò$:Ç:}H¸Ùφëüm–;ÚãèÙÈ ™ep3"MÈæG½µî6sü´~EG'Î’Ê«ÌÝã¨E†n¾nÈÇ‚TÇ ¹è#ðÁ#ôLçÌ.™~UùŒ÷‘)kìÈR£Ú yuÜ’¡·Ý¡ìWCEL'œÆÃhI‘ƒé}Fû;Ï{@'eè0›(©îó!OÔ~’Œ ðAÚX°Jø”Ùb€%xÒ}òŸ½ çL¼]~ÿá‚{}x£:sçºÉýFâ¾w¿‘æüS5céüSÝ®|a5\§q×ù»r„­®Ù3¡AÏ4>,Î^0ÖÓyƒ‘ƒ¾ÆwøÔ8œZ³-ƒ;ÛÖØTj¸à¤.¦[î[Ì üŽ“ŸðE½‡ïkVà±³ßÿqz}ƒÍUÌ qìðáÍc‹£O °þA3mIƈW™Êfƒ¡g2…uåÀ§uC†:·xèdí‘Æ#`“‡épüC´³€X¥(¢¾¢çÉú8î’ÍfŽÂ9/Àã9' Ô¼Êçy0â>Û…Žuí,NÝïþA™úP:O}ÄÔáÚ‘ðMµ‚]0“²rÔ<‡ùV…ûhWÍÖ P³µý@…ãFω͡—ÞiŒu|ZôbÜØ—ž”Ûý™áX¹ÃNÆšÙ½èšÌtX¸6ß¾‚÷ìê\˜j=)ºl¸I]|B"s$òŸvƒœç‹gòí¾ÂÇÚþ Îåùøûl`t—þîNÿhlꓟ(bå!o6*z‹Ùì ÈöµJ,e)×.ûXùÛ† é%é=¯ÇDð¥a"9ïƒ(Ü«»ÈClø­vÒ¸åòwÑï~ŽÚAýœ:ŸnJX²»wqÚ:ÝZ7ãŒÚ0o1z求1ué¢4‚¸)­¡f‚1\²IŠak•Prö¼£tf'ÀØû&q’«=øàø|Ï?|íLØa€ŸÎi:{(¬cÓÔôêyœE`m¨cô4HÓí©>A «ùãÇê ô9ž¢g 鋆?Øúq)¡‹ $†5sܦÁ€·ƒÐÛìI¸}óîô%Ç?gƒÕÃwo§‡§Ïy½ëÓ[fÞÜúbÚùò>Ft—óÚÙ…c ‡1×kZ™"(W öw(¨HÂGó*¦È |N×[n+R@EG¤ T0©£Ê¬ÀÀ­/è©¥ª’Î’8:Å´YŸ¬Ã8K $-+]ðæ™=ˆâµãÌVÄ5"'ö”!:ÙdÀ7x_¡™öæõCërèC=Oäx>»GܦN6Ä1@ ÞfànR‡Ø¶7_p=’Ùƒ™W½ÒXRå]óÎ>Õ²âÀÍwtﺿº5†ŠÌ¬Ã4YðÌâ8¥fãÓ^bŸ#ÿ©£}Žç}ö€ߣ?ç9syeÇê+|;|b‡ý n*Å·çYsy&ú‚a9©#jça| Ùr哯Ø>9ÊoÚ' y?…À=·öl§/bM·ê;©gÝŸþ=m;æþûú‰*?«¨iK×_–ˆ~…ùIKàénüdÑŠVŒ¤ýZœ£FŒÑ¡W‘–­Ó"ò#oÐxj–€ü°xæs° ±#,€±Nª9Ôv¡œÜLÊ­« nxk¬34ç˜Ù;¼ËgŠoL`¯Àïßò〡×§—ÿñpzÁ>‚—_ü~Ú¿oºq'Áé†%¬$eP§Fx|½*ÿõg´wŨßÑ\xùÂ×÷æ#µÝ`§£ˆÐäÓÒ Œ4Q9 âÀh@»¸äme¾&—-yfÒQ:CRŽÞ]npÔ>fd.pÔµx#¦²ž7ÃWÚ¡ãq“ =2GúndL£2›£#§ÜÞJ{Hp³J5QÁÏP'Ë"v ìÈÉCƒäʺð[3U¡,qš¬ixïm‡úMz»ÊMÞ¥ Çÿ>/Õ‰‚÷$øÀ\Ÿ?ç¦W¯_MÏ`†ç£ý7/¢/>&À4¿¯ð³üÂá=2‚¿³ï‚ú":ë‡M¬Ä>KH_“MÜÔB?·Ææ +“©ê¸&.-oÌQ!ÏjÝåtdìsʆÚv¸‹Cÿ[p ü‹ÂeÚ—?ÒÓ„#þ?•ÿX½~=X:×£×O—jœ#ÍSu `êRˆ£SmªG2 Ì£…øà$1Òƒl}´Ûe´ _ߪocÒãLjßÀ(ÐG^q\u ÓtçpoºÃHë_ÎŽ§g|µÍW xöðÿ0+ð¦ÇÌ ¬¿ø’½w§cöÔú½Ž†ÊðìÖ(ãÚ·²-ü=å¬É»SÞåÚ«ŽN˺զ-v›u"§\Ê#ÔÁ1#M:(Ý…0ú ã|¹'hmeuìADzSà1Ÿ¹uu$c¯ÊržÒ×!¶Ã ë›Ê|y .ŒÝX¹Ç2³ :tÛïH¿êX—töFeäoUå±S-½¼Aò§L÷Æ {õ•}%Š4zˆ¶0m‘‘,Àõ¾çOŸMÏÿ0½xðçK‡‚3#Öû8}–‚pªŠEŽö˜UÌÒaÍ4ØÏu~)¤CëdOn%˼€Þu5W°´††8»Qaè7úhœÂ_¡3ºÊ !‰*àwÆLŒo|ÐYI臤rÿ×Ë„ËBZn' ãËåKá²F®7¿t®W¿Ÿuíc #§ñd8¬ÑÓ’bÑ4|1•ƒ¸m4KY3TWö14¤ä'tIãP^›Õ ÆÐ:B..£Vû›js‡A>døp÷˜§ß3+ððÝ;fžN^=à@˜Ó+f^3+ppï{˜–õÕµx¦ø‡L®Ùæu¿ÐmŽ%UF½è¡dî¸Ê¢¥a•7^…F8šÕßõ’‡Óüp M¥W§ÉÓ7ìÍŽöÀ!3 :ù*fq”¢cb·£÷8t|wßwô>foJX*(À½§¾ŒžW»'ůèì\¸œ°Ë´|f ¯µ® Nº,¼®àÞ 2i§úðÉfKp}Ë eD³¿°vŽž'ïÒ#x¾zórzùäÉôô¯™Þ½y¼ÕšÚeöæèæ´ï;ü©5ï ?Åoíx”0"ƒKHÀâØl•ÖÜl¡UÒx…[pïÿlS®Ð²•.žuOš†µ}nÂ;Ë›Ï>ú …î$t¼Ý´Ë°¾/Û8Kúê4°t®N— %4Pëãø7.1ݪÓÐVè¸UE^Ð\.| 'eÜÎÓxg`J¬ÑÐVÎo`EcX‡uwƒVȱPŸ$·ò)šjrþð_”ÝeãkÃÿrÂîà ‚G¼NøøÁÿžÞ¿šÞÞþÝ´ûùýzƒà˜Z¼FßÝíxšù\dœvœYœÚYFÔz‚Ž=$‰¶ÁÆIG‘u‚tòÀMpvÁÃb@ˆÚ âÎt °¶yÓ3 ‘49@¶_6ehèÈ3šÝM‚‹:AòW®Ì|M‚;jwé@n-3 B&èîòW3ðµM™ H'À6³!ÐCþ#DÉ\ãÊ’ÚÊ>7¼?øË{—Í™†¡•錵ý/_M/˜æöð?1³ä…GF¯÷9¢×“ú˜‘Égƒei§„`gB]ê>”CÖwÓf„›x47yîÅÜ!³8A‰à+yÙQbTåÆÁâs§ anÍÑöA¨:õ€~}¾E;` êS õœþtë—NÂOëç§J—ÀOig)ûÅ8ggõ#0_å*gkª Ü fYß l;eyë¿1Æ#¯]×XºÉ,Âøõ-^eØu¤…:ަÈk Öldæˆì˜ìÇ󯆽<¹ÃŒÀz>=yù×éÕ ŒY±Wà_øbÛgœ+p“õåãéàþgÓë?ÿ¥ÖÝ5æÈ¦¿Ô5œç5Ãá0ÂU‡Œ çng!_ @ÿ<žÓ>]ž'çòW_káú^×°Å)Ù†ÍÌ€]x g]ydNµÚ:,Üz¨DF÷.è°3­bgÀ½ ¶.è8ÎJJ·g·?´Ó9ÃÀ¾#¥¼ö O¶ š‘0[ú‘dÜÀ,Øt„¶}ò•µNÐ×Âãýthg‹™ù½f´ÿÂiþ‡ßM¯Ÿ?‡@¯mÍH‡©þ: t¶Ô»3ašõ@øÈ…=Õæ´2wÒ*›$ •rZ¡pÊ'Œæ(ŸaDI[´¡©>o:¥ý¢á}È …g,¡Ì• £ÿz&1Úe#êÑ%ü¸|––NÀëç§J–ÀOig)ûùÃ*ߟ_aŒuÅù•’FN‹«,s;ÒDsÞôf6² :Ƭb@}gÜò¹™qÖ!6xÐmc zŒ³£¸²è%cD4Èf¸nDÅCü3޾ËfÀo8þ1o¸WàÑ)ßÿþO'ßMÓ›Û_3+à'ŠqVÿò¯ÓÛ§“gO‹žå£‘¥›v)HÄüÐ6gÄéëÂOøáÈBA‘l…®š¨ë°}ß4^„ÖÝ´ƒ2¢š{°}þÛ²SÏ©÷ìOœ"<ÿ¢dÛÔÎm©íùêj!Wšž]_îƒ<„W,š!t)P_K‰!xÊë…»èüw|×áæíéùsœ>Çó>ÿžãy}Õœ•¯lÒ9Ûa}ßsùékØ/ñ^Ö[áùŠç3² ;2D:ÙŽ š´å:ÝŸ@”8â‚Ó^?â¥"š|ë/M§;©ÂýŸÈ> >ÈAÙ[M /«˜õÚõÝ[e45’™7…§ž+¡c µN@Ϭ'HÐ2nç~98’J]/f0ÀF $ê5›Õ‘Û™ë•CÕ‡¼VËæ3ä<敹㽚xþ޽|Œèû“×Ì |7½{ñýô’ŽÂêwÿ6íñIäöBœ=}:½öç‚Ór¸Çètå®xhµƒÐd#nzÅ ÀŠ…ùìSv@w«“÷OÖ2g è0¯× )gtÝjô6tE•¬Ã†„ÕŒL©,ËÀ²l@%ëWpÖYä ,ªÈ^ôâüCy®®4¹ŸTkÃ[9ª¥í<åQóƒRf?8坨ÁÈ ·Økqp|kzòfúÓ¿ÿûôêÑ_#»' º©oçðˆ¦ùé\y/ÓC­á¡Ã$p¿ H‚¯Û Jd$î÷9ÌþEpœð°Ž’Ûþômí\ŒF”cDA-Ì¢9·¿‹‡ƒŒ`¦®< éŒ+£3Ež pð=ºu—Ï!ó<¤= ÜZ?J®/ÿ¹%M¯ãŸªßíû)œë*û[ä».Þÿ¬t—À?ëû—û‘˽ûŒ_ùF‚ÄWøÿgzû’i~y°¬´ÇHí¹üÌÄìv¦}Ì›Ê:Ó7©|Š\\º’6D64àäK\*ŒºúyL}*W+Õ$©4ÅK…Î+‚|¬cžfž'k*—½;<íÜ×G' K0Ô9 ½æoÉ —Æ àðâ}þ[ƒ:XÂßWKàï«ÿß÷m#µf:ÜqüΖñ jjíéV}ß–-HÇ ‡ãÚ“­2r#?8uyÛ ãÙd΀øðÒ•+Ž8:FŒYfHÆO"od·ˆ_;íØ-G¬LÕþŽéègîxÇ^ÎxüäÓûÇLæß›V7?ãÓ®ÿÆ«j¯§óç?0#À×ÑÅÊ#s!è1¿Ù¾â‚äJ'‚óéW¶ãâôëÁoqT]ìLî|å,צRu*NZ„^MßÇ¥Hç_ÿ„)…qµ²èŒ[šÕ1ôx;++xò‘IÇlŽ–!C|JôŸÀç8º¾qësŽcæRèðÍ[6ö}ûzâ¤Aê®ÙW±æÝ}×Â÷ìXB·:M:Ò¢&’,N[¨gYZµ-*õ¾¥y dæ ˜÷5RŠÒ5n¢àwpZ¨~Ò1 ®NSé¼ø†1%ÆTöt!¢â[÷£öL·ƒÍì›HL¹¡óéÈ¿¡z}AÖ¿©ðS…¥sðëÜê¥ðëèù“á²ýGíˆmçæJrÜö.ax“Ø8 ¯FÙ²áI2˜¥03¸Jkj*;Œthz!"ÂG¾Q“—@ÃSi.ÝNÕ2Ò‡Hq:íüÃÆBÈøžÔÁ³JuŸ]ð_³n}ßc‡OnNßÒ` ûñ;Îýx:á5Ãõ­ûÓúóo¦³wt8 fz÷’º~ºcy@ÝÔ;#~—ÒTgàâÜŽ•ŽÛNN‘œSêµÐŽAÉSÚ(‡hà!3:Þ<_ .qÜ‘³4¶¦è«3 \nþ·oV½7\7Ëïõ1yLz›8£XQßìÑp}ûœ}kâ9挅=ÞQ”篞MoŸý™+Þ9¾Íy8—ŸóìW/JÕ®º/HE=ÒiÊÝÝ!cç½_¥Ï-˜ˆƒ¦É*Ø °™î'ÝugZ*Ê:}7‘šRwvŠZ¶`äB-Êò71h ¦ ¸`Û1 ­óÿ ÷$G>¾µùàößÖø¿Á̧ÔÖ¿çí[:OíÿVy«¹æ8à6œzF-pbµ¶ÛaøM¢Ó²E€zZf+;„Ý6Ü‚må­´Å£2á XòAá6÷­´8N·[UCMlv»¶£å|”E9É>‹òßæ5È›|\æ›Ó[ÓSö |ÿ†oœr$íÓÿœÞ»æÍ¬À9£ÞÉß;f|Çè1¼5-åd€3V™`¶À/çå½¼À_eÚD|7ë9[À†C„ín@½ñ ´n4DP~5éoã`‰N³mãâü7#Ṳ̂ívÜK ÕvZÒ´«’ŠQUI]å¹…q¡ÊÜeÿÄþ]O·Û§ûrÊÁ=i> xxââîÁÑ´Ïg}…O}ç´Ã8yªÃGXRÄÖñ òg¾ƒx5’¤m®c·Æ>_É ›+3ºÄM4L‹O¡‚`%;à4šOù 3o«Ó¡ðÁ?'. ä—À²o-€8/@Ü©ÿ]^E5„^dHv¹,¸ ,€+QãBä ”UžVŸ1¥ëk_XĬw‚¤ ›ƒ×²’£v,%i «É™&»±3ekAãÎbSW¦zÛÕ[š Už3–hÔ·° ­ÃÒŒ’«LŠM\ª„)Žp«ŠÏÝÿ†QîÇGÓ«÷,0+ðÝ;Ž~ËC¯×Ó)‡ÕœðéÙõÝßÑÀ©3+pΦB; ®ë‚wˆË¦Ç$Ø¥‚8j½†‚û ‚ƒSU]ü§).c%ΈÞt° A=e™@˜jàŒ‘:ãp v„Šº(²s~@Wî­u]¥µÇ ÈÉóü=ç0µtã.SùŒöàäíÛéÕ«ïi§ôØÔ·{¤ãçƒ<:ôIç m2™}fzìÞGŽÞ®ù™šó$’¶~¥ãìIçy*PÚ’‹„FPïVñÖçDwÕæB)ùŠ˜N¢ ^ Ê”YÓt€s Sž§sÏ-±WgU² „~Ò­b£è_4l·/€å²hà 40Û«+ µX4P÷œYœnÓ™5SG@1”5ŠÊTŽX§®mÕZ­æšk¶£?‚…ÆÃ Jår$Á8ßZŽ£ Ñ*lžU,3 àÌ(&$äoš6¯¹¼ñŒË#aú3=.éœgÌž†XËþW–sìð÷o^gVà9Ú¼çË='tÎîL;8Ë ö\¼c‰€½«}(;íÌä3âEj/RdzÕGYÊõÖd}”E©›käwä”KÚ©ŠŽD€)}DNÊin9éüÕ§·$Nv–Šì%Òƒ~Oû‡Ÿ\*˜ÚΕlãþyÅ:UmŒÀ+#šŽZgoÇ4*G;*RuÔ:qž%ξã~†"sÃËN§µíhÈ£žDðŸH¨åqñ];¤Ò>:}t¢—°hàº4°t®K³Ÿ0Ý6è«ÇÓ9kº¯ßâÊѪ–6pŽT=†Ö“ÖÜ!Þf]G^_Ï+%¦ÇQþ Ó¨­gåk{TK'`8ît„¶ƒ§Íþ* <\‹ƒVºH•—+0g&Ä‚`ÑDªÒF q5OŒñ¶åñ*…?»6³eØñ8upQ‰^v¦Ïødî6 þᄆø˜Íƒ·/¦‡;üìåk¾§À¬ÀáíéüŸ)¾N"\qÞÅé;fP\vzþ9p®kò¾Cù{¶oíð"[8zÀ Ûm-=¤=”Ì:0Í¿ÜÓjzœ½j©®Œ‘ý9ôwéìíÝeß›ûN¹¿`7ÿ{Î@ðK„¼»¿Ãh‡WøöÙ±¦ÝõEÀ¡g©¡?ï§N›¬B”'íÝK'CøÞŠÂ`&U¬:)%>ìS6`:fu2?ÖãÇÿ㎊•þé-ßLxͦ¾“7oÒ&vüM;|EÑ{œæ·¯çIGå‚Y‹:ˆHýV§²ž ؘŒè…‘=0ƒò${+Ìwç!UF±ÄkF¤è έ³¾eÉ´v*ÞTEÛ+Á2²§N-ŒŒr Å|=WéLŒª5ʇRJxذÿÌÂ%Íèݾù¤Ýr¦ÂrY4pX:W Ä…ć˜,½C€)Þ•›ÉxUM˘qΰ¾š>ÏðÏÀH¿9Œã°Çe‰­ -”VÐéïù€kdz.i¬mpÀ5a”TÃKä¼ýÁ_~:þšul`ª£k§"-—ʨ“!tºqÚ‘VÁØî5ìz}Ð…:–ØDç‘·PááÌÈ@FÂ÷÷™ØŸþ…7ž°aÎ7<ž¾|‰;g=ýè³i¥ã½ûåtÁI„§/ž°¡Ž=ê‡×+ôÚ?ÔË aF1‘ºôô½œ±˜,-Ø‘Þí,}C ¸›ö”{ïÆmÖöïNç,óœ0íÿøåóé¯ñ¹‰‘NÌšã’}ŸýÎrØ´&(m[¬*’†mœ%Œ”¥' ÂY`u•©ïÿFFï[éQÙ aQIû*èÔv'ÇòÆ5ÞÀ ƒ®Ük±¡ás`7`ÄTWšó$ÉÚŸ·|C`Ⱦ>ð08æýÿì Èï-È]­9çãð¦Ó>äKiI/—EW¥¥pUš\èÌБjÜ×LÿŸdè…1#w`knuÐÚ´3?&3Œ›uÞܧ±Ô‚ç@Ö=îý V·H•¡uùYÇn™î&>=Â$ |ƒãq¸~QïoÒ߈ÉG^ù(#ÜCOùä¥ÌÛa–Ü4asœ/UcÄ•gT")¹Ú·0606ê\"£mP%:¬#9æü/ùâà‹wwX`Óà»'Óã7§7¯L'ût²nÝ›vùL±#ÓóWO§SrR>Óì,ÈGZ&òö@5-œÃ+E À´O^3|Åðô-£“i‡Ñüágÿ‚ó?æ¾®¦×¼ÍðÂsùÙÌz}™Ñþo5챤㱆z͉Á/èUOþBl$ù8ûªJ0{?Ìp4àY¾<¨êžàW×é>qÈRŸØ ÆrY4p5X:W£Ç…ÊÇ4À¨•ÃÛ³6Ÿ†‘ÕPjÿŒËùWnv¼Ž”,×3i±õGíùб´Ž•ãü%2òÃth§O!F3p ΜM4¨åA*Ï5£uÀyC@#>PdaÈòCIߥÃLY öÀ"ŠSOÒ[²:ë M;!µ· x ´Œ%ƒ{ „(¦3*AK)L§ßâw½þîÖ 6ÚÝËßs®Àc>OüöÇÝ›NÝ…ÿÕ7ÓáÅ7¼AÀôü£ïÙ…ÿ"ð3RÕFi#µÝ7 œÙå½üã{˜vááu/9¨çùÿҡx%2½NxäC=;‡8÷w¨/ïï©2Bžö0ÂÕf&†„ýŸLtúi– óýpòxzñãé¯@œÞÿÝ´¾}o:Ê^¦òY«ÿäkù¯ð¹:6[hW½yÞþ{Ó>/òÞ½†Þ¿ŸÞ>a´/{­õˆ·ãÚ>£}•pAÇ!â#œj-÷–„Ÿ7N‡§0¢âÜ÷qÿ[YNÁ»þŸ–‹CŠl•%†zçåf$j)CgèxfD(”Èg(üéZb(ç/®´[×éÀ¦\ùWKA©bœ;™ð6Ž’ˆIgÉKDiJC†¶Ç]0³ý©ßz°70:zvŒ.xer‡¿ýå5@”µ„ëÒÀÒ¸.Í~Êt‡…¾`úrç΃桵=ÍÕˆ£UÔHÆÃ“%S¬ßÓX:½ÜéàNìi,5Ä ¸LtˆÄÚ •LjbŒO=Sê›—©¦½ yäI=àF{‚3hÚÍ(k.’V½‰˜ƒ­%ZâÈ4í‡bDr@ÛcÙÙì-O7á ”SÃx IœØ-ŽŒõ÷5 ==¹?=dšþ»wϧ§Oÿ:½~ô—é' ®î3íñåtë+Ndùä Sü¼{ïxöpø+ŽÞ}wr6=ÁfÃÿúãt¨?â²ÓÍ^ƒµëúNó󯜚›;È:rç_mõcÄlÙW–ƒ}Ul§¥›ž6ã,ëøatRTì}Áf&\•IÂf 2m<ÔGÊŒpïÝ…Ä^@ŽŽÄ¡TœÌ,˜„t‘gৃtð6%ÑT„"wv­W·¦  8)ÛÚ$é8Ù0o?ÂYŒ£[tÈзaÞX›ÜrY4p5X:W£Ç…ʶ´¨×/Ï9ó}O¨ÃëÂm1ƒ³!בèF‡M-Ç™ÙNif_[<õ!+oÙhK‡• ¦ˆòSFID¶iÈ `Jùj’ßÑY£ŽJñhîm„–¿óáá%Õ3 Í–Û®9CÅúÁ¤%†œ.=øZá˜Û  ÷0œ‰6º#/ȃu¾bŠÿ Ùù·Ó{ìx=}ûú³O§çý¿3+ðöóßñjÞçÓoið¡¡Óó÷Ó+ÎxöÝwÓËþ‚Îi9·kÅèsµï=Ü3FöÙ°,vê"°%¸V”¶ÎbmHu85²”XÑpg½ÌÛLÇ@œéâbáÂéMȉà-ÈêÙúXðK¾Â0êò4#(¼Â.°’G¸E^ O– b‰S$¨•†HÊ—Ñ4¸vBì¹'ÊÀLJœ?ia܇ocÚX¢kÔÀößÎ5²YHrЊ|mOßÄ)À7g“5»yøDû‘§0ÑW¦Ê#`C!5óÊYŒ5Í2â%™¤Ù´?.™ÐÀj¨¡•O´ºþ<( ò”5͆@DmvxwèëüSUZãƇa›„%:aþlw8qÂÆ|èH:B„·í‰s ~uŠ e£9Ó°ÃAcV§.mrÿ—wîLwyÍìˆÑÖå3Ïä>utÔÞ:Ž‚SqÖ!)ɦ ò—¶ðvÄ‘ðCG(= ÔËqΕ ^¥LºIp¢êîH5rÓ•¯²T&~n{Ú*¥/+‚Ô|įNž…W]‰ÊlŸš(Ÿ~®ZÏácE‚ü”¢d%ß2XÖ?ÛÓiðÆ"ˆüò”qOÇA€©›$3Wã³Èáaý%,¸ ,3× Ô…$Æ.†Óˆ“Ñ/é@Ë+”1+C‡<úQ[|FÒ)è3Ná ½8ÕhjÜÉkq)Ëá2FÉIß:²1MÐÎ4²óÔ«øÂRF:›¯Ä)¸e1æ&ÊtI§ìâiÅk¯»_òìöx6ªvàoÑÊ(OZÀà­üNöÎ!òljV¦Ëí8A7Å•n&¬ê.zuWÎIŸrO9ÔuWýâÑÇÛÚPï'gëËh\u”³—€ëÜkßzžðogÇ9€jpfƦÔHØ´ˆ·B–:_b¤s¡¬ÊÐê(9?D̽Ü®;b¹Ôs5“àV舫 Å‘¢UòŒufÀê9°Ô§„º)÷ZLìHéü{I&øÀ²ioLG(õ¨“ªÆÜkñºQÄê·ßð0ö™Æ¥ÙI…€,.)Qtp´œP:Y®×¥ÿ—°hàÊ5àÔpÇÆ²› ƒ¦;Òj–Ás«•-¡èûè!0ŽBó¡4¦ÎÂk4íKh(ý¯ÓŒ¥Žÿb|¡-Ýž†Î4mp¡!«ëË ’hµ¾‚ì´…Óý‰A‚oƿʻä+]òψP¢e$½•˜¢\,ŒW£v¦I¶ˆëDÌŠntvüK Õ’ù¼J(ú ²à§FÑ é&³Ä¥kcÝA'Ì” ªê8£f‰l5"í£‚X àe&‚L§:ð^+­›û\û6;ÃS«ôeQ~à‰#O¢¨¤Ðr¼Áß‚§Žy+‘ñ_g“^$74QX:úƯ::âjƒyõ¦S®6É¢h[6Ϙ~tlåÄõÌßÕœ8 –÷pü Ô†•T/¹¨¾Ï!L†È:ÒÑÚÅ”j/㽈(wt(´H[k¬ßåÜÄ![ïÒj¤!ãÜ!hxâA 9lZš |Ž©+ÉnGÉÛ¶Úa£‘¯švTyb%^õ §Òñó³^Нâæ~@CGo½´‘v›­Q¿`ù€÷*GÕ•ÝàL@Š Õz°‰œ¶>¢ÿJ•\*À&ä™nðH I=දg€D³NêÍéÒqÓ§ÆÏÂ#Hóý$­o-TíÒ°é–‰48@ȧÍÊ- ËmŒµ‚[iq‚XÉÕ¸;pˆzÉ rß¼N*]pé5xŠæ>¯m.aÑÀuj@Û°„EW®^/^ݺɧcÙÉwvRÆ-œbAËÊÎ@u­$ÓÍIš#~z;ëÌc,5˜]WÕ«hØg2"hUGèŽèemcì‹ËÀ Ñqw¦×îŠMÈøc0À² }q: ¡°ñK;|€gÆ0R^ʱ¤Õà¢%ªaÐlZq¦ý—Ý$A[ãýJWd†Jªª[þÙÉò(_óO¥-õö@óiÇo Nw¶æ5`:ðn‡4ªsQ±<{‘Z̨$íM³)CªÔˆÙdFªhÚ‚M(Ù+Ÿv&Þµ~ŽŒ{T_wDZkÏ®5ŸúƳl&”µ$°<)ˆ¦>êŒî#HÕóÛ ãÙjžN:¹ïõ€³ M3™å²hà 5Ðfâ I.¤ li€óãO&ñ¤ù­ù šF`ü¯ýNÓKG°IcYÍûsG»{ò㥬Ip cm03#}1Í1¿ædg`:¿íB#ïHwÀ;_ÓsI%ÆŸÕ ¡[ɤ›E@8„zDT'‚²ïƒw¹8•‚l;žøRŸØt‡À‡NE4¯Â½‡blù‹¾]jɨ¼Úý¯S·,ˆ$‰–Ö+í y×ó¡‘åpe¨Nµ*¤‹–&‚ Ȥ"u,LõÔ¯p<*’€”rpŒ ÆÑÁÈÌú @šæçÛ-2@÷@D^²Îø¦Š±—c¾IºCu–|ö¤hL™eS ð¹Ì¦>â0Oâiõ,@?RÞOõê’ïŹ×ä¤ý[c@(,—EW¯ñx^=á…â¢hÀ¡ºÃAâ2µ[ÆH¹ëÒUŒ¸I«O&F50½ËÀ´ áOƒ‘xé€ÒþŠâ )³@‚ $6’^ ÆÅ“zbá AØ®[¯Mf4 ânaÌÕÁM!1C“Î(OïGÇéö&Y¬×´gáƒZ\†˜[,)¤’ô¶C²˜Þ–ú¯úÉè–=à5K#Yk’x²Êý²€êóÈÖl{yp¬Ó´~K$|¬OÙö/Mu„òPI[a/}*Å¡ƒúÆó=Ha,ógÝêhJ0,dSp™P7%\»3ÍÆÑùê\AUaìÑŒ~°…üy4}ŸWÐ}»5^@—°hàÊ5ð1ÓqåL‚Ÿžbm63§®ñez5¯„lçMÑb=-­-KÚ•bCËÞÎ\j]wàÅ®kà)ÎÆ«°h\c—ù *þaÔh×Õ;¤­ U·)vf†%ÑDmä•3¢ÛXQt΄`ƒ`¬CòÕŸzI°î¨o>iV(¤CEhÁ­ hÍ9)‰R9c]µA×reDóìƒA.p;äu€Žø…C03äÛ9[Ö²ÏÎdñ%;H‹– »˜gXaÙ°Ãù{¼BkØ~NX.‹®HóŸçÑ[È,ø@4³sç³yI´lá0–f´u!ðf‚àŒ¦¯9ÄjÐÁ!:áRCh¦˜rpÉÇøO^†§:ÖÜ¿ŒÈ½à|ä"KÀ%•þ 3í”o;äv$Ôa0@Ü#AÞv„mб¹B¯Ö¬v:M2øÆÖÔ™÷VÐ„Ò µ¢“ ÍõÍE]j¢á„°8r=®õˆZ%Ù(fñ¶Ó³NuÔòA²fUÜ\JH7nç@øv™uº ]Æ1‰skÍ|ÛRú‚fP@xÑ(N¥+KŠ€)KJúJ•C®öµsîg®ž.+å)#QAºîoQ7y\óf ú$öñº`†LÝõ÷ŽïÞã(€ý®¾Ä‹®EÛväZ,D?m 8½¹ºu£Œ•#”Y¯8ïò0öv $*³‹ÅÔ4°."Ôhª`uÕPcl´ü1ð£QXF*&Û"pÊÖ8–³Šå5³Çhjb5šLM98òmá-7˜'Ý$uGÄô`F7X˜VMËËǘ›á•®Å ÙPn‹%Ù09êȉ)˜I˜f˜2¥¢0Š|h¨ò²¬PBY7).i*€Ð#ŸÎ@¡Õå/0n¸Ó Vº[(ïTuÚÕþá@IDAT|8#‹ý S²ò‹¾FßG÷$‹1™­Àض&ýd“·è£o™‰†ì ³rN Ê|_(AÀÚ&‚ÉÕ]> *_•Šgë©îÙ\?µ«,÷‘|ilî/©°ÚÔL¹‚‚•´:êïIHÄeÚ…üp¾Ä¸;.¢-aÑÀUjàÒŸêU’^h}êÐpV÷îaÛpüù2 †}X:Ë4ÏË-coVýXø˜qÀ¡9\.évn©bY{{EÒmÐGõ&“Ø2ü)Ôl ¤Û{øR6i¿ePÓ ap€ 7Þú ï?*á%o^’Ü´¤ÈDä´¿FþiH¶O´®0C+åd -Ž_äv¾j8³)W"˜Á¨e€ æ‹¸W;XÆQ±yÊËWÓÒ‡°_^§É,¤zþKOŽDËCÍ„¦]¤¼lQ·*,æŽTálƒ¡Œ¥›T©)¥3@¦0d-˜+šØâì›ÎLa_ìÒ Ð!es0¦¬Ò §ÜÓ*‰¼åóÚ8¡I'À¼òÚ‘Ê3Æ3wÀG´:lw„¶Ä‹®B؃« ¸ÐX4pY«7gÇS6sÞ…Å;?.!Y»4ñ m\Ñ+ÔH5K 1¶mœÁOv/3ÄÍo*Îæ¾Œ«î²}Žÿ³,)ºÓ’†Y-Å‘äLvÈ·Õ:ª•Lâ¤U-¢±¤(hP¶ …†¯áYP%…F~°¦V‚ª™A¤¥¥Q0³~w§ü°ôØ‹ï˜âÐ.ÕŠYPkeM:žö¬isèúédy(ñpð‡›ín”I·Ë«%Å+d˜‹cܺwâ ÷¾T àÁ©ÊS …2—ŽMÌéQ/y s<ÚWxM-e£¬:†Bºl£ïYîÁ?ÒvÚö Új%K$ܨîÈuÿ7ºöF_õÔ¤#À,Ù!{ y’Z.‹®^³ý¸zÒ ÅO^Ãæõ©[1t5ú¯€ÝÇÀƒß»œF8F• #§ücø™µtik¤clc~Q·tˆSûâ *ZEO€Pß·/YŒS5EüYdÝ[oJp`+¸ŸÁiúÐ(V¡cÚ?. ¸i¹ÔA¤,#>JýŸ¶¸ùζTlûÆàšJH'!C ÙK+!m"ÁêÃ=Ž/m™Ê0œŒà‡Ü X†ÍÌ €»^ª:Hƒ0ð¤¶ü6ãõÁ^èò-Ñ@Ý Üì¡pëê¢HT ÃðŒ^¶1ª~:1Ò’¦ñS¡p“€zJêª{O%ËfajtžY‘УõY¾tÑ@Ï]Ø)¿Rä:J~Èྔ|ÙázIß/":÷âú¿aå×2™‹Þ¡µ><œöz#G0–Ë¢ëÑ@=×C{¡ú‰k`Ø@6Þˆë÷Û·ÕÛÓ‰CÂŽúK'  ÈK`;Ž–sjj©ÜZ‡×H‹T4Å$‰‹W޽§²´¬ºS7½íÿþç¡ówà‚-Ý‘µX”'– L‘äƒP´qëèŒõl6CùâŽRAG‡ˆ”íƒÚ¢—ÓšgCÂÜžðioÚ-C˜èl`Ê sBu¬‘ÝŒ?éñËÛÎr„>¸Â”ŸÎiHòC=âl~ñµ~ñÏ :å,UÑ T‘uÂ:u·=rz¦ƒL^”¦«ìÁ³|„ð^ÔAkñß²º×«L<;5}1Ë*ë4á/ß§¾2—žÿÄ©”©ì-¨µ~)‘ }ž'uî¨ÌìîÑ 0t»’Y.‹®XÿÝÂ]1ƒ…Ü'¬aWizÎ'óºÓY×ÈÛ‘.ú™G›±m‡+“!H…Å5K½a óá)L,]Ù—eØ›ÏÞ¬|“j`=>øSΟ™TÄõFÞâÓް?wĆñæ/(ԉÞzR,ª×:;#AeRDpýÃSlãQ‘Dºd3>¬2ñªVÃ#—AhµQ22ð‡SžWŽÆòÍ ƒsõõîÊ–ú¡‰lP«Q«Î¿|¡ƒÕÓ:;ùt^Y†¬E‹2]mB:αå’7!÷ªRrOH¿Tš3`–õãPorPñ´eÈ`W ‚n¼ž‡jKË`å¹½òr×# Uo°:²Lf>=¡Rôª~-°ƒ ¾žy|{ù°ÚXÂõjÀÇs ‹®W7óIà Ö65ºÎnÆ Â5x8ÙYˆíÂXU.§ŒK¬;‘Opy¯¹º45ÚfÇ=[ÞK±³k{&ü7=­å]ƒÑN«é…a•ó‘ ¡þ6ËŽÇ–¯Ø©cœéhC÷Wªbut@ÅÁ+Ï—ºƒpE›ŒÆòæSuiõ ^:Ø ±Ë•!ú CéœM~ŽÐ Ñg¼º¹‚Y”… ‚‡ÛèôÛñ;Ú¹¯ÀuúVÊ͵ÆFC‘‹KÅUÒÊ+n “"a»Ì8ÎÕûÏóa#¿‘.]$›ç­óc+N]!PqÚa…thgž³ŠS&Ë‹XîZ=_!4ÓJg£þ1‘|ÔÓ©‰~ù8VãÙ<;åYa9à°;U¼\ \‹Æãw-´¢Ÿº4ž†Ãc>¤¬ì™Fq8}÷äìûQVuµJ~d?XÃY*è ´¦>Å¡/‘ú9Vëú=×Õnx‰H#í0>d$ÇTùŽ•8wTrbØ0Ç.Ll9wQéÍ·\`šì ðñ³Çë¼Ð3Ô&± Šl¨h3ºé8A.™øe—?t^ðTš7¹!uÄ¡2ù³Z¬Qw;2W}ìGúª.8!"oXZw”Í:åL^Á7¥¡P²Ž¼d‚G,Å8Ð&m,üƒYˆªXüÕ™µ«ntaÚöùët¥‚= ¸5Åì!3JY;r…©A³¨’µn`t2޼ùb&út¾'wÞ[…/è@.ŸF'K¸n ,çüL WoÿgVúTчAܹuk:ÙáQÃé_ð~ûîœ)ô Î‡Ú ÐñèŒ j¾Öÿõ*ÃØêÜâô’ÖTÛi˜ ¬/eá+½‚ùxÝ9;Þ™òÎ'p·˧ðe6‡sÇäb'g°ù“ì‰Û¡µ ɧqd ”½ÎB@¬ñC”>+G»jø °*W ?Éa;˶ê1F¨úÕ±pMÝö:~ëðUêòôÏë³ñ62ÒÉ?×äË#Z—ýþÅÄANtaJ0ÝÕÙ轘.¨”ZžA+=•¤æ†¦sp 6˜ECñÚÁ kÏ¡xÁ¤fcÂìÙÌF«…W(šiF%«ÓàL ŒË)¾8$ë™Û8kxŒöŽê”‘âÁ©¡n­ð7Ì#Bß*õ¿]Vm´Ò¨C½Ð’>…ù®žŒ›IØŠ¼‡ÝÿÐévðé‹R· @h‹«NK›Å#ÏuB‹Ø°þ%Ákf[䥜¦*ÿùF;ÛB°>ŠÞ;>n K¼hàÚ4°±¼×Æb!ü©j@Sz5òyÓ=-Ü0ˆqc­cn;¨“ÑÀ·“ÓF„™ÞÎ L㼊WC¬Á íx¯á¹ÛÏC±ªNíÐëzÒ&sOÃkºµ‰qãDIÇÀÄVhçQ¢qEUv‡AÒv‚[NÆJ‘2¼¢›“ï“wÅ­dpFZjÒÞ–ãWn:Bìµ(=X;­"r%‰,§¨hãèAÅ!Ù6µð*C¾Þl(y" K6N8´¨ƒ4NX]Wä ÔK»ªztòÒ+çJÁ]߬åq²ÒøÅ ôVeUQgo]Ã*εi׳1ÓXy$¼P©ì2öžO[3‚,Ëý½ˆÐ¶` Õ›0înu–ú‘ÉÿÎ ìîL»û|Es ‹®Y± ×Ìc!ÿ‰j ?f²â«f+öô’sÔëZ–±GäÀv>˜ØØTí¼°Æé¸Ëth:CüIÄ0c`3,¤,ÅÃ=„€¥Ý… §†Nm¦ÃIŽ¿˜m<ÑÚ¨×"AÞDJ‡žÆY@ˆ †'2e$ßÃÑ– :³HH¶F”’í ê8úWÎZ&˜_X‡ãÈœ;1Ò•ã,/gŒv‡†ŽTZí¼ävËÖÍ3ÞN[ÿºâJ?q3"ßÁ&w¹Ì¬+ qÒð3Óu­$¢U· «ÌG®ÃŘÙX+m¥ÐmƹG€û÷mwXôs•ÆAP²Eº:²e¡,b†xNJ¹/"‡ù\õîàsà{ÇGóA@ÙŒI•%,¸ lýY_ù…æ'­6‚tÖ|8'èùÎ<Ö.–Q ™ØD•)g±ý€¶AîrãÚŠKHöôa;E|žåòí¸ª(×H€q‡hè8Ië+fäN0NËøÁè„ìø–hh—ƒ-2nür‰!`‰•IàI‡² U¿øéð,K gV´9ÚØ°"—Р|½!VŒº9ÿ´’Ë  Pƒ_m¤µQKä“p‹ÖŽV”f=~3lD%Ày0†5ζ25P޹+Taß«G'Äb8 "ÒÙ±C(]šç?H½YÐ<*WÊ(ÍWi0RØòxßí4®v‡ݹ;bËeÑÀ5i`Y¸&Å.d·4€\ÝÿóÉZ¼V/OkÎp$[Ø$5–à X祡4´ó3-¬Ûp¤j9­íŽ„Aò°þ‡ò ¡‘7ß±´âIN! ¿ 4_CºMsäSmfV@åØžªó·-Ç+Œ¶4ÊÒ /‹° ]å·h§ªiÛòù#Ц¼–š‰8ÔóÞDOܳ̔X^ŽÒ”£äžÊéåË·õDA£7¢¤…ÃF©eaœkCJ@Ó‰ª’Ñf0Åñ”m§+Ñn)O‹ƒN¡¡wL%KÔY‰C(m±ŠA°åV0r<=s¹rlëÂY/—URA†Öƒ õ¼§É ö-…f`ÿþ½iwwì‘ 6—%,¸ øÈ-aÑÀõh -ÔwAãg˜–±ÍŸ–±B7¼`ýjX»ºv>†tTmû_Ùý‹âlëiw8ŠÕ´ óC£ê-+nIÄi Zxåj›E9`Ë„è¦Lcø=Keƒ¢‰Ô =QÁÕÉw£C¡úLs“Àï`çªpå#eȦ<¨ÑJ&<¹ç”DΘ8-­7½œ»Ž¿œ¿ù‚mꔣ¶nñ‘œ?u!ÛY4×Úþä»|CD’mþ (ÄSšJH%Òè@ˆiÝŽ+e¢ òK­gN2Ì A²ô®Î 1* XÇòh¦Å¯Z&¾r›P³ã~ì{‰žC·¹]tì—{­)T–Ë¢ëÑÀe»u=\ªŸ¬Úxž3ªqʹ7÷E!±ç[f”$( ¸£å J£§]uäïOzyë‹yUÎØ~Êçt1Óà Òï•k­Ýò¾Ÿk˜e¹1ëâH¡îÕ_Ö‘†Xe ‘á\ãÔ=p£e'­Ó“—Î[Gç!Lš[!8àE¨`“6OPÆ8ñbY4ªˆÂÑ1’›œþâ~î×Ò_ÌÔ¸úH°S`gÀõsäM§C~àzo$ozã~gñҾܿ´‰K!é³-¾£x.3?”ä®"$‰,êT¼zÖ¶îp×þ 6;úq*XÐå¹ ‚%¥Ûè7Ù‘eè°ÔC·Pª>iå^û`Èuå#OîÇé– öŽºvêÌ™%±hàŠ5°,üL…ÆØýÌ:Ÿ2zÇõí»Ç÷º›C=“^øaü:³ÑÏrÃq×Yý…!í¦úµ¥u² tx¤QkŠ ×þwÆ2À`ÎFÄkä­A~sB!e1ìÀ)†$e!rU¡>Æ_˜´H˜Öëêüò¬˜O Ãè÷H:EÈÛ.Êö”ÌÄÒp˜O»Ë‘Is°•Nhš— Á¨a”–¥Ö"ZÚßù™ Ðü‘y£ƒØàÿ;-·ðÀðfÒ£¢ oyJZµPA46)u’WßUîµáÞjÁ)ë •Í› !€ISxÚe!0ÞR ÌûNÿ”ר­Ö´Aú#b° ÷ý-p &5a"ÏÚ¿ß{$ q¸Áù®„ד‹éè.ûeýk£+XdÀ/mïdT6]'=féC?ÔV{ßœ†í Ñ"¬ãç|à=‹P4ûHÉŽÄC—ŒõfñH÷Pwä7¿"7W*y%Ò‡Ïr÷(„º-m(aR¶ÎT@Š­0ËÐrTõáÈÒùZtTí¶®’:3²ºañF[o8è¥ ŽðuôÆÙÈ6äÈÈ_r”¥S3dN¥¤KoÉK]ÚKJ· Q`eöÁ¥rã«{õœ0ʻ؈+ˆj#„[QÈ­|x­X¥Çª Ž´Z0âⱩkYß3eØFP¢ð–Ú9d´§±ä©ëïã|Úãà,ÃÌw wI.¸J ä±¼J‚ ­EÛ˜0G–û·xÍÉihÌöp2eÐ5«,lUŒÍÝXwJjúZ[ZF·‘ÝäWi×û T7ÿåhߤ^Dê:² cË0&Ô € ¦Å:¢WyÈFË¡Ü|üh ßÄòÞ¹õAJýÈ^„¤ÙUJ „Y@WÚ*Ð aÕ(z®yAˆÂ¥š©7*Å-y¨Ùñ Ø*õ˜ØÜ Sí/ ¥«óWÛd§ ò€F%iöf‘®jCw:Æ™gOZ¿EfÐGz bh…gh6O9â¶w[ŸÒqŸ„ÙŠNßÓàßÁ.ƒ·u‡O[,kž³¬òQGãš>œæ-Û*wú?ÿÐ¥Ï崳ǧ3–O«³%\¿fû|ý¬Ÿ²V|Ýì|o?F° ªæ²Æ¥­—Þõ]ùmsªÑ#}âª_£ûL ý—øœ¾m˜jŒô|Ö€\É4ÄîY•káÛa@"ëjäAv*>Sü–çGðÚ‘€¿¦Ðß›ñ¢Î M§<ë%¤¾y+åv*Ê]”à ~. ÿì½[ÏmÝ–×5׳Ö{>ì÷Ý{—HŠÃ–ˆA ($J Ô è e*1/T 8T¼UÐD9ƒ€`qH¸€¯` Üyç¡¢I%&&Z{üýþÿÖÆœÏÚ›Äìçywí5úZsôÞÛ¹·1žÖzïcÌ1¿\:#ÈbBÁQÑu‹ßIN²}Èr«DC9ë}¬fbW¢__S|TH;IÌä?«.ôÔ˳õXWÝ#O\ÆçÔ^›ú;·Å‡Zµñ; âgxÁ6 ­Õ&}ýïùh".ø”oœåôÀ#xàœ<‚“O¤ž/}Êù€^@²¡¶)É`ª— |lOÎʼÁÔ‚nVþÜ÷A³üÅåé}`nkï[ŸúÝv‹„‘ÕP™9H¯6Wý÷ÿ,¤TOŸà¦A)7*$Û¹°öiz9v\c{A£ŸO~÷W÷®rúDx“P’Šâ#y)êÕÜ®|Ó ¬hûÑšúKˆ~‘¢S¤ëð€…È1“ÀÌÌŠ˜á s5nÉÃk •ruèê š¤]»”ÐvvSh6¨s ÍÛ®`ù'%_…- µÍt9Ä6í¥¡-E(EŠ=ZvµÊÓ—±ƒ—êÚ·]:±;²é>Py}¯µ%“€¶†¿“¢•ÔíA¥”'wÏøV“0þDΪOÎãÃ{à~¤{x}§†·Ô¯ù-€¹NR&{õç€ý²:¿˜¢^xýÏÇ´Ý{ûu³D•Ø{Ø×Ý€‰û‰Í¯H¬Rg[UR;YiRKÈÿH£m`Ö _Ô›éÝYXm ŽÒ§ñÛ}ŸdÝeí¬¼I(»DF[@†+§Ÿt¨3âÔ!W†6N±•„µ ÑÀÚ]Yô_är1¶êEí™?wÙ„ˆŒˆ™-Ìš6ÇnÅz2pw&#âø”Wºùºó)©5éFpLR¦Zt;•2,©BÒc{›Ë;ˆƒqùÏ 5ª²…)·àhÙý–;=oÒë³;P²/d’·ç…k(hz‘«3„´öÜ—gl¹¡Ú]¦—/”ñäò>?l¹ÊH÷<œø¶{àœ|Û]z ¼çD]ÇG]^ð#'Fâ¬GýªWŸ/Á5йR7Žzïå+Ç$åsgO7yA׋¶«}'Û¿Þõïn> ’e¥Zø…-GƨMG¢C~V„c·¤rZ’dél¿@z7EÊÑÔ˜ËD'ëÍð,—õ¶• ³}&-sPF r‹Mª¤•Ž9sÊ &6ÀuÌRnpÈŽh„¥7ÉFøÁØÀÉ€ÙÞ °Àã Zº\@4€Õ]@A g]#é@T·EÞû+~‘|Ê:þ˜nt.çÔúiXÉfwL›t—C\¼ªRi(ÙݰKß2êùâóPRMË9¯´÷½ʳ¤¾‘½Eå:Šà8©ÄǵÁùªÿ%V>׬¯ æÿ³÷æ!À‘sV§Ê %ü”{zàð€/7yÆC€&2©_ë{ÉëO-ÆcïÕû[èö¼êdÀDwPé¦4îJÝ´¿påõ¶‚2wÿ $Ѻ´]ý ƒÛñ€”'Ÿ|'Þw ø"¡e¹Ê“†AµOBè‘“D:²À –#ÇëÁGë‡ì`Á1Кü×*ŠJhjr£€4‹!$ œuK·þà –c«ÿ0ðKÞ¯ø n¸7H„¢œ¿ÁUE0=_÷lй9(]Z)·V„í˜øT¨C9èâ0¨Àå¯R\N×ÈJ%j‘~”UîÁ$óœ;iª£“š´=€XIa;þÕT¦×@ùC5ׄ8h,ç.;Ô)€ëm€f†ðþdz›†î¬N<€öoûDŸ"Oà}¥)?tá6À®³âú’<² JtUûŒ•¹-úÝö‡NFÊ,ÛáØ]é&ʬ³ÃÐ{ ´ Ò#À_³¹ò®K]D˜0bSŇ/Á¿kчFÍ$þ²í¦?eŒÑ‡}™|Töd‘ =vVö­¬áV$ÚšTÆvWøKº5cˆM(ËR¦!YË#F9!Qï¨ð½›œ…ù)u'_’-ly„Y"‹Ú\¸m[+géµ×aWnXö5hA Ã-QIñ9o'iCsúúG1žëƒ–¦=áG¡s$x Ì„@Â0—jy"kdD˜hèÄÆ)Cà ÈWw|SæÙ{çO릳<¼®K¯ëÔð6z A•;à'wÿ}±Obüâ}ׇù–mRxè Û—W.­ò\Á›öK]™Â¶45ør°›t¤ðÝÿ þövâàŸFÿ<”—ÏùÌ 2ÈkQ ²@£”V-ùykáô¥ñ£0“1ÿ-V²M·£°Â‚°üKy£S‘ýy`ù,"˜É#{åíl ^w.ôhôÞ*ó‘1ƪêõçøX÷*[;G[h…{Ü {†ÖI†“Šâ¯M1gÔöÓ¥é§0pá·8ÛIÞÖ'¯Rb+ã_9½ïßô:A‚r½7•n} Wdê¿…)+'à:ƽÞòuJT]Ox Ð'—wùÝ Ë>€™Îy8=ðh„{Á§ÈÓ·¸ã×ÍžðŠÓ§Üë¼ã]ó–†Û ~À-3ÓÉMç¦á|•-«å„׃Ölâ7MìÓ"û ½¼__ž±o¾›ÑkPŽõ«Û ­~}W„±å¾AáÆ7nø¿†oZf-¥™#ì[ȹ†ªn ¾XG"’9k øÒ›¹Aå`KYÀ2]ÙÝÿØU] |fº6ö>É[cjMl;?0 [6‘j˜d~Ä­í7ýÓ D”Ç62ž Sä[Ûvê áXZܲR>~’>üW|d!|ùkÉØ§R,%úbHû¥Õ¯7“QË­_ÛË«{Ç-Ù–k£²ùÈœ¶·¤yÆÅiýþçŸÝû%À•sÖ§Â!Bö)óôÀÕ¼àéW¿B~âûÎ ~_C&Å |‡ʬÜgkÜ]Öd¨“؇”ª‰¾|ßà{ÿ ¶¾¸_ Ü)a–xÜ1!ÀˆÝ?‰áif f]½Ô ™êè ÝÔRZê "Çì[nu˜y7Ã+X_™h4kYå¥5]F €MžŠ*^f,b«;«÷ðó0d÷ß>ÏcضªŽ úoÆ, ‘}cÊaÞâk9äµ›ãÒˆ;ð5ÁúÞ'ã«#µm˜´)æÌyS{Æ”kªô!wÅi{lšèsìØRd+ºò™–wRо„Åy«ª;^Á3ñ×àC'78hsÕ7ü‡/í¬,;ü0»dOç§€œåôÀƒz`þTÇ)ümöÀݸàóï!·ù°ß$ù„~ã£Ûÿ® ¼×™Øf' >°¼uj”ª? $§_ŒÉIR¸Ú’4B9ØÉR7€tûÆ<Ù¥[BÚ$~E3¶ß–íWlu+=y2°ê¢7¬[K0í5XzÛ‚mûI¹á¡/x!ׯ©5KŠÞ 72êÏ•¹2VUF~tÚØdkîâDz¼£‚~[Ò­Òn°±¾å¥[y¬æ\­P‰nJÀƒsÒr;¾è§¸Š¼âwB¦Êv¡*l;´Î>¶ Mu\é•X½v$lÎmé!ø¯ÂîDà ¯É~ŸŸ¾ó…Yg9=ðØ¿ÉGPuªxk=°Á’Àvwy—ú|‚ß@Ûmÿû~Ùzl“ô\Ëáî@~@… jÛ‡÷ ¶}éQ••´ÿÝa¿þ,ðËd¥ö#‹É‡µ!\›ŽUáô©€çØlB¤_`Âåè‘䓈—¯Ò ò +«myìQû—8~j¦&zI$“F— ]å`OþŠ©•·2¨ í%Í„¨>-Ÿrø(Ÿâ¦ÃÊ+>Y]ƒQJ’”´|”$ë°‡7fº¢å»¥[=Ëë» o| ÌûQ©vz+ga‘EÇ~ËÈ›~ds=;©{ñWÚØÊ¹Tøº8ÐâÈåp½N„èá–r ±Ô.aú.—^´u¼«?ÆÓcpïñ¬-;yÜþYŸøv{`¯Ûo·ÜSÞé«Iyà“p0 n³Í/aÃh£Ùð¼„ößœ,ÀÁÂûþ>þg»t&ù¹¬‰¸Âh•I Ž"à@f7µÀ­rÛÝÄ?‚0´’5I€®ÅPÔb O‡mêé x+Ã,ñ ÈhÆev¨Ú6”¡˜-¶¥qhMô .'0Ê•@°‘;;#/ú眄 ¢µ]>eH˜¢T¸"W†`Êš-ÚU²eƒÊ²“.2©…ûiñì´Ô¿‹K*ÎHà£728,O8Gði]d¿s.üïÆ r…ø6)#+ü½%qÇ2gûPÖíþèäp\ ”Ñc[í·ßÉ.- *ÌZ|-§mWþïï;v0žåôÀy`ÿVHü)öô€·!ïõGg>KV¢É[Å6€z¿ [Üíª¿+ü†WÛ„ÒÁû€ÏäÞ>i‰HßàªïÇŠä@Ldu³ 84þI(Ï/eIZ š‘eݲ‰«v óUÁ›H“dEm¶ Å"ít,îs %Ì œ¦]‹C³ÀZŠÚQ}ò§– Ø2«Ì-!Ú¦¨ì„PGÎèOã»Ç¾¾”¾c¢²ü8BëÛbĹ´¾9ñ í nÙŽ¶(¯©µÃ¾%“;$/šï³Òíé¼ò–YÛsj@†ŽÉÛJjØ•~¦(µÃc$¡@OÛ;äÐÏV¿ô¿Œ1F¾ì0€ómÕ>PT¹Ó9§ÈûäÕ‰ÿî{¬æ¾û†ö`#20ê·;~åì5ï<ùj‘ãY²xõ÷ø:³5ï긓”ûý ‘nóH½÷¯ íAØÇ¼0¹å!Cž #¸…Œ $ •Ã1ɱ¹ÒÛ}`­* Çêˆçp$Éh.T{L"‘„j>mò{Ñ›oˀ㠡€Ø¾ÔÉ^!Ä`h!ÔS6ÍÄOI}Ò‡ˬýX7ÂòŠßYù®è%I²¤¿P¢Â© r¤wŬ÷õûò§Û¿qÑÜ­o'MÒY›m—.ó¡{š=ª­A©Ô1ºãƒ.M­C`]*:;˜½n,Öao9üºíÀ÷ü,OHCÞ‘¢íê?ŽLÁôú¥þ‰v.…÷xcæúkëj9§¾ýÈßË·_ì)ñôÀÕ]™‘?üðòÒï8ó0^0$YKMp•£)dàIþ·)…'ׯbÓÚØÚzSÉu÷%Ùö)ß×¾»ð ‚Fß&ÿ\ùp™MLF~¢ž >%Íé›p Ì~¤(ýK¶°²([žeäÒÕ”Iþ²Šñš9:›P.É?_a¬`‰Z–ÞªŸä82Ìë‹Éä)ôË<õ´¯Ô-ý ÆW)óó9VD&7}“ÿuRÔQD ò÷ Þ›$7”-\ZeÇá´-®¼¯‰Pª[¡½ÁÏé AðCãDCÚ}KòÊŽ´éXÙ÷\­8[‘¥ âýXvš)¥íþ3-Ø"C½uÇÂ^åTò^s+û%â÷—{ñ(ô,§Ì·“¦äüv{ Û§àO>æ'y€+y‚]^A›ð_ÿ4ÀÎÖ; éöKiM¢î\ñ‘õÐËyÙ"yt÷ÀÕ¾ÅÕÿÒØO±qSÜ*÷Í€)7ÛæÚ–t@#“—›½Sy29 ÎXFA+‚?Âv“] b ¨s?!RbrÆ:ynK ª>dt1ï¤âͼÊ @=~椬2A¢cé1[°É¹eÛ;Nûc¥ƒ?hÇåa[én?ÛÙDÙl"·¯}šœýùPu(ÓW®8õÚNÒ`-\Xô…!88â¼rB#­«$p«èb:•‡,JÝç„;ª%ãÉŽ#bfA)Ø>r^ø7ñäòÁ¼8¤çáôÀ{àœ<°ƒOñƵFл?b@Àó»{SvÅO œ²©ÃK“>Á7ÈÝ;§s×›}Á~`ߨ îp[ Ñž°»AXûæóZc¯oÜ"(:BÚ >d!‰¬»!êe!¾Y/<ŽéЃí°—€ÿYeÚ·ˆÞöÕ¤ÒŽŽ$Mi2ÉQˆ‘›dteLrZ㇤©»J²Vµ Í é\Ëšr£!tKkö©åTûÂÒ!©Ðc½ònåÒo W)¾ Â¥ÝFvŸ(\ú[â¼Úħ`h´(š×i†VúðpÜgEÙL{Bº[PN¯ŒRx¬ŒÖpb€7ÆÞãM€g9=ðX¸F…ÇÒxêy{=ðɧ—çìÌcëä*Wû½ ΆģO/w\I^›§û Àº¯Atè½›X@û‚oäèÈTå¿`’Ý€*ÀHCQtŽîmG6¼®ï%ŠÀ´@ “ò5"‰>\@h¨‚ƒC•Ǿ» AÌ„g™…ñ¿71±‰\‹äû‘V5–­e¶¤h= @;îQE²Ûà7òf»ä„F‘š¬º+Îö­ýÔî¶ß¤¸Ë½C¶õàµh»p?ãªÔñ"„åYÕxVó`Å”é7E&GÉ2®½[}Å+­‚zå^'(…·>®¬±a¬ Ö+ó•·Åø{ð‹×ÚYN<´z ?´–SþÛí f|Íé%/;Iɪ”VâávãQ‘Oû^ž|H– šÝÒï×ç€À“p,½B§vWÁ¾"­ƒ£²jÒ=’à-Mùú ƒ ñ¡†¨’²e=B7 Ý—«¢ou' ¿‘Ió ⛯BV ÆH Ïë…á —­ã–fr‰Õb½…þÑöÞÎȹ¸ÝY>ðäéM›¥dÕYo¹Õx —hïwGd9¨Áí¤"¦Í5qÿ–\zú’…>"ðk€…i—8i¶½ÄG8‡!KÛõš³CÉ$â)”™ ªC.K¸ÓR´W™8ê·8~qÚ¹I<8û`Äm±­ ÿü]—4Þù°€[º¥?ëÓßnìuûí–{Ê;=ð ¸ã'_ókgßPÜ7ã'j‚5Î6©x›<^<èyXM>Y½uкýmßOJì ÜFÙFì0$ÁûüÁ&MôšC$¿É%Ñä¡òÜm'ðgŽòÚœ¿¶ õ0Êg>ÆX†ÀÅçJW„‡~ÐWšf6…)Ûæþ©¯>`‘AíóA£HG"$ª©-C1cm¿˜ëq}$d“ßÊg‰œkA9ú2ÍØS[=`LñgN}Ñɾ„¿‰÷’sÞ G¢nydL÷ø=ñ$´yØÏ(¬hCìˆ oÛ× mp]˜×íC‚Šï=Ù»ÍØÔÊ5ˆÇtñµjäWš´BÔÕa¬I¿¸Ì –Wî > Ä Om»Íc@ö¶õ¤ZS¶>pž?–"£Fî2,*8ú’rQ Û›|Žùô,GRÿ­ùÖÊÙ²AÉZ¸xun_Fõâïùuø‚›A*ÃÏ*JŸƒwXtpŸœ[ÚÎs”PÙ“V[²Ú§³É~¹rõMÇg¤_®@ª¼"äwž¿üy8=ðÀØ¿µVsŠ›=p—ï°0ßeuÃCNÏøæÒ3"š ÔGtœ­~ÃìÛK•P*­!5‰Óíl—Ä®lÅ §Ëg*D>˜44I YŽŠXªÊh78#+Åú’RƒeTfÀöú‰}´³²Q §‰íµÎ»°•Šö³—oPG½… ng‰iZ²ÛRØ&òìAçi¹’„ç–ò$ÊE#¨:ÏLLÀæÔݵ±¼~)µL7)ÓZz?{k!ý±Ç¡Ù—G×,­ØD}œ3hŽ"%.ÿxƺҷDî2Ó–ÀÅë»”H-ýnÿÛá €×”Ÿþ“ly½dž~ðþå>–ý›Iç<œx lT} ñ§ØÓWäGN>ÿrc"ô"¼&Ø69'‰8ƒçDea‰ÚŽéggš$] æ’$Ú­|C3®!\ô«†Rob÷¡ÀW¯œL¬,mò¿·TKЕœ¢O¾š´ ók6„å ›ä×2Ï(+c[¦Ò!·mÙþÖ…þ#ŽEzñ7;)×}Œ«?V¸\™,ëº5:¯‰þ0úøÒºšrŒßùŒ¯¨Þޤ4çñôÀCyà¼Úʳ§Üoî/}Ævísr:A’è× H˜L&!lú ZVí²óô•I’p›dÒ]iš*f×àž6'Ê’Æ€Õ³Á[¸*7„÷ÏàåîÈ`Ñ>ä4ˆ{l+(p•QÙ%gbƒÌþPåï0xìäÀZf3“ôY•_eK[Uàùß.ýk8”³ehËCçÞR"õD/홈È"Y¾èûÂÓ„K£ÃDµ6ÙPŒvDõ¶­ýXâ“6Vé-ÖÝ7é«\š[µåY )M¸ÕUG˜Öô¸ÐQQw(Dø¹Õ/†íDaÈ©JÓ#g¾[K"FçØ««ü½ *£m¯ªµÍËúõ‹×—÷ø±¬'çàêê³õà8 àÁ]|*¸çO?ÍjÇÕ¥ÅʇíÚ`04pζhÂ+‘8_´Êìä%Þè©pÊ>høºí¿ä¦uÍ3&9!×—½RþýÐ3!q‘]åš°×võ»Í³N1|ñQÒ2„Ty,ÀI€ Äí ‡ö`¦•ÈøÑô ŠÚNY¯ðH \¢ÐYC q÷fVë­Ž¼ñ0³0üÀo48¿ˆÇâDXa7‰Yh2öÔ¼ÉQ‘+n?4'½>­œNðò¿’ü[2Ïæ8 –öZV§¶¨uÏC̽AÍ!xáôÓÖ7†Éw(’†Ï=˜vcœ×gžÐPˆB3õ!B¹¢åIëZ+÷zÍ3•Eè;w/.ï~ü1²–z˜ÎêôÀzàœ< sOÑ7H4gCý õί:]]ר ·Àû(•?”#ÄÛ1ZK³`¯2ä3z—Ç$嵐=+WÙN"A¶ Û½À#„tº¡+T¹ê“;Ôëä@èimÙ¤Ú®íFM“%²ù¯õÉ;¢(±-þ!1«Þ"‘¡IQ €$Ía°Úþ­‚À8¬Üd0':¾’ùúÌCv%0*Vb‹I.¬µ"®íª*ǾbX°ƒwLʹ¡SfÀbèÜNÄYÔŽS*; =»JËŠý°¬z2Üàäí‡*EY¾9þV¬”èâp<ôg{p ‰ÍösŠ ¼Às'\XBÓÉdš —v& * -°Ö×£z½?8߈wÎò˜ðò<Ëé÷À®š/¬rújà ‡“Ì»òÖôé±³ZOH€^¶ ¿šÞ]‚½¤¯+}ƒ¹)$ÉÚˆî Ø[ šôm¤—t#½mŸP'<¦¤,¦ËëÜ’8ñ”똤`<ÐÇü!<ø2yÁ¦ ÃÚŒgÓ,/<Ùv9èoÓŒ#~û4#Î:°ºøtõ‘¶›©Pg^Lt—ä©äüí‘¥9ŠTÒhJâÛÒ¿-ÖÛÐȼÂWŽ\Êß3)ýâl/w®\Ý`©§/[ºÂl§›ŒØÀõCèoù‘fJ›6ƒª‹nõ«çj§º×éSO.ïòž ËÚ•Îy8=ð€Ø¿¥TqŠ>=€&ØÞ}Ä»Îù! “ŽÁÏDÿÊÕøàMи¡g°Ìg£'ý¦‚ë%,>üeÛ€­ûÒ«yuni4ÅÜ+Dú딤‚£¡}H]£¬ŒîÚ?1쎤SœGÅ6£,û²hžm3‹—²ê榄eûí'Þ’šÃöáLº2Öd»EÏ@䋚 öØÉÌÚ]yŠT†ø>Ö`¸} Qž[6AŸ&­¡f9dÎ9/Tx¯ÚÑ3]è›VF÷à["wNްôuƒ;š ,ptO_a⬠j=0iP}á+\·zïC ÊBOÝ­ná˺} ðñ· ïYN< ü»9Ëé÷À^hO>ùäò’÷øF;ƒ-ß ¸‰„F\)›Ùí»&œIAÃîMÐÖô•n›2{H ‹\q†Þ¡ÏÄ£º’ücwüó0\ÃsžzO–gn!ÐJ>1øù†Â^„ŸZ^¢1J¸ jÅ&¯Ç7cXD@ª@~>øíxNL—,¨m†>ÛòY@òÿÈZod/_V“y4S´+*©Å&¯˜–CEúÂ$I-&ùÕñ‘§ &ÚˆØa+ —U~qõÛa¿4޳8ŒöÓ·²´aKÎ/ˆ˜Vd‡&W02ƒ–1ÙTù¥92—³ j½pgv MÁ9:Ší°A9pšN¢K0–òc@‡.ൎ²¤«Ô¶*vUÙ¿- p·ëÅ÷ýØ<ç`ÏeT‚ÇýØX«…m[vÏ””ÂÊzûžÏ!8Ü4íR÷(¿×fôŠW¨ˆo 2Í•¿xµ´v½É;óʑ݌ÿ!ÊÔ÷îý! ƒølœx`ÌåøÀZNñ§ÆO>ùèò‚€×ó«€®ìÍ0ýf>Áp"îË$æFƒ}²ṫ5Ó‡†\“ÿpo÷`Áe©|³D^vl{õ“Ä»Îퟂ«;ƒqß ž"©/쉭щþÈZ¤T÷Ë5ÀChV°„‡„AÝ• ðd‘Ú5e³‰ô²Ê`{©Rl\–È~”@ …ù$¼WPÇîm–À°)·_è¨Vàž—'œ+iB'Ž’¶4í Úýø¬ÄâbtúÇsYÍå]™Õ¹½ÚÚ¤»<ëŽ[kt‰œ~”Óë¥çTW煮Û!Úº<Ú¹×\Tí`·‚#[ùúªúlˆÞZ¸G«ÓkËþN†ö”»ñâDáÝ>”ûÊÐÞy<=ð`Ø¿¥Sp >= ²B§öoåOL‚ÎËw¸ Y*R¹Ñdâ$Y/‘Ô$å¿&î7‰'˲يæ}m':«ëºrï$B&“º“ÛÚâ´€‡è°¢QòÅõ¤‚Ð’$g îrܳ1\Ueø—™ï®2¡f7ø³Š–|uo-MÊòPw__¾-]ÙÄ•ëò6°3+uý>4G3P>k}ȆVó-óô#LùÕºÿÚÎyƒ_¹~¤Õ$'Âw²E³ýÁ9IZ [¹>„©pŠ°È¢ßIIÊMQ4êŠ8€•[xx‘gmÉ­.¤ÜòFçžg3VŸr½¶x'Vþ&Þç2g9=ð˜¸ùSxLµ§®·ÕÙFÏÖ9IØ0é}üIlØÝ6ö{éûÐÕ&㉼L m˜L µ³ 8…‘à“€÷V@wùe‘Å"©Ù€Hl¹™<<Ͷÿê )À`­É0÷5¾<µ`p>E»¶;ÊUæH)Ô‘!pˆìb&ÉxºH`ßtB2C«X‰ù8–ð!Ë 6e§TAÉÀvÄags°j#AUEŒ^‰¨ñÒÔ¾J\®NJëW='ϤÌÌìXÄ‘¯7X…VŸÛa¯Æð-b$ÞV¹ à=l¶ AYj‰íQÑšNæc#HÜQV•­éž:kËÞe²ÿ„óøÌgµ9^ üùàþ ”û<žx8ìßÔÃi8%ŸÀ /O>xïòšO¢¢QWÄFM:vC; Å(m@4HZ'0A³m*%í#™ºµ~' 鑵7^“J6ZCx["ÊCòÞ’V¢µÁ?’ŽäéYöé±JvÁRjdÄŽk½yØ´¾þØeéÒ:æCBÚ¢¡–LÔÖ4STüÍþ’£뱿æ(«–ÆŠù€·%êÍú9‰(2:¶µ* ƒšÞOzªë"õiOí=wy—?®|?Ö;ñÐ.‡ž!´mse-O&dʈ(ëÆ[sj#ä€C«éÅ/Mú¿Åídlévr³ú`9ŠóQõ(_ÃsMg—˳wÞ½¼ûÌdåôÀãyà›…ÇÓ~jzk<°‰€=¿¼þäSî6ÝŠ§¶d¿xÚ…ä(¤«ä+Î[OÃ'Ì„k‚²½‰ «úèÚ"ì6ا£˜|Ø9˜HnN4«Öî{ÄQÚ,Ò…@–I¢½}!¸¼­iÃãWçŽùüFíÑÎñ—YžÐ wÜÉPÕ©êЂº–d-bø¬m:Ød¡®ìC‚¾¼ù; ˆ­ÅMj%í<⪫ð ÅCwûY:ÅÈ¿^j)8@IDATžKÆ^ÓÐJŽð„°g5r¤å£‹b+ÀÀ—í¦ÿôcWxä£Àt‹´ýØ$€"ŸEXw¦Ú¿ÂËUž{m2Ië«eèÑæ”Õ+òÙûÏ+K~Ö§ÈG˜y ù§ØÓ÷<ð„ À;_ýJ¢iІÜËÅ+q£f2ÑSlƒêÒ”¨Ú˜ M鲡˜«Üî DG„Ïî€û²î<t#„II%;‡g$úN4Áž,ß Ô~C@N'¯ØÞÅ4®X˜Æbçª H[äèª< e\†þ˜qˆ_˜l5:¬é„ÏDÒ¥oÃtÿáMmfâ^칈ëúSf}1Ò"Lö?EÞp¶*|~"³‡m[_åØ[Ý«+Bó¾‚"È󬄕ŸÉVTì’‚þâT¼$K0/ýÐÖ¯9}0¼ƒ ¯£÷¾zþ°¾>Ëãzàœ<®¿ßzmùµ3Þyî6°yË@hPíúÎ`zSŒ´àR¦m°4À&°Â•œTòû.+ÿì©¥PÃòðψ_9¥õ˜"8œrÇÒêžä;òMƒP“H`Uçµ–ó&µ‡8‡Ðç"b×q«DZSKçG&ÿb·¦ya~jfÛAÂØ™ÖÖ>Íïd"zå£d Í9ïÍ ÉU‡ÜìÓö£ÎlÞØ`:Ç©kzp¾€giT»r´ãÍ•ïN¤ÛO•®D¡”èÄÖíÒˆc`tÖ•"v×F}ÂK[Q·ÇànÚÝ1 ?{ jÙÊλ+§‡³cÂ/­¤ÆqO‹ó ,;ÑìyAÖ³gçO³Üúÿl?¼Î ÀÃûøÔð¦¾üe¢$+q^ l 56ú%;ƒ©ÇÄÕÍ[Á¬7Q·ÁÖ€[&‰ü˜:š>ŽãQ7DìúüÞª[â¦9‰S^»# =K{?›4F!42u‚aòï­ƒb#ìæl“ÜÕ¾iÁó_hG_6¤b–ŠQOзL[¸bµuhnàÛO-Ï®?Ì-®a ÛÛÐ'áW³ÐÀç?)•´¶-;Þ˜'üV—xlÐ;a(ßrC?>0Ùž¸Ê÷ë„›¼¹Fû41q£bß䳿´Ú»ø´a0Áæå¨+p -ö©ö×-#—<þ2‚¬Áâ´ôuQö_?ë$˜îå]n‹Ý]·åôÀƒ{àœr~‹.~s•ò-²¿ÝäFNÀ—¾D>êÖü®:}:Ú‰À½;ôG´a”5rìÍó`p¯ICúÏ´ÛÔû*LòAiIíÊ»ÝÀÒ7X«ÓràHôŽŸÎ½¼âËŒÑ# û5eÉ¡]~,½ßK#cñ&E9›o48ÉH†Y:õÑ^[B+Žeëö®}éÇ‹JmöAÕ™lŒãŸð]4s•S°¬ö9è?‹ãÔ¤ø“º \ÜUù­Éa kñŽÏ®¿ÊwàhÚ˘AÞÄkÃD¬¾Ú‚¤1ÕÈ-ì’aks\m?úÇb:ëÒC/ŽQÞ¶µ5myºêo»~À ¦lâÌlâ5y¾tìŸ[DtwÎÅø‘ʵôþ§çOë—³<®Î ÀãúûÔ†^s ÀT™˜¹Ù1¡œX8ÔàjÐ>ʉ²P“ì¡KžÕa‚»Ñ\"½ò¾ í›îÎfáG1JS„]³ LQ®ò ÖüÏäÅÝ w1ÂdMcÇÒ·;"˜oð»Z@ËþðçõÆ ¼Š« ÒFž4*Qe‡cÿ€/pñô»‡ÍeÉŠï¨ó`%räÜp¦¯Š&rpñí*VÔRvte¢D(áΆºpÒ&Ré*Ë ƒv„¤|ô¥«eâ[–F€CÑ-q´Z«®Ô%*ð°ç†æj@"O^>ûFËì&)=£ª× ½†¹ò ×Õ£BaÒfÌÔ¹>rŠŸ0øÕ͵Þy8=ð°ðš<ËéGñÀ& ·:Ÿ¼Ço$©NP ÈFw²1NMÐÑ%êP^ƒxƒl“‚:\¥uá*ôµo[á¢pÀv¶˜nÔ3™[]†êi#Í•Ú-Ëqï¿D;¶½/Ô?®Û±Þ~‹¤Ô¨Û³êë£8º2ö O²ä¶kR{ Û9°¸PŽaü¨“‡ô¡à€Ù˜Î8)·ÈJ&üÛU1„Õ‰gÓf,y^À•u˜@ŸÛ_˜µeÇöCU1{ Tæ¬oá…>,Ó&…ŸÛ²~“^Ü!“vh—ÂàJ{ÁÕÒ)—wJR¨3‡ƒ(°U"kG™Ö²1™òü¿Y–=‹Ñ­œO>û¬¤Kð&ãÙ?=ðø&áé´œ"OÜz€¯<½pÍò¸AÒG¤5èNôΪ @³Á—Àè§?lÜnØnÒ²æj¡5b›+]¯k3ï2.ÚàØÄOvf@‹òn€ØâžVI ›$6!ŒQ±É¼c­løÓÁ‡Ÿ´»óµ>bëÈWAܤ![Ö' opW¢Ì‰á0÷A<³ IÜ£B•¿© ÛÝA~RFlú².xàvc£ˆOãMüàB;2–WÒ•kíÞ^Éy9êôóŠkÅ+ëƒ/Í jÎãéGñÀ9x7ŸJôÀÚ§üêÙs¡Ñ`üÂiÙÆ{ð…p¹4“ͨø·1:79•y{ „„ùoÚ"@£Ký®Îó,‰ŒÔd?êHÃÚ®roåù@@¾?À¨¾jC¢TÀØâçIÞ1°ÜZïtâZæ&AŠtäcj¡&íxS;QQ dIþض¾‹Í óCJ™1I«ØpŽrA\å%QˆÝtâri½0Üî ¤½Ù5ôW»4X²õEiÇãÄ"s.êЊ/Á’ãAðsPö4Wþ¢U±8aö3~;  0Ú+Ãk"¾ ²RÄ¥ÐHsûiï¹ìi9×ÌЋïY×èQ®ù)÷jôzƒç½ù€«BzN<¨6Œ=¨’Søé=°ï ÷;_šŠ‰ÆGìòA4~V'«·jÃè†Ú&·`Ű]Ñw5f¨½-öú mzW yÂh¥gG!Ë·Þ«5ñeµÆÝr¹¾3xËiªæ“I@º,µäj/’KLa0ÏÌžreaƒy¾ý±q+ǺIׯ >,îÐ@¯£Ï†ÀŒá)ŽŽ•'Ÿ,Èõk†ñ;ÝN>D¨kjð›ø¯i)œ d’0ß…“ÆñhËë…QÃ=£N4ciá;äú 8D¶r’É•M?¼òÓŠ|)Äå_iV_$Š‹È2ÎNš®’"NÉòôì“|RÅ»àÒæp—Ë£‰Û‰WèÇÙ¶£ÈŠü-^ÇÒsn…óqLÝïžÏ¬“Îú=p~ ð[tö®b¿E¶“ÄwÔ§xyå;t·¬Í’Þl&›™”ŸP7’)ö–©&Þ^^ÐwKÿ9,™Ý7‹7 KªLÞÊ6k¢•Ó‡á U˜ºƒ1”ß2ªy®ü͚ݨXÜØlÊd!¶’(œ&(%zÉ‘£;h’(Ú&ì®V•òËŠJUGÆœvZBæá¶0¦$¡ÀœÜÜ ] )ÉÚW$tÛõ· FÉ$Àwì.…ÀuhHÐ@?߉§édÏ H½ qíDxÚ²Ôÿ1E†ô?èñ{v‡GR¸!¬mÔ£å56cЉp ¿b šç02!ž!8^hý¯¾<‹Bˉ‚ý¸Ë†Š<±³,…m+mômw°œ|ðÑG´±s>¡=§Øó§ýÀZNñ§ð€ÛâW_úÚSrW¢®D'É›$‰<÷Ü yìÓ´o¼]*7+8ᴯŞŸ‰ÐÔYÁ‡ AÜ m0–"¼(H"±\“@ñò»Í¯DìÏãß¾‹Ü=Àœ Á }_€e.-èü4¬ä©§¶jÁ–$'‰²Ú™$â”B%N¨LK¨í|<e;Ý6„mTxwůÀMþkó›É_ÕI¬úÌ$¿cC°ó¹&âÑ¢£·Äöí8æµÕ†¼È¢Ù!q´À]G³¶g|ŠAWÄÇP÷ ”;÷œJ®Ÿ„»i±&+ËäŸëh•Cº:<ç± À4{jW>ÀAm3ƒ°¦£È|l¯P´ {Â7bÞûè)ÏrzàQ=`ô8ËéGñÀ¾êÔUÏϘ@sÿYíûÒBbÿ%­5@%o‹ýYq ž¸Š´Óꡬ ³¶6‘[ ÓMš}qaûÀ`úPjSþXö&{Öó³òW̾ ™MY•ÃÁÃŽ}&ÚÉ6›(“ÜÉâv³òMéo–XhÒPO²M«¨Ý$Vt˜ø7‰ ,š{nr¡ï9W°W¾ÙÕ½ç‹âXB§|;SføéÝÊ;l“ùŠrà3§úB¢øÍs ;üï¹±)ä3ι#P¿(Omc†y…¡´ÝÔ%né‚U§t‚ cx¡Š^|X›äëõëYÜ"òäñwîæ‡¤Ö§ÃßäÏü1Ôž:ÞF$`ÎÀŸ~øÑ-_b¢AþÜ€èçe¾ƒÏ¥é.@>‰¿á|N0íN@Ã툻(3q›„Ò`í\Âûú ÔaP‹EÈBÛN‚\”5ü†ø&e#ö®*ÁÀf²õ©üÒ: £D4æOlÕì³ ýÒÝŒƒ¦¼B2FÑS”¢Xë¦ýPýT)I€áÖ¿V B™T}Ý0d&xa>Àèr—¶‰1iл”ׯÐ2cÐK“;cç9+VßÝå}^t}>FÃÏrzàq<0‚£ìÔrzàÕfˆ/–çkpM´Nü6‚ ó[î¤ÓhÞö$rãë&Él{%¯3ÜÄQeùrKÁ»ÏãÄ¡¸öÒ7]Ãü½¢L>ùm÷D¦À¥ŽZÓétE„Ú)ÞÞ°ìr´½¹a 9®‘ŽÕ!*¥Ÿ¾ÔÈÕm8¢¯¼¡DŸ½ª¡S§2åüÐNá(1QÛÞ(eåÖ; Р¥³öt9_+?zȪ‡OÒ¢Íúx¥*ßœŸAèé»wêµàJÜvh_¬ >­Ø«¼èñzçdɧü«}ÀòN6hRÀGpj›+Ñ:Ÿñkó-j}ë/MR¬ýÙiÏwö^¼-d{ Õ.}°>EÉ÷w:‹˜ópzàQ<àßÀYN<º|á–7vÕ×­#ÑÑÕ©aÔò‚çò ÙmR¨,ö“õT¢}:ÅCº+ÏÒ’$–ä6“b˜·TZÛöìË7ŒV|6ç^±ÙBØ!Óu´¡ÝŒ`ÐoRH] #?“À•cÕLRÖo8Œ UY]R;©XsèÇk`‘u¿ö 'ôeJâ±Lª–?³-­ÃpWGŽ•{ÔñpϪÅA¹óŒÀû´7h^?óšÕjäÖ÷ÐÂÜ+£“[ådbÈLI¹ðãX–ãZKï<œxxäOöáÕœNÔ{Á=õç€ß} Á3A¸ÉÝP™¨(¡‰"¯Æ%dZ¿0‹0p6$ûbo$9tmÙm³˜X »MCW”X>.qe/|o j²0ŵ6ÐG¦ƒXþH\B;j ‹LIùÚcwfG@ !/ÊCâ+c%uP¶˜~Ä]¿¶ÿ“k‡·”ËI ÃöŠƒž„uç}ÿØ·Pº ìnw,0}“~kUQàzc§+™@Ÿd˜‰BG'ü¡oÉ÷ú1FyIâkÛèDH¸eébw.ÊM=œrdzîõ°â‹Ò¢ ‹Œšü36j'rR‹·ÙO¹"WôMqrÚDŒ¬îåè9 bྷ´¶ñyŤï˜Ä‹Ÿ\>ä·1Îrzà‹ð€/g9=ðh8¶\?öÙB}ÁSëß—û|°l0¦NP%ÑgÅdÖ1øö»Òð“ˆÅÉI€Qÿù=Ö]az έü&Qx€ù‰lynJþJ)2OQ¿Üx×B© ²?6S 7ñ»Jt?«Ëˆ”œûç[°Â¢€ŽãìçYt9©¡çX)‘B·‰múãÌR“;N ωÌ $[ÕïÒRì·•dÖÑÝÀÀéÿEO Í“#ñ-ý‚$Fí—Š‰@tÓí$£6Ý ¯»Ž¢5ª>ñtô|ö,¸.÷áá3°¦¹:§)_ïsbËEƒ‚· z­_”US©IZñã3ä$Ás(YûR¹Õà˜„{*ó<ÝþÁç|%–rÿ: è<œxPô/ìAUœÂO|£ž~öÉ幫ˬœ‰„$0“·Éìx#[¢3A“¨iHuÅdI7ÒŠOéZJº^“$è´©]I›+.ÿ€‡@Ù-çq?ƒHˆd§Ð‹Z´FØáåš^61f¼c…$¦ìöO±–L¢Pýköúì¤Ø4µª¥×YJÊtÄýÌHRµâJô§?–´Èx´#s–>ç$!ãÇŸì*^Û™\I+¿–u{!â@>ñÜ£ íœX#.ðiSÇÚ2ç±=«H?¨::£ª[ëê×›Žm½rµžä-Íz°”>Ô§¾è¤ÖòÌÎ'¾´*dP{Nô‹ õ\ú¡Òz=z†zy£gëã/}IÂÑ•æy8=ð(˜§XEשäô@^Æ¢žòÕ§çd“½=ÛØ" ¨=$9¼û ŸiT<µ<Ô„á)‰ÆÅyA`5öfWº$§_è’ÐîÓ+$I’Z™opÖœh¥e¹moÿjϦןr÷gGBvn?$sôÖB(­aZíôÆ·*ß‚NÕF5@÷ÀédÞ˜4@L(Ö|´Ã1g¢D_Q6[ý³ÒO2r Ê ­$$!Œ É‹CjÏB½-N®ŽPÉÔD ´®à}žãµ ~†Ô¡­Eà••É Ôg!2Xäd’"ž‚蘇ü( N ׎Un`Í‚SÇh(°!jÎnFb` ¸ûâý¯T65:¿=QO¦›±çùu;Cz‘Aû²TuNgt#ð8W(îµQ_Êò‡½÷A_Ïrzà‘<0—ë#i;Õ¼õ0'Xžñâ“ç$œlUgkÔbi0µ$ErØ÷„åcPåŸ±× ›¸.k @xÜbõ‡‚L/ñËl„·på+#Á9me•ÞÆÊ´æ>²-Üv‹ú¶ÝF“Žùà†ÓfŠ4~nS©Vú§H2Ê=w9õÔ!˜¶!Êŧ[Ö´!«DÚí¦–Ô”æDHénõ„&¯8Éзšrßo @s;ÕrÏÚ¸vîJ\=&ù$ÿÈlò[õ/ŽóAÃWØÐÝ'9ÂgLòMB-U§0ûö„!SZõVv,œDð" ''>y/©ž3ñ;:?^Âr¿ž¾²v¬¾ )·a䘛Ét Ÿ]í+ÛO&ÊCu^GŒ|9þ˜:m{™ày-–QHd*×·^1 þ`žþ,§Óýk{L§®·ÚÇÇŸ¼â©~Béå%³€ñü}(+7ÇLW¨ÆH›²¼—ßß­¹3™€Ç—ød²€,ƒûÌ.ÂdðV¦¶¬•íä# @Â2uèÒ ù"¢’OöÖÎ*5TG^ÌcB»iEJúØ’Ä BZKir„gL@nëX”î¿—d&Ok< MS,]S­¾Oʚɚ%¾pf¾€æà$Æ&㑚ú·ðLZ€¿"ƒF’´;5¦8Ò'µñ<º~ŽéÖlÛgâ„<­©_cºòëC„cDÞúÇ·JLÜ~J4ãE®2£AÅÛ¯,ý ;¦^¹¡—oy·ïË/®Ÿ|=pŸ]Q~rªòÞ¼Ö³œxTñøQµžÊÞZöRž}ðÑåÕ;ï6ÀòÓÀ&(a?+{CªYŒop}aЖsLS\VûP%g† aSš-‹‰$“…ä¹(´#ü •ª…‡‰ 6øÆâ¼µ\)hKËA¦‘9²I[c{iìü­ZÚØ¡)ª«kIÜ¢^ŒÔÓðNâ²7J¥XýN*2ñ Ô] #Sÿ’ôC‡Mw³*–üÉ]ï&õŠ¡@gBà½ý&uˆv‡ ”"҇Õö«W$íL@œ„U)zȉÌx*0Òt5ïL”Zé9GÙQšÂ%jRF]†Qý°‹µ¤Ö7´€×EƼxåÄ^bü¤x]æÚ,\O.þZ;'Vî8 kXó-ü½ï’xÅk±ßã§€Ïrzà‹ðÀñgûE(?u¾}Ø7žÝ½Ë»Ïç'P@ùNõk²H/ÑÒI€[øGØ¥-ÎÇ´š2D€¡óa*·©R\_Ù+pQÀ+˜&Êrk KKQ! ÑZ›"iÊVW®>¯ÐÉ@ÓTìƒvH)ñTÖ|Fjdæ!G$VV“qà]s2º¬ÂMwh8VŒŒldWÃGÉàœ ÅhÕÓt,±lÌSk›þéËÞ j)NÖÃ#4«øiËcr„6;$pÜÙ—•âdÂÒs’VèãøIöÇV÷ÐJu<à9£(%Éž~Oãj01÷ 5áÛïÉT+_>LÃa¢WVŽÔ9¹Ë]ÐÕ¥ ~ª¯ÒÒ&ÙË­rª:äÄßâ(é['ñ»»UútùuËÚá-‹ËÅ·ZúwðÁçO㎳|8'_€Óßj•àïÞáKl_þÊÉ ÜDàl¹²‡œ J`wƒ÷¸Môl2x’çLp ±G`žàM`î.BpUšúòÀh ~ÑK–b•9²¡C;ÐæUºüµ¤V_t7$A3ªK­ ñ~F-šv?~8ä Ÿ¶ÑP^rÒ6ÙX“:2ý ß²5½È¨|iÃ>%ñ½ç nØâÚ]}—¥É˜ÝÐ#†”I€¿°IÒU²>H_UK+Œ¾ïÈo ØaÅ®éB2ܹ—uVÜ’úQ†0l7©;ñnýŒ‚Vmš)Ø–¸Ÿf΃÷ nЉ?ç¹®êµA3')¥>¿€ïqÚÔ·»Ö݃ϳ Iü†Ôë¹ÚÓzà!‡eÎ åÇŸ}éòþG}Ð11~–Óá¯Ö³œx44¤ÐyÀ³Ï>3ª&àû⻬®ÙØ•R“ÝÝå9«¹®I'@';°’'ºz+·e‚µÁÝÛáqÕÈ»´uÛ&1*ß—F€TT“ƒ!I:É0ÐÍ»ú´‰mÀÐAi“æM¡aYù׿¨ÈØ•¡è|<`O’|9ì›”ãlH7ƒ¬±òYVp{ôpTxRy»|·`:AHò„Ö„œmr¾ÏßjÇ*‡D÷Õï!Š ªyòœ(œDø÷7U|Ój_˜CŸ„åÛü|ËäðÄ,@ß l’7«ÐuÁš¢'Þ›6}|M=⥛2iÓ7qÛK£à'qPE 0ê$4PɡЙ`ÜÍ6ID¯¬ÓŽÊ²Hk;§ëLôZ"§_}”vxH*IB* -IÅï£'Ù°>ÎÀGÑêƒ÷(¶¬8œüzŸB·hSÎKpe6QfU“Yý[¯Øð9aÛ¯ò™#2'.²®l¥†F5Ýc¦6ÀØ©éWוI|†öF„úÐûû}2¼¶äÉHŠ´ã/Ƹ;+²æ¼BjQòJoM Ï8ì­UÛ޾ɩy ÒUõúób(ˆ¼O¸–Þç{[ ²³œxTœ€Gu÷©Ld+šàøìý.¯Ÿ=%§š$6à.‰þ¶Jb¶Ñ›(þ$·äžon“D³- ¯yms*©'²|ެÊ0 +ßbÏî0u`êw5r6ÊÍÀÊNNFóM´ ^üØšDͲ\‰zo<ÑžJ1-ÊžphcY¿ìÊwq¹›cKèDÁV¥d4ôQÇae_õƒ2!ŽŒQ]y% tïpŸäa½ v&ĪPfAùꢴ(Ã:ÆmSÙ·¶jãö•¢ToöH¥I]ÕC\ϧÔ-Ý!qä:DBx¼r7/2’>„gb‰t¡Í6‚­µ¯ò³k°:s>B]yW)m»bmWžcQ‹çìá3´¿òP·ŒÎƒ_+x †€È{–Óésð-zûü#ýöMÈ7Ñ=ùÄ{Ÿ†u¶ê¹OÜ$˜žˆmþô‹îø=vSEÞ—œÜàÙ÷U­>7`ñ˜ ùŒÏ¬LZ&6'µpØi`&R'EÁ÷T$óMZÔâ2I`¢±LÆ´i']3(å)ñ«ŽÖ0fRX¶ EP|c3}–®$miÏj‘?ÛÍëo%ÌôFÒŽ+­êwÚcs-)Î&÷Úåî†xWü;™Yÿebõñà£É_1øP.¯÷P:¡«?M˜•ëDMâ½ýP[zÔË®¦mçœVKv/ôµ~wÈY͇ ˜Q®“ðé:^uD|mPTÔÈï¹YkMä:ø”á9 \òú¯Åó,Ê'KhéÛ‰iã åk°~ôidú£K;ãy8=ð8'àäSÅH$d•ôùgÄqRAÑ@¾‰ÀDÙàß$ܤh Í7©È]™:)â8/¹QI4ÿºk ( C;hŒN7Gà]eïä.á܈M° te˜\¤Ç~aÉJf&i­” bò~ÀÒíWƒ×鬑92§QA›hÒ2¯¡‚Fg×ÅN‰\GûtÿàW¨uE*!¶ErrkäMÜŽoi©Mþ±epG?ÚÀ€s/]E¦¿ n»#£×4É•¾»7ÝRwh5¸g®FgÌЊµx=DGü‡$²Å¯NJñ>u…ÙÈë™8¯¯Š»É™ó ¢RÊ-Lw;c„ 2€Šr¢ã¹0ç÷œv Š,‰øìXzú†ã,}ðÙ§ÉŽ´ÏÃéÇòÀ9x,OŸz¾Áï|ö9ïà…@DR÷‚¢?ƒk ïj˜ÞÈÉÿM†×;:YýwÑU)Óͬp2‚É%¯¦&ä^mP1× ž0†æ¾¾—Î& 34ä52+\xcƒ¶Ù¼)·qÜ1Y6iÈã-û VBþ»rŸÿ¡2ª[€íŠb,`òBøwb“—÷@ôd”»ºô>¸_!Ô†¨Ê1ÙtÛ»cSOX«¤ºzc3Ý}ü6:òОçb|š–ñËy‡! Ô:ÿªÝ€ê™©‡à”Z&´VN êò]©£àšëö¾4úƆ¬ãø-™d“,ˆþ¶Ô‹ÛdWK€%i(·ø…;È»2òƒH’L²‹In’[Vº’Ë pBn裡˗ç&ae %šÅK#>Y¿Ö¹ò>ô—4¶u´XŽÈ-8}Ѳ£µË£:eíÖ2¦,ÚD%Þ²+þt[n9Œñ ݤôË«»rŠj;ŽT:F9>KŽ1ri¦Æ/£L(¼œ¤Í¬¡ø\ËO[¦¯=+×zÇ"™Å9J` u¿ô/ùš‹×àGóK€!<§Ùçà‘~ªÃ“„ÞÿÊW./üñ·ýy-°YÏØüó„ÓgIüŸ¬6>û ”q9"Œ¶|x“p‚©x©ÜI0 Êÿ‰OXâ{k âœbÀdG~Ò¹}žÄ’u»¼4l÷þ:ZʲÑÝìßΔa’x:ËÁبüµæ¿ú´<}°ûüÅåïÂøÞ¯}MQ¸‚³œxd4Þ<²ÒSÝÛí}Úù“_ô_~é¿÷/OÞå­€$Þwïð†?¶F œ®ú¿NûQ9)›Àkœ6Iú`ž¿ëþr^Šã;äIÀ5ð&lûrS8‰‘«\îù&ý8¿É ’¬¤ME“€ÐF¯¸>ŸØ\©Â‚ ‘Ä!€ºL4þðNžIìo88ÊÐJ¯>ÓK@&î ø¼‚_CÌXEÞã#Ì‘`Õf¦'½•Љ€ö¸Â|iÆ‘Z¹mÄ>:.}öÿ9Úq±lû[‡]Yùx´=õ$°z­4·;!†V2ŸÌ/zu°¨Mþ´Ói­»Õ=zágñãµÏAxÚÂPw´CSÏû›iq},~ý-ÿ ¯x=SŽ«ÿ ™^I#Âüßü÷ú}Ï_0©ÍñÂßW¶ù¼|áËÑõâ»__½ü¡¿ø—/¿è{¿7çfÿ&@ŸåôÀ£yàœ<š«OE·Ø­ìßð~ÿåŸþ éòÿâ_vyöêëIš>`õõ$_Ì›ÉàÞ/}é}íÜÛ6¸”YYù  Þnß›Ì:0áš‘ÓËÈ믚d¯–„7IÉcB2ÜSÌQ4LBÂ_°#PýÅí–°¤KFyø˜@`Ò*=…n‘ˆöA»Tòdnƒ Íñµ»ˆhòËøè;Ö¦úêP‚ÙV?;Ø!hB–Àµ®õø!r†\‘öa.½¾Î[ïóS#È}z¢¥ êWþÐ]~Ñßü—ðSõòsö¿¼|ÎÓëÿ/‰ÞÕ;S·×Mt> H*Ë}ý×dÆ'l`ÝÂW¦Á™Kæ0Ý‘ LÔw`ürÆûö†þ¦û¡¶½ŸoÛ¡®É¥È÷Êf†Ê» \e{Ë@¸Ykx ð#¬²ÀI¡¬RÚh¢¦u“ŽxÇè„%÷ÎÇ.1£%¼C}•ÛI >ÀƘâ´ìdXSôå!5-ýàÈ5¶­&`µ×›|}aÛCk¦Ä*šûM Ïã“yXBœ¥0jõd,‡®< ¸ñ£&G®ô¶Óéy“Æn´ Xî¯0AtVâØ½5Â}¥¿æšÊý$F×ÓÉõÿ󘉙ݑÃîãªîÄtK^a­´6yÕæZbà{¾ïW_þÀOþÇ—ö7ý¦°¼ö”wœåôÀåëÕûEYpê}k=à$À­Oá§|ù¡ÿ^~è§ÿÖåùoþ͆ÍË3f/YÕ¿ ~β«+YWøÀ´/gUž­n§D]CtVÍ4²o°FmSCW×ÀÈî˜,Ì Øs& #yìõ$—¡K‚1 ªIÇK’I䇑ý‹.Ã/heg÷!vC"|ôÝ«ü‹Ä^È‚(Ú‡ÝÁHÃgKÚ ˆÆÁ,Œ.2ûCKE9òPBR;šÄm˵0Û•¢ê«&ÿÚèN€&ã q9Ô •~l ¡O6L‡Dzɿ=õ–7ãŽ@´=ĵ«¶]ÛöÝÛ‰uíTÜœ_çgù¥IŒ,ÎÀ&õ’f‚@3WË"Åx]HgšïŽpo-uÂà-('VÙb Yù3[sÂædÊI‚_k}έ­ÿ‰?zù/þúßHòwçÀÏ™üëûóøÅyàÜø}n×}‹ûÿAþŒ‡¡Ì’ůýê_}ùÚ_û«—Ÿù?}ù‡ÿùvùÒÿñ¿ç›&q¬ ´§eÓ„Ù¾Áú)K6·m³•"«]èLPYôAÓtdM &wd–ßk?¯¦ªIqGC\ñ¿ú—A¥È z@¶6“0 ýQÆÎ˜d[|ú¢­ÈÖÞõ¸­î´¬–¥#áîøâ$ûSп8¯£'>LÊLÑs–•¿5¶h¦I[Fy_»³c-ø<Œª3üùj¾b"x_E,½ßÌxê/]~'ø É÷ÿŽ»ü[ø]~Å?ù+ÃdöÅ%×{zçáôÀësðÅúÿÔ¾ ÑܱºÛ¢¿þ_þñË/ÿ­?|ù<(õsñÏ_>%‘<‡&ÛáYâ²ßxAÍ-Ò"h‚1ÁÝ[´ý Ÿ)B¸)Îm;?(dbBŽ0Kx©}øÐ”ׯÄU&Hw:™pŽIb@Üâök…¾„ÇÉŠßD°„ˉ†š”#‚Šœçò‰ž’¯†hÐË©2žAUÃt¬ÌQ$©k 'L(È“Aß# j1y˜#ÛUX0JԮЋí„d){¿ÿI¦½•"-µq‹†#x‡QÑÔó¡©–ÈòÛ‹ Œóëô§|Ò!Ðç?dîeûFFlQ±IߌMyžëdlðzÙ¹&¸V”!:oûäü«y¸”íòéü¦\—wÐ}ôµ_~ù}?ù“—áwüŽè3ñ»â?“Üq¾C¨å3Ö®è Ì&¾½X¾ÎÇÊϤa4I¸J¶ŸÓhä»ûw·ädøàxš9de?m' [Ôão„`kúèHRtå˜äÛùt’’«×dp £Æl”¼»`lq@IðT½!\V»ØUà^a¤rua"ÂêÍ“fa»y²‘Ôʪ±ÝD™= ÌÙIS,Q°èÖÿLÎúN|¨ l”3…¶Ä;fùÒ íÝI€ˆƒ–cܾÝ–×Þ‹ßñ“œss_U¶K©žž;€~nr'\ øÍí~ÒüL´À'K+ އ-ýás(Ïž>K‚wÂõ+~øG.ÿöŸø—_õ}ßžÝîßIm€çáôÀwÎ ÀwÐÉ8M¹ïýnôq[àÇüòKø‡/?Ã×ÿ¯¿ü.Ÿrÿ9±ü9™Æ@íÅœít¢¾AÚ o²Ý×úÅ}¤ë5 ‚ØÝçL†,’¶fH@q;?/Òà󓱂wšà7»›Ž:“d68X;áÐ'[î^»dU I'D¥)ÉfC2ZÞû¯1$n‰¥2=MI–ƒF=€¢&üt&ßI©*w&=ЗvGP~“›ª MvŽÕôèæ»I³¿; B}þN÷þEÂ{´ÉÉ„™XS4P{ Ö&ç&p‘€wŒ¼«zš€SœL ?j ª Þ C]|b¯ò¦¸~WΫdw&>ÞÏ—™Yãsàõxè•ca*Ð">™Ý0p¾øÁ/þÞËïû‰?rù±õw†ÖëU?ŸÛýqÇyøöÀ^ëßÁ&ž¦½íØ”·¾ÂmßöÇþÈå‡þÛŸ¾ÜýÈÆ5> à¢Ï—å%,@}…ì >>¡ý•8YÀŸ~E6v`ÎtG؇¶LÌæy ø¹5`‚Fq{؇ٞÇÁdn·ÙMͶC@ßäg²1)ÿ|°€ñŠÌÚW™Ä nQ¯69ÁÈ.Âmv\¢%WtùºœºÒ£¦‘DJ_ñÁ\»Õ§MÅ8v-kò·–?õPlûI'@ôKóŠÛ€ì[â"mÉG<é)Å~>‚K_Kä¡s$ðÂsH•w>È“D ¨“KF!ŽO¿Ïß3cê>Ω÷h²l)÷ùÑéubmÈ5àäç:yš×ì@ý¶çß½üy¶ûo“¿×ëN^!?ËéïXœ;ß±§æ4ìMÜ»-ðk½-ðW.ÿýßþÛÜøS—öÍm [²®Ð¦Md÷¼†I€»Þ£ö+†¯Yíe»JZØääûLOÈYµ‡Ã¾É@SK‹‰=¿3 xRüÙþ¶–”a2ùQ\šLì™\ÒЇ•cv*2uXÍSŸYp—ÂÛ’æhC|ó^¤ÛrP,út>½Ó€k›ú³èu$Ú\Hì&j¨2¯!¦ÖöøeíPŠÆ2ž}±“Žˆ_…ÒÜÊL_C„WôûPŸãôœ¥ZmÖ†N´=òÁ™Ø÷VMìá5‘o>`Sï8ß `>ó‘¢~š±vkh^`ÒÓw˜°ñ _Ë?ñƒ?tù7ÿÈO\¾ÿ7ü†ô÷!¿¬xN|‡{àœ|‡Ÿ Ó¼ûØ•Un ¥ÝýØå—þà^þ»ÿú/]þ7¿-@ôv¥þód nG“¤IM|E0)ÌI€žÏLþa"@Ǭ œÉÆ  ÜÄæÔá©+pþ[ä7Aä­vôw»ÜÌ1$IaIpкq¬ØIOÊül¯pŒ»&R“OŸAÿÆNåõ™dfy ±™Î™ŒE%65Þff4 i" ŽAšþ’6ƒÌêW&J&PqÔu<‘ .s%r /ÊQ‹dY-k罂µ&íõ t›Šä‘ž®6|eò,|À<’(T:‘A¸1œãÝáÈ„+Z˜xy"ÇO½M€`Ωãµ<¹¥àXÔ¦Ûýï}ùóËïý?yùñßý»?·ûëžóø Ó½ÒaÚ~Zý{ +-™ßàg…›ßø›ór÷£?š¤ámŸ¨N¢Ì-&y⟠æjÎm_3ìcÞ0ñøîw“™‰ÅÄ“š¦‰*¼¶…Ccî¿ö„VxK)Må˜düÀü®¨“„!æ¹²g«enQJ®ýJ³ŸI‚ì÷¯:xjJhÎ+"ɾ]q—<ÿ›§KëÑ]”¬è©^:£¡tŽPšÔ»šN¶(o{kjŒÛÆQ¯=IáOLúNˆÁ˜b¢WG?z×WõöFðp*B?9™‹t©¡É§Cx©Sv ó|Üñà‡šåùÍ¿ç÷^þÜßûû÷’ÿ¹ÝïI9Ë/Tœ;¿PÏÜiwïØ >¯ýØàmĨÈ C{„å<1Jª}1r0¸h‚@‰ç÷9²ÜyjòöÏÿ®ßuù¯þþß»üÎß÷oÉÿÜîÇ]gù®òÀ¹ð]u:ÏÁèÛÛ¿äŸúU—_òÿÂågþÖß¾üÃ?ù§z[šlŸ3 xšÕ ‰ÄÄC.óËþff¦‡×Ó¼°|C@ZÚIðVôà wlú‚K v0¨IDAT´LÄÁƒƒÙïõ[¦B^7Ä» ]Z°À¡ƒ1É[úBňà}Ä `&>å— SLе£õ®‡MŽÝyÈ@"^ø¹ý]ÜŒA­€ïõ›ìýʤu #U %úÇ,±±?Lv¤P‡R»úhĤ½I]ÍWñåƒçUžÞD6.Ò´ß"ôê3:ävv8qÒé Ï´/ØÎ`_¨öÓþž_÷ý—?ÀC~?À’å|º?n8ߥ8'ߥ'ömÖ›·~ý¿ôc—¯ñûëÿÃ_ûk—ÿùÏü™Ëglñü}uëS¾þÌ·¹úäÆvWÞŹà­oÐ7éû>yL& yÊÄ'½‹Y1ûT}ú LJÊ®Ð6QÉ ã”Nn ‘߉AvL€Ú…MêL)è¹Üùj_dw‡#ö'CC¡MY¾#AÛµƒL‹®ðqÅñ•;Û-á³&ð&ýð–϶:,ˆH±/( XÿÚw{%¥uX†N2HŸgð¨“&§h>9 ÿ¿öÎ=X²ÎóÏÉK$dM0‚ 7ec‚J4ˆH¹Èed`²Ãº”SŠ Bmm© º\Œ²²µ#LFeµjE."Œ°hÁ‚(‹ Eiµ;¢TÍ,לKöûù=ýœtç$§眼o¿ß'é·»Ÿ[?ýé>ýý=—~:"è7j÷ˆ²FVÙ0‰‘ŸÒT‘ÿ8´š¢!A™õÅõUsÿnsÓYýÙtÚG?švÞygc>OæM»¶(‰m=?ŸW¨w ¼n·ÝôÉáóÓ±·ån„fó¾«[ _BI€‰?(ÑA¼óg‡ÕäŒP诅ùcô!šÂ=©'Zˆ€fñÒŠ}Ø“bûù}óØ' ÏÊ7ÄW^僆?Q‡ßÕWžñÆ‚Ö8r©6óAÉ,ùÉjýňŒùÇZHÀ--¼¨>¥W [ šÅUó_¸d¿èøõm·¥‡/ûjÚíéß§—¥€Ìà¦&™š–wÔãS¯¼ †èHñgP‹>€ê½}ÅA8³æZ*Нè!¢Ä~,GÄÿ\(å ŸÊ?") YÃA¤ÈŸ}DŸ¼ÆGc*Ž‚„‡¢³q`ŽŠSl…#b&™(H¹âÉÿxW~&'ƒ´’!PeŸ[Šê’Û‘ž¼É'·px ¨’iC°ËTÍ „c'áØŽ7”Y¤ÃOäÍq‰Ç쎹̙i´‚È¿…s"1+Z8åhmïBNkE`¼ÇL ?ƒ@èªyÝû§O\|Iz÷Ê÷)¶¼%üŒ®õÿô=p‘}Š™B‚!P&zÛ?˜¿ûÝéÁ—ž¸úê4O°Iú0¨)zg©Š?CF‚Ú 8ÑêOÕ_ÿ‘}ú²ód>Ú ?„KJ£$¢ƒÖÅ„A4G$W"³è‘FeRôˆŒØo%ŽdRÄŽ´¨ô°£ÕA¢HZ9ŽàøîÑH›ƒ´ÉŽœ"D<Ž£´QCÎ!º¼uˆQÞó‘'çSòÒ:÷ý—\s9òõ[›³ÊsPë3Ì¥¨Ô6!×ÚgÑ8m‚­ŽIAT F"â´&9' <ó&À7Þ¾Øu§tºšûOUsÿk^ó7÷Dÿô"ü—Ù‹gîsîYõn×JÞ³þߦcoU·ÀôívýEð]¼Y3c|À ÆÄ3!©Hž@(×LUÅŽÑæJç‡IÎ[bOÍÒÑ¥ ÏðWXiJG¸¨ûÒMcw4aÇU!¦„¯ 'ŒnJþ´FÈ?ê¾YHiÞŽ&p­£ "(jd)ƒøä‹1@V4ÑW¹2»àL>¡5ñW"9Ò`<„ÐÇ~äROeÍýT&ºXy©;1É:šþµ…ÔàåwíæEaœkUÀ*]./qd åsÐ&»ñéf1ž¨Ž×ÏG d¹¸‡žtJÚðÓ»ÒG×­ ñws¿ Øõ,·ôì¥÷‰oÕ-°ßâ´ðš é7w’úò—ÓÜß?¡I„Tsœ¡o  !’$Zh!ïCÔ¡1íGkxª«`ní#—1x ‰+ÄÊ5ýÜ\?Nr˜×RÄÙdØqþ‘*;rÏrZ|²?åÁ§Ô¸‹¸ÒÕPBH$Vˆ8û1@çÆ×ñÂÈT-„ç$ “­ ‘–ôÄSf¹tÅ_¾ae¨„W‰Äìò¯ÄÙ*Z¤¸Êƒ8Š_eJdÕÌ•s1 "@ñ”w BŒ¨ÙtÉe"õ2Á Êü¾þ-KÒ_jtÿŠãŽ‹¼ÝÜüÓãlôø Ðë§?²[àà•+Ó¢#LmüvúÝÕW¤×÷÷§—Ô¾˜ÓÏŽØÌÐ>Û ÖC ¨43b=† XÚG¢ùÆ@4ðã'ÐYÄ+Y’"R Gœ¢I='Ò~ž§€ë· ¨%SFyàb,ƒÖ!y ‹W#+G ªÆMJºôæˆ`"rT­QeD^ñ#·ØV¨Ê‹ ‘ÎÊÛJ¦óWÇÐ?ʉK‚p•¸3~BûQóÇr@ôõ«9ˆK¸æc@ý#7òÑ¿(ŽŽ·²1À?eŽ˜Éò¨ìˆ|>~.-.1ÄO†ktªšûÏXû‰DkG÷Wà½2¨þÔÍÂz›@½[à5sç¦£Ö—Ž»í'©ï„%8¼)΀;„G¯JÜò§©êÛBÇÛÈXt H¹ÝèPº‰cà*„ EüÑ6jÉÑôŸ,öÙ$fnÊÏñðɾ A€•®ÔÖ«1{Y˜QȈ©£EÞ9e)eÄ€ 0¿ HY˜QOåPòQò:ç£_ŽyfñôÚ¯‹ÔÌ©G< ²”;¶IX tCûlÃ2ÆQp¡äÇS)jÿ”G– þåø¬ã½~­±[6ë•ü8Ö&¶ô5HÜ€ò8ðø¦¯ÝuWúø¿ÿtˆ¿›ûL`˜€[†QxÃÐ-o ¼qß7§7nøZzäž§__vYÚåwè»z- Q’ðó‚ß–ÖH<%>ÀhœW Á úUˆZ KUV~ˆ25Ø;„UÈõبb‡Z6é*AÇ$„“ôúUPþG{'Çc`ԇɯRŽ5›²)¯| å£Ý˜yXaQ뎲Åa"/ qµÁ!¶”_ÛQÅÅQóÏYçŒ"ä(;a*i†'EŠ“ÊQ([FE¦*W¥Œ¦–È&ÊDyOAX3Àw{ó¢ôñK.Iï“€cÐ'¯ôytàð °0ŒÂ& ”nRÓ}«&ZüÎ#Ó/7þ}úݾ<½~Ó@zfk½2ÍëR Ù~? åct?r‡,¡åÑôÎà‰S¼ª‡"~Zˆ‡"uÄ‹7åØQ>?Œ.FzE&/ŒÒOwv•¡ jÆÙœ¨ò§Šù ›%I”ÑT¶á8ØV|ŽÉk~´…¹A¬ÊFÉ~ñB•V'10"oí«Y¢ÉCe”G—†"F\¬œqR Ê‘8æÁ–tU çKþUt´`Œ½¨r~èüO§|êSiwÍù€£É?ZwbÏ?&`u<ƒìLÀF!€P±ða˜æÌIïT?òq·Ý‘úNŠ«¦·÷þtåw¤uŸýlˆ?µ~œ'ó þ1Q lù 5Øž&`3TÓÇaü+5/¯ºúª´ô;ßIý‡-S­^*Å A‰ã6I¡™¼f±—Øõ+<ö³0”þê†TåÆ@ˆ I.¢‹t²û•1@xô‰†X¢¸rògr›ÒRß° c33aŒ`[- LnDmœ"ç42#â`øgƒC+Å(Íü9ÇðSDŒ‚œVqðÒç¿Ä?L²Œ-Õ¾IƒÇk%=Ç"¿\šˆ?¤ÄqžŠKú2›-ˆ=}ýœO”AéÑwŒš.Hÿî¿|3]¦)žßzÈ!Qã'o×úÑζCÀÀv9Ø  N ÌþzSàôܘÞxÑ%é¹9»¤9R-j÷4a3*`¯ â§}j¬Ì ¯×ò›_yS·:N8b'­ŒôˆÝñf¿Â#ÛNq´Š–vœ¸¥E€PŽ™ãQ&f¿Xáic.€È‡š{®ñ—¬e7„?Æÿq9§²Î¾% Ó!7ÍcãG3¾Ê|¢\ÚÎ;[jÿ5c‚\á̱òñ”§â3Ð’ÖL•!½ryÜúóÓ5ªõ¿ÿ¤“(Zˆ?5þèbÿ˜€ l‹€þ¤ìLÀÆK Ä…µª  *;ò㙎—ítÚ‡UËåÕ? ¢ÿè Pk€±ÒI ¨G V¢F5Mãè!KUaò7¥¡æË1µ£¡Š[D}Ï5m \¥Ö•„"Ë¥5 OL¤|rU:w)DmšÜ¨™“^ÇÔ/ »Ùè©¶•55<2’“R3Füª›CÁ”#Z "$›ô*Ÿ2V íǶò‹c‘&ZE4í8ŽüÂxÒ>-}²†0¯X‘¾rÇOÒº‹>ŸöØcä§ìÜÜ;h@@Nv&`M Ô»öÞgŸôÁ¯\–ޏñÆ4ø¶ÃUFŒ²XÇë‚2 èÒŒ<ˆ^´("‰ÀÑ·=H—/7£k]m£„'5fúÿÃÐ>5þYjÊK\Ötu Hœ c,BväÀ?ŽG·€¶"mÎ’À–}%a±­0Zˆ3Üì_…Eó<þˆ6N+Î!»ìÇoä£XæŠA©2yˆC„k3ΟµøµÙ{¿!{ÅUé«ê~9èÐCÃxrsÀñ Lˆ€ß˜6'2L t  yû-;"-úþ÷ÒƒßýnúÍW¤×ýó?§—äxÆ8u©Ú, ½Ú *¡Ô6­ÆÒt®ª¬-).§(r’ÆÐSÔ6÷Ñ#–ôíç7ðǧJ£µ´<Œ€<‚¡Êƒ•\e„8ÄÅ8ˆ.m‡«».)ærCê‰÷)göf”>Ó&3oB :Tšó9É")ùTF Ó,GŸ‰öóAN4ÚÐ&Ð:2#½Ý_¥3×›æÏ›A´œx€_ ð L˜@ü°ÂL ›_eFy%Ü”—à¯/(Ëå<ÃÈ'e¥|¹ŒÊ( âqþù\ÂxÀ‡|"DæƒiÎÞ{¥Õ_¹<]ñý›Ò¡‡®óáXÝ/:v&0ilLJgd™@é I|ɲ¥éÔïݘÞôÅ/¥çö˜§ø$~¤4q“•i…$H=¯÷ "®ˆ3ñ¤¦,ˆl¿ÒDÍ_aè$-,!²JéBð倇+LÛ!ά#\µlò##åFKÿÙ ÿªŸž}ĉ&NDÔþ¦4‘3ˆ cxÝ¡ŠKyÂhÐ*¦L®Žøçæ~ÆGp\E›Ó&“x÷ÚsÓ×î¸3rο‰×ùJs¿G÷ ‘ L"˜D˜ÎÊ ò¶Fï¤/?ûì´ÿ±+Óƒ×\›ž»þ[i®p@oð áY2¢V. œ!ñ$-’‹¶Ò ΘÐÙMyÊH(j¤6DeÆSê­l³Š×Âè®W¶!îd†‘Á¨Bƒäa °Orļʘ}YúÉõ9O€L€âbPŸ r':yqmæ:~Þæxj.‰VŒ™š»f´HlN –-Ok.º(¾l™"(+u©ÀÎ}ýÃ?&0éò_ô¤gë MÀ Ðj,”˜Í›¿gZyÉÅéèþ0 .;*iöàøf¯¶åI4>@ƒcL@ˆª ‰%ZŠ`GÓ9ÝÙ¨“‡k[qBdùÑâ›ßÈi£Õ@q#/©ožTHâZËÅ+† T”ȇl"+½ÓH>œCLôCŠJü£Ù^ÂM9(_ÄgèkMfoPFIt;È+Ê!¿8ÊHD5÷kê¾´ZßZ¸ê?ñws?íL`ê Ø˜zÆ>‚ Äø€\«Jû¾ýíéôoH‹¾üåôÒüùê Æ¯EÕùè_—È«ê".úû‹h²ÎBšà…#¶ÅŸ|*‘g A˜€ªŸpL 0ctì"ÞøÅRU㬘gÄhÀ©l b®ùSûWÅ#Ï0TäC­?÷ïWeUâ|^´hÈ0Pú¥ç|$}ýΈæ~júnîÀþ1i!à.€iÁ샘€*ż'a¥V½ô¬³Òâ—~ý_¿•~ÿÍ iwMÐch`—˜J0gðÚ „|&ÞK¸i- [€Ú3_”ŽÒšN{ò——p©±6C”阂]•Cy#æ¹é^±hU üø‡è󯀬‚r& r,mç ëqŠ¢cP.º38¶)<ÝC*ë î7•zá‘ËÓÇ>÷¹´tù‘ÒÍýAÁ?&0½l4äíH 9ú+ôUS 3>`ž¾÷s~¿êøô¿¾øå4㾟K-õªà Iqók„®úÃ%¦}®„¶O†5vñ¡—8‡!/K‰³ñ£v¯Ö+(æ"Ð?&" ‰Ÿ<Ø-‚.Û# yéøÊ> yÒb€qëø*‡þåÏ!ŸÂdñçCI1›¡’EÛÖƒswM«/¾8¶zuôïc€àü©ÞÀà˜V•Í?­ÇôÁL ç `HÖßx³>dsÆwoH‹¿zEzyï7¦9šÏ³ôó¦À }hHЍVýñŠC«@ÌÔ'Ío Ò,ÙÁfBöµŠšyä,1Ïò››¢¦N8­ʈ|lˆ1›ùàþZbm Ý#qlŒ¤¾:ÎЀÚT럥òõkr eqvºæîŸ¥3Ö¬ ñglTÃÔΦŸ€ €égî#šÀ0@ÕìéûÆ-=õÔ´êö[ÓšùîyUÉËG†bú`É7“ú ÐÄNs;†€ÒC`@Í;¯nV“û`ÌÈWÊ+â*~¬%Ö4ËSíÐ@ƒ±%§Û ÖÚfÑ­ÚV¢ê0;èÀKOƒqåßO3€ÜòÄÚüf55 1øOþ´ ð©ã¨íë'Öá¯<"¡ÒÍ›N»ä?¤«ô?Ò²£ŽŠó+ÂïZ?ìL`ǰ°cùûè&0LQ¬w ¼é ·¦ÓþÛߦ7\“^Z¸ošMs»Ÿ™ÿ˜}/ÞPÄ8FùÓ= Üb[šŽ!À²Y# 9b®=º ¨Å#ó,xÿ¼Ï· hÎgì!­CŒK "3ö€–Ò‡ÑBªé3…ïL•¡OãÞqöYé÷ÜÎ9ïÜ´óÎ;G­?Z;T^;0Î àA€q\ &µc e¼§õÛN8>íûî£Ó¯¾õ­ô»«®Jó$È›TÓǘ-ù.y+qŸ)L 꿳„ú•ñ€xS‹ÏÝ ×ýø|Êx@k>.Fr Ä€ÐOÄc¯¦íêäïãÝ?53ìþÖÒÚ/\’Ž~ï{IÂO놛û‡L £¸ £.‡ c[Ä xêØíµ¯Mïùô§Óñ?¹#ÍøÀª¨…c½öÍ–Ó- A‚o„|€4,ȶt[­÷!ÔCRx&blƒs«]ÊHB^Ö!þ4ý'뾂™ÃŸ_奸òŽ…Ú~Ÿâ2ºÿôK/Mßøñ-!þ´ ¸¹_ìL ƒ Øèà‹ã¢™â#CªÔ|á[öO§|óšô¶¿½.õ￟êé“Gìµ(œ¾~„š/FÿÔøå¯ª:¢OmƒA¹†qÝ´ýc8„ ³€ˆjúGì‰9 „ >јEp€Wx§_~ýZÞ~úi隟ýC:çSç¥]wÝÕÍýbbgÝ@À]Ýp•\FPž®Ò-pÐ{W¤}5™Î}·1ýö+—¥×Kœ_%LY÷¤š9çáÕý™ÔÒ¥Ö4ñb0è÷ùŸ%ÞÛg%ïØ¯½•€ø÷é)Í€ø÷ÍÖ R}jý»p`Zsñߤ÷{,¹¸¹?(øÇº‡€[ºçZ¹¤&?Œƒ! aÞe—]Ò1ªu¯ºã§iÖ êP­¯ 2ÂÍGzx50Z¤ìj Bü©É뇩xÃPËkÞû§[€}ÒúÔOÿÁ,Ž¥$ò K¢ODÿ¬YéÔ/|!}ãÖ[BüÝÜïÓº“€ €î¼n.u¨¿-°`¿ýÒ‡¾¾!-ÿûï¤þC߃é§РÀè`›EB®ÿa°fþ4^ZKt  ÕðyÛ``“"hæBÜË 8䤓ӆ»ïN]¿ÞÍýAÅ?&нÜн×Î%ïqåmjàÒ÷tÀQG§}pSºoã éáËÕ-ÐÿrzI5úY2yUàU³ÏqIƒù´Î Iù‰€ ›ãÉ0[½›Ôü?˜^§W?qñ<º¿Çï9Ÿ~»¸ ]×ÓgÓƒŠ!@·ÀœÙsÒ»>±&r×i§Ÿ©Á{곑ï‹×iÚÏ"¯.)~?a¥%@a1¡ÿ²úúÓ& ö;õóŸO_¿ùÇÝ߃÷–O¹Ýl´ûúúìzˆ@éÀØ{áÂt²ZŽþþMipé;DÏ÷¨Ö¯|fdÁ  ÕHÍ›ÔìÏd>8Þ*8øä¥¯Ýó?ÓGÿê|7÷ÿ˜@»¸  ]×ÓgÓãh (_Tå>½eÙ;Ò’ï}/Ý'Cà_yEÚýOL›xK€¦~ d áÍêçgîþøBáÁ‡¤5]”ÞyÌ1A“7ÈדùôøÍåÓo·´î’ú„L€Wú¤ðZtFï©©yO½í¶´Ç'×¥ô àl {@+ÅÓL}Z é­‚_riÚð£…ø—Ñý1úŸüìLÀZEÀ@«.§Oƶ&µz©<ÝóçÍKï¿ð³é¸ßžfbz.Æô¥Õì¿ôì³ÓÕwþ4½vmÚi§¢u Z,ü[õž ´ˆ€¦ý¦ ЛN8ª5,BT‚Xèáuj–´ÌÑ2WË|- Ôz½Öv&Ðuâo]ïñ™^•þ‰üÇôìÿù¿éõ‹öIû.Ù?·n×ø»îÒºÀÝ»§kóŸ´ü‹–—´lÒò²&­d‰¯VhC_´ÖŸEÇè°3^ Pºʹ.>è ÄRwîç¯Óð¶ ´›€»Ú}}}v&`&`&0*£b±§ ˜€ ˜€ ´›€ €v__Ÿ ˜€ ˜€ ŒJÀÀ¨Xìi&`&`í&` Ý××gg&`&`£°0*{š€ ˜€ ˜@» Øh÷õõÙ™€ ˜€ ˜À¨lŒŠÅž&`&`&Ðn6Ú}}}v&`&`&0*£b±§ ˜€ ˜€ ´›€§nx}óç&rtè/¾øbº÷Þ{‡Krë­·¦çŸ~x´¹sç¦N8a8háÂ…iÉ’%ÃûÞ0è^6º÷Ú¹ä“Dàî»ïN7ÝtÓ¸r[½zuZ¾|ù¸âvB$Îí™gžI¬'â0FcS7 V¬XÑ8ë&Ìg>"ÁG‘-Z¾6`FÀñnO°ÐÓ—ß'ßFO?ýtúÕ¯~•¨áO•«‹/NK—. ãh—]v™ªÃN(ßûî»/±Ô]1 &b¼Ôóñ¶ t3Ý|õ\v¨xöÙgÓÍ7ßü ±«E™²Í'žx"±ÜsÏ=éÒK/²ãLVÆÅ(Àx¡‹ã}ï{_ê4Ãe²ÎÕù˜ÀXlŒEÆþ&ÐE¦³I½‹°Œ«¨´”°`¬Zµj\iÉÚ@À@®¢Ï¡g 0°ïúë¯O?üpÏ2˜¬Ç¸ÿþûÓÚµkÓ‚ &+[çcKÀ¯vì¥qÁL`Ûhò¿üòË-þÛÆÔ(ôücúÒ—¾”zè¡FéÙº‘€[ºñª¹Ì=Oñß°aCB°&ê·çž{¦mŒŸÈ«ƒ-O'¥»öÚkS·½ñÑIü\–î ` ;®“KiÃ削?£õßõ®wûUFÆÕGÊ—íÇ<=õÔSé‘G™òˆ&BÌ=öX°zµeÛ¸qc <ì°Ã†Ù{ÃÚDÀ@›®¦Ï¥'\sÍ5ªù7Òíd2 –bÐdN«Ä<°½¤SNß}é¿/ec€$o'L¤µäÛßþvºð Ӽyó¦´ÜÎÜv;‚ºi$€˜ñº]G­Íš5S*b¥–\D·Iù¦:.eb™È›ÌwpÝu×¥Ï|æ3S]LçoÓNÀƒ§¹h#@ {´Yù¶•â¿~ýú)ÿm¿“Â0.¸à‚ÆEÂàÂx°3¶°ж+êói-»îº«Ñ¹íµ×^Qó÷7[°ÑmqÞyçmñç¯2öÂÎÚDÀ@›®¦Ï¥µ¨ý7­…žsÎ9®ùrGÐ]QÿÀÑ(Q^áEW@ýCJ¯ˆ`èB6ºð¢¹È½Gà¿øE£“¦¹Û_í3þÑBÒÄ1ÐÎÚDÀ@›®¦Ï¥µšŠÏÊ•+[Ëb²NŒ’&Ž·xýÑÎÚBÀ@[®¤Ï£µxÅŽ&èñ:jÿ~mmû´h!9äC¶±ã·¿ýmmÏ›&ÐÝlt÷õsé{€À“O>Ùè,:ê¨Fñ{9òÑGÝèô}ôÑFñÙ:™€ €N¾:.› ˆ@Ñ™;wîðD8†·} „Ùx¯úm€ñÒr¼N'` Ó¯Ë×Ó›&ÿsÌ1=Ík"'ðÁ7JÆtÃv&Ð6Úp}­%ÐTlæÏŸßZSubx`£¬ù‚ ´€ €6\EŸCk üùÏntn|ÙÏ®¦Ìš ÈlVÇ6é%``zyûh&Ј@Óþfþo„7"—7åŸþô§ñFu<èh6:úò¸p½Nà™gž7³yÚßqãÚ*b“I^xá…­ÒzǺ•€ €n½r.wOh"6MF³÷¼'i ,Gm ­¹”>‘6hb4±6²z5ç´ë®»Ž;ùsÏ=7hLÀ@'_—ÍL`Z41¦¥@>ˆ LÓÙ‡000N#` Ó®ˆËc&ÐÑÜÕÒÑ—Ç…k@À@XŽjÓM IÓ4_«³›¿Ú71nNÕÝlt÷õsé[N ‰à j¦çfðl‹ÓÃÙG™z6¦ž±`&°çž{Ž;-@Ó‰ƒÆyË#6i=ib”µ›O¯Ë Øèò èâ·›@Ó‰}ž}öÙv™¢³kbx¾…)ºÎvÚ Ø˜vä>  ŒŸ@Óyê{ì±ñgî˜A é—<ݲoœ¶°Ж+éóh%¦bó‡?ü¡•¦ò¤š~piÿý÷ŸÊâ8o˜66¦ µdÍ Ð°xñâq'üÍo~ãq㦕#>ùä“ãNÁµhÚ-3îÌѦ™€ €iîÙ@SM¾WÏ@À‡z¨é!z:þý÷ß?îóor-Æ©#šÀ"``÷aM`¼8à€ñFx¿üå/ÅïåÈôÿ7¸Ï>ûô2.Ÿ{ËØhÙõé´À’%KR“‘ç?üpzüñÇÛb Îèç?ÿù¸så¸ÿܸ± Øè‚‹ä"šÀ 'œÐ 7ÜÐ(~/Fæ•É»ï¾{ܧ¾lÙ2÷ÿ›–#vÝp•\Æž'pØa‡5b@³ö-·ÜÒ(M¯E¾ùæ›òÊ•+Åwdèt6:ý ¹|& ¼¸bÅŠF,n½õÖtï½÷6JÓ+‘(yß}÷ût9ä¸ãNàˆ&ÐltÁErM'žxb£±¤Ù¸q£@Ôã#®½öÚšÏö7Ï:ë¬íGr è26ºì‚¹¸½K€÷ÏO?ýôÆ0šôu7>@•€ïÐíÐÉ­ˆÿ•W^ÙèÑtB¦FpdØAfí ãú°&` °|ùòôè£6j¾æ07ÝtSzä‘GÒÉ'Ÿœ,X0#Q}ðÁ‡ŒÕ«Wy†À ©!´×^{¥U«VíÀRûÐ&0ulL[çlSBàÌ3ÏL|¿þ‰'žh”?¯²0–àðÃO¼^8Q‡è?õÔS‰qþbD"å䵿µk×N‘Ó™@ǰÐñ—Èì$4§³L…c Ùºuë¶›5]kÖ¬I6lh4‰MÉA,5á3Î8#¼y¿}¬–^—+³ ò­&ƒçÊ1§s]Îíhl$ÕËyî¹çŽÉ¤ÏÛ&Эltë•s¹{š}ÒçŸ~ºîºë^•ÈÑ,Þén*®±Îý‚ .xU-$cåkè$ØIWÃe10Ö¯_Ÿh9°›4û[ü'‡¥sé|6:ÿ¹„&0&ºè6(MùcFtÀv `H]xá…®ùo—”#´…€»Úr%}=M€}ÌÈìv;ªžÚ3¯Ìñ¦B79ÊÍë•ÝVînbì²v&y]\*hL€.}ìcéØcM|ä¦ †kœQÃGqDâ3¹Ý& Å`i:ÃbC<ŽnKÀ@Ç^Ì&F€Ñüt °`LÅÈ}júh7Š'eæËM¿¯0±«áT&йú6oÞܹ¥›â’õÉé,Œ…˜Y-E³«e'­çh™«e¾–âu½Öv&Ðuž~úéôØcE¹Ÿyæ™qµP»_´hÑð¹N–àc˜LÇõò#øžÑoøR¶rCt¦Êü'-ÿ¢å%-›´¼¬¥¿Z´¬–!­õHï]´`@v&`&Ðýl4»†~  /Ç600V°ЊËè“000fl4ãåØ&`&`&Ð 6Zq}&`&`&ÐŒ€ €f¼ÛLÀLÀZAÀ@+.£OÂLÀLÀš°ÐŒ—c›€ ˜€ ˜@+ØhÅeôI˜€ ˜€ ˜@36šñrl00h­¸Œ> 00hFÀ@3^Žm&`&`­ ` —Ñ'a&`&`ÍØhÆË±MÀLÀL l´â2ú$LÀLÀL Íx9¶ ˜€ ˜€ ´‚€ €V\FŸ„ ˜€ ˜€ 4#` /Ç600V°ЊËè“000fl4ãåØ&`&`&Ð 6Zq}&`&`&ÐŒ€ €f¼ÛLÀLÀZAÀ@+.£OÂLÀLÀš°ÐŒ—c›€ ˜€ ˜@+ØhÅeôI˜€ ˜€ ˜@36šñrl00h­¸Œ> 00hFÀ@3^Žm&`&`­ ` —Ñ'a&`&`ÍØhÆË±MÀLÀL l´â2ú$LÀLÀL Íx9¶ ˜€ ˜€ ´‚@¯›·sG†ÜßNr›€ ˜€ L#‘Ïè‘û#‹²½ð‘ñ[µßëÀXsäMÁþH¿±ÒÚßLÀL`Çíyíç÷(×ÃÀ(#or\oIá-00N"0òy]öëeÄÏNll}Œvc”hHQ·Žî=00"À3º<³ÇzžwPqwlQl¼’ýæ©o(jÿ+£ÛÇLÀL CðœiÔŸãRÌÎ(† €±¯C¹iJÍ“¢>?vt‡˜€ ˜€ ì`/ëø<·YÊs\›v# ÌéÑ£ûõ›¤l³.7%Àÿëëë;Aë]´ì¤~³µÌ¬-U}µE›v&`&`$0ò™Ìó¸,´Ê²¼¤å-/j!¬<»Ëºä¡ @ÀÙÈ7‚+7I}Í T n0°2çhAüaÈ‚€ø—¥ò²30˜ ò<æY\žÉÔôY¨œ#€íÑZJ¬‹«o¿žZÛØúr×o¶‹õX7HQn¾"þc[çî=00‰(ÏãÑ ñgÙV @Ï‹¾ø ;Ã(†7ŠP¿Ñ¨ÕÑ/Mü$¨ß”ø—V€Rû/- ĵ30hN <“Ëó¶<Â_žËì?üK¼R‘#½]€ € £~ƒáà ƒ ×n¬"ìÚDŸ­ˆÝ@°);0˜8"ÜÅà¹\žuþ‘F@y~—t”`䳿žu6¶¾ôõ›ƒ›ç+Â_½ÜPÄ©×üÙ¶ v&`&0IxÞâêÏÝb°.@}] ÂYêÏvíÚAÀÀ–û€çf©¯¹‘ê®ÜH寫×ü‹øƒ¡žÎÛ&`&`#Pž»¬‹¨³æù\Öu€íFxI§ÍØfÝóÎ@¾¸9mÖ8n~#]¹‘F ÿHñ-íȼ¼o&`&°} Action File.New Archivo.Nuevo File.Open Archivo.Abrir File.Merge Archivo.Fusionar File.Save Archivo.Guardar File.SaveAs Archivo.GuardarComo File.SaveImage Archivo.GuardarImagen File.Import.LDD Archivo.Importar.LDD File.Import.Inventory Archivo.Importar.Inventario File.Export.3DS Archivo.Exportar.3DS File.Export.COLLADA Archivo.Exportar.COLLADA File.Export.HTML Archivo.Exportar.HTML File.Export.BrickLink Archivo.Exportar.BrickLink File.Export.CSV Archivo.Exportar.CSV File.Export.POVRay Archivo.Exportar.POVRay File.Export.Wavefront Archivo.Exportar.Wavefront File.Render Archivo.Renderizar File.Instructions Archivo.Instrucciones File.Print Archivo.Imprimir File.PrintPreview Archivo.VistaPrevia File.PrintBOM Archivo.ImprimirBOM File.Recent1 Archivo.Reciente1 File.Recent2 Archivo.Reciente2 File.Recent3 Archivo.Reciente3 File.Recent4 Archivo.Reciente4 File.Exit Archivo.Salir Edit.Undo Editar.Deshacer Edit.Redo Editar.Rehacer Edit.Cut Editar.Cortar Edit.Copy Editar.Copiar Edit.Paste Editar.Pegar Edit.PasteSteps Editar.PegarPasos Edit.Find Editar.Buscar Edit.FindNext Editar.BuscarSiguiente Edit.FindPrevious Editar.BuscarAnterior Edit.FindAll Editar.BuscarTodos Edit.Replace Editar.Reemplazar Edit.ReplaceNext Editar.ReemplazarSiguiente Edit.ReplaceAll Editar.ReemplazarTodos Edit.SelectAll Editar.SeleccionarTodo Edit.SelectNone Editar.DeseleccionarTodo Edit.SelectInvert Editar.InvertirSeleccion Edit.SelectByName Editar.SeleccionarPorNombre Edit.SelectSingle Editar.SeleccionarIndividualmente Edit.SelectPiece Editar.SeleccionarPieza Edit.SelectColor Editar.SeleccionarColor Edit.SelectPieceColor Editar.SeleccionarPiezaColor Edit.TransformRelative Editar.TransformacionesRelativas Edit.TransformAbsolute Editar.TransformacionesAbsolutas Edit.TransformToggleRelative Editar.AlternarTransformacionesRelativas Edit.TransformSeparately Editar.TransformarPorSeparado Edit.TransformTogether Editar.TransformarJuntas Edit.TransformToggleSeparate Edit.AlternarTransformarPorSeparado Edit.Snap.Toggle Editar.Ajuste.Alternar Edit.SnapMove.XY0 Editar.AjusteDeMovimiento.XY0 Edit.SnapMove.XY1 Editar.AjusteDeMovimiento.XY1 Edit.SnapMove.XY2 Editar.AjusteDeMovimiento.XY2 Edit.SnapMove.XY3 Editar.AjusteDeMovimiento.XY3 Edit.SnapMove.XY4 Editar.AjusteDeMovimiento.XY4 Edit.SnapMove.XY5 Editar.AjusteDeMovimiento.XY5 Edit.SnapMove.XY6 Editar.AjusteDeMovimiento.XY6 Edit.SnapMove.XY7 Editar.AjusteDeMovimiento.XY7 Edit.SnapMove.XY8 Editar.AjusteDeMovimiento.XY8 Edit.SnapMove.XY9 Editar.AjusteDeMovimiento.XY9 Edit.SnapMove.Z0 Editar.AjusteDeMovimiento.Z0 Edit.SnapMove.Z1 Editar.AjusteDeMovimiento.Z1 Edit.SnapMove.Z2 Editar.AjusteDeMovimiento.Z2 Edit.SnapMove.Z3 Editar.AjusteDeMovimiento.Z3 Edit.SnapMove.Z4 Editar.AjusteDeMovimiento.Z4 Edit.SnapMove.Z5 Editar.AjusteDeMovimiento.Z5 Edit.SnapMove.Z6 Editar.AjusteDeMovimiento.Z6 Edit.SnapMove.Z7 Editar.AjusteDeMovimiento.Z7 Edit.SnapMove.Z8 Editar.AjusteDeMovimiento.Z8 Edit.SnapMove.Z9 Editar.AjusteDeMovimiento.Z9 Edit.SnapAngle.Toggle Editar.AjusteDeAngulo.Alternar Edit.SnapAngle.Angle0 Editar.AjusteDeAngulo.Angulo0 Edit.SnapAngle.Angle1 Editar.AjusteDeAngulo.Angulo1 Edit.SnapAngle.Angle2 Editar.AjusteDeAngulo.Angulo2 Edit.SnapAngle.Angle3 Editar.AjusteDeAngulo.Angulo3 Edit.SnapAngle.Angle4 Editar.AjusteDeAngulo.Angulo4 Edit.SnapAngle.Angle5 Editar.AjusteDeAngulo.Angulo5 Edit.SnapAngle.Angle6 Editar.AjusteDeAngulo.Angulo6 Edit.SnapAngle.Angle7 Editar.AjusteDeAngulo.Angulo7 Edit.SnapAngle.Angle8 Editar.AjusteDeAngulo.Angulo8 Edit.SnapAngle.Angle9 Editar.AjusteDeAngulo.Angulo9 Edit.Transform Editar.Transformar Edit.TransformAbsoluteTranslation Editar.TransformarTraslacionAbsoluta Edit.TransformRelativeTranslation Editar.TransformarTranslacionRelativa Edit.TransformAbsoluteRotation Editar.TransformarRotacionAbsoluta Edit.TransformRelativeRotation Editar.TransformarRotacionRelativa Edit.Tool.Insert Editar.Herramienta.Insertar Edit.Tool.Light Editar.Herramienta.Luz Edit.Tool.Spotlight Editar.Herramienta.Foco Edit.Tool.Camera Editar.Herramienta.Camara Edit.Tool.Select Editar.Herramienta.Seleccionar Edit.Tool.Move Editar.Herramienta.Mover Edit.Tool.Rotate Editar.Herramienta>Rotar Edit.Tool.Delete Editar.Herramienta.Borrar Edit.Tool.Paint Editar.Herramienta.Pintar Edit.Tool.ColorPicker Editar.Herramienta.SelectorDeColor Edit.Tool.Zoom Editar.Herramienta.Ampliar Edit.Tool.Pan Editar.Herramienta.Desplazar Edit.Tool.RotateView Editar.Herramienta.RotarVista Edit.Tool.Roll Editar.Herramienta.PivotarVista Edit.Tool.ZoomRegion Editar.Herramienta.AmpliarRegion Edit.Cancel Editar.Cancelar View.Preferences Ver.Preferencias View.ZoomIn Ver.Ampliar View.ZoomOut Ver.Reducir View.ZoomExtents Ver.Todo View.LookAt Ver.Modelo View.MoveForward Ver.MoverAdelante View.MoveBackward Ver.MoverAtras View.MoveLeft Ver.MoverALaIzquierda View.MoveRight Ver.MoverALaDeracha View.MoveUp Ver.MoverArriba View.MoveDown Ver.MoverAbajo View.Viewpoint.Front Ver.Vista.Frente View.Viewpoint.Back Ver.Vista.Detras View.Viewpoint.Top Ver.Vista.Encima View.Viewpoint.Bottom Ver.Vista.Debajo View.Viewpoint.Left Ver.Vista.Izquierda View.Viewpoint.Right Ver.Vista.Derecha View.Viewpoint.Home Ver.Vista.Inicio View.Cameras.None Ver.Camaras.Ninguna View.Cameras.Camera01 Ver.Camaras.Camara01 View.Cameras.Camera02 Ver.Camaras.Camara02 View.Cameras.Camera03 Ver.Camaras.Camara03 View.Cameras.Camera04 Ver.Camaras.Camara04 View.Cameras.Camera05 Ver.Camaras.Camara05 View.Cameras.Camera06 Ver.Camaras.Camara06 View.Cameras.Camera07 Ver.Camaras.Camara07 View.Cameras.Camera08 Ver.Camaras.Camara08 View.Cameras.Camera09 Ver.Camaras.Camara09 View.Cameras.Camera10 Ver.Camaras.Camara10 View.Cameras.Camera11 Ver.Camaras.Camara11 View.Cameras.Camera12 Ver.Camaras.Camara12 View.Cameras.Camera13 Ver.Camaras.Camara13 View.Cameras.Camera14 Ver.Camaras.Camara14 View.Cameras.Camera15 Ver.Camaras.Camara15 View.Cameras.Camera16 Ver.Camaras.Camara16 View.Time.First Ver.LineaDeTiempo.Primero View.Time.Previous Ver.LineaDeTiempo.Anterior View.Time.Next Ver.LineaDeTiempo.Siguiente View.Time.Last Ver.LineaDeTiempo.Ultimo View.Time.InsertBefore Ver.LineaDeTiempo.InsertarAntes View.Time.InsertAfter Ver.LineaDeTiempo.InsertarDespues View.Time.Delete Ver.LineaDeTiempo.Eliminar View.Time.AddKeys Ver.LineaDeTiempo.AnadirClaves View.SplitHorizontal Ver.DividirHorizontalmente View.SplitVertical Ver.DividirVerticalmente View.RemoveView Ver.EliminarVista View.ResetViews Ver.ReiniciarVistas View.Toolbars.Standard Ver.BarrasDeHerramientas.Estandar View.Toolbars.Tools Ver.BarrasDeHerramientas.Herramientas View.Toolbars.Time Ver.BarrasDeHerramientas.LineaDeTiempo View.Toolbars.Parts Ver.BarrasDeHerramientas.Piezas View.Toolbars.Colors Ver.BarrasDeHerramientas.Colores View.Toolbars.Properties Ver.BarrasDeHerramientas.Propiedades View.Toolbars.Timeline Ver.BarrasDeHerramientas.LineaDeTiempo View.Toolbars.Preview Ver.BarrasDeHerramientas.VistaPrevia View.FullScreen Ver.PantallCompleta View.CloseCurrentTab Ver.CerrarPestanaActual View.Shade.Wireframe View.Sombreado.Malla View.Shade.Flat View.Sombreado.Plano View.Shade.DefaultLights View.Sombreado.LucesPredeterminadas View.Projection.Perspective Ver.Proyeccion.Perspectiva View.Projection.Orthographic Ver.Proyeccion.Ortografica View.ToggleViewSphere Ver.AlternarEsferaDeVista View.ToggleAxisIcon Ver.AlternarIconoDeEjes View.ToggleGrid Ver.AlternarCuadricula View.FadePreviousSteps Ver.AtenuarPasosAnteriores Piece.Insert Pieza.Insertar Piece.Delete Pieza.Borrar Piece.Duplicate Pieza.Duplicar Piece.PaintSelected Pieza.PintarSeleccionadas Piece.ResetPivotPoint Pieza.ReiniciarPuntoDePivote Piece.RemoveKeyFrames Pieza.EliminarFotogramasClave Piece.ControlPoint.Insert Pieza.PuntoDeControl.Insertar Piece.ControlPoint.Remove Pieza.PuntoDeControl.Eliminar Piece.Move.PlusX Pieza.Mover.MasX Piece.Move.MinusX Pieza.Mover.MenosX Piece.Move.PlusY Pieza.Mover.MasY Piece.Move.MinusY Pieza.Mover.MenosY Piece.Move.PlusZ Pieza.Mover.MasZ Piece.Move.MinusZ Pieza.Mover.MenosZ Piece.Rotate.PlusX Pieza.Rotar.MasX Piece.Rotate.MinusX Pieza.Rotar.MenosX Piece.Rotate.PlusY Pieza.Rotar.MasY Piece.Rotate.MinusY Pieza.Rotar.MenosY Piece.Rotate.PlusZ Pieza.Rotar.MasZ Piece.Rotate.MinusZ Pieza.Rotar.MenosZ Piece.MinifigWizard Pieza.AsistenteDeMinifig Piece.Array Pieza.Secuencia Piece.ViewSelectedModel Pieza.VerModeloSeleccionado Piece.MoveSelectionToModel Pieza.MoverSeleccionAModelo Piece.InlineSelectedModels Pieza.FusionarModelosSeleccionados Piece.EditSelectedSubmodel Pieza.EditarSubmodeloSeleccionado Piece.EditEndSubmodel Pieza.FinalizarEdicionDeSubmodelo Piece.Group Pieza.Agrupar Piece.Ungroup Pieza.Desagrupar Piece.GroupAdd Pieza.AnadirAGrupo Piece.GroupRemove Pieza.EliminarDeGrupo Piece.GroupEdit Pieza.EditarGrupo Piece.HideSelected Pieza.OcultarSeleccionadas Piece.HideUnselected Pieza.OcultarNoSeleccionadas Piece.UnhideSelected Pieza.MostrarSeleccionadas Piece.UnhideAll Pieza.MostrarTodas Piece.ShowEarlier Pieza.MostrarUnPasoAtras Piece.ShowLater Pieza.MostrarUnPasoDespues Model.New Modelo.Nuevo Model.Properties Modelo.Propiedades Model.List Modelo.Lista Model.Model01 Modelo.Modelo01 Model.Model02 Modelo.Modelo02 Model.Model03 Modelo.Modelo03 Model.Model04 Modelo.Modelo04 Model.Model05 Modelo.Modelo05 Model.Model06 Modelo.Modelo06 Model.Model07 Modelo.Modelo07 Model.Model08 Modelo.Modelo08 Model.Model09 Modelo.Modelo09 Model.Model10 Modelo.Modelo10 Model.Model11 Modelo.Modelo11 Model.Model12 Modelo.Modelo12 Model.Model13 Modelo.Modelo13 Model.Model14 Modelo.Modelo14 Model.Model15 Modelo.Modelo15 Model.Model16 Modelo.Modelo16 Model.Model17 Modelo.Modelo17 Model.Model18 Modelo.Modelo18 Model.Model19 Modelo.Modelo19 Model.Model20 Modelo.Modelo20 Model.Model21 Modelo.Modelo21 Model.Model22 Modelo.Modelo22 Model.Model23 Modelo.Modelo23 Model.Model24 Modelo.Modelo24 Model.Model25 Modelo.Modelo25 Model.Model26 Modelo.Modelo26 Model.Model27 Modelo.Modelo27 Model.Model28 Modelo.Modelo28 Model.Model29 Modelo.Modelo29 Model.Model30 Modelo.Modelo30 Model.Model31 Modelo.Modelo31 Model.Model32 Modelo.Modelo32 Model.Model33 Modelo.Modelo33 Model.Model34 Modelo.Modelo34 Model.Model35 Modelo.Modelo35 Model.Model36 Modelo.Modelo36 Model.Model37 Modelo.Modelo37 Model.Model38 Modelo.Modelo38 Model.Model39 Modelo.Modelo39 Model.Model40 Modelo.Modelo40 Help.HomePage Ayuda.PaginaDeInicio Help.BugReport Ayuda.ReportarErrores Help.Updates Ayuda.Actualizaciones Help.About Ayuda.AcercaDe Menu &New &Nuevo &Open... &Abrir... &Merge... &Fusionar... &Save &Guardar Save &As... Guardar c&omo... Save &Image... Guardar &imagen... 3D &Studio... 3D &Studio... &HTML... &HTML... &BrickLink... &BrickLink... &CSV... &CSV... &POV-Ray... &POV-Ray... &Wavefront... &Wavefront... Select by Col&or... Seleccionar por col&or... Single Selection Selección individual Piece Selection Selección por pieza Color Selection Selección por color Piece and Color Selection Selección por pieza y color Relative Transforms Transformaciones relativas Move Snap Enabled Ajustar traslaciones a rejilla Open Selected Model Abrir modelo seleccionado Edit Selected Submodel Editar submodelo seleccionado End Submodel Editing Finalizar edición de submodelo New Submodel... Nuevo submodelo... Prope&rties... Prop&iedades... &Print... Im&primir... &LEGO Digital Designer... &LEGO Digital Designer... Set &Inventory... Escoger &inventario... &COLLADA... &COLLADA... &Render... &Renderizar... &Instructions... &Instrucciones... Print Pre&view... Vista pre&via... Print &Bill of Materials... Imprimir &lista de materiales... &Recent1 &Reciente1 &Recent2 &Reciente2 &Recent3 &Reciente3 &Recent4 &Reciente4 E&xit &Salir &Undo Des&hacer &Redo &Rehacer Cu&t &Cortar &Copy Co&piar &Paste Pe&gar &Find... &Buscar... Find Ne&xt Buscar sig&uiente Find Pre&vious Buscar an&terior Find All Buscar todo &Replace &Reemplazar Replace Next Reemplazar siguiente Replace All Reemplazar todo Select &All Seleccionar &todo Select &None Deseleccionar to&do Select &Invert &Invertir selección Select by Na&me... Seleccionar por no&mbre... Absolute Transforms Transformaciones absolutas Toggle Relative Transforms Alternar transformaciones relativas Rotate Separately Rotar por separado Rotate Together Rotar juntas Toggle Separate Transforms Alternar transformaciones individuales None Ninguno 1/20 Stud 1/20 tetón 1/4 Stud 1/4 tetón 1 Flat 1 placa 1/2 Stud 1/2 tetón 1 Stud 1 tetón 2 Studs 2 tetones 3 Studs 3 tetones 4 Studs 4 tetones 8 Studs 8 tetones 1 Brick 1 bloque 2 Bricks 2 bloques 4 Bricks 4 bloques 8 Bricks 8 bloques Rotation Snap Enabled Ajustar rotaciones a rejilla 1 Degree 1 grado 5 Degrees 5 grados 15 Degrees 15 grados 22.5 Degrees 22.5 grados 30 Degrees 30 grados 45 Degrees 45 grados 60 Degrees 60 grados 90 Degrees 90 grados 180 Degrees 180 grados Transform Transformaciones Absolute Translation Traslación absoluta Relative Translation Traslación relativa Absolute Rotation Rotación absoluta Relative Rotation Rotación relativa Insert Insertar Light Luz Spotlight Foco Camera Cámara Select Seleccionar Move Mover Rotate Rotar Delete Borrar Paint Pintar Color Picker Selector de color Zoom Ampliar Pan Desplazar Rotate View Rotar vista Roll Pivotar vista Zoom Region Ampliar región Cancel Action Cancelar acción P&references... P&referencias... Zoom In Ampliar Zoom Out Reducir Zoom E&xtents &Ver todo Look At Ver modelo Move Forward Mover adelante Move Backward Mover atrás Move Left Mover a la izquierda Move Right Mover a la derecha Move Up Mover arriba Move Down Mover abajo &Front &Frente &Back &Detrás &Top En&cima B&ottom De&bajo &Left &Izquierda &Right &Derecha &Home &Inicio Camera 1 Cámara 1 Camera 2 Cámara 2 Camera 3 Cámara 3 Camera 4 Cámara 4 Camera 5 Cámara 5 Camera 6 Cámara 6 Camera 7 Cámara 7 Camera 8 Cámara 8 Camera 9 Cámara 9 Camera 10 Cámara 10 Camera 11 Cámara 11 Camera 12 Cámara 12 Camera 13 Cámara 13 Camera 14 Cámara 14 Camera 15 Cámara 15 Camera 16 Cámara 16 Reset Reiniciar First Primero Previous Anterior Next Siguiente Last Último Insert Before Insertar antes Insert After Insertar después Insert Step Insertar paso Remove Step Quitar paso Add Keys Añadir claves Split &Horizontal Dividir &horizontalmente Split &Vertical Dividir &verticalmente Re&move View Qui&tar vista Rese&t Views Reiniciar &vistas Standard Estándar Tools Herramientas Time Tiempo Parts Piezas Colors Colores Properties Propiedades Timeline Línea de tiempo Preview Vista previa &Full Screen &Pantalla completa Close &Tab Cerrar &pestaña &Wireframe &Malla &Flat Shading &Sombreado plano &Default Lights &Luces predeterminadas &Perspective &Perspectiva &Orthographic &Ortográfica View Sphere Ver esfera Axis Icon Icono de ejes Base Grid Cuadrícula base Fade Previous Steps Atenuar pasos anteriores &Insert &Insertar &Delete &Borrar &Duplicate &Duplicar &Paint Selected &Pintar selección Reset &Pivot Point Reiniciar &punto de pivote Remove &Key Frames Quitar &fotogramas clave Insert Control Point Insertar punto de control Remove Control Point Quitar punto de control Move +X Mover +X Move -X Mover -X Move +Y Mover +Y Move -Y Mover -Y Move +Z Mover +Z Move -Z Mover -Z Rotate +X Rotar +X Rotate -X Rotar -X Rotate +Y Rotar +Y Rotate -Y Rotar -Y Rotate +Z Rotar +Z Rotate -Z Rotar -Z Minifig &Wizard... &Asistente de Minifig... A&rray... &Secuencia... Move to New Model... Mover a modelo nuevo... Inline Selected Models Fusionar modelos seleccionados &Group... &Agrupar... &Ungroup &Desagrupar &Add to Group &Añadir a grupo Re&move from Group Qui&tar del grupo &Edit Groups... &Editar grupos... &Hide Selected &Ocultar seleccionadas Hide &Unselected Ocultar no &seleccionadas &Unhide Selected &Mostrar seleccionadas U&nhide All Mostrar &todas Show Earlier Mostrar en paso anterior Show Later Mostrar en paso siguiente Submodels... Submodelos... Model 1 Modelo 1 Model 2 Modelo 2 Model 3 Modelo 3 Model 4 Modelo 4 Model 5 Modelo 5 Model 6 Modelo 6 Model 7 Modelo 7 Model 8 Modelo 8 Model 9 Modelo 9 Model 10 Modelo 10 Model 11 Modelo 11 Model 12 Modelo 12 Model 13 Modelo 13 Model 14 Modelo 14 Model 15 Modelo 15 Model 16 Modelo 16 Model 17 Modelo 17 Model 18 Modelo 18 Model 19 Modelo 19 Model 20 Modelo 20 Model 21 Modelo 21 Model 22 Modelo 22 Model 23 Modelo 23 Model 24 Modelo 24 Model 25 Modelo 25 Model 26 Modelo 26 Model 27 Modelo 27 Model 28 Modelo 28 Model 29 Modelo 29 Model 30 Modelo 30 Model 31 Modelo 31 Model 32 Modelo 32 Model 33 Modelo 33 Model 34 Modelo 34 Model 35 Modelo 35 Model 36 Modelo 36 Model 37 Modelo 37 Model 38 Modelo 38 Model 39 Modelo 39 Model 40 Modelo 40 Report a Bug Reportar errores Insert Step Before Insertar paso antes Insert Step After Insertar paso después Move Selection Here Mover selección aquí Set Current Step Usar como paso actual LeoCAD &Home Page &Pagina principal de LeoCAD &Recent 1 &Reciente 1 &Recent 2 &Reciente 2 &Recent 3 &Reciente 3 &Recent 4 &Reciente 4 Paste with Steps Pegar con pasos &Find &Buscar Check for &Updates... &Comprobar actualizaciones... &About... &Acerca de... Mouse NewPiece NuevaPieza NewPointLight NuevoPuntoDeLuz NewSpotLight NuevoFoco NewCamera NuevaCamara Select Seleccionar Move Mover Rotate Rotar Delete Borrar Paint Pintar ColorPicker Selector de color Zoom Ampliación Pan Desplazar Orbit Orbitar Roll Pivotar la vista ZoomRegion Project Empty Name Nombre vacío Error Error Error reading file '%1': %2 Error leyendo archivo '%1': %2 Error loading file '%1': File format is not recognized. Error cargando archivo '%1': Formato de archivo no reconocido. Merged Fusionado LeoCAD LeoCAD Nothing to export. Nada que exportar. Export 3D Studio Exportar a 3D Studio 3DS Files (*.3ds);;All Files (*.*) Archivos 3DS (*.3ds);;Todos los archivos (*.*) Could not open file '%1' for writing. No se pudo abrir el archivo '%1' para escritura. Export BrickLink Exportar a BrickLink XML Files (*.xml);;All Files (*.*) Archivos XML (*.xml);;Todos los archivos (*.*) Export COLLADA Exportar COLLADA COLLADA Files (*.dae);;All Files (*.*) Archivos COLLADA (*.dae);;Todos los archivos (*.*) Export CSV Exportar a CSV CSV Files (*.csv);;All Files (*.*) Archivos CSV (*.csv);;Todos los archivos (*.*) Error creating images. Error creando imágenes. Export POV-Ray Exportar a POV-Ray POV-Ray Files (*.pov);;All Files (*.*) Archivos POV-Ray (*.pov);;Todos los archivos (*.*) Could not find LGEO files in folder '%1'. No se pudo encontrar los archivos LGEO en la carpeta '%1'. Export Wavefront Exportar a Wavefront Wavefront Files (*.obj);;All Files (*.*) Archivos Wavefront (*.obj);;Todos los archivos (*.*) Error writing to file '%1': %2 Error escribiendo el archivo '%1' : %2 New Model.ldr Nuevo modelo.ldr New Model.mpd Nuevo modelo.mpd Submodel # Submodelo # Submodel Name: Nombre de submodelo: The submodel name cannot be empty. El nombre del submodelo no puede estar vacío. Duplicate Submodel Duplicar submodelo A submodel named '%1' already exists, please enter a unique name. Ya existe un submodelo llamado '%1'. Por favor, utiliza otro nombre. New Submodel Nuevo submodelo QApplication Group # Grupo # Solid Colors Colors Colores sólidos Translucent Colors Colors Colores translúcidos Special Colors Colors Colores especiales Solid Colors Sólido Translucent Colors Translúcido Special Colors Especial QMessageBox Error Error Failed to load '%1'. Fallo al cargar '%1'. QObject LeoCAD LeoCAD Could not open file '%1' for writing. No se pudo abrir el archivo '%1' para escritura. Status Save a picture of the current view Guarda una imagen de la vista actual Export a list of parts used in BrickLink XML format Exporta una lista de las piezas usadas en formato XML de BrickLink Export a list of parts used in comma delimited file format Exporta una lista de las piezas usadas en formato delimitado por comas Print a list of parts used Imprime una lista de piezas usadas Undo the last action Deshacer la última acción Redo the previously undone action Rehacer la acción previamente deshecha Cut the selection and put it on the Clipboard Cortar la selección y ponerla en el portapapeles Copy the selection and put it on the Clipboard Copiar la selección y ponerla en el portapapeles Insert Clipboard contents Pegar el contenido del portapapeles Find object Buscar un objeto Find next object Buscar el siguiente objeto De-select everything Deseleccionar todo Invert the current selection set Invertir la selección actual Select objects by name Seleccionar objetos por nombre Toggle snap axes Alternar el ajuste a la rejilla para traslaciones Snap rotations to fixed intervals Ajustar rotaciones a intervalos fijos Do not snap movement along the XY plane No ajustar traslaciones en el plano XY Snap movement along the XY plane to 1/20 stud Ajustar 1/20 tetón las traslaciones en el plano XY Snap movement along the XY plane to 1/4 stud Ajustar 1/4 tetón las traslaciones en el plano XY Snap movement along the XY plane to 1 flat Ajustar 1 placa las traslaciones en el plano XY Snap movement along the XY plane to 1/2 stud Ajustar 1/2 tetón las traslaciones en el plano XY Snap movement along the XY plane to 1 stud Ajustar 1 tetón las traslaciones en el plano XY Snap movement along the XY plane to 2 studs Ajustar 2 tetones las traslaciones en el plano XY Snap movement along the XY plane to 3 studs Ajustar 3 tetones las traslaciones en el plano XY Snap movement along the XY plane to 4 studs Ajustar 4 tetones las traslaciones en el plano XY Snap movement along the XY plane to 8 studs Ajustar 8 tetones las traslaciones en el plano XY Do not snap movement along the Z axis No ajustar traslaciones en el eje Z Snap movement along the Z axis to 1/20 stud Ajustar 1/20 tetón las traslaciones en el eje Z Snap movement along the Z axis to 1/4 stud Ajustar 1/4 tetón las traslaciones en el eje Z Snap movement along the Z axis to 1 flat Ajustar 1 placa las traslaciones en el eje Z Snap movement along the Z axis to 1/2 stud Ajustar 1/2 tetón las traslaciones en el eje Z Snap movement along the Z axis to 1 stud Ajustar 1 tetón las traslaciones en el eje Z Snap movement along the Z axis to 1 brick Ajustar 1 bloque las traslaciones en el eje Z Snap movement along the Z axis to 2 bricks Ajustar 2 bloques las traslaciones en el eje Z Snap movement along the Z axis to 4 bricks Ajustar 4 bloques las traslaciones en el eje Z Snap movement along the Z axis to 8 bricks Ajustar 8 bloques las traslaciones en el eje Z Do not snap rotations No ajustar rotaciones Snap rotations to 1 degree Ajustar rotaciones a 1 grado Snap rotations to 5 degrees Ajustar rotaciones a 5 grados Create a new model Crear un nuevo modelo Open an existing model Abrir un modelo existente Merge the contents of another file with the current one Fusionar los contenidos de otro archivo con el actual Save the current model Guardar el modelo actual Save the current model with a new name Guardar el modelo actual con un nombre nuevo Import a file in LEGO Digital Designer LXF format Importar un archivo en formato LXF de LEGO-Digital Designer Import all parts from an official set Importar todas las piezas de un set oficial Export the current model in 3D Studio 3DS format Exportar el modelo actual en formato 3DS de 3D Studio Export the current model in COLLADA DAE format Exportar el modelo actual en formato DAE de COLLADA Create an HTML page for the current model Crear una página HTML con el modelo actual Export the current model in POV-Ray format Exportar el modelo actual en formato POV-Ray Export the current model in Wavefront OBJ format Exportar el modelo actual en formato OBJ de Wavefront Render the current model using POV-Ray Renderizar el modelo actual usando POV-Ray Print the current model Imprimir el modelo actual Display how the model would look if printed Mostrar cómo ser vería el modelo imprimido Open this model Abrir este modelo Quit the application; prompts to save model Salir del programa; notificación para guardar el modelo Select all pieces in the model Seleccionar todas las piezas del modelo Select pieces by color Seleccionar piezas por color Select one piece at a time Seleccionar piezas de una en una Select all pieces of the same type Seleccionar todas las piezas del mismo tipo Select all pieces of the same color Seleccionar todas las piezas del mismo color Select all pieces of the same type and color Seleccionar todas las piezas del mismo tipo y color Move and rotate objects relative to the one that has focus Mover y rotar objetos relativos al que tiene el foco Move and rotate objects in absolute coordinates Mover y rotar objetos en coordenadas absolutas Toggle moving and rotating objects relative to the one that has focus Alternar mover y rotar objetos relativos al que tiene el foco Rotate selected pieces separately Rotar cada pieza seleccionada individualmente Rotate selected pieces together Rotar piezas seleccionadas como si fueran una sola Toggle rotating selected pieces separately Cambiar rotar piezas seleccionadas separadamente Snap rotations to 15 degrees Ajustar rotaciones a 15 grados Snap rotations to 22.5 degrees Ajustar rotaciones a 22.5 grados Snap rotations to 30 degrees Ajustar rotaciones a 30 grados Snap rotations to 45 degrees Ajustar rotaciones a 45 grados Snap rotations to 60 degrees Ajustar rotaciones a 60 grados Snap rotations to 90 degrees Ajustar rotaciones a 90 grados Snap rotations to 180 degrees Ajustar rotaciones a 180 grados Apply transform to selected objects Aplicar transformaciones a los objetos seleccionados Switch to absolute translation mode when applying transforms Cambiar al modo de traslación absoluta cuando se apliquen transformaciones Switch to relative translation mode when applying transforms Cambiar al modo de traslación relativa cuando se apliquen transformaciones Switch to absolute rotation mode when applying transforms Cambiar al modo de rotación absoluta cuando se apliquen transformaciones Switch to relative rotation mode when applying transforms Cambiar al modo de rotación relativa cuando se apliquen transformaciones Add new pieces to the model Añadir nuevas piezas al modelo Add new omni light sources to the model Añadir nuevas fuentes de luz omnidireccional al modelo Add new spotlights to the model Añadir nuevos focos al modelo Create a new camera Crear una cámara nueva Select objects (hold the CTRL key down or drag the mouse to select multiple objects) Seleccionar objetos (mantener pulsado Ctrl o arrastrar el ratón para seleccionar múltiples objetos) Move selected objects Mover objetos seleccionados Rotate selected pieces Rotar piezas seleccionadas Delete objects Borrar objetos Change piece color Cambiar el color de una pieza Get piece color Obtener el color de una pieza Zoom in or out Ampliar o reducir Pan the current view Desplazar la vista actual Rotate the current view Rotar la vista actual Roll the current view Pivotar la vista actual Zoom into a region of the screen Ampliar una región de la pantalla Cancel current mouse action Cancelar la acción actual del ratón Change program settings Cambiar preferencias del programa Zoom in Ampliar Zoom out Reducir Fit all pieces in current the view (hold the CTRL key down to zoom all views) Encajar todas las piezas en la vista actual (mantener pulsado Ctrl para ampliar todas las vistas) Rotate view so selected pieces are at center Rotar vista para que las piezas seleccionadas estén centradas Move the current view forward Mover la vista actual hacia adelante Move the current view backward Mover la vista actual hacia atrás Move the current view to the left Mover la vista actual hacia la izquierda Move the current view to the right Mover la vista actual hacia la derecha Move the current view up Mover la vista actual hacia arriba Move the current view down Mover la vista actual hacia abajo View model from the front Ver el modelo de frente View model from the back Ver el modelo desde atrás View model from the top Ver el modelo desde arriba View model from the bottom Ver el modelo desde abajo View model from the left Ver el modelo desde la izquierda View model from the right Ver el modelo desde la derecha View model from the default position Ver el modelo desde la posición predeterminada Do not use a camera No usar ninguna cámara Use this camera Usar esta cámara Reset views to their default positions Reiniciar las vistas a sus posiciones predeterminadas Go to the first step of the model Ir al primer paso del modelo Go to the previous step Ir al anterior paso Go to the next step Ir al siguiente paso Go to the last step of the model Ir al último paso del modelo Insert new step Insertar nuevo paso Remove current step Quitar el paso actual Close current tab Cerrar la pestaña actual Remove the selected control point Quitar la selección del punto de control Open the model referenced by the selected piece in a new tab Abrir el modelo referenciado por la pieza seleccionada en la nueva pestaña Move the selected pieces to a new model and replace them with a reference to the model Mover las piezas seleccionadas a un nuevo modelo y reemplazarlas con una referencia al modelo Create a new submodel Crear un nuevo submodelo Display the properties of the current submodel Mostrar las propiedades del submodelo actual Show a list of all submodels Mostrar una lista de todos los submodelos Switch to this submodel Cambiar a este submodelo Open LeoCAD's bug report form on your default web browser Abrir la página de reporte de errores de LeoCAD en tu navegador predeterminado Move the selected parts into this step Mover las piezas seleccionadas a este paso View the model at this point in the timeline Ver el modelo actual en la línea de tiempo Toggle adding new animation keys Alternar añadir nuevas claves de animación Configure instructions layout Configurar diseño de instrucciones Insert Clipboard contents in the current step Insertar contenido del portapapeles en el paso actual Insert Clipboard contents in their original steps Insertar contenido del portapapeles en sus pasos originales Find piece Buscar pieza Find next piece Buscar siguiente pieza Find previous piece Buscar anterior pieza Find all pieces that match the search criteria Buscar todas las piezas que coincidan con el criterio de búsqueda Replace piece Reemplazar pieza Replace next piece Reemplazar siguiente pieza Replace all pieces that match the search criteria Reemplazar todas las piezas que coincidan con el criterio de búsqueda Insert a new step before the current step Insertar nuevo paso antes del paso actual Insert a new step after the current step Insertar nuevo paso después del paso actual Split the current view horizontally Dividir la vista actual horizontalmente Split the current view vertically Dividir la vista actual verticalmente Remove the current view Quitar la vista actual Reset all views Reiniciar todas las vistas Toggle the Standard Toolbar Alternar barra de herramientas estándar Toggle the Tools Toolbar Alternar barra de herramientas de utilidades Toggle the Time Toolbar Alternar barra de herramientas de tiempo Toggle the Parts Toolbar Alternar barra de herramientas de piezas Toggle the Colors Toolbar Alternar barra de herramientas de colores Toggle the Properties Toolbar Alternar barra de herramientas de propiedades Toggle the Timeline Toolbar Alternar barra de herramientas de línea de tiempo Toggle the Preview Toolbar Alternar barra de herramientas de vista previa Toggle fullscreen mode Alternar el modo pantalla completa Display the scene as wireframe Mostrar la escena como malla Display the scene without any shading or lights Mostrar la escena sin sombreados ni luces Display the scene with the default lights Mostrar la escena con las luces predeterminadas Set the current camera to use a perspective projection Asignar a la cámara actual la proyección de perspectiva Set the current camera to use an orthographic projection Asignar a la cámara actual la proyección ortográfica Toggle the view sphere Alternar la esfera de la vista Toggle axis icon Alternar icono de ejes Toggle grid Alternar cuadrícula Toggle fading previous model steps Alternar atenuar pasos previos Add a new piece to the model Añadir nueva pieza al modelo Delete selected objects Borrar objetos seleccionados Create a copy of the selected pieces Crear copia de las piezas seleccionadas Change the color of the selected pieces Cambiar color de las piezas seleccionadas Reset the pivot point of the selected pieces to their origin Reiniciar punto de pivote de las piezas seleccionadas a su origen Remove all key frames from the selected pieces Quitar todos los fotogramas clave de las piezas seleccionadas Insert a new control point Insertar un nuevo punto de control Move selected objects along the X axis Mover los objetos seleccionados a lo largo del eje X Move selected objects along the Y axis Mover los objetos seleccionados a lo largo del eje Y Move selected objects along the Z axis Mover los objetos seleccionados a lo largo del eje Z Rotate selected objects along the X axis Rotar los objetos seleccionados a lo largo del eje X Rotate selected objects along the Y axis Rotar los objetos seleccionados a lo largo del eje Y Rotate selected objects along the Z axis Rotar los objetos seleccionados a lo largo del eje Z Add a new minifig to the model Añadir un nuevo minifig al modelo Make copies of the selected pieces Hacer copias de las piezas seleccionadas Insert the contents of the selected model references into the current model Insertar los contenidos de las referencias del modelo seleccionado en modelo actual Edit the currently selected submodel in-place Editar el submodelo seleccionado actual in-situ End in-place submodel editing Finalizar la edición del submodelo in-situ Group selected pieces together Agrupar las piezas seleccionadas Ungroup selected group Desagrupar el grupo seleccionado Add focused piece to selected group Añadir la pieza enfocada al grupo seleccionado Remove focused piece from group Quitar la pieza enfocada del grupo Edit groups Editar grupos Hide selected objects Ocultar los objetos seleccionados Hide objects that are not selected Ocultar objetos que no han sido seleccionados Show hidden objects that are selected Mostrar los objetos ocultos que están seleccionados Show all hidden objects Mostrar todos los objetos ocultos Show selected pieces one step earlier Mover piezas seleccionadas un paso atrás Show selected pieces one step later Mover piezas seleccionadas un paso después Open LeoCAD's home page on the internet using your default web browser Abrir la página de LeoCAD en internet usando tu navegador predeterminado Check if a newer LeoCAD version or parts library has been released Comprobar si hay nuevas versiones de LeoCAD o de la biblioteca de piezas Display program version number and system information Mostrar versión del programa e información del sistema ViewName Left Izquierda Right Derecha Back Detrás Front Frente Top Arriba Bottom Debajo lcApplication LeoCAD LeoCAD LeoCAD could not find a compatible Parts Library so only a small number of parts will be available. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD no pudo encontrar ninguna biblioteca de piezas compatible por lo que solo un reducido número de piezas estará disponible. Por favor, visita https://www.leocad.org para saber cómo descargar e instalar una biblioteca. Not enough parameters for the '%1' option. No hay suficientes parámetros para la opción '%1'. Invalid parameter value specified for the '%1' option: '%2'. Especificado valor de parámetro inválido para la opción '%1' option: '%2'. The file '%1' is not readable. El archivo '%1' no se puede leer. Invalid parameter value(s) specified for the '%1' option: limits are +/- 360. Valores de parámetros inválidos especificados para la opción '%1': los límites son +/- 360 Invalid parameter value(s) specified for the '%1' option. Valores de parámetros inválidos especificados para la opción '%1'. Invalid parameter value(s) specified for the '%1' option: requirements are: 1 <= <near> < <far>. Valores de parámetros inválidos especificados para la opción '%1': se ha de cumplir: 1 <= <cerca> < <lejos>. High contrast stud style is required for the '%1' option but is not enabled. La opción '%1' necesita que esté activado el contraste alto para el estilo de tetón, pero no lo está. Automate edge color is required for the '%1' option but is not enabled. La opción '%1' necesita que esté activado el color de border automático, pero no lo está. LeoCAD Continuous Build %1 LeoCAD compilación continua %1 LeoCAD Version %1 LeoCAD versión %1 Compiled %1 Compilado %1 Usage: leocad [options] [file] Uso: leocad [opciones] [archivo] [options] can be: [opciones] puede ser: -l, --libpath <path>: Set the Parts Library location to path. -l, --libpath <ruta>: Establece la ubicación de la biblioteca de piezas a ruta. -i, --image <outfile.ext>: Save a picture in the format specified by ext and exit. -i, --image <outfile.ext>: Guarda una imagen en el formato especificado por ext y termina. -w, --width <width>: Set the picture width. -w, --width <ancho>: Establece la anchura de la imagen. -h, --height <height>: Set the picture height. -h, --height <altura>: Establece la altura de la imagen. -f, --from <step>: Set the first step to save pictures. -f, --from <paso>: Establece el primer paso para guardar imágenes. -t, --to <step>: Set the last step to save pictures. -t, --to <paso>: Establece el último paso para guardar imágenes. -s, --submodel <submodel>: Set the active submodel. -s, --submodel <submodelo>: Establece el submodelo activo. -c, --camera <camera>: Set the active camera. -c, --camera <cámara>: Establece la cámara activa. -ss, --stud-style <id>: Set the stud style 0=No style, 1=LDraw single wire, 2=LDraw double wire, 3=LDraw raised floating, 4=LDraw raised rounded, 5=LDraw subtle rounded, 6=LEGO no logo, 7=LEGO single wire. -ss, --stud-style <id>: Establece el estilo de tetón 0=plano, 1=trazo único de LDraw, 2=trazo doble de LDraw, 3=flotante elevado de LDraw, 4=redondo elevado de LDraw, 5=rondeado suavo de LDraw, 6=LEGO sin logo, 7=LEGO trazo único. --viewpoint <front|back|left|right|top|bottom|home>: Set the viewpoint. --viewpoint <front|back|left|right|top|bottom|home>: Establece la vista. --camera-angles <latitude> <longitude>: Set the camera angles in degrees around the model. --camera-angles <latitud> <longitud>: Establece los ángulos de cámara en grados alrededor del modelo. --camera-position <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector. --camera-position <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Establece la posición de la cámara, el objetivo y el vector vertical. --camera-position-ldraw <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector using LDraw coordinates. --camera-position-ldraw <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Establece la posición de la cámara, el objetivo y el vector vertical usando coordenadas de LDraw. --orthographic: Render images using an orthographic projection. --orthographic: Renderiza imágenes usando una proyección ortogonal. --fov <degrees>: Set the vertical field of view used to render images (< 180). --fov <grados>: Establece el campo de visión vertical usado para renderizar imágenes (< 180). --zplanes <near> <far>: Set the near and far clipping planes used to render images (1 <= <near> < <far>). --zplanes <cerca> <lejos>: Establece los planos de recorte cercanos y lejanos usados para renderizar imágenes (1 <= <cerca> < <lejos>). --fade-steps: Render parts from prior steps faded. --fade-steps: Renderiza piezas de pasos anteriores atenuadas. --no-fade-steps: Do not render parts from prior steps faded. --no-fade-steps: No renderiza piezas de partes anteriores atenuadas. --fade-steps-color <rgba>: Renderinng color for prior step parts (#AARRGGBB). --fade-steps-color <rgba>: Color de renderizado para piezas de pasos anteriores (#AARRGGBB). --highlight: Highlight parts in the steps they appear. --highlight: Resalta piezas en los pasos en los que aparecen. --no-highlight: Do not highlight parts in the steps they appear. --no-highlight: No resalta piezas en los pasos en los que aparecen. --highlight-color: Renderinng color for highlighted parts (#AARRGGBB). --highlight-color: Color de renderizado para piezas resaltadas (#AARRGGBB). --shading <wireframe|flat|default|full>: Select shading mode for rendering. --shading <wireframe|flat|default|full>: Seleccionar modo de sombreado para renderizaciones. --line-width <width>: Set the width of the edge lines. --line-width <width>: Establece el grosor de los bordes. --aa-samples <count>: AntiAliasing sample size (1, 2, 4, or 8). --aa-samples <cantidad>: Tamaño de muestreo de anti-aliasing (1, 2, 4 u 8). -scc, --stud-cylinder-color <#AARRGGBB>: High contrast stud cylinder color. -scc, --stud-cylinder-color <#AARRGGBB>: Color del tetón cilíndrico en alto contraste. -ec, --edge-color <#AARRGGBB>: High contrast edge color. -ec, --edge-color <#AARRGGBB>: Color del borde en alto contraste. -bec, --black-edge-color <#AARRGGBB>: High contrast edge color for black parts. -bec, --black-edge-color <#AARRGGBB>: Color del borde para piezas negras en algo contraste. -dec, --dark-edge-color <#AARRGGBB>: High contrast edge color for dark color parts. -dec, --dark-edge-color <#AARRGGBB>: Color de borde para piezas oscuras en alto contraste. -aec, --automate-edge-color: Enable automatically adjusted edge colors. -aec, --automate-edge-color: Habilitar ajuste automático de colores de borde. -cc, --color-contrast <float>: Color contrast value between 0.0 and 1.0. -cc, --color-contrast <decimal>: El color de contraste ha de estar comprendido entre 0.0 y 1.0. -ldv, --light-dark-value <float>: Light/Dark color value between 0.0 and 1.0. -ldv, --light-dark-value <decimal>: El color claro/oscuro ha de estar comprendido entre 0.0 y 1.0. -obj, --export-wavefront <outfile.obj>: Export the model to Wavefront OBJ format. -obj, --export-wavefront <outfile.obj>: Exporta el modelo al formato OBJ de Wavefront. -3ds, --export-3ds <outfile.3ds>: Export the model to 3D Studio 3DS format. -3ds, --export-3ds <outfile.3ds>: Exporta el modelo al formato 3ds de 3D Studio. -dae, --export-collada <outfile.dae>: Export the model to COLLADA DAE format. -dae, --export-collada <outfile.dae>: Exporta el modelo al formato DAE de COLLADA. -html, --export-html <folder>: Create an HTML page for the model. -html, --export-html <carpeta>: Crea una página HTML para el modelo. -v, --version: Output version information and exit. -v, --version: Muestra información sobre la versión y termina. -?, --help: Display this help message and exit. -?, --help: Muestra este mensaje de ayuda y termina. Unknown option: '%1'. Opción desconocida: '%1'. High contrast stud and edge color settings are ignored when -aec or --automate-edge-color is set. Las opciones de tetón en alto contraste y color de borde se ignoran cuando se especifica -aec o --automate-edge-color. --viewpoint is ignored when --camera is set. --viewpoint se ignora cuando se especifica --camera. --orthographic is ignored when --camera is set. --orthographic se ignora cuando se especifica --camera. --camera-angles is ignored when --camera is set. --camera-angles se ignora cuando se especifica --camera. --camera-position is ignored when --camera is set. --camera-position se ignora cuando se especifica --camera. --camera-angles is ignored when --viewpoint is set. --camera-angles se ignora cuando se especifica --viewpoint. --camera-position is ignored when --viewpoint is set. --camera-position se ignora cuando se especifica --viewpoint. --camera-position is ignored when --camera-angles is set. --camera-position se ignora cuando se especifica --camera-angles. No file name specified. Nombre de archivo no especificado. Error creating OpenGL context. Error creando contexto OpenGL. LeoCAD could not load Parts Library. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD no pudo cargar la biblioteca de piezas. Por favor, visita https://www.leocad.org para saber cómo descargar e instalar una biblioteca. Error: model '%1' does not exist. Error: el modelo '%1' no existe. Saved '%1'. '%1' guardado. Some changes will only take effect the next time you start LeoCAD. Algunos cambios no tendrán efecto hasta que reinicies LeoCAD. Parts library and Anti-aliasing changes will only take effect the next time you start LeoCAD. Los cambios en la biblioteca de piezas y anti-aliasing no tendrán efecto hasta que reinicies LeoCAD. Parts library changes will only take effect the next time you start LeoCAD. Los cambios en las biblioteca de piezas no tendrán efecto hasta que reinicies LeoCAD. Anti-aliasing changes will only take effect the next time you start LeoCAD. Los cambios de anti-aliasing no tendrán efecto hasta que reinicies LeoCAD. lcAutomateEdgeColorDialog Color Preferences Preferencias de color Edge Colors Color de bordes Contrast: Contraste: Set the amount of contrast - 0.50 is midway. Establece la cantidad de contraste - 0.50 es la mitad. Reset Reiniciar Light/Dark Value: Valor claro/oscuro: Saturation: Saturación: Set to classify where color values are light or dark - e.g. Dark Bluish Gray (72) is light at 0.39. Establecer cuándo un color es claro u oscuro, por ejemplo, gris azulado oscuro (72) es claro a 0.39. Set to specify amount of edge color tint or shade from the saturation adjusted part color Establecer la candidad de tinte o matiz de color de borde a partir de la saturación ajustada del color de la pieza. High Contrast Alto contraste Stud Cylinder Color: Color de tetón cilíndrico: Parts Edge Color: Color de borde para piezas: Black Parts Edge Color: Color de borde para piezas negras: Dark Parts Edge Color: Color de borde para piezas oscuras: Select Stud Cylinder Color Seleccionar color para tetón cilíndrico Select Part Edge Color Seleccionar color para borde de pieza Automate edge color appears to be enabled.<br>Black parts edge color will not be accessible.<br>Do you want to continue? El color de borde automático está habilitado.<br>El color de borde de las piezas negras no será accesible.<br>¿Quieres continuar? Select Black Edge Color Seleccionar color para bordes negros Automate edge color appears to be enabled.<br>Dark parts edge color will not be accessible.<br>Do you want to continue? El color de borde automático está habilitado.<br>El color de borde de las piezas oscuras no será accesible.<br>¿Quieres continuar? Select Dark Edge Color Seleccionar color para bordes oscuros lcFindReplaceWidget Find: Buscar: Replace: Reemplazar: lcInstructions Show Step Number Mostrar número del paso Show Parts List Mostrar lista de piezas Font: Fuente: Text Color: Color de texto: Background Color: Color de fondo: Border Color: Color de borde: lcInstructionsDialog Instructions Instrucciones Page Settings Preferencias de página Print Imprimir Vertical Vertical Horizontal Horizontal Page %1 Página %1 lcInstructionsPageListWidget Pages Páginas Page Setup Configuración de página lcInstructionsPropertiesWidget Properties Propiedades Default Predeterminado Current Model Modelo actual Current Step Only Solo paso actual Current Step Forward Paso siguiente Scope: Ãmbito: Preset: Ajustes prestablecidos: Select Step Number Color Seleccionar color para el número del paso Select Step Background Color Seleccionar color de fondo para los pasos Select Parts List Background Color Seleccionar color de fondo para la lista de piezas Select Parts List Border Color Seleccionar color de borde para la lista de piezas Select Parts List Text Color Seleccionar color de texto para la lista de piezas Select Step Number Font Seleccionar fuente para el número de paso Select Parts List Font Seleccionar fuente para la lista de piezas Step Properties Propiedades de pasos Step Number Properties Propiedades de números de pasos Parts List Properties Propiedades de la lista de piezas lcMainWindow Transform Transformación C&ameras Cá&maras &File &Archivo &Export &Exportar &Edit &Editar &View &Ver &Viewpoints &Puntos de vista Projection Proyección Ste&p Pa&so T&oolbars Barras de &herramientas &Piece &Pieza &Help &Ayuda Transform Options Opciones de transformación Snap XY Rejilla XY Snap Z Rejilla Z Snap Menu Menu de ajuste Movement Snap Ajustar traslaciones Snap translations to fixed intervals Ajustar traslaciones a intervalos fijos Snap Angle Menu Menú de ángulos de ajuste Rotation Snap Ajustar rotaciones Snap rotations to fixed intervals Ajustar rotaciones a intervalos fijos Standard Estándar Tools Herramientas New Model Nuevo modelo Open Model Abrir modelo Save Model Guardar modelo Sh&ading S&ombreado &Import &Importar Sub&model Sub&modelo Selection Mode Modo de selección Change selection mode Cambiar modo de selección Time Tiempo Parts Piezas Colors Colores Properties Propiedades Timeline Línea de tiempo Part preview for '%1' failed. Falló la previsualización de la pieza '%1'. Preview Vista previa Close Other Tabs Cerrar otras pestañas Reset Views Reiniciar vistas The file '%1' has been modified by another application, do you want to reload it? El archivo '%1' ha sido modificado por otro programa. ¿Quieres volver a cargarlo? File Changed Archivo cambiado %1 (ID: %2) %1 (ID: %2) %n Object(s) selected %n objeto seleccionado %n objetos seleccionados Rel Rel Abs Abs M: %1 %2 R: %3 %4 M: %1 %2 R: %3 %4 Merge Model Fusionar modelo Merged 1 submodel. Fusionado 1 submodelo. Merged %1 submodels. Fusionados %1 submodelos. Import Importar LEGO Diginal Designer Files (*.lxf);;All Files (*.*) Archivos LEGO Diginal Designer (*.lxf);;Todos los archivos (*.*) - %1 (ID: %2) - %1 (ID: %2) in group '%1' dentro del grupo '%1' Step %1 Paso %1 M: %1 %2 R: %3 M: %1 %2 R: %3 &Undo %1 &Deshacer %1 &Undo Des&hacer &Redo %1 &Rehacer %1 &Redo &Rehacer Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*) Archivos soportados (*.lcd *.ldr *.dat *.mpd);;Todos los archivos (*.*) LeoCAD LeoCAD Error loading '%1'. Error cargando '%1'. Supported Files (*.mpd);;All Files (*.*) Archivos soportados (*.mpd);;Todos los archivos (*.*) Supported Files (*.ldr *.dat *.mpd);;All Files (*.*) Archivos soportados (*.ldr *.dat *.mpd);;Todos los archivos (*.*) Error Error Saving files in LCD format is no longer supported, please use the LDR or MPD formats instead. Guardar archivos en formato LCD ya no está soportado, Por favor, utiliza los formatos LDR o MPD en su lugar. Save changes to '%1'? ¿Guardar los cambios en '%1'? 0 0 1/20S 1/20T 1/4S 1/4T 1F 1P 1/2S 1/2T 1S 1T 2S 2T 3S 3T 4S 4T 8S 8T None Ninguno 1B 1B 2B 2B 4B 4B 8B 8B lcMinifigDialog Minifig Wizard Asistente de Minifig Templates Plantillas Save... Guardar... Delete... Borrar... Import... Importar... Export... Exportar... Save Template Guardar plantilla Template Name: Nombre de plantilla: Template name cannot be empty. El nombre de plantilla no puede estar vacío. Are you sure you want to overwrite the template '%1'? ¿Seguro que quieres sobreescribir la plantilla '%1'? Overwrite Template Sobreescribir plantilla Are you sure you want to delete the template '%1'? ¿Seguro que quieres borrar la plantilla '%1'? Delete Template Borrar plantilla Import Templates Importar plantillas Minifig Template Files (*.minifig);;All Files (*.*) Archivos de plantillas de Minifig (*.minifig);;Todos los archivos(*.*) Error Error Error reading file '%1': %2 Error leyendo el archivo '%1': %2 Export Templates Exportar plantillas Error writing to file '%1': %2 Error escribiendo el archivo '%1': %2 lcModel Pasting pegado LeoCAD LeoCAD Error creating images. Error creando imágenes. Inserting Step inserción de paso Removing Step eliminación de paso No pieces selected. Ninguna pieza seleccionada. Group # Grupo # Cutting cortado Duplicating Pieces duplicación de piezas Error Error Error writing to file '%1': %2 Error escribiendo el archivo '%1': %2 Grouping agrupación Ungrouping desagrupación Editing Groups edición de grupos Adding Piece adición de pieza Resetting Cameras reiniciado de cámaras Removing Key Frames eliminación de fotogramas clave Modifying modificación New Model nuevo modelo Inlining fusión Moving movimiento Rotating rotación Scaling escalado Setting Part cambio de pieza Hide ocultación Unhide mostrado Replacing Part reemplazo de pieza New SpotLight nuevo foco New Camera nueva cámara Move movimiento Rotate rotación Zoom ampliación Pan desplazamiento Orbit órbita Roll pivotaje Insert inserción New Light nueva luz Deleting borrado Painting pintado No models selected. Ningún modelo seleccionado. Showing Pieces mostrado de piezas Hiding Pieces ocultación de piezas Editing Camera edición de cámara Changing FOV cambio de campo de visión Renaming Camera renombrado de cámara Look At mirar al modelo Moving Camera movimiento de cámara Changing Properties cambio de propiedades Nothing to select. Nada que seleccionar. Array only has 1 element or less, no pieces added. La secuencia solo tiene un elemento o menos, ninguna pieza añadida. Array secuencia Minifig # Minifig # Minifig Minifig lcPageSetupDialog Page Setup Configuración de página Size Tamaño Width: Ancho: Height: Alto: Preset: Ajustes predefinidos: Units: Unidades: Margins Márgenes Left: Izquierda: Right: Derecha: Top: Superior: Bottom: Inferior: lcPartPaletteDialog Part Palettes Paletas de piezas New... Nueva... Delete... Borrar... Rename... Renombrar... Import... Importar... Move Up Mover arriba Move Down Mover abajo New Part Palette Nueva paleta de piezas Palette Name: Nombre de paleta: Are you sure you want to delete the palette '%1'? ¿Seguro que quieres borrar la paleta '%1'? Delete Part Palette Borrar paleta de piezas Rename Part Palette Renombrar paleta de piezas lcPartSelectionListView No Icons Sin Iconos Small Icons Iconos pequeños Medium Icons Iconos medianos Large Icons Iconos grandes Extra Large Icons Iconos extra grandes Show Part Names Mostrar nombre de piezas Show Decorated Parts Mostrar piezas decoradas List Mode Modo lista Lock Preview Color Bloquear color Add to Palette Añadir a paleta None Ninguno Remove from Palette Quitar de paleta lcPartSelectionWidget Search Parts Buscar piezas Options Opciones Edit Palettes... Editar paletas... No Icons Sin iconos Small Icons Iconos pequeños Medium Icons Iconos medianos Large Icons Iconos grandes Extra Large Icons Iconos extra grandes Show Part Names Mostrar nombre de pieza Show Decorated Parts Mostrar piezas decoradas Show Part Aliases Mostrar apodos de piezas List Mode Modo lista Lock Preview Color Bloquear color Favorites Favoritos All Parts Todas las piezas In Use En uso Parts In Use Piezas usadas Submodels Submodelos lcPiecesLibrary Initializing Inicializando Loading Parts Library Cargando biblioteca de piezas lcPreviewDockWidget Lock Preview Bloquear previsualización Ctrl+L Ctrl+L Toolbar Barra de herramientas Preview Toolbar Barra de herramientas de vista previa Loading... Cargando... Unlock the preview display to enable updates Desbloquear previsualización para permitir actualizaciones Lock the preview display to disable updates Bloquear previsualización para impedir actualizaciones Unlock Preview Desbloquear previsualización Unlock Desbloquear Lock Bloquear %1 the preview display to %2 updates %1 la visualización previa en %2 actualizaciones %1 Preview %1 previsualización lcQAboutDialog About LeoCAD Acerca de LeoCAD LeoCAD Version 0.00.0 LeoCAD Version 0.00.0 LeoCAD is a free application for creating virtual LEGO models. LeoCAD es un programa libre para crear modelos virtuales de LEGO. System Information Información del Sistema LeoCAD Version %1 LeoCAD versión %1 Qt version %1 (compiled with %2) QT versión %1 (compilado con %2) OpenGL Version %1 (GLSL %2) %3 - %4 OpenGL versión %1 (GLSL %2) %3 - %4 Color Buffer: %1 bits %2 %3 Depth Buffer: %4 bits Stencil Buffer: %5 bits Memoria intermedia de color: %1 bits %2 %3 Memoria intermedia de profundidad: %4 bits Memoria intermedia de éstencil: %5 bits indexed indexado double buffered Memoria intermedia doble GL_ARB_vertex_buffer_object extension: %1 GL_ARB_framebuffer_object extension: %2 GL_EXT_framebuffer_object extension: %3 GL_EXT_blend_func_separate: %4 GL_EXT_texture_filter_anisotropic extension: %5 GL_ARB_vertex_buffer_object extension: %1 GL_ARB_framebuffer_object extension: %2 GL_EXT_framebuffer_object extension: %3 GL_EXT_blend_func_separate: %4 GL_EXT_texture_filter_anisotropic extension: %5 LeoCAD Continuous Build %1 LeoCAD compilación continua %1 Qt Version %1 (compiled with %2) QT versión %1 (compilado con %2) Color Buffer: %1 bits Depth Buffer: %2 bits Stencil Buffer: %3 bits Color Búfer: %1 bits Depth Búfer: %2 bits Stencil Búfer: %3 bits Buffers: %1 Shaders: %2 Framebuffers: %3 BlendFuncSeparate: %4 Anisotropic: %5 Búfers: %1 Sombreados: %2 Framebufers: %3 BlendFuncSeparate: %4 Anisotropic: %5 Supported Soportado Not supported No soportado Supported (max %1) Soportado (máximo %1) lcQArrayDialog Array Secuencia Dimensions Dimensiones Offsets Desplazamientos Rotations Rotaciones Array is empty. La secuencia está vacía. lcQCategoryDialog Category Categoría Name: Nombre: Keywords: Palabras clave: Edit Category Editar categoría New Category Nueva categoría Name cannot be empty. El nombre no puede estar vacío. Keywords cannot be empty. El palabras clave no puede estar vacío. lcQEditGroupsDialog Edit Groups Editar grupos New Group Nuevo grupo Group # Grupo # lcQFindDialog Find Buscar Name Nombre Part ID ID de pieza Color Color lcQGroupDialog Group Grupo Name Nombre Name cannot be empty. El nombre no puede estar vacío. lcQHTMLDialog HTML Options Opciones HTML General General Output folder: Carpeta de salida: ... ... Transparent image background Fondo de imagen transparente Width: Ancho: Height: Alto: Index page Página índice Models Modelos All Models Todos los modelos Current Model and Submodels Modelo actual y submodelos Current Model Only Solo el modelo actual Steps Pasos Single Page Página individual One Step per Page Un paso por página Highlight new parts Resaltar nuevas piezas Parts List Lista de piezas At the end Al final After each step Tras cada paso Color: Color: Create images Crear imágenes Output folder cannot be empty. La carpeta de salida no puede estar vacía. Select Output Folder Seleccionar carpeta de salida lcQImageDialog Save Image Guardar imagen File name: Nombre de archivo: Dimensions Dimensiones Step Range Intervalo de pasos All Steps Todos los pasos Current Step Paso actual Custom Range Intervalo personalizado From: Desde: To: Hasta: Width: Ancho: Height: Alto: ... ... Output File cannot be empty. El archivo de salida no puede estar vacío. Error Error First step must be between 1 and %1. El primer paso debe estar entre 1 y %1. Last step must be between 1 and %1. El último paso debe estar entre 1 y %1. Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) Archivos de imágenes soportados (*.bmp *.png *.jpg);;Archivos BMP (*.bmp);;Archivos PNG (*.png);;Archivos JPEG (*.jpg);;Todos los archivos (*.*) Last step must be greater than first step. El último paso debe ser mayor que el primero. Please enter a width between 1 and 32768. Por favor, introduce un ancho entre 1 y 32768. Please enter a height between 1 and 32768. Por favor, introduce un alto entre 1 y 32768. Save Image File Guardar imagen lcQMinifigDialog Minifig Wizard Asistente de Minifig Templates Plantillas Save... Guardar... Delete... Borrar... Save Template Guardar plantilla Template Name: Nombre de plantilla: Template name cannot be empty. La plantilla no puede estar vacía. Are you sure you want to overwrite the template '%1'? ¿Seguro que quieres sobreescribir la plantilla '%1'? Overwrite Template Sobreescribir Plantilla Are you sure you want to delete the template '%1'? ¿Seguro que quieres borrar la plantilla '%1'? Delete Template Borrar plantilla lcQModelListDialog Submodels Submodelos &New... &Nuevo... D&elete... Bo&rrar... &Rename... &Renombrar... Export... Exportar... Duplicate... Duplicar... Move &Up Mover arr&iba Move &Down Mover aba&jo Set Active Definir activo New Submodel Nuevo submodelo Error Error The model cannot be empty. El modelo no puede estar vacío. Are you sure you want to delete the submodel '%1'? ¿Seguro que quieres borrar el submodelo '%1'? Delete Submodel Borrar submodelo No submodel selected. No hay ningún submodelo seleccionado. Are you sure you want to delete %1 submodels? ¿Seguro que quieres borrar %1 submodelos? Rename Submodel Renombrar submodelo Export Submodel Exportar submodelo LeoCAD LeoCAD Nothing to export. Nada que exportar. Export Model Exportar modelo Select Export Folder Seleccionar Carpeta de Exportación Duplicate Submodel Duplicar submodelo Copy of Copia de Save Model Guardar modelo Supported Files (*.ldr *.dat);;All Files (*.*) Archivos soportados (*.ldr *.dat);;Todos los archivos (*.*) lcQPreferencesDialog Preferences Preferencias General General Application Aplicación Language: Idioma: Check for updates: Buscar actualizaciones: Default Sistema Czech Czech Deutsch Deutsch English English Français Français Português Português Español Español Never Nunca Once a day Una vez al día Once a week Una vez por semana Default author name: Nombre de autor predeterminado: Fixed direction keys Teclas de dirección fijas Open most recent file on startup Abrir archivo más reciente al inicio Custom paths Rutas personalizadas Parts Library: Biblioteca de piezas: Color Configuration: Configuración de color: ... ... Minifig Settings: Preferencias de Minifig: PO&V-Ray Executable: Ejecutable de PO&V-Ray: &LGEO Library: Biblioteca &LGEO: Restore tab layout Restaurar configuración de pestañas Rendering Renderizado Axis icon Icono de ejes Highlight new parts Resaltar piezas nuevas Fade previous steps Atenuar pasos previos Base Grid Cuadrícula base Draw studs Dibujar tetones studs tetones Draw lines every Dibujar líneas cada View Sphere Esfera Mesh LOD Nivel de detalle de malla Mouse Ratón Mouse Shortcuts Atajos de ratón Action Acción Shortcut 1 Atajo 1 Shortcut 2 Atajo 2 Button: Botón: None Ninguno Left Izquierdo Middle Central Right Derecho Modifiers: Modificadores: Control Control Alt Alt Shift Mayúsculas Mouse sensitivity: Sensibilidad del ratón: Edge lines Bordes width ancho Anti-aliasing Anti-aliasing Stud Logo Logo de tetón Logo1 Logo1 Logo2 Logo2 Logo3 Logo3 Logo4 Logo4 Logo5 Logo5 2x 2x 4x 4x 8x 8x Shading Mode: Modo de sombreado: Wireframe Malla Flat Shading Sombreado plano Default Lights Luces predeterminadas Disabled Desactivada Small Pequeña Medium Mediana Large Grande Highlight Color: Color de resalte: Size: Tamaño: Color: Color: Text Color: Color de texto: Location: Posición: Deutsch Deutsch Color Theme: Color del tema: Dark Oscuro System Sistema Custom Paths Rutas personalizadas Stud Style Estilo de tetón Plain Plano Thin Lines Logo Logo de líneas finas Outline Logo Contorno del logo Sharp Top Logo Logo en relieve Rounded Top Logo Logo en relieve redondo Flattened Logo Logo aplanado High Contrast Alto contraste High Contrast with Logo Alto contraste con logo Settings... Preferencias... Automate edge color Color de bordes automático Contrast Settings... Preferencias de contraste... Views Vistas Model Views Vistas de modelo Axis Icon Icono de ejes View Sphere: Ver esfera: Top Left Arriba izquierda Top Right Arriba derecha Bottom Left Abajo izquierda Bottom Right Abajo derecha Draw origin lines Dibujar líneas de origen Part Preview Vista previa de piezas Colors Colores Background Fondo Top Color: Color superior: Bottom Color: Color inferior: So&lid Color Color só&lido &Gradient &Gradiente Interface Interfaz Inactive View Border: Borde de vista inactiva: Overlay Color: Color de superposiciones: Active View Border: Borde de vista activa: Camera Name: Nombre de cámara: Axis Icon Labels: Etiquetas de icono de ejes: Marquee Border: Borde del área de selección: Highlight New Parts Resaltar piezas nuevas Fade Previous Steps Atenuar pasos previos Lines Líneas Conditional Lines Líneas condicionales Line Width: Grosor de bordes: Edge Lines Dibujar bordes Automate Edge Color Color de bordes automático Marquee Fill: Relleno del área de selección: Grid Cuadrícula Lines: Líneas: Studs: Tetones: Objects Objetos Light: Luz: Focused: Resaltado: Control Point Focused: Punto de control resaltado: Control Point: Punto de control: Selected: Seleccionado: Camera: Cámara: Categories Categorías Parts Library Categories Categorías de la biblioteca de piezas Name Nombre Number Número Import... Importar... Export... Exportar... Reset... Reiniciar... Category Categoría New... Nueva... Edit... Editar... Delete... Borrar... Keyboard Teclado Keyboard Shortcuts Atajos de teclado Command Comando Shortcut Atajo Search shortcuts Buscar atajos Key se&quence: Combina&ción de teclas: Assign Asignar Remove Quitar Grid spacing must be greater than 0. El espaciado de la cuadrícula base debe ser mayor que 0. Select Parts Library Folder Seleccionar carpeta de la biblioteca de piezas Supported Archives (*.zip *.bin);;All Files (*.*) Archivos soportados (*.zip *.bin);;Todos los archivos (*.*) Select Parts Library Archive Seleccionar archivo de la biblioteca de piezas Select Color Configuration File Seleccionar archivo de configuración de color Settings Files (*.ldr);;All Files (*.*) Archivos de preferencias (*.ldr);;Todos los archivos (*.*) Select Minifig Settings File Seleccionar archivos de preferencias de Minifig Settings Files (*.ini);;All Files (*.*) Archivos de preferencias (*.ini);;Todos los archivos (*.*) Executable Files (*.exe);;All Files (*.*) Archivos ejecutables (*.exe);;Todos los archivos (*.*) All Files (*.*) Todos los archivos (*.*) Open POV-Ray Executable Abrir ejecutable de POV-Ray Open LGEO Folder Abrir la carpeta de LGEO Reset Colors Reiniciar colores Would you like to also reset the interface colors to match the color theme? ¿Te gustaría además reiniciar los colores de la interfaz para que coincidan con los del tema? Select Background Color Seleccionar color de fondo Select Gradient Top Color Seleccionar color superior del gradiente Select Gradient Bottom Color Seleccionar color inferior del gradiente Select Axes Color Seleccionar color de ejes Select Text Color Seleccionar color de texto Select Marquee Border Color Seleccionar color del borde del área de selección Select Marquee Fill Color Seleccionar color de relleno del área de selección Select Overlay Color Seleccionar color de superposiciones Select Active View Color Seleccionar color de vista activa Select Inactive View Color Seleccionar color de vista inactiva Select Fade Color Seleccionar color de atenuación Select Highlight Color Seleccionar color de resalte Select Grid Stud Color Seleccionar color de los tetones de la cuadrícula Select Grid Line Color Seleccionar color de las líneas de la cuadrícula Select View Sphere Color Seleccionar color de la esfera en las vistas Select View Sphere Text Color Seleccionar color del texto de la esfera en las vistas Select View Sphere Highlight Color Seleccionar color de resalte de la esfera de la vista Select Object Selected Color Seleccionar color de objeto seleccionado Select Object Focused Color Seleccionar color de objeto enfocado Select Camera Color Seleccionar color de cámara Select Light Color Seleccionar color de luz Select Control Point Color Seleccionar color de punto de control Select Control Point Focused Color Seleccionar color de punto de control enfocado Unassigned Sin asignar Are you sure you want to delete the category '%1'? ¿Seguro que quieres borrar la categoría '%1' ? Import Categories Importar categorías Text Files (*.txt);;All Files (*.*) Archivos de texto (*.txt);;Todos los archivos (*.*) Error loading categories file. Error cargando el archivo de categorías. Export Categories Exportar categorías Error saving categories file. Error guardando el archivo de categorías. Are you sure you want to load the default categories? ¿Seguro que quieres cargar las categorías predeterminadas? The shortcut '%1' is already assigned to '%2'. Do you want to replace it? El atajo '%1' ya está asignado a '%2'. ¿Quieres reemplazarlo? Import shortcuts Importar atajos Error loading keyboard shortcuts file. Error cargando el archivo de atajos de teclado. Export shortcuts Exportar atajos Error saving keyboard shortcuts file. Error guardando el archivo de atajos de teclado. Are you sure you want to load the default keyboard shortcuts? ¿Seguro que quieres cargar los atajos de teclado predeterminados? Left Button Botón izquierdo Middle Button Botón central Right Button Botón derecho Override Shortcut Sobrescribir atajo Select POV-Ray Executable Seleccionar ejecutable de POV-Ray This shortcut is already assigned to '%1', do you want to replace it? Este atajo ya está asignado a '%1'. ¿Quieres reemplazarlo? Import Shortcuts Importar atajos Error loading mouse shortcuts file. Error cargando el archivo de atajos de ratón. Export Shortcuts Exportar atajos Error saving mouse shortcuts file. Error guardando el archivo de atajos del ratón. Are you sure you want to load the default mouse shortcuts? ¿Seguro que quieres cargar los atajos de ratón predeterminados? lcQPropertiesDialog Properties Propiedades Summary Resumen Author: Autor: Description: Descripción: Comments: Comentarios: Measurements: Medidas: Scene Escena Background Fondo So&lid Color Color só&lido &Gradient &Gradiente Image Imagen ... ... Tile Mosaico Set default options for new projects Establecer opciones predeterminadas para nuevos proyectos Parts Used Piezas usadas %1 Properties Propiedades de %1 %1 x %2 x %3 cm %4 x %5 x %6 inches %7 x %8 x %9 LDU %1 x %2 x %3 cm %4 x %5 x %6 pulgadas %7 x %8 x %9 LDU Part Pieza Total Total Select Background Color Seleccionar color de fondo Select Background Top Color Seleccionar color superior de fondo Select Background Bottom Color Seleccionar color inferior de fondo Select Background Image Seleccionar imagen de fondo All Image Files (*.png *.jpg *.gif *.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;GIF Files (*.gif);;BMP Files (*.bmp);;All Files (*.*) Todos los archivos de imagen (*.png *.jpg *.gif *.bmp);;Archivos PNG (*.png);;Archivos JPEG (*.jpg);;Archivos GIF (*.gif);;Archivos BMP (*.bmp);;Todos los archivos (*.*) lcQPropertiesTree Property Propiedad Value Valor Position Posición X X Y Y Z Z Rotation Rotación Visibility Visibilidad Visible Steps Pasos visibles Show Mostrar en Hide Ocultar en Appearance Apariencia Color Color Part Pieza Target Objetivo Up Arriba Orthographic Ortográfica FOV Campo de visión Near Cerca Far Lejos Name Nombre Multiple Objects Selected Múltiples objetos seleccionados lcQSelectDialog Select Objects Seleccionar objetos All Todos None Ninguno Invert Invertir lcQUpdateDialog LeoCAD Updates Actualizaciones de LeoCAD Connecting to update server... Conectando con el servidor de actualizaciones... <p>There's a newer version of LeoCAD available for download (%1.%2.%3).</p> <p>Hay una nueva versión de LeoCAD disponible para descargar (%1.%2.%3).</p> <p>You are using the latest LeoCAD version.</p> <p>Estás utilizando la última versión de LeoCAD.</p> <p>There are new parts available.</p> <p>No hay nuevas piezas disponibles.</p> <p>There are no new parts available at this time.</p> <p>No hay nuevas piezas disponibles en este momento.</p> <p>Visit <a href="https://github.com/leozide/leocad/releases">https://github.com/leozide/leocad/releases</a> to download.</p> <p>Visita <a href="https://github.com/leozide/leocad/releases">https://github.com/leozide/leocad/releases</a> para descargar.</p> Error parsing update information. Error parseando la información de la actualización. Error connecting to the update server. Error conectando al servidor de actualizaciones. lcRenderDialog Render Renderizar Settings Preferencias Width: Ancho: Height: Alto: High Alta Medium Media Low Baja Quality: Calidad: Output: Salida: ... ... Cancel Render Cancelar renderizado Are you sure you want to cancel the current render? ¿Seguro que quieres cancelar el renderizado actual? Cancel Cancelar Error Error Error starting POV-Ray. Error al iniciar POV-Ray. An error occurred while rendering. Check details or try again. Ha ocurrido un error en el renderizado. Comprueba los detalles o inténtalo de nuevo. Error writing to file '%1': %2 Error escribiendo el archivo '%1': %2 Error writing to %1 file '%2': %3 Error escribiendo en %1 el archivo '%2': %3 Select Output File Seleccionar archivo de salida Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) Archivos de imágenes soportados (*.bmp *.png *.jpg);;Archivos BMP (*.bmp);;Archivos PNG (*.png);;Archivos JPEG (*.jpg);;Todos los archivos (*.*) lcSelectByColorDialog Select By Color Seleccionar por color Color: Color: lcSetsDatabaseDialog Sets Database Base de datos de piezas Set Name or Number Asignar nombre o número Search Buscar Number Número Name Nombre Year Año Parts Piezas Sets Database provided by <a href="https://www.rebrickable.com">Rebrickable</a> Base de datos de piezas proporcionada por <a href="https://www.rebrickable.com">Rebrickable</a> Please select a set from the list. Por favor, selecciona un base de datos de la lista. Downloading Descargando Downloading set inventory Descargando inventario de base de datos Keyword cannot be empty. La palabra clave no puede estar vacía. Searching Buscando Connecting to server Conectando al servidor Error connecting to server. Error conectando al servidor. Error downloading set inventory. Error descargando el inventario de base de datos. lcTimelineWidget Step %1 Paso %1 lcView LeoCAD LeoCAD Error creating images. Error creando imagenes. Error Error Error writing to file '%1': %2 Error escribiendo el archivo '%1': %2 leocad-23.03/resources/leocad_fr.ts000066400000000000000000011766531440571307300172770ustar00rootroot00000000000000 Action File.New File.Open File.Merge File.Save File.SaveAs File.SaveImage File.Import.LDD File.Import.Inventory File.Export.3DS File.Export.COLLADA File.Export.HTML File.Export.BrickLink File.Export.CSV File.Export.POVRay File.Export.Wavefront File.Render File.Instructions File.Print File.PrintPreview File.Recent1 File.Recent2 File.Recent3 File.Recent4 File.Exit Edit.Undo Edit.Redo Edit.Cut Edit.Copy Edit.Paste Edit.PasteSteps Edit.Find Edit.FindNext Edit.FindPrevious Edit.FindAll Edit.Replace Edit.ReplaceNext Edit.ReplaceAll Edit.SelectAll Edit.SelectNone Edit.SelectInvert Edit.SelectByName Edit.SelectSingle Edit.SelectPiece Edit.SelectColor Edit.SelectPieceColor Edit.TransformRelative Edit.TransformAbsolute Edit.TransformToggleRelative Edit.TransformSeparately Edit.TransformTogether Edit.TransformToggleSeparate Edit.Snap.Toggle Edit.SnapMove.XY0 Edit.SnapMove.XY1 Edit.SnapMove.XY2 Edit.SnapMove.XY3 Edit.SnapMove.XY4 Edit.SnapMove.XY5 Edit.SnapMove.XY6 Edit.SnapMove.XY7 Edit.SnapMove.XY8 Edit.SnapMove.XY9 Edit.SnapMove.Z0 Edit.SnapMove.Z1 Edit.SnapMove.Z2 Edit.SnapMove.Z3 Edit.SnapMove.Z4 Edit.SnapMove.Z5 Edit.SnapMove.Z6 Edit.SnapMove.Z7 Edit.SnapMove.Z8 Edit.SnapMove.Z9 Edit.SnapAngle.Toggle Edit.SnapAngle.Angle0 Edit.SnapAngle.Angle1 Edit.SnapAngle.Angle2 Edit.SnapAngle.Angle3 Edit.SnapAngle.Angle4 Edit.SnapAngle.Angle5 Edit.SnapAngle.Angle6 Edit.SnapAngle.Angle7 Edit.SnapAngle.Angle8 Edit.SnapAngle.Angle9 Edit.Transform Edit.TransformAbsoluteTranslation Edit.TransformRelativeTranslation Edit.TransformAbsoluteRotation Edit.TransformRelativeRotation Edit.Tool.Insert Edit.Tool.Light Edit.Tool.Spotlight Edit.Tool.Camera Edit.Tool.Select Edit.Tool.Move Edit.Tool.Rotate Edit.Tool.Delete Edit.Tool.Paint Edit.Tool.ColorPicker Edit.Tool.Zoom Edit.Tool.Pan Edit.Tool.RotateView Edit.Tool.Roll Edit.Tool.ZoomRegion Edit.Cancel View.Preferences View.ZoomIn View.ZoomOut View.ZoomExtents View.LookAt View.MoveForward View.MoveBackward View.MoveLeft View.MoveRight View.MoveUp View.MoveDown View.Viewpoint.Front View.Viewpoint.Back View.Viewpoint.Top View.Viewpoint.Bottom View.Viewpoint.Left View.Viewpoint.Right View.Viewpoint.Home View.Cameras.None View.Cameras.Camera01 View.Cameras.Camera02 View.Cameras.Camera03 View.Cameras.Camera04 View.Cameras.Camera05 View.Cameras.Camera06 View.Cameras.Camera07 View.Cameras.Camera08 View.Cameras.Camera09 View.Cameras.Camera10 View.Cameras.Camera11 View.Cameras.Camera12 View.Cameras.Camera13 View.Cameras.Camera14 View.Cameras.Camera15 View.Cameras.Camera16 View.Time.First View.Time.Previous View.Time.Next View.Time.Last View.Time.InsertBefore View.Time.InsertAfter View.Time.Delete View.Time.AddKeys View.SplitHorizontal View.SplitVertical View.RemoveView View.ResetViews View.Toolbars.Standard View.Toolbars.Tools View.Toolbars.Time View.Toolbars.Parts View.Toolbars.Colors View.Toolbars.Properties View.Toolbars.Timeline View.Toolbars.Preview View.FullScreen View.CloseCurrentTab View.Shade.Wireframe View.Shade.Flat View.Shade.DefaultLights View.Projection.Perspective View.Projection.Orthographic View.ToggleViewSphere View.ToggleAxisIcon View.ToggleGrid View.FadePreviousSteps Piece.Insert Piece.Delete Piece.Duplicate Piece.PaintSelected Piece.ResetPivotPoint Piece.RemoveKeyFrames Piece.ControlPoint.Insert Piece.ControlPoint.Remove Piece.Move.PlusX Piece.Move.MinusX Piece.Move.PlusY Piece.Move.MinusY Piece.Move.PlusZ Piece.Move.MinusZ Piece.Rotate.PlusX Piece.Rotate.MinusX Piece.Rotate.PlusY Piece.Rotate.MinusY Piece.Rotate.PlusZ Piece.Rotate.MinusZ Piece.MinifigWizard Piece.Array Piece.ViewSelectedModel Piece.MoveSelectionToModel Piece.InlineSelectedModels Piece.EditSelectedSubmodel Piece.EditEndSubmodel Piece.Group Piece.Ungroup Piece.GroupAdd Piece.GroupRemove Piece.GroupEdit Piece.HideSelected Piece.HideUnselected Piece.UnhideSelected Piece.UnhideAll Piece.ShowEarlier Piece.ShowLater Model.New Model.Properties Model.List Model.Model01 Model.Model02 Model.Model03 Model.Model04 Model.Model05 Model.Model06 Model.Model07 Model.Model08 Model.Model09 Model.Model10 Model.Model11 Model.Model12 Model.Model13 Model.Model14 Model.Model15 Model.Model16 Model.Model17 Model.Model18 Model.Model19 Model.Model20 Model.Model21 Model.Model22 Model.Model23 Model.Model24 Model.Model25 Model.Model26 Model.Model27 Model.Model28 Model.Model29 Model.Model30 Model.Model31 Model.Model32 Model.Model33 Model.Model34 Model.Model35 Model.Model36 Model.Model37 Model.Model38 Model.Model39 Model.Model40 Help.HomePage Help.BugReport Help.Updates Help.About Menu &New &Nouveau &Open... &Ouvrir... &Merge... &Fusionner... &Save Enregi&strer Save &As... Enregistrer s&ous... Save &Image... Enregistrer l’&image... 3D &Studio... 3D &Studio… &HTML... &HTML… &BrickLink... &BrickLink… &CSV... &CSV… &POV-Ray... &POV-Ray… &Wavefront... &Wavefront… Single Selection Piece Selection Color Selection Piece and Color Selection Relative Transforms Transformations relatives Move Snap Enabled Pas pour les déplacements activé Insert Before Insert After Open Selected Model Edit Selected Submodel End Submodel Editing New Submodel... Prope&rties... Prop&riétés… &Print... Im&primer... &LEGO Digital Designer... Set &Inventory... &COLLADA... &Render... &Instructions... Print Pre&view... Ape&rçu d'impression... Print &Bill of Materials... Imprimer &liste de fournitures… &Recent1 &Récent1 &Recent2 &Récent2 &Recent3 &Récent3 &Recent4 &Récent4 E&xit &Quitter &Undo Ann&uler &Redo &Refaire Cu&t &Couper &Copy Co&pier &Paste Co&ller &Find... &Rechercher... Find Ne&xt Rechercher le suiva&nt Find Pre&vious Rechercher le pré&cédent Find All &Replace Replace Next Replace All Select &All Sélectionner &tout Select &None Sélectionner &aucun Select &Invert &Inverser la sélection Select by Na&me... Sélection par no&m… Absolute Transforms Toggle Relative Transforms Rotate Separately Rotate Together Toggle Separate Transforms None Aucun 1/20 Stud 1/20 tenon 1/4 Stud 1/4 tenon 1 Flat 1 plaque 1/2 Stud 1/2 tenon 1 Stud 1 tenon 2 Studs 2 tenons 3 Studs 3 tenons 4 Studs 4 tenons 8 Studs 8 tenons 1 Brick 1 brique 2 Bricks 2 briques 4 Bricks 4 briques 8 Bricks 8 briques Rotation Snap Enabled Pas pour les rotations activé 1 Degree 1 degré 5 Degrees 5 degrés 15 Degrees 15 degrés 22.5 Degrees 180 degrés {22.5 ?} 30 Degrees 30 degrés 45 Degrees 45 degrés 60 Degrees 60 degrés 90 Degrees 90 degrés 180 Degrees 180 degrés Transform Transformation Absolute Translation Translation absolue Relative Translation Translation relative Absolute Rotation Rotation absolue Relative Rotation Rotation relative Insert Insérer Light Lumière Spotlight Lumière projecteur Camera Caméra Select Sélectionner Move Déplacer Rotate Tourner Delete Effacer Paint Peindre Color Picker Zoom Zoomer Pan Glisser Rotate View Tourner la vue Roll Pivoter la vue Zoom Region Zoomer sur la région Cancel Action Annuler l’action P&references... P&références… Zoom In Zoomer Zoom Out Dézoomer Zoom E&xtents &Voir tout Look At Viser le modèle Move Forward Move Backward Move Left Move Right Move Up Move Down &Front &Face &Back &Dos &Top De&ssus B&ottom Dess&ous &Left &Gauche &Right &Droite &Home &Trois-quarts Camera 1 Camera 2 Camera 3 Camera 4 Camera 5 Camera 6 Camera 7 Camera 8 Camera 9 Camera 10 Camera 11 Camera 12 Camera 13 Camera 14 Camera 15 Camera 16 Reset Réinitialiser First Premier Previous Précédent Next Suivant Last Dernier Remove Step Add Keys Ajouter des clés Split &Horizontal Scinder &horizontalement Split &Vertical Scinder &verticalement Re&move View Suppri&mer la vue Rese&t Views Réinitialiser &toutes les vues Standard Standard Tools Outils Time Temps Parts Pièces Colors Properties Propriétés Timeline Ligne temporelle Preview &Full Screen &Plein écran Close &Tab &Wireframe &Flat Shading &Default Lights &Perspective &Perspective &Orthographic &Orthographique View Sphere Axis Icon Base Grid Grille de base Fade Previous Steps &Insert &Insérer &Delete &Supprimer &Duplicate &Paint Selected Reset &Pivot Point Réinitialiser le &point pivot Remove &Key Frames Insert Control Point Insérer un point de contrôle Remove Control Point Enlever le point de contrôle Move +X Déplacer +X Move -X Déplacer -X Move +Y Déplacer +Y Move -Y Déplacer -Y Move +Z Déplacer +Z Move -Z Déplacer -Z Rotate +X Tourner +X Rotate -X Tourner -X Rotate +Y Tourner +Y Rotate -Y Tourner -Y Rotate +Z Tourner +Z Rotate -Z Tourner -Z Minifig &Wizard... &Assistant de minifig… A&rray... &Arrangement… Move to New Model... Déplacer vers un nouveau modèle… Inline Selected Models Fusionner les modèles sélectionnés &Group... &Grouper... &Ungroup &Dégrouper &Add to Group &Ajouter au groupe Re&move from Group En&lever du groupe &Edit Groups... &Éditer les groupes… &Hide Selected &Cache la sélection Hide &Unselected Cacher l’&anti-sélection &Unhide Selected &Décacher la sélection U&nhide All Décacher &tout Show Earlier Montrer plus tôt Show Later Montrer plus tard Submodels... Model 1 Model 2 Model 3 Model 4 Model 5 Model 6 Model 7 Model 8 Model 9 Model 10 Model 11 Model 12 Model 13 Model 14 Model 15 Model 16 Model 17 Model 18 Model 19 Model 20 Model 21 Model 22 Model 23 Model 24 Model 25 Model 26 Model 27 Model 28 Model 29 Model 30 Model 31 Model 32 Model 33 Model 34 Model 35 Model 36 Model 37 Model 38 Model 39 Model 40 Report a Bug Insert Step Before Insert Step After Move Selection Here Set Current Step LeoCAD &Home Page &Page d’accueil de LeoCAD &Recent 1 &Recent 2 &Recent 3 &Recent 4 Paste with Steps &Find Check for &Updates... Vérifier les &mises à jour… &About... &À propos... Mouse NewPiece NewPointLight NewSpotLight NewCamera Select Sélectionner Move Déplacer Rotate Tourner Delete Effacer Paint Peindre ColorPicker Zoom Zoomer Pan Glisser Orbit Orbiter Roll ZoomRegion Project Empty Name Nom vide Error Erreur Error reading file '%1': %2 Error loading file '%1': File format is not recognized. Merged Fusionné LeoCAD LeoCAD Nothing to export. Rien à exporter. Export 3D Studio Exporter vers 3D Studio 3DS Files (*.3ds);;All Files (*.*) Fichiers 3DS (*.3ds);;Tous les fichiers (*.*) Could not open file '%1' for writing. N’a pas pu ouvrir le fichier « %1 » en écriture. Export BrickLink Exporter vers BrickLink XML Files (*.xml);;All Files (*.*) Fichiers XML (*.xml);;Tous les fichiers (*.*) Export COLLADA COLLADA Files (*.dae);;All Files (*.*) Export CSV Exporter vers CSV CSV Files (*.csv);;All Files (*.*) Fichiers CSV (*.csv);;Tous les fichiers (*.*) Error creating images. Erreur à la création des images. Export POV-Ray POV-Ray Files (*.pov);;All Files (*.*) Fichiers POV-Ray (*.pov);;Tous les fichiers (*.*) Could not find LGEO files in folder '%1'. N’a pas pu trouver les fichiers LGEO dans le dossier « %1 ». Export Wavefront Exporter vers Wavefront Wavefront Files (*.obj);;All Files (*.*) Fichiers Wavefront (*.obj);;Tous les fichiers (*.*) Error writing to file '%1': %2 Erreur en écrivant le fichier « %1 » : %2 New Model.ldr New Model.mpd Submodel # Submodel Name: The submodel name cannot be empty. Duplicate Submodel A submodel named '%1' already exists, please enter a unique name. New Submodel QApplication Group # Group n° Solid Colors Colors Couleurs pleines Translucent Colors Colors Couleurs transparentes Special Colors Colors Couleurs spéciales Solid Colors Translucent Colors Special Colors QMessageBox Error Erreur QObject LeoCAD LeoCAD Could not open file '%1' for writing. N’a pas pu ouvrir le fichier « %1 » en écriture. Status Save a picture of the current view Enregistrer une image de la vue courante Export a list of parts used in BrickLink XML format Exporter une liste des pièces utilisées dans le format XML de BrickLink Export a list of parts used in comma delimited file format Exporter une liste des pièces utilisées dans un fichier texte avec champs séparés par des virgules Print a list of parts used Imprimer une liste des pièces utilisées Undo the last action Annuler la dernière action Redo the previously undone action Refaire l’action précédemment annulée Cut the selection and put it on the Clipboard Couper la sélection et la placer dans le presse-papier Copy the selection and put it on the Clipboard Copier la sélection et la placer dans le presse-papier Insert Clipboard contents Insérer le contenu de presse-papier Find object Trouver un objet Find next object Trouver l’objet suivant De-select everything Vider la sélection Invert the current selection set Inverser la sélection courante Select objects by name Sélectionner des objets par leur nom Toggle snap axes Basculer l’usage de pas pour les déplacements Snap rotations to fixed intervals Utiliser le pas pour les rotations Do not snap movement along the XY plane Ne pas utiliser les pas pour les déplacements sur le plan XY Snap movement along the XY plane to 1/20 stud Fixer le pas pour les déplacements dans le plan XY à 1/20 de tenon Snap movement along the XY plane to 1/4 stud Fixer le pas pour les déplacements dans le plan XY à 1/4 de tenon Snap movement along the XY plane to 1 flat Fixer le pas pour les déplacements dans le plan XY à 1 plaque Snap movement along the XY plane to 1/2 stud Fixer le pas pour les déplacements dans le plan XY à 1/2 tenon Snap movement along the XY plane to 1 stud Fixer le pas pour les déplacements dans le plan XY à 1 tenon Snap movement along the XY plane to 2 studs Fixer le pas pour les déplacements dans le plan XY à 2 tenons Snap movement along the XY plane to 3 studs Fixer le pas pour les déplacements dans le plan XY à 3 tenons Snap movement along the XY plane to 4 studs Fixer le pas pour les déplacements dans le plan XY à 4 tenons Snap movement along the XY plane to 8 studs Fixer le pas pour les déplacements dans le plan XY à 8 tenons Do not snap movement along the Z axis Ne pas fixer les déplacements sur l’axe Z Snap movement along the Z axis to 1/20 stud Fixer le pas pour les déplacements dans l’axe Z à 1/20 de tenon Snap movement along the Z axis to 1/4 stud Fixer le pas pour les déplacements dans l’axe Z à 1/4 de tenon Snap movement along the Z axis to 1 flat Fixer le pas pour les déplacements dans l’axe Z à 1 plaque Snap movement along the Z axis to 1/2 stud Fixer le pas pour les déplacements dans l’axe Z à 1/2 tenon Snap movement along the Z axis to 1 stud Fixer le pas pour les déplacements dans l’axe Z à 1 tenon Snap movement along the Z axis to 1 brick Fixer le pas pour les déplacements dans l’axe Z à 1 brique Snap movement along the Z axis to 2 bricks Fixer le pas pour les déplacements dans l’axe Z à 2 briques Snap movement along the Z axis to 4 bricks Fixer le pas pour les déplacements dans l’axe Z à 4 briques Snap movement along the Z axis to 8 bricks Fixer le pas pour les déplacements dans l’axe Z à 8 briques Do not snap rotations Ne pas utiliser de pas pour les rotations Snap rotations to 1 degree Fixer le pas de rotation à 1 degré Snap rotations to 5 degrees Fixer le pas de rotation à 5 degrés Create a new model Open an existing model Merge the contents of another file with the current one Save the current model Save the current model with a new name Import a file in LEGO Digital Designer LXF format Import all parts from an official set Export the current model in 3D Studio 3DS format Export the current model in COLLADA DAE format Create an HTML page for the current model Export the current model in POV-Ray format Export the current model in Wavefront OBJ format Render the current model using POV-Ray Print the current model Display how the model would look if printed Open this model Quit the application; prompts to save model Select all pieces in the model Select one piece at a time Select all pieces of the same type Select all pieces of the same color Select all pieces of the same type and color Move and rotate objects relative to the one that has focus Move and rotate objects in absolute coordinates Toggle moving and rotating objects relative to the one that has focus Rotate selected pieces separately Rotate selected pieces together Toggle rotating selected pieces separately Snap rotations to 15 degrees Fixer le pas de rotation à 15 degrés Snap rotations to 22.5 degrees Fixer le pas de rotation à 180 degrés {22.5 ?} Snap rotations to 30 degrees Fixer le pas de rotation à 30 degrés Snap rotations to 45 degrees Fixer le pas de rotation à 45 degrés Snap rotations to 60 degrees Fixer le pas de rotation à 60 degrés Snap rotations to 90 degrees Fixer le pas de rotation à 90 degrés Snap rotations to 180 degrees Fixer le pas de rotation à 180 degrés Apply transform to selected objects Appliquer la transformation aux objets sélectionnés Switch to absolute translation mode when applying transforms Basculer vers le mode translation absolue pour appliquer les transformations Switch to relative translation mode when applying transforms Basculer vers le mode translation relative pour appliquer les transformations Switch to absolute rotation mode when applying transforms Basculer vers le mode rotation absolue pour appliquer les transformations Switch to relative rotation mode when applying transforms Basculer vers le mode rotation relative pour appliquer les transformations Add new pieces to the model Ajouter des nouvelles pièces au modèle Add new omni light sources to the model Ajouter des sources de lumière omnidirectionnelles au modèle Add new spotlights to the model Ajouter des lumières projecteur au modèle Create a new camera Créer une nouvelle caméra Select objects (hold the CTRL key down or drag the mouse to select multiple objects) Sélection des objets (maintenir la touche Ctrl enfoncée ou glisser la souris pour sélectionner plusieurs objets) Move selected objects Déplacer les objets sélectionnés Rotate selected pieces Tourner les pièces sélectionnées Delete objects Supprimer des objets Change piece color Changer la couleur d’une pièce Get piece color Zoom in or out Zoomer ou dézoomer Pan the current view Glisser la vue courante Rotate the current view Tourner la vue courante Roll the current view Pivoter la vue courante Zoom into a region of the screen Zoomer une région de l’écran Cancel current mouse action Annuler l’action courante de la souris Change program settings Changer la configuration du programme Zoom in Zoomer Zoom out Dézoomer Fit all pieces in current the view (hold the CTRL key down to zoom all views) Zoomer pour voir toutes les pièces dans la vue courante (maintenir la touche Ctrl enfoncée pour zoomer toutes les vues) Rotate view so selected pieces are at center Tourner la vue pour que les pièces sélectionnées soient au centre Move the current view forward Move the current view backward Move the current view to the left Move the current view to the right Move the current view up Move the current view down View model from the front Voir le modèle de face View model from the back Voir le modèle de dos View model from the top Voir le modèle du dessus View model from the bottom Voir le modèle du dessous View model from the left Voir le modèle de la gauche View model from the right Voir le modèle de la droite View model from the default position Voir le modèle depuis la position par défaut Do not use a camera Ne pas utiler de caméra Use this camera Utiliser cette caméra Reset views to their default positions Réinitialiser les vues à leur position par défaut Go to the first step of the model Aller à la première étape du modèle Go to the previous step Aller à l’étape précédente Go to the next step Aller à l’étape suivante Go to the last step of the model Aller à la dernière étape du modèle Insert new step Insérer une nouvelle étape Remove current step Close current tab Remove the selected control point Open the model referenced by the selected piece in a new tab Move the selected pieces to a new model and replace them with a reference to the model Create a new submodel Display the properties of the current submodel Show a list of all submodels Switch to this submodel Open LeoCAD's bug report form on your default web browser Move the selected parts into this step View the model at this point in the timeline Toggle adding new animation keys Basculer l’ajout de nouvelles clés d’animation Configure instructions layout Insert Clipboard contents in the current step Insert Clipboard contents in their original steps Find piece Find next piece Find previous piece Find all pieces that match the search criteria Replace piece Replace next piece Replace all pieces that match the search criteria Insert a new step before the current step Insert a new step after the current step Split the current view horizontally Scinder la vue courante horizontalement Split the current view vertically Scinder la vue courante verticalement Remove the current view Supprimer la vue courante Reset all views Réinitialiser toutes les vues Toggle the Standard Toolbar Toggle the Tools Toolbar Toggle the Time Toolbar Toggle the Parts Toolbar Toggle the Colors Toolbar Toggle the Properties Toolbar Toggle the Timeline Toolbar Toggle the Preview Toolbar Toggle fullscreen mode Basculer en mode plein-écran/fenêtre Display the scene as wireframe Display the scene without any shading or lights Display the scene with the default lights Set the current camera to use a perspective projection Utiliser une projection perspective pour la caméra courante Set the current camera to use an orthographic projection Utiliser une projection orthographique pour la caméra courante Toggle the view sphere Toggle axis icon Toggle grid Toggle fading previous model steps Add a new piece to the model Ajouter une nouvelle pièce au modèle Delete selected objects Supprimer les objets sélectionnés Create a copy of the selected pieces Change the color of the selected pieces Reset the pivot point of the selected pieces to their origin Réinitialiser le point de pivot des pièces sélectionnées à leur origine Remove all key frames from the selected pieces Insert a new control point Insérer un nouveau point de contrôle Move selected objects along the X axis Déplacer les objets sélectionnés sur l’axe X Move selected objects along the Y axis Déplacer les objets sélectionnés sur l’axe Y Move selected objects along the Z axis Déplacer les objets sélectionnés sur l’axe Z Rotate selected objects along the X axis Tourner les objets sélections suivant l’axe X Rotate selected objects along the Y axis Tourner les objets sélections suivant l’axe Y Rotate selected objects along the Z axis Tourner les objets sélections suivant l’axe Z Add a new minifig to the model Ajouter une nouvelle minifig au modèle Make copies of the selected pieces Faire des copies des pièces sélectionnées Insert the contents of the selected model references into the current model Insérer le contenu des modèles sélectionnés dans le modèle courant Edit the currently selected submodel in-place End in-place submodel editing Group selected pieces together Grouper les pièces sélectionnées Ungroup selected group Dégrouper le groupe sélectionné Add focused piece to selected group Ajouter la pièce qui a le focus au groupe sélectionné Remove focused piece from group Enlever du groupe la pièce qui a le focus Edit groups Éditer les groupes Hide selected objects Cacher les objets sélectionnés Hide objects that are not selected Cacher les objets qui ne sont pas sélectionnés Show hidden objects that are selected Montrer les objets cachés qui sont sélectionnés Show all hidden objects Montrer les objets cachés Show selected pieces one step earlier Montrer les pièces sélectionnées une étape plus tôt Show selected pieces one step later Montrer les pièces sélectionnées une étape plus tard Open LeoCAD's home page on the internet using your default web browser Ouvrir la page d’accueil de LeoCAD avec votre navigateur web par défaut Check if a newer LeoCAD version or parts library has been released Vérifier si une nouvelle version de LeoCAD ou de la bibliothèque de pièces est disponible Display program version number and system information Voir la version du programme et des informations sur le système ViewName Left Gauche Right Droit Back Front Top Bottom lcApplication LeoCAD LeoCAD LeoCAD could not find a compatible Parts Library so only a small number of parts will be available. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD n’a pas pu trouver une bibliothèque de pièces compatible donc seulement un petit nombre de pièces seront disponibles. SVP visitez https://www.leocad.org pour apprendre comment télécharger et installer une bibliothèque. Not enough parameters for the '%1' option. Invalid parameter value specified for the '%1' option: '%2'. The file '%1' is not readable. Invalid parameter value(s) specified for the '%1' option: limits are +/- 360. Invalid parameter value(s) specified for the '%1' option. Invalid parameter value(s) specified for the '%1' option: requirements are: 1 <= <near> < <far>. High contrast stud style is required for the '%1' option but is not enabled. Automate edge color is required for the '%1' option but is not enabled. LeoCAD Continuous Build %1 LeoCAD Version %1 LeoCAD Version %1 Compiled %1 Usage: leocad [options] [file] [options] can be: -l, --libpath <path>: Set the Parts Library location to path. -i, --image <outfile.ext>: Save a picture in the format specified by ext and exit. -w, --width <width>: Set the picture width. -h, --height <height>: Set the picture height. -f, --from <step>: Set the first step to save pictures. -t, --to <step>: Set the last step to save pictures. -s, --submodel <submodel>: Set the active submodel. -c, --camera <camera>: Set the active camera. -ss, --stud-style <id>: Set the stud style 0=No style, 1=LDraw single wire, 2=LDraw double wire, 3=LDraw raised floating, 4=LDraw raised rounded, 5=LDraw subtle rounded, 6=LEGO no logo, 7=LEGO single wire. --viewpoint <front|back|left|right|top|bottom|home>: Set the viewpoint. --camera-angles <latitude> <longitude>: Set the camera angles in degrees around the model. --camera-position <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector. --camera-position-ldraw <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector using LDraw coordinates. --orthographic: Render images using an orthographic projection. --fov <degrees>: Set the vertical field of view used to render images (< 180). --zplanes <near> <far>: Set the near and far clipping planes used to render images (1 <= <near> < <far>). --fade-steps: Render parts from prior steps faded. --no-fade-steps: Do not render parts from prior steps faded. --fade-steps-color <rgba>: Renderinng color for prior step parts (#AARRGGBB). --highlight: Highlight parts in the steps they appear. --no-highlight: Do not highlight parts in the steps they appear. --highlight-color: Renderinng color for highlighted parts (#AARRGGBB). --shading <wireframe|flat|default|full>: Select shading mode for rendering. --line-width <width>: Set the width of the edge lines. --aa-samples <count>: AntiAliasing sample size (1, 2, 4, or 8). -scc, --stud-cylinder-color <#AARRGGBB>: High contrast stud cylinder color. -ec, --edge-color <#AARRGGBB>: High contrast edge color. -bec, --black-edge-color <#AARRGGBB>: High contrast edge color for black parts. -dec, --dark-edge-color <#AARRGGBB>: High contrast edge color for dark color parts. -aec, --automate-edge-color: Enable automatically adjusted edge colors. -cc, --color-contrast <float>: Color contrast value between 0.0 and 1.0. -ldv, --light-dark-value <float>: Light/Dark color value between 0.0 and 1.0. -obj, --export-wavefront <outfile.obj>: Export the model to Wavefront OBJ format. -3ds, --export-3ds <outfile.3ds>: Export the model to 3D Studio 3DS format. -dae, --export-collada <outfile.dae>: Export the model to COLLADA DAE format. -html, --export-html <folder>: Create an HTML page for the model. -v, --version: Output version information and exit. -?, --help: Display this help message and exit. Unknown option: '%1'. High contrast stud and edge color settings are ignored when -aec or --automate-edge-color is set. --viewpoint is ignored when --camera is set. --orthographic is ignored when --camera is set. --camera-angles is ignored when --camera is set. --camera-position is ignored when --camera is set. --camera-angles is ignored when --viewpoint is set. --camera-position is ignored when --viewpoint is set. --camera-position is ignored when --camera-angles is set. No file name specified. Error creating OpenGL context. LeoCAD could not load Parts Library. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD n’a pas pu charger la bibliothèque de pièces. SVP visitez https://www.leocad.org pour apprendre comment télécharger et installer une bibliothèque. Error: model '%1' does not exist. Saved '%1'. Some changes will only take effect the next time you start LeoCAD. Parts library and Anti-aliasing changes will only take effect the next time you start LeoCAD. Les changements concernant la bibliothèque de pièces et l’anti-aliasing ne prendront effet qu’au prochain lancement de LeoCAD. Parts library changes will only take effect the next time you start LeoCAD. Les changement concernant la bibliothèque de pièces ne prendront effet qu’au prochain lancement de LeoCAD. Anti-aliasing changes will only take effect the next time you start LeoCAD. Les changement concernant l’anti-aliasing ne prendront effet qu’au prochain lancement de LeoCAD. lcAutomateEdgeColorDialog Color Preferences Edge Colors Contrast: Set the amount of contrast - 0.50 is midway. Reset Réinitialiser Light/Dark Value: Saturation: Set to classify where color values are light or dark - e.g. Dark Bluish Gray (72) is light at 0.39. Set to specify amount of edge color tint or shade from the saturation adjusted part color High Contrast Stud Cylinder Color: Parts Edge Color: Black Parts Edge Color: Dark Parts Edge Color: Select Stud Cylinder Color Select Part Edge Color Automate edge color appears to be enabled.<br>Black parts edge color will not be accessible.<br>Do you want to continue? Select Black Edge Color Automate edge color appears to be enabled.<br>Dark parts edge color will not be accessible.<br>Do you want to continue? Select Dark Edge Color lcFindReplaceWidget Find: Replace: lcInstructions Show Step Number Show Parts List Font: Text Color: Background Color: Border Color: lcInstructionsDialog Instructions Page Settings Print Vertical Horizontal Page %1 lcInstructionsPageListWidget Pages Page Setup lcInstructionsPropertiesWidget Properties Propriétés Default Current Model Current Step Only Current Step Forward Scope: Preset: Select Step Number Color Select Step Background Color Select Parts List Background Color Select Parts List Border Color Select Parts List Text Color Select Step Number Font Select Parts List Font Step Properties Step Number Properties Parts List Properties lcMainWindow Transform Transformation C&ameras C&améras &File &Fichier &Export &Exporter &Edit &Éditer &View &Vue &Viewpoints &Points de vue Projection Projection Ste&p Éta&pe T&oolbars Barres d’&outils &Piece &Pièce &Help &Aide Transform Options Snap XY Pas XY Snap Z Pas Z Snap Menu Menu pas Movement Snap Pas pour les déplacements Snap translations to fixed intervals Utiliser un pas donné pour les translations Snap Angle Menu Menu pas pour les angles Rotation Snap Pas pour les rotations Snap rotations to fixed intervals Utiliser un pas fixe pour les rotations Standard Standard Tools Outils New Model Nouveau modèle Open Model Save Model Sh&ading &Import Sub&model Selection Mode Change selection mode Time Temps Parts Pièces Colors Properties Propriétés Timeline Ligne temporelle Preview Close Other Tabs The file '%1' has been modified by another application, do you want to reload it? File Changed %1 (ID: %2) %1 (ID : %2) %n Object(s) selected Rel Abs M: %1 %2 R: %3 %4 M : %1 %2 R : %3 {1 %2 ?} {3 %4 ?} Merge Model Merged 1 submodel. Merged %1 submodels. Import LEGO Diginal Designer Files (*.lxf);;All Files (*.*) - %1 (ID: %2) - %1 (ID : %2) in group '%1' dans le groupe « %1 » Step %1 Étape %1 M: %1 %2 R: %3 M : %1 %2 R : %3 &Undo %1 Ann&uler %1 &Undo Ann&uler &Redo %1 &Refaire %1 &Redo &Refaire Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*) Fichiers pris en charge (*.lcd *.ldr *.dat *.mpd);;Tous les fichiers (*.*) LeoCAD LeoCAD Error loading '%1'. Erreur au chargement de « %1 ». Supported Files (*.mpd);;All Files (*.*) Fichiers pris en charge (*.mpd);;Tous les fichiers (*.*) Supported Files (*.ldr *.dat *.mpd);;All Files (*.*) Fichiers pris en charge (*.ldr *.dat *.mpd);;Tous les fichiers (*.*) Error Erreur Saving files in LCD format is no longer supported, please use the LDR or MPD formats instead. Enregistrer les fichiers sous le format LCD n’est plus possible, SVP utiliser les formats LDR ou MPD à la place. Save changes to '%1'? Enregistrer les modifications à « %1 » ? 0 0 1/20S 1/20T 1/4S 1/4T 1F 1P 1/2S 1/2T 1S 1T 2S 2T 3S 3T 4S 4T 8S 8T None Aucun 1B 1B 2B 2B 4B 4B 8B 8B lcMinifigDialog Minifig Wizard Assistant de minifig Templates Save... Delete... Supprimer… Import... Importer… Export... Exporter… Save Template Template Name: Template name cannot be empty. Are you sure you want to overwrite the template '%1'? Overwrite Template Are you sure you want to delete the template '%1'? Delete Template Import Templates Minifig Template Files (*.minifig);;All Files (*.*) Error Erreur Error reading file '%1': %2 Export Templates Error writing to file '%1': %2 Erreur en écrivant le fichier « %1 » : %2 lcModel Pasting Collage LeoCAD LeoCAD Error creating images. Erreur à la création des images. Inserting Step Insértion d’une étape Removing Step Suppression d’une étape No pieces selected. Aucune pièce sélectionnée. Group # Groupe n° Cutting Duplicating Pieces Error Erreur Error writing to file '%1': %2 Erreur en écrivant le fichier « %1 » : %2 Grouping Grouper Ungrouping Dégrouper Editing Groups Éditer les groupes Adding Piece Resetting Cameras Removing Key Frames Modifying New Model Nouveau modèle Inlining Moving Rotating Scaling Setting Part Modification de pièce Hide Cacher Unhide Replacing Part New SpotLight Nouvelle lumière projecteur New Camera Nouvelle caméra Move Déplacer Rotate Tourner Zoom Zoomer Pan Glisser Orbit Orbiter Roll Pivoter Insert Insérer New Light Nouvelle lumière Deleting Suppression Painting Peindre No models selected. Aucun modèle sélectionné. Showing Pieces Montre les pièces Hiding Pieces Cache les pièces Editing Camera Édite la caméra Changing FOV Change le FOV Renaming Camera Renomme la caméra Look At Viser le modèle Moving Camera Changing Properties Change les propriétés Nothing to select. Rien à sélectionner. Array only has 1 element or less, no pieces added. L’arrangement a seulement un élément ou moins, aucune pièce ajoutée. Array Arrangement Minifig # Minifig n° Minifig Minifig lcPageSetupDialog Page Setup Size Width: Height: Hauteur : Preset: Units: Margins Left: Right: Top: Bottom: lcPartPaletteDialog Part Palettes New... Nouveau… Delete... Supprimer… Rename... Import... Importer… Move Up Move Down New Part Palette Palette Name: Are you sure you want to delete the palette '%1'? Delete Part Palette Rename Part Palette lcPartSelectionListView Add to Palette None Aucun Remove from Palette lcPartSelectionWidget Search Parts Options Edit Palettes... No Icons Small Icons Medium Icons Large Icons Extra Large Icons Show Part Names Show Decorated Parts Show Part Aliases List Mode Lock Preview Color Favorites All Parts In Use Submodels lcPiecesLibrary Initializing Loading Parts Library lcPreviewDockWidget Lock Preview Ctrl+L Toolbar Preview Toolbar Loading... Unlock the preview display to enable updates Lock the preview display to disable updates Unlock Preview lcQAboutDialog About LeoCAD À propos de LeoCAD LeoCAD Version 0.00.0 LeoCAD Version 0.00.0 LeoCAD is a free application for creating virtual LEGO models. LeoCAD est une application libre pour créer les modèles LEGO virtuels. System Information Informations système LeoCAD Version %1 LeoCAD Version %1 OpenGL Version %1 (GLSL %2) %3 - %4 OpenGL Version %1 (GLSL %2) %3 - %4 Color Buffer: %1 bits %2 %3 Depth Buffer: %4 bits Stencil Buffer: %5 bits Color Buffer: %1 bits %2 %3 Depth Buffer: %4 bits Stencil Buffer: %5 bits indexed indexé double buffered double tampon LeoCAD Continuous Build %1 Qt Version %1 (compiled with %2) Color Buffer: %1 bits Depth Buffer: %2 bits Stencil Buffer: %3 bits Buffers: %1 Shaders: %2 Framebuffers: %3 BlendFuncSeparate: %4 Anisotropic: %5 Supported Pris en charge Not supported Non pris en charge Supported (max %1) Pris en charge (maximum %1) lcQArrayDialog Array Arrangement Dimensions Dimensions Offsets Décalages Rotations Rotations Array is empty. L’arrangement est vide. lcQCategoryDialog Category Catégorie Name: Nom : Keywords: Mots clés : Edit Category Éditer la catégorie New Category Nouvelle catégorie Name cannot be empty. Le nom ne peut pas être vide. Keywords cannot be empty. Le champ mots clés ne peut pas être vide. lcQEditGroupsDialog Edit Groups Édition des groupes New Group Nouveau groupe Group # Groupe n° lcQFindDialog Find Rechercher Name Nom Part ID ID de pièce Color Couleur lcQGroupDialog Group Groupe Name Nom Name cannot be empty. Le nom ne peut pas être vide. lcQHTMLDialog HTML Options Options HTML General Général Output folder: Dossier cible : ... ... Transparent image background Fond d’image transparent Width: Largeur : Height: Hauteur : Index page Page d’index Models Modèles All Models Tous les modèles Current Model and Submodels Modèle courant et ses sous-modèles Current Model Only Modèle courant seulement Steps Étapes Single Page Une seule page One Step per Page Une étape par page Highlight new parts Mettre en évidence les nouvelles pièces Parts List Liste de pièces At the end À la fin After each step Après chaque étape Color: Couleur : Create images Créer les images Output folder cannot be empty. Le champ dossier cible ne peut être vide. Select Output Folder Sélectionner le dossier cible lcQImageDialog Save Image Enregistrer l’image File name: Nom de fichier : Dimensions Dimensions Step Range Intervalle des étapes All Steps Toutes les étapes Current Step Étape courante Custom Range Intervalle personnalisé From: Depuis : To: Jusqu’à : Width: Largueur : Height: Hauteur : ... ... Output File cannot be empty. Le champ fichier cible ne peut être vide. Error Erreur First step must be between 1 and %1. La première étape doit être comprise entre 1 et %1. Last step must be between 1 and %1. La dernière étape doit être comprise entre 1 et %1. Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) Fichiers images pris en charge (*.bmp *.png *.jpg);;Fichiers BMP (*.bmp);;Fichiers PNG (*.png);;Fichiers JPEG (*.jpg);;Tous les fichiers (*.*) Last step must be greater than first step. La dernière étape doit être plus grande que la première. Please enter a width between 1 and 32768. SVP entrez une largeur entre 1 et 32768. Please enter a height between 1 and 32768. SVP entrez une hauteur entre 1 et 32768. Save Image File Enregistrer l’image lcQMinifigDialog Minifig Wizard Assistant de minifig Delete... Supprimer… lcQModelListDialog Submodels &New... D&elete... Su&pprimer… &Rename... &Renommer… Export... Exporter… Duplicate... Move &Up &Monter Move &Down &Descendre Set Active New Submodel Error Erreur The model cannot be empty. Are you sure you want to delete the submodel '%1'? Delete Submodel No submodel selected. Are you sure you want to delete %1 submodels? Rename Submodel Export Submodel LeoCAD LeoCAD Nothing to export. Rien à exporter. Export Model Select Export Folder Duplicate Submodel Copy of Supported Files (*.ldr *.dat);;All Files (*.*) lcQPreferencesDialog Preferences Préférences General Général Default author name: Auteur par défaut : ... ... Custom parts library: Bibliothèque de pièces personnalisées : Open most recent file on startup Mouse Souris Mouse Shortcuts Raccourcis souris Action Action Shortcut 1 Shortcut 2 Button: Bouton : None Aucun Left Gauche Middle Central Right Droit Modifiers: Modificateurs : Control Contrôle Alt Alt Shift Maj Mouse sensitivity: Sensibilité de la souris : Check for updates: Vérifier les mises à jour : PO&V-Ray Executable: Never Jamais Once a day Tous les jours Once a week Toutes les semaines Fixed direction keys Touches de directions fixes Rendering Rendu Edge lines Bordures Axis icon Icônes d’axes width largeur Anti-aliasing Anti-aliasing 2x 2x 4x 4x 8x 8x Shading Mode: Wireframe Flat Shading Default Lights Base Grid Grille de base Draw studs Dessiner les tenons studs tenons Draw lines every Dessine des lignes tous les View Sphere Disabled Small Medium Large Highlight Color: Color: Couleur : Text Color: Location: Application Language: Default Czech Deutsch English Français Português Español Color Theme: Dark System Custom Paths Parts Library: Color Configuration: Minifig Settings: &LGEO Library: Restore tab layout Stud Style Mesh LOD Highlight new parts Mettre en évidence les nouvelles pièces Plain Thin Lines Logo Outline Logo Sharp Top Logo Rounded Top Logo Flattened Logo High Contrast High Contrast with Logo Settings... Contrast Settings... Views Model Views Axis Icon View Sphere: Top Left Top Right Bottom Left Bottom Right Draw origin lines Part Preview Colors Background Fond Top Color: Bottom Color: So&lid Color &Gradient Interface Inactive View Border: Overlay Color: Active View Border: Camera Name: Axis Icon Labels: Marquee Border: Highlight New Parts Fade Previous Steps Lines Conditional Lines Line Width: Edge Lines Automate Edge Color Marquee Fill: Grid Lines: Studs: Objects Light: Focused: Control Point Focused: Control Point: Selected: Camera: Categories Catégories Parts Library Categories Catégories de la bibliothèque de pièces Name Nom Number Nombre Import... Importer… Export... Exporter… Reset... Réinitialiser… Category Catégorie New... Nouveau… Edit... Éditer… Delete... Supprimer… Keyboard Clavier Keyboard Shortcuts Raccourcis clavier Command Commande Shortcut Raccourcis Search shortcuts Key se&quence: Assign Attribuer Remove Supprimer Grid spacing must be greater than 0. L’espacement de la grille doit être plus grand que 0. Select Parts Library Folder Supported Archives (*.zip *.bin);;All Files (*.*) Select Parts Library Archive Select Color Configuration File Settings Files (*.ldr);;All Files (*.*) Select Minifig Settings File Settings Files (*.ini);;All Files (*.*) Executable Files (*.exe);;All Files (*.*) Fichiers exécutables (*.exe);;Tous les fichiers (*.*) All Files (*.*) Tous les fichiers (*.*) Open POV-Ray Executable Lancer l’exécutable POV-Ray Open LGEO Folder Ouvrir le dossier LGEO Reset Colors Would you like to also reset the interface colors to match the color theme? Select Background Color Choisir la couleur de fond Select Gradient Top Color Select Gradient Bottom Color Select Axes Color Select Text Color Select Marquee Border Color Select Marquee Fill Color Select Overlay Color Select Active View Color Select Inactive View Color Select Fade Color Select Highlight Color Select Grid Stud Color Choisir le couleur des tenons de la grille Select Grid Line Color Choisir la couleur des lignes de la grille Select View Sphere Color Select View Sphere Text Color Select View Sphere Highlight Color Select Object Selected Color Select Object Focused Color Select Camera Color Select Light Color Select Control Point Color Select Control Point Focused Color Unassigned Non-attribué Are you sure you want to delete the category '%1'? Êtes-vous sûr de vouloir supprimer la catégorie « %1 » ? Import Categories Importer les catégories Text Files (*.txt);;All Files (*.*) Fichiers texte (*.txt);;Tous les fichiers (*.*) Error loading categories file. Erreur au chargement du fichier des catégories. Export Categories Exporter les catégories Error saving categories file. Erreur à l’enregistrement du fichier des catégories. Are you sure you want to load the default categories? Êtes-vous sûr de vouloir charger les catégories par défaut ? The shortcut '%1' is already assigned to '%2'. Do you want to replace it? Import shortcuts Importer les raccourcis Error loading keyboard shortcuts file. Erreur au chargement du fichier des raccourcis clavier. Export shortcuts Exporter les raccourcis Error saving keyboard shortcuts file. Erreur à l’enregistrement du fichier des raccourcis clavier. Are you sure you want to load the default keyboard shortcuts? Êtes-vous sûr de vouloir charger les raccourcis clavier par défaut ? Left Button Bouton gauche Middle Button Bouton central Right Button Bouton droit Override Shortcut Écraser le raccourcis Select POV-Ray Executable This shortcut is already assigned to '%1', do you want to replace it? Ce raccourcis est déjà attribué à « %1 », voulez-vous le remplacer ? Import Shortcuts Error loading mouse shortcuts file. Export Shortcuts Error saving mouse shortcuts file. Are you sure you want to load the default mouse shortcuts? Êtes-vous sûr de vouloir charger les raccourcis souris par défaut ? lcQPropertiesDialog Properties Propriétés Summary Résumé Author: Auteur : Description: Description : Comments: Commentaires : Measurements: Scene Scène Background Fond Image Image ... ... Tile Tuile Set default options for new projects Attribuer les options par défauts aux nouveaux projets Parts Used Pièces utilisées %1 Properties %1 propriétés %1 x %2 x %3 cm %4 x %5 x %6 inches %7 x %8 x %9 LDU Part Pièce Total Total Select Background Color Choisir la couleur de fond Select Background Top Color Choisir la couleur du haut du fond Select Background Bottom Color Choisir la couleur du bas du fond Select Background Image Choisir l’image de fond All Image Files (*.png *.jpg *.gif *.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;GIF Files (*.gif);;BMP Files (*.bmp);;All Files (*.*) Tous les fichiers images (*.png *.jpg *.gif *.bmp);;Fichiers PNG (*.png);;Fichiers JPEG (*.jpg);;Fichiers GIF (*.gif);;Fichiers BMP (*.bmp);;Tous les fichiers (*.*) lcQPropertiesTree Property Propriété Value Valeur Position Position X X Y Y Z Z Rotation Rotation Visibility Visibilité Visible Steps Show Montrer Hide Cacher Appearance Apparence Color Couleur Part Pièce Target Cible Up Haut Orthographic Orthographique FOV FOV Near Proche Far Loin Name Nom Multiple Objects Selected Plusieurs objets sélectionnés lcQSelectDialog Select Objects Sélectionner des objets All Tous None Aucun Invert Inverser lcQUpdateDialog LeoCAD Updates Mises à jour LeoCAD Connecting to update server... Connexion au serveur de mise à jour… <p>There's a newer version of LeoCAD available for download (%1.%2.%3).</p> <p>Il y a une nouvelle version de LeoCAD disponible au téléchargement (%1.%2.%3).</p> <p>You are using the latest LeoCAD version.</p> <p>Vous utilisez la dernière version de LeoCAD.</p> <p>There are new parts available.</p> <p>Il y a de nouvelle pièces disponibles.</p> <p>There are no new parts available at this time.</p> <p>Il n’y a pas de nouvelle pièces disponibles en ce moment.</p> <p>Visit <a href="https://github.com/leozide/leocad/releases">https://github.com/leozide/leocad/releases</a> to download.</p> Error parsing update information. Erreur à la lecture des informations de mise à jour. Error connecting to the update server. Erreur à la connexion au serveur de mise à jour. lcRenderDialog Render Settings Width: Height: Hauteur : High Medium Low Quality: Output: ... ... Cancel Render Are you sure you want to cancel the current render? Cancel Error Erreur Error starting POV-Ray. An error occurred while rendering. Check details or try again. Error writing to file '%1': %2 Erreur en écrivant le fichier « %1 » : %2 Error writing to %1 file '%2': %3 Select Output File Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) Fichiers images pris en charge (*.bmp *.png *.jpg);;Fichiers BMP (*.bmp);;Fichiers PNG (*.png);;Fichiers JPEG (*.jpg);;Tous les fichiers (*.*) lcSelectByColorDialog Color: Couleur : lcSetsDatabaseDialog Sets Database Set Name or Number Search Number Nombre Name Nom Year Parts Pièces Sets Database provided by <a href="https://www.rebrickable.com">Rebrickable</a> Please select a set from the list. Downloading Downloading set inventory Keyword cannot be empty. Searching Connecting to server Error connecting to server. Error downloading set inventory. lcTimelineWidget Step %1 Étape %1 lcView LeoCAD LeoCAD Error creating images. Erreur à la création des images. Error Erreur Error writing to file '%1': %2 Erreur en écrivant le fichier « %1 » : %2 leocad-23.03/resources/leocad_pt.ts000066400000000000000000011715451440571307300173060ustar00rootroot00000000000000 Action File.New File.Open File.Merge File.Save File.SaveAs File.SaveImage File.Import.LDD File.Import.Inventory File.Export.3DS File.Export.COLLADA File.Export.HTML File.Export.BrickLink File.Export.CSV File.Export.POVRay File.Export.Wavefront File.Render File.Instructions File.Print File.PrintPreview File.Recent1 File.Recent2 File.Recent3 File.Recent4 File.Exit Edit.Undo Edit.Redo Edit.Cut Edit.Copy Edit.Paste Edit.PasteSteps Edit.Find Edit.FindNext Edit.FindPrevious Edit.FindAll Edit.Replace Edit.ReplaceNext Edit.ReplaceAll Edit.SelectAll Edit.SelectNone Edit.SelectInvert Edit.SelectByName Edit.SelectSingle Edit.SelectPiece Edit.SelectColor Edit.SelectPieceColor Edit.TransformRelative Edit.TransformAbsolute Edit.TransformToggleRelative Edit.TransformSeparately Edit.TransformTogether Edit.TransformToggleSeparate Edit.Snap.Toggle Edit.SnapMove.XY0 Edit.SnapMove.XY1 Edit.SnapMove.XY2 Edit.SnapMove.XY3 Edit.SnapMove.XY4 Edit.SnapMove.XY5 Edit.SnapMove.XY6 Edit.SnapMove.XY7 Edit.SnapMove.XY8 Edit.SnapMove.XY9 Edit.SnapMove.Z0 Edit.SnapMove.Z1 Edit.SnapMove.Z2 Edit.SnapMove.Z3 Edit.SnapMove.Z4 Edit.SnapMove.Z5 Edit.SnapMove.Z6 Edit.SnapMove.Z7 Edit.SnapMove.Z8 Edit.SnapMove.Z9 Edit.SnapAngle.Toggle Edit.SnapAngle.Angle0 Edit.SnapAngle.Angle1 Edit.SnapAngle.Angle2 Edit.SnapAngle.Angle3 Edit.SnapAngle.Angle4 Edit.SnapAngle.Angle5 Edit.SnapAngle.Angle6 Edit.SnapAngle.Angle7 Edit.SnapAngle.Angle8 Edit.SnapAngle.Angle9 Edit.Transform Edit.TransformAbsoluteTranslation Edit.TransformRelativeTranslation Edit.TransformAbsoluteRotation Edit.TransformRelativeRotation Edit.Tool.Insert Edit.Tool.Light Edit.Tool.Spotlight Edit.Tool.Camera Edit.Tool.Select Edit.Tool.Move Edit.Tool.Rotate Edit.Tool.Delete Edit.Tool.Paint Edit.Tool.ColorPicker Edit.Tool.Zoom Edit.Tool.Pan Edit.Tool.RotateView Edit.Tool.Roll Edit.Tool.ZoomRegion Edit.Cancel View.Preferences View.ZoomIn View.ZoomOut View.ZoomExtents View.LookAt View.MoveForward View.MoveBackward View.MoveLeft View.MoveRight View.MoveUp View.MoveDown View.Viewpoint.Front View.Viewpoint.Back View.Viewpoint.Top View.Viewpoint.Bottom View.Viewpoint.Left View.Viewpoint.Right View.Viewpoint.Home View.Cameras.None View.Cameras.Camera01 View.Cameras.Camera02 View.Cameras.Camera03 View.Cameras.Camera04 View.Cameras.Camera05 View.Cameras.Camera06 View.Cameras.Camera07 View.Cameras.Camera08 View.Cameras.Camera09 View.Cameras.Camera10 View.Cameras.Camera11 View.Cameras.Camera12 View.Cameras.Camera13 View.Cameras.Camera14 View.Cameras.Camera15 View.Cameras.Camera16 View.Time.First View.Time.Previous View.Time.Next View.Time.Last View.Time.InsertBefore View.Time.InsertAfter View.Time.Delete View.Time.AddKeys View.SplitHorizontal View.SplitVertical View.RemoveView View.ResetViews View.Toolbars.Standard View.Toolbars.Tools View.Toolbars.Time View.Toolbars.Parts View.Toolbars.Colors View.Toolbars.Properties View.Toolbars.Timeline View.Toolbars.Preview View.FullScreen View.CloseCurrentTab View.Shade.Wireframe View.Shade.Flat View.Shade.DefaultLights View.Projection.Perspective View.Projection.Orthographic View.ToggleViewSphere View.ToggleAxisIcon View.ToggleGrid View.FadePreviousSteps Piece.Insert Piece.Delete Piece.Duplicate Piece.PaintSelected Piece.ResetPivotPoint Piece.RemoveKeyFrames Piece.ControlPoint.Insert Piece.ControlPoint.Remove Piece.Move.PlusX Piece.Move.MinusX Piece.Move.PlusY Piece.Move.MinusY Piece.Move.PlusZ Piece.Move.MinusZ Piece.Rotate.PlusX Piece.Rotate.MinusX Piece.Rotate.PlusY Piece.Rotate.MinusY Piece.Rotate.PlusZ Piece.Rotate.MinusZ Piece.MinifigWizard Piece.Array Piece.ViewSelectedModel Piece.MoveSelectionToModel Piece.InlineSelectedModels Piece.EditSelectedSubmodel Piece.EditEndSubmodel Piece.Group Piece.Ungroup Piece.GroupAdd Piece.GroupRemove Piece.GroupEdit Piece.HideSelected Piece.HideUnselected Piece.UnhideSelected Piece.UnhideAll Piece.ShowEarlier Piece.ShowLater Model.New Model.Properties Model.List Model.Model01 Model.Model02 Model.Model03 Model.Model04 Model.Model05 Model.Model06 Model.Model07 Model.Model08 Model.Model09 Model.Model10 Model.Model11 Model.Model12 Model.Model13 Model.Model14 Model.Model15 Model.Model16 Model.Model17 Model.Model18 Model.Model19 Model.Model20 Model.Model21 Model.Model22 Model.Model23 Model.Model24 Model.Model25 Model.Model26 Model.Model27 Model.Model28 Model.Model29 Model.Model30 Model.Model31 Model.Model32 Model.Model33 Model.Model34 Model.Model35 Model.Model36 Model.Model37 Model.Model38 Model.Model39 Model.Model40 Help.HomePage Help.BugReport Help.Updates Help.About Menu &New &Novo &Open... &Abrir... &Merge... Co&mbinar... &Save &Gravar Save &As... Gravar &Como... Save &Image... Gravar &Imagem... 3D &Studio... 3D &Studio... &HTML... &HTML... &BrickLink... &BrickLink... &CSV... &CSV... &POV-Ray... &POV-Ray... &Wavefront... &Wavefront... Single Selection Piece Selection Color Selection Piece and Color Selection Relative Transforms Transformações Relativas Move Snap Enabled Grelha de Movimentos Activada Insert Before Insert After Open Selected Model Edit Selected Submodel End Submodel Editing New Submodel... Prope&rties... Prop&riedades... &Print... Im&primir... &LEGO Digital Designer... Set &Inventory... &COLLADA... &Render... &Instructions... Print Pre&view... Pré-&visualizar Impressão... Print &Bill of Materials... Imprimir a &Lista das Peças... &Recent1 &Recente1 &Recent2 &Recente2 &Recent3 &Recente3 &Recent4 &Recente4 E&xit &Saír &Undo &Desfazer &Redo &Refazer Cu&t Cor&tar &Copy &Copiar &Paste Co&lar &Find... &Procurar... Find Ne&xt Procurar &Seguinte Find Pre&vious Procurar &Anterior Find All &Replace Replace Next Replace All Select &All Seleccion&ar Tudo Select &None Deseleccio&nar Tudo Select &Invert &Inverter a selecção Select by Na&me... Seleccionar por no&me... Absolute Transforms Toggle Relative Transforms Rotate Separately Rotate Together Toggle Separate Transforms None Nenhum 1/20 Stud 1/20 Prego 1/4 Stud 1/4 Prego 1 Flat 1 Prato 1/2 Stud 1/2 Prego 1 Stud 1 Prego 2 Studs 2 Pregos 3 Studs 3 Pregos 4 Studs 4 Pregos 8 Studs 8 Pregos 1 Brick 1 Tijolo 2 Bricks 2 Tijolos 4 Bricks 4 Tijolos 8 Bricks 8 Tijolos Rotation Snap Enabled Grelha de Rotação Activada 1 Degree 1 Grau 5 Degrees 5 Graus 15 Degrees 15 Graus 22.5 Degrees 180 Graus {22.5 ?} 30 Degrees 30 Graus 45 Degrees 45 Graus 60 Degrees 60 Graus 90 Degrees 90 Graus 180 Degrees 180 Graus Transform Transformar Absolute Translation Translação Absoluta Relative Translation Translação Relativa Absolute Rotation Rotação Absoluta Relative Rotation Rotação Relativa Insert Inserir Light Luz Spotlight Projector Camera Câmara Select Seleccionar Move Mover Rotate Rodar Delete Delete Paint Pintar Color Picker Zoom Zoom Pan Movimento Horizontal Rotate View Rodar Vista Roll Inclinar Zoom Region Zoom numa Região Cancel Action Anular Acção P&references... P&referências... Zoom In Ampliar Zoom Out Reduzir Zoom E&xtents V&er Tudo Look At Olhar Para Move Forward Move Backward Move Left Move Right Move Up Move Down &Front &Frente &Back &Traseira &Top &Acima B&ottom A&baixo &Left &Esquerda &Right &Direita &Home &Base Camera 1 Camera 2 Camera 3 Camera 4 Camera 5 Camera 6 Camera 7 Camera 8 Camera 9 Camera 10 Camera 11 Camera 12 Camera 13 Camera 14 Camera 15 Camera 16 Reset Reiniciar First Primeiro Previous Anterior Next Seguinte Last Último Remove Step Add Keys Adicionar Passos Split &Horizontal Corte &Horizontal Split &Vertical Corte &Vertical Re&move View Re&mover Vista Rese&t Views Reini&ciar Vistas Standard Standard Tools Ferramentas Time Hora Parts Peças Colors Properties Propriedades Timeline Linha Temporal Preview &Full Screen &Tela Cheia Close &Tab &Wireframe &Flat Shading &Default Lights &Perspective &Perspectiva &Orthographic &Ortográphica View Sphere Axis Icon Base Grid Grelha de Base Fade Previous Steps &Insert &Inserir &Delete &Apagar &Duplicate &Paint Selected Reset &Pivot Point Remove &Key Frames Insert Control Point Remove Control Point Move +X Mover +X Move -X Mover -X Move +Y Mover +Y Move -Y Mover -Y Move +Z Mover +Z Move -Z Mover -Z Rotate +X Rodar +X Rotate -X Rodar -X Rotate +Y Rodar +Y Rotate -Y Rodar -Y Rotate +Z Rodar +Z Rotate -Z Rodar -Z Minifig &Wizard... &Assistente Minifig... A&rray... Quad&ro... Move to New Model... Inline Selected Models &Group... &Grupo... &Ungroup Desagr&upar &Add to Group &Meter no Grupo Re&move from Group Re&mover do Grupo &Edit Groups... &Editar Grupos... &Hide Selected &Esconder Selecção Hide &Unselected E&sconder não Seleccionados &Unhide Selected &Mostrar Selecção U&nhide All Mostr&ar Tudo Show Earlier Mostrar Anteriores Show Later Mostrar Seguintes Submodels... Model 1 Model 2 Model 3 Model 4 Model 5 Model 6 Model 7 Model 8 Model 9 Model 10 Model 11 Model 12 Model 13 Model 14 Model 15 Model 16 Model 17 Model 18 Model 19 Model 20 Model 21 Model 22 Model 23 Model 24 Model 25 Model 26 Model 27 Model 28 Model 29 Model 30 Model 31 Model 32 Model 33 Model 34 Model 35 Model 36 Model 37 Model 38 Model 39 Model 40 Report a Bug Insert Step Before Insert Step After Move Selection Here Set Current Step LeoCAD &Home Page &Página do LeoCAD &Recent 1 &Recent 2 &Recent 3 &Recent 4 Paste with Steps &Find Check for &Updates... Procurar act&ualizações... &About... &Acerca... Mouse NewPiece NewPointLight NewSpotLight NewCamera Select Seleccionar Move Mover Rotate Rodar Delete Apagar Paint Pintar ColorPicker Zoom Zoom Pan Movimento Horizontal Orbit Órbitar Roll Inclinar ZoomRegion Project Empty Name Nome Vazio Error Erro Error reading file '%1': %2 Error loading file '%1': File format is not recognized. Merged Combinado LeoCAD LeoCAD Nothing to export. Nada a exportar. Export 3D Studio Exportar para 3D Studio 3DS Files (*.3ds);;All Files (*.*) Ficheiros 3DS (*.3ds);;Todos os Ficheiros (*.*) Could not open file '%1' for writing. Erro ao abrir o ficheiro '%1' para escrever. Export BrickLink Exportar BrickLink XML Files (*.xml);;All Files (*.*) Ficheiros XML (*.xml);;Todos os Ficheiros (*.*) Export COLLADA Exportar COLLADA COLLADA Files (*.dae);;All Files (*.*) Ficheiros COLLADA (*.dae);;Todos os Ficheiros (*.*) Export CSV Exportar CSV CSV Files (*.csv);;All Files (*.*) Ficheiros CSV (*.csv);;Todos os Ficheiros (*.*) Error creating images. Erro ao criar as imagens. Export POV-Ray Exportar POV-Ray POV-Ray Files (*.pov);;All Files (*.*) Ficheiros POV-Ray (*.pov);;Todos os Ficheiros (*.*) Could not find LGEO files in folder '%1'. Não achei ficheiros LGEO na pasta '%1'. Export Wavefront Exportar Wavefront Wavefront Files (*.obj);;All Files (*.*) Ficheiros Wavefront (*.obj);;Todos os Ficheiros (*.*) Error writing to file '%1': %2 Erro ao escrever no ficheiro '%1': %2 New Model.ldr New Model.mpd Submodel # Submodel Name: The submodel name cannot be empty. Duplicate Submodel A submodel named '%1' already exists, please enter a unique name. New Submodel QApplication Group # Grupo # Solid Colors Colors Cores Sólidas Translucent Colors Colors Cores Translúcidas Special Colors Colors Cores Especiais Solid Colors Translucent Colors Special Colors QMessageBox Error Erro QObject LeoCAD LeoCAD Could not open file '%1' for writing. Erro ao abrir o ficheiro '%1' para escrever. Status Save a picture of the current view Grava uma imagem da vista actual Export a list of parts used in BrickLink XML format Exporta uma lista das peças utilizadas no formato XML BrickLink Export a list of parts used in comma delimited file format Exporta uma lista das peças utilizadas no formato de ficheiro separado por vírgulas Print a list of parts used Imprime uma lista das peças utilizadas Undo the last action Anula a última acção Redo the previously undone action Refaz a acção que foi anulada Cut the selection and put it on the Clipboard Corta a selecção e mete-a na Ãrea de Transferência Copy the selection and put it on the Clipboard Copia a selecção e mete-a na Ãrea de Transferência Insert Clipboard contents Insere o conteúdo da Ãrea de Transferência Find object Procurar objecto Find next object Procurar objecto seguinte De-select everything De-selecciona tudo Invert the current selection set Inverte a selecção actual Select objects by name Selecciona objectos por nome Toggle snap axes Bascula a grelha nos eixos Snap rotations to fixed intervals Fixa as rotações por intervalos fixos Do not snap movement along the XY plane Liberta os movimentos no plano XY Snap movement along the XY plane to 1/20 stud Fixa os movimentos no plano XY por 1/20 prego Snap movement along the XY plane to 1/4 stud Fixa os movimentos no plano XY por 1/4 prego Snap movement along the XY plane to 1 flat Fixa os movimentos no plano XY por 1 prato Snap movement along the XY plane to 1/2 stud Fixa os movimentos no plano XY por 1/2 prego Snap movement along the XY plane to 1 stud Fixa os movimentos no plano XY por 1 prego Snap movement along the XY plane to 2 studs Fixa os movimentos no plano XY por 2 pregos Snap movement along the XY plane to 3 studs Fixa os movimentos no plano XY por 3 pregos Snap movement along the XY plane to 4 studs Fixa os movimentos no plano XY por 4 pregos Snap movement along the XY plane to 8 studs Fixa os movimentos no plano XY por 8 pregos Do not snap movement along the Z axis Liberta os movimentos no eixo Z Snap movement along the Z axis to 1/20 stud Fixa os movimentos no eixo Z por 1/20 prego Snap movement along the Z axis to 1/4 stud Fixa os movimentos no eixo Z por 1/4 prego Snap movement along the Z axis to 1 flat Fixa os movimentos no eixo Z por 1 placa Snap movement along the Z axis to 1/2 stud Fixa os movimentos no eixo Z por 1/2 prego Snap movement along the Z axis to 1 stud Fixa os movimentos no eixo Z por 1 prego Snap movement along the Z axis to 1 brick Fixa os movimentos no eixo Z por 1 tijolo Snap movement along the Z axis to 2 bricks Fixa os movimentos no eixo Z por 2 tijolos Snap movement along the Z axis to 4 bricks Fixa os movimentos no eixo Z por 4 tijolos Snap movement along the Z axis to 8 bricks Fixa os movimentos no eixo Z por 8 tijolos Do not snap rotations Não fixar as rotações Snap rotations to 1 degree Fixa as rotações por 1 grau Snap rotations to 5 degrees Fixa as rotações por 5 graus Create a new model Open an existing model Merge the contents of another file with the current one Save the current model Save the current model with a new name Import a file in LEGO Digital Designer LXF format Import all parts from an official set Export the current model in 3D Studio 3DS format Export the current model in COLLADA DAE format Create an HTML page for the current model Export the current model in POV-Ray format Export the current model in Wavefront OBJ format Render the current model using POV-Ray Print the current model Display how the model would look if printed Open this model Quit the application; prompts to save model Select all pieces in the model Select one piece at a time Select all pieces of the same type Select all pieces of the same color Select all pieces of the same type and color Move and rotate objects relative to the one that has focus Move and rotate objects in absolute coordinates Toggle moving and rotating objects relative to the one that has focus Rotate selected pieces separately Rotate selected pieces together Toggle rotating selected pieces separately Snap rotations to 15 degrees Fixa as rotações por 15 graus Snap rotations to 22.5 degrees Fixa as rotações por 22.5 graus Snap rotations to 30 degrees Fixa as rotações por 30 graus Snap rotations to 45 degrees Fixa as rotações por 45 graus Snap rotations to 60 degrees Fixa as rotações por 60 graus Snap rotations to 90 degrees Fixa as rotações por 90 graus Snap rotations to 180 degrees Fixa as rotações por 180 graus Apply transform to selected objects Applica a transformação aos objectos seleccionados Switch to absolute translation mode when applying transforms Move e roda os objectos en modo absoluto Switch to relative translation mode when applying transforms Move e roda os objectos relativamento ao objecto que tem focus Switch to absolute rotation mode when applying transforms Move e roda os objectos en modo absoluto Switch to relative rotation mode when applying transforms Roda os objectos relativamento ao objecto que tem focus Add new pieces to the model Adiciona novas peças ao modelo Add new omni light sources to the model Adiciona novas luzes difusas ao modelo Add new spotlights to the model Adiciona novos holofotes ao modelo Create a new camera Cria uma nova câmara Select objects (hold the CTRL key down or drag the mouse to select multiple objects) Selecciona peças (carregue na tecla CTRL ou puxe o rato para seleccionar mais objectos) Move selected objects Mover os objectos seleccionados Rotate selected pieces Rodar os objectos seleccionados Delete objects pagar objectos Change piece color Mudar a cor das peças Get piece color Zoom in or out Ampliar ou Reduzir Pan the current view Movimenta horizontalmente a vista actual Rotate the current view Roda a vista actual Roll the current view Inclina a vista actual Zoom into a region of the screen Amplia uma zona do ecrã Cancel current mouse action Anula a acção acutal do rato Change program settings Muda a configuração do programa Zoom in Ampliar Zoom out Ampliar Fit all pieces in current the view (hold the CTRL key down to zoom all views) Faz caber todas as peças na vista actual (carregue na tecla CTRL para aplicar a todas as vistas) Rotate view so selected pieces are at center Rodar a vista para que as peças selccionadas fiquem no centro Move the current view forward Move the current view backward Move the current view to the left Move the current view to the right Move the current view up Move the current view down View model from the front Ver o modelo pela frente View model from the back Ver o modelo pelas traseiras View model from the top Ver o modelo por cima View model from the bottom Ver o modelo por baixo View model from the left Ver o modelo pela esquerda View model from the right Ver o modelo pela direita View model from the default position Ver o modelo pela posição por omissão Do not use a camera Não utilizar a câmara Use this camera Utilizar esta câmara Reset views to their default positions Repor as vistas por omissão Go to the first step of the model Ir ao primeiro passo do modelo Go to the previous step Ir ao passo anterior Go to the next step Ir ao passo seguinte Go to the last step of the model Ir ao último passo do modelo Insert new step Inserir um novo passo Remove current step Apaga o passo actual Close current tab Open the model referenced by the selected piece in a new tab Edit the currently selected submodel in-place End in-place submodel editing Create a new submodel Display the properties of the current submodel Show a list of all submodels Switch to this submodel Open LeoCAD's bug report form on your default web browser Move the selected parts into this step View the model at this point in the timeline Toggle adding new animation keys Activa a adição de novos passos Configure instructions layout Insert Clipboard contents in the current step Insert Clipboard contents in their original steps Find piece Find next piece Find previous piece Find all pieces that match the search criteria Replace piece Replace next piece Replace all pieces that match the search criteria Insert a new step before the current step Insert a new step after the current step Split the current view horizontally Divide horizontalemente a vista actual Split the current view vertically Divide verticalemente a vista actual Remove the current view Apaga a vista actual Reset all views Reinicia todas as vistas Toggle the Standard Toolbar Toggle the Tools Toolbar Toggle the Time Toolbar Toggle the Parts Toolbar Toggle the Colors Toolbar Toggle the Properties Toolbar Toggle the Timeline Toolbar Toggle the Preview Toolbar Toggle fullscreen mode Modo tela cheia Display the scene as wireframe Display the scene without any shading or lights Display the scene with the default lights Set the current camera to use a perspective projection Define a câmara actual em projecção por perspectiva Set the current camera to use an orthographic projection Define a câmara actual em projecção ortogonal Toggle the view sphere Toggle axis icon Toggle grid Toggle fading previous model steps Add a new piece to the model Adiciona ma nova peça ao modelo Delete selected objects Apagar os objectos seleccionados Create a copy of the selected pieces Change the color of the selected pieces Reset the pivot point of the selected pieces to their origin Remove all key frames from the selected pieces Insert a new control point Remove the selected control point Move selected objects along the X axis Move os objectos seleccionados no eixo X Move selected objects along the Y axis Move os objectos seleccionados no eixo Y Move selected objects along the Z axis Move os objectos seleccionados no eixo Z Rotate selected objects along the X axis Roda os objectos seleccionados no eixo X Rotate selected objects along the Y axis Roda os objectos seleccionados no eixo Y Rotate selected objects along the Z axis Roda os objectos seleccionados no eixo Z Add a new minifig to the model Adiciona uma minifigura ao modelo Make copies of the selected pieces Duplica as peças seleccionadas Move the selected pieces to a new model and replace them with a reference to the model Insert the contents of the selected model references into the current model Group selected pieces together Agrupa as peças seleccionadas Ungroup selected group Desagrupa o grupo seleccionado Add focused piece to selected group Adiciona a peça activa ao grupo seleccionado Remove focused piece from group Apaga a peça activa do grupo seleccionado Edit groups Editar grupos Hide selected objects Esconder os objectos seleccionados Hide objects that are not selected Esconder os objectos não seleccionados Show hidden objects that are selected Mostrar os objectos escondidos que estão seleccionados Show all hidden objects Mostrar todos os objectos escondidos Show selected pieces one step earlier Mostrar as peças seleccionadas um passo antes Show selected pieces one step later Mostrar as peças seleccionadas um passo depois Open LeoCAD's home page on the internet using your default web browser Abre a página internet do LeoCAD com o navegador por omissão Check if a newer LeoCAD version or parts library has been released Verifica se uma nova versão do LeoCAD ou da Biblioteca de peças estão disponiveis Display program version number and system information Mostra o número de versão do programa e informações do sisitema ViewName Left Left Right Right Back Front Top Bottom lcApplication LeoCAD LeoCAD LeoCAD could not find a compatible Parts Library so only a small number of parts will be available. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD não achou uma Biblioteca de Peças.compatível portanto só vai haver uma pequena quantia de peças disponível. Veja https://www.leocad.org para saber como descarragar e instalar uma biblioteca. Not enough parameters for the '%1' option. Invalid parameter value specified for the '%1' option: '%2'. The file '%1' is not readable. Invalid parameter value(s) specified for the '%1' option: limits are +/- 360. Invalid parameter value(s) specified for the '%1' option. Invalid parameter value(s) specified for the '%1' option: requirements are: 1 <= <near> < <far>. High contrast stud style is required for the '%1' option but is not enabled. Automate edge color is required for the '%1' option but is not enabled. LeoCAD Continuous Build %1 LeoCAD Version %1 LeoCAD Versão %1 Compiled %1 Usage: leocad [options] [file] [options] can be: -l, --libpath <path>: Set the Parts Library location to path. -i, --image <outfile.ext>: Save a picture in the format specified by ext and exit. -w, --width <width>: Set the picture width. -h, --height <height>: Set the picture height. -f, --from <step>: Set the first step to save pictures. -t, --to <step>: Set the last step to save pictures. -s, --submodel <submodel>: Set the active submodel. -c, --camera <camera>: Set the active camera. -ss, --stud-style <id>: Set the stud style 0=No style, 1=LDraw single wire, 2=LDraw double wire, 3=LDraw raised floating, 4=LDraw raised rounded, 5=LDraw subtle rounded, 6=LEGO no logo, 7=LEGO single wire. --viewpoint <front|back|left|right|top|bottom|home>: Set the viewpoint. --camera-angles <latitude> <longitude>: Set the camera angles in degrees around the model. --camera-position <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector. --camera-position-ldraw <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector using LDraw coordinates. --orthographic: Render images using an orthographic projection. --fov <degrees>: Set the vertical field of view used to render images (< 180). --zplanes <near> <far>: Set the near and far clipping planes used to render images (1 <= <near> < <far>). --fade-steps: Render parts from prior steps faded. --no-fade-steps: Do not render parts from prior steps faded. --fade-steps-color <rgba>: Renderinng color for prior step parts (#AARRGGBB). --highlight: Highlight parts in the steps they appear. --no-highlight: Do not highlight parts in the steps they appear. --highlight-color: Renderinng color for highlighted parts (#AARRGGBB). --shading <wireframe|flat|default|full>: Select shading mode for rendering. --line-width <width>: Set the width of the edge lines. --aa-samples <count>: AntiAliasing sample size (1, 2, 4, or 8). -scc, --stud-cylinder-color <#AARRGGBB>: High contrast stud cylinder color. -ec, --edge-color <#AARRGGBB>: High contrast edge color. -bec, --black-edge-color <#AARRGGBB>: High contrast edge color for black parts. -dec, --dark-edge-color <#AARRGGBB>: High contrast edge color for dark color parts. -aec, --automate-edge-color: Enable automatically adjusted edge colors. -cc, --color-contrast <float>: Color contrast value between 0.0 and 1.0. -ldv, --light-dark-value <float>: Light/Dark color value between 0.0 and 1.0. -obj, --export-wavefront <outfile.obj>: Export the model to Wavefront OBJ format. -3ds, --export-3ds <outfile.3ds>: Export the model to 3D Studio 3DS format. -dae, --export-collada <outfile.dae>: Export the model to COLLADA DAE format. -html, --export-html <folder>: Create an HTML page for the model. -v, --version: Output version information and exit. -?, --help: Display this help message and exit. Unknown option: '%1'. High contrast stud and edge color settings are ignored when -aec or --automate-edge-color is set. --viewpoint is ignored when --camera is set. --orthographic is ignored when --camera is set. --camera-angles is ignored when --camera is set. --camera-position is ignored when --camera is set. --camera-angles is ignored when --viewpoint is set. --camera-position is ignored when --viewpoint is set. --camera-position is ignored when --camera-angles is set. No file name specified. Error creating OpenGL context. LeoCAD could not load Parts Library. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD não conseguiu carregar a Biblioteca de Peças. Veja https://www.leocad.org para saber como descarragar e instalar uma biblioteca. Error: model '%1' does not exist. Saved '%1'. Some changes will only take effect the next time you start LeoCAD. Parts library and Anti-aliasing changes will only take effect the next time you start LeoCAD. As mudanças de Biblioteca e de Antisserrilhamento só tomam efeito após o próximo arranque do LeoCAD. Parts library changes will only take effect the next time you start LeoCAD. As mudanças de Biblioteca só tomam efeito após o próximo arranque do LeoCAD. Anti-aliasing changes will only take effect the next time you start LeoCAD. As mudanças de Antisserrilhamento só tomam efeito após o próximo arranque do LeoCAD. lcAutomateEdgeColorDialog Color Preferences Edge Colors Contrast: Set the amount of contrast - 0.50 is midway. Reset Reiniciar Light/Dark Value: Saturation: Set to classify where color values are light or dark - e.g. Dark Bluish Gray (72) is light at 0.39. Set to specify amount of edge color tint or shade from the saturation adjusted part color High Contrast Stud Cylinder Color: Parts Edge Color: Black Parts Edge Color: Dark Parts Edge Color: Select Stud Cylinder Color Select Part Edge Color Automate edge color appears to be enabled.<br>Black parts edge color will not be accessible.<br>Do you want to continue? Select Black Edge Color Automate edge color appears to be enabled.<br>Dark parts edge color will not be accessible.<br>Do you want to continue? Select Dark Edge Color lcFindReplaceWidget Find: Replace: lcInstructions Show Step Number Show Parts List Font: Text Color: Background Color: Border Color: lcInstructionsDialog Instructions Page Settings Print Vertical Horizontal Page %1 lcInstructionsPageListWidget Pages Page Setup lcInstructionsPropertiesWidget Properties Propriedades Default Current Model Current Step Only Current Step Forward Scope: Preset: Select Step Number Color Select Step Background Color Select Parts List Background Color Select Parts List Border Color Select Parts List Text Color Select Step Number Font Select Parts List Font Step Properties Step Number Properties Parts List Properties lcMainWindow Transform Transformar C&ameras Câm&aras &File &Ficheiro &Export &Exportar &Edit &Editar &View &Ver &Viewpoints Ponto de &Vista Projection Projecção Ste&p &Passo T&oolbars &Barras de Ferramentas &Piece &Peça &Help A&juda Transform Options Snap XY Fixa XY Snap Z Fixa Z Snap Menu Menu Fixar Movement Snap Fixar Movimentos Snap translations to fixed intervals Fixa translações por intervalos fixos Snap Angle Menu Menu de fixação dos ângulos Rotation Snap Grelha de Rotação Snap rotations to fixed intervals Fixa as rotações por intervalos fixos Standard Standard Tools Ferramentas New Model Novo Modelo Open Model Save Model Sh&ading &Import Sub&model Selection Mode Change selection mode Time Hora Parts Peças Colors Properties Propriedades Timeline Linha Temporal Preview Close Other Tabs The file '%1' has been modified by another application, do you want to reload it? File Changed %1 (ID: %2) %n Object(s) selected - %1 (ID: %2) in group '%1' Step %1 Passo %1 M: %1 %2 R: %3 M: %1 %2 R: %3 &Undo %1 &Desfazer %1 &Undo Desfa&zer &Redo %1 &Refazer %1 &Redo &Refazer Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*) Ficheiros Aceites (*.lcd *.ldr *.dat *.mpd);;Todos os Ficheiros (*.*) Merge Model Merged 1 submodel. Merged %1 submodels. Import LEGO Diginal Designer Files (*.lxf);;All Files (*.*) LeoCAD Error loading '%1'. Erro ao carregar '%1'. Supported Files (*.mpd);;All Files (*.*) Ficheiros Aceites (*.mpd);;Todos os Ficheiros (*.*) Supported Files (*.ldr *.dat *.mpd);;All Files (*.*) Ficheiros Aceites (*.ldr *.dat *.mpd);;Todos os Ficheiros (*.*) Error Erro Rel Abs M: %1 %2 R: %3 %4 M: %1 %2 R: %3 {1 %2 ?} {3 %4 ?} Saving files in LCD format is no longer supported, please use the LDR or MPD formats instead. O formato LCD já não é aceite para gravar, escolha os formatos LDR ou MPD. Save changes to '%1'? Gravar as modificações de '%1'? 0 8x {0?} 1/20S 8x {1/20S?} 1/4S 8x {1/4S?} 1F 8x {1F?} 1/2S 8x {1/2S?} 1S 8x {1S?} 2S 8x {2S?} 3S 8x {3S?} 4S 8x {4S?} 8S 8x {8S?} None Nenhum 1B 8x {1B?} 2B 8x {2B?} 4B 8x {4B?} 8B 8x {8B?} lcMinifigDialog Minifig Wizard Assistente Minifig Templates Save... Delete... Apagar... Import... Importar.... Export... Exportar... Save Template Template Name: Template name cannot be empty. Are you sure you want to overwrite the template '%1'? Overwrite Template Are you sure you want to delete the template '%1'? Delete Template Import Templates Minifig Template Files (*.minifig);;All Files (*.*) Error Erro Error reading file '%1': %2 Export Templates Error writing to file '%1': %2 Erro ao escrever no ficheiro '%1': %2 lcModel Pasting Colando LeoCAD Error creating images. Erro ao criar as imagens. Inserting Step Inserir Passo Removing Step Remover Passo No pieces selected. Nenhuma peça seleccionada. Group # Grupo # Grouping Agrupar Ungrouping Desagrupar Editing Groups Editar Grupos Moving Mover Rotating Rodar Setting Part Definir a Peça Moving Camera Mover a Câmara New SpotLight Novo Projector New Camera Nova Câmara Move Mover Rotate Rodar Zoom Zoom Pan Movimento Horizontal Orbit Órbitar Roll Inclinar Insert Inserir New Light Nova Luz Deleting Apagando Cutting Duplicating Pieces Error Erro Error writing to file '%1': %2 Erro ao escrever no ficheiro '%1': %2 Adding Piece Resetting Cameras Removing Key Frames Modifying New Model Novo Modelo No models selected. Inlining Scaling Painting Pintado Showing Pieces Hiding Pieces Editing Camera Changing FOV Renaming Camera Hide Esconder Unhide Replacing Part Look At Olhar Para Changing Properties Mudando Propriedades Nothing to select. Nada a selccionar. Array only has 1 element or less, no pieces added. O quadro só tem um elemento ou menos, nenhuma peça foi adicionada. Array Quadro Minifig # Mnifig # Minifig Mini-figura lcPageSetupDialog Page Setup Size Width: Largura: Height: Altura: Preset: Units: Margins Left: Right: Top: Bottom: lcPartPaletteDialog Part Palettes New... Novo... Delete... Apagar... Rename... Import... Importar.... Move Up Move Down New Part Palette Palette Name: Are you sure you want to delete the palette '%1'? Delete Part Palette Rename Part Palette lcPartSelectionListView Add to Palette None Nenhum Remove from Palette lcPartSelectionWidget Search Parts Options Edit Palettes... No Icons Small Icons Medium Icons Large Icons Extra Large Icons Show Part Names Show Decorated Parts Show Part Aliases List Mode Lock Preview Color Favorites All Parts In Use Submodels lcPiecesLibrary Initializing Loading Parts Library lcPreviewDockWidget Lock Preview Ctrl+L Toolbar Preview Toolbar Loading... Unlock the preview display to enable updates Lock the preview display to disable updates Unlock Preview lcQAboutDialog About LeoCAD Sobre LeoCAD LeoCAD Version 0.00.0 LeoCAD Versão 0.00.0 LeoCAD is a free application for creating virtual LEGO models. LeoCAD é um programa libre para criar modelos LEGO virtuais. System Information Informações do Sistema LeoCAD Version %1 LeoCAD Versão %1 OpenGL Version %1 (GLSL %2) %3 - %4 OpenGL Versão %1 (GLSL %2) %3 - %4 Color Buffer: %1 bits %2 %3 Depth Buffer: %4 bits Stencil Buffer: %5 bits Tampão de Cor: %1 bits %2 %3 Tampão de Profundidade: %4 bits Tampão de Desenho: %5 bits indexed índiciado double buffered tampão duplo LeoCAD Continuous Build %1 Qt Version %1 (compiled with %2) Color Buffer: %1 bits Depth Buffer: %2 bits Stencil Buffer: %3 bits Buffers: %1 Shaders: %2 Framebuffers: %3 BlendFuncSeparate: %4 Anisotropic: %5 Supported Aceite Not supported Recusado Supported (max %1) Aceite (máximo %1) lcQArrayDialog Array Quadro Dimensions Dimensões Offsets Espaços Rotations Rotações Array is empty. O quadro está vazio. lcQCategoryDialog Category Categoria Name: Nome: Keywords: Palavras Chave: Edit Category Editar Categoria New Category Nova Categoria Name cannot be empty. O nome não pode ser vazio. Keywords cannot be empty. As palavras chave não podem ser vazias. lcQEditGroupsDialog Edit Groups Editar Grupos New Group Novo Grupo Group # Grupo # lcQFindDialog Find Procurar Name Nome Part ID ID de Peça Color Cor lcQGroupDialog Group Grupo Name Nome Name cannot be empty. O nome não pode estar vazio. lcQHTMLDialog HTML Options Opções HTML General Geral Output folder: Pasta de saída: ... ... Transparent image background Fundo de imagem transparente Width: Largura: Height: Altura: Index page Página de índice Models Modelos All Models Todos os modelos Current Model and Submodels Current Model Only Apenas o modelo actual Steps Passos Single Page Página única One Step per Page Um passo por página Highlight new parts Destacar as novas peças Parts List Lista das Peças At the end No fim After each step Após cada passo Color: Cor: Create images Criar imagens Output folder cannot be empty. aTem de indicar a pasta de saída. Select Output Folder Selecionar a Pasta de Saída lcQImageDialog Save Image Gravar Imagem File name: Nome do ficheiro: Dimensions Dimensões Step Range Intervalo de Passos All Steps Todos os Passos Current Step Passo Actual Custom Range Intervalo Personalizado From: De: To: Até: Width: Largura: Height: Altura: ... ... Output File cannot be empty. Tem de indicar o ficheiro de saída. Error Erro First step must be between 1 and %1. O primeiro passo tem de ser entre 1 e %1. Last step must be between 1 and %1. O último passo tem de ser entre %1 e 1. Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) Formatos de Imagem Suportados (*.bmp *.png *.jpg);;Ficheiros BMP (*.bmp);;Ficheiros PNG (*.png);;Ficheiros JPEG (*.jpg);;Todos os Ficheiros (*.*) Last step must be greater than first step. O último passo tem de ser superior au primeiro. Please enter a width between 1 and 32768. É favor escolher uma largura entre 1 e 32768. Please enter a height between 1 and 32768. É favor escolher uma altura entre 1 e 32768. Save Image File Exportar Imagem lcQMinifigDialog Minifig Wizard Assistente Minifig Delete... Apagar... lcQModelListDialog Submodels &New... &Novo... D&elete... &Apagar... &Rename... &Mudar o Nome... Export... Exportar... Duplicate... Move &Up &Subir Move &Down &Descer Set Active New Submodel Error Erro The model cannot be empty. Are you sure you want to delete the submodel '%1'? Delete Submodel No submodel selected. Are you sure you want to delete %1 submodels? Rename Submodel Export Submodel LeoCAD LeoCAD Nothing to export. Nada a exportar. Export Model Select Export Folder Duplicate Submodel Copy of Supported Files (*.ldr *.dat);;All Files (*.*) lcQPreferencesDialog Preferences Preferências General Geral Default author name: Nome do autor por omissão: ... ... Custom parts library: Biblioteca de peças personalizada: Mouse sensitivity: Sensibilidade do rato : Check for updates: Procurar actualizações: PO&V-Ray Executable: Never Nunca Once a day Uma vez por dia Once a week Uma vez por semana Fixed direction keys Teclas de direcção fixas Open most recent file on startup Rendering Restituir Edge lines Contornos Axis icon Eixos width largura Anti-aliasing Suavização 2x 2x 4x 4x 8x 8x Shading Mode: Wireframe Flat Shading Default Lights Base Grid Grelha de Base Draw studs Desenhar pregos studs pregos Draw lines every Desenhar linhas cada View Sphere Disabled Small Medium Large Highlight Color: Color: Cor: Text Color: Location: Application Language: Default Czech Deutsch English Français Português Español Color Theme: Dark System Custom Paths Parts Library: Color Configuration: Minifig Settings: &LGEO Library: Restore tab layout Stud Style Mesh LOD Highlight new parts Destacar as novas peças Plain Thin Lines Logo Outline Logo Sharp Top Logo Rounded Top Logo Flattened Logo High Contrast High Contrast with Logo Settings... Contrast Settings... Views Model Views Axis Icon View Sphere: Top Left Top Right Bottom Left Bottom Right Draw origin lines Part Preview Colors Background Fundo Top Color: Bottom Color: So&lid Color &Gradient Interface Inactive View Border: Overlay Color: Active View Border: Camera Name: Axis Icon Labels: Marquee Border: Highlight New Parts Fade Previous Steps Lines Conditional Lines Line Width: Edge Lines Automate Edge Color Marquee Fill: Grid Lines: Studs: Objects Light: Focused: Control Point Focused: Control Point: Selected: Camera: Categories Categorias Parts Library Categories Categorias de Peças na Biblioteca Name Nome Number Número Import... Importar.... Export... Exportar... Reset... Reiniciar... Category Categoria New... Novo... Edit... Editar... Delete... Apagar... Keyboard Teclado Keyboard Shortcuts Atalhos de Teclado Command Commando Shortcut Atalho Search shortcuts Key se&quence: Mouse Mouse Shortcuts Action Shortcut 1 Shortcut 2 Button: None Nenhum Left Left Middle Right Right Modifiers: Control Alt Shift Assign Definir Remove Remover Grid spacing must be greater than 0. O espaço de grelha deve ser superior a 0. Select Parts Library Folder Supported Archives (*.zip *.bin);;All Files (*.*) Select Parts Library Archive Select Color Configuration File Settings Files (*.ldr);;All Files (*.*) Select Minifig Settings File Settings Files (*.ini);;All Files (*.*) Executable Files (*.exe);;All Files (*.*) Ficheiros Executaveis(*.exe);;Todos os Ficheiros (*.*) All Files (*.*) Todos os Ficheiros (*.*) Open POV-Ray Executable Escolher o programa POV-Ray Open LGEO Folder Escolher a Pasta LGEO Reset Colors Would you like to also reset the interface colors to match the color theme? Select Background Color Seleccionar a Cor do Fundo Select Gradient Top Color Select Gradient Bottom Color Select Axes Color Select Text Color Select Marquee Border Color Select Marquee Fill Color Select Overlay Color Select Active View Color Select Inactive View Color Select Fade Color Select Highlight Color Select Grid Stud Color Cor dos Pregos na Grelha Select Grid Line Color Cor das Linhas na Grelha Select View Sphere Color Select View Sphere Text Color Select View Sphere Highlight Color Select Object Selected Color Select Object Focused Color Select Camera Color Select Light Color Select Control Point Color Select Control Point Focused Color Unassigned Por Definir Are you sure you want to delete the category '%1'? Confirmar querer apagar a categoria '%1'? Import Categories Importar Categorias Text Files (*.txt);;All Files (*.*) Ficheiros Texto (*.txt);;Todos os Ficheiros (*.*) Error loading categories file. Erro ao carregar o ficheiro de categorias. Export Categories Exportar Categorias Error saving categories file. Erro ao gravar o ficheiro de categorias. Are you sure you want to load the default categories? Confirmar querer carregar as categorias por omissão? The shortcut '%1' is already assigned to '%2'. Do you want to replace it? Import shortcuts Importar Atalhos de Teclado Error loading keyboard shortcuts file. Erro ao carregar o ficheiro de atalhos de teclado. Export shortcuts Exportar Atalhos de Teclado Error saving keyboard shortcuts file. Erro ao gravar o ficheiro de atalhos de teclado. Are you sure you want to load the default keyboard shortcuts? Confirmar querer carregar os atalhos de teclado por omissão? Left Button Middle Button Right Button Override Shortcut Select POV-Ray Executable This shortcut is already assigned to '%1', do you want to replace it? Import Shortcuts Error loading mouse shortcuts file. Export Shortcuts Error saving mouse shortcuts file. Are you sure you want to load the default mouse shortcuts? lcQPropertiesDialog Properties Propriedades Summary Resumo Author: Autor: Description: Descrição: Comments: Comentários: Measurements: Scene Cena Background Fundo Image Imagem ... ... Set default options for new projects Definir por omissão para os novos projectos Parts Used Peças Utilizadas %1 Properties Propriedades %1 %1 x %2 x %3 cm %4 x %5 x %6 inches %7 x %8 x %9 LDU Part Peça Total Total Select Background Color Seleccionar a Cor do Fundo Select Background Top Color Seleccionar a Cor Superior do Fundo Select Background Bottom Color Seleccionar a Cor Inferior do Fundo Select Background Image Seleccionar a Imagem de Fundo All Image Files (*.png *.jpg *.gif *.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;GIF Files (*.gif);;BMP Files (*.bmp);;All Files (*.*) Todos os Formatos de Imagem (*.bmp *.gif *.png *.jpg);;Ficheiros BMP (*.bmp);;Ficheiros GIF (*.gif);;Ficheiros PNG (*.png);;Ficheiros JPEG (*.jpg);;Todos os Ficheiros (*.*) lcQPropertiesTree Property Propriedade Value Valor Position Posição X X Y Y Z Z Rotation Rotação Visibility Visibilidade Visible Steps Show Mostrar Hide Esconder Appearance Estilo Color Cor Part Peça Target Objectivo Up Subir Orthographic Ortográfico FOV FOV Near Perto Far Longe Name Nome Multiple Objects Selected lcQSelectDialog Select Objects Selecionar Objetos All Todos None Nenhum Invert Inverter lcQUpdateDialog LeoCAD Updates Actualizações do LeoCAD Connecting to update server... A ligar ao servidor de actualizações... <p>There's a newer version of LeoCAD available for download (%1.%2.%3).</p> <p>Existe uma nova versão do LeoCAD em descarregamento (%1.%2.%3).</p> <p>You are using the latest LeoCAD version.</p> <p>Tem a última versão do LeoCAD.</p> <p>There are new parts available.</p> <p>Existem novas peças disponiveis.</p> <p>There are no new parts available at this time.</p> <p>Não há novas peças disponiveis.</p> <p>Visit <a href="https://github.com/leozide/leocad/releases">https://github.com/leozide/leocad/releases</a> to download.</p> Error parsing update information. Erro ao ler a informação de actualização. Error connecting to the update server. Erro ao ligar ao servidor de actualizações. lcRenderDialog Render Settings Width: Largura: Height: Altura: High Medium Low Quality: Output: ... ... Cancel Render Are you sure you want to cancel the current render? Cancel Error Erro Error starting POV-Ray. An error occurred while rendering. Check details or try again. Error writing to file '%1': %2 Erro ao escrever no ficheiro '%1': %2 Error writing to %1 file '%2': %3 Select Output File Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) Formatos de Imagem Suportados (*.bmp *.png *.jpg);;Ficheiros BMP (*.bmp);;Ficheiros PNG (*.png);;Ficheiros JPEG (*.jpg);;Todos os Ficheiros (*.*) lcSelectByColorDialog Select By Color Seleccionar Por Cor Color: Cor: lcSetsDatabaseDialog Sets Database Set Name or Number Search Number Número Name Nome Year Ano Parts Peças Sets Database provided by <a href="https://www.rebrickable.com">Rebrickable</a> Please select a set from the list. Downloading Downloading set inventory Keyword cannot be empty. A palavra chave não podem ser vazia. Searching Connecting to server Error connecting to server. Error downloading set inventory. lcTimelineWidget Step %1 Passo %1 lcView LeoCAD LeoCAD Error creating images. Erro ao criar as imagens. Error Erro Error writing to file '%1': %2 Erro ao escrever no ficheiro '%1': %2 leocad-23.03/resources/leocad_uk.ts000066400000000000000000012131621440571307300172720ustar00rootroot00000000000000 Action File.New File.Open File.Merge File.Save File.SaveAs File.SaveImage File.Import.LDD File.Import.Inventory File.Export.3DS File.Export.COLLADA File.Export.HTML File.Export.BrickLink File.Export.CSV File.Export.POVRay File.Export.Wavefront File.Render File.Instructions File.Print File.PrintPreview File.Recent1 File.Recent2 File.Recent3 File.Recent4 File.Exit Edit.Undo Edit.Redo Edit.Cut Edit.Copy Edit.Paste Edit.PasteSteps Edit.Find Edit.FindNext Edit.FindPrevious Edit.FindAll Edit.Replace Edit.ReplaceNext Edit.ReplaceAll Edit.SelectAll Edit.SelectNone Edit.SelectInvert Edit.SelectByName Edit.SelectSingle Edit.SelectPiece Edit.SelectColor Edit.SelectPieceColor Edit.TransformRelative Edit.TransformAbsolute Edit.TransformToggleRelative Edit.TransformSeparately Edit.TransformTogether Edit.TransformToggleSeparate Edit.Snap.Toggle Edit.SnapMove.XY0 Edit.SnapMove.XY1 Edit.SnapMove.XY2 Edit.SnapMove.XY3 Edit.SnapMove.XY4 Edit.SnapMove.XY5 Edit.SnapMove.XY6 Edit.SnapMove.XY7 Edit.SnapMove.XY8 Edit.SnapMove.XY9 Edit.SnapMove.Z0 Edit.SnapMove.Z1 Edit.SnapMove.Z2 Edit.SnapMove.Z3 Edit.SnapMove.Z4 Edit.SnapMove.Z5 Edit.SnapMove.Z6 Edit.SnapMove.Z7 Edit.SnapMove.Z8 Edit.SnapMove.Z9 Edit.SnapAngle.Toggle Edit.SnapAngle.Angle0 Edit.SnapAngle.Angle1 Edit.SnapAngle.Angle2 Edit.SnapAngle.Angle3 Edit.SnapAngle.Angle4 Edit.SnapAngle.Angle5 Edit.SnapAngle.Angle6 Edit.SnapAngle.Angle7 Edit.SnapAngle.Angle8 Edit.SnapAngle.Angle9 Edit.Transform Edit.TransformAbsoluteTranslation Edit.TransformRelativeTranslation Edit.TransformAbsoluteRotation Edit.TransformRelativeRotation Edit.Tool.Insert Edit.Tool.Light Edit.Tool.Spotlight Edit.Tool.Camera Edit.Tool.Select Edit.Tool.Move Edit.Tool.Rotate Edit.Tool.Delete Edit.Tool.Paint Edit.Tool.ColorPicker Edit.Tool.Zoom Edit.Tool.Pan Edit.Tool.RotateView Edit.Tool.Roll Edit.Tool.ZoomRegion Edit.Cancel View.Preferences View.ZoomIn View.ZoomOut View.ZoomExtents View.LookAt View.MoveForward View.MoveBackward View.MoveLeft View.MoveRight View.MoveUp View.MoveDown View.Viewpoint.Front View.Viewpoint.Back View.Viewpoint.Top View.Viewpoint.Bottom View.Viewpoint.Left View.Viewpoint.Right View.Viewpoint.Home View.Cameras.None View.Cameras.Camera01 View.Cameras.Camera02 View.Cameras.Camera03 View.Cameras.Camera04 View.Cameras.Camera05 View.Cameras.Camera06 View.Cameras.Camera07 View.Cameras.Camera08 View.Cameras.Camera09 View.Cameras.Camera10 View.Cameras.Camera11 View.Cameras.Camera12 View.Cameras.Camera13 View.Cameras.Camera14 View.Cameras.Camera15 View.Cameras.Camera16 View.Time.First View.Time.Previous View.Time.Next View.Time.Last View.Time.InsertBefore View.Time.InsertAfter View.Time.Delete View.Time.AddKeys View.SplitHorizontal View.SplitVertical View.RemoveView View.ResetViews View.Toolbars.Standard View.Toolbars.Tools View.Toolbars.Time View.Toolbars.Parts View.Toolbars.Colors View.Toolbars.Properties View.Toolbars.Timeline View.Toolbars.Preview View.FullScreen View.CloseCurrentTab View.Shade.Wireframe View.Shade.Flat View.Shade.DefaultLights View.Projection.Perspective View.Projection.Orthographic View.ToggleViewSphere View.ToggleAxisIcon View.ToggleGrid View.FadePreviousSteps Piece.Insert Piece.Delete Piece.Duplicate Piece.PaintSelected Piece.ResetPivotPoint Piece.RemoveKeyFrames Piece.ControlPoint.Insert Piece.ControlPoint.Remove Piece.Move.PlusX Piece.Move.MinusX Piece.Move.PlusY Piece.Move.MinusY Piece.Move.PlusZ Piece.Move.MinusZ Piece.Rotate.PlusX Piece.Rotate.MinusX Piece.Rotate.PlusY Piece.Rotate.MinusY Piece.Rotate.PlusZ Piece.Rotate.MinusZ Piece.MinifigWizard Piece.Array Piece.ViewSelectedModel Piece.MoveSelectionToModel Piece.InlineSelectedModels Piece.EditSelectedSubmodel Piece.EditEndSubmodel Piece.Group Piece.Ungroup Piece.GroupAdd Piece.GroupRemove Piece.GroupEdit Piece.HideSelected Piece.HideUnselected Piece.UnhideSelected Piece.UnhideAll Piece.ShowEarlier Piece.ShowLater Model.New Model.Properties Model.List Model.Model01 Model.Model02 Model.Model03 Model.Model04 Model.Model05 Model.Model06 Model.Model07 Model.Model08 Model.Model09 Model.Model10 Model.Model11 Model.Model12 Model.Model13 Model.Model14 Model.Model15 Model.Model16 Model.Model17 Model.Model18 Model.Model19 Model.Model20 Model.Model21 Model.Model22 Model.Model23 Model.Model24 Model.Model25 Model.Model26 Model.Model27 Model.Model28 Model.Model29 Model.Model30 Model.Model31 Model.Model32 Model.Model33 Model.Model34 Model.Model35 Model.Model36 Model.Model37 Model.Model38 Model.Model39 Model.Model40 Help.HomePage Help.BugReport Help.Updates Help.About Menu &New &Open... &Merge... &Save Save &As... Save &Image... &LEGO Digital Designer... Set &Inventory... 3D &Studio... &COLLADA... &HTML... &BrickLink... &CSV... &POV-Ray... &Wavefront... &Render... &Instructions... &Print... Print Pre&view... E&xit &Undo &Redo Cu&t &Copy &Paste Find Ne&xt Find Pre&vious Select &All Select &None Select &Invert Select by Na&me... &Recent 1 &Recent 2 &Recent 3 &Recent 4 Paste with Steps &Find Find All &Replace Replace Next Replace All Single Selection Piece Selection Color Selection Piece and Color Selection Relative Transforms Absolute Transforms Toggle Relative Transforms Rotate Separately Rotate Together Toggle Separate Transforms Move Snap Enabled None 1/20 Stud 1/4 Stud 1 Flat 1/2 Stud 1 Stud 2 Studs 3 Studs 4 Studs 8 Studs 1 Brick 2 Bricks 4 Bricks 8 Bricks Rotation Snap Enabled 1 Degree 5 Degrees 15 Degrees 22.5 Degrees 30 Degrees 45 Degrees 60 Degrees 90 Degrees 180 Degrees Transform ТранÑформувати Absolute Translation Relative Translation Absolute Rotation Relative Rotation Insert Light Spotlight Camera Select Виділити Move ПереміÑтити Rotate Покрутити Delete Видалити Paint Фарбувати Color Picker Zoom МаÑштабувати Pan Подвинути Rotate View Roll Ðахилити Zoom Region Cancel Action P&references... Zoom In Zoom Out Zoom E&xtents Look At Move Forward Move Backward Move Left Move Right Move Up Move Down &Front &Back &Top B&ottom &Left &Right &Home Camera 1 Camera 2 Camera 3 Camera 4 Camera 5 Camera 6 Camera 7 Camera 8 Camera 9 Camera 10 Camera 11 Camera 12 Camera 13 Camera 14 Camera 15 Camera 16 First Previous Next Last Insert Before Insert After Remove Step Add Keys Split &Horizontal Split &Vertical Re&move View Rese&t Views Standard Tools ІнтÑтрументи Time Parts Блоків Colors Properties ВлаÑтивоÑті Timeline Preview &Full Screen Close &Tab &Wireframe &Flat Shading &Default Lights &Perspective &Orthographic View Sphere Сфера візуалізації Axis Icon Base Grid Базова Ñітка Fade Previous Steps &Insert &Delete &Duplicate &Paint Selected Reset &Pivot Point Remove &Key Frames Insert Control Point Remove Control Point Move +X Move -X Move +Y Move -Y Move +Z Move -Z Rotate +X Rotate -X Rotate +Y Rotate -Y Rotate +Z Rotate -Z Minifig &Wizard... A&rray... Open Selected Model Move to New Model... Inline Selected Models Edit Selected Submodel End Submodel Editing &Group... &Ungroup &Add to Group Re&move from Group &Edit Groups... &Hide Selected Hide &Unselected &Unhide Selected U&nhide All Show Earlier Show Later New Submodel... Prope&rties... Submodels... Model 1 Model 2 Model 3 Model 4 Model 5 Model 6 Model 7 Model 8 Model 9 Model 10 Model 11 Model 12 Model 13 Model 14 Model 15 Model 16 Model 17 Model 18 Model 19 Model 20 Model 21 Model 22 Model 23 Model 24 Model 25 Model 26 Model 27 Model 28 Model 29 Model 30 Model 31 Model 32 Model 33 Model 34 Model 35 Model 36 Model 37 Model 38 Model 39 Model 40 LeoCAD &Home Page Report a Bug Check for &Updates... &About... Insert Step Before Insert Step After Move Selection Here Set Current Step Mouse NewPiece ÐовийБлок NewPointLight ÐовеТочковеСвітло NewSpotLight ÐовеПрожекторнеСвітло NewCamera ÐоваКамера Select Виділити Move ПереміÑтити Rotate Покрутити Delete Видалити Paint Фарбувати ColorPicker Zoom МаÑштабувати Pan Подвинути Orbit Прокрутити Roll Ðахилити ZoomRegion МаÑштабуватиРегіон Project New Model.ldr нова_модель.ldr New Model.mpd нова_модель.mpd Submodel # підмодель_# Submodel Name: Ðазва підмоделі: Empty Name ÐŸÐ¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð°Ð·Ð²Ð° The submodel name cannot be empty. Ðазва підмоделі не може бути порожньою. Duplicate Submodel Дублювати підмодель A submodel named '%1' already exists, please enter a unique name. Підмодель з назвою '%1' вже Ñ–Ñнує. Оберіть унікальну назву. New Submodel Ðова підмодель Error Помилка Error reading file '%1': %2 Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° '%1': %2 Error loading file '%1': File format is not recognized. Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° '%1': Формат файла не розпізнано. Error writing to file '%1': %2 Помилка запиÑу у файл '%1': %2 Merged Об'єднано LeoCAD LeoCAD Nothing to export. Ðемає чого екÑпортувати. Export 3D Studio ЕкÑпортувати 3D Studio 3DS Files (*.3ds);;All Files (*.*) Файли 3DS (*.3ds);;УÑÑ– файли (*.*) Could not open file '%1' for writing. Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл '%1' Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу. Export BrickLink ЕкÑпортувати BrickLink XML Files (*.xml);;All Files (*.*) Файли XML (*.xml);;УÑÑ– файли (*.*) Export COLLADA ЕкÑпортувати COLLADA COLLADA Files (*.dae);;All Files (*.*) Файли COLLADA (*.dae);;УÑÑ– файли (*.*) Export CSV ЕкÑпортувати CSV CSV Files (*.csv);;All Files (*.*) Файли CSV (*.csv);;УÑÑ– файли (*.*) Error creating images. Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ. Export POV-Ray ЕкÑпортувати POV-Ray POV-Ray Files (*.pov);;All Files (*.*) Файли POV-Ray (*.pov);;УÑÑ– файли (*.*) Could not find LGEO files in folder '%1'. Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ файли LGEO у теці '%1'. Export Wavefront ЕкÑпортувати Wavefront Wavefront Files (*.obj);;All Files (*.*) Файли Wavefront (*.obj);;УÑÑ– файли (*.*) QApplication Group # Група # Solid Colors Colors Кольори Ðепрозорі кольори Translucent Colors Colors Кольори Прозорі кольори Special Colors Colors Кольори Спеціальні кольори Solid Colors Translucent Colors Special Colors QMessageBox Error Помилка QObject LeoCAD LeoCAD Could not open file '%1' for writing. Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл '%1' Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу. Status Create a new model Open an existing model Merge the contents of another file with the current one Save the current model Save the current model with a new name Save a picture of the current view Import a file in LEGO Digital Designer LXF format Import all parts from an official set Export the current model in 3D Studio 3DS format Export the current model in COLLADA DAE format Create an HTML page for the current model Export a list of parts used in BrickLink XML format Export a list of parts used in comma delimited file format Export the current model in POV-Ray format Export the current model in Wavefront OBJ format Render the current model using POV-Ray Configure instructions layout Print the current model Display how the model would look if printed Open this model Quit the application; prompts to save model Undo the last action Redo the previously undone action Cut the selection and put it on the Clipboard Copy the selection and put it on the Clipboard Select all pieces in the model De-select everything Invert the current selection set Select objects by name Insert Clipboard contents in the current step Insert Clipboard contents in their original steps Find piece Find next piece Find previous piece Find all pieces that match the search criteria Replace piece Replace next piece Replace all pieces that match the search criteria Select one piece at a time Select all pieces of the same type Select all pieces of the same color Select all pieces of the same type and color Move and rotate objects relative to the one that has focus Move and rotate objects in absolute coordinates Toggle moving and rotating objects relative to the one that has focus Rotate selected pieces separately Rotate selected pieces together Toggle rotating selected pieces separately Toggle snap axes Do not snap movement along the XY plane Snap movement along the XY plane to 1/20 stud Snap movement along the XY plane to 1/4 stud Snap movement along the XY plane to 1 flat Snap movement along the XY plane to 1/2 stud Snap movement along the XY plane to 1 stud Snap movement along the XY plane to 2 studs Snap movement along the XY plane to 3 studs Snap movement along the XY plane to 4 studs Snap movement along the XY plane to 8 studs Do not snap movement along the Z axis Snap movement along the Z axis to 1/20 stud Snap movement along the Z axis to 1/4 stud Snap movement along the Z axis to 1 flat Snap movement along the Z axis to 1/2 stud Snap movement along the Z axis to 1 stud Snap movement along the Z axis to 1 brick Snap movement along the Z axis to 2 bricks Snap movement along the Z axis to 4 bricks Snap movement along the Z axis to 8 bricks Snap rotations to fixed intervals Do not snap rotations Snap rotations to 1 degree Snap rotations to 5 degrees Snap rotations to 15 degrees Snap rotations to 22.5 degrees Snap rotations to 30 degrees Snap rotations to 45 degrees Snap rotations to 60 degrees Snap rotations to 90 degrees Snap rotations to 180 degrees Apply transform to selected objects Switch to absolute translation mode when applying transforms Switch to relative translation mode when applying transforms Switch to absolute rotation mode when applying transforms Switch to relative rotation mode when applying transforms Add new pieces to the model Add new omni light sources to the model Add new spotlights to the model Create a new camera Select objects (hold the CTRL key down or drag the mouse to select multiple objects) Move selected objects Rotate selected pieces Delete objects Change piece color Get piece color Zoom in or out Pan the current view Rotate the current view Roll the current view Zoom into a region of the screen Cancel current mouse action Change program settings Zoom in Zoom out Fit all pieces in current the view (hold the CTRL key down to zoom all views) Rotate view so selected pieces are at center Move the current view forward Move the current view backward Move the current view to the left Move the current view to the right Move the current view up Move the current view down View model from the front View model from the back View model from the top View model from the bottom View model from the left View model from the right View model from the default position Do not use a camera Use this camera Go to the first step of the model Go to the previous step Go to the next step Go to the last step of the model Insert a new step before the current step Insert a new step after the current step Remove current step Toggle adding new animation keys Split the current view horizontally Split the current view vertically Remove the current view Reset all views Toggle the Standard Toolbar Toggle the Tools Toolbar Toggle the Time Toolbar Toggle the Parts Toolbar Toggle the Colors Toolbar Toggle the Properties Toolbar Toggle the Timeline Toolbar Toggle the Preview Toolbar Toggle fullscreen mode Close current tab Display the scene as wireframe Display the scene without any shading or lights Display the scene with the default lights Set the current camera to use a perspective projection Set the current camera to use an orthographic projection Toggle the view sphere Toggle axis icon Toggle grid Toggle fading previous model steps Add a new piece to the model Delete selected objects Create a copy of the selected pieces Change the color of the selected pieces Reset the pivot point of the selected pieces to their origin Remove all key frames from the selected pieces Insert a new control point Remove the selected control point Move selected objects along the X axis Move selected objects along the Y axis Move selected objects along the Z axis Rotate selected objects along the X axis Rotate selected objects along the Y axis Rotate selected objects along the Z axis Add a new minifig to the model Make copies of the selected pieces Open the model referenced by the selected piece in a new tab Move the selected pieces to a new model and replace them with a reference to the model Insert the contents of the selected model references into the current model Edit the currently selected submodel in-place End in-place submodel editing Group selected pieces together Ungroup selected group Add focused piece to selected group Remove focused piece from group Edit groups Hide selected objects Hide objects that are not selected Show hidden objects that are selected Show all hidden objects Show selected pieces one step earlier Show selected pieces one step later Create a new submodel Display the properties of the current submodel Show a list of all submodels Switch to this submodel Open LeoCAD's home page on the internet using your default web browser Open LeoCAD's bug report form on your default web browser Check if a newer LeoCAD version or parts library has been released Display program version number and system information Move the selected parts into this step View the model at this point in the timeline ViewName Left Зліва Right Справа Back Ззаду Front Спереду Top Згори Bottom Знизу lcApplication Not enough parameters for the '%1' option. Invalid parameter value specified for the '%1' option: '%2'. The file '%1' is not readable. Invalid parameter value(s) specified for the '%1' option: limits are +/- 360. Invalid parameter value(s) specified for the '%1' option. Invalid parameter value(s) specified for the '%1' option: requirements are: 1 <= <near> < <far>. High contrast stud style is required for the '%1' option but is not enabled. Automate edge color is required for the '%1' option but is not enabled. LeoCAD Continuous Build %1 LeoCAD Continuous Build %1 LeoCAD Version %1 LeoCAD ВерÑÑ–Ñ %1 Compiled %1 Usage: leocad [options] [file] [options] can be: -l, --libpath <path>: Set the Parts Library location to path. -i, --image <outfile.ext>: Save a picture in the format specified by ext and exit. -w, --width <width>: Set the picture width. -h, --height <height>: Set the picture height. -f, --from <step>: Set the first step to save pictures. -t, --to <step>: Set the last step to save pictures. -s, --submodel <submodel>: Set the active submodel. -c, --camera <camera>: Set the active camera. -ss, --stud-style <id>: Set the stud style 0=No style, 1=LDraw single wire, 2=LDraw double wire, 3=LDraw raised floating, 4=LDraw raised rounded, 5=LDraw subtle rounded, 6=LEGO no logo, 7=LEGO single wire. --viewpoint <front|back|left|right|top|bottom|home>: Set the viewpoint. --camera-angles <latitude> <longitude>: Set the camera angles in degrees around the model. --camera-position <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector. --camera-position-ldraw <x> <y> <z> <tx> <ty> <tz> <ux> <uy> <uz>: Set the camera position, target and up vector using LDraw coordinates. --orthographic: Render images using an orthographic projection. --fov <degrees>: Set the vertical field of view used to render images (< 180). --zplanes <near> <far>: Set the near and far clipping planes used to render images (1 <= <near> < <far>). --fade-steps: Render parts from prior steps faded. --no-fade-steps: Do not render parts from prior steps faded. --fade-steps-color <rgba>: Renderinng color for prior step parts (#AARRGGBB). --highlight: Highlight parts in the steps they appear. --no-highlight: Do not highlight parts in the steps they appear. --highlight-color: Renderinng color for highlighted parts (#AARRGGBB). --shading <wireframe|flat|default|full>: Select shading mode for rendering. --line-width <width>: Set the width of the edge lines. --aa-samples <count>: AntiAliasing sample size (1, 2, 4, or 8). -scc, --stud-cylinder-color <#AARRGGBB>: High contrast stud cylinder color. -ec, --edge-color <#AARRGGBB>: High contrast edge color. -bec, --black-edge-color <#AARRGGBB>: High contrast edge color for black parts. -dec, --dark-edge-color <#AARRGGBB>: High contrast edge color for dark color parts. -aec, --automate-edge-color: Enable automatically adjusted edge colors. -cc, --color-contrast <float>: Color contrast value between 0.0 and 1.0. -ldv, --light-dark-value <float>: Light/Dark color value between 0.0 and 1.0. -obj, --export-wavefront <outfile.obj>: Export the model to Wavefront OBJ format. -3ds, --export-3ds <outfile.3ds>: Export the model to 3D Studio 3DS format. -dae, --export-collada <outfile.dae>: Export the model to COLLADA DAE format. -html, --export-html <folder>: Create an HTML page for the model. -v, --version: Output version information and exit. -?, --help: Display this help message and exit. Unknown option: '%1'. High contrast stud and edge color settings are ignored when -aec or --automate-edge-color is set. --viewpoint is ignored when --camera is set. --orthographic is ignored when --camera is set. --camera-angles is ignored when --camera is set. --camera-position is ignored when --camera is set. --camera-angles is ignored when --viewpoint is set. --camera-position is ignored when --viewpoint is set. --camera-position is ignored when --camera-angles is set. No file name specified. Error creating OpenGL context. LeoCAD could not find a compatible Parts Library so only a small number of parts will be available. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD не може знайти ÑуміÑні бібліотеки блоків тож доÑтупним буде лише невеликий набор блоків. Відвідайте https://www.leocad.org Ð´Ð»Ñ Ð´Ñ–Ð·Ð½Ð°Ñ‚Ð¸ÑÑ Ñк завантажити Ñ– вÑтановити бібліотеки блоків. LeoCAD could not load Parts Library. Please visit https://www.leocad.org for information on how to download and install a library. LeoCAD не може завантажити бібліотеку блоків. Відвідайте https://www.leocad.org Ð´Ð»Ñ Ð´Ñ–Ð·Ð½Ð°Ñ‚Ð¸ÑÑ Ñк завантажити Ñ– вÑтановити бібліотеки блоків. LeoCAD LeoCAD Error: model '%1' does not exist. Saved '%1'. Some changes will only take effect the next time you start LeoCAD. Parts library and Anti-aliasing changes will only take effect the next time you start LeoCAD. Зміна бібліотек блоків та налаштувань Ð·Ð³Ð»Ð°Ð´Ð¶ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñтупить в Ñилу лише піÑÐ»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑку LeoCAD. Parts library changes will only take effect the next time you start LeoCAD. Зміна бібліотек блоків вÑтупить в Ñилу лише піÑÐ»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑку LeoCAD. Anti-aliasing changes will only take effect the next time you start LeoCAD. Зміна налаштувань Ð·Ð³Ð»Ð°Ð´Ð¶ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñтупить в Ñилу лише піÑÐ»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑку LeoCAD. lcAutomateEdgeColorDialog Color Preferences Edge Colors Contrast: Set the amount of contrast - 0.50 is midway. Reset Light/Dark Value: Saturation: Set to classify where color values are light or dark - e.g. Dark Bluish Gray (72) is light at 0.39. Set to specify amount of edge color tint or shade from the saturation adjusted part color High Contrast Stud Cylinder Color: Parts Edge Color: Black Parts Edge Color: Dark Parts Edge Color: Select Stud Cylinder Color Select Part Edge Color Automate edge color appears to be enabled.<br>Black parts edge color will not be accessible.<br>Do you want to continue? Select Black Edge Color Automate edge color appears to be enabled.<br>Dark parts edge color will not be accessible.<br>Do you want to continue? Select Dark Edge Color lcFindReplaceWidget Find: Replace: lcInstructions Show Step Number Show Parts List Font: Text Color: Колір текÑту: Background Color: Border Color: lcInstructionsDialog Instructions Page Settings Print Vertical Horizontal Page %1 lcInstructionsPageListWidget Pages Page Setup lcInstructionsPropertiesWidget Properties ВлаÑтивоÑті Default Current Model Current Step Only Current Step Forward Scope: Preset: Select Step Number Color Select Step Background Color Select Parts List Background Color Select Parts List Border Color Select Parts List Text Color Select Step Number Font Select Parts List Font Step Properties Step Number Properties Parts List Properties lcMainWindow New Model Ðова модель Open Model Відкрити модель Save Model Зберегти модель Transform ТранÑформувати C&ameras &Камери &Viewpoints &Точки зору Projection ÐŸÑ€Ð¾ÐµÐºÑ†Ñ–Ñ Sh&ading За&Ñ‚Ñ–Ð½ÐµÐ½Ð½Ñ Tools ІнтÑтрументи &File &Файл &Import &Імпорт &Export &ЕкÑпорт &Edit &Редагувати &View &ВиглÑд Ste&p Кр&ок T&oolbars &Панелі інÑтрументів &Piece &Блок Sub&model Під&модель &Help &Довідка Selection Mode Режим Ð²Ð¸Ð´Ñ–Ð»ÐµÐ½Ð½Ñ Change selection mode Змінити режим Ð²Ð¸Ð´Ñ–Ð»ÐµÐ½Ð½Ñ Transform Options Snap XY ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ XY Snap Z ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Z Snap Menu Меню Ð¿Ñ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Movement Snap ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Snap translations to fixed intervals Snap Angle Menu Rotation Snap Snap rotations to fixed intervals Standard Time Parts Блоків Colors Properties ВлаÑтивоÑті Timeline Preview Close Other Tabs The file '%1' has been modified by another application, do you want to reload it? File Changed %1 (ID: %2) %n Object(s) selected - %1 (ID: %2) in group '%1' Step %1 Крок %1 &Undo %1 &Undo &Redo %1 &Redo Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*) Merge Model LeoCAD LeoCAD Merged 1 submodel. Merged %1 submodels. Import LEGO Diginal Designer Files (*.lxf);;All Files (*.*) Supported Files (*.mpd);;All Files (*.*) Supported Files (*.ldr *.dat *.mpd);;All Files (*.*) Error Помилка Rel Abs M: %1 %2 R: %3 %4 Saving files in LCD format is no longer supported, please use the LDR or MPD formats instead. Save changes to '%1'? 0 8x {0?} 1/20S 8x {1/20S?} 1/4S 8x {1/4S?} 1F 8x {1F?} 1/2S 8x {1/2S?} 1S 8x {1S?} 2S 8x {2S?} 3S 8x {3S?} 4S 8x {4S?} 8S 8x {8S?} None 1B 8x {1B?} 2B 8x {2B?} 4B 8x {4B?} 8B 8x {8B?} lcMinifigDialog Minifig Wizard МайÑÑ‚ÐµÑ€Ð½Ñ ÐœÑ–Ð½Ñ–Ñ„Ñ–Ð³ÑƒÑ€ Templates Шаблони Save... Зберегти... Delete... Видалити... Import... Імпортувати... Export... ЕкÑпортувати... Save Template Зберегти шаблон Template Name: Ðазва шаблона: Template name cannot be empty. Шаблон не може бути порожнім. Are you sure you want to overwrite the template '%1'? Ви впевнені що хочете перезапиÑати шаблон '%1'? Overwrite Template ПерезапиÑати шаблон Are you sure you want to delete the template '%1'? Ви впевнені що хочете видалити шаблон '%1'? Delete Template Видалити шаблон Import Templates Minifig Template Files (*.minifig);;All Files (*.*) Error Помилка Error reading file '%1': %2 Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° '%1': %2 Export Templates Error writing to file '%1': %2 Помилка запиÑу у файл '%1': %2 lcModel Group # Група # Cutting Pasting Duplicating Pieces LeoCAD LeoCAD Error creating images. Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ. Error Помилка Error writing to file '%1': %2 Помилка запиÑу у файл '%1': %2 Inserting Step Removing Step No pieces selected. Grouping Ungrouping Editing Groups Adding Piece Resetting Cameras Deleting Removing Key Frames Modifying New Model Ðова модель No models selected. Inlining Moving Rotating Scaling Painting Setting Part Showing Pieces Hiding Pieces Editing Camera Changing FOV Renaming Camera Hide Приховати Unhide Replacing Part New SpotLight New Camera Move ПереміÑтити Rotate Покрутити Zoom МаÑштабувати Pan Подвинути Orbit Прокрутити Roll Ðахилити Insert New Light Look At Moving Camera Changing Properties Nothing to select. Ðемає чого обирати. Array only has 1 element or less, no pieces added. Уточнити МаÑив міÑтить лише 1 елемент або й менше, не додано блоків. Array МаÑив Minifig # Мініфігура # Minifig Мініфігура lcPageSetupDialog Page Setup Size Width: Ширина: Height: ВиÑота: Preset: Units: Margins Left: Right: Top: Bottom: lcPartPaletteDialog Part Palettes New... Ðова... Delete... Видалити... Rename... Import... Імпортувати... Move Up Move Down New Part Palette Palette Name: Are you sure you want to delete the palette '%1'? Delete Part Palette Rename Part Palette lcPartSelectionListView No Icons Без іконок Small Icons Малі іконки Medium Icons Середні іконки Large Icons Великі іконки Extra Large Icons Дуже великі іконки Show Part Names Показувати назви блоків Show Decorated Parts Показувати декоровані блоки List Mode Режим ÑпиÑку Lock Preview Color ЗафікÑувати колір попереднього переглÑду Add to Palette None Remove from Palette lcPartSelectionWidget Search Parts Пошук блоків Options Edit Palettes... No Icons Без іконок Small Icons Малі іконки Medium Icons Середні іконки Large Icons Великі іконки Extra Large Icons Дуже великі іконки Show Part Names Показувати назви блоків Show Decorated Parts Показувати декоровані блоки Show Part Aliases List Mode Режим ÑпиÑку Lock Preview Color ЗафікÑувати колір попереднього переглÑду Favorites All Parts УÑÑ– блоки In Use Parts In Use ВикориÑтані блоки Submodels Підмоделі lcPiecesLibrary Initializing Ð†Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ Loading Parts Library Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ¸ блоків lcPreviewDockWidget Lock Preview Ctrl+L Toolbar Preview Toolbar Loading... Unlock the preview display to enable updates Lock the preview display to disable updates Unlock Preview lcQAboutDialog About LeoCAD Про LeoCAD LeoCAD Version 0.00.0 LeoCAD ВерÑÑ–Ñ 0.00.0 LeoCAD is a free application for creating virtual LEGO models. LeoCAD Ñ” вільною програмою Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ñ–Ñ€Ñ‚ÑƒÐ°Ð»ÑŒÐ½Ð¸Ñ… моделей LEGO. System Information СиÑтемна Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ LeoCAD Continuous Build %1 LeoCAD Continuous Build %1 LeoCAD Version %1 LeoCAD ВерÑÑ–Ñ %1 Qt Version %1 (compiled with %2) Qt Version %1 (compiled with %2) OpenGL Version %1 (GLSL %2) %3 - %4 OpenGL Version %1 (GLSL %2) %3 - %4 Color Buffer: %1 bits Depth Buffer: %2 bits Stencil Buffer: %3 bits Buffers: %1 Shaders: %2 Framebuffers: %3 BlendFuncSeparate: %4 Anisotropic: %5 Color Buffer: %1 bits %2 %3 Depth Buffer: %4 bits Stencil Buffer: %5 bits Color Buffer: %1 bits %2 %3 Depth Buffer: %4 bits Stencil Buffer: %5 bits indexed indexed double buffered double buffered GL_ARB_vertex_buffer_object extension: %1 GL_ARB_framebuffer_object extension: %2 GL_EXT_framebuffer_object extension: %3 GL_EXT_blend_func_separate: %4 GL_EXT_texture_filter_anisotropic extension: %5 GL_ARB_vertex_buffer_object extension: %1 GL_ARB_framebuffer_object extension: %2 GL_EXT_framebuffer_object extension: %3 GL_EXT_blend_func_separate: %4 GL_EXT_texture_filter_anisotropic extension: %5 Supported Supported Not supported Not supported Supported (max %1) Supported (max %1) lcQArrayDialog Array МаÑив Dimensions Розміри Offsets ВідÑтупи Rotations ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Array is empty. МаÑив порожній. lcQCategoryDialog Category ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ Name: Ðазва: Keywords: Ключові Ñлова: Edit Category Редагувати категорію New Category Ðова ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ Name cannot be empty. Ðазва не може бути порожньою. Keywords cannot be empty. Ключові Ñлова не можуть бути порожніми. lcQEditGroupsDialog Edit Groups Редагувати групи New Group Ðова група Group # Група # lcQFindDialog Find Пошук Name Ðазва Part ID ID блока Color Колір lcQGroupDialog Group Група Name Ðазва Name cannot be empty. Ðазва не може бути порожньою. lcQHTMLDialog HTML Options ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ HTML General ОÑновне Output folder: Вихідна тека: ... ... Transparent image background Прозорий фон Ð´Ð»Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½ÑŒ Models Моделі All Models УÑÑ– моделі Current Model and Submodels Поточна модель Ñ– підмоделі Current Model Only Лише поточна модель Steps Кроки Single Page Єдина Ñторінка One Step per Page Один крок на Ñторінку Index page ІндекÑна Ñторінка Width: Ширина: Height: ВиÑота: Highlight new parts ПідÑвічувати нові блоки Parts List СпиÑок блоків Color: Колір: After each step ПіÑÐ»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ кроку Create images Створювати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ At the end У кінці Output folder cannot be empty. Вихідна теки не може бути порожньою. Select Output Folder Обрати вихідну теку lcQImageDialog Save Image Зберегти Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ File name: Ðазва файла: ... ... Dimensions Розміри Width: Ширина: Height: ВиÑота: Step Range Діапазон кроків All Steps УÑÑ– кроки Current Step Поточний крок Custom Range Інший діапазон From: Від: To: До: Error Помилка Output File cannot be empty. Вихідний файл не може бути порожнім. Please enter a width between 1 and 32768. Визначте ширину від 1 до 32768. Please enter a height between 1 and 32768. Визначте виÑоту від 1 до 32768. First step must be between 1 and %1. Початковий крок має бути між 1 та %1. Last step must be between 1 and %1. Кінцевий крок має бути між 1 та %1. Last step must be greater than first step. Кінцевий крок має бути більшим за початковий крок. Save Image File Зберегти файл Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) УÑÑ– файли зображень (*.bmp *.png *.jpg);;BMP файли (*.bmp);;PNG файли (*.png);;JPEG файли (*.jpg);;УÑÑ– файли (*.*) lcQMinifigDialog Minifig Wizard МайÑÑ‚ÐµÑ€Ð½Ñ ÐœÑ–Ð½Ñ–Ñ„Ñ–Ð³ÑƒÑ€ Templates Шаблони Save... Зберегти... Delete... Видалити... Save Template Зберегти шаблон Template Name: Ðазва шаблона: Template name cannot be empty. Шаблон не може бути порожнім. Are you sure you want to overwrite the template '%1'? Ви впевнені що хочете перезапиÑати шаблон '%1'? Overwrite Template ПерезапиÑати шаблон Are you sure you want to delete the template '%1'? Ви впевнені що хочете видалити шаблон '%1'? Delete Template Видалити шаблон lcQModelListDialog Submodels Підмоделі &New... &Ðова... D&elete... Ви&далити... &Rename... &Перейменувати... Export... ЕкÑпортувати... Duplicate... Move &Up ПереміÑтити в&гору Move &Down ПереміÑтити в&низ Set Active Ðктивувати New Submodel Ðова підмодель Error Помилка The model cannot be empty. Модель не може бути порожньою. Are you sure you want to delete the submodel '%1'? Ви впевнені що хочете видалити підмодель '%1'? Delete Submodel Видалити підмодель No submodel selected. Are you sure you want to delete %1 submodels? Rename Submodel Перейменувати модель Export Submodel LeoCAD LeoCAD Nothing to export. Ðемає чого екÑпортувати. Export Model Select Export Folder Duplicate Submodel Дублювати підмодель Copy of Save Model Зберегти модель Supported Files (*.ldr *.dat);;All Files (*.*) Підтримувані файли (*.ldr *.dat);;УÑÑ– файли (*.*) lcQPreferencesDialog Preferences ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ General ОÑновне Default author name: Типове ім'Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð°: Custom parts library: Бібліотека блоків: PO&V-Ray Executable: Програма PO&V-Ray: ... ... &LGEO Path: Тека &LGEO: Check for updates: ПеревірÑти оновленнÑ: Never Ðіколи Once a day Раз на день Once a week Раз на тиждень Fixed direction keys Уточнити Кнопки фікÑованих напрÑмків Open most recent file on startup Відкрити нещодавній файл під Ñ‡Ð°Ñ Ð·Ð°Ð¿ÑƒÑку Rendering Ð’Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Edge lines Лінії контурів 2x 2x 4x 4x 8x 8x Axis icon Іконка віÑей Anti-aliasing Ð—Ð³Ð»Ð°Ð´Ð¶ÑƒÐ²Ð°Ð½Ð½Ñ width пікÑелів (ширина) Shading Mode: Режим відображеннÑ: Wireframe Ðрматура Flat Shading ПлоÑке оÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Default Lights Типове оÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Base Grid Базова Ñітка Draw studs Відображати контури шипів studs шипів Draw lines every Відображати лінії кожні View Sphere Сфера візуалізації Disabled Вимкнено Small Малий Medium Середній Large Великий Highlight Color: Колір підÑвічуваннÑ: Size: Розмір: Color: Колір: Text Color: Колір текÑту: Location: ПоложеннÑ: Application Language: Default Czech Deutsch English Français Português Español Color Theme: Dark System Custom Paths Parts Library: Color Configuration: Minifig Settings: &LGEO Library: Restore tab layout Stud Style Mesh LOD Highlight new parts ПідÑвічувати нові блоки Plain Thin Lines Logo Outline Logo Sharp Top Logo Rounded Top Logo Flattened Logo High Contrast High Contrast with Logo Settings... Contrast Settings... Views Model Views Axis Icon View Sphere: Top Left Вгорі ліворуч Top Right Вгорі праворуч Bottom Left Внизу ліворуч Bottom Right Внизу праворуч Draw origin lines Part Preview Colors Background Фон Top Color: Bottom Color: So&lid Color Су&цільний колір &Gradient &Градієнт Interface Inactive View Border: Overlay Color: Active View Border: Camera Name: Axis Icon Labels: Marquee Border: Highlight New Parts Fade Previous Steps Lines Conditional Lines Line Width: Edge Lines Automate Edge Color Marquee Fill: Grid Lines: Studs: Objects Light: Focused: Control Point Focused: Control Point: Selected: Camera: Categories Категорії Parts Library Categories Категорії бібліотеки блоків Name Ðазва Number Ðомер Import... Імпортувати... Export... ЕкÑпортувати... Reset... Скинути... Category ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ New... Ðова... Edit... Редагувати... Delete... Видалити... Keyboard Клавіатура Keyboard Shortcuts Комбінації клавіш клавіатури Command Команда Shortcut ÐšÐ¾Ð¼Ð±Ñ–Ð½Ð°Ñ†Ñ–Ñ ÐºÐ»Ð°Ð²Ñ–Ñˆ Search shortcuts Key se&quence: &ПоÑлідовніÑть клавіш: Assign Ð’Ñтановити Remove Видалити Mouse Миша Mouse Shortcuts Комбінації клавіш миші Action Ð”Ñ–Ñ Shortcut 1 ÐšÐ¾Ð¼Ð±Ñ–Ð½Ð°Ñ†Ñ–Ñ ÐºÐ»Ð°Ð²Ñ–Ñˆ 1 Shortcut 2 ÐšÐ¾Ð¼Ð±Ñ–Ð½Ð°Ñ†Ñ–Ñ ÐºÐ»Ð°Ð²Ñ–Ñˆ 2 Button: Клавіша: None Ðемає Left Вліво Middle Ð¡ÐµÑ€ÐµÐ´Ð½Ñ Right Вправо Modifiers: Модифікатори: Control Ctrl Alt Alt Shift Shift Mouse sensitivity: ЧутливіÑть миші: Grid spacing must be greater than 0. Розмір клітинок Ñітки має бути більше 0. Select Parts Library Folder Оберіть теку з бібліотекою блоків Select Parts Library Archive Оберіть архів з бібліотекою блоків Supported Archives (*.zip *.bin);;All Files (*.*) Підтримувані архіви (*.zip *.bin);;УÑÑ– файли (*.*) Select Color Configuration File Settings Files (*.ldr);;All Files (*.*) Select Minifig Settings File Settings Files (*.ini);;All Files (*.*) Executable Files (*.exe);;All Files (*.*) Виконувані файли (*.exe);;УÑÑ– файли (*.*) All Files (*.*) УÑÑ– файли (*.*) Open POV-Ray Executable Показати Ñ€Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸ POV-Ray Open LGEO Folder Показати Ñ€Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÐ¸ LGEO Reset Colors Would you like to also reset the interface colors to match the color theme? Select Background Color Визначте колір фону Select Gradient Top Color Select Gradient Bottom Color Select Axes Color Select Text Color Select Marquee Border Color Select Marquee Fill Color Select Overlay Color Select Active View Color Select Inactive View Color Select Fade Color Select Highlight Color Select Grid Stud Color Визначте колір контурів шипів Ñітки Select Grid Line Color Визначте колір ліній Ñітки Select View Sphere Color Визначте колір Ñфери візуалізації Select View Sphere Text Color Визначте колір текÑту Ñфери візуалізації Select View Sphere Highlight Color Визначте колір підÑÐ²Ñ–Ñ‡ÑƒÐ²Ð°Ð½Ð½Ñ Ñфери візуалізації Select Object Selected Color Select Object Focused Color Select Camera Color Select Light Color Select Control Point Color Select Control Point Focused Color Unassigned Ðе вÑтановлено Are you sure you want to delete the category '%1'? Ви впевнені що хочете видалити категорію '%1'? Import Categories Імпортувати категорії Text Files (*.txt);;All Files (*.*) ТекÑтові файли (*.txt);;УÑÑ– файли (*.*) Error loading categories file. Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° категорій. Export Categories ЕкÑпортувати категорії Error saving categories file. Помилка Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° категорій. Are you sure you want to load the default categories? Ви впевнені що хочете вÑтановити типові категорії? The shortcut '%1' is already assigned to '%2'. Do you want to replace it? Import shortcuts Імпортувати комбінації клавіш Error loading keyboard shortcuts file. Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° комбінацій клавіш. Export shortcuts ЕкÑпортувати комбінації клавіш Error saving keyboard shortcuts file. Помилка Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° комбінацій клавіш. Are you sure you want to load the default keyboard shortcuts? Ви впевнені що хочете вÑтановити типові комбінації клавіш клавіатури? Left Button Клавіша вліво Middle Button Ð¡ÐµÑ€ÐµÐ´Ð½Ñ ÐºÐ»Ð°Ð²Ñ–ÑˆÐ° миші Right Button Кнопка вправо Override Shortcut ПерезапиÑати комбінації клавіш Select POV-Ray Executable This shortcut is already assigned to '%1', do you want to replace it? Ð¦Ñ ÐºÐ¾Ð¼Ð±Ñ–Ð½Ð°Ñ†Ñ ÐºÐ»Ð°Ð²Ñ–Ñˆ вже викориÑтовуєтьÑÑ Ð´Ð»Ñ '%1'. Ви хочете замінити Ñ—Ñ—? Import Shortcuts Error loading mouse shortcuts file. Export Shortcuts Error saving mouse shortcuts file. Are you sure you want to load the default mouse shortcuts? Ви впевнені що хочете вÑтановити типові комбінації клавіш миші? lcQPropertiesDialog Properties ВлаÑтивоÑті Summary Резюме Author: Ðвтор: Description: ОпиÑ: Comments: Коментарі: Measurements: Scene Сцена Background Фон So&lid Color Су&цільний колір Image Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ &Gradient &Градієнт ... ... Tile Тайл Set default options for new projects Ð’Ñтановити типовими влаÑтивоÑÑ‚Ñми Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ… проектів Parts Used ВикориÑтані блоки %1 Properties ВлаÑтивоÑті %1 %1 x %2 x %3 cm %4 x %5 x %6 inches %7 x %8 x %9 LDU Part Блок Total УÑього Select Background Color Визначте колір фону Select Background Top Color Визначте верхній колір фону Select Background Bottom Color Визначте нижній колір фону Select Background Image Оберіть фонове Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ All Image Files (*.png *.jpg *.gif *.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;GIF Files (*.gif);;BMP Files (*.bmp);;All Files (*.*) УÑÑ– файли зображень (*.png *.jpg *.gif *.bmp);;PNG файли (*.png);;JPEG файли (*.jpg);;GIF файли (*.gif);;BMP файли (*.bmp);;УÑÑ– файли (*.*) lcQPropertiesTree Property ВлаÑтивіÑть Value Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Position ÐŸÐ¾Ð·Ð¸Ñ†Ñ–Ñ X X Y Y Z Z Rotation ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Visibility ВидиміÑть Visible Steps Show Відображати Hide Приховати Appearance Зовнішній виглÑд Color Колір Part Блок Target Ціль Up Верх Orthographic Ортографічна FOV ФокуÑна відÑтань Near Мінімум Far МакÑимум Name Ðазва Multiple Objects Selected Обрано кілька об'єктів lcQSelectDialog Select Objects Виділити об'єкти All УÑÑ– None Ðічого Invert Інвертувати lcQUpdateDialog LeoCAD Updates ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ LeoCAD Connecting to update server... З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Ñервером оновлень... <p>There's a newer version of LeoCAD available for download (%1.%2.%3).</p> <p>ДоÑтупна нова верÑÑ–Ñ LeoCAD Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ (%1.%2.%3).</p> <p>You are using the latest LeoCAD version.</p> <p>Ви викориÑтовуєте найновішу верÑÑ–ÑŽ LeoCAD.</p> <p>There are new parts available.</p> <p>ВиÑвлено нові доÑтупні блоки.</p> <p>There are no new parts available at this time.</p> <p>Ðаразі немає нових доÑтупних блоків.</p> <p>Visit <a href="https://github.com/leozide/leocad/releases">https://github.com/leozide/leocad/releases</a> to download.</p> <p>Відвідайте <a href="https://github.com/leozide/leocad/releases">https://github.com/leozide/leocad/releases</a> Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ.</p> Error parsing update information. Помилка розбору інформації оновленнÑ. Error connecting to the update server. Помилка з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Ñервером оновлень. lcRenderDialog Render Ð’Ð¸Ð¼Ð°Ð»ÑŒÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Settings ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Width: Ширина: Height: ВиÑота: Quality: ЯкіÑть: High ВиÑока Medium Ð¡ÐµÑ€ÐµÐ´Ð½Ñ Low Ðизька Output: Результат: ... ... Cancel Render СкаÑувати Ð²Ð¸Ð¼Ð°Ð»ÑŒÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Are you sure you want to cancel the current render? Ви впевнені що хочете ÑкаÑувати поточне вимальовуваннÑ? Cancel СкаÑувати Error Помилка Error starting POV-Ray. Помилка запуÑку POV-Ray. An error occurred while rendering. Check details or try again. ВиÑвлено помилку під Ñ‡Ð°Ñ Ð²Ð¸Ð¼Ð°Ð»ÑŒÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ. Перевірте деталі або Ñпробуйте заново. Error writing to file '%1': %2 Помилка запиÑу у файл '%1': %2 Error writing to %1 file '%2': %3 Select Output File Обрати вихідну теку Supported Image Files (*.bmp *.png *.jpg);;BMP Files (*.bmp);;PNG Files (*.png);;JPEG Files (*.jpg);;All Files (*.*) УÑÑ– файли зображень (*.bmp *.png *.jpg);;BMP файли (*.bmp);;PNG файли (*.png);;JPEG файли (*.jpg);;УÑÑ– файли (*.*) lcSelectByColorDialog Select By Color Виділити по кольору Color: Колір: lcSetsDatabaseDialog Sets Database Каталог наборів Set Name or Number Ðомер або назва набору Search Пошук Number Ðомер Name Ðазва Year Рік Parts Блоків Sets Database provided by <a href="https://www.rebrickable.com">Rebrickable</a> Каталог наборів надано <a href="https://www.rebrickable.com">Rebrickable</a> Please select a set from the list. Оберіть набір зі ÑпиÑку. Downloading Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Downloading set inventory Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ–Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð½Ð°Ð±Ð¾Ñ€Ñƒ Keyword cannot be empty. Ключові Ñлова не можуть бути порожніми. Searching Пошук Connecting to server З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Ñервером Error connecting to server. Помилка з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Ñервером. Error downloading set inventory. Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ–Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð½Ð°Ð±Ð¾Ñ€Ñƒ. lcTimelineWidget Step %1 Крок %1 lcView LeoCAD LeoCAD Error creating images. Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ. Error Помилка Error writing to file '%1': %2 Помилка запиÑу у файл '%1': %2 leocad-23.03/resources/library.zip000066400000000000000000001352441440571307300171670ustar00rootroot00000000000000PK éX+Eldraw/UT ÕäTÖäTux èèPK &Y+Eldraw/p/UT HåTIåTux èèPK&Y+E£Yzldraw/p/lpg_box.datUT HåTHåTux èèmQÀ Cÿ=…G°ÄìþGÛFéfHüx¥MѺÍ>ö`½Í@t†×2˜¢à£àkIÁÏåÚ#_õi}sÉÅêáñ°ÀXÔˆ†!æQRÿPK&Y+E;²„«.´ldraw/p/stug-4x4.datUT HåTHåTux èè3T04S02P0† `ˆ ‹KJÓu*ŒôRK¸ AjuIQ V«K’ÉD¨PK&Y+EÀþu<.´ldraw/p/stug-16x16.datUT HåTHåTux èè3T04S°0P0† `ˆ ‹KJÓu-*,ôRK¸ AjuIQ V«K’ÉD¨PK&Y+E¶è5T]ldraw/p/lpg_openbox.datUT HåTHåTux èèmQÀ Cÿ=…G°ÄìþGÛFËfHüx¥MѺÍ>ö`½Í@t†×2˜R3 €OÍ€¯%M?K”k|é-¥õAÌ%ÕÃñ°ÀXèDÃPK&Y+E-o©®ì ldraw/p/stud.datUT HåTHåTux èè•WY–à ûï)¸€óJé›û_lRÈâE&áo2È ØHJsÊ%q¢’jÊKþ«+¯¿§Ïò)ïüý¾r°\g³Œ SYrɵ´840¢¹Êèb3ph6`D³s{b`¹ÎÇr‡*Òoh`ICñÎ%ufÒí@TòÐwï\Ró"=JD%FñäIîm{¬nÚÁ'`G‹óømu¼€¸àjqßKÈ&*\71™ªµ†lºU¦_ ’×–ÿ çÍÜášÍ¼¨ßM ÕkuL{\(T6dÒs4#Fâ¦Ð• Óîuþ¨«Y_ï´ÖŽå¡=JÜs”UÏ NV¬Kâ†Þ9Q´ý;‡‰šåõ?ö 3U9%mU9¬‚U’Þh/<Æ¦ÂÆY­”ˆE½Ë¨•>ÖLo¤ïFûX80Æ‘-5Ú²|œŸÃk¥#±áäî–íÞ{#@œÒ0S\§n4ŠãF¢›­“ñÛ0µ¯[j;Hèýã¡L)>JãxS¶årܽ±w ˆ6“:JÈâÎMØL¾¡&œç0üpð37fµÿT_ÿPK&Y+E’‰+Ù.´ldraw/p/stug-8x8.datUT HåTHåTux èè3T04S01P0† `ˆ ‹KJÓuM*LôRK¸ AjuIQ V«K’ÉD¨PK&Y+E‡°×*¤ldraw/p/stug-2x2.datUT HåTLåTux èè3T04S04P0† `ˆ ‹KJSôRK¸ Aêt‰UV§K´‰TPK&Y+EgÝèö/Äldraw/p/stug-32x32.datUT HåTHåTux èè3T04"0i¨`†º¸¤4]×ЬÂÐL/%±„ˤ^—T õº$Û@œPK Y+E ldraw/parts/UT &åT'åTux èèPKY+E¢µÍ,€Tldraw/parts/3003.datUT %åT%åTux èèeŽm ƒ0 †ÿ{Š\ #}-`ûBÆdÊæ Ç_R-f•¶éKú<¤BÇ÷ãú$P"4BG’WØÝŸùÛ3·ó¼ {±eÅ× aêOãt]Æä=1×Å)²vj'š£.˜Œ<ÊF/ ÒT»XÓ\pÞñqâî¿T³ŠþPKY+Eéaš'„Fldraw/parts/41539.datUT &åT&åTux èèeŽQ Â0 †ß=E.I¤vÿ1¼L{n`…ߦ[m7)ü É÷‘ ݦ> Š„“’z’üô¯¾ÃgdDœŸ}XI†m,ÕËÆ¡ði2-ã}^†×cŽÔyr9õzÙ`W¤49JΤDÃ"Wsa—ìrn fk®Ýžä‚òý¡ê´hW±çöPKY+Eæ9Äqþldraw/parts/3666.datUT %åT%åTux èèÏ] Â0 àwO‘ DšÚá d²áËØVØñM¶TVÝCèCBøòÓ·¡Í=,À'bÀ&€>‚ßøÊïîܵÙÜÅéÈçœÌ¹Õû ÖªžH1˜¹Z”Â0?ïÓÜiÙõ4 I:(Me|ükIë5,S-H#ë]º&v·ù[R;,kY 8<‚ßõµôPKY+Eœ×/½2ïldraw/parts/3045.datUT %åT%åTux èè…SANÃ0¼÷ó#Û2}ð^4DE´¨ÏÇib{<Þ EÙéÚ³»ãñ|œ¿&<|¿¿} Ý#â’Oóùõ8áqþü.»€°‡ ùà¯O[NçÃÝáå´‹ˆ ..h~-›ü}Ã7t‹¸j3Pñù._4¡¬aÏè¢!1šL„Õ4cÎõS³®Ík  š£¯I~Tàn˜QÕº3jçûm‹Þ¼Vsè]!ªªB“ ½êºëùt%ù‡54¥:eÞdú$ˆVóµ’Äm»ŽX€°"Ñ´3¶œUÿÐ."÷™åÜÑ$ƒž«bÛ€u„Ù7jޤÚfêQ)2+±;‡æÀ YV„Üõ"Ø7Á<Rq®Š:eœ 'tV«ÜBýq³Ù–5Ø©z ânöÿPKY+Et©K Œldraw/parts/3042.datUT %åT%åTux èè}SQ Â0 ýß)r@×Å@¼7Pö!&‚àñ]Ýš¦I:¬y//m^à:/¯ ÎïÇý t‚_à²|nóÔEˆC€øÿ¦­FŽc° èCÉ@S°÷ö£Œ¯WA)„Åj­=L`Klñf DŠX­üZÝ+¦™L´M4I|-“¤rÌãQ]Ìš[ÜTÓÀ^r<}pû­b.QÉ¢ÈdNô!½B)ƒ‚mš¦]@eŠŽs/µî…lu±‡rm]Sô}z vÏ„‰$ÇÙÝ ±-r™:–#µšbÀЧë+Q½=ÕlŠ›¶LñçÈggŽL1ëÒ4¥ž{q<¢õ½ûPKY+E¤Öd–Ôldraw/parts/3030.datUT %åT%åTux èèÏQ Â0 àwO‘ D’4ÔîÞ@&޽ 7pBo³utT…ч¿ÐïoZ‚ëÐÎ(D`:1°ô¶ê|Íï5êùÑΫ•ã4ØÊ_,Q*|Ð"ÓrµZƒ2 [ S§îyã®Ôøôit¸‘l5çE¾:jT àr.U²A6xÝ)í ,»Ú↱Ò'‹?±+o©e‚PKY+Eê’½¡påldraw/parts/184.datUT %åT%åTux èè3PpJ,N-ÈI,IU04S¨P0´à2±t @ÐP..)M×54«04ÓKI,¨64ÉéšàÔ`Ta„©Ü€$åf$©6"E5IŠIri~$6u - !ÔelfUi¥ÞÉ)HOʯkPKY+EIU*Ý‹›ldraw/parts/3795.datUT &åT&åTux è蕎Q Â@ Dÿ=Å\ eëÒcx©XúSlÁöø&š–m뇒È›LÎC›:2âÁTØ0¶úHÏž$KukÓ‡ýüã(EÛèV‚s«ž¦þ2NÝý:æ"sÒ :f™Y×£ì2µe4Ò,jÑh=Öû6 Œ¼ÃÝš¤¥ » JÒ7´øbÍ)öPKY+EGÜòh«´ldraw/parts/2465.datUT %åT%åTux èè’Q Â0Dÿ=Å^ ²›¦½ˆ¨Å­Ð㻋‰MÍÏH†ð&“Ý„i÷¼žn$4‘Ä•èDNZ&Bÿëk|wëî0f°AAÁ-Èm@­.ã@ L‹{¶}2ôàŸ*Ú¶uºñœ ²`º—}?œÇ~*]m¤@N{*~fS„¯Lá{¥h'ÿ„º-Ü”¦')¼€]Êʲâ]6¸Ú1„KïÒP^¬¢þPKY+Eò­†vldraw/parts/63864.datUT &åT&åTux èèmAƒ0 ï¼b?àÊNÒˆ‡p¯¨@¨"9pàùÄÅT@>ìf¼Œî3lð@"È3$Œ¨E¯µtŒ9O¯”Çå¶ÇЯ¦¸ˆŠx:#ƒ¥¸‹Ô(B ‹âyÝÐÉoþƒèx”š£¤š<ÁÂÑø›¯©íPKY+Eh¡Õ¡ldraw/parts/6112.datUT &åT&åTux èè‘Q Â0Dÿ=Å\ ²»½ˆ¨Å­Ðã7‹‰MÍÏH†ð&³»!ì_·óŒ,+8f‚.Æÿù>íº= ܹ­‘Û¹ÆÈû0bÆTcÆ™Glþ2½ÖɈ§‰Ï‚ð诇®¿IAÆI§ø>)+Ê<ë&»¶ˆ›ŸH¢BÙ›bZ8\üy†æ÷?ŠÙ½PKY+Eb©mf‘ldraw/parts/99301.datUT &åT&åTux èèTmNÃ0 ý¿SøAùÒÜ€Œ­?E°!ŽOHšÄ~N«jj×>¿¾Ä~v,½\çω¿ÞÎïúM×ó|½Nô4œO?ÓÁ‘;’·dÿoŽlþõÿïÛýòp9Ý o'ÍìÕ+Ľ<³­èÉG2!3C¹ À#=Pñ +tù&äLºŒ³)ÝʃñGާ×|ñ@}]ž$žn ³ lKVT {µd ÄMÊ(Râ¦É´@.¤lU¸éâþ»¥hb#Òð e/Ðyœn$Tkµ%xËoÍ:ê]Kªs*@g¥uíCÈã ýòÎqÝÓÈ@]æYS¹2Fì ‘µðӵ⺪ó’Uš‘{™•5[xŽuGäÙBx;+'8«l¨óàt(T8ôÀµG™(_Œ Ž’å<œ*±uÛ!.Ïq®·LU#½j«žfð©P&ƒlðWôõ`JW›PÎâPKY+EKøFcDsldraw/parts/3867.datUT &åT&åTux èè3PpJ,N-ÈI,IU04S¨\† –bÐÅ%¥éº†f†fz)‰%µ@>HL@Õš@iHNAz|R~X PKY+Eý]?4ldraw/parts/3675.datUT &åT&åTux èè…SQNÃ0 ýß)| 8‰zàœX?E°¡Yš¤Î³+4-Mž_úùÙÓËiùžéñçãý“b¤H×ü^.o§™ž–¯¿ùz`â‰\ðä)/L¾ü¶çïùr|8¾žB"ïh^î›|Ž~ÃÊֈk¡-b:þ/ß…‰qÛ„IÂyq9$àzªNæ-›‘{=cö5 Ò[0'Â4£>YXU­cwØÐ¹ï 5ý¨Z}` ]_ÕÍFÄê Zô^5ÐÝÈŸoX6j²u ¢!Gx€y€Y4!ûcnQiÝTq_Ù Ô(¨Ø+»ÀB× dȬïÖä++eìŒêÊÆ 3¦hØ= Z*¸2R;/F±˜bŠ¥Íñ~ì9^€¶!ì¡” ÇJ»Æ]ÜFÕôëkŽäXãGh›«1¹PKY+Eæ”õ¡@¿ldraw/parts/3676.datUT &åT&åTux èè…S[nÂ0üÏ)öAÎjá´?ýî ÚUˆT4 ¿N{Þ¡ÄfÖ;ãÙï—á·‡ãíçë ´„)>o×Gû¼÷ÏK/C¦¦ƒîaùtÕú7Þ¿[œpwú$h1ÌK|Ï»¸Œ'l~–ï釂;pFŸpÛØ!A^»ƒDã«%‰’I`¥L] :ÿ=ÁNU‹Ò û@Ұ´l’3&$ß1×BJoëé|aŠ_k)÷ªé¤Ø«HEULk¨nÂÍŠÍP’ÀIJpbUŠ5©ÏJ7—MMdÁ X²^ɤ§HúBµ21‡œÒ¬©ãì Ô*c™8ÔΆ€ § _— ê*hÂ9…/Ÿ*R=j%Kl'dÓ]¹ oëi09XBh-È ±53[pHR$JZ•&›uŽ÷?PKY+EÞ*j‹Oldraw/parts/87580.datUT &åT&åTux èè3PÈI,IU0R¨âòÌ’ çÔ¼’Ô"…à’Ò.CC304Ä ‹*ôRK ªt@¢ ÒĪÄJr Òãó Ró’ò+´± ˜46‚)…Ò@t-& -@d§A:@Ö€l3Œ ”éB­€²PUê”ꢩ…+52@èAVŠä Tu@ePKY+EÜБ"èldraw/parts/4161.datUT &åT&åTux èèSAnà ¼÷ó"Ð/ôU“C”H­’Têóklv‡YÂ0 »³ñqýþ9áývþº gdü!¿ dBŠˆË ˆë×ÿ÷Çïñpü|TÞ‹´ð‚^B*yAça™Ìë+¾Á]I•ÛøAh;´Ò„Ù&iÒð<Ô€R(]ÉÑ­kRnŽ6£RÀ"6Ò9q^œ6þhão?zPO!g'Â=1øBô= ¢ËWO¢žÁ[ö’¡2¨Eƒ¢ZÖRe]e›Yj¿ LÌH×c“¥y¦ù誣šõ|Œ©rÙlÍæÚà ­—‰²Qq­R¢¦X‰t“ª ‡'n×îf›Un½È¹7Fû™®ÃyVcG[LµÍ íâG õÊÅþPKY+E¨œ¼Ï Hldraw/parts/3665.datUT %åT%åTux èè}SAnÃ0 »÷ú€ ÛPó€ÞvÞ Š%‡aEWdÙ°çÏ#K”Ó!»ÍŠ&éõúyŸè<¿¿}Ÿ(Ó/%z¹ýLó2‡Di X¾bÁãúéúµ|Çñ²(ïZ¦Ì«TYr-ûXñZ9acóc×èG8 å×¶¤Á`e@‹ˆ‘ó^+#VV°Ssœ•QåÔ ‹Eƒ…ÑaÖ±šÇí¬^¯eûÙ‚½lÃ2÷¹èt00½;LÐ'ë󰻉j k•­$ÄH%ÑkÖÃâˆÄtÅÕv ”Kä“+æZÕ¢©IãÊ-¦Æb‡»j6R¬%–¦ž‡{´Y0¿ ó<µC>º9ß!ýÿ>Œ-t½T'³Þ;+°Kþ?ouÂÙ ç¡ìÐ5±uPÿPKY+EÆ–Cz>ldraw/parts/3005.datUT %åT+åTux èèeŽë €0 „ÿ;E¨äJé."¾QT|€ãkjÕª’#|— S25EK `‰]á7çe-ã2[NJA¶Ò5{D›K0uccÕçÃx,iÐè¯ëŸÃˆÃÊQ?ÄèB$ôTàS.À‹/©.T½Ù¦½Ÿør¶PKY+E»ªô÷Fldraw/parts/3794a.datUT &åT&åTux èèmÍQ Â0 àwOñ_ £ÉÊØ»<€LVTÛЊ;¾éÚÊʤ- í÷7§¡óŒ‚ÏÃßqt£wOœý»?0¸YïêKEÕw>*’pKl`M"mªú2Ì·Ë4»ñ:-›ˆ jPK’6.»„ Ý-RÑœ„aäÚ°Ù ŠßǦt”!•2CuôþÆ—JÑPKY+EôNéldraw/parts/2420.datUT %åT%åTux èèS[jÃ0üÏ)ö*Òb‚þ{^!ü•RzüÊkiµ/AHláÑH;+Ídøø¼í@økÏû÷óëñ¼(WH%C†ö*é7ÇŸý÷þv¿í'‘xébz…‰€[G‘†A%”`û¢GàÉLhœ·šµ:”eõ Õ×б‹Ên‚qW|Bizµ;Æì},W‰ÒÉ*<™ ð&ÑM€£àPÑþ5RaÁÄÆÜã VWnA]FŸ6 PùŪ,wof+3 4ßõÑ9ö¢'S6‡Ã|$Wf!rüyjÎñÚ×áNT![‚;DKRÄQðÑ­4ñ9¤ˆ*T•–?‚©ž÷й‰ÂÁ¶Óáp XíWe"qÅØ.ò‚æŠW›¥<öTDÕú«\p‰ºãP ‡Î¥¢Ko²Ø>_k¸h­ýaRÄJ{äPKY+EŒwå#ˆ„ldraw/parts/3623.datUT %åT%åTux èèÎQ Â0 àwOñ_ ’´5x o “ _†XaÇ7][YՇч„òåO—±‹ üA rŒôßõ_ý±ïbvûÔÎ0òé—„¡\ȹTKçûuš‡ÇmZ6#N@Š“+2Ôp÷3Ö[ÔBK±9Ÿv¤•k#¼A”ãsÓ:ªZY¡9ú?ë[eè PKY+E ¢<³ZÊldraw/parts/819.datUT &åT&åTux èè3PpJ,N-ÈI,IU°P¨P04â2T04SÐ51PACtº¸¤4]×¢ÂB/%±¢Ö$Ò€C±I… šb"Õêê1‚º¨¦ÁÌ@!§ =>)¿¬PKY+Eó6pvldraw/parts/6636.datUT &åT&åTux èèmA ƒ@ E÷=Å¿@$‘1xîEq(©.ºðø&‹#eÿÞ›Ïx¾§ Á }DAÊ`0¤ö毴ô¼ºyÉŸa^«±ÿ†Ó(’™©M‘v¸+É3ZD˜¨>â£{¾@tü”’£¤’ÏÇ è ~0ÀuþÞ§± †ÂúO/´¼p+Ž%€-‚~¨EJ ®ú1?qˆ ]¾%Ž* ñ"#T2H`¤c®ËU6Š3£Rî¦),-^iÖ0•RË1)2C_UI¶‰­kªëµgO?ÌO¹D%‹,Ÿ‘œè§t ¥ *lÓ˜0m*“¹]½`Té7ºµ†ÊÙúLæ3úôÐÛ}b-$6½Îø·y÷‰uZJóé@‡DÊV¥9© zTY‰ ácØJÛ³ß.Ç‘ùf/ެW+±k¼œm9<¢ím÷PKY+E‘^2\Ðldraw/parts/3334.datUT %åT%åTux èè3PpJ,N-ÈI,IU04S¨P02á2±t- @ÐP..)M×54«04ÓKI,¨64ÉôàPoQa®šHźF&`³AšL Ž² ´±‘BNAz|R~X PKY+E§¢ÃÔ¿Yldraw/parts/728.datUT &åT&åTux èè•Ò] ƒ0 ð÷"Èh¢¶9Æn0Š/2sÐã¯;EVñÁ@iþDÜÆvîAÀÑ…€4`¥À?Û÷{þ (V®];GküêCÌ–WL*hs »lþË€O¨ŠPa€Só .° g˜~jý;°à3!QX“¸ °Z$ìb¯á>½úçc²y—ÒP»ÿ@/ºN] ïºêJ»«M*|·Ÿ.az¬DåÔ ÌËÆÄqçW.*küá&´±Ž~PKY+Eõ“‹>Ьldraw/parts/3755.datUT &åT&åTux èèŽa Â0 …ÿ{ŠwH“n9€u"¢¸¡v|ÓÕ¸iF)}”ïËKÀæ~>\ÀíÖ++HÒaü¾þÙ¬›]Ÿ¹eÔÂaÓ/q€GÄ“…kwÚ¶Ýñ¶o‡™$Š ¤¨Åi/)œjÜGÇÁŸ`vÌ]©ü9|Á”«<–<¹@¥1 ÆÓ?a¶XIüPKY+EÆl)ù§ldraw/parts/3684.datUT &åT&åTux èè“Q †ß=E/€ÄÍg¯à ŒóÁh¢Ñ™x|Ç`ÐþÔÄ,äßG¡ý‹¥Ãíþ8Óþy9]©ß’§ÏünVŽ\GÎ’Gv~êøßÃz8މ3€ž| ã£:}⤟$›ôE–j„ºÝô|ú™/Ë<í •‘²<©dù-¯½¿–ïéaz]Œ÷?m W©ƒ¬ªh–EÅ hå¤;›o«F¯8Âi”o÷W&zÌAlˆîZ2£V;µ€1Á^UÏÀ¬°Z14yÞ$êhÇëÙq¶äÛ±Ì}.6 ÌèŒÉƼìÃnb»šBçÚdë‰Î0!O£ÛJ³!›Z+¶ÐÕÔéy†>ô¾ñ¦cè7Öx‹ÐòפŒä·{Ž”¤ÓÖ¼;B¼%äÿ&âÏSŠy®eB;úŽöÇa¼<ÎC(:âáâ{É\¶²ê¸´×¿AË6ÒÑsn*AE¬5eN+ÿãQÓ6/Wªm¤PKY+EhQ…Xldraw/parts/4201.datUT &åT&åTux èèeŽÝ Â0 Fï}м@$µÍµ/"þ1DqC'ôñ×tcG!ýHÏIJ°ÝÎwÈ Ž@õðê~OŸ%ËörœE_´r¤/×Jë1ö‡a¼>OCvVŠjå]g–éÚj­ VÁËèdAu©Ûtý’„<ªºØÒh8®ø.äÄ?<¹/µlAgPKY+EácÊævldraw/parts/87079.datUT &åT&åTux èèmŽA ƒ@ E÷žâ_ %Æ`ç îE©HAª‹.<~ɈZ™Åÿ0ïñÃhÞÓÁ -J”5H Fòâ/EÚÏ´Œí¼ Ÿ~^¯îJUCAÖž’ÑÈJþuÅŒ´§›ê3¾ºáF1íLRFéÂt‡®8s†ýPKY+EFÆ~ ˜ldraw/parts/3300.datUT %åT%åTux èè}S[ ƒ@ ü÷¹@ÀGð¥7è Zü(,…B_­Ýìl’Tt&™¬™¤¥Ë¼<':½î· õôYïóò¾ÎSÓS/Ô·pmŸ³âœÎ ÇTfѸ>÷îFÄ×Ïß ;Ê0*Vjýa!_bÇ«<•òZéom¯4Ì•Ð@ßD—¤ÇrI&Çý<›ƒys³›fÔKÅ»–vx{)Ñ8ÖH3j@¸Å·„!Ù‰êdø ´“õ&:¯=в'Øòl“¤â¶&ô›ãp{I‘ÕŽu¸° µà}ÏŒ'¨Mljc7ãðû÷Áþ~=ÝP+*Þ@zäá)2 ìûñ|ÎÇç® tH2¢5Oƒá»æ_aN¤«üd,34‘z ³Ë»ô,=,f é’M"è_¬8ÃA“0é@˽³ÑE×ÂÉûÍÎï,LGÑ ã»^yhñC޼ŸÈɱõ0Äo¹ÚߪAEq¨Å‚b.² tÃe䩺˜X"mUžÖ «}ªÕ|ÖÑÓÌå˜-Ûÿ Tø&e«†Æ§<+Q|ù'’Ó×&Ž4~*øý8Rs —Ôÿ4‘ƒoIsë)"ºÂÛHxûÐI.ôPKY+EšH- ôldraw/parts/3037.datUT %åT%åTux èè“Qnà Dÿsй`êô 9Aç#J¥V­#åøÁ6Ýa#Y¶d<<vgñ8~ÿü^ðõw=ß>ñ@:„ƒ‡GÈ/üú´ïÿ|Ÿ>¦Ó¼qa'çvƒ;vŽˆ .-jôë ÿG¿é/Y«+”ÙÆ;± ÌЄFäéò £T—IU‰Ih5Lsùí¢– #.« Cç˜#Áª:·×yoqù4­t\õ Â\ÑùAxÍp§yq$Za[ŠP;…úF©J”Z«åfÅ –‘Û6`.Pï\0Q®Ͳ3o19–vºËf%Ù`ÉÒmà–·¡ÖÂ7ê8‘®€±è³.hcm«¨§•1߃ÞoÆe&ï<ﻟ±6r;°; JñéP;*jY :ú÷ñµRôPKY+Eã)Mªþldraw/parts/733.datUT &åT&åTux èè•Q Â0 †ß=E.IK‘öÕ‹ˆN¢¸¡z|“¸Î27h)$¡|_úS‚ýóÚÜÀD.fh H«Òóë¯áÝ¢~{>_Ú+ìWaívpZ¸. ,Y‹á ´fmU^CúÅÒ,ÑHZ—¾º÷í¡ë/S3/p&­&Ø NñÕÜrb1ΫCT'}NŒ3· ³qÁÀIÁ?'S¤áš²x ¼àPKY+Ei°+ÛSõldraw/parts/2639.datUT %åT%åTux èèS[jÃ0üï)ö ²½ý÷½B ¡?%…Ô…¿²«} Bb ÆÚYi&ÂÇ÷õ¸Â3?ï?ûíñ¶À²CX#DÈñüÆü{ü}…õ¹^>¯G%nx‘^e¯°b[Á2Uƒù­< jAâ´Õ¨Õ È«GH¶¸„Îý 8©l7Å eØö2W°½´yÛ9šÇ ñ $~ÂÈQd`/ØUäòTh0õ5˜ÂL¦`¹qmY)@F¤{è­ª³Ì½©†2ùäÛ>*G_ô`òæ°›Ïäð,xŽ/$ëxékw§¢.A¢& ì(èèfšè‚Gå’È Éï ÁP?ö¹ñÂQy&&³ýOD!™bd—nYFÛtñ$s3•Gžò¨RÉŒî(Tݡ翨C‡Ì÷‡Í×Ü&Zs¨TùQ’ùPKY+Eà#¤cldraw/parts/60477.datUT &åT&åTux èèu“Qnƒ0Dÿsй€+ÛX(ß¹BNP•|D­”(I¥?`0»;ë ›á±öz†ˆóÏí~ÁéqýúF:¢àéFÄù"Rèñùú>¦Ï×!#„´¨%ÖÉü\âª7ÙªšYáƒú`{C/Â8o«Ã¨Äa„Ö””‹HRÂÕ[î\q•]MÒê`>·-¾D¶ßhú] ÓVäÀø¬‡ï<0𾂃¡e3Ä÷ŒlíïÑ  ÕˆY‹YdYéꪷ™Ee-0X6–G+‹õÌꟀTõլ׾§•e›5mÿ |Ù£!ö §Kdþ ™ú’Çô~*ØõØRuŽ.)ÿÞh‚Uÿ9Í©'O4×–ðò.“è7PKY+EŒ FÈEldraw/parts/3040b.datUT %åT%åTux èèu“Ý Â0 „ߙ %Qè¬Àx@ ø‘Ÿ¦±ïÔJM¯_ÛçzÙ]o÷“lçÃEÒF¢|$¬‚„I|¾B¾ËÂ>Ÿ¯÷q}Ü¿VQb~jôe‘ߣŸõEFµ@™UÞ™ õ }p“$©0-'i5#%U–ý«$CÑf¹‹GZÚ5åkPPSÖé¡Î9,å¡â/œŒø®÷·ì v@k2Ä ¬Å·‰ ùD«igG(¦)®®Ôc„¹XA<¹b¦U-›4®\cr,t¸«¦l­eaêq¸G@›õK1 â¨wÑÕùéÿÁÃÐBÓ»Au4ë½³›äÿyËNNè0f‡®ñˆýõ PKY+EƒØ¯–_ldraw/parts/3008.datUT %åT%åTux èèÐA н§øà ¥¬½ˆQkŒÑØFkÒã—iÁ6èb‚ yÃg0Ø¿nç;†ÁTÈb”û»ÿ4ÛæØ'W)ÝNéXç”L™ªBû'ANeö&ërað讇¶»@ t›gŽþ2–tœ&#Î*ÔiŒWó:Ý—u|>–­ÅÍ‘ñ$(ë²üiÜQïæ¥É¸ÛŒm uѬbM†MMa¶…ì.j©È~PKY+E|ªtŠ…ldraw/parts/30144.datUT %åT%åTux èè•ÎQ ƒ0 àwO‘ DÚ´t>ï"ÃMÙ˜²)ôø&ZµT_¤”þ/MÜíë ,_“iÐÈѾÿal<åU9,öE+ù¼PÝ(.}úæÑõõ÷Ùù¨Ç8Þ 9mÔ!:ôXé13Þ‚4Ûy”Œ^©˜b´ÆTãÊñàwÎÏy¼Rj™NPKY+EIÆNL™ldraw/parts/4282.datUT &åT&åTux èè•A à E÷=Å\`Ê8Zñ½AIiÈ&4ZðøU£$5Ydœ¿xßÿG‚ûØù({QñT† íüøï€øúê|…I[ËçY*h ÙLöe¹DZP—æ®ÌøÎ8iîßÏ)lM7 &yA+®p™šw&“[E[E2§l—³Å´E±&UÙÐXqÜñ+i<Æÿ*5lDPKY+E^ Jšuldraw/parts/3069b.datUT %åT%åTux èèmÁ ƒ@ DïýŠùHñCzKEQü|Í–.-›eò&ÃxNóÁ}¤)ƒAÂHnüµ¡¶™·±[·ay­Gõî÷ˆØO µ™BEÉ6-B,§Þá•—þ‚è>›’£ RIfÐ8ú~êKÊ PKY+EëQÈö‡oldraw/parts/3020.datUT %åT%åTux èè•ÎA Â0н§øI¦CÍ1¼T,Ý[0BŽïŒNKZÝH ïgp»ÜƒQ ‡ˆØ‚8ÀNÄ>ù9>Þºü±P»±ÇSp–<õfœ‡Ë4÷÷ëTªJÓB@:x¡ž UÄ*ÚHkZSlm}*F¾Â§­¤…ÒήT%ý¢Õ/¶NÙ PKY+EýÓ‡†ldraw/parts/2454.datUT %åT%åTux èèŽa Â0 Fÿ{ŠïM¬=À."êÆenÂŽoº7W)¡á½$åãz¹1A´;;ÄÇØþÃø¬Šê4&îOŒ$vãPï Kî}sìúº=wÓJÒò €½˜£³3ÇÏ÷„yð'¨-iW\þŽì¾`J«,æ<™@¹±ÊÓ/auXN+üPKY+E¬á4j•±ldraw/parts/2356.datUT %åT%åTux èèŽÝ Â0 …ï}Šó‘¦Õk_Dücˆâ†Nèã›l+–NAzÑù¾œ8l—ã‚„¸`py{Œúö¯†$Éò´ïGVl`ÂØ'_Á²‡ÍªðtŽª2…íkvmw¾ÚTH+-…fŸ¥l¯ýL“ÔÑÅ!³ãÐeåcW¢FPkš2N3þƒ+MßñPœT³Š¾PKY+E®5Åauldraw/parts/6881a.datUT &åT&åTux èè]ŽA €0 ï¾"¨$Rƒñ.ŠE±=xðùvKµ*…MHgH˜úus¤t’VB¢d”‰SJƒ¯Ë“-,ƒnŸüYÏã‘¥Vɦi2lo)Nþ’…é‘*\Å&lNò ÷)Ý—47j~ìƒ*ç¶åŠ/± PKY+EqNlž)ldraw/parts/3036.datUT %åT%åTux èè•ÎM à à}Oñ.0eÔzŒÞ ¤4dš@-xüjÐjú³ ó=ç1ÎóàGX¸ƒ‚² Í`0x;õ~øçD:èãmðYÛ4ѱi°tà®=w5v[‹Q–³sÅÇ¥ó:]–u¼_—ЄN±=ÈX(#ëRòÒ)3&ß)ëÒ¦´y{XnXS}í%JöM£¤_ÔÔ{Ù PKY+E}Øï+œldraw/parts/4287.datUT &åT&åTux èèSKNÅ0Û¿SøA™4êرæˆv@€q|Ò¦ÉüB]dj9îxƸy{_q{}z|Æ4aÂ7w¯_ëu[— fÄò„ ‡Ïís¹Y6æýõ·XBÊ÷cŠGKQñ+´rÂÉÎ{Õé×p˜Ëgš˜fHL@”¢.áô’AËíŠ:IƒQ†¾ÝZn³ ö”›'‰k¯I4×ݶÛh¸S»k›úõw±KÞC80Ϻµ MÆ¡‰MәƩEc[.›"¼BQ euuä&¶"ë䛀)=}oL“ I‡ý )ùG!ÿ A}̇äש¹¼›׈ ªhÞ›¦I¹ÚŒ¥IÁÉ…À¦™WûPKY+E5$·>Áldraw/parts/3298.datUT %åT%åTux èè“Y!Dÿ=E]CÃdàŒ>$”/ùÃØ?¯Í ‚n#)#>A]_ûݶÇ!¹ujå2rñ—„aœ‰úÒ0îýåÐõçÇ©3jð ÃNg™×ëψŸ®±¸¶Ô0ꦜ˜›:á%¤’»ÚRÁTë/–þãù–ZøPKY+E¼à7OFsldraw/parts/3811.datUT &åT&åTux èè3PpJ,N-ÈI,IU06R¨\† †f `hˆA—”¦ëUé¥$–@Ôù I0efbUk¥A"9éñIù`-PKY+EîPJ‘ldraw/parts/3006.datUT %åT%åTux è蕎] ƒ0„ß=Å^`ew¤¾ö"¥?"¥¥Jk!Çw# CAÉCò}™:}·'<©TJÚ…ÂQZßßé×3<êûeЬÛÎn'w|ºg«JxbA$‚p1XçkìÏÃØ½¯ƒÏ¬Öö˜Û¶HR²($$s…Å–¥,´Ç©V g±ä9 \™`<ÿòa%mð PKY+E¶Ï!XÈldraw/parts/3034.datUT %åT%åTux èè•ÎA Â0н§øÉŒ1æÞ@*–nŠ-!Ç7S¦%­.,Yü¼ÏŒÃµoR AF<08€‚ƒ>Æ6_éÝ‘d9>šdVþ·;èž ¢þèl-‡héú±» cû¼¹ê\<¨L|–ÙZžä«ãµS*qI­FÝ£{§A\ÅÈvØ´–4SÚØ…I¿huÅÚöPKY+Eù–$¢”Ÿldraw/parts/3032.datUT %åT%åTux èèŽA‚0E÷žâ_`L§*Çð#aC„Äšôøv°TIL’y¯ Î}Z"üÁd ô1Ê|„gGåxk›]¨°Ûh øO–üôsR8ŸcPÏiÐÝeÛûuˆ+§J çÁl3+9OöËu’RÃåTÕköNƒ˜¦kZ¦-I3JûAI¿P·\±åöPKY+E®j6ÉUIldraw/parts/702.datUT &åT&åTux èèS[NÄ0 üç¾@PêZ=œB ¤²H{|Ò$ŸY­v›´ãIl'3žöÏ×/ ¸–çùgÿ~ßX6H˜!CÈõÇóïåï#áß^.\¹éNrº—€Ô#T§†€I°|ÕGàÉ4>¶â\Ê2{®¯6»ÁŽ:Iî#p,•×cX·:7°ôyÝ$ZƤñd?`’( ðLxVQþ–áÐ2v8.ÃG8”¢Q Ò¶+ÑWs2l)¤Èã^ËU8ˆþ.Ý"®Ó.2k‚Îò”–€d«†iè“wI¿D®¨$ï ­ýp§.ONe“p·ähªy0|˜³ÊøLRH–e(‰FÎÖ@öÁû(‡E6js,·—Qà8‡[[Pç¹Ñ!ýtböB¨RŒc¹=’QM1›pÒš)Ñâì™ìÌž)n]ª¦”s/N$ô¾7_PKY+E¥ÆŒúKldraw/parts/3048.datUT %åT%åTux èè}SÁ Â0 ü3…°”„X6@}TT¢ê‹ñii;¶S¨¸»œÝsà1}æîËøzC¾A„/$x.ã< —)C Û7þ׿1H+ŽD 3èS̈—ã‰E¢XVƒGM´8ÙëA[ïhÇÙ6´ ½›N†TÚ¼Êl`úHA6GÔ õº¨Zj‡xÀ몆þtƒõÚ>ÖH¢x 3z=æ¤ztè¶ÕFàuì j¦s§>§_ãÌÝ^P«‘äng<*ôå²O­%©Þ'oe|a½pt„Ìúäf…ö.M%¾“èJ‹^Q¾ìµ¸\²nüv¿ÎÂ7«u½Ú*/øPKY+Eí/—7óldraw/parts/3685.datUT &åT&åTux èè…S[NÃ0üÏ)öF¶kR¾p‚Bó¨‚õøØilÏŽ¡(±5;ÙÝÙ‡•—Óü5Éã÷ûÛ‡ìïÅËuywò<_^O“<ÍŸ¿ÓupâF1Ί•øqb—§ž?çËñîx8^|ã?é²­øø°«ÅdSµt ÿ—ob¢AòéFD“†€h0VÜ´>S¬ÖëÍÀ~;hö¡kØ€+Ö©j¹µµC¼êh2/Õlz—‰¬*Ó¨AD/z‰n4R¢?zC“«“ç¦A€©5¿µ‘ü¸õ¦ˆ%„Ë;Ó—³ÐÛvY{¦¸í’4zRò XF÷†—cƒTÚ ]*øaf!ª80Zo…«¾Š¼..¡¦åRA«B©<†è¨–¹™ÚîÇf³{«›ÊIð«ÙÿPKY+EǾx{lgldraw/parts/4186.datUT &åT&åTux èè3PpJ,N-ÈI,IU0±P¨\† †f º†f ÊPÁ tqIiº®±Q…±‘^Jb D‡±XˆÂ¡ÁЬÂÐ ]±ªu!ʉ7ž4Õ¤š®kbö.ˆ²43€ª5Ò ‘œ‚ôø¤ü °PKY+E+Û_KŒldraw/parts/3041.datUT %åT%åTux èè}SQ Â0 ýß)r@×Å@¼7Pö!&‚àñ]Ýš¦I:¬y/I›—à:/¯ ÎïÇý t‚_ ¸,ŸÛT c öã~À~”ñõ/ BÐ@ ábu­=L`[lñf D#°µòkõ¬˜fZ0ÑÑ$ñµL’Ê1Gu1+nQSmkÉñôÁí·Š¹DUE¾ «p¢éª2(ئ‰Â´P™bâ< A­g!G]ä¡Ü[÷sFŸƒõ™‘ä:»®.h‘ËÞðÐq9R¾ hô †>]_‰j÷T»)nÚÅ3Α(ŽgŽD1viŠRï½ohuï~PKY+E½ ~FÊldraw/parts/3038.datUT %åT%åTux èèSA ¼ûŠù†Rìü‚/0êÁh¢Ñšø|K‹°;¬‰i“Òa˜Åcw½ÝOØ>· âoô«Ý€àáÑM/üüÔïs|×Çý¸ðþ¤¹?ôB„ë:±Ó`ú~Á¿°Fg’ŸÕ3߉y†&\ñývƒD“q‰*0 ¬È´šé·Q͆.£¬¡=Na° NûöÚ÷¢Ë§©¥ãª"ÌMD/ˆî4_‰VXÁæ"”N¡¾Q¨%Vk¹ÄCšÂ`)bÝÌ ™¨wÎ4Q®¢ÆaÙΫ&ké¤73“–\º Üò6©ö…ÈMPµN +`ì#:Á Y ´±ŽUÔÓrÌ÷ Í›éÒɯÌÛî§Œ˜êè8Ì6åöKMüPKY+EñpBKIldraw/parts/60481.datUT &åT&åTux èèuS[ ü÷{L!Øøí<±~M4>/RÊî ˜j ÓaØÝ™²¿Þî'Ù=ÎÇ‹Œ òŸþaåÅ2¤Ç§_ÞØõùzOëéðZ Qœÿ¡aÈ›¸M»_`D3)-Êwæ@yC/Ü(QÊâGƒ¥"-f ¨Èr¾ÑJ7°Ú ·zˆE¡ÓØSz: UÔaŸû̲T‡Šg¼ð¤ÇofäZ=‘°µâ÷ ,Í×DP>Ðb:ÃÙÒ4Í•õa^(D¼¹Ð̨ª›Ôï\5Y nºÉL¶Ör!õî¡fAýRl!êº:ßPÚïGð2´ÐÌ®×f½u–ȦøÞrÂÉ ":¬ƒ¹]×8b¿ ~PKY+EçÒbí…Xldraw/parts/30145.datUT %åT%åTux èè3Pp*ÊLÎV0R¨cc.CC304Ä ‹KJÓu*ŒôRK *u@2 ÒĪÌÜÊŠä¤Çç¤æ%åW éb0i SjfeEÐõ˜€ôÐ\8¤ÙlÈjËÈY©.Ô"]µ.L¹.†z„r#$(Ê‘„®¨PKY+E/+ÇÖ|èldraw/parts/3645.datUT %åT%åTux èè3PpJ,N-ÈI,IU02Q¨P01à2T04SÐ521P0Pе0P0T0C]\Rš®khVah¦—’XÕ`l–4éÁ¢ÂI9H!ñÊ-Hs Ä-ºÄšQNœZR\MšI @°Añda`Ui£A•SŸ”_ÖPKY+Eêý(öã«ldraw/parts/85984.datUT &åT&åTux èè}’KÂ0 D÷œb.`‘¤Èà ±@ Xq|HCRÿ¢jk_Üé$œîçÇ×õ|Ã’‘ñF©×~Ù”JBBNõž (§Qn¯ Ó!ݪÃ[££¶ªä3<¾ÕgtÛZQ¤Yõ±€wbY¥:¯êdºÞ1ìÙ ‹nÕ Ù5F]`–Ò¿ÍÓU>dÞ/;ÂÂb5b&Ìç’Yé«^×qÉ £1‘n;8h SjêòàD±/j™PXeÚHE©‰…Ãón¡y«µÝIÛo¡Pª·`™³q¸ÌÙÔ{±λtý3Þ+2þPKY+E_§¶Dldraw/parts/3009.datUT %åT%åTux èèÏQ‚0 àwOñ_ ¦£ð"FÁƒ¢˜p|WØ„L–=´Y¾îïÇ×½n!¡;(¨bØäõ=|š}s¢;:)s…¬0µôj·¶¢8ŽÆùÔ0ýíÔõ×ç¥WC•‡Qˆ¸…Æ÷7ã§}ÔÞM5ÌêdÉs'¼†4§Ä.·”0åú‡ƒ¥m¼ì’Ë¿PKY+E5$·>Áldraw/parts/3747a.datUT &åT&åTux èè“Y!Dÿ=E]CÃdàÜv§Äsÿ#ºm¦'ÈùÈôéIFZ à6h>ãË¡` ±ð58Í rñ–3Âõgþ&ñ›Lˆ KŸ—Ó›j-ÐÉ«Q&•ƒG « *ì“þFØQ²u ïܬÓfU"uOot'ù=}Í•TϹIÙqÆÞp2™Ñ¨Y¨ž‡6/ƺ³ªƒ˜ ¬É¡%†Í¡_Uš4‹¦ap trS4³¥0™ÎhO7ºñÕìlw]?Ün¹Ä5‘MáµKËÀ¸.YÖöêO¡w7]óé Ý2Ð,çÐB»—JwMU*9Í~ò`F™¶f­-ÖPKY+E:ã¡–•ldraw/parts/3021.datUT %åT%åTux èèÎM à à}Oñ.0EG+=FoPR² I <~£ÅØ,‚‹7à7? ©ó梡H+ÈÓhóí?#qàkßùͲ|HÃ!îx‘I#w*“{N«0­ãsY‡ùµ„ª…l<ÂáÆ…æ4ü×bÓ5.N-)FÖÈÖT°ªå¹ÚK*”û£QÒ­®Ø»È¾PKY+E±ñB‘üldraw/parts/3832.datUT &åT&åTux èè•ÎQ ƒ0 à÷"ÈH2‘z‹Ý`8&¾ˆ vÐã/™q+Ý”>ü…~‚ëÐÆ0¸ vÊ\â³GIr~´Ñmµßî—>=²+“=¡‘Ãà©#‡¹¿Ms7Þ§”•]G«5p#›õ¼ÈO§²ŽVÂ'ßU²A6x½ e}ŠßJ‹ÆB±Zü‹³]J©ðPKY+Er`·Tõldraw/parts/4187.datUT &åT&åTux èè3PpJ,N-ÈI,IU°P¨P06â2T04SÐ521PACtº¸¤4]×¢ÂB/%±ªØ‚xµ$(%É ÆF )KÌ Ú L`Ì r Òã“ò+À:PKY+E'kr ldraw/parts/397.datUT &åT&åTux èè•1 €0 EwOñ/PI¢Hg/"KA¡z|k)èâ $/áçfý¹»äÁ„ ž:. ÆF ªñÖ˜®`l¶ýæR£y|Fö—–,_š4ô¤E«^ÔÖ(Vy¡´¹ê¨nB[•ÒÝϰ¬G®+7PKY+Eþpc…pldraw/parts/3004.datUT %åT%åTux èèÎm Â0 àÿžâ½@FK°‹ˆ:™lcNØñmÖvÕRJBxòÁ¨Çǵ…`†âA°'(ãkz7Usž¢û“‘ZÕ†:ND]NÏá~ê‡[wéç]OøäqÔM¦ñúÕâ–k¼Í1´ê²ÇöÆLx).IYi)c*õŠƒ¥ßx»¥”~PKY+E£ìÜe'ldraw/parts/3297.datUT %åT%åTux èè“]nà „ß{й ÈÈz‚ªÉCÕJ­ò#õøµ16»ÃF²ò<| ì_ÄÛ÷Ïï§ëçÇrFÆÊ‹@&䈈!ˆõ×ÿo÷Çùõü~_99È…Ãà›RA(‹:ÓËbþÎqÕ7ÙªŠÕ½ñAh;´ò„ÙiÒršs¤U#JQ¢t'ÇwùœÛ†ãͪ°‰tNœg—ƒ?ÚøWg~PO!gážêBøáÁòêItÂ+𖆽e¨ŒjDÑ¢¨„–ڪ쫢l+‹ö»À`n ]ÍóŠæg »Žn¶æcL+ËÅÖ4OÈ0O°Þ&ªŒŠµN‰†¢‚t“ê ‡wê@ws™Un½Èy6Æò3®ÃyÖãDPµµÃ ËÅú•›ýPKY+EWÈë‘qldraw/parts/3068b.datUT %åT%åTux èè]ŽA € E÷b.`Œ“„iE¤‹¿ËBÿÞç‹0ìa‚ ¨±`{0„€y:1r¼*/BÚÆ˜ÖcŽW»L§Fø¹<;*¨*/þ'¾þQI’ÔHk6„f´BÝ—45?öA ßLV¿ørŒÝPKY+EŠÒƒ§ldraw/parts/6678a.datUT &åT&åTux èèSA ¼ûŠý6=û_`¬£‰Fkâó…BawXÓ´é00;‹¥Ãíþ8Óþy9]iØ‘§O~7ŽÜ@Î’MGvyÚøšßÓv:Ιgþ zòŒOhü¤Iã,ã+,Ñ…”‡Â7lAù?LcA§9f)Žþ¬ U0,«ÖbÆØè‚½ÅŸX—.­ôð PKY+Eìc%Úldraw/parts/3007.datUT %åT%åTux è蕎M Â0…÷=Å»ÀHfŒ1k/"þQD±E+äøfÚCêÂ2‹y0ßÇ<ƒÝózºAà;3ÐaÔû5¼[’ «óaH¬üÏ.@—4ðzÑœ,±)Xƒ{ßî»þò8v¡¶o$KÙ^ËL²*EGŠ ¶éó)‰i*‚ŠXÓ”qšñ_<Òô/+ÕlD?PKY+E$®šò‚Bldraw/parts/3031.datUT %åT%åTux èèeŽQ ƒ0Dÿ{нÀ–MlŽÑˆRñGTh 9¾ÙMT3Kö ³BŸ±u=<áaÈÔ$ñ™›ÿÜ`x<¿­ÛH†nT­$Ìî.4.C3/ýÔ;ˆTuèR}¿ŠäáãFkU¢Ç¼Öhk ¦kÎÓ™äå { œ)Ñ*_qæ¶PKY+EÐõ«¡‹qldraw/parts/3035.datUT %åT%åTux èè•ÎKÂ0 Ð=§˜ 9I} n€Š¨º©h%‚”ã—”~`ƒ²˜H~‡qî›ØB @°ã°ÏG|v$IŽ·&¾í”Ô&ö¸ \œÎÉèÇî2Œíý:¤U§Î+@>Àªb¥d]}uÄ:¹¢ð%­ª¶ÇöNá³1-·­¤™ÒÎ~h–ô‹úå[—Ù PKY+E)Qªé&ldraw/parts/3958.datUT &åT&åTux èè•ÏQ à à÷"ÈHĆc7-})kaxüŬN+ Z„(úýF nS· @. ,€Ž€¬2<¿Ö÷ˆ>økß­_í û¿ØWácͼ÷=s-Š}N+;Ú\›¼îLËxŸ—áù˜Cj´‰Uf·aŸBºS‡| ©nc±9f%vŠm!T°xŒyµ—˜(VöG…r¦¤M~ÅÞ)ûPKY+E@Ç´‘&ldraw/parts/3754.datUT &åT&åTux èèQ Â0Dÿ=Å^ ²S›=€µ"¢Ø¢z|7m·¦æg !Cx/³aÚ¿nç;Ýq‚PˆLiþÏwÿi¶Í±Ÿ¹“ƒsbÎVï'$ݦQ±1KÒð讇¶»NÝë1ú:u ó6øÊ‹–’2¼KI,„4¥ˆéx»K·çÊRM£ÀºÜh,w~åAãoÞÔ#ml _PKY+EîöN˜ldraw/parts/4204.datUT &åT&åTux èè•ŽÑ Â0 EßýŠü@¤éº6Ïþˆè”!Š:¡Ÿo‚‹¬V¤Ð^È97u°¹º30d ¸"¹Ù‚Ï÷>=zäÌëÃnz± HQGÚÞx7ƒ>˜!ÃËØo‡ñxÝy©µ`ŠÐ7Í|j}¥ÕÔ’òôNZ K4²³È®ÀÂ"Wš‚_œ…"þRRñ¿Šü PKY+Eq9ƒ–Mldraw/parts/3460.datUT %åT%åTux èèÐQ àwOñ_ †"cØ-[|YÜ1Ùñ¥˜¡>4<´!_[ŠÁuêâÆŠpb°µrßñ_ÃyèbvÒ]”ŽuNÉ”S•Khÿ$È­lÂÞdr´Ór¿ÍËøèçõPÓz8PZ¬±™ºÒÞþ”¸í5>uÍ!"C·„ÍÑÞOjGR- LŽþÁÏøZ%ôPKY+E™¶†úwldraw/parts/4162.datUT &åT&åTux èèmA ƒ@ E÷=Å¿@$ÆiÒ}©(¥ Õ… oRcqh™Åÿ÷æ3n¯q€`…^R@Ê`°ÞüidbŒóó>Íû›Ö¦,á\ 2¨@ÚhŽ”ô£dWÌPD˜¨>⣟"|‚hÿ/5GH5y€ÆÑ?ð;_SmPKY+EŽ3¦d£Jldraw/parts/30400.datUT %åT%åTux èè•[ Eÿ]Ål` #í·1¾Òm´&,¿SŠM0|pÎË(Ø¿nç;08 vC@X_Ëý=~:dÇÛËqŒ°­gu=Jê6T@½Jk§—t%ŒÔ†»e &~T\ŽAÎCwè‡ëóÔ»¹ÕX™( f§“•ôF‡b"ÉÕæ›¼ïß÷Q ÄÈ*Ã=„Y. L þpfЏ¦˜¬_Á >PKY+EÛÆ%yldraw/parts/6934.datUT &åT&åTux èèmŽA ƒ@ E÷=Å¿@J’ƒé¾´TJAª ߉D­U²øò ãöi$Œ°‹@ d %†¨7Ÿ:²¬Úþ}ïúæûìÆëë1„S2H "lެôàdwŠRC#]5¿ãwç’øó5mmOÒ‚Ò»¢…¤3T·/ö\Á&PKY+E^XÀldraw/parts/4202.datUT &åT&åTux è蕎Q Â0Dÿ=Å\`%Ù,Õo/"j¥ˆb‹VÈñÝŤ4FA $ûÞl6·Óá A„ç…‡o@k;ïï}|t$Q–ín|±¿“”’g‘8°¸²¤ E—¡ÛöÃñºïãÜÒK@¡ÎVÖW\Yb–IZ¦d¾í·¨ËSWàQ‘+ƒ²Bœ™¢}SBñ¿ŠWü PKY+EŸÿß,–ldraw/parts/4445.datUT &åT&åTux èè“]n! „ß{й€+ d“ç^¡'ˆš>T”¨M¥¿ûCÀ íJË{LÀÛùrýÀë÷çûò 8æòÛE-N\V38†Íq~œ«*6ï`óÞâòiZé¸ê„»¢óƒðšábyu$Zá[ŠP;…úƨFÔZ«åfÅT –‘Û6`.Ðî\0U®Íò3o19–uºËf%Ù`ÍÒmà–÷¡ÖÊ7…Ú8‰®€³êó.hck«ª§—1߃ÞoÆu&<ﻟÎÈoü@^Ò‚ë+!>Ÿ1Þ×Çéõô¾n¼ð¢@2‚T´¼ê¤|KÜð¶hÎmü ì¨ýÊq2ö1-­Ž4jÀ¬°.3knŸ¤Ú~8ºŒf°†õXÇ`Gƒõ­ï6ÐiFé¸êwŔѻ¢ËWG¢^°­½S¨o j@Znñ¦2Øf†8¶ó¤íΦÊÕÕ8,ßùÐd-›ôäæÉä€5—n·¼O}¡rST«#tœ}T'84ï‚6¶±ªzzŽùÌy3];ù+ó¹û)#¦:³ÝD¹ýjÿPKY+E™¨-‡tldraw/parts/3245a.datUT %åT%åTux èèŽQ Â@ Dÿ=Å\ eÃâ·µRD±E+ôø&Ý]-«²„ Ù7“lïç㌠âµbpq€?FÝã³mÚý˜¸?1Ÿz¨†Œè& ûºÝ®N·C?-@É‹Pe!Íèâ ,-ß.+‰]ªbhŠ˜Ûu\ø³®6þÖÓ/宪PKY+E ÓÂ"$ldraw/parts/962.datUT &åT&åTux èè}SÛmÃ0 ü÷\€¨­2 í 1ü$ˆ‹12~ýˆ¤I– ëîøH¶ô{ÿúz\ú+ɽæ÷g|žo}÷þ4 ôÀ4¼š@A(´°–-œpŽg†}*3‘èŽ 8·ÏÛõE† ¥˜ä¬ôõ†…lˆ ¯F°TfЙõO«ï*ÉLˆ$´—hŒRZÆH٘óJÌ7WÓéÀÛõYÔó“¡mOPÿ(Cc…‡Ò :Ò ˜c}®39€ÙªPa=ºuRF[ÍÅ6óÜ ü•Òòþ±¼¹%$žIŸj˾\/)¬Ár'&¯&νšOö݉šE¡JLhjöå:%)¬šb ÓZQ¼aÝ+Š3§{E1#Z-JÙî¬&]jFgpÿPKY+Eê+5Wldraw/parts/3660.datUT %åT%åTux èèuSAnÃ0 »çú€‹DÐú€ÝvÞ †5(†íÐeCŸ?7Že‰rQÄv †Cf¤÷óõ{¦×Û×ç‰ä…˜îùz»üÍ·e> M{×ßöŸå÷˜øÎ»ÃÇ20±Pâñ±åõqÊç±à ;´pÒÆ^ÿ+½`Ny¡ºO{‹æÅ¡ƒ©LÔd@ó²ÁUD…¼B½¾“fMªµ†& ƒc6ã©çíîöÂ?L˜l†t‰iµaÇE—>YL{àÀXJ$Á{“-O4¦Éóª"ú-´6¤ªi)};M}ž•wcÇG•”®cè=–»Oj]ÐÄ Ñ«0”½óÍ¿CŠŸ¹GbIž¾¹ØwHy­ØÓ2«*¶Ühö£ó¼Pls øPKY+E¾^=¢Áldraw/parts/30363.datUT %åT%åTux èèSAnÃ0 »÷ü€ Û1‚û…¾ h{V`ÃÖ}~;‰%J†ìÐ4-‰RÄñöýsÅá÷óü…ô‚'ò.!HCDB¬__ÿîËþrº7^ø1#„<£%ÖÍô_bÃWX£•4q;?ˆ Ë „)œÒ7Ã(áa„B˜‹…’£;/Fy9p´m«Ñ™Î?Nž:ÿ¨óoÊP/!W#½a|!ú–уæ‹è†gðZ†­e¨ªÀ,Á, Z1º"Ëe§©ý-0±,Dz« 4Í3ͯ@WµjÚs›Sã²Ù’ÍbÆà ­·‰°QpµR¦¡¨DzIt†Ãó§ô6Û,jëeγaígºLç]؉ ·˜ª‡AÚÅA˜~åfPKY+E(­+¦ldraw/parts/4477.datUT &åT&åTux èèÒQ àwOñ_Ó"¢Ü˜™-¾,n‰˜ìøRañ¥á¡„|¥¥p»8€±€iÇ`²m|ÆW¿ï»XÜIéŽJwP:Ö9%SVU>B9툙äX^l‰ :—h ã|¿Nóð¸MK•<L@°…ºõ~û—â>íøtk ’HREªæ]ú_fr…¼i¥Y©ùµeª’jº5ѺÄÞPKY+EÂðj‡vldraw/parts/2431.datUT %åT%åTux èèm1ƒ@ û¼b?`d_¬ã’!$)x~Î`PN »ÅŒ—ñÆ‚úH)ƒAÂHVì’g`ŒKßÌK7µóZ}Þ_Wž Ѝƒ“ê)áb¨YHðÈžÚ†MnEø¢ýý^JŽJò3Gwà9_RúPK éX+EýAldraw/UTÕäTux èèPK &Y+EýA@ldraw/p/UTHåTux èèPK&Y+E£Yz´‚ldraw/p/lpg_box.datUTHåTux èèPK&Y+E;²„«.´´(ldraw/p/stug-4x4.datUTHåTux èèPK&Y+EÀþu<.´´¤ldraw/p/stug-16x16.datUTHåTux èèPK&Y+E¶è5T]´"ldraw/p/lpg_openbox.datUTHåTux èèPK&Y+E-o©®ì ´Çldraw/p/stud.datUTHåTux èèPK&Y+E’‰+Ù.´´¿ldraw/p/stug-8x8.datUTHåTux èèPK&Y+E‡°×*¤´;ldraw/p/stug-2x2.datUTHåTux èèPK&Y+EgÝèö/Ä´³ldraw/p/stug-32x32.datUTHåTux èèPK Y+E ýA2ldraw/parts/UT&åTux èèPKY+E¢µÍ,€T´xldraw/parts/3003.datUT%åTux èèPKY+Eéaš'„F´Fldraw/parts/41539.datUT&åTux èèPKY+Eæ9Äqþ´ldraw/parts/3666.datUT%åTux èèPKY+Eœ×/½2ï´öldraw/parts/3045.datUT%åTux èèPKY+Et©K Œ´v ldraw/parts/3042.datUT%åTux èèPKY+E¤Öd–Ô´Î ldraw/parts/3030.datUT%åTux èèPKY+Eê’½¡på´² ldraw/parts/184.datUT%åTux èèPKY+EIU*Ý‹›´o ldraw/parts/3795.datUT&åTux èèPKY+EGÜòh«´´Hldraw/parts/2465.datUT%åTux èèPKY+Eò­†v´Aldraw/parts/63864.datUT&åTux èèPKY+Eh¡Õ¡´ldraw/parts/6112.datUT&åTux èèPKY+EÑS¬âw´õldraw/parts/54200.datUT&åTux èèPKY+E‡†u{T´&ldraw/parts/2453.datUT%åTux èèPKY+Eb©mf‘´ïldraw/parts/99301.datUT&åTux èèPKY+EKøFcDs´¤ldraw/parts/3867.datUT&åTux èèPKY+Eý]?4´6ldraw/parts/3675.datUT&åTux èèPKY+Eæ”õ¡@¿´Ãldraw/parts/3676.datUT&åTux èèPKY+EÞ*j‹O´Qldraw/parts/87580.datUT&åTux èèPKY+EÜБ"è´+ldraw/parts/4161.datUT&åTux èèPKY+E¨œ¼Ï H´›ldraw/parts/3665.datUT%åTux èèPKY+E[0I´ ldraw/parts/4460.datUT&åTux èèPKY+EÆ–Cz>´nldraw/parts/3005.datUT%åTux èèPKY+E»ªô÷F´6ldraw/parts/3794a.datUT&åTux èèPKY+EôNé´ldraw/parts/2420.datUT%åTux èèPKY+EŒwå#ˆ„´® ldraw/parts/3623.datUT%åTux èèPKY+E ¢<³ZÊ´„!ldraw/parts/819.datUT&åTux èèPKY+Eó6pv´+"ldraw/parts/6636.datUT&åTux èèPKY+Efù]ÇŒ´ï"ldraw/parts/210.datUT%åTux èèPKY+EЉUȧôÈ#ldraw/parts/3028.datUT%åTux èèPKY+E+Z˜)M¤´½$ldraw/parts/3857.datUT&åTux èèPKY+E!ê‚­‡´X%ldraw/parts/3001.datUT%åTux èèPKY+EãÆX´-&ldraw/parts/3044b.datUT%åTux èèPKY+E‘^2\д„'ldraw/parts/3334.datUT%åTux èèPKY+E§¢ÃÔ¿Y´.(ldraw/parts/728.datUT&åTux èèPKY+Eõ“‹>Ь´:)ldraw/parts/3755.datUT&åTux èèPKY+EÆl)ù§´*ldraw/parts/3684.datUT&åTux èèPKY+E‡‘Z˜æ´|+ldraw/parts/6212.datUT&åTux èèPKY+EH¾Áb´b,ldraw/parts/3026.datUT%åTux èèPKY+E„ˆ‰­´q-ldraw/parts/3710.datUT&åTux èèPKY+E'øx,´H.ldraw/parts/3024.datUT%åTux èèPKY+E1(} $L´/ldraw/parts/2449.datUT%åTux èèPKY+EŠÇ²§´€0ldraw/parts/3002.datUT%åTux èèPKY+EhQ…X´^1ldraw/parts/4201.datUT&åTux èèPKY+EácÊæv´12ldraw/parts/87079.datUT&åTux èèPKY+EFÆ~ ˜´ö2ldraw/parts/3300.datUT%åTux èèPKY+Et·1Œ†´J4ldraw/parts/92438.datUT&åTux èèPKY+EdÓ‚ëc´%5ldraw/parts/4286.datUT&åTux èèPKY+EšH- ô´ˆ6ldraw/parts/3037.datUT%åTux èèPKY+E`w3‹­´ö7ldraw/parts/2456.datUT%åTux èèPKY+E3u~…^´Ï8ldraw/parts/3023.datUT%åTux èèPKY+Eã)Mªþ´¢9ldraw/parts/733.datUT&åTux èèPKY+Ei°+ÛSõ´™:ldraw/parts/2639.datUT%åTux èèPKY+Eà#¤c´:<ldraw/parts/60477.datUT&åTux èèPKY+EŒ FÈE´ =ldraw/parts/3040b.datUT%åTux èèPKY+EƒØ¯–_´þ>ldraw/parts/3008.datUT%åTux èèPKY+EÇåx¢´â?ldraw/parts/60479.datUT&åTux èèPKY+E|ªtŠ…´Ó@ldraw/parts/30144.datUT%åTux èèPKY+EIÆNL™´¬Aldraw/parts/4282.datUT&åTux èèPKY+E^ Jšu´“Bldraw/parts/3069b.datUT%åTux èèPKY+EëQÈö‡o´WCldraw/parts/3020.datUT%åTux èèPKY+EýÓ‡†´,Dldraw/parts/2454.datUT%åTux èèPKY+E¬á4j•±´Eldraw/parts/2356.datUT%åTux èèPKY+E®5Åau´äEldraw/parts/6881a.datUT&åTux èèPKY+EqNlž)´¨Fldraw/parts/3036.datUT%åTux èèPKY+E}Øï+œ´”Gldraw/parts/4287.datUT&åTux èèPKY+E5$·>Á´ Ildraw/parts/3298.datUT%åTux èèPKY+Eªb'ñG ´xJldraw/parts/782.datUT&åTux èèPKY+Eqh,ˆ–´ÅKldraw/parts/3622.datUT%åTux èèPKY+E¼à7OFs´›Lldraw/parts/3811.datUT&åTux èèPKY+EîPJ‘´/Mldraw/parts/3006.datUT%åTux èèPKY+E¶Ï!XÈ´Nldraw/parts/3034.datUT%åTux èèPKY+Eù–$¢”Ÿ´éNldraw/parts/3032.datUT%åTux èèPKY+E®j6ÉUI´ËOldraw/parts/702.datUT&åTux èèPKY+E—T¸´mQldraw/parts/6111.datUT&åTux èèPKY+EEÊAº®O´XRldraw/parts/3027.datUT%åTux èèPKY+E“ó`“4´TSldraw/parts/2445.datUT%åTux èèPKY+Es‹FSÈ´5Tldraw/parts/3497.datUT%åTux èèPKY+E¯±ÜüLœ´ÖTldraw/parts/3865.datUT&åTux èèPKY+EDX©õŒ´pUldraw/parts/3043.datUT%åTux èèPKY+E¥ÆŒúK´ÂVldraw/parts/3048.datUT%åTux èèPKY+Eí/—7ó´ Xldraw/parts/3685.datUT&åTux èèPKY+EǾx{lg´Yldraw/parts/4186.datUT&åTux èèPKY+E+Û_KŒ´IZldraw/parts/3041.datUT%åTux èèPKY+E½ ~FÊ´Ÿ[ldraw/parts/3038.datUT%åTux èèPKY+EñpBKI´]ldraw/parts/60481.datUT&åTux èèPKY+EçÒbí…X´g^ldraw/parts/30145.datUT%åTux èèPKY+E/+ÇÖ|è´;_ldraw/parts/3645.datUT%åTux èèPKY+Eêý(öã«´`ldraw/parts/85984.datUT&åTux èèPKY+E_§¶D´7aldraw/parts/3009.datUT%åTux èèPKY+E5$·>Á´bldraw/parts/3747a.datUT&åTux èèPKY+E)+[ÖRë´€cldraw/parts/3046.datUT%åTux èèPKY+E:ã¡–•´ eldraw/parts/3021.datUT%åTux èèPKY+E±ñB‘ü´ýeldraw/parts/3832.datUT&åTux èèPKY+Er`·Tõ´Üfldraw/parts/4187.datUT&åTux èèPKY+E'kr ´~gldraw/parts/397.datUT&åTux èèPKY+Eþpc…p´=hldraw/parts/3004.datUT%åTux èèPKY+E£ìÜe'´ildraw/parts/3297.datUT%åTux èèPKY+EWÈë‘q´…jldraw/parts/3068b.datUT%åTux èèPKY+EŠÒƒ§´Ekldraw/parts/6678a.datUT&åTux èèPKY+EÉýÍ­¶´¬lldraw/parts/3033.datUT%åTux èèPKY+Eìc%Ú´§mldraw/parts/3007.datUT%åTux èèPKY+E$®šò‚B´‚nldraw/parts/3031.datUT%åTux èèPKY+EÐõ«¡‹q´Roldraw/parts/3035.datUT%åTux èèPKY+E)Qªé&´+pldraw/parts/3958.datUT&åTux èèPKY+E@Ç´‘&´qldraw/parts/3754.datUT&åTux èèPKY+EÊ9 ˜´õqldraw/parts/3299.datUT%åTux èèPKY+E×ò¤¦Š¿´Msldraw/parts/3010.datUT%åTux èèPKY+E‘PϵK´%tldraw/parts/3456.datUT%åTux èèPKY+EîöN˜´(uldraw/parts/4204.datUT&åTux èèPKY+Eq9ƒ–M´vldraw/parts/3460.datUT%åTux èèPKY+E™¶†úw´évldraw/parts/4162.datUT&åTux èèPKY+EŽ3¦d£J´®wldraw/parts/30400.datUT%åTux èèPKY+EÛÆ%y´ xldraw/parts/6934.datUT&åTux èèPKY+E^XÀ´gyldraw/parts/4202.datUT&åTux èèPKY+EŸÿß,–´Ezldraw/parts/4445.datUT&åTux èèPKY+E’ø‘Ž£´¿{ldraw/parts/3039.datUT%åTux èèPKY+E™¨-‡t´%}ldraw/parts/3245a.datUT%åTux èèPKY+E¡FNMP=´û}ldraw/parts/2357.datUT%åTux èèPKY+Eo+­¥q´™ldraw/parts/3070b.datUT%åTux èèPKY+E¢{:€B´Y€ldraw/parts/3022.datUT%åTux èèPKY+E‚ƒXÜ—^´'ldraw/parts/91988.datUT&åTux èèPKY+E€–³5®´ ‚ldraw/parts/3029.datUT%åTux èèPKY+EìG<ö±´è‚ldraw/parts/6213.datUT&åTux èèPKY+E ÓÂ"$´Æƒldraw/parts/962.datUT&åTux èèPKY+Eê+5W´7…ldraw/parts/3660.datUT%åTux èèPKY+E¾^=¢Á´£†ldraw/parts/30363.datUT%åTux èèPKY+E(­+¦´ˆldraw/parts/4477.datUT&åTux èèPKY+EÂðj‡v´ûˆldraw/parts/2431.datUT%åTux èèPK‹‹Ï0¿‰leocad-23.03/resources/minifig.ini000066400000000000000000007367001440571307300171260ustar00rootroot00000000000000; MLCad.ini ; Version 2023-01 ; SUPPORT: ; Feel free to modify the file, but I ask you to send me a copy of it ; to be able to distribute it to other users as well. Send copies to ; holly-wood@holly-wood.it with a calling subject. Please do not send copies ; if using unofficial parts, also make sure you are using the latest part ; libraries from www.LDraw.org. ; ACKNOWLEDGEMENTS: ; Thx to (in alphabetical order) Michael Heidemann, Michael Lachmann, J.C. Tchang and Andrew Westrate [HATS] "Baseball Cap with Button on Top" "93219.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cap Aviator" "30171.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cap Aviator with Black Goggles" "30171C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cap with Long Flat Peak" "4485.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cap with Short Arched Peak" "86035.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cap with Short Arched Peak with Seams" "11303.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cap with Short Arched Peak and Black Headphones" "11303C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cloth Wrap / Bandana with Rounded Top" "18927.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Construction Helmet" "3833.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Construction Helmet with Hair Ponytail" "16178.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Construction Helmet with Dark Brown Hair Ponytail" "16178P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Construction Helmet with Nougat Hair Ponytail" "16178P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Construction Helmet with Hair Short" "16175.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Construction Helmet with Medium Nougat Hair Short Pattern" "16175P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Construction Helmet with Reddish Brown Hair Short Pattern" "16175P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cook's Hat" "3898.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Crown with 4 Spikes" "18165.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Elves Hair Long Wavy with Braid, Bangs and Ears" "19201.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Elves Hair Long Wavy with Braid, Bangs and LtNougat Ears Pattern""19201P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Elves Hair Long Wavy with Ears" "19204.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Elves Hair Long Wavy w. Ears w. Yellow Tips, Ears Pattern" "19204P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Elves Hair Short Spiked with Ears" "19203.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Elves Hair Short Spiked with Light Nougat Ears" "19203P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Elves Hair Short Spiked with Medium Nougat Ears" "19203P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Fire Helmet" "3834.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Fire Helmet Breathing Hose" "6158.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Fire Helmet with Fire Logo Shield Pattern" "3834p01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Forestman Cap" "4506.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Forestman Cap with Small Red Plume (Complete)" "4506C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long Straight" "92255.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long Wavy" "92256.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long Wavy Partially Tied Back" "92258.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long with Curls" "93352.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long w. Ponytail French Braided w. 1 Hole" "11605.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long w. Ponytail French Braided w. 3 Holes" "15675.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long w. Ponytail and Side Bangs" "92257.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long w. Ponytail, Side Bangs a. Riding Helmet" "92254.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long w. Ponytail, Side Bangs a. Mag. Riding Helmet""92254P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long w. Ponytail, Side Bangs a. BL Riding Helmet""92254P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long w. Ponytail, Side Bangs a. Sun Visor" "15284.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Long w. Ponytail, Side Bangs a. Dk Pink Sun Visor""15284P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Short, Bob Cut" "92259.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair Wavy w. Curls and 2 Pinholes" "15677.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair w. Top Knot Bun and Hair Band" "15673.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Hair w. Top Knot Bun and Medium Blue Hair Band" "15673P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Party Hat" "24131.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Garrison Cap" "4156.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ghost Shroud" "2588.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Backslick" "64798.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Bob Cut Parted in Middle" "29633.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Bubble Style (Afro)" "87995.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Bushy Swept Back" "28551.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Coiled" "21778.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Combed Front to Rear" "92081.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Female Beehive Style with Sideways Fringe" "15503.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Female Long Straight with Left Side Parting" "92083.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Female Short Swept Sideways" "20877.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Female Ponytail with Long French Braid" "88286.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Female Very Curly - Parted in Middle" "29634.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Female with Elaborate Knot Bun" "13251.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Female with Pigtails" "3625.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Flat Top" "30608.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Islander" "6025.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Male" "3901.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Mid-Length Smooth Wide Bob Cut" "95328.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Mid-Length Smooth Wide Bob Cut with Gold Diadem Pattern""95328P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long and Half Braided" "30475.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long and Straight Parted in the Middle" "41612.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long Straight" "40239.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long Tousled with Centre Parting" "20595.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long with Curls" "11255.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long with French Braid" "59363.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long with Headband" "30114.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long with Headband and Feathers (Complete)" "30114C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long with One Front Lock" "85974.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long Wavy" "40251.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long Wavy with Bright Light Yellow Knit Ski Cap Pattern""80577P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long Wavy with Bright Pink Knit Ski Cap Pattern" "80577P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Long Wavy with Knit Ski Cap" "80577.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Mid-Length Straight with Blue Crown Pattern" "18835P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Mid-Length Straight with Crown" "18835.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Mid-Length Straight with Gold Crown Pattern" "18835P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Orc with Dark Tan Ears Pattern" "10066P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Orc with Ears" "10066.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Orc with Medium Nougat Ears Pattern" "10066P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Orc with Olive Green Ears Pattern" "10066P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Peaked" "42444.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Ponytail" "6093a.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Ponytail Off-centre" "15427.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Ponytail Off-centre with Magenta Stripe Pattern" "15427P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Ponytail Off-centre with Magenta and Medium Azure Stripes Pattern""15427P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Ponytail with Long Bangs" "62696.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Pulled Back" "92756.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Short Bowl Cut" "40240.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Short Combed Sideways with Left Parting" "99930.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Short Swept Back with Sideburns and Widow's Peak" "21268.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Short Tousled" "40233.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Short Tousled with Side Part and Lock Sticking Up" "20597.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Short Tousled with Side Parting" "62810.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Short Wavy with Centre Parting" "26139.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Short Wavy with Side Part" "11256.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Short with Curled Ends" "59362.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Shoulder Length" "4530.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Spiked" "98385.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Spiky Long" "53982.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Spiky Short" "53981.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Straight Cut with Short Ponytail" "17630.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Swept Back Into Bun" "99240.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Swept Back Tousled" "61183.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Swept Left Tousled" "23186.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Swept Right with Front Curl" "98726.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Swept Back w. Widow's Peak, Chin-Length a. Bushy in Back""21269.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Tousled" "10048.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Tousled and Layered" "92746.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Wavy" "43751.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Wavy Parted with Black Large Thick Glasses and Green Eyes Looking Up Pattern""28145P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Wavy Parted with Black Large Thick Glasses and Green Eyes Pattern""28145P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Wavy Parted with Black Large Thick Glasses and Green Eyes Winking Pattern""28145P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Wavy Parted with Black Large Thick Glasses and Light Nougat Eyes Pattern""28145P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Wavy Parted with Large Thick Glasses" "28145.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Wavy Windblown to One Side" "32602.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Large High Bun" "27186.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Ponytail and Baseball Cap" "35660.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Ponytail and Bright Pink Baseball Cap Pattern" "35660P06.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Ponytail and Dark Blue Baseball Cap Pattern" "35660P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Ponytail and Dark Red Baseball Cap Pattern" "35660P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Ponytail and Dark Turquoise Baseball Cap Pattern""35660P05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Ponytail and Red Baseball Cap Pattern" "35660P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Ponytail and White Baseball Cap Pattern" "35660P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Ponytail and Swept Sideways Fringe" "87990.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Ponytail and Swept Sideways Fringe with Purple Highlights Pattern""87990P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Ponytail and Swept Sideways Fringe with Yellow Hairband Pattern""87990P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Snakes" "12889.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Two Buns" "30409.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair with Two Locks on Left Side" "15443.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Beanie" "90541.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Beret" "90386.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne" "2528a.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Admiral Pattern" "2528AP32.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Corrugated Metallic Silver Minifigure Skull and Crossed Spanners on Dark Bluish Grey Background Pattern""2528AP3A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Dark Bluish Grey Tattered Lines and Spots and Metallic Silver Emblem Pattern""2528AP38.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Evil Skull and Crossbones Pattern" "2528P30.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Gold Trim, Gold Button and Blue Flower Pattern""2528AP3C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Large Square Skull with Crossbones Behind and Red Line Pattern""2528AP39.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Metallic Gold Captain Pattern" "2528AP35.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Metallic Gold Skull and Crossbones and Dots Pattern""2528AP33.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Minifigure Skull and Crossed Spanners Pattern""2528AP34.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Squared Skull and Crossbones Pattern" "2528AP3D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with Small Rounded Skull and Crossbones Pattern""2528AP31.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with White Evil Skull and Crossbones Pattern" "2528AP30.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with White Skull and Crossed Cutlasses Pattern""2528AP3B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with White Slanted Skull with Eyepatch and Crossed Spanners Pattern""2528AP37.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bicorne with White Slanted Skull with X Eyes and Crossbones Pattern""2528AP36.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bowler" "95674.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Bowler with Red Flower with Yellow Centre Pattern" "95674P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Conical Asian" "93059.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Conical Asian with Curved Sides" "26007.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Cowboy" "3629.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Cowboy with Cavalry Logo Pattern" "3629PW1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Cowboy with Silver Star Pattern" "3629PW2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 ; Update 2023-01 "Hat Cowboy Type 2" "15424.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Crown" "71015.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Cylinder Tapered with Hatband" "27149.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Cylinder Tapered with Hatband with Half Side Dark Turquoise and Medium Lilac Flower Pattern""27149P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Elf with Pointy Ears" "13787.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Elf with Pointy Ears with Bright Green Top Pattern" "13787P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Elf with Pointy Ears with Dark Pink Top Pattern" "13787P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Elf with Pointy Ears with Red Top Pattern" "13787P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Fedora" "61506.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Fez" "85975.dat" 0 1 0 0 0 1 0 0 0 1 0 -14 0 "Hat Flat Chef" "98381.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Imperial Guard Shako" "2545.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat High Cone Shaped" "2338.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Kepi" "30135.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Knit Cap" "41334.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Ninja Wrap" "24496.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Pillbox with Flower" "41944.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Pillbox with Flower with Black Centre Pattern" "41944P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Pillbox with Flower with Metallic Silver Petals and Black Centre Pattern""41944P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Pith Helmet" "30172.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Police" "15530.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Police with Gold Badge Pattern" "15530P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Rag" "2543.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Sombrero" "90388.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Tricorne" "2544.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Tricorne with White Plume (Complete)" "2544C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Wide Brim Flat" "30167.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat with Wide Brim Down" "13788.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hat Wizard without Brim" "17349.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Aztec Bird" "99243.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Aztec Bird with Eyes and Cheeks Pattern" "99243P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Bald Head High" "28125.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Bandage Wrapped" "24073.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Batman" "55704.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Batman with Angular Ears" "10113.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Bird" "25971.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Bird with Black Eye and Bright Light Yellow Beak Pattern""25971P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Bird with Penguin White Face and Orange Beak Pattern""25971P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Catwoman" "98729.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Catwoman Short with Wider Apart Eyeholes" "55705.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Circular Slice 60 Degrees" "45755.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Circular Slice 60 Degrees with Green and White Rind and Black Watermelon Seeds Pattern""45755P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Circular Slice 60 Degrees with Yellow Cheese Red and Dark Red Pepperoni and Sauce Pattern""45755P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Chicken" "11262.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Chicken with Yellow Beak and Red Comb and Wattles Pattern""11262P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Hooked Beak and Feathers" "30276.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Horus" "93249.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Indian Buffalo Horned" "30113.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Indian Warbonnet" "30138.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Indian Warbonnet with Coloured Feathers Pattern" "30138P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Horus with Eye Pattern" "93249PQ0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Nemes Type 1" "30168b.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Nemes Type 2" "90462b.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Nemes with 2 Darkblue Snakes Pattern" "90462bPQ0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Nemes with Darkblue Stripes Pattern" "90462bPQ1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Pig" "17351.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Pig with Black Eyes Pattern" "17351P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Pumpkin Carved" "20695.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Pumpkin Carved with Green Stalk" "20695P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Rocket Costume" "29580.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Rocket Costume with Red Top, Visor and Base and Rivets Pattern""29580P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Shark" "51349.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Shark with Tail and Fin" "24076.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Shark with Tail and Fin with Red Eye and White Orca Marks and Teeth Pattern""24076P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Shark with Tail and Fin with Black Eye and White Teeth Pattern""24076P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress SW Royal Guard" "30561.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress SW Zabrak Horns" "92761.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Turban" "40235.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress Werewolf" "42443.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headdress with Panther Ears" "25264.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Army" "87998.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Army with White Stencil Cross Pattern" "87998p01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Alien Skull with Fangs" "85945.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Cap" "60748.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Cap with Wings" "60747.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle Closed with Eye Slit" "89520.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle Rohan w. Cheek Protection and Comb" "10054.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle Rohan w. Cheek Prot. and Comb w. Eomer Pat." "10054P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle Rohan w. Cheek Prot. and Comb w. Theoden Pat." "10054P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle Uruk-Hai with Lateral Comb" "10051.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle Uruk-Hai with Lateral Comb and Hand Pattern" "10051P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle with Angled Cheek Protection" "48493.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle with Chin-Guard" "3896.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle with Dragon Crown Top" "6122.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle with Dragon Crown Top Black with Dragon Plume" "6122c01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle with Dragon Crown Top with Cattlehorn White" "6122c02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle with Fixed Face Grille" "4503.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Castle with Neck Protector" "3844.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Classic with Thin Chin Guard Cracked" "16599.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Classic with Thin Chin Guard Unbroken" "50665.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Classic with Thick Chin Guard" "3842C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Classic with Thick Chin Guard and Visor Dimples" "3842b.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Darth Vader" "30368.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Gladiator" "95676.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Imperial AT-ST Pilot" "57900.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Iron Man" "10907.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Iron Man w. Visor w. Gold Face, White Eyes Pattern" "10907C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Mandalorian" "87610.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Mandalorian with Black Visor Opening Pattern" "87610PS8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Mandalorian with Blue Visor and White Upper Cheeks Pattern""87610PS1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Mandalorian with Blue Visor, Dark Blue Upper Cheeks and Side and Two Black Horizontal Stripes Pattern""87610PS3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Mandalorian with Dark Grey Visor, Blue Upper Cheek and Light Lime Trident Pattern""87610PS2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Mandalorian with Dark Red Visor, Black Mark on Right Cheek and Black Hand Print Pattern""87610PS4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Mandalorian with Dark Red Visor, Dark Green Cheeks, Yellow Strokes and Metallic Silver Weathering Pattern""87610PS0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Mandalorian with Red Triangle on Forehead and Light Bluish Grey Cheek Pattern""87610PS6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Mandalorian with Reddish Brown Visor with Slanted Eyeslits Dark Bluish Grey Cheeks and Reddish Brown Pattern""87610PS7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Mining" "30325.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Modern" "2446.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Modern with Black, Blue and Silver Unitron Pattern" "2446P51.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Modern with Blue and Silver Spyrius Pattern" "2446P50.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Modern with One Red and Two Green Stripes Pattern" "2446P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Morion" "30048.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Persian" "88284.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Roman Soldier" "98366.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Round Bubble" "30214.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Samurai" "30175.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Samurai with Horn (Shortcut)" "30175c01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Scout Trooper" "30369.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Skateboard" "46303.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 ; Update 2023-01 "Helmet Sport with Front Handle" "12899.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Square Head" "19730.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Stormtrooper" "30408.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Stormtrooper with Stormtrooper Pattern" "30408p01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Stormtrooper with TIE-Fighter Pilot Pattern" "30408p02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Clone Trooper Commander Phase I Front Face with Yellow Markings and Silver Visor Pattern""61189PS1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Clone Trooper Phase I" "61189.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Clone Trooper Phase I with Dark Bluish Grey Rangefinder""61189C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Clone Trooper Phase I with Grey Markings and Black Visor Pattern""61189PS0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Clone Trooper Phase 2" "11217.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Darth Vader Upper Part" "19916.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Mandalorian with Rocket Pack" "30380.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Mandalorian with Rocket Pack and Blue Jango Fett Colours Pattern""30380P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Mandalorian with Rocket Pack and Dark Brown Boba Fett Colours Pattern""30380P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Mandalorian with Rocket Pack and Dark Red Boba Fett Colours Pattern""30380P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Rebel Pilot" "30370.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Rebel Pilot with Blue Rebel Logo Pattern" "30370ps3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Rebel Pilot with Checkered Pattern" "30370ps4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Rebel Pilot with Red Rebel Logo Pattern" "30370ps2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Rebel Pilot with Yellow Grid on Bley Pattern" "30370ps1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Rebel Pilot with Yellow Grid on Grey Pattern" "30370ps5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet SW Snowtrooper" "44360.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Underwater" "87754.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Underwater Atlantis Portal Emperor" "89918.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Viking with Horns" "53450C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Viking with Nose Protector" "53450.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Welding" "13792.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Welding with Dark Blue Stripes on Black Visor Pattern""13792P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet with Bat Wings" "30105.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet with Chinstrap and Wide Brim" "30273.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet with Front Prongs" "10305.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet with Front Prongs w. Dark Purple Highlight Pattern" "10305P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet with Hexagonal Top, Hoses" "30120.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet with Hexagonal Top, Hoses, Gold Alien Pattern" "30120P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet with Hexagonal Top, Hoses, Silver Alien Pattern" "30120P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet with Underwater Antenna and Clips" "6088.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet with Wings and Eagle Head" "24088.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hood" "30381.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hood Fur-lined" "30287.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hood Fur-lined with White Fur Trim Pattern" "30287P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hood Medieval Cowl" "4505a.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jester's Cap" "62537.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jester's Cap with Black Half and White Poms Pattern" "62537p02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jester's Cap with Blue Half and Blue Pom Pattern" "62537p01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jester's Cap with Red Half and Red Pom Pattern" "62537p03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mask Wolf" "11233.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mask Wolf with Fangs, Scars and White Ears Pattern" "11233P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ninja Wrap" "30177.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Plume Horsetail with Bar 0.5L" "22411.DAT" 0 1 0 0 0 1 0 0 0 1 0 -4 0 "Police Hat" "3624.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Police Helmet" "13789.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Police Helmet with Silver Badge Pattern" "13789P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Russian Fur Cap" "43894.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Imperial Officer Cap with Silver Code Disc Pattern" "16497P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Imperial Officer Cap with Silver and Black Code Disc Pattern""16497P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Imperial Officer Cap with Silver and Black Code Disc and Dark Brown Stains Pattern""16497P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Top Hat" "3878.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wizards Hat" "6131.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wizards Hat with Silver Buckle and Stars Pattern" "6131P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 [HATS2] "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cap Aviator Goggles" "30170.DAT" 0 1 0 0 0 1 0 0 0 1 0 8 0 "Cattlehorns (repositioning may needed)" "87695.DAT" 0 1 0 0 0 1 0 0 0 1 0 -6 -18 "Crown Tiara Flat with Arched Bottom" "96491.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Diver Mask" "30090.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Feathered Headdress Small" "87696.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Feathers with Pin" "30126.DAT" 0 1 0 0 0 1 0 0 0 1 0 3.83 17.76 "Feathers with Pin and Black Tip on Both Sides Pattern" "30126p01.DAT" 0 1 0 0 0 1 0 0 0 1 0 3.83 17.76 "Feathers with Pin and Black Tip On One Side Pattern" "30126P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 3.83 17.76 "Feathers with Pin and Red Tip with Black Stripe Pattern" "30126P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 3.83 17.76 "Friends Glasses Heart Shaped with Pin" "96486.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Friends Glasses Oval Shaped with Pin" "96490.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Friends Hair Decoration Bow with Pin" "96479.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 -12 0 "Friends Hair Decoration Butterfly with Pin" "96481.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 -12 0 "Friends Hair Decoration, Bow with Heart, Long Ribbon with Pin" "11618.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 -12 0 "Friends Hair Decoration, Bow with Heart with Pin" "94725.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 -12 0 "Friends Hair Decoration, Heart with Pin" "96485.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 -12 0 "Friends Hair Decoration, Star with Pin" "96489.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Friends Sunglasses with Pin" "18854.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Headphones / Ear Protection" "14045.DAT" 0 1 0 0 0 1 0 0 0 1 0 -11 0 "Hair Decoration Plume Ribbon" "44740.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Helmet Ornament Horn" "71591.DAT" 0 1 0 0 0 1 0 0 0 1 0 -6 -18 "Helmet Ornament Horn Elaborate" "11437.DAT" 0 1 0 0 0 1 0 0 0 1 0 -6 -18 "Helmet Visor" "2447.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Visor Ice Planet" "6119.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Visor Iron Man" "10908.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 -8 "Helmet Visor Iron Man w. Gold Face, Blue Eyes Pattern" "10908P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 -8 "Helmet Visor Iron Man w. Gold Face, White Eyes Pattern" "10908P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 -8 "Helmet Visor Iron Man w. Silver Face, DkRed Line Pattern" "10908P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 -8 "Helmet Visor Iron Man w. Silver Face, White Eyes Pattern" "10908P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 -8 "Helmet Visor Large with Trapezoid Area on Top" "89159.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 3 "Helmet Visor Pointed" "2594.DAT" 0 1 0 0 0 1 0 0 0 1 0 6.5 0 "Helmet Visor Space" "23318.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Visor SW Clone Trooper" "61190F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Visor Underwater" "6090.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Helmet Visor with Grille and Feather" "3843.DAT" 0 1 0 0 0 1 0 0 0 1 0 4 0 "Helmet Visor with Pointy Sides and Eye Slit" "48489.DAT" 0 1 0 0 0 1 0 0 0 1 0 8 0 "Plume Dragon (repositioning may needed)" "87687.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 7 "Plume Large (repositioning may needed)" "87694.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 7 "Plume Small (repositioning may needed)" "87693.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 7 "Plume Triple (repositioning may needed)" "87692.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 7 "Plume/Flame Triple (repositioning may needed)" "64647.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 7 "Rangefinder for SW Clone Trooper Helmet" "63586.DAT" 0 1 0 0 0 1 0 0 0 1 -15.8 1.2 0 [HEAD] "Stud Blocked Hollow" "3626B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Stud Blocked Hollow with Standard Grin Pattern" "3626Bp01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Stud Hollow" "3626C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Stud Hollow with Standard Grin Pattern" "3626CP01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Stud Solid" "3626A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Stud Solid with Standard Grin Pattern" "3626AP01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Stud Vented" "28621.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Adventurers Mummy Pattern" "3626BPA2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Alien Female with Red Eyes and Dark Bluish Grey Lips and Wrinkles, Open Smile with Missing Tooth Pattern""3626CPCE8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Alien with Large Dark Blue Eyes, Turtle Mouth and Gills Pattern""3626BPAR.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Alien with Lower Fangs, Single Orange Eye Open/Half Closed Pattern (Front)""3626BPC94.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Alien with Lower Fangs, Single Orange Eye Open/Half Closed Pattern (rear)""3626BPC94.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Alien with Robot Red Eyes and Mouth and Silver Metal Plates Eyebrows and Mask Pattern""3626CP8G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Angry Eyebrows and Tense Mouth Pattern" "3626BP0F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Angry Moustache and Teeth Pattern" "3626BPW2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Angry Moustache, White Teeth and Gold Tooth Pattern" "3626BPW0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Aquanaut, Green Angled Sunglasses and Brown Hair Pattern" "3626BPAB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Aquanaut, Red Headband and Freckles Pattern" "3626BPAA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Balaclava with Black Eyes and Curled Eyelash, 'Z' in Black Circle, Light Nougat Mouth Hole with Sneer Pattern""3626CPD6F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Balaclava with Black Eye Mask with White Eye Openings and Light Nougat Face and Scowl Pattern""3626CPBX.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Balaclava with Black Seams and White Eyes with Light Nougat Lower Face Pattern""3626CPD8C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Balaclava and Light Nougat Face, Cheek Lines, Frown/Clenched Teeth Pattern (Front)""3626CPBN.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Balaclava and Light Nougat Face, Cheek Lines, Frown/Clenched Teeth Pattern (rear)""3626CPBN.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Balaclava with White Frowning Eyes and Light Nougat Mouth Hole, Reddish Brown Cheek Lines, Open Smile with Teeth Pattern""3626CPD6I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard Stubble, Black Raised Right Eyebrow and Smirk Angled to Right Pattern""3626CP72.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard Stubble, Eyebrows, Smile, Scar Pattern" "3626CPQ0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard, Hair and Sideburns in Vertical Line Pattern" "3626BPAD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard, Happy/Angry Pattern (front)" "3626CPBB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard, Happy/Angry Pattern (rear)" "3626CPBB.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Beard, Sneering/Scared Pattern (front)" "3626CPBH.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard, Sneering/Scared Pattern (rear)" "3626CPBH.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Big Eyes, Curved Eyebrows, Orange Mouth Pattern" "3626BPAO.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Big Smile/Sad with Tear Pattern (front)" "3626BP4H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Big Smile/Sad with Tear Pattern (rear)" "3626BP4H.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Big Smile and Teeth/Sad with Tear Pattern (front)" "3626CP78.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Big Smile and Teeth/Sad with Tear Pattern (rear)" "3626CP78.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Black Angry Eyebrows, Scowl and Headset Pattern" "3626CP75.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Bushy Eyebrows, Smile/Angry Pattern (front)" "3626CPNF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Bushy Eyebrows, Smile/Angry Pattern (rear)" "3626CPNF.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Black Eye Mask w. White Eye Holes a. Dk Brown Cheek Lines Pattern" "3626CPD8K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, Black and White Goatee, Wrinkles and Cheek Lines, Neutral/Angry Pattern (front)""3626CPBM.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, Black and White Goatee, Wrinkles and Cheek Lines, Neutral/Angry Pattern (rear)""3626CPBM.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Black Eyebrows, Chin Dimple and Lopsided Grin Pattern" "3626CP8I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, Freckles, Smile/Worried Pattern (front)" "3626CP8S.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, Freckles, Smile/Worried Pattern (rear)" "3626CP8S.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Black Eyebrows, Medium Nougat Cheek Lines, Dark Tan Chin Ornament and Sad Look Pattern""3626CPD6J.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, Reddish Brown Dimples, Lopsided Open Mouth Grin Pattern""3626CPD69.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, Sunken Eyes, Beauty Mark, Right Eye Scar, Neutral/Angry Pattern (front)""3626CPS4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, Sunken Eyes, Beauty Mark, Right Eye Scar, Neutral/Angry Pattern (rear)""3626CPS4.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Black Eyebrows, White Pupils, Chin Dimple, Cheek Lines and Smirk Pattern""3626CP79.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, White Pupils, Chin Dimple, Open Mouth Smile with Teeth Pattern""3626CP73.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, White Pupils, Dark Nougat Cheek Lines and Dimple and Grimacing Pattern""3626CPS3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, White Pupils, Dark Nougat Dimple, Cheek Lines and Frown Pattern""3626CPS6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, White Pupils, Scared/Lopside Smile Pattern (front)""3626CP8W.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows, White Pupils, Scared/Lopside Smile Pattern (rear)""3626CP8W.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Black Eyebrows and Cheek Lines Pattern (front)" "3626CPB9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows and Cheek Lines Pattern (rear)" "3626CPB9.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Black Eyebrows and Dark Brown Cheek Lines, Firm Expression Pattern""3626CPD8F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Eyebrows and Silver Sunglasses Pattern" "3626BP8K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Full Beard, Thick Black Eyebrows and White Pupils Pattern""3626BPQ5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Hair, Eyebrows and Smirk Pattern" "3626BP0D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Headband with White Batman Eyes, Broad Smile Showing Teeth Pattern""3626CPD85.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Mask, Blue Eyes and Black Lips Pattern" "3626BPBA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Mask, White Eye Holes and Contour Lines Pattern" "3626CPD6B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Moustache, Beard and Messy Hair Pattern" "3626BP44.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black/Silver Sunglasses, Black Eyebrows, Chin Dimple and Grim Mouth Pattern""3626CP8Z.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black/Silver Sunglasses, Chin Dimple and Grim Mouth Pattern""3626CP84.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Standard Eyes, Smiling with Tongue/Standard Grin Pattern (front)""3626CP8E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Standard Eyes, Smiling with Tongue/Standard Grin Pattern (rear)""3626CP8E.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Black Straight Eyebrows, Large Medium Blue Eyes, Big Smile with Teeth/Scowl with Teeth 2-Sided Pattern""3626CPNG.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 ; Update 2023-01 "Black Thin Straight Eybrows and Light Bluish Grey Lips and Eyeshadow Pattern""3626CPCCG.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Headband and Dark Orange Hair Pattern" "3626BP66.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Sunglasses Pattern" "3626bp7b.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Sunglasses and Stubble Pattern" "3626BP7E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Wrap-Around Sunglasses Pattern" "3626bp7c.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bright Light Blue Glasses with Black Squared Frame, Smile/Screaming Open Mouth Pattern (front)""3626CP8M.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bright Light Blue Glasses with Black Squared Frame, Smile/Screaming Open Mouth Pattern (rear)""3626CP8M.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Bright Pink Headband with White Squinted Batman Eyes Pattern""3626CPD63.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Angular Beard and Glasses Pattern" "3626BP8D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Bushy Moustache, Eyebrows, Black Chin Strap Pattern" "3626CPCBE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Eyebrows, Nougat Cheek Lines, Smile/Smile with Teeth Pattern (front)" "3626CPX5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Eyebrows, Nougat Cheek Lines, Smile/Smile with Teeth Pattern (rear)""3626CPX5.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Brown Eyebrows, Freckles, Open Smile Pattern (Hollow Stud with Pierced Base)""3626BP8B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Eyebrows, Freckles, Open Smile Pattern (Hollow Stud)""3626CP8B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Eyebrows, Open Lopsided Grin a. White Pupils Pattern""3626CP8K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Eyebrows, Smirking Face, Pupils Pattern" "3626BP83.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Eyebrows, White Pupils, Lopsided Smile w. Dimple Pattern""3626BP0G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Hair over Eye and Black Eyebrows Pattern" "3626BP7A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Hair, Eyelashes, and Lipstick Pattern" "3626BPA6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Moustache, Stubble, Eyebrows, Frowning Pattern" "3626BP3R.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Bluish Grey around Eyes and Open Mouth Lopsided Pattern""3626CPCE7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Bluish Grey Eyebrows, Moustache and Sideburns, White Pupils and Open Mouth Pattern""3626BP8G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Brown Eyebrows, Crooked Smile and Laugh Lines Pattern""3626CP05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 ; Update 2023-01 "Dark Brown Eyebrows, Goatee, Sideburns and White Pupils Pattern""3626CP40.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Orange Beard, Gold Teeth and Eyepatch Pattern" "3626CP30.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Orange Eyebrows, Trimmed Beard and Headset Pattern" "3626BPSH.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Orange Moustache, Beard and Messy Hair Pattern" "3626BP42.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Red Moustache and Beard, Sneer, White Pupil and Eye Patch Pattern""3626BP36.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Red Lips, Open/Closed Mouth, Freckles Pattern (front)" "3626CPBJ.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Red Lips, Open/Closed Mouth, Freckles Pattern (rear)" "3626CPBJ.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Dark Red Lips, Smirk/Eyemask Pattern (front)" "3626BPB8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Red Lips, Smirk/Eyemask Pattern (rear)" "3626BPB8.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Dark Tan Eyebrows, Moustache, Dark Tan and Grey Sideburns and Stubble Pattern""3626CP86.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Eye Patch, Black Stubble and Messy Hair Pattern" "3626BP49.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Eye Patch, DkOrange Moustache, Beard a. Messy Hair Pattern""3626BP46.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Eye Patch, DkOrange Stubble and Messy Hair Pattern" "3626BP48.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Eye Patch, Red Moustache, Beard and Messy Hair Pattern" "3626BP47.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Eyebrows, Cheeklines, Determined Pattern" "3626BPC6A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Eyebrows, Crow's Feet, Open Mouth Smile/Queasy Expression with Sweat Drop Pattern (front)""3626CP70.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Eyebrows, Crow's Feet, Open Mouth Smile/Queasy Expression with Sweat Drop Pattern (rear)""3626CP70.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Eyeglasses and Lightning Scar Pattern" "3626BPH1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Eyes in Mask, White 'A' and Black Line on Back Pattern" "3626CPBL.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Evil Skeleton Skull Pattern" "3626BPA8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Robot with Red Eyes and Lips, 4 Metallic Silver Mouth Squares, Black Beauty Mark, Eyelashes and Headset Pattern""3626CPD2B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Balaclava, Medium Nougat Face, Beauty Mark and Crooked Smile Pattern""3626CPD89.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black and Silver Sunglasses, Black Eyebrows, Peach Lips Pattern - Hollow Stud""3626CP8V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Glasses, Brown Eyebrows, Open Mouth Smile with Peach Lips Pattern Pattern""3626CP76.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eye Mask, Dark Red Lips and Red Diamond Beauty Mark, Wink and Open Mouth/Licking Lips Pattern (front)""3626CPD81.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eye Mask, Dark Red Lips and Red Diamond Beauty Mark, Wink and Open Mouth/Licking Lips Pattern (rear)""3626CPD81.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Black Eye Mask, Dark Red Lips, Red Tongue and Diamond on Cheek, Open Smile with Top Teeth Pattern""3626CPD6D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eyes, Thin Eyebrows and Red Narrow Lips" "3626BPC42.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eyebrows and Eyelashes, Beauty Mark Under Left Eye, Dark Red Lips Pattern" "3626CPD66.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eyebrows and Eyelashes, Freckles, Pink Lips, Open Mouth Smile / Angry Pattern (front)""3626CP81.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eyebrows and Eyelashes, Freckles, Pink Lips, Open Mouth Smile / Angry Pattern (back)""3626CP81.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Black Eyebrows and Eyes with Eyelash, Broad Grin Pattern" "3626CPD8E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eyebrows, Beauty Mark, Single Eyelash, Dark Tan Lips and Crooked Smile/Scowl Pattern (front)""3626CPNA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eyebrows, Beauty Mark, Single Eyelash, Dark Tan Lips and Crooked Smile/Scowl Pattern (rear)""3626CPNA.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Black Eyebrows, Dark Red Lips, Smile/Worry Pattern (front)""3626CPH0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eyebrows, Dark Red Lips, Smile/Worry Pattern (rear)""3626CPH0.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Black Eyebrows, Peach Lips, Open Smile with Teeth/Sleeping Pattern (front)""3626CP8R.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eyebrows, Peach Lips, Open Smile with Teeth/Sleeping Pattern (rear)""3626CP8R.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Black Eyebrows, Peach Lips, Smirk/Smile with Mud Splotches Pattern (front)""3626CP77.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eyebrows, Peach Lips, Smirk/Smile with Mud Splotches Pattern (rear)""3626CP77.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Black Eyebrows, Pink Lips, Eyelashes/Sunglasses with Medium Lavender Frames Pattern (front)""3626CP8X.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Black Eyebrows, Pink Lips, Eyelashes/Sunglasses with Medium Lavender Frames Pattern (rear)""3626CP8X.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Black Eyebrows, Wide Eyelashes with Thick Dark Azure Mascara, Smile and Dark Orange Lips Pattern""3626BPC5E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Brown Eyebrows, Medium Nougat Lips and Brown Beauty Mark on Left Side Pattern""3626CPD6H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Brown Eyebrows, Peach Lips, Pensive Smile/Scared Pattern (front)""3626CP8Q.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Brown Eyebrows, Peach Lips, Pensive Smile/Scared Pattern (rear)""3626CP8Q.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Brown Eyebrows, Pupils, Eyelashes Pattern" "3626BP09.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Earth Orange Lips and Light Blue Glasses with Black Top Frame Pattern""3626CP7F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Glasses with Dark Green Frames, Red Lips, Smiling/Smiling with Teeth Pattern (front)""3626CPX2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Glasses with Dark Green Frames, Red Lips, Smiling/Smiling with Teeth Pattern (rear)""3626CPX2.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Glasses with Gold Frames, Peach Lips, Smiling/Smiling with Teeth Pattern (front)" "3626CPX1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Glasses with Gold Frames, Peach Lips, Smiling/Smiling with Teeth Pattern (rear)" "3626CPX1.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Jagged Dark Azure Eyebrows, White at Sides of Eyes, Silver Lips Pattern""3626CPCG1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Large Round Glasses with Bright Light Blue Lenses and Black Frames, Orange Lips with Slight Crooked Smile Pattern""3626CPD7I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Lopsided Smile/Determined Pattern (front)" "3626CP8D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Lopsided Smile/Determined Pattern (rear)" "3626CP8D.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Magenta Eye Mask, Dark Red Lips, Grin with Teeth/Neutral Pattern (front)""3626CPD6A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Magenta Eye Mask, Dark Red Lips, Grin with Teeth/Neutral Pattern (rear)""3626CPD6A.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Medium Nougat Glasses, Laugh Lines, Red Lips, Neutral/Raised Eyebrows Amused Pattern (front)""3626CP8U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Medium Nougat Glasses, Laugh Lines, Red Lips, Neutral/Raised Eyebrows Amused Pattern (rear)""3626CP8U.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Nose, Red Lips, and Large Eyes Pattern" "3626BPW3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Peach Lips, Smile, Brown Eyebrows Pattern (Hollow Stud)""3626CP8A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Peach Lips, Smile, Brown Eyebrows Pattern (Hollow Stud with Pierced Base)""3626BP8A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Red Lips Annoyed/Smiling Pattern (front)(Hollow Stud with Pierced Base)""3626BP89.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Red Lips Annoyed/Smiling Pattern (rear)(Hollow Stud with Pierced Base)""3626BP89.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Red Lips Annoyed/Smiling Pattern (front)(Hollow Stud)""3626CP89.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Red Lips Annoyed/Smiling Pattern (rear)(Hollow Stud)""3626CP89.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Red Lips Small Eyebrows Pattern" "3626BP08.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Red Lips Smile/Scared Pattern (front)" "3626BP8I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Red Lips Smile/Scared Pattern (rear)" "3626BP8I.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Silver Glasses and Pink Lips Smiling Pattern" "3626CP8L.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Smiling/Scared Pattern (front)" "3626BPQ3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Smiling/Scared Pattern (rear)" "3626BPQ3.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Female with Thin Black Eyebrows, White Eye Shadow, Orange Lips and Three Black Stripes on Cheeks Pattern""3626CPCE9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with White Ski Goggles with Pink and Purple Glass and Black Strap and Red Lips Pattern""3626BPC87.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Freckle Nose and Standard Grin Pattern" "3626bp07.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Full Black Beard with Side Burns, White Pupils, Open Mouth Grimace Pattern""3626CPX4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Glasses Rounded, Brown Eyebrows and Smile Pattern" "3626CP8Y.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Glasses and White Muttonchops Pattern" "3626BPA1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Glasses, Brown Sideburns and Moustache Pattern" "3626BPQ4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Glasses, Grey Eyes, Eyebrows, Cheeks Pattern" "3626CPBK.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Glasses, Grey Eyebrows, Beard and Moustache Pattern" "3626BP0E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Glasses, Pencil Behind Ear and Pointed Moustache Pattern" "3626BPW8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Glasses, Thin Brown Eyebrows, Smile Pattern (Hollow Stud)" "3626CP87.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Paint and Slanted Eyes Pattern" "3626BP6U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Robot Pattern" "3626BP64.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Brain and Yellow Mouth Pattern" "3626BP6Y.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Eyebrows, Medium Blue Eyeshadow, Thick Red Lips Smile with Sharp Tooth Pattern (front)""3626CPD68.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Eyebrows, Medium Blue Eyeshadow, Thick Red Lips Smile with Very Sad Frown Pattern (rear)""3626CPD68.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Green Lips and Red Eyebrows Pattern" "3626BPB5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gregory Goyle/Harry Potter Pattern (front)" "3626BPH4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gregory Goyle/Harry Potter Pattern (rear)" "3626BPH4.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Grey Eyebrows and Stubble, Medium Nougat Cheek Lines and Chin Dimple and Black Glasses Pattern""3626CP7E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grey Eyebrows, Moustache and Stubble, Sad Face Pattern" "3626CP7A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grey Frame Glasses, Brown Eyebrows and Open Smile Pattern" "3626BP0I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grey Hair, Beard, Moustache, Angry Pattern" "3626BP0A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grin, Dark Grey Beard and Eyebrows Pattern" "3626BP39.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grin, Brown Beard, White Pupils Pattern (Hollow Stud)" "3626CP88.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grumpy/Angry Pattern (front)" "3626CPBD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grumpy/Angry Pattern (rear)" "3626CPBD.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Half-Moon Glasses and Grey Eyebrows Pattern" "3626BPHA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Headset Over Brown Hair and Eyebrows Pattern" "3626BP69.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP Harry Potter with Glasses and Lightning Bolt, Smile/Frown Pattern (front)""3626BPH7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP Harry Potter with Glasses and Lightning Bolt, Smile/Frown Pattern (rear)""3626BPH7.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "HP Narcissa Malfoy with Dark Brown Eyebrows, Crow's Feet, Angry/Smile Pattern (front)""3626BPH9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP Narcissa Malfoy with Dark Brown Eyebrows, Crow's Feet, Angry/Smile Pattern (rear)""3626BPH9.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "HP Rubeus Hagrid with Wrinkles Pattern" "3626BPH8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP Voldemort with Teeth and Nostrils Pattern" "3626BPH6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ice Planet Female Red Hair Pattern" "3626BP65.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ice Planet Messy White Hair Pattern" "3626BP62.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ice Planet Moustache and Eyebrows Pattern" "3626BP61.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids Robot Pattern" "3626BP50.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids with Black Hair, Headset, Green and Copper Eye Grid Pattern""3626BP56.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Classic Pattern" "3626CPB4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Spider Pattern" "3626CPB3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Islander White/Blue Painted Face Pattern" "3626BP3K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Islander White/Red Painted Face Pattern" "3626BP3J.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Large Black Open Mouth with Uvula and Red Tongue Pattern" "3626CPD6E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Large Blue Mask Pattern" "3626BP6V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Large Glasses with Dark Grey Eyebrows, Moustache and Stubbles and Dark Brown Cheek Lines Pattern""3626CPD67.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Large Tongue/Scared Pattern (front)" "3626CP03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Large Tongue/Scared Pattern (rear)" "3626CP03.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Lefty Mouth and Stubble Pattern" "3626BP81.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Light Bluish Grey Thick Eyebrows and Angular Beard and Open White Mouth Pattern""3626CP74.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Light Turquoise and Orange Painted Face Pattern" "3626BPW7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 ; Update 2023-01 "Lightning Scar, Glasses, Black Eyebrows and Smile/Angry Pattern (front)""3626CPH2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Lightning Scar, Glasses, Black Eyebrows and Smile/Angry Pattern (rear)""3626CPH2.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "LOTR Brown Eyebrows Worried/Smile Pattern (front)" "3626CPM2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Brown Eyebrows Worried/Smile Pattern (rear)" "3626CPM2.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "LOTR DkBrown Beard, Stubble and Stern/Clenched Teeth Pattern (front)" "3626CPM7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR DkBrown Beard, Stubble and Stern/Clenched Teeth Pattern (rear)" "3626CPM7.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "LOTR Frowning/Grimacing Pattern (front)" "3626CPM6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Frowning/Grimacing Pattern (rear)" "3626CPM6.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "LOTR Frowning/Scared Pattern (front)" "3626CPM4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Frowning/Scared Pattern (rear)" "3626CPM4.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "LOTR Frowning/Shouting Pattern (front)" "3626CPM5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Frowning/Shouting Pattern (rear)" "3626CPM5.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "LOTR Orc with Grey Hair Pattern" "3626BPMA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Smirking/Shouting Pattern (front)" "3626CPM8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Smirking/Shouting Pattern (rear)" "3626CPM8.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "LOTR Thick Gray Eyebrows and Smile Pattern" "3626CPM1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Thick Grey Eyebrows and Smile Pattern" "3626CPM9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Tired/Poisoned Pattern (front)" "3626CPM3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Tired/Poisoned Pattern (rear)" "3626CPM3.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "LOTR Uruk-Hai Lurtz Scowl and White Hand Pattern (front)" "3626BPMB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Uruk-Hai Lurtz Scowl and White Hand Pattern (rear)" "3626BPMB.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "LOTR Uruk-Hai Scowl and White Hand Pattern (front)" "3626CPM0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Uruk-Hai Scowl and White Hand Pattern (rear)" "3626CPM0.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Mask Br.Green with Eyeholes and Smile Pattern" "3626BPB2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mask Purple with Eyeholes and Smile Pattern" "3626BPB6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Medium Azure Zigzag Line Pattern" "3626CPCFB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Messy Black Hair, 1 Tooth in Mouth Pattern" "3626BP4F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Messy Hair and Eye Patch Pattern" "3626BP31.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Messy Hair and Moustache Pattern" "3626BP30.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Messy Hair Female Pattern" "3626BP40.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Messy Hair, Beard and Eye Patch Pattern" "3626BP34.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Messy Hair, Moustache and Beard Pattern" "3626BP33.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Messy Hair, Moustache and Eye Patch Pattern" "3626BP32.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Messy Hair, Moustache and Stubble Pattern" "3626BP35.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Monocle and Black Slanted Eyebrows Pattern" "3626bpb7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Monocle, Scar, and Moustache Pattern" "3626BPA7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mouth Closed Stern/Mouth Open Scared Pattern (front)" "3626CP80.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mouth Closed Stern/Mouth Open Scared Pattern (rear)" "3626CP80.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Moustache Curly and Spiky Beard under Mouth Pattern" "3626BP45.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Moustache, Frown and Pointed Hairline Pattern" "3626BP4C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Moustache, Stubble and Bald Hair Part Pattern" "3626BPW9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mummy Face with 2 Eyes/1 Eye Pattern (front)" "3626BPQ0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mummy Face with 2 Eyes/1 Eye Pattern (rear)" "3626BPQ0.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Mummy with 2 Eyes/Gold Death Mask Pattern (front)" "3626BPQ1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mummy with 2 Eyes/Gold Death Mask Pattern (rear)" "3626BPQ1.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Open Smile with Teeth/Eyebrows, Scared Pattern (front)" "3626CP8J.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Open Smile with Teeth/Eyebrows, Scared Pattern (rear)" "3626CP8J.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Open Smiling Mouth, Teeth and Tounge Pattern" "3626BPC44.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Orange Beard and White Smile Pattern" "3626BP80.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Orange Glasses and Smirk Pattern" "3626BP8J.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Orange Painted Face Pattern" "3626BPW4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Painted Triangles Pattern" "3626BPW5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Peach Lips, Smile, Black Eyebrows Pattern" "3626BP8C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Peach Lips, Smile, Black Eyebrows Pattern (Hollow Stud)" "3626CP8C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pursed Lips and White Forehead Pattern" "3626BPB1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Raised Left Eyebrow, Freckles and Crooked Smile Pattern" "3626CP71.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Eyes with White Pupils and Missing Teeth Pattern" "3626BPC15.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Lips and Black Upswept Eyelashes Pattern" "3626bp6f.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Lips, Open Mouth and Thick Eyelashes Pattern" "3626BP20.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Moustache, Beard and Messy Hair Pattern" "3626BP43.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Moustache, Eyebrows and Hair Pattern" "3626BP4D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Moustache and Goatee Pattern" "3626BP41.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red and Dark-Turquoise Painted Lines, Eyebrows, Nose Pattern""3626BPW6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reddish Brown Eyebrows and Freckles, Lopsided Grin/Frown Pattern Pattern (front)""3626CPNE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reddish Brown Eyebrows and Freckles, Lopsided Grin/Frown Pattern Pattern (rear)""3626CPNE.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Reddish Brown Eyebrows, Cheek Lines, Open Smile/Frown Pattern (front)""3626CPH1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reddish Brown Eyebrows, Cheek Lines, Open Smile/Frown Pattern (rear)""3626CPH1.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Reddish Brown Eyebrows, Green Eyes, Lopsided Open Mouth Grin/Gritted Teeth Pattern (front)""3626CPNC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reddish Brown Eyebrows, Green Eyes, Lopsided Open Mouth Grin/Gritted Teeth Pattern (rear)""3626CPNC.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Reddish Brown Eyebrows, Medium Nougat Scar, White Band-Aid, Lopsided Grin with Teeth/Determined Pattern (front)""3626CPNB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reddish Brown Eyebrows, Medium Nougat Scar, White Band-Aid, Lopsided Grin with Teeth/Determined Pattern (rear)""3626CPNB.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Reddish Brown Eyebrows, White Pupils and Dark Orange Dimple Pattern""3626CPS1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reddish Brown Headband w. Squinted Batman Eyes, Sad Mouth Pattern""3626CPD64.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Robot with Red Eyes and 4 Black Outlined Squares Mouth on Silver Background with Black Rivets Pattern""3626CP8P.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Robot with Red Eyes, Metal Eyebrows with Rivets, Broken White Teeth and Stubble Bolts Pattern""3626CPD2E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Robot with Red Visor and 4 Black Outlined Squares Mouth on Silver Background Pattern""3626CP8O.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Robot with Red Visor and 9 Black Squares Mouth Pattern" "3626CP8N.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ron Weasley Pattern" "3626bph3.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Scowl, White Pupils and Angry Eyebrows Pattern" "3626BP8E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Severus Snape Pattern" "3626BPHB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sideburns and Droopy Moustache Black Pattern" "3626BP3N.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sideburns and Droopy Moustache Brown Pattern" "3626BP3Q.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sideburns, Goatee, Beard Stubble, Scar Pattern" "3626BPQ2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Mask and Mouth Grille Pattern" "3626BP6X.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Robot Pattern" "3626BP63.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Sunglasses, Eyebrows Wavy and Thin Grin Pattern" "3626CP8H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Sunglasses and Red Headset Pattern" "3626BP68.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Single Large Black Eye with Pupil Pattern" "3626CP02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skull Cracked with Metal Plates Pattern" "3626CPN2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skull Type 1 (Smiling) Pattern" "3626BPAQ.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Small Blue Mask Pattern" "3626BP6W.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Smile and Gold Tooth Pattern" "3626BP86.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Smile, Black Eyebrows and White Pupils Pattern (Blocked Hollow Stud)" "3626BP84.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Smirk, Black Hair and Goatee Pattern" "3626BP82.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Smirk, Black Moustache Pattern" "3626BPA3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Smirk, Black Moustache and Cleft Chin Pattern" "3626BPAP.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Smile, Brown Eyebrows and White Pupils Pattern (Blocked Hollow Stud)" "3626BP85.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Smile, Brown Eyebrows and White Pupils Pattern (Hollow Stud)""3626CP7H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Smile, Black Eyebrows and White Pupils Pattern (Hollow Stud)""3626CP7G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Standard Grin and Eyebrows Pattern" "3626BP05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Standard Grin and Pointed Moustache Pattern" "3626BP03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Standard Grin and Sunglasses Pattern" "3626BP04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Standard Grin, Eyebrows and Microphone Pattern" "3626BP06.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Standard Grin Pattern (Hollow Stud)" "3626CP01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Standard Woman Pattern" "3626BP02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Stern Black Eyebrows, White Pupils and Black Chin Dimple Pattern""3626CP08.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Stern Black Eyebrows, White Pupils and Dark Orange Chin Dimple Pattern""3626CP07.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Stubble, Moustache and Smirk Pattern" "3626BPA5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Alien with Large Black Eyes Pattern" "3626BPSB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Black Eyebrows and Dark Bluish Grey Scars Pattern" "3626BPS6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Black Eyebrows and Dark Grey Scars Pattern" "3626BPS7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Black Eyebrows, White Pupils, Dark Brown Forhead Lines, Cheek Lines and Chin Dimple and Open Mouth pattern""3626CPS7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Black Goggles and Chin Strap Pattern" "3626BPSL.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Brown Eyebrows Pattern" "3626BPS2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Brown Eyebrows and Beard Pattern" "3626BPS9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Brown Eyebrows, Smile and Black Chin Strap Pattern" "3626CPSG.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Brown Eyebrows, Solid Black Eyes and Black Chin Strap Pattern""3626CPSF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Dark Bluish Grey Chin Strap, Stern Eyebrows Pattern (front)""3626CPSI.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Dark Bluish Grey Chin Strap, Black Goggles Pattern (rear)""3626CPSI.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "SW Dark Brown Eyebrows, Black Eyelashes, Red Lips and Two Dots on Cheeks Pattern" "3626cpsq.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Darth Maul Pattern" "3626BPS8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Freckles and Thin Brown Eyebrows Pattern" "3626BPSD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Grey Beard and Eyebrows Pattern" "3626BPS4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Grey Eyebrows and Implant Pattern (front)" "3626BPSC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Grey Eyebrows and Implant Pattern (rear)" "3626BPSC.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "SW Jawa, Yellow Eyes with Orange Rim Pattern" "3626CPS0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Red Lips, Black Eyes, Thin Eyebrows Pattern" "3626BPS0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Reddish Brown Eyebrows, White Pupils and Dimple Pattern""3626BPSO.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Scout Trooper Black Visor Pattern" "3626BPSE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Small Black Eyebrows Pattern" "3626BPS3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Smirk and Brown Eyebrows Pattern" "3626BPS5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Stern Black Eyebrows, Pupils and Orange Visor Pattern" "3626CPSH.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Tusken Raider Pattern" "3626BPST.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tan Eyebrows and Frown Pattern" "3626BPH2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tan Thin Eyebrows and Moustache and Grin with Teeth Pattern""3626BPC83.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Teeth, Pupils, Brown Eyebrows Pattern" "3626BP0B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Thick Angry Moustache, Stubble and Long Hair Pattern" "3626BPW1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Thick Black Eyebrows, Lavender Black Eye, Adhesive Bandage and Frown Pattern""3626CPCF4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Thick Black Eyebrows, Red Eyes with White Pupils, Light Bluish Grey Eye Shadow and Fangs Pattern""3626BPC25.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Thick Black Moustache and Eyebrows, Grin with Teeth" "3626BPC21.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Thick Moustache and Short Eyebrows Pattern" "3626BP0C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Thin Moustache, Stubble and Sideburns Pattern" "3626BP67.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tribal Paint and Frown Pattern" "3626BPAC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Uruk-Hai Scowl and White Hand Pattern (front)" "3626BPM0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Uruk-Hai Scowl and White Hand Pattern (rear)" "3626BPM0.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Villain Black Facial Hair Pattern" "3626BPA4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Villainous Glasses and Black Facial Hair Pattern" "3626bpa9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vincent Crabbe/Ron Weasley Pattern" "3626bph5.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Beard, Sideburns, Moustache, Eyebrows and White Pupils Pattern""3626BP8M.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Bushy Eyebrows, Goatee, Wrinkles, Smile/Open Mouth Scared Pattern (front)""3626CP8T.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Bushy Eyebrows, Goatee, Wrinkles, Smile/Open Mouth Scared Pattern (rear)""3626CP8T.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "White Face Paint, Black Lines Through Eyebrows and Eyes, Bright Pink Hearts on Cheeks Pattern""3626CPD6K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Hair, Eyebrows, and Moustache Pattern" "3626BPN1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Headband and Nougat Cheek Lines, Smirk Pattern" "3626CPD61.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Pupils, Black Eyebrows Closed/Scared Mouth 2-sided Pattern""3626BP8H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Pupils, Dark Bluish Grey Eyebrows and Dark Red Scars Pattern""3626CPS2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 ; Update 2023-01 "White Pupils, Cheek Lines, Black Eyebrows, Wide Open Mouth and Chin Dimple Pattern""3626BP8F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Pupils, Grey Eyebrows, Beard and Open Mouth Pattern" "3626BP8L.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Skull Mask, Yellow Eyes and White String Tied in Back Pattern""3626CPCEB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White and Blue Stripes on Cheeks, Black Eyebrows and Big Grin Pattern""3626BPC33.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White and Light Bluish Grey Bushy Eyebrows, Open Mouth Smile Pattern""3626BP0H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White and Light Bluish Grey Eyebrows, Moustach and Goatee, Dark Orange Wrinkles, Concerned Expression Pattern""3626CPND.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wide Smile, Red Lips and Crow's Feet Pattern" "3626BPB3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wiry Moustache, Goatee and Eyebrows Pattern" "3626bp3e.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wolf with Yellow Eyes, Black Scars, Fangs, Closed / Open Mouth Pattern (front)""3626CPAP.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wolf with Yellow Eyes, Black Scars, Fangs, Closed / Open Mouth Pattern (rear)""3626CPAP.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Yellow Eyes and Mouth and Aluminum Foil Blotches Pattern" "3626CP8F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------Non-standard heads------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Alien E. T." "27956.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Alien E. T. with Blue Eyes and Grin Pattern" "27956PX1.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Alien Squidman" "85947.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Alien Squidman with Black Eyes and Lines Pattern" "85947P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Anubis Guard" "93248.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Anubis Guard with Gold Eye and Stripes Pattern" "93248PQ0.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Baby Head" "24581.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baby Head with Eyes and Smile Pattern" "24581P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cuboid" "19729.DAT" 0 1 0 0 0 1 0 0 0 1 0 -6 0 "Cuboid with Minecraft Pumpkin Pattern" "19729P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -6 0 "Cuboid with Minecraft Steve Pattern" "19729P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 -6 0 "Elf" "43745.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Elf with Green Eyes Pattern" "43745P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Ewok" "64805.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Gremlin" "26056.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Gremlin with Mogwai with Light Nougat Ears and Face, White Fur on Head and Around Right Eye and Dark Brown Eyes Pattern""26056PX0.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Goblin" "42109.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Gungan with Flat Eyes (Needs Work)" "92743.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Gungan with Split Eyes (Needs Work)" "30371.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Kel'Dor with Breathing Apparatus" "61200.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Kel'Dor with Dark Bluish Grey Breathing Apparatus Pattern" "61200PS0.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Martian Head with Clip" "30529.DAT" 0 1 0 0 0 1 0 0 0 1 0 32 0 "Martian Head with Clip with Eyes Plain Pattern" "30529P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 32 0 "Martian Head with Clip with Eyelashes Pattern" "30529P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 32 0 "Mechanical Head Cyborg" "87567.DAT" 0 1 0 0 0 1 0 0 0 1 0 32 0 "Mechanical Head Cyborg with Tan Face Pattern" "87567P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Head Cyborg with White Face Pattern" "87567P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Head SW Battle Droid" "30378.DAT" 0 1 0 0 0 1 0 0 0 1 0 32 0 "Mechanical Head SW Battle Droid w. Dark Red Insignia Pattern""30378PS2.DAT" 0 1 0 0 0 1 0 0 0 1 0 32 0 "Mechanical Head SW Battle Droid w. Orange Insignia Pattern""30378PS1.DAT" 0 1 0 0 0 1 0 0 0 1 0 32 0 "Mechanical Head SW Battle Droid w. Yellow Insignia Pattern""30378PS3.DAT" 0 1 0 0 0 1 0 0 0 1 0 32 0 "Mon Calamari" "64808.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Nautolan" "57901.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Nautolan, Black Eyes and Mouth, Brown Tentacle Bands" "57901P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Protocol Droid" "30480.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Protocol Droid with Light Yellow Eyes Pattern" "30480PS0.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Robot" "98384.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Robot with Blue Eyes and Red/yellow Teeth Display" "98384P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Rodian without Pattern" "47545.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Rodian with Eyes and Nose Pattern" "47545P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Round 1 x 1 x 1.333 Pencil Top" "29030.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Round 1 x 1 x 1.333 Pencil Top with Orange Eyes Pattern" "29030P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Round 1.8 x 1.8 Biscuit with Filling" "14397.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Round 1.8 x 1.8 Biscuit with Blue Filling, Black and Metallic Silver Gears on Front and White Clockface on Back Pattern""14397P01C01.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 24 0 "Round 1.8 x 1.8 Biscuit with Bright Pink Filling and Reddish Brown Eyes, White Brows and Mouth with Red Lips, Cheeks and Freckles Pattern""14397P03C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Round 1.8 x 1.8 Biscuit with Reddish Brown Filling and Reddish Brown Eyes and White Brows and Mouth with Dark Brown Moustache and Freckles Pattern""14397P02C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Round 1.8 x 1.8 Biscuit with Reddish Brown Filling and Reddish Brown Eyes and White Brows and Mouth with Freckles Pattern""14397P04C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Bart Simpson" "15523.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Bart Simpson with Eyes Looking Left Pattern" "15523P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Bart Simpson with Eyes Pattern" "15523P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Homer Simpson" "15527.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Homer Simpson with Half Closed Eyes Pattern" "15527P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Homer Simpson with Wide Open Eyes Pattern" "15527P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Lisa Simpson" "15524.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Lisa Simpson with Eyes Pattern" "15524P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Lisa Simpson with Worried Eyes Pattern" "15524P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Maggie Simpson" "15525.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Maggie Simpson with Wide Open Eyes Pattern" "15525P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Maggie Simpson with Worried Eyes Pattern" "15525P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Marge Simpson" "15522.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Marge Simpson with Eyes Looking Right Pattern" "15522P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Marge Simpson with Wide Open Eyes Pattern" "15522P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Ned Flanders" "15529.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Simpsons Ned Flanders w. Glasses, Hair, Moustache Pattern" "15529P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Skeleton with Five Spikes" "93064.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Skeleton with Helmet" "93065.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Skull" "43693.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SpongeBob" "54872.DAT" 0 1 0 0 0 1 0 0 0 1 0 8 0 "SpongeBob with Happy Pattern" "54872p01.DAT" 0 1 0 0 0 1 0 0 0 1 0 8 0 "SpongeBob with Shocked Pattern" "54872P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 8 0 "SpongeBob with Super Hero Pattern" "54872P09.DAT" 0 1 0 0 0 1 0 0 0 1 0 8 0 "Spongebob Octopus" "64767.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Spongebob Starfish" "54873.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Sonic the Hedgehog" "26051.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Sonic the Hedgehog with Green Eyes, Tan Face and Half Smile Pattern""26051P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Trandoshan" "87570.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Trandoshan with White Teeth and Orange Eyes with Black Pupil Pattern""87570P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Trandoshan with White Teeth and Orange Eyes with Black and White Pupil Pattern""87570P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Toydarian" "92759.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Toydarian with Watto Vest and Belt Pattern" "92759P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Wookiee with Bandolier" "30483.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Wookiee with Silver Bandolier/Black Nose Pattern" "30483P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Yoda with Curved Ears Type 1" "41880.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Yoda with Curved Ears Type 2" "13195.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Yoda with Curved Ears Type 2 with Black Eyes and Grey Hair Pattern""13195P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 24 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 [BODY] "Plain" "973.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "#1 Racing Pattern" "973P80.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "'S' Logo Grey / Blue Pattern" "973P23.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "'S' Logo Red / Black Pattern" "973P14.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "'Tine' Sticker" "973D01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "2 Chinese Letters Yellow Stripe Pattern" "973PAQ.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "3-Piece Suit, White Shirt and Red Tie Pattern" "973PDB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Air Gauge and Pocket Pattern" "973P29.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Airplane Logo Pattern" "973P16.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Airplane Logo, White Shirt and Suit Pattern" "973P8V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Airplane Logo and 'AIR' Badge Pattern" "973P85.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Anchor Motif Pattern" "973P09.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Apron and Lace Shirt Pattern" "973P4M.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Aquanaut Sub Logo, Zipper, and Weight Belt Pattern" "973PAG.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Aquashark Blue Shark with Red 'X' Pattern" "973PAK.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arctic Parka 'A1' Pattern" "973P7A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arctic Parka 'A2' Pattern" "973P7B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arctic Explorer Logo, Zipper and White Fur Trim Pattern" "973P92.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Argyle Sweater and White Shirt Collar Pattern" "973P93.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour Vest, Silver Wolf Head and Blue Round Jewel Pattern""973PAW.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Astro Pattern" "973P6F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Autoroute Pattern" "973P27.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Aviator Jacket w. Eagle/'SMH' on Back Pattern" "973PQ5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bandage and Gold Necklace Pattern" "973PQ0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bandage, Gold Necklace and Gold Belt Pattern" "973PQ1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Batman Logo in Yellow Oval with Yellow Utility Belt and Gold Buckle Pattern""973PBO.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Batman Robin Pattern" "973Pb2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black and Blue Marks, Red X-Men Buckle Belt Pattern" "973PC6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Collar and Pockets Pattern" "973pst.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Diagonal Zip and Pocket Pattern" "973p0b.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Dungaree Pattern" "973P1A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Falcon Pattern" "973P43.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Futuron Pattern" "973P6B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Half Pattern" "973PBM.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Spider, Yellow Circles and Red Shirt Pattern" "973P4K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Stripe Pattern" "973PX2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blacktron I Pattern" "973P52.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blacktron II Pattern" "973P51.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blouse, Belt and Necklace Pattern" "973PQ6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue and Mint Green Stripes Pattern" "973p2e.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Castle Bodice Pattern" "973P4N.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Construction Overalls and Silver Belt Pattern" "973P7O.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Dungaree Pattern" "973P1B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Futuron Pattern" "973P6C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Flowers on Tied Shirt Pattern" "973P2G.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Horizontal Stripes Pattern" "973p1d.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Imperial Guard Officer Pattern" "973P3R.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Imperial Guard Pattern" "973P3N.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Jesters Collar, Belt and Crown on Buckle Pattern" "973P4O.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Plaid Shirt" "973PDD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Shirt and Construction Zipper Jacket with Safety Stripes Pattern""973P8P.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Shirt and Safety Stripes Pattern" "973P8G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Shirt, Brown Suspenders and Construction Jacket with Safety Stripes Pattern""973P7P.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Striped Dungarees Pattern" "973P1R.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Undershirt Green Bow and Gun Pattern" "973PW5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue V-Neck, Pockets and 3 Buttons Pattern" "973P06.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Vest, Collar and Star Pattern" "973PAR.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Vest, Collar and Test Tube Pattern" "973PAS.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Vest, Pockets, Shirt and Drill Pattern" "973PAT.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Vest, Tools, Shirt and Bomb Pattern" "973PAU.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Body Armour with Dark Bluish Grey and Metallic Dark Grey Crossing Lines and Metallic Silver Teeth Necklace Pattern""973PC2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bomber Jacket and Black Shirt Pattern" "973P70.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bomber Jacket, Belt, Black Shirt Pattern" "973PA5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Vest, Ascot and Belt Pattern" "973P3B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Brown Vest, Buckle and String Bowtie Pattern" "973PW9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Business Suit and Tie, Breathing Apparatus, Octan Pattern" "973P6H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Buttons and Police Badge Plain Pattern" "973P1F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Card, Suit, Vest, and Gold Fob Pattern" "973PW8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Castle Breastplate Pattern" "973P40.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Castle Bodice and Cloak Pattern" "973P4H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Castle Chainmail Pattern" "973P41.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Castle Crossed Pikes Pattern" "973P42.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Castle Female Armour Pattern" "973P4G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Castle Red/Gray Pattern" "973P47.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Catsuit, Ring Zipper Pull and Belt Pattern" "973PB8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Chain Mail, Belt and Straps Pattern" "973PF2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Chef Pattern" "973p2a.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Chef Jacket with 8 Buttons a. Long Red Neckerchief Pattern""973P8T.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Classic Space Pattern" "973P90.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Classic Space Simulated Wear Pattern" "973P91.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Clockwork Robot Pattern" "973PC67.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Coastguard Logo, Zippers and Radio Pattern" "973PU0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Coral Shooting Heart and Rainbow Pattern" "973PCJF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Corset and Gold Trim Pattern" "973P4Z.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Asian Characters Front and Dragon Back Pattern" "973PNA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Construction Safety Vest with Reflective Stripes Pattern" "973P8I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Construction Vest with Reflective Stripe and Buckles, Front Pouch and Red Pen Pattern""973P9G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Corset with Reddish Brown Laces Pattern" "973p4w.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Crew Neck Sweater with Bright Pink Collar Pattern" "973PD17.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Crew Neck Sweater w. Collar and 'HAIL TO THE CHEF'Pattern" "973P89.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Crocodile Skin with Dark Red Scar and Blue Round Jewel (Chi) Belt Pattern""973PAZ.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Crown on DarkBlue/MediumBlue Quarters Pattern" "973p4j.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue Muscles and Gold Necklace Pattern" "973pq2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue Overalls, Tank Top, Gold Chains and Pendant Pattern""973PXB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Bluish Grey Corset, Laces and Rope Belt Pattern" "973PC5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Bluish Grey Straps, Belt, Pouches and 'ACU' Pattern" "973PXE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Bluish Grey Suit Lines and Tie Pattern" "973P9Y.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Brown Collar, Patch, Rope Belt and Pouch with Back Pattern""973P4Y.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Brown Collar, Patch, Rope Belt and Pouch without Back Pattern""973p4v.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Brown Muscles and Belly Pattern" "973PX1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Green Belt and Light Nougat, Olive Green and Orange Rectangles Pattern""973PX8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Green Corset with Leather Belt Pattern" "973p4x.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Grey, Black, and Yellow Batman Pattern" "973PB1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Orange Vest and Purple Bow Tie Pattern" "973pb7.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Pink Stomach Lines Pattern" "973P9D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Pink Stomach Lines and Tail on Back Pattern" "973PCBD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Doctor Coat over Medium Azure Undershirt, Stethoscope, Pocket with Pens Pattern""973P9M.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dragon Clasps and Red Ties Front and Dragon Back Pattern" "973PNB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dragon Head Pattern" "973P4B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dress and Red Beads Necklace Pattern" "973PD13.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dress, White Apron and Red Beads Necklace" "973P88.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dress with Wavy Lines Pattern" "973P5C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Exxon Logo Pattern" "973P1I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Explorien Logo Pattern" "973p55.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Extreme Team Jacket Logo Pattern" "973P8A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Blouse with Buttons, Dark Pink Panel and Name Badge Pattern""973P9A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Jumpsuit with Zipper, Markings, Classic Space Pattern""973P6G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Jumpsuit with Zipper with 'SALLY' Name Tag Pattern" "973P5A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Outline with White Tank Top with 'APERTURE' over Bright Light Blue Tank Top Pattern""973PX5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Pirate Corset with Gold and Blue Pattern" "973P3M.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Pirate Pattern" "973P38.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Top with Dark Pink Stripes and Flower Necklace Pattern""973P1Z.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Top with Two White Buttons and Black Straps Pattern" "973P9J.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Shiny Pink Robe with Spots Pattern" "973PHC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Shirt with Two Buttons and Shell Pendant Pattern" "973P8K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Shirt with Two Pockets, Tan Scarf and Black Belt with Gold Buckle Pattern""973PCD6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female Wetsuit, Coral and Dark Azure Trim and Turtle Logo Pattern""973PCKC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female White Shirt, Open Jacket Pattern" "973PAE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Gold Star and Zipper and Red Tied Sash and Muscles Outline Pattern""973PC1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Harlequin Black/White Pattern" "973PBA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Jacket, 2 Pockets, Buttons, Necklace Pattern" "973PBJ.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Lab Coat over Medium Blue Shirt w. ID Badge Pattern""973P8Q.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with LtPurple Scarf and Gray Belt Pattern" "973P7Y.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Top with Yellow Neck and White Undershirt Pattern""973P9F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Female with Zipper, Magenta and Medium Azure Markings Pattern""973PU1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Fire Fighter Five Button Pattern" "973P21.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Firefighter Vest with Gold Badge and Belt with Radio Pattern""973P9S.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Firefighter Vest with Reflective Stripes and Utility Belt Pattern""973P9R.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Firefighter Vest with Reflective Stripes with Heavy Duty Utility Belt Pattern""973P9T.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Firefighter Vest with Reflective Stripes, Pockets and Dark Blue Belt Pattern""973P9Q.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Firefighter Vest with Reflective Stripes, Utility Belt and Red Flashlight Pattern""973P9P.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Flight Suit Jacket, Name Tag, Badge and Zipped Pockets Pattern""973P1O.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Forestman and Purse Pattern" "973P46.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Forestman Black Collar Pattern" "973P50.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Forestman Blue Collar Pattern" "973P49.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Forestman Maroon Collar Pattern" "973P48.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Four Button Suit and Train Logo Pattern" "973P84.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Front and Rear Stickers w. 'TINE' Logo on Blue Background" "973D05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Fur Stole, Shoulder Strap and Belt with Gold Buckles Pattern""973PHD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Fob and 100 Dollar Bills Pattern" "973PWA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Ice Planet Pattern" "973P61.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Lion and Belt on Red/White Quarter Pattern" "973P4L.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Necklace and Yellow Undershirt Pattern" "973P72.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Tie Pin and Black Tie Pattern" "973PD7F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grey and Gold Batman Pattern" "973pb0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grey Muscles and Arc Reactor Pattern" "973PBH.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Castle Bodice Pattern" "973P4Q.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Dungaree Pattern" "973P1J.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Futuron Pattern" "973P6I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Lantern Logo on White Background and Muscles Outline Pattern""973PC0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Necklace with Small Bells and Belt with Buckle Pattern""973P0D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Overall and Blue Checkered Shirt Pattern" "973P9V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Stripes and Leather Strap Pattern" "973P3T.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gryffindor Uniform Pattern" "973PH1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Halter Top with Green Apples and Lime Spots Pattern" "973P1X.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Halter Top, Dolphins, Swirls and Stars Pattern" "973P9Z.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hooded Sweatshirt/Blue Pocket/Drawstring Pattern" "973p7j.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hooded Sweatshirt Open with Drawstrings over Dark Red Top Pattern""973P9B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hoodie with Bright Green Drawstrings and Waist, Equalizer Bars Pattern""973PU4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hoodie with White Drawstrings, Silver Adjusters and Kangaroo Pockets Pattern""973PUF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hoodie with White Laces, Blue Scrollwork and Kangaroo Pocket Pattern""973P1V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hoodie with Zipper over Lime and Green Striped Shirt Pattern""973P99.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hogwarts Uniform Pattern" "973PH0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Horse Head Pattern" "973P2M.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hospital EMT Star of Life, Open Collar, Buttons and Pocket Pen Pattern""973P8N.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP Harry Potter Uniform Gryffindor Stripe, Shield Pattern" "973PHA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP Jacket with 4 Button Vest and Bow Tie Pattern" "973PH4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP Narcissa Malfoy Pattern" "973PH9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP with Dark Red Sweater and Yellow Neck Pattern" "973ph8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP with Grey Sweater and Light Nougat Neck Pattern" "973ph7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP with Jacket and Dark Red Sweater Pattern" "973ph6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "HP with Jacket and Light Grey Sweater Pattern" "973ph5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Imperial Soldier Pattern" "973P3U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids Female, Blue Diamond under Circuits Pattern" "973P58.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids Robot Pattern" "973P53.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids with Blue X under Circuits Pattern" "973P56.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids with Green Circuitry and Silver Hose on Sides" "973P6K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids with Silver Circuitry, Lightning Bolts over Blue Circle""973P67.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids with Silver Logo on Black Panels" "973P57.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids with Silver X on Green Verniers" "973P59.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Fist Pattern" "973PBQ.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Classic Pattern" "973PBT.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark VI Pattern" "973PBB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark VII Pattern" "973PBC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark XLII Pattern" "973PBF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark XVII Pattern" "973PBE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Patriot Armoured Suit Pattern" "973PBG.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Spider Pattern" "973PBU.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ivy Dress Pattern" "973PB5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket, Badge and Red Tie Pattern" "973P7R.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket, Bow Tie, Vest, Boutonniere Pattern" "973PC23.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket, Orange Vest, Green Neck-chief Pattern" "973PB3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket, Pink Shirt, Ring on Necklace Pattern" "973p7h.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket, Pocket, Badge, Blue Tie Pattern" "973P7Q.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket, Silver Zipper and Sand Blue Shirt Pattern" "973PHH.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket, Tie and Police Badge Yellow Star Pattern" "973p76.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket, White Shirt and Dark Pink Tie Pattern" "973PD31.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket, White Shirt, and Necklace Pattern" "973PA8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket, Zippered Pockets and Classic Space Logo Pattern" "973P6J.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket Hoodie over Light Blue Sweater Pattern" "973PU7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket Open over Red and Light Green Top with Necklace Pattern""973P1W.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket and Medium Nougat Collar over Light Bluish Grey Shirt Pattern""973P9L.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket over Bright Light Blue Shirt, Gold Necklace with Heart and Belt Pattern""973PUE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket over Light Blue Button Down Shirt Pattern" "973P7Z.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket over Medium Blue Skin and Light Blue Waist Pattern" "973PD1D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket over Shirt and Prison Stripes Pattern" "973p7t.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket with Metallic Gold Trim and Red Sash Pattern" "973P3L.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket with Pockets over Dark Red V-Neck Sweater Pattern" "973P1Y.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jacket with Striped Trim, Silver Buttons and Pockets over White Undershirt Pattern""973PUA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jail Stripes and '23768' Pattern" "973P7K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jumping Dolphin in Blue Oval Pattern" "973P2I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jumpsuit, 'P.V.' ID Badge and 'PETER' with Ghostbusters Logo on Back Pattern""973PX4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Knit Sweater Pattern" "973P9C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Launch Command Logo and Equipment Pattern" "973p1q.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Leather Jacket Pattern" "973P28.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Leather Jacket and Badge Pattern" "973P7U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Leather Jacket and Light Gray Shirt Pattern" "973PA9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Leather Jacket, Badge, 'POLICE' Back Pattern" "973p7n.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Leather Jacket, Slash Pockets and Waistband over Red Shirt, Silver Oval Belt Buckle Pattern""973P9E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Lifebelt Logo and ID Card Pattern" "973P79.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Light Blue Parabola Shaped Belly Pattern" "973PCFD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Light Grey Waist Pattern" "973PD1E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Lion Gold on Blue Shield Pattern" "973P4F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Lion Head Medallion and Fur Trim Pattern" "973PF4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Logo Vestas Dark Blue Letter V Pattern" "973P0C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Armour, Brown Belt & Gold Buckle Pattern" "973PM5.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Button Shirt with Braces Pattern" "973PM2.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Coat, DkBluish Grey Shirt, Evenstar Pendant Pattern" "973PM7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Cloak, Rope and Belt Pattern" "973PM1.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Cloak with Dark Bluish Grey Folds Pattern" "973PM9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Jacket and Dark Red Vest Pattern" "973PM3.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Jacket and Yellow Vest Pattern" "973PM8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Leather Armour with Buckle Pattern" "973PM0.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Orc Leather Armour Pattern" "973PMA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Scale Armour and Belt Pattern" "973PM6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Shirt, Dark Brown Belt and Bag Pattern" "973PM4.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Uruk-Hai Lurtz Muscles Outline Pattern" "973PMB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Magenta Questionmark Pattern" "973PB6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mail Horn Pattern" "973P1S.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Maroon/Red Quarters Shield Pattern" "973P4U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mayan Necklace, Tribal Shirt, and Navel Pattern" "973PAC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "MBA Level 1 Logo Pattern" "973PT0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "MBA Level 2 Logo Pattern" "973PT1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Medallion, Belt and Silver Buttons Pattern" "973p3d.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Medium Azure Vest, Orange Shirt and Lime Bow Pattern" "973PC4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Medium Blue Trim and Flowers Pattern" "973P96.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Metallic Silver Roman Segmented Body Armour Pattern" "973PC6A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Modern Firefighter Type 1 Pattern" "973p77.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Modern Firefighter Type 2 Pattern" "973p78.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "MTron Logo Pattern" "973P68.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Muscles, Light Bluish Grey Shadow and Gold Belt Pattern" "973PBI.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Necklace and Blue Squares Pattern" "973PWE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Necklace and Fringe Pattern" "973PC11.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Neon Yellow Stripes, Radio and Badge Pattern" "973P7V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ninja Wrap, Gold Shuriken and Armour Pattern" "973PN6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ninja Wrap, Gold Shuriken and Dagger Pattern" "973PN7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ninja Wrap, Silver Shuriken and Dagger Pattern" "973PN5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Octan OIL Badge Pattern" "973P81.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Octan Logo Pattern" "973PT2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Old Obi-Wan Pattern" "973PS6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Open Jacket, Blue Top and Navel Pattern" "973PD1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Open Jacket over Striped Vest Pattern" "973P34.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Open Jacket with 4 Metallic Gold Buttons over White Shirt and Tie Pattern""973PU3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Open Suit Jacket with White Shirt, Dark Red Tie and Reddish Brown Belt Pattern""973P9I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Open Suit Revealing Superman Logo Pattern" "973PBK.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Orange Dungarees, Sweater, Blue Pen in Pocket Pattern" "973P8M.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Orange Giraffe Spots on Front and Back Pattern" "973PDA4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Page Suit, Gold Buttons and Dark Green Trim Pattern" "973PUD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Palm Tree Pattern" "973P2H.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Palm Tree and Dolphin Pattern" "973P2J.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Palm Tree and Horse Pattern" "973P2K.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Patch Pocket Pattern" "973P26.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pharaoh Breastplate Pattern" "973PA2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pinstripe Vest, Red Tie and Pocket Watch Pattern" "973P9H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pinstriped Jacket and Gold Tie Pattern" "973P8L.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Captain Pattern" "973P36.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Captain and White Ascot Pattern" "973P3K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Green Vest, Shirt, and Belt Pattern" "973P3C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Jacket, Torn White Shirt, Big Belt Buckle Pattern" "973P3P.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Open Jacket over Brown Vest Pattern" "973P39.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Purple Vest and Anchor Tattoo Pattern" "973P30.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Ragged Shirt and Dagger Pattern" "973P3A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Stripes Blue/White Pattern" "973P3E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Stripes Blue/Cream Pattern" "973P32.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Stripes Red/Black Pattern" "973P33.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Stripes Red/Cream Pattern" "973P31.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Vest, Anchor Tattoo, Rope on Back Pattern" "973P3V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pirate Vest with 3 Gold Buttons over Red and White Striped Shirt Pattern""973P3G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Plain Shirt with Pockets Pattern" "973P7G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Plate Mail and Chains Pattern" "973PF3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pockets, Bright Green Shirt and 8-Bit Alien Pattern" "973PXC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pockets, Radio, Badge and Belt Pattern" "973P0G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Police Female Shirt with Gold Badge, Pocket and Black Tie Pattern""973P7L.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Police Jacket, Silver Badge, 4 Buttons and Belt Pattern" "973PCBF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Police Suit with Tie, Gold Star Badge and Light Blue Shirt Pattern""973PU8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Police Uniform Vintage with Gold Star Badge, Buttons, Buckle and Black Belt Pattern""973PU9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Polo Shirt, Name Badge and LEGO Logo on Back Pattern" "973P1L.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Polo Shirt with Pocket with Pen and LEGO Logo on Back Pattern""973P98.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Prisoner and '50380' Pattern" "973P7S.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Purple Greatcoat Pattern" "973phb.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Purple Greatcoat without Border Pattern" "973PHF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Racing Jacket and Two Stars Pattern" "973P1H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Racing Jacket and Two Stars Red Pattern" "973P1N.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Rear Sticker White '1' on Transparent Background" "973D06.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Collar, Belt with Pouch, Metallic Gold Buckles, Laces and Dark Green Stitches Pattern""973PF5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Cross and Stethoscope Pattern" "973P25.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Cross Pattern" "973P24.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Dungaree Pattern" "973P1C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Futuron Pattern" "973P6D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Horizontal Stripes Pattern" "973p1E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Imperial Guard Officer Pattern" "973P3S.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Imperial Guard Pattern" "973P3Q.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red, Green and White Feather Necklace and Red, Green Belt with White Dots and Black Outline Pattern""973P3J.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red, Green and White Floral Necklace and Black Cleavage Pattern""973P3I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Loincloth and White Bone Necklace Pattern" "973P3H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Necklace and Blue Undershirt Pattern" "973P71.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red on Bottom and Fringe Pattern" "973pwd.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Shirt and Suit Pattern" "973P22.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Straps and Belt, Yellow Clasps and Cord and Muscles Outline Pattern""973PBY.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Truck Pattern" "973P1T.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Undershirt and Fringe Pattern" "973PW7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red V-Neck and Buttons Pattern" "973P17.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Vest and Train Logo Pattern" "973P82.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red and Gray Shirt, Pot Belly, Jacket Pattern" "973PAF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reddish Brown Apron with Cup and Name Tag Pattern" "973PUG.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reddish Brown and Dark Tan Tie and Lapels, Lavender Shirt Pattern""973PHE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red/Peach Quarters Shield Pattern" "973P4T.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red/White Waist, Zipper and White Star Pattern" "973pbl.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Rear Sticker White "1" on Transparent Background" "973D06.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "RES-Q Orange Pockets and Logo Pattern" "973P8B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Riding Jacket Pattern" "973P12.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Riddler Black Question Mark on Chest and Lavender Belt Pattern""973PBN.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Robe with Black Gathers and White Neck Pattern" "973PD99.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Robot Pattern" "973P63.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Rock Raiders Jet Pattern" "973PAJ.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Royal Knights Lion Head and Neck-Chain Pattern" "973P4E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Royal Knights Lion-Head Shield Pattern" "973P4D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Rumpled Shirt, 2 Revolvers in Belt Pattern" "973PAA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Safari Shirt, Black Neck and Brown Holster Pattern" "973PA7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Safari Shirt, Blue Tee, Red Bandana Pattern" "973PA6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Safari Shirt, Gun, Red Bandana and White Chest Pattern" "973PAX.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Safari Shirt, Gun, Red Bandana and Yellow Chest Pattern" "973PA3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Safari Shirt, Tan Bandana and Compass Pattern" "973PQ7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Safari Shirt with Red Scarf, Belt and Water Bottle Pattern""973PC27.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Safety Vest with Reflective Stripes over Shirt, Red Pen Pattern""973P8R.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Safety Vest with Reflective Stripes, Pocket and Train Logo Pattern""973P8O.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Safety Vest with Reflective Stripes, Reddish Brown Shirt and Belt with Pouches and Pliers Pattern""973P9O.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Samurai Dragon Robe Pattern" "973PN0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Samurai Robe, Sash and Dagger Pattern" "973PN1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Scale Armour, Crown on Buckle and Chest Strap Pattern" "973PF1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Scale Mail and Red Diamond Amulet Pattern" "973P4C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Scarlet Spider Pattern" "973PBS.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Security Guard Pattern" "973PB4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shell Logo Pattern" "973P60.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sheriff Pattern" "973PW4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirt Collar and Sand Green Neck Pattern" "973PX0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirt with 3 Flowers over Yellow and Silver Stripe Pattern""973P8Y.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirt with Black Belly Bump and Collar Outline Pattern" "973PD11.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirt with Cargo Logo Pattern" "973P2N.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirt with Dark Turquoise and Dark Pink Vertical Stripes Pattern""973PUB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirt with Red Collar and Spaceship Orbiting Classic Space Helmet Pattern""973P97.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirt, Badge, Blue Tie, 'POLICE' Back Pattern" "973P7M.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirt, Pink/Salmon Tie and ID Badge" "973P87.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Armour Front and Back and Drill Pattern" "973PAV.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Ice Planet Pattern" "973P62.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Metal Plates and Dark Pink Electrical Wires and Buttons Pattern""973PBX.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Zod Emblem and Oval Belt Buckle and Muscles Outline Pattern""973PBW.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Six Button Suit, Red Tie, and Airplane Pattern" "973P8U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Six Button Suit and Airplane Pattern" "973p04.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Six Button Suit and Anchor Pattern" "973p05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skull Badge, Chains, Armour and Belt Pattern" "973PF0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skull and DkPink Roses Pattern" "973PC00.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skull and Red Roses Pattern" "973PC44.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Slingshot on Back Pattern" "973PD12.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Slytherin Uniform Pattern" "973PH2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Shirt '10' and 'ZIDANE' Pattern" "973PG0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Shirt with Octan Logo and Blue Stripes Pattern" "973PC4B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team Goalkeeper and White '1' Pattern" "973PG1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team Red/Blue Stripes and Red # 2 Pattern" "973PG2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team Red/Blue Stripes and Red # 3 Pattern" "973PG3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team Red/Blue Stripes and Red # 4 Pattern" "973PG4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team Red/Blue Stripes and Red # 7 Pattern" "973PG5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team Red/Blue Stripes and Red # 9 Pattern" "973PG6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team Red/Blue Stripes and Red #10 Pattern" "973PG7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team Red/Blue Stripes and Red #11 Pattern" "973PG8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team Red/Blue Stripes and Red #18 Pattern" "973PG9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team White Stripes and White # 2 Pattern" "973PGA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team White Stripes and White # 3 Pattern" "973PGB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team White Stripes and White # 4 Pattern" "973PGC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team White Stripes and White # 7 Pattern" "973PGD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team White Stripes and White # 9 Pattern" "973PGE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team White Stripes and White #10 Pattern" "973PGF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team White Stripes and White #11 Pattern" "973PGG.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Soccer Team White Stripes and White #18 Pattern" "973PGH.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Space Police II and Radio Pattern" "973P69.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Space Police II Chief" "973P6A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Space Port Logo, Tube and 'C1' Pattern" "973P8E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Spacesuit, Silver Belt, Chest Piece, Space Shuttle Pattern""973P8S.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Spacesuit with Front Strap, Badges and Ports Pattern" "973P5B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Spider-Girl Pattern" "973PBP.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Spider Man Pattern" "973PBV.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sports Shirt with '39', Orange Basketball and Orange and Red Diamonds Pattern""973P9K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Spotted Singlet and Necklace Pattern" "973p2f.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Spyrius Pattern" "973P66.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Stethoscope and Pocket with Pens Pattern" "973P86.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sticker Shell Logo on White Background" "973D04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Straight Zipper Jacket Pattern" "973P13.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Strapless Suntop Pattern" "973P2C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Striped Shirt and Silver Buttons Pattern" "973P3F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Studded Armour Pattern" "973P45.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Studded Leather Tunic and Belt Pattern" "973P4I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Studios Director Pattern" "973PD0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Submarine and Gauges Pattern" "973P08.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Suit Jacket, Lapels, Red Lining and White Shirt with Collar Pattern""973PXA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Suit Jacket, Pink Shirt and Magenta Scarf Pattern" "973P9W.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Suit and Tie Pattern" "973P18.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Suit and Red Tie with Train Logo Pattern" "973P83.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Suit with Pocket, Red Tie, Train Pattern" "973P8H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Superman Logo and Dark Blue Muscles Pattern" "973pb9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Suspenders and Red Bowtie Pattern" "973PA1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Armor Clone Trooper Pattern (Clone Wars)" "973PSU.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Belt Pockets and Necklace Blissl Flute Pattern" "973PRG.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Black Vest and White Shirt Pattern" "973PS5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Blast Armour (Green Plates) Grey Pattern" "973PSB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Blast Armour (Green Plates) Bl.Grey Pattern" "973PRB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Blast Armour (Silver Plates) Pattern" "973PSJ.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Blast Armour (Uncoloured Plates) Pattern" "973PRC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Cad Bane Pattern" "973PSW.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Camouflage Smock Pattern" "973PSM.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Closed Shirt and Brown Belt Pattern" "973PR0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Dark Red Robe Pattern" "973PSX.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Darth Vader Grey Pattern" "973PS7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Darth Vader Bluish Grey Pattern" "973PRA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Darth Vader Death Star Pattern" "973PSZ.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Grey Shirt, Belt with Red Buckle Pattern" "973PR7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Gungan Dark Gray/Dark Tan Shirts Pattern" "973PR6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Gungan Gold Trim Pattern" "973PSL.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Hoth Trooper Pattern" "973PSH.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Imperial Grand Moff Pattern" "973PR9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Imperial Officer Pattern" "973PSQ.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Imperial Shuttle Pilot Pattern" "973PSN.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Imperial Trooper Armor Pattern" "973PSI.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Jawa Pattern" "973PSS.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Jawa with Dark Brown Pouches and Black and Tan Straps" "973PRI.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Jedi Robes and Sash Pattern" "973PS2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Kylo Ren with Jacket with Silver Checkered Lines and Belt Pattern""973PRL.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Layered Shirt, Brown Belt Pattern" "973PR3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Layered Shirt, Brown Belt, Braid Pattern" "973PR4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Layered Shirt, Waist Sash Pattern" "973PS8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Leia Hoth Jacket Pattern" "973PRD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Loose Dress Light Bluish Grey Folds Pattern" "973PSY.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Loose Dress Light Grey Folds Pattern" "973PRY.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Loose Shirt, Black Belt and Silver Buckle Pattern" "973PSO.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Moisture Farmer Pattern" "973PSV.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Nute Gunray Pattern" "973PRH.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Pocket-Vest and Techno-Buckle Pattern" "973PSC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Protocol Droid Pattern" "973psr.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Rebel A-Wing Pilot Pattern" "973PS0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Rebel Mechanic Pattern" "973PSA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Rebel Pilot Pattern" "973PS1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Rebel Pilot Bluish Grey Pattern" "973PR8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Robe and Rope Belt Pattern" "973PR2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Robe, Sash and Silver Neck Clasp Pattern" "973PR1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Shadow Trooper Pattern" "973PRK.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Scout Trooper Pattern" "973PSE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Scout Trooper Bluish Grey Pattern" "973PRE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Shirt with Open Collar No Vest Pattern" "973PS4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Shirt with Open Collar and Light Bluish Grey Wrinkles Pattern""973PRN.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Stormtrooper Pattern" "973PSK.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Tank Top Pattern" "973PRF.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW TIE Fighter Pilot Pattern" "973PSP.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Tunic and Belt Pattern" "973PSF.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Vest, White Shirt and Light Nougat Neck Pattern" "973PR5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Wrap-Around Tunic Pattern" "973PS3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Wrap-Around Tunic and Utility Belt with Pouch Pattern" "973PRM.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sweater V-Neck over Light Blue Shirt Pattern" "973P94.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sweater with Dark Azure Shirt with Collar and Orange Ascot Tie Pattern""973PX3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sweater, Bow and Heart Shaped Necklace Pattern" "973P9U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "T-Shaped Green Neck Pattern" "973PX7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "T-Shaped Light Nougat Neck Pattern" "973PX6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tan Chest and Black and White Tail to the Left Pattern" "973PDB7.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tan Chest and Black and White Tail to the Right Pattern" "973PDB8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tank Top, Braces and Yellow Skin Pattern" "973PQ4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tank Top, Stains, Wrench, and Tattoo Pattern" "973PAB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tank Top and 2 Dark Red Dots Pattern" "973PXD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Telephone Pattern" "973P8F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Three White and Silver Squares Pattern" "973P8X.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Town Vest with Pockets and Striped Tie Pattern" "973P8J.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Train Jacket and Red Neckerchief Pattern and Bold Train Logo""973P07.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Train Logo and Red Diagonal Stripes Pattern" "973P19.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tri-Coloured Shield and Gold Trim Pattern" "973p4s.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tri-Coloured Shield Large Pattern" "973P4R.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "TV Logo Pattern Large Pattern" "973p1m.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "TV Logo Pattern Small Pattern" "973P1K.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Two Pocket Shirt with Red Bandana and Light Nougat Neckline Pattern""973PU2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "T-Shirt, Blue Dungarees and Tools Pattern" "973P8Z.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "T-Shirt with 4 White Horizontal Stripes Front and Back with Cat Pattern""973P9N.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "UFO Alien Orange and Silver Pattern" "973P54.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "UFO Alien Triangular Insignia Pattern" "973P6U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "UFO Alien Yellow Insignia, 3 Blue Bars Pattern" "973P6V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "UFO Alien Circuitry, Red Level Pattern" "973P6W.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "UFO Silver and Gold Circuitry Pattern" "973P6X.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Unitron Pattern" "973P64.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "US Cavalry General Pattern" "973PW1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "US Cavalry Officer Pattern" "973PW2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "US Cavalry Soldier Pattern" "973PW3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "V-Neck Shirt and Blue Overalls Pattern" "973P7W.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vertical Red Stripes and 'Clutchers' Pattern" "973PC3G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vertical Striped Blue/Red Pattern" "973P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vertical Striped Red/Blue Pattern" "973P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with Patch Pockets Pattern" "973P73.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with White Shirt and Blue Striped Tie and Buttons Pattern""973PUC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest, Patch Pockets and Police Badge Yellow Star Pattern" "973P74.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest, Slingshot in Belt Pattern" "973PAD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Voldemort Robe Pattern" "973PH3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Waistcoat, White Shirt and Bandolier Pattern" "973PQ3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Waiter Pattern" "973P20.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "War Machine Armoured Suit Pattern" "973PBD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White/Blue Triangles, Blue/White Amulet Pattern" "973PWC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White/Blue Triangles, Red/White Amulet Pattern" "973PWB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White/Red Armour and White Belt" "973PWF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White/Yellow/Orange Racesuit Pattern" "973P95.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Belt with Light Bluish Grey Triangle Buckle Pattern" "973PXF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Braces and Cartridge Belt Pattern" "973PW6.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Buttons and Police Badge Plain Sticker" "973D03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Diagonal Zip and Pocket Pattern" "973p0a.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Envelope and Zipper Pattern" "973P7X.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Fear Lantern Logo and Muscles Outline Pattern" "973PBZ.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Jesters Collar, Belt and Lion Head on Buckle Pattern""973P4P.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Jester Collar, Female Outline and Black Quarters Pattern""973PC3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Orca Belly Pattern" "973PD6E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Rope and Patched Collar Pattern" "973pdg.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Scarf and Brown Belt Pattern" "973PAY.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Shirt and Jacket Pattern" "973P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Shirt with Dark Blue Tie, Gold Airline Pin, Belt a. ID Badge Pattern""973P8W.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Shirt, Black Tie and Ticket Machine Pattern" "973PHI.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Shirt, Red Collar, Black Zip, Badge and Coast Guard (1996) Logo Pattern""973P0H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Shirt, Red Tie, Black Suit Outline and Three Blue Buttons and Coast Guard (1996) Logo Pattern""973P0I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Suit, Brown Vest and Tie Pattern" "973PA4.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Tiger Pattern" "973PBR.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Vertical Stripes and Red Bow Tie Pattern" "973P7I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Windsurfboard Pattern" "973P2D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wolfpack Pattern" "973P44.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Yellow Buttons and Grey Belt Sticker" "973D02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Yellow Chest and White Beads Necklace Pattern" "973PD14.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Yellow Futuron Pattern" "973P6E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Yellow Neck and Patch Pockets Pattern" "973P9X.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Zipper and Police Badge Plain Pattern" "973P1G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Zipper Jacket, White Shirt, Name Tag and Radio in Pocket Pattern""973PU5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Zipper Jacket and 3 Pockets Pattern" "973P1U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Zipper Jacket and Police Logo Pattern" "973P75.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Zippers, Badge with Minifig Head, Radio and Belt Pattern" "973P0F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------Non-standard torsi------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baby Body" "25126.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baby Body with Yellow Hands Pattern" "25126P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baby Body with Yellow Hands and Bib with Elephant Pattern" "25126P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baby Body with Bodysuit" "15526.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Cuboid Torso with Stud on Front" "24078.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Head and Torso" "53988.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Mechanical Torso" "30375.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Mechanical Torso with Blue Insignia" "30375PS3.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Mechanical Torso with Orange Dot Insignia Pattern" "30375PS4.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Mechanical Torso with Orange Insignia" "30375PS1.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Mechanical Torso with Red Dot Insignia Pattern" "30375PS7.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Mechanical Torso with Tan Insignia" "30375PS2.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Mechanical Torso with Tan Three Dot Insignia Pattern" "30375PS6.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Mechanical Torso with Yellow Dot Insignia Pattern" "30375PS5.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Mechanical Torso with 4 Side Attachment Cylinders" "54275.DAT" 0 1 0 0 0 1 0 0 0 1 0 10 0 "Mechanical Torso Cyborg" "87566.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Mechanical Torso Cyborg with Tan Pattern" "87566P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Mechanical Torso Cyborg with White Pattern" "87566P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 40 0 "Short with Ridged Extended Back with Orange Collar and Black Tie Pattern""98127PD7F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Short with Ridged Extended Front" "98127.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skeleton Torso" "6260.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skeleton Torso with Shoulder Rods" "60115.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Torso with Integral Arms" "17.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 [BODY2] "Plain" "3815B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Belt and Copper Buckle Pattern" "3815BPX2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Belt and Metallic Silver Buckle Pattern" "3815BPX1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Belt with Silver Belt Buckle Pattern" "3815BP8I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Wizard Buckle Pattern" "3815BP40.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Clockwork Robot Pattern" "3815BPC67.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue Coattails and Dark Tan Vest Tails Pattern" "3815BPH0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Bluish Grey Belt with Silver Buckle and Rivets Pattern" "3815BPAW.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Bluish Grey Robe Lines Pattern" "3815BPB8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Orange Belt and Metallic Gold Buckle with Cow Skull Pattern""3815BPK1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Belt and DarkBlue Loincloth Pattern" "3815BPQ0.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Belt and Orange Cable Pattern" "3815BP6U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold O-Belt and Loincloth Pattern" "3815BPQ2.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold X-Belt and Decorated Loincloth Pattern" "3815BPQ1.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Harlequin Black Square Pattern" "3815BPBA.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Holster and Belt Pattern" "3815BPA9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark XLII Pattern" "3815BPBF.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark XVII Pattern" "3815BPBE.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Patriot Armoured Suit Pattern" "3815BPBG.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Laboratory Smock Pattern" "3815BPDE.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Leather Belt and Red Diamonds Pattern" "3815BP4F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Coat, Shirttails and Belt Pattern" "3815BPM2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Dark Red Belt and Scale Armour Pattern" "3815BPM1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Leather Armour Pattern" "3815BPM0.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Medium Azure and Magenta Stripes Pattern" "3815BPU1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Purple Greatcoat with Dark Grey Border Pattern" "3815BPHB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red/White Triangles Pattern" "3815BPW1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Coattails Pattern" "3815BPX0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Roman Tunic and Belt Pattern" "3815BPC6A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Tied Sash Pattern" "3815BPC1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Robot Pattern" "3815BP63.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Scale Mail Pattern" "3815BP41.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirttails Pattern" "3815BP42.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Belt Pattern" "3815BP6W.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Belt and Salmon Cable Pattern" "3815BP6V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Studded Belt Pattern" "3815BPC44.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Gunbelt Pattern" "3815BPS5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 ; Update 2023-01 "SW Kylo Ren Silver Checkered Lines Pattern" "3815BPS1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Stormtrooper Pattern" "3815BPSK.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 ; Update 2023-01 "SW White Robe Pattern" "3815BPS2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "War Machine Armoured Suit Pattern" "3815BPBD.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wetsuit, Coral and Dark Azure Trim Pattern" "3815BPCKC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Apron Pattern" "3815BP89.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White and Gold Markings Pattern" "3815BP6G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------Non-standard hips-------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Hole" "41879B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short without Hole" "41879A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Black Open Toe Shoes Pattern" "41879AP01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Dark Blue Shoes Pattern" "41879AP02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Dark Blue Toes Pattern" "41879AP04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Horizontal Stripe" "16709.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Light Nougat Feet Pattern" "41879BP01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Magenta Open Toe Shoes Pattern" "41879BP02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Orange Toes Pattern" "41879BP03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Stripe, Slingshot on Back Pattern" "16709P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Yellow Horizontal Stripe Pattern" "16709P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short with Yellow Legs and White Open Toe Shoes Pattern""16709P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Skirt" "36036.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Skirt with Black Folds Pattern" "36036PH1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Skirt with White Robe with Reddish Brown and Dark Tan Hem Pattern""36036PH0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips with Tentacles" "87749.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Genie" "98376.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Genie with Red Belt Pattern" "98376P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost" "19859.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Black Pattern" "19859P08.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Bright Light Orange Pattern" "19859P09.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Dark Blue Pattern" "19859P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Dark Bluish Grey Pattern" "19859P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Dark Green Pattern" "19859P0B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Lavender Pattern" "19859P07.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Medium Lilac Pattern" "19859P0A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Orange Pattern" "19859P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Red Pattern" "19859P06.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Sand Green Pattern" "19859P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Ghost with Yellow Pattern" "19859P05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips Mermaid Tail Standing" "51345.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Legs Old" "15.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Martian Legs" "30530.DAT" 0 1 0 0 0 1 0 0 0 1 0 48 0 "Mechanical Legs" "30376.DAT" 0 1 0 0 0 1 0 0 0 1 0 46 0 "Slope Brick 65 2x2x2" "3678a.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Slope Brick 65 2x2x2 with DkGn Dress Pattern" "3678bp4x.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Slope Brick 65 2x2x2 with Queen's Dress Pattern" "3678ap4h.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Slope Brick 65 2x2x2 with White Apron Pattern" "3678bp4w.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Slope Brick 65 2x2x2 with Witch's Dress Pattern" "3678ap01.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 [BODY3] "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour SW Clone Trooper Tasset" "61190c.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Costume Flowerpot" "35709.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Skirt Straight Curved 0.55 Length" "65753.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Skirt Wavy" "24782.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Skirt 0.7L with 11 Diamond Points" "16820C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skirt 1.1L with Straight Bottom" "600880C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skirt 1.1L w. Straight Bottom w. Dark Green Apron Pattern" "600880P01C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skirt 1.4L with Straight Bottom" "U9209C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skirt 1.4L w. Straight Bottom w. White Apron Pattern" "U9209P01C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skirt 1.5L Fringed" "14295C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skirt 1.5L Fringed with Stepped Edge" "18200C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tail Duck" "24779.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tail Duck with Blue Hip Pattern" "24779PK0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Utility Belt" "27145.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 [NECK] "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Airtanks" "3838.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Armour Breastplate with Shoulder Pads Large, Pentagonal Cut-out and 4 Studs on Back""22402.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour Plate" "2587.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour Plate with LOTR King Theoden Pattern" "2587PM0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour Samurai" "30174.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour Shoulder" "30121.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour Shoulder Pads with 1 Stud on Front, 2 Studs on Back" "11097.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour Shoulder Pads with 4 Spikes" "15490.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 ; Update 2023-01 "Armour Shoulder Pads with 6 Spikes" "12618.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour Shoulder Pads with Neck Protection, 1 Stud on Front, 2 Studs on Back""15086.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour Shoulder Pads with Ridges" "11438.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour SW Clone Trooper Pauldron" "61190b.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Armour SW Clone Trooper Tasset" "61190c.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arrow Quiver" "4498.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Backpack Non-Opening" "2524.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Backpack Openable Closed" "30158c01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Backpack Skydiver" "12897.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Backpack with Horizontal Pin Holes" "15406.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Backpack with Sleeping Bag" "30323.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Backpack with Three Pouches and Bedroll" "26073.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Backpack with Three Pouches and Blue Bedroll Pattern" "26073P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Backpack with Three Pouches and Dark Green Bedroll Pattern""26073P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Backpack with Three Pouches and Lime Bedroll Pattern" "26073P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Backpack with Three Pouches and Red Bedroll Pattern" "26073P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bandana" "30133.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bandana Ninja" "15619.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bat Wing" "98722.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard Long Forked" "60750.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard Long with Five Braids" "60749.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard Medium Short" "93223.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard Short" "15501.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Beard with Rounded End" "10052.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bracket 1 x 1 - 1 x 1 Thin with Stud Hole" "42446.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bracket 1 x 1 - 1 x 1 Thick with Stud Hole" "28974.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bracket 1 x 1 - 1 x 2" "18986.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Breastplate with Fins and Embossed Atlantis Triangle" "89917.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 ; Update 2023-01 "Body Armour Vest" "15423.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cape" "4524.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Cape Cloth (Formed)" "50231C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cape Cloth Floating (Formed)" "50231C02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cape Cloth High Rounded Collar (Formed)" "20551C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cape Cloth High Rounded Collar with Black Outside Pattern (Formed)""20551P01C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cape Cloth Scalloped 5 Points (Formed)" "56630C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cape Cloth Short (Formed)" "99464C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cape Cloth Tattered and Pixelated (Formed)" "U9490C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cape Cloth with Holes and Tattered Edges (Formed)" "86038C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cape Cloth with Inside Dark Red Pattern (Formed)" "50231P01C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cape Cloth with Pointed Ends and Collar (Formed)" "42450C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Collar Fur" "26066.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Collar SW Darth Vader Helmet Bottom" "19917.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Container D-Basket" "4523.DAT" 0 1 0 0 0 1 0 0 0 1 0 1 0 "Eagle Wing" "93250.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Eagle Wing with Tan Feathers and Red/Gold Pattern" "93250PQ0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Epaulette" "2526.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Face Scarf with Notch in Back" "24504.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hair Beard" "6132.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hood Folded Down" "15428.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hood Folded Down with Purple Inside Pattern" "15428P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jet Pack with 2 Octagonal Nozzles" "6023.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Jet-Pack with Stud On Front" "4736.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Lifevest" "2610.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Moustache" "15439.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sack" "92590.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Satchel (on right shoulder)" "61976.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Satchel (on left shoulder)" "61976.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Scabbard for Two Swords" "88290.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Scarf Long Wrapped" "25376.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Scuba Tank" "30091.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Scabbard (on right shoulder)" "95348.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Scabbard (on left shoulder)" "95348.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Vest" "3840.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with 3 Yellow/Black Chevrons Upwards Pattern" "3840P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with Crown on Dark Pink Sticker" "3840D01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with Crown on Violet Sticker" "3840D05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with Green Chevrons on Yellow Sticker" "3840D03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with Green Chevrons on Yellow.LtGrey Sticker" "3840D07.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with White Maltese Cross on Red Sticker" "3840D02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with White Maltese Cross on Red/LtGrey Sticker" "3840D06.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with Yellow Trefoils on Blue Sticker" "3840D04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Vest with Yellow Trefoils on DkBlue Sticker" "3840D08.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 [LARM] "Right" "3818.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm Curved with Hand" "U9332.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Arm with Black Lower Arm Pattern" "16000P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Elbow Pad and Ghostbusters Logo Pattern" "3818PX0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Medium Azure and Magenta Stripes Pattern" "3818PDA2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Medium Blue Lower Arm Pattern" "16000P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Medium Nougat Lower Arm Pattern" "16000P05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Light Nougat Lower Arm Pattern" "16000P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Yellow Lower Arm Pattern" "16000P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------Non-standard arms------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm Bat Wing" "10303.DAT" 0 1 0 0 0 0 -1 0 1 0 0 0 0 "Arm Robot with Hollow Stud" "62691.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm Robotic with Blaster Socket" "34335.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm SW Super Battle Droid" "41890.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Arm SW Super Battle Droid with Blaster" "64796.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Clip and Rod Hole with Thin Forearm" "53989.DAT" 0 0 0 1 0 1 0 -1 0 0 0 0 0 "Bionicle Arm Barraki" "57588.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bird Wing" "11263.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Flipper" "24074.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Mechanical Arm with Clips Parallel" "30377.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Clips at 90 Degrees" "87568.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Clips at 90 Degrees with Tan Pattern on Left Side""87568P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Clips at 90 Degrees with Tan Pattern on Right Side""87568P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Clips at 90 Degrees with White Pattern on Left Side""87568P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Clips at 90 Degrees with White Pattern on Right Side""87568P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Reinforced Elbow with Clips at 90 degrees""15341.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Straight with Clips at 90 degrees" "59230.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm with Clip and Rod Hole" "76116.DAT" 0 0 0 1 0 1 0 -1 0 0 0 0 0 "Mechanical Arm with Clip and Rod Hole with Thick Forearm" "98313.DAT" 0 0 0 1 0 1 0 -1 0 0 0 0 0 "Skeleton Arm" "6265.DAT" 0 1 0 0 0 1 0 0 0 1 -6 0 0.5 "Wiry Bent with Clip" "10058.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 [RARM] "Left" "3819.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm Curved with Hand" "U9332.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Black Lower Arm Pattern" "16001P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Elbow Pad and Pocket Pattern" "3819PX0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Medium Blue Lower Arm Pattern" "16001P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Medium Nougat Lower Arm Pattern" "16001P05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Light Nougat Lower Arm Pattern" "16001P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Yellow Lower Arm Pattern" "16001P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------Non-standard arms------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm Bat Wing" "10303.DAT" 0 -1 0 0 0 0 -1 0 -1 0 0 0 0 "Arm Robot with Hollow Stud" "62691.DAT" 0 -1 0 0 0 -1 0 0 0 1 0 0 0 "Arm SW Super Battle Droid" "41890.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Arm SW Super Battle Droid with Blaster" "64796.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Arm with Clip and Rod Hole with Thin Forearm" "53989.DAT" 0 0 0 1 0 1 0 -1 0 0 0 0 0 "Bionicle Arm Barraki" "57588.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bird Wing" "11263.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Flipper" "24074.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm with Clips Parallel" "30377.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Clips at 90 Degrees" "87568.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Clips at 90 Degrees with Tan Pattern on Left Side""87568P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Clips at 90 Degrees with Tan Pattern on Right Side""87568P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Clips at 90 Degrees with White Pattern on Left Side""87568P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Clips at 90 Degrees with White Pattern on Right Side""87568P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Bent with Reinforced Elbow with Clips at 90 degrees""15341.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm Straight with Clips at 90 degrees" "59230.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Arm with Clip and Rod Hole" "76116.DAT" 0 0 0 1 0 1 0 -1 0 0 0 0 0 "Mechanical Arm with Clip and Rod Hole with Thick Forearm" "98313.DAT" 0 0 0 1 0 1 0 -1 0 0 0 0 0 "Skeleton Arm" "6265.DAT" 0 1 0 0 0 1 0 0 0 1 6 0 0.5 "Wiry Bent with Clip" "10058.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 [LHAND] "Hand" "3820.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hand Harpoon" "65611.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hand Hook" "2531.DAT" 0 1 0 0 0 1 0 0 0 1 0 0.4 0 "Baseball Glove" "13543.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Boxing Glove" "95321.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 [RHAND] "Hand" "3820.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hand Harpoon" "65611.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hand Hook" "2531.DAT" 0 -1 0 0 0 1 0 0 0 1 0 0.4 0 "Baseball Glove" "13543.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Boxing Glove" "95320.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 [LHANDA] "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Acoustic Guitar" "25975.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Acoustic Guitar with Black Fingerboard and Neck and Metallic Silver Strings Pattern""25975P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Acoustic Guitar with Black Tuning Pegs and Metallic Silver Strings Pattern""25975P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Duckling" "49661.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Duckling with Black Eyes and White Pupil with Orange Beak Pattern""49661P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Duckling with Black Eyes and White Pupil with Red Beak Pattern""49661P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Clam Closed" "30218-F1.DAT" 0 0 1 0 0 0 1 1 0 0 12 -2 -29 "Animal Lobster" "27152.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Lobster with Eyes Pattern" "27152P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Snake" "30115.dat" 0 0.469472 0 -0.882948 0.882948 0 0.469472 0 -1 0 0 -4 -4 "Animal Starfish" "33122.dat" 0 -1 0 0 0 0 1 0 1 0 0 -26 -6 "Arm Bandage Wrapped" "30924.DAT" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Axe" "95330.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Axe Blocky" "18788.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Axe Head Faceted with Bar 0.5L" "22407.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Axe with Pick End and Long Handle" "39802.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Axe with Pick End and Long Handle with Red Head Pattern" "39802P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Axe with Red Head and Silver Blade Pattern" "95330P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Axe with Twin-Blade" "95052.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Battleaxe" "3848.dat" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Bar 0.5L with Blade 3L" "64727.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bar 0.5L with Curved Blade 2L" "87747.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bar 0.5L with Faceted Spike 1L" "88695.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bar 0.8L with Tip Bat Emblem" "37720D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bar 1 L with Three Prongs" "68211.DAT" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Bar 1.5L with Clip without Hole in Shaft" "48729a.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Bar 1.5L with Clip with Truncated Sides and Hole in Shaft" "48729B.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Bar 2L with Ball Joint-8" "22484.DAT" 0 0 -1 0 0 0 1 -1 0 0 0 -10 0 "Bar 3L" "87994.dat" 0 1 0 0 0 1 0 0 0 1 0 -40 0 "Bar 3L with White Ends Pattern" "87994p01.dat" 0 1 0 0 0 1 0 0 0 1 0 -40 0 "Bar 4L Light Sabre Blade" "30374.dat" 0 1 0 0 0 -1 0 0 0 -1 0 12 0 "Bar 4L with Middle Bat Emblem" "37720C.DAT" 0 0 -1 0 1 0 0 0 0 1 0 -32 0 "Bar 4.5L Straight" "71184.dat" 0 1 0 0 0 1 0 0 0 1 0 20 0 "Bar 4.5L with Handle" "87618.dat" 0 -1 0 0 0 -1 0 0 0 1 0 -80 0 "Bar 6L with Thick Stop" "63965a.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bar 6.6L with Stop" "4095.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bar with 8-Shaped Modified Plate with Offset Stud" "50018E.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Bar with Bat Wings" "98721.DAT" 0 0 -1 0 1 0 0 0 0 1 0 0 0 "Bar with Octagonal 1 x 1 Plate with Opposing Studs and Bar at 90 Degrees""50018D.DAT" 0 1 0 0 0 1 0 0 0 1 0 -18 0 "Barbed Wire Loop" "62700.dat" 0 0 -1 0 -1 0 0 0 0 -1 0 -2 0 "Baseball Bat" "93220.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baseball Bat with Black Grip Pattern" "93220P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baseball Bat with Three Metallic Silver Diamonds with Rivets Pattern""93220P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baseball Bat with Three White Diamonds and White Grip Pattern""93220P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baseball Bat with White Grip Pattern" "93220P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Binoculars with Round Eyepiece" "30162.dat" 0 1 0 0 0 0 -1 0 1 0 -5 -1.6 0 "Bladed Claw Spread" "10187.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bone 2L" "93160.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bone 5L" "92691.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Boombox 1 x 3 x 1" "93221.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Black Rimmed Speakers, Cassette Player and Switches Pattern""93221P03.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Magenta Rimmed Speakers, Cassette Player, Switches and Lime Decoration Pattern""93221P05.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Metallic Gold Rimmed Speakers and Digital Music Player Pattern""93221P04.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Metallic Gold Rimmed Speakers, Cassette Player and Buttons Pattern""93221P01.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Metallic Gold Rimmed Speakers, Rotary Knobs and Sound Wave Display Pattern""93221P06.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Metallic Silver Rimmed Speakers, Cassette Player and Buttons Pattern""93221P02.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 -6 "Boomerang" "25892.DAT" 0 0 -1 0 0.5 0 0.866025 -0.866025 0 0.5 4 -20 -4 "Bottle Cylindrical" "95228.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Bottle Cylindrical with Bottle Ship Pattern" "95228p01.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Bow with Arrow" "4499.dat" 0 0 0 -1 0 1 0 1 0 0 0 1 0 "Brick 1 x 2 x 0.667 with 8 Studs and Angled Handle" "15071.DAT" 0 1 0 0 0 0.920505 0.390731 0 -0.390731 0.920505 0 -11 0 "Broom" "4332.dat" 0 -1 0 0 0 1 0 0 0 -1 0 -76 0 "Bucket 1 x 1 x 1 Conical with Raised Handle" "95343C01.DAT" 0 0 -0.642788 -0.766044 1 0 0 0 -0.766044 0.642788 0 -1.5 0 "Bucket 1 x 1 x 1 Cylindrical with Raised Handle" "12884C01.DAT" 0 0 -0.642788 -0.766044 1 0 0 0 -0.766044 0.642788 0 -1.5 0 "Bugle" "71342.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Camera Movie" "30148.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Camera Snapshot Type 1" "30089A.dat" 0 0 0.5 0.866025 0 0.866025 -0.5 -1 0 0 -4.062 2.5 -18 "Camera Snapshot Type 2" "30089B.DAT" 0 0 0.5 0.866025 0 0.866025 -0.5 -1 0 0 -4.062 2.5 -18 "Camera with Side Sight" "4360.dat" 0 0 0 1 0 1 0 -1 0 0 0 -24 6.5 "Castle Lance" "3849.dat" 0 1 0 0 0 0 1 0 -1 0 0 40 0 "Chakram" "35485.DAT" 0 0 -1 0 -1 0 0 0 0 -1 0 -1 0 "Chainsaw Blade" "6117.DAT" 0 1 0 0 0 0 -1 0 1 0 0 -11 -8 "Cheerleader Pom Pom" "87997.DAT" 0 1 0 0 0 1 0 0 0 1 0 5 0 "Cheerleader Pom Pom with Blue Pattern" "87997p01.DAT" 0 1 0 0 0 1 0 0 0 1 0 5 0 "Cheerleader Pom Pom with Red Pattern" "87997p02.DAT" 0 1 0 0 0 1 0 0 0 1 0 5 0 "Circular Blade Saw" "30194.dat" 0 -1 0 0 0 -0.422618 0.906308 0 0.906308 0.422618 0 15 -17 "Cleaver" "98369.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Coin with '1' Gothic Type" "96904.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '2' Gothic Type" "96905.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '5' Gothic Type" "96906.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '10' Gothic Type" "96907.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '10' Sans-serif Type" "70501a.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '20' Sans-serif Type" "70501b.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '30' Sans-serif Type" "70501c.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '40' Sans-serif Type" "70501d.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Comb" "30112b.dat" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Compass" "74948.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Compass with Fleur de Lis Pattern" "74948P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Compass with White and Yellow Pattern" "74948P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Computer Laptop (Closed)" "62698-F3.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -2 0 "Conical Flask" "u9180.dat" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Conical Flask TransClear with Coloured Base" "u9180c01.dat" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Crossbow" "2570.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Crown with 5 Points" "39262.DAT" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Crutch" "24077.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 0 -66 "Cup" "3899.dat" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Black 'C:\' Pattern" "3899P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Black 'I Heart SOUTH PAWS' Pattern" "3899P05.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Black 'Shhh!' Pattern" "3899P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Black Outlined Marshmallow Face and Yellow and Orange Flames Pattern""3899P08.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Medium Lilac and Medium Lavender 'I Heart HLC' Pattern""3899P07.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Reddish Brown 'TVA' Logo on Metallic Gold Rectangle Pattern""3899P09.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with White 'DUNK ME!' Pattern" "3899P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with White Octan Logo Pattern" "3899P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup Stein with Handle" "68495.DAT" 0 0 0 -1 0 1 0 1 0 0 0 21 -16 "Cup Stein with Handle and Trans Bright Green Drink Pattern""68495P02.DAT" 0 0 0 -1 0 1 0 1 0 0 0 21 -16 "Cup Stein with Handle and Trans-Orange Drink Pattern" "68495P01.DAT" 0 0 0 -1 0 1 0 1 0 0 0 21 -16 "Cup Takeaway" "15496.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cup with Bar Handle" "38014.DAT" 0 1 0 0 0 1 0 0 0 1 0 10 -16 "Dagger" "88288.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dagger with Pearl Light Gray Blade" "88288P01.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dinner Plate" "6256.dat" 0 0.0954045 -0.866025 -0.490814 0.981627 0 0.190809 -0.165245 -0.5 0.850114 7 -5 -26 "Dinner Plate with Four Black Outlined Orange Bones Pattern""6256P01.DAT" 0 0.0954045 -0.866025 -0.490814 0.981627 0 0.190809 -0.165245 -0.5 0.850114 7 -5 -26 "Dinner Plate with Green and Lime Lettuce Leaf and Yellow Splotches Pattern""6256P02.DAT" 0 0.0954045 -0.866025 -0.490814 0.981627 0 0.190809 -0.165245 -0.5 0.850114 7 -5 -26 "Dinner Plate with Metallic Light Blue Swirl Pattern" "6256PH1.DAT" 0 0.0954045 -0.866025 -0.490814 0.981627 0 0.190809 -0.165245 -0.5 0.850114 7 -5 -26 "Drone Body with 4 Arms" "66967.DAT" 0 1 0 0 0 1 0 0 0 1 0 -9 0 "Dynamite Sticks Bundle" "64728.dat" 0 0.5 0 0.866025 0 1 0 -0.866025 0 0.5 0 -28 -9 "Electric Guitar Classic" "11640.DAT" 0 0 0 1 0 1 0 -1 0 0 0 40 0 "Electric Guitar Classic with Magenta, Bright Pink and Metallic Silver Stars Pattern""11640P01.DAT" 0 0 0 1 0 1 0 -1 0 0 0 40 0 "Electric Guitar V Shape" "93564.dat" 0 0 0 1 0 1 0 -1 0 0 0 4 0 "Electric Guitar V Shape, Silver Strings, White Body" "93564P01.dat" 0 0 0 1 0 1 0 -1 0 0 0 4 0 "Electric Guitar V Shape, Black Strings, DkPink Lightning" "93564P02.dat" 0 0 0 1 0 1 0 -1 0 0 0 4 0 "Feeding Bottle" "6206.DAT" 0 1 0 0 0 1 0 0 0 1 0 20 -20 "Figure Club" "60659.dat" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Figure Flask with Handle" "4429.DAT" 0 1 0 0 0 0.965926 -0.258819 0 0.258819 0.965926 0 -20 -30 "Food Apple" "33051.dat" 0 0.857167 0.515038 0 -0.515038 0.857167 0 0 0 1 14 33 0 "Food Banana" "33085.dat" 0 0 -1 0 1 0 0 0 0 1 0 0 0 "Food Bread Bun" "25386.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Food Carrot" "33172.dat" 0 1 0 0 0 1 0 0 0 1 0 -50 0 "Food Carrot Top" "33183.dat" 0 1 0 0 0 1 0 0 0 1 0 12 0 "Food Carrot with Bright_Green Leaves" "33172c02.dat" 0 1 0 0 0 1 0 0 0 1 0 10 0 "Food Carrot with Green Leaves" "33172c01.dat" 0 1 0 0 0 1 0 0 0 1 0 10 0 "Food Cherry" "22667.dat" 0 1 0 0 0 1 0 0 0 1 0 -11 0 "Food Croissant" "33125.dat" 0 0 1 0 -0.819152 0 0.573576 0.573576 0 0.819152 4 -27 -9 "Food French Bread" "4342.dat" 0 0 -0.292372 0.956305 1 0 0 0 0.956305 0.292372 4.5 0 5 "Food Ice Cream Cone" "33120.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Food Pie with Cream Filling" "93568.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Food Pie with White Cream Filling Pattern" "93568P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Food Pie with Yellow Cream Filling Pattern" "93568P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Food Popsicle" "30222.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Food Pretzel" "10170.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Food Sausage" "33078.dat" 0 0 -1 0 1 0 0 0 0 1 0 0 0 "Food Turkey Leg" "33057.dat" 0 0 0.985 -0.174 0 0.174 0.985 1 0 0 9 -24 -1 "Friends Access. Bag Round with Ruffle" "93090.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -28 "Friends Access. Bag Round w. Bright Pink Ruffle Pattern" "93090P01.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 -28 "Friends Access. Bag Round w. Dark Pink Ruffle Pattern" "93090P02.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 -28 "Friends Access. Bag Round w. Light Aqua Ruffle Pattern" "93090P03.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 -28 "Friends Access. Basket" "93092.DAT" 0 1 0 0 0 0 1 0 -1 0 -15 -2 -29 "Friends Access. Comb with Handle and 3 Hearts" "96482.DAT" 0 1 0 0 0 1 0 0 0 1 0 9 0 "Friends Access. Cupcake Case" "97784.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Friends Access. Cutlery Fork" "97781.DAT" 0 0 0 -1 0 1 0 1 0 0 0 -1 0 "Friends Access. Cutlery Knife" "97782.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Friends Access. Cutlery Spoon" "34173.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Access. Dish Rectangular" "97785.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Friends Access. Dish Round 2.7 x 2.7" "97783.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Friends Access. Frying Pan" "97790.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -56 -12 "Friends Access. Hair Brush with Heart on Reverse" "96480.DAT" 0 0 0 -1 0 1 0 1 0 0 0 9 0 "Friends Access. Hair Dryer" "96484.DAT" 0 1 0 0 0 1 0 0 0 1 0 8 0 "Friends Access. Hand Mirror with Heart on Reverse" "96488.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 9 0 "Friends Access. Hand-held Food Mixer" "97793.DAT" 0 1 0 0 0 0 1 0 -1 0 0 -3 0 "Friends Access. Key Ornamented with Stud" "19118.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1.5 0 ; Update 2023-01 "Friends Access. Lipstick Dual Mould with Black Handle Pattern""25866P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Friends Access. Lipstick Dual Mould with Light Bluish Grey Handle Pattern""25866P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Friends Access. Lipstick Dual Mould with White Handle Pattern""25866P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Friends Access. Lipstick (Complete)" "93094a.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Friends Access. Medical Feeding Bottle" "98393F.DAT" 0 0 0 1 0 1 0 -1 0 0 0 13 -4 "Friends Access. Medical Pen" "98393J.DAT" 0 1 0 0 0 1 0 0 0 1 0 9 0 "Friends Access. Mixing Bowl" "97791.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Friends Access. School Bag" "11245.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 0 -38 "Friends Access. School Bag with Medium Blue Buckle and Star Pattern""11245P01.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 0 -38 "Friends Access. Spatula with 3 Holes" "97787.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Frypan" "4528.dat" 0 0 1 0 0 0 1 1 0 0 -4 -24 0 "Goblet" "2343.dat" 0 1 0 0 0 1 0 0 0 1 0 -26 0 "Goblet with Hollow Stem" "6269.dat" 0 1 0 0 0 1 0 0 0 1 0 -26 0 "Gun Blaster with Studs on Sides, Bottom and Front" "44709.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gun Flintlock Pistol" "2562.dat" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Gun Laser Kryptonian" "13952.DAT" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Gun Laser Pistol with Trapezoidal Heat Diffusers" "87993.dat" 0 1 0 0 0 1 0 0 0 1 0 -4 0 "Gun Laser Pistol with Rounded Heat Diffusers" "13608.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gun Long Blaster" "57899.dat" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Gun Musket" "2561.dat" 0 0 0.707 0.707 0 0.707 -0.707 -1 0 0 -25.1 -33.7 0 "Gun Pistol Two Barrel" "95199.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Gun Revolver" "30132.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Gun Rifle" "30141.dat" 0 0 0 1 0 1 0 -1 0 0 0 -8 0 "Gun Semiautomatic Pistol" "55707a.dat" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Gun Shooting Blaster with Dark Bluish Grey Trigger" "15391c01.DAT" 0 1 0 0 0 1 0 0 0 1 0 4 0 "Gun Shooting Blaster with Trigger and TrOrange Projectile" "15391C02.DAT" 0 1 0 0 0 1 0 0 0 1 0 4 0 "Gun Short Blaster" "62885.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gun Small Blaster with Telescopic Sight" "92738.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gun SW Short Blaster" "58247.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Gun SW Small Blaster DC-17" "61190a.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Hairbrush with Long Handle" "3852A.DAT" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Hairbrush with Short Handle" "3852B.DAT" 0 1 0 0 0 1 0 0 0 1 0 -6 0 "Hand Armour with Two Studs" "15407.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 -10 "Hand Fan" "93553.dat" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Hand Gorilla Fist" "11092.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Hand Truck (Shortcut)" "2495c01.dat" 0 1 0 0 0 0 1 0 -1 0 22 -4 -58 "Handcuffs" "61482.dat" 0 1 0 0 0 1 0 0 0 1 24 16 12 "Harpoon" "57467.dat" 0 1 0 0 0 1 0 0 0 1 0 28 0 "Harpoon with Smooth Bar" "18041.DAT" 0 1 0 0 0 1 0 0 0 1 0 28 0 "Hockey Stick with 1.1 L Bar" "93559.DAT" 0 1 0 0 0 1 0 0 0 1 0 10 0 "Hockey Stick with 3.6 L Bar" "64000.DAT" 0 1 0 0 0 1 0 0 0 1 0 10 0 "Hose Nozzle with Side String Hole" "58367.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Hose Nozzle with Side String Hole Simplified" "60849.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Ice Axe" "30193.dat" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Ice Axe with 3-Rib Handle" "18738.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Jackhammer" "30228.dat" 0 0.326 0 0.946 -0.899 -0.309 0.31 0.292 -0.951 0.101 2.5 -18.5 11 "Key" "40359A.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Knife" "44658.DAT" 0 1 0 0 0 1 0 0 0 1 0 1 0 "Knife with Flat Hilt End" "95054.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Ladle" "4337.dat" 0 1 0 0 0 1 0 0 0 1 0 -36 0 "Lantern" "37776.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 0 "Lasso" "99253.DAT" 0 0 0 -1 0 1 0 1 0 0 0 0 0 "Life Ring" "30340.dat" 0 0 1 0 0 0 1 1 0 0 -4 16 -21 "Lifeguard Float" "90395.DAT" 0 0.34202 0.939693 0 0 0 -1 -0.939693 0.34202 0 3 20 -9.2 "Lightning" "59233.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Lightning with Marbled Medium Lilac Pattern" "59233P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Lightning with Marbled Trans Bright Green Pattern" "59233P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Lightning with Marbled Trans Purple Pattern" "59233P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Lightsaber Chrome Silver - 1 Side On" "577Bc01.dat" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Lightsaber Chrome Silver - 2 Sides On" "577Bc02.dat" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Lightsaber Hilt Short Curved" "61199.DAT" 0 1 0 0 0 1 0 0 0 1 0 -13.6 0 "Lightsaber Hilt Short Curved Light Bluish Grey - 1 Side On""61199C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -13.6 0 "Lightsabre Hilt with Bend" "42114.DAT" 0 1 0 0 0 0.930418 -0.366501 0 0.366501 0.930418 0 -19.5 -2.2 "Lightsaber Hilt with Bottom Ring" "577B.dat" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Lightsaber Hilt with Round Guard" "18673.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -16 0 "Lightsaber Hilt with Steep Sloping Fingers" "23306.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Lightsaber Metallic Dark Grey - 1 Side On Blade with Cross Bar""577BC03.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Lightsaber with Bend Chrome Silver - 1 Side On" "42114C01.DAT" 0 1 0 0 0 0.930418 -0.366501 0 0.366501 0.930418 0 -19.5 -2.2 "Lightsaber with Bend Chrome Silver - 2 Sides On" "42114C02.DAT" 0 1 0 0 0 0.930418 -0.366501 0 0.366501 0.930418 0 -19.5 -2.2 "Long Bow with Arrow" "93231.dat" 0 0.966 0 -0.259 0 1 0 0.259 0 0.966 0 -11 0 "Loudhailer" "4349.dat" 0 1 0 0 0 1 0 0 0 1 0 -16 0 "Loudhailer with Orange Stripe Pattern" "4349P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -16 0 "Machete" "29109.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Machine Gun with Drum Magazine" "55707b.dat" 0 1 0 0 0 1 0 0 0 1 0 -16 0 "Magic Wand" "6124.dat" 0 1 0 0 0 1 0 0 0 1 0 8 0 "Maracas" "90508.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Maracas with Green Border" "90508P01.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Medical Thermometer" "98393D.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -26 -5 "Megaphone" "39144.DAT" 0 1 0 0 0 1 0 0 0 1 0 -16 0 "Metal Detector" "4479A.DAT" 0 0 0 -1 0 1 0 1 0 0 0 -24 0 "Microphone" "90370.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Microphone with Black Top Half Sphere Pattern" "90370P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Microphone with Metallic Gold Top Half Sphere Pattern" "90370P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Microphone with Metallic Gold Top Pattern" "90370P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Microphone with Metallic Silver Top Half Sphere Pattern" "90370P05.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Microphone with Metallic Silver Top Pattern" "90370p01.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Mug" "33054.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 -20 "Oil Lamp" "98383.DAT" 0 1 0 0 0 1 0 0 0 1 0 4 -20 "Pharaoh's Staff with Forked End" "93252.dat" 0 1 0 0 0 1 0 0 0 1 0 -42 0 "Paint Brush" "93552.dat" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Paint Brush with Orange Tip Pattern" "93552P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Paint Brush with Silver Ring, Green Tip" "93552P01.dat" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Paint Brush with Silver Ring and Medium Azure Tip Pattern" "93552P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Paint Palette" "93551.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Paint Palette with Paint Drops Pattern" "93551P01.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Paint Roller Brush Handle" "12885.DAT" 0 1 0 0 0 1 0 0 0 1 0 8 0 "Pickaxe Blocky" "18789.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pike / Spear Elaborate with Metallic Silver Head" "90391P01.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pike / Spear Elaborate with Flat Silver Head" "90391P02.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pipe Wrench" "4328.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pitchfork" "4496.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Plant Flower Stem Green with Bar and Hole and 3 Plates 1 x 1 with 5 Petals""24855C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -19 0 "Plant Flower Stem with Bar Green with 3 Flowers" "99249C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Plant Flower Stem with Bar Green with 3 Flowers with 6 Rounded Petals" "99249C03.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Plant Flower Stem with Bar Green with 3 Roses" "99249C02.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Plant Flower Stem with Bar and 6 Stems and 6 Plates" "19119C02.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Plunger" "11459.DAT" 0 1 0 0 0 -1 0 0 0 -1 0 -20 0 "Plunger with Medium Nougat Handle" "11459P01.DAT" 0 1 0 0 0 -1 0 0 0 -1 0 -20 0 "Polearm Halberd" "6123.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pushbroom" "3836.dat" 0 0 0 -1 0 -1 0 -1 0 0 0 44 0 "Radio with Large Grille" "19220.DAT" 0 0 0 -1 0 1 0 1 0 0 0 0 0 "Radio with Long Handle" "3962b.dat" 0 0 0 -1 0 1 0 1 0 0 0 -1 0 "Radio with Short Handle" "3962a.dat" 0 0 0 -1 0 1 0 1 0 0 0 -1 0 "Rice Bowl" "34172.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Rice Bowl with Metallic Gold Stripes Pattern" "34172P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ring 1 x 1" "11010.dat" 0 0 -1 0 -1 0 0 0 0 -1 -4 -2 -6 "Ring with Triangle" "87748.dat" 0 0 1 0 -0.866 0 0.5 0.5 0 0.866 0 -2 -25 "Ring with Triangle with Gold Bands and Crab Pattern" "87748P01.dat" 0 0 1 0 -0.866 0 0.5 0.5 0 0.866 0 -2 -25 "Ring with Triangle with Gold Bands and Manta Ray Pattern" "87748P05.dat" 0 0 1 0 -0.866 0 0.5 0.5 0 0.866 0 -2 -25 "Ring with Triangle with Gold Bands and Shark Pattern" "87748P03.dat" 0 0 1 0 -0.866 0 0.5 0.5 0 0.866 0 -2 -25 "Ring with Triangle with Gold Bands and Squid Pattern" "87748P04.dat" 0 0 1 0 -0.866 0 0.5 0.5 0 0.866 0 -2 -25 "Ring with Triangle with Gold Bands and Triangle Pattern" "87748P06.dat" 0 0 1 0 -0.866 0 0.5 0.5 0 0.866 0 -2 -25 "Ring with Triangle with Gold Bands and Turtle Pattern" "87748p02.dat" 0 0 1 0 -0.866 0 0.5 0.5 0 0.866 0 -2 -25 "Rock 1 x 1 Gem Facetted" "30153.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Sack with Hand Grab" "10169.DAT" 0 0 0 -1 0.866025 0.5 0 0.5 -0.866025 0 0 9 -31 "Saucepan" "4529.dat" 0 0 1 0 0 0 1 1 0 0 -6 -24 0 "Saucer with Hollow Stud on Top" "38799.DAT" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Saxophone" "13808.DAT" 0 1 0 0 0 1 0 0 0 1 0 7 0 "Saxophone with Black Mouthpiece" "13808P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 7 0 "Serving Tray 2 x 3" "29635.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sextant" "30154.dat" 0 0 0 1 0 1 0 -1 0 0 0 -35 0 "Shield Broad with Spiked Bottom and Cutout Corner" "10049.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Broad w. Spiked Bottom, Cutout Corner, Hand Pattern" "10049P01.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Octagonal with Stud" "48494.dat" 0 0 0 1 -1 0 0 0 -1 0 0 -2 0 "Shield Octagonal without Stud" "61856.dat" 0 0 0 1 -1 0 0 0 -1 0 0 -2 0 "Shield Octagonal with Troll Skull on Dark Red Pattern" "61856P40.dat" 0 0 0 1 -1 0 0 0 -1 0 0 -2 0 "Shield Oval" "92747.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Oval with Large White Circle, Dark Purple Characters and Lines Pattern""92747P06.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Oval with Lime and White Circles, Dark Purple Arrows and Lines Pattern""92747P02.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Oval with Small Lime and Large White Circles, Dark Purple Chain and Lines Pattern""92747P04.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Oval with White, Lime and Medium Azure Circles, Dark Purple Lines Pattern""92747P03.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Oval with White, Lime and Medium Azure Circles, Lightning Bolt and Dark Purple Lines Pattern""92747P05.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Oval with SW Gungan Patrol Shield" "92747p01.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid" "2586.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with American Indian Pattern" "2586PW1.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Bat Pattern" "2586P4F.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Blue Dragon Pattern" "2586P4C.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Bull Head Pattern" "2586P4G.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Bull Head on Brown Border Sticker" "2586D01.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Crown on Dark/Med Blue Quarters Pattern" "2586P4J.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with DkGreen Dragon on Medium Nougat/Tan Pattern" "2586P4K.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Galloping Horse and Feathers Pattern" "2586PW2.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Gold Lion Head on Blue and White Pattern""2586P4M.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Golden Lion Pattern" "2586PH1.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Gold Lion on Red/White Quarters Pattern" "2586P4L.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Green Dragon Pattern" "2586P4B.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Indigo Islanders Pattern" "2586P30.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Red Fire Breathing Dragon Head on Black Background Pattern""2586P4N.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Royal Knights Lion Pattern" "2586P4D.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Silver Skull on Dark Red Pattern" "2586P4H.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with Silver Snake Pattern" "2586PH2.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Ovoid with SW Gungan Patrol Pattern" "2586PS1.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Pentagonal Castellated" "22408.DAT" 0 0 0 1 0 1 0 -1 0 0 0 4 0 "Shield Pentagonal Jagged" "22409.DAT" 0 0 0 1 0 1 0 -1 0 0 0 4 0 "Shield Rectangular Curved with Stud" "98367.DAT" 0 0 0 1 1 0 0 0 1 0 0 -1 0 "Shield Round" "3876.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Round Bowed" "75902.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Round Bowed with Bullseye with Star Pattern" "75902P02.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Round Bowed with DkGreen and Gold Rohan" "75902P01.dat" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Round Bowed with Gold Eagle Pattern" "75902P03.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Round Bowed with Mercedes-Benz Logo" "75902P04.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Round Bowed with SW Dejarik Hologame Board Pattern" "75902PS1.DAT" 0 0 0 1 -1 0 0 0 -1 0 -4 -1 0 "Shield Round Flat" "59231.dat" 0 0 0 1 0 1 0 -1 0 0 -10 -12 0 "Shield Round Flat with Helmet on Dark/Medium Blue Quarters Pattern""59231P40.DAT" 0 0 0 1 0 1 0 -1 0 0 -10 -12 0 "Shield Round Flat with Silver Skull on Dark Red Pattern" "59231P4H.dat" 0 0 0 1 0 1 0 -1 0 0 -10 -12 0 "Shield Round Type 2" "91884.DAT" 0 0 0 1 1 0 0 0 1 0 -4 -2 0 "Shield Round Type 2 w. Aztec Bird on Dark Red Pattern" "91884P04.DAT" 0 0 0 1 1 0 0 0 1 0 -4 -2 0 "Shield Round Type 2 w. DkBrown Ring and 4 Rivets Pattern" "91884P01.DAT" 0 0 0 1 1 0 0 0 1 0 -4 -2 0 "Shield Round Type 2 w. Dragon Heads and Ornaments Pattern" "91884P03.DAT" 0 0 0 1 1 0 0 0 1 0 -4 -2 0 "Shield Round Type 2 w. Silver Rivets Pattern" "91884P02.DAT" 0 0 0 1 1 0 0 0 1 0 -4 -2 0 "Shield Scarab" "93251.dat" 0 0 0 1 -1 0 0 0 -1 0 -9 -1 -1 "Shield Triangular" "3846.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Bat Pattern" "3846p4f.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Black Falcon Blue Border Pattern" "3846p45.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Black Falcon Yellow Border Pattern" "3846p46.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Blue Dragon Pattern" "3846p4c.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Blue Lion on Yellow Background" "3846p4g.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Crown on Dark/Med Blue Quarters" "3846P4J.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Crown on Dark-Pink Sticker" "3846d01.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Crown on Violet Sticker" "3846d05.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Dark Pink Jewel and Gold Border Sticker""3846D0A.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Dragon on Medium Nougat/Tan Pattern" "3846P4K.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Forestman Pattern" "3846p48.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Goblin King Eye Pattern" "3846PM0.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Gold Lion Head on Blue and White Pattern""3846P4M.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Gold Lion on Red/White Quart. Pattattern" "3846P4L.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Green Chevrons on Yellow Sticker" "3846d03.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Green Chevrons on Yellow.LtGray" "3846d06.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Lion Head, Blue and Yellow Pattern" "3846p4e.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Maroon/Red Quarters Pattern" "3846p4u.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Red in Blue Frame Pattern" "3846P47.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Red Cross and Helmet" "3846p01.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Red Dragon Head on Black Background Pattern""3846P4N.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Red/Peach Quarters Pattern" "3846p4t.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Royal Knights Lion Pattern" "3846p4d.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Town Hall Pattern" "3846P02.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with White Maltese Cross on Red Sticker" "3846d02.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Wolfpack Pattern" "3846p44.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Yellow Lion on Blue Background" "3846p4h.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Yellow Trefoils on Blue Sticker" "3846d04.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular with Yellow Trefoils on DkBlue Sticker" "3846d07.dat" 0 0 0 1 0 1 0 -1 0 0 0 -12 0 "Shield Triangular Long" "18836.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 0 "Shield Triangular Long with Bear Head on Dark Red and Red Background Pattern""18836P40.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 0 "Shield Triangular Long with Black Pyramid and Sun Pattern" "18836PQ0.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 0 "Shield Triangular Long with Dark Red Edge with Rivets and Black Bat on Metallic Silver Background Pattern""18836P42.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 0 "Shield Triangular Long with Gold Rampant Lions and Crossed Keys Pattern""18836P41.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 0 "Shovel" "3837.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Shovel Blocky" "18791.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Signal Holder" "3900.dat" 0 1 0 0 0 0 -1 0 1 0 0 -36 -2 "Signal Holder with Black 'POLICE' and Red Line Pattern" "3900P01.DAT" 0 1 0 0 0 0 -1 0 1 0 0 -36 -2 "Signal Holder with Green Circle on White Sticker" "3900d01.dat" 0 1 0 0 0 0 -1 0 1 0 0 -36 -2 "Ski Pole" "90540.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Sledgehammer" "75904.dat" 0 0 0 1 0 1 0 -1 0 0 0 -14 0 "Slingshot" "20546.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Slingshot with Bright Light Yellow Band Pattern" "20546P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Slingshot with Dark Tan Band Pattern" "20546P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Small Bow with Arrow" "95051.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -10 0 "Space Scanner Tool" "30035.dat" 0 1 0 0 0 1 0 0 0 1 0 -19 -10 "Spear with Round End" "4497.dat" 0 1 0 0 0 1 0 0 0 1 0 -40 0 "Spear with Flat End" "93789.DAT" 0 1 0 0 0 1 0 0 0 1 0 -40 0 "Spear with Four Side Blades" "43899.dat" 0 1 0 0 0 1 0 0 0 1 0 -144 0 "Speargun" "30088.dat" 0 1 0 0 0 1 0 0 0 1 0 -13 0 "Sports Barbells" "29592.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Spear Tip Faceted with Bar 0.4L" "27257.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Staff with Crescent End" "95050.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Staff with Spherical End" "95049.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Statuette" "90398.dat" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Statuette with Astronaut Pattern" "90398P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Steak on Bone" "98372.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Steak on Bone with Red Meat" "98372P01.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Stretcher with Bottom Hinges" "4714.DAT" 0 0 0 -1 1 0 0 0 -1 0 26 -74 -2 "Stretcher without Bottom Hinges" "93140.DAT" 0 0 0 -1 1 0 0 0 -1 0 26 -74 -2 "Suitcase (closed)" "4449-f1.dat" 0 0 0 -1 1 0 0 0 -1 0 0 0 0 "Suitcase with Iron Man Armoured Suit Mark V Stickers" "4449-F1D01.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 0 0 "Suitcase with Hinge with Lid (Complete)" "37702C01.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 0 "Suitcase with Long Handle (Closed)" "37178-F1.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 0 0 "Sundae Glass" "68504.DAT" 0 1 0 0 0 1 0 0 0 1 0 12 0 "Sword Blocky" "18787.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Cutlass" "2530.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Sword Dao with Curved Blade and Hilt" "25111.DAT" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Sword Double Blade with Bar Holder" "11103.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Greatsword" "59.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Katana (Dragon Guard)" "93055.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Katana Type 1 (Octogonal Guard)" "30173a.dat" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Sword Katana Type 2 (Square Guard)" "30173b.dat" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Sword Katana Type 3 (Square Guard with Smooth Endcap)" "21459.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Sword Katana 3.5 L with Short Smooth Grip and Square Crossguard""37341C.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Sword Khopesh" "93247.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Sword Longsword" "98370.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Sword Rapier" "93550.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Sword Roman Gladius" "95673.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Sword Saber with Clip Pommel" "59229.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Sword Scimitar" "43887.dat" 0 1 0 0 0 1 0 0 0 1 0 -18 0 "Sword Scimitar with Jagged Edge" "60752.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Shortsword" "3847.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Sword Shortsword with Elaborate Hilt" "76764.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Sword Small with Angular Guard" "95053.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Sword Small with Curved Blade" "10053.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Sword Uruk-Hai" "10050.dat" 0 -1 0 0 0 1 0 0 0 -1 0 4 0 "Sword with Angular Hilt" "48495.dat" 0 0 0 -1 0 1 0 1 0 0 0 -10 0 "Sword with Hexagonal Decorations" "24108.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Sword with Hexagonal Decorations with Flat Silver Pattern" "24108PE1.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Sword with Hexagonal Decorations with Light Bluish Grey Pattern""24108PE2.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Sword with Hexagonal Decorations with Pearl Gold Pattern" "24108PE3.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Sword with Jagged Edges" "11439.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Syringe" "87989.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Teapot" "23986.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -10 -20 "Teddy Bear with Arms Down" "98382.DAT" 0 0 -0.069756 -0.997564 0.809017 0.586353 -0.041002 0.587785 -0.807046 0.056434 -1.6 -4 -28 "Teddy Bear with Arms Down, Tan Belly, Black Eyes Pattern" "98382p01.DAT" 0 0 -0.069756 -0.997564 0.809017 0.586353 -0.041002 0.587785 -0.807046 0.056434 -1.6 -4 -28 "Telescope" "64644.dat" 0 1 0 0 0 1 0 0 0 1 0 -11 0 "Tennis Racket" "93216.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Tomahawk with Flat-Silver Blade" "13571.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool 4-Way Lug Wrench" "604553.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Tool Adjustable Wrench with 3-Rib Handle" "604614.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Battery Powered Drill" "604549.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Binoculars Space" "30304.dat" 0 1 0 0 0 0 -1 0 1 0 -5 -1 0 "Tool Box Wrench" "55300.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Box Wrench with 3-Rib Handle" "604552.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Circular Tooth Blade with Cover with Opposing Studs and Bar""50018G.DAT" 0 1 0 0 0 1 0 0 0 1 0 -28 0 "Tool Crowbar" "92585.DAT" 0 1 0 0 0 1 0 0 0 1 0 -30 0 "Tool Fishing Rod" "2614.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Fishing Rod 8L Clip at End" "93222.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Tool Fishing Rod 12L Straight End" "96858.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Gavel" "11250.DAT" 0 0 0 1 0 1 0 -1 0 0 0 6 0 "Tool Grappling Hook" "30192.dat" 0 1 0 0 0 -1 0 0 0 -1 0 9 0 "Tool Grappling Hook with Bar" "15534.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -11 0 "Tool Hammer" "55295.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Hammer with 3-Rib Handle" "604547.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Handaxe" "3835.dat" 0 1 0 0 0 1 0 0 0 1 0 -16 0 "Tool Hexagonal with Hollow Stud with Perpendicular Bar and Ribbed Handle""50018C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Hexagonal with Opposing Studs and 3 Ribbed Handles at 120 Degrees""50018A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Hose Nozzle with Handle" "4210a.dat" 0 -1 0 0 0 1 0 0 0 -1 0 -12 0 "Tool Hose Nozzle with Handle at Bottom and Top" "22921.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Impact Wrench with Opposing Studs with Angled Ribbed Handle and Rear Bar Handle""50018B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass" "30152a.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass with TransClear Lens" "30152AP01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass with TransRed Lens" "30152AP02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass with Removable TransClear Lens" "90463.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass with Thick Frame and Lens" "10830.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass with Thick Frame and TransClear Lens""10830P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Mallet" "4522.dat" 0 0 0 1 0 1 0 -1 0 0 0 -28 0 "Tool Oar" "2542.dat" 0 -1 0 0 0 -1 0 0 0 1 0 40 0 "Tool Oar Reinforced" "87585.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -30 0 "Tool Oilcan" "55296.DAT" 0 1 0 0 0 1 0 0 0 1 0 -6 0 "Tool Oilcan with Ribbed Handle" "604548.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Tool Open End Wrench" "55299.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Open End Wrench with 3-Rib Handle" "604551.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Pickaxe" "3841.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Tool Power Drill" "55297.dat" 0 1 0 0 0 1 0 0 0 1 0 -6 0 "Tool Screwdriver" "55298.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Screwdriver with Wide Head and 3-Rib Handle" "604550.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Scissors" "18920.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Tool Socket Wrench with Ratchet and 3-Rib Handle" "604615.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Spanner/Screwdriver" "4006.dat" 0 0 0 -1 0 1 0 1 0 0 0 -14 0 "Tool Rip Saw" "18826.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Rip Saw with Reddish Brown Grip Pattern" "18826P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Wand" "36752A.DAT" 0 1 0 0 0 1 0 0 0 1 0 4 0 "Toolbox 1 x 3 with Handle" "98368.dat" 0 0 0 1 -1 0 0 0 -1 0 0 -2 0 "Toolbox 1 x 3 with Handle and Classic Space Logo on Back Pattern""98368P01.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -2 0 "Torch" "3959.dat" 0 1 0 0 0 1 0 0 0 1 0 -13 0 "Torch without Grooves" "86208.dat" 0 1 0 0 0 1 0 0 0 1 0 -13 0 "Toy Winder Key" "98375.dat" 0 0 0 -1 1 0 0 0 -1 0 0 -2 -20 "Tray Oval" "11252.dat" 0 0 -1 0 1 0 0 0 0 1 -6 -3 -16 "Trophy Cup 2.4L" "10172.DAT" 0 0 0 1 0 1 0 -1 0 0 0 34 -20 "Trophy Cup 2.4L with Metallic Silver Terrier Dog Pattern" "10172P01.DAT" 0 0 0 1 0 1 0 -1 0 0 0 34 -20 "Trophy Cup 3.6L" "89801.DAT" 0 1 0 0 0 1 0 0 0 1 -30 54 0 "Umbrella Folded" "27150.DAT" 0 1 0 0 0 1 0 0 0 1 0 18 0 "Underwater Scooter" "30092.dat" 0 -1 0 0 0 1 0 0 0 -1 20 -22 -8.5 "Weapon Billy Club" "13790.DAT" 0 1 0 0 0 1 0 0 0 1 0 -7.5 0 "Weapon Blade 3.4 L with Bar 3.6 L" "11156.DAT" 0 1 0 0 0 1 0 0 0 1 0 20 0 "Weapon Bladed Claw" "88811.dat" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Weapon Blade Faceted 3.8 L with Bar 0.5 L" "23860.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Weapon Blaster with Two Barrels" "17010.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Weapon Club with Spikes" "88001.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Weapon Crescent Blade Serrated with Bar 0.5L" "98141.dat" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Weapon Curved Blade 8.5L with Bar 1.5L" "98137.dat" 0 1 0 0 0 1 0 0 0 1 0 12 0 "Weapon Grenade with Large Tapered Top and Four Indents" "40598C.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Weapon Grenade with Small Tapered Top and Two Ridges" "40598D.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Weapon Hand Dagger" "88812.dat" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Weapon Nunchaku with Black Handles (Straight)" "67100P01-F1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Weapon Sai" "98139.DAT" 0 1 0 0 0 1 0 0 0 1 0 7 0 "Weapon Spear Short with Pin Hole" "98338.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Weapon Trident" "92290.dat" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Weapon Web Effect Web 4 x 3 with Bar" "36083C.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Weapon Web Effect 5L Narrow with Bars at Both Ends" "36083A.DAT" 0 1 0 0 0 1 0 0 0 1 0 5 0 "Welding Gas Torch with Hose and Gas Cylinder Top" "13793.DAT" 0 1 0 0 0 1 0 0 0 1 30 35 0 "Whip" "2488.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Whip in Latched Position (Shortcut)" "2488c01.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Whip Bent Flexible" "88704.DAT" 0 0 0 -1 0 1 0 1 0 0 0 10 0 "Whip Bent Flexible (Formed for Electrical Roof Wiring - Right Aligned)""88704-F1.DAT" 0 0 0 -1 0 1 0 1 0 0 0 10 0 "Whip Bent Flexible (Formed for Electrical Roof Wiring - Left Aligned)""88704-F2.DAT" 0 0 0 1 0 1 0 -1 0 0 0 10 0 "Whip Coiled" "61975.dat" 0 0 0 -1 0 1 0 1 0 0 0 -8 0 "Whisk" "29636.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wine Glass" "33061.dat" 0 1 0 0 0 1 0 0 0 1 0 -32 0 "Zip Line Handle" "30229.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 [RHANDA] "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Acoustic Guitar" "25975.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Acoustic Guitar with Black Fingerboard and Neck and Metallic Silver Strings Pattern""25975P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Acoustic Guitar with Black Tuning Pegs and Metallic Silver Strings Pattern""25975P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Duckling" "49661.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Duckling with Black Eyes and White Pupil with Orange Beak Pattern""49661P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Duckling with Black Eyes and White Pupil with Red Beak Pattern""49661P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Clam Closed" "30218-F1.DAT" 0 0 -1 0 0 0 -1 1 0 0 -12 -2 -29 "Animal Lobster" "27152.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Lobster with Eyes Pattern" "27152P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Animal Snake" "30115.dat" 0 -0.469472 0 0.882948 0.882948 0 0.469472 0 1 0 0 -4 4 "Animal Starfish" "33122.dat" 0 -1 0 0 0 0 1 0 1 0 0 -26 -6 "Arm Bandage Wrapped" "30924.DAT" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Axe" "95330.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Axe Blocky" "18788.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Axe Head Faceted with Bar 0.5L" "22407.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Axe with Pick End and Long Handle" "39802.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Axe with Pick End and Long Handle with Red Head Pattern" "39802P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Axe with Red Head and Silver Blade Pattern" "95330P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Axe with Twin-Blade" "95052.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Battleaxe" "3848.dat" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Bar 0.5L with Blade 3L" "64727.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bar 0.5L with Curved Blade 2L" "87747.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bar 0.5L with Faceted Spike 1L" "88695.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bar 0.8L with Tip Bat Emblem" "37720D.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bar 1 L with Three Prongs" "68211.DAT" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Bar 1.5L with Clip without Hole in Shaft" "48729a.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Bar 1.5L with Clip with Truncated Sides and Hole in Shaft" "48729B.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Bar 2L with Ball Joint-8" "22484.DAT" 0 0 -1 0 0 0 1 -1 0 0 0 -10 0 "Bar 3L" "87994.dat" 0 1 0 0 0 1 0 0 0 1 0 -40 0 "Bar 3L with White Ends Pattern" "87994p01.dat" 0 1 0 0 0 1 0 0 0 1 0 -40 0 "Bar 4L Light Sabre Blade" "30374.dat" 0 1 0 0 0 -1 0 0 0 -1 0 12 0 "Bar 4L with Middle Bat Emblem" "37720C.DAT" 0 0 -1 0 1 0 0 0 0 1 0 -32 0 "Bar 4.5L Straight" "71184.dat" 0 1 0 0 0 1 0 0 0 1 0 20 0 "Bar 4.5L with Handle" "87618.dat" 0 -1 0 0 0 -1 0 0 0 1 0 -80 0 "Bar 6L with Thick Stop" "63965a.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bar 6.6L with Stop" "4095.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bar with 8-Shaped Modified Plate with Offset Stud" "50018E.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Bar with Bat Wings" "98721.DAT" 0 0 -1 0 1 0 0 0 0 1 0 0 0 "Bar with Octagonal 1 x 1 Plate with Opposing Studs and Bar at 90 Degrees""50018D.DAT" 0 1 0 0 0 1 0 0 0 1 0 -18 0 "Barbed Wire Loop" "62700.dat" 0 0 -1 0 -1 0 0 0 0 -1 0 -2 0 "Baseball Bat" "93220.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baseball Bat with Black Grip Pattern" "93220P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baseball Bat with Three Metallic Silver Diamonds with Rivets Pattern""93220P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baseball Bat with Three White Diamonds and White Grip Pattern""93220P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Baseball Bat with White Grip Pattern" "93220P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Binoculars with Round Eyepiece" "30162.dat" 0 1 0 0 0 0 -1 0 1 0 -5 -1.6 0 "Bladed Claw Spread" "10187.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Bone 2L" "93160.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bone 5L" "92691.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Boombox 1 x 3 x 1" "93221.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Black Rimmed Speakers, Cassette Player and Switches Pattern""93221P03.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Magenta Rimmed Speakers, Cassette Player, Switches and Lime Decoration Pattern""93221P05.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Metallic Gold Rimmed Speakers and Digital Music Player Pattern""93221P04.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Metallic Gold Rimmed Speakers, Cassette Player and Buttons Pattern""93221P01.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Metallic Gold Rimmed Speakers, Rotary Knobs and Sound Wave Display Pattern""93221P06.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -6 "Boombox 1 x 3 x 1 with Metallic Silver Rimmed Speakers, Cassette Player and Buttons Pattern""93221P02.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -6 "Boomerang" "25892.DAT" 0 0 -1 0 0.5 0 0.866025 -0.866025 0 0.5 4 -20 -4 "Bottle Cylindrical" "95228.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Bottle Cylindrical with Bottle Ship Pattern" "95228p01.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Bow with Arrow" "4499.dat" 0 0 0 -1 0 1 0 1 0 0 0 1 0 "Brick 1 x 2 x 0.667 with 8 Studs and Angled Handle" "15071.DAT" 0 1 0 0 0 0.920505 0.390731 0 -0.390731 0.920505 0 -11 0 "Broom" "4332.dat" 0 -1 0 0 0 1 0 0 0 -1 0 -76 0 "Bucket 1 x 1 x 1 Conical with Raised Handle" "95343C01.DAT" 0 0 0.642788 -0.766044 1 0 0 0 -0.766044 -0.642788 0 -1.5 0 "Bucket 1 x 1 x 1 Cylindrical with Raised Handle" "12884C01.DAT" 0 0 0.642788 -0.766044 1 0 0 0 -0.766044 -0.642788 0 -1.5 0 "Bugle" "71342.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Camera Movie" "30148.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Camera Snapshot Type 1" "30089A.dat" 0 0 0.5 0.866025 0 0.866025 -0.5 -1 0 0 -4.062 2.5 -18 "Camera Snapshot Type 2" "30089B.DAT" 0 0 0.5 0.866025 0 0.866025 -0.5 -1 0 0 -4.062 2.5 -18 "Camera with Side Sight" "4360.dat" 0 0 0 1 0 1 0 -1 0 0 0 -24 6.5 "Castle Lance" "3849.dat" 0 1 0 0 0 0 1 0 -1 0 0 40 0 "Chakram" "35485.DAT" 0 0 -1 0 -1 0 0 0 0 -1 0 -1 0 "Chainsaw Blade" "6117.DAT" 0 1 0 0 0 0 -1 0 1 0 0 -11 -8 "Cheerleader Pom Pom" "87997.DAT" 0 1 0 0 0 1 0 0 0 1 0 5 0 "Cheerleader Pom Pom with Blue Pattern" "87997p01.DAT" 0 1 0 0 0 1 0 0 0 1 0 5 0 "Cheerleader Pom Pom with Red Pattern" "87997p02.DAT" 0 1 0 0 0 1 0 0 0 1 0 5 0 "Circular Blade Saw" "30194.dat" 0 -1 0 0 0 -0.422618 0.906308 0 0.906308 0.422618 0 15 -17 "Cleaver" "98369.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Coin with '1' Gothic Type" "96904.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '2' Gothic Type" "96905.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '5' Gothic Type" "96906.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '10' Gothic Type" "96907.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '10' Sans-serif Type" "70501a.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '20' Sans-serif Type" "70501b.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '30' Sans-serif Type" "70501c.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Coin with '40' Sans-serif Type" "70501d.dat" 0 0 1 0 0 0 -1 -1 0 0 -2 -4 -10 "Conical Flask" "u9180.dat" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Conical Flask TransClear with Coloured Base" "u9180c01.dat" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Comb" "30112b.dat" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Compass" "74948.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Compass with Fleur de Lis Pattern" "74948P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Compass with White and Yellow Pattern" "74948P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Computer Laptop (Closed)" "62698-F3.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -2 0 "Crossbow" "2570.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Crown with 5 Points" "39262.DAT" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Crutch" "24077.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 0 -66 "Cup" "3899.dat" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Black 'C:\' Pattern" "3899P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Black 'I Heart SOUTH PAWS' Pattern" "3899P05.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Black 'Shhh!' Pattern" "3899P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Black Outlined Marshmallow Face and Yellow and Orange Flames Pattern""3899P08.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Medium Lilac and Medium Lavender 'I Heart HLC' Pattern""3899P07.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with Reddish Brown 'TVA' Logo on Metallic Gold Rectangle Pattern""3899P09.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with White 'DUNK ME!' Pattern" "3899P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup with White Octan Logo Pattern" "3899P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 -15 -20 "Cup Stein with Handle" "68495.DAT" 0 0 0 -1 0 1 0 1 0 0 0 21 -16 "Cup Stein with Handle and Trans Bright Green Drink Pattern""68495P02.DAT" 0 0 0 -1 0 1 0 1 0 0 0 21 -16 "Cup Stein with Handle and Trans-Orange Drink Pattern" "68495P01.DAT" 0 0 0 -1 0 1 0 1 0 0 0 21 -16 "Cup Takeaway" "15496.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Cup with Bar Handle" "38014.DAT" 0 1 0 0 0 1 0 0 0 1 0 10 -16 "Dagger" "88288.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dagger with Pearl Light Gray Blade" "88288P01.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dinner Plate" "6256.dat" 0 -0.0954045 0.866025 0.490814 -0.981627 0 -0.190809 -0.165245 -0.5 0.850114 -7 -5 -26 "Dinner Plate with Four Black Outlined Orange Bones Pattern""6256P01.DAT" 0 -0.0954045 0.866025 0.490814 -0.981627 0 -0.190809 -0.165245 -0.5 0.850114 -7 -5 -26 "Dinner Plate with Green and Lime Lettuce Leaf and Yellow Splotches Pattern""6256P02.DAT" 0 -0.0954045 0.866025 0.490814 -0.981627 0 -0.190809 -0.165245 -0.5 0.850114 -7 -5 -26 "Dinner Plate with Metallic Light Blue Swirl Pattern" "6256PH1.DAT" 0 -0.0954045 0.866025 0.490814 -0.981627 0 -0.190809 -0.165245 -0.5 0.850114 -7 -5 -26 "Drone Body with 4 Arms" "66967.DAT" 0 1 0 0 0 1 0 0 0 1 0 -9 0 "Dynamite Sticks Bundle" "64728.dat" 0 0.5 0 0.866025 0 1 0 -0.866025 0 0.5 0 -28 -9 "Electric Guitar Classic" "11640.DAT" 0 0 0 -1 0 1 0 1 0 0 0 40 0 "Electric Guitar Classic with Magenta, Bright Pink and Metallic Silver Stars Pattern""11640P01.DAT" 0 0 0 -1 0 1 0 1 0 0 0 40 0 "Electric Guitar V Shape" "93564.dat" 0 0 0 -1 0 1 0 1 0 0 0 4 0 "Electric Guitar V Shape, Silver Strings, White Body" "93564P01.dat" 0 0 0 -1 0 1 0 1 0 0 0 4 0 "Electric Guitar V Shape, Black Strings, DkPink Lightning" "93564P02.dat" 0 0 0 -1 0 1 0 1 0 0 0 4 0 "Feeding Bottle" "6206.DAT" 0 1 0 0 0 1 0 0 0 1 0 20 -20 "Figure Club" "60659.dat" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Figure Flask with Handle" "4429.DAT" 0 1 0 0 0 0.965926 -0.258819 0 0.258819 0.965926 0 -20 -30 "Food Apple" "33051.dat" 0 0.857167 0.515038 0 -0.515038 0.857167 0 0 0 1 14 33 0 "Food Banana" "33085.dat" 0 0 -1 0 1 0 0 0 0 1 0 0 0 "Food Bread Bun" "25386.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Food Carrot" "33172.dat" 0 1 0 0 0 1 0 0 0 1 0 -50 0 "Food Carrot Top" "33183.dat" 0 1 0 0 0 1 0 0 0 1 0 12 0 "Food Carrot with Bright_Green Leaves" "33172c02.dat" 0 1 0 0 0 1 0 0 0 1 0 10 0 "Food Carrot with Green Leaves" "33172c01.dat" 0 1 0 0 0 1 0 0 0 1 0 10 0 "Food Cherry" "22667.dat" 0 1 0 0 0 1 0 0 0 1 0 -11 0 "Food Croissant" "33125.dat" 0 0 1 0 -0.819152 0 0.573576 0.573576 0 0.819152 4 -27 -9 "Food French Bread" "4342.dat" 0 0 0.292372 0.956305 1 0 0 0 0.956305 -0.292372 -4.5 0 5 "Food Ice Cream Cone" "33120.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Food Pie with Cream Filling" "93568.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Food Pie with White Cream Filling Pattern" "93568P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Food Pie with Yellow Cream Filling Pattern" "93568P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Food Popsicle" "30222.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Food Pretzel" "10170.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Food Sausage" "33078.dat" 0 0 -1 0 1 0 0 0 0 1 0 0 0 "Food Turkey Leg" "33057.dat" 0 0 -0.985 0.174 0 0.174 0.985 -1 0 0 -9 -24 -1 "Friends Access. Bag Round with Ruffle" "93090.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -28 "Friends Access. Bag Round w. Bright Pink Ruffle Pattern" "93090P01.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -28 "Friends Access. Bag Round w. Dark Pink Ruffle Pattern" "93090P02.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -28 "Friends Access. Bag Round w. Light Aqua Ruffle Pattern" "93090P03.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 -28 "Friends Access. Basket" "93092.DAT" 0 1 0 0 0 0 1 0 -1 0 15 -2 -29 "Friends Access. Comb with Handle and 3 Hearts" "96482.DAT" 0 1 0 0 0 1 0 0 0 1 0 9 0 "Friends Access. Cupcake Case" "97784.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Friends Access. Cutlery Fork" "97781.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -1 0 "Friends Access. Cutlery Knife" "97782.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Friends Access. Cutlery Spoon" "34173.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Friends Access. Dish Rectangular" "97785.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Friends Access. Dish Round 2.7 x 2.7" "97783.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Friends Access. Frying Pan" "97790.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -56 -12 "Friends Access. Hair Brush with Heart on Reverse" "96480.DAT" 0 0 0 1 0 1 0 -1 0 0 0 9 0 "Friends Access. Hair Dryer" "96484.DAT" 0 1 0 0 0 1 0 0 0 1 0 8 0 "Friends Access. Hand Mirror with Heart on Reverse" "96488.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 9 0 "Friends Access. Hand-held Food Mixer" "97793.DAT" 0 1 0 0 0 0 1 0 -1 0 0 -3 0 "Friends Access. Key Ornamented with Stud" "19118.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1.5 0 ; Update 2023-01 "Friends Access. Lipstick Dual Mould with Black Handle Pattern""25866P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Friends Access. Lipstick Dual Mould with Light Bluish Grey Handle Pattern""25866P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Friends Access. Lipstick Dual Mould with White Handle Pattern""25866P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Friends Access. Medical Feeding Bottle" "98393F.DAT" 0 0 0 1 0 1 0 -1 0 0 0 13 -4 "Friends Access. Medical Pen" "98393J.DAT" 0 1 0 0 0 1 0 0 0 1 0 9 0 "Friends Access. Mixing Bowl" "97791.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Friends Access. School Bag" "11245.DAT" 0 0 0 -1 1 0 0 0 -1 0 4.6 -1.6 -38 "Friends Access. School Bag with Medium Blue Buckle and Star Pattern""11245P01.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 0 -38 "Friends Access. Spatula with 3 Holes" "97787.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Frypan" "4528.dat" 0 0 1 0 0 0 1 1 0 0 -4 -24 0 "Goblet" "2343.dat" 0 1 0 0 0 1 0 0 0 1 0 -26 0 "Goblet with Hollow Stem" "6269.dat" 0 1 0 0 0 1 0 0 0 1 0 -26 0 "Gun Blaster with Studs on Sides, Bottom and Front" "44709.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gun Flintlock Pistol" "2562.dat" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Gun Laser Kryptonian" "13952.DAT" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Gun Laser Pistol with Trapezoidal Heat Diffusers" "87993.dat" 0 1 0 0 0 1 0 0 0 1 0 -4 0 "Gun Laser Pistol with Rounded Heat Diffusers" "13608.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gun Long Blaster" "57899.dat" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Gun Musket" "2561.dat" 0 0 0.707 0.707 0 0.707 -0.707 -1 0 0 -25.1 -33.7 0 "Gun Pistol Two Barrel" "95199.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Gun Revolver" "30132.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Gun Rifle" "30141.dat" 0 0 0 1 0 1 0 -1 0 0 0 -8 0 "Gun Semiautomatic Pistol" "55707a.dat" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Gun Shooting Blaster with Dark Bluish Grey Trigger" "15391c01.DAT" 0 1 0 0 0 1 0 0 0 1 0 4 0 "Gun Shooting Blaster with Trigger and TrOrange Projectile" "15391C02.DAT" 0 1 0 0 0 1 0 0 0 1 0 4 0 "Gun Short Blaster" "62885.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gun Small Blaster with Telescopic Sight" "92738.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gun SW Short Blaster" "58247.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Gun SW Small Blaster DC-17" "61190a.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Hairbrush with Long Handle" "3852A.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 -10 0 "Hairbrush with Short Handle" "3852B.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 -6 0 "Hand Armour with Two Studs" "15407.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 -10 "Hand Fan" "93553.dat" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Hand Gorilla Fist" "11092.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Hand Truck (Shortcut)" "2495c01.dat" 0 1 0 0 0 0 1 0 -1 0 -22 -4 -58 "Handcuffs" "61482.dat" 0 1 0 0 0 1 0 0 0 1 -24 16 12 "Harpoon" "57467.dat" 0 1 0 0 0 1 0 0 0 1 0 28 0 "Harpoon with Smooth Bar" "18041.DAT" 0 1 0 0 0 1 0 0 0 1 0 28 0 "Hockey Stick with 1.1 L Bar" "93559.DAT" 0 1 0 0 0 1 0 0 0 1 0 10 0 "Hockey Stick with 3.6 L Bar" "64000.DAT" 0 1 0 0 0 1 0 0 0 1 0 10 0 "Hose Nozzle with Side String Hole" "58367.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Hose Nozzle with Side String Hole Simplified" "60849.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Ice Axe" "30193.dat" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Ice Axe with 3-Rib Handle" "18738.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Jackhammer" "30228.dat" 0 0.326 0 -0.946 0.899 -0.309 0.31 -0.292 -0.951 -0.101 -2.5 -18.5 11 "Key" "40359A.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Knife" "44658.DAT" 0 1 0 0 0 1 0 0 0 1 0 1 0 "Knife with Flat Hilt End" "95054.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Ladle" "4337.dat" 0 1 0 0 0 1 0 0 0 1 0 -36 0 "Lantern" "37776.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 0 "Lasso" "99253.DAT" 0 0 0 1 0 1 0 -1 0 0 0 0 0 "Life Ring" "30340.dat" 0 0 -1 0 0 0 1 -1 0 0 4 16 -21 "Lifeguard Float" "90395.DAT" 0 0.34202 -0.939693 0 0 0 -1 0.939693 0.34202 0 -3 20 -9.2 "Lightning" "59233.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Lightning with Marbled Medium Lilac Pattern" "59233P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Lightning with Marbled Trans Bright Green Pattern" "59233P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Lightning with Marbled Trans Purple Pattern" "59233P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Lightsaber Chrome Silver - 1 Side On" "577Bc01.dat" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Lightsaber Chrome Silver - 2 Sides On" "577Bc02.dat" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Lightsaber Hilt Short Curved" "61199.DAT" 0 1 0 0 0 1 0 0 0 1 0 -13.6 0 "Lightsaber Hilt Short Curved Light Bluish Grey - 1 Side On""61199C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -13.6 0 "Lightsabre Hilt with Bend" "42114.DAT" 0 1 0 0 0 0.930418 -0.366501 0 0.366501 0.930418 0 -19.5 -2.2 "Lightsaber Hilt with Bottom Ring" "577B.dat" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Lightsaber Hilt with Round Guard" "18673.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -16 0 "Lightsaber Hilt with Steep Sloping Fingers" "23306.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Lightsaber Metallic Dark Grey - 1 Side On Blade with Cross Bar""577BC03.DAT" 0 1 0 0 0 1 0 0 0 1 0 -20 0 "Lightsaber with Bend Chrome Silver - 1 Side On" "42114C01.DAT" 0 1 0 0 0 0.930418 -0.366501 0 0.366501 0.930418 0 -19.5 -2.2 "Lightsaber with Bend Chrome Silver - 2 Sides On" "42114C02.DAT" 0 1 0 0 0 0.930418 -0.366501 0 0.366501 0.930418 0 -19.5 -2.2 "Long Bow with Arrow" "93231.dat" 0 0.966 0 0.259 0 1 0 -0.259 0 0.966 0 -11 0 "Loudhailer" "4349.dat" 0 1 0 0 0 1 0 0 0 1 0 -16 0 "Loudhailer with Orange Stripe Pattern" "4349P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -16 0 "Machete" "29109.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Machine Gun with Drum Magazine" "55707b.dat" 0 1 0 0 0 1 0 0 0 1 0 -16 0 "Magic Wand" "6124.dat" 0 1 0 0 0 1 0 0 0 1 0 8 0 "Maracas" "90508.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Maracas with Green Border" "90508P01.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Medical Thermometer" "98393D.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -26 -5 "Megaphone" "39144.DAT" 0 1 0 0 0 1 0 0 0 1 0 -16 0 "Metal Detector" "4479A.DAT" 0 0 0 -1 0 1 0 1 0 0 0 -24 0 "Microphone" "90370.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Microphone with Black Top Half Sphere Pattern" "90370P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Microphone with Metallic Gold Top Half Sphere Pattern" "90370P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Microphone with Metallic Gold Top Pattern" "90370P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Microphone with Metallic Silver Top Half Sphere Pattern" "90370P05.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Microphone with Metallic Silver Top Pattern" "90370p01.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Mug" "33054.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 -20 "Oil Lamp" "98383.DAT" 0 1 0 0 0 1 0 0 0 1 0 4 -20 "Pharaoh's Staff with Forked End" "93252.dat" 0 1 0 0 0 1 0 0 0 1 0 -42 0 "Paint Brush" "93552.dat" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Paint Brush with Orange Tip Pattern" "93552P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Paint Brush with Silver Ring, Green Tip" "93552P01.dat" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Paint Brush with Silver Ring and Medium Azure Tip Pattern" "93552P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Paint Palette" "93551.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Paint Palette with Paint Drops Pattern" "93551P01.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Paint Roller Brush Handle" "12885.dat" 0 1 0 0 0 1 0 0 0 1 0 8 0 "Pickaxe Blocky" "18789.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pike / Spear Elaborate with Metallic Silver Head" "90391P01.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pike / Spear Elaborate with Flat Silver Head" "90391P02.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pipe Wrench" "4328.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pitchfork" "4496.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Plant Flower Stem Green with Bar and Hole and 3 Plates 1 x 1 with 5 Petals""24855C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -19 0 "Plant Flower Stem with Bar Green with 3 Flowers" "99249C01.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Plant Flower Stem with Bar Green with 3 Flowers with 6 Rounded Petals" "99249C03.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Plant Flower Stem with Bar Green with 3 Roses" "99249C02.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Plant Flower Stem with Bar and 6 Stems and 6 Plates" "19119C02.DAT" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Plunger" "11459.DAT" 0 1 0 0 0 -1 0 0 0 -1 0 -20 0 "Plunger with Medium Nougat Handle" "11459P01.DAT" 0 1 0 0 0 -1 0 0 0 -1 0 -20 0 "Polearm Halberd" "6123.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pushbroom" "3836.dat" 0 0 0 -1 0 -1 0 -1 0 0 0 44 0 "Radio with Large Grille" "19220.DAT" 0 0 0 -1 0 1 0 1 0 0 0 0 0 "Radio with Long Handle" "3962b.dat" 0 0 0 -1 0 1 0 1 0 0 0 -1 0 "Radio with Short Handle" "3962a.dat" 0 0 0 -1 0 1 0 1 0 0 0 -1 0 "Rice Bowl" "34172.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Rice Bowl with Metallic Gold Stripes Pattern" "34172P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ring 1 x 1" "11010.dat" 0 0 -1 0 -1 0 0 0 0 -1 -4 -2 -6 "Ring with Triangle" "87748.dat" 0 0 -1 0 0.866025 0 -0.5 0.5 0 0.866026 0 -2 -25 "Ring with Triangle with Gold Bands and Crab Pattern" "87748P01.dat" 0 0 -1 0 0.866025 0 -0.5 0.5 0 0.866026 0 -2 -25 "Ring with Triangle with Gold Bands and Manta Ray Pattern" "87748P05.dat" 0 0 -1 0 0.866025 0 -0.5 0.5 0 0.866026 0 -2 -25 "Ring with Triangle with Gold Bands and Shark Pattern" "87748P03.dat" 0 0 -1 0 0.866025 0 -0.5 0.5 0 0.866026 0 -2 -25 "Ring with Triangle with Gold Bands and Squid Pattern" "87748P04.dat" 0 0 -1 0 0.866025 0 -0.5 0.5 0 0.866026 0 -2 -25 "Ring with Triangle with Gold Bands and Triangle Pattern" "87748P06.dat" 0 0 -1 0 0.866025 0 -0.5 0.5 0 0.866026 0 -2 -25 "Ring with Triangle with Gold Bands and Turtle Pattern" "87748p02.dat" 0 0 -1 0 0.866025 0 -0.5 0.5 0 0.866026 0 -2 -25 "Rock 1 x 1 Gem Facetted" "30153.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Sack with Hand Grab" "10169.DAT" 0 0 0 -1 0.866025 0.5 0 0.5 -0.866025 0 0 9 -31 "Saucepan" "4529.dat" 0 0 1 0 0 0 1 1 0 0 -6 -24 0 "Saucer with Hollow Stud on Top" "38799.DAT" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Saxophone" "13808.DAT" 0 1 0 0 0 1 0 0 0 1 0 7 0 "Saxophone with Black Mouthpiece" "13808P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 7 0 "Serving Tray 2 x 3" "29635.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sextant" "30154.dat" 0 0 0 1 0 1 0 -1 0 0 0 -35 0 "Shield Broad with Spiked Bottom and Cutout Corner" "10049.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Broad w. Spiked Bottom, Cutout Corner, Hand Pattern" "10049P01.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Octagonal with Stud" "48494.dat" 0 0 0 -1 1 0 0 0 -1 0 0 -2 0 "Shield Octagonal without Stud" "61856.dat" 0 0 0 -1 1 0 0 0 -1 0 0 -2 0 "Shield Octagonal with Troll Skull on Dark Red Pattern" "61856P40.dat" 0 0 0 -1 1 0 0 0 -1 0 0 -2 0 "Shield Oval" "92747.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Oval with Large White Circle, Dark Purple Characters and Lines Pattern""92747P06.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Oval with Lime and White Circles, Dark Purple Arrows and Lines Pattern""92747P02.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Oval with Small Lime and Large White Circles, Dark Purple Chain and Lines Pattern""92747P04.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Oval with White, Lime and Medium Azure Circles, Dark Purple Lines Pattern""92747P03.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Oval with White, Lime and Medium Azure Circles, Lightning Bolt and Dark Purple Lines Pattern""92747P05.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Oval with SW Gungan Patrol Shield" "92747p01.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid" "2586.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with American Indian Pattern" "2586pw1.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Bat Pattern" "2586P4F.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Blue Dragon Pattern" "2586p4c.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Bull Head Pattern" "2586P4G.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Bull Head on Brown Border Sticker" "2586D01.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Crown on Dark/Med Blue Quarters Pattern" "2586P4J.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with DkGreen Dragon on Medium Nougat/Tan Pattern" "2586P4K.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Galloping Horse and Feathers Pattern" "2586PW2.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Gold Lion Head on Blue and White Pattern""2586P4M.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Golden Lion Pattern" "2586ph1.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Gold Lion on Red/White Quarters Pattern" "2586P4L.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Green Dragon Pattern" "2586p4b.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Indigo Islanders Pattern" "2586P30.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Red Fire Breathing Dragon Head on Black Background Pattern""2586P4N.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Royal Knights Lion Pattern" "2586p4d.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Silver Skull on Dark Red Pattern" "2586P4H.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with Silver Snake Pattern" "2586PH2.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Ovoid with SW Gungans Patrol Pattern" "2586ps1.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Pentagonal Castellated" "22408.DAT" 0 0 0 -1 0 1 0 1 0 0 0 4 0 "Shield Pentagonal Jagged" "22409.DAT" 0 0 0 -1 0 1 0 1 0 0 0 4 0 "Shield Rectangular Curved with Stud" "98367.DAT" 0 0 0 1 1 0 0 0 1 0 0 -1 0 "Shield Round" "3876.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Round Bowed" "75902.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Round Bowed with Bullseye with Star Pattern" "75902P02.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Round Bowed with DkGreen and Gold Rohan" "75902P01.dat" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Round Bowed with Gold Eagle Pattern" "75902P03.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Round Bowed with Mercedes-Benz Logo" "75902P04.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Round Bowed with SW Dejarik Hologame Board Pattern" "75902PS1.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -1 0 "Shield Round Flat" "59231.dat" 0 0 0 -1 0 1 0 1 0 0 10 -12 0 "Shield Round Flat with Helmet on Dark/Medium Blue Quarters Pattern""59231P40.DAT" 0 0 0 -1 0 1 0 1 0 0 10 -12 0 "Shield Round Flat with Silver Skull on Dark Red Pattern" "59231P4H.dat" 0 0 0 -1 0 1 0 1 0 0 10 -12 0 "Shield Round Type 2" "91884.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -2 0 "Shield Round Type 2 w. Aztec Bird on Dark Red Pattern" "91884P04.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -2 0 "Shield Round Type 2 w. DkBrown Ring and 4 Rivets Pattern" "91884P01.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -2 0 "Shield Round Type 2 w. Dragon Heads and Ornaments Pattern" "91884P03.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -2 0 "Shield Round Type 2 w. Silver Rivets Pattern" "91884P02.DAT" 0 0 0 -1 1 0 0 0 -1 0 4 -2 0 "Shield Scarab" "93251.dat" 0 0 0 -1 1 0 0 0 -1 0 9 -1 -1 "Shield Triangular" "3846.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Bat Pattern" "3846p4f.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Black Falcon Blue Border Pattern" "3846p45.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Black Falcon Yellow Border Pattern" "3846p46.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Blue Dragon Pattern" "3846p4c.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Blue Lion on Yellow Background" "3846p4g.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Crown on Dark/Med Blue Quarters" "3846P4J.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Crown on Dark-Pink Sticker" "3846d01.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Crown on Violet Sticker" "3846d05.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Dark Pink Jewel and Gold Border Sticker""3846D0A.DAT" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Dragon on Medium Nougat/Tan Pattern" "3846P4K.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Forestman Pattern" "3846p48.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Goblin King Eye Pattern" "3846PM0.DAT" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Gold Lion Head on Blue and White Pattern""3846P4M.DAT" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Gold Lion on Red/White Quart. Pattern" "3846P4L.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Green Chevrons on Yellow Sticker" "3846d03.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Green Chevrons on Yellow.LtGray" "3846d06.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Lion Head, Blue and Yellow Pattern" "3846p4e.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Maroon/Red Quarters Pattern" "3846p4u.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Red in Blue Frame Pattern" "3846p47.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Red Cross and Helmet" "3846p01.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Red Dragon Head on Black Background Pattern""3846P4N.DAT" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Red/Peach Quarters Pattern" "3846p4t.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Royal Knights Lion Pattern" "3846p4d.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Town Hall Pattern" "3846P02.DAT" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with White Maltese Cross on Red Sticker" "3846d02.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Wolfpack Pattern" "3846p44.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Yellow Lion on Blue Background" "3846p4h.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Yellow Trefoils on Blue Sticker" "3846d04.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular with Yellow Trefoils on DkBlue Sticker" "3846d07.dat" 0 0 0 -1 0 1 0 1 0 0 0 -12 0 "Shield Triangular Long" "18836.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 0 "Shield Triangular Long with Bear Head on Dark Red and Red Background Pattern""18836P40.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 0 "Shield Triangular Long with Black Pyramid and Sun Pattern" "18836PQ0.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 0 "Shield Triangular Long with Dark Red Edge with Rivets and Black Bat on Metallic Silver Background Pattern""18836P42.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 0 "Shield Triangular Long with Gold Rampant Lions and Crossed Keys Pattern""18836P41.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 0 "Shovel" "3837.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Shovel Blocky" "18791.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Signal Holder" "3900.dat" 0 1 0 0 0 0 -1 0 1 0 0 -36 -2 "Signal Holder with Black 'POLICE' and Red Line Pattern" "3900P01.DAT" 0 1 0 0 0 0 -1 0 1 0 0 -36 -2 "Signal Holder with Green Circle on White Sticker" "3900d01.dat" 0 1 0 0 0 0 -1 0 1 0 0 -36 -2 "Ski Pole" "90540.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Sledgehammer" "75904.dat" 0 0 0 1 0 1 0 -1 0 0 0 -14 0 "Slingshot" "20546.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Slingshot with Bright Light Yellow Band Pattern" "20546P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Slingshot with Dark Tan Band Pattern" "20546P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Small Bow with Arrow" "95051.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -10 0 "Space Scanner Tool" "30035.dat" 0 1 0 0 0 1 0 0 0 1 0 -19 -10 "Spear with Round End" "4497.dat" 0 1 0 0 0 1 0 0 0 1 0 -40 0 "Spear with Flat End" "93789.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Spear with Four Side Blades" "43899.dat" 0 1 0 0 0 1 0 0 0 1 0 -144 0 "Spear Tip Faceted with Bar 0.4L" "27257.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Speargun" "30088.dat" 0 1 0 0 0 1 0 0 0 1 0 -13 0 "Sports Barbells" "29592.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Staff with Crescent End" "95050.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Staff with Spherical End" "95049.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Steak on Bone" "98372.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Steak on Bone with Red Meat" "98372P01.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Statuette" "90398.dat" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Statuette with Astronaut Pattern" "90398P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Stretcher with Bottom Hinges" "4714.DAT" 0 0 0 -1 1 0 0 0 -1 0 -26 -74 -2 "Stretcher without Bottom Hinges" "93140.DAT" 0 0 0 -1 1 0 0 0 -1 0 -26 -74 -2 "Suitcase (Closed)" "4449-f1.dat" 0 0 0 -1 1 0 0 0 -1 0 0 0 0 "Suitcase with Iron Man Armoured Suit Mark V Stickers" "4449-F1D01.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 0 0 "Suitcase with Hinge with Lid (Complete)" "37702C01.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 -1 0 "Suitcase with Long Handle (Closed)" "37178-F1.DAT" 0 0 0 -1 1 0 0 0 -1 0 0 0 0 "Sundae Glass" "68504.DAT" 0 1 0 0 0 1 0 0 0 1 0 12 0 "Sword Blocky" "18787.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Cutlass" "2530.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Sword Dao with Curved Blade and Hilt" "25111.DAT" 0 1 0 0 0 1 0 0 0 1 0 -10 0 "Sword Double Blade with Bar Holder" "11103.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Greatsword" "59.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Katana (Dragon Guard)" "93055.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Katana Type 1 (Octogonal Guard)" "30173a.dat" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Sword Katana Type 2 (Square Guard)" "30173b.dat" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Sword Katana Type 3 (Square Guard with Smooth Endcap)" "21459.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Sword Katana 3.5 L with Short Smooth Grip and Square Crossguard""37341C.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Sword Khopesh" "93247.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Sword Longsword" "98370.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Sword Rapier" "93550.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Sword Roman Gladius" "95673.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Sword Saber with Clip Pommel" "59229.dat" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Sword Scimitar" "43887.dat" 0 1 0 0 0 1 0 0 0 1 0 -18 0 "Sword Scimitar with Jagged Edge" "60752.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Sword Shortsword" "3847.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Sword Shortsword with Elaborate Hilt" "76764.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Sword Small with Angular Guard" "95053.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Sword Small with Curved Blade" "10053.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Sword Uruk-Hai" "10050.dat" 0 -1 0 0 0 1 0 0 0 -1 0 4 0 "Sword with Angular Hilt" "48495.dat" 0 0 0 -1 0 1 0 1 0 0 0 -10 0 "Sword with Hexagonal Decorations" "24108.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Sword with Hexagonal Decorations with Flat Silver Pattern" "24108PE1.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Sword with Hexagonal Decorations with Light Bluish Grey Pattern""24108PE2.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Sword with Hexagonal Decorations with Pearl Gold Pattern" "24108PE3.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Sword with Jagged Edges" "11439.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Syringe" "87989.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Teapot" "23986.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -10 -20 "Teddy Bear with Arms Down" "98382.DAT" 0 0 -0.069756 -0.997564 0.809017 0.586353 -0.041002 0.587785 -0.807046 0.056434 -1.6 -4 -28 "Teddy Bear with Arms Down, Tan Belly, Black Eyes Pattern" "98382p01.DAT" 0 0 -0.069756 -0.997564 0.809017 0.586353 -0.041002 0.587785 -0.807046 0.056434 -1.6 -4 -28 "Telescope" "64644.dat" 0 1 0 0 0 1 0 0 0 1 0 -11 0 "Tennis Racket" "93216.dat" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Tomahawk with Flat-Silver Blade" "13571.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool 4-Way Lug Wrench" "604553.DAT" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Tool Adjustable Wrench with 3-Rib Handle" "604614.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Battery Powered Drill" "604549.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Binoculars Space" "30304.dat" 0 1 0 0 0 0 -1 0 1 0 -5 -1 0 "Tool Box Wrench" "55300.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Box Wrench with 3-Rib Handle" "604552.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Circular Tooth Blade with Cover with Opposing Studs and Bar""50018G.DAT" 0 1 0 0 0 1 0 0 0 1 0 -28 0 "Tool Crowbar" "92585.DAT" 0 1 0 0 0 1 0 0 0 1 0 -30 0 "Tool Fishing Rod" "2614.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Fishing Rod 8L Clip at End" "93222.DAT" 0 1 0 0 0 1 0 0 0 1 0 6 0 "Tool Fishing Rod 12L Straight End" "96858.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Gavel" "11250.DAT" 0 0 0 1 0 1 0 -1 0 0 0 6 0 "Tool Grappling Hook" "30192.dat" 0 1 0 0 0 -1 0 0 0 -1 0 9 0 "Tool Grappling Hook with Bar" "15534.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -11 0 "Tool Hammer" "55295.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Hammer with 3-Rib Handle" "604547.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Handaxe" "3835.dat" 0 1 0 0 0 1 0 0 0 1 0 -16 0 "Tool Hexagonal with Hollow Stud with Perpendicular Bar and Ribbed Handle""50018C.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Hexagonal with Opposing Studs and 3 Ribbed Handles at 120 Degrees""50018A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Hose Nozzle with Handle" "4210a.dat" 0 -1 0 0 0 1 0 0 0 -1 0 -12 0 "Tool Hose Nozzle with Handle at Bottom and Top" "22921.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Impact Wrench with Opposing Studs with Angled Ribbed Handle and Rear Bar Handle""50018B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Light Sabre Hilt with Bend" "42114.DAT" 0 1 0 0 0 0.927184 -0.374607 0 0.374607 0.927184 0 -19.5 -2.5 "Tool Magnifying Glass" "30152a.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass with TransClear Lens" "30152AP01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass with TransRed Lens" "30152AP02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass with Removable TransClear Lens" "90463.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass with Thick Frame and Lens" "10830.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Magnifying Glass with Thick Frame and TransClear Lens""10830P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Mallet" "4522.dat" 0 0 0 1 0 1 0 -1 0 0 0 -28 0 "Tool Oar" "2542.dat" 0 -1 0 0 0 -1 0 0 0 1 0 40 0 "Tool Oar Reinforced" "87585.DAT" 0 0 0 1 0 1 0 -1 0 0 0 -30 0 "Tool Oilcan" "55296.DAT" 0 1 0 0 0 1 0 0 0 1 0 -6 0 "Tool Oilcan with Ribbed Handle" "604548.DAT" 0 1 0 0 0 1 0 0 0 1 0 -3 0 "Tool Open End Wrench" "55299.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Open End Wrench with 3-Rib Handle" "604551.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Pickaxe" "3841.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 "Tool Power Drill" "55297.dat" 0 1 0 0 0 1 0 0 0 1 0 -6 0 "Tool Rip Saw" "18826.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Rip Saw with Reddish Brown Grip Pattern" "18826P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Screwdriver" "55298.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Tool Screwdriver with Wide Head and 3-Rib Handle" "604550.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Scissors" "18920.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Tool Socket Wrench with Ratchet and 3-Rib Handle" "604615.DAT" 0 1 0 0 0 1 0 0 0 1 0 -2 0 "Tool Spanner/Screwdriver" "4006.dat" 0 0 0 -1 0 1 0 1 0 0 0 -14 0 "Tool Wand" "36752A.DAT" 0 1 0 0 0 1 0 0 0 1 0 4 0 "Toolbox 1 x 3 with Handle" "98368.dat" 0 0 0 1 -1 0 0 0 -1 0 0 -2 0 "Toolbox 1 x 3 with Handle and Classic Space Logo on Back Pattern""98368P01.DAT" 0 0 0 1 -1 0 0 0 -1 0 0 -1 0 "Torch" "3959.dat" 0 1 0 0 0 1 0 0 0 1 0 -13 0 "Torch without Grooves" "86208.dat" 0 1 0 0 0 1 0 0 0 1 0 -13 0 "Toy Winder Key" "98375.dat" 0 0 0 -1 1 0 0 0 -1 0 0 -2 -20 "Tray Oval" "11252.dat" 0 0 1 0 -1 0 0 0 0 1 6 -3 -16 "Trophy Cup 2.4L" "10172.DAT" 0 0 0 1 0 1 0 -1 0 0 0 34 -20 "Trophy Cup 2.4L with Metallic Silver Terrier Dog Pattern" "10172P01.DAT" 0 0 0 1 0 1 0 -1 0 0 0 34 -20 "Trophy Cup 3 L" "89801.DAT" 0 1 0 0 0 1 0 0 0 1 30 54 0 "Umbrella Folded" "27150.DAT" 0 1 0 0 0 1 0 0 0 1 0 18 0 "Underwater Scooter" "30092.dat" 0 -1 0 0 0 1 0 0 0 -1 -20 -22 -8.5 "Weapon Billy Club" "13790.DAT" 0 1 0 0 0 1 0 0 0 1 0 -7.5 0 "Weapon Blade 3.4 L with Bar 3.6 L" "11156.DAT" 0 1 0 0 0 1 0 0 0 1 0 20 0 "Weapon Bladed Claw" "88811.dat" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Weapon Blade Faceted 3.8 L with Bar 0.5 L" "23860.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Weapon Blaster with Two Barrels" "17010.DAT" 0 1 0 0 0 1 0 0 0 1 0 -1 0 "Weapon Club with Spikes" "88001.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Weapon Crescent Blade Serrated with Bar 0.5L" "98141.dat" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Weapon Curved Blade 8.5L with Bar 1.5L" "98137.dat" 0 1 0 0 0 1 0 0 0 1 0 12 0 "Weapon Grenade with Large Tapered Top and Four Indents" "40598C.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Weapon Grenade with Small Tapered Top and Two Ridges" "40598D.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Weapon Hand Dagger" "88812.dat" 0 1 0 0 0 1 0 0 0 1 0 2 0 "Weapon Nunchaku with Black Handles (Straight)" "67100P01-F1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Weapon Sai" "98139.DAT" 0 1 0 0 0 1 0 0 0 1 0 7 0 "Weapon Spear Short with Pin Hole" "98338.DAT" 0 1 0 0 0 1 0 0 0 1 0 16 0 "Weapon Trident" "92290.dat" 0 1 0 0 0 1 0 0 0 1 0 24 0 "Weapon Web Effect Web 4 x 3 with Bar" "36083C.DAT" 0 1 0 0 0 1 0 0 0 1 0 3 0 "Weapon Web Effect 5L Narrow with Bars at Both Ends" "36083A.DAT" 0 1 0 0 0 1 0 0 0 1 0 5 0 "Welding Gas Torch with Hose and Gas Cylinder Top" "13793.DAT" 0 1 0 0 0 1 0 0 0 1 30 35 0 "Whip" "2488.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Whip in Latched Position (Shortcut)" "2488c01.dat" 0 1 0 0 0 1 0 0 0 1 0 -8 0 "Whip Bent Flexible" "88704.DAT" 0 0 0 -1 0 1 0 1 0 0 0 10 0 "Whip Bent Flexible (Formed for Electrical Roof Wiring - Right Aligned)""88704-F1.DAT" 0 0 0 -1 0 1 0 1 0 0 0 10 0 "Whip Bent Flexible (Formed for Electrical Roof Wiring - Left Aligned)""88704-F2.DAT" 0 0 0 1 0 1 0 -1 0 0 0 10 0 "Whip Coiled" "61975.dat" 0 0 0 -1 0 1 0 1 0 0 0 -8 0 "Whisk" "29636.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wine Glass" "33061.dat" 0 1 0 0 0 1 0 0 0 1 0 -32 0 "Zip Line Handle" "30229.dat" 0 1 0 0 0 1 0 0 0 1 0 -12 0 [LLEG] "Plain Leg" "3816B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "3 Black Diamonds Pattern" "3816BPBA.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Astro Pattern" "3816BP6F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Lower Leg Pattern" "20461P05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Orca Pattern" "3816BPD6E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Triangles on Foot Pattern" "3816BPCBD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Lower Leg Pattern" "20461P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue/White Triangles, Fringe Pattern" "3816BPW2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bright Light Orange Lower Leg Pattern" "20461P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Buttoned Cargo Pocket Pattern" "3816BPA3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Chainlink and 3 Safety Pins Pattern" "3816BPC44.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Chicken Feet Pattern" "3816BPC97.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Clockwork Robot Pattern" "3816BPC67.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue Coattails Pattern" "3816BPH0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue Loincloth Pattern" "3816BPQ0.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue Lower Leg Pattern" "20461P09.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue and Gold Loincloth Pattern" "3816BPQ1.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Brown Lower Leg Pattern" "20461P06.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Green Lower Leg Pattern" "20461P08.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Red Loincloth, White Claws and Fur Tail Pattern" "3816BPAW.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Red Lower Leg Pattern" "20461P07.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "DarkRed Lower Leg and Triangular Notch on Side Pattern" "20461PX1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Bluish Grey Robe Lines Pattern" "3816BPB8.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Turquoise/White Triangles, White Fringe Pattern" "3816BPW3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Golden Circuit Pattern" "3816BP6W.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Circuitry and Orange Cable Pattern" "3816BP6U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grass Skirt Pattern" "3816BP3J.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Kilt and Toes Pattern" "3816BPA2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Holster and Belt Pattern" "3816BPA9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids Robot Pattern" "3816BP60.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark VI Pattern" "3816BPBB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark VII Pattern" "3816BPBC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark XLII Pattern" "3816BPBF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark XVII Pattern" "3816BPBE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Patriot Armoured Suit Kneepad Pattern" "3816PBG.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Laboratory Smock Pattern" "3816BPDE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Leather Straps and Red Diamonds Pattern" "3816BP4F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Light Nougat Lower Leg and Black Shoes Pattern" "20461PX0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Coat and Shirttails Pattern" "3816BPM2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Leather Armour Pattern" "3816BPM0.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Scale Armour Pattern" "3816BPM1.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Medium Azure and Magenta Stripes Pattern" "3816BPU1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Orange Cable Pattern" "3816P6u.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pocket and Holster Pattern" "3816BPX2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pouch Pattern" "3816BP40.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Purple Greatcoat Pattern" "3816phb.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Rags Pattern" "3816BP30.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red/White Triangles Pattern" "3816BPW1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Coattail Pattern" "3816BPX0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Lower Leg Pattern" "20461P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Roman Tunic and Belt Pattern" "3816BPC6A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reflective Stripe Pattern" "3816BP8H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reflective Stripes and Black Pocket Outline Pattern" "3816BP70.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reflective Stripes and Tan Pocket Outline Pattern" "3816BP71.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reflective Stripe and Silver Triangles on Foot Pattern" "3816BP8I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Robot Pattern" "3816BP63.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ruffles, Black Lower Leg and White Feet Pattern" "20461PD92.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Salmon Cable Pattern" "3816P6V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Scale Mail Pattern" "3816BP41.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Circuitry and Salmon Cable Pattern" "3816BP6V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirttails, Gold Band and Fleur de Lis Pattern" "3816BP42.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shorts with Black Line and Brick Logo Pattern" "3816BPC4B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Gunbelt Pattern" "3816BPS5.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Stormtrooper Pattern" "3816BPSK.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW White Leggings Pattern" "3816BPS0.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "War Machine Armoured Suit Kneepad Pattern" "3816PBD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wetsuit, Coral and Dark Azure Trim Pattern" "20461PCKC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Apron Pattern" "3816BP89.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Lower Leg Pattern" "20461P00.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Lower Leg and Green Sandals Pattern" "20461PD87.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White and Gold Markings Pattern" "3816BP6G.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Yellow Lower Leg Pattern" "20461P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------Non-standard legs-------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Leg Skeleton" "6266.DAT" 0 1 0 0 0 1 0 0 0 1 -10 0 0 "Leg Skeleton with Square Foot" "93062.DAT" 0 1 0 0 0 1 0 0 0 1 -10 0 0 "Leg Skeleton with Black Square Foot" "93062P01.DAT" 0 1 0 0 0 1 0 0 0 1 -10 0 0 "Leg Skeleton with Pearl Dark Grey Square Foot" "93062P02.DAT" 0 1 0 0 0 1 0 0 0 1 -10 0 0 "Leg Skeleton Long" "23769.DAT" 0 1 0 0 0 1 0 0 0 1 -10 0 0 "Leg Wooden" "2532.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Leg" "53984.DAT" 0 1 0 0 0 1 0 0 0 1 -10 44 -10 "Mechanical Leg Angled" "87569.DAT" 0 1 0 0 0 1 0 0 0 1 -10 -4 0 "Mechanical Leg Angled with Dark Bluish Grey Foot Pattern" "87569P01.DAT" 0 1 0 0 0 1 0 0 0 1 -10 -4 0 "Robotic Leg" "10177.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short -> Hips:" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Legs Old -> Hips:" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Legs -> Hips:" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skirts (Slope Brick 65 2 x 2 x 2) -> Hips:" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 [RLEG] "Plain Leg" "3817B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "2 Red Diamonds Pattern" "3817BPBA.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "2 Safety Pins Pattern" "3817BPC44.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Amulet Pattern" "3817BP40.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Astro Pattern" "3817BP6F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Lower Leg Pattern" "20460P05.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Orca Pattern" "3817BPD6E.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Black Triangles on Foot Pattern" "3817BPCBD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue Lower Leg Pattern" "20460P02.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Blue/White Triangles, Fringe Pattern" "3817PW2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Bright Light Orange Lower Leg Pattern" "20460P03.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Buttoned Cargo Pocket Pattern" "3817BPA3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Chicken Feet Pattern" "3817BPC97.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Clockwork Robot Pattern" "3817BPC67.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue Coattails Pattern" "3817BPH0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue Loincloth Pattern" "3817BPQ0.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue Lower Leg Pattern" "20460P09.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Blue and Gold Loincloth Pattern" "3817BPQ1.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Brown Lower Leg Pattern" "20460P06.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Green Lower Leg Pattern" "20460P08.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Red Loincloth and White Claws Pattern" "3817BPAW.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Dark Red Lower Leg Pattern" "20460P07.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "DarkRed Lower Leg and Triangular Notch on Side Pattern" "20460PX1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "DarkTurquoise/White Triangles, White Fringe Pattern" "3817bpw3.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "'EMMET' Badge, Reflective Stripe Pattern" "3817BP8H.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "'EMMET' Badge, Reflective Stripe, Silver Triangles Pattern""3817BP8I.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Golden Circuit Pattern" "3817BP6W.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Gold Circuitry and Orange Cable Pattern" "3817BP6U.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Grass Skirt Pattern" "3817BP3j.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Green Kilt and Toes Pattern" "3817BPA2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Holster and Belt Pattern" "3817BPA9.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Insectoids Robot Pattern" "3817BP60.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark VI Pattern" "3817BPBB.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark VII Pattern" "3817BPBC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark XLII Pattern" "3817BPBF.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Man Armoured Suit Mark XVII Pattern" "3817BPBE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Iron Patriot Armoured Suit Kneepad Pattern" "3817PBG.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Laboratory Smock Pattern" "3817BPDE.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Leather Straps and Red Diamonds Pattern" "3817BP4F.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Light Nougat Lower Leg and Black Shoes Pattern" "20460PX0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Coat and Shirttails Pattern" "3817BPM2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Leather Armour Pattern" "3817BPM0.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "LOTR Scale Armour Pattern" "3817BPM1.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Orange Cable Pattern" "3817P6u.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Pocket Pattern" "3817BPX2.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Purple Greatcoat Pattern" "3817phb.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Rags and Patch Pattern" "3817BP30.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red/White Triangles Pattern" "3817bpw1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Coattail Pattern" "3817BPX0.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Lower Leg Pattern" "20460P01.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Roman Tunic and Belt Pattern" "3817BPC6A.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Red Tied Sash Pattern" "3817BPC1.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reflective Stripes and Black Pocket Outline Pattern" "3817BP70.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Reflective Stripes and Tan Pocket Outline Pattern" "3817BP71.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Robot Pattern" "3817BP63.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Ruffles, Black Lower Leg and White Feet Pattern" "20460PD92.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Salmon Cable Pattern" "3817P6V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Scale Mail Pattern" "3817BP41.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shirttails, Gold Band and Fleur de Lis Pattern" "3817BP42.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Shorts with Black Line and Lion Crest Pattern" "3817BPC4B.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Silver Circuitry and Salmon Cable Pattern" "3817BP6V.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW Stormtrooper Pattern" "3817BPSK.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "SW White Leggings Pattern" "3817BPS0.dat" 0 1 0 0 0 1 0 0 0 1 0 0 0 "War Machine Armoured Suit Kneepad Pattern" "3817PBD.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Wetsuit, Coral and Dark Azure Trim Pattern" "20460PCKC.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Apron Pattern" "3817BP89.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Lower Leg Pattern" "20460P00.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "White Lower Leg and Green Sandals Pattern" "20460PD87.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Yellow Lower Leg Pattern" "20460P04.DAT" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------Non-standard legs-------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Leg Skeleton" "6266.DAT" 0 1 0 0 0 1 0 0 0 1 10 0 0 "Leg Skeleton with Square Foot" "93062.DAT" 0 1 0 0 0 1 0 0 0 1 10 0 0 "Leg Skeleton with Black Square Foot" "93062P01.DAT" 0 1 0 0 0 1 0 0 0 1 10 0 0 "Leg Skeleton with Pearl Dark Grey Square Foot" "93062P02.DAT" 0 1 0 0 0 1 0 0 0 1 10 0 0 "Leg Skeleton Long" "23769.DAT" 0 1 0 0 0 1 0 0 0 1 10 0 0 "Leg Wooden" "2532.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 0 0 "Mechanical Leg" "53984.DAT" 0 1 0 0 0 1 0 0 0 1 10 44 -10 "Mechanical Leg Angled" "87569.DAT" 0 1 0 0 0 1 0 0 0 1 10 -4 0 "Mechanical Leg Angled with Dark Bluish Grey Foot Pattern" "87569P01.DAT" 0 1 0 0 0 1 0 0 0 1 10 -4 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hips and Legs Short -> Hips:" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Legs Old -> Hips:" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Mechanical Legs -> Hips:" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Skirts (Slope Brick 65 2 x 2 x 2) -> Hips:" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 [LLEGA] "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Flipper Thick" "10190.DAT" 0 0.996 0 0.087 0 1 0 -0.087 0 0.996 -10 28 -1 "Flipper Thin" "59275a.DAT" 0 0.996 0 0.087 0 1 0 -0.087 0 0.996 -10 28 -1 "Roller Skate" "11253.DAT" 0 1 0 0 0 1 0 0 0 1 -10 28 -1 "Skate" "93555.DAT" 0 1 0 0 0 1 0 0 0 1 -10 28 -1 "Skateboard with Black Wheels (Shortcut)" "42511c01.DAT" 0 1 0 0 0 1 0 0 0 1 0 28 1 "Snowshoe" "30284.DAT" 0 1 0 0 0 1 0 0 0 1 -10 28 -1 "Ski" "6120.DAT" 0 1 0 0 0 1 0 0 0 1 -10 28 1 "Ski 4L without Hinge" "99774.DAT" 0 1 0 0 0 1 0 0 0 1 -10 28 -1 "Ski 6L" "90509.DAT" 0 1 0 0 0 1 0 0 0 1 -10 28 -1 "--------------------Non-standard accessories------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hoverboard" "21271.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 0 "Hoverboard with Magenta, White and Lime Lines and 'HOVER BOARD' Pattern""21271P01.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 0 "Plate 2x4 with Curved Beveled Sides" "88000.DAT" 0 1 0 0 0 1 0 0 0 1 0 28 0 "Snowboard 2 x 6" "18746.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 -1 "Surf Board 2 x 6.5" "90397.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 -1 "Surf Board 2 x 6.5 with Hearts and Flowers Sticker" "90397D01.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 -1 "Surf Board 2 x 6.5 with Medium Lilac Batman Logo Pattern""90397P04.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 -1 "Surf Board 2 x 6.5 with Pink Flames Pattern" "90397P02.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 -1 "Surf Board 2 x 6.5 with White Shark, Black Open Mouth and Gills Pattern""90397P05.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 -1 "Surf Board 2 x 10" "6075.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 28 -1 [RLEGA] "None" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "--------------------------------------------------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Flipper Thick" "10190.DAT" 0 0.996 0 -0.087 0 1 0 0.087 0 0.996 10 28 -1 "Flipper Thin" "59275a.DAT" 0 0.996 0 -0.087 0 1 0 0.087 0 0.996 10 28 -1 "Roller Skate" "11253.DAT" 0 1 0 0 0 1 0 0 0 1 10 28 -1 "Skate" "93555.DAT" 0 1 0 0 0 1 0 0 0 1 10 28 -1 "Skateboard with Black Wheels (Shortcut)" "42511c01.DAT" 0 1 0 0 0 1 0 0 0 1 0 28 1 "Snowshoe" "30284.DAT" 0 1 0 0 0 1 0 0 0 1 10 28 -1 "Ski" "6120.dat" 0 1 0 0 0 1 0 0 0 1 10 28 1 "Ski 4L without Hinge" "99774.DAT" 0 1 0 0 0 1 0 0 0 1 10 28 -1 "Ski 6L" "90509.DAT" 0 1 0 0 0 1 0 0 0 1 10 28 -1 "--------------------Non-standard accessories------------------------------------" "" 0 1 0 0 0 1 0 0 0 1 0 0 0 "Hoverboard" "21271.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 0 "Hoverboard with Magenta, White and Lime Lines and 'HOVER BOARD' Pattern""21271P01.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 0 "Plate 2x4 with Curved Beveled Sides" "88000.DAT" 0 1 0 0 0 1 0 0 0 1 0 28 0 "Snowboard 2 x 6" "18746.DAT" 0 0 0 1 0 1 0 -1 0 0 0 28 -1 "Surf Board 2 x 6.5" "90397.DAT" 0 0 0 -1 0 1 0 1 0 0 0 28 -1 "Surf Board 2 x 6.5 with Hearts and Flowers Sticker" "90397D01.DAT" 0 0 0 -1 0 1 0 1 0 0 0 28 -1 "Surf Board 2 x 6.5 with Medium Lilac Batman Logo Pattern" "90397P04.DAT" 0 0 0 -1 0 1 0 1 0 0 0 28 -1 "Surf Board 2 x 6.5 with Pink Flames Pattern" "90397P02.DAT" 0 0 0 -1 0 1 0 1 0 0 0 28 -1 "Surf Board 2 x 6.5 with White Shark, Black Open Mouth and Gills Pattern""90397P05.DAT" 0 0 0 -1 0 1 0 1 0 0 0 28 -1 "Minifig Surf Board 2 x 6.5 with White Shark, Black Open Mouth and Gills Pattern""90397P05.DAT" 0 0 0 -1 0 1 0 1 0 0 0 28 -1 "Surf Board 2 x 10" "6075.DAT" 0 -1 0 0 0 1 0 0 0 -1 0 28 -1 leocad-23.03/resources/parts_cancel.png000066400000000000000000000015431440571307300201350ustar00rootroot00000000000000‰PNG  IHDR D¤ŠÆgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<áPLTEŽ.#ˆ,!& * Ä@0òĽò¿·ãE)ðº±ð¶­äF*ﲨåH,î­£æJ/çL1í¥šèN4ì •éP6ÛJ4ì‘êR9ë™ëT;땈íV>ê‘„îX@ꎀïZBê‹}ð\Eé‡yñ^Gêƒuò`Jé€qóbLé}môdNèyjõfQãXDèvföhSèscøkVèp`ùmXèo_èm\úo[èjXûq]èfUüs_ècRýubècQÿÿÿß5ÔtRNS7="TIJ#8€à{-bKGDJ µÆtIMEã KkÅ=IDAT8Ëe’mCA…gì®UºÞ’$‘$I’DIøÿ¨Ù½ãÞÙçÓÎsÎø0Ž!@ 7 ÞàFB±T*òÔ¤ \R”é j¨\DT°!™‘P½Œ©ê†e\¨]!5}ƒ W¸Ô¯‘:HÉŽž+dÚ‡Æ ÒvðÓáOªFóiµÌgSçºÑ¾KÐÆ\7:÷c®ÝF—æºÑ{$ôx®ý'CßÎU#ƒgÃ2V®ÞoøB&÷1zeŒì}Œß,Æ´‘‚É{‚ɱáÀô™ÍÌçÌ?‘9°C¼¨Å²€“SvŒö±üFVœe|X±Œµþ‰YCÍ…oJL´¨ÍoÄ&Ìõ«/jû§Øê\PcµÛïw˜Cu8óСa‹¢¹2Ù@º(/Os!rÙ|þœ.Êuí¿Í?²äZ3,k†%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+tEXtSoftwareAdobe ImageReadyqÉe<IEND®B`‚leocad-23.03/resources/parts_search.png000066400000000000000000000040461440571307300201560ustar00rootroot00000000000000‰PNG  IHDR szzôgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“IDATXÃÅ–kl׆Ÿ33;³¾¬×W ÅÆØØ8nˆ€˜k¶!¨MBq¢6iE)BBM¥VUz¡E”ÑHmU©?šV¨(¨ý‘H­—„c0`.j@UHŠ ¼¾îzwggçœÓ»æV‚MZÔ#ærÎÌ÷|ï|—#´Öü?‡¸×ÜÆM›ÚNðBð¤Ö:Gßò’" ¢-ýpë–׺ÏäÉ]¾±zMaÝÌúCáphÖÒ%K¨­©&?ºmÍh,ÆG»9ÔÙÉÈHìì‡Î/Ýñæöáÿ@lظi¥pv·®ZÉœ9³'ô‘S§N³k÷¼tjÕ–Ÿ¾ºç~Ô¸@¬ÿñ†Ö¢ßzi-áp€gzØyì#Ž}Ø‹!2Ë•Ö,¬›Â3 jY>{:###¼ñÛm =ó³­[vMâÀS+¿TÚÔÜùæÚ5Mòm¸••N¥ \Š˜¦Àñ‘~®÷^aJ®à×k—SŸÃÐÐ ¿Û¶ƒï—µíy·"Vöhœ7¿cYKEEÅ Çâ<÷Ë¿,¬¤eÁ4–Õ…¨.qIIF=Ũ§èÊåRÕd.õ\áÙŸïáíuORTT̲–&âñxGÛžwçéñL@<ÿ‹ 555¯<û•/Šoÿ¾Ï.å»O<ÌÓ0ƒIŸ¨+‰y’Ñ´„aÈ/@X6ûŽ_ uÁt¦N­àï§N—•”–½}öƒ3‘ñ ÀšVUµuñ¢… $ûO_æZ\ðhÝ4æVäÒO3èúŒ¦ ©I*p¸Jãjm ªj*Ôöº J²xÑB¦UUm½Eá{-Ó\QUY Êgß?"„Âe´Ì,`(éõ$®¯q¥&¥ÁÓà AJ”e`ÛvÀ`zM%ûÎE@úTUVb™æ 8GiœT^Ž’’s}.Áœ<ª‹FR> _“”W‘ÈO ƒÇĶMƒòÉÅœëK¢¤Ï¤òr”ÖAÀ™HZ)¤ôAJ'ˆi ¢)IÜËOé¬q2iÁ ‘II¥QRáKm‘J¢¤VjÌÁñ³@kR ”$°±LAÌ“Ä}…«nÊ>æ½ãf¶&Hï 04@%%J(&Úcn‰Ö)%¦DAÜS$ýŒôÃ6À lËʤ}E¦œ( ;ˆT î£ÁR×®õ"•¦aRB@÷GÒ×$}EÂW$|i S`YDZ°‹€i`X‚ᑟ/ÏA*͵k½hHM@%FG;»/õ 5,ª L‹î!—¾Ñ4®"êiŒ;º†Îª†!èðX\i#\ìé!>; ¨‰xçÏÿs{W×q´0i,ÓL.pˆû&‘¸ë+:lJ£¤&Vx®—’H_ñÉu—Ì+% >Êûíí¯3 ÀÝ÷×÷Ž D.;~_¼X—Âqòð ¥BI…”é+ÒiEÚS¤Ò/-éíóè‡Õõi| Ží²Luîìw<sL¦‹Ýÿ:ZZV¾¦ºfEùAf…\ºS!Fý aÈÌBƒ†hBðIŸåIVO¦Àôöð§?蘆u•xx֜キ·í5@Ž ñx:/7¯7øB͌晊 *—¾T /‡X2ÈPܦHû,(ˆòÅIC8‹¾Avìø#såñÇ—““¢¶¡qãþ½»¶Þ b, ÓÀÀÞ½m;¥’†ë¦^_¶¬™ùsiÈOЭ¸ÙâZÃB['Nþööz¨žP8D<‘¤¶®ž2N°ô‹S­;ê©cÿ1Ä×yÀäââ’Ú¯?ÿÂoJJЧÏkl¤¢r*eee7Š‹‚H$ÂÇW®ròäIÜ”§**+Œp8LÀ bX¹<Ñ<›Bûc8¿žÎC°ôåö»Bˆ»Ü`ÊÌ™õõK–6¿ …æέ@*‹h?°ÿî?Z¿¡mZu5–æç ‹í?@ó[`;pþe:©»B|Ú®8U# ¡ìï[¯ˆCÙXúÜ÷×o>¸dÚ­¹;9y`мìÀ§BÜs[ž5:ÖÕîl,ŠLž»Ùµ“€êw^]q°¾à*U…Š`Ž•ùBó›YˆutRÄ\ùØS?éèô½º•Îg èúî8ú³sé¬G}@÷Ó›ö7‰ÖÒuI&eF§ŽÕàùÐð+–´8”ØG²Nß.ïcÜ€øê¦ÝM]ÃsˆD“·C¤5Ä]d&)sÿ×·A|mÓ;M]óé¶p]™©WƒÎCeÌZàˆ]Mç¢5DF¤]|×â¦Yñ™ÍŒ?l²ùÖæUµÆ@ñÜ+m‹€ ÀЃ¸b*Ÿ}6 \ͪä=h€1ˆ<2µ2Y'[ þ _pGeõÃá¯%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+tEXtSoftwareAdobe ImageReadyqÉe<IEND®B`‚leocad-23.03/resources/piece_show_earlier.png000066400000000000000000000037501440571307300213310ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYsÄÄ•+êIDATHÇ…•il”ÇÆó¾ïž^¯×öúZ{}cƒ øÀ¸`ÂÜ&¤ájÔƒ/!­ZzH­Ô´j¤DQQ”´Ú¨ŠÔCj«ªG(52¡PÊc ŽÆÇ®Á^k¯Í²¶w}íñN?pDTDéù0ÒÌï™gFÿù )%Ÿ5.¾½×±™þrtqa[tq¾ÈtàžÁ`ê6Z’έö¿5ÿèÈÀg1Ä“ .½½×47|eq>ò}WÙj›«´šTg&³¤Ntip(Èİ—¡[WâRÊ¿XRœ/oùIëÄÿ5¸ðæËïMµæ–Ö,¯\÷4f  ³„¦Æ Ï„ˆÇbh#É)©¤e»‘š…žÎKô\o3$¥îŒKqíKo’O48w°eC$l]µigZ^Aá©Q<ÝŒ û˜6ç³`ÍA×L(ñELá1ìK£”–WP¹º‘ÀÝ gý}f&nnFˆîï:¨?fpî`KEd:رvû Ž4G ·:/ÒÝãe(eá¢-l'!£øn\&%ÓENI5jh’4ïa²#רܲƒé™0G[ŒŽEÔµBêã?oýµRJοñLÊôÝ@Wmó ÓN.ž9ieü²g=eµå$¥'KDxïÀsÌNùil\Ë‘þ'(éèŸeþæ)ŠÇÏŽgvàñz8rüü‘hrÆW¾Ñ¨g‰„Ãï–W¦8R9w¢ëò¾‹4§‘šžŠÍa§÷ÂÌÝ›@ÓTvïÞEvj2u…vRR’Pò72š³Ÿ§O±¢¢Šê²¼]ýÞ¡ç+W•kj“!¸…DüÕõèh?EîÆýdÕlGQt,QRžƒÙb$8ÜÃPWf³Ÿï©N'![)‰¸D..âtfRY–MgÇ¿hhh 46´Ê· þQ}~µó½«Kzz?!§aYÕ›1[Ì8ì6Fçqf¤`µhä–”¸Ý‰ª/`³qV­'#·Œ™›—˜¸z’Š•¥TT×0 19r»ÍšvécO@ÝÓ\ô;©jª%¯B/mÞ'ŒF#f“ƒÁ€Í¢°0¿DºÃŠÕl¢~Ûjš¶°i÷~*+ë]9…ù­oP0ÒÅXh’ܺF Êëìf~6ˆ–XL×LÉ)~-Ù^h4,)ƒ]G™×òŸ °ÙÄby¤å– ¬Éd-«Ä¤J&¯Ãø³o³¼a f«qñ íïhxéEt%†b2!­Éc"8òç}¾žW#Š«t4h¢ hÅÅÅdggö˜œÀUXNrzþWˆüp% k°9ÓH,Eñ^¸Èªr*vmeÒç)]µâ[ZZ^ŽÃ3ªN ÉÒ¦ ŸÃív ?¨¿ŒÌ,22³˜š 0:âeÞ3Ìü+ߤ¨®[z&ü^…Äš¯ïhsf«ÊÈH¤®·/\Û°® Wž›„„„„¾~ý/ yßÌ™‘…ËbãîËȯ¨Ä–™‹. I1%Qܼ‰e÷©Ý¿m«QÅ¡õôëóÜ%FWn> ýÓ?ÉãéGQŠK–! ·¼HNÅJÒjjÑlv¤L÷¢ÇchÎ,T»=ºD‰#埇«ûÞ=¼Vóù¦Ý›ŸÞú@JÒ -O`Ê?ÌÝKí!°åºq55£…EoƒÇ=ƈþéø×´@ lËÈÎ#þ?^¯UUxJÔ÷†PPŒÝnÇÐqz:ôþI‡¢(÷7ÄâL•M?÷7nÍÆA!Ä  _‹ÅbÄŸÐsî ô£ª*¯ýø{X,&¶µëȳ"^S*ÇþÈ­˜›L‡¯c•—÷ì–g¶÷H~xu[{hUÍÆ­¤ed’øïbû:;¼ü|Àåö ê&ƺxvU%ï´% à2€¬“q˜ShðQ¤9úÊvÕ¾ž‘™2'I¢,µ¶*22s iéY$ÔÿÝ¤ŽŽDQdin> ²3…ùÈ41F­¥šÖ¹nœF…8qRMé4:‚Ïí{ñ¶ˆàTU-C„¸Ø×ÌÌÉÍ'¡²ÈZBUUMÙéaj~Z˵xbùIT4FÚ$B²ÑhÈ5™ KÌfƒG Y“½ÄÕEGŸÏ‡$騤=ˆ>ç\::A‚(‚ ÷8RIh ô‚‘–Ô9ûâw6r¤X,Fü1?§§«½^ÇÁÀá°pzëû<<@†'›îœ’UÓðEï³ F©0—³uõ&Ô(÷çûøsç1öë×—dÙîï볦e.y¿ðÉ)~zø(   áxä¯ì½º›¨'ב·8ã…^Xèe6æ|÷Y¾Ø–w÷åo>Õ$feÙýíÍwÕþüǧ¨Þ²sQ?â*$fÊ┟ÑÙÓ¬õÌô²@b‘Ï$œï8ËÆæ¥þWw쿀ƔXRâ½îk»íñuP¡êK;Âc* ö£ E¿M=0zÏwM â@81GCÛ9ªš³‡¿W»§Þj5w›M†aÝ‘#ßÍ ‡ç\WïeÚ7v§ûÑ’i<˜ð÷ú¸Þx–ü\»oÃê–¬eþXïÉ‹â4@Ó¿ëÙÐ’5üƒí{?u¹ì·N[«ÉdнöÚ7R ’'f‚SÖ‹ç.{¦&§t’ÞˆMVÐo7ë¹}õÓhY‰óÎúõÙõ  ¬ÈÉì·wé#'úþ™=ð «îz{^Ùùô™ädùž¢<€AÓêK€, §½}tõõëý>ßXæèhÈ àñØÂùù)þ5k–Ü(,ôÞq „hPmGOœ*½ãëN}~÷Ž&‡Ã:¬(¶~«Õ<L³ÿF"®ì¾%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/shaders/000077500000000000000000000000001440571307300164175ustar00rootroot00000000000000leocad-23.03/resources/shaders/fakelit_color_ps.glsl000066400000000000000000000005631440571307300226250ustar00rootroot00000000000000LC_PIXEL_INPUT vec3 PixelPosition; LC_PIXEL_INPUT vec3 PixelNormal; LC_PIXEL_OUTPUT uniform mediump vec4 MaterialColor; uniform mediump vec3 LightPosition; uniform mediump vec3 EyePosition; void main() { LC_PIXEL_FAKE_LIGHTING LC_SHADER_PRECISION vec3 DiffuseColor = MaterialColor.rgb * Diffuse; gl_FragColor = vec4(DiffuseColor + SpecularColor, MaterialColor.a); } leocad-23.03/resources/shaders/fakelit_color_vs.glsl000066400000000000000000000006461440571307300226350ustar00rootroot00000000000000LC_VERTEX_INPUT vec3 VertexPosition; LC_VERTEX_INPUT vec3 VertexNormal; LC_VERTEX_OUTPUT vec3 PixelPosition; LC_VERTEX_OUTPUT vec3 PixelNormal; uniform mat4 WorldViewProjectionMatrix; uniform mat4 WorldMatrix; void main() { PixelPosition = (WorldMatrix * vec4(VertexPosition, 1.0)).xyz; PixelNormal = (WorldMatrix * vec4(VertexNormal, 0.0)).xyz; gl_Position = WorldViewProjectionMatrix * vec4(VertexPosition, 1.0); } leocad-23.03/resources/shaders/fakelit_texture_decal_ps.glsl000066400000000000000000000010611440571307300243310ustar00rootroot00000000000000LC_PIXEL_INPUT vec3 PixelPosition; LC_PIXEL_INPUT vec3 PixelNormal; LC_PIXEL_INPUT vec2 PixelTexCoord; LC_PIXEL_OUTPUT uniform mediump vec4 MaterialColor; uniform mediump vec3 LightPosition; uniform mediump vec3 EyePosition; uniform sampler2D Texture; void main() { LC_PIXEL_FAKE_LIGHTING LC_SHADER_PRECISION vec4 TexelColor = texture2D(Texture, PixelTexCoord); LC_SHADER_PRECISION vec3 DiffuseColor = mix(MaterialColor.rgb, TexelColor.rgb, TexelColor.a); gl_FragColor = vec4(DiffuseColor * Diffuse + SpecularColor, max(TexelColor.a, MaterialColor.a)); } leocad-23.03/resources/shaders/fakelit_texture_decal_vs.glsl000066400000000000000000000010211440571307300243330ustar00rootroot00000000000000LC_VERTEX_INPUT vec3 VertexPosition; LC_VERTEX_INPUT vec3 VertexNormal; LC_VERTEX_INPUT vec2 VertexTexCoord; LC_VERTEX_OUTPUT vec3 PixelPosition; LC_VERTEX_OUTPUT vec3 PixelNormal; LC_VERTEX_OUTPUT vec2 PixelTexCoord; uniform mat4 WorldViewProjectionMatrix; uniform mat4 WorldMatrix; void main() { PixelPosition = (WorldMatrix * vec4(VertexPosition, 1.0)).xyz; PixelNormal = (WorldMatrix * vec4(VertexNormal, 0.0)).xyz; gl_Position = WorldViewProjectionMatrix * vec4(VertexPosition, 1.0); PixelTexCoord = VertexTexCoord; } leocad-23.03/resources/shaders/unlit_color_conditional_ps.glsl000066400000000000000000000001451440571307300247200ustar00rootroot00000000000000LC_PIXEL_OUTPUT uniform mediump vec4 MaterialColor; void main() { gl_FragColor = MaterialColor; } leocad-23.03/resources/shaders/unlit_color_conditional_vs.glsl000066400000000000000000000015241440571307300247300ustar00rootroot00000000000000LC_VERTEX_INPUT vec3 VertexPosition1; LC_VERTEX_INPUT vec3 VertexPosition2; LC_VERTEX_INPUT vec3 VertexPosition3; LC_VERTEX_INPUT vec3 VertexPosition4; uniform mat4 WorldViewProjectionMatrix; void main() { vec4 p1 = WorldViewProjectionMatrix * vec4(VertexPosition1, 1.0); vec4 p2 = WorldViewProjectionMatrix * vec4(VertexPosition2, 1.0); vec4 p3 = WorldViewProjectionMatrix * vec4(VertexPosition3, 1.0); vec4 p4 = WorldViewProjectionMatrix * vec4(VertexPosition4, 1.0); vec4 Position = p1; p1 /= p1.w; p2 /= p2.w; p3 /= p3.w; p4 /= p4.w; vec2 Line = p2.xy - p1.xy; vec2 Cond1 = p3.xy - p1.xy; vec2 Cond2 = p4.xy - p1.xy; float Cross1 = Line.x * Cond1.y - Line.y * Cond1.x; float Cross2 = Line.x * Cond2.y - Line.y * Cond2.x; if (Cross1 * Cross2 >= 0.0) gl_Position = Position; else gl_Position = vec4(p1.x, p1.y, 2.0, 1.0); } leocad-23.03/resources/shaders/unlit_color_ps.glsl000066400000000000000000000001451440571307300223350ustar00rootroot00000000000000LC_PIXEL_OUTPUT uniform mediump vec4 MaterialColor; void main() { gl_FragColor = MaterialColor; } leocad-23.03/resources/shaders/unlit_color_vs.glsl000066400000000000000000000002451440571307300223440ustar00rootroot00000000000000LC_VERTEX_INPUT vec3 VertexPosition; uniform mat4 WorldViewProjectionMatrix; void main() { gl_Position = WorldViewProjectionMatrix * vec4(VertexPosition, 1.0); } leocad-23.03/resources/shaders/unlit_texture_decal_ps.glsl000066400000000000000000000004141440571307300240460ustar00rootroot00000000000000LC_PIXEL_INPUT vec2 PixelTexCoord; LC_PIXEL_OUTPUT uniform mediump vec4 MaterialColor; uniform sampler2D Texture; void main() { LC_SHADER_PRECISION vec4 TexelColor = texture2D(Texture, PixelTexCoord); gl_FragColor = mix(MaterialColor, TexelColor, TexelColor.a); } leocad-23.03/resources/shaders/unlit_texture_decal_vs.glsl000066400000000000000000000004201440571307300240510ustar00rootroot00000000000000LC_VERTEX_INPUT vec3 VertexPosition; LC_VERTEX_INPUT vec2 VertexTexCoord; LC_VERTEX_OUTPUT vec2 PixelTexCoord; uniform mat4 WorldViewProjectionMatrix; void main() { gl_Position = WorldViewProjectionMatrix * vec4(VertexPosition, 1.0); PixelTexCoord = VertexTexCoord; } leocad-23.03/resources/shaders/unlit_texture_modulate_ps.glsl000066400000000000000000000004271440571307300246140ustar00rootroot00000000000000LC_PIXEL_INPUT vec2 PixelTexCoord; LC_PIXEL_OUTPUT uniform mediump vec4 MaterialColor; uniform sampler2D Texture; void main() { LC_SHADER_PRECISION vec4 TexelColor = texture2D(Texture, PixelTexCoord); gl_FragColor = vec4(MaterialColor.rgb, TexelColor.a * MaterialColor.a); } leocad-23.03/resources/shaders/unlit_texture_modulate_vs.glsl000066400000000000000000000004201440571307300246130ustar00rootroot00000000000000LC_VERTEX_INPUT vec3 VertexPosition; LC_VERTEX_INPUT vec2 VertexTexCoord; LC_VERTEX_OUTPUT vec2 PixelTexCoord; uniform mat4 WorldViewProjectionMatrix; void main() { gl_Position = WorldViewProjectionMatrix * vec4(VertexPosition, 1.0); PixelTexCoord = VertexTexCoord; } leocad-23.03/resources/shaders/unlit_vertex_color_ps.glsl000066400000000000000000000001351440571307300237310ustar00rootroot00000000000000LC_PIXEL_INPUT vec4 PixelColor; LC_PIXEL_OUTPUT void main() { gl_FragColor = PixelColor; } leocad-23.03/resources/shaders/unlit_vertex_color_vs.glsl000066400000000000000000000004041440571307300237360ustar00rootroot00000000000000LC_VERTEX_INPUT vec3 VertexPosition; LC_VERTEX_INPUT vec4 VertexColor; LC_VERTEX_OUTPUT vec4 PixelColor; uniform mat4 WorldViewProjectionMatrix; void main() { gl_Position = WorldViewProjectionMatrix * vec4(VertexPosition, 1.0); PixelColor = VertexColor; } leocad-23.03/resources/shaders/unlit_view_sphere_ps.glsl000066400000000000000000000007471440571307300235470ustar00rootroot00000000000000LC_PIXEL_INPUT vec3 PixelNormal; LC_PIXEL_OUTPUT uniform mediump vec4 HighlightParams[4]; uniform samplerCube Texture; void main() { LC_SHADER_PRECISION float TexelAlpha = textureCube(Texture, PixelNormal).a; LC_SHADER_PRECISION float Distance = length(vec3(HighlightParams[0]) - PixelNormal); LC_SHADER_PRECISION float Highlight = step(Distance, HighlightParams[0].w); gl_FragColor = mix(mix(HighlightParams[2], HighlightParams[3], Highlight), HighlightParams[1], TexelAlpha); } leocad-23.03/resources/shaders/unlit_view_sphere_vs.glsl000066400000000000000000000003621440571307300235460ustar00rootroot00000000000000LC_VERTEX_INPUT vec3 VertexPosition; LC_VERTEX_OUTPUT vec3 PixelNormal; uniform mat4 WorldViewProjectionMatrix; void main() { PixelNormal = normalize(VertexPosition); gl_Position = WorldViewProjectionMatrix * vec4(VertexPosition, 1.0); } leocad-23.03/resources/studlogo1.zip000066400000000000000000000007431440571307300174370ustar00rootroot00000000000000PKMp2RP/PK+p2RZ3|'* P/stud.dateű 0ÀU\ !ßdA°,Ôý[¹â@øôÖ‘%Ç\ý gPK:p2RÇ:“à(+ P/stud2.dateű 0ÀU\ !Ÿ"ûÁBÝ_°•+„G§aì‘|—šØæPK?Mp2R$P/ \ÍšåíÖ\ÍšåíÖÓÀ–åíÖPK?+p2RZ3|'* $ P/stud.dat Åã‹tåíÖö›páåíÖêÊtåíÖPK?:p2RÇ:“à(+ $ oP/stud2.dat ¤Ò †åíÖö›páåíÖDì{yåíÖPK Àleocad-23.03/resources/studlogo2.zip000066400000000000000000000007441440571307300174410ustar00rootroot00000000000000PKbp2RP/PKbp2Ru7on(+ P/stud.dateű 0ÀU\ !Ÿ"ûÁBÝ_°•+„G§a쑼ÔÄîæPKap2R¤xMà(, P/stud2.dateű 0ÀU\ !o‘}BÁBÝ_°•+„K§aì‘ÂKíoyQPK?bp2R$P/ ²ûÞ°åíÖd4à°åíÖŸÅ€œåíÖPK?bp2Ru7on(+ $ P/stud.dat ½­Þ°åíÖÿßåíÖ€œåíÖPK?ap2R¤xMà(, $ pP/stud2.dat F26°åíÖÿ%ßåíÖ=$‚œåíÖPK Áleocad-23.03/resources/studlogo3.zip000066400000000000000000000007451440571307300174430ustar00rootroot00000000000000PKlp2RP/PKlp2RÅS(+ P/stud.dateű 0ÀU\ !O ûÁBÝ_°•+„G§a쑼ÔÄîæPKkp2RQ-Ý), P/stud2.dateÅÁ ÐU\ è´O t<¨û ^å—VAÛ PK¢k1RP/8/PKR3RéQš} P/8/stud.datRÝNò@½ç)Æ»ï»XÜn+6xU (F…ˆ1JÌÒ`“þÝÅŸ·wZ…*1mÒíÌ9gΞ ‡‘[+ø×“ֱޑ/ÿneŽm-µšJ:*Ek·,M®¨eá ­Õ¹,¨qtÝI¢»§AráÓÐè\;ýŒ0v¢q÷ZŒ{5®woG]HPi댞­œeëB¡8Ž®áÕe¢É¡ âÈ T96Ý«kÊy/†¸›Œû½{¢ÜU¥£Ëþh¹¢1M£E‹=ÀJöí.iû÷›KƒIPdK{™sæœÍ:0µÛ ÆTða Œe=-~l90v!x4çíLXº ·v]ê.ÜPÌÀ # ¡(puۋû§qü‚§‰–…´òa6é…I¸ãv˜ãÖ¸aÔMûc&Õr±µb‘#lU†¢(¼…gÔF– xÛ.DˆB"+°mÿØeù6ˆ êÇÉppO”»êêêz8MÆñ=i9œ9>ýð`¹4f?ÊL.%f°,uMNËb“K¡RüZïEj1£]†¯¥âŸáa’©æ0^.e*E³ õ÷ Þà}aN‡qÿïUX9(„µ{/Q©v= }¸Òˆ*ÛH°*›{ÙB@ˆSž[¹bn‡xk™—sˆÖB­H×–UÏÎÁóœ·EjйˆÇè–{—yÞiã@­=š›r|Ú&Ç4ñ•Žw¡ Çk¹@E;õçïW÷x}æc¶Âj _B«{8¿eþûÓ2ÿywÃ<ý¤qõ%Dö¹Ï›Rþ©Tú7—½nÖÝù>3ÆÆø«¥Zí^û?PKR3Rðà*¼ÌØP/8/stud2a.dat}’Ýn›@…ïý“»öb]X(EîÁ¸q”ÚÆM£ÔŠÖ0¶WâÇÚ]’öí;'-8±ø[-ß™9;:,MÁü€%oÁ'¢«³WÌöH·—yµ†p/Êõ5U3³SØaŽõ~“:mâ0ÚåÎyÓÏKh´¯æVšœùŸ/ÉÑ}¾éãœÂkÆ6С-`.½èi/ûøu)Ð.s‘òÞ$ºÃz=Öë²ÇØMg?(x³ègBb—»¼ßÊí¶Jÿ䲑÷h¯G{ÿèc¼gŒ?³J–;ÞÂPKR3R—Ðq¨‰ P/8/stud3.dat’QoÚ0Çßù×·íÁÌI<±§,ÀJÕ‚ªªC•‰°”ÄÈvºíÛï’A5膪(Ééüûßý}: ß(È›5”ZÁ»‰tž¬üñ¾ÇáNV8„ø»#*ê+é)—4~gìnèÌÁ :§+YÓÁÕí(KîŸfÙWˆŸæVWÚëg„å|”äcy0`<è¸i:¾[Œ!C¥·zÝx¹.šZ¡…4Mná­Ó¦†°ÏaÒÄ¢TöýOߣ*_&)¤ã,ŸNHrߦ®®§‹|–=P/2.àÑ­KíÜ ¾¥7lŒíÄ…©ö¥–uŸ»XE ÿU*üóœ èz³ÍFZ–°ÜÓLð…gºOŒX(þÒ]£¤¶*éýÁKjê?3 8ÙZÄ kV*fmµà²…˜ˆS]кbÁ€t;]š¤;Yo©¯7íÌ^Ëøÿ›tÐë&£l]ÖE§ó9®öÅÜÒ‘³øÃþ¸9îœoûD†ð²c½èÒ˜ ½Ýþ‚öY0j‹íFYþvôRYÚèâÀŠP„ç´8¥‹_¥îèßPKR3RÅ„ûѽ  P/8/stud4.dat’QoÚ0Çßù×·íÁÌq2ñ–X©:@!¬«:Tr€¥ÄA¶Ómß~—@«ZTEJ¬óïÿ»Ëq˜»*ƒ´Z!L÷¨áÃHZÇFþþØá0‘ö!üe º™t‹*·+MnèΠZ« ©éâêvDwÓä„3£ åÔÂb6ˆÒ!îõ÷n'ó!$˜)ëŒZUN®r„Jgh Ž£[xBcU©At9ôÁ"B”Y]÷Çu(Ë×Q ñ0IÇ£{’ÜÕ¡«ëñ<&÷äÅãã><ØU®¬]Â÷2S…lJÓˆ×e±Ï•Ôk|M*>ÃÃ,%C¥—0ÝlÔZÉ{š!ÑÒ}a¼ÇDðŸî%uT;Ò¹£w\êCÏt޶±@íZ©BVgó.—qªóꪘ×#ÝNååâÔ[òue=£sØg>Û¤ÎM|FQá_Öù§óyþý4Ú—â–* ?íŸ7ŶùÚÇ¿0„—êx@Ms`½èÐ<ÞñÛ£ý X€Ùë >aþÎò÷§åïÈzXÞñä­ïdø3%m Ñn 8uZÿÍÕy-6¼ÀŠVYâÀ¥·~ÿPKR3R­W¯8ÊÛP/8/stud4a.dat}RÑn›@|÷WlÞÚ‡sá .rŸÆ£Ô¶lÜ4J­è kû$8¬»#iÿ¾ q¢€ «½™¹Õ8°´UIµA˜PÁ“´û²²p) BœíÐÀ§±0–´xúÜs`* BðÇÏýLXj†±ô®éÐÀ5# ¡èàâf´of‹<̵,¤•«ù(LbàŽ;`ŽÛà&Q<]ưÀL«å¦²b“#T*C QÞÀ#j#K¼ïÀ "D¡F‘Ø·m¦\Ž#ˆâE2ßå¶n]\M–ÉlqGZgŽO/Ü›M.YÃÏ2“[‰lKÝÓ²8äR¨¿7µH-fTeøÞ(þîç j ³íV¦Rä°:ÐNðâÞ7æ ÷ßð®PÐ k…°öè%*Õó¨w±@e;£VOsÏ[Ñæ¹µ+户—y¹†h/ÔŽtmYïìì1ÏùX¤ŠxŒºÜ;ÏóÚûy‰­öÕÜʳàËá%9¦‹¯u¼3KxÍXϺ´̧Íãÿ ´Ï|¤¼×‰naƒ6hc±›LQð¦ñï„È>÷yWÊoK¥ÿry*ÕÁg°¼c‹?cµT;¯ÿPKR3R‹·_ñ=P/8/stud4h.dat•QÛNÂ@}ç+Æ7}XÜn7¤á­–¢$ ¤/QbŠ»À$½íÖËß;E1R…hšt7³çÌ9g†ÃÄV âj®a´Ö9¼ ]Aøju®´‚‹"ÕpÜOJËz&y9iq&™î‚÷PO®Ú*±Tô+»*LbÌ༨R÷³e}›ÑóÑe/òoGÑ9xcƒZ|Ö0÷ü8ÁãÎ7Âá$„H+,­Áye“9Y¨È ð/áY›‹D›CJ­!ðNT¦ÛöÕ¶¨ËY?€ ŒâAÿŽ(7uéèb0‰GÑ]­%Ìq¿9„«Bá)ïÂP2!ë`?‰.s9Üc’Ã|£ÅŸ0Iaº&¸þ9 žË¨*ÜÃ<—\}ãm‡Â¸$Þ ÓbÓ’z§ëíüÊ&¾Öqý:_“n9àt€“ô£Ëæs>Ï-W2©ÕR×CØÁz ¬÷;ömùº~¬t0¼¦¥ÃÛ˜¸RHÑ àí*=½¥¸7€Ür`EÖøÀÌ—îüPKh3R_Ä¿Xµ P/stud.datRmkÂ0þî¯8@%­¿uU§âTjEDdÄöª¶‘$•íßïÚ©sîI oÏËÝåÌM×Lx†ÐthÄÜÐ…W˜½Tу†j-2žÓC}Ü ¼åë4x†™™0∰˜u½°³‹Ùjè÷&ó m”؆oS„"Qï{c8¢ÒBæà47"øžBgØ0o¦F*O}ü^û+¢,Ë«ú`8§Áмy¹4a­·©Ðz/2‰À©*r$³C*xáoTçÖ³ E¾i’ˆHðªž@Î ïÑb-Ëq¯xä”Qé˜qcNÞ¾Ì?s¦½·SˆææFªm•jöÿ!´ ñg—QYv‹x{‘Ê ø{žïÈ×ȲF?ÁM«Éþ6¹üYÍeÕ8¯öåìZ.Æ;,›ã ´Ü;®ã:×¢'Þ6zOÅ}ªÔGQ…üPKh3R©§S“”™ P/stud2.datSÙNë0}ïW Êñ5½”·Ü.EÐViØ„*”Æ“b)Ke»,Ï8$¨„U±äx|Μ3ö˜ÁÂn%Ì6X LÓÁP„ej)lí}­á”v œ¢1ªLtïì(®îfñ˜kU*«.æGAglì1Þ &a4]D£TÆjµÚÚtU l+‰Â08ƒÔFÕð!G„0ИʇöÉ(Ë¿ãÂ(N&Ç7D¹r¡½“É"™Å7àǤõ×cûp;Oˆ¥ª%Ìò\e*-àbCe` Úßá9Üc‚ÜšU¡ŒYÂy-U®PB^ëF4«ËM¡Ò*ÃϨüÉÄßóœÏ‘ÇÅï„*EíËÔÚV;¬«×³¢ÿ`­K¬l/ÕASµÿ½…BôxãÆñ²G‰¸ìÀZUkИ£F*×€­AxÂE?ðÝøóµîÛõ|ðGÀšO´³ß­]v”kt}¶ ìf¿[ôÄoSzâÇœ¯ý5™^R‡M£ë„¨‚ Þ—»2Ùs¡¹‡íW;ê°,ñž%Þvûð/PKh3RY/®Yž[ P/stud2a.dat}’ín›0†ÿç*N/€<—5ýG)]SuID躪Š&2K`"Û´ÛÝ)¥Â|È~^¿ï1'„µë$,÷¨áY¹ßmçàBX„LîÐNBXˆÏÁÄÄT GSIGœ9‡Z²pƒÖªFhZ8¹½Ì“û_Ëü¬Œj”SOw«Ë¤È€…á,YOÍÓl±Î G©¬3jÛ9±­:-Ñ@š&·ð„ƪV›†@îˆ&…lpêþ¸ írq•BšåÅüê$÷~êäz¾.–ùD³y} ÂSx\¤Rz˪R¥5Üí©  Ó#ÏȂӀG»­•µøÞJU)”Pµ¦7-Ûf_+¡K|OÊ>± öZçsÆãGºkªwl„sƒwÚê—³¢ïdgÔn´ÕY_uôy„3"FºYtå³DÜ`£ô VhʵàZà÷³oô~|ùØ÷ÿïŸDÅBÀéAwEÛûí‘Ï7Ú+2‘ñ19tÃ|ñƒúa‘ý,HÊgc~lSþ­•ØxÄÆöM$6ŠÄgÃ^2MþPKh3RÚo°.eÁ P/stud3.dat’Ýn‚@…ï}Šé`¤?ñŽ¢VUƒcŒiVvÔI€5ìbÚ·ï@mcmm`ÃÎ~çœý0³¥‚¸Ü ÌtJª!`,3lƒáz«©¤åJPÚ½.Ú0äC4†2™óÀͨ‹—IôÓ‚2²tD˜O;AÜO¸ž#Üš„Ýñ¬ *2¶ Miå&E(s…„a0‚#†t^S‡#B(U†MûjìòØ !ìFñ ·dÉ¢*Ýô³x-9Kp–Ï/¬Ì&%cÖð¬m luQ‹R’y‚¿I½[XMc¤| “í–’)̼x‚¼ ݽ#îÏ?ÓõQòŠªÄLZ{Êuþ±fþvb†¹½°zp*7÷ï)<0ñ]çV³rÜ;Öí)Õk÷2ßq®ÕÕý„[NK\ù:³† l*Àñ¹á¯~ܪ­û¾ã£Úau;>Iñ_ðº%ßäDúžï]²þ9›¼¥T³ïPKh3R.Ö [•œ P/stud4.datRéNã0þß§ •cL7å_6„¥ˆm«4,‹P…ÒxR,å¨l‡ãí§•p*VbM¾kìa°°­„´]!Ì6XL³ ÁPY ef©¶ö®ÑÇpN œ£1ªÊôàâ$ ¯ngɘkU)«î.ç'aglì1Þ¡&Q<]Ä TÆjµjm¶*ÚZ¢†( /àµQM |È€Ì! 5f²Â¡}´Rù}A'éäôš(W®tp6Y¤³äüñ˜¼~yìnæ)±T½„YQ¨\e%\n¨ ÜŽöx.#÷˜ 7fU*c–𷑪P(¡htgš7Õ¦TYãGTþ…åÄßò\ΑÇÅïŒ:Eí«ÌÚwÔÔÛ³¢}¸ÖˆÖ¶'t]û_GÑã»ÄË$âò¬U½j¤v Ø„'\õß­ÃÏ}_¯àƒ?ž mºÇß}GNåÝ ½A=dð’ýT’}«¸¯ÉôMØ4þŸSpÁûÁžKþTª÷Á{ÈàS$ïâ/g}¸M4xPKh3Rpö{‡ž^ P/stud4a.dat}’aOÛ0†¿÷W? •cL—ò-„0ŠX[¥a ¡jrãKg)q*ÛíßïÂTÂ@±ëü¼÷Þ9Ç`ã[y»CXÐÀ³ö¿šÖÃ…t©Ú£›0XÊÏÁ)äTIO¡¸%Ξà 9¸Açt- œÜ^fñýÏUöÖV×Úë'„»õeœ§À›Œ÷Ô"I—›2TÚy«w­—» ¡5 -$I| Ohn ð)rG„$¶(USÿÛO(ËÅUIšå‹«’Üw¡“ëÅ&_eÎçäõ%`gð¸ÎI¥ÍVe© -+¸;P8@gGº®F0A Ý®ÒÎmá[£t©QAÙØÞ´hêC¥¥)ðRþ‰åñ·º®ÎYÀÅ‘îš:EÛ9ÖÒûÁ;iÌË]Ñ>Þ[Ä¥Šú®ÃÏKˆˆéæ} ¤+žâö¶ÚìÁb‰©]¾ˆ.úNß­Ó}ÿýþIá ‚^´éŸpøÎºôHƒ× Ú2‘Ñ19LÃbùæa™þÈI*¸àcqlSü©ô{›}HòQAüõfN_*šüPKh3Rò2ûÛA P/stud4h.datPínÂ0 üÏS˜(JKµ!þu¥@%Ö¢RÆBS!.Xê )co?¶‰±¡M‰,Ç9ûî,`¢+ qµBwXÀ+é-xG…D Ã2Æ€ ɱ {FÚÛ–L4—œJoKÕ…˜r”U&a¡)ßÔÙ’¿›£^äÌ^ÂhcE9i: LÇ='öÀ¦eó„ò]/˜x¡¤½V´ªt²Ê*fWàºÎ¨öT`µ°Dp…‰Ì±¥ºÁSú.¸^ûý9·ÌêRsèOâ0špñ½¿Ð¥¤”Ø_ªÊüì«¶õ³±m´,Æ1ÓQ±„0MiMIÓÃñËIÃó6NNǬãém6Ê Öß+dç7ä¿GŠ?'žWåO¼¬À{޹ӶlëZxç’eý–ÑMáögÇM¤u%Ȫ‘ŠŠMû¬¨ñPK?3R$P/ ­\ÿíÖäâBãîÖžj%ýíÖPK?h3Rˆ :qr $ P/2-4stud4.dat @[ÜNþíÖ᢯äîÖí/<:zìÖPK?¢k1R$¾P/8/ ';WÌìÖP€)ÞîÖÔÙ-QÌìÖPK?R3RéQš} $ àP/8/stud.dat ¢ 7þíÖ¾Â.äîÖ';WÌìÖPK?R3RŠåúhÆ $ ¤P/8/stud2.dat ÇËð6þíÖ,ò*äîÖS;/WÌìÖPK?R3Rðà*¼ÌØ$ •P/8/stud2a.dat ‡Ùõ6þíÖÙo'äîÖ¬1WÌìÖPK?R3R—Ðq¨‰ $ P/8/stud3.dat .ƒù6þíÖUµ"äîÖºþ3WÌìÖPK?R3RÅ„ûѽ  $ ` P/8/stud4.dat £Àý6þíÖÉ©äîÖºþ3WÌìÖPK?R3R­W¯8ÊÛ$ H P/8/stud4a.dat ãº7þíÖGGäîÖia6WÌìÖPK?R3R‹·_ñ=$ > P/8/stud4h.dat ¿'7þíÖ½ƒäîÖˆÃ8WÌìÖPK?h3R_Ä¿Xµ $ ëP/stud.dat ‡=»NþíÖ`ÞªäîÖ’>:zìÖPK?h3R©§S“”™ $ kP/stud2.dat Æ»ÀNþíÖu{¨äîÖ’>:zìÖPK?h3RY/®Yž[ $ (P/stud2a.dat ó'ÅNþíÖb·£äîÖ’>:zìÖPK?h3RÚo°.eÁ $ ðP/stud3.dat *¼ÉNþíÖoËZäîÖ’>:zìÖPK?h3R.Ö [•œ $ ~P/stud4.dat 4ÎNþíÖc«LäîÖ’>:zìÖPK?h3Rpö{‡ž^ $ <P/stud4a.dat p ÒNþíÖ\Ý4äîÖ’>:zìÖPK?h3Rò2ûÛA $ P/stud4h.dat ­ž×NþíÖˆ©1äîÖ’>:zìÖPK2oleocad-23.03/resources/studslegostyle2.zip000066400000000000000000000221431440571307300206700ustar00rootroot00000000000000PK˜D4RP/PKh3Rˆ :qr P/2-4stud4.dat‘ín‚0†ÿ{gi+:â?DÜ\œÄ9CÈ‚ôÈš ˜RÜv÷+Î-g¶iŸ÷£=æªâTk„és f§E`gØfX¥ÞµL+½èTê¹=¸+P¦0/² %JûR$/qŽ(#M]¾³|šú70“"Jì³xÀ턨‘ëMæøÈE©¤XW*^oªœkO×uưGYŠ"fèA‰®#1æšêMµ´Kè‚ëùÁh¸Ò’e½tu;šSUgY:Ë ×' ÁÕ ¹yÎÚ³!¼Óa!Ë$fÅy]C‰$ÞòË3ekC8 t1‘G0ÝlD"4¾Øqtôf ]× Ô “WŽ}ÁËDŠÒÇn ê 6½ô}¹- ´  K¿ôÏá¡Ço·j}z¦'¤Ý íßHò_Kò§ãçôF“=¿‰÷h¥Å,Ö,nýLIÞ·â¼xƒ´/’¬QˆÕ¤yÚ> PK¥D4RP/8/PKÀU”O$lðE×P/8/stud-logo.dat]Akƒ@…ï…þ‡×[{P´…¼ÙUC@L1)¡´E6u¬º »kÒŸŸ5É)Ìa†yó=æEظ©Å‘]2_®Qê?•VÁK†mÏ %+²x,¤uAfäñéþ.B%GJ°ø¶…­t³N®×&ñ¾Ôu¤ðu~fñ¡Ìêt׬ë%>”î:þe94‹æÝðÈŽt9Z‰¼Ú䨩eë ï''÷aR-‘–8±¬žÃ ,DjH¶#…îßÿ1û¼"¯·«âÓC»y#~Et®ø¶_Ã\rœPKR3RéQš} P/8/stud.datRÝNò@½ç)Æ»ï»XÜn+6xU (F…ˆ1JÌÒ`“þÝÅŸ·wZ…*1mÒíÌ9gΞ ‡‘[+ø×“ֱޑ/ÿneŽm-µšJ:*Ek·,M®¨eá ­Õ¹,¨qtÝI¢»§AráÓÐè\;ýŒ0v¢q÷ZŒ{5®woG]HPi댞­œeëB¡8Ž®áÕe¢É¡ âÈ T96Ý«kÊy/†¸›Œû½{¢ÜU¥£Ëþh¹¢1M£E‹=ÀJöí.iû÷›KƒIPdK{™sæœÍ:0µÛ ÆTða Œe=-~l90v!x4çíLXº ·v]ê.ÜPÌÀ # ¡(puۋû§qü‚§‰–…´òa6é…I¸ãv˜ãÖ¸aÔMûc&Õr±µb‘#lU†¢(¼…gÔF– xÛ.DˆB"+°mÿØeù6ˆ êÇÉppO”»êêêz8MÆñ=i9œ9>ýð`¹4f?ÊL.%f°,uMNËb“K¡RüZïEj1£]†¯¥âŸáa’©æ0^.e*E³ õ÷ Þà}aN‡qÿïUX9(„µ{/Q©v= }¸Òˆ*ÛH°*›{ÙB@ˆSž[¹bn‡xk™—sˆÖB­H×–UÏÎÁóœ·EjйˆÇè–{—yÞiã@­=š›r|Ú&Ç4ñ•Žw¡ Çk¹@E;õçïW÷x}æc¶Âj _B«{8¿eþûÓ2ÿywÃ<ý¤qõ%Dö¹Ï›Rþ©Tú7—½nÖÝù>3ÆÆø«¥Zí^û?PKR3Rðà*¼ÌØP/8/stud2a.dat}’Ýn›@…ïý“»öb]X(EîÁ¸q”ÚÆM£ÔŠÖ0¶WâÇÚ]’öí;'-8±ø[-ß™9;:,MÁü€%oÁ'¢«³WÌöH·—yµ†p/Êõ5U3³SØaŽõ~“:mâ0ÚåÎyÓÏKh´¯æVšœùŸ/ÉÑ}¾éãœÂkÆ6С-`.½èi/ûøu)Ð.s‘òÞ$ºÃz=Öë²ÇØMg?(x³ègBb—»¼ßÊí¶Jÿ䲑÷h¯G{ÿèc¼gŒ?³J–;ÞÂPKR3R—Ðq¨‰ P/8/stud3.dat’QoÚ0Çßù×·íÁÌI<±§,ÀJÕ‚ªªC•‰°”ÄÈvºíÛï’A5膪(Ééüûßý}: ß(È›5”ZÁ»‰tž¬üñ¾ÇáNV8„ø»#*ê+é)—4~gìnèÌÁ :§+YÓÁÕí(KîŸfÙWˆŸæVWÚëg„å|”äcy0`<è¸i:¾[Œ!C¥·zÝx¹.šZ¡…4Mná­Ó¦†°ÏaÒÄ¢TöýOߣ*_&)¤ã,ŸNHrߦ®®§‹|–=P/2.àÑ­KíÜ ¾¥7lŒíÄ…©ö¥–uŸ»XE ÿU*üóœ èz³ÍFZ–°ÜÓLð…gºOŒX(þÒ]£¤¶*éýÁKjê?3 8ÙZÄ kV*fmµà²…˜ˆS]кbÁ€t;]š¤;Yo©¯7íÌ^Ëøÿ›tÐë&£l]ÖE§ó9®öÅÜÒ‘³øÃþ¸9îœoûD†ð²c½èÒ˜ ½Ýþ‚öY0j‹íFYþvôRYÚèâÀŠP„ç´8¥‹_¥îèßPKR3RÅ„ûѽ  P/8/stud4.dat’QoÚ0Çßù×·íÁÌq2ñ–X©:@!¬«:Tr€¥ÄA¶Ómß~—@«ZTEJ¬óïÿ»Ëq˜»*ƒ´Z!L÷¨áÃHZÇFþþØá0‘ö!üe º™t‹*·+MnèΠZ« ©éâêvDwÓä„3£ åÔÂb6ˆÒ!îõ÷n'ó!$˜)ëŒZUN®r„Jgh Ž£[xBcU©At9ôÁ"B”Y]÷Çu(Ë×Q ñ0IÇ£{’ÜÕ¡«ëñ<&÷äÅãã><ØU®¬]Â÷2S…lJÓˆ×e±Ï•Ôk|M*>ÃÃ,%C¥—0ÝlÔZÉ{š!ÑÒ}a¼ÇDðŸî%uT;Ò¹£w\êCÏt޶±@íZ©BVgó.—qªóꪘ×#ÝNååâÔ[òue=£sØg>Û¤ÎM|FQá_Öù§óyþý4Ú—â–* ?íŸ7ŶùÚÇ¿0„—êx@Ms`½èÐ<ÞñÛ£ý X€Ùë >aþÎò÷§åïÈzXÞñä­ïdø3%m Ñn 8uZÿÍÕy-6¼ÀŠVYâÀ¥·~ÿPKR3R­W¯8ÊÛP/8/stud4a.dat}RÑn›@|÷WlÞÚ‡sá .rŸÆ£Ô¶lÜ4J­è kû$8¬»#iÿ¾ q¢€ «½™¹Õ8°´UIµA˜PÁ“´û²²p) BœíÐÀ§±0–´xúÜs`* BðÇÏýLXj†±ô®éÐÀ5# ¡èàâf´of‹<̵,¤•«ù(LbàŽ;`ŽÛà&Q<]ưÀL«å¦²b“#T*C QÞÀ#j#K¼ïÀ "D¡F‘Ø·m¦\Ž#ˆâE2ßå¶n]\M–ÉlqGZgŽO/Ü›M.YÃÏ2“[‰lKÝÓ²8äR¨¿7µH-fTeøÞ(þîç j ³íV¦Rä°:ÐNðâÞ7æ ÷ßð®PÐ k…°öè%*Õó¨w±@e;£VOsÏ[Ñæ¹µ+户—y¹†h/ÔŽtmYïìì1ÏùX¤ŠxŒºÜ;ÏóÚûy‰­öÕÜʳàËá%9¦‹¯u¼3KxÍXϺ´̧Íãÿ ´Ï|¤¼×‰naƒ6hc±›LQð¦ñï„È>÷yWÊoK¥ÿry*ÕÁg°¼c‹?cµT;¯ÿPKR3R‹·_ñ=P/8/stud4h.dat•QÛNÂ@}ç+Æ7}XÜn7¤á­–¢$ ¤/QbŠ»À$½íÖËß;E1R…hšt7³çÌ9g†ÃÄV âj®a´Ö9¼ ]Aøju®´‚‹"ÕpÜOJËz&y9iq&™î‚÷PO®Ú*±Tô+»*LbÌ༨R÷³e}›ÑóÑe/òoGÑ9xcƒZ|Ö0÷ü8ÁãÎ7Âá$„H+,­Áye“9Y¨È ð/áY›‹D›CJ­!ðNT¦ÛöÕ¶¨ËY?€ ŒâAÿŽ(7uéèb0‰GÑ]­%Ìq¿9„«Bá)ïÂP2!ë`?‰.s9Üc’Ã|£ÅŸ0Iaº&¸þ9 žË¨*ÜÃ<—\}ãm‡Â¸$Þ ÓbÓ’z§ëíüÊ&¾Öqý:_“n9àt€“ô£Ëæs>Ï-W2©ÕR×CØÁz ¬÷;ömùº~¬t0¼¦¥ÃÛ˜¸RHÑ àí*=½¥¸7€Ür`EÖøÀÌ—îüPK F4R“Wܤ/P/stud-logo.dat‘ÁnÂ0 †ï“öæ‚Ò®ÚºRR¨í„B(4"…¥)o¿¤¬ÀåàÄúüû·C¡° ‡a¥ãdz¯ÀT+ò6„ò dBaýúBaÊŽ8€Úé°>gÖ§ãÆ´Àœ5RV[4°:)lokOô²a/6³| ßJïv¢LnæF…g¼"“$)äÈEmØ6–m%B£¸ÓK’8ƒ3šZhaŸ‚óIlñ#öí¯³âu>G $i^NFKW´¸&{_“¢œåKiª,˜â—µkx’¬B‰ª‹¬üXíBÚIáÔ¹¬?€qÞn‰ö"]w-µñÞ¶§‹A÷ö²È÷èeo$‰žA£0 eÛÂ.ñoW<©ë–Z]ÑGøÝc÷µPK+¸2RZ3|'* P/stud.dateű 0ÀU\ !ßdA°,Ôý[¹â@øôÖ‘%Ç\ý gPK¨C4RY”.˜#WP/stud2-logo.dat’ÁJÃ@†ï‚ï0>@B².=ôÓ´BZÒj‘²m¦Í@²)›MÕ·w·1V£`™Ãì ßÌü?¬ Ýd0; „WÒ9ÄÑdqµ¯À¤’Îí–9IˆIb}}åA"JBm¦˜SÎÍ„¶ý Ñy¥†0M‘¨5*x>H<½^,qÒ`µž¥¸—ÕnG[Åz®¨$MGl‘i%‹R̨֊6›¡‘™Ù†A GT5U˜ë‚a Pd%ºúÍH±{îÆ!„QºœŽŸÌÐÊ6}ðà‚fÿ«æÇlÖ˲Ë~WÿI:üâ¥ÿk+š<Iô¸´ÃœqÖ¿Ä¿_Ú¾dÇûpßó ƒËb=YÌ¢ŠäžµlG·áž]œ;݇øPK:¸2RÇ:“à(+ P/stud2.dateű 0ÀU\ !Ÿ"ûÁBÝ_°•+„G§aì‘|—šØæPKh3RY/®Yž[ P/stud2a.dat}’ín›0†ÿç*N/€<—5ýG)]SuID躪Š&2K`"Û´ÛÝ)¥Â|È~^¿ï1'„µë$,÷¨áY¹ßmçàBX„LîÐNBXˆÏÁÄÄT GSIGœ9‡Z²pƒÖªFhZ8¹½Ì“û_Ëü¬Œj”SOw«Ë¤È€…á,YOÍÓl±Î G©¬3jÛ9±­:-Ñ@š&·ð„ƪV›†@îˆ&…lpêþ¸ írq•BšåÅüê$÷~êäz¾.–ùD³y} ÂSx\¤Rz˪R¥5Üí©  Ó#ÏȂӀG»­•µøÞJU)”Pµ¦7-Ûf_+¡K|OÊ>± öZçsÆãGºkªwl„sƒwÚê—³¢ïdgÔn´ÕY_uôy„3"FºYtå³DÜ`£ô VhʵàZà÷³oô~|ùØ÷ÿïŸDÅBÀéAwEÛûí‘Ï7Ú+2‘ñ19tÃ|ñƒúa‘ý,HÊgc~lSþ­•ØxÄÆöM$6ŠÄgÃ^2MþPKh3RÚo°.eÁ P/stud3.dat’Ýn‚@…ï}Šé`¤?ñŽ¢VUƒcŒiVvÔI€5ìbÚ·ï@mcmm`ÃÎ~çœý0³¥‚¸Ü ÌtJª!`,3lƒáz«©¤åJPÚ½.Ú0äC4†2™óÀͨ‹—IôÓ‚2²tD˜O;AÜO¸ž#Üš„Ýñ¬ *2¶ Miå&E(s…„a0‚#†t^S‡#B(U†MûjìòØ !ìFñ ·dÉ¢*Ýô³x-9Kp–Ï/¬Ì&%cÖð¬m luQ‹R’y‚¿I½[XMc¤| “í–’)̼x‚¼ ݽ#îÏ?ÓõQòŠªÄLZ{Êuþ±fþvb†¹½°zp*7÷ï)<0ñ]çV³rÜ;Öí)Õk÷2ßq®ÕÕý„[NK\ù:³† l*Àñ¹á¯~ܪ­û¾ã£Úau;>Iñ_ðº%ßäDúžï]²þ9›¼¥T³ïPKh3R.Ö [•œ P/stud4.datRéNã0þß§ •cL7å_6„¥ˆm«4,‹P…ÒxR,å¨l‡ãí§•p*VbM¾kìa°°­„´]!Ì6XL³ ÁPY ef©¶ö®ÑÇpN œ£1ªÊôàâ$ ¯ngɘkU)«î.ç'aglì1Þ¡&Q<]Ä TÆjµjm¶*ÚZ¢†( /àµQM |È€Ì! 5f²Â¡}´Rù}A'éäôš(W®tp6Y¤³äüñ˜¼~yìnæ)±T½„YQ¨\e%\n¨ ÜŽöx.#÷˜ 7fU*c–𷑪P(¡htgš7Õ¦TYãGTþ…åÄßò\ΑÇÅïŒ:Eí«ÌÚwÔÔÛ³¢}¸ÖˆÖ¶'t]û_GÑã»ÄË$âò¬U½j¤v Ø„'\õß­ÃÏ}_¯àƒ?ž mºÇß}GNåÝ ½A=dð’ýT’}«¸¯ÉôMØ4þŸSpÁûÁžKþTª÷Á{ÈàS$ïâ/g}¸M4xPKh3Rpö{‡ž^ P/stud4a.dat}’aOÛ0†¿÷W? •cL—ò-„0ŠX[¥a ¡jrãKg)q*ÛíßïÂTÂ@±ëü¼÷Þ9Ç`ã[y»CXÐÀ³ö¿šÖÃ…t©Ú£›0XÊÏÁ)äTIO¡¸%Ξà 9¸Açt- œÜ^fñýÏUöÖV×Úë'„»õeœ§À›Œ÷Ô"I—›2TÚy«w­—» ¡5 -$I| Ohn ð)rG„$¶(USÿÛO(ËÅUIšå‹«’Üw¡“ëÅ&_eÎçäõ%`gð¸ÎI¥ÍVe© -+¸;P8@gGº®F0A Ý®ÒÎmá[£t©QAÙØÞ´hêC¥¥)ðRþ‰åñ·º®ÎYÀÅ‘îš:EÛ9ÖÒûÁ;iÌË]Ñ>Þ[Ä¥Šú®ÃÏKˆˆéæ} ¤+žâö¶ÚìÁb‰©]¾ˆ.úNß­Ó}ÿýþIá ‚^´éŸpøÎºôHƒ× Ú2‘Ñ19LÃbùæa™þÈI*¸àcqlSü©ô{›}HòQAüõfN_*šüPKh3Rò2ûÛA P/stud4h.datPínÂ0 üÏS˜(JKµ!þu¥@%Ö¢RÆBS!.Xê )co?¶‰±¡M‰,Ç9ûî,`¢+ qµBwXÀ+é-xG…D Ã2Æ€ ɱ {FÚÛ–L4—œJoKÕ…˜r”U&a¡)ßÔÙ’¿›£^äÌ^ÂhcE9i: LÇ='öÀ¦eó„ò]/˜x¡¤½V´ªt²Ê*fWàºÎ¨öT`µ°Dp…‰Ì±¥ºÁSú.¸^ûý9·ÌêRsèOâ0špñ½¿Ð¥¤”Ø_ªÊüì«¶õ³±m´,Æ1ÓQ±„0MiMIÓÃñËIÃó6NNǬãém6Ê Öß+dç7ä¿GŠ?'žWåO¼¬À{޹ӶlëZxç’eý–ÑMáögÇM¤u%Ȫ‘ŠŠMû¬¨ñPK?˜D4R$P/ L€oÿîÖÈW‡ÿîÖžj%ýíÖPK?h3Rˆ :qr $ P/2-4stud4.dat @[ÜNþíÖ%ÔíúîÖí/<:zìÖPK?¥D4R$¾P/8/  –(ÿîÖ –(ÿîÖÔÙ-QÌìÖPK?ÀU”O$lðE×$ àP/8/stud-logo.dat ƒI·Õ‰[}ÿîÖ –(ÿîÖPK?R3RéQš} $ æP/8/stud.dat ¢ 7þíÖ„ îúîÖ';WÌìÖPK?ÀU”O•±†üÜ$ ªP/8/stud2-logo.dat A¤öH·Õ©&@þîÖ‰u{ýîÖPK?R3RŠåúhÆ $ ¶P/8/stud2.dat ÇËð6þíÖËþîúîÖS;/WÌìÖPK?R3Rðà*¼ÌØ$ §P/8/stud2a.dat ‡Ùõ6þíÖ¥îúîÖ¬1WÌìÖPK?R3R—Ðq¨‰ $ Ÿ P/8/stud3.dat .ƒù6þíÖN#îúîÖºþ3WÌìÖPK?R3RÅ„ûѽ  $ r P/8/stud4.dat £Àý6þíÖsu*îúîÖºþ3WÌìÖPK?R3R­W¯8ÊÛ$ Z P/8/stud4a.dat ãº7þíÖ¼ï1îúîÖia6WÌìÖPK?R3R‹·_ñ=$ PP/8/stud4h.dat ¿'7þíÖ˜:îúîÖˆÃ8WÌìÖPK? F4R“Wܤ/$ ýP/stud-logo.dat ½×~žïÖYyaŸïÖL€oÿîÖPK?+¸2RZ3|'* $ YP/stud.dat Åã‹tåíÖ°øöAÿîÖ’>:zìÖPK?¨C4RY”.˜#W$ ¨P/stud2-logo.dat –#ôýîÖ~ ù¸ïÖMÆqýîÖPK?:¸2RÇ:“à(+ $ ùP/stud2.dat ¤Ò †åíÖî{ÙÿîÖ’>:zìÖPK?h3RY/®Yž[ $ JP/stud2a.dat ó'ÅNþíÖbIèíúîÖ’>:zìÖPK?h3RÚo°.eÁ $ P/stud3.dat *¼ÉNþíÖ5ïíúîÖ’>:zìÖPK?h3R.Ö [•œ $  P/stud4.dat 4ÎNþíÖšõíúîÖ’>:zìÖPK?h3Rpö{‡ž^ $ ^P/stud4a.dat p ÒNþíÖøWýíúîÖ’>:zìÖPK?h3Rò2ûÛA $ &P/stud4h.dat ­ž×NþíÖ¡îúîÖ’>:zìÖPK¼‘leocad-23.03/resources/stylesheet/000077500000000000000000000000001440571307300171575ustar00rootroot00000000000000leocad-23.03/resources/stylesheet/branch_closed.png000066400000000000000000000001641440571307300224540ustar00rootroot00000000000000‰PNG  IHDR‰ pHYs  šœ&IDAT8Ëc`C üÿÿß„©nà7tð¹pðF“t8 † (êL9QrIƒIEND®B`‚leocad-23.03/resources/stylesheet/branch_end.png000066400000000000000000000001611440571307300217460ustar00rootroot00000000000000‰PNG  IHDR‰ pHYs  šœ#IDAT8Ëc` üÿÿ߀š`ÔÀQG„¡ø0Ã(ÃøË9+¹1?7IEND®B`‚leocad-23.03/resources/stylesheet/branch_more.png000066400000000000000000000001631440571307300221440ustar00rootroot00000000000000‰PNG  IHDR‰ pHYs  šœ%IDAT8Ëcøÿÿ?Ø€Hu £Ž8Ò $ †á¨ÃÒ@ŸÂ±-øË)šIEND®B`‚leocad-23.03/resources/stylesheet/branch_open.png000066400000000000000000000001761440571307300221470ustar00rootroot00000000000000‰PNG  IHDR‰ pHYs  šœ0IDAT8Ëc`£€:àÿÿÿ LªAÑ5â'ËPŠ Ãf(ņQÅ›£` ²L9‚šIEND®B`‚leocad-23.03/resources/stylesheet/branch_vline.png000066400000000000000000000001571440571307300223220ustar00rootroot00000000000000‰PNG  IHDR‰ pHYs  šœ!IDAT8Ëc` üÿÿ߀š`ÔÀQG 5pÔÀáh ¡ ?…XhîÂIEND®B`‚leocad-23.03/resources/stylesheet/close.png000066400000000000000000000003761440571307300210000ustar00rootroot00000000000000‰PNG  IHDRH-ÑbKGDùC» pHYs  šœtIMEß 1äE'kiTXtCommentCreated with GIMPd.ebIDAT(SÅPA À0«ûxÙË96¦^ÊhA(11Æ1®=wŸ¨Ýܘ¨Ä ³,Ì3{ÑSðEÈÄ<4V„JÌ"pJÆìÒý‹£:°ëùqv×ãÌá\2òJjÍ.û½€ƒ9ý²ÀTIEND®B`‚leocad-23.03/resources/stylesheet/stylesheet.qrc000066400000000000000000000005411440571307300220570ustar00rootroot00000000000000 stylesheet.qss branch_closed.png branch_end.png branch_more.png branch_open.png branch_vline.png close.png undock.png leocad-23.03/resources/stylesheet/stylesheet.qss000066400000000000000000000040771440571307300221100ustar00rootroot00000000000000QToolTip { color: rgb(58, 58, 58); background-color: rgb(224, 224, 224); border: 0px; } QMenu::separator { height: 1px; background: rgb(80, 80, 80); margin-left: 10px; margin-right: 5px; } QToolBar { border: none; } QTreeView::branch { background: transparent; } QTreeView::branch:has-siblings:!adjoins-item { border-image: url(:/stylesheet/branch_vline.png); } QTreeView::branch:has-siblings:adjoins-item { border-image: url(:/stylesheet/branch_more.png); } QTreeView::branch:!has-children:!has-siblings:adjoins-item { border-image: url(:/stylesheet/branch_end.png); } QTreeView::branch:closed:has-children:has-siblings { border-image: url(:/stylesheet/branch_closed.png); } QTreeView::branch:has-children:!has-siblings:closed { border-image: url(:/stylesheet/branch_closed.png); } QTreeView::branch:open:has-children:has-siblings { border-image: url(:/stylesheet/branch_open.png); } QTreeView::branch:open:has-children:!has-siblings { border-image: url(:/stylesheet/branch_open.png); } QDockWidget { titlebar-close-icon: url(:/stylesheet/close.png); titlebar-normal-icon: url(:/stylesheet/undock.png); } QDockWidget::close-button, QDockWidget::float-button { border: none; border-radius: 3px; subcontrol-origin: padding; subcontrol-position: right center; } QDockWidget::close-button { right: 4px; } QDockWidget::float-button { right: 22px; } QDockWidget::close-button:hover, QDockWidget::float-button:hover { background-color: rgba(255, 255, 255, 30); } QDockWidget::title { text-align: center; border: 4px solid transparent; padding: 4px 0px; } QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { background-color: rgba(255, 255, 255, 40); } QTabBar::close-button { background-image: url(:/stylesheet/close.png); background-position: center center; background-repeat: none; } QTabBar::close-button:hover { background-color: rgba(255, 255, 255, 30); } QTabBar::close-button:pressed { background-color: rgba(255, 255, 255, 40); } leocad-23.03/resources/stylesheet/undock.png000066400000000000000000000003631440571307300211520ustar00rootroot00000000000000‰PNG  IHDRH-ÑbKGDùC» pHYs  šœtIMEß 2 ÜìþiTXtCommentCreated with GIMPd.eWIDAT(S½QA Ê>Þz¹ƒ9ìf]JQã÷±t÷Åâf¶Wù©& 0~s­$²JV òE¬º¿”ÕÄ͹ØwÞ‘1¹ceŠ3&]mýŽfçDûÍ4öuè-IEND®B`‚leocad-23.03/resources/time_add_keys.png000066400000000000000000000027071440571307300203030ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYsÄÄ•+ÉIDATHÇ¥”[l“eÇß·¯]»vÝÚµÝ&0Æ`'SÂA"ÇÁdb$†à¥x#*†(1zcˆÑŒFƒD‘hä8Û€Á2•ºum×ówx½è& Ÿä¹yÿßûœ^IÁÃZËg®•ÉððúTœçdùBG—$:ÌÙæ£ÖœüÝ3_¿Ýqïéa­_æO õ ìµç9Ïß@ni5d‚ÐWè»rˆ®†)ÉÄçwá¶é›z hÝí( öŒœ¨¬®)tÏÛ$A» ú ™€LÙ erí§ñwûêíîœU³Þ&þвK²„ü´>µbÁ´Ü'W‚vR×@H`L‚ˆJ°¯[® S¾2½´ïÿ‚þ;¡OSo-ß.ŒÎ|(msšw–׬# j÷hÜEo9ød´¡ƒ³•™>gQé„â…s!9ÄÉoª¿¶1ǦЪ<(=±¶”­(‚„Ô^:H ˜d.?ilÜÅú¾@ær癢òâ'd‡Æ”ÊÓÈéÐk#f¶Ê㉟ûHªÈr0QrØ!9Zt ´Äû‰ŒèKp¡ÜÍð†…øRíÑ€Ô(E̞ʒC˜Æ$TØs­€z„H;2È)Ü^²^ϦU‹s¥³MKòrX˜íR@˜œnœvÊn¢Œ›"]`B6dŒô†ÐÁZ¼ճ ³v‡ÿvßv»Ëš1wÙZpY ÒŠC $x@Π{$Åê£4ˆ_ç ÌÛüd¸2qˆ4ÁÐÁôbñ$=¤ã ˜.úÕ Ã Ô»›jüû!tL.Ð"é&Ðã`-¡÷F€ÆNÎú¸M§ÒÐI%®cqeÀ½Ý,THøÒ>f&˜ ¹Ú|œ#-´-ò±™U¡AµîÙÕ‹]–ÂE$"ö4`¬Ð÷ù¨¸­‚ΆfÎ6é§ÚüÔÙ@»/‚º÷-Uá@ªþù5˼Îâø»[ðT¼ ‘`„@ ‚‘IÅ–B0{éºp‰ß~¹ÒûÁÏl¢*hÿ˜ä£Û-U¡@²¾zí2¯«xþîf<å+A½ Äú†Èu;ÁfôÑ–•ù£—K§Îñ{c ýïÙœ„Ë6ˆF„¸[ƒÃïY«Âd}õš¥^×äø»šñTÔ@²¤¾¶.ŽüÐ0d1£x Ì9Yºš"ãëáFmßÕuð 0” ñˆ:Œ~v‡ÞµVõË×-õºKfâïnÂS^ÑFÐûñÝT9¸ï\ÿ›{y% ×\&¦•x˜8"áÒâ€*„ëi”ÚmRUpˆ´xñLü·šðTŽŠ‡Á6‰ëÛØSÇŽ$4ˉ«ô_èA$Ò%6ý]QSæõL.»ûòX ÄÚÁœ ’‚! tƒ ¢q!R<‚)’Ì$Oÿ­<Ó_‚Øy0ü÷4È2!]B–¢š; ãQÄ”„ýñ<ò«^„ÔUÐ˜}Ÿ|M*™>”Jé sBÎcBQÈ/}”áôtZ§î  Ù²—2Ät !U@1+ÛóöÎê±!ˆ…ct×·²O@X¢ëq„ÇL2+”jNÌ€it]|âŠü pJ´.h@ï%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/time_first.png000066400000000000000000000024151440571307300176430ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYs  šœIDATHÇ••[ˆÕUÆûΙљ¢AÉÆc–S¦]Œ¦,o½ø&a8>&]+(1Á"A‡ Š"ƒÐf¦Â Ф,´2«‡*"uÊ£ƒsqÆsz8ŽÎÑ9ƒ.Ølö…õ­o}{­íÌŒq[»ë„U‚¢j8çÈeŽæ‚ûù§·–ur¶ô…ÃÃoéhÈO<¨V6wPñF.}‰{ÿ¹ß,yöP)Tå¦ñu@ð‘QåèIOSÞÑ?°$×ìüž'¾*-œ×R<}¶zi/«»!Šœ+ eá|Y0¹6€;×}QZ±´­øücí”ËéÒ~ ‚ˆyU#y:êÇ?/† ¥UËnbÝ#³8øg…‘ÊäIUQ„’7ƒ»×(–Ç|iõê[èZ^äÐ_J#T'pQHb„h8U¢(’Ò¤Îç¯é-V*¡´rU;ëV´óɯç9w!1½)…)’˜ƒ˜ gF †%»ÊyÇ£=í•r(=µi!Ý;ƒÞcCŒUçjY@.3¨Y£’ÔHIU$zƒÛ—ØU-Ç3Ÿ¼‹% Úèþq˜áQAÅÐhø hC’””ÌQ &<Ó[~}µ>ÚôÌb:Ì ç‡!ÊU#s €š‘Ï+2A·:KB%Å ½ VSlöý{Ö§ ÝŸ^ÄüŽ6öäüX"ŸeŒÇ«f( a*ðÁ0Sb4jµ}Ñ;k Ó Ý›·>H¾©‰ýßâ.æ7¨‚‚AmÎ M hŠˆ!#CB šÒž™³¦ÓÒÚÌ{_Ð왃˜qQTÉ6A·¬žT jĤˆXl=ûÇs·õýVêß½ë{V.¾ AñI‰QIIIÞˆÞˆ±6¨DB¬1Qˆ^±˜ ƒÇ_œÝÿ÷Ùî}oáŽ!>Á !)1ÕRêƒÖõ¯ú^bJðJô†¤úËCÇ_Ú020ÒÓûîw,¿o:I #E%%F#E©{ÚW0P|„è­Æ &$ź†Nn骎ùWöîþ†Î;r$ ÅZºb¨Í¦qrK‰ ŠH…DÅäêJéۺ×Ë]û^?Hç#7-OÕ 1*¡j¨6J‘(Þ+¾šHI ^0 Lf£ÿ¾Ü“åÙÐýö×,º9ÒtcŠÄ¤¨4P x1‚W¼RR45n×£¥íÝYÆìÞ72sl€öb+•òHT.¤Z>Õ M§þpÆÎìè§97çØgÇh<ͬy­¤ÐH|TbÕB­eÈÔ@¹ÿÕÓnZnîÑ¿œ*œèwù¬®’1%e“ “Zm\‹•û_;Ìýýð¶yWœ ËŸnÛs0p—Ë]À% ÿvÎiiß><¾þßâz.­%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/time_last.png000066400000000000000000000023331440571307300174560ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYs  šœÝIDATHÇ•–OˆUuÇ?¿{ïs„pFÊ!ÑM›ˆ°1µEYQ›ÀM(¡#ÄPD -¤\´Šh[Hë4$ˆÌÌŤ©S-ÊÂ-™ÑçH9¢MoÞýý9ç´¸ÏÑçæt6÷>Þïw>¿ó=çûã:3ãFìØ×¼öÕž KùñÔ[Ç~(½­‹IAŒÅ‹2ì¾ÏsÖ÷<³w¸yhφ• ´ZÊžúX½tŠqWWÎÖ½#3ÿg·.NÉpj}O¿}¢¹P€$¡ Æñ±’“ãžãã%e~@»>\A÷’¼ï‰7Ž-¢AÈ\m+“-e²­¸dóB™bìÚÔKOwÞ÷èkCöøëC}ÿY(j†ˆaj¨"5HT¾¿àÙýܽt/É mi>öêÑZˆzEĈb$5B2,Õ4(GJÆ·£ž[–ÓÓ“á§µùÈŽoæ…¨$’(Iªä!V²Í„RÄaœó¼¹}ý-ÁOKsýà¡ås&‚šÃ{%$%&E“Ö’b)AL•®GFÛlÞ¸Œþu=”Óqbíö/·ÍÝ#jUAñQQIõ%3Ê D©ÆV“røÌ?l~²—µßoÅO×lùbëM@BÄ(£¢‚¡¾¶É‚D||¬´U¯O·Ø¸¡—5ëïaºUîðÙÏ·vöhÅ¥ŒJ Ó›Ìr²Š¢RÉCª`¦Õû‰³-Öõ/£ÿþnö}ôÛþ6}öw»Ê$F™Œ PS­¤ŽD¥¢…CÍ0»Søy¬MowNWWÄô±%M¥W ¢ê|`¢3³ìC¥§†ïüŽSSÊÁO~%¶ýå3‡V«¤»¢ÞW2ùd˜Äš bÀÌÑöŠ6²Ê™7n[—qe|ŠñŸÆ)`ÿÈÑç:ƒÑPU|0颱N¢(³& T¹"cr|ŠK?þAVäF†fªÖDˆ‚"Îp¦h], QÒK§pyÆäÈ5þúå<ù¢üݳCƒïÌ:” Av)ä™dX¬›¢”3J¯˜B¶(gbø"Ó’Ŷsß½xà6''Á£í•F^õѬ«&… EÁåS˜ž¸‚+²ßï¸-y5ÚBHŠo+Ú An¹ìŠ9Ç!”ÑqõØ9ÒõëdE¶âüÉ—.S–Råâ$`†‰£êyÊTr\91J#•¸†[y~øåÚä3=HFò‚+Õ<¯ò >|ï$Y9}X56üÊ%!±Îsv³S“—š§w®ºSâ[6Qt5 /p Š œ› )]ožÞµà/ €bqÁÁ÷g J^Üæ_ Pжà„å†%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/time_next.png000066400000000000000000000021771440571307300174770ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFPLTEÿÿÿ&&&ZàT†ÜL|ØFtÓLuÓKpÎHjÉEdÆD`ÁA[½>T·S¸cšäa•áb—áb—ãc˜ãf™ãd˜ã\–â»ÚõUqÅ>Tµž­ð‚§gç—W×Ö(ý’›Û»û‡G†Rxz~y}³e ¥ðþñùe§Ù(…ï{n£~…RóáØUo†¤W%%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/time_previous.png000066400000000000000000000021631440571307300203700ustar00rootroot00000000000000‰PNG  IHDRשÍÊgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFPLTEÿÿÿ&&&ZàT†ÜL|ØFtÓLuÓKpÎHjÉEdÆD`ÁA[½>T·Tµb—áa•ácšä>S¸Mh¿šÁíZ’á^”à^“à]‘ß:M°\‘ß\ß^–äž/6˜b~ÆQâ/8™UqÄ/9™/<›ÿÿÿš¨8tRNSðåååWVVHâ稩€VWãåð›ØÏbKGDˆH pHYs  šœtIMEã KkÅ$IDAT(Ïc``DL0šÄ™¥a4ª‹Œ,ŒF‘`•“W€ÑHlŠJÊ*ª0!Á®¦®¬¡©£áÚ:ºzú†0&Áidlbjfna £¡\VÖ6¶vöŽPÚÉ"Áíâêæîáéå ¥=||Á<~þAÁÁ!P:84,$Á¥cb“@|É)©ié™YP:;;'7l~AaQqqI)”.+¯¨„X.PU]S[W_ߥ›š¡Îlimkïèìê†Òm=0 õöõO˜8iò(=$ÂӦϘ9köD‘¹óæ/X¸F#»èâ%K—-‡ÑÈ%¶båªÕ0%Å%Ö¬…Ñh‰ArŒF“`”‚Ñ MRo™ŽQ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/time_stop.png000066400000000000000000000013671440571307300175060ustar00rootroot00000000000000‰PNG  IHDRójœ gAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<PLTE222KKKiii‚‚‚›››´´´ÍÍÍæææÿÿÿÿÿÿÿÿÿUWSÞßÝÞÞÝÞßÞßßÞßàÞßàß™›–œžš ¢£¥ ¦¨¤ª«§­®«°±®ááࢤ ¥§£©ª¦¬®ª¯±­²´°¶·´¹º·âãâ«­©¯°¬²³°µ·³¸º¶¼½º¿À½ÂÄÀäåäàáß´¶²¸¹¶»¼¹¾¿¼ÁÃÀÅÆÃÈÉÆËÌÊçèçââ὿¼Á¿ÄÅÂÇÉÆËÌÉÎÏÌÑÒÐÔÕÓëëêãäãÇÈÅÊËÈÍÎËÐÑÏÓÕÒרÕÚÛÙÝÞÜíîíæçæÐÑÎÓÔÒÖ×ÕÙÚØìíìéêéÜÝÛëìëííìììëëìêêëêÿÿÿ°<—atRNS$).38=BGLJ(†)<bKGD ö´aõtIMEã KkžIDATÓµÑÇRÂ…aBèäÜHUºJ¯‚€RÄPCÿç`†Å…à_~»3Ç`¸s‚ñš(0‹¸Id6HU‰Ü/LÌf¨>àñ) G`f¶€¢±øsâ%™z……Ù ÷[:“Íå ŬÌ6”+ÕÚ{½ñÑlÁÆlGûó«Óíõ¿°3;0ýŽ'Óm³óÅrµÖˆH‡“Ù…ÍzK—vp1K˜íuýpØ'HÌòíx™Y‘%NVî}Ì 9Xt -%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/view_split_horizontal.png000066400000000000000000000010431440571307300221300ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFPLTEÿÿÿ |µ r§‚¸¶¶·‚¸žÐï™ÍìšÍì¶¶Ýõ8Û9Û7Û |µÿÿÿ{´Ö××רØ××Öãäåäää {´ððïòðïz´ }µÿÿýÿÿüÿþü {µÕÖ×ÕרÖר×ÖÖññðòñðóñï~¶{µ |µØk³htRNS²ÁÀæúÂbKGDˆH pHYs  šœtIMEã KkÅ{IDATÓmÍÛ‚0Ðá¢P Ê€(^Т¢Õÿÿ@mØ45zæm2ÙE”¤3‘ΓÈrµJå ‹r)ÊU¡Š¡ ¨Ù¬EÓ²vÅÆÛº¢ãÎÛóÙŸ$çÞ-4Ãtnú†Ãå:e¸ýýb8ÞÅø ì× Äöé½lŒošà îpKm%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/view_split_vertical.png000066400000000000000000000010631440571307300215520ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF{PLTEÿÿÿ¶u¨‚¸·¶‚¸ƒ¸žÐï™ÍìœÏî¶¶Ýõ7Û8Û´Üô |µÿÿÿ{µÕÕÕÔÕÖÜÜÛÚÝÝ{´ááááâãæåååæçìëêêëëz´ðïðîïðz´õõôóôôûùøøøø {´~¶ ~¶ILä±tRNS²ÁÀæúÂbKGDˆH pHYs  šœtIMEã KkÅ‘IDATÓeÎY‚0àáªHAX9価üÿ_趦‰Æyù’ÙyX8ž¾¸ ç"¼s"iBÈ8y<’T¦šX}'ž”EN]”UUòÑÀŋꦩɢ‹¶ëZ^LÑCO`¤iž'^F`¡uÛV²èb?Ž.ÎÏG@ý|ªWËr^òÒ(yª4ÿ$n%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/resources/view_zoomextents.png000066400000000000000000000021051440571307300211230ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFPLTEÿÿÿv¹ë%^Æ-T¤)€@«t¶ç:™l fDp¶énµéüýÿöúÿ÷ûÿùüÿ÷úýöûÿüþÿoµéðøÿÈäÿÌæÿ’ÊÿÁ_dmY\bX_i‰–¢ÂÞóñùÿêõÿÎèÿÒêÿ¶Ú_dlÅÆÌÿÿÿÍÒÖlqyíúÿp·ëçóÿ›Ðÿ™Çï^biñôùÅÈÌfhnYagadk»¼Âûÿÿhjp†Åçáñÿ¡Óÿ}•©°µ¼ÅÈÍpzƒ©ãùžîøàúe€¸»ÂÂÅÍnŠÚïÿÕìÿaflêïøijpºãùÇûþ±ùý–öüŒâû\_føþÿRTYØíÿOSYùÿÿNPVÒìøÒùý¼÷ü³÷ü¾÷ýU]bò÷ÿUY_q¶éÓìÿ¬ÚÿYbjäèñcgm¿àùÚöüÕ÷üôûþîýÿY\cNQUÐìÿ±Üÿ‚—¦§ª®ÄÆÍ_enÂâ÷íøýôþÿinrµº¿¸º¿P]vÌéÿßñÿÖçñPTYÜÝãÌÏÕlosJMQijoêëï:mÌÊéÿáòÿâóÿ¨ÈÙ§©­ô÷ùøûÿ°³·RU\Ÿ×Ìêÿ4iÓs·éÍíÿÅèÿÇëÿÁãñw€‰KLREGLJKPNR\'Gœ¦Âÿ•ÂÿÕíÿr¶ér·ëtºïv½òw¾òv¿ór¿ü¤»÷{’×§>Ñ©tRNSê)€{öîKõÅ/3?CNQR'_ÝÁ>×@.bKGDˆH pHYs  šœtIMEã KkÅõIDATÓc`‡1F1 I)ii))i)Y91 €¼‚¢’²Šªšº†¦–¶aËgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“8©IDATxÚå½{°dÇyöûºÏ93s_{ï>±€Oˆ•ˆ’¥“…MIV,‘NÙ«¤*%+LÅN¥¬¤ŠeE-Y\˜‘cÇ éˆT%¢œbL%VPlFVĸôÀŠ“4 R¤@‹Åîb÷=sgæœîïËÝ}NŸ3g ¦Ù™{ýúÞî&¼ŒË… ô·nÑÅK—Lóž<þøÂ—Ÿ~úôxýÆibuv<§ÂðDzê0!±Š0óH[”&·Ò…åÛ¹Ö9sæÚOœxžz¨ßlã"¹xé’ áÚ—>ò‘7Œ66Þ2ÞÝý~ŽÞdŠâÕ¶ÈO&@–@`@ Dª—€ä? ‚0HAIvKgé·²^çKîòçï9ñoßðS?õ"âFŸÌ죸;ÊË .\¸ }ôQ†üW?ô¡Ú¾ùü…b§ÿÃÅhôÆn¢ˆA^ca˜a…Y BÊÁ\˜@Ê×ÊD(ï‚ RŠHi¥ÑÑiš@%c!¨,ûZº¸ø‡‹GŽýÎ÷¾ë¿¾Ôèãˆ#¼l ¦°/~ðƒÿIÿêµwñxøýÊ ŒŒ„`R€ˆ-€(MÚ‹Tw¡ä+$,@”‰‚¢$ ×í@’6;¸|üÔ?ùwîïüo;ÞíåeaB¯<òÈýßøâ“ÿ,ÙëÿÐh0Â^‘³"²R$¬D  Zêql 0þ0t9¸Dõú˜E”f³°¨^šèîÂ"Ьóä‰ïþîŸ~ÓOÿôŸž’KÀ]w=È… š}Ô>ó/þÅ>ýéOÿ±l®wûƤHi+Š•ša 1£ÇEò$/î–ŽÐC$4µZ!"VDx1IR,¯àÄüÈ÷þÍ¿ù/qpW#€ˆ‰\¹rôúÐ×vŸùÖñBë@6Ûèf î²±)¼€<‡ö”:Éé EÆœªã'†¯ùÑ}Ýý?ú£Wà˜Ñ>òçÎõ«xéÊÃ=¤àð¯ÿ ÚÙ<>’1 iýñ_NÙŸøpüa€YÀ?/Ñ`ˆ{6|·Õ € iäÙp¯÷õ'ÿôoÀÅóçïê9Nîtö-—.Ìúúw÷×7Á€&qS ´Sì4¿ÏÛ^Le m—²(µ½½íçŸ#\¼té…ué%.w5<åç9Kt–ml`7I±rd±Ì&/Ä(ú·àl¥òD&@ÄSÿ’êO"Á`0ÀÖît߽鞿YÊ]ËžD„Þzÿ%tìI­ ŸþÖ¯?Ñh Ëa1¶ËâX96Ø:Où¸{%ëgÇúHˆ>e=® Ëk]»Æ¸ß"‚"/pûæm|ë[—ñ¼µH– üØý÷'"r×êZwzø¡‡ô¥K—@DÀÐÍF½¥E¼’×¾þg¸¶¸ˆäô,YE7ëJyVàu-AÅàmûÉÖ8ïÓ#HÄU¤Æg²™|„íܼ~ƒÑã…VÐéõrøØÓO‰}ëüyzì±Ç,Ñ<ÚéK[î8f ?ué’< ”&“<öØÒãO<ñÖÝ[·Þqrmõ¯Û'Ÿ<6|úëbö†´¾~7ŠmluŽOEïØQô–ÑëfÐ:…RІ&ÈÕ¬7Xxë¬ø<"9eamñ¸ÀpÐÇÖæ&Ö¯_ÅÆÆMØnÝSçôdå¾ûè5o~p»»·÷-œ8úÑc§Î~â¡w¾s+jA_<ž.^ºÄ¸ÃÂBuñüyÕúSßœ‹÷\ºÄtáÛ†¨‡ÏŸWM¬ÿæ?ÿç§žúëi¸Ûÿ«Üßû‹‰Øc’çr±–”æ´ßOV†C²·oÁ®o@‘B¢ˆJ)€€Â2†ù»{l›-ìZÆH€œSðâ*Ðë²(MDƒHûÀ7û˜!ÆÀ[0£!ì`&߃…7ýH’Ž@²$ÑR­PX†µÝÕUt×Ö°²´(«+«”i­²‰NaEv{K‹Ïz ÿ÷ÊÉ“ðcïz×31<.ž??Á _¶0 èßøÈGî»þÌ3?2ÚÜü«ù`ðÖa…ó1FyÃÖ€ ¥„DAkðí èÏ?4ëBÆÛÈ’.: Ë[(­‘d)²NY–I`ŒÁ¨(00Çó¹œÃ ²á%þ Ф“ôP$)L¢Q( À€`°(I0ÞÛC>"]^Ùâ¾çÍ8~â` ˆµ0+’D% iŠN’b,wzŸé.-ÿîÚÉÕýð»~þ«ñü]’§y´êâÝÐkáÚÇã7¾kpõÊ_.vvß1ì½µGèÚñ#SÀZ1 @”R$p!9òœY+ðæè _@¢ªÈ¡P ·|D€&B’¦ÐYŠ´Ó…NSè4iÀ–Qyž#ÏÇÈóãÂE ¶°l`DPˆ€A0 R° Œ‰0P(à€n ° XR€Rèo®C”†ê-&ǹÄÚñã€5H@H„  PÌ¢«D µJzI‚NšÂ²•diåsÉÂÂï-¯­ýÞøîw!ž×ó@rG¦^¸èœRS ~|þ×~õ[77þÊxg÷ívoø=pšç†E0rqwš?_J-^D Zc¼½ý…/ Uç é£Û=‰¤“B) Ñ$I§ ¤P©©Ä™oÌ(Ø¢È Š"÷ˆP ·…µ0 Œ°£nD0,(È}Œ|å€U€‚(ÃýëÏAYu ¦À™ÄÚ±£ ËH$ä²O´TišY”V¬&‘´§t²Ôé|¹»¸ð±ÎÚ±ßýñ_üÅÏx«¨B† ä‘GájQ.ú€.6"^Ÿzÿûߜ߸ñWöúý·ó ÿ–åyŽ‘µ` PÎ&ö8{PÄ<üÙ#kÑÎ6ô“_DG ’<ñ‰ZDwù4:ˤ)Ò,ƒî¤Ð:Ès0LaQ˜Âs€EQ`l, ,[ä°">ÄQ¸ÂcC(ä`‡XqÏ0V †Û›ílA¯õº%¬®…bë89›[H"$Pä>šEÀÊš$K3êe)ŒR<.õþßtyíwϾå-Ÿú¾Ÿø‰½Ο?÷Ò¼œ Pª ôO¾ï}ß7¼~ý£ÝÝŸ@>~°#Œ|œcl-˜¨PEV”hEÂ2Yw—g¸¸ ‹@”Æ^ü§_À’(¤ùÄ{P”"ë® »°­tš"ídÐi •¤€Öf!@Ž"Ï‘ç…0Æù…µíe;‹¾…ÿ0‚cý©I,V£"ÇèÖó`he èucpúÍbuu ÚX¤#€”œ@Ã!‚  àÂΊY´R.ô Vg*QÝN Ñ ¹JŸË{Ø]^ú—ïyåŸüðOþ—Û1QÀ< äÌà§â©U}úý£¿Ð¿}ûí£Ýݧ|ü@ÊŒ±c±":5è¬{—ò÷#F®Ú¨À[­°×ßÅèÉ/b‰ÝÜ@›>Ê T‚ÞÒ ²^:I¤)’4%*Ñ®Ë(,Ãcy¼(œçÈGCÖ‚ IR ®€_ã#8 ;ö¯`X¥Q˜ÃÍÛ0…A‚^]:]°58ûàƒX]YEb-2å@ ¼84Ãq¯€ÑoŠCY+Vé 7(­”îf $0 ›´¸ðGÉÊòG—ÏÜûGoû™ŸYŸ‡ gF€üÿüÏ¿éÔxü7ÌÞÞÓxôzm-FÆ Ès‘$5 PÄVAéêep‹;=þ8£X+þ`€Á“_BW ºEެØCG§HU†$I‘õzè.,"éz u™Ûg…a ëõ€ùxŒñpŒQ‘؆-rk`Iƒ³¬Vø ¸’ÿQN0ÎsŒ·6`¬…‚@˜qïƒßƒ£K+HØ #Ur€ä俈ûFRr^ —ˈ…VaVÌ ¥Hº›¥Î 6u§óX¿ ÿçþÍß{Ñ@\ø‰ŸúÞðõ§¾ù•RÀ‘Ud KÜí¤V)¥Ä%JÑ„ƒeÿzkÀbAàÙ?+‚B+ì †ØøÒ—ÐµY^@ç;è¨Ý´ƒN’"Ó ²N†ÎBiwÁ)‚ y[ QxàmÂZŒ³ v +›taÓ¬ÖȉÕ+ `åÈF0{}gBÁ@PPG<€ñª7½ G—V²E QTxa$Q‹áö:²#'°tæ>¤JX¶Î3ª(שּׂíaÆr0ˆˆPŒ6™åQ¢U·ð˜ÉdZáìò1œ‘£ØíáÚå¯âÙ§ WOC÷Dà ™gaå˜å,î,qI$@FÀ²¿<°ÀHè…N d†‘ u7ø ‹óÜãbú6%°€õ9¨Î”ƒÝßì\ÀžÀ)©Î2p‚k…€EQXÑ„]J Î ˜D,߉v”ÞÈC ²?çØÙÙÁí×±qí2˜RôÖNàè½Gf°­8-¥4ØØñ`wwσNî–C €¯àµÌƒg’dWƒV HjñVëÒ´V{ Xí-âÕ¦À­íÛxöÖŸãz÷$äôY,¯ÅBoZ£Ìµ‹ëÔßÄå&©ÒÈ X$‚VÀØ Æl1Öc$è M²Â"ÑŒ„œõ©£z­Ä2˜­Ëíc— bÙø¿á’Jà‘@†lQ½@ vqqHà;š°BŒE!ôèˆãBZÄËûʼ£0ôÈRŠË÷°±±[מCó&’•cè¼Y’xl¶N;/CÖ@*"Ý?š¦ýæÜNïLDèI?{þ­_î>wåõ#°TKk*ÀE\Þ©;ŒíÑÏnãÙ‚°sê>tŸÄ’ç €£Lñ¥z»ÎR›ç¸õ¯c¸ÝGa-òñ¶sÚˆ³ÛÇX'`‚R ­RhR¥V]ÖÉQ&G‘Â!…lL ö2Þ09SÔS~ðOvž)Ç™4‰Òè,­¢“¤XìuñÊ×¾YÖ‰Ôdz3­üšƒ¢ÈÑßÝÅúÍظv†Îê d½.¥BzàF5à@,¬JŽÿó÷~ö³oô®ã˜·´–9@€)ÙgßöÐ@‹@<ó *ý$ ¹'Öz X뾯µnl߯å[Oãz÷äž³X^]C§·Mä2s©|”9ú!‚@C¡@B ©:°0…ÉBÆÐM%^¿P!ÈsR@Œué`Þ7!¥FïÞ",¡»!!©KȤàDN0÷zJ!õ²¿Tâ"à!‚Ñp[››ØxþvׯCõVÑ9~ Iæ•@ [²…:¡3‘ ¢ Õí ¢¸Á‹£.@ÃáŽJ¸,¬-ŽÛj ƒ° £¼êÈqÜËG±5âÙ+OáÙož?y:'O`iy©N'ÜÄaâ”RK'7Î]ìf”Ó´Ùƒ˜ÙxNYÀŠcíeè—e!„ P‰§.ªL97b_‡RN:v®‘ÂyøåW…Ø2‚Á;w¬-Ðß`ëö l\»‚"#[;‰¥³¯†&í€nm`U!ãðÃTšÀŽövKÜ!ÁdV+Àµ•e›š&-VEÕ# *ÏN$6ÿæ Žö±¶¸ˆ×nì¬ãòí§ñüÂ=à“÷`qu½nšÈ+ä'­@‚(no0.‚\ nd ‡¢BÛåï»Ü>Qa)ÔO-m,²LÂcæK`ÏÞÅõC9kJüø¦ ÄµSŒ‡ØÙÙÆÖkؽyÔ]B¶z‹YZö­xT&aHQ‹¯ÇE ‰Tº9å‘Ã#Àþ²¤·¸=­u„ˆ9C}2A{U{!IðêÕcx¯ac8Ä•çžÂåonÜs/z'Nbii ‰vÖ2) b)UÊÓÒªŒ&*DÙ‚¥’„<çÈà°ýòu§¦ †;ªJ¬àéD•Ža‹AÛë·±yý òáéÊ ,œ}5tà26pLP8©ªMª¡_ýY@)FÚI·^t(Yìî¨r=Ýôî†(? Õx•”åR®‰'q|q¯- ÜØ^Ç·n}7NANžÂòÚ²•Œ76`GC©wÑ‘ò”GBÅ$º.¥¤ ¢L¨0A÷(·$Ï×à93´",Yç¶··±uóvo\¥]d«Ç°rô¤CBnzÇêu‹Bâ±ðÃb½î.œpéÅB€÷¸€¶¶Ö)É· ûÀ(.=Á%@ÜKi‚•µ“x%ÃúÞ._ù2.CcïÌ+¡ÖÖ û°½1{•xdr.o  Ü!dY ‚Ù¹ K{úòÊ@y_5ûÚ6>Ï銪ÛÃÂâz+KèïìàòŸ}ãÁÒåcèÝs’$ò«ËãdóióVgýR»Þ6É""”$°ƒ½Y`3„Â+Ë›¸q4ÊIÔÌîæ‰ǃÐ%7¨´oËš€ÓKË8¹´Œ7äc\ß¼‰Ëy‹Ë°K+@žAûã­sUkÂ3Lñ¿5„l è@{*R8Å ù24Ý€¼L ±“×Jg謜@Ú[€aƒWžÐ9rGVŽƒ¸bó­J\Yg¥ôÅr?<;i´Xi¨LÏžUpÍt–vÂDÔÖaP¥N•©H¤ý’èY áHÖÁ‘ÎI|—1¸5âÙá.ØÎÁ#1ÈŒ l•”ü?Lš¸†óÿU“»ŸÐKe°¥¿ 8ï­;P‹‹€"ä\`oë(é ³¼ŠÅ#I5ÜÈ%=u ¼d~<'!ÄTCœÊF­s(EÐ¥Y`Ê\€–¶ÙiÎTëx,ßcD¨…öê¨Á^nAçu˜zÒDáìÊ Î,-ã ùׇ#|+Ïñ<Æeh0t1t? í—w×)=²ÎêrŸ*î€øº_N–ªª³ è#3Ð,®®:¥.¼å}ÓOTG2jèMíøµ¹dX¯öR¯óâ#À{¹€×·6Œó\U»#M±6K@¶ @S¡qS¶ÏlÁyûvdºÚ]ÀjwÁ¹Gc<3à²5ØMA©‚f)Fc :ñîL jrFãŒd1JTÚe=0€‘)PäC M‘.¬ —z‡¯©´ hr(ÔJQ»-×'ĵե@°`Éh´'fÌž ~2<|rm·¸œØ’b-¬0â€ö~…‘‚×Ë}¹Y’âÜrŠ{ñ@>ÆsÃ!žp fñ44AÆ÷ŽN@äÄA¨Ï‘ŽS$Ù@ZgPËk!·Ãb #€îtÑY:‚DéˆE0¼)ƒ›|3P{å`šx¢4a«¹e¶ e´FGu¶àÑY‹ ä`±7sA.Û"xV]—fV&rY˜ƒç°êwÛ÷Ô"“XG¹DÜú€Õn«Ý.¾Ë,ãÖp„g†\Ænojiº0Á6Ø Ý‹:ƒ"@¬…H"…¬·êö`¡0,†Øî‚U‚da½$ƒ&¯\ŠwþH•¨OâP³àËšÈÖÇÀ7‘ Y”VÄ›[„&^4!á½ÕSýdì‚O~ðQ§‚³¥ì §\ÁOð=9Úê'‡ü4ªÞáèñˆÒK¼beg—–°5ã¹áÏŒ÷p³³{ü´ ËŽ÷`Û`3†^8½°¤FEŽþ^y>†ÊzH–BëÊG&à)'y¹Ñƺ›z@3Ú¾8yŠ©Þ©Ôx1Yüò¼à{;¸úänÒOˆ–Ø£«¢ZDÓõm?Ÿ%hß?ÛGZ¯·Œ†‰ø Š»ÏªŠJˆ0´R8¶°€c x1¸±·‹gv6ð\ÚÁÞÒ Ò÷ SE>Ænýõ°ÂHºKè®,Akí7•´­úå„.y#%öpN„çZ1¿Uqšºå‘ˆ""ˬǻ¾†™6%˜Ë xã¯?2¾ùü{}½½ƒ"ÙÇ@Ó.F. iåìSõÆiüŒ\ºDÕP@p¹7Ò¯^=Š{WÖ°5ÚÕ-|sã®ê[ƒm¨lé :Iæ“P Ÿ©ï’4šÀ'ŠúLû*}1˜@‚–9š¨«ùBC¿"*Kû Îh*ZÊL;„#¢DåØ_‰aAÞO_—âÌ;’ðí¯Û7ú¸§Ëœ™ÚÛÍ)ªÝ§ˆRCFˆà‰œX\Æ÷ž>‹·ß÷*¼.I=Å#G‘&)H,H šT™»¿ ÈÓ€¿¿§1Ë¡¯3ƒ~w2±€Õÿo>ð±¿5“0Ï1ž¬dWOjNµNÚÁ…ËIl6QÉ]©€O“ˆòëÂj’ꞈã –:=Ÿže=â¸}&ê‹Ûö†vk#&ìoÿÇ?jÌ9IM¿Dlÿ3cÐÌ" „€ÄÚ ¥8ߦ°Ð¤&_iµS& òµ7Ù#HM¼³M*5'ÿF³RÔ/ 꼄ƒ᳃çPQ[5 R ÛŸH'KC44™þLUG"@‰R€X q…—‡Í½I”^=¶£‚RÔð^¨¶eÊÀxòZí~Ë,Ô¨kš%~]‚ª‡PA‹/ù2AíS Ò[qÛút û·e S½è2ÛuÕ[Ü>°¹F™.ç…·+·%9¹Mœ–Šö¿½úqîàþŽñ}ç)šhšøšÆYc >NÐÔ˜Ò¸½f`HêA¥ÉjIŸ-uÆrõq| %³ÎýMÕ'ž&w-R}“dÎÏ!fF€÷øo¶²EJƒ¢Ä{§ÜQIqÓÊĽ Ì>øÕ¥:åLrªìõ–aO³T›¿kr¿Ù}©H³ªnÔ:–‡[µ9q“ÝÎFD°Æ¼t mímQ) .=3y;Ûk F’gP|Z¨»¤ù_³!jïÓ¾²{àÇe^w’é×]¿óÖ§¥¡ {kÎWçG9s|G4Õ&·š±ðPõGSOßuàG&ß rÐõøÎ¤AY±êF—Zë}!ºÞääí׆´Þ›Z¾s!Z]yIu×w¶k0­»ÄJí;Øý倨zžjƒU­ÜÈkès•}^h"BÛ+%BÈ|À#‹³õ­JX™×ƒC›P7+ ̧¸vFƒ-ëb«¢õ¥(hŒµ]6·7î†Ëèü;ÙÖÞh—PͤƒÆãûÊóì¿Vd˜˜ˆfÕJÄ,˜€›-`öP00‡ „„5ëÍ‘KSŠM®ÖûEB·}žTþ|åSašñ’(„X¾Ó:›Õq/aö[±9#5.Dvwß²ï{S) nÇÎ ~tcÀ;”'ÊM`öPp}N(wðëÎí‰R¢Zû\r™r ã‹®#Ô²§o„å­ ïz'OLø$U׬™þlkiP3s¨Fù%™Å>8œ¦!är)b>z|%m73˜BG徯ŠZ€Y>+NÖ“Ô®Í2î Tø¿¥“íãk>7Ï´Nu¶4½=³Ö/s=ý‚ ¥ò¼»2W(˜BZÝx8Ü%È@‘RÛñ¢µsÒ¾vlÿ€n5vÎ4™Ë2ßÛSïE>…–O|rÈdEsBæ*n?bÙS;;e(xÖ÷çÖ²^Ýë ¹“í*âÖVö¯p’õO¾­0í¨àT,?Øß};U·žFíSzݦ÷µ½µ¢ÃZ÷³Ài²»³¸¸·ß8ÚÊ<"À‰¶‹sÝYh+±gs†2ø•”äúµ–lãiÓé·0)­ëm«ƒR‹+xöçcçï‹_lðº$iÿ=þð\¡``~àW,»Jé§§ûöë¹*_Ù×±(Ó¯…eXq{ûz g€¥´"ÁKS|wú~§Ð¹0m.(sÙl(M CDú÷OÿT½oæÌ2óÜ«;µ‹º„w䉎Ù(]›Í÷f¼öÙKdåªà¹Ê\ðpàl'höUñÂŽ»˜E7§Ó¡šœÙ¢n­·´ƒI<ˆóZï_ª¼‚±p²ÓûÝ=T’nó…‚9 „„)çurkð|¿* Ÿ㤟€_ U´*Þ“!‰êijRv½·î:×Þ£ø¥ÖzgPë]ØW4ÕÔYCÄâÍ@½u˜¹<ì©a¢ÀäVÔ ›™HM$h7ó¦ãbsÑI¸Fm F?B ¤Õé„:­ÓÊŸêO˜bÎôrx¾ü·†²3Ù^ñ%V)Æ·qˆr(@VV¶9,Ÿ(ÓÓÅÓˆ'8ÀA„ؼìÇëUTÙ>ÿ´‰œxh°-7¡Í' <Ñ@ƒÒë`n~_këC…< ´°0w(˜“„°Qé …§ÌQ;p ßxâîA\`þ³.>Ä ¦åANªªG&¯53_ëY=~]CÛ˜1=FØ\_@D‡B€yuçoŽÖ oÿü"çÖÂò«yK›,%Db¥Ùÿj7A¤U)Œ'nIëïÉžL^e &Úæ s"@ —ôN®S ‘˜R̶}fmv6Dª?Q£$žþè»F¬4ª}Z˜¬-ßµç¨ýÝi ÔA߆jÓgÅZ(@{[À|¡àÉÑPBHxñäñ¾UʈR4¹ÛMû–[Yú!Kŵ™"ó§?>U·5Û|¦õ¾¯tÒAÝæ²¦‰;ñßZ+bk9[82w(˜ʰ؈ŒÛ/©\DÓ&ò…š„“ó%ûߟøƒ'®6ûº v¨ˆ#q¯™CwqÖºWÆ}Œæó»‚i¾#Â}­Ë´+uñïÚ~¢µ¦ëH0ØW Äeª—Nµ\›ø9µÊ&•Ï’þQZ3xî++ h+•u IÄgç vFÛs‡‚[F?[ùÓ…ûÆÒÉúdÙw©úFù{–žÌšê±ß´¡vânñÚ„pví¡Ö´§K̬¢6MFn|·ŒUj ’Sh©Ÿ,Ÿ›;¦læ¿?yñb.*x‡ŽÄ«$W3°S5UŸ¼6$ˆØ2Mù´Ê“yf@5*‰X~ÙO¬†•ì“GÍNöRœL|B>AøÜò™R¬—¢Ôà×~ÿ÷ó¨É™Ëa<^Èó.)5éü(aÀWæ+³8‡ª ÚæêàÇ}g Ï⿟Ù}—æ Ú"ÎmJ‡‚_ZP†„­ls ·?©%Š5uÔXð¼Ê`¹QRø=ÓK³6Ò„Ùg}V$’ƒ> Hˆ¯ ž«. @––·!Ü¢ïÇ,#v[‘8  IXbDˆ7ë=`R÷{fš`Ÿwb„ª +Ÿüø÷~δiz‡ÕzîUÁ¡Ìï 1ÃMVìs¿ã޵sƒ:g˜tMr‚òÃSäƒÌ¾6Õ¼¡~ïã/zIKp§=³RéV+¶ÛC‹KémQp= ÔD„É3qR7hŸt®ýª!í÷ø ýK åÐÌc?*oCV%þ“ÛŸæ^ÊaDÀ®Ù¶^0†CÚÕÆ &õ R UËšÀijf¸ÅSÁi›GÁý²ˆgð¨L ‰‡v9¾¿ŸUõñÞ¿ªÝ,;T$8|B õv8m¨NÎ,“,µˆ{#%ÛGÛäÔ ¨ÅƨFž WI"m‹[ÍÆI¼û;Î&Ù¿L˜Á A›¢W¿6¥Oñî˜QýÎ'¡‡ÑœÌô7r"[Sv8I3V Âv*ˆäz3 RÓ $v•⺃‘¢¾aR7 #nP²‰©ýªDìœ9œ±¾ÙO±sßý;é I"ÂÕ|Z±d`;Þ€K‡js#@ K·³=" E`wø_˜< §t5†|°µ=݆à = Ž œHàÊkXN`„Œð‡nNÕ^<$˜Fõ1ðÛt§v«ÀͯeTA B²yؾÍ!$Ü;w¦o ;¤ÎBP÷WKD^©â­”ËØ˜4&t µ;ÓuÙŸdâõ_‡@ˆØ¬”rœÍYŠÕãŠaÅ›PÕºQ^c(¥©0lGæÚ :.óë~ãè1údy¤¥ñ®[M@W ˜ñ]ÂSœØ5¡DËvJ½ ε“è倵ï¨ö*zr¨Å›"õì)ÇPÏî›ß-kèšÈÎë%â4RA¥a@ÜNac•-íâe~3ÐkþfaaJ…†þ¿¦EË´ú½F‚vÐ&Þu§uÔ¹A51á»îY¨H¥¬£9óåùÅQ ½1¦ð×~öüäYC“"¯¤úÆøBЫ¦§ Äcqݦþ.óî”æ,s#@Ï¿\ZÛ4Ù#nßа¼Îúë2¬»u¥'.MÓÑ}óÔáIDB™RÕÚÆxEÚûpØÒŒZÖÇPŸÐßò=iùÀ†ÓiØ„ë6D»fÂó—Ã8‚]¼xÑ ÍúðúÃÆ"BqÇÁí‡mº4ä KnÐJ®uway„l\AC'hóï‡5êm Q7ú_YKû×x®®ì1˜Ø]W\».`˜p(/Iÿ‰'ž(fè~k9”@ü¾Å8ßêh‚ewð©òJ޹ƒžEêþh™T,ûã¬7)¥¨*KuÞüU‰Jþ¸š~ âÄyü;Š* ->1Ëò>i»¸ÏìÇ–e=þÝÃÅ#ÂYþ¾b'ïi²>ÇhË_žé¬àf9¬#ˆ€³Î:ˆ`àNÓ…SD¤T«:Š‹¯ZH †)aÑV„!ß ôxE±L÷® ß˜ê°Ìm”¬R¡š2ÐiAöƒ¸¼xçÃ[…RÈ‘S"º¤.MpQ»c]´T±A‰Û¸±VãípP$6Ã*M…*B¹<‹½¾¡Z²o늺ٯVµ¿¥åíæá“h3c›Šl ð*Ûwà'À‰ ÇA,&77ï,,oæÛ»`/´gm GíÊ+‚@“Ôv×Öþ€%viÍN w[Óéfåé ?*vÍ*à£ÚñzEg”¢#f×uNQ£pi˜s– â§£ú¤ðÐFÉx UŇ(HU—¢=ÿ ár^à*€„ê»tÄ€Wㆺ۔9HýoÀ‘J¶Ç÷CâŒ8öÎÌ`ï©d¬8nPSˆR‰N”äöÉMÎ/|òæú¯F£œA›³½(A‘§N-~0K>¢“¿s„‚s£E©4IT"€V^' ÊTT’ šüæ ^¹Ó¨öÒ¯Ÿú¥ä€ùáä’°ûxx‰TŠOôûS9@p6ûdÌ7(ÅsdÂydªä}Ä8P½CkeJ'ºÏ²W0þîÇoÝøŸ|sð/lg>¼€´ðF±ðE ÁƒŸ¹rõg¿ºg|ž‹?&%¬´Ù¢(ØHÁ@!€aA!nÀV+ãåñ“Ïþ·‰'Îû 1¬×ÚÃuKë­ˆR‘cOm^q k &lmÈÄÌà·šm—+à³oK/×Eeûÿ +X,.ÁVPX#…1”Ö¬½cÍo͘×FÀ×~J^0ðCe/Z¹ä«ë@úO;×ÿÕöîG~`yùk,üCGtºšCHØQJ1©»É«äsðñUVXp˜W¢JÿžÎyAqxV±PÚöTeR€ ¤p¥(ðœˆg”¢\-ý;|…žÕ—fjÅæ+e˜Ë ÖG.4Ì0ÖPZ+­ußÚ¯nðŸ~rãÖ?Þw¤@«šò‚Ê‹%&Ê@?‰…ÿ¹“þò"ÑÏ­’Fas£Jtª5 ‰S¹oªàæ~;¥nšhb]K´$]…kýGé\APÿf0ÄgEÐ%—Ï€~š‚çìr®±úR¾#°~ÇæÛìßù(-<ç²Æ JëdÀ<‹zï'nÝøï}/»ÿ¶"@(ä¢cYø{÷Ü÷À¹”ßw"I~D‰À°)2¡DkM ÚSw⡈PÊy0"8ïce5TǼ’çžþ €Jð©½!>+@—¤¶ÅeÍ©¿ÎîëΧzªg†õmWïL`ëë/؈˜$Ñ©a`ÍGŸÏÍ»þlkëßl?w/UyQE@[¹‰…÷÷·Ÿÿ½ÿý–;_cÆ[Vtz4'"pa œµ ¾*Yw ˆÈ®Ÿ 2(¾Y ¥.@ÁáŒKò6æ³…ÅsÒ >T_¿Áò9ä”,ßS=;VÏTQ}`÷¯ÝC`Ø!­5i½kùéËÿÙ'oÝþû·G£-8v_÷9½Då%ç¢/xÔ™¸ž;óð Ñϭ锌ÍòbÁYN,hE¥'‘"Ž àJÞk `tu¤¼rVCp* :ë áÓ{c|V€ž¬šD€Ø¡X>sSTÀ N ð!ýKÀ0ÌÌÖZ'}ky,ø•Oܾý÷á(=xÎ_rÀ—ù6#€|‹@r (~g÷_¿tìÿLP|×B’¾NA«\L%ä§!ð_òöºO(ò/ òŽxÊ÷HáëæJaq@ª&sK7léŒäy ðîAKŸJg ðËb”Ö‰h¥bÿŸ«ÃñÛ?¿µõ;¾©íË,_Òòíæµ¶ÿ|(à8ýŠ¿v,á|*կʭ…bk´N-ŽÒ~àE%.ªë| ¯b# ƒ(ß!ÇC| ™Ð0 ƒÂG\ÚêA“¯´{”òßFTo+ª7 h"ô sy ÅÏþ›íßñó"Xºww¢ÑF‰ÅBö{ÏþÒŠàÝG“$ÛÂjR•êà4J P€]w$•b`_DP• ŸŽð8º¹biùâÊ®”o½ê_ú¤B †ef˜”NFàøÇ7n= `„éÛ«{'ÿN6î‹|ó@ò P|lg÷±W­t» zuO§¯W¤UÎ^,(Ï·ƒÍᯠð÷ÊgPŃ8ðÑDø"\1×PÙZNž ó¥’íNà©J^ÁVXÄÒ‰(¥vÙþáÕ=óŽÏm®ÿ6µßvßVîPëO,þÁÙ³?~BÑûOêäþB, \¤”¤)œXP$ÐÞ4 ®d§(:s²L8¡*†P*“¢ |f4Æã t0EáCòmÈù“J Ná©ÞXNuB;Ö\üì'7oÿ¶oþ޲ûÖ ¿Ó˜RÔ€¼XH?ðŠ³¿°$ô‹GUÒcSÅ^,8kÁÅ(r Q™t!8”jˆ >;® dÉö¹ÒàYd‚ê»gÏî°¤T:ÂHäýݼù÷ PI¢;ÊîÛÊÝ ÚJ,ÌǶw?~ïjïÿè Îõtò@l-€|J)UÑà ʱ[™|~^œO@¸j-®ùÐ4—®d®Øzü » CJ% ­·ý“õ=óŽOo­Ž“Ý5ì¾­Ü­ ÖÇX,üÊ+îù±ã¢ßwJ§¯7, 1EJIª}^"§$†ˆc°H"«¡¼¯ðÙbŒ'˜Ql³s`çÛ³ùö#vÏ€NUB}co …þãëëÿÌ÷û®c÷­“{§;0G‰Å}àÜ™ÿvÔÃ'tÒÍmn•·ª°r\BŠò#ERÀçFžð"ÀA+PzDù,¥ÿž°l˜«•JÇBþà¯ßú%¸Ew-»o+w«h+±Xàíì~êUKú·RÐ=]}OJZ­) – |^±?gÈ[Bàr¥‰ _µŒkÞ‡`ý5†x§NüªeaÏî•Þµü©£ñ_ÿôÖæ?0†£ú»–Ý·•—¨õ; ï½ïÌÛîa¼ïd’½© .2¡DiMºL=“Ò­¬Ãià <^äø¼(d`X(ˆ°ËQ`ö¹>_±iEýBÖGbßý'¿éûsWËù}'òNwàuÑ} |àì½ïê?|aËÉiCCPicc8”ÏKaÇ¿³(A`f{ˆ¡CH¨LeD宿شmY”Äìì»»“³³ÓÌìš"^:fÑ=*úé*˜“––Í9R»,Ÿ•"t%1)f¨m-’¢ë’ë²%‹ÙÌ*±tìÌ©vO¥žv¥æS¹¼Aç¯ö°õ°\þù¬\ÞzN=¬/õßÀ¼ýE¯Œ°p cHRMm˜sŽò{„Ún”å3'™IbKGDÿÿÿ ½§“ pHYs  šœ!ˆIDATxÚí{dW}ß?¿sn¿¦gfwµ’FÚ+›‡SRÙæ‘»Œ]l€ð(HR²v¥¨dVIìP*¦H…äÛ'…UŠDlXŠ#/•rˆqÙØ½ÀH–°0†2°»Zíkfg¦÷žóËçœÛ·{g¥ÕN³Ó³;¿ªžî¹÷öí{Ïï{~ï󻢪œ.‰€ÄMüœþ—Ó9ç’VÞ«¯ê¾Õ½Àð0[áo ñhçm Æ0Ö*)àèÇ Û}å¸5I+ægÀÆ}ûö=¹Ú7t:$"xx92›¼s®ãœ;´¸¸øø£>ú•ßþíßþÚ#<òp è +™†§q½c;× U€%0¿¼hß¾}ß:Sƒ0NRÕ’ñÕwUÅ{÷çÞ{TuñÈ‘#róÍ7ÿÎ7¿ùÍï$‚ã ‚`+ùY³Òk! IPkšª™˜_}WUŠ¢h·ÛíwìÞ½ûOn¼ñÆŸ6Ä1°2Ωy†h°@5€*ï³G™Ÿ$sŽcÇŽm¼ùæ›ïÚµk×› °¬A¬éI ¬9ZN|ŽJ‚DU‰à½ç™gžiîܹó¶ë¯¿þM @`ÖÆ!ªžÀš¥“éÑÄËQ©^hÜrË-ÿóºë®{#u°f@0¦­i$>=¿žÍÈZ\\¤×ëÙ›o¾ù³ï{ßû^̲†@°&™öã¦QPTßÓ«zìþýûi4ö¦›núüµ×^ûzÖÖP¡QFW?‹ƘòÝSî_\\DUɲ,`ÍH‚q‚NÀµJÕ€Pbp¢Ñø€µ–,˰Öb­e~~ž7¢ªöÆo¼x×]wÝõWÀ›6m»sçλw}úÓŸž8›`]ŒÐÉTÁÉ<ª$8~ü8µZF£A«Õ*%A½^·;wî¼;J‚‰ S¬:šÇEIcðÞŸ`žìÕï÷©ÕjCÑà Ùn¸ányç]wÝu0ÇH‚uð”TAÒóésÕL¯^¯‡µöÙÒµvçÎ_&cÀÙDI Tgóh$pT%t:òÿg!»sçÎ/cÞqÇw|UÁº xž´óÓ6çÜ ¡â“½þúëïQÕwÞyç«* Ö%À³PÕ+ý\¥d¦(a5T\¥ª¡" >õ©O­š$XÀó¤åÔ@u{õ¸å@0¢Rìõ×_°j XÀ)Òrb}Ô Xnÿr 9§Ý±cÇ="òŽÛo¿ýŒƒ`Ý 8Åûª„Ëå Nfü‚`”§"B¯×+%Á™Áº8 :Uq¿ÜþZ­v¾ønwìØq1æŸßvÛm÷s†@°€çAUC0ýŸÞGë–û®ˆ`­}¶Ÿ°×_ýÿ2ƼýÖ[o½Ÿ36^W§@£1€åT€µ–<ÏÙ»w/Þ{Š¢À9W欵4›M¦§§‘2d¼Œú°×]wÝgëàyÐÉò EQðÐCqôèQæææXZZ¢ßï—‹Jª¯z½Î† xÁ ^À‹_üb.¾øbfff¨Õjt»]û«¿ú«¼õÖ[o}'"nÜ XÀ)Шè¯Òh­@–e)Džçe6±ºÆÀ9Çüü<ÇŽã‰'ž ( ²,cË–-lÛ¶ /¼ÐîØ±ãÞ¢(¶ß~ûí@€ˆ8Ætk$ðlUUZ.˜T@–eÔëujµZ™&^nµQJ% ^<üuþá42 ª8ïñª8çÀ' ߀ƒ±DèäŽÙ_ÂE¯}-ÿìÏ’µÛ'èð€¢(èõzôz=úý>Ýn·ü?`¹…¦£•Æési-bQlݺõŽw¿ûÝŽ–¦ë¨ò>ÎücO|›¯ÿþ­´‹œÅ^ŸnQ±m XUŠtÛsüæ“ðŠzO=˘nÔYÃOݰƒ ®¼’"Ï!–§ÙYý~¿”Õ÷Q`”ù‰éË ½ÒoMOOw>ó™Ï¼ùK_úÒßÝCV¸,}¬8|øðê Îü|~ž¿üÍÓ;†«e Š8‡)5æÉîØB”^QŠ;2WÐhÏð?ú[´7oÆEè áýýœf¿s.^¢?AäÚUI1 ‚<Ï©×ëÿí½ï}ïï‡ ]KŠ•à¬¨PUÔ9Œ1ô~ðCй£tÄPsœÃ‹€ó¨†…ŒåäÊméÿt#‚)r°±†¹ù9ö?ù$/;ÿ|œ÷Hô¬µC3¸ñÿ£3=»œ:¨Jª¨×ëon#H€>÷ô¼iíFã ¡ŠÉ2¨×hMOsÑÜñwÿáø›ÿû%¦6Çe?¹Ë^õ*.xéKi4›dITç9^ÕÄrà¹h@’5ÂìÏC'¶É”ªa¦‹`¬-gzÑëqä;Çþ‡ÿšƒ>‚=†ñž¥~Ÿ¾’YºyŽyúS¹Çoš¦Y«33Ýbs«…±aÿÜÒs KÌç}ºý‚®Wz5¡c-ÚnÓŸ Ìó€,,,"½óEÉëdEAwß>òÃÏðý?ÿ ÌÔ?qå6.}ík9ÿe—Ó˜j ‰n¼b¬YVQŸ £Ò ²`%µåI}VD€$&Mœéy§Ã3ûûzˆÏ<ü0G¿ù z&ã¢W¼œ _õj.~íkio˜n‡œôþOöž>”¬XçN”¨Î!YÆ¡Oþöá |gº‰›š¢U«SœF³ÝûÀ|RfDQ L+ 4ÂRÃ3ƒ¡Óï³´3Y½N//XêöXÈsŽ{Ï’wt:=ú™¥[«Ñè¨Ò- º½.}yä™2ïÉ £ŠQAŒ ¢8¢J¯PzNétŽsðÿ}™î½÷²eû?ãmÿþ7pÑSXŽF;•=Ç1¤Ù+5­ˆp^­Æ˜ Ë“ Ͼ fÉ7m¤ÕjÒƒxG¡ŠÚÁ@úèÞÕ½ÒA8*Ê,Žq´òœöÂV‚î9OW=]<=#tÔÓ/ zy—®B¯€ž(yfÉQz- ³@K=u爫¡¡zÃŽÌ€EPï™;>ÇÁ¹9Ž;†`˜¶MOw°#YÂçbzuû³•žM” (ox¦ÝØä|+\°Ôgá{GÙÇa¾Q‹Ã›7ag¦™ªÕ°^ñ2ˆâe p@„ƒ®à˜+hZaÊjÆ!IÒ÷Ž\<9Ž\ Ç”ÌîfÐ5J‚*3( lRÏ”WjŒz2ºD ßÏ9t|ÃGr|q#†f½N­^£á¡ÞnÝãÉÜÁå@°\‹qÑDI¢¨m܈|áñVhÎ4¸\„-G ØÇ÷g,?:ý³4Z-Æ”*u4Îó!NÚÉû, Y¢%.HL9¼Î‹ß+^ ˜V¡f”º …º`{d&D/u927Ç‘cGÉsG­^cª5…PïÑ£"LoL9 ÀXËeÖòb_ã5Y“ïç}¾MŸЂ>JÍyê]ðÖãˆ=ï­E­ÅCn ÞZ¬Í°Æ’IH  >0rÒ£%ã2Уhì˜zk ˜¼µ€!ÓV iµ0 }¡ÔŒX£Œ–¡©äEÈ4¸ƒªÑ-S#œ'–ÍY›+|“ý.ç Íùžui(5ï©©‚ÍÈcÈÙÍ«[Ü5‰”A<­þ|bþ@ïCH-{ ö@ÖhRk…núælÀXÐ-‚i5V kŽá0HáQÃÀl‡R C @0Õ0kIx°§!†—Ô›\F“£Î±Ws¾Ý€Xìåx V,u#X¤[`¼”§¬Šx¥j‰Tˆ¯'¥ëší&­V3œk\ã4&š, ÉÔêÈì4VÃtã°Qg ¶A<Šv`T$…p ^”͵ŒÍ’ñ“F¸«;ϱÌ2˜£ÁëHÌD†³.C¨FeG=AjŒ*Ys Ûl®ö°.K“€´ Û²™i2ÄÆÙ¨A¬†AïªÑŠî‡‘:Ql[3y ™Õ˜²5D‹p>â,j„ï³?Fj±R/Ö™)/E„ÖÌL¹d’f?L  4ˆíi2¦&øh#aÖÉÞ~»²É$Mô¶>@],1£h*O:MV}úAÈäDë]  Ë Ð°/V‹B}fªlD=îXþJi²$ tü¦Y2ıD]ì%|6*Š1•'8&†ÄiiÊí1OØæM2#•rp–´t—48¦B"¥$¨º¡ü<€ijfC¼µIs'pm`ªvv&ÎLIQDc Ht`ë!!uxÉx’ÛmÚ_•ßé£DPUC°•Šát®¸¯þö@ì'#o”š³!$Lž ˜,yT¹ ³aÆÆj^Ñ2ç®&Lo‰aV£>†¼£,f'W.}N[“MDùpOÀÄõJ›àð­ •æTÚÈ0x¶¬7ÁˆhE 0‰4y* ’ÌÎ`ãì‚`0ëÃLµ?-‚FÀùŸq‚ŸÈDë.A"}ŠbÌðì‡`Ì™Š/I«¨ ­lnÌžzàLÓÄÀlÚ€3 ê±!/T‰F6W /Ô”V¾x­˜í±t« ×Dæ”âžAôN?#ÑÒÂ>ZåxrRéVZqqjÃØ%ÀØŒ‰‰S%Í̆¿jX¦5u©L±àëc¢åvi’!FŸn¶?ŠÇ„ï1>鉧a_ íÆŸŒù‰ÊËô¦fgV{4OJçz‘à¢m˜ÅYS.í’QæÇA71R'¾¦M¡”«Òö@PFé[aØ¢O ¨‡OGî7’*c¡±R©µaã)לiš8 üi3=MŽ"¼˜0ÁTMZhÉ` "Â+³1Ed4Fîª\Œç‰R¤Â›„±2FRÇ:ø²f¿rZ¯)ëQ¦f¦ÃµLóa‚%€™™aÑNƼ5'¸eUsk°‡¸Ä;$cLðÕ•Œ)uzÊÞ …€‚ˆÿ§|@Y¬ ÅÇ@tHg ùˆµ–ÖìLt-Ç&Î^ I™nSXbð"ƒE2H¦º|edÙµ×as!ÎÈäòIò†«?†¾#£¯è…$›1eC¢žÀ‘ô=‡RoOf*&¥²o5ðÍ:6fô’,N=˜:’𭆄#bD¯,ä ¨…äÂ-çÉ…èà°_' × –R(•”WT`[M­áŠàI¢‰SñD˜f iµÁ̡¶2cÞßÄ‚ P<†Jl8¹kQ6‹ ,K. È ‡èì“Ê5”¤ÃÒ¡j$–n•¡^±&Ø*õF‹F{ê´ËÁ~Ü4¹q€ffÚ¡XÓ„âIºRÏF¶ÅAõe•V"ÈZ±ª ¦tËœ4O+ÚaØ„`¸ dh§F; êœlºM-ö.˜DšH ª` 23M¬«Š|?QQ‹È `SúþÄÚ¹²«bÍÔÅP®¿S8!Ht“*¢ˆx(âÉêíi²¸žoÒf?L"ˆ)aÀ·ÛXÌnÏ`JX˜„x(+~Jž—‘‘÷U;¡üÅ’ÑC^"Ãy„ò;š¤B¨.&Æ ¼¦¢Êècc:€~4©°2:{½€p{1©³qâ¢O_¡Oj*êHÉ$FÔë%”PÅ© NC@½´Ä›aÎʶÁHì…2þŸ€UQªUH. šššÜT0L¨˜RÂfü†Ù*s‚¾vª!QD¨÷ Œ1hÌ âÃb/©r(xêâ ÆR0YïñO%ÒpB¬ 1ÑT%A08ª±avbSÁ0¡ ¼¨Mq¢8k(—‰%=¬p q| þ„ú€$qÓ20ñŠOT…ÄêŠÍ¤œCeaRI,%Q ÀãI¢_Ê^¥=þDÐXib½™™¡°BO•ZEÌ:ÕòÂCý_ˆé«xDM¿q§ñàmò S(׸°¤<Ó@ý”þ½–ÆÞP´H5E˜Ë€T§0pP1­ç±$l5h2U@ sÞ&zE½†Èø¸ÄËT¬p_füÂJ¡ÔÌ0¼ˆ $I…p.õ>x¥K¨¥ Éµ¤Ê\Þ_R!# +¬)1µqÓÄ&‚`Â%€™¥‹§ðŠJXû¯„Z;„°V@‘ôQ.›¨ãAÊã4†îT…L’˜Ž Ž+~ªÉ^AE‡²ƒ)Vì¤RÄãÛÏ0>×$e7β †¾wXš¾,´ðYãÒ¬0‰1FÃJ"å䢸¸B×h ).%w”®Rè ˼Ã!ƒ’oG%Ž€¢62_Ãõ b¡~ ƒL¦0á* Û°9Q¬†¾<ê=N„š‹uaÊ“Il§± ” ’ ÔšdøÅRb/J)ØMtÝðq¯Éñ«&¢ái´42½†í©w»×ЯÈ{Ãô¦† UÕŒ`GÀZC­pdF¨yÅ¡4|XÑ›V‹Y#Aסa1Htâ*ñß´|ÌhdƒÄ’–î@ôÛM²úuà. ¨Ò"F!½ ñ ¯GŠE¼(Ív¨šDæÃ„º)T×~Ñ‹è¿üeçXðJÇÂ’(}` ¥‡§§JO•¾*9aÖ"xZ¾):çƒqæbÉ£¸¬u”î\T ..JIÛ10%P äªô'w¡·–Ž÷êÙòê×pÉe—Æ[+ÎòH`,÷ª5lÿ?÷2ýkÿšÃVÉgɼ@ÇBOß{rÂÀ¹(¹(… Ížœí|h1ã|á>J‘à‘Êp–Ì&Zõ)æ@’ÃSx‡KŒ÷ŽÅIh'×Ísrcù—ú ÿýï¥Þlž´Aä$ÐdJÔëu^÷áð¶¯þ9ü“×ÑóaÖ-KXè¡ÿoÏ{ú(¹x ñúQ*„\A˜Ñ¡oPšùÉxs„T®÷©ƒHú8 Í( Çõ¼ÇI<…=çȽã§ßü‹ì~èþÅM7L4óa’efÐå9ç¿ì%¼õóÈ«?õû,½ø"´(XPèg†žzâéIhñÚ'ÌÆ„0ó C ïƒ*È£{™|wDñQï§äNPÁk(Tɽ'×g N (›·\ÊG?ó‡üç;ïà¢K.)7É̇Iam­Zº9Ç?zË/óî¿Êÿî&Ž%wÊ’ K]úêé©§0¡ID%BN°Üs‘ 6‹dÜùâ V¼BáØ˜*wÆ{#äÆÐÏ}cxׯÿ[>{ÿýüì›ÞT>$bôÁ“Jã|dÌ ‹¢øÊû‚}Q”¤ŸùÞ^îÿào±ð§A]ÁfBÖwdÆP‹½üjŒ ëôC ƒõ`l(2ù‚Éù®-ùôL¶Ø‘ŒÊ :^!³8ZËüÔ5×ðo>öŸø‰-[ʇ?þ¸)˲ ü8,¨jÿtÏ5ñà„ ŽmV]žsÁK¶²ýóÀOú6:[^ˆw°d„¾5tÐ÷Jß(=õ¡¨D‰`*Þƒ„Ñ Ýœö+ýøÝ„N¢…ó̼èþÃwð»»?ËOlÙBžç¨êaþØÇsµ/àt(©…ô¤ŽËßòfÞóÐ}\ü÷s4 3µ‹°d„޹¹úОÐÞÅÖð>Ù¹W õô½’«#'u¬ÅyOámïÿ5v?ðoøå_.ãR«Õδ®?ËÝÀS½xc0Öâ£èý™ü:ïüú}d¿t ] Ö~Ï:êéˆÐz=Bì ð«¾ï£+çƒî/TÁZrUrçxùëßÀ§ïû*7}øÃÔëuŠ¢ÀZ;q ž÷Žñ\«…Í—^Ê[ÿàN®úÜ,½äR¼‡%ú™¡«JW=9BèÇêàæE `<…„g…£}á øÀm·ñ‰{îfËå—¯iq¿Md.àtÛÔë!¼ë=—ÿÂÏó²Ÿ~â÷øëÿò_9¿ç( ÔÔR3žšî`Q3ž>VHˆä¹ÜáDØ~ÓìüÍߤÕj•Ïþ«Op…ïéÐÚ–_ËÝ1Ø, Ïúáê[vñÞoÜGëmo¦gB$¯'–®Ž‘ âUñ6ôîç/ÿ¹Ÿáö¿ü »>úÑòAÎÖÚžø}6ÐY€D¶¢6^r o¹ã6ÞpÏgȯx) †¨œ1(Eá¨oÞÌo|ò“üÞ½÷òÒW\qÖ‰ûå謌x EÁÖ7¾õµ¿`ËG?ȱ©… VOáwîd÷7æßõÎòi_«`ÝŸù1c èbçÜ_®ö =¹¢(Ÿ;8ð_ùèäуûyëG>¶W¼8sÁœ•µöÀC h¬ðÞO4Î2Ƽ‘1à¬VëôÜ´€sœ&[Ù=ô¡ç<×ââ"»wïf÷îÝ|ðƒäÊ+¯\íÛ;-:gðÀ 19‰±gÏž~úé¾»mÛ¶!PìÝ»—={öðàƒð‰O|‚}ìckRœ36@•ù»víZV]lß¾;v<ç¹¶nÝÊ-·ÜÂUW]iðå/yµoñ´èœÀÞ½{K]¾mÛ6®¾ú걜· ¢o}ë[«}›§Eçž|òÉòó8uõÖ­[ËÏË©Žµ@çªÔn·cWÒûUb-ÑYQð|hÜŒJªe-€pŽH€-±hà±ÇÛy÷îÝ»ìo¬%:'°uëÖr†>þøãüÙŸýÙXλgÏžòóZœ€à÷'ºýöÛùìg?;å[\\dÏž=|üãÎsíÝ»—üãe`ëÖ­\sÍ5«}‹§EgM (EåF)|®¾újtEXticc:modelGeneric RGB Profileêo®«IEND®B`‚leocad-23.03/tools/icon/16x16/000077500000000000000000000000001440571307300156315ustar00rootroot00000000000000leocad-23.03/tools/icon/16x16/apps/000077500000000000000000000000001440571307300165745ustar00rootroot00000000000000leocad-23.03/tools/icon/16x16/apps/leocad.png000066400000000000000000000023001440571307300205240ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<.PLTEÿ€³oi³ff²dc³dc·ffºig@ÿÆUUºfj¸MK‰IHee€MM®C?¢WW©XXÂ+(¯*(†XžXX¡SS„<@Ú++žLLq*)v_ h*)’ML{))ç-+å!Ú($½%"f m lx z#"s})%è,'è)&ê("í*%è+'x z$"}''ì0.é(%ê)$é*%{! {"!z"!|))è0-í)%í*'z! {"!}%(ê1*ì)#í)$î*'ð,(v z!!y""å5,é'$ì)$y w p#Ö.)à)%å'#é($ê,(Š!r p h#¿0(ß%!ä'$qrnUµ# Ý%"ä$!loRµ×$$‚RCU¨»ROŒ§i¼QP¬SR¦RP¤PN±^]¢+)F*)^]é85´?@mMŒ??‘64õ&#‹ "!ö+)É*'}v!!{#"†('ù-(í-+ì1.‰$#u!!…'&ú-)ì+&è0-Š$#v"!ö-)é0-Œ$"‚&%î,)î-+ê/,‹#"w""}%%Ô+(å)&ç,)ˆ#"w!!h!!Ï$"Ú$$á)&†! iaÔ%"Õ$"fgÐ$"| ÿÿÿ·42­{tRNSZÐââÐ\ FóôG 9¢äúýýúå¦<§ûýþþýû¨‰øþþþþþþþø‰{úþþþþú|júþþþþúkZúþþúZIûþþþþûJ:üþþü;,þþþþþþþ, ýûþûý!¨ùýþù¥NÜúûÝL~ûý³¹#b±obKGD¹:¸`tIMEã KkÅIDATÓc``db``faecç``àäb`àf`àáå«®©­ãs…„EêDÅÄ%›$¥¤dš[dåZåÚ•Ú;”*ªjê]šZÚ:ºÝz@ýC#ãÞ¾~“ ¦Í€æ“,,­&O™:ÍÚÆvºPÀ~†ÃLÇɳfÏq²qžîpëæîá9o¾—““÷ €ïB?£E‹—,µ\ ³ôˆ ðŠŒŠ Ä,[a¹rUüê„Ä5I@®äµëRR×oHK߸)#“!‹!;gó–ܼ­Ûò ÀܬB®¢âí;JJ¹¸€| ú¿¬¼¢’¡ ÈR{Gô€Ý%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/tools/icon/16x16/mimetypes/000077500000000000000000000000001440571307300176455ustar00rootroot00000000000000leocad-23.03/tools/icon/16x16/mimetypes/application-vnd.leocad.png000066400000000000000000000014701440571307300246730ustar00rootroot00000000000000‰PNG  IHDR(-SgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF;PLTEÿÿÿæææªªªçççßßߥ¥¥ïïïéééââ⨨¨÷÷÷ëëëäää©©©ýýýîîî«««‰‰‰ñññêÜÛб±»sr¯<;‡.-”nmº¤¥×ËÊÞÞÞôôôë±°Ü13­--}_ v,,‰31̯®óóóð¿¾ò*%î("Ù*'€!v~$#Ó½½úúúôÏÎò2.ï*'ê.,‰%$v ‚+*ÝËËûûûõÚÙé.+î)$è,*†""uz&%ã××òììÏDDè'%â(%ƒ" p w>>íëëÿÿÿþþþíâáÅwvÎ%"uŽrqãááøõõØ•“¬Œ‹õôôlÝ­tRNS+89:;=>?@ACDE6OXdknÍÈRabKGDˆH pHYs  šœtIMEã KkÅÄIDATÓc```b†F `fQ0c† °ˆK€€¤ L@Zdå€"`VyPT’“b °)‹ƒ€ŠªªX€]]CSK[GWO߀,ÀahdlbjfnaiÅà”³¶±µ³wpt’ã p9»¸º¹{xzy;s¸}|ýüƒ‚C|¸Á«MNN¼ÿ´wî\‡>x|˧O]/˳= ¼˜"ŸÙzÜí÷ùxÐe;Aô9ÊÇð™G))ó¹áœŠcÎe…s ?ÿhñ,@6 KB³4ò]ŠVJ’’†Û 0“@f&¤dØ@Åø˜`›†zYÙî¤X–@D¤$Ed)E0)* fªõ²† `1‡<«0‹ŠÎW$©òKJRT" %g Äd®0ò¢ï;»gð§¡½—77?™†¿zoßp1æcFQÃ2oæ<’)*8H$B”‚‰€YTJe¤ P+-±Ã¥NïÀ$¿š÷Z³ÙßqîÍÃFÑOñëãÎ×K% 'Ì‚Äí2Ñ2Œ$Ja’FÖ,­.½³¼ú“¥^ogx¾É™4îJ·;¸ÖÞZøÎ©·‹f0w23|‰"(•2ÿÏ”lCŠRJ%äÝ$k•åo[1ýèýõO¯åüI[süyàÂð>ýõÑc?ÜïÒ¥ƒµìäxõO,Þ)#÷”j>‰ÍP,v ~öÇæú[£üù j÷ò÷{ >ÍWj²Hooµ?zÐØÿÆ Ù Húš÷nbQò÷‹²Å/n`?¾µ±þ€YÈÞ­€÷öèÿvòÑËåƒO¼qìè[¯9ò;¦§Ÿ­Ÿ©bì³@þ„1iP•Î.%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/tools/icon/256x256/000077500000000000000000000000001440571307300160055ustar00rootroot00000000000000leocad-23.03/tools/icon/256x256/apps/000077500000000000000000000000001440571307300167505ustar00rootroot00000000000000leocad-23.03/tools/icon/256x256/apps/leocad.png000066400000000000000000001362441440571307300207170ustar00rootroot00000000000000‰PNG  IHDR\r¨fgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“€IDATxÚìýieIv~ÇýÞ·Ä–[efíÕ Àf7@ ±9q1,‘²ÚŒ) E “ ÔÈæÇü¡¬»M†š£Ic†¡Œ h# Ù5c¤Œ  ›èÆ"(hº 6º¶FUeå/–·\÷3?|;î×ï‹ÈªŒ¨®FzZä{ï.~ýºûÙ¾sü8áqùF.ÄÌÀ'?©>s÷.}ú‹_´ìi71s `|ÿ«_½4šl™;{‹ÕjÌW¶'¼ZW'«ÚZ«@)e0jc´"«–X­NÆÝÉ‚.=qB[[‡W‹üÁ?x  #">åñêÓ/¾¨>uý:ÓË/3LÀi÷<.ïS¡÷»K*ìÆƒ>óâ‹j±ó+¯\ºýÎ;ÏY³xæàÕן^.çêæ«g­¢kX­®uGGWV¹„åê˜ÇÆtZ«˜ˆÊ'OìIÔ€µlµ²mÓ(½T:ÐM³¯Æ“==ßW+{_oŒßn›Ñ«;Ï>{k´½ýÖõË—¿ŽO|âÁƒpLá _° z̾Êcð>f&|ò“ê“/¿Œ—SœS{¿ökÏïߺõñÙ×ßü6kW¿ourü‘ùÁáGìüäº1¦mí`;‹n¹„± ‚a3;J £ì(#µ‡sœ¾°Ò俘"(Z)3”"´£¤5дXYFGdÆ›÷Û­Í×ÚÉæ«m£sûùçóÚ‡?ü•O|âu"êŠ×ÖüÒKÀg?kÏ Q<.çX3€÷©¼ôÒKÑ3sóà—ùã÷_{í{Žìþ@7Ÿÿ;Çö?FÝr«5Ìb‰E·B·²èÀ€µÌJYDà$à‰(+…-#Q;9‘G?ršâÕá+b_-ÈZf0˜Ad‚Ò¤´Z£i´ã1¬nÀJŒvv^™loýúÆ¥vócÿß.}ï÷~™ˆæ¢+¿ô=fïOyÌ.°iO/¿œˆþµ×.¿õ¯¿ü{o¾ñCóƒýÿÝÉþÁÇ[k»X`>Ÿ£³ c C+¥Á`"kUÐÛY)7†‘®= Q"ß@ëž¶¿ £ÿ¨ ”‡E!Ó@€5žïX+°…eÀ ¥iD “ÉjÜ¢ñèÚÕßžlnÿÓ+Ï>ûsÏÿ÷ÿ"=õÔÝPï§_|±ùÔ¾`3‚‹+Àf¦ÏüàêOñ‹Q~óç>÷ƒ»¯½ñçNîÝý!3;zN¯8:ö6¤ˆ-H‘µf0)º  T!·#ÕS.ð)Iz®a(Ô?‡ŠŠzAôŠÿ½NÐËãƒJ¯'é(JÜ`A‘‰x–@~â¹N2–YM”R“­ ðÖöKúðÿãÛÿãÿø¯ÑÊ7ýT÷çãòðå18‡ÂÌŠˆ,üÎÏýÌÝúõýëîÜùö£½},AJíõÒ~Gi{Wæ>>\Øÿþnb(¦H¼R]°á( +…"†e£õ7QýYªÖž‚œxÊ»"É*k,›ííð¥Ko=ñ¿ÿ¯~üÏü™¿8Ðôe<.¦†ðÝ;úœrà¿Ç@¾pMä íî á½~‡j›8y|œOøëµÃ=#Ô}¨×5‘ëŸþùñ9â7¼VAÖ×É6Þk­…b´G„Õò«_þÈWÿÁ?ø;¾¯-3?^ ‚Ò¼ß øf(ôòËîýöoÿ•Ý7Þ€šŽÑ±(¥¶ÿ”?CaDÕ8;ãï±ô_Þ(«MÀJžÃ9` ¹÷…šïX˜½Oÿ¥/ËöWÎó?cç2Ø2”jôÁ;·püÊkÿ93ÿ-ƒÙu!ƒüMZsÑ÷X¼*ÊüÚk:zë­ïßÛ?1« ª'˜Ôõ¡¹Åû2Ý}³Èê ¿#¤/,]Š\HtŽ„ "¨OF(e\£ÿ6±\T9À0äq+ïeÀ‚ÕrµäÙ[ûµþO¿Û_öØ xå±ð^‹SEÍüîÝÚƒý ³\4rœ•¨˜¡}?ÿi⫌ÿ#Êo^Á5ÄÚ~ýÁ¥¨.¡Ê–U<7´©_µÐo^œkMôÌéx¹bÑÁko~ €ÿõ3?øƒÔ›ù»±ä EonŽÕðýn/À£*£šÑ[«%ŽV+Ì L®\Æh4Y¥(­³þ|òrAÞÈ¢mzŠk{‹ãÍCUçüw¯ê¨ip¥VÎýýò*¶Œ+Çý‰à´Ö¹»Õ³ƒÌ–N–+jG#L'“ÇÀß#*À£*D†Æcl6—«£}̱¼z“MhÝDL€HäBwƒŸƒ6‰+®¸ªõ‰ ˆ¦@Ô8Nî9¸Ùr‰/?¹R§,¢‰"F¡@8űôÃ9VZï"vÀ2Æ`>?ÁÁþ>Ž—K¬tƒ=ÓáÚd"Z^|øâßï‘ÿ@—Ç à½–O~ šfÕ ™lÐÎ|;cˆçû˜ϰ¸|ÓË—1¡HdœÔØ€R)ž?¬ãçéSí2÷úô§;Ø~æ©û÷‰ÀMCJkM&ti¹ÂÈtÐ˺ÝÛ8øú¿ÅþÕg0¾qÛW®`:B7D@ZTRlñkÂ:ÚáÈ·°ü¹ãþWî•übˆøK`2Z!hHh nq„ ÃsËa°…µ'sìï`÷Î]ì½ó&:6h¯Ü€ÚØ@§5TÓ¢Õ.)‘Âö•+ðéOz €^|ñEý…/~Ñ>Îððåq Å ʧë6ô7~ã¹_ÿÅ_|q¼µù&{þÄÞ?ý%îNNÈì‹%ìÉ ŽgØ;¾‡™YàØZÌ,°Ð;Ð7žÆÆ×°¹µ…éx=j<ñ«¨âGMŸÂj¼Šç (‰nÏ ¾‹—ª¸¤ÿòXƒ1b Û,æ böàvßy '³°Œ",©]¾†ËУj:Áhº =óG¿ë{éùgžþg¼wÿo~ø;¾í¿í‡þÔ×d;_š/¤tbÁÂSÊc°¦0³ú ‘ú4¥¥úú?ù'Ýûê×þØÉÞ½=¾wÿólvyã‰'póæ Þýå_&sp><€Ïaçsµ0‹9Žq´:Á±ãØv˜Yƒc¬Æ;ÐWobrù26¶¶0žL1Ð4 DÊ­¢XrKp¦"V"¯XÃ$„Y_ç'aí€1Ëå‹ù Žp¸·ÙýÛX:¢· °ªÁR)ðø2FÛÛhF#—¤¤CoLÑnL1ÚØÄ‡ÿwð[:yë¨í£ÍË—yóò培ù Ÿÿîû±ß”-x Ðxé%|öå—-=fÕò˜ä…˜™~H}± ú[¿ð ßv÷ßü›?q´·÷£Gwï~ßhµÚìNŽ0ï:,»ÎŒ/]ÁG_xAÏ~ó7ÐíîÂÎfàŘÏÁÆ‚»•S黋ՋŠNØ`n—8¶KYƒ ,°Ókh._E»¹…ñÖ¦ã ÚÑMÛ¢i)ÒLv|K#"òä“Â¥gú\qÉKDN¡Ôa^Íg¶`¶0ÆbµZaµ\a~r‚“ãcœÎp´ÿ˃û°ì²""¥Ñi…7 éšéºùd!Õ4Pízc‚v2ÅdgÏ~â ÙÌ.îÜãfÔè‘RO¦XiÝm]Ýù›[—î™}ìç¾ëOÿé/ûè—^z Ÿ}œ~<+¿ëôÉ—^R•ýôÆç>÷¯½ò#÷üèbw÷¶Ýª]an-,ÈR ¶ŠI‘µ^xêiðî},Þº{rœœ€—Ké`W+°qÕ)ÀZXk±è –Ý Óan8±s;ljµ˜3°dÀ°Ow 7/¡™n8i8 Ð6#4†Ö ´Ò 툋@E¢IñEâ€B HÚA8À^£·`XkÑ™1è–+,– ,æK,NŽÜßá!–‡û°Üá³ý€¶aÀPÓL '¨fÕ8¤#ƒcpÔ*¨vŒfc=š`ûÆ \¾~ØÝ…ÖÊqk¥,[ bÖc­±1™bE„éåK¿±uéêÏ_{ùwÿèÇ…žþ®cñF꥗^¢ÇÌàw)Ú‡™õë?û³ßõà·ûG÷ïÿèÑÞþwŽVK5?:ÄÒ2,Á½µÊåã÷Ä£Ýr…ËÝ Û›èîÝ…™ócØ£9Ìò €" ¶)™RÊYùÊcÆZ,Á|Ù9†Ð-°° ^`n;,Ùbi€Ž°Çzšl‚FГ1šÑjÔ¢iZ¨¦n4iϚȧèê¯æsRœa˜a±¦s@Ýj¹€YuX-0Ëót‹Ìr•÷Ž€¢ª@ –*e=·S@7Pí.9šŠ9-¤5ŒgŽz4F3¡ÝÜ„žL°uí ðjíÑãÉØ%õˆÉ2«F[ÃDÔ´lŒ§°MƒñÖÖoO¶·>óÃùÜü¡?ôKô­ßz ¦Cضìwå~¿k€Ø”ȉ~òµÿÏßù¾½×ßú‘ÅþÞ_ìíýþ¶[b~t‚…sOu¬5‘5ʨ ReŒ<\„ŸµÐ¯¾ŠÍÑš<›ÁžœÀ.æ0's(­1Ùܬ‰Â— ¥ ´›øJ5Päöü°ŒíÐu+ÌWËÕ‹U‡…1Xò Kc±âÖ ã3:v/Ö9íöç@±úH{ç½SçÝ5lMXáOP¤œŠî8Á²…rD¯G°M è1Ð4`R€Ëòã|ä¢ -¹Ä –ZkÌç Ì0ÞØ„n[´Ó)š ¨FƒOæxîc¿MÓÖ€  à²ß ±ej4“±–¬Õ­Ö´1ž€ÛÍtòõ­«W¿¸}í‰Ï=ÿíßþÅoý#ä®|Í_|QñŒ›°~3”oj ˆ>ÐT8¾óÕ¿ûwààë¯þè|÷à-fkº%ޱ„…bêX)¥¬%ÖnÆÚ[„ѲO…õè»·´µ´ZÖf Àbsû Ÿ³¥ pÄO ¤ Š´“ÚÞõ¥4A‘‚õR™Á²3èVK,;ƒUç>»p±èÈÂØÆÆGŒvCHˉ¹ƒ…‘…e•¢•Lá €ü‚; ſtß †:¥aX=7Ð#­`ÉáÆ'2·ìúÑz­É>ˆóz0 4f{»Àj…fº Ö Zk5 0&—¶ñÂ'>ކÖ1Q¯(Ÿ€<„%Ê2³VLÖZeYkE´ÑŽ@ã ôxtwãêÿ¿­'®üì3ÿ¶ò‰?úGßóçE ù‚oòû=—Ï«|Ó1± OÆÅùßü›k_ýÕ_ý#Þ|óOžÜ»÷GíÑÑ ´Z`q2ÇÒV¤ŒÕJ)cÉ*i<»Y›2úˆnób},<í¨Û·¡, x2Ê2À+0a<}ͨØzÙë$ŸÒJi(­@Z£ÑÔh(?ñ•&@““Ü c8ÚâfÕaµZÁtV«50EÇÖí4ÄÖ©ôØ®óÚ…³q¯ÀÆï+0üî^>2(0˜¬Ò`ÕÀêFiݺ]€`<‘¯Ø" €ñ[°§¤Ð_Ç´‚5ŒÙí7¡GГ‰Ë$Üh@)("l^¾„gïÇ¡µ¬…ò›—†…—ܘ"OóK´}AP- ¦JCO¦°m3ÛºöÄ/m^½ô¯=÷¡ü]öÏþ–œW/~“º¿Y@ ÌôÑéK×ã×ýÅãÛïüÉû÷þ8œ°yõ <õ{>Mn­d²ýkL@j^òÍAù•™ìv?ÒfÚ2“VÖ‚™õ˜ÆctºÅèÒΗ§W¯þ£«O=ó3è;¿óŸÓw|Ç‘˜¸­Î¿áÀP4Þ›Ÿÿüï¹ûo¿üóûþäñ»ß×,W[«ãCÌ­óV+"³æà ç!¹zƒë— ›ÀúˆI+˜7Þ@óæ›P讃6“RÖ˜0‚Âã­Knzi¤´‚V^Ò+‚nFÎhhÏ%H;È- ²"¶Þ²#r0`: ÃÌÊ8 ³èlÓXftÖ c€…àˆÞ¢CðäßøµG‰9¢f`åÏuPè`#¸ÖI|ò«ÝoÃ̰ڿëHz{j4qÁLÊa"ÄÀæµëxò[¿Å™HÄîþ8¹"ýÊJ@ÖížódøåÖ”› Q#ðSÊ2ik­ašãév4‚ÞØ|eãÊÕÏ_yò™ðýì‰>úÑ}1c>îÅoD@/Usàë?ÿóßþÎoýÖìíýÈñÝ»ß×.ÓåÉÆÂÜž{Öª\Ò—„_‹e-K¾šÎ…XB‹<§‹aWXþÎ×ÑþÎhIƒÌÚ(ëó4@šéÚñd­cZA©Z9w ÖN Ý8`P)3 ¼¼£¸­Œ·ßmPù òq €;ØŽ±2Ã:g"tà³Þ%`˜ÑyО¡19äÞØÜ†H~xootpîGC6Úþ¼Ï¯6dEI{ ÙˆI£³æ÷3F#çðਰyý:n~ä[#Ák?ÄÎö'¯xW¥E‰ äÄo gTþYfhÅÊ»•Ö4·Àh ÚšþÎÆåk¿0}âúçžýð‡ñ[äG2÷â§_|±L#”o°&O½úöÜÿÍûCÇ{»?||÷þ÷´«E³<:Æ~®*òDŸ¯JOËcÅ5â\êŽö8+áäæ娅<öN¶Ñ8yóëÐo¼1i4v ÕY(Ë 6`žAc" £ímhj `AÊÙ¸Z¹ÌAJ5Þð €4¨qòK‘“Q®“±1°µ°Æ!ÿ¶ë` ;W`çzŒq Â:‚·>ðˆƒ}Ï6JwK^ý·¹êŸlÿÔ'|`œ$ï(׬_ήu3ÀÀJa1;Àjï>¬jÀÖ;—Ñ4#XM€n@õß~ò&n~ø£PÌkÔŠ?JZ±p  \ ˆqá»P5²–Yi&k-¬ÕŠˆ¦ãO€ñèÎèÒ•/N.oÿëúè/|×'?ùu9³^ô}_ËûÆÖ}ûµ—_þ®û¯ýGÜÿ‘Ž{ß©MGÝÉ .cFFô™yÎýôV$¤6€°.v]»²Ïxyœ¸éÏ?Ò©ÌZãøí77^G ±éИÄ m ¬y ÀMC=ÙÄx2u5dAºR^) Ý4.@9 Rn)lð™‡FZrÛü8ÕŸÚo:Xãˆ>þY Û¬\;MÀ¬àô ÇœjÏÑ·Eô H´ŽˆÁ?°èT#”.Â~•Âb±ÄêÁ]p×Á £m_FÎrÓ-T`O=‰›ú”gèÚ«ðÒöÚ?ÐL0 š@©ú’Eú“ļ ò60D–¬ulPÓq `šÑþôê•_Ú¼zãg¯~äCŸÿý?öc_•óíÅ÷9ÖàBÀ¢½ú÷þÞ÷Ü~ýÕ=º{ïO.îï~{³\b>?Ag ê¨QDÆ…àÊ„•™‚Dy ÚŠÙŸÇ¹QXÁZ¹ˆ35Ÿ}0‹ÂfŸNŠiÞz æµ×0&…ÖŒŒ¶Ä°3(8·– Çm0šna49 £È…ÐO@bÜaÒ` ƲqÝ9¼=zúÆ:3Àƒ•5>Ô×-JZ®–n}BÓZ{Žú­ 0‡àr1â÷Êÿ%¿` –mtõ…”aà™4:6˜?ØŸÌ`H9ÁtP;W< n¥¶Øzú)<õ‡¶Ð^µ×@@÷©qG\ üæœÀ“ÍŸ<!¥»òÚ#ùI’GZhg„w13d&bèq£¡'c˜ft<¾z執w>wý…~þü…¿ð9í^|b ΢¹‚û•—_þþÝW_ýÑŃ?´xðàj1Ç|>Gç©3VÚZb¿ó^PçO“âòáLâK4ý‡ïDï7©,¥>¿£ŠÛhÌÞ¾óú+˜Fc–hW-3´e°=€"í@ìéFc<ÝDÓ´ … PºñfCþ¡v2 yÖë]†9®Æ³ÆxW s :ißE•Õ¬º¼r€µhZ Õ°ìÌ%¦´…äwDîüþ+FÕ_âÂ;àúÕ§SœÀìÃP°‰fE³})Ó(2€gpã… <СÉá3€|AJ €ÎÆzDZ$ ‘Ó Á=Œ„$‰÷03¼{lõ¸iÑLFèT³?qõ_Lw®|îÒ /üÜwÿù?ÿë,| ПM±SçVΓ¨—*$ýæoýOÿÓÜ{ãµ~ÿÁ_Îf¿GÍOp2ŸcE€†êB4+äÅÍbCe£ý˜ R|O @=¾=,níÙ÷í÷a°Îæûh&øâáÝgºÁá;·±zåk)ÆtYƒÆXhk ì!Œ½š©©4tÛb4ž¢<Øçâá•nœVÐ6 ç $Ò`J-gãŸýΰñ8@ÐpfA‡ÅªÛ¬ñî>k]ª¥A­#ºŽÈ…žÉ!I~§8&´²+åApûYRÎ-"‘˜û Æâhs°ï¢ áò#wJÞ¹ j­á5ÅÛÏ<‡Ï?m ´·Çá3´_ ¢iàç…foøà¡+°&F ¸ ûAn‚@ÂÓ”ò7ú›A kãêEé1€fc‚¹Rvzéò—6.]úÙ+þÈÏ|×øþK¹ûñK€.ñGU΋Dºbæé—ú§ÿȽ·¿þïßÛû!{°ÿµ\`>_À°eÖa¥•6†Ü »‚ Dþ´áß©^wÒfkÛ‘§,65‰J´mýñF·Ž¼ú "4f…¦s€²º;„&…–Z7ù¨ñ€Ÿ†n4Úñz<†V‹ ÐÐ.ÎLvVNr{4ßZ äÃ~mç$¾5»D›«•Ū[E³!œw `kÖÚ-ÛÕm&õ†Urÿù¨?錮Cø%Ì÷§ÀÎ,кHCòÁL ß§ ھ䘑 [@i[\zî9Ü|ö9(cТ à¢ý|¦EÏR¨‡ 8¹9ì£ ­ :‚‘„ÊÏ'ﱉAÜðAcÖGhúyWL¸9ŸZY˜ŽAhF“1–Zc|éò¯·¶öò‡?ü¿|ÿòŸüÊ9Ñè`ûÞkQì/üµ¿ö±ÕÑì/›ÃÃ?eìýÌç˜/蘙´6¬¥LG.Ðýl•ÂPüì%¨¨hK± Q‡¿¤ˆ,À̉(À@ãà*t–ÁM‹Ù;8þÚ×0ÒÝ­ Aký„[ ! M i4º"òËt] @ÛŽ0šŒ¡›ºñ@ã¥0|+òÄïÝ”†Ñ±S÷mˆø3~­Àr‰nå";¸U¿Ž¬<°Öyñ€mܲ]nTü£œ¤ö½ÝÉ Ÿðé‰?0çVË%ºÙ>ìr (Ѩ(~Zc v.GmºuZw¸üüó¸ùÌ³ÐÆ !‚f  ëUÉO’ðéðзA'f ¼B+H£<³È žÂ•Ȳu“œŒeÖ…]±e4-“és¥°Òí¿ÄÆöOýGÿý_ÿ‰¦òH“‚zÆjù¿ú¯¾÷KÿËßÿ…å;·6Ôö6¦×žàK;†”VŠ™¬å¼‚!rA2Të ÿËU=6ûT^–‡„ˆ/+k”:=\ÐK<œÅøE?Õ ÷<ñ‚»Ïý2p1ñd„lØ-ýUìV­u¼ÂH1qæ¨Æ®ºÂîý]Ú½õ&=¸£ ƒÛq»TŒw¿öê³p÷kíç’üÒh4»vå \¢¦Ý5zg¹‡Ûw¿†Ùí¯aãÆO>ƒ­+W0ÝÜti±#Ý…5éŒÞêÛšùÏò”–èOñ|¨7ir;‘ _Â…ÒP¡®®»Ä}Wä¤"hB0 š †:(ë¢;Öp+ÚÚ/ÆQLÐV¡QŽ¡¬–Kè®óë\°ÛXÄùÐ;†aÁà•qRÞt°ÆÇÀKxËÞ^gtFºëœ v÷Zë˜Cp/Z,|H±YÂt ÌÚ-®P ¹5ÿ1Ò½¦a¬Ó"<r$ÓɸHÊ­$L’ßig¾Qƒ¥³.ÉÈ3½ Î{iï}ó륿·åÉŠuð=‹¦4{Bà8­3(gBÑ()áãdC¸¬éïµF¾œ/p0ÛÇîí;xðækXÚ@»};¤I5ÛÛ˜\¿"³=²òHÀ§þ4ºrmÞ) E˜N¶ps²‰ýÕwGxgy»¯ÞÁ=nÑ<ù<6¯ßÄdÛi*H~›$¿ÏU‘ú<Ú]ú7rWò›²ÒHÅH™2c½1 ¿m?N@*çþQlÑ* ÂNº6 4p …M  †\¾b§ (f´°è Û õÑ k± ê|,@ÚÂË-r` ÷éâúÙ-ÿ…ctÎn÷àØûés‚`‰œKGØì4 iXXî`™œ ¯5ìÊÂ6Ê1ž¦w°ºqà¢Ö`M`Ö`60Ð`åÚk•r‹‘E‰’:])e+°Ç`LµBëGSƒHÁÞO‹‚R¤{Û”£|¿Âû÷.Ä GbÚgŽäÅ©ýbÞ…mÙ„FæL×Y,NæØÝ½ÝwÞÂáýwÜjµñ“'1Ѷ#ú.—äUÍ%­†r.€~òÉãUÛ€ÙeFC„'&\OðÜj÷—'¸³Üû¯àðö+˜Mo ½ù$¶®^ÃxsжqCL`'&¤~òÎSÒú !±Ä(âˆrŠ¥/튨üSǪé‘ýö^òˆÑŒÖ ­4¾Ž€æZ70VA“±Îíg¬q)4hT‡Žµs[ë@-å ,ÅÅ;3Ðãsú…8ÿ Ñ]˜¯%8ÂöºuÒÈ0V9ƒÃ+ûíâ–:lDNUg«ûÐÂK|â±G]0‘5 Fçò À8â‡r I¼äîV7FV`¡û-¹y¤Éã ,>D€O¢ý)b1w@Ðt$ì 3‡ÒÜÉö`ÒBËÃ~¢… Z’ÑÁX.–˜Ífxpç6Üz‹å ÙØÂdz ÍxŒVû¤/ì¡aKZkìܼy ××¹ÂÞEy¤ à“¡®_?4Jƒ I³a&M†Å„íQƒíÑž4›8X­pg>ÃÕÃeÐI(vô´…Pç3)0¨?tÙȪ3ú÷3”Àh@+íRtã¤;œä%o44Ö¢Q š  ÍNš)´:²Ð¬ÐX' Tg½·‰ƒ'еÃ&@“è<ÉŸ¶+¬Ùg¿–?H¿MV1¬UNºÃKz$ÎÀ–`·†ÎB9oC£ñ7-¬éœ=§E؆`­†c < †F—?–½ëÏI~¦`ûsô"@ç±’ )ŒÉI}prÿÅ É@X¢û‰h1¾áš0•ÂÜ ¦g æ%ßSœL"(È}ËP!¸ÀãÁƒxpûf÷o9ü§até F“mŒÚÖEwÂlPq¶ÌÄ «FOÀ&D¼…ôV:JÊ4)ÃòÝà[/…­·½Ùý¸¥ÒNúG†`’‚FÂ÷sÛ’uFHg]0c=jßÁ°×Œó8¸`¢À lç58 À}ºåÂPäöJ`¼ªÌdýjA‡# k #›ÆäÌ*íW{u_ âŒËx#´€b0M¢V@b±˜õ˜¿J"<0‚ÜñÌ g²1LÌ1ýŇ³CìÞ»‹Ý7ßÀ|uâÚ¼±ñd£ñmÓx¥Ô&ï(®I0±ÒØyê©™¤±GUÎÅè^ý˜ åò^')êóËf`Ý b»c»ãI³…½åw–'¸ßÝÃ×ïáÁk#¨›Ïarý:6w.aÜŽ ´ÛL3…L; ÑCµ…ØözlM…‹b¾ˆ?ŠÃë(ˆ_B ãO„PÓ†cëvØeŽý@‚í1 Ú}2 ¶pH¶² Ú¹1 bhE€UQÚ`A@@•­S±Ù«Ô¾½Æ&‘Tt¶.(.Óeïµ'w9ÈŒŸÚË*Xb—-X+ØÃhî)r¡Õ^í×p`ž3­ (Ç$؇ÉoA`Å.Âл*¡cVØT c0FÊiQ`×'eú/ Î2¹`§a< xQÒªÀt*°ÎÜ…2Ú$ALn>‡]•µ˜ÏO°·¿·oaÿΛ.¬]+4;WÐŽ7ÐŽÆhUPó ¤PJapÞkAÆ=ÞšÎtÝ!pª{èòh€ ÖO&GÔê%Y´¹}zÐÙdÊž%GVcÝà©M<1ÞıÙÁ½ù î¬v±{ïÞyG70ºñ$¶._ÆxsmÓø.±ˆ)ýÈ/J4³ÙóM¹±É#+碘7fºiÙÍ…ðPjÔØ‘­%×±Z¶Õ[íOy­àîòww°ÿú<à&a—.aܶ h‡Â’'ÿ€ ‘„a’"Û!Â?âu©©Ò{P¹!Z̃N*ML ÂŽ)(Ò8é:,`±"ÆO Æ*4äb:6ÐÐÞ+à?íŽÁã°®«¼=î=8†îZËÑpuqþÖ#ÌÞE§|rŽ%Øc øì=샀ءü+À¶våú¥SÛLƹà§l V+¸„ÃäCJ>K>ñHH: †f´!lh`L„@§ L‰IÕû{þ´ ŒSÊü“À@9%Ãï õÞÎ÷´j£®ïg“5˜/ü®Æ·ocÿÎ×÷Fzó2šM´­õ(VÆxUAH}I$€óÙªñèøÆG?:fæ|ǧ÷V-ð {vkëèw6&3M¸iˆ¼^çi6iûœ?<¶žŽuƒ›Ó-\oâÙàAXía÷Þ«8¾ó*Ž6V°yõ*&Ó‰K¦ †57ÎdÏÂë,‚ôܹùŒ€SíâîY… !]¾r8BpŠ&§ª†e6КÐuŒ¥V76hxì²)ò Z‚}kœk‹R`ùpWæ$!dû¬'lx€±öˆ¶#%ÿà(ýÃâfg¿Clg`›ÆmB¶3`¥ÁÃŒbpçÐ}—.Ìxâ÷nGÀp ò ‡Ù3{_Ä´ŠÑ‚=Á;Æ9òøIëA¾ZRhü»(‰ìÃ1Ü€öÃc&Rò“Ïr‹7 „¡TÄd2 @g:áÁý{Ø}玸¶ŒGhÇ—ÐLÇn»¶ ‘çíp;@帑|~ÎòvÖÍáÆñ±3!ñç¤à‡¸£ÿî¯Ï¢Ý$Þ©l~¾ÿ`öZAX@âì½kÞ•øl·Ýå î,Opoq¯ßÁƒ×Z¨›Ïcrí:6¶·0¡ƒ#ÉúÊ•HQ¹ 8Îa ®´¯Äd4€åÜ:"¦@®FÃp[^™t«Ð2£ƒÂ²[bÅ.‘†B MZuÐÜ@Ã8ЯS eœ›\<ùöRXlløâ2þzâ§zÌ .0³r`ŸíüV]€õY‹YkW‡Rà%Ãjv*¾²nG_£¼áô—ÔŒVغä›Ö&âwê?œõm´Zï!š–СõU-Zå˜AãàcR–:^RÿS {5Þ‘øm¶!p'ƒ,–‹f{xp÷ön½Ž»ÅAjc z²…fpçÚšé¶#úÑÈ%x@>OUˆ^Jþ!Nž1ʉF¤@ ‡øñïð?ñ^ȳZÎC ¬v¶V›Jäê¸èó¢SX~¡<òJÃ{ F£'ôWFzŽËsØH¦¦g=#|ÇÖkM¾O»Å³ƒöîÝÅÞ­ßÁÊ®Ü|O¡§Ûh'ÁÔô5Y/Äš–²¨Á3i®¹–¥ÅLÌjµD»¹9ÉBÖH©‡/çÆ°¹} °piûÌp›KF ;‰ãù‰èòóR[°Ùhl6Û¸9ÙÂÁê2î,Žp·;Àî½W1¿ó*Ž·nbtãIl\¾‚ñÆZi‡_{‚¢ÞÃÉ/|MöZÐöûÃà/lª¸B‘º¨â·X‚²€m ä—ÁªŽ¡…vÅà0ˬv»ü¬ÚÆ­¾kF°Ô@kø=|Ê0lILsy'ý: ¶ì%{M#öZ§Y¥Á­öLnµ¡Ò`ÛùÌ=Áµç¢™Ü`hR.Y§"PÇÐ#¦ë\:3tP~?P#-4m@‹%Ôxê:€4”Z°òœW¥Ð*•$¨L×å§ ^îýèrÄ︛sµY,NN°÷`û·ßÆáÞ7†ºÞ¼ =ÚD;ù…´ ÂÏçzX'BÒSM•YŽ "·½ÜÖÆaF[°ŽL /áèÙa5åEE”vÕáðøû÷îcïÍ7°´.<—FS4Á¶5B(ùQUÁ?¿ÿ½®ð—^ˆ @ŒÎ¢mˆK¿±Àg}+õáÁíxׇÎÓ. '«ò©§ÂgŒÅ–ð¨ÌÝå?{`¢wÅ=V+`{Üb»mñ´ÝÄÞj…»A+¸û æ·_ÁñÖM4×obzù2&.C¯{¼ñR-X­Hðqùd/Mâp“[’¢È8­À¿îîHV¾^¥#‚ÍÞ\²Šâ5Šnb¨u¶Ü°Õ eœ§Hv¹rA6«¶m€eèÆ!ù­ó݃5˜ ¬qí pãðjHRá•e°VN *í_[%oEX1¨:íh€Æ­ÒcíMí¹­òjŒ WîeãøÎ1u˜…{Aã·ÊëV®ß»`¬#hãžC ã˜HçµJ’]9¢W+·hB1”Ï™ïWWn5µOˆê;JìÄb2)¢ùž‘Øå ÇÇÇ8¸wûï¼ÅÒkÖ£z¼…f²‰¦9÷­MU±r¯‹LHå§D`Vµ¿nó£ÿ¢òpØ2¨i ˜ Ýþ^Ë#gŸðiÖšÑXHg@Y¢\+°‘ _a'M7ÑQ¨_Ý(<À¨VŒ¦Åv{7Í6ö— Ü]œàn7Ãž× N¶o¢¹ñ¦—.»%ÊËFK>¼7!ñIº;fÂ7uÜH"¤•r~{çŽÆBæº# F1BXg£é5&—ë3ï¶#DW7ÎíÉ`Kà±v9½Æ ¸0nÁµ[¥Ô’ËïÕ4@תIcî+—ÿ{Ü€W j›téjÕ¹iÕxiÞ4nœF'•(rÁÔj‚5Îô!•ú lè1”8¸EJW¡êT?0ñÕɳƒìݹ£{o:~F=u.<ÝŽ\Š6哦x÷e(’ø£ kŒäåÖ~Iß½s…G™¢ Ø®zVê>¼à‹Vó_z‰ñòËP—®XM€eaÕ‰>D¬Ä‚å9ƒ\ïl1c -/éMˆ«ý¢©Ö˜nlà‰Éž_íàÞâwWØ=¾ÃWocF^£kW±±¹‰f-M$çN1©”¿Ã5‰IˆåâÿÀ ˆ€QƒÑnN·¼Vp‚ÛË<8z G³·0S›8¼þ4ÆW®`ºåüÆ£«Wнu ëd„Œ(ž)Ô}bwm0!KÀ(ˆFíÜ•HX•mÛYTá°‚"޼è9ZÇÈ‚¬SÙÙgs†%f¿—×I(à †)›ÞÃ÷j!¢ŠmëݨÈm‰¼Zbrí¦Ó eâpoûwïàøàŽë­ 6v Ç›hF#þ­à‚¬l•$«ó©†)Iâ§ŒøSŸ¡ò!‚ÈJ¼P9rp3\à ¥»Étz. Aó`aíß½{3‚:&¨1=zÖå‹7wñ ô9y\2*íçJn• ,¤áõZ&\Ñ\ñtçÃŽǸß`ÿöocùp²óÚ'®cré*¦Ï<‹ù»Xîï9¡F~©‹ì‹ ü ŒBƒ<ŸQå'íÛÓÀ‚AÔ¤’p·R2-´ˆc«Ì¤‘Ò)¨Áþ¤·àêT^z‡„$ʹA~%ˆ¼'H3§’iÿéØUz~ê 9ÏK׌›)®`£ÔdÍhM;F‘ù È'Õ Å1©y➉Ü@òHÕ”¶†<•ß~ ÈaH`»œs.Kó`¾×ßéW G¼ÖQ=Âf?dv— Ž)•ßcÅB¥¨1sj6»4DØl56ÛmÜœná`qÉå*XãÁá-œÌná°Ù„zò´W¯`²µ‰nïVûûÞUÆ·&½3CHHGô ޏFw ¿m¶[,ë>õÐÆ€žÈi]Bxnæ!Iᢠp¢¥bÈMþ$ÑÁEˆnŽÂöï‰ 0¤ _Œ'ؾrãm,Ws¼þÕ¯âèþ[®MP“-èÉšÑÄz¡>A ŒæzðœÍ[!bªØúé»´2ƒ.>© ®‘€,Ç‘qEëf¶që–Ã1ñçhà?ûÏêç>w¨Ñ¡£ql)ˆ^þ®dêzo¥2j}©}”ž•ê71Ø…oLpm:ÆóÝ6î/渽8Æýn†ƒ7¿‚%·ÀÏAí\F»µ sp€nÿØœzÀc €‚ú/žä$";bj ˜a=ñ3¢‰{ Yè²ô¤„‰¦ã¤t³ZÅÙ­|PÖÌéw>69w “?33"‰& ‹s¶[€­ÅôÒ l]½†fÔb¹XáÞ«_Åüð>@Fhš ©7B£ÈÕ©|ØägÀìù@àÎ (ˆ_DžJÔ?¹%ñ×µƒØ&âÆXÊçXÚ×ÊÁG°LÔ6‡êé§ËwzTå‘3ÑÈŽ¶/(,lCnÖ]^„^lºzúyà \¿öæœÁgá&‚û§;4ܵØj[<5ÝÂþêîÎqgu€ÝÝW±¸˜ÍP[—0š~æäfvl^¥;³à‹“ØhÀìƒl¸aðÀ +o2pøSr¢ f€¡7æôæG®òñ}W®ÝXÛÕÞ¬p«$¨ÇÜÁš…éö5L·/C5 NNŽ0{ët‹¥[s?Ù€m¡OÐ6Xg‘oÙ•Ì©¡6 ªøT ® ïU €_迌¡à_uÊïM ô*(®Š{ç¤ÙÙ™ýðOþd‡¿òWpå<4or¿óÒÍ4à¶ŸÈ;5^L}Fm¸xš6PúoKáÈnί’UË Z°¥4ª `Ôn6<1™àùÕ6îÎ總<ÆîüfGw°j¶¡¶¯€®=»\‚OÁ ¤¢Ü6Ød½*Oug(2¯j@¼B0À:JB à Õy`Ö RCe€‚à—{wlâlãÿ D.u¹%É*ÓgHÜû–XÛ-¡Ú6.ÝD;Ý0;ÜÇÉþ]XË1.¿™n¢m'.ÃbPâ%ñ­“– ‹À¨†dω~ qœÅÿ•{Ã\ þj‹\bnh=Ú§`Û}P¼A(¨v2‹Û+‡—-FªçSõ¯({@Øæ%^Ð7¿úßýEIa<›2•2 #JÓ<9ÇpÕP»ÛkÏ=agÔbkÔâi³…½Åîœáv·ý½–Ü Û¸»u ¼¹,OÀ'û@·SJ™PÀl@4óÄ#¸Õø­Çtj[´Áƒ¶š ò®D6âýÄ«¼œKþ` K ÂA¡'åÓ¾§ßñÞ0p¾˜Î€`ÑŽ·1º²R#tÜa¶wóã0»ÝqÚÉ&ÚÑ&ÚÆo¥Î>–Âs!)–QóH¨ýBñÉ„j‰=$ :HbFuâj R ‰‚ß¿d Õ4`Ÿ ùLdå¼07v¶fŠ–mp±•ª+â$~öž')µÃh[$X%ëL­uqâÙÅd Ÿ:üÈîXžÞØÄõéZ]½ùï,öq~ÇÇÀªÙF·±ºü$¸[‚NÁ«cg÷k7LÌaELp ®R3b_y†à‚ÄH„¯)yø½Ã„´°iÊl‰Kº†Š­Ú©¸–Ù€éÓ­ËÐãM°–ó9NŽîÀtK€šl¡™l¸ º¤Å‹±h—ìû¼ßÏ4¬I¹É¦KIY™Ù'5Ç$TÖ‚â–0‡¦šd ˆa ôÖ¦\ øbè€}•åp ¯ê‹*ÞÉŠ“þX$GW³Šqn°•Ž$öÌïàøXŽ/ÁŽ·+7 -ƒO`OŽÀ8ô4ÅpŠ'ˆ±wÄJÍGÄ b>xÂ_‚´Æhçšéóå1NöîburìÐŽ 7/£O¡›‘c~œ¤}`,¡- !-§m® T÷‡ÜÂò=+Œ?¸uË[å|¥ìV¹˜;o™Ä³²ç悹蓙¥ÑnnîãËùh/½ÄŸ~ùeà™§º¦± ¼]ЩO¸©¼Y0àv ÇC¯Œû+}•èS?¨i]Yˆ­âøü¨HpDöi…](ƒ:X@ÐåÜaU¿V%è0†’PXfãôn­4®M4®LÆx¦Ûƃù·OŽpoµ‡ƒå>–˜`5½l_…¾tXž ›í‚WÇ.˜¤™øÚ=êO)@ˆ”˜Œ¾/™áýò&b • çž j|»qíÖ% ai ΰ8zÓu@Ó@Mw §h›±Ëf ä¶½HÄí¶RCã0dF´?|†!«rô>G¤ Ѥè|þ™ú³7ÏÓbŽbÑ ›×nç³8'ðIŸ ié`A &².Í S H &éK”?QýE?rK¨°ï}8¥E%0ˆ°$Fà®Âô“¸@á!þ”•ŠÔï•"˜(”ßTÄaMƒ­Üؘb¶¸„;ócÜYìa÷äNŽÕøìÖUèëÏCYs¼sp/"ø¤Ç®6öȺíz^'}½{0~‚Ұ݉_Ò?Âôê³h66`Háx~Œ£;oa¹8v&ÁxµqM»‰fÔº|ùÌn)°'ø’HCÞ~F>ÃÓ:­>Ðc…fÓ©ؼŽrL[Î+‹«3  ÆŽª*›^',ZdÉdꈈôÕK< , îæÆZïÊõëÁPN¹%$È8e1¨ŠÒá^‚•HÏ=E B/¼Óz§Ô²Û!4Þ½é:ËÊk ‰øó,È^³HË󲺬xd4}ýšÓƳ, ‹Vi<±ÑâÊt‚çºÜ?™ãÎÉ w»ÌîïcA#˜íë í«h/?š¯ÐÍvѸ0ZR#·˜ˆ¯j›üÁäÂ’6Q±lçrý¶o Ý¹´c,WKÜ?œádï6¬µ.>~º5Þ@3rÒžÀ>ýyˆsñÄ4 abõºå ª ËÚRA™êQ‚Á ÒØ!c/¹‚s” (aYwad^-ÇÂS1†Â²a¥Z[t‡Àù,Îs-úÈGfhCÖ*—‘&ç %ñ»·Œ_ªR¨‚4ÏÖÀŠmä’_j½+»4á’Ù¥½À- ¶_;g˜$x¤ï¡­–àAOÊê–LÀMJ›¹5µg,ì—Ën·#l¶#<µµ‰ƒÅUïA8ÀƒÙ[8ÞVÓkΪáSkm@'hšöôÝ w†èBѧŠq^Ã$jC3èú-¦Wî‰ArÄ<ù„H©\O×DײH5´gO¶¡µPºYM¯^ý2ßûo½u°4 ÛË^/ óÒH QŽÞ ˜P5¢ þò*$ÂÚw ÷ˆÙ3ä†H³ª^o…G© )Ì(1ž!hr¹þ¬ßwk4ÂÖh„'76±·ºŠ»G3Ü^Ìð`ÿMノÅô èÚMŒ®ßÀäæÓ€]¢›/ÁÆ@5 ÚѤ,;ƒýƒ=ÜË£'Y›j´ 5™¸½ðBf öqʵ/jC"²& ÂŒ=q‘\¶-<”ƒ¥\X#5ˆd–³€Å…½p߬®”º=œ¢5-* 0î ˆ} 꿼Þ1M:Ü÷Ý{>ú\À9›ß²»;g<>tû¶3Ä&Hùúz±ÿ5 ¨ÎˆÝ§Ìò38}ÊKÂ!ªM–‚]GÆÛd» ?§¥—»÷²Åÿ…/Å×R„Xv«íFMƒ›M‹ë“)>Ô]Åý“cÜ:>½Õ¼ýs«príi´—ŸÀdgcÝ¢3Kcï[8º÷VŒ•§ÉjìRkiÝ:ÍÊ:ŸH×]j@Jè9rKP…ð:Ý/’Dƹ^Ýæ;Ïã(,¿Síõ¾ÕfT9W#Œ1$ãŠé²J“7õ4û*Ü»uë\¶å\>õ)£þô¿8TX4B`Ÿh°C{ JAïgVPÙñËõæ²H@FúƒK+@ú 29^ãCc)ùP  ±²X„óÈ[Hìãp³Ud…7Ñ‘Tßh´B;r¦G‰gáR°îŒZlµ—ñÔÖöç—qçäïÌ÷°ûàMÝš ¬6¯àdö«Å±{Ú¸5›Ðã t;r;ö€ãE«CîN8ˆDû¥:ŸIDÁI¥ Éòž^Ê®-¤~ï3M­ S `©þéðKé½úW–«X×.e—X@–Ùijºqøº¿„ó+ê½WÑ/A‘áKÀ2¡w5.ÌÌÌë8iÀÓï0èòOÖ êG¹ô·¹ ŽðC$…ô1ŒÜ³Yr¬¢ ÅCX3!ÿËŸïJ=Kã˜AÚr ÄiÂÍ­M|ü‰ëøžÂ÷\{ŸØ¸Šg1Çæþ[àîzìA(!ÒL1ÁRìn—áðKûp&‚Ó .MZ\š\Ás—®b†çðÕ[oã_³ÅÞdòùmzW·W¶G²_Ã¥ÒZ)±PÊz6Õ€òÝ•b¿o’R»ž2X)rîôÐÿê}”§â[M«¬þôŠ`îì×$“3xf½±¹O$Q‘G_ÎÓ ¬g„i|/·Å§Î‹WÔ"QDuÒõ6Cpÿ#6¢Z§,ÑUï) =?­oþºIvó ö]¦›~Ê´´©^±¡B ™€J!ª²n9Òd4Ætº;û{Øì,@â9ÂíÎϼ}5[8¶o-Eæ Lޱ—çóºèW׫PŒÀÄ©ŠNV|OOà¢uÙ]T?Öw€„š­Ï5¶j2…9<:×¥À¾)çVÜ»míªh–b‚ÒàúãJP”v*dv£$pp"&ÊVËü"ÿzÊÅð²quùå¾ò¾ušFýˆk³³Ò=ÞÜp¿êŸOÀ"!ŸýÉïÏ÷²ïrE š”"t¦Œ…föû$8ÂW*=ß}³1—KìÎBgè½ìêLú»—$%SxÕÆ¬f.‰*Ð 3ARk[1Pa &ñ‘õ¬ÿ?1&¯_õšWû†\€:¡°ì}(Zœ" usˆs.çÆ>ú˜xªu.£’ËÆ\vH†œ—Vn奞Ó8ôz/àzÀ>¾Þ8ÌCÜ·ZƒõÒQÅ77yÔZ ÚÒâˆTù»Ø¾Æ_&¶¿KÚƒh´äiY8sè‡øÛOpò ˜d)#òŒØÀê šÀ”7Ö†#¬þc óÏkÍþà7ünâ³Ç‘k÷IÛ>›„ì!Ü^âBÀl ¥Ð—÷öQp5iÏ5pŽ àS¡å³£;<š€qñj:ù·/5³mK ¨ýòÞ2R(ÓPãééå¢ü:!uƒäõ7Ü^=–vp¨«bߺöå36^W5dûêIr»’ŠúÓ+Rq]„üB–íí?7üOU$Ú mh!ùoV’¯×—þ € c1ÂŒüÂs èóÏÂ’è¹3Í¡–Ñ?}ϲ’ôÄ,Ü·,2øGrg%ïUˆ+#CÕíæÄÜ€?ˆ à3þÓl¶3ÓèBäîºìpÐ'f‰ñÒ×Rø_˜ÂrMÑ\©êØù!ç1^W›rÀKþ"°8UXÞ+‹ rVU#;–€¸Þ3†’=Se¦U…wïM„+êw*¿=£*†LÊf¼{@“O“š³g•SöÈ~àªJŸn¨Sj›ñÎ>ÃK•?›£Ùó<¦"Àš+[zpüë]Ÿßh­!4-Äd çVÎS`Ð7^8ì´† V$纴ç‘Áa9® ?¤ä—Ÿ€ðˆ”Ù¦} @~Ö¬r’7PAŒq®é¾$ô_-ü‰%Áu ï׫Á^J Î÷€ºÜ€Šóá˜t쥽„¼€òö ¹Þ¢DÎLƒ\Û|m *ùËþ¯j÷åAƒ@~J0JDbyÏ„#ë$­ ø ]é™@˜2E†9HËÿ"«ÚK;G8çr~ àK/¹—|òÉY§Àê/B퉕Æ_j…䵺ωcûǪúU”pa•ß{(¥rÃÈÖáG@)<Õ6Q¸~:rHÆÙ½2Ò.3/B=ž*kšlÒlü+G"ÃÀäÄgYÃÅúÙ÷iÞ1=šýÄ•þŒ¥j5  ÿò¾Ôóáù/©WÚ§ôSí% îòÌåEþ—u¤0½ví\sçé|ùe€fÒîÍÙ2”"°aP“-“˜Dò0g=õ‡‚Õæ)¬¸ aÙ…‰0V奞Óo­W(4µú)k’-î¥,kA^—W:4\:¯¡µÊÞK’ÁæY?'¯‚’ÉýÖ­iõˆæƒò¡¡ò^ î*$Þ"û C&"úfN­=’_Þ˜b®Â'÷^røÕ9wMŽÄlj$>rk¹2æ?n;¦ Á‡‘ÛøžÖVšÉ*…ÑOïáœËyºÝîî!ñò,ÄHœ"˜š¢¨q×%lmTs6H²±^¢†=äÕôI_>ò¬”XÙΠˆ›‚DÓ+.)½7=8ØwÝ÷(TØz9w ?ù“M‰àÂé/ƒ­S‡Õ@¤©%7òÙ ½}ÀŠh¸,6¢-Õ.©buFe 2¯x’+R…¥b?@€Ô'\è~gŸáÝÙ“8UúW¾õ*Å$ 0º!Â`àšiŸWn:ÓTç5Ç2OKÿ"9kR»‡´ÎîÉÛw6V “Ú݉¸åšŸk‘ ={ðöÛ‹3=ä=”óÄœÅIdxgk¦¨ƒR¢×Ö™ ’<¢&鉵J{¿ÁEx"²Ó=é‡'ÐBíL7¨þ-Õš+À½ 㪌¦òpî_"×Ä\ƒ„>°¸¶1Ò Xpe¿U[žãÔðèâïÔRÓ( weyq¹Â/°¨²Å5 `Xw(ÞcÐö/ûY&–ñ×[F3þøOýÔ¹.®6é'4¶/Í:jqc€ýµÈß\€Sb¸Âhe™†yílrš€”¼*Ñ+[Kº„Ò?.8ÙÌ2˜XŠê.GDooM1ò;E?*.ƒzÝ2Áþº¨Ülª½OHR.PÜ{ü#-µ¶ –’ë–âj×b8™¡¢ú‡ëaÛˆÂÃWkI1ŒmlÌ(­6ûb®¸×jôž¡›TT×!ø\q)’K±S¦b©¼YÊ  íü@ØDÓM µÅ|õ2ö?dmõ”q8² #â¥YÜ»3¯A•÷Vª‹ .)‹_Á©šª¨WâáÑÃA@+h)½sÍ«zjáj§ç§††¦,ë0$ø^tZzã¤g”¡Àá{é3x7L/F!ö$D¹+’1 ÉÆþ{xä™Ë¹2€—Bãö”Þòi¥4Ò&Úi3Q@"`(çtÁ!ù¶ÜòwûsQOfz¤¶ˆ½AæN\{&á5¡RåwümnªÝ‘\tY&d©}R:Tžñ^Œ $1Kú@N¥ÀGEÞÁJ9³dÎnZgïÕKö ÛÚÇ€ûýÒkh~zÇò¨z.<~í¨¾¢ôÄnˆ[a•+… f5ƒºÓÞE9WðÙðq{@Jcoyü˜"b~§NC/F¥¨Ä«ë¼ÖÎO/o´‘¼K†#l¢ réu†mƒ¢Zö’¹œÀµä£Y’d¬-ª—ž2]RzÑœ÷8N’S²¿ªJKS¢ Áõ;»6+møØU’!TT‘,ø§Ç5}=£¦6”’¿<¾æekÀ&%F#Ëa½@LQy# GyÅçS.Ä`¨;¶!4ëK_×YBÇ”3¯\¬î ¡•Iþ¸ô6ë>í«’òÍ#ÉaTü^JÀÓ¡õ˃+f{Ÿ·{ã"Ò^Pœüüe%5t?©Eé#·ÙÝL#@,–%Ï]XŽT®$å)0‡Ôóõ*B¾ j˜•ô 5Ê >¾oßp@Î$\&¡?¡êHCÚûŵé³îú,p…BêK °Á™¶‹a°Öк/~À€{¥†vͨlç0óÞ+ÔT»à·÷ýâNÉ5ÂŒ˜H3ïÌäòËÇ¥ªÆ¥¯œ2߸ I*ÿ@…´+iQdÀNÜa4±¨Ø¿§ªÕÀÅ®Åòe¼¨(µ_‰“pyŸ_xg1BÅë–Q9©œ*Ã¥ä/Û¾¦ ížg ‚œ ]ÐÿMÉ/?ë €òƒ1´W*?@–à&×fÝc˜X7`‹»§vØ#(çÍÜk§‡E¾ìUÚ@Œ^¨;QÒ9l gÇWˆ?¸ûâ F[ß}ª’«“ßçGVd³ü»‰aâ~(¥SÿJ(IªRý§Ñ¥{U ²ÎE°hN*íXˆ³’Uo{)+Kâ¯Éðžoªù†KŸ¯¿~æ©~IüÚ„;x÷î¥s.›>€[çßݨ;”† š '›¸€r!€¾z}fu z•e’ʽm«ei†¿Þº™Ó$߀V°°•ì¾Ê3ƒ”©X°ìJ\îú=!?å|Š÷KBƒ áªëû¯«q¢GX©-Ü«HÔ’ôÉzošUƒ&b[×x~÷â @74}½,ª­†¤~鳩 Uά{À´©–$×ÍiìY(Œ7šp¾K‹Òž}öÀ%!R!®™Äî´ž@Kk{È#õÈëe_’ßIç ·¥$ô„>$¤)Ï rɯÄÏõ)%7 ÌÕ«£g*å€è`ah–Ý"€È»œ>Pjª¸ö”éQI¨Je ÿuôUô@šO¡åºP٪ʢ³z›²;=á÷Â/‚)ÅP•É_¦³Ö°VŠŒV˜Þxê\÷ åB4\ÞÜl—ïhñ©×ß_3Å<Ê/‰>%˜ňO ?úÃuβ¤¸m%œ™w­@í<ðÜšï?42ÿ¾T"²ÜœNˆÍÒ›Ý[Ìõ—(ùÕº 9çìîSºVVÚ)<$2Ÿ¿Ì%š;RTðªÝNƒÏY–ˆd>ýÞÉ x žø^aR1˜Ù¶W®ìç»8ïíÁýçêÍÛG êF„&íôR¤0,ôú¨û!{/þ<ÍÝn²ÃužRl Fu#Ue¥‰‰É¥Þ¶nԃő®¨TÀÈgdEм¸ …–稟êReW¨*_ªuO9ÇIŠì ¥$¹™g¶~¾W_ªb(N,=¡f¯çŽ»Ówïaøí+ݯw…¿ÓÖÜ5€Ú@·´Í_Ëy{{F#}”%ùÌlàJJ䲓jŸkKÒ*lø^ÎQ†‡Ík ÊÃs§ôX  ©¸âÖÓª|~%åX v¯¡ßò9÷¹¬¬_²-ÙÓö"•»4–„IÑõVƒÛ"¤Z2oê<³PFrP£ç,ª÷H]µ«p!*äŽ(·¤䘞eÒpvO™ÁŽlúó|Ù÷“Šï¹ºï6åsÖÎ×ð#{óÚµ™jÆέ'ØÀ)¯mëS4€zÉ]~¾láS›²^òg¯Ëùw)I‚d¡°–rÞz2õãð{ }¹œûYäL¿Ëj*Vmve­Ÿ‚Ò¿ŽO:áj*Äà™Œé cmèsËú…%a² øµª}­N>ýš°‘Læ¦öÏÉ…EZs¢t{8½ví›Ç €—^ZbccŸ`ÀTªáCÀÍ»-y€‘ úqn½ìs6–*6nÂÊ$Ì jœ$KòÏ÷­!þˆ€å½Ó—~a?DWf&…$r{–[Ò±q< b }ÑcÕMaód¦AÅ—} Ÿ=àá üó,;úžf6¬»' þ’Ñ„w‰œ ¦½cÇ“ýÿà©§N†úûQ–sea:‘Q3M:×â]Qù±‡od’þ¶6zUn ¿Jó²=ð'PÝÞ©h•E:qfpï¦p¸Öá=Ûpý­-ýt_g,2§hÍr)¯­}fEÕû©ææË=ùÔ¢¡±“µÐúó§—õ½u*޽’i4ô¨9Àÿx÷°-y7å"4»³3Sl*‰{knªuEüÖ•ï.äXõž™ÿL“Ö'h@`×`Å6d"/ù=€¤¤ë(ÔÎkòz dâõnÃêD¦²ç*`!£ ¤<á©’Œ¬¿t©úÌìùÁ~¦D|˜Wt÷ Ä/‹=Ã5Tc0;¨1‘S÷Z‚ œù!8ä©ûÆNR0+7…)¥¬úcééÆa•?2j¼þ-3‚ÉÆUáêË¿» íš-¼ûÏÍgÄñ®€:@PùÃ૨í„T_cT ÌMϨír”ÇIrîÆ^mµÈÓgH{&«j-„yS>&ƒæ â?mk°Ìæ/½œ<ü$™Þ㬦@½ƒj‡%ç96Ëú³¸†¬é¾ÿ;–Q€çmœ?ˆK‚‰4©äíIȾeÏ+ “üâ2[ óÕ¢ŠŠ ˜çÒd×Pº®ÚºŒ„*ü$twT&}ý'_oè(™ÉueáÓ*™UÅEúeõs-÷öè³ùñòB™úï,…uïgr‡õÐÃX5ÉGåþ†,QñVC*~'P<­Ò™µ^^SD_öþ˜&b‚·Í7K‚q°·‡Ñ6Øz)…ea[íðpÌô&C<޲.±È'žë#Ùi,ä"Y#NW%ŸU¤5¿r•ï qÈ ä}û¢Ê™Kظ¾Üß@Çä8¤¨Ö¢'ñcŸÖ{C$NF½ïÞcŠ[Ô—éÉÒÎçâÅ÷¤ mj½­¿Þ“ðÐJ¹ì£¡)NnºPÓ‚Ìb}]¹8@©»¶mQF›Éˆ·\•>¿°`H|B~ ÙM¶ ÿz¬AݧÜOÒåAÏuCyfÜlýn]gˆRµô—ÒYH–K|!\dyë@A¿:òïƒÄo©aDu]·È÷ÈÚêøïµΑ_ô ׆Á 8ÊÆPÑúbÙVyºž%Øfç1pürWß)IF2EZ¶%HþÓóüˆ—„œLìXyýöLLV–ËS1¦¢H#|HG®M¸ìt²Ö¥«/¢ L…tÍU!øŒzÏ©“L‰ög׉W«iÍ…76}}H™™KôÜ$Êv%ãÐW"Îx* "@©ã–Gûþòo À—g›æˆÆã™fU¦Ú6hÕçëD­<ÁJWŸ*¤«‚-–óÊÖ†G ”~*ÉW«]¬Š[¡êTä*s‡HHuïl(WÆE“ Öá³oág R®åŠeDXÖ”×ZÁeý„ÀõfZsám¯¯¡¡1+m{÷-õ \]ïÏ<öµz|j}þ„£­ÕþÝ×_?jã.‡üäOvjkëØÀÆ\Þ’B†$¼'Ã~e QØæ"û(ªÓ`æÞȬ[š»öÆülE·eB_àg(ÿ‹ ˜˜aUWâ×qB ¤Zn‰È~²§ÄÁ*[šL¬Š´=À —´§ö@ÿkZAÆ(ø”?rÞƒ0$?F„ÔûU¶Œ+’_â}ž{Ÿý{s¯L­²v2ƒ›öè©+WÎ}WàP΄iDD†7wö¨ˆ®Ô7ì—8´Ø8Sà%žb‹Ï²(j·¾û÷®í‚S3ùåe½Ï³Ê¹5õªÍ&Ä mFU×c8¨T[Ùu5†Pþ^ïMYï¨÷qþ Xr¡ •ú‰ûÌ9©'Â匨‡e9Å;‡p›ÚÑØµ1PãÑìÇê§.d)0pQƒMr>Ÿ)ŒR~½µÒ¹´çkêHøA¨.þñnƸ‡jL n½y¦.©Û³éhZ,¨¦¨º¿$}jŠ•‰î¨i Ÿ-™œk®•Sa¿f&}°ç¹W xÉ*ou&hŒúD…!øõ¥›Ó¨{<òæÖ¾ë£`ëKƒ‰Å7ÆÐÀ¥d´Ô«Õ·ê}¾3ƒ•"°Vûµ¸8ÀõÃÆøÀoVYhCM“¸@ #0ú˯î¿J7öÓzÙßÃ+ëÎ!BjsÔ9«:«Ö"FÄÏõÓÓ%9ÚÿÌì™@qOu…»Šâs”@XÒ)êàÊ÷!l½T˱©-.ÂpõúJxЇ†÷ŒRœåëH…Ä÷ºu/ï‘ßú~•\¯ˆšê…@k¨Îβ Ϲ\ø¤3– |Ü 6¨† g ýÍ÷÷Co&ÚA~ªÄ„¨l7”W3xTfuyà|­Åú¢$mÔ/´”x †• qdS#ñK„žÂ5/OkHâ¿×áC _ɲOÑÖ3o$Bê÷¶ô¿ÝVqe•ýÖ$³I­gñ—ôtOhA®ÕŸV‚­¡("V–AmóÍǾ-ÀN«î>tHûýB¿ça¼ý?µ£ 9Ýk½?Ëíú#¯AöjHó©NüCÖ_)å#ÍÚ`oPoø”®¿°ÛPܲÒÊ”»*;ÑVX«rBWìüµ©Ì„ä?;¯é¬g\$ÎY«°º>@j¥ê_Vƾ‚–€ Žç-R?['à"åì·„kµ bb(ûÍd@,© Ë\øTx£££;f<[¹˜ÕÜ9IqŽi½B9Í·ß× Ý€–ë~Ý`?‚.Q¥tñ¿Äw7ŠU7¥q.BUv>«nÁŸªœKÔÌò?*’É4ŠÚm¥ý_E÷‹ßò-3m¥Ò¦µCç*¡ÈéÁX÷®Ùû¤7pÈÇ“Šóù™:Ý–¸nÅ’k ÛÙÛðâ7øŒÿ4;›F7 6`R ¶`±oR²žMqÞb½„ɽ A#È¥þi¯œü gÏŽ[¢ýAÃɳBep™˜#<@ļÆ|qƯ“~ úæÔ‰E‹ýû +©¬ßõ4¬¹»ÂqÉ4d„kÖ=¿Ä &Buƒb× „*.ä¬Å¥× w–ø@EÆ'-¤xš5–X´Y=xw=þîÊEiŽô®>qd´[9-ë œ“ÄåT}ιîåŠ8åÕîõùýó%C¥þ|Up/±D®.ÐBtfÉQ²]**Ï rG,>Õ•Fg8IgëçZŸ i 96ñèĜIJWZBåaù6ý™ÅÙ äÏ* ½iîsž5ŠÜ¦ z{óðuÉ™ÊÅàOí­´F˜ÑL*JøÔýE~zÎíóa[¼Ürðøa>Å[ŽÍî?m°†Æ”Nù-+à¢Î\Ê<$³ÇÃ[“øÍÕ#^Ы¸®-”&DmÔ,ƒ,ôÆÖp1K‹c Ýl63a(M°F€¥¶ž=5¢äâ:¿¬âþ îÃÈ›‡Y P»½bùÚô312KrÑÌb»E²i%Æ> )¨œ*ïOÙt¹0ªk½Æ¨èÃô°ÄÏ£Ç^ÅvZë%?É!¨él«°øN}Fié'ï@Ò$PzHz•øe¥«Óã}àb–¬èk×f¬•ésb5ÈófVój£Oðgy-µÆ®vu2ΰ$QbÑx[‘Èiº¨›Å¡ `{@!}dbþ¬/©ÿ¼'ˆf gå“_õ®ÕøŒ/ ÔUÕ@ÊW,%?¡·L˜kïRPcHØ~®qõo–^ù-é Ã)R‘ÎZ£ºù¬8|®åB@œ_W®Ì˜šy°jXu¬ž8ŸKѺF0\†ÌÇ×Ϫ̃GëLà”… ááóÕÄ[­=îY* :/·,/}ؾ>K‘üHzúJ<“¤z¯Ë‹ß¥—äôÆû ú™Û¢‡ ÞyƒN5[ÐZ™ñÖÖ7˜ñØá@9wåsºFx¥ µ[üÅçÆk“4¯ÇTÚ|f {‘ É+&OV¨Ô=4[¤y¨Ñà¾Ê+ÛÇé™\œ’es{yË{ò†œ5:Î.((.f;ò7GЯPS²4æ…Ã"0ó´v–&C –ì ˆcy A¬“ùd8@½»Ï¥\¨ ð¡7Þ8¶£Ñ[jZ“»Cî·³®È_Éu¹ËìÊ{*¯]æ) ÷K×ãé#RÈÇÿ(ÍoØÎ%5U¿¶§õ{)LE dŸA…kÞúaŽ4§o®¯‰?(Åž÷?ªÌÍó¿Þ’aùEƒÏz3Ù‹É©(2Í‹<^ÀW~d ÑÞ½ýýý¡÷[É™1‚âU{ïjA> ÖŠK/¤\K‚µÒ a¦t†7ç`!çú–”*®M¥ïÅ ên=©„‚2ýx(I(íÕžÚ#²¾1ÎTáy°"48ò/Da¹šlýŽª hœIÒ¬¹½Ù«Û/”¶´¼—×Há²ö µk‡´ jˆ>…:© r`ßÁØw¥ />kCvmr*qj±ïb ßå®±MÍÅæ(šz¾åSþÓÌçï˜ÑÖZï׈¿æ7;-{(u¬]“FKâgoñKˆåý‚Ùô|Vy¨6k ËÏ”z8€|\Ô·½.¢*×ȯR'¤vMœýõöK`”Ì–·SÿõËŒ>µ ?Eô¾W! ùÉi|=Ë=”u¨Üô"ÂÚŒÁ¡ -ˆ½§« •?2&1VUpT)XÃwàÅ d†|&¼h£¬VPÌ0”lï| ›Çs[¼¦ú;ãܯ 4ÒýHáë=Vä pÃIönã}rK/ˆ–e ø8üöà SdIÃ÷€c‰¤mRÙÒ.Uù-ÙõYd gjŠÄ$âg¼œÅ5>Q‡ÍAS•!K\cÀ‚•D¸8,5¸Œoà`Y홥–S†ᥲ¯â-"á !+á¸úCÅ2+€tw\.Rp²îú3‡éèá”^aN÷=‰+‡> „ÄWû[å¯Z ×ùÈø§Rv…`%¾¦Ÿåí¥ÁœÇ „ ½n§àbdTq?§{•:Ãà­›ÑDš§j9ËÉK\ªŠÅš´­ý.{pýIñ{Íœ#ôÃ@O>kî©ÕÍ×Õž_»×–_u‡Y¨]h°ö—×fÖ`k ’³ðÌ·¨'L±š_œ¡½^Aìy®Œ!ˆo3†Á‚ÚÂÚ€þJ¸1…³^Ÿ†+TA²~y“¨3‚o±s`ý_íÖ\DÆzí¶r9«ì±lŽEzO°ù«I=E9-ˆ¨G”Ô'Ä7_Û¾uí©2¯9Ž5ç¨2ýJMÂdPÓé!|ñ‚<ÀÅ2³³±×13 ˆ¬ñºO}AL>¿ËH@Ù‹ŽˆãñµR¹ô ȧ äŽu({íBˆ(³×Þlÿ؃^ÿ)Ÿ¥†n°w©ýTšWfÕ%åØKôü!¬Ó³ä÷¯ª^•*”Àâ\])‰]5Hô•¾_§UÄ6 \#¥|±Ä%Ë µyÝ;¯IDAT$QŒ±¬•"O'{gïÝGS.\°o͘ÑÁ&–X‚Ð}<>ý/.C²e£$“ùªa]€ÀpmÏTȪ×0lΑ*%½ ‡¼Rb–^¾ÐÜŠÈ­2¤""-"ŽÜïܳЗ„“„¾âZuù=ò‘gÕP'zÚ€ɃïòËGj„]Sî†Ì*0™Þ½C YE]ÆZc¨=¨T®åÂ@Äö™K‡ÜèU'øn+Ÿ}µ+-& ÁD‰„Ïú̈ƒÅÉöÏ:Ê¿@ßCRz)‡‹r³‹j€ì4 wöÉõ‘ Ü£0TtB ö‡ü⪠©Ìôï9ô­EfÏ“•`‹ó½@*Ï8õ9ï½N (¯;£èо^)eèððèô|´åÂ@`Ö»ÌVëC—¬¢/¥v8Ÿï (ÝIœ…§cÃ%ΕþºbEå*4kû85Ÿ±|‰þ—'åËL€¼'ò³Á¾òËW*D–ç9óOÑÖ•³0ˆËx–×2ÖYC؃ðÊžy(ÍèaÞ;|ä~q}K'Ë+W.t)0ð>˜o4Í‘µ{!%k윚ûgá®vÍõ2@y}a6ˆ.q÷kñLÕ[(_jÖs¦ÚR ³ÕÛTi€ê œðTŠmwcA)ízweÉBÿ±¿V\5À`£Ó¯˜™_“üCÆ»©_ÞSj›§Áå¼5Êaåq¬„Fíß?<<8Kݲ\8øáŸüÉÎ6ÍLeóö,/-ï4u;¯¯C0œóïôÏÜ °y•¶~§È¶—Þ§‡ õs¦N*tï2©ô‘É^ËÀûîL0‹KñÞtM‰I†19ëfž§ç»-=ãö0ÔEëêF®5Èã§a´*Z\ÙñPˆ¥pð;Ëå…í ÊEbNˆÞØœÁš`ñ÷³ØR½NFdyÍ=îXZ2Üïë'>|æbÿICÝ%ôþ…}©%i Æh4[º zDpoøÅê÷®È0(å 5" Ëó@Ü‚|öV+µˆCyÿ©áÃ…Zÿ0„ϧ[7_†@¡º­Ê‰_~² ×Xß~ =û¾p¡K‹N Ba¦Ób“¤GP£ÏXOÍõÓ‹‚C&†"© °8Þë–š *ÜG•ëa{ÕÔ“˜%1M à 2@)ê¡ÜÇ u¿ÚyröÔ˜‚n¨ª\8)^dÅ—.F–òUB§aÆÂw³cÔÿ~Õ¿´ýËßå÷¡:N»&s õÖøµ öUC³‹Ü8”‹\ ø>4ºÙ÷1|Üb(Ž< >?r×w"yîHØåâÚøÕÂéaÂþN´PQЋ†Ã.Fn=º;e­.âÇR•¨2/³LRŠô¸> çâƒ{é¨,„ŽÉû©î ¤øéK;.ž˜´.Ì‘šT*=&Pn¹“\SPEõÅ55÷bhæ:iÞÿð.ÔÿTÃKs›Ž³"M>(.Lr*¢¼Íá:¥÷ü×uk y¹P–óÑñ!§°r‹ ¢”°\f«–Á-…Û¨°§µQHþÑoM)™ih)mò žI½’Ëü‹ÝÀpªM!‰_nx(cgc…( xõ‘Û€­§ ¢ã!CÿÉ©µ `Å ( Ý/…Jpª Á$Õ]Õ=€Êü@ønV²“ú!øTQz`ÐïcyNPDLŠ`¹ð¥ÀÀ›aI0µ´k´ÎF®gw%Ë.…Ë àÄÅû—¹à³Š>Ö—kvŠ'lÄú¸€ˆÏ |" LìC…9­/²ˆALK…³Ø&ŽÌ ¥ïJ]•½ùZ\ÛÏ•ŒæËf<*ð0 â™®Ÿ55\^耩|9+aŸõúš”çÚ/*¯ÍUüð¾g¼–NÑÓ‰*¹%úí ¦¢2æ.¼øÍ¬„b&“ýNi0;*ãÌQ:‹D Ì`fXfÏ<Ÿ;¼–6°Ô¢Y >3}kL ÌLäw2®$/ôX!ök@m%{1‘- †X^´$M!6²–k¾8(a!÷`l_wÅ^ÏT·Þ.=3cÍù‡Õ-†¥>÷.ȹ¤ÿ„]|â¹rþ°áóÐ_ ùæü¯ìjvúŸm¦÷ò•I¹Pð)? zczйyçÆ `¥-CüŽÀévú´É–0ö%Yíšr)°¨#D#F“ ²ïÀÀwÄ÷÷“Pq_ ȼ"¡IÓ°SöDˆà‹²MÔû• œBU‰ÄJKa})uZsþaÅ`‰nôÎ V\bûÜ?µ6ä°è»òùBkªY£ €©›»¸x`¯Ý˜u¤?ÉZ¶J¥ÔÌ™×+Ó7¢¬¿@å² È8º<îŸ>2ÔK¼( ˆ  LMÖÛ—¨ONJ dƒF Bc3e¥ Ê>B{zéÃTÿydSÛY ÿ,$û¾sM@<÷´)Xj1sgý“A‰WÆ1H[EÌM¤~S úk#4çí&ÊUúÚ‹dÚ‘ úð‡Cà 5d% ÍÈ-E_Í ­V±ºvz€÷¡\¨ðÙ Û罟¹NšÁú…D鯾°¯$dÏöÀ[D(:¦&Ñò}{·¨òhËÚÞP‰)ß§z¬pùr)u‡Û»Fö‰ ¥E`e¹=CFôœ®I{'ÚlEùªYla³åöö7¿ Ê'žzjéæ°ÛC;HzöÁá,'¦”QS‚”%w3rï×P)ÍŠ**¯ä°¹©¼!EÖe»Ï—Ÿñ…匃Œ` ¦h#pJ&áë»ÀR2†*FSmoñy–ÊQ\+4yÂzâçÊùª·“‘8Û|™7‡Í/½ZA¨&,¦†”1ž xŸ0ú‰ŸX±n÷I)@¹€`†#ðLå÷i¨ËA+\’vnb×[Òg C“0m`2TKÈIX Ý&ÁPé寳ý§r_D –t©µ… Üã¢ý:Î/ýaMIôrÑ yÝ•9Ñsû毟Ð~Î0Êô|!Ù³`³&Á’vh=,5ÆÒëúõ Ý8”‹Ö一lÉ#ÿi eÃäâm¼@ªV’IôT±¢c#.`K3¢¯Ì¶´ ^œ.Éã sܲ¿¨h°s(U3°H¹—¹®¹+¹¨;-ëõ4fr&X2MÞý´à5džˆ?S¯Åo×_…Ä'€‡l Îë }CÈë×fL]Joi·såìû‹“¶Å^â3ûÅÿ> @)¬ÐÐ À€+µ—_6âÒ +ï‡ àxáææAŒ¥–¶Q`äcåÃŒ(lડç^ÂX$ &°nÑuoÌËÈ馇«¬„„$$ —¯a$´Åï~[Ý™ ¤‚d̸¸)CÑß})û¾&tû[¨% //.™Ay(Ôðšÿ]˜‰Y"—Š& …éqIR[DdF¢GÊø¡|ÄhøôšaÆŒ¥YA@ò×E– g/…—¹P»0íý*Ì ‹àŒ¶?“sÚûå”™%¹u8Wùr¦Ñ‡Ÿ*€‹ %þb–`Ή9ÉfÝ<̉FÜ_ðÖŠmR[D)®ŒhËNgù÷,h¨bòÍš…!PFX…=Ü«Cô)ýÎå÷Þ€uC›½œ®©þEu0%©í9N¨ÖñýXB?™Ð•ã‘|*K!ÄÅF³Ü"ídäÎ%%žÙ"C‹I2¤E9V\#ÏÂ-’ ZIrVü _â)ÆÅ…IœÛ­å{ã”c¥Ê?hÿ‹¸‰žz¯Í³:§&ç9K5ÝDk[ 3œß[¾'gÉ]$¡úï”»oYI¯‹Û"i ê1Ï”¬"¬,îúÓßü vॽNÅœ¨YÇx_„UŽi™3w äòÌT™,ùïÚ$C?ÜûgÖʉMâ†Ü]-×Ô‡"ìÊ$|^Í$HòÇJŠ}=N2è6Æ'äiÖs]áôžñ0Õëâqò-+ìz*¾×û7°>Õ#°p¾¦QXÑAR›õZÍÜ¡ø<¡½Ä¼_iïYwÿ}Ó;[Jj4K•¨ÃóÈµÍÆ…¶·²#À%V^x¹èœ€qE ì¯`¥•bËL.ŸU†Ä²_¬ãC4ËIeˆkj§ †UyU)Ϫ› I·!!“ë•“”³ÞÖ¶N2rX ¼f;m_ST|vm#–~ åsIJ:q.´=³‘žSJqFŽ=$¾çÇ)Ó|rõߊëñ S)6@b.á¼Ì×Üדœ –»óB½1pU¨Ð)5ó3æp…ÛÔŒc>ÀÓ†ò‘— gŸõý:ߞ؂­rÈjȦc¡!2 E!ñ.¥(XǪŽ\L2ƒòÀ.&*3¬%%t×rÁ‡s[å²/§ó¾r_fÄ•;T@A#dîÓ^é¥ÅÎÞ9%´´± åÕãÄPYÔ'Vª²üLm©)ÚùRe.~§ñ±ƒ÷¸!·> h iå#ÁiyŠàÎ q|gÑ7œ6‚˜• œ="Í ñ¨¼·ú„.瓼ÆixiN3k S£È2ò~_€÷ÁÔ^½¹o”î˜9tª“·Q­è@¡Ö&à§o öÁ!AùÕiòP¶Ãi×%ã¨ÍŒ|…â/Ú]ÝyU ”«'*í¿g­ŸÊ&jÕÊ%ùU )?ô™ÚXÃ9†>ÓX‚.â¹07‚K”Äq¦Ö@߯  £2+(7騭­á ²N;pmPõóº\ŽGãÛ·bîÌx¼÷©\¸ÀÌLD8fÞ'âcŒÜš”¸v@  áÐÑ)gÐ^³˜zabô4/‚°6 KP*w‰É$Ð$þ¤’I»P!ª1UY¤¯<]tXp¢ÂûE)^dJŽë ¼™PUÄsEFGÙMRÂ"/yûæG)½{Í0‚¾Ê.³-×¢åR7ûí+Ï”wÑßR(ô²Wºˆ_ÊC…ðË:ä¹Ò¼ÉûE¿Ã'Óƒa¼Ð¢-—ïK2à}`5ŸüÖoŒ›v_ƒ.[—šˆ“jö¼è<id亾ó* »Þ*\À]PéâcNþc)µuòTH‚°k‰\!¼ÀT$Þ"î^½„+¨~bˆËÓÂûßoR ”ׄ-Ïm$Û8REÏÉ ¸?ñs,@¦Ä¤žºï?%QŸè«Ä_\¤û2"Vœ…ûÛ<¤ã†±NÚËÏ\©1HÑ'b°lÖ7¼?»³|Ðæ *ï› ð'>úÑF°Ö¹ü¬ú î?$Îlüñ°ZСî£Sßùü…ARá{O‰!XÿÀ(µÃ„ŠàsÐÝ¥Ÿê‰QpmÍ…Êw9Á$®Åò:¹Å¹àn5Ñô<±ž¨ Ûþ…,ª,êN)ÑÊG…éX? XeãXVŽ—XRZ¹*²TÇe˜ªª®Ø/8å˜x5û,î"þŠ(Tý4N,F”ÕJÎ;aüœt°3[À6Íþoo®Žñ>•÷#Àõ˧?ÝÙÍ=°Ebã7 îËßa­$fG½!cát@LÅž2ƒ-‰SÎýÄäþlZèl’TËOø›²öØï‹‰$f ‹ -Ó•.Dy4gÂmÔƒðkÏ©.C\×VnÇë")ùÏ92±fqH‡>¥ä޹¼™e7V©à³y8‚wÇR†©2agú¤*ñ'ÂΙÇËú8†§ 5cÝ_Œ{²¹ËÙ°9øò—¿ÜÞ#çS.ÞpÅip«Õk c-Hi‡VÃ-ÔpšqŸKä_#¥ö½?§D2H«@ Ú‹a·¡2§žeŠ÷Gßd¬Ì/ÝÍ@ÒD€e†™`s»>ŸØR†Ï—#Šó rwd®’÷"^ý‰¡}z$&të`2¬ .æäº¬.Ï­ÝRtg_¥ŽÜ7þNøLŽn@%Ï»ÜqË}K˃9ì] eƱpI¦•ïAùïšÖÌÂßRš\žA°=z€¾‚qaå}e+¥÷Gä6«¶°P^’“Ïcð= ˜²iá\A,À«´1‡´XËl1†ÙCqpç¹L²23þYŠPË‚å¿P¿ .òÊ; ³c<¢)TÜv‰,kÌ"î{Ø›€ŽûŒ#óŸ—Œ&¾·ßŸ®|LA ®_DÒò@0È 7·÷¥–Õ§€šäLFF"r.oDʆwPRBE ×øß,)53ËDŽ qk2)*^Ä„ÔÌ+:ÎIö¢Žì~rK7°ïùú'`(ïK(pXÈãv7ÚýÖGðyŽ×ýbU °°°ÄèV †9].kmÄâ@H»Ÿ‘z|AL@L ˵ȵÐÏ·b’­“,ýÖœ© ý›‚ª­RSxàRÆŒ¤L„!AS)@Ké]r‘šFQ# £=±×rfòõwÊú³$â^ׯ ·åÓqë·m Z¦»&ù£‚bbŠõ<÷i2¸cŽ]®C¤ÐçäÒK¶® h ZBX3 Uxû8€–(uý}Îtàè9`a0È»íÈÅŽø¡R¶Ly]r›¿"'ÝJ>ôâ‰DZpÉš(xÉû`‹:‚:.éŒr¼ýLùªÊLªÕÌáòÍÈw[.I¹(FÖ—¯¢Ì“z'‰_îûH¨!¯S˜^÷/tˆìùåõåûÈpÏãØ’Y¤r±Š~KŒ&µÁÀ½U¾ÞE–÷ËpÓŽï.•Bg-)Ò`AØðqЏ¦àM;v9„a°ÀBâ N*¬RP±Ê"èB ^-ÔÝ0I #D¥ !7Ñàöõ bê>{¿5E{±0óSÃ*Q~ë® ñYnB ÄInCªaûX€Œ¶ËoÈ›’ý®;…b{oä‰pÍM%ÉÛHƒ×Êß™>@ü’VM–’9UÐøL¹®ÊïÔà-¼å}a_ üæS÷Ž_Ì  ê[h¸ÃÞêW†Ë[úÖFûžØ™Žä­—înm½R f€~¬~X‚jü1穗Ĕ˙YÆ¥“ö:ƒy¥*Mö€¡¿ŸRøQ°ësOO¦ • 1ÆL#÷Q ‚†'~ÀOîÌ7Þ·›³R£ÉRk‘ïèÿ“·ÕüùééèIü¡ÇÅßI%Œ÷1Ê:DýYIãÈÌ ®› 5ã<^'ï©t¡uÇú¼ï[évwMŸ{y_ÀËþeÍtúºÑ+6Öh¥tXè©‘KFŽ œò@™ëuŠ4±kå5À…;M!¬-ÏA-g¨€IõYl §1°´ý’ìýÎ\áĘàŸ@f6˘AÐDÒ±"þ3;:Hÿ;gjª®>[>¬ͨÐ~®F7÷ŽIÍCnãu–½òÏÜ5ÃÕk„9XCï¹_wUâg÷åËå}a0:ÆŸˆÐ ïº^5ZµFiX­³xä…ýÞ«xW…àïüʯÜùÑO|âÚøøð{ :Ã[KLH:¿…C£¾À2N®ä¾pð ”ßu(Þ)Q4*nág4{•AF Rvƒÿ*>S6#·'^´¨úU´#Mhª0p£$^‰“¤ 2„_CxÆ,VD¸?_à€#:kîŸ~ÛKø®bE„_ìî³f<äw® š›0Ùdþýì3>ÓÆÞIf@Mê[ÄÞÆ9äÎÚ¬‡ìó[Z£À”vµf0º®³Ö2·­nŽ ïšñÆ_ú™¯|ùQçRÞ/ÿÒøû¯¿þ¿û£ßòÕÕññ÷]Öty±a¨¨Q[¿ô2Ûâ-Ôàk§ ’ØôRÚ ÞÿK‰¸jŒ ÓÚ%àE€%åb¹½šnIHÚ’ ƒDŒL`T"*¿ ü’$|‚2÷cï~Ï%XLä"CXfo;A)BGÀƒÅï0pì×UáRuÆ•JB¾óõ‘ؘª÷•¿s‰,ذ$ø’À)s-!G²´…@ÆiÅHáafô#y½\±È?á!U~  ³†aÙ4Zk«4óÙ;''ÿ‡ÿõÍßùe ßíYÞä±x¾›£ßömWÿ›ÅÉ_½aíy s³4 ÐH7*¬Ó^kÈ^aA)Ä)xµ^ØÈ’à A²º#Ž æ^ù‰ÛË7@y=ŠÃB—þBˆúOíQÏD¨Œ‰:˜­(U®l ×êLqéÖXᕽ}|‰;J ÎDÉLJÉ^»¾o㢣Ì+²¨‹ÚL<4»þµá3¬LõŠ(Åp+«ÈÔ9¦óm …߯¦çÂuß-¬Pd.ïäâhƒ{i—I‡À×½D /JæEôR¡Hjû$ž` ™"lzN¸EH,©dEÏ*;Kh±îÒ6ÔOùÝáb¥:"ìz ¦”šPiÎe,jm÷ rn^ˆª†@ý§ËÍf“ƒ2GFs!b;µ‡†î²Ts4=Ù…_¢N6j )£3ÖZËV7º91¶ÛeþkÿôöÿàÖññWdÒº õR¾^÷æéWýÿÚÝû¸·ÿ7ßΕ»šø»/k½½´–Ù2(f‰ :B°‡£fŽDé± Îð£ëÂ0ýI›]v„ £S_HRJð6% §®Sä_é··2\AÞô™ú¦€Jò’ (Žº-· ,xŽœ®¦MÅ›£ÂÌÈ?kÄ?(éŵà¡ôéms²£éovêÍüÊý,ˆ>ùíÃrËGFà?Ц‹ )Àü³Ù?+¸ª;cÙ2›–”f­Ôéþñë˽—~óþÁÿ `'õû[W¾Oåý6jEÃsÆ7nÜü¿lm|æšåŸØ!`ÙÃjI+¥œ‹Ž¼b«àLg8UY~@‰ƒD !Ä1.I^(®å÷– ë _¤´Tqx댠òÓ½| F¯ Œ£,ªÐ b+3ìDA+œ4^ÝO&@ÌÄäË:s ÛãXœ6€ÚþPß "vXÅ·ýcQs2Yè®ç“KÏ›Ö}f«⢰ wl¬!­tK„Ãμ}¯ã¿úë»wÚßú Eø¡|ChEaxh¾|t4ûGö>wãê¥2>¶CúED+»êÜr•#„Ú7ZùFÔdQ/ô²ï¼Oè¹ÿôIæÏÜTúÆ¢[1CY¥µÖl¡I9‰Onµ_Øçüâ"JaÅÁç¤É^HráºBU&:#—œ”è}Ð 1] i¸ž«XqÎ$ÈÓFþ)y‰`^Zc…Wð%n+…¦xD"µ>ª˜Ë`Š+.eŠ­u’Pês휭o Äh=-.Ç’ð}`”²qi®«‡á¢O’ƒO2¹p/3Å|+ÃLl 5MûÝê—ßZ¬þË×þ7ÛûòV¾Ñ@(‰ƒ~èCOþ5à37Á?¾ÃÀ® C‘ÖZ5ì<Ú*OŽˆÓ’áqA& Là(… ibð6„ž£¨„FJˆQtrSPœ/äÉÜ·]IcB6W=Th ^ãðÈvÜ-Ðß«•ÆJ)¼º€éM€À¸GôYÞâX8GÖk*'¸¾&Q|JpNH`Ü ß3Û^Ô#¥²“ü}ì!÷Jˆ5û–ãÔŠ{RŠÚ£´'o&ø±°t1 ¨¶Ñ´oqçØÚÿú_Þ½û߉ù,„oèòhÔJ4 ^ßÛ;øüÞÞçžÚÞù… ð·l6͇VÔy³À úîEêåBÝ÷³Š9ÇÝ©‚žÖÞQÁ$z o+AlSJ·ELòƤfzsBQÑœ:2赡ò¸€ðêŠl/(yI‚£ŸüÂK{Êë ös-ï€hš¨'ÝÛ;°P!~¹J4 2Xk‘Ýs,7î Àf©5ˆ»ýž”+k¬µl›FkCšö:ó?üÒÝ»/½}|üßÌ ¬¾¡lý¡òAaœ·Î,PÿãÁÁë?»ðÓÿÎ¥Ëo)˜ïÞiÚKÆt`µJ)‚ö(.Xò¤BÙd øZð DÁ+Lx.AÂ(2#ðu%"ñ ‰8¹ÃóTzfª?é(ñÚÁQ3eC¤Í®”‚aÂÞ21™mÁ›ÕyÅÈg÷/ª§üx¦Ú{ô]¾s @Ádä½`îÙôÌyöç(ÅqŽÏË%0%,„Û€ÎÖšŽ”ÖJkµoͯ¼µXþÅ_ÛÝý뎀¨@}ÃK}Y>(&@­héŸ|òúÿu2ù¯ŸÿÄ ³2LŠZ­•fˆ‚Z‰Ââ‡Ußk)Œ€bb Ð’‰Ò92оiPø $-EþÓÃĹÒsà’£›FôФ¶€ ÄIRJcE„×ñ% ÜV´v‡=1ý>kÓiËfd’ÜËv0®H|yÚ²b ÆÝ|rOD{$ßK2m’@SÀZc ¶ÑêØ˜ýý®ûÌ¿ÜÝûoãð~ ?””Pþ ¼Ypxxøù½½Ï=yíÒç7¬ýè¦n>Ü’òÞ/ÚÈsôB#è[D£…Úœ„5K"],$yŒÙb<‹y÷ÏSÅñØòËE+ØBß}H™6¦_@ý볡¥`@Ø[,‹µ”ú¡`X!‚1Kf,4š!›?\J&±=AËð]vGŸ‘p.½ã0›©ð‰AÈÕ~Û“uD¿ò÷[§î3 ›¦Õuêþßù׫îϾú`ïç|(u¿V>È @nüíûoüìþÁßú½—¶ßl˜¿ûrÓ\Z1Ȱ1–g€ãLŽK‰GD!20Ì6%°ñ)¬Áð ÀþŠÍþèþÁ—>7ÝøÛß¡õdDøÞmjTgW¦câÏ2PÐ/’ábùÃå"èѪ'j‰È{²bIj’ä„-Uýµ—$½03(Vß!œbñÜ>h(Zá5€ÿ{W#ÙU¿sï­ñôÌtÏx°06a1%‘"ù?ÂßXÈRBB") ‰±±‹ÄjB~%‘ˆ $€b €ñnÀŒ°YÌlcÝ6ÆÝ3]Ý]¯º§º»Þ½çäÇ]_UÍ`ˆÇîåi¦º_½÷ªººÏ9ßùÎVÕCÌIäš1z¢#¸éõOFô5~!ñ±Tè‘gÇÖ"È©ŒFó>"̈Œõ 8Õ¼vŸ6ÚÕ®yàÃÌ‘BU1J`ì;Õ£`\‰ÓRÕÈìP½XêÙø\R+qVþ’µ—åŸ]à1îõ-;aÇNi£EiU9¹éqkÿxqé:ØAp’ìT ܰқ»¹ê}öE¦jؾzFwX€8„±=òc9ì²V ý%Rj4JAQ¯“ïQtêˆò7nS~BÂèΦQ)Úá”Bo£Æ<…4 š¡ŠLhA.¼‰_SüœŠ8_0¾L#^Ç1=þ¢d7•êJùùH2y׸‵֑6Ê¥â[püçßí.\¹¼¾~;îO’m¢Ì–aÁruß ºó©K;» !¯Ý¯Í® ®™…Ä×Ä9%B°‘6Œ’ ‰rìîãò²ˆÅù¥Ï—Læ 1,¡-2^•ÎIÜ€;œ*WcÞ`ÔûËä×kœ2Jä1#,H¼IѼÞX9…7†5ÉÓOðú€_ìŠE>Yñ€eÇâ˜Í.£×ãÊÑ?ÜY×WÌ/-};îO’ü•ä2À|# qxãù½ì·ÔÆ5ç~}GCç¬"hERÄaÙȤbÊCÀbPÌߓʃHòLÿ']Ì/-³÷)\(“¢”ý8:>õ¨È zŸ_K†JáÑa“çSÁt éÝ‘= p™¶CÃS#\Ëq‡aÈHƒäK©=)ˆ¾FzÒù5;!†SFQ„Ší‹ëõß>XU÷„—Ýô:žniÀˆÌ–aAyþæªí…û§ï×àWÎsȈÅÚf‘Ϥ¦˜ š }"áb®;Qö”ž+ÎÄèxl’Õ —,'2$½G®ø©ÀäÓ€ œ ÉM…eî ÂpD˜k£²ç‘ÊJ>$24Mí)2eQÏh/8šë{å·Ö9¥´R­ì~±Lî/¿slñíÝ9ä¿ó ÷'I‹N-¹ä¼óvPáªC„+‘~ÖÀÖ¬Bº£µšüÌœ8]¨œ4Û…ýÒÜ'Ñ@¡Ü!ÿ¦ dÐH(cÒ¶¢ÒÛ—+ˆšý»F6”£ƒî= 8ñ—·ïžŸ›è xá\)Úu dÐ P’¢jþ‹û¦_H ù¬c¤c´^Ðcþ§ï­¯¿++‹’?†îŸDZpj ì-è÷‡·Wýoœ±ïЗö`ø¼=ºsÉ."U³õSHHû»±É(æÑ“7Ë>‘t 'WåÌÞù•ïq*Dî/-xÿùf ëÀ`„ŽWú‘:„øXæù‘‘Í$® *‰š(?  ú¨iDB¼ïœvJŽV•uwέ»+~´¼øq ‡kÌûN¶ª •$­x2;¬üÇ%¦îU/Ÿîè³ ÇÖ )Åi©¨‚ E`ì6””OÐÄÛ%I˜Â¤/Ê0âd† *¡ Õs‰J õ L@¯¶¡På·Y”•÷i¤ò@áýÇ¿ÎǸ½¼‘\¯i²üþó`œuŽd:F¯2Ï/:þ›»»Ý¿ê×~Žmرw:¥5¿‚̆&#èuË+?¹±_}òSû­&ùí}ÊìªÙ2„YȨ²Ã0*vDáT „YsE½PbÇÓpÎÂs šªžòúáø$#^&Û—°GÍPÕÇ”JiÀò¾ñú1¯hxŠ")Ïi*rù?Acì5RzoÜó×.óh«õ¬|üÎîÂçƒo…·¼-;öN§´àWy_ €úŽ~õMš9pý4pî¥_²Kiå{ ˜„tJT%E'Ÿ2Ì»íK <#†X雈BE(ûòŽ*/Oâdp^ÒýýfÅž³˜çÉ!@»§cÁó’S}‚fÌ/%öæðÜ(»FlŸƒ%Éå¼ëXœ§•ÖÒѪrö®y±WÜÓ]ügäy|-Üÿ5¤5¿¦ÌaÁ-½Þñ[ªês/Ü¿÷»Zäå{9 bg-“R¤TØ1—¹œSÎÑ *»ê< $dR¶¡¹¶¬€ì…ŒíÃ?E¨²ÇHpq9hžƒâžq\Y£ÜVšÞ;tH_•c¹óùeu#ƒ…²ñ@ä<ä·µsL NGë‹ËLWßµ°ðÖ…Áúcháþÿ[Ú,ÀS#*è,Øõ Î}û 誳Hï[s>[ TGktl7.(êÆ@Ò°¿ Ü\æï z.ŠêTÎô ÏQÞ‹PR‹@‡å ®¯ã^tÉW4dVÞ“ I© (WnpX™¡ÐÁqñ†„ö_‘ÅÏi<–&)_A@`çÇo+cÌ„UÇÿrÇß‹.æÂ[Ú´Ûv¶’´à©‘fXP­YÜ}ÆuÏUtÖc^þ,¥•uµµÂ™Tט<”¤`Båq m)‘Ô¿©µqø/TVæ-ˆ6†8ùvàr¨@À©Y ¯ÌòĈïà‹?a&;©(ó-æøÅ×@4$¶Ö*m´ÒJõÙ}|8¼âK‹ÿˆVÑ–ð>¥Ò€§Pf‹°àÈêêÒ-ýþõì¹{¹—Mió\E>,4Ó†¢»­P˜œ6ÆbýHèÃWõIGá%¸Yƒ<בBßYÌCa­x­œã/âø Àe?DD_B1CÞžð{xÒk!¾.-;q‚÷—–EÞsd¡û'Ýõõ‡ÑÂýÓ"­8 2[Œ$û×~ï§7VýO¾dfzU ¿f¿1gXç `f2Ê+k“(+îrj€ò@’2§ôaJP¡^…kUH K<²Öᨠ:êõŒ‡_•ÂHüeå(€ K2ÍH9¼;?o ;qº£5šz5úë̇ï.Þ.kÙýÓ$­8}"rÐêÛ'´¹öÒ3»MçU»‰”ek­0 a 4 eP*5’Aˆ9þìIC^ ¶õ•!C¦ÿS¸áô¸0#E?’Ì/0‰³4*ˆœçÏmA’J% ú”H"ädúÎá8 (¦õBɯò,â•?÷öyÍmxþбW;°ët´¶ÊPÅüÅûeýðCÝÞáö=o3H[ ¸y$W¶}ö¡šÎ»hüÅ4€ çËaÒŠHÁ„jÂ4c :}òë½((=AA‘Ÿº£Â÷~ò¯@PCá‰á~(ÀbX†’:÷ ÂFa.?3'å?ºm‘œ-pîëŽ1 ‚Êñƒ‹âÞñÃîòWÃ)­âoiÀæ‘Ì®®®ÞÚïßxÎôÌ-|ñ^m.ÔDd-[‚#&J{8…1/ߘ;®$uŠx/ØA(l@󬄩L7nå ÊÏ*Ö÷—;3gP;fv"ŽÑ'˜‹µ|èÈb÷ ÖŒîo:i À&“ÙrÝyU=vKÕÿ·Köì{TC^³ß˜iKDÂÖ ´J,, jôóRë¡ÇX(d¼ÈÉ=À“„¡H8Ôþ{Ò/–ñæ{žÝ‡øåš0Š*v_º_†—?´¸|=€­×ߔ҆›[ò^ÃóÎ;ð!Mïšqü¶3µR>, ê(¥ˆ”o2  &Ñ)tªâ#ñ!ÁϬAx¢ÞÀX"-€#Â`˜‹:öžÞ…¼ddœ„%¥"BÅàÊ{>~†Vñ7±´` ÈeŤâ?=ç‚W¿¤#>K©×i¬µV)ÑJwðʯÐAÿ+*¹ Àð‹aû XFæ ææàa¯ü¹“OÀÎ11Zé>ËÚÀÊßßµÔý(€ìåš[]Ú` ȬwÂô ?»Zýâæªÿ™íyPcxé>Ó9ÈDa‰_ &e–€Jv?O!œ+ì0/Àz(&òÊ´ Ñ·þæ¼? `ÙŠ°‡ûNkÕwÃ#k—ß_õ>`ˆÖëoiÀÖ“:4õÞ=»¯~Žsï8¤XË  £Šl›!@˜ M N€'ì÷ Ð#?ÑØ¸/aµJÀ!Èì¬ p¿çÜ#½Z®>ºÜ½.¼·Vñ·˜´`‹ÊeEXpŹÏå«”ýà!M¯ßÅ€¶h­}¶@K\† `Ia®Î uõ±W~Çì‹Xà¬e¢Ñ'¬­W!ýöÂâ‡ÑÂý--m°Ee6Ì8 èÏ­ôæní÷¯}ÁÌÔQzÅ~mÎb9ç,”RGzÅ*ÂÀ:VcÀùiYùV[;aqNk­­Öª²ö¦G¬{Ã}‹Kÿ‰îoyiÀö<’ìùxö»ù‚+Ïd¾ò9Fï^w– JÝ4è(_ <_[ü@°Ïí»Àò»ÚY¥”}ç®Wµìþö’Öl#¹¬ ~ï /ù]Wàl¥/?€uÖ H­0äS~sÖáA–á+­ÎZ´Òê„­í ÈÇŽ,,~-ÜßvÒ†ÛHf‹‘d·õz wTýÿzîÞ™»;d_ºO™s9¶‚Òä@XaÆ‚kXë„…2J3-[wÓÃuý†--_‹îoKiÀö•rR±~çùç¿í9àwžcÌ™CHœc@Íék–Šà4iz¶þÉr=¼ú‹½/„{i´s÷·¥´`›Ëa@>ÖÞŸyæ9zï™po!…UŽ 7ø!Òj`4V†õZåÜG¾}üø5ÖÐÂým/m°Í¥œ=0;ôïèõ¾ºÏÞ›Ÿ¥ôù,|ñ€͉pòßöWÞtïòòõðé*˜“––Í9R»,Ÿ•"t%1)f¨m-’¢ë’ë²%‹ÙÌ*±tìÌ©vO¥žv¥æS¹¼Aç¯ö°õ°\þù¬\ÞzN=¬/õßÀ¼ýE¯Œ°p cHRMm˜sŽò{„Ún”å3'™IbKGDÿÿÿ ½§“ pHYs  šœ[øIDATxÚí½y´%×]ßûÙ»êLwìÛ-µ&[²„e0¶,Ù£˜,;LËRÌŒH vðJòˆ^b Ùb=^BÐ" †,Â˳!pࡇúÝ¢(öú¤.5ˆÈ&³tš¼ŠCU×õÆd29µ¾¾þÔúúúñ£G>|øð_¾÷½ïý“O|âÇ3À: X¥”„Cìõ÷½Ô¡öúoà™QÓ˜þóÀ yä‘E1Üë t)a§ÂŸî›>’ýÍêêêã>|ø÷ï¹çž_þä'?ù8°Š³*wá’°¶²öú«ÏÍ_øÇ"pýÃ?|¨,Ëù==¹K »Ðþq»µ¶%ü"·‰eYbŒ9úÄOÜï½÷ÞûK¿ôKŸNãˆÀúÇEo dØêÜ• A¿Ž^øðÃÿFY–s{zr—ÎEø»ÚßZ»‰Œ1Xk  ‡ÃSõWõ¾¿ý·ÿö=À“8× Æ[3 Ì*è=ýô!ÀWàH`–b[`;2–@Àúú:'Ož\úâ/þâïüÔ§>õ«×]wÝóqdßÇ»€jV#e1fÒô_šD)•ÏáCkŸO»þA¸»Ï[7”?FÁ8zô(óóó_ø»¿û»‡^ûÚ×~!°@&=Ã,4@JùFxŽš¡;‘¿tÿiš?}·œ‹`Œáñǧ(ŠË~æg~æ×Þð†7ÜD&=ì4H c°•?»ñ‚í2]2?}ôQƒÁÒýØýòwÜñ22 ì f…ÒBMÖþ{Ц‚°]šp» 1†|}ûö-ÞsÏ=ï»ýöÛ³%°˜è"ÿági `+t?}ˆ`ccƒ‡~˜Ë/¿|áð3 ìf‘ò|Ñ5ù»HIaÚëim@úüøñ㬯¯³´´´ø?ðrvà9Â,@Æ€4[p6œ­žàðáÃ,,, µ^|×»Þõ¾Ûo¿ý¥dxN cG8›üí´„8=N ÕÕUNœ8ÁÊÊ J©Åw½ë]ï{ÃÞIà9ÀÌÜìFÃdìÒš´6 ÔˆH«– }=ü."<üðüüå/§,KªªZ|×»Þõ>àëåW~哸Òá‰ïE]1ø\#[›°ñv_K…8}m«ý¶Ú¶ººÊÉ“'ƒ+°øŽw¼#[Ï22dì[YdÝjAhWNÓü]Eþè£2??Ö:#“À³ŒLgÕÎ[½v¶}¶{¤û„çÇÇÃ`0 ( Š¢€l <«È1çâLÛo+Á÷f~«ÿÀZËñãÇ£ µŽ$p÷Ýwgx cKLô®öŸÖPÔÝž¾?|bæ·ÞûùÏ>ZaŸÈ$pþ‘ Øù̺­{+BèvžÍxê©§6¹©;p×]we8ȱ%ΖŠÝŽÂÏí„ÚëÖZN:Åh4¢ßïo²”R™Î#2dDœk00<ß*ÏßÍtºÐZsâÄ ƒeYÒëõ(Ë2[Ï2d´°è ôvÛ·Óö©vOß{âĉøzJÝÀ`&gŽLgÅ4W`ZÑÏV±iu)AtIàôéÓˆHü®%H@Dßþö·gxȱ ;uºZ>ÂxðsùÌ”ÂÏ@gs Òþp–À;ÞñŽ‹–f–2.=t€½^ïœH`'­Ä)¦u9Zk/ZÈñ¬`+ëm'©½€Ó§O·Ö8Ûûºš?üî—k¹Æ꺞:Ûp.VÈñ¬ Û¸ÓA¡éïÇç¾ûîc}}ñxÌxýÙÕüéù¤ûLûÖZz½×^{-/{Ù˸îºëèõzñ<ü¼ÂSoûÛo?tèÐ_Ò€6‘ÀnGš?WÈñŒ°¤˜’@ €@áˆ`2™`Œ‰~~ðËSÁ q€º®ã±¶;Ÿôº†[­4”Üpà ÜrË-\~ùåTUÅÚÚƘ§ßò–·|ÝÇ>ö±ÏàÜ©$ `«ÈpAã™@× š=þ4¸±±Áx<Ž,€ÔØNËw­ õ¾4+0Íz0ÆpÍ5×ðe_öe\qÅáÜžxãßøÕ>úèç€U¦@&€­N` xì±Ç2\Ø LÓþáù4¨ë: { €ñxÌúúú&`»ó Zšð§çÝ%€î1Ò÷WUÅÕW_Í«^õ*–——Y[[{蕯|å×OktH ÀV' à‚ÆN Ødt…++ ªª–0ã>i7ß4K¦ûþÝï°]=@Já¼Óïö²—½Œ›o¾™Ó§OüË¿üË¿Gë€ññm¯ß^ g2žL¨î2bé¾i`(Ô Ï­µ”e #}OØ> Ó`šð‡ŸÓ2Ý÷¥®@xþÉO~’cÇŽñš×¼æå¿þë¿þ~í×~íÿÓþ8Á'8sÙL0¬µ ‚žRß®¬e²¶FuúÕ™U&§OSŸY¥o`'lm°îKEÑ+ÑEAo8¤\X`°´D9?Ooy™þh„Lù [×HÒµ·“öà­ÖèÎ L…?áB¡OZߟjä.¦Y!Ûe-¶þp­§Å3Âó'Nð›¿ù›ÜvÛmoüéŸþéO½éMoú/8í/™2ά1¨dim€ÉÉ“¬>ö§z˜ÕÏ=Ê™£ÇXê…1”€Æ"¢k¬ÐÉSyÁS 4V„JÀ”šÁò óWdùÚç±tí Xxþ5ô÷íC—îö¬1S‰h¦õý‡’ßðÂ~ŠH«7@k=50-¸öÙNû§Ï»±ŒÔ*©ëš|à¼öµ¯}Û7}Ó7}èñÿ— .€bÆH`fc?þxŽt ÀÆÑ£<ñ‰OpâOrò¡G 1†qUSՆʬ­ °ªpw ­QÊ «`PX ¨Ä åÔ8m<Ôý^‰. Æ(毹†Ënz)—¿ìfæžwu<Ç`ºÃÖÀTƒ¦q ÐÛÅÒGØ7ÕÒ]íÝÝ–î×}¾]*1M;¦ŸŸ¾>77Ç+_ùÊÇ_õªW½8Šsj¦Äö\þöü2쩆=õé¿æsÿë·8ý™¿F×ãšµºBkåÂÎh[£PX¥q÷^P@E$ ƒ ­Üïøß…°Q£•8~°–¡.™²dø‚ëxÁë_Ͼ—¾¤e L3Á§¥»>O·¥‘ÿ4“0hv*ØÓ^ßI6cš%¾~õÕW3 ~ö¿ñ¿xû?‚¥‰ ì9dà@(sæ þßÿ;kŸú뫬™Ê  ‚±N¹X±è–€Ê9¤ÿKà„À¶^÷daŹa«¸÷ÆxY·ÌýùŸó—‡¤ýõ¼ä;¿ƒþÊ>L]S$.B@ìKsïi×^èÜ å¹½^/¾7X!8MÛwï v7[ÐÝžn›æJ¤q€.A<ñÄÜrË-ßòú׿þgë·~ëS8 `æ\lÌ:¬­©Nœàôß`ž8ÆPBY F);…û*…ßæ57J%òmAiÀ:­¯¼ò·Í‘Dƒ’-ÚqEÜÛ”3ùç––xå¿ü^毹&º,©€vMé´ l~i¥`ºß4 "=vszÛ—üvß.8dºÚ?Ý." ‡C<ø_ó5_óO€8+ &±öZþ²0ëÐ%Â'~ò¿°öè£Ôƒ>gÎ×à_@-îž{ÁGÚÖ¾X÷€'ü€w(qï4ÚG!Ê/؉Š,!”…µ¢¤Ð ÿ$°ç˜YÈS+¨RQô‡\­4<øÇ/¿Œ…åez½0V¹ˆ¿v²®¼n‰švŠß z…ÅHtä ¦CK”Ü}Ó$¯"9¸Ô¡PMjNž>Åñ“'Y_˜ã ææÝgZ‹.ËMšz „¿y:; hûn 0LKãu?c«8Dú|ZÐ0ý}«Â ®^O†‘î§!íi^vÏ0³p©Âú›¿(Kо«|S£só#¾ÀjùÌÃYR^~KKKŒz}ÐŒúÙ$àÑUHÎgÀÚÎý×D}`0:ûX*ĽÉ_W<}ê GŸ8ÎêdB½0ÇÂhŽáܽ~ß½ÝZç*$BרüúPý´¶¥ûl'”]låßo·NÀvµÓ4ý´lAØ6 æp² ¸{ŽL3ëKIuQÄbe '~„Ïüã?ÌÍ WrýpŽù#Oñø‘Ç9¶¸€\v€¹•eFÃ9Fƒ…îQh¢Ÿ¯”¢6Ö[mvb}¼@¿q)Âí.¢±Ô¶f<®X__ãÄ©SMp·jBŠß´CÛ¥Së#üž¾6”Š¢PlþL—*B´…ÞL&œúìg9ú'çØÇÿ9u»±ÁÒÊ>ºÀh…î—\up& ¬­9ñàž~ðaž¢Ï±Ëùússô‡†ƒ>….é—]h 4¢ … ‘BXG@‚+&R"k©ŒP›Šñ¤b}ÊÑ?{€Áx3Þ`½ª1Z599c “ñ„êÏ>CoÐGά1ô(æGˆ1@Y–,û\¾²ŒNËOꚺfuªì¦‘@8—î9lþóÛ4e¨˜1óf˜.X„`—Ö®e×oŸ<Å“ñ)Ž}ôc<þ§025õxƒ‰©YG»D›µKˆäg–[U©]M¿ÒŒÇÅÜU¸£(&bA,%š², zôc™Ô†qU1žL×5ãÚ0® ±k¨&¢µ‚‰R•ÿøÈZ°ÊÅ­rAAA!ÆãÊ•,[ Ð¥™øYV± ­@‹°V[6ª Ë£ýÇÿôÏø°X¾ø‹yÞ-·põK^ÂÂÁË)CQ„ºª\ÆA7]Óïluý»Å´i¯ÂvÄ–L&nÙfLø!ÀyAÄ#ú'Ÿä‰?ÿsŽ|ä£<ù©¿`TWLªšõªb=6µJ5Å÷®§)Ô± J (¡Ð`MÍdRS ЊZ\3E˜>!bQâ´»ˆ`”`•rÖÕ , % Q¥Ïò‹Ÿ_%X­¨P+és­”öCîË¡65fc=?ï¾r‰îJlÌ š›­2†R¶ÂØZªÉŒáèŸþ'ÿâS|žë_Àóo¾™+oº‰}Ï{^“MðdÐu¥ˆß}낞í°UÌ ëìÆ"–KYn³™!‚Lçë#Ùº,[ƒ0V=Á“ög|î£ãħ>Å<0žLØ0†qY&IviÕÉ[ãgD¼Ö×X+ˆ×A¢\‰nO+T Fƒ¹Vþ^‰€öõzÖ ®UP[¨jñ„¨Ea±Tb Ô>5(º‰P4FYŒRNð­`Ä[ãµuLí+“Â{üçj_U¨’^å?K)…±‹P¢‹¥žTPU<õ—Åø³Ÿå/ÿçû™¿òJ®~Å-\õ²›Y¹öZzý~2ã×÷ÓJÂíЭFL·uŸo—"ìkZÏÁ¬#Ànàý¹®ÐŸùüQŽ}üã<úápò³Ÿa(Âxô…1¬×5U]³Öø¾yÆ`Dš²»VŽO¹%ýùÖï+¾«‚àr‚b]iK¥„>0(…¾V0®0J1ÒCèiDFÐÞ"¯ƒöWšZkªº¦ª cœv×ÂxRajƒô{˜ÂiîJi* •$R+……ÕNÀÇ“ “ÕUŒ5X¥£ÙR1V྾)|9±$—Á_ïÛmTq*‘#­,b¬¿>pfô‡¬ýôåŸþÂ{¹ê†0Æ´& í»©ìÆ¶ZÀtV1³0+uÐJQ®ùŠSŸ~šÏš#<²8Ç/cqß2 Ã!%N@bè,j³N»^èÌS"L›w\·ˆPº€½[yRYú…PŠJ„±†X…¦o,ýµ zUE¿(âÄ^k„ÊêÊ0¶–Z cÆ"ÔTµ‹ Ô¢¨•¡6cêjBUhŒÖÎPŠÚZ*c0•ÁZ¨ §¡.ˆÒ±»¥FQ*Eß …¸á›ÿKჂZœPûGsݼu`U3—PYI€áäêžxúO}„9Âç®ÙÏhe…¥…½JÄö´ †)g>§qaÕqÜËe¡'°è;üÖ,Œ5ô”aÃ*eMßj zÚ¢Bû<~°>DÀ(íŠv¬‹;ÔÖçÿQXe16¤«5µ:†ˆ¾QÎß7¡dô†ú¼RÌ¡YP0'0DÐÞô/z¡@„B¹€›'|o¯ù0WœX\v½ŸÓš/XZäzµÀSëúë#<¨ðèUû­ìgq~ÞYJaëPû¯â,?p. pnDQøÑ`â&y÷”r¾|%Lj´k*5….@¢]ÝQb­—;Wih¬;k¢]í~­„Ú(D \ øW‰bôPô´Óî¥rÕjŠÐ7ÝEþc\ßGûÐkå–Û~zu•ã'NðÔñãÔƒÅE–®ºŠRiĨ¿P´æ¨ø·-.Ò ü«ç.|]÷a§õ2œ I ¸^X ¨Ü m“VZ'¿Nã> ¬Ö»l4à²á—˜š#GÎpøÈ1Žì[„˰¸°Èp4¢ŸÿOZôônŒK™¢Ñ¢(¬h”×ø£„¾Äjc1TzÂD¹¾||Ž>Ø¡1A“ÛôxÛ¢ÜÜZóàGŽ =寄k-nŸÕï[¡,`¤4}_û/1Ïï“x>Eª}]ÃÆÆO:Å“OçÌSO¡çèï[fTô(p5bLì¢w‚žÛ<™=6Œ––’?ÝùÓ¼;­Øj"Ѭ"À ¼)Y”%zT ¬7gCÕâlø);?‹ÿe¤ ¾he‰/° <¹:á³'å!ǯ>@ÿ>–æçéa%Á%®BP{M2ä Q.Ânp]|…/>(°Ö¸%þB ¯‹Dú¸ƒŠ- î¬}ó‘¢5Wù1a® Áp1 ­B? šžRh‹ëW÷ÄæÂ…®Qª65§W×yêéóX·À§R(ë||‹×6^( ˆ~¹ ñ—ðš×ý uüR„„P–ì¿*4¹IÝƒО‚ ú÷¹&$oÎEX„TüjX¾@¨šL8uæ4O?u‚ÓOGÍÍÑ[Xd~¥ŒV‰XKXì(þô„Øn¡k4­NHhnyß³ý¿PMü³!À`}«·²ë÷ý[Òû¢ñá!„î8Á¯ž…ò7©a¡(ø¢•En´ó[ðàÉÏñ U|þêýÌí_aq~ŽR—®zN(+q¥ß ‰µ'ƒ¸€uçj(ñ<^ˆÅ›ïÖ[jÊá„à¤ÿÞ*YJL¬KÝ…‚w¼FPé¢1ͱ†Õµ ž~úižzò8ÕÚ˜ri‰Ñ•WPª°ˆ©û̳´B7dÓü¬–Æ S ´¶Ì¯ìsçzžv7]†2ìû–(l²j.òùAѵÒZ~G+*¬ç´8€&Öû+­¸j~À• yi]sä±3|æ±'8º²„ØÇâÒý…y6Nž¦OÐÊ5ù„‰S½pŠRÞl÷¦1É䟛4èîúøZ~À„„%ˆ'¯P…ä¡ Á6k ý¢`~a© O~š§žzŠ3O<‰ôé/.0Z^F‹³ŽÂ\ çAðCÁ”V*ÑøáytZBÖÐ?WhQ 㥮±IdàGð$u€ê—~°f ÕTù-%‰o ”ªÙðKo)/î}Ö‡±—Ê‚}û—¹Ñ.rlmÌgŸ~”ÃkÏ»½´@¹¾A}ú jl^á>Sœ¨â‚~6jj/˜˜Ø–ë­~—±À Žò©?ñ–AªÐИ4.D«Ã]XœT¨aŸùáˆÑüˆ3«k<ôðCLV×è-.17©øk™ðùžb<º4aU!µõK„¹õÂtXœfÝ?áø¶þt´[ÆÆÉ¾–Bý!5– S»ä^¯ÏÂÂ|3ìÞËc°~tŒ‘¤×莀˞¤VSò >ö k…MŸãÊ•{ÃÅù½¾M.(dØ‚0ªÁ±R禙wåe:,ÞiS­FÔ¸@ŒÄX|“ójïOã6„éÁûû}öú|a=äóUÅg6Æ. gz}TOSXƒL*dÃ@¿p&…kNRæt¢Ý´äZ|P&†¢Tèž[S@”bÃÔLª ”½áaÙss<¹´–#÷•~‘ã÷o¾_0õã[$_„ïÝOÊÆíµŠUü3Œæçýßavµî,af `–L¸è,-2é—¨§ÖкÄRëâo@ R$©ÀÈMºKªxó‡ïNš‚ Ѳ¤wÈúŠ aYò‚^Áó†Cn©+šLø¬s¬TLæGÎ*˜TÈÚØRß—©$K |åµELMÙ –æ‘¢db ëu…A¡{%ÃÑ…Ò¾Ä×I0÷'Íä±…–!”\Æ˜Ö ä‘nóÛc R©R[ê~Ÿá¢_ðdvîŸY9i˜Y˜%D `8Dé‚ÐÑ#®ÅÎÝÀÚk4IRþ®¶ —{êÆh(|•ž–PMØ^ù¦‰|ë•oSäE©à²AŸý/6#>?©øëµuéÁ©aŸb~„® ¬­c+GRöÜyÖÆ¤ÒôæçQƒ>F¶bu¼ŽåpĨ()TÓѧpÕy6DöZHôð]š8ƒkä Ö€¨†ãÂáf`JB–~\˜N\‰pL­Jk nQÒYºYB&€ ¬V3¡üн¢â$\ÛL{ Xñ…1þPÒþ ò RM˜°G?°>•g½³]àŠI²N4æ Å çJ®81©yhmƒÏª ŽŽØýû(˜Œ1këØIE±0G9!eÉØÔœÞØ ªkt¯Go~Ñ ÖðDåFú†”ÄH0÷Ãj—ì6ÿ UÐÙÁ¿ÞTý… d°ˆÜg ªp–Ò*Zåp@0Üë»å‚B&€Àk!ÕïÁüˆR¹Aàê•r~÷R7Ú9V¸Dièh¦Pé¦TÑÆ³‰€Ò)íß®Cm®7ü#Ô6~„¡W\1ðc8²±ÎgNŸá‘¹’õù9Ê•º`RM8³¾Æ™Ó'1"”ý!ƒþ€²(\@PlLÿ5UÍ9»ô]2²«½h®JžÇíSµ4D’4c)é¼×ç/KOýÁˆÞpè/k¶v‚L»€ Ñ—­Pþùç˜ôiJdÓ(–ÿÙ-±mûpÁA)R³ß½QYiiý°|w ~©Ö‘ÝþøTd<×7o¼É, eÁ-,rýüOŽ7xèøŸÖ§8Ò/89^G÷úô#E‰Râ—ò6¾ïÏÍ h øú¾×Y'‰Ï.MÅž¢c4ÄK—ÔGÄ Ø¤&cEü^I–ÖHèÀÔÃåEÊ^c¡e 8;2ì©6(”øšzã\%q8lz׬fikGm}º&ÂÝ”ß%E!-—FÖBšP¹EEg:îÚŒ]5 3û®ÍqÕü<_¢¿vê]ÚÇЯu§ü”å:ÜéøL†V^ÒU#®ÁçOË„c”éBØXmáoæ%áb *M 6qhŠ«”Ž( ÃÅ…8 (Çv†ÙU4cˆk¿ G.j„16ù8-¬Ò±>Þ|WIëÔvQH¬—˜ ûÇ5¥ƒöõ ûÐüéRwHåMt?‰WBT/ .Ð8ßï±Øë»>±Ñ¬×Í5xÌLH J6.º4.‚jk}’oOµÔL­i“|Ò, uIe£ÖŠÞ°Y?0cgȰCè™_\ (ЦG@«Äjo4ŸNjmƒÐ…‘Xº é$´´*?·Y`´)‡%º‘dÂ"ºýÙá©’¦¬ Ä 1”¡Ð&Z~‚P*ü!—¯=x‹ Îèõx¡ìúù›Ò|í·Gò‹ƒTh7m¥Çã",¸4¦Ò0\pÃ@Ò…:3¶G&€]¢…4¾«WuAk…ô• q)_š¶±à%HR;¤æLúI=!î †˜nóR«Ä›ñ‰~aÚOá-$˜¢©ÙßÈñ-Áíâ¦tì˜$ŸÕ=Bb¨´ œâÿ‰à ­¢˜ˆæ¸vÍv…b´²¯o 3˜¥B hQós¨2 oYAë&]ŠF´k½ •+ Ût´‡Ò`IüÜPÝ–Ö6?ÓôbRPÓz-1Ó¡U¡, 9tŸ²,Ä=3¿™öÓt˓Ӿ€øÙLvج]º…?Íû½ДJ6VÿÅ¢ËN ˆg-•¹¥ÅH"³tïÌÒ¹t‘-€"šäóóèÂÙÄFbY…ö•@MتA(`‰B–ÚÇé>QR!iìê&"Þ.†qš0©´÷-u©/Þç„ÐÑl¤,‰ÊûÏR!Øø÷B{\+VNI Mž‡øÀ¦¯iÀÔÿ,¢¸Òn²ƒ¤e… ússÏýq#À.Q.-auá¦Ý‚[ÇO¥¦j{º¯S_º¥™s=D³iE¼!1“õfs¯{ò‰ä }ºÑÅ+4Þ%ñÅöZš ¼A“rQ‘!šxƒ7^ZŸ™Žçhu2&ç¶•–oLõôË¥ù€¤¶ ^œ6áHçIL7úVà…¥å½¾=.8dØ-._AJ¯U㪈jLûtz]h”PÛmõ¤yF¹Õ‚dZaŒjiÔiÏ£·5yˆ5xÁ‡F“C$¯ð<¼#f“ã6Âιø4ØÞõíÓí-kÆXJº³ãê¨ÖZ{©i/¶cB(Í0ÏØ5r `‡ Ajn1IIAš‘ñ$à‡†›·Qv⫊S)K}ºc2§Mót…?‰ÄÇÞÚÆÕHÏ1já±I#R“Èù|â6M3q—ðýÔ41o½]èÓÙSµ-åWA–pž4„ a%Õ€@Óï‚¡£˜±{g–Î¥‹lì±!h4¤Ö Œ _…QVñš±*/M“5uë^Øš:¡¸Z޲Ö= jÄ7!héÔû$BýkåªæÒÀBœÅZ~‘¦æ>ÉR8í¯Z.Œ?Ä&“¿{ž´~OD-JUKà»AÒØå—” ,VÁ`.7í™vˆYÖ ‹¬¬EoB­\¾ZùÕvÐ(ì§² @(puÂßöž}…NèìóZµÔŠÚ¯ê¡Š$úÌù¨‚UòVoþwÜó-¯ž´çé¤=¸îú§…7ª}´S~éÃ8¯ØÐ#ûmÆØdê'%À1Ø—W¥„ÛÄŠb8 7šË1€]bf `Ö-€~5R(_ËÛ1Q]ÓM#(*É¥¹§Ú—KÌÕwS]±8‰H{‡Öþû,TéµMöfyòèKCL)6=‹’ŒòRñ«ªiŸ#!PG¬áIÇz5VM7pI×Hn’hýt$X›¶ å.ì ? ïÍ­À;Gvv Ýï#+Khe›Q€ÉýVÊIƒT±Ý74„jÀŽð»P|ÒWЉ„Ú~eÛé½fi¬öé4þútÓ¾ýBX±·‰ÒK qÇ·–X'Mh’¸Êr+‡WR Þ¼9Pj™tâ"‰%ÐXî¿ÞòRœc;G&€"Fï zË+”“¦²mSî;M¦´nnú õ¼ßD3Z A+[âݬã¬ö§¥E…AÈ;òÝÚW%[Cs’o_hë¦}È4½Ú:~2ò«{¶J鸥½’nbæRzÍ*E!X;ÿ:æ¿õ5XXˆ³fÙäž5dØB—™ û¥öé¬M^@c{lzUs“Óv/†¤K‚ué‡ÄN¦ޭ±'é[‚°ÓªóÜ3«šSRàGù8CÈ ¤§§šÇ¦¸Føé.N2N^mŽÓìÓ|qþcHf ¤©Á¦° sóþúfý¿dØÒ–`]S}ó jÿZ5ð±×?ÉË5{¶þ Ñ ð» ‰¿Lòö ¡u;ø5=>×öK5Ñÿ°ð¨ÒÁšh&òAúäs›pgr h Ùt6&¨VóoðR$%³öÀÔ”tÜùjF~hnÞ2œÔe’•uÝ`PÛøŽe ÍeŽm81‚\M{ŽJTm«(E+Ñ2±·€H»—¾y§L8||ÚÓÐ- >¹Jßï„[ûbÝÀ&%Ü”â d¿Íô™Dü;ÅHq{x_Rˆ4\YÞ››áG&€]À‰^^r†·€ •qâF{¤Z?øûÑÇ–$¿-á¦n¿_˜ä8žB‚ÀiQÑJˆïŸ²cw¬¢! èöP±¦!V#KçfQퟱW Ù„´ñlR×Â&D“¤ !Ž0SÉE´Mt29…fšÀ\hÊ.À® `ˆ«/,¢uÑô¤‹Žælº¸¦ºfìO° lÔÂ>.žX iÄ=Ek¦>SJ€}†@üñtÜ[|Éò–oâÖ S¾Æ?5­uH»M r†uÿÂy§1…inGºÛ`“ïÔ¼O%߯)ÂjA­ FI•’RÍ4 ŒÝafëf­˜ÃŸ”Ó–KKØ¢[ì`æ¨fžŸÓt7¥7.6›¾iEÜ&h¯‘¥)¥¢¹õj°*TS_Œƒè“'Dↄq\ÍTßX; Ú‰ÂOë¥S 'ýNÒ¬5ƒÝ쀷 ÜDóFó‡½CtTA³2qËRjì«a~yi&‹€Òï5‹ÈÀ9@­,»eÁBd=)€‰—4Í¿‡â,ÙtÓKÔ”[˜¯Ö¥ël˜A–fÎB„¼µõÉyŽ JÒùBxùj% &¼$‘øæ•ԼᆵSà_“ºTñß©cJ®Q»¥ÊzÍoIÖHã­´ b´/ÇΙvèjÏ/`Eal’ÆKÕ hÜxn7–#ÜÀViLPϤ™€´ZÎaSmjjZÅññ}é’äSô¤jëioý'{ˆoòµÝÿ]"h¡}3TÇ}‰ÁÃÄúñó;Zq` ¤AÆð[hÏΓД±;dØâ’ÝóóL ã&—ÖШTHi߯‚mÇZ¹5xœt hÁE4á-­Ü>L”…Yÿ:¤çd ÑÐÎû§V‰+gš.i@34TZK$–}|OR7àû+b¢ $v‚†‰Ä»£¥Åx½2vŽØBCKólª£Êi{Õžì•Ó¦"!qQi6DaÐ1ßMWd8G¨Ë Ä Ó@#!àÍv ”üAT1—¬ ›¶cÝqÜ$þBüPïW799—÷¶.8‚i­b#‰†Ýä5ø³lçÚ­j¹×¦•𦶎´Lõ4ÙÂêtKEÂ9&½ )´™YGyI°sF.Ú%Â*Ázq-6Véë>Zgƒ­š€]Sì¿§$yöÖ§W•*ü"¤Íæh(û ŸhK{•ŒPk}V°:üçÁ £?¢É.ª=¬Z±JiY$ñ/ÖŠ×wß—>O‡¦6ÛŧPýuôûØ)Da;–Í`FWާ=ƒç0³0«hZ‚ç°eá‚s¦QÓÁŽû³o«Pãæjˆû4†l”Rÿf ~Ý€à#x Î¥©¨ƒtÂÉÉø÷H<3uVºU˜$¾ö¿óSCþ´Rc&Έ×LÅí­9 ÞeHûZî–†ÑâÂsõç¿è]€s„ZYÁzáþwÌDSºñå›”XH†I;Iª+Í„z±QP ÒLâz~MTѽØ5ù9ññݩĭ­e·h ç¦wwҜӫ’SêT%¶F€_d5Ù?X:‰ÿß4ù‚ qYN,îß¿'÷ÀÅ€L»DlÈÛ¿‚ñíou+vî²î&uw´‹\7AAòîÁ&W ø´¢„å¿Cn¬£ÑÃRb®·Ø‘QH°ÇÚÙ䃻Ö`wº™Uâµ{ˆЊ´§h—élÎï‡ÏhïAâ.H«*¬£f<‚éßøü «ñå®[ÑœÛp9ÇÎ3ëÌj œW±°À:‚ 7«rùó"$¸,1:¯pZÝd‚)«ÄÅÂÐìÆ¿×.²nm“&ô뢔›èk€B J4Êx;ZðÙ…&Ñà…¼ Z6>{xoú‘>¼×ús4ÃEºÙ‚´\¹ ¶si€°íïKëð¤aãz 4IÙ³;þÜâì ÷̬"[»D(5-æç˜ [o¢º »5Bõy5Üx±âæˆßÁ6é37øÂ¸Ñ\¡Ö5mÍ›ô:ËB¼àÜse£ë¡,`ß:UçÁüO"ìi8>äX¦Û âÅ9tÜ€Mþ@ÓÖÛ b&»ZiCÜâËâg†ÅG­¸5ãÜ19ß Ì Ú¬"À.|‹‹¬)Mív …µÍ"¡V…¸€óã››[ü‚é1›Þ÷À bß߆alô{ÃÐÌ8Ó_7'§”#Ñ®WÀ"ˆÒZpiG—¥l4õþ‰)?­¨BñPº=ïĉgóžf?Ÿ¹ð.‹x $”üMI ¤]­e¢,ó9 xΘY`V-€…êAI±*ÔÚ‰¯N ÙEœ"âÖ¯KMÿÐ è7øÀž JÒ¥áZ‹}j·$9ƶ*ÎЂ ˇúÿ"ä#´s3¤ÐÊ—Çâ¢MŒ­]5B’Ls‡›Ìxÿ>KÚ4•Fõ¥©îK‹T3ÌJˆ“¸ý]Ÿ‚¦??Šç˜±;d `·&ù`èZ‚µ3SC„^‰°Þѵ*¦ÿ“"–èYÇX†öX‹´òùèÑñf€À{!í\‚è–=êUº¢qbþ½c³§cÊÛˆÉ<gñbâMôfVŸg©&Ø-  M š§§5ƒ |.Äù}|f¡ôã,€ŒÝ#ÀnáoÆb4¤Xò7žR(­±¦c§Ñn£‚¯«|ÑKS`q³lt¶}#Ž’èûFÝçÇ Ó?¤ I½·™%98ÎÛ þÄ`DlgNú¸Œ7¡˜¨ùŽqA’ Ì݉Ý,„ÿ¾Í3g¸SnR ¡32dML'%¬‚þÜC¿,X¶vììQ3õzÈò" ¨Á¯°ãnÚÚß÷…j¢Õ¡F@«ínªÿ¢©ö‘¤TG ˆŽ ;͸-¯ÑýH0ã·áL­øw…÷¦ãÂcI1MÑ ‰¶nyÿÍîMdÞ)3ÝI5NZ/àýéIW!>C‡§&gê@M%¥†‹Kô‡yȹ"[»DІZkô⢫µW ƒÂ(ÁZ°—$rÚIí|Ý€tÂì_òvqÍ‹•lÅíIKíÞÚ@š¢!礄b#ëÿøiM:rKl/Ç¥ü¸îÈЈ#ÎÚƒ&À™„H°¾±§;ó,|†ÅzëçÖÄkè,Ž`i æG”eÙ:ÏŒ#[çå#`2AOa‚ Û&xW„G®Ô7âLö‚ ¶‰Ž‹ï¦Wnôx!ĉNKlòó6ÔøzƒÆðð¥Å^%ÊÕÜò FHÔæE:Ü™Ib¨¤c>›¬A¨3€Ä^@ŸÛ—¤ºÏ¥,RK–FBŒÁOAL8vSw0Zj:µÎúl·Èp.ðBR^v9µRÔ ×‘§… ;ÜÊ;!}%ZT¼à"Äà Â†ÛÞ Å "þx¢|”\I,>’´yÇK”j é?ýÒeªY÷/”ÇÀ]<¿°~¡Ä†%hÒz⸭kNÙ§)ù„y~‰«´8¨!£þÍèr«Â$âduA-æWV’ë–±[d8Xñ+ê®,R‰P)5yˆi/à…(J¯ÙŒ×Æ=’r[Ÿ3>§5M¥x!òÂh¼×mbwNBM€r ó¸<— ´7U6±îß×TÓté5Ä‘æëãÀèæ§ÕBÊÅûCÓŽ/UŽu !úˆÀ“–«˜ôÄà÷ 6 CªU,øŠ@«..úï à\0³0«eé¹õ–—YUn]€ZY´@I¬iEû`ÛÄKœÖªÄ¯¤CÓ‹ç¢ú‚·æ_ðçÝ~àIˆÛf}¾à¹ëDM{O iÝ•ÆD)J›¸à]ùQñ¿8=(Të!Ž.F† DÚ}ÿ©ÿ„\B#SáÎIb =ƒPZσ`QºÄа°²2ÓeÀá~™UÌ,\(–—¨ ͆Jïç‹ò?ÅÝ®…vKz‰¤P>(f¬¸…F¬ËD7Ì Ù9´s“2 ÂÖÍ îƒ ~ëê†DµH@µ"únƒqF…Cc€+œÀ`¤æ«=N’.žäí>k­ƒb!1>SŸI¥`R0êjo€°¸’;Ÿ 2<è•ýlh£¨½y¬mhßwkîˆqîB©TÓÔª-.s ~ùn%hq™„´¡¦2 }¿C4ƒB×.õd”VÎý°MÒO”j¬ïüÛ¤ 9 —–·ÝZÂn[ïnâV7dÐZET¬ì³ISQ Æ€¨´µ¿/"ª¬E+XÈ‹‚>#dxèí[blaÝZz8Á-pÝâ‚vaeœ`ö—! öÄA˜y§µDc@¼5aCJ!ÛxÍíc¢Bî0 &Y¦GrÂhqâÄ¡`Ô7Ú>¸ ­9"qxhZÓïƒ}ДûCsbðï#!k XIU`œ¯©í¢ªpõæó,€g„Lç/€½}û8í;ñ”úY±¢ ½9eÐÖÚGñÅ­Ä£” TÊ»ÂÖ—ñŠ7À£‹à¢Šâ…IŒ¸iâÖ/Ä™NðTâ×Tÿ:øÔ¢òRéÝ0C3šâ!*©O €¶Ož.k{07#Çü¹„úB –¶'ä÷ý9)•T:4ÖC¨=dÛòþÿ³ëgÏ2f–f:¨£]EÞðàA&¥Bo¤ßCÕ†(”}ûšPÈæ²…Kå5-Öùï…Ò~Ò¯ +þ®hFû¶^# ë{œÅàzÄK‡K †À]5æCîJ»²bíIuwSè„j´,Ã>Äh ŠT#¨±ZYµµtðÝÓ¡©a×ø^K\ó Ä6šã4©U#BÙëaê´æàÕ× ”Bû¿É,bVÏ r%à9AkÂ^ºê*^ô¶É©B!Æ0Ö°.–‰Æc„‰…J)j F˜(¨”Kºú¨•«Ü«E˜(‹ÑÎ bü´à¬ö¾qkÅN§­k+±*/ß‚fuUо_@¬³"ˆª©Þ hÆ7Úkü0Á'Ü0ª;Ôï‡*¿°@ˆ‘¦ 9 4±Mɵ8 ÔÆ¥Y¬w®ÖRYCm­k8²‚©kú‹K|ßúO\õüçÇÊÌŒÝ#_µs…gõW¾åñÆßÿmԗߊ5–a¬¡²Br$ – 0Ñ.‚]a©Ä2A¨}$Þˆ+%6^x*툠֮í͉%ĵ†Zƒµ*vß…&=cÛ3øÜ 놑„N=,Æ6L× mò·«šbL}$ 7‰ÿ.­W1ø†&e›%ÔÄ">X‹uõÊ“ÁÁX¡ò.+^ÒX1Ô_ù­ßÂ{?|?¯½ý IïBƹ À3„­k®¸ñF¾ù—~ž—ÿ佌^Žª…u„ οŸàj*+TE­\qPåç †*ÿI4ß“õò…];2ƒ6bm¾µjëg6B1þþòMy®$~·´rò6š ÙMU_cH¢íEK¬Ý·6±hÌ|·M0ÖFkÁˆò‘‚Õþ¹­¹æÅ/áÞ÷ÿO¾ïßý;–——©ë: ÿ3D&€g]–cÀZnú†¯çÎüWüãïbUƒXËXÁØ:í_‰#ƒïTÖ=£ÄB7_…K-àÂhÁh#o{XÏ ¡ÄØJ¨ ŒÅ/õz®/Ê‘.çåØ"~Xã°YÏ0²DwÂ:†Êk|·¿õcЬŸ{`}šÓxíL}ë-#Çšµ†#Þü¯ˆŸûÀïðŠ[o¥®k¬µ± (ãÜ‘ à< ( 7ij®™Ÿ›ãuÿúûyãþå«ouþ9ÂX+&x¡jë*÷Ü ¢%P ¡RIç 7‰+ µŒ²ÞÄwskOâ"iν7ah)ŽHLèlô|0ãS¿<ŽãÂí'üøû¸7·FvûÈnþ!¾Ý×;"ï«uÊÚv-ÑÚ¹_þwîàþøø¶ïþGî\Œ¡,ËìóŸ'ä«x¡ËD0UÅ5/ùb¾å—‘/y÷`|ÕåôŒ°0Ñ0Q0VÎÿŸ®¡H\‹k†*Ìô>p%ŠÊ» âgZuáf†¨žUÞ5(œ 4 ] A” $6-Ë¡)øñMiPXi(I²_l –àï'?”õƶáàÚHÓq)5£„Z)¸eÒ4ÖZ¾ð…üèÏÿ?üS?Å•W]EUU€'ÛŒó†LçJQôzØà¼ñþîG>ÄÕÿì»9£9=QžPMVÿ°â3P‰0Q~ô¸–hb×!¥æ]gøuŒ üÿ^kb•&ýx¡K–%nt¨ê“äΰ‰ö…>MzΙñÖ†žî¸DWÁø˜†õ±…¡öõhçJ™A¿{×]üü‡þ€¿ù•_Íýž_þ;ãü"À³Ýq ¾â]ïàÿàwè}åÿSuãRSYËX„ Î ¨”Óøuxx¢ JLV!ÞîÝ€ºpq 1ßf giÁ‘Í Db›|h‰i;i~o|OÊø Â'"ã{$ÏÅ™üV9b „ …¥V‰åK¾æ«yÏþ!ßõÏߊRŠº®³¹ÿ,#_Ùg©[pÕ}!ßüÿ¾—/ù©Ïøš«(kËX+*­¨TS#0±âb)­×@ùˆ:·¡Ö£­ÖºY¸Äh¨E93&à|öTÃ7QþtVÁ·^°ý(t °ÞÏw.q|·‘˜tæ¾Áb å܄ڲÿÚðC?÷süÛŸû9žwíµTU…ˆä ßs€Lϼ[`ŒÁÃMoü;üýüWÏw³ª,…àIÀÇÚ¹+μq€&SP…Úxq>vLb“à›Ñ®€H¼T‹j*ò¬m¯Mæ´Ç€ù™}1HHÓeý¼ë³V¹©<¢‚©/q ~º@Œ+†ú–ïýçüûÿ×|õW¹ëãÍýœÞ{n0³;Ë¥À犠Ñl]3¹íÞÉK¾ýÛøý»ßÅäw~e¡îã«¥_/K‡yÞd/‚Pú"æ è ÆQn‘ÝÌPÖ•Û˜ÞsçÒ†a‰.•˜ïÑ2P‰ïq‡õ IV‡¾þÆZpÖŠ¢ŠŒÁˆåK^ÿ:¾ç‡~ˆë_øB€hî_Œ˜åû8[{]–NsWWÞøB¾é¼‡¿ñ_Šñuϧo-µv¦ýX‰ * ]Šp"Á”v.ALzÜi]11ßÞ¤ fyRŸß¤øZ³I›`Ÿ·.D5eÁÁj—¿OMþ¸‚‘XD¾‰É²|õ5¼ó§šï{¹þ…/Ìæþ#ÀAuÜ‚—Þþu|LJ?ÈUßû=œ)4®xh\¸Þ‚‰‚ * ±+)v寮Î_bà0øè!›zëMLÁù¢ O*®àG%Ó~:uû!Øç{÷­Oº¾ߥ¨šˆ~$%P~ /ø†ö¿óó¾Ÿ×ßq‡‹ø“Íý=F&€=FQè¢p .ý>_y׿â›?òû ¾ú+}´^1îŒE¨tST‰«,¬E|ÊPÅ,A¢R6¦âjܾ֗æºÊ;G¡ 'FøJBñÁ¾hÖK{|—KûùÔž¸~ÊÂ÷&X^òšWóß>øAþÉ;ßÉp8¤®kŠ¢È9ý@&€A‘¸W\=ßøžÿ›W½÷g©n¸Ž²2TÆeÁºþÚg B¶ ôÔ!+ *Z ¡G öBouSØÕö!|àj¼%A³ ©‘f^´(T“ö£(UP[æäí?ùŸù¿ôK¼è‹_œÍýD&€Bp ¬µXcøâ¯z=ßùG¿Ç Þñ½¬{•a‚b\¸B¢ZT,%®}‰±ÁmŸÌ{˜ˆu«„+ŸF ‡Òü¶ ±>?¤_¯ Dù›æ—šTEµ†Z)¾î-ßÍÿøÈ‡ùšoü¬µÙÜŸQd˜Ah­£[Ðëõxõ÷þ ¾íþßgᎯq¢Ø(5c±L¤©hR…nš)Tl7®*íkÂàÐkDÓÃo•òe½¾„WÒƒ|¢‚e`Ñ¥3åkc¸ñÖ¿ÉýÀø?üCÌÏÏS×5ZëlîÏ(fÖ»Ó€»EÙë9ß¼®9xÝu|ÃûþâÐ!þàîï§ÿé© -5ÅÄPúô]¡«[qJ Ü@QeA?¯P+´q •ÔÚU6ÃD$ö‚†G%Ûü`!‹û0kª¶Œ.»Œ·üÀ÷ó†oû6ªª¢,Ë\ÂKNf<tÝ‚ßvoú£ßç…ß§%Ee© Üíš‹&>FP+|˱O ÞE0Î%¨•m4|HÝY늈šßºæ^øøSˆ±T_õ]ÿ÷|øy÷}[6÷/0d¸@ºJ)¾üŸýSþþG?Äâ7½ WÔ³Qh&Xße(TÆ—‹ #ÔZa´ø‰=q¡OAû M-¿iVY‹*ݺæ6|Á+ÿÿù·ÿÿêÿúQ–——©ª*›û2\`H³ž÷<ÞøîÿÌkùç±/¾‘žqYqYø%Ë$!©Äµ"צ‰Ü×øA"xa÷ÙCRÃ|´è!uÍ`y…ïùw?Æ»ã7¸é¯ ®kD$›û 2\€h¹uÍ‹^ójþáþ_xÏ÷sf~ŽÒXÖµbâÛŒ'¡`Èg &¾rP’,@¨é7ap‡ 58­o-F)^÷÷ÿ?ÿ'áë¿ã;¢¹_–e6÷/Pd¸€¡µv#Éê€[ÿñ?â;>öGìûÖ¯§ö€&e›Œ&ž*q­Ç“Â-8šNê5âfV¾ŠÏ µ\{ËÍüÇÿï7¸ëÇœ}ûöesÿ"A&€‹…/¬1UÅʹã?ý{¾æW߇zÅËPb0 Ö{:™ˆ³*ãS}¡ÇméÇ€Cq™üoÿ ?{è7é—fsÿ"C&€‹©[𯺕ð;¿ÉK~ôV÷-RZãªC¶¡ÒŠëçïù±ß…BŒ«üŠ;¿÷~ì#|ãw~§‹;dsÿ¢C&€‹ Á-°Æ€·¾éðÿä¹ò;ÿ~°JlX˜àR~µˆ›^„Ïýü›oæÞ_ûÞù÷²ÿÀªªrq‡lî_tÈp‘B…+ý­*–öíãë~ìGyãoÿå­¯ÄbÆ…¦*J? ÄP,,ò–ù~öÐoóò/»5Ïã» à"Gê¼à/ç;~ýò¥ÿñÇ_q…±([S«‚×þÝoç>ö¾ùMoj™ûyßÅ ¦ºìÙ (¥0FÀàÆ÷öûýÑ^_ ‹ Öð i®®­ñGÿá'ùËóåßõxù—~)àJx³Æ?¿˜L&ëÃáð«€Ç€3À:0*±ÏèàÏ™22žeÌ2dû.#ãFîÌÈx–1Ë÷q¶22.adÈȸ„1³.À¥„{x µí¶ÛnãÍo~ó³òy÷ÝwïÿûY]]ÝôúM7ÝÄM7ÝÄÁƒ¹õÖ[w}î;AøŒë¯¿ž›nºéYùžgG&€K‡æ¾ûîãþûï?ë¾<ð@K¨o¿ývn½õVn¸á†óv>égÌÏÏsçwrÛm·íõeºä àÀ{Þóž¨õÏ8~â'~âY9¿ÕÕUÞýîwsÿý÷óÖ·¾•ùùù½ºT—2\äØÎD¿ýöÛ¹á†6™ù÷ß?ÇŽÛd ì7Ýtwß}÷Ô×î»ï>Ž=Ê¡C‡6½öÀpÏ=÷p÷ÝwgxŽ à"ƽ÷Þ;U€o¸áÞúÖ·rðàÁ©ï „pûí·Nh>|^Î)ó¶ÛnãÞ{ï娱c­×>Ì»ßýnÞúÖ·îõå»$³):4Õß¿á†ø‘ù‘-…n¿ýöó.7ÜpïxÇ;¦júûï¿G±ŠŒgŽL)Þÿþ÷oÚ6???SšõàÁƒÜqÇS_{&1‹Œ#ÀEˆC‡m2­î¸ãŽ]iþç·ß~ûT+àðáÃçÍíÈØ™.Bl¸;[N¯°Uúüä^ŸÚEL!¶ üÍšöت([Ï>2\d8vìØÔê¾ë¯¿~¯OmKlU`4ÍÉ8¿Èp‘áèÑ£S·_qÅ{}j[b~~~jàÌ™3{}j=2\dØJkÎzaͬŸßÅŠL—02dd\ÂÈp‘a«Hÿ´Àà,aÚù-,,ìõi]ôÈp‘a«`ßVÁÁYÀêêêT˜Õ´åÅ„L<85 öàƒîõ©m‰­Èé|ÎȘŽL!¦ÖÌriíV/}éK÷úÔ.zd¸±UeÝ´üYÀoÿöooÚvðàÁl<Èpâ¶Ûn›ê?:th欀í—2ž}d¸HqçwNÝ>mÇ^áØ±c¼ç=ïÙ´ýàÁƒy>às„L)n½õÖ©BtìØ1îºë®]úzàÎ;q<ðÀüðÿðÔèÿ,Í,¸Ø‘G‚]Äxó›ßgû¥X]]åž{¹Ã˜®ÓF‡oeUìa¼ØVÞüæ7gßÿ9D&€Å¡C‡v´{ó›ßT¸ûw'ô4n@ú=·f íÿWþ¼6ükMK(ÿÈȘ5¤÷q»—'¸{¹òCŽlBêÿ§^ã4éYø3fA¸k¨hH f†â³@á‚Yœp×ÉöÇ Áôæ&ŒYD×54Vm*üi6`O1 mH74‚¯É‚Ÿqa ÜË)ÌœðÃì4-Í“Ö4‚ŸÍÿŒ é=liÂÌ?ÌHòSÑv ˜ò3#c–!S~v €f‚f…`3 d¡Ï¸![<Ÿ ìy!PFFÆÞ!Õdd\ÂÈ‘q #@FÆ%ŒL—02dd\ÂÈ‘q ãÿ¡3n±É´CÝ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+=tEXticc:copyrightCopyright 2007 Apple Inc., all rights reserved.žfÜ)#tEXticc:descriptionGeneric RGB Profile§8Ž$tEXticc:manufacturerGeneric RGB Profile=h>tEXticc:modelGeneric RGB Profileêo®«IEND®B`‚leocad-23.03/tools/icon/32x32/000077500000000000000000000000001440571307300156255ustar00rootroot00000000000000leocad-23.03/tools/icon/32x32/apps/000077500000000000000000000000001440571307300165705ustar00rootroot00000000000000leocad-23.03/tools/icon/32x32/apps/leocad.png000066400000000000000000000042461440571307300205330ustar00rootroot00000000000000‰PNG  IHDR szzôgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“½IDATXí—]Œ%EǧªúÞ™¹óÅ(Ëî°òµ*#¢¢‰&‹QãJLÐb|Ð}2d#‰‰†È|B $$ôAyQ"hD6A#“h01~ÄVT@wq‡ÝÙÙ¹÷îýî®:LJîû1,&vÒé[u«Îù÷ÿüÏ9ÕÂë» OåÎk:½âvñS=¨° Ðçþ]˲ßç!üð£÷Þ{Ü@ìµ Ëk9¾ïÈ‘ìŽcÇF?»óègêýÑÃFЉB3¥ô!ðÁc1„Ï~äþû¿ß‘#õ;Ž+}µ7»`nãðáp+x@ï8vl°Ôé|ª¿³Í©v§¿ÓïÅ^¥^ŠÚKIû©Ha?6;~sg›ÚÍÛª½:¶ùJþ& Èmà4ž{òË_\/vF6ÏÇçv>ûëÅÁ%ë–//ÓÏ2‰`I­0•î``纶NŸ‘ýïyoïªëO¹B²Ò˜{òÓ<ðâì Ø8<2v>žxêèÑ+ZíöRºESñþåÍ"´žŽÕ¿ÿÁÖ¼UæWWév»¶uú´ìö;´4ÙéP—æÂ»;Û¶öÎwɵ‡Þ̲€Åh^äi÷ÓF£ñÄ'|ð³>àôW×]wõÎú‡^vÑÅ,ÕHY .‡áĪûe¥VÖ[©_Ü×7Îÿ›67‡Á…n&ŽI‘Ê€L6ãˆÉŒL„º€(8)3[fË€T’`"Cº››Ã±ܸ(T£N@¬D/†àÓêmJó!ÌÔQ'Ó1-qRíÀ*›†tf}:€Ûª§ˆ´½/bâ ‡àDqâpÕâi1Ÿ—Š!³qVLÉwΉ1)·«ÝÀÛÆ«½´œ9WF_¦qœ+c…Vc?dzM;±ªÚt6µÏ2p÷بє™~¥3ÝÜd²f‚«è—jÓ„Yy—ÄÎ‰ÚØ„5gaîiQ\MVÊnêøÂk򾂼‹wªÃ(Ç"{„=æ”f’ ·+ͨU"“6QÖŒ#™LOX›0Q>ˆÅ«0‚¯:݆ÙS„Í€P›f1dR5µò ‘«¶.ðõj0H©52G4¥¬‚$ª &º×{~NÞzì\sN¢$‰*z!wWû —5(…&I”Å&˜iUR!™•ÀÌP+ÐY0•sµ°bä­H&#KZj`³Ún«ÐtkÒ’xœ àDÍ;'ÑOUŒÌ¡b8SÌÆ"UP79gï"¥Šú²4 ÕТØ‚0nÉÛCßUSj¦:‡óAœd)š¸ V‰Ñ¡ˆ9L 3-£Qu´’™2ÖjÍ0ç$W33IÑp¹s“V<›p²Ø:M>ß\wá¢^ŠE–’«ùà³Í Ä{ ¨áMÖîl^?¿ð°ˆ\QóþZç’¥ÁEDþ rN•”RQY4ÜnŸxi”ßü›fóÑŠêDf;Ô«0°çÿ/@øNyþäÁË÷ß¼¢á[ëYö0Z<^$9aoJsTœÄø¥_¶ZVû³ÿæøõ˜„e£¼# ß»ôÒ¯.:¾¶¯V«ý¼H<[äXž¾ñø¹³@^1;.„ÿ¿kc¦ym¬­üîÁƒ~þÀú/XZºzfYø_lþŒµmJ¾&Òx%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/tools/icon/32x32/mimetypes/000077500000000000000000000000001440571307300176415ustar00rootroot00000000000000leocad-23.03/tools/icon/32x32/mimetypes/application-vnd.leocad.png000066400000000000000000000050371440571307300246720ustar00rootroot00000000000000‰PNG  IHDR szzôÉiCCPicc8”ÏKaÇ¿³(A`f{ˆ¡CH¨LeD宿شmY”Äìì»»“³³ÓÌìš"^:fÑ=*úé*˜“––Í9R»,Ÿ•"t%1)f¨m-’¢ë’ë²%‹ÙÌ*±tìÌ©vO¥žv¥æS¹¼Aç¯ö°õ°\þù¬\ÞzN=¬/õßÀ¼ýE¯Œ°p cHRMm˜sŽò{„Ún”å3'™IbKGDÿÿÿ ½§“ pHYs  šœ‹IDATXÃ¥–ßo”YÇ?Ïyµ3ï ­nfJ,%Þ(\h\m4kb¨Äü¸Ð¨ü^ùc0F—½HRª@Áe³&8É^‚I—D .ŠÙåBöÆuƒ‚……êng´S:óNéÌûžg/ÊŒ-v¦ì“œäœç=ç9ßó}¾Ï9¯¨*ËMDv#lÜæ{ªúîF¹|#333¿í¶PU±ÖÇ1µZjµZ:}úô„ˆü¸·Þºn Àüü|WªJ’$Ôj5ÊårîäÉ“'›Í¦755õÚz ºðDYw¡ˆ`­Åq|ßçÑ£GÌÏÏgΜ9n­åâÅ‹=0|-Ýš1Á÷}úûû™žž&ŸÏ»§N:¾ÿþ¯Óƒ–ÌZ6Âu]Â0¤R©`ŒaxxØ=qâÄ/öíÛׄ»ÞæÝLDÚ¢J¥R$IÒµuëV÷رcÇU•K—.M­•w½à½š1†¾¾¾vJ\×EUqŽ=zÜZËåË—;‚èk±V1®@éí¿ðàõ?ШVúÒ!C_zŽŽ9ƒû÷±ªd2¶mÛæ†ÿÊ/ùÈ«/óîÈf¢¤É¬Q"q°FX4Pk6q¶ ñýs¿â'g_ÂuÝUqžŠrµ–ѯîaüÏÄþè{L;–…¸ÁBb©Ä _ùÁw9wí_ܳ§uë­áZ:¾†ÍfóB’$«&Û8Æ<Ó܃iÞzñ§¼/òÉ FGGˆã¸£àÇÁó¼o©êoºŠ°ÅBË®_¿ÎÕ«W9|øpÛ÷Úë¿çFn€›7oröìÙö·Ý»w³wï^z±žÊ°^¯S*•Ú¾b±H¹\¦P(N§‰¢ˆóçÏ311A©T¢X,²}ûvvîÜÙñ@ÒÀr0­þ7ctt”|>O†ˆa266F:¦\.wŒÑO"~2H>ŸçîÝ»íqEíyår™z½N>Ÿïé¿rÍ<9Ž¢ˆC‡P((‹íñøø8“““8p€]»v­³íïTÖÚ ON,•Jí~.—[áËårí~:&Nwη1=UÁ}cÌw€þ®ümÌ€û½02@ª·¸=[¨ªj}¹ówL0)>TÔ%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+=tEXticc:copyrightCopyright 2007 Apple Inc., all rights reserved.žfÜ)#tEXticc:descriptionGeneric RGB Profile§8Ž$tEXticc:manufacturerGeneric RGB Profile=h>tEXticc:modelGeneric RGB Profileêo®«IEND®B`‚leocad-23.03/tools/icon/48x48/000077500000000000000000000000001440571307300156435ustar00rootroot00000000000000leocad-23.03/tools/icon/48x48/apps/000077500000000000000000000000001440571307300166065ustar00rootroot00000000000000leocad-23.03/tools/icon/48x48/apps/leocad.png000066400000000000000000000075031440571307300205500ustar00rootroot00000000000000‰PNG  IHDR00Wù‡gAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“ZIDAThÞÍZk¨m×Uþ¾1çZûìó¸÷ÜWš¤IZҗд·±Š­½ýc£¥þ(Ü "þkAÑ–>R‚)X±R°”« PPH@š}ù¸·¥Š¤=m‘6-7†’äæ>ÏÙ³kÍ9>¬µ÷ÙûÜsã­qÂbïµ×œcoŒo<æZ›xeƒ$Éþíc»ww<~»ªêMr¿ÀJNƒM Øù¼•å÷˲|ê]?üÉü ï¾R_ÿð¾wÜÛý˜WÓ{W;%!!»Ã]ÔÜ„Í`$`†ñt*‹Å·±¶òÐ}úéÇþÏû‘Ü7½víKE]cPO¡œh.‚ûE  ‰b£(¡¢Dµ¶þ¾÷~êSOÎdþ¤ºÄ›(‰Ÿx÷»Ã‹ƒÏlm%èNwï™ö{¸ ìv‹Ð d€!B€ä Ê·pH@’Ó¼7žŒmÆüóè~%O'¿ ù›WCDN “”á9¥$Á‹’ÃkV<õ¯86ŽÞ‚Õ£ÇX®”ª²Øï÷±Ó`˜*Œ-`—À•ä†Èa]©·½‰wþÂ/â¶cÇ|5%­Ê±b<#ºÑ0ͤeùO+Ýî—¦9ãþ3gz­ÞZ`\§N­|e:ýÂðèæ{ÒúÊëò\@º{}ô¿óMÏ•6ãæÑ#(»]ÔUBo0ÀÎ`€Át„1…QXAß Ãœ1 1˜L´»º»îí¸kó0Ö<£ ¢¤T¹$iåJˆH9¡7â…ËW¿ö]÷_}bkk4Ó9Ài€ø—Cuq÷¶_Ï ÏáÙ°:¾xâX1<¼iÅÚjÑ¡ÁÜ%wˆ`Œ‚^t銋›»cmÒØíåÇUqÎyÆ(M0Î#ôSÖÈÉ]¹Æ¡ :ŠŒC‹œµ¢ÈH+”ƒÝ¡ÿxgÇ·/]ªãtÒաïyDZãá‰öDh#ÿØ/Æ¿Sֺ믹»Jñ® /Æk.èâ¡Cº|äÒú:bg…%KY+$Å—ÇC]`à¥C ‘ÈžQ×ê”Qgbš… Œ•ÑxÖñ²àm°™²ÌŒ‘@®j\ëõtm{ÃÁÀ”²•e©•õ TE¼8.ŠñBv^®ž;—~ûž7M@.ºe;RÆ­Ã!‡ý>.t:¸pøz‡×7HJ,¢qâÆã)jµdÊB±N‚¢AÆU 8ä®(qÜïër¯‡ÞÎ6¦“ Aª,J•k*g:Gž;—uŽ‹hÀ =3"&&ˆ@, p$%¼öÊ^¾z/nlââê*§ÔýŒnÑEDŒ¤Œd€Cí%ñÙMµ£»ÚÅ`wÄK—/c¸}•r Ĉ²\Q0.À3 !0c!éˆ8 ‹ýÛ`d¤ ,Ñ¥á§ä¸sw€þ°çcÄ3Gñ¸Z¥tÈÈj¤4Çbe6`í0r.=ÿc€²èÀ!‚H@É`p69’R¿¾‹ €SÞ#‰îr3¹ ÀÍ(edìtpÀqwGðÒú:žñŸÓú9ÁÊX€¬D2CŠX¬"Æ3CaäÌÚ¬‹’\1.¦JõRþ: Ø£B{˜€ÓE\`£¼-ôh.G €0t-à§»w®¬ážTṪÂ3Ó .eG ‘)LCD%Â^j,½—ر×7¹» 4¡Ï …Z-|É´ ³Ðkü¬f^0@pI6ÞxˆÖp›ë#'ŠNt:xãú:^ÈÂÙñ.^JB7”$ScÃ%…fFe—C 1ÆÅ´?£ å0„ž¬¡  »Ì]lãíD6þh©ÉhÚæ$a-î^íà¨Àˆ€ h X{p~ó™"ÉÝ]ÈÔ MÖ÷òf»6ÑÏ0ТE@2kZDÚ¼Ë_´‰†Ãlèd$bÛ?ºbÖcÎÖª5„-ÈÒ\öžt³ÆûÐ ùuA<p¦•eŒ½D 4iTc*i¯Ûµ¹FÄ2(k˜…Àö¦û¶8û{ãe9{WňÃÁ2ô`phWÕ,ɳ¬I¥b+U!¶^nR,å7æîk6b{.[¡VÉ=ò,{ÁÛËureÙà†˜XÚÀ…©±µ&Â<É@c Ö °öl9 ê̸=O…í—&ß/^{ùÝ-iò0€ÅÂ;ûò‰Ù—••a°06-p€[ÉEÇÍé¡E—†æ·áõÆŸƒÀMlÛe¯G×í æ>ÞŠÚ aäh”y–[ yš÷ßMæ‰ëƒ€9´2—öŠ{Hr›ÿ›9i`°Q±¶6€yàþö³ÂÕŒ»†&Ç7Êk¾`Ñ` Njñz?̘šrs~½³AhƒVËÀÚ=ã]X:ðH;óuýb ihlJ¹äÖ°ïs7µ ‹TZ\gø½Ô©…XX0QÊY MÎÓ¬o†ÏN&“ýv´åÛºaô¥3¡¡¡öý6?Ú sjin8roAçz€Pëµ}ùž mRëo[Ç£ÕÈg¤°§Øâ”¥%ZZÚ*ݲl`É\H´Ä†43!ÂŒûÞlH®³pû‹dñ©-Zúå”Ï2òÌP;pj€¥Ù¬J…ïTS I ­@Z 4ë½ÁN€¸ 6#°ZÏ’|Ë~íãÙ]–”`dö¬ö3 íË}Ðuf#enW4$²¦Ê­Ùä°ñ†Éþ«q³Q T˜çõ¹uµ¼q™ƒá2ˆ:eͼ`+ SùÎAº ¦ïŒÝ‘Êh€ÓXÈ%=K0#èmѽ6‚ ÙC]b ÔÒÙž@ò,ZÓ#Ù]©Ùn ùO bÜ‘3R.ÌbJªC$# !«iÚ¬²×S¨y¼Nƒè˜›“{Êïņ#ÈÉÅh¬sj2i^2³‰„ª—p¡•Ù§úÏu™s,zveBvÅ60 ,2(+k7p³r×®pÞ…u5´@Ÿ,Y`“2¬sÊ•»heœ cœÒ#WªúÃ[½Þ³ úêeÌ@Üß<'ÊðW¯¾ëôzð‡N„ø:(Ü«’Š!D+$E$ѤX“¡é&¥Ç&5ž!ÙÍIuÛáf5%. P£¸'(9B™ «úéi¥Ÿ\½Á Ø«§K#à t ˆÏþø ÷4ËÎßÜbȵëÞõW¦9@Êró¶ÈÉŒ’ ‚D&yÞ—sRÇk4×jw8uN¨<åJ20Æ~]îÿÃÕ+¿õ\5þÞBœÞð}rÀËŒçÚä÷P|~4š<Öœý¥ÕÍ/L•o!¼!ÐB’gwIÁŒîMÛ-‡h”g¯®…@*«r ’ÃIV)åZî²+€»uþµéä׿±³ó(€ À^WqÃqÓï‰O·`g´úË;n{×øÐ«BùÆ Ê«HÆ`f¤²­Î_¬ÎKXP“œ¤¤ ¯+D¯®ÏOœ={íò#ûŒzSoñÃÍLBK©EZ=ÑþàBoð×?³±6­=ß»‹î"Üë ˜B³-|Æ3.[ Ü1É)gw’!ržî¦ô'ߺzõ7Ÿ¾³.7õŽø'p­¦÷_GÙùû©ñ„™ýl¤…:ç,ÈSáG^Ê)·¯ñ‹ŠÆAžìòoüsïÚ߀êférÐx¥ÿ•§±G«¿¸ëøû«óб¢óæŽ,T_K ç¥rEŽí:ýGªõѯl_ùÛ}üÿéãÿÙNñlÓ¾ @çswÜþu t<›ç<á;“iU¤ôçß»rõ“Ïíõ4M°þ¿| ¡à“·n¾öswÜñùß{õ«žÄææ=³ßO6sþW ÿ°ŒeuÃ3•%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/tools/icon/512x512/000077500000000000000000000000001440571307300157735ustar00rootroot00000000000000leocad-23.03/tools/icon/512x512/apps/000077500000000000000000000000001440571307300167365ustar00rootroot00000000000000leocad-23.03/tools/icon/512x512/apps/leocad.png000066400000000000000000005234301440571307300207020ustar00rootroot00000000000000‰PNG  IHDRôxÔúgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“€IDATxÚìýyÐ-ÉuˆýNfUÝ{¿õí¯Wt£Á‚¤.C-CJÄBDRTØÍÈ–äPx<3V8fƶä‰qLxk¬ÐØá[öynˆœ67f Á À0˜ê~Ck¢€h,ìÆì¤@°ÖF¡³i½íÚe3ÙnrØ4Í^7›Ý™\»~ËîîÞj¶wnµÓé«þøøZÛuw`è:€knw››hwv€¶…r¸¡«5­iMo­€5­éÍ&fØéÐmmÃÇlvo;>8ñÅû‚÷ ×_èøúW¿÷…{û£ƒúãsnµÜæ ôp˼ëá‘Sû‘D™%D&ñMŠ|ÞÄϰ@D‘¾’å3Ògb È·!DtŠxµ3Ç“˜AÌ`f ›m‚ù²± A ŒÆ6°“)ºÝ´³ìdÒw›[{“í­W»®{mãÂ…—»;w^n·w^´‹åËÍÙ3W\m76¤qk66°Z›*×´¦7ÖÀšÖôG%fÀ@»±žÍâç{†Û·rνwyõÊ{Žÿ÷¿ky|ôèroïþààüüö-ô‡G轋0¢sLQë&Sþ¡ë`‰À ÔqdîD…['m>ÿ@!}&Q÷Ëoœÿ‡¨ùS9Îzwn? ”Ú üc¿ò­ËÿMúnýj‰ùµ… 1_"¢K¦ë~̰dÐnn`zö,fg϶;;¯M77ŸÝ:îÙÍ­§ ™§'ÛÛ/ i^4wI00]¬Vo÷,XÓšîZZ kZÓ7C‰Ašn3›éßäÎí{ýÁþ{–·oÿá«W¿o~tôý«›7>¾výÒbïçàû~è8jãdmdð¶Ym—Xi­G#kôq‰°=Æ-\œ`EÖ›5sdÌ`N ?I„";çtw%@ Hû#莧vc™"Û—îEÙAõË6 @´CgñGŒ~>Çááø…ç·‰±ÝtÝ»M×ÂÂ`vf›/ξü•6ÏŸrûܹÇfmûXkÍãtñ⋆>!.Ô4êùÖ´¦5}#Z kZÓi$Úýd‚f:fLvwm˜¿§¿}ûGž|ò‡æ·oÿâÕW¿çðµ×ϯs ‹9úÅ2jÌÖ¶1h˜¦eŽ|51áÌÐ)º%d%öXH˜»8"QÖ±Ó?6ÒBBR[IxȤÝÈØ3ãæüÕèÎF éU|þ¹ù襗޿ÿÊ+ï[ìïcµ¿~¹7MŒ1  ™M3¿‰üW1îS˜k<‘+Xž’V­¡ýr-¥¶CuDð CˆÖÒZ¹eÔ¸€)¤j˜ù `®ïY<Ëu F”8õ'ù!do1hSB1GPê§39A Ö¢±Ô%³Â°B¿ZâàÆÍ ~ì±÷w]÷þÉîî¿6ù•_Áî½÷½²ý®w}aûÂ…Ïn¾óáßi»É—íùó cðþíž]kZÓŸ(Z kúΦäHg··éábX®þÂßûüŽ®\ý±½+¯¼oqç·nÁ1G8»1 Æ¢ÙÜT¼5ré€Zá¬ól(ŸËçJ$`Í|1ÒØëÓˆÊÕË@\Ìþ‚6¤_+ÞÄ¥+ÖÏ¿”6õ3©ïä ì_òáè¦Êw`lŽÈcFÉ4AwˆW“8:8Ø®&˜Åñ1¸óÊ+šÏýîƒÓíí¿<½p ;—/^Ù}Ï{?³}áü§6î½ïSfgçëè&0¾æ5­é;‘ÖÀš¾3‰Íövd«þ‘ãçŸÿàÑ«¯ýô­§ŸüÀÑõë»Gׯa\ÉÇ0™ Êˆ"„ŸtÝÄ€Ó̼]kµXyð#iè‘£®löª•ð¼hæJf`iZŽ+Dûpt$¬¿6[û€k`H}gò+GΫ¡~.fræÚ°tŒ+÷°Ïã#‹¤CMÌéA ,‡Å•Wpû•— Ï}î_Ý8wþ_ݺ÷¾áÜCïøìî÷¼÷c»÷?øëtöìºô‡Goñd[ÓšþdÒZXÓwIx^Û¢™L<~á…¿¸ÿܳ?û…ç|ÿ¥—f‹½°<Ù¶ÀQ½†–4ÓPóäD7òÆ×Ú´rm¥-£ØÏ3œŸò:UvŠ<‹G>úXöçHRh€X·©ŽEÀ Šûçg©¬$%Þ®„%=ÄB¨þ‹§«Ç­n®'Î_g¹#G*¤oš&Ž[7Á|>ÇñÓOµ×Ÿ|òÇ»ßøß~ðÁ¿îÑG¿´óÀÿÝîÃïüåvkëË0ÀÐkŸ5}ÇÐZXÓ·7¥LŠ´µ…ÖZ¬^zñ§n~úSýúW¿úÑ;Ï~}wqt„À1¤Œ6f‰‰D(ŸBÈ´°ÍÀ1ÄŽ…©j† q×ßKyvªOýDY§ìÕ_Ђ‚.ÈéµR.j¾ØÛ¹0>ˆ~\Ë '›òþË¿4ð̉•i j´dbÕ† ÔýÉBŸ4T#-̞ʽ9ƒ&\ó'QBF(}§d2Á…€›/¼€[Ï>ûƒÝlöƒgyçtö¡wþÚÅ?õ§þëÍûîû§öÌ™[4ý:ÄpMßÞ´ÖôíI‰ñOΜ¦“{æO<ñ×n<öûóÆO|ÿák¯a>¦džÍ23á”»}ËÌ3Oš6g-ºøî ûMŽðU¿Š€RxœºFNx9ÄŽ´•<æ à“ÌO{pÅÈ‹¸ÕßÑ £k²SÞ(LQòj×Däç-Þ‹•üP!µá!'ÿã2h¬½!)=aò PwQ”© €x]HFC°“ Æõ§žÆÍ§Ÿùð•Ï}öÃç}ôwá{¿÷¿¹ðþ÷ÿ?šó矠ÃC¸am"XÓ·'­€5}[’½pÝÞwßyúéãÚc¿ÿ¯Ý|晋ËÃC m£=?1ýàCe'Ï¿²_× }m{Ö̇+f“8åO¬`rœ`䢿FóÃH—6´ߨ®`âÕ1“ÖôQõKN£â]8¶(˜¿«1Ò_É;£Ù±²Žˆ`E Ð턪±ü«êçÈã1~m‰mæðËÀåût½IÂÀb±ÀË_ø½^{ì«ÿîΧ?ýoßûC?ôߟÿþïûϧç.üº_.á†~mXÓ·­€5}{P*jÔÅ4ï»õÙßýw^ýìïþõ[/¼Ð­ ˜É4›B@Pá`,?„cFÆ*§~³OÙ< íéÄ%®fdˆNuUûc»;²g?™»rø&WÌ1J²éRÑœ¹:© ùq*ûCA?ª®U#ÇD1iÊP† e!&ÝSr œxœâ} …Àbû¤B%n‘Bc¤CDkAˆNY>Kfê¦ðÜ|ñsë¹ç~aç·çîýÁü{~è‡þáô>ަna-¬éÛ‚ÖÀšî~2fwSkºó•¯ü¯¯|îsÿÓëO=Ù a»f:‰Ê´÷I³¦¬4~ÕÜHáÏßpÉ”£“6h›yMÅ¡íôßGo£c$GÄÈ8űÎáKºS,{9»@ç Öàt^í³ „™t­$ Š}¤“ý—¶¸#™,”„”‘0À†•b/hƒÀür/1äã kœ‘€ -¿Õ$°ŽÀTÂP’2@ PÓ‚ZÂþµ×±ÿKÿ샯~ñ ¼ÿGÿô¯<øáÿý陳¿=_§ ^Ó·­€5ÝÕd¦SÀZ;òÉÿåK¿õéÿÍk_ùýÝÕ|3›Á4Ñ9.p(>5ÇŠ ORF{­…g ¿æ·¬—:‘ÏÕ<¼8 Ö úX‹”‰žUzÒýGîHÖÀ«¢O_]£ü*TH„ fP®ˆùÊʽ±Ja<Î<˜åÖÚ¦Rî{‚˜Rr ˆ¨Š˜¬ÜÞµÐ+}€8Ù- %#¨±@Óààú5ìÿÿþÛŸyý±¯üÌýÿÒŸþ^~ÿûÿC´ÍóµhMkº»h-¬éî#á ]Þ»óç_úõßøÏ^úôoþÐñÁ!h:M§Ù©/òŽì aíµ~"ÄMÁȵñš=JšÝȘ‹t!^þbOço‹ÿT߻У%棙}:Ö>ÖS?=n¿ØÑ)7-Þ •Ÿ]ͺÕój Dw^ ‹ºïéíè…‰×ãª,€# ªt£rp§HÕL™+‰IÌ%å1_P®€HÒ—Rw£ B¶5-n>÷ö^|éoÜ|ê©_xô/ÿüßloÿç«£qMÅ5­éî µ°¦»ŽL×gÎbþÌ3ÿðé_üoþÝWŸ~ ˜F~Œ€ øºNZ¹ÃXó/ Sü5×QNr@I„“˜Tå ¢ð¹R¸(Ü_™Plà¹[Ú‹]3<éÛ¨Íõ'î¡®yC…U é}6'í”k0ºz%Ü/óäQ'jÇŒ=+ôyEp#pPOŸ}ê¾fÔ%Ëu„G̨ {+5ʘ˜2“)3^ù½±½÷üsÿ衟ø‰¼ãCþŸc^_cMkº›h-¬éî!æTÛnüögþë'~é—>x°·»±‰Èèc‡QJ[ÜyÔ–A²‹G3þÁÝœ’ëd%VÙ¯³¦*|+«à§hÁê8çÖGÕÇü%ÕŒ=Ÿ“;U®?R#æ]'ªÂîÄþO¥JÈ›3´íŠ=¢ºL˜t…¡"2Ž‘ÌpV?q<åN3®þd¡fl®`5°ò<9/Cv­scÿÛÍ-à©úOnqpð£|øÃ}vþÜo`Mkº‹È¼ÝXÓš¾)b¶và‡^þÿþ“/}ùñƒGG°¢õ‡è™ŸÃ8$ç,»œÂRÂ61&±éç6TÒ›áñ 3ÝÌiOpî“¢Y×øƒfº|òÊŠ«"[œÅ× 0¶]ù0и©\W°~þÚŸÔé,„DÆÉRÕ ³ÍŒYI8yŒe$T d- |£gzƒ=ý ~ƒóN §š?zÞ…‚ŠpšG>xPÛ‚›ÏÿÚ¯ßóûÿø¿øµÕÞÁßÀšÖtÑZXÓÝA³MÀ xþ¿ü/ó‰_þå{0lÛ"pH•ï„ù³—`(ÛoÑÄó÷DÔB¿ÑÙoÔ¿€¾o6R+µxtÎaø•çai;¤P7ÝAó²¦ *~ PÃT9ÖQ(²¦_˜~ õcˆQD®ª úåE„¯üjt$½«ŠsŸ¬ÁPÕ@ÐNù¡øäÈòhôò9Éw ¨ï’s)`fSÜ|êiúÊÿýÿö^~ùõ‡o5ÑÚQqMo@k`Mò‰ðîÃ/þWÿïO<ó©On;Û€È „µDóo6?Îö¸>M>UëÉ3F—¦ã‘ÖÎê;ñ Ð5bGê¦9¨È”k´£mऄê=3Ãò/—õ-PHqj$}œ\Y³ÜÜ8¾¢‘@¥3"æˆ@ˆ(ÀehÆÙtU!.Œ\ªj§z+§&sõ†e~èçÁ1”§ãr\PŒPÚ“’ó\2“ î¼ø¾ôþÑ?Ø{ñÅÿm|½ã°Äo=qq˜õV¿¦“´žkzc²ö߯›AŒï¿ò‹ÿäWžú̧Gdb½{µí¼hÿ# $Æ©LÙûs}RçÅÚ|€ÈàNÀתí l¯+ûUŒMÁÞrö ‹6X¾ga ¥¯¡–7 äž‘–]‡-j=xt~f“'aqÝ7iwlF(ïD 5£ö5ø_!0§ÙüÇ‚ÜhL˱FSt¦Ç7v,Tö 7@Õ†2ï°j2æ!Ä‚n‚£W_Åcÿøÿ‡7Ÿzòß`ïâ Þ¿=ÿÜ~é%ß¼‰v2ùì¸5}‡ÐZXÓéD··÷'A‹ÙÝûäoüÊÓŸþÍf€Äü‹æ&§iVFÈ¿bÄT‡0Ü€“l¬Êq‡1«© ˆÚ¥fr”4î1±f®êž ûáS¯(÷ªž._{ò—“m c3ûú>ot£LßWBÀøÙŠ@U•NâúÎã#>ñëi¨Œ“Z Ï“ F¿…¼üj(sCHèu-ö_|_ÿØÇþÑ0_ü…ì\Iô­ÿ‡$œ¨Ì—kZ“¦µ°¦S‰ŒAíع·µÃ3OÿÏüÚ¯ÞÜ÷ k¤É*´5<[¹““ú YW̤ŠÃÿƒ®!h “O9ŸGgÈ5%Ã?«#¹îl´Ú¥ÿ ú?ŽÃ?ѦQB‰Žr úï)ZwõØ •¨‚ÒïDˆ°8Êwã¡#)=4oÖ}:)22>Ê´rrübîÒE`¾576Qà˜õñðúsÏbð~”Ñnl'f¢ád†’c‘ñ2 c̘Ky N侯så£kª6Y©Ê#Áß”ò °xÔ'Ù!hÐA1a `®7Kµ»t_1‹r_­Ù—”ytII,0¶~]ëXÔ~J^çâh©o,%ù2CUiüªò€8ùY¾ªŠ‰é¦À Äa *C_æÄH†:ÅÈãª_9Ô‹G ¹X“40â…Ï}ö~öá‡ÿO¶µÏ»¾ÿ&ÀÈ4X­–XìÃ6Mt\ÓšN¡µ°¦7&¡K>:BwéÐv§jËo:óùÏÞ~ì÷ß{4ŸƒCÔj‚ ‰ŸÓec'8ÊL©Ô³Ï×Ô wü޳8a “̶‚»«vjýS_“™hàŠK±N]+A ¹C„EåaÅS€À95pv zоJïÇ*yå:¹’Äçd&=ý§æŽ#œ\d¥NóÈBQ«ï’X‡kØ¢Hw:%°Ê¾.ˆŽ®ƒTòPyŸTL.bÅÌŸ2:â.WÚÐPl¤%.ÝIEJ½$BÀµ§ŸÆõgŸý·úÁü;æøè½4¾1Û4p}7 0Ö‚ÝÚþ¿¦7¦µ°¦7&Ž%vɸƒ˜¶iZà­Ö(ºýsÏýͽ«W1 CÒrßÈf¬´ÉS2ÌUö}½¯Ÿb¢EcD>G§?ÞWÇ:ôµm]gÝ+hxSª9ŽÀÈÒÿm—N \´m¥^« )Ôcœ+@Eì§[»zjG%%NM©k¨œ#OXJöª1Çb;é÷<æòâxÔW¿Rã¬zH2Ö¨‹QÕÿÉL(T”üL£PÅü$§¡ÅdÃ1㕯~õøÐûßÿ÷šÍ­c~ Q4j0û¯\c k`MoLk`M QÓÀÃZsérü20ð–Ø4 Ú=~þÙ,ŽàKIW^-ŒS84kÆ)†Ã5mõ5â°Íª “µS… $µ¿hèÅ6] !…ÉÊ9¢MhºFò˜«á(PºvA«ÝÒâ)c£{qMôQëzWc-㤭/ùTíK‘uZâÂR½7=×…ŠÊ÷àÄð%WÆpóå—/]{áÅߨÞþذZâ­ ¯ã½;8xí5Üÿ¾÷aè×%‹×ôi-¬é&æTÝbþÜshÏžC»³ ô‡|óîÕuÀ|þÃǯ½¶;¬VÞ#0Ãr*Ù’×I˜z¤²k»€:>K®˜eÍ‘´Ù¢Å‹ª?È«6~®YAJp®ú[³XÔý–Î2»2º*i«êšqØ#U,WòT-œt”;¡Ôrõ[mT?GîN¸?­ý,pe]8ÙTÉÿ¾Á¸•)PZ¨ßyƒÅgCÍ‹<\Y)sàÄ3dŒh²qì1¡¿~7oü™óÜÿ±n5Å›JÌh&‚÷xþ_ü  i@†Ö‰ÖôMÑZXÓ7M¶ë°º~ Ãþ>fgÏ‚c”À›ˆ˜Éa~ü=ýÁa grÁ ›¹`D—.#ïùLÌu‰]®‹Øjïreâ?aÏ>ÁúFíŒaóJë­”ϧ‘ q’Û—’Æ•†ªµòÑ5§ Óãジk¢>KJâb|§,XQ-Œ‰oĨ¤oZ€ò"”p6*”Çè ÞgQQư c~ƒßGíž|Åœ0ž'U; %§¤L>À‡ÂêèGû{ïmºáM6Øn‚ùÞ¬Ža».¾uêß5}“´ÖôM3ÃL&0ÅüölÞsöò=òã›r"‚éÅsáèð&ø”Ì0†¢×šŽ‡¯üÐèd:ü1tŒ“L± 4 ¬ÍúâJP÷{9è„ ‚“ý?⟰tR'hó‡0nÅé3o%åˆ8öî'•ù_3]*·¬ø}‘JTGùôßÔ8йƒ2ŠR%ÒÌ\š;âgúÃzʸŸ&œtæ«‘^E_„Úl¡$6äêIã{U¾)ITÎô!À1cåŽöö/ôË%ŽöñǦÀ€1Ñ1v°ÿúk@h' ߢHƒ5}{ÐZXÓžˆ`§S óc8³ûïS›g¢3¼êA΃¼;S­¢)&#ʦ‚gI3)hCyç¯Õ‘ÒK§1œ´y“fX'¼û08F¦›ÖÌ^s?}CùƒÏ‘ýû³öo•Ý94á&Ùµs?ÔefVkïÅaA?ÏiÎyÌ& œ½ðõéQô0§À÷ãçW‡§¼ˆüÕ)n'¾ÐïJ¡œ'Œ,(Ï#‰ #;uÂ)õ§ Á> –ÁÃÁZ¬ú~wqx„åñâ›XoD1ë ið0€ˆ°:À[w­ºÖýÈæ"S4[1Àõ¸j÷ÄZËO¬V¡4Ò¾~äú]Åç¯4C· ‡Ô&©÷ á%ñ²ÊRdVá¡#§Ç1çW%‚s>fïáÃjp˜á-àA`ž9×·ÎýlTÏ·Ùý|š®Cðoo¶Î5ݽ´ÖôG# ì:¸ù~µ‚ÝØ@wÏ=oBã4¡À°! á€Æ;ôŽ1&€µ62 ´r“»[ùf-oäV Z,êSpò‹“ªë¸bÀx¬ªÛ&†œãõ«ë"3£ñ5elÞà.©F Ì[_Ç(¬n¬T³âýÊv_Ü?ÏØûà4À^‘ðÈè™Núlœû‘Fž…ŠÔÖ"„Hs" èg:åÝi)N»TÉ¡”H#LŸÒ}C€~pXô=–ÞÂ#À¡5MÃfþà )ÿµ ZÛ€W1Æ?¬íükúcÒZXÓ˜aÚì=Üþ>ÈZÐlŠfkûÞ¦µ†š–-3`‡«a@`F7™À6Sl·#›¸†õ#C ¨¬ï„^µØ®¥¡|IŒDˆÉkІ]ûì±:>ávEC_÷ œäû÷9ù–ós¼}%DœÎ”ë"9§·xªä®Êwíð Õ{«®‹ ýª1ŸqœEÑš³s¢úº6ëÇ/ƒJ(‘ÌVwͼ7øÀ!Àõ=–«%ÞÃlÑ# 4 š¶1\™þ@Ê Žˆ°±µ zxNͰ¦5ýQh-¬éÍ!"˜Ù îè´˜ƒÃnïüaö»Ò”È‚¡ ­h½ÃàC*rÒM§° C¦”¢²Z¨býKeÀ@‘SP;<ŸÒɹh¡ÌuFýÂòè¬jäÂ>úžç/& É }9®Uyðó HA’±®rŒ÷µ0ÿ"@‹ëŒ}(4ô.‘5È^ ùÞ¨ N±Pj3”«J_ë°?õ®b“Å1mr9áœDô§HM‘`Ž^þžœCß/1?žcµ\Â&ƒ` B°«`àôO‹i‘µŽ¬ñdO ÆZø¾GC„ùñ1˜LÓ‚ýšñ¯é­¥µ°¦o QÛÂ/7zs˜ÜwðF&cz¤ÒØM7/W˜˜ÈK˜CòÊbPúå nsvsÝt†&®0Ræ•0Íœí˔ިŽS/ênaWŒ,€•æLE¡Ô€AfL‡4Íã_®¢­1Gß;„bˆáˆà­Å*ÿlÓÆŒ}ÆÀyC“‹%Óš$¬V+˜¦…wël~kúÖÐZXÓ·†ÄA°iá+W@³ºK—Nœj¬YLdp†`Úͤ:ÄM“(€œƒ € €q}¿ÀòøýÖ&ºÍtÓ caŒ‰í†8ÚI9ÍeEŸ8"ËÙOž2²^R¬³~¬¨¡JTÖÈ…H3åÔÆˆvâXòW0†³caìQÄãªOb£ÏàÆÉD:%¡LѶCáÛ'M*6>6'­#\5"¶sû>ñ }{”r¡Öäå8¾jw4¯Ê#›qÊy)?BÐj _’Ae p„ùCÒúÃ=Vó9æÇÇX.—ð!€ðˆf&O¾1轇k,ÚI‹gY 2&:©Z;ØÆF§UD$Š}lg8>ŽÇÒ¿5­é[Dk`Mßr2³üb^ÌaÚfs¦ëòïD¦‡hº1îh˜¶Cã]J™?qˆB€Æ3ý€ÕñÃìýöº­M´“)¬µ°DÑ'€LruAØó«³ÊÕ`s£5cŠM:còÊfžÛ­cìå¾%Ô¬þ]xoá…5“{òël{Zߥñ±ôSìñ:ºAÛ ä aþ!µOZ¨Ðq|£c @  ÛSÌYÛøóåª2`y6% hL_Ùùõ8f_øŠy¥œ¢_ ŒÀŒ<\?`¹XàxÿÇó9|ðh¬ Á3Ãà…#`ðhZØn26MDˆâ”3C4XkÑ4 wn#„˜P‹½‹VÛšÖôÆ´Öô­'æèÐup{w@óc4ÛÛ°[[ÂTVh," …"²Ó´ .Þƒ(À2°dÆ@@‚[ XÍob…€ùdfkÓÝ3˜loa²1CÛ´0&1ü@±À¢P=ß… g¾öbÏ6ð± [Ù¾ÕÃj^%_y÷ŸL-V­dlûä½5ì¯éêúö*´QŽƒrP¶ïÚ2 ÷L£ö§"¨°8;RÅÈsç´ ÂÙýZ"©ü ¸VóC°g˜Î ý>nÞñMƒÉÖ.lgá0MÛ¶yü‰"ì…Ê(XNw¶÷ „ùÍ[8¾qÓšuxßšÞfZ kzÛ©ÙÚ‚NÛ´‹+¯ü¨;šÿŒiÚ´wRÞüc1Ž6Õ¶…á¦vððf€_ÍAîéБŠ}è±ìWX®^ÇrÿuÌ»-4[g1ÝÝÆl÷,¦›hÛÆZEfN!Þ+jo*üŒT à›×Ùç#,NbwNýΉ…´mþ„-[9ñq¶NWvëÊÉ/_óFçÄïjó@õã³ó3¨¾Vþwr¯ºqŠ4s. C%è ¨Pu]ô(1à‚‡böÈþ Áaïí?ÆñƒG߯0ßÛÇþ›8>ÜÇr>GàUœm m‡@+ô«€åüÝù‹èš LJD%cl’YD»,¶ÓŽoÝyïÕ/駦gÎ~vëÂÅýéö68 ËUD Ö´¦·ÖÀš¾µ”ŠÙ¶C³µ êºÅë¯ýØÁó/|ôö ÏðÕ/~ñ½çßónÜsï}Ìdˆ‰r]x±;3clm´¡¶„M3Cg-æÇS,Vh¹Ç`-µèZ‹ 0z°\`¹8Àá­³ ´[g0ÝÞÁtk³­ t] ƒ8¨ÐA€’IÂP §+K>*îY=¶p¿sÑu¬ùˆƒ ó/³&,| !,zµyAµ©ÜåuL[Œ½jߢҸ¨¥.ºæk{'±ÕË}³cÞx%³# †²/åÏœ¯ÍÂT®ÔÇð®Çr¾Äñá!Ž÷±¸³Å|Î÷Qøk4„˜ÔÎÃržLw°yá,f[³8ŒZÊܘ}"d(b?7vvùÕ§ŸxÏã_}üc—¿ë»^Ú¹téSd~àŸo?ÿ™í‹¯»¾G| ¿Z}Ë–ášÖ¬€5}«h“¢LvÏ€ˆv–{wþåë¿ÿåî_¹ò¡[O?ýèñ;p«%úaÀ®È$ÍHø DæDsL~|ÆL&4m‹ébŠÅâ+·€Á!`€Ã„i;Á>0V‹=¬æû8¼Ùâ°Û€Ýœa²}& ››h§4mÌÇN³ Jè ¾0`ÉL—¹kbAõ52Ó ‰€Òו0 àøB'ú¾áñØI1ÜSœåRWBíz‡Xþ(wHùä*_‰ºårWVº&¤è ¬J'!iô]HBC©'P„ƒxMŠÛ÷êÇr>ÇüèÇXÞAß/cÒ˜h&FÇàŽŽ=Ü‚Á“ ´›Û˜îœµ"j ô‹ Š!‚— HŒƒƒìá u“ÉßxæsŸûçï»ÿÚåGýÔåïz×?ß<{î×w.^|}utŒÕ¼„%®iMo%­€5½ù”´cÓXØ­m`:úþœŸÏ?tõñÇúðÕ×>xû…ç<¾uýbf¶²vs æxŽáxö!ÅPS¶@S dÅø‰†cú_6†€Í ´ÝýjU¿ÂàŽà‚…3½¶y€k§p`ôì±ê÷Яö1¿sÇÍf²‰fs“Ííøo6E7é`›ÖjçA‚—0®¾˜=õ“®šÝkô$Åeô·ãê5A”ü’— ¤ÓàJèˆ"ef4²Î'î_eNL””@¢ãú‹G=i?BTˆ•^”qBB;T„t¨Ü4šD¨8î催 ÎfŠÒ(žû!1üULÑ{t„Åñ!–ó9VÇ–+°ñ ˜ŽaSŠê‚gOž[88vÑ«ó&[›hÚàHDqn¢8]F»¿öYIïÆDiµ_ÍAÆ ™NÁ Ì >ñµË/>ñµ¿º¹»ûWÏÝsïþ=>ú©³÷ÞûëÛ—.}bë칯÷ÇÇð‡û:þtMkzSi-¬éM¢Ä€ŒEwfè:ðüø¾£¯ý#{/¿ô‘=ö¡ƒk×ÎÏoÞÄà}t€2íæVÞà˜˜€þè®ïAÖ"( ’•=9”»f­‘Aѹ+4°è¦S ýC? ÷C ïò+ f‚Žöذ8x ~Žåá1†CàÀv`ka» ØY +œnl¡›NÑv-Ú¶ƒmm ïLÈd_aÊDH™kÍ cÁÈŸñ‘´]’ù[4äÂÞkM‘+øY¢+Æ<†ÞÓ˜Uweõ›ôûŒ¯MœóP9•€£OÞû×§ÜIÊ)˜ üC÷BðpÀa5`µ\b9Ÿcqt€ÕbŽ~q ×÷`ŠIuˆÖÛÛ€€Ï xà¸Çà6Ðt†¶›¢Ì¢s€|B¢Dè“¥ü¤…»‚d„°<:ŽÏ±N…N‹Å¯<óÌî+O>ñs;;?·sñb¸÷ÑG?½sñâÇÎÞÿ'&m^¸€Å;n.¸¦7ÖÀšþxDY‹n{ÀÁ=zçÉ'>pøò+?sã©§>¸ÿòK›óÛ·À6ÆñS7A# €S8^rÙfDÿ€Õá–‡©xeweF_Ç™ÇÿQIûÂ`2™¡ë¦˜¸!2Œ¡E…p0p¶ Œ> p¦Á¦8vè]~µÀ°w Ç‹CjAí¦Û@;›¡›m ›LÑÎ&è&34EÓÄ:ÆH”%Á ('1©XkÕDT 8ºÄ­– ³ŽB‡ü^x¬xæ—x~ 縪b!8ùPAD€Ð>‚t°ÜG˜_Pô%€!‡rnöàü™?'/}ç<ܰÂj¾ÄjµD?_ _aÕÏá÷½1`:À˜Æ0l4P Ç{øp­‡!F ´¹‹®›¢t¹fEAwÑìóg`d!(ñ-VÆì{ôû{Åt ïL>fÒÐaÑ÷˜¿ô’¹úì³?±¹½õg.^úgï½ï ‹ƒƒŸ¹÷ž_›9ûÛít–pGGo÷ê_Ó]Nk`MxJqü“Í-°±€÷êöSO~dï¹ç~úÎK/üÙý—^îæ ¦µ hk;jL*ÙJ:„X…ñcÑcqó&,Õ̃JÕ¸Ê9S®rÈvaö” ¿·m‹¦m1 S8çàƒó\0xÇŒ=<9xÎNᛀ>.,1,–ûö€%Y°iÛ ™Ma»)šÉ Ítmסë:´“ lÓÀ6ÖÆì„1f1%qv(SÂMyô:6_ë‰0Á>ÿ&c«mú”`ÁP4’’õs–—ß’9”pPŒjZ ÄrÉ£»äl‰e‹° 8BˆayÎy8ï‚‹ˆÍr…¡_¢_.1,—èWs ‹%ÜàÀè£VîÛF&jÝhA¶éý7pðÌÞ!X·|¸1 IÓí k§°¶É‘!x1Ñä!‚j‚r"SÆ 0æpÒì°šÌ`d –‡XîïÓ¢Cb¥ÄÔ`ÌúÈâ:B ¶…m;8çqíÊ\{ñ¥~泟ýá3÷\þ÷Ï?ðà3÷½÷½Û¾xñW·/_þsׯоݻšîBZ kú¦Éll ÛÚ‚Là«Þ{á…Ý~ú™î_yåÏÜyñÓ/—`Ä>ÍÖfý*Þë€dt˹ßU$ kàWK½þšË—kŠÆJEcÎy’† ’d.Ù¸¹"ÃæfЦ³ànK û€¼wp¡ƒgÀñ€Ápàx¸°Â”¾‰ŒÁ±‡çä0æ†a7ÃXj¦[‚i&hÛ ˜I‹¶› é¢ÃbÛu°m‹¦i`›ÆFcSbê¿T‘GòK²¾õîåìd>¡ì}GŸÕµRÅPôy]U ¿¶tïÀ©+š‘«´}•À’d1¯~ð“íøÁà =碆¼Zaè{ nŽa¾‚zxöaî“Ó¤( °dÐt 01A"s›"!º”§ßÀ3ÃáSE?` ̺(¨ÙÔt¥´2ûäã …Îs-›KRx*åô I€#5º)3ptó&üñ[[Š@‘æ­ùõÆ9šÌ †¶mAm‹îܸۯ½öîg¿ð{ïÞ¹páqñ¡‡_¾ü®G~uçò¥¾{ùžßöƒ»eún¹x»·Š5Ý%´Öt:% ¥™NÑÌf@Û¡ýõ=xù•Þ~îÙŸ>|õêí½rÃj…vÒÁÌ6Jú\fx.›ÜHq„. «±áX8¾qÓ®…É*~ ±*Ì+jb<8U ´†r:Y!“Í‘1 +lmkKNxÏÁ;xßÅòÃìáÃfpܧï{8&cÀ¶‡³ <,€@Î;8à‚‡_Ãóô̘S² Æ60“ø·if0]‹¶é`Û(X+ÂAÓ60Ʀ’´¨E¹Þ¼ò=ÐcOj¼Y8˜ /P ðT2€xÙ—wÇAìó±DspÞ{xï\Hýï{øÁÁ C¿„–pÁ!8ï¢`údSµ\—Ð 4`P×Fó ˆ|y£lÀì£c(7qÜA¼‚Ø"˜&:ìušv ÛLA 1Z@| ÆÕ Ëø%M?Õ0ÖÀRˆþ†KæBæ¬ÅKÁ¦þèó›71µñ}…P×SÌc¬ŠQÎï kSR¬ŒÙu 0öö°ó ïxñË_þÛ»;ûâÿvöÞû>}öþùtsãSgÏ^]b8:Æj±ÈBÍšÖ¤i-¬)'hßv4³ €È®îÜù³7¿ò•î½øâ‡o>õäû{w0Ì—ðl7™N`B Ëb©Ð‡"°Í‰ÙK*Xe©–»&d-†ƒ#›×1ÙŠ SÄI0û„òÎ9pï€àá‹öòÉ$2C)ÃZöˆwïõ 2c,,Y m>pÖ\‘Ç]:žÁqHæçO‘ù{àÉ"à Ÿ4QF0»èoàWlV>½Øp €£g9ÙYLƒ " j Lˆl|g¶…1€±& M|&˜R’#C™™Dé(¡ ),/£ÚR¶û™{Þóž_Ú:{þ×v.]zeX.0ÌpýºÄðš ­€ït¦?™brf†0,6úã?{ýË_ù郗_úðíçžý¾ãë7¢Ñ%¦3™À&†Ï^´I­Å³²Ù+mRǃ‹Zšd±G®à\ùõkàå Æ`èAC0 à¡Ü€°êAƒ‹L‡=|¿†mZئA-`ZË%õ)çþ7Q,íºmLNó;‘|ñÌÑNí=\b~.0\ØÊóÎ:¸àà9 ž =¼i=ʃ1ñ˜-‚ud(€Cb´!€GˆrNJPÀR•/…²§äïЀ9NPj ¡ŒW>Œ„e„ì[|¬ZÇ&…ôY|öL„Ó"õgŠe`€ ™d÷ 6Ä¡ÐÄ £„‡“‹J‘1h7br¢Åj‰—¿öĹ—ÿêÏoììþüÙK÷ßóîG?}îþú™{ïûøæ¹sO‹9V‡‡¹žÃš¾si-|‡ƒf2E³µ ¿˜oûºö¥/~tïùg?´ÿòË]¿aÕGïä¦Ý܈°~à_’ŽÅF´ïku0Šƒ&Ճכ®8‹†£# ïÑ4mŒµ÷<  ~€\¬ æ8øèÕåxàÝjlbìFÍfÚâ¤%‡ùL â—5ëÄÄ@ô3p‚¼Cü<¼÷1ãb‘B28xï#J\BRNz°i±‚lBd^`îº;G'Èhj‡ÈP[²à‘›L>žÕ1ùNŽ&Xïui4J,á¦!€m4ÀØÈáá³SÐäA°9€Ûhÿ7Ÿ´WDÛyš'”4r‚ØhÁÿF9M ˆZ=s€£L  `;Xó2}’þ┸À÷”ÄÎwÉV¨ (oLÊþ†Õ1xšˆˆˆñÆ{7À4 `cΉà=xèÑåœÿIçWy r–‹PBÅ/èù‰”å1û¤L‘JBCò“ÁL' ýªÇkÏ=»yõé'fsgçg¶/\ü?Þóî÷|f÷žKŸ8ÿÐÃë67¿¼uñ"æ·o£÷󹱦ïZ ß)Dë“onbzæ ˜ÃÅÅí›:|ü±Ÿ¼õä“?yðê«÷^¿ŽLJb67Òf%› g'¯J£Í¿rW?%ý8<ÌE\HhÀ‚÷裶#á‚ÞÎAì‚‚Ì› 8,àûl6”5öNt`dAad!m¸&£¿\â¾S„B ‚%‚‰RZedSƒ‡N sfxöp>֚̂˜Ï.9"8•ÊÖóÁÓD-ŸW`šôŒ¦)`Œ HBàR¶B†àcxšT™ÁÁÙæð7À!„è0™ Oqù܈MBlv; ´‘Ñ“àØœ':F„"^Ò‚yˆö{ÃQ«+€O“hÛ§6Á ´¶Y ¶6jýFL<Šsi=Gî šÉ‚*¡G›ŠˆíùÎ àÕ6 \Uöø(„h‚2ÉLcÍÆ€glL,U%k$ GÅuQ„ì*’ %ø,¯Oñ)“f:Ńw¸qå ^mmþøî¥ËÿÉÙûïûòüÎíOœ½ÿ_Û:á3ÍÆÔ-°Ü?xûö©5}Ki-|›Y‹nk'î(Þ=¸ÿÕÇ>tû‰'ÿâ­gŸýÐÑõ×w¯_‹ðjÓÀtXB²ý9í+KiY‹E]¤ü»¸.‰f/iÝJ;ñJáUzÑf#³ `g8?€↚r’ãŸ÷ 5ð ð·i›œ1O¢¤6|=V&“{,(ÉŽ^‡A(òBÓEÇ<„äÜ–±÷-àhW÷ÁgGº| œºG²­ûhFH÷„àäĈ{6j¾~…@0L×íùHå•y¿£IJV¨ÀmB?ÀC:ߦÁsi ›4J>¡= ]!€Ø%¢V!©Ï@ †KÑ@ x¦=ØS4y$çI63ÀØf˜6j릦‡4»< H(ò;©N5+õ×Zû­–2ß³dÐ÷+çAM“JI'Á2ÄH2©¼²‰ëØȌ •uâUêbRZ{ŽnÉä2ÿƒt£Ì[I¯lI¢hH=£šßd2*Ç ˜¶í:8ö¸yõ n¼ôâû¿þ;¿óþÝ{îù{çßñÐs÷¿ï{>¾sùò'vî½ï7µG~±Àâ`kàÛ™ÖÀ·qÒàÛÍM€~±xôÎןùЭ'žøèÞóÏýØíçŸÛ^Íç`cb,úd¦töj¤‹cTŒëŽ¡ŽçÑ*VÖÛ-e¤ %<;åUû[j'%LÅ­&0Lr‚2œs²ì!ÌŒ Þ¡&M£{’ »Ïõúr>WÎÑÙK€EÖ‘øzŽž÷TÂÅJAŽp7¢_…± ¢Ì¬‰> ¼‹Bs4%°ü–]Tõ£™ ™B؈L/DO‚(8úàÃF8 bÁDZ} ‚MötÊùâ™&½›!22˜«ѼB]4õ³‡ ŒlÒø‡Ñ_ß§lCâmÞ Q¨ ©B¦qôÍ,&K²“¨9Û&\2 ‹$•CÉg¿‚öõô òŠ•ª0}õ%ÕÇ:É”þ?axÏ ??V jZDA•JcÄ9<9&P L€±97@€< góŠ'Y+óTJ!Ç™Äy~Ê[“õ$t–9G{ϵi!÷UÚöQ¾h[Ø®BÀÁÍ›¸óúkïzý·¶/]ú·.>üЫ—ßýîOìÞsÏ/Ÿ¹ïßò®¿îÝ€þx^øíFkàÛ€8Ø ´[›0Æ ßÛÿÞ;W¯~èæ×ÿ‹û/¾ôçn¿øü¬?š#ÃtÐ,BûÅ«Èa^²mæÏñ·üW«M•sŸJ#›¼§s(SA8‹Ü Ê(Ô~ú `€ì%÷XL'õ=»$"°ÎmÜÃKøICS¥R^‰¨ç¤¯f¬5úÑ!t'‚ëócK;„è±m‰U 3Üžú–„cd‹–³Ü…Šù;ç¢í8Ødc¶!F0p‚œ™MÒþMεÒ; %ýI^ýÞ´QГ„IhÓ{ñ‘AÑ$ l„èšÇF´XÖ¢_@ ó¢é…bŸ˜Á7`r jÁ6ÚËÉnD@XÓ€ Åh‡’ ÇÑã ÙÿÅA.1PˆÐvJ¦ñgS¿fþIÑ®Ò F/çs4mPy÷ ÀõÉñ´˜]dö¶ÄüÇkt ç‚dá–K{r?£ÖJ~Pµ„J…:~’öO(Âr®© „¦" h°.†éÄÄCm× Ìöñü¿xß‹_üÒßÚ8{æo]zøáëgî¿ÿ·Î½ã¿<ÙÚþäìÌ™—lÓ Ÿc˜/N¬5Ý]´îVb†LÐll ™N±º}ë»÷_ý£×¿öµ¿tç¹gÿÜþÕ+v˜/¢Æ<™d{~ä >k¹OyÈUæz©oŸ65²-Sùäí'n;² a|Å–)ÇJŠÙ´8W×+ýÅ¡úò‘4Öä ï““ iåNy³-™êÒö*ñð;Ÿ{¿· |ÑÎl¼09 0,EÆá8æ!ˆ®cqS7`ŽÙß„±dP E¦˜a»6BÛ!!nH†QPGä š¢ssˆæèÀ™&x,ÙhŠ@>LF” ˆeDÑ„‘Ÿ¢K ÒÈÆh ¶– šE[>1˜xÓ¤y©0Ù$DÓS.¢‰¹È“xéçtDõ]ìaãü>ËtÕõ'ÈoTêpz?¬çln3 m>0ÜjîhŸÆ bÉúV³3Îñ#‘Š…¢ù‹0b´„œŽ¥ø“6›‰·Œ=[ÔÕÚª Ò™8'/Á wJ%–©iѶ-ˆ –ÇÇxþK_ºÔ<öØ_™nný•s>¸÷úSO}úÞ÷¾÷Ÿo_ºøk;—ïyiµ8ã¾_—2¾i-Ü-”ÂõšÙ ˜N1;ýÑüï\yægö_~éÃ7Ÿzêǯ_£åá!@v:™ÍJ}ôr;•54i¢ª$³qÙ;TìqÁ•ò¯4q5“•{´@cþ"Q¤”„!h°7ªÿ>e­‹EÖ¢`bYK8 E!Çù!&ÐQŒå¤p#°ma$@Üœu”› "‘Ù3l"Q Q4š—Û,ϧSÔ˜CF]H©§8†Ê!Bï°!¢ÉI04Å€Ów^lý>އÈ~B`KpIÐ3†B4Gä×¢yÇ”›¤Ñ$8&€1IÚ±Áb@t ¦ØèMb^NÁ=ñÙfŸð(¤ÚºÐ°0|]Š˜”C\Ç4~œæŒÌ¨Ñ,OŸ ´_Ï,±#Õâ)ªcZ„%€M_Þ¨^Á+ Û ³ÁÈóDH_„pƒâ#~+¸J„%i›ó|S"² †ëï B'DùÝǵÆ9 7¾ï·P¬A»± CÀ0¬põ‰¯¹òøWî©OþÆÏ¹÷Þù=ßýÝ¿uþ¡‡~uûž{?¾yþüýñËÃÃ(€¯Ã ï Z ‰¬E3Âlï«¥ö÷ÿôÍÏþ/Þ~ú©Üzö¹:¾u˃P×Â4-ìt#3 Ir“}öJ’üd¿§$¿«…‚f\œ7mÙ d«ƒ‡8óX‰o®ÎI»Rµ%, ™!0ФkMi½FCjÈm:ˆ(f„~×th¬Í÷®´D*0,‹c†À‡èÕ.¡aâ•ä‘mŠå8š<Òæ¬âÉ3¬Ìå/+Ʀ;%ã!%X’F²Û, |Flr >úK„äGàºc“ çSæ;εhâ 6} âÐ…d‰‚Jö•H³!dªÆc»´ê•€Çj4c–6u=‚ò­¾g9StŽÌTTæ]z·å ëÖGbeZ" ²a‘ï„ù!xÀ˜’8'1ÊÂ^Òöå=‹¿lAž’Ó&t€ò4‹¾/HS¾—²~âzN')P9ILežéµ§Ö¦Ô2œû/*30–2œ÷¸öÜs¯=ùÔGf;ÛÙ¾pá?»üžïþ­ûîýÕó=ü±ÉÎΛÉóƒý¹¦?±´~;‰Íl†fgM5Re\d}ê¥XÞ\})£-‚óXø‘=ÂÔ ©·ÅymÕXJñKKxá6B`ì½ú*n½øâ6“Éî^¾çßÛ¹|ù¹{¾÷}ŸØ¹÷¾OœyàþOkVGÇæs‡…5½]´Þfê¶¶ÐtS0‡ó‡W^ùó‡¯_ûK׿öøOÝyñ…{¯]K¾ma'S4²x3Óí/ƒ–õÆŽÑ&«´úSx¹âI%šü¦aïŠóŸFŒ²öP—e¼Þ´8¡Aì©éû¸Qˆb:ZÙHc¾bhh‹ ˆØõð¾CcÚØŸ¬AK q ‹kHª F$!éYÛM¶Zb8X6‰éǾ§Ä¬Zƒ“Ó`Š`0%5íi¹×D(‰^ýÉ1£Ù&_G¥Tl= ñõQÊ Y±ÉZ]¾N¹F”ù4†ëeƘQ¿ ‹—b<šEh¾ÖÆKÏkH^Ηsõ5A3C¥½´a< µPQ÷wŒ ”gºoà¿Z!Ì Öä#[61D±çò•¢ÒBÊUýdRB·<2Ò“‘°¢\'A¤8cõ*QLåªPEŸ³/I¹Š Ê@qúË«ˆ5KW —1¡PÖ‹˜öŠûPü@m‹¦kA ì½þn½òÒ»žÿŸÿ7·/^ü7/<üðk—ÞýîOl_¾üËgßñЧ™ÃQ°/|»h-|+)AÂíæ&l×ÁóÀþ•+?qx啟¹ùÜs?qû¹g/ߺ@ÓÀllªR¥)ÖXáâYÓ$ÈjG/ _6ä€RŠ-&T\l$r}ÎGrˆ]†Ÿ5ܨ¿ƒÚd•-22¨õä_imb•0@ôÉE‹kÁÉsÞ¦l¾q§òn†ÆÆ,wÚ‰ÐCw€²q–Sð6Ê· pHöRgd›Ö8‰AºÆ–ß“ `ò'ðÉ‘O ne` )Ô/ pñŠP`RB•r¬ïs.o¤8AˆO€ ûu”wW²æ¡SÿD@Ô!{ꮣ5ƒ‘X’Z-]™X„uË»ÐZkôS ÒF±2>yVSôëpÎÁ/ ãbÍ„C 4Haœ²–•ðQ  z\˜Tú榇doÏø¼žeJäõ&ýŠË‘Õ œ}d]ga¸Zg%ÊF£;Ø(ï'Ú QÙœX aœ'€mÔ41¢€åá!^úÒï}ù‹_ü›»gþæùGÞyýìƒþÖîüò™ü¤m›—ºÙšÉý|žË#¯é­¥µð§p=;›]‡v6}`qóæný™ŸÛ¿zå/Ü|æÙsË£xï£P°±¢åø¼± Ã/œYíѰ-ä9?môÂ8/Бe#Ðßœ4Ù©U¯4²ŒT¼-õL;I«¿ÖÑ(1ä’ P`ßXÙ]YCImŒá†R컋^ê,Ïà‡®í`)›¯Â8bX·$p1’X6:ŠN€¢MIˆ˜@§Y°bý„qGæDØÊÕçô(E&Hûa‹)UæK\¥@ ‹ã³/ÿ‚°j3Ÿrhíð„Ð?K¢$yw",ëǜ̪§»œQ 'Q¯™¿Ê ÍIàlnÉË5º …âìg.çU@`‚ïØõ±ÎÄbÀ.;·J˜_.f•æ•I÷Ð!ª,èOZ{”×bñÙ‘h$…S~Œ(ÏRö•!1?)A ˆB}NFˆ"-« [5ªZÔ*ãm’ [ÂK1 ¦˜ÐÄÌ@•o:_y$s±¦™È`µ\àå/ùÒ•¯üþ_™lnü• ï|dëâ¥Oß÷ê—lÛ}rûòåç‡åýÑ~豦·ŽÖÀ[D¶ëÐnmÓ)ü­[ïØæ™Üxú韾õä“?qû•—άá†!zøO§ÑKÑs[odÄ#Ýiì™%LxÌÌ+•. {ù¢lôã8û±Uq¬éëí7k#Úö)ŒKd–¼1j[.c,dˆæ/²Öe-2ë/²i‚r±”èÝŽh5¥>±+¢d“>"EC’_Mi4¡"¢L”Âû8¦ù•»“f< ²NÓÊZ¯åbK–ç‹×'x9{o“ÒÎëHrC~a&²*ˆ‹8y]%‚!dfÏáâðIDéÁ²P!¾ L¢¬ñåçÁLM:a'at\{¡Ë+áqœ G ”¢<äsžŒlóO<5›ŽN»gʨ0À¬½Ë7dÀQ#ï–‘yù˜Y°s|„ ˆ‚êsW( @#A÷2Ž9F19ÙôW??9k¢¼AÿŠ›ƒšÁIšÈ(ŵ•ò¼‹“®QwÆ_Ä„‚ˆ€P搜 ³$B÷KÇE‡1„n¶X‚÷W¿úØ®išŸ}é÷>ÿ³Û—.Í/¿÷½¿}îáw~lç¾û>±uñâ“«ù1øàÞyœ¢‘¬éAkàÍ ŽE?ÈL¶·af3 ·o}×­Çû™ÛÏ¿ðSןxü/¼zu6¿³óœO& ®CÓ¶IH9ËÚCÍØõ¦Vß;ÿœŽ5‹%al(»^ør³J‹×¨üU ƒö5PM¨Ôºe3>ÑbB#´ãUñÄç’Fœèr)±Nbœ €ðù +ʱ‡E—;8C´-И¬eÉÆííQ“´i# ( ›™R÷T¡RJZ6¹|«O0}Lldsä€À¤”´KŽ,¤î‚èã µˆÙü¶‘7|äþ” ôhò@Þˆ5ƒ=¨y=ê¡´Å“SJkõA™3ʤSÃü2âcv¡DZ$Q™Ú'@üdªæçNß…Ìüë¾ óú¬k˜: œ#MÊØGHÝ9°8/`6Kç`Bk“àYJWËB˨ŒÑwáXˆJäŠ0PcTÍtøkaº)Q$\TÚMQ™°Œù"¬óHZK26iŽ‘lô{#Ô;§~Ⱦ"Eà(õO|‡² Cí>1nÍ,"Á9ÜzéÅ_ÿúOv›[?¹}é"_zÏ{>³sÿý¿zö¡‡eº³ófX" n- ¼ ´þ¨”˜¾itÛÛ " óùûn|ùËÙå培öøã?±ÿêU³ØßO̾‹%ue3M™Þ´´=Fàó‚!–…Ù§mK1…¸˜uœt¤ Â³”ar™6ðè8Ýr)zWmé˜ åÎ ÿÔöh1KDæ'y¹G†…onYÁšòÿÕ#ÙÖ5ÃÍ¥‡Døa€½G†$¨ÙÜVŽyí-Á³±½´Å’„Ï<#m°PñÿùmEæ`Ê&#%ô‰Ð²hå†cAöä÷â©Ë5€Hk $!ÌK~}õþ„aÊw9f?iòZ»—ÊŽƯ5q™&ż€Ü¶rÃI‡?iSûøEÓ/Ž~ T÷Ñ×JÛ9k!ÒøŽ„H‰øÐã7¸dmiŸçÂê¼ìÖ¤Z=àlN©œ«B˜’Gñ åÀ˜IÏ:Ç!2c³A™EjV%æn¨ %l±ŒA²$¦R"~fº)*å8£;²DSMƒ¼d©’£ÂŒ¬ùt‚¤sMŒÑ(ɤ(¯R.–yfØ6î• ÆÞ«¯Ò­çŸûóíÆæŸß¹|é?9ÿÈ»~oçž{?qæ‘w~¢™N~·ÛÜ îZc×lìJë‘ûÃLÓ`²» x? úõ/~ñ§öžþ'o<÷ÜŸ9¸ò2V‡‡1ýnÛ¢ÝÞ_ÐÑÏÚG–Ÿ TIyuæK¡¥írI }–ÍžO #€Þpd÷³’–ÍÙv]3Š,9§¿Þe‡ŠšXi(›¶ØÏ=ÊȃùZD¡À%Æh)¦³EJ<“ã§‘M°‚ÙóΙ®ëÀZPg2Zl±ñ Þ#%ñ!ŽupL‚乆Iå™â‘UÓ»ó00`¤²›ìÓPèåÝqa ÅÄû:I )c`fŒ¸ÔÜÌâ¡4ètÏ\œ:Ï~%’*˜¿6ãH[â\Z¼êËÿÇŒ¾þW˜WB€Ü+¨ã8F¡B8·¬Q5›Osø3ü8O:ðà—=Âñ°HùV±¢Mó$ˆ ¢3=ÅöR–oNÙ+I·Ôê ªçº¯òŽ)©å…Q«±åˆ(ÓþÔBy¾½V¨´ÅT;þ ZbôDPè“öJ`W<åá…ƒzs"œËÛàâ—R‹Ç-À6vk`ÆÞ«¯áÖ‹/þH;™þÈö¥KÿþÎ}÷=}æïøÕóç?n¬ùäììÙå°X ?>®ö¯5}cZ ß 1Ãv¦gÎ ürõc7{ì§®?õÄOï½òÊû÷^~ýr Ót°]‹ng'n¦IC+팸°hÇ@ÙP´·¼1œÀ?鬧AÔ”€ÑN{¬j­ÄÄzZ@)p½|§Ã¿tùÜ[ÙMÓÆ#š—ÄBçüeÚQª(¿³©'Fœ ¹%‘T*@ =b-ú’ë=P³‡ÛÀX[iO’(&ç‰%g)E0RéwqÈ‚|`“ 9N%Ê–úíÂì””'™ű**š‘ÏÞîEs’ÔÁ $ïÿd#)E2ép-V›½ØhQiÒžÅÕÒdzœGÿ•Ï<úÈâr¾+>4úî´ë…ዳèéç”ÀA3[ÕÉ2Í©J$$ó½zÅ…~àÝ œOÁ R“Äœ¬>+’€¨òh'BH†åeÝ(AD"* Š7å‚“¡µµä¡Æ› s®–AU,û@mÒ¨U|úrfAR«~´ˆF #˜Æ¿—"[J¸(=JŠEr0`šMÛ‚\¿Ž½«WÞså _xÏÖåKç•ÏþåËï{ßÇvï¿ÿã»>ô)ïñ0 _¬Ã ÿ Z §QšÑÝæ&0™nh^xáÇŽ^ý§¯=þÕŸÚ¿zõ{ï¼ü2œ@ÖÂvºííì„#ÕêFý̇Iî!?©ÓødgêF¿eí Rgx´'”ÕW„ ª€h#6‘˜xWRn[4¿qß²G±(à1/({°öê¦ò{ —2•¥¢A>qC’å.&2©o °‡ÁAJóŠæ {Iî2‰Qy "÷f*uaÎ&õ£$ì‰ù#ÊõÜ)-ÖYñ¤O 6£#uŒSx ‰ÈFâã¦àë´û¦¨ -@¦ó ƒ¨î!ï‹CF|p0ÆBÜÀ¸)&~rÈZ™Ú†¯™Ÿf€ºÅÓ¿0éÓÈ|…©ò#”®i¡±Ü]„ yõÅö-Â)? ønµDX­JŸÛIt EB|z÷J«× …Êr-öw]£ ‡ãŠ–ÙnãU!¦çÄT —Cý¢Š¸ c.š¶Ìl{¯öŠÂØóÍ«=ªôI]’MònNhÜšù¿WY]árâ§$sZ\$lÓÀ¶ ÀÀñ­Û8xíõw\ýÒ—þõÙÙ³ÿú¹G¹vî}òìÃýÊî;úMÓ6WÃ0`X.O‘TÖ´1sλo'À˜Ì_ýÇn=õäÏÝxú™ÜzöÙG®½ŽàbÍy;ÆšI…e²ÆEªM@xØ_u©Ž‘P¯>Š«Uõë­ÀÀ%‹¬z½ì¸üBÉ ™\R Pá ¬5Åú7'ñ¬ μy•ÌtyO¯³èÉ  áT|'iQc±”Ú#&ppˆåi©À•ð%³GßhÉÂtÑQPBšB²E„¤!‰:!Âø€ô-Fk±9“[†WEÌ qLÒµµ †òÌœœsÖ™3Ò¿b«ä€æOç‡ôŠcœ :çAª,<8•ö!ÆÖBvbª€©L4ýÞ3óKÇ4:Öþi~A=$Å9-PLö‹ –°=¥Ÿ@!òW§ ¥úŸ n5 Ì`ÀÖ%Øß–ÁX.Tk-;eæµ—„ˆ°' ˜“à•Lì¥\˜«Ì×(`Öõ/D®E:ÇS ð 9¨ªæå·:tÇÔùy(ÓCSÙœ*c îÉ,Á8ÑÏj? ÑÇ,HDtD¨â”X¾²¯š¦m0€~±ÀÕ/ùò«_þò_ë67ÿÚ…GÞukçþ{?}þ»ý¥K—>ÙNg/{熾Gû§ïh€C€™4h66`'-0¸ÍùíÛöÆã_ýÙ[Ï=÷¡O=ùÝG×obè{Øé¶k3 VNyHs¹²ë–r"ÿuŽÏgQÈÔ\-–&eÓ)^ùié²’è¦V%²9›žbÈoô»fö àÐû…fó¬úuN9«´˦¦ß8n¤žHmðѾËýÄç[¥8©<˜û¬¹ŠÖÀ •"Ós¬5€m’|D(™)?›Õ2VìûXNiÐ=J–µ’U1eÎãµ§c¦¤éçŠaäùó‰€ÉG›~ý.²ËU¶éK-±Ï'{5‡˜l(D'T9‡=’ @Æ&6iÝ(©ˆ3Wó¤Hó­üÔœkøù;‡=X!Å ÏõÙŒ¤!}mžß¤æ©šÓu²Üd>é{øù<,`¬@°lc ¸ä[ÑŒìõ#s™Žú“¸ÿ8W ÕºªðÞèíÏY88^– çsôº—ûŠÙJU!ƒt Ť¡1¨“qúÝžäÕ…«®0çüüJÁ)Z@î|ÉZ£ŒZªÌIàÍ“Œ¹Bµ°±Œs /<ÿúÿÂäwçv|èÎö½÷~úâ{Þó1c›_ݺ|ùE"ÂêHE|‚ßy3LÓ¢™ÍÐmnÁÏç[Ë›7þÂõÇ¿ú³·ž}ö·ž}ö]Ç7o¢ïû£ß¡›t‘éŹLHÙV®™0â‚Ϋ%ªœL#yئì"UMLÝ€Hù®j—Õ¬$,©†"·[ åz;mQhÍ*kA#3Û’ó’a²ÒðRÄÿP˜~eè>†¥û¤8CÑõ,•ý…)ž°ašG€“`R“Á'$`b`­‰ã?²JéÖ(H$†a „êTüâÖ*L$¯âæ(•u%¡“lÜe²”LPc‚Ì€CÊRù†²‰ÆÒÈTûFZ|àTJ˜9•ŽÕKÀXJ˜CÙ&Ù¸EÔ¨óh¸_Ï/ù¬=ùeІ/Ì_g|,L®zµŒ‘Ý—Ü?-gfÈ_·§çtl×30¬zø~ øCÀ0B p“í1`ŸÉ&aO¦´‘e‚I>r©XldüÕiÈ@œI ²f”¬ž¤HŒMôÒV©0¨^Äh Ž•zSÌ'Î?mOÐf¢¨…¨¾R*ÆoËÓƒG[‹V\ªÆµÉP pœSxK)p1¡1E3M7›DkO|íìõ'Ÿøù+ŸÿüÏo\¸°ºõõ¯êÌÃ}üì;ùåÙ™³_÷}~~óá;ƒ¾c²íƦÛ[Xn/nÜøÉ«¿û;½þµ'>xçå<º~3fã›Maº]‚‡Åਰ³†–i8O¾|?¥d1[­9D(M[Yh"8H(Q•³;m#ãTEª/úʘ³êçXÊÏëê x´©¦…<”¿•òŸ¯g¥–v £B6øŒžSž¬ÌqâÆ«1@ƒd«'€ÉÃ`GÈpÑüIE,3ÁÁ; B¶12À€b™]mÃMÿ,G¦A&Bú‘9LÚI3(1J#ïÎ$¡Bæ‘¡2~b´„"¦\ Ã(Å©ØcE#‚ ï3ˆó'q~Î'Í?í¯/fä“Ï8ÄòÇ,P,—™¤ ±jÐá‚Å_BFSЈz6JÖÇñüÔ‘)ê=ÇÚ \(É ¢ÕÄ’†…ïHuF¸a€VàÐÇöƒ0™€°»d6J3Bœk&½A¥Òe>a®”×­¤"‡ÎXnùä‚Ô#“›I¯×_:Ìï‚ë iôUu*còF&q-4ÔçhsgåƒÆ¡$ÊѪO9º)IüÙ9ûFÉ&R>KÁ.Y §"Ù?EªEÁ¬™Í¢síàpçå—'·¾þõt[›Ù¾tÏ?<ÿžwú̃ïøÄ¹ïz×ÇÛÍÍÇìö6†ã9¼cT’å·!}{ )ïþds ýÑÑÅÃ+¯|øÕ+W>rí«xïê•{®]ƒ£™LAÓ)Ú¤}—êz”·¸âÝ®aqõIIÂÄøì²[—s#D5×륣Ûvo£5RPßóT/]Ý7uÖPj‘¢<œ¬I}ކ⪤LyЩ4:¶õJù@)PO›ÞS@›ÃÞʸqè£Ön›ÜçT%·3üÅþ87 €Ñ …!“ÓšŠˆ3c†„BJý2J™8RÅ­~íÁDíÛd$‚eJ«šâô3ÑÀ)k:œÂ)u9e©1?®¯ ²k@ð>ÂþìâêØø ï"x¢ÉÁÚèõžÞêäL‚Òh¶Öà‹ÃŸ\1Îø( \„@ÀÕ¹YÏ­~Ïþ”G׫ÇËs5Àc<\߃ûc„~ 㾉)¤‰{À'Á¤ibß|v±C&½«4'€¼€ò»I{‡R9`$303‚W*ìr_Å´£Ö8×c“aJr \3’îu"¯j!ž‚è- '>Êmò©D–S”@¤×Ž3ª:†eÌTËÌ*ºø³ž%J¨È÷1°]‡¦kÁqçê{óùg?ÐÍ6>°}ùòÿa硇>þ‘ïúø¹w=ò±fcöùvs ýñ1¸'M¹ßôí%¤™Õmo£iZøÕêòþ‹/~ðàµ×þÒõÇ¿úS{¯¼ræðÚ  ‰žûf¶…wYÌ~ä¨&Û«ãätE\˜Þ\d¢jv]kè\ •¤g{þ8†ãJ; µ€”æ]Ìf¨ø¼´=B$²(¡~ÏO”“œŠµ)¯<œ‚kÓ5¬«Þ„³æ¦CÓ==jæâ…­q -Û÷ˆX´é6‘ Ë0äP¢¸]ø´…„¹Ú¼KYéÔš¬±ËpštÏãúSè_‰kF}2'½l–!a!Ž)ç~K[…ùsíÐÇ1Ì/2ü„Bp±"”Ÿ_§6#DæïEû+A2ëé%ºcµÅÀ|a.D‰‰Q1K(/ýÕ â{¢};´°'-äˆõ›Æ¬J/KCœ8_K$DzçeÄ%à·š#,æ ߃À5 ¶ ðð!ö«M @ÀÑ@%T  ôëh–qš]"ª™¿–ü32 z/‘ ªU®ÖF¹NGym©k*[i •ÈŸyÅtâ0:ïDÈáˆÊ»)…Èò>Y¡¢Bå.êy+ó+_Q…¾Jÿ‚M1µ–ýÉv1t›CRÆ?úÊïþînß{ï°sÿý_¹ðÝßý+;÷?ðñéÎöoQסŸÏ†ß.ôí!¡ÛÞŽá9Þß³ÿâ Üù•Ÿ»ñäSºýÂógïÜY Óvh¶·Õ‚ EƒÈjY.‘Y—ÉJ§06Y£¤ 0­-Ëx¦í¿ìR¥\')ؽ,ò 0È ùbÅ…N2üú€UÛã6C*¿«;=Ž­¦zÛ€¬ØJ„b­b®ÿ_'x†’âþ‘¯¨{êÏ©î¢÷4À"ºTÁ/Š1B_4=NEW.mDmÜømœ ¦ò6Oï?• –G®†(µÞh¢@²Ï粩AÏ’{€áB¨6ì¢é…„Šh}6%ñÉ÷ŽÑ AA™#Ã÷±Z`D $,LdVŒÊså^ „à@!Dox¶1[›'éáê8Tóª¼OͰ«$FˆÌºÔƒP‚tÆ ñW¨mÂZ€å +ŒYÎ àú~µˆÙþ>Vùc €=Hn€XÂ1D'ÉVÍ.¦³×)ç8þ¬…ÂÑ–@¡Ê~QæEþ£ñ¿ÄÐóÖe‚óYyß@¾N/zª>뜄µ©&Ûò뉭„‹²±‰‡)±ZQ› öMȬXw¾ç\ E‘*c Ï×>GÅׂ£ ,í"«÷KíýO ”‚k¦ka»Ìû¯½†½W^ùW>ÿ¹ؽ÷þoûþû¿øÞ÷þòìÒ¥o\¸ð™Ét†Åýü8e½;鮘cÞv6ƒm„a¸¸÷ÒK?yëé§öÖ ÏàÖ³Ï\XF;[Û¢ÝÚŠ6¸ÀE;eNXÂaK_žì(ðž @Íîäx¤|KGQ‹·'N@Áº(«×¬=ˆ´Ô@…ùqÞ5.qÃå>º”§)hÅ)І,¾²G”±Ñ:¸²ØÉJcãkFf„J`¨³@ÀŒ²ùêw‘Þ‘ÆN%ÆÝ°pðÜÁR£ DÊ6þ “Ç,%ÆñŒ!; [ÀüÎZelǤØüj‹¢T9+¥”MÐÓ)íX9©m5‡ýQœ 9·½Ê¯$>_ëÕœaþó Â!E Æõ´ksx U°1Ï‚gØÂ~BÎóP‡ú‰æ_ç#¨ßgI—«ãt’Û2ËBJV¤… ab• òH±Á¸~…Ð÷àa8B‹` Ø„ØÙ(°5E․ùÇ@RÆP ÏT‹Á±UÊDéw {+<Ï(µÖ(™ż õˆRšŠe—ã¬íË|©¤M\rÊþ£•ˆêɲ–_P‰ºXYy‹e›ÿRÐêeîV(íËjã´B•ÖÂÓ8wH!¢%Duïã¬àÒ˜C„ò}£Ù6¾›¦í€n‚À{×^ÇW¯~ï•/|á{7/^ü»»ïxè©{Þ÷¾ÿ~ëž{þ»íûïû!0ŒµweháÝ%pŒûœžÙÅlw§=¼úêO¾þ•/ÿÂÍgŸýéÏ<}ïòðÞ4³)ìÆf.¤Š{寜¹v%F*Þ§½þ‘gWÅ“»JÖ!y¯ë\ÛTyÆ•XÙÀÆð’öÕ¦ õ9K»#©=ÿžë…Ÿøç‰TKÝES?YVtü{õp²™”CrY3˲çóJf¼H€….g‘ÜæHú>ا’¾éŠ”ƒÜ£ë<‡Xù &øHŒ*„ã†È<[Äzæ’ˆ&iþ¹JŸÄøçl„&A¾i^Èùi3¥`ÀF ~žI6 ™=„ÀA@ˆ¹è½¼³¤u&ŸŒàR|,S¬héTúŸKD³AZ%(0~(Ø#˜ˆlÐP˜™õ¿ æ…¤ü ãy‚:«Þ8ê@„¤H q •ùQpù̪Š`€üjßÏÁΤ¬L` vˆU$›.n> xDcÁ¡“Èa2H²šÄ¹TÖ¼)Ï”ú¢ ûa¸¼½n*çÜ ,© ©½D¯½:©}N}Ìk'ÝU#†êo½E»ºÑK:gâ,O㮜·ó›V¾61ä7j@€jƒR‚#C÷8›%ä¬1|€²‡d¥„b§pÙXE4EuØ qtã&ö_{í»¯|á÷þÞæ… ïâw÷.<úè/N··ñ샾Ddp7Ñ]%˜IƒÉ™3;W>÷¹çÉúÏþ{/¾ð=‹ý=xçÑnlÀLRY]¼÷c7ëòmTº• @Ö¨³ö.Þþ±aí›Ñ*ñDUqŒjÚr½²Ö'Ä~äœwƲaˆf{˜fø%œn,ŸSÕU ÒǬaüZÓè¸HþµÃׂ‰zà²éÕžëò›Â7ä©6:`£¯zÞH 1 ÅËŠÛZÞhµD­¥½ºE¾ÈKK/±Bqaj֮ç$ª ÍµŽ¦þ~¼Z¦heê™ôÍNùJ?7ƒ#Cf *±\FOdXÁEç§¿˜$%~kÓͬîÅ÷à9žm`8 ¬`ÐÀ˜Id>!D >É-!0ƒ¼ñE?‚ئaDmz0!À6 Û´`L  ©"¡xñ »ç´‘d X4ºlÒˆÀ)Ÿ¼ T¬)í£’é“° ™‚Kþ>$Ïþ詬†È Ž‘]Åk:°ôSò  äq‰ =4€÷nl Û°.€LvԼΑ¥ÇE*O‹6ã€òAÈp¼˜èbß}Á!ôCÌú6•µŸHjäT’€ÌMì_ÀܾÛ°²&;ôQÊ—/Œ=¨TÉÌbö©Í<¤lDÈÖº§ â89ü <,cèãoFÄÜ€¦”C"Ù[€=жÀ[À{ ±ñÁŽàN©]a:#»¾î¨dí¦£ä}Ð虌úžÊƒ–ay¤„vA™d½f„@œ÷ä< šÏ,µ+‘Ѓñ° Áy•µª’W)…FAª4!%<èõ^*– ŽUÞ¨ÞN?'‹IKÓ¢Ú Iyÿg„Fí³Ùä•o—Li`°÷XÎW8<ØÃþ­[8Ú¿‰~~§„e̶ë‡Àïüþ_k-¼Ed^|î=÷ðÓK"¬¸Çêx‰Åñn^ÇÑÖ&&»ç1Ý=ƒÙκvcÅAŽŠ$ Tü…ö‰ÄÈKž /Ç9NÚq.¬”´ —_:dN„ô~à ô»è_Á$™`Ã`^åkBh@4S@ )¥Û€ˆà$q’1b.y( -%r æêÏ)‚%uq*fäác˜b¿B¾m€¡Ï=¸µ1̑ٳ5qn„UrjÐØ(P„AÙü)¬Àðd¸1aðÙó?GO$F•–Dô…0š‘'¿2Öí½ªJ¡«2C¥x’âQV›V&*æ¯ö£´`U&·XO 0Û’“ Ý>Æ*{‰ø¯ddC´u¹D0„Qq_å&”ÈþšÄ#É q2¤Quª¯zK¬î2þ]&Z‘<”_2gr6}yï±Z,p¸wû7oáèà6†~ŽèL PÛ‚ð< P;ÛÆdcd÷°qæÜ1î"º« ~¹³³íœ6p¸ÚÂÞòaÀÀ´i1€±ްºv€£›Wq´±ƒÉÙ ˜»€ÙÖÚ¶16)b”¡WaÆ… ³:N¢ÒÚ%üFrO#þ”kª— Âš²PZ3ñœ^8~YÄb‰±Õ)Ue²bžâ—B¨Ñ q*a0šk5È……´x¤ly<Éâ}Ii–HãS÷2µ“WlÄP4p€ãBCŠK×o‚„ÙǾŽ.W&0˜È@ܧ~ynʦv¸>D;­%DsXcT¨ ƒ¥Ð@†ãTS€ ÆG´<ÆÁÍþ è G&{SÍ-ˆí?eü‘ð=ÎÏ– ÷0ǘ“ƒdÅKÌŸ-ˆ 2kóiÈÄ‘²xÿ'H?ÃñRb9Aô’T(™bÍ>õ±(¤~Y E>„”¥1 „ø.‡(P˜‚Y ²Ñy0iÈ0”‘8?(G& xDÞƒÃ/ñò«£”À+ X€x@˜¡È ,°¹úË( 0€pÑ!Òœmþ. „(%µ=‚“µ–Li±—ð>ÎÈ—Dˆ€f“’a’YG§®•D<YŒÇF$Ê1ÐN{r,Ÿ+3BZׂD1‹àAyg¡BCèUR ×_%)Òª¹Ú/AíW¥ êK_! îŸÚìªc‰(ï-•6Ÿ Ί@>E.É{)«û¦¾'"äñKkÍ ý€ùá1îÜÂþ­›XßFpÖZ MI¢ÐšÉ%ÌfÛhºŒyhºn…»ˆî.`¶± ÎÁ€1í:LÛgf8Z-°¿ZbXá˜,­ÃÐ XÝF¼‡ÕõWq¸³‹é™KØ8³ƒÉl†¦m’²7#ùaI Yëd¸E^g֊ߣVpEÏn§AMætMöˆêÉ.mLL˜®NPTtz%‰@5‰xN@y.¦b@ݽ™A2+ÑF§yôåkÊžQœH#”.Çð†¸iÚd³ñØûœÉ?gù3É?Ú•9Öà€À}dÈÔ¤1lR»>»1Ýñ3ê±1ÙŽhÒ&šë,xQ 0ȇT¹4E(-È©`ÉÙ9Lv"aÊHN]ž¹xâASж/з}‹†æ¢Cû’fžPš@± ¬`~0¾$Ûy/ BøÜäSâ[00D#„I ÇùE–ñ:kÀ°èãdÁÔD¡€SD…Q‘Àä’© f‡Rà€IDATE& z m’ ! žð^˜¤´QI(BkRþBªÑX0—w nSäH@Še'Û²¦™ ÀdS‡¡ÑrMB€$Jše  3$–Èl ¦¼b¥rUöø²nòüUÇ’‰A+Æ9#¥\£ǼÊ>‘ùXý®˜x1Äß%ÅîIŒ[¡i¯Ñ¤Žuèò­ÞòTÎH‚UÙxŠ=¿ ÒWÊ&=ÑîÅ17£¼éäàVó9öppçŽön Ÿ/âú·€Z ßcaº]t›h§34M÷Œà£ƒ²± c渋è®ìææ1q(33kqvc ;ÓM\t=VGØ[-q<æ cb} nŽÕÍcÌïÜÆ|¶îÌlœ;‡ÉÖº®‹qáìA¦@fJ—–Ý?3K™tÚ~=΀WÁð²’q! Ú„ ³CMÜ|OÙ(X&ó8Œ¦mÔ„4£%ïêåXªBäA+Ý—F÷•¤¹«!Û³û•;Š#N„¤Ù7Ñ.oMSu|8ÁŽŒ¨y0<ˆ’¦I6f „$D‹ ¢ZBÇñ; ±e“k ‚‰x Ç_,8ûP€ãï–µ±# E&¤w­OEÉSGÞk¸>ÕH°½DBH&Eñö™ÍÇÆBÊš8P>VŠØH0{ •Ì2äÍZÅ\Ü€,%¦ícd‘Õå 0,˜Ð`îPœ÷–`´ÉüáÀ<÷5ì ÌC|>Ó–\Gе€nzp°ànÛ§€°j€|Ìîæ ¸¦ N+ŸÖ@ÓE^ä}nÚ&&> «xÿ†jÁí€ào-Ø$Á7àY+hŠø~$A‘ #›6“ Y%ŽI¹û Égô‹Š²Ó}Ò_zXúAÙû–óÑž:yÖôYç §òÉËÊ Í•ÐQ#€y?‚rDT˜aFPk$ G÷¯“‹ê_Ê‘WÇýHv1×÷8>:ÆáíØ¿} ‹ã=x7ÀB;i#"ÅÞÜLÐlÏ0l¡™v±fsÊ"˜ÞÚIamx«Ènm'ÌTÙ{âÖg a³›`£ípnêpÔ÷Øëç8èç8†ÃÊ4˜5@ïX/ÑϱwãUØí3˜ž¹€é™]Lf3ØF¹Hd“P–^ójP°yì L³x °÷ªj ÉÐ'Ù1³+DÖñºå6:ïTêKµ=9ÎwÊ~!ß(È«^àÁ • ú¦%Ì[½”Âî3”(h^AG!;êùê´D°DXyŸ½˜=G/} ubäQ G‚h+à ~Æ &C± “ Â&iïRnÕ‘ÍExš4¦L€¥$Æø8ié97@^Ÿ’ÐJ–÷˜q—IU°D(@YI¶¥µ´»XÚ•²¯OQÄéUŸYGI®¢åCÖ‹X.W8>8ÀþÍë8¼}ýj4…µ1'´çˆ<¡™Ânna2ÝBÛ4Å÷%TÇ3xÙÖÖZx«ÈnmkJÉâÅID˜4-&mƒÝé‹aû«#ì=Žü n0m Ð÷‡XÝ8ÂÑíë8ÞØA·{Óݳ˜lo¡›N`SúÑx˜…,ç¾Fa8¬ë´¦‰W ö”YÜÚ¶VÙ³jd<Ëì6UZÃ]E(!ÖBAb(r:•XVTpšúò„”Q},ßU_šªlnú²êÙÔ •zÁ™92Ò3ƒà\,žƒ(ˆVÍA I€ò Â7Ð0DÓ±Q¨"Ñ‹Voä“ÒGTNU^Cr D†mÎú1SDïî’“.Nˆ1ˆÛGLb”’ü¼ç„°$È_ìó"4‰ Å@fì@ÉÞ—mþÿ¥Á Bæf r½ä*åX"ʬŠpzàUÔðÅÆ<è!ð<ß%/}ƒ@+`6`KXDÉciºèÒ)î¾1`x„Õ Ò1àxÑäÆ 4 =üÒ Í&>B °ñ ¢ãŸE,X؇@ƒ˜­1¸ï^Å8‰1å!F€'€|ŒÄ7 “þz'Ê:uŠF И6 ‰5Ë*9,b²ÈzÁ ä/K-Ì?íH9´€\جèÒ5È~¹Ë"`Èâ+0E리ãdƒ±ÍS…Ô°‹– MméXÖE#oÈ5]”æ>ÎF„,ø"ùŬãàÎmݹ…ùá-¸¥‹3YH{´v²‹v:E;Ù@c²X™1²â£]ÝææZx«Èlm#oøÅ–%‹+{“' ܃雓 . Gýû«9Ü1æì±´-¦ a`þðV7°º¾Q³ç1Ù=ƒéƶiÒÂWá>¤`y•î·l oG%-òh±‹}·Ø›ã½Æ©ù ÀP‡,—óèV"«¿5އŠQŸïCQêßHH'D¦+šû µaåñ+çkÈN½@“Êö¤±¶Æ`p.îÛŒ¨¹§‡œû;6ñ8¥&²0)R€}ܬV\6N+ IòÐÍ%¾ƒ&u5¨¬>é»@DŒ >‚q '$d߆<ˆ#ŸÖ®b@å›”!ÿ˜‰T¢ù‘½ùs _Žh˜¬†¯„V•EWòrMŒœc0kYC‚ùm^uÅÖ?èPŒ>F8Ø%Â5?nÁ/£kú †–."–À&Ä kaÀó>ö¡M¾‹>f"l ° |ÎÓS4z‡˜;¤‡?›ôÂàâ9-%ˆØÄdàÎçùÌžT&‡(Ìdh9 ùq~3%Ô!tÖ¢% I¦)‚­RB#Ï)Pž÷D,¦µŇ„‰ ºÀªÔŽ.—[úMÙÀ zÈê£ãX¡‘ê¾÷„¬Áœ8'o4ãÍN›Q65½…¿ÉžüéÙ8ô‹‡û8¸u ‡·ncµZÖÃÐnÄë¼BÙÍÆºéš®Í{‚D·”±bè”ï1ÙÜ8Â]Dw—°»{ 9™ÉÖöx™#2i¤PLH’ï´k1íZìnlb±ÚÄA¿Š¨@° ‡¡³plÐû%V·¯b¾w óshwÎbvö,&[›h»ÖJŠd&ªxù\è…Kþm­ì*ÐTùf¤+”@2Ãeo]õ{ñØ™,X- 1IJnùy”4DVÖ‰ßè8}7Šn<Ñ×"-i! Õû4ˆf†âÞÑÂÊK>º’ðƒCÅ1|/êà} ½bþÉ'ïþ&:÷¤ˆfJ°m*c¬t‚ЕÔïÄ › ÆÆdB!õCæ›ÓI(qÐ쟴™#!òëWŒ2~Ñ5+¥*„‚ÎH¡dÔ‹Sbæ(m„€$ªˆ#`ªEŸ&–>!]ð„ &›Îï£ó83ÿ¨^srÑdÀˆ‰¸aDu»‰×LÌ.:쵨3p.€ÍØ ˜ÿ(]¯ixåÓ‚›0bÕ¾<3ÀîצMšÿ 죙†›è›‚¼·HÅŽú×ß0µàvqšd\Dd­Iéð°g„6±Ð,Ì–{C`LŒÁ$1þ…€ô.2sgÅäÓü¯’¾“u•¯‘ðÔ4it;ã6ò~ óu2§©"IŽÇUÞƒŒ\åûRußñ¾ Î9Ê/›”@ ðD,…ºaÑêõQÕ¾™ÖÒ08,ç8Ü»ý[×p(Í(p©†(‘÷ˆ²7sFâ{(¾±GűÀ+V^™!|Œ™gt1ÆŸÐ(¡$2ff ^Å9½äW1>aÁ3ŠèÁÒÅ÷Ó*›¿@ò`„£UtÞj“¦>ôàeJêÓ ‡¿Ðà€b.X ˜N6IòìcaŸxOâU4¢G¿écå?à-ÈÄ4Ç1úÒžàm*Ðpr‚_‹”¦š=:Ó`bbªÆDÿ“æ A˜¿†ösöŒ4_÷,“”QbtA¡’/CL2;Q©8(³O× 3zgLy LÞj¨[çÈGj¾fBÍe½–!ÛOLÕ&¦Õ„ŒB¨äO iSž®ðÞc9Ÿãàöìߺ‰£ƒ;𼌾8b$PhàÂ2†­¶Ûh&[˜lNÑØ&úgpò I#¯ÁÊòÀ5É»,+@°Æbºµ}€»ˆî*À\¼¸OÖŒ¼05Þ¬µé¢)É ê’¥FÑYƒncÛa†sn ‡ýû«9ÝKZÛÁàBÕÑ€þx·f˜oŸÇäì9LwvÐÍfÑST6þœØðyñR5¡J-µ4¯E—SdQMã9bÒå‡2&*¶Hæ”7 a@ɇP¡#!>‡íå„FECÒïGž¢”Ÿ-ZSaÂ&Á§ÂäÈ:6X>$ÇÀ¤¿ F[8­zN¼êay•ìÙLˆL?ÚèãægP¼Kb ÎoòŸ‘1"•Ï?ÄRÁ‚øô\âWPÂ5õóë÷‚Ì”el|qHùÊû-(¨o„ñç¹Y(HwÉ)0iWàXiîz¸âé°@ð±zN|W\Ú< d‡ƒÏ€o±¼n/ez÷sW*—ÐGÔ=€AG‹Ä¸Ó9Ë0øÙûX„hþb Çð)S¡À.jùŒTØ'V/ôi—K& —æ–ÐöéÀpë2¼çµ›X (¢*!"Jh3º50˜6­1©B¥eÀ …¥ä·¢jÑæ_ÖL´ ”×nZ‰ÈÉÈT\¿QLºDöÔÌ\œGö ¦•˜}áÖ'µfø:dZ·®üó3qj_ôžØ¿´ç¾R jb }ãƒcìß¾Žƒ[7±<>ˆ~†Ð´-€€à<94“]L¦[è¦SXcrÖÍûò¼Uîr!Õ”w€X_‚Ú“ÍÍ}ÜEtW «¯>vlÏ]ߺY4j$I1- of"©J"Y>p§>Îå\7º fÝg¦Û8îç8\-°ïÌCYtÓžVnŽþÖó½kXÌvÑž9‡éÎ.¦Û[è&“X`F´oµ2¢ÃyÚþ•è\àøl<+ ;EDÁ[Aï(pÓi#vŠiA1Ÿú—"Ó ƒ—¦>»Âüó¹²%}«²©M!à ¨K»”RbB±d`£þžlÕ€ìΓd¤ìCÌ~×J¶1 ÎÂy‹&é¿1K‡ÙŸîjJYæTÈFrµÇ‰!ãR8Ç&&o¤<™@&Ϋ ^hHÏ›§BbÌÚ $ï9W¸Ë›rÚ•Ü(Ì¿ÄLGåQ³R}/eÕ œ7d)s}³(’BD ¢@à `BJ$$â‰T=Œ=ôs. ãæG±ÂOEøm‘a;æX«a#B¯XpÛF½e`‰çw ÐD&Í®fã÷Ùƒ]ƒ`e‘ ¹°7-ä ì9iþH×X   Ðv€ }Ú À΃Û&VC2ŒàÜbä‚Ä쇤ùÇXÿŽ ,bè_“f™M~’ªZ4ß±Ã_­­…ŨõzÆWé½QÐÂXó/ëL¶ÃZSÏ8•LäJy Ê>XÖ}føêYò÷r l#þ_0g¦/‡¢8é}œáÇb¾ÀÑÞö÷nâxï&†Å d Lc@-ŽÅ ¼aP3E3ÙB;Û@ÛN¢#&$ô4ÓIœ;a€s‚™ÀL'˜LbwcÛ¼§ë~•ÉjŒÔ:¨‘˜zÄô/!8lŸ;WŸzêðÝ?ò#¸[论‡ßq cÌ$ÊDMΑc‘Ôâ±>£ÎRÅ£–bæ/k€íÉÝçýæ}ƒÕ!ö{‡9zÃèpd0¸–·¯b~ç5̧;˜œ9‡éÙ ˜nm ëš(­¦ìBA©…R‚J¬9)(=§Öµ*éY¾Ó:½:‘óÏ'[ä£lB¦úêÍd[23;kÓèÁúµé@AÛ(?W RDïdDç<› lK„©\píׯvbA&&p 0äa,Áð*1±ÌÖ(f™büm 0Å·bˆa’gtö‰m’¤0’ä%D_æìñwËäU©ërþSföUÀËü.Î|2fAP$˜4%q)Ú“Ð’ã`©¿Ï÷™˜hHUL³,„zl¿JŸå¾„õ1S†%x¤>s°t)U/¼/{&„. C‡ËˆL´-¸YÎÃ/Ðĺ„|PK`ï½û‘ 1À˳ÏÿÿÙû“]]–dM ûÌ=š¿YíÞ;3oV«.IPC|¾‚ô鑨DH‚$E ‹"%H «JdUÝ&óœÝ¬µþ6:7 ÌÜÝÜã_'o R¸ ÈÎÙ+âðp÷p·Þ>k¤Ö¤©~þÔÒ–ÜNÀ‹µ€[€e¡ÈyHÈû †rRó ™ÀƒÎ‘[à¹Á†€†æÞMØ«ÛÊÐ8q8kÂ× åhr ךÑ=ª‚@T2j¨ÐHÈ‹-Õ51[ÏîO_”­ r–\wUÙÞdl¬br"cÚ4ý‡ZG,‰–+{O &6 |™g ×+¯¯xýöÇ·oO'PëÐ4€op ÌaFàðüæQ‚úºNÝn,H}ÕŒ$¾P[.n 7FaY©Nu¼UØ><àå§ßÿ øÖÙ_ÿæ@]{Ʋì IR¬Édzxñ¥¹ÛžÕ<1n‚ ºoZôM‹ûÍŸ§ ‡áŒ×ñ§9àÉ36ù ­ š‹BDÈZ³'‚ç€1æ0¡¹Ì"(,Ôµð~Ø¥È{)„£FmàÀXbu4‹ë|7:¨ÀâE´»«D” A å´Gÿwþ¦Ùwjµ 8ß&(2jèÊ4b©^ 3Ñ\hÎ9üñ»Æµ›¾‡úT3³Wœbª6iþ?Ss “®F3i‚¤ú 3¸ï¾ ¦þ„F˜?]ÅÙ‰Ö>ªÿ½‘~„àizûa‚ð·h/ ¾@p\Èš¾Ø3â«fOªå/ò QkU?–.€[ýQ ùQà§Ÿ§¡Sp"‚8øé[Xd¯v lºŸhü¬ÿÊ:˜hq4£P"ðr¶~*W€±ˆÉšÉ)žcg¢OÃÈÝxœÿÍuIÌóº ¢¡ qC[û`tYâ€ÑÅg= ѲiRZÛ™¨¸…¦qÂé툷ßðöã—ë Â8Áy Ù:jûËÄ5×îÑÞmѵ;´Î>³¢®Æw¯-˜k‚U]­-¨·Úà²õ 5@øËŸÿùŸ€€þXGû«_ŸÜf{å%ìkÁ,šrË3â\–’ï&ýß>[K¶*»(¬ŠÉÁá®ï±ë:<Ïw8 ¼ç'ò¸6„Î5˜Â$5¾ŸqyýŠËv‡öá ¶ÏZƒ ï$w¢†™ÙÏ#Q×Á’5Ó!™†QHÿ….Ž<%l~—Q—‘ÿ™ùª2·cøv´DL‚,0£ôd~PÚ©v—ćM€|˜TGŠu®È‰ŽHè™±¤x:×Àûã$)Ä@Ó;æ0`1ñ‡”vE)´²`û# KŽ€IãDœRnbÁÀ!•–€:À'ÚÉqˆ9ÓÌœ€¥22ŸYÎ “ KŽ%žIƒÒw¤ëq?pžÍTQ1rЂ…—¤'™$‹Ä„ÀE*Þq«H‚jc/ùü-ª3à‚ƒ¦a²`û·$Lûº ´Nþ€a¨^°_'ïéägð ¡#‹ÌÏ$„@üJN?°M¦Y ý,ÜHFòîÐ<Ðjt0ŸÁÞ#Ì Ø{𼈰²0\ëf™“… X¢û›€Î1&E>ˆUœ«Jêªc qP  ìÈ&÷ÌalêŸÖ¾JYC¶Z`ÒT ‰ÙZ}KP(E¦¦ÀÚä“HW¢K5»¬z+"ÍOöŽÊy­Çó°0Æëo//xûñ3o/˜†303\çÑntg2cYf°káw{tÛ{´}‡ÆÅ´ðÿ]¨E|QA•¾Fÿž¢_h†i¸øIb Ú®;?þêWJü£ÏÏ'ÚnÏ@øÕÑÄãd (NaEfsXÏ裴"²„ÍÜ)ÀM7\Pp—MÛ¢ï:<,{\ÇY2¦ŽáŠ!C»Á– #N/Og¼}ýîá›§OØ<<¡ÛmÐ4^72KJ¡]”ÉGÚ@•iÝJÙ¶ïÐëi'^ƒ`”¨ÇíN¹W² 5ÑóŒ&ÒFY5ƒ*Þw ‘0"üšs wšµ¤$¬%ë@þVÀäm`xßaj=¦eÆf€<<7ð.HL@hÕÀpZÇ“E,÷ˆF(3«7ÂXêE“®S\±24æ¢Æ£Ö™ÖÌüÍWР¼<¾äЩI¢œöe±‚g,y&ÃËTk‰aÍ‘Z4Hj 0:A°6ms> ±¶0 àÐÓ%Íó´½2Þ|Y·¿#‰Y8Œà¦aÀàRPhÓ‚ÇI„ŒÅ#lzв , xq€÷‚%€ BÔtP#ˆjøâ…gÖš¨wâóðÄ,Ð{Z€¸]$ÍÂy,hš˜­óè\Ï |#È~-Lp gÿ¿0}j€dÉéÎ&œ”Žh–V|ˆ\3"ºp¢KÌp¥(x› »"01ÿ¢vZ+.83¾ÒZ ”Ì?­!.^o§Žœæ' c™&\Ng¼¾|ÇÛO?ãt9‚1JÐÖƒ:s%¸µ¹ƒïïÐo6h»&£ †ÅôºŒi`¥+‰Šã5cˆ¤²˜‚ØfåVI3bèbÌðýæzÿüéOH€´ãîþ‚Ýî­pþÛ½ÀÕyõ»Hk™‘­]F¬ó,òcXÍèB=9Üm:ì7>M{†^‡ ‡pÅW´ tÍ ãrÂðí§ÓîÝãlŸ°½¿JÕSEž¡T@FÞ7zÖøú ÊRj)Åf-0jd’RÆ ÔÚzTŒ Ì弤™Ô{¢ m ™êÜÈÅQ dj ŽŠ"NŒß£=G­'Ì#8,pmƒÎ3ÚeÁ| ˜š¡Y°„·x8O‚%æ R*Xýþ†”x¨Xb8 Yð¬}Sâ¿ðÒç…f¢Í·¹ÖQ̰ÁZ6 #V–3°¿º<#pÃBŽê·ÏP&ŒŸ.fÌ€ö, #‚k„a†#ĵÐékëÔbÔ3x®AŠðAòü x`šÁÇQqþUj9šºH`§@!ŒS ––¤ª_Å­àØ7F‰ÒgBh½,Ç YZ؇àŽR¿`Ì…} ûLZÒW!ŽYÍüäÀÔÂÓ€~dxOŠ'±ÀÍ3´DhÁêžÊ¢'Nš¾3ɧΉ¥Š˜“ñ+Aûš¸ ÇßäðgkAÖø)árĺ$9úöwà S ^gv~4;Uö»|‡œ‡Píõ¸(ÓÁ™Ù§ 9ˆi~¸\px=àíÇ7ß¾b8Ä"Ö:x¿c/3¦‰À›®»C·Ù¡ëöh½ªaQå#ã!$ÚUrí{¢iœÏM‡KÚX™þ ÒW͉¢D_ h6ýyóøø§€?ÚAîþþ KŽ(µ¬<)ð‘7±½˜ `¾”¥D9 C¾dS©qÓ"lÛ}ó„§Í‚ó<àm8àmq\\}@ëz×aäãéãñ¯?mq||Fÿø»ÇôÛÂç%.±. ¦^€Õ$ë²Âñy.†’Á$ãx¯t¶ÈïI82wd >\£ÔySfsL a#ý>D!iBŽ áÒÀ¦Aãrðh˜ÀŽŒƒhn]C˜—ÓyÁì=&·€¶3<;ê‚OAP³*ÌEKG`4¦BddÚ>N"#9GžÏ”çM1ŽÃGTq×D;0ÔÚ O øO´˜´C³ìƒXÇ=T‚Ž3bCxk™\IŒåÐþ¬B†FÔ#H<Ài¿÷À4 j¯ @ªú©ï¼uÀ´ œFÀìÔ1ø|Õ‚:n%f`¹èÐ$Lj†øïÝ"5f€=À^ ûÌœ°Dð„?)ô骟Öðœ2 Að3h Ià9 t‹Ô-X¼§Á€n’Zðä ÄÜ"sè|HÚ¿ÔŽPDJbxuIÅ*~Ž9zDGKþ×2â˜!Bý¡´òžÉi|öÊí>%÷×b¥ÒŠØeÁ ¥ètU“=³ìD8Ä"cÑ=Dz‰£àÌmÿ|ÆáÇW¼~ÿ†Óá Ë<rsçµR‹%\°·…¿Û£½Û¡m:8×v‚\U7Æš^SÅümüBˆ2…+”ÇêrÂ10ß*ÝT™ 8´Ûía³ß_ðŽ%„îï_I‹n¬$7Êß6Üb)›è—l2*Ílw€‘¤-(NŠÚ¯õظ(5u«óßá¾ÛáËvÄa¸àm:âmžpf‰˜Ý‚…a¾bøù/pùþ3.û{©Aðô ›»;´T“"3!1þdJNf.=7éx…– £`æB¡Ñ×®ØÌ^*ZFtÏä@"ý†”gY? Jð#û'TµÏ1ÂBð¹ìn$–®Aèœ~ ˜œD{O®šfÁ<æË‚Ùy°óð›>¸ñÏJ`ƒ®#§–˜žb•HA”áj|@˜bJ¡ f‰¦]] „[-yá¤`8]AvåÚ Á}DB5Eë•å\mN!qÙëÞÑBA3!pº˜`–tG8Ñ‚0J)`n¤kœF"õŸw­X0¨‹£ÓÁ‡ ‘ûê£gÏ,1êÔ8,$e/ÔX18 L,öø g†6Ëš@ 8‡0WØ‘60š.À/ãáÒeÐ2s†ÑôU@éˆyÿ±œµƒfp ®Íâ±¥:‘ÒÄZúfÝ f½‰nÕq?%㦊r¹Uiœ]Gke‡‹7°Ùôœ„‰ø_rU…€ipz;âõÇwÞ¾a8¼ˆg¯'4àB1Oó ÚÝ£íïÐv[4ËZv±hã^Z+au3ó••‘|ÿ U¿°—Ö*žãÕl‡°Ùß½Þ}ú´ÊMûÛ||(àô¿ûßÃp Ýþ7»©ÈgŠHH¥|ËUcTd¤}ٙɕú,’džÛ€!Ö‰çlöv}‡m×ây¹Ãyð6ŒxN8…Y†Z– Ó2ázü†ñøo_ÂéîÝÓglïRA*Lfc“Kf{ØMËf‚Jÿ}yÒ¯êµ|©ÒMœøø¦®Màe<­]5ýDꨤ8DP³;i _SQ¤Ô¬TŸg֤͛ÁN­#ÜKiÁ0g€6˜žšÀ®Áì3óyÀè®ñpM#Ń8—ƒf0¢µA5(0)Ž€cñÅ“bT B`zdþ‹¬3íÙÌçºÀRa’DöS ”è"ùü£)6"?³ù I‹#H”}€äùƒhÖ¹wb&ǬV‚F`Ž[‡0`n@}+U÷ÂLö=°qÀ4c÷[ÑÖÚáÌ@ÛIß›a˜z 'ð8I0áÜIm Ý?‘@îº Áú—Ê‚R̉CÊ| IªŸ>£~/Ê<}#Z~X°LÜšv„mx4p~ÍÀD;ÀAÊS+ ^DÔH-Áø§TÕÏ«`šAH…µÀ5q (ë¨òÍ2¼oþŠ™a•î$èÚˆZpæWÁbH¼ ß»xK©—jo}$ººä äÂä„iÆåtÆáõo/ßp>¾`ž&€ø¶œ¤x.A³Qü¾¿‡ï{ô}罘øÕª•(¬H¶‡¬:–²ŠÈRéÂ*RlÙ“·db êùÈ–Š:Áo6¯ó0 ÙlðQŽ%´_~…ùññÀ!˜¼æJÏ5̦òT²r)@9Õ¢È8w(Z°[%|X©Þƒƒš9%×wÞ¡ÛîðÐoðeÞâmp/8,W\˜1º=9L0ޝ¾½âòò×ííã'ôŸ°½VX•L˜P”±”ªµ½_Ê0ƒem€M)øŽÄMÊ6“ âÖ«ªó$ØÇÿU•ÌŠÕÉró,AÈåM„˜^6ÍÏK tR³/Œ#–¨tß2ºaÀr X6’Ò7_®—j·p}'XîAM¼lcò A3‚êkÒ —†¼†òbËóšÖYD(«+;2'̧ÒB€]ü d&™C¬ Hê Û!™zÁõÑ£ T"q01xj¤Zb‰ÖGO¢e/“àô“ZšðyBð­¸eÚá".fê„)€GêI}ùñßD4ÂŽÁ¾S¿Ö)l\ÄJÁ^ û„ 8ýìG ø¤È Ð4-ø ðhŒ YÝ>M ×\AÃ@ fa†[¾ hÔB™=AS•ˆÄ,§‚T dcŒQá²€X§¸þSÊ 35Ì$¡„TŒŒp“UeM¾Øâµ <ï¿TZ;Z,R|N¬_©*%³ö¼áíëW^¿a¸^À<Áy‚oZ˜g„Ô·…ßîÑõ=¼ïT¸gÄB -ž(•š, gël5Ú¼×=Ê4­ÐòÍ”Sñǭʵs”Ðïv˜Æáðýÿcüÿáˆr|,àïý= ÿí?~ÇŸýÈ%²›ÁºjÖeæb„Ê­“/Þ\F‹SJ^JÑrÝUOÕò<ö]M×ãó¼Çið6^ñ6^qâÍ}‡-9LaÁpü†á톟þÇûOØ’`!'Y@° GZ´'DÑ#Þ«¾Vý"¼hu…T‹"h€Î¢Ö¿`­\ɘWŸ)ñ;n­Ìk„Y4IÞÃ$ ?ž€N¾Éñ÷ ´„ §œ|vxZ¤6@0‹æqÈ-`^fŸ¿ó*´-šç/V Z&©‡@̤%|£EÃa‰…}PppàiBßHD>)ž€óâNp@W1Ó‘¨»ÂMRj–€Zavtd¸{—¢ýÓ·fœ.Ýœ z¨™$1'ô#ÃÄ+_}üþ…lÍóÙ4µÞk•e4¹/Ö›ÞÅæž¼;“+1•¦ê’q/Xæ×Ë€Óë ?ÿ‡Ãæù*@G­ƒw™é°ó þ]¿GÛmÐúY½ Õ NÙ kæ¿^mêÍû§ˆ¬Të‰FðbÜ>ÖSËé[¤Trfl÷woÝ~t|(Àÿê×hž_Ü:I…74L¹ùÊÌ$)R晕yieS_žaMß¶@G$ô\¬ªèËˬàÞÎ;<·;’ûæaÂùpÀÛë¿}ÃåôæÔÍœˆó°xš|¿CßïÑ´-<‘|Ö=k…\qÿ2˜¸¶åÚ1ç6ßW듲˜è`5WÖzW½·Â°}zzýü÷ÿ>>Òñ¡|ù ÿô|úܬ¸ã%‚âßJh-]ŸGÄ‹O‹BÛK·DèפçUcïµÒ¬Ý°±} k F¢9캻®Ã§Í½X®G¼Í3N¼` =9l<0Âpúñô‡Ÿ¶8Ýÿ ÛçglÐo;xߨÉ.  õ†"ÒLd?Q¢-7ŠÅJHÿrÜlxƨ"˨ƒ:Ý`kaPÍ'&c¿ ÒW¢ˆ ZrPBªñÆ)}*°ƒóöù8Ž[pã@Í"L­Îô°€©ZÀ5¦—Q׃Ã$!ù®3?Fþаúï',SøðâóÇ¢ÅZؘg€;’¢<4‹‡s ‡¾áÑÀ;©åàü 7Ð42ï~:1ËXÐ,À ÀÆÁ+äs€sèN÷KJm:eô¤Ñýâ*‰æ‚øû ±|uŒ ðXæÚ›R(Y»Œ92¢…FK‘B'ék?8™=”´úÒ°fW¦Q€¸ŽbßÒïšz»,®N/¯xûö3ŽÇWLÓ.oÅ¿ÏAúx–”Ú~v{/Uø¼W $§hþȤ©nI3S—WšXy•òCÉêjÍþ\P—L³KÏ€ùÁ^[›„ ËÎÑöááíñÓg|¤ãc ›-ðôø ï@.&X•ìîr&mû+™ÿÊ:³¦nÙ†JëõzeiÛÅ~£²ÔdhÚø²¾iÐ7 º®óˆÃtÁëxÂaq¡“gô cZfLËÃ÷¿Âùå'œïîÑ>|Áæé»ým«A\™;$ Ÿ¢µÀ2ñ¨˜þZAÚNGÜ‚yŒT˜)™Ê 1F—t¡220j÷.Ù$˜Å”6S"º4\Ð൦±7Ð@¸=@ò27L‚ôðkÁ´À--¸k„”ÎWpðp›L@ü¹€@Ë|F83¦m‡Ðt\…¶pÎIºÔ„¬¸­D¢)'½±À³fÍd’3ج]RâÊYG%HÀ_Òü$L~x8ÆÀ ,i©Ù?L­lTóŸp׃¼Cp pÔsv`¾‚¯ÚOj€eP¨fî L  Q÷hT(âž_\À³¸°X(þ»#çFø™òðƒ§ 4s¤¦ƒïF`bÐâ@—wÑ w ÀŽ@Vú»Š ë…Ò|†¼ˆXbÈËx)L 0'¿¾£È~]ú›˜ÍoÑ¿¡AØDŒ(…oÙg6pc<²v[™—Ä)»‘J¢'ëÆåw¤öJGFCRì'3ccPß7¾}Ãåü†À#ˆ<š†×ƒÃ²L‚8éz¸Í¶›š¾ÕRÆ,û+¿îšià-=nޱ¤ªºŒîÇ p-û¬ôšUÓë:*Yï§õûUÝ<>wÏÏøHÇÇÐýËë;Dû‘Í\/LmvN·Ý\Öò”ªVNØÂjG³u4çEñžLû¼~m’a-1G-’¢´ßôØ÷½ ÞÆoóçeÀ•[ÌÞcãS¸âúvÅxxÁÛOw8?îÑ?~ÆæþÝ®Gãœ2eŠŠb øùlöàÌ`Pô7jõ©ó˜Mùÿ8™åx£fR®æ‡­Am¤‹ÝáÁ); b¯Ä-ÚX`K„ë¸aðS£P³#ˆgð•À-ÝÐ ¦bÍ? 3Çü:€&„ë‚à¼[{ :8?"\GÌ#ü‚°i0p  q 6Ö#'xߦ•‘ÌÈHØ“ªµ+uŽß‡Ç‚AN ò…¶ &‹Ê0ƒÃ(ú,ÀgñÑh»[I±ãA­"¾ÅrÁ—hBþŠÏ_°’5rÖÑ4R¤%æý/À#–êÏ÷òÌÂjòoá0Á-‹Œ½ib7šì[çÜ"Ì]Jí\;‚Îúµ"›à*Ã&ðIÌkjhá­øæ±  ACõ™àh† ˜ Ôˆg ˆº„ûŸSú A ™dÄ쀈ÂGɊÉ‘ܬ³eÑÊ»,ä&P DÇÑ =ý…dÒWË›‚Eåƒ!•íÆËÇ·/_q~}Å4ÀÓ×¾Ù,ñË5 ô-¨Û¡é·hÛ=š¶Q<$&fÁØÑ4÷†•ÞÒñJ•*ÔKy’²R=Z¤4óê%•0ðždPö#anÉÚÝ?¼ìîÿðG=üoûB¾†F‚e$Y/ýåŵÒHíñ07¡Áñ>6'iñÕÆTº´9í€r‘³°nV-ÐbD]‹§%à2nqÏx¯8, ®4b‚Gß6±`š^0üô§ïóöíÓ¯°}|B¿ß¢íÚe+À’Ï2’ÙÑô®²„=ÉrñÊܵõJPN…Õ½Ù%ZÙ(kGñ:±Õâƒ:qV_¼¶sM.ò‘T¬ó 8ãœ0*4„à#øª]k¤å0jàV ^›%ÀD[ ž”ÄP€_$í°õt6Ì’+ÏRÎ>ñyϦVð H iÉO`êUXup:rò‡€Xg="À±"¤E7Sª6¨Í< â,¾€Ü x$p$ƒb 0M çÁ×f Ó¸ šÁ§QJ{F0+¾ƒ‡d,¢ds³DºÏjCÄœâ9€GøYöé3<Ëœ‹$1’Íœ0 ó×{ˆ'``=  ™AçI„%")àtS À| "$É÷àÉNˆnbAt §J~ ¤r9&#º2@L¤„ïdHëwHS¹ÇâÒ¦ˆ$¨æ}B‘R›ÀB(ŽGfÁOHd‰ÅJ…‚yÆåxÆáûw^¾ár|ÃF¸FNy`ñó€Åêá÷[ôû;´m ç<¤žÆRf7CmÚ¯°wf`u^:@Œe‰s=­üûï¾Æh+Õv–‚. |ÓbûððÒmwøHLJ†ôŸ#oîéËïþªä±Å¶¸!ônüùWáÛÉm”ÎìÏ fm[Iõy|GÖpž;ëDaƘ¢HÍxСÙlq·Ùâó<á8 x/x›¯‚+€€¹ñز$Žß0àå皇OØ<~A¿G·éAÞ_f 7bÌ%Q㎦f˜ hÄîX¨(IÝû?9¹)Ïw~Ô|Õ4À4¹Ny \\2uÇh"Jå–%fÞ‹(Ð2hZT¦ÖÔ>n´ÆÐ|PÚ€0ÀµðLàvQ&Ú ,Ô%®ô!ž»ŒÜ ra Z;€æØ; Ç‚XhÔ¶fA¦›¡™…hŒ@rK-Åë:®œº™Ìúu‚<‘ø’šÕƒœ‘©Îj¨×t9jÄJ@X¼0дD€¡Ë,Ey¯Ey‘DÿÓZ‚wh<àš4<ÐÎ1<- ¡‹F?ƒ3»|ЬR[‡deÀMA”ÏÃW]êtµ„ ‹d×(&ƒæè| ¤L“b@Ή«@aœA›à¨aÀKñ#‰öwZÄIqÒ¾A*R%µ+8eåä4º|ÔÖ5Ù7\aòb0 Ò†©…ñdúÏWÙî-ÖôÐ$êÍKÀ4Œ88¼|ÇéåÆËÌ® hZ¢Ì–9²ßÁoî°é{4m§"õ%zXŠíq<+…›Pß…ÛÓÓ««É1×kÂnáÐ×}©›[•úš5#S2˜pm‡§?ûíMßã#J¸þgÿÜããÙ?=-Ë_ý…·¿Yߘa9æšj«õÑóhÕ/¬þÕ½)}Y+®å?Yºµ<Õ¼$–šÍ½4ÌÐTï’&ôL%u[¸i¥DñãvË4H ‚é‚C`\±`ö z'ÊÓ81ü|ÅéûïqÚ= {úŒÍã#6Û|׈6ÃNÃä%ÎÅÜ>}cÒBâž"dú dŸg¡”þ¿ÂE#‘N9…M…V¦•Í› ÷ê.]RÍŒN ZT'&P ‰lw’Ÿî `RxÜÆ‰¾SDÅÖË ; :eï¤[­Ïk€¤ôuPó»˜öÑz0Í öºpœÍ1ìĽ€añú<€yÜû¾‘o̓˜ò{Å ø¸­¦ÆrÁM4 À pD%ï¼ Xf'€< ‘L×êz‰îîFàÂ`jåûw î{-b2Üw²æÛ ͉߀|#–ãԶ$ˆŽ`¿§èp+¼5,Ó‚<Èb½ïÔÛ3ƒ l{P§+æ }ØRŸfðÑeŠ©¸¶A¦¥Vž¹…CF«¿oÙç³u7D•¥(ƒ¡k5 04œËóâ[PùƲTüÅ!`ûðˆ¿þ§ÿäp=ðoý{ÿc|”ãC ý¿óïÀm·ÇSãOX–‡Ì>(¡Ôå W‡q˜5b5{äýeFn)ò<^M Š¢Ó2Ó¯6$ߊ¨Žd®¶}µ‹-mƒs­f‰–€®ßà®ÛàÓ<ã8x8LGœ‚Ç@]C؆£ZÆã Þ~ßáxÿýó3¶Oèz ‚"eZœA—R¹âÔAÓS lŠ^ÊÏ0BC4á—¢u´z˜/Æ:ié½öÛhúSľ~Lu;84úHÂ]L™#€'XH^œRåd]€ÅB iF.kêàxN–&ñ/„…ÄÜÝ2€Y t§ô€bå ´D³¼kRL† Dš§U÷ÄdÏÃ-â¿4–Eav=Ð`µ°Mt ahÓ€›À(лY°Íœ4=öuÔÀÐ6~Þ ú­Z¥¼úÕÈânÐuA2E7˜'aÜ­L¬#eÜ­¤ Â/ÀigÏ yO,ýv¾f°`·€Æ)0A ˆƒZý†a_SAPˆþ{4 ‹#Áµ¤ÁgL‹—”@Là0ƒ¯yÿr•š®] †]¤8ºrw#Â*êڊ鸫Âc…ÕºŠa)ü‡–ñW4 Ñ'N÷¥fƒÑü9š÷CbüÓ8â|8âøí'_~`œ®&¦ÛRMqAW“½CÓo±í7ðM/(§ 6eŽX‹¢^:±òÍŠòzšäZ—nùü¹æNkR´ôÈÒ®•§ ÎÙ»Ÿ«r4§ŒqÇmŸç¿úoÿÛó?þ¯þË? ¬Ãù·¿;¹~s¦°<Äë„LϬĭVúâ›:ý¢Áò1Žà™—'Ù“o,VT%³¶’€pëÀD²W†ÒZ®çåj¬Íﬖ„©+¸RŒhÓ6xì{\æ{¼]¼ÎNËvh\‹žs˜0 g ×Î?þ —ýÚ‡OR¦x·…j¤3kÇ,C®]EQ"ÄL.ÁŦ´ÿ§¼b/ ®÷ j¨‡!“<Ðߣéöhû­–*m?§õZ*©ð×ͳ³a<¥HSÛÜë¦Íaa²S$Í·NÖfK"^¿’o],Þ[?WÚBpÞŸ~ó¯ýë§éú¡j}, ùôt¢íö–X1 ˆDeqhÕð|͘¢“ù\™3æ¨]kÍü7\Eùz% 䔺rý&wžp}ƒ9§êÜö¢Ì0+Fk ‚˜*Öz‡¦Ùá®ÛâÓ<â8îð:\ñ6¸„#yt°¤ÁÛWŒ‡ïxûv‡Óý3úÇOèïïÐmz°uƼg·!e¢–€…ìÄ¡º&´˜ÑtOj3Ž9¹Nì7 û§äPýµpRJNÑùuMˆà gvµ0DýÁð˜Ah 3$,`µ*D½_ ¾6* Ä"Á-b>eß  ^À çм>[$Ï~žïAót-x‘ß1…b‡òÒ4 çI² Á9j¦Ë‚\M9áµdï4Lp˜¨9Lòõ6:´ó ÚßÖ8 æ¾×Ï“üÔëî£<P«þnbð0‹ù›´}/Z5cÍßKßá4í’¤@³F6Ú·0‰ï¿‰pÅR܉%Ÿ¿H òŒ¬ ¢\ pG"ä1ƒ&q© qoLâþ‘؈IL’¬‡yÌ‚$ðE¦.„"!ôQÞ›‰&¤´·l*ɲ* ô…ªjèXLÛƒµ®e| ¹°\''_¾ãøúãñˆ€E¦hK<8àòcAð¾½G·¹GÓõâC·Si !'÷µÖ⹊i¢‚Æ•8+)ŒJ’,öhi¡/Ý¥V 2T» ËUŠò­Ž¼+¥…&¦æ.MÛwŸžOÓåO1´ƒžž€§ç ö»S*“• à”ò™2þš%§‚?ÙZ f~BaÈŠù舑êdÔ 9R-z”›ÀZôÄW«7òÂHh}ùÔåìo‹· æ<Ô*6›ÎÇ®í±i{}9!µ¢áG&5#b¼±¶¡ÅUïÊümÃÁa£Ñ6ÚžÄ15»Fφ ¡î ¯ï„¡Âì$ö ¡Y)ï[HżF³g€F4·Êˆ&IËs¢_Dp2a͘ÅmÀ$(ˆbÂ߈)›&Å9èà:©5Á“ޝ×@Ëe-èZKÁò§¦×‡ ‚¨÷ºf—Qðzõ7h¡&´=¤ôõ¤‚LÖ fÁ îÕMCŠ^Èò aTæÙKœ†_ÄÅ ÀÔÎ"†V˜?Mº¦z^ŽèÄ¿ïEógßHl‚cTb‘+—QBÛŒ«N÷ sQ@ ’dæ¿èî‰.§l!Ìû™U±4µKa*Ùg‡€ázÅñå ‡_q>~Ã2Ž¸Æ£qÙSË„€‹ë@Mf³GÓöhšF33" pI°R¦PŒÕá´órßãÞMÛºdþ0J—µ–èº3wäêQptO-2æ=®h±<(YeªáݸFȱEOŒ\h6ýeÿü|ÛéøPîî€MÏn÷JØ?Uí+ g³´š…¹5¶]–ŸiµlºNq9¹øã‘‘îë`^Pïƒ[‹ŠFÌïåBµRl”m¢àûb\ Vp‰ùÎ;´~‡û^3Ưà oË€3ÌÐy LîsËÛL›ÐMh{׫Y°Öz7dÊ¢Z˜ ZŒ¨Ã®mñ¼Ùâ4J1¢×é€Ó0crŒ­sc`øé€ã÷¿Ài÷„öñ›Çgt»š6219§8÷Zâ†>º%虥ÄI ŽnNçä™Ç»¬ …ì Ì}u„Í_þ-CÑ–#-DlŒµæ\Þ»(ƒ$N Z ‚Z ¢æÏz.&V§…¤%¶úVIŒg´¨ÈÉUá’0¢±¼äÀbÑÒ—E¢Û5Ð&ÖùEXÉ Æ©Æ:À j:w$X³”Ó¥V4á°Ì jÖ_Í{ésìèÇÅJ$i! œ5ä"š« ãfè*B;½g‚¼—“}7H\DLðuxTT¿¸Ã"BEGæ?W€¼ÓyºŠ 8“+0`r:gÀ3è Æf/’Nq¤ˆØIP#/já1µ5I r¬‚z$Ðhƪé'Æó,³´itlŠï(}£t®R~Ôöß^püö‚Ëé¦ñ,4ÈïeÕóŒ0ÌR.¹Ûõºþ¾iá2rùXX[ó¢é=Ž"Ç4Ô,:¥;Þp²[&\gWÅGÖø+*ºfõ?uUF©M[Ýdt3˜æÖ2@eDÄdÐ0LÚýîu³ßËŒt|,@£\h·ûSM²Q¦4'U!6Åa1€¼Øj&û»aöÙu»•˜nÑæú¼n·†ØU…yýeö(iGäÅm\¾ÇÎQÜ!½÷èv{2F§Ú²úŠÑ"C1åÒ/bAh’øÏc4¸3Ì_ž úN…EU*04ëGvdE›”â,Rƒ˜‡Ç ¾•ÀBH”»ÀÏ xÉ÷±¼î Ån˜4j~„ž ¯ÑïŽ!Ö^žt!ú¹Ð’)7Ñ^´”QQòf h$ñÇÐÌ,B…#€Ñ.# 0‹•ƒôU˜ð”Ûp„1³ò´ð`æÞFæ? °'b²_´ Ž—ƒ¸%Z”ïmõ½¬®" Z\®Ši ó¶L`Ï7–ý!ÚÔ\ÜŒÉJ¥)‚jwê ‘RËH1yݳ%ZI«Ž¿'ª²µ`™f\N_¿âôõg\ÎGð²`!`á 3à:жG·½ƒï6𾑵ŋÊ6!î³Lxba«x™_qð-&›…"K#×&€’v»ê–Ü'Æ-nêWÝ'²Ó[2ÿ‚†syÿMbn³ÿÏ+¡ßítû–iÄG:>”pü_üÇpû=øx<¸ûûR¬„_°]HQ#³Ë9žWRfÞ\mˆü‰,.—b4HFâÌG H”xZå*¨‚¾Ø~aÃZÊ“päÈýÒÌ!0„8)‘a–Åw½#Zö8O“ NWÃ3úfƒÙ†®×+.?~Æu‡îñÝÃ6»-šÖ+<œ;ÎZ±Ü'Õ³k¢¥ã|¸8¨¨M…$ÞÄNjª q`$M/º $ñ_5ìF¸œhhÄI¤i^Ž€ã¨†Æhdž‚˜ä™Ú¤'’šäúÞdÖ×ÒƒhTÈ `žÅ À¢±º0AŠñ€FŠ Ïh¨!cRkA ^’G¨Æ’ÆÇêï†w¢m£•9lÄ‚x 4¢»YðB'Åëý¬¥‚{e¨‹2æV¾N¬à@ ž$ϼ³QwŠ”Î6â aòòL«Ï,$u:v3(° ÚE#Ê¥±hþ ˜0áŽÀnÖRºÒwò‹š¯[1ûwÑãÓ3ÐgÀ¨u`?ƒ– °!ÏbY¡VÕQqý0kÁ1ò$uã¥*ñ/Ã8Çu+53kiŒû°"CHé­‰¶1x ˜Æç·#¯ßpúþÓtÐ!ß¾·@`„0‹ý¨ÙÀõ{tݾkUñ 뀒ÆíEþ Gü ›m´¢¨¹D)‹ëÖÄo-§H÷EŠk룚ñšÅç†2ã6_%É­Tί}ÿ/0üŠâê_†ò§vÝ~÷ÒõLÝŸ‚ÿhpm ¿¿{#çLa /¡h|ÎÏ”E²P~yËþ×Ò(Ì“V@Èmå_ß‹°üÊ£–¯T²DŠø¿e"«†“Û±;ë†õ °‰Üù}Óâ¡ßà2Ïx»žð:8..˜Ä¥Ütؒž0¾ýŒëæç‡GtOØÜ= ë:Õò ¡!‚_lMz™H#$t¥âsij`2¡U¨<2¶kÈ U\8D«€ º1Ï‚æÇNŸÉŒ[ˆ^@®UÁ+@²K@`Q£„RÚhäÄ·]ŽÁ¬š?{c dLâœ,HA‚bpb"…ãà¼éÐÉ7{°W‹Ã¢‚‰—ª|3(l$Û‹'.­d# “ôÏ1àûÜj&„0‹áb•˜½Ìµ‹n† Êd1Ë =Ð~aB+ýu ö•4GŸu´ÚÆ,^èä/Á˜`Bò,é3‹UÇ«E'È{©ñ"0ð É—l“€¯"ø°WïТ¾sEŒñŠÚ'G×JŒ;a5\yø˜:÷,$R¿`€)\ËÙÀŒ°,¸œÎ8þxÁéð×ãæe„g ñ‰IÀŒ0Šý*4 \{¦Û¢éwh›F¹RÉi›®˜þÏ%u#kaKtCᶬé¥r²²°ó *U[3aéñû4V òŠvÆmCÎοô¦µ…!W!-3úý®§Óá?ÿOþ ‡þƒÿè?ÂG9>”Ðþƒ?‡þ„ùÛ·2å$i™‡P¶5WØräÅ_râÿí}¼bÕõ•ò¹0.Èxo­ÉsÙ[›%JÌU7s/nùÛnÌÝ{.‰ú< ( sCÀ]Û`×>áyYp¼ŽG¼NÎhFë}Ûa0Œo~úëÏ\îÐ>}Æþñý¶‡oš4gÄ@PÜÚȆvŒs ”¢¬¾í*0IMšºžTE¯X>¨ù3Øu’^aò‚줚1pê¼Y3$õói0)SfR3>KÄ|H}G«CˆÏHæD œ€X¡(¨5 ºÄø*âHþe­ŠÀâ:È>ÚYJèάÊü(ïIÌà˜AÅÂNR¦t,Œ¸‡`, hpà^c0ß»òÌ ‹•;äÀ»Ñkð¡ÞÒ A¦AâH­4ƒg/š? ’98P¯cÁ ç%«t…!1 ¸xàуz‚«Þ+†C±ê‰µ®ˆ"ý‰/B],,B‡ç´Nƒ]‡Ä BeÌpššéR@X¤ªÅr>Ë)¬±ž½,üiœp>¼áðýN?^0M'3œ#´¾I\œ—+fÁïáú-úímÓ)‚ç¢ë9n »ë³%Îúósb¬¹FP«Lt{•&$"s,öpE¿j]$¾é=è6^_*[°^ÄÄüÍNfP£ä½Goö£îM|¯Z=œGÓoÞ.ç3ÆóéøP@óùÜçÏhžžL %ªæøâvïxpëý«-~É…f²©§^ ¥Bmì 3_ù–¬TPœWæ©òukWÙ^ÜM%d8~kx+ 6EˆY Œ÷Øì¶¸ßlñyq˜F¼G–WÑ Ñ9`ëZLaÀõõ'Œ‡Ÿñúó#üÃ'lŸ±¹¿GÓyÁì+_§” %EOt¶ `rbAÐX²(Qåé2ƒéѾ™¤Ó’µ³Q “>»À¡U³“55 sšÍþŠ¡ –jï2cE_4&e^\ÏWœÞ^qxý —?°Ì®sp\‰À3‚&% ÝÃw[t›;´— M.¿µ^bÖ”^˜‘¢û ©Ù‰ÖIƒ£›°ŒÙߢ­¢xWuÊ„­V¬J«iI™c ‚egÃú%éã¡„Ë÷$zRH«žæû ~#é’wŸž_ý¯þ9.¯¯øHLJܧOÀçÏðŸ>½9ߨªQøK2‹w­Ù±Š—Õ5m¼ëZö¼'`Ÿ«ßÛr°f>½‹òÛÒ‚Ík²p_%³–1“½wäM­÷Rî{–ÆÍæ"kr“¿]º–ßk]9F1·ŽÐnz컟ú-NÓ Cgœc$Æä;ô>` 3Æë+†ó §ï?ἿGûðŒíã#ºÝ¬Â „À”yëÎûT´h‰…^H„˜ô‚_v Z¼ä¸ƒÅ”Ì1]LÁ}¨…˜ ”;/`°“R´ E´rjuâbä~£‡b )ã¶ö"Ÿ™?„^Ë Õ¤šôU]ŒÜ'q /Z3 IÔ‰8ñE‚LšÒøâ ”sVŸuD‰dô@'im¼°bù«>/‘ÛŠæXã$_@a¤¯h¤X Ï v¸g)ÊÃê:èLÚ F2|ÒÎÔˆO½eЬBë{S”{ש¦¯ï¥†$ý1ö•èYcœ|ï …µQrN¬0KsŽÂ¯¬™1[5DÒ9S9fö ×I;PM:IÈ1è/£Nxr)Õ1í?ެ>$&3wæqÀåxÂñûwß1^Þ¤hz)­ËA_`ßÁõ;´ým·…×,ŠXì'ÒºLKâÖ×ñtb)rm’XÐ$>“ô“L"]ˆÏ”´.yAÊ,©ŠÆ¥öo¸2³…`í,­i_¼+“(Ôš(VMX~ooY‹·)>!#3nÞvOÏøhLJððlwÀó§èZ`R0˜ýl²@Ët9êóYf€©…•ÂNÕÕ‚i­!eƒÛk…ß-1j]^„d Lq}&ú¿ì¹ DLƒ ±¥¯íE6»Å;í_\=•ó¬%İíZlÛ› ÎÓÓˆ·ñ‚ã|Ä%,h]‹Þ{lyÁ¼q}¹`|ûáëíý3ºÇOØÜïÐv½$Í¥‚ZÀ{PÛÉ¿¢¦±2³Db«DÜiB"KÊ >™ß¡õ$çMÒäkÊtIApxÕê‹fHÝШP!`= ˆ{ÄØðˆÀ½æô‡¬ùCÀW$8kŸ¸ÞÃA³ ¢…ò¬_Äë7_ ŽÑJ!ðÅqk“Î)5’ !„‘±:5«4x¿<·"Gðöq/2&ˆÔ ƒo4‚ÞµÑÚùŠ@@§ÏŒÊ”z-c¬`;¾àfƒÄ M!Êù½ÄA"ÙÙMо¶X€¯`ï$(x·ú<^,@Ó©¥FÞËq´²ŒjøîuÞæ<Þ9ZF•Ì5ÿ¦ià½ddÜ|N&~^$…ïtxÃñë7œN߱̈q{5[ ¾ ˜Ã Õ Û¾Û£é7hš>æâkmЍåÖtªæµœssV­8c­••÷´—ÒX%[)™Öo©hÔmË,Ù×û½*" WvÙúMïvd=mõ|ÚÓÀ ×`óðø¶}x”ŠšèøXÀNj-Óãã uørÉ P,Ø•™&™ì=¨ÎK/m´¼›‹¥µ–×qöܦ¹0².þKÏÜzGÝó̸óxó=Öò‘ß‘[J¢H¡‡¬Ã ^OP¡$°Ã~ƒû®Ç—ÍÇq‡—áŒÃ<âŒ#&LÔ¡o&,Ï/¸_púú;\î>¡}zÄæþÝVÐÈ„áIθk;øÝaš°Ìsêߊù3kPè¤L1j†Í‹¼šý•)P«LØÎç">ÿ Eæ0j^D£cÕüÁN#Ó5P5{® Ä4ƽFI³Áܤʀċ0`ÅB¥`ðÂp™TxѾr0ß’‘ã¤þÁ$KmúÊ,bÙf FÔè}@˜?Ôm}¯äÊ!B#KŠ%ϳ>@Ákß(Ճ˙ A“&ÓujöŸYA}âQª9Esä9¿72ruoÇ=.>ŠY „$Vˆ˜â9¤6dž®²‚âøÔçO1]Tjg"ªùÄ“€¹{U‰5n%1¼»œwèúí¦0 )Ð/0æQªð_~àøãg ç#B˜á\#r:3ž˜%N¦ÿ$˜ü]‡Æ+.?BBä\3ÕŠ tQöBaáŒV7«(ëµ™[¸L›E°Ý-ë9ò#„?LÇnÿ–ûP#Ž·%BÅeƒ7úU»Ø– 0‹î7¿y¥¶c^–´ò¬o}P•]Àkfÿ¦wž±ìò=Öë=ëeœßáÌù>®Zº½IÊ¿¹Ø@XÈ«;ßÛŒyNn›æì‘„ˆÛ¦Á¦½Çãæ—iÄÛxÂëxÁ ®˜± o:l0†+Æ—¿ÄðòW¸nïÑ<|Ææé ›ýš®3ïà·;„)`™gð8™Àš¬00®¢¦HMõc®a4Z).p9Õ΄ ÓÍ¡‘„”0ý7ÿ ÆéèîÏË_ÿå>- Šà¢Âæ’Æ+ö×øïmv^¶T²äZÀ¤_ø­>ì}Ï,FÕ5ûvÅÙK=¯u°Ï­,Úòþdèwþ¬ nYFì¬/æ™ÑyBç;Ü÷¾Ì÷8Œ#^‡ Þæ+.P Ó%Ó¹bÔ;ñùKðž'"2aI sNüÝ*ïÆ×‚H‚™.[ºX ¤î¼Óß[pÒ¬[a¡.¨†íM ¦p ySÈ… bß§1D¼K±p² ¸â7\bÑ£à˜W‡ÜåžxMž…Q–E ’ºšìƒäôÃIw°H¾>Ǻ³ÖAPÝY1öIƒæ&Èü{Mw\ƒuY0$£…w¦gÑL?#Ûï N#û3°“Öõ.ÊŠ-:G ÈD±Ì¯Ì3¹L1óg9‡Ív‹Ýã#ÚÍ`žf Ç#/?p|}Áp> Œ\{€Äw?s»Øth6Ohº-ÚF±Õ½TTÄLûÙîY‹Ùo3‚é^‰¸)ÂXÔâxlþ"¢#V6[x$ Zhéá;–ó_ºVÆáÇÞ™y‡¥ÅV²`ð#ÊÒG Wʨ…ÓnõóŸxO)bð]ËÝþáÕw[4ýŸ€€þhÇðŸþC€ÿüùêOxÍ£ÙÊev A£b#X[‹ò™e}·Xz½ ªx¦6·—˨„ZûÚQüš ûä'#ÙG³wÜ"Žòlžj4UZß~Ðífj* :7ž!ÔJr°#•æAÄ*Œ1V€$V iñ´Ùà<ÍxÏx®8Mg Dh4hp aÆðòÆ·o6[4Z¢øîíó'¸~úþãá h†€ `R†F S€/¾wnUh€W¿8ÄÌ/qrά 5ùU£õÀK²-ÊôÔ‡L¤>üMŽ5À ;H꘻«`Ä@; âçÇ I`€ys¦ lL-Ϋ™%¨€Ó˜E1¬x*ìȪÐ`<,:71ÍM "żv±4,ˆø3@@Œ5àE@|Ð&÷Ó4^Íï$æù ôj%™/(‹HLb|«™`P!ôÚÆ4 ý÷ì³Ð&KyÔx…øýF]£½žÏò\Š‹€¼'e^è{¡š² ö+¤9“¢WÎh ’÷Ï€žM·ÁÝó3öŸѸãumÿõ+N¯_1 £hú®ß5Ò@à0‰-Æoáº;ô}¶W ©h²4…L º‘)ZbfÁ·,m1{œmKU+F]é¥åýé]·4+#TGMkÉâîç̅ܯ[š¿(ʼ »@l #Qêù/ö±¦Ç%%4ß"ôw÷çò_þ§òþoà%àïþÏÿgø(LJºóßøçOG×õ'Z–Êwá2ãש£ß9Ékfo{ß¿v ܲºtí·ºÝn}i‡ó¢3Òxò8Z_²Ô»r p†âµ£y™³é#•}æ¸a̼¦>é{¯€_ÖûsAаÞáÉ÷xè;|™f¼¼Žæ—0bäwØ4Œy™q=¿`¸¼áøý'œvw蟅íÓ3¶¿ý;h޾Ãx©L@è\AaÐi».Ð(6±óEÜé‹MhˆXáPâV à0iš™æô¥_³~SFÁhÁ*ܤsÕòÓzb±À’ÂAæ*e4hÊ]ÄGPŸ.ઘûFŒæd~oÓ3bQ7‚¾Ç²»höÏïEªÊ}þ‘¹G]r@tyÄ6¤žC§÷MyMÔsÄ4PW ´m‡ýã3>}BÓµ¸žOøöíÇ×︞¿c™&À®iá¨cÏRð‰'Uøº=Ú~ßzÙ+A«ð9Ko,ý1x`ír™Á9²‚X™¹ u/F –NuC¬K¿$=ù™„ ˜û[|û5‰d™±”ôª´ÓF™#»,ìû ýJÌß´ÂÚe(#+ÞèHÕ4efº¿VSo7ÛÓ4 —Ëï)Sä£Jh>¸/¿:Óv{âä“HA+¶`ƒüø¾_=·€(Jï²Õüo1Üõ3eD}~¯1PeÔ­ê™ôNŽ\#¸æŸúU4“ßk¥W¶È^•ÂÆ#D¡ÂÝD!KžŒíŒ*tó&ØdCh$ °ïlÛ|ÚÞá4^ñ:œñ:M8ñŒ!\1“GÛzlLó Ã#†×Ÿ$Vàéר~úŒÍßù»è. /?0½½a™Íkl¤b Wsµ2e5¨5@Ì£DˆÑþ,Æ™ùGˆ=µ×@Aæïõ¾“®Å„„+˜GHÐaâÏmÚ‹Y™¥vAv\å[±WB&¦bÉfPæ3¢ fÃä8HÖMYüHþ^Ä´ŸcÌAD˜ ƒ_‰$柵kV¡!Æ„$0ĻȄ£ãjRfŸÑÂ>iE0®¥àŠQ8âÄü§ôNÒ¦¬æ1í\éßRíñˆ !ß:ÆqÈ1Ôk6Ž~eüwOO¸{|‚kz\Î'¼ýóÿ§—ßcœf0/ðŽáÚ(Ì9„0`&É*ðýÚýMÓÁ;¯ß2Ç2¼§™¦}iiCâØ”hI0;ÑÖBq[gwáÞ¿­å ¶”n}£ê›ýcýÝj?ö™.–ˆêwVêçÙ°¾}KŸIÖªŸ·]5ïÈO |×?ÿý¿º>>â£JpŸ¿È¿ùM »»SŠ€Në:û‡„ÁŸXî-®£¸þ‡ú—|¦ŽÄÏrïßäùR'ÕØrk€£ZC·³ûÔgi7j$LH)xe‰á5Á(Œsœ…®|·‘¼M?X\¨©¢ç ýv‡Ç~‹Ë<á0F\.&^0»O˜Â‚áòŠëù‡Ÿÿ§ÇÏØ<F÷å7蟞1¾¾`x{År¹j.}ÄÍW¦kPƒâC)½m’œï¨M#Þ¡ilA¹&ß;©–Îò.ŠÕ/ r¤éenRÆÝ#Z%O, 2o#¢O]>º²$J…" ѤL:káY˜°0rYA €^™pôýç¼xJ%’£Å#jôNµ|2ÿ•¸òÂ<'íUdÔCZÍ"LˆÂInc¶+VˆÖ ËEZ (¯Ñ(¸¼6±¨P3ißfÄ4>Jó è  gQNª:Ù ›í÷ÏÏØÝßp8½ðúýŸâüã;–eL€=)Ž„‘/—l·hº½øöÛFâ< Ð’‰«à³òü}JQúüCÕ*®|k/—¯HtÃ0ÃLFªø CFkšô^××VÔ[c*éÓmØöÊæï@´Óq^4-ñŽ<ÅoóFDg0·º&HJâ2èáœf,h|‚äñkMÒ,jAAK“º1±lP£ÛBÊñæ´·4W¯½©ë ±È$£`ƒì FtsPŠ=0”Ó&|…Ü1ˆqWžqê.áĤ{äT?Ö{b?bÌ@è Á}ñ< CÙìïPÄE/3\»Ãöá OÏØÜí1‡?¾þŒÃ¯Îo`^ààà»^cë&ëa\Úôh»šn‡¦q@*2•ù0E¾M–ÅÜ ÙÍä†fe{b*‚®ÕöxÃÈ9“Š|Td S«H˜g̽ƒ§V±Þ¯²ï©Íî¦ûƵ[øô«1ÝoÝhEzê¿oŒÞö=¹`!JS»ÝöŸž™8à£KØïÓŸîáñ‡á0nÊ…Œ1ñŽz•ÆÔâ[¯Ü”5¶v6*ýeÕKr ÑÛU­.}Y”<Á>[.U.Úá[#ÒK1Xï&f'eØ=ÅW$mž©qu œŽû#Jã•Üx-´²i ›f‹§Í_¦ o£¤¦#ÎÌGGÛÀ9`<}ÃpúŠCsÿôÝã36wàóãËï1àqù ïn´Ú øÕ4Š´(;¤2ÂÈ€=2AÓð4g €“ú#ó„Qã ¯`¾؉õ'µRµ ¾è·H˜Xcˆ3xPÐèRæÏRÈžó$Ç`7bði­Ú€?ù^‘e¸Ük}ñ™¡B™2kÄ}v;’MQôâ3Q+RûÑ–µhì{ ókDˆû!‹à1~Áåo£ïÍš{Fø³Ï¸¢˜ù¡ b0{^âÎ7¸{ú-v×c¸^ðûþÏpzù†™'±\9Gù°,WÙÓ;ۡí6hÚΑ€…«¶Œ¨°¢Ù¿ëÀáL2s|Ç~#â+ž›ÈfE?¬œM³\½7uÙì{ÓdAbØ´¿¦BµzR©uçL`Œw(Lø7š¨^õ7µºÿ®»å*+YÊ—ä€:+…ÆŽœ‚“6q–ØW²µ?§Fk‰:?Yþò^[±,p6ÝgÍÁ¤ ivQÊ &ˆ}Q †`ÝÚ¤•pç±!àaÓk*á§á/Ó¯ó„ótÄ•Zçл;ž0NG\ÄõÛïAwwh?£ù³€v0½}ÇtøŠ0 ·€h#fò  ŒB78( ÈÍŠÙÞDÇ$Äô¬Å@uN<2ó!õ¤Ì_}þ¤þn>h4[ … 8QL)$¾ óg6‚‰”NÕY˜edÊ"à†,®.K*Xê|qNý[ôÎì:È´ ŸLÊl)Õ! Õðí® ÈzYÌDÀGN†ñ}!}xYÎ<ß;›¾)Œ3Há“í2Šq „o‹ Q¾7‹¦òŒ#1û/£´Ùlîq÷ð€íÓxßár>àë?ýg8_~ð!yø¾UtÈæ+– PÐÔ=¢é·h»Zo¤Þ¸¶í’7Œö]‘Ѧm«Àp{ÍÂQpïüR¶M¬Þº"/«8ÂÒ ñ7kÃ^½Å›KNïˆÿä"JylµB†wÆ»zijô©Gbˆ Yœ¡Ýí_šM¦ÿX¥€&ÌÿôŸÈÞÃðF›]þ1¯Ü2ß”‘ì\ùÁå:1WK´6b•çïÆ­ªbÝjañúš lÉ¥BoÚ4·Z' öů\œ, q4Lå»c-ðb³R9òXùŒx½48ª7å{R< 3$ÌõXØdÓ8ôÍa‡añ2ìðc¼à8Ï¸àŒ‰Ú¶ÇÀF ¯_1¾}Űy€üŒöù3¶Ÿ1_±¾a™N²™”9†TŠU¦nÉ̸E5ÿX 0€é$Uä(–ðŒ¼ÓA]ž@Ôé¬O`Á4(C<§Ø(ˆO_ÏÔ% ˜ÌµR8ö`R³8ç¾Êgž¥Ûj†·G4™G† óo 3U¨ã”( ÕiBFŒØ¸Ö²Íë¤ý± cLL:¿7¾3æäç÷Ê›P2pè%~]TEVï1 ù½¬íaHýn{Ý㯰¹#àøòÇ—ŒóX„äÐ6.ÈËH`TÛߢé7hÛZ÷$`“Œ{ì=ksR uצïaÅ eOšV´š7eÖ=âfCi=0Ú»µXk€’â™, ß>nP¹âJì“€ê:)y¼Æ"Z†ÖÞ…j¼E§V÷þ¡Þß²+›KÌØ<>þ¸ÿõ¯WÁÜáøPÀõÿô¸ûàðöæîå‡$[ß–U)¥-Œ”'˪aEf\ä•"2ªÛÌŸò¥rS$Û›Ù5©nf– cÄ|ê”6–¶5›ûõÛ.:[±±ù¢ñ¦Í@«½‹…$>P¸G4­.b𭌢r/-Цç©&y2d«G²M°ZàíÆbiÅÁvÓcÛuø<ï`hÜàužpZ&L< !Bßõ˜8`ß0þÝ÷höhîÑ G„ÖËxÀÎ+‚›2"pá|c1 Ñâb>þVsùÅ„/>¾£8öÉ 0A`hwªy²2ÿNÌûè Ö¨‡àúGív£ FÐ~h™dÄ‹®HiP.x¸„Äž ëŽÎ=e¦¤ÀL|£„-Æ DCzöù ä° l”`Ëû9]B‡Ì¬mz`|¦lÚFé¢ðiÿqÂ3hR?„-È31ÕQΗ4^ƒ&rxl{|B»»Ç8žñòõ¯p:½b8|Û‚šà€FÖ‚Pm‡fw‡¶Ý¡iµ€¡Å²E,n¬œd£•8 ƹºJksA~Ä¥ÇgÙ¥=“I€¡•ôaÉGÁ¾ìÄ«ûj×]mî¯_¯d¡M÷}ÁÊs£²å„$tÁ[ê{5^ oœi¨¥›õn0ÿ¢kr&ø¾‡åíë?þ§8}ÿø»çïâ£Jèþõà0¯ÉÍ%xNXS3ÌæÒ³ô1›G¡!-j6z|bÔ%#§D„(¹D+Œ´ñlG\– ¬ÿ+—4.Üéïb4P‡Eø+y)ÿ”VB£¹ga¡Ò 캯ÌhÙºïI f.kå%}<Á¦w©ÎaÖàÄ )X.¥Ú5ÏÈqšf ó^´ T— ~õ*Lò‰1ˆ«Çƒ0뜢ýå½²®¢« "rj¿xÀ¢%Š»í#¶OŸÐl¶X–€óÛ+.—˜† ˆ¾%0íÀ–<ܶ ¶×bÃ=ÿ´3øtÂrþ†e– APЂÀ+>jà ȃ ÌZ 0¦òñ €—šX4€U`pë%¡‡ò;GQH² ĵÀŸ`2˜¤ q“?f¬tH 7eä,Œ;#N8M·TŒxùë¸X òó,v@FŒ†Ý)Ýw%Ÿ¿÷‰f~ˆ’¾~\Œ11Š“¦ÿiÿXŠ-…0Ã5 v÷Oèï>Áu=¦áŒ×ßý \®)äÒ:¸F³‚“ >’XßoÑÝÝ£íz8ïÕìnÒøâšälE+ä{|Îü\®øjç×>~ù%5xXÒ;8ÃsÛ>ÔÚÝþw{uTB«ÞT£}¨hM‰VUm‘9+X! àƒ ˆHKOOÀóó+µ-0(œªÚΜªªœ8ZVs³ Œ²d ÜX5•Í€€"XbÀ Íl¿%+FBLUÚ:™…¦¶xÇUp!)¢¡‰iHfYcβæ­[Gz}9Ì´ûl°ž‹Äd½;ó4½÷ó·ý#¿ßê ÖÀ\M7J¢–Bò‘*a0~ †d+Äwt­Ã§vƒÇMašpïð2žð:^q 3&f¿Aï™G §7 Ç–îËÝ=üÝšûGøëQ\×WŸ¶S&Lгö·SMŸ!ð·7 # €ùýŸ|þ-8F¾óˆh=V$wC„†ª”æb~X+:uèü2Kaf§– Ðdz 1êî`1Ç‹MËЋ‚XÓ˜[­Š¨ÖjÅú fjù$¬ ;<"€Ca°¡>iÍ1³"¿×ÃÑ"}GÐ9’2¾R’ÁË" íï°Ù? Ù>"0a¸üÀùÛ_a®ps:À·Ä/XÀ í~»AÛíѶ¦¸*³Ý°®?]«+K@,"eEñÛ”7®FeNsFHqELQîƒì õÞQ+µÆhÇÉ¿ðLZSÕÏ5o¾I¢SüVV<2“k'ºøÅc…y?¹Mj%«ìÅzšjg†MÅÌD—™AMƒíÓÓëþù Þ{|´ãc wô縧§·íÞRY"yű—ê…VCß"sA{‰*¶fIhgʤ-“¥d  |-õ3²³(ägŸŠ± €aþÅ«Kù:ÃDî•Ú‰ J*þÖg VoøHÌ‹Cç½xÄ^SK‡•R`‰L æõ>JãÑ¢&µ©QßPÊ’ªAšÍ<@R }×a×uø´lpš&ü®x—®˜™Ðú ¶Ž0- ß}‡e{Ú=ÀúWÐN3Âõ|=gEüóŠÀ‹üQÔ<€#˜E“öR´§G¾`GÇ'˜Ó";'eþbÞF‹\ 8âé¬5"'n€@ü§dâ/“¸a¶¢‰KqDq¤ÊÎeæÀNŠ*A‹±×lFÜ Ñ¿¯Ï$ó’SÁ{­¾ÜhìAnCÒ¥Nƒs.Ó}ƒŒ(ª^ûÞ‚ç+–ÀpMþáWØì@ÍÓ4âõí+®§ó r¾é@­Z aáì<¨Ù£¹ß m·h¼hrH[©Üke”¾3ðã"©Y؆}€«=P“–ayMò·•›/Z‹­U›ýAí§?pÁŠçµN¼†n¼t]F׺o…ðÕ&Xí&æûKã³ÌÞêx¿8%•[¶¤ÂYqŒ–8'ak6Ø<<¼nîï«@ñq|,`»MÒoÿÎ+úÍÈóÜE%µdþÖUÙ«M4|¼?8—››¼âRu-ƒQ5ôÔ¯d]°×nHµæ½Æfªû[™ËèUíG•êEÞ"!é3JÅ»-¯¯Å¾×S[˜`$ð[ ÜH«±mF!*í@EXK”1šDsRXÎ‹Ž >êÅÐ>u ¡ó=îû×y‡·aÄËpÂÛtÁ™ Z è›#Óùãñ;¦n Ú?Áß}‚¿{.G„ëË8Â(©z´E¨\¾è ²ÍÎZ)ÁÍ_&D`>‚¤œž>sLˆã/>àV¢¨™¶ÈÁ¨¦X˜2CƒdIÏ)™‚¢fAŒÂ¬Ëˆ¥èÏj~ßa–œR*5–¼{ÈÁñœMÒNÓúbæAª(… Ý“é½pMª¢µK (i¹^Ö¸ ^àÛ=öwÏhv÷`.—#Î_‡ižà¼ƒkz¤:=W<Ô€IDAT ØÃ~ßmÑm6ð~¯ˆVÄѲS­O2Óf”R»€-[‹[©ˆ-ï0ÆoVaÖ¿Õœö2ö€‹{êíÉ5Y©Y÷-ñ»Õ~.qÜ¢YņF^Á\5²RŠ9-”$Øñsu~ƒ¼Vä&?–zßZjEž\ý4ž¥ñÏ®ëÑßß¿¶Û–yÆG;>”0ÿó®1¶»#þ”®CâÌ+`$t»¨ œp¾¿pÅÈoIx•Ñ€ŒŸêViñ¥’ªYº‚‘½ö©?Ê@³Vlš"cúâR(Ìçó/ºGfóݸç}i›óe³I ›þXYG±&ït f‚ìØ ¢DiŽŠ1rå …ÜÏO„}ß`Û¶ø´Ùá8 x¼Œgü#t l¨Ã4_pýqÁtøsÿÚ?£ÙߣðéárD˜¯¢é: jœ…ñjÀŸÀ _ð‡pR¾ÂêòQû¯mðˆT9/å`šò¼ÄOÁk!#(Ó…hêä”ÑÇ´BYpRÂ8y‰`€HÓÝB ¼‹¹ÙŒ–]_@Ò$)T¸ñ½”ÀjMá"©fHÒ{s¼BHú–È3xbžA®Ãæþ ýnêï1/ǯ8ÿøe™áàÚN…#óf‡j÷ð ÏÛ6^-GKVEfI+Ó¨¾YÁ·Ö»|K ðË,ÅÞµÞPke%Ö7°K~ÝŠ5ÍE!¢Ðk¾«¯²ê# ŽÕ¶]íåúÊ­‘rEZÞk¡²®š]ÓùÕyE¯¬ÌP«"±/üKç|;ª!„ßwÃÝç/âhþäø£—ÿÍÿ:ýí?}¾º»ýi*êÜëïe N >HÉoq©ÆHv6Wí±.ìØE\nq*úS²u"ªæ7p®]`•Òèwo4Ò¥ŽWÆ7“"o1š¿u!–ùÊ•Œd‡KvnóæbÂE QyoÂòÜ–3³"|¥Z e’³Cª‡}CþÒ¸£ Oží[ k6¸ßtø2íð6\ð:\ð68ÆD„Öõè|ÀŒçïϯbØ=ÂÝ?£yü\XŽß†«hÌ~V€©S-~TÁ´ƒl¿h×@‚„‹Ntôñ_õ¼Uà¢f‰êgýŒ Ž=9õ;Ç*†ê Ñ&¥ÐÑæ¬õ„Ùg¤= +êk§¨³ô—5ÊŸÐIöBŠúo q11k@Þ îÀ,à>)Ð0æòÓ,s|üšÈ„°È4]îî Úý=à®×3ÎßþãñM’ †oD3Ø9¸vnó A}ž—c*¢Ý9ú·ßÑ…UíRñÏjõ:D$¿šé›w˜=„j!¼QBOïL-·™¿ÍÓþ¯ðªß7„ü•ñæÖúº¯6¸×³—¾D²Ìâö›âÄÕx'¸ùÒwûTÏE©–P¹&Ì=ÌMߟNo/ÇLIüÿàà£JèþüÏÓßþ˗˰ݱ,ÈÑpl9MfÙVÔMÿV¬’‘5G.ï±é„ež¿i³ …§ºÔ®ÁõÿXBr£¯eæ,§Üñ´@ C†}me6,j{¯Þ‹‚PÔ,:µÖÈcº‘ *u¼ÂªR ²o4ÉaÖj‘;’RÂ8VçSMŸ¹zOî[/3—‹u1am¾%FK„nÓbßwø4íq¼Ž^Ç ŽËWžÑº½w˜yÁ41ü¸b:v6øÝÜ—í2Ï,ç¯â{¦äÂ숚ô]E—b@Rìæ„ÀÎQ öÊì'Ñü4®’Rë8Ðbô¿–&Á¡‡kò@ ‰Ó¿“ôA€SŸkYa ÒÀÂXåœjñNß+m0b%DÉóŸÕò€œÔ.d{mCÿ@€ëÕR²Ü‚È€Žºû'löŸáº¦eÄáø—ó+æia†k<iA!ž°„Y‚Û¾Û£é:4¾9MíM¥Ä3aL5»Ãt® Nëõ]2{Ë6 ‘6m#+¦ÆC…ŸB ærŸT½aCó`ÞónmBÁ‚ë@¹|ÝŠ#ÖJY÷Àª·m¶7æ I)Iã«™b¶k),ŽßŽ£PŠÞ3d–ôͲú¤VX1­ù½ÛïÿÝ?úG—ëËkêïÿèßû÷ðQŽ%¸ßü&ýíó›‰vû/K楌ÔF®V;ø†¼jÍþ+ûQÅèx£`þzÍ‚¬±ã¾÷¶Q¬ÜÒëfá–¯Òþk™= _”ÈåÓ\& C¼h™l7ßSZ>Öÿ¢ýêºêŒb}Õˆ)F—3 ó¤·Q5þ’èQ¨RÞ4 tî¶uØ´;˜àŸóÉó'ÐýýAN^:‰DœzØ*gÉ·Îy±­YoÍpoq¬׸X²zW•&c™ýmž‰ÒFÇ(Wü/ fŸTš?`4ã_Ø,ùg®” 36*µ|Ùäå®, …Æ€W ±5˜m5;Ûy+bرŹªÇ[ZÓ»œé{¾fFìÖI‰b¾ÙâqÓã:ÝKÁxÄa"\XJÝt˜ÑJ ‚ã §Ú èî3üþš‡ß OX/˜®ð4œÀ“ëô…@‹ ïËj%ˆš0 ó‹‚0^Á¦ ƒÿĸ€@‡ a«xˆšp ™lT³A‚b"&©¶—£££PàL» RÔÌÌ ôÙÏx”{rh7[Ü=|F»½Cð †ËoõÏq½¾€¡bNÉÕ‚Àjà7;4›;´ÝMÓ¨¥„.Z‰©rV„Ýq?ÜÒŒ£Œ`$ú¬Mrd‰¥üŽ™*½ ­n½ƒ±zä–-Ê--.+ÊÁIÖ½I‡êK7¨Ž¹ó6ËÌŸW-qõüí£ 4oºiF\w–«1ÖÔô§nT ÌèvÛãöó3BøxÀp·Ï;Ý?¼snS ;+)±Y<ªõ%é­»„8™ø‹õh)H*ë!µÃÈÌΊ+%â±EË­E¤¾éka"3¿Gù&3HmÀœÇ÷¬ŠâÆyaW,Íþš¤¦ã5Aމòd ÞÎ+qþ™ž9C  C&b¥2xÑ GšJÄ“õ+cO€¤*ié¯wi-‘o.°Ã=îúŸ–ŽÃ€×á,CË€„Ž6ÞcZÆyÂøãw^¾bÚÝ£½Fó뿇-/§7L‡,Ã<  8±n¨~ô&ì$Ì?Ö,ˆZ])hlA+õ@HÕpšÃOp Ö2µÀ©;m‚±N®˜×e¯uê`Ä8™éŸ ¥Æ 0Äý±L¼H fÛaw÷ ý]Ôö'¼~àøö‚y< Ãv-\ËìÅ‹À£¤ð5-\·E×Þ£é:x]KÒ§¼nÉÄËÀÐ2÷$¿¿5Ä™=¯Ì‚2+Å{«ñßÊu×=`òõÓŠL{$Æd)=Ñ»µQh‰²éŽZ¯››{å8‹ê|f¬%YxG)©zk!ÚWÄ—ì<®0L  SJúžöÛUã²ÖµœciYm¯Ñol-„Èë„Áhö»Ãæþ³~´ãc ›²Þ²»ÛÿˆXúÉU¯ô¸n3,7RŒ\·’ûšù}Ñ„ÆZLþ$ 6¾Ä˜³l\ 1r¶Ô‡¢ökÌ–Žbï|='ëÄzc]«™?ÌÍÝ)-((Sz³_}0º±ãÖRHÌÚÈLýÊZ\tn3Ñ"R¿,9.A†cë5L‹%@ÁÜ)-Õ¦uØ4[éò²Ì_Û(ñL_ŒÞ`­{\UÉ ™Ó"/µ“úBžÁÉ»ã¦É“‹GL_ª†‹ü{ûª4CÅ&;–÷Äu3€º@ž6Ê42J•FUxÞz'Xá°êE.È"s”×PÔ¹­:Ÿ#`:¼a>CXœAMŠõ‰–'>C‡Ú¹Ÿ|ú<‰‹g±û¦¢=ѯõëىϜ€ìóÏ…}ÀÙŸO¼º ³¦² ԀŒ‚õAÓ÷>ýÛç_‰¶?Žxyù ǯ_1N#¨•ïáÚ\[ „3¸þív‡¦máã;5sÁ®šiî]½”Œði÷€Õ˜+:ÑâbZfVºÁ²gœÌµ¼ÄKlV¢rÃÀTÊñ¡€ùÿãô7ÝíAóüæv;ðpM$›£rC¨|þyMd&–ãÖ®YÎdRÅ1=%FvkÓÔæ@» ÿ\«å~Dâ"‹:›ÉsIâX' #%’kÀî Ó¹RÃ1àêhÖz“šÀÅÖXiÈZ¶ªìWîSÑe¹m0~¯B©˜ÿ-F_ù roi5 I äü­ ½Ns€#1)•É_¬1$ž¾!tM‡û¾Ã—e7u¼ gœBÀ„³:j±a^.¸|ýg¸|oqÙ?¡}|ÂæÓop÷å7§7Œ¯ß0Nórä 8É•ù¤£‚@Ü*Dq«°¹O! )¿<àbì ’OϤ<[rZ$ǹ–!0˜ü曇'ìž~ ×m0 W|ûñ3Žoß1žß\Kð}«pÍŒ€ ص@»AÓïÐv;8/Ú¾eÎ~[É+Ì]WkA3 ‘ IºNõ£¼Äyµ®Ìê¦ÒÂi Ù÷æ—‚¬U½ &sZxŒ#ÜÁ¥FEiA\ @ñÜZVûf}X•¤fß™"qqþŽ˜s>²b(kAŸ*Âdhe)T‰Š‰vVd‚Ö=)Çûbb™­†Û§~þùð_ý/ÿW˜‡!=ýïþ às´ÿæ¿‘þ¦ý–¿üË×,²#ÆðUŒØn6­œ|³F3¼½sÒmyC¦f*‘NK¹2KÄöÅ•Š8ÕóÉìë—c»ó‹nлãKÞÕÁ«›#¡+®T÷ämO7š±÷ÛñÇó\’)¯Ê“°ÚÁñ÷[QΑ¨ÜÝXdˆ‚0ºÔCÎmÆ#W÷FÄØ¬ÆڦŮkñi»Åi¼Ça¸âe<á0]q¥€‰ Ç]¸†V{+ +ÆvS/ãO¢ÒP-‹ý›;rK .ÈQ½áo\»Ý÷’‘×£©¯Ä=ssÂŒ¦‘¨bMoo}Õ”ªYܸë5P ?ï?lÆGU£É@Ø<>¶Ÿ>a¾^ñ%Ÿ¿]/oð^‚–Öë@¹)ó*ÝcVû_ñå,n¦t³z! |½ LF¼ôùÐf ßgSµ4Ëþaš•ûTXwÊ ±°:`EÛtÙúQ 9þ¨"]•ÏÞ¾š!QJ½Î*h–o4ßšiçŠÛ'ÍÛo¸èÅ ?lêWyÝ)ÿK|÷¿=ÇÇŸòß÷÷p§Óu-xY“-—%[ õf…¾Úp£O½dW4æ %†jLW5¸`¬ée&ö€ÛÕ‚NþN½Ì åà3ÓºÁüQ¿7IÓ%«,ÿmÛFžƒÒlXjÔœZÉ ƒ#HÞ­-ÖÂf|&ŠùRõQ›ý«ÑDløâ»púVEKïXj]NÃñ ÷‘‚Eû®Ã¶kñi·Åiñ2ìñv½à>`b‡¶é°0-3†Ãw\Þ¾ãÒÝ¡yø„í§OèÿÎßÅöÏ~‹ùø†ëËwL‡Ât+ä¼/ÿ6P °Æ ƒ¸•JxĈpüLˆUدƒïïÐ?|ÆöéÚýaYpx{ÅáÛO8½½b¡·HKú2„XœÚ-|»AÛõhÛ ˜CòíãÆ¼Úêqî-™NgÜ+Fr{ÄGnl£b$ׯšýS”½Ä3뾡vÚm•N"»¡‚ù§1+ó/÷Q¹­9oNí{ÍdK¡¦žØZ¹]÷¼|çmæÏÕ3ùïõèó$—´“ã"ÈÜóÞ{J¥ÁHÿï(3+Á¦¶Üóêfûâ%Þcûôüºþ„±+3Ô>Êñ¡wŸþ¦û{àéù•úMà°8f‹òÅ…,•ìU[mv_“É_ê"5ÛZ3]{¯5•Ý&ö^»)2¤€±2$NgäêB*΂@0h 'Nª¦c¿ íX™ü*flt—›ßªÎ½Ï’xd‹ñ¨àF¤9Û\l@K@É}µúFë—KÍxº‘†„’è%ÑÅD\—5V2¥È°ÁyŽ Bb”NJŸPÞ î2kLâH½wè÷[qØl.´Ý-,§¥ Q‚—µT³ÝÀìÏÏ7έñªxFo¨7J¾–mn«{ôz¦öeÇyûОÄñ›k¿SŒæó/ïºñ2kKÔk¹ëyä)Ž ‚–Ñ&ª¼+WDa¦0xÔ»¾þžösÇ©»¾R"8šy¨‚Šn…Õ¼Ô×jÁ³¢`Ç[ødüs¸Û4Øo:|·8ŽwxÎxgœ–3®Ñ£s;8LËŒËá®§#®?·hî?cûü»û;ìî ,Ë<‹Ùíᜇo<\#¥…çqÆëË ß¾âøã¦y5€sß´ˆáwÌ,XÐÂu{4»ãñ^qÿC©±Ñz~le¸¸›]"¸Ñ/®³ŽoiþéÎ!+ПøHi¼«öW?ÜÞµÈÅ_¥^ Û¶®Ei¶dŸ0Y›¨ÚHt/‘ ãöÈKiÝÌßh× >å_”ÞWÒ¼?$W¬c2×®émùXüXJS¢°žöó qÜX>Škø¥ýZ§xƒŒ4Ì |×þì·oÛû{ŒçÓñßÊãC Ãý_çf¸_ÿf¢Ýî (q1ê'Œéäóïs¯ƒûÖÇZ³¯dWíVöÜ¥{+éBëOÊ-•×J×õ$›v+ÎŒŠ?ÊûþÐý-çÖeÉÙÞW’…$ !ÆEP¦xO¡澯jüR‹a±+Y!ô›Ÿ¤Ý¥÷mŠÊÏRNO‰„nÙ|=@NV(W"—=¥Üe†Û®Å¦kð¼Ûà×Ó„·ë?†〠O`ö-:ì°`\®G¾ÿÇ»O蟱½¿GßoÐlšÄ3Ñ&„p9]qx}Ãáõ÷^X殚ÎAÒ ÆŒ°p·u;ôý^µ}ñæ(`GÆjnjm¹œc•B¶ìYu¸Ôüó?&, ¿Zn]õWYqÙ®,Oö³ʯ¾¶ÿ­íu/TOQÂǰ·ðúñ"‚±l&ͽ‘1op÷wJ~ZõúÖkóõ÷­#uöÙ—ÙVßÃ.6›“Ë—®„½÷f»<ÖJ]¢z¦ ~ÓÿùÿëÿyæiƲd À¿ú?ùŸþáÉü[r|( ÿ·ÿ‡Å¹ûÍo°ü—ÿ÷7^fÕb„P†ôÑí—ÏùÙd4Ò¨)§¥Y Êaci@¹ó‹õÊ)}G¯ 4£ÜÔƒ‡!>¶ R‰¶Z¾7”q%6B- Ð ™TDû¿§÷Š’wWŒâè}Y{Îã«§Ö©h^¾GËoDŠ\iݬ5Érn÷—*W iZ¢¸IÞ ¦l/ÈþÓR¼aó¸ñl [•>iæ+ußÄg¤‚6 @å¼Cë7¸ï{|™÷8 W¼^¯xœ–#]1…“ï±0ò„ËËïp}{Á¥ïÑÜ?aóøˆív‡Ö;óp=p|{Åùø‚ázxó š®×yš8`av-¨ëáÛ­¤ðy‡°fJQûŽŸÒP÷2­MRì2Œe¢%‹òvŒñ Õ(ÞQ3ñÈüªu„h°meÛ垨¿>V;z]e¢^ªQ€I1¨z* ¦ÌfK€í(I a”sbÝéIzgï¼Ë ËÚ5 /G\ÆEÝJL·ۈ½-(öëz¼E«7h\o¾÷/×|óh•Jô«L'o¶ÛÃ×ÿþ¿›/߾ݜúLJèÓsyáËÐ~ˆ8Ä’Ntý!ý]-6‹ú½oÈ5ëÎÄ †]EXõ[­%EZõ¬:§¢k+F^LPÑÄM†•„òm¹ïYÂ_¶š’²o,ÛŸÍKnFYid¯Uñ«gßéLÙ¢¹‚ ¥iàò=á1?÷¾²Q’rk °èŒeW3±·‚›}O NcSƺø¤¶rMaÛ6è›=ž¶;üzžðv¹âu8j ‚€‰gtú¶ÁÄ .ã®?½àõ{‡ÃþýÝ#ÀçÆãfžàhwÐDNLøËUr|êvèú œïáœà€—µ™ŸËQ™‹X‚ì+AAç•Ê5³:±Ó¢ b…  ß~ßu0Ûê-x³½·òÞy¿Õ¦RH@Y$nÖÌüxÝL¶@š ¥¢qÛ þ‡‡ÇïÜ~{dщ±Í óWéÆLÙ”²¡ƒ¥‹Î>f¿÷ÊBú7>jEoäxA·Ù½}ùó —ûÇ™ÆÿVJ€Á÷ô º¿?ˆ97$M €ü¢¤m–‚Ý!…¦¯Ÿ»¦è'¦ÆŸMް=¢1že‚µ9³\-EŠj¦µ:˜nS•çu‡”·nÓ©¢T»i5Ô~±\¬zoçÔÌ?÷¨°°Ä~ËË9þIëL8Ÿ Fª{@é–ÔébÂMGŸ_Ù.Øš)iIè),ËåÆ¿e ©ªèš°bƧ‚©‹’øfÊZ[üV5†M1¶´Ä_@ØÖ;tÍ÷m‡Ïó§iÂëuÀËpÄq’Å“[°a‡É×eÄéõgœŽ?á:I|‰kª BúÓí÷ÇýÓ#xðQ%ìÊrÀޏ|!ïÅý{¢mú“ê½TJˆ¤Ú92˜PÚÂé\ŸÅ€¢LŽ]Uºó,H¹žç¢<ºi£‰“rgj÷WÒõÙçdó¡óx€yæææ.vFŒ®Óãˆl€› 3L©H°­^¿7Z2Îç;E_­Ù0u¶4cR©i¡|¢˜¯ ïˆ"ˆ³a¶eªVYdÅZ8W£ÙLŠXS«¾#3.·î9¨,?,k‰02efª±;fwxÜmq·Ý`˜v8Ž#^¯W¼#NóhЄ /Ì8Ï‚kÄ·ßïáû-ïu½ ã·kÂbPÄïmcU’&•Òrã÷½Ó‚Œ‘¦Ö¬ñêó—MsöEY}-´Ã2Ÿ.~°ú¼Z¼é›Ö%ª½b…¢¼†ßµÚa(ö‰F|ªÌàÅz6‚Ž}'ߘ³›òy¼DÅ]é(wV{¹³¬ñv;vÖV±Pñ»Ò ¥1%—MT”+eÇ`É»%·«Î¸úÙ\34š•f·û»—~{‡iû13€&|þ\œÿùó‚I-6LƒoðVL\_Š$öd|—‘1saA ²ƒö=ÅOÙUö¥\™IÉ]A}CªÞ Ê Íÿ=i×èEßiuWÖcâ8 Í/^«ž³ÕËìøJÒQ’Òâûq¢…ò—ß…ÿ@»¹U+ºD?«½§dRq>ë9X™sßSvª6,äq$öÌ·»5ße;òªèZÊŒ@å  “ûƒùþðëZlûŸö{ ó„Óð}ñr9b7¼‚Âa󄦿ƒo8çÔBÍüfŽ+BZˆ!/j¬yÆxõ| ˆË"¨®žÛ¤ˆ‰C¹kÍÿvC%c¶¿—˜ kæoÄà¢ÕhÙªe +× 2Ù …øŒlÊsfÿ³éÓíã&Š.•ÓsK)ÀêK¢n픺*êí£Þ0šŠù9VKšV-Õ}ÊI|óµë9(ƽîkA;ÒÔ0ົývÛ£ÝnðQ%\þ/ÿiqîúËïþúOÏà’›8‚†XÒ¿]d¼¶~@’f•Àf†j˜La“6[žßÛ’7VßMS£þ±Z÷%#[ùÄMZéõ¦ c»²Ji…¹N·IÚ{#² CM¶Rt3±^¬®—½£E ÑÔÌߤ”/¾EÈj¢½¢$šIdRY3ÊÚ§Õ”¢žµñ[6Ô*÷º˜3.').'¾ÑRšƒüõ‹/sòwë@œÞ¨\‘‰èû¾ì÷x8^ð¿›áyÁ™<›;­ôÌK£ åø¨úæébX¡‘Æ¿&¬\W‘ø/•]Y :T/N*º_ˆšñÛ¸[‡¢\Wå7/ÖZ“µ‚a-˜šÏD±Ì¯Û —¸'rœÔz˜sÓ_(´yï-…ÆÎã»Çû4,£ÜåÞ[gQ”@:¨¿¡‹µ®À¥Ù_ÚàºÙ[]])M+Ñæ¦´þÞ‰qh?£ ´{úôãáÏþ 7}*äøPÀôÿùçÔõàe>¸ýpx•kº[^õ¹ìdZ°–Êß§3ó×Ãn>˜uÓNºÁ¨¬¹ k|z»BmWê|Þê÷tÉ ãA-µÂååôoaá²dm½¨ß#tÅ>ªæ#Ú)‰Ð½ž‚"ug¡Ì4‰oÜø·¢vÒ¸ÞÕ…r︞d#£Qó êÀ«³xÇ ]Ž+Iª£³Y›i|793–R)2‰¬àfæ(-õ››I~éBbx× ï;´mƒžöè¡•çBn'j³Å÷¬ÖBíãqy—Ñ ØÚ r±§b-Y!Æ iMTŒ®"ê7þ M°û °V2ú/øò…u–ˆ½¯°°æcBÊÎÌ?gÇÕLÉt4*N×û«-úGV~ݼ>³@“ƒa¼ª&RСԱ[sĦm…ÊÝX·œ£cý@‰WTBÆæîÇo?¿þ×ÿé?Äp8Oÿkþçø(LJÚëß.Îi³AøñãmdD[‹ãÎÑ¿od¦&y×Äh\à†¦]Hô†¸¦ûËÕ–L¶Q‹M¯¾µóª<ð›ù¼{”ÍWùžÓ€V‹>í¨)ƾPÉpêg,!(CœL"UnfõpYÁMnâcE—h…áÅb15ºHó¢u-FÁ ¹N¦"²¢KV«åF”¾[ò¡]IÑ2ý¾vN$šßæpçbO|£Ýz¥ÅuflMIÃ_ {XM™Ö9ˆZnüï=À²ÌÉŸêÀp18S#Íjfš}¾%ŒoAÒa UEÄAÛÛBi7Ì?jãÅkæÿ®5ÿz«ç£êXôt%9SiðCÞ·J~­Wá;¢bú¡|_ê›'‹47.ÆÀEp ƒœj0ϼ·Ö~i Û^÷¹ÿÊÑZuÞÚ J7Ù{ì„SVº+é6{n;¸ñÈ­ýqë[%^±²`Ø—È‹»»{\‡Ãÿ_üK•ð'  ?Îá¾|)Îi»šæ•Ú8#›1r¾5•È|Y“(½¬j€¢ÏáHê@5+p¹±É2Kón”›Eïl»Q3©êz›ß³f,|ÌüY¿¹K^ä0 ÅÛªdúo±ûÓüÆn.ãcr¦eéX6ך`¨Äüq{žuÀqó;¬ÉKщ¤9)Ì{ITô©3²öbØ€žóï‡h a¢Ñ…£¥)ý?¿'}<½1}²(•¸¬Rq!ÃèEŸ?™6´G9f²HȹLœYì2R,¸œÁ,Ø¥k”ûV DÍ*èš½¥{ÑÙ{ë}a*Îë‰^3ÿÚZF{c¯hÅ8­.­ÏòûqõÌ/«ÐF (p D’5L2~£øq¹ê[̆¸!Ðs5g–ùߌ´…Ö-­ÇtkÅÓÍgêyDËøRäõ©— w٪ټéW)1ÿÒ:R„öÞ_âúïžÆïlö¼™O©^Éxøíoßúû,ÃõøP=>–ç»=8¢k”‹i£ŽEÿ*e¹,(É÷È2ÞÏÕÓ1 ;µ³ißÊ­Í×+‰õŸ6ÔŠùÛ•x£™w@Ãè¥+j}ë„ÜÖoj°Î›ÔÖ˜µÄ²1 Èmdæ([¸Œ‰êe­Hà- S»m¬`“sçñà|cbÓœIPÇØ7&ÞÈõ ­ÐdSÿ,m´ÚGñí‘Ip|¯oÛæ-B—$×RˆÒgŠw•Œ{¥Y®ÖrÃl¯gÛª¾;Õ¤–Q3‡¢,8ƒBÉüMÿþ¦yþ „ y…g™Ë6QK@¹&d]‘~;Gæ›WÒO4ûg… ÎBh¯YH|«'–9®­_¶AÙµ¸×ÌóË'“¸&yý¶ÂZY'ÑuPoŠ4å÷¯÷oA²«Ï¾Îͯ„›_ÅU³¶i‰iA·²&’˜\%‡Xžâª¿å{ªFDúa’?†àX…ƒ’Tš‘Y.‘Mè­ô2³8m\A¡2ƵeüBµµ¤fnµ ¯W‘Åú2‹È0S¦Í­=`ΣۮàëÖL®) 6tu˜Ïç&÷êãÕ ¥jÄ®œ¬ùZa Þ8–ùߨùQmV›†ºÊ¼‰4 XåÛEl2ƒ3ã7ãæü]FX¾Õmá¿LAK+û ™œÎãp©ùÇ6Ù®e˜{°¢ 7ºò>Ý»9Ò¼!8¸¶ú»û·~¿‡wõøP€ûò«ò@Øß°Û½!ÌŸ3h†ÛÁÿ½ûÕ,Yòðˆõ}ûV{ïºt÷9C ¯ón€z± ?èÁ°ûM/z ÿ–4aC‚Í«e  hEP´8’)Î /žv]vUwWWí~X¿_d¬½«û眯¦×œéÚk}yŒŒøEdf¤ BÎÉÑ(<ãOiÆUEG¯·ØIà¢Ím³õÊ;iI°ˆyqŽˆsÈ=š|¾·¨nFS¤AYŽH‹\å``»å^\¼›%¸ŒÍeëÑŽg†hÕbéú.ö裒P /†¦ðqå Ùi /‚»ÖT˜ËÓ¨[IàRÿ%ÅoîʽË ú:9Ò1VÊw9DŽ2~rãF1ÉðqÂel¶@9·èŽS/*á©¡}+|²=¾žã ÑÞ2÷¸£¬B3§I‘ýžÀd=‚ªx’ ¡8¯{4'2+nâߢÈñ×Y9fC*Oä&ÞUúé•Z€ª‘€`@‚NY˜7àᯉ»i“"i„>Ólq JžÂAóIC;#ÕÆ!Ź8Š1àCìgå½FÉw‚,ÁÑu9Hðm]åxyqwysýæìòjºÑ󔞓ïÿÆß(­?ˆ\^½_Î.îV]ØÅ((¤ðíàYàœu(RòXìÂ¥ XìÃêV⿆ €¢[¬¯Nù LŠ¡éZa"ÛÒÀ’ß×FéL›ïZ¦Óæ1 ©ŠðC³¨ÂCC(†3<(3Ñ…*¡Þ¡UPEW׌ªÆ»‡Éì¦×yÁNPˆÄò ï}¶‰>:P+ÿ²"Ap¥ž‹6ûDyÔ4]øÐWæ.㼫%ÍèótlMhîÕ¶v :›iÐë¤ïúªªÎŽw¿û_ý¿¾·ï¿ŸŽþÖoýäTž“Ç¿ô—¦oËÏ.÷ÿŸÿæ}ü¸ÃßãXŸ¿ƒ²÷/ï©|÷qí$Š ¢Eø©Ó®û®S(êä¶Îß•Ñw7XåZƒ¸'cSô&Ò£qŸ,:Ë?E1y€6µLœo¨ ‘¦›¬×P¨Oˆ”¥! % –Þ #Ü•Qš_¼ä|±Y˜°iQ—²+sÂÀøÇŒÐ¸½=ÈÍzÝCOwÇY±vÜëÐtB¬ÖcXÊ”N/€öb‘<#ÖÈXXÏ¥“âÝP”ãVŒºql'¢“ºaZ¹<«ùÜ7ÎXî¹îò>Áûñ¶2rÓôBy´Ñ–Û೓ŠpV±O:Q5þy×›Q/½{¨ç»VoåÁ à’VS%}ÙÇ»f>@f~·¦@oUY.ÎïþåýäÛ—/Ó óç÷¿—SyN ”=""Ëoü†|¸¹}“—»s†ÿ·ÍIXÈ k—ÛMgÉoMXTßjZ/ÉoŽGY°V%#®ù§pšm­°@! M^/Ç]ü(QxzÁ`lE{"óÆ««•’Ö³+ Š)ÑóhÓÙ×péBlfj¬ç_ªRNòGJ¼šµÛšå~õÊU|AÒ™÷ޤ/…:NTÄ´h‘/ ¢–(¢»É4UH/®2 ÍÚ3ÎZù.5†©È²`k·Bòœ­½—¤0ö~z\q©Ï›;À…Pd7€4Š4Õ%3Ò ÐI|¢åH7æø178fºú;Çx‡`\ eE™Zü &²Ý]Ì>ˆý¥g© Õ ÎdÌhCÝÑO7) Ô(y mð€–qwÙf„ ÑJì‹ b™z½Ìs¡œ¥¦Íd9½o„„N4ü¾±WDÖ÷r~sýæ«¿ð仯¿–S~N ,_¼˜¿}õ¥èÓ§wÛZašdᆰW$ZN„¦sÒæc/¤I‘нӏÊï¨ß|²¶Î ¼õ ­[7ãé0ª_]€À3î (z ê-…ÃlI%7! çþuxX`Yƒ@RD±릎a,| üÄ2NØRE=1Ý´¨P hh i]B.“ð0~X¶ŒÚ«K>—œ,x¢Žޱq*fÔÓ­‡²9Ÿ ƒà;`ÏN×RyÃàðy{Í ˆ‡ÉF@ëeT˜µí~ƒ$Ñ6ð33ÒlÐÕEŸü=éˆßjþà%Tž>¾{› øEa3fÔ=®PökK]³{_¹{SUæ)¸3ˆ XSIÆfV¥¬¯äPþnxtMç8p‚mÅûbŒç…ÁÈ8»€09~°ÿ Íê·z9k6…à’ÏOšlžÆ³«'w×Ïž‹~ü(§üœ@DDnŸ‰Þܼl<ƒf%¡ —ÐHNûÝF445P`üÛI±Ïh›5;!r]Dn Œ³å±Üu y•¿rS¤ÖLõðTÄJØž¸’?³5™5P´ÔÂg´GKHásW=°IQOÀÊ1T¶¦ü@ÍEÄÆqßË>ÉA™‚²BA2)-¶¦”ß]ïE&p}à€oq6ËEžä±Ú¦sgÇ:W̪ý…|•Fì¼t`#ÞCxa( 5œ Px1!Mã]H+ó7VÜ8s±š}Ó¹Ò)¹=gÀ&*Ã7›hTûê´/¼áÀºzŒrÂo½ªF’+&H­~&!Ï¿+Kç7ׯ¯žÞÊýwßÊ)?'Ž?ÿùôMEDã7^šâZ0Q@ùsØ]WK~n8…^ Ü V""à¶œlÊÛú0ˆ'Pìˆ|}ŠrÀམ>õtCÔìÖre||—,Ë$ÏV³5û yNÜDøe’—Ýð ¿Ú0ñÒû ¢¼¿a,8V>©0Ñ^E‚¸‚ZJ¡ ' H µ ×Ç;XîX3Ÿ¿OÂ×5]àT„d̃©Nµˆ¹€Æc`Œh:Ò÷ay•tÄXtD-e,¦ )f†fÿ]ÇÅYT•†  žŽÁ“ȦüÑíÚybM=ÁÜÖ±¼ˆ8˜b»¸ÖrôôÁ¸¯Âû‹ûm2X¨WU9X.'º7l;ši*ßáìs^ë°Õ6‹ cå] Ÿ 8 Ù¼EñQ'ºÎæ7z:*ÌjÉOvh–ýFÐQÒøøÌâ¶C€YN,Å.•íΙÃ"g××_ÎÏåxq!§üœxÿwþÎôM/.dý½ß{¥Ï_ˆÜ–ûøÍ¡`—1À4‘ þ»eÐ)¨ÏöGNŠT~®m»ƒ=ßòÀ ô"šëØV„§[ÍŒÊQx Û™ZE"$-¬Â4ðªËDà­Nuco d¥Ã!N°ÙXÎêÊÛkà¾K?ëà ¨¶#ºâŠÔ•‹J¬3WaZ•?Y×@ó”A œa§i¯¾-D{ü œŠŽÙ—|ðâ"æ%,P•e)åÁb=zz²y5@OÑí>G”ëÌ,¬N•_éMmxÑóòg/ͬè³MÙœƒÑŒùדS#DZÔ§„h;ýQ_yQKÿÊ{TûHø5ªvüoØî:°¼e„Tj`6À²ðMu •§›wív™òÞ{~*ÂÀ”pDÖ‡f9×_|ùòÙÏÿØI91ðÝßû{óÇÃA–³ãÝáù3±ßÿýy¨ÄÇ¡i,bæQFShUË_Du¦ëj=%0=*&¯³N°ø‡gƨmcá–@« 3 ù›Ù´™µZÏ}6' ¹£É“\a¹‡”AhŒUJÁbë¤aÐÈš{1OŽhZ¥›ôÜ”Åp —<1E¡I ö½:9Gê)}ŒÝ˜*õ° ‹@eðÈ/Ãi°‘ÓB˘Öñªt,Ö·RådìwÏ‚Jµ®DjjÐ ü Ñ3kò¢c£JÃb Y2ÇŽº´§-jºšoÞƒ¾¦rȆñ¼X [Smi‹e)4T;dÜó<üØî;W&Cè˧ºÒsOOý½èZÏÉ×ðÍŽ «óçQs­@‡;wȆóOqhDÌäâæFîþð_ÿöö—÷oßN¹ÿìŸý³Ÿ:¿òç¤Àñ/Ïqäì\ìýwwf°Æ+¼ûÛH&Úšl–*fŒhT¢›¬<^NQy‹€ÔjI49ÖÏáц«ë<å¿úUy°F†7 ‰dT@ «éïÒˆðFo R¶Æˆ+‡Ú Ć?wÙ¾ÈAá‰ãRéåôù[UÁ† ü›­eð#á1Sp¤+8 ª'¨r½·³Q¬oúÄv ÷'Ïò#ö©«ó–nØBh:šu30aZJ%m‰®Wd¿O¤ò‡x5jtÌüÒé]™32´îøhVþÔ0 í¶|,™´i˜[º—ä!‹¹«8«Ÿy\d Ë€,Ky”Þ pÃÅn…ŠIW…2`¢à·°€¶÷mç½2 4ðñ[W¹|þ\î~ÿ÷ï^ýË1o*‘ÿõðÈ©<'–/¾˜¾éù¹¬ß}w'Ç£h\‡gÓÎqçBçj·5¿Täî µ±ÈÊž´ -wøŽ26A¯cÿ@s)Q•zaùçïy1ʨËüç2Õ0¤ðŽ_¸ÑV´ _ c •1>øjÝÛ &² ½;*^4/Ï™ú4êõ!^ô“õú½j“ -bÍeM §˜’oЪõ5‚GCá?U±ûf®°b‹C¢º¼ÙØI 5䯥zY[ëÀ#IWlëB€Áp’\K¿½šÒw´’BPC[ÓÌòÊxÞªüÊ´ …v+Ž**û>z5€´³Ü縙˜,sl‹àE¼¸P=Š m-ÚÂk¥i>¤(J}ÉEÖ$…¥[bì•?úFÒü¨ð¿æÉ`L6^¦Jã©‚^ȼ@©ïÓ¬È8¤GuèD­Ax!I° uÕ‡°L™{á©óÏÃSÓ¢yEVõíìÁ ùY’—%ç ]…Z«­s¾£kzšÂF(yö{T¹º÷›áw«,•-·Æ‚`ÞÄf $’nÝ+Ë„ˆöi0)À° p¸×9 'IWâW‘2Y‹Gh]åpvöñêùó»ãÙ™Üø §üœX®ŸLßôü\l½¸“Ë«7²ÞߺU{ïQI¢i%Û°ÞkØÝtEÚ ÏŒÂ^ËLE´„¬¤qqpƒ87çk¦Ÿ6'Ný™&vi­y§MŠÝl¤¶%6½ÖS>㯈àFm·2—ZýAÞ–ììeö":¿Á¶Ô‡Ô`ßV-¥1êš?\:Uù†g*pˆÁü#têG†wzXqU[[Þ”„½2v¿Êr~þÍÅííÝápü ü2ŸÃÏ~¶÷Ó[½¹~mïÿx è|h€‹‘Ž7À¡Å°xšÁ}„wÉÍDl-ëbè0K5eÅ­…ØÖÙBÈÖ,B]µòÆÁÁ$'w,_¯Éò½‰ß‘…¡v©(Ð.kn¶¬Ol¶N¡¡<„­Í³y*ŠƸm:¦S96ÕÕ9ÑšÉ=¬ClƒŠavkÙ£¾ÜöYéÛ_áé0)÷Y`/–­¥¡™;ÕÇ9ø$ 3æ“£hí](^Ki_UÝIZœ³[ÅÚ¤˜G…õC5Ñ1–f›-1-YZ±Òæ<}ÑÛǪ*›ò§ø°‰žJ…ïB²<Ê®®ûþ²s Lþ¦u¾þ0ꈈ˜­r¼¸xsq}swP•ûãI©Ðé9©Ö÷÷þÓ7]"Ož˜oôx]d;^î9#¦HË'ç--Ub„´! #mQÌÆ’¥Jš0­êç]Hy\…æÆ3¥br}S¦þLÿ«K̤]CܺRñ÷¼†ê…ÖËS&sl4Ô7ÚmfþÂAp†êä1¯O³0é·ªñÀñ棗±¸™æz‚½¬ú>ºXÙ(ª+\|5/$nmÄ“&¸NÊCYO(Œ/dPD SŽù-¨ Z¤4ÄiÓÃ~ŒPÂ.±] ØðVðYy¥}.Þ~Pu ¯Ncåmoy¾ág2±DæçjÃÓÅ?îW=Lø V‚þä>Ÿ™«'oÁÌòo8Mꌭ¶5?ýïàO¦wŠÌG™ç8 R«+Ð#”d ,Á¡”cº›ÉJ!)Mh-³ WÚàçYD«háÀ9ȱ&’¡^“¡dqŠW+3„9;&@ýéÁH …‡åî{Ù–`¶˜ýÜv0†…da©«k3·ÅûÁB:}unÅŤ ä*Oä&ÏÆ‚o¹©:ó2$ |ýžò°'#Q²ŒÞS}˜\`¡ mr¯£…åãúN‡Çø4ÔuÏ‘^ç¶cž=EàµÓÒå©uJÑ;£Xéžàf ]¸àW [ò(·(ˆêµ,[AM°ºˆŠvघ{Í}œkÒØÎ[?ÓUÁYs¨6T¶Û\lzxbkñą̂½£uíaõ@Õ¹6“R.‹èñøú_ýãl÷ïß‹ÝßOÔü ñ/Ê©<'ÎþÒ_n¿/_}%ö»¿ûZ>|(†€s“¦r¨¼^in†ä 8’.VÑ â<£"²Zn,Üõ8ò¿±)ÔjoC™4ÚÇËDv×HYéçä"ïˆxÆõÞÏ Ð’1åa2™’ ˜,8–È 'A”Õ±ÚyÐB£V¶àoLit/ È2³œ}e1òÑ0qÒÃ0P£K°:~X~ºžÀúÇ»Üd¬Šù* ƒ—¨Ïi sbíî"íQÛƒGšË€ª2(CË7šÈ#Ù4l<ŸI_a øv%\AáÏcÌw?âw<ªZü CÌ ¯öÍ=7Æ9± ß“§'J ývÒ’•‡fÎN;ý{ܧž÷UÐ 4žÞhÎÕÌ<Ü8Y^Ý£œ¥‰“x¡ ÂÏr8Šwÿì¿øûòþÍ›–ÿ«ÿßl~mž“‡/¿l¿/?ÿ¹Èíí›u]·-’nD¦À{ÈzsÏ B§øÙæÎV”ñ;Ä€ʽheŠCŸ«0Âõë:û¶"á#è›ø§ÈæXú(€ÜÕR ™gŽØQŒ§­µõ›Ý%~n×êf§jåD—Yx`{X ƒ¾Ž,k\¥ÁXî¹ïŒl¾i\½\TþÙî¬7ï DaÃÉãWJ©<€G~ ´ȯF|z?˜WÒ·c\¶áï3LÉJ±o³;9/{*f~xCt(<ãmî¬NÔãà Ø‘ϰ7Àø›ò8OùRoÖT‚÷¥Ÿ/È8z<54N•ªã°)ÅIÔ=s’Î"Ù›o™Ç&êØTÇCµ¦ ÑR¢ÿdeÉ)tAç hÑ_~ëx“Xùw‚”¥žûûr~}}÷Õoýå»W/åÔŸ“Ë—_ì|ÿR–§Oï¥"iXgr¶.§$*`je1³A3¬XËËE’Å `êä¬/f‹­¤“ e”]ô `  /‘wió&žÙE–„Â+‹Ã,7í˜Æ~ƒ@HÞVu .ÖR8l'3ë©ã9 L×AD?¢h–#<n2ƒ÷!X¥5"X…ÛPT¤üÉhŒ_‚TÁ±Y¦¡keWz(²šÜ•ï}ªÇ/œ¡ÛJò2%ÿcŠŒÓѨR>i-P°ÜKŒ  c=dtBTŽÎ¿~6ó3¦ßÄóƒ‹`Í%@-¹5úX±‹AöFX­„æ )Nmn¦Y±LÀVЩá"„AS¦àRÀ¿>äK|&?>Ÿ^„Ô³’¬ˆcwä¢QqÈPI"î]t`®ƒnš èH·üáÓ`¸i¸ ÌþZÙÕ‚­rq}ýúÉ/DÛFœÖsR ‹ "²|ñBôÙ³×.]LÑ%c‚·1ø½L™xr2yЪÇL¡Ë­A룜i׿êC XÐIîïÃ9–@CzUÊèpÿö½Î£E²ÀKˆzˆì&!|ûà¢~<ÒJ[óÔl™Eí«—òŠ/M%ÜY–Ø´n->v}ä“Ù²Bû@X'ï‰ß F9Šc¼¶àÈ%•e[lbãåïŒæ’VnŒ­œQV;SW㵠ݵäï”*ºÒ$uV KjóvÎå~Fp6§¸BbÂ}.¡]TÔ`@›vòùà¼Ó‰ IWVË‘nì'¼´zt¶¦@:6R£t¢U‹€¢÷ö!vtPU€Ø|X¯9¨W¥cÊŒÚ?(`/®òç77w×/¾½_åÔŸ“‡›ëöûrq)‡gO¿–ãAÄVÑq½Ü$ S7zØb÷š¯Xu¤p¥”áL,óožiÞÜ” ój¼yh=›EãÃr»X#+ÍDµ³+oÒ÷P¬›-)ô#`µÚà1¨M‰aAÓ0Ag•ò²B”f° ÐÙÃ/ÏK!ܳP­e8·/N@¬T`röÃìB¶*(ÁÂâD>¶h‹r(V›ç«×©â¾móÅ/VrUUÅ Ñ‚ ™ª¢ˆ§€U"/ò·:ä ‚+Àû-æ±Lúm[^$o NÑF=4O6AFœ5^OÒ­[Ï~ VN£î»%›Þæ=+£Ê¦B2š2M"<²åHD8v*ƒc!A°ZÝò‚(n-žpR7„÷ e×·¯.oŸÊýûÓŽ(rb`¹¾Ùÿíé³—r8nqq·àþãé-à¯Y7Ào¨?¬äu2šŒp‘šÕâíN•K±ÀR¦ EùG ;n±´œ¡­ôàM˜$£ÚiI B¬#²z‚FLèvg3(§ÖŠ€ÚY¹`9()ÇÕ:NëQIw1à–ÿ1Èá®…ÙlÊ<„²Ï`Œpca¶xß=rÍÌWT—Rˆg¼#€7t¥a+1^Ñò÷b)FAƒcòï½w9åñæ óѯ5Sy‹Ù+ã!3ü÷wõ MM©dÔ.IÇÕ ÊßVÑÃQήŸ¼<^žËÙåÅ'õû×ù9) Çóýß®o^ÉÙ1º[VVxÓ¦þÍŸéxéP\1XDhÀ†EN¿Q¨ƒÒÆ8çæyAÒe‘ö|©V1ÑEÃYuv–§ Ñ;…Ð*1ý…¨˜¥}É„U´ýêñÿÑ× 8ˆ 4Àb}{¸œ'­ x~r\gõnÐ}¨WFËs˜÷$ Tì@MáÜs*â¬ÑÁS3Û‘±ä1-ÍÊmw®-7Æ­žä1Mïù;RãV ­«”×$0Tš÷Ap£‘“ }r¬Æ·5çD‹*€ à´¡ï•ÀÖ°KùÓ©ðz:2o9–Pˆ†Ç…CÆPáY"Åi,"`ýThçšj®ã9ÿ¦Â[øôÁ|N×ê¡â˜¹ó áä ÈçQ¹Xè¬Üq¤N‹ýŸ{¬îˉþëº)„'_~ñõíW?£Nõ9)ðîÿøØéÅAì»ïÞösYÿà÷ib™ï@nÇà&ûÀ( Ìs\w Kº¼¯&c³×¨Û6¥í J' ´ °´¦Âm>ÊÅø5ûGÉšï¢tÔÏÒöÌ«ZgŽÀ4mÎâ˜ñ³ÍE4‚KS/ŒÅìšÅ€ÖGSG%AÔ¬Ôâw&¤íVK3ÇÐ?Z ‚òu|êúšøÎŽG PÄõ4C ·+6¦{jØ(`¤_h,øldZ=tU4šßÓèä(å1Û-ÐâõƒW®+ÊJîB\W”KÝ“v ȼWdæ­ÚïnÌ«:xëV·û¯Q‹/òEF¥¿ISìm—镺ð1/„Ôý©ŒÕ tóÓã_¸Ï‚Û¡¹™¯‚v ‘ 5“`é Å–$ÜÃJ±6MTdµUί¯å›—¯^ÿÞÿû¿’÷oï¤{þâ_î«ÿ:>'Öï¿ëøx9;{+—W"÷÷ Ñmg‚Öè?ô‰Þ¬‚tqËŸ‚í¸~É?§ø>ûC‰‚å¯&²jZ9ÑÖqÎ?¦˜(Q—5 >8Rþ²çZÇÎfI±YË6Û>+BËß=(h혡ÆVk ÚJãeÔ::?~1²¾,bÄÎs@n$;<¯r—ø £†>To¶³ÑÛH°õw™ Eçv¬¼9x(Y†‚žl,{`yH÷):ÆÊ2ñMZm9vÄÏX*“,ÕnŒ÷BjÃ-8Á)ã™éå8HëF±ŽÇ´ÉÌò»bC”‡ØÛÔxÿ:ÂþMªPOÄh›1OÏœ‚P ŸðéÆŽhĵÐHÔñ)¶1”ÁT ˆ ~‡BÏ5haè¶œ!³•Â…R;ÏD"–¤«Ÿèá^zx¬46Dd]W¹|öLþÍïüÎÛßÿíß–½çùïý{r*ÏI€ãŸú3;?EÌî¾?,eµ#m(š”ð·ñÏŸÓ²ÁìÝ’"oD†Ok±FB¤òw¥ïL¬uCéšS‘6,¢¡‡í¬}, µ¿ˆB_RÿÖkÀi:„Š~³£mR)“t´ÍàÛn܆¢šç=ÜV5£I.x÷8‚*-4„¾-µ^übu#áÂ(6%-ZZs_$ÉJëx’µÞ´ÉKôAñ1‚.`çx¬­!(¸ 9HÒ&z$pÈK¡Dm; õbQN6Lêâ@^RþØ•ÞzÜ>ˆA¯%öFtÓv7K]péæQ¯ümúòÐ3 E{,IMc6·®ÄØ@å_Ë)’`—†â4Ôþ›v4²¾?6,´§ì½Õ6 à©='öâÈñ(¢òVÏ/¾•u½uDièûÛáP0°òsu# ð(®°ü‘÷0 ¹+ ƒjZÿ ]sù!ê6ξ'‚ªî]X@TØ9ÅRT¯±`®º“ŠîÏÓ-ÏN[ÙÊñw~‹V–Ë€Òbo4¾5$ áÐ4HrÀ’/ØCâÇôöQïdÅI€CúÌB‘Åts Ój¸°-5|£ Båµþ×ú£B°*Î…8~üzýz?'/^ìôâ(r8¼•'WßÈz›É]ËŒöç±ð®žj< ¤…”-Äl¼î¨à\¯%^râõ޽'ñ­®‘‚ý],Ãí=zØßö"Ì"åHâ†Æ¡ó*"«‡‚ÕD2ƒ^¢Ã¹Iäc™«ÒµÚÊ‚rˆ–¹®¸‹_T×a·ÿPÌú"D­´iš‹ØPpWŽ¥U6ÏN·ç!yQHnÓ¨uZîœþp%³LV;‰=l몠ŸªÂ¥â Fè„vÐ&î˜/ªÀ²ZñI‹ñÔ»8¼ˆÛ`X­¥ÝK²ã‚·ØÞgÐó–­mþÖÍ[_jþÃh ÷Pÿ´)¦Ž¨Î?wkñÚæ†¾6il'Ãn¯ë5JÕ{ fðòI­l>® kU=QaÇø™h6ÙcŸp«ÞryIEl59œŸ}{õüù[5“õ'À/ù¹Ú9x<Šž½•«'¯mµß˜q%[¤džïÙ eöL`²XíÓæ¼"\‘ë’Uc¡Ø'Å(_5(¶ ˆRd’"Ü´I\R=™d«4Ž©TNA‰®·*ÕAéúçUf ’x[&l×|ÝHQ(X‚Y HOË}(º×$P½#&$òl^«r+[ ­€ûñ_¬”ÀJ1khl](s˜^à7öIÈ,¼«§ª«…[^V;tl‡»$@åû7› öª'>öOù×þ`¿PlÏš´)åŠäüžƒ/V´Ö ($qC¦6LöDÿ®íù…ÁÚž_wë;°Œy€xÉÄJkÓv&€RIÝÆÒ"kiníXû ¾¡,M:óìÔúI¶M€zqñîòöé[Yï¿ìg¹¾ê8D//?,Ož¼’· ÷º¶g_ù£’í¤uÒ£Z0#3yÔÓÖ ÑOnÎäºÂÍ?j=KùÖY¬üfÑ;»³Øù,®ÙM1dp„»Ê¿´“pD'‚tÌç†}¼·õ T°iµ»Å.»²i„>$÷ ù¾úðU2ÁÅ6~¨.SªïŠp Ô 7+åVqÛƒ½ˆß¯5 ȼUij¼µð ¨T¿Òl…O߇³³-Ο¨>­9ÞðGܸöè4(˜ÌotØ¿Zdû:Krà}ƒ_’µAQXÝ# 3áôûÐ4 ɳӨžëuTæñͦÙ#u7—Iç_䨟Øòø·z'F üP¿O'®Ýãû@‡ÇîW9^^¾¹¸¹¹³~¿ôçòIÿýpØféÍÍkYׯ™ƒóq¶‡É}ÕLJôL·¸@´ üÊâjuÅá—Ò´€V{yŸžîXµGND@0–2Ý“ìñõa¿I4ö´ëW@ˆ›¾$a+®IEÎGv¶é:ƒ¦ðÊ?nhә޳x)6yF;$ç!Ž5¯@æ¶v#ÃÒÆU÷;‘Ëqê<7®Ì*’k ‡V¥ÐÜoÚuŠKNðÂô¯¢W ‹+‹Æsµ–÷Ž9åQqÖNÂ9€éý·íßaC,»6ÓÜ;Ê„³ê;ö˜¾yzcwæÝ)0y¢Z¾6Ð\³=c>ý?·A$äÄ“>³HéQS;¯l7xÚ.kþZªm†ÎñêêÕù“«ë÷‡ŸÀ/ûùæ?úûTEonDÖõN¯.ó3âWKÁ‡ Ñ dä2àPJí&5P$xŒ¯Z˜^ Â#.8iÊìÁâÅ'Õ&ÃþS©Câ‡×‘ŽBég:-è »€':3aEÝ3I&:Ïb ¿iš¬1(ŸN÷`išÔBçqµi‚“ð’&1[¤;U¼Tx¢ö™ô" WçÍøÝK0W4ÆS[7?‚(\‹NoÐ\f„³¶íºh×¼†CZ<Ä6Јp ¯ˆPHœŠÜU õÍÞ¤ñ¬´ÆxÒ,qÏo@Û~Ç€/&B!¾½><³½¦±™€ÇZêôàž yS—´êª¾ ö–«ÌÒx¶¾›l›Íò¶³1SI×í¹‘Ÿ KGb‰L{–˜Æ§þÃ\Âï)šóÇÚcg"bfrþäÉë«Û§òñ»o¿ìÇÞ¾Ùÿíì(zyõfŽÈ Ûïy&•¿µ‚ѧ”\{m^‘˜O¬´s®leŽ<´G¬:¶n;H[[×Û9øÏô^]éÂkþA1V n6ÚeöX­ÊÞúdüÄXÌt®]R@W"YR O‚Ѹï´+˜ÌiÄUé>Q“G‰ræwøñI­më,=\Ò(e°ãé—e²Þ:01®+ÉÜo¬ÃxŒÛþ0ëhÊ¿òµ~× F1]­zžCí†×É00×&÷=¦¶ï/}í?óü·iîHù sö΄ºI0- {Ä,žöø©;I®7i`3ÿÖF=--©L °ïÒ­I>?°x2*;žŸËz¿Þý“¿ý7åÃÛw;½ùŸü•¿"§òœ8ü™?³ûÛòÕWòý?ûï_Ëý½¸ HVI¡*i‰ˆÄÝàìqի>§ðï c¾TÁ»éS軎Šp·?«Çé‡b‹óc¬ü=þ6•ànKuÑéÂb«××ÀÕ#íÉý8¡0g¼3£är'/‘§‹ÞˆÎ«J{Žóà‚¡´ƒ¢–T¥(P8…¦»üi§ާÊ¿òš3úÖÐÌm«àqòt«\@Ø#_hhK¦uªi¼«×QÉh•ÕÄA“b¡Œ©8èZÿ™LÊ(8ØËFçÀphI8Åçî˜)øåôšo3°EòY¸Š—úYÁ §J/+¥Ф2yæ°,}î¡)ÕC¡¹Þxk”?o/4>9 - ¢ Ñ5Mæo³XHO„(ª‹ÎÏ^¿{ùR¾³oŒžÒsR@_|¹ûÛòÅW¢OŸ¿Qâ$"©e.h˜m‰þ®ëþ{`9ø§‚¢ƒðwTˆSŸ,¯Iå¿ÈÖ4“–Dšs€Œ2pp¡üKáºÙ°øLóÍPuå:5,i£•XÜ—YP2 ¨ª*Uhç b§¨«qjP‹‹¾M¹ò;zÚpVP $…ñºyD÷Z(]™Úíðvð‰‰ fxЕbüíOÕU<5|Cö Ö¯ÚéÒðD€cWJ8|Ð6á«dƒ®uY)f« ¨i–MÓœ`#(­M瀎“¢ï¾U^˜›×Ž(+½ ØSÌ4Z `qq¡ã£T èDý¸7ðšA)×›ô©iÚÀ`G» ß™GKSBï= ÍLä~½—‹ÛÛ×_ü‰?)ß½~õX!'ñœ8<¾ûÛòü…,ÏŸ¿–e I‚k}~Ýk[dj rÊäî$k{|­æ»W~ñÝbLƒÍ`¥©LÉad€Š~Æ8à˜·€kVGïHÉ 4÷4?qļúžµÖo…?¦Ö¦é¤Ä ¤‹Ì«Ö·ðø&š9¼iîÔbs‚Ù<‡|’”8K<»˜‡"ÆÐë9–µ-ûャ±ŠÈùíÍ›«ÏZƒëŸ“z{óàoúìé×rÜ®Öå(Xb(ÔÈb·³`äÁ÷½°ºhÁèNs`•¸˜êi'´îµ³~«ÂoØê£¿ÚI,Ø…ªNqÛN8@óm}ÉÚÝˮ˼Ï0 k‹«`ŸÅ7á)& ~€€DDÁ)$bÀÑBk’ ²Q…MÊ_šÒQ‘GID u½½3Ö3ùZUlÈÈÓò%D ïØ¨YšNßò‘×—‚tÞH:a*Æ?‘f ž¤½œqV QSU\3ŸkÛ±‡ÈðX&óÔþù¡®Ö1@IÉð}¯ ÎïõÍ©ƒ×ѵZ%˜Z‘ª0é,¸—êäÖ g¢Æ¸ô$ðº€j6:…pÜ•ê é ­‡iý³UtYäâæöõåíS±§¿PäÄÀrõdÿ·ãQ–§Ï^Úٙغ:E—/^Vág~«»«> ûó„@Zó“6—÷ñÐtÝsO)ºRo_‰Nï|d¶µZ†õ3"rYâßÎBû…3 d}G8R÷²)!…À¥;×Là /n#Ùji.ÔéUMuõŽå¢âD`q t¥vC! ÑQeuÛF:ŒI@4Ë=Lôa»c„Éí÷&ìØÔ¾ PS)àËõ|á|ÈëÑF'㤗îùò ±3ç‘^Ý¥u=ßáØuUìõÏ"gÝ äþ¡2š5}îóàÍxh‘w^$Üí(l¢beGŒ=ÕÃWz§`΀ÀñœoP"bo¼É°ÁDEV=äøäúåñâBŽ——ò9<'äæöáߟ=-gg"ïßoƒ»êŠH$™f{‘´¿*f”"àQþ³E›þ·å{u‹yÚµ*û¦ÞÚÆ=üÏÂØ¿íXAS&uí"@ÜÍ7VHùÖBK7©º.4…IhUš[J ü¥û©Å(”w{&¿ÿOÿé»W¿÷{²~ø {Ï_ù·ÿm9•ç¤Àñ·~kÿÇe½¸x«gÇw²®Ï¶ÖàýŒ»á$«›ÍÊúfå?ÉŸZÏY­»qn¼môîm›…q ÓÉÚ”Nß¡ô‘â †À܉þÖšu\ŒB«ÆÀ8د’ûPqES [çí]œJÕÎI\ù;U4éÊŸHR¿I í”/º›c¿T.þNÂJ€‡±óLÈ»±À©¥¬Ìq@„¤im Ë«Bë)ÂZG’ÙkÓ’©›™®ëºÊÙÕÕ‡÷ß|óöíþA[§ûœ8|ùÕþË"zuõV./¿ P'mõÝ™€jÛþ»'äñ½¢¨%­Ÿé©nÀFùçznº³šŒÝŒRƒå?äfÝ>o”î]ÂíßE4ŒÙ Áîi­±–¥Ö‹åìö¨Š> 3zÀÝï f”Ф{¨-6¦KT7Y)·¬ùÔ›J{r×"ᦥ`ªéÁØFŒ2×ÑÇ?ã‚Sn[—ø¤»ã‡± èWºè§†š¶Row9ÔÌÁ83AqG–jo3Ýð¨¤y¥ÍX0‰ HmÇã®ku˜Ìµ—>L=Óc7mS Ú¤wœ•ÁÒw,0•AŠ>Ç3Ày‘E8¾\ oî£þ4tŸúl\Ë®aö‰O`Ÿu=Þ=ûÍß|»~ÿý£‘Oå9) ÏŸíÿ¶,¢××oõêÉ;[·õv|V‰PÆã“])Ë“I­Ä±/íÏXøëXçªV\Ì-5oÄU¹©Žø¬ÈözÛÛ<ó·=% )´ÜíÛmš5ñãcôEë’N9=€ØH¦ªB‹Œ3O ¥á"UÄV9\\¾½|zûöãwg?€_ų\^=ðã"ru%zsójc/7CׯôT˜þ½w?ìV›Ÿp%<¸Ý©wû3öÙ¡‰{3?»M{!‡ªÏMƒ½º»£ñ‘ò + RKÅßÒϳ-n߸•ç³K€yâ~Þó°Ü¶†èÎ$ê«´ã†à§SKŠkª¡X IÖç¼dÁ-ÎÖ€ÍkÞ¶ pKfŠzÂMãõvT¶&˜v’ÐxÕÝÿwvEgÝàQoh?š+¥ú¨\B"×ÁR(ƒñAÑhÐŒ†sèù4ÃG“kpéžpÈD"ÒåAe]@æ¬yF8Ý'EÖLŽÈfý0‡·\œxowl8q!uÜ{Äßý F6/¯Þœ]]PÓŸÀ¯äyh `¨,wJœ>S|òNû N¦É’OX€ä¼¿‚}m,D~ícÀr#Ô‹A‰rI’‡®e›‡†eºyÄL—/çb?ü~Ï7õ?~ðw}òDì»oÞè“+ñà*´¯ßt4óõ.˜“親 @;^¨ VgN(¡b&ïiÍŸzûZa3—M?:d·¯ùcZã÷5óùûtåiíxz1·÷ l©†§¯é*jÅ]ëqÅ;þÈI?‰AIÍm ¯ o¤t¾r€QýÅn :$È`ÅŽkšNw8ÞW¤Q-ýðn!çõÃq™9ZË…¹I††éïoLÂ|Bº²£¶‰A9ß²Ã' ’«'+ˆ•ôÁ±cüh¤ŠRò~iå!a¦¯ŸËÕ<þô°Ç§Û<Öä¥;Õ ‚{úA©H²4ÞÑ›3/¸ŽˆY2¯ºör¼ðÌ%§d– ,s푺€êÊ&"ëjr|òäÕ“/¿çç²þà—ÿÜÿËùàïúì™èùÅ=ãòŸ`h4m í¼V² ØBÅõúM(lyb:h–”]xlùcYK#ùØø=! –!’nYÏ@PÎÉV*Ù¹²Ä±C<ç?žEË-lN‰‹~ÂD¹#ÐeAËÕ_ª%ìm~«Ó;¬t+'Ûã W…ÇÊrMáÞÔÕDnœö By-"jÛùrY‡'ÀGz€Á!ˆv2Eñ hi(ìœ,ò•¸c!Ž…UòhºŸ»·¹PƒWt(¶È•èZkµƒµ2.¿R­¨à§ ‡`(ñ^¡<Ág °A…â)fS»€§p™ß3~ÃeyQe¡ÖShÒ+ú kËù t‘Mˆ8ˆBð›X‚a&pO³È òsЉvöû8XUìØéäi;CÊ9÷”€ÖÎøš¸ƆzÑlt&²>Ã?²-…Î*r¼¼ûÞüw÷ïʇwßÈCÏÿôö?—SyN œý¹?ûàïË‹/äûׯ^É}ºþcG*›âŒÀÅ”yü©ŠØ}KQŒ=,„ŒÊ© £ÖÙ)?jÏœ’R§PÕo–6N’ãf6OG\$×E袑¡XßëuïYûIO`ÿƱ&M!. T,NTàE'V“ QÅÆôFTI³‰ ¬>$µ6uR5y‡Ï Öí®Vo‚P-)c³f|r@0\àû¨Áy†;Eã VÝ;²{ùO}å'Eºû ªå[cÞíFÇBÍ`Ócì‹ð–'·²fYÇ–Ç´é¯ðÌï´Ñµpäž "î[l_µé GR’T !€€ŽÜ6!$  oÐ|ó08¥ç¤ÀòÅ—ÿþå—¢Ï_¼¶eX½`A˜£°Ü.JŸô#Õ8ýhä,¶¦`ðEQˆXål%Ó C&ùƒÖ¥HlˆËRÀUmÉàc’“»Ò¨ü¨»„ÐEwo•â?Sûa¹‚fiuÞM”gÑfhM—ɹ×èxK/Kµ{¦Mó ÔsùúGÚ^fE¼¯-8I'oœþh¥öÃ4]™ OV«A¦"AV”A("÷(4¦_4@…߯†÷; à¬#EÂ^„/Cššo0…Þø½öxoßzvŸz<æTÙîœ~ 7@”jÌë™Æ¢2´Í5E7Q_êŽLОý˜Òu†¾l{û髼 ­BåZÊ÷’ö.Ù :nƒiXÄœ ƒi¨³­¥/öJP7Eúùée!ŸU€+ €Ïon^_<}:Ï­~N nnü]onäðìÙK=;[ï·Ø¸}6íø;ÓGC а“¡8FMiS^JHÿ>j½¦aúâš(îx–¨c°§§L%÷Bl ø~vž!1˜°’5’Œƒ®YÁ¶½ŽäÞƒhãì>™ L ‹í¯E}B¦61ÍÍAêV.ZøõLý4ÚèB”Ì¿ck§+gÁÐ[}{š°Ó”ù,fBDÇ?Ý®<°Eô ÅŒJ`NF¿\¸ÆÆ-D§QLƒ¹†Â8c* gçÎ$¨§21 ,@m¯ô‘6ÌG(bÜt¾íàÆÊFÒ˜}uBÓµˆÚ¢Ê/1Gpë÷ÒTÞ˜ƒz/AWnä² ßáØÝM➦W| #®É)FÅ”*Ìkƒ÷TÆ{V»“Èb2æHž3 ÍLt9ÈùííëËÛÛÞ q¢ÏI}(€ˆÈù¹èíÓWëŹÞ½Õ3 ×B3&-{x*‘5^ÜfÓ&²‚üqóO¼¬4æ©”@êv¤K—„KQþÐÒtÇ¥, ¸Ý¥¯2èP\š–þ¹‰è²•Ö²"EgÊÖÕü=)¢ `:g®IQÉØØ§¯ãwË~„e¸kñO\Æ<àU• £âU; *›„þt±;-¡•JCÞ´U€G‚6÷;pÑÐs’;»5ј˜ÀÁ¬Š¨ó„F´"\çØ$œ ûO»˜/©¸c*0A 'ú ¨ä#³‹ðf]G4 QæVSKx``Üñ”ÌCl8‡šF:cmÅ]ÒÈ Rú„ÌkŠ6Ø¿¡‚ï<õ äU2¿·]+å&ðQXWÑ‹ 9»º|y8;ÊáìL>—ç¤À·ýÿôp‚ÃAäþþÝáÙóï×?üÃs‘dϸÆ]N¸Vâ!ïÂãsá¬è÷Á‰mB.îd&+²âÓÜGݪ°ÿâܤVE„¢µ,"¦°ë*&[î¸Ee9’ ë¾·Q]Ú'ø­;Ø¿š=¯EgRÈUÀ ÞèF‚@\ù™¸™‚ô¬ý¦J §X;‡“&E±‘È…o¤ýziò\ŒÖÔÈzÇj;A ÕðÄΟɻàù‰}’ Û?Ww§&§ÓÕ1$ô>eÙRÊzg^©Ê«³¢w@¤äðQ1•Qu©Å°%yû%BÆX¸™›¹§Ø±µÕ4ØŸ 8—eZ)#4¡þE²ÈÚwlZ¦0ÁPÛhôy&†Á4/D&y5Aš¯¥ÞÕD¹|ñâõÕ‹/d9ž”Ú|ð9©ž|øgÿ߇˜ÉòÅïôææ­¬÷_äz¹»ÚÁ:™lA‰¿;'[}È¥óžÒ—ÌÖÖkO¥ß·©½ˆGm£k~JËñ+ `OáÂÞü ;FF¤,€ø‹Ñ‡‚½ÒéVæ¦U£`Á%€¯wè“,E«¹D§°º1¦¿@8Íp}zÇØÂ¨Í„àsÚ«ŒÛ()¶@ç}ØÈ¢î¤´U+¾JÅB‰ÉRDdRËA£ŸÍÀ¹ž>!õM›Ôö£ç©­Pt¾WCIùeډױaêcÊJ³Ê'ÿž ‚à!Úu±t5(”+RÛ-’Ø•dSêF¦æ(t®iPi‹‡6lÆ´›Y)¸D#_Œª2pöÌÔq'ž<ùþßüöo¿{óÏÿ¹Üü(=ÿ‹çß‘SyN œÿ¹?ÿx¢gOß}~þVîí‹0~Md,D‚”vkË9]hÝzZD„Sv͉æ„A&ÌGá½S}òè7Útäâ€$,Xq%£~î[ ‚Ó½Õ 0À] ×­¬­Éâ¹Q_ ®¨ë Åо]¯¼yìœD¸|‹Kd‘Çß '; ê]Ìd½I(ÆÎ}²øà7éO aé(Í”öôÓúO ·iû´Ý €Ap´¸à*5Ìr |$»Ðí¼DÅ&]࣬„ÕW†÷õµ!¹—&yU…ö„µ˜‚ƒÃM¡&,Þ)´üuîߢ‚θlÍ“}Œ—$šÇj¶×‘'HÓò Ê@ÄnN£®…Ýh)6çAà U˜‹´É€$iŸ‹‰:ÝåÖ¸`Sœ5¶®rvuu÷îåËwßß½ÕE>—ç¤Àòå—¦ÑçÏïôÉU\ ,Õ­Ê"5E±•ŠÅÜÓO«9–?´èörÆå›éÓªäò|bØ8| º‘È.>ÝËæt|@Ð?o]×]õµ¥²¯™ú6\ öX©g°t‰¬£¦«¶=/›"•»èCGÉð`¢¥‚™jÀ¥Žös©Cû(“¸ X<~@0ñ|ÿCåïJGë:7ë\ŽÂí€×]én±]·Ög;¼)!µ ÄÁ ‚ñ¶«’ñBc:RÍ8åÛÞÓÏ=EÎ~‚¾LQ!K=¨ô;Œfñž†­U[q%J¸-“ÀI‘B+^P¬Û¦OT†£ík²ZX*ù.t†«6çÛÓiNWÜ8YnáÛ–Æ.hƒý U` 3Ù–=ˆ†™  1€J¶eE>2§1Õd¯«´y6Ï`|¶e{˜@}—âÉA¾òÚEj:jlÒ@”–áD,G5³õ³c|{ËÚT˸Ç•ÕMq­£•AJ©Ý<êòd+Ò86— 1ÖÊó½k Å›(@¬± ´œ_¼;»¾¹·µ•Ó}N ,——¦ÑËKYnn^« aïçÞ·Çò¦<t3Yœ³qvd‘€ _5m¹íK?U½<›j‘>! 6)´„õ¤ÍnÒF¡oí¸î|qXâ(5jZ…o.Ôµ@Ê/,´k¤¨ -ÀRFXÅ>ÃUF iJd8QŒVŒÍkàc4ÜÐ5 E«g»C5’åK£®©Ç»¸†6¤måpÙ£Aª*ó‘f£I²‡Ût¸tѵœ@lФÇs°Ã⢻&¼—T.ùÏnL,úóÃó*;Æ;R€C`íY†õ‰ë/È:5z†Ÿf>œŽ›js>c‡µðnÙ½Õ ¢9L¤RŒÃpå®.ß..åðþó‰ rj૟}ZºçÏ_eôº¼ ÄW -¢µX/c´<[þ¬¶ð AÍU¿>ôTû¿X9“À‰¤Mô ,í EY<:G×Ë9²7¥YÕ›BV”>âÚfUQx/AµJt”:G©Ü,+‰qÕº ­Ζê…Ç3ŠˆuHPº>Ê<15 ø§ã×ðjÞPOÑËØ DèýØ ×~‹·BèBÞÚÈ C;küŸô£ÕÏhSa0ü*{¶O…Ú9Ûxlª…ŸB{TÄyÜÑ$&’¿Žûð>Pì37¾*3~&lS‹ §;ù{O@µã™ ôÞƒF‚ âlAÚÎ`á2úOÁOçÒ—Ç8æÅúFcãyú ž´Ñ»ÐÜ¿ïab}Gÿ¡ñÇ‹‹—‡ó39œŸ”Ê|ô9©Þ|ûù??šF¯¯åþíݽ¾&î ìÜežPUÃTù}žžü^§Ò,¶°$®‡rukÜ'(rôš¢t?¤çnqµ 2äf(û5Û‘ïR„㬠wœÂ^™Žì:Gý£0Oí×zCØÂTƒÁWT«f¶ @iÂXb «°hÌд Öø¾í¬×„Ð >±(Ãp,”¹N*ÏzßѲqú„4ZK)MVÉ~ëŸiªLÚóRúÀÁøÍÐ’¡³½2 óK@n´riÆ UM‡B˜¨hO ÄÚ|“äaï[ ƒ3óƒ)öæHrI¾YáÄJz0o†LUmÃý”“£tTc§[6b5K˜*t±ƒŽ MZ<ÌVäbA¼/B£áÃÅÎQ°%VØ›³'×/Ÿ¼x‘f}&ÏI€ïÿÛÿöÑ4zs#föZÏ/@"¡èpe19|âvj•C–bSz~çr+ït¾}l®©^Žã~Vp¹^-’Þ3§I±jÑÀí)„¬–©BRþ=à1è7ºq“Ù¼9è‡xsÖZCyº¡ŒC;}ÿu{†¥H ÂÂKA “ì§·Tx JŠÅ€>í¶ì— f7·\_,YâbÅ-ŽV°áµ3­p²¹•ˬ°ìYÇl²yU<×2± «¼S•?8ò•QÝÃ4ˆØÇÕØfò8å<ÑlXZ·…]wõˆµ¶#^ù`Ž 9Ë•i}»)³ûÞ·ÆDçRbÝKت) ºx 2ï HO€Ëô–Yº¾íÍOæãù¥|ÿþ»×¿ó÷ÿþ§]ü¿ùß>žæ×ä9)püóáÑ4úì™Ü«¾ú`¼C¼ºsCt¸Å¢¤wº=|éìþ§ï(HÊša±-k ¿ðÇ´réC‚—“bû{t6ÌÁ­µp 7úŠÍwqÓíS{óÓ̶t€±ñß:‘¥(ÕÍ2Ö\¿ßÍæ†ùa‡ÿ:v†ç¿É/mÙcwšRšº~*¥ì4µrÒrî=A¡,ñ¨‘ç,ó2/úáiïµ{@ï• åúÝÛb¹Yñ¨XzxõŠé}Šbú°Á€¨ -ù¶Ï†Ì?ÏÀ tÄ>¢5Gò‘ôûȸi"x 7Ä¿&qv>œ2ZÉîÛ Š˜Lž o?ˆàt.W€Dªúh \ŠÀ¸éñm«ƒúBHUwC ‘šD7ÊÍãÌôâ°ÀBõzZô €Ö¯–O M¶â‹™h"qÓ*Õ ¡(ÕRìUÃ?ú˪{:3‡(ìTl ö”ó ÕE€\ŒŸAãÅ> 7-ÑqtjµØÙ•K,s€ø¼P@ ¿±Ò!o0w*Ï´È:±Û´çäö@asŠ(OÔÎ$ºŸ§Ì“G/jfà¼Yó±þy=pÇ€5v:€|©†T¡3¶m59äìúÉëóëëšžîsZàSâ\\ˆÞܾ–ó ‘Ø7û˜6ëÌ-Ü~ØjGœý¯¦©¶3C… 8G®Âm-Ö'¸ÑØû  Û¸Ÿ¹ûß/’8^Æ ‹•?  ¡5ÔòF¥Xú‡?3]ËE," ƒý³©&w”¥IEìÎþˆcÍ<Âip²3zR¸æøw4;KwºM¸Ì›ã^q[!´‰ßR AgsÕ––}ò!*ÿfNÚJ/:ÓÖ¹¾êðHf›NI3(½Î<.€QښѬzžÀôˆM¸kÕ”ö–Øæ3k’Ê_çñ/,‘}¬à€RyvÄÖ.oÒ²4‘½œå× £»1y¨,>± dž/fÚ’@¾ð# -à(æ©ñÜØÝ„UŒ:—ãQŽWW¯grüx!ŸÓsRàðóŸ?šFEäø›¿ùZÎ/¾“ûõRQ ˆOB43rûÔ·¶\ØïFïQÃxº}ìÜŸW¹³5,­°”•'á[|Whû‡UpÀ" ¢ØU2š º´æ=ÇÚöÜÊ A©Ɇi¬ìh×jg:c0Ä;m÷'ŽÙÚ5«®d¸i²Zí4¼xßyÓÜH¦)äÔ¸¹{@+™x-ÁÑ–a¬NG„5J¹6€é«E­,H‘W]…(µêž¤%t5ÑÕd9;“ÃÅÕ+]ÎEßxjÏI€oÿÓÿôñDggbfïôöæ­­ëeê0OÆríP¦t ûñ=þ×<%½Ì‡Ãß'‹&‚5im.¥vUlkÔ‘™*"¶aü@ä-X‹îêÅîϱÊ0C/é&—!ô×ÇÏÂ]›Ñ÷x)GÈúB0ÐZqB~”‚1f“m‘T(h…hèÆ&••>§Z'˜ˆ‰î’BŒTXÕµý¬Äg…¹ÊìLgHΓnÍY …)õïááÌÙ(eŽ ØŽ”倗¿_†ÚNÖH6ž7óv¬|™Ò°½Q·µ º1oßËOë-óêˬùŠoj©VêÕ#£SÐ+Å(ž8T(»îDb©  §mu‘ ¦k»­4玉¬ë*‡Ãñ»‹çÏ^_<öS  _åóáÿ£Ç­«èÏ~þ­^_¿]×õ+gÕ°Ò}“œÍL_§BÝ %Çñs¦[®8Ä DµN¬q8Ô ‘Ø… ìŽdž‰H{kíü]y!ÀDüSÙå!Šê–ƒxš^t)WëšÂ÷VGÎÚ¤¯i©›Ÿ¢¦æªÖßóôÉå<Kq¢5”P”?ë-T$Óûø# ÛU:Ë ç^ëhÔèUêN¡Ž=øþXú‡få¿»€’·6ÝÄ ¨ Ñ¬é±¨šè2ÍË`¢j—Ïûd&‡ËË·o~çx÷ö÷~GÖŸàøwÿÝÇÓüš<'Ÿ@DD¿úêÝÇ¿ó·ïä~DøÈ9ž¸»ËF!'ç'¨{0œ£i”µ÷«’ °¸»=Û€®:nºïø¢Ä„g Ø!¥‹¹±i”ÂzXIŽ,ú˜Tk-Õ•à,¹þ]Më)2;•nìi£óí…ê›\-ÿòR;|2ðÊïpT¿GŠ_ª"U5Ú;ÒˆûQ!Å(M]‰­œÄ³b¿¿-É(@팶çZæê×úK¥‰à¸]Göšz]ÙwÓ„ÀáÂWij4w:žœ†¹äiºù >ÍÏŽ¾y—L˜K ßgÏÈ"HUÛ4ƒ¶¤0ƒ>G]*$Œg …–Ñ5,Ãäxyþöí¿þÿ}ûý›7òøZÍi='–/ "¢_~µêõõ[±Ub@¸ŒŒÖ9úšÀº­GÉ+ðÄ ²Ni¶û«é¬ÂNUÞ&hM†‚V~X#`%ZEÚ¾×Ë€|/ÖZ]GJ²{ÛQÀñËCzR»kÍ‹îñ²¢—Âû¯) ¥Š"ÊÆã ©XœiÔ­Å dCG8WÕc x™{½PY8Î0þTè⪾ývf…x§¨JÿM—m ËØ©lçûñ2\5Ž{¬ŒÍ`£Ðcï¦ `[ƒþ@Oú›âx,ë˜ýX¹¶ºô×AwÓls`yÄ +-X¹½¸æ÷%æë<8šù‰$2UÇ*´ái¶”+çyWoôSàÉy¹²G{9ÝâQþÚåóQkŽ¢"s.ŒI<ŠžÎ-cS]ù7Û¶ ø¨œUôìüîÉû·ÞÝÜÊçöœø„8""úå¢77ïÄÖ˜‘´¡Ä­ e|9›7㱎ɕ¼¼ódµRÒëë¶åYôœlyzvV|¨¸À‰&Ë„1LЬ*ªMHˆ¹±ÔÛi•Y¡iš •2ÃHBvÜÝ^ôs5´Œ^l^,¯ãH-yˆeö ÈÝf@ôøáòŸè û3Ð Å͘|pqxK© ñEå}Þ%T³6ì3ÚfeÙ#Ú`´òþ®#¢‘6¼S鬱±ÎÀÛ—Š]GØ‚ÍJD>ÞtÆJýk›2Wº×áÝ.¦í‹I³_åSʘ£JÌòi­#7iSBm‹ÑßA•ç¿×2á2‚µÊž.³q•€›e’›2!þ5YW“ÃùÅÛógO×ÏÌø‘SŸ@Dd¹}*z}ýjv“ûÎßL»­)-¤]ƒÁAä{nŒª[È:ÅÖMpWˆ5e±Cóväd(‚ŽõõáMh[y㽸=¥Í>HW:E“iJ2Ÿ°òßÄØc!PAÓV\-Ã>Á ÑÞís»­1>.Åp¨² ¶£nù*ÞµAg+ˆ'(fIáÚHºÜ b’±$YÕ€oÓÁƒË' ” ý"À†4‚ $ݰ»8ŸÀ$ õnDë¬a³Xe󢬒<¯ÞlÍ2'ü„KúæÐŠuT7¢«GD&d ^7戧7@±Ë" X;I gr­»ær,>«8z:ú4³*–æ§;´D“$ß«ÏkäÔî‹ÛžúÎårIíEmÕ‹©ƒÓ¢J‹tËÅù»³'Wb>¯«€EN èåÕ§¥;¿¹¾yé’8ŽÁ ‡”Ÿ‰…+C~øa®ÕŠ ÊÞÞ¶gVßøìO·ú¥»ÐëÍŒ)I³F#QŽÔáQ·$.ª»ÁÈú0‘\Ÿžƒh¤ÐÝé²Î­yXÌ×ÐŒÃ/&±‹^wf´ €œN¥­—ÑϨIY¡nºk…²FkW Hä䢕†ÕA.ìºåï´R”âÜ' ÃÅïúo…ru |¢ZA¥àÄ™”¿“„54Lkó:5ÕqEÎ+÷eí] ›t„}>*¹é×{DÍŒO‘(€ì,à›Áüƒ“&S*ç‘2™Ñ“×÷(÷ß‚¢S"Ù]2z ÌÆJw&ê1³•¿6µìïðè<x¸ÎRTü>)9Be…XíU€9žNËä!•åüüÕrv.ËÙ¹|nÏi€ßx<€È°Ö¾xñRÁÕ'†±âAšº!, MIðL~ÁææˆÖU~ß­ä)¶r5aOä=-Â(—=²œ¸÷\T¿x²+¤5廒•ËÝßÑóF»T =Íx"ç~‡›ªÛÕÙ0éUjÛÜ&þk‘Õ™,cÝØÔrÿ…GêDg™\¸ØûÖÚ"ÞÜi¥BÔõ’·*‡àb×KàÙÉ)0”¤ PO`žÃyð^ù›do¾êô‡DDG‚‚ùÎ(ï!00êÝé~‡¹—yq†ƒ]¼ðÂj{ó?Ègx?€Ï›˜=>œÄB7—Âó䊩SôÚ²æïþÙRô¢ãÖ®DdÌš&¿qXéyÝŸ¡_F§ØíhŒy©w/|1Žg•éµÜÁËååËåüâ'ð«~¾û¿ý_?)ÞÜÈúêÕ½} ýºAjû6¯ðkû¥Ü2åÇ_<Û´ë~óÂÑ[EÓR9'ó0 >_ÏÅ aŒ¬¥äp©5+KEã½h¤«ê\[„§}—¦Š¬Æcåh.-Í€û„å4V;Ž #©¶&–A6Ž*{–0Gb̦Æü;7öY­J|ãÝ^û©Z(‡i†eð{"ŒXk˜Õñø+0Qjͪ0ªØÁ¯‡ ç«Ó lyáqPdˆðlycK¬쌷<(‹#[âOgP*“Š©Ê~€ySÿ'}cïàÃ5u“‘åÂ"¼ S=>¾LD%#©Ôc÷áá]™ÏÌDίo^^>ÑznNý9)ðáþÃOJ§WWbï¿£WOD>~JK{*^û»MíÜȾ–lÚ„½ë…fI$³ãM¤±šËÁöZ¬¦Št×V8Q•=(L/b%È–c· ³@ë"×ñL/{ˆzî•¡v"ñT" ËDLîO|…³%aM\ à†°äž$È|6nþšÐHït‘—zxY‰2×ü¬§vê|SåÚ¶ÅŽeHµø¬Šà:Vš$àvgIwºjm)—úØ3Ï$mô …Ö Üí­J` YsJÌ=0í;¾Ê—A¯û¤g:OÝ¥`íú®†¯î6 ö4ûa6©b¥…}/3GôÏè‚©gçgx8Ÿîé–$™ò(Ç«Ïmgì2m|$²\^ȇo¿}ýÿðÊÇoÞ}-Oë9)pöþü'¥Ó›[Y÷w^~XWÑÕò HKײ¢*2MŠz  eHÌV%sµîezÏȘ:MV ]éíÀ4*:Åß&Cµ¦Gˣ⠮“7b7Œ×wUÆ¥<ãÅiû*F®®YY÷»v÷h±Ø£‡ëô*“¥Näô±íL¨9瞬çP£¾B‘Ö››†Áë¼ôƒ ¤¬©(6tyLDZ¼îêê»bª¨DîD0Š7Ø¡nô?:¨½~,2¦PÚþ7:ý×¹8°%ëe@‹m‚Þ:Ây1•iýûÞ±áÆÚ¬–­šôôþÑ.åÛ.!p« kÝÉÓÒgÌ>˜g"zäJf vÑQCX=Þ6à#—•ëøp¼¸ß¿ó‡ÿäËúñƒ|nÏI€OŽp{+ë»w¯åxùø¥™Ä5ªN1e‡=+v´6å©y£E‘gF¿|wFÉ\/‹f—þ›É@9ü:MÜýŽ:µUøxdeø­©´£ÞØ¡°ç}“ô  ›#h“›Spˆƒ¸Û© Ød¡Í’²—…há›S¨ücÄuŒ"hЊâðH­û'¥ÇpoHD¯ì’ñ¶úعÝÈÆÂÑ€fÑ=l/.—AH l‹ƒJÒù¨ !}· ù»ã‚æSZ<¬8—ì<’ªd£Å*«ù™Ñ*Ùø†aâg\ÂÉyâà”Ìy_WP` ^tIT¨s¯ºÝÓ‘w‡òH)±íêm•ý‘Á¦ìU<Ïù×m•*ûc‹#Ô7ÌËÞ¤Q'¹3AÖqaÖÅÓg¯Î¿øBÖ÷ßÉçöœ§Ï>-Ýí­è³çwzvùæ^L¡–s÷{®RÇ5Áº­C±©¢H0…¼h¸‰E6 eàbxrΗ7‹A^?ç 1Ê=j\ì¶މ»´EpáªZRõÒ’vçLÕ’¦(w¯¾£Ú•cZ ²ÓâwÁ m>ÅMD–rN^J]r pà–ø½äHF]·žõ•Œ*ÜcçŸÒcŒIAT”6ôÞ¸Ñ/}ÆÝfÅ€#(C£ÊõþPþiYr ?)ñòê3/„க”fÊÙÆÊÑinI@%I3ÅãoïX!ˆùò:ù°!Q!ßäyBæíŸ“m²¨0ÉNQ»ïÒýÎüÎæLÎ_笼ï)gŽKg—scз¥ôûlÒ¤$1hGz%F¬‡â]¡Ä˜Ì¿a|„íQQ¹[T××oήoäþpZêòSž“êÑrýiqôúFìéÓ×v~.z.žíØí˜‚=X›¥ 4 ‰,¡üÉh£<ˆ¢¹ó7kêñ³ðxA )²âò̺`zRUp9¬Bs@”tò4€ú݉uÊlk²ÆyuìvúLj xܰú2A ‚;)¿Qoµ@«áDq$•è D£IJ®«/ÝI¦*ÓÓ[²9´cdaR¸€R&[p°ì3á5÷~%øEªªy‰îT^C!Í¡¦³•™uìÛ‰;–¿•÷2ÀÆz b°Â{ò‘ƒb|.ó+yÃJ{x}ºh÷¸æ8óP7L*ד¡ÒL)ÍÞ^d€Ê…œ¹2‡•¿ðxO¾„赥̭|È…INñ\’ȹ)SÍÜIé‰*‘’¸7ÈD–ƒ®.ï–«ËÝ£–§üœÐËO»‹Y/.Do®_ëÅÕ{[׋Ã:tÛ˜3KeV¨Î#Ö¹òh}}|©±Lp2º´ÜCµŒ(ú–ÍExÖR̰á?;æÐ;!ºæ”(9ιg!lÕ»bÃõí< "ä%­žS ‚³/f2?Ò—DzG$…¶á¥<%ÕÆZÕ;êØfaÄï#gœ•wDzÍ8Ѳ9œ{þ‘·AFp—Ñv”„ƒ-L Ì0 =V0¾ANŒ÷Lx[Æ|ÏWât5h¼BœƒI7—ñ”é}@7ƒ¶8Ñ'PÁ é±r­DÔmDWô( ¢Ö# ×ò†ÝyªìýÜéîÕ&´gM™KÓzRÍ L¤îûG³þÅ»–æ¹5_¼Õ•É*= Ò[UAÎȦÓ'ÿàÆàr8“ÃåÕ«ÃŹÈÚE»:í礀üü7>)™žŸ‰oôâüÎîï/ü¼2ZRa­Œg•í,€U!, óØÕP"Ù¾m%OåŠË#[Õ•ÉŠg·ºù@P-)Ü{n]tϦ5WòÐÎBPX­IžñÖ®½ ‹ļ¿þ[Ó!E*…òð¹oÜkŸÈƾþÁ4¾Ñ2Š­¹¼¯C…Ë zt(ý¬^ó7¤«¯U7,^"îÜðÀZ3Ó¢,ì,ÆSvG :4Ëè9ÌÜØy?ö5ˆMž€&õ®eˆ¿(1´çë…[«ž:W”¯§©è·ŒåÔNø¶"+`þ  );Ê´`iò"Óf¹žšû^‡î—yÙm–#ºûë¼Lä_÷äèärÉ]Âl‡à_WYÎïço‡ƒØÙi©ËOyNªGßÿg÷“ÒéÙ™Øáð<¹¾S“¯\I¦ˆ5ÛÂÿæDRô^JØ $ÓÕì»ðƒÝ{‚«€+°wSãÏ“ÕP£ÀöOž¬^Ã@@º6´…-“ oÄâ¢0§ëü)s¡S£<齘Ҵ4M“• hXÏSdgi·Miç¤Àòâ‹OOûÕW¢7×w[]‹9¿Ð¤¶ u`²Nºý …‚5˜ÌÿÖ2DÅôV-¢ÛÌÃïì2c¡‚eÀÄÄ8½º ¾Õ-V¸ ˆJBkÑ{†|ßF´\7£F‰T‰…wÂï ~§VRj«#ÃÛnš0B÷†â+j&ÐÙÞÞèNq7%Æ‹Ð,/[kì]5ýƒÕêÊ4ém¼ó;øWiW4§Ðo:Mn£ßÍc@׃ÚthÆ·8ܦ áòý0{@¡ã–}P‘U@}ãæ#+|Dƒbk™Gå¦#5™õÌjËÞLº¤üñ …|¹É†BÔ©V}Ì¡êI+|P‘wß8}mßÞý¶3ºÉVÒ?lËÏjT›Zøh"Ê]nÝö7Jî :’Æa‰¥f(ÚÄV9œŸß]}õóõãÕùŸ“úüÙ§§}ñBôææ-]o‹ÂÆ„£Ù!d†É.XZäR«k™Y#3ûks_@[·Ñ'1*‘iöÁ±,Û¹¸$0°VcÎçÓC@ù¤×ЉWElinBˆ6æ†ÁÐ줹¿ ó)2£“HÜ›mŸ¬ÃJ\˜°;j:Ã+M€AæO›5Lñä5t§G-äMHwåÖ5<ÈSƒ¯h¯A! ÙE­äAˆ¥Ÿ›Q *z8£1XVYœ62G+”A¥ž½MÁ³ËÁñÁ90EüËÁÈ?eÀ{`00ˆ£1¯<<)lIɃdrksL?éc0·€,x £mƒíHÂðä!Ÿø2j)¶1n›©Hc†gìñâžš¦%ýL1™Êt®ÀyšI)oôÑO§Ò •Åð‰¨`0xúWÏÎßž<û Oˆœxrýéi¯¯E¯¯_[(q¶-MÓ7ÈŽ©ûÑjDخĿÕY”e(äÁ2!¾eQ!·?"xЇ…ý%½X,)£TR™ïpñ3úéÖ€¸@/‚IÙÈQä§±5‚¡Z_ÙßÅ8 iGëA‹­íX†+ºÉÀ‰¹Ÿ1ÄxAÙ“@QTþà±/w¡—vl£+Qocw¾I=5@ÀŒ‡‡¹­X€¬%òoŒ™àÇ,% (<¢Ì»{a|K@ãV¬ ýFÔß O0ï`tJ!å¼ÑèïaÐ1=RæÆß*6Ðl*9ÖÓ,Cq,ú¥ŠKÑtºŽÛCʾ!Öö©Z쳃„@­ˆÐÂF™9…öj=*O#hm9sC•ÒÔeJSí{†Ð2EQwðÔ 9žÔp=?{³<¹’å3 ,rb@>1À–öRôúúk‹ˆJB,-A“âTå§Fk¬Xªå#[€ŠîÞÊ£zò´º5\Sä y§u+«â¨š‰Ù¦ 𱺨%­Së ïC ÷%™…|¬«w!–Ô ›³"ªø™nÛ–^ÒeÒD%„“Öá5ȤšVPŒ ']ÍJ¶d4ÕZ+¶r0™Ò@h Q?¶i ¦¤Ôäç2Üô‡2ÑXQ¤Àß™aÓð”?Ú€%Íp@i™,´+ÿÑv•à«-;ÃfU‡`@¿3!Öd‚à¥XLl<úà-·Rø¸h÷I —1í©Ú\)Î5ÄWUØzÁÞ×:²&˜õ”Çç!y*Á¦» JS`Ëçöyxz–‹‹×Ëù¹,çŸßUÀ"'ô㈈èÅ…È—_}ŠÑ Òš?@¨>PÑdEò)Lb·r‚Ë-ä8ìôµüÅ ¾èI'qSš.mÍ<™ß_ª¾TL°cLÒ]Wµ‹ÓÑ®—U œ”¹v„%Uê»Në°È¥.Ëi2îÂáÆh/dd| [°€®íYÃ’$¸âÍ ¬àÆG%¶·ƒI»Yù0Éé"Fd^Sèœô„vV³°Q&ûã‰?Vúî þÇ*Cºu<žï ãómWðr”QÑ[„|†>‰\ï϶6Êß5O’ȃÓIýàz3ŬþÜy ZÒÛôÖQ8Úï{°¾M2£šeõ¶Æs*òXŽNŒåHnà«DŒŽ.¢ç_Ëñ(r<)UùÉÏIõêÃþŸrZ}ö\ÖW/_Ëíml®QÝÖzÖÁ¦™£ÉWŽÜÓ«#v<¾S]U{VÏCBpÆÌä k¢(º]¡©`„YS¾çv+‡cgí –O°6Kák-“4D#q9ï:˜«šFGEòFÞå›+y{Ç,'}ºC9o!Ñ™‚¶o|„Ÿ°iþ›sE:Ÿî_\õXнz?§ ¶4„œÒ( ´l®¥="…ÏJ;ºÅSEóhî¶M¿í ó•æKü»Ô½3b‶$ ø|ȃËc{vAÜËà•5Ê—O_ðmŠâFƒÂï8 *dH8OUíQ:FDë8}êù>ò¶ÍzD¯iƒàlÏԤط'¦y}"BïÈ7É@W*‘fc Žïé|‡«'_Ÿ]_o!å?Ãç¤ÀÇÿò|zâ³3‘ïäöVäí[Ù.’®Ö°àÆ£y3^N&mQ¶OÈ jaAžeÌPÕŠëÅZ—^@NÐ °†ÂWéOj"¶„ëWic˜§w«¾ZFK ÄDÀÜ®OJ¨\i}XhUš-Šk–inc½eŒ éÓB×Vz¥•zV‹pÅ·ü—¼?}˜ùØŽ¾ÊÖ GKwe’Ø÷R¬[5´„ö4S@%aI9 –»mEúbÿã3ÒUQÌ÷ʃã9ÿ»Ú±˜·èü¤šTØêsð —ù¾žA8ªIä1Óg*ÍOÁÞA.—8+<cplæ‰zCÊ) ¤iY©\x$C£†NóüíNÛwqS1EȰ¶cèÓòM£L—Ãè]Hnìögd<Öà“d¥â 2Y.Îe}ÿÝëoþÙ?“ûo¿•Ïñ9)ðCâ,W—rÿõׯ7T¿±Ç*& „6ÝãëzÁ8t?¬ÖFY Ö”RvÜl9òƒB?õå°#(Å×`P‘"𽱩›ûbCµk+þ8NæYVwæèL¬%{ aé€ûÃ-N”qPµŒ7\é[hS¤Žþ‚2èܨ"Óo 6ívðùùÔS Ô}Qï :h(4EZ—&’ña«Îµ©á%)´”­ ‘¤¡byNfgÖR~ÚÒqßæC÷.9•ä!¾—a¥Ì4ŸcÃ_M›-]ùó9ÍŒè·Ðìb ÏS.Àå\,“vîÈæ5Ò*!ÀdÝ;zrøÈ»€Î)xÇæLø¡åÅf•éé2ŽG… ÅdIœÊèWOËÁ(\w‰ QÊÜ+ׯÿÀ+ÌLôâB>|ûÍÝ«òOÄÖŸ<¿ògyþâ“Óê“'²¬òFgb«Å•¾+ ±ajÊjw­[HÎÓ[8Íáœû\¶í÷á@ÕbÞÆRŒƒC†ãïÕ–ÚQþå×M˜¸'À²µb”˜UåÕE&Ñ4H× FðÍÒ ŒÅVÌè½É‚RÈÉWo‚ƒ –*p(ØRÜ-³oœ[â§Fùs4·æ>«=ç±™\Þd‘×& R°.‰>Üëíñ²„Äà¡0Ôƒã›õÄ%[ATFó2Ú’@aJ0ˆiè2 Tl ´l³œ§SÁò_ó56FÍ@¿X­Ž˜Šæ¼QPpæéph½è'ðKçe¹„ÎþÓQe4‹scÝZVWÎÕŠƒçÔÌUÔ_oïX&oo_®žˆýt àWÿèíí§§½~"úñÃ9;]ïaBäN൮cƒa„¬€Œ¿"j^C¥>…?ç„À3´ˆ¥ýûvP›ëqge="ÂÔlPÕÇ7QD ‹@ w t½vMz¹ä«kÕÉ[ð°fú±ïÍô¥Sûa1A×÷¡ýŠ­–nLÕ¾ïÐë¡ìEÐm> õÊ–ÅR.k¸w§Ûh}™èËßXLzà¿ÛyÆxÁ:Ë퀻:„5²¢|v‚)PG¸òEM»æýŽwlj$&àË€|øº² y oT¬Ûòc¬y ø§Mi[°¯óSHó¹68Á辰f®O˜ †MêÔ)ôá×™_w`V™[Ðë°óôÜPStfTuÊ”ùPŒ¼mž›è²ÈñêêÍru)öáðƒÛ{ Ïi€››OOûä‰èÇû7zyñ½­v®"y‹]¸µüŸUV[À%œþ4œŒ',ÿM=Ï1ªjt3‰TžÕŒ”¿\LúY,ø/…À•Ô|R-Ūí¼£åT¬kG\Ðßâ%pSòY¨ 4A]!„éóW§ÍFץРË'UaNg_X¸ù*aIUŰ@SY4TJ5ëu ‚J –ü÷±Îñ ˆ,FÎuæýBƒ)>ãBW\óv¾$ÁŒ›¬²ÿ¾ÁÍœÇDú ':ÏÐh‹a¹„*¸œçQVþØ/KCYÂæ%Z9ð•å&É «°]´]Ü”y*H®@?צÓ°]þÃØ4-Ú[üôn¦x‰+4±+yz‚¿æÙ¸÷dºùàÖ‚]PTó¦·æpMÉh†Í¾#æ6¸hJHE2Üa‘åâòn¹¸[~¿úçö€Eßèåå[[ïG a£P¶*›ûvYDd·¦á~¶„'^ÀƒË][y¸¾ÉŸ<00 Ø3œ1˜Yè¨RÚ–°ñëNeœÈU ù.Â'„A”¯™À&³*¤6Ò£ÉJ­š|s§ówŒÌ†Á¤XÏØ‰ÞÙŽÞ:Q&ðD!a!ë±rÃæF´©&ï´½ŠØPŸÆ$ŸÇ;-°!:5ϳ»7,Â%+äø>cÂ*=ŠÊºK‹jPŸ9êD×#œGM` i@Ö®šc#îáë÷| S¢*»á·ˆ<5àF,ƈ$uw{x”y)Ý'ÍVO2My':W€ÐTÓ‰†i Ê7ôÔ0Fºþ2ÏòZ,Ê-9t*£ž4àæUj¶…½ª à7¼b«èáðAÎÏßèÙ±;ŸÇsR@ï@8ÆEdyc¯m½ÿÂ~*UÇæ2ÜúnåV‡l©“”mU¥ÍMéÖO;~Û¸b!Gëb*Ý~~æ,žT4Ð7¶Ä¯®•àò#LO(ýh­Ilp㫬x²¡Ê¦#g<‰;Ç«ØyRhGêr®ËW&A¡+”:×in B=ªY¦äqÀ$Ͱ„l «iųȽˆ ˆTCœ¦è^-y yÄ;•q &áVÖGÃ5sÞÞUs‰vRÁÉ,”+”ˆË¸ÏãÅ\Ã[¾p>*}HÈ$–Ó VËò1O™‡}RËbž+"ÍA@“lÕÒK5´] §£×Ñ_ÃÊ.¬3ŠŸÀ€4i&L‰$— štu¤¬üÒïJÁwkJ«uÌi°ôlt9ÚNAÊêað¶šØÙÙÝáâüõrv&ŸësR໿úzbѧ·ïåââ­,`¶hªätDZÝK`œ@3dÁt×ù ½3cXÑ:»Õ“rÎ~)Þ04--O åF7*ÞÓfâAN¸øyeT<êt×¢‰ŽX3© `¡—&ðsôvO±ÏýM)EÆ8íq0rdú ´té*Œ {x'qV&ÅÆ:]Ww«Š´£[“¬T¿+)nèìØÌvmžª-Å2JVÍS ¼Á  JÕ¹èÑX™æÑìüÁ³[¦ ˜'pFôÝÌW¬ Ok¨lë÷PþŽöd/Üüy|¯„׃ÅL·‰XCCŸ´³_)êo¤^äéÂÈ)|FŽšRýîD´¡. ¡Sì©rÝ}ßiÄ#_ŒþµÝÝ|ó„›Ã`YEgoôxv'ª¢K{¾ù䟓rüë0f"—¢OžÜÉ=»æÄ6W´Ÿ-Göͬ)±7å>D¾ÁuCóML° ÚŸ÷h Ný®¯ªº€—ml<^D(GÞ ”–ò–o³«,Û¾\£Ñ%éV.JÿâØ4+ðÆóüÿÌo°‚F£Y”©š@t¶q<ÊaO•KeVˆÊió9µ—úèaúÙTÃCO: cˆl8ÌDmì/ZY‡»·ÿôŸ~·~ÿý'ÖszÏI€åÿñ–þ«ŸÉý“ë×¶‚“ol!ÁàÓוzl”åO܇Êm(ƒÊ˜k*-»„J)Ä[;©ÈøäI ”¿`»`ç³ œ¯çxò[?R*€°I/sèRÁ)´CÄ]ÛÁô/èîkwpéPgŠ6 Ç…iœ"Ž3„ °C[p0 ¢A4<ŒÀžƒ­ ÷”\tÑu†>Íœç©VKœ+6hªŽJ@è· g˜›X ÷B$ùyöWøfZ‡ÎãóIƒˆ]J<1Úß¾c¬r@”sàãpgnúE Æ  ^"Ö8^©FûV:w Ꞇ¢°EÖwï!„aýƒŠ»kêü;ò@ò#[ã³èêõß’`·³#d_¯Õ:Pü™‰w«™¬><æª8Ù礀þ€8""úÅ—¢××oeõ“ûŒ¤ÝN?K®Éh!¨a&ùq¬°—ÝÂ4^Ïì욊ug[‰Ùz¦Y_ÙE7UâZƒYž3 ö7Ÿ¦Ãƒ0` ¡úéš•zd¤‘±ã:­p­²Ï+ÍŒÿî)h­1M]9ø¸’hð–¥D««%_ˆÈuô­á«HÖéåvÌT‚OÄ6<º ôÞ@X¢2=¶p ë¯Ê4غ¾¦‚àꆙFóx±9‰‘2kýÄÕ©ˆyÓgwûÜÞÙýM€'<*>¿‰È“W‚U÷ç•+ÿ˜îöpÝÌ(€×b9;yžY浦 h€Þ Ú{Sb¬b²£›j*·³­‚“y€Ÿ ÕMÆi–Þrï< :ÙoºµßC~4óˆ¸Ðé»®¢ggoŽOŸÉzvRjò='Õ³åéÓ–þÙ3Ñ››»Œô¥E¦!{àæ®)„ϰðbífaª±.6‹IHAˆkû`‹¶“l›ð|¶ؤ­Ï-HIÁ(;vKË ‰9@’ÌS…_sï*©\DŠð‡:øa+›7øÕ`,MDµi¼¶ý* @¨ý§ZúÞ8»­ÓÄ»èG({ÃÏ&ÚTŠ8o’‡e…v°h€×MàyЪdkìpwp• Ö˜,#ú”ù4!QÒ?Úk{Cfå¯Í_•H5²¯éݦ,0±ÿ–ÊÎÛæËaN×%q4²Ä†²¹¬P«“Øò_§RЋ;agôvt×cF؈ýà—¿˜ˆ®²ÆXà@ º\Øb„¸%Ka Ü-ƒÁ“Ÿ½m>˜Þ<˜iM:¥ƒz+‘öYïø éx 2'Λ:W”Ç»–Y¦AÍ:éýÚŽoÕs7Ÿ>Orµ¶ >°÷ââÍòäRlý üZ})˒뫘}Ž)[ e. ¤Ô¬ü1ˆ ³…òhËðuFvo9wQÊóeD´O r}LÂR (Z±ZÚ«ãâœ8£"ƒJ×eVãÍá–@SwéSÞG%áZö˜å YPÀJS—ÞØ'L¤íUYÈP™ÅÊO á^•kÊÍi%&èÇT›rhU‘Ê`x=\°+XŽÆ]Ì4#Å¢Ò:G4óVêÍß|¼¬MSyqå\t—{ç pØÈãåñøfb¶Ù_Ð¥Ÿ¨RúnZcÛ\ CLºlÆ¿•©7…ýoè@§’ yú½2‚s1­ä¶ŒŒ ‚’T€ óïU›öet á±Gý¸`ý¡œ«`N¨Êr~öRGÑãOÇ=žÀ(""b«ØÅÅ×v<]‚¢èÒóSùi­u†»«;«ºUÊÙqi&“Teaåúæ2&#Í à$òÅ¥'ðC'ù°&¸è&—S$êH%}ò+Q™$«uÁ¯ãåÚ„Uyú¨]Ц(êRt¾¿ƒõih#šÔ£aPJ¿•…cKölùøBMn[D™Î9*ÐV]ÆfÊ™Bƒdy¸…7R:OŸˆƒ"Å!„Ì{%ðýa ìQ¥8.¥üGÿ"ê¡+˜8†• õ¯,‚‹ rUß´oü¡ ²©üY‘ÔtYΰœ\ØDŠ,§A˜Ñ[Ð4÷[Ò‘÷ܰÆ[?'ÎÇð Üßì –F˜ åP¬(¿ÄŽÏ¦ÌQÈœë0ý»=Eýlߌ…VÓû¬Kº€@¦¥ƒaå.46+Qº7ùü¯T~ Þ]û%t ,´…‹ ^Û”f¶üç‚Êá2Kñþ®0ë8¨Ïædßy’àÕÔh?Öˆ”º“';ŽEéVË(c®É+s[Q)#Ún 3±œìxÉh¨ü½ òº©´so2Nð[õV`÷>!ï£X,Ïä#*máÕ ld9;ÿZ–ƒÈáó ,rb€,—OIÿñ£èÅåÏEìív\6Aeë@ڱ˺J°QýÍv~ öãÓu)‚ ÕyZùùÏ µçÞüó%8|7ÙÛù»×f\gXÎü¼Ž÷ð°Bs€ D£é‚ßôj$=%.„zOBµ­VPRŽwêH#~f lµ`$§ÒXù Ü!e!½QÑ»gJçEñdF*QtL˜íõ$Âß°;ÕÃ0=ÀW¡ð 3ìy$j|I3“åâJ>¼~sw÷þk‘ûÏó*`‘‡?ù'~X†³s±oß½‘Eá"› ±šó|P‚¡Cè•o[V-;ƒÙb÷Gᢎ ‡ÊgW¹¾¹µÆïÀrQ$Ówp5ª7Ö]yÒ°qônSÿ„&@º ©oðnuR;³߅@<$,p’Ï7ŒOÿ*[ñÙV^(s<ñÆGÿ¸pSÀÏ MÁ¥25 R°Ý´M—"Ø=þí„»Ô=$yµÑX°tƒ!7«æh!â€~PÛH–aºƒqìt74.;z™GOë@b. ±ythk­J¸¦§µv/u0§Ï <³zl·Ù=ešƒ9Ê£aTÏà4dž~'¥ìKN OÏ_S—_©Œƒ¯¼©H³Fþ­Ê"l}Ñ’äˆ,( tÏŠVI€©æÉwƒ4e#ƒfJN0²E P†€ÑP™÷°ˆªÜɇ÷bëAbÏI}þÅJo¢ß\¾‘³3÷æLw¬ ‰Ì¢…kÔÎŒ]”>2jÆÏÉYLU:*®É÷&|¯ÇYWÝúlØq„À¥Z­7Ö.u ‹é‹Ä[mÍ……K@õì²w…-õÑ…®š”. úI"޽”¶âX”hDÞ. ‚eF´êpìØSL¡ ‚ü2ÛhZJ­,k_NÊd+õV¿Í ‘oè3²Vš—–“ïáìŒÄ*É=¢-¼Z0b-ˆú¸s¾X²CH‚ÊþÜ.)YŠ ŠÊßëò[ýB×MÈ7ùŽÊ‚ÖÈc¸ÜÒ¯ãÇè hÜLPêuù”s†Ë0€†¨˜‚ù—7ã! ð,§Ô˜Öh£’&)f̃èú·RF€)‹.±¥¯MžQIÛ½DLÜvšè“õ†m9Ü\¿Ñã™ØO€_ç‡ÆË ‘ó³·rvþQÖûcj]_ч‹t»p»ÔEYÀ¡Ñš $ lâ=ÿ›?æ’ñKo‘õჹޜX¹æO*Ô¸&Þm\ô‘_e£‘¢.@?b*?bE½Q8¦ˆž&µˆà½èYµ]Y ÏúøÆ¦E/E©2ç†Q˜TJ6Nò˜*®°Še£Yêþ1^å¶D§6•) ¹qêbü⡈‹röcy±qH[MÒYY/Ç>°âMõßü6Ý(+J~óþ¥Hë×ú£øþ„= OÌK]cÌœ ¹jÞÀ qä¶r!§$’cÆÊR1w%€Àr+('IdéP5)ÖeúÀùä.ePÿ ø\KBÚl\&Wy¯NŠú­éÞdæw ³K^ǰxzaÆ/ =*zqùFÇŸ–~]žå漸;;»ÓËó·ëº>þŒÝç\Dª‚a1âO¦ÊKMæfu•ßs}»÷$CâVºA°vùÆÞ‰*<ÙÞ¥ü!¯“Ft:7³Yb•Z0qBv©Qivr Wü¾µÉ]7¹3?ö"@(Èn©´ˆua‰„@«Ž¤F VGsuþâñU ËÃýô1Cð€Êbô' ÜrKi*¶¼åĽ¨„>¤rZ™4aÑ•!ªúºŽo7®L -9ºÂzo@r°HÎÕês±gÅ…"ˆ ëY"ئü‹=J´°ÄØ7¤—R¨äæ¬ÀºiàšÿM½æMm~0C5WPÒt³ÛȇyZžiدe÷÷ÈÞÕ”üûóÌDõðq¹¸¸Óãñ'À¯Ë³\_ÿ ôzq.vyñZ®ž¼–ûûç™Î-§!ÖÔ-8¿É§$BÖ¥‚.’âƒý¥˜_âú ¥* ÑÔâzã ‡[gØç€>5X:Ð(Ö¢ã”4Õ·!ª˜ŽÅk؈Öh T rÔ$  )èMdK…š×¶zÓ°ô±q·éØI¡¥(Lu–#èÃ1Ι)Jc™DE¶«“Xö[¼ÛpÚL¦RÛ  5=!Ñœ5= ÞÿžQØÊmXŒEuÉ+2ì¶±2úWXM!–@|*-èÊ«hÞyǤe釬zµÁ9Ô ö¯Œ8/† íð¼W½„Â̹ÈÞ O@ôØ$€)M ÍÁJС1Þ„Ë’ç}¹mžXɯ#°б.9…Œ£†àÌÀz‹·”0‹©¢§V7Ä{¿ïä V(€Ú‡&y»Q@Úàœåx|«çgot9ì[-ŸÁsR@Ž?°¹‡ƒÈÙÙ·ruõ:Bs®V¸ícƒ¿p⽯väkÞÿ-©ßÃÂ,†AX ðM¤(Cƒ(r0ß<ÍRÞ7AÆ{öìèév®aÚPtƒ(f>÷¾¡æB“±4tl&hü†Â…Dü(k6Š…_„š¹³0g54ÿ†Jxqe9 °[{M!…‚¿§Eî@ïÜ•ZøwYØ‘ŠxôÏ»1üY…ñ\öØ-™t @úœ'>Þ8¯`.µÏ¾äŸs6šbÒ0Wc€3”wF4,{„]ø†õHÎ_>€^™Æðµó¸ä©ñ0l.zú°•ƒ´§.7^œibáœü xl±þ܃SІÏ(Á^3¨kutxOš4å}ÚŒŽÌöŠQeè>‘³ã=ïT—|ÏI€oÿÚ_ûaTDnoE‡·[0‡dàjm£½’ˆ\’‰f¬ã|ÍéGJ.0ªß+ûqÔñDܹy/-WdÓÞŸÑ6+Ê׮ѣ]ч-®!Z=.<\ù§0ôM‚XÖ°`FÍuîݼŠ]ÆÂh8Zn¨±’ÑCß ÏÃõ²}cÏnÛ•ŽËQ©Å̫ʡJ¨@÷ž8Ù‘`h¾MÑðn~µ´Oq_> ēԃ•Ç“,] _ô)R¼©ç{k0ZZþAЋ"¼æŸ#ˆq p:¼Läå@®¡45xlõ9`蕨 N|XòŸ’``5…:]€ýÅ4BõšX5ÁËÂ:Cñ’&Ñ/dhÆ ÛVy-ßã–@¬½ÉÅïŸu¬)6a”›û°ñámXEŽÇ×z~þ˜”c.Ÿ×sRÀ¾ÿîçYž\‰^^½1[ÉBÉ!àì9Aý]ÁùæÉ‚±PqôsŒ>Ã)ß3˼JØ'Û:Êð‹_èÂðb„ðû’ÂÐá£_qï½¥•+Ïå@Ñ›MD¹f2˜6ŒÕ±'ªîÙçàFÆÅi8ÜqìZ3¡³ö «FãËEÕ‹}ž8¨~SâE't®3txÄPÃ]Ë`Ï 3q`"`?¦i1ž@¥Éâ/ Ψ°œ?Fy/ã= )<áx=ÛY6&…– ¯»å¤ÜZ_¤ì °‘7‹Y¡ÄüN åΛ“÷(Wh£)ß™ÿÜÄRFó “†âÆÈŠÉÇ ˆDçç¤Àòâ‡ÅÙÀr{û:ÏÍ¥0@tî šü]`%›bde Оš]¦AþnÑ /Alù|­–o_ËÀ!jO ™ËhIÞb¸½§"-5aé¸$oø B(¥´,DIrvIê‡~Ѥ‰”hô¶ý­¹q‰ƒ ‘-MF„RC$ÀB›4p°¶yYEBHd•ŒPiÔ<éqBXd4–ñ-,ôbŒ)näá8ŠTéSÐkÍã`nÒS mºw>!‡òm×øRn764À:*CÿÌà[º©:VÓ*<‰(òäs€/:‘µäQ(s.C…­øäqî.ªVšÂ¨æÁ»7…ø¨'NñL`µ2¶Á ÕæVJÏ€V#±|«ä(évBF„”Ë6šèùÙ›³§Oe=ÿ|/91 ?4€ˆè³§²ÜÞÞmº`ÎÆ°Ó—8ÏWOü&Ò¯+OÜN/Z)CKžºÃ.þÁ‚¼­£(¤=!mÂ2VkÈ…&qÜLqÖ*x˜Ž:ÖÀµš¨ÆÄ×4¹ç¿Õ¨ñ7ÚºQq Üñ•F³¡o¼C…šï)äÙ4Ö–§2Ü!pϤ¶á²¯Q Sáx€;$’9Ó}Ÿ#°u†6äB³8$ò ÷/1€,+<£õ›P»+¯y ¨Ž3õìøF/ÏEíó½ XäÔÀÕ;ynn¾–ÃAd5±¥Šz‰÷°„ý±œ(l(\Œá½ÅÊÉÊ;©!`l>çÏØ[Ck‘¢äÎUÁ“ Yk‰Ì@QáF?¬'Ê pfØz|Œ6ÉA1Ò&×l_¿Û=÷t¯S1EÃN–bEkÙÞ¹^xv !çÕåû$rYÈ N¶Œ ”.ÊémeªQ•f¥e½8I™Y‰Ÿ\9Ô’2él3 ú#­¾Q%ÒŒî/hÊà¯;ƒÑ´£BµÜ‹]®`–¿™Ž!~GQ­g䘔}n6vë;Ày`æÛjÚö˜f¸ýëÄ©À Û>+vµnôËÚƒÑu*#NMJFš@ôl8]‘I™k ˆçÑîß)CŒ§UL°ìºËg½³ó7ËÅÅgHäÄÀáæÉʳ<}úµ"ë*¶,),r6R¼ëí+[þÕÚVƒKyÒt {»²¥_ýY£ßê(­S}³6q³@½}¬ÀÌ“J@@h>T{$Øáܰ*‡B ²„Âm@ïBkÓŠ™0-ù ‹¢VPRƒÜ%ÃVŸúã9xO‘Ç'-<º2ä#ø!ÇÀ2ÙhÂpÉ•Å4îãW$«p÷òU“ñ‹Ð\6:†Pží/¾”ž4T8Ä+Œ ÎFlÊž OÖøkG‚…7qC(¤jœ$š¹ÊöË€pט ¥ 5eE?Àö i$h.Þ[e¢E[%ãT+¾Æ˜‰’¶òà¼Aë¿ÝÀ)¯Æãü¾JDT)ÊŸƒ+ÅûðTð Žï þ ™o‡Žå2\¶ƒoqÌÖ¸ù=\g6±½ßÊ·8Þ|vöoäpùŒ¯91°\\þð<ç²ÜÞ|-Çã!ƒÁcmsÎÄl‘<¯&á,Œ4­ò"š%o+NÝBœÄ¹45´ÌªÐÞ8ÏNÓNÒÚ’%Y èÜ4˜–-Ë#¼/a› Š7¡è4Ë54·r1j ƒ†©ËÅØHa"Ù÷jA±·Àå‹`ÏAž ƒ¼Ð •”[,•Î80,ØsÙcx ‘9¶÷ÏKa0\kìè ‚40 H X¨m½´„xˆÅ¯!×ík¶ž¹½Ø×ñûžíO¿”ù)’p+»œÊqãÉä͸ˆâX0§·ôÎ(L)·Kiàr£î Qæ ÒãÑ?߇c¥? rã¢àïí6°i‚Ô¤‘ßMše¸´ ïˆ{® ¸P8ÊAûÍß(RPsLB6 ‡Ò3ŸRyÉŠæÞ|sU]# ¹%˜êŽ,è ^ M\À¦‘‰b]Ó’¨AqªsÍ[ÑP)WàãÖI¥–«~\\‚Hõ¸ ï¼&ÃMÊÏd!Ö 'aQ$ÈÈ}[™*:¢2؉û´g\+ý¥å­´Y‡Y[ òoj 7ʽ€wm†X£6l²{,Š2,õ8è4™ç¶¬.ø¾Ú ­D â%uXÛ0KŠB­´Çz˜×ŽeÍc{y²?Óùst© ``ÅͰÅ×ïs¾XÇYTh¦bl½I؉2º‰@»l¿ŒíY…e§ä¦GJù,¸ÉÕJ„RáßôâBî_¿¹ûæ·[äþó½ XäÄÀÙŸü?¢‡g"÷ïÞ/*뺩;Œ)Oh¬~óÆ=ÿžŽîÙ*±æÍ4ª.†\ëVæv²x-y &7¶o!–ƺ"\ 8È’Kl¸"Â.L9›æ\±.þXS¨ÈX†åa£øëÄ%À¨Ïx ä*e^mÏyŒò—É ÑHŽ©l7êˆýêéYp') v`lÜô;¶›~©[ìä87ÀE<à4ØF´»´“³YÜà+ÈaÑŠ :ô÷è[>ÜaƒÜÇ‚Ÿ<Êš)y|ùÒ%˜} ­G,&»ù¸ª–ÿLäÀ´]¡hŠò$!¯¢íóÁþ1+]æþ‚vlÛc…ÁÑ„gѤ@£^îKöÈSL£YƦžD©K)]ž‘Ê奥¼V _ÒØ™i=ÄÌîÖo¾¡±üŸ“úìÅèáQÄÖ;9?/«]è¢bÎ*ºDG¤»âÍKAŽ›PDbΙG@¾â®ÚÊÂü'S1zÞDò:åÉ©:çñ¿¼mËü|Ì Üg#9zD¶o ÙôÚ>ÂÑ´Ù>7œS`ñ¼[÷ø˜”¤ »ƒ{ÓÖµ0'·£ŽÙv“…$0öÁÏÜnˆŠ-€‘/…(©èá&‡ŒØÿYæv¯Ù׌,#¢®u?Ö7+¨¹<&¸‘Ú^Í|eŒáV­r›7>ÂÍ^O·¬vàZîÀÊÓ oÆ{‚¹í*½1ªà‰} ®,© ‰9^7Î&_ð IÃÒVÿ õ&u Œð8,°Üà—Y¡•›²†,ŸgÃMî¡Â§0ÁólõWùa§ó*8¼/î)‘¿*'ªšF—ÁwD`Ð4Èb,sȃÙfùmkø•å³’Ç—AuˆŽ­¼'WotY|î³}N žýˆ8Ç£˜Ø\\|cëýÎÙDð)¼ ƒqµŠ¦ufl=ãò±ÚÚ¤é,ÏÙ––;×Sóù_‘Qtz¹0v_ü”ýËÎ1ÅR%OdÏ´l{)øWŸt0ùÝhõv€n§ hpf½ï;öo©8åÀ\Ô[ÊèìâîÁïÖ·î¦tÚ¥Ìu!çÇÝSÛÐJÉ«Wš¶ßØ‘'"1Ù}…žùfæåb A Ëä]SÙ å_@äÜÔy/B7¾•Ï`’‡§Aðò- KCî%²¢¨¼)ד§~¼»¾áÍ„ú§B+±«e̽÷ý PHx‹ÚæŠ|ë/ó 2ÿŠÚ¼ÈB÷„õ'A!}i»Y;3êxVPÒ8~JDÖ:Œ¯óZÄyò„ =ŒA¢ÔÍ@9¼_./ïDõ'ðëô,×W?8bËr§—Wodµ6Å×ñ³S¾P /A+î-rK ðé¾ÛŸmÖ¬·NÊA¡“ ÄI§ Àá%>[LX¦g€w'a ]ˆ Šð&#/O:'-~3^šèqáùØfŽÚÐÑoëcÝÙí´PIÙÅš+?±xaú"rœáCº7!aR<Ùts“+r‹Ê^Øj[šJa-!ðDÇÜ<Ÿ"£²ñFmØ{‹ñÚ–5 0ÑŒŠ­¿tÀ«Å0ÄjƒG—y¹ ú϶œ†à7&BªkRk´ÁDØ-¼} â嬰ÁÍÿÞÔ½S[Ǭ®<…‹íêhëoCÏJm#py"=¼e ¸ýê`\ [UãQ(A¥=iªò÷uÇ  º¼=¨xü&x$2{[”èžÞ ….ÙªºÆç .E,r yÔ }ŒÉGYƒ•½¹Ý›ù† ÑNHe‰<؉(M³E¥/'à°hÒ"ulDýW ue«©^‰lݼ½+y±r}ô×sÎÇ-°[­â€4 +Êb47°ÆE]â›m·N«ŸœÐ\èÊ`J¸ïG ‡îé@:Üë +—ÏV&³Er.À@oHs^ñdšPâò©Â4웈½ÚFBºû{÷ôà.e `AàçT9°ro¶åz<¾ÒãáƒÒgúœ¸ûOþ“œGUDnnÅLÞèùYkñ0–(<âÞV€°e<&JZ½TY7ž]¼Iõ^7²àò'ßñtl]"àÔµE;ˆ—<£íNÞÆ“-Ïøb‘šS°Ý| õ›]ÞÛlÔ±…9÷À€Jñ¢:¥Ó”Žz*¥‚Ô;ó0⌷R&ƒ¡îý1Oµµ¼§ò¸"dÜÈ4æ|ĘÆ&Ç€>¯õâRäþc(ŸÝsRàþåË‘ËD×UôòâÍ*Û¹há$òNqä/PÙÏ(¹½Ø­]‚ýfK“]–U± ½ÏiªfŠªüûéWwgK¸ÐðÀÒ¶¡l¶Øb­ÍßGŽmcÎ*®å)[T¥Óò&5w75GÙ!€Ã굿HÂi¼ÐJßTºóÈ"`Lé –â(ÉÚ‰Íhw!œÆ  &#¸©.•¥Ûöl(ËÛh(Xþ õ23¨@…3šã«ñ/»è·ñÍÑ4A~õÂøÈiŒ¦ÂÁ¢†žñ2Jš°Ø~‚yüžŒD³©ç^Ükûm$ßu…þxké/²=¾æ`!Oð¹H³ *qä34k „q­¹°v¥åÔ†]'BÐ6Ú©ãÒ©ìŸï­Ø6¬:àÇMŸì…Ö1‘»ïÿÅ¿ûøa¿ŸÉsRàìOÿ©•oùâ yÿ;¿óRÖû`?¿ò5†'="ÛòOðÍÞøQq¿ Ÿ2˜ö*rç³†Ç ëÀ{€Yž“²÷6”YS»ñx›p ÝhC]hòT%¨+f´à‘z§°žSï«Ç̨¿áÈÙáÉ|«¦†÷2jòwáHçȯÀŸÀÇ—"ïZF½óÙTï<u90ï•@:+”9ïG ²—åõÇo¾ûþ{ùÜŸ“Ëóç?.ß‹¢Ooß„ð×áÆÀ°6F Õ1,Ç…M„UE&VÄÔpc\BC%êÈ8Q,’ÊMHõ@„Á–p_9sy侫—Y‚¶ÐTê#‚è£L×ù"MØŠ¯q˜`×Yù–])0Ä‘\aÑ’Æщñ g?÷½ð X±¼a·S¨FôâÿúÚPð ÆÜÁ ®Bƒf½¸ÌrúúÕ´~½×Ödò†¨ë4à̉ñ½´*Mªå=óêlÂp(홯*¿hSî<±2*z¡­­—ÛPÏt­A×®Þ¦L Oqvþz¹¹{ÿ^>÷礀ÞÞþè|z{ûÚ–Eâ–*z,Ür9m·4KÈVciRñ²Hc[¹×5[t@ÇÓôé§’‚5¥ÓôÂ:úP+Ü®YèWdŠ,' [n)Lç^ºúÌÙÜŸ) b½µìÇ–^@Y£+ÖŸ!ôR,öÒæñôé¤S´.àåp„çMvܡڷjGåF&ô0dfÞ¿”Š -Ô:Lõ Ý t¤õz vš[ŽK È/ ¼CoS׈¢rÜò„†”äç%ÛáÞ=e®Ï|®ØµV`%ò~Œ ,GyÈhZÀr÷¬È'ŸR§òäŒú#ÍàR"‘Ah›ú—c¼øD›þà¿ëg¾s]ÙºÎ|Éæ)òLÈ"œeØHÑÂÉ Íw*ó!ž˜Räæj(’Œ™ºÇ!öߌ `¥,=;¾>Ïe=û¼cˆœÐË~°ˆˆ^\ˆÞÜ|-‡3‘u…+ ê/´Ä˜±R•m?ª(Ü%ϧg59\xò»ÅÄ0ÐuÛ-޼ˆ‰¬Ê묾ïÕ²jî/ékVn¬PðËèÏèW¸ÿ¡Ÿ”8¼Áÿ8ÝL|®KXÝû(–!’·mŽ1-†<åE_Fò„ûNŒã§ öZ‘ÃákSé7Ó~fÏi€_` `yúâ•b÷ÓÚh 8“FȲó2]U>-]Á°õ¤–·MùÄQ(˜7pƒbƒºX@&'!¸;X‘oËP0«:P16ÝÒËE§ X@ @ ˆV[5Õìyì e×7Ç˰ÿÕ#am[PáŠàe1[%L¼´8‡U>þæXLoƒßµð2ç5¤*¾IõOXY8 Z 6ýé•À±³Œm¡ÔfÈ;6h:ð¢ýRÄeÓg;â¹fò* ^CÞÛ&ƒhæ±IùNÀÅ%€c¥ T è¹B Þ—›e—ãôêóaø&MJ£2PEíÜÁ‚~'‡ZSVµ¤«*ƹ™ŸAù£V‡¬é½Ì4dŒtXªÖ3É'?É£ (L†Íg£PöBÅü.@Ö=rëùùËõü\¦Û?Ãç¤À»¿ù7~\ƳsYß½}§ÏŸ‹ýÁï ÊSb±YLdº[„,8WúÉz¸ @AI ¡„’Ò4ÝÄiB©i±Ȫ$uô…¤/º&5ÛJ.2Z´‹ç&Ç5@%Š5‰gœ%»/X3UÊTÚæq´D¬Îm›—€â &Æ¥X/±Å¾ø>\è´Á¥s³ËgoG¶-w1c ˜A„ئT÷\¾» à̹Ó9ÈœÀ$Ž&êükã›…·‘ X°Ý†dFàçß1^Î#ñN¶sSdz†R´û^;@%cÍË>Á¹ô—+j„íç ^(Cé'@Äe”Jd»T I¤X/P0äÈ'¦PÒwñ»üÐ’B ëæ½d#‹>‡çÊù‡€€Š{&xRˆz]."˜Ïœw²¯J|$¥wyD´{€»…±ò«™ÈñLìþþõýÛ;‘åsN |üÃ?øÑyõêê­>y²ÚzO¢n¨`=t'Î;‹§ø &F•9ºøA0’@1X×x/’ܨ©p¤”Ai4ëÑ ­ƒ–m+–GûÏvm^·±S¼¨ŠIf}žév%¤"yž 7îݧ _8u²Õ‡4Î>Ãq2¯†-0hH5l­üÕÙf˜b¼<(yÖÄ9ð%ë\AabŸ0TíäÀf,s­&¶Zô‘­eÃ’’®í±„†(<éJæy‡A¼ƒiÞo^ó8¸5q5ÆÀX8¢ìÅHÅ&D Žt¹ ÕèEå_ëTþµ(&8´£ü©¿A·&Mi¬{æ,;<ŠbùÔu0CQûã‘jPûæÆÌ²apÙ@i”2P)¸˜fNü^hM-À¡#lØÄ“S&"z~.÷¯^¿½ÿúåŒâ?Ãç¤ÀùŸúqqdYDÇ»÷ÇÃ7ëj7"dH¨¬)Àÿ–hÙŸj,¨¡µd±yM«[Ý„öÿh™L³úRþh‘³¬‡ 9ò µJñÛ-çí7¹­:ý3ž‚ð@¤¹LÊc/8¸1©çñI´Yit‡_\©ÃTž5Sv è~‰ÁHÎ „-‘¦5ôt°´ô1\Þ8îð“(1N6uAë#åÿÀI¶ì9[Ëu««Ê)ˆG5-“Q,Ÿ`ÅâÂ=ÈW³zîéKÆô¤&+E«@!q}áö'Û¹ÌÐŽDÆõVžlÁj¡ÿ䮊òU·>/mY¹%úIÙÏüŒòi©ÀÛ²"€0k«€s+ ¤~[¶ž;L4É™†¼:˜‹pä’ò'.D4]tÕ««·ÑØÏü9) OŸý¸|Ë"rv~'çß®ëzsÐa)îKïD8²Z…÷º“€3¿>-ýdÎF$ÿý P¦ãU™7’á=éT—Ínn´Ùì, µYþ¡K‘±­êTeÏwϲc|†Õ¡,”Ú‡hŠ…‰ètS {‡,™Ò×±hFŒ‘„®cJZ㊅ ’M' Ñi6øç¾lÂÓ£Y¸[ØôþV³tõúHh—B:rtô º¥u]«š,qHcÍßUh-7,}nIå*ßæz{Ü—ˆUðÓ¼yh\úãü°*¯öJ‡Vmg©Ìy¾â5ÑSK3•ŸÕìpŸí¼Lá–u—b¼=Ûû®Ñ;ç’~£çg¯ó´Ìçýœ8<}úã2.‹èÅå\]Þ‰ÙÏL6ù»¸ä,Ög7E8æcVCçRQ¤•#Zh]¨š­-.1Ýp"éY‰àKÖÞTÆìµic÷Óˆeÿêê‚*¨ŒºÐÞc:³í?©áøÖsp‘ ÷Âe80ÒtB –T&G†ÃA·³+(ìkQ³REe2÷¿ŽÍ¤º(.¦±¦œyTkž:Ý#ÅsƒÕo]ïæ4Æÿó<] NÎóx•LûyºvuÏ*x1Wxe*—Is_ò¡eI¸-qÅò3ÄH–K\t)j¤#™þ£[†iÄÑ7|!h˜—Oö @¥kgk#¬Rúu_ùY{µížzu rDLßë‘õÎG‡¡ëì=È뀸%D'’È[@ɘ{TÁþ ï*¿§hûVM\ºèïÞ¨¥á_Wqî\Bc[ÁÁ¢—¯^qJðJ×ígèovt“QÇã=ßË}A+ŸésRàÃïýÎ˨‹è͵Ȣ¯<©;ïQ`ÍAu·ÄxäÏ&ÌR¦’åß Xºõâ0÷TKX+oÖKÀÆï‹åÉÐÊ.m÷" “²¾(,~W:ª"`2ø7#vre0€ ÞÁ=_.}Ìw3¤H¨Â.O&HÓÖ G1§Ðš•:Ö í ,[ê›J#vB4M©ÿXW¼ÃN…Á6Y¢ªØ‚‚©ýló?£ |SUŒ]q°Áe-@˜…x~ë7_bK«¥^|Î0·mVËÖw, _ Þó;Tؼïm#¿PüÆp£¡ItŽå]ÞÕß+Ð5øÃ•ÿªE‘—ñŽb OÉÚ§A’ky¯"Ïj§<‘ñpRƒó_«#u8¼´ãqñøµzÞýÍ¿õ£ó.77²Þ|£—"î> ²à n&­Í9¯Ø“ lêz™§0–’¥ Ê5´auz5 Öi½×9zÅtë«Ê»ñ nJá Béj(Òí÷œª8EX¥ÖsÄêkæ  ךÃ2Òár÷#=K 6°|¤A{¤‘@›rg¯KoeÓaè…/¯Xô•©§~ÌÉdÛ“DU¸9¾ÇØB)2E, QZõÙVR.¸÷dŠõoPOìtV¡ös¡ˆ þY©n8f:øÑðñªzÆ\®þE07Žmˆ+?95—Cë”øyŸë4àÀLZx`V¼óþ½8õéaèðI ÁGÎx6ÍÀ…K™½5ê®çþM^öc¸|‚ºm£ÄJ|žm°kcD 5xó ¨ 0›âRê½b>çi.DôLlˆ¿3U¥¡¢üUD}-ïß‹|üøøu{Ž¿ù›?:ïòô©¬/_¾²u a¾=cJ\5©klþ•Ýl“èZ<õCfñ+aM-•y(i_ݵ0£EdI J›DØ ø2‡âís^V=ë‘Á’Z—1¿Sœï†YnXÄëyÝNâM‚MÀÔ94ÇC™ BjTÏb?ǧ \Ÿ–9øÈÅÖ?-²®èCƽG±b å¨tɸð†HdκümD1øÃclžš „l#ˆû5¶â1Œ2( "G'! ï]˜áÉek© íu¾Á¾y~ûÄ2=J¯FKžJ~kRT 2çy¸mÝ{¯Òê_(ÿ PéÞ/P=ì°B£ü‰Á@â¶z@ƹ@ñ9ïÞPœ¢b";ƒçMâ4Ãh„H<šhTÈá ¶Úëÿê_màÀsR`ùâÅÏûì¹,·7¯B¦šÄMq÷ ‚¯–Duƒ{4!wgn§èAŽÝŽÂåz¾©l7 YPv˨3”6(ò¸+LšjÙ×Nø?¸.'BË d8 'I¯ƒœg¤1×+ ÚòoŠÎ!’Ìm’ø$ˆ_ S¬cG\©lK.øcU ¥ÖéÞZPÉÀQ”}” np´hfQÏj ¬ kÜo@'³(R™JMz2b.4݃ڻ¶6KMR{iVçéyÑßM¶õà «7Ÿç …3ŽjaQìŠb£{"Úk¤ì¬ioE©§À†ãE”¤(7ƒzëòÄš¨æñródòIçA§‚BËþ‹ˆ¾ò‹ºì`û¾Œ'*îYcL¤è ja3]Ê2h1lVÎÇ¿NYè›Ïiîψn £±!žÙ@ñáx|-—"‡òGá9)p¸}ö£ó.ÏžÉrûôµ-ãR˜@ŠÚÈ(wHokð(-Û-ÃÜË›DPÀÂ|¹ÏºI‡² 6,æHR|è-°"ÓQÇÂDjæŸ pÒj‡4 Øœ6¹!Ê0ž]üºí»ØÌ.Ñ>Ï DÕj·&IÜDe&Ð K*ÜÎMí\ 5g¹hâ…B›€1pãƒá>€!-)0@?XTL²,ÜÆܼN´Ø6 nV_ÞIÈ1ø'¥T‚PDÔB•1;0ÐLqæ`æÅLÁ€F²œw>¾‘Åÿ£ü˜‘+”§”®h^þ”Žveò€Mï’î@Eö¬ZȳÊõ*ç! ‚5UE]zo÷>Ö@ªÂz¶ /uM»OA¾!Ipž`õNö:¥L\î CÎÛ:%™i” ^fHCÑó³—‡«K±ïÙÿû¹>'ôöæÇç½¹½½}µ¹y¶+óÔ0sø´kWý+½R‚`¾@çÀŒ Œ‚lìöW¿´'õZU¸q/Þ‹Þ@=B“XL“š`R/ØLn*$Õ!¤FÈÞ+ÖÊŒN‹í3÷ðŠ¾§Dç9 ¦±É‹-}Eãx}Åa"óõ.æÉ+ï~üYÇ3Õ²ÎþÍ1 ˜F˜ òZ¼Ö0Ê­íôs®Zj£Ÿb‹»›¨[§=-’XÆTfú UŒ[ÁÊ»«Eðs²t¥ßL˜ý¤€´µ*CûßkÉí¼éy ~íøfîïΣثÂÒDÅHÍ­tƒ&>5}Ï;2V@5À§lÅ8!ü\@¥óS4y´æwTNs:÷³³7zvöGâ" ‘Sç?î:`=;½¾ùZÎÎÄ>Þ‹|š°éø(­$DGLÐrÇ›Ól BèÏäÂG¡íøa˜¡Á÷~Ð8Tþ$£PÚü>VaåèÒêÁÀ2ñî“vbù7 >EQqHEE!¼R¿¨Éš‘â_Ø"¸¥³Ÿ„V#PÂ#Ò¨6ÿËa¶y£°³i "eéŠEžq°QÇúÒê ¾¤&ö(†”?ôì™ì‰»7 öàÝrĄԂÆÚê´âÏ?ƒ—İœ(üaN¡² #Ž!ÖË}·ß Ò8mKà.ÁÝûÈó^°A:·GÐ]òHæé80ß6A€à¦ žTë¥y1ž™Ç÷ßÑ*/ vãí4$* py„Å’Nå‰ñZùähéž< :PUS"»€IDAT";ßB¶¯± ³¹ôxöJÎÎö#~fÏI€ã‹ç?:ïòü¹|üòÅK;;Š~ø^DΆ0ª"™]Ï1•ÐÊ–tûnòÍF?Cé†ÁÿÐN}« ¨WPÀá2ÁX½ŒQ´·Ë½hùCWPPâ¦@o¢ë¬HSù ÔÑNc¦«}*èBÁjÌTløë8ÄrH~­ÿÊ›SvC†¸ÊÏbêho/*Hßã`Á¼Î£"ºÂ! Ñ~ö> qœ*ÀPY5sÕБu$|}_‡»DÅÇ/È’>º \†£G›ä^7…xËŽÄþI¾¶né@e#T÷ 0°à¨–žÏ R\#Þê*nòº)DJ=tùç™.Ô©ï†.ÇñvPÿæýEÈÏÚ”é2fa’4v|ŠÕˆ„ k7b`•wKŒ´üÖ b"QSF_fá"ŸW ú&ƒ†«‰-‹,Çã×Ëá 6Ž‹îÏI€¿ÿ¯t^}w'ë»oÞèÅ¥ØÛwÈŽuZH7Ç´¡€aC‰ Û¨¬%sC”E4ëf$XP |ˬS±îV ¡PP²óж#¨€IeSè]/¶¦&Å%,’mmP,Ï-²b¡’Ñõ0êÚ> A Ѧ£ySR0"£4:oÌBðª®JFÃÒd.D‰ Š€ÆXh÷ž°S}dlfêJ~¤ßx ¼#p,õÐ+¡B×ÇFB(Äê»÷¤±.CùcÍÝÒ®s-i¤yŸíÌ×øÓxxÛ<Ñ™ý÷xÒðbôÝ™z׆ñ0!|Rܦ±D.*s•®SÔàªüýŒo5Ÿ‚K@Ù;{˜bËK™"*ûºa•ðf•¥ãŸ7K£ßLV=ŠžŸ¿Ò³³™±>Óç¤ÀÝßüÛ¿@n}òä½}öþþþàâ°}^ç8ÑøàœðÝÿî™_d³Þ#ÿ »XÑzÏfD¡*¹Ëu ÌŠ.¬Æ¢!\?†Ç&Dz¬5dE¹µU'¾×±#ÿDXF°(š»Ë¶®LiêMf)X4áE-6!MmÂ]øÍ RŒÔuúÞsUµ·X=’`!n 7m±Ýsü6^U}c?‚ +›;4a"ë‚» ò¬ 9Ðj ¡“‰Bñ”ØT°0zHù×}-´iR#Ÿ'Þ²6ÙãõWŒC•6Vé^Ñäµ(mmeEó°—tC#5NÜØâ!L@YR~#åEÀ£m¨(ÿ0H@Ûë’…‘òÏȨÞÇ1&"Ç£¬fàÀsRàøóŸÿBùõÉ“wïÏÏÞÊzab²øÙj ý:犻Y^·Ü™lñ699<‹[ïB¨™„~3Aq&ãššBª‘ëYÖÜ›aUûò„MØø;´5tAc\†­¸ÑÐÎGeÞGfë÷[d<%‹`;ÝVº,'—_X2àÑ@´¢ ‘¹yÙCZ®ÙÚâvyõ@Å}D$£—hPÁ›Ja¥¡  1 U4,®™O×8ÄØmÂ’äb½ªÇ½90üþëc…½‘ʼnǼ(;ÀÔËh$r?cð™Bèyƒ­›Ž@lÌã@…,ö:8}ž¶òÂÛte4y*X“Úÿ°X í8÷‡r¤¥20YT`£ûI¨åÊehŒAå)šŠµž |^¢«rOº“TñúÙÙ÷÷o^sÿõ¿‘?*ÏI€Ã—/~|fUÑ'×wzqñÖVûÒd¸>¥nš¥‡äѾ‘À7ØÄŽTT¨’®©Pî>½TþZ¤€ó§î¸5MÏDd„¾ˆ0îÛ¤ü±Ò-_{ͳÖ{ÎÀÒR±2óPQû}) sÖS0fUM!(ÒXi…6nmVQ<Ö!0P)sѳdLË ÖÙ18”ô`ŽŸ¾Ü…;Ú¥é/öcë#hKÑ®rhk¹O:ßËÄ=S@jkS÷P–I±Ùi¡"|Cós-{O©.cà›#²äÉ€÷ C­×ÓˆL½êžŽ9Œ`ålZ )¼0d.ö9²!–Tþõü}ÿ=åoMzF_ÔüdÁ“Ã$¡}¦%!½—b§¡£q+ĤÐe¹[Î/ÞÚòGcý_äÄ€>}ö dVY®oÞÊåå;?ⱊÇ$g4)–÷€mVŽ—!ÑO$ÖoÑ"WcBóÝóû33µ´.²í%¿UË^Nò9ÓI±+xdÔ]8Þ¼Û UsÒ o÷cùaädH’xÈdX*~Ó‘±Ã@­ÀÓw̳䋥°œ6Åä–¡kDÚu.Ò.)ðKJú9~¼6bmëm)ª–qbâ>Ÿ®UòB¿¨æÁ€DY-x"™ËJIÁÂKNc¿Z˜½En ›h9/÷¸âžæ —?äÍÚe&ýŒº„ùY¼Ì:ß`.TÐ!À70ø5¹ÑNøÚ܉M¼‘¹Îâ8W»2J „ òO\J^©Ü¨àï~W‡sEÊKôûÌß4`#ÒZŒ„ O^–¡HÖdQ0j±œ§òàßUtYÞ.—wöá'ðkù,××?>³ª,··«>yò:üÛV=ß#4íH_•Þ:µ1V*gþ÷ˆÌ®t°üAž \ý½Íƒw„Cä¯e bwkEpT+@° ÕÔ¤?²]¡.òÅ@새_×ƒÜ ±PP«§w7lBqKU&Æ Ì6³¸`3‰È“‚ÜuM€z†¥ò¦GŠ4–3ø "¬s¦a¥ú*Ømcƒ&èá±K–ÐK®´¦R[4‹6c¦Ï B5Ìt6j`*ÔÜë¡•Œlù{~/Ölú4ý;*rT ´?¡ZÏñ{Z¡RÖ™E@ù – W«}B\ÙÖè;*²GúkÐVÜŒIÞ‚©Ç:ùžÜà±ññôÛC —íòk²„ß¾ˆ»ó…Ð(cøò_r?#˜Œp) '^ºËym"z8|£ççïâ>ò?ÏI=»øñ™½¸}òäeX¾±alãr_ÏG+KŒ£)Ô}²©ˆ¬ºm²2M"´ö.õ~F,QZsÁ˜|hY`ú†‚¡¶cÏrjÒкj¶Pø*^,€{ã>Šƒ •_XgÝ=>"ø‹ˆlû3Öpµ§ Pnf( Œn¦d a†¸¨IëY>“…‹õ ³@JÂ2ªïè*s ¤¤¹³S4‘g‚e%é Ÿ7GPÅÁ½4oÑᮄCÈ‹u“ ÿÖã’5Mågt à)‹:~Ä¿3+N1 bJCžu¼ã2Õ+Y†'©yÒÛׇx©”+ÛØ¯±ìtæC™dºž¯Ê?ªÄþèœ@ÊwFçùªÌ#èûnmUZÆT,Λ «9Bû‹xPTäp|­gÇû‡øçõœ8¼xñã3«Èòü…,77/×ÕÂhÈ;ÔITÒe@;;¢»Ax_‘dFW<”ÓNzeaÒ]ÃZÕ'ÍB¯,±œ½[›p÷ɇ òÑq+Ï ±O.EfUÇÛ¬“/`™ø*´–’Ø—·¢Ròz†ˆ+~1L­€Ç=5 ´÷ñ¤¶O{¦ªƒî)¢ð^}#K¥£™í|#‡¨)s/ðªBb Ò |ÅØšZÓ6[Æ_”we‘†cž`{¼6sà¶ËÁ³æ{Œ7;`ÊŒu3_±[kɳ§~š d'¯ÅÞ ÌSåÄn½;r¢Öëï«6óõ2拸ÐÐÊþð*íwŠ*0y׈bšã\oÈøB|t¯"z8¼4=ò5äŸùsRàîïþ"ÇE–ë¹ÿöÛ×zu%"l’! &F2¤_k8gXˆ%XIL|8Xa‚b¶Ö‚)“¸nRÓò1Ú^­(Î Oìžö¹£EÐy[Ê.e´žƒ‚ µ­JЪ%K,tVEØ·ÀZþ( (Ÿôcâ}×8¹±µ3—\«ø:cX+~B ZF¢E8°g£‚€èŸ \íãmµ"——öé„FóBà6¼–‚œÆ›ÍRƒ²8Ònñ&`ùH™ˆÑÐp¡UWœ#ØèíuŒMXúÙ¿´`ÍÜYþÄFÁ|…±óbª’òì6–¡œ%ê—œû2  >Ö:÷|8ÉÛîVôïm½fÊ© ÊŽÓYx³"s[Ð1Ýï J¤)}«ÇL­ÉEìÆ{²p™6«…}.ÀŸu²Ö&ãW‘³ó—‡Ë+±¥Fû|Ÿ“~÷w¡üúäJD—Wr<ÛÖ‚·¯diø_a™ÏË¥è(Ðrâ>„œ…7 j7N¶‘ºéA ¹ü`±R•Èï*ôxH-!ƒg/F³Ëú&è.8©U\)w4ª^„ì XÿÕ# nôKñcc‘4×¹Ù…-š{\x¸«1Ö{h?™ö“Š’tÔçèá1±ì[1XÇã‰Û®è \)bøY¼D݉¦á¶p¥¾ÈFß?A=*㢆å`±P-Öv‚w" r9°Ë­*{ŠíÓ6vÜvO©çqÄ,Ú3[—ÔáëY|pjçq竨=‘QÃ:hià=¹sJi¸âI«¸¿HG&Í6Y¶=O¾3‰”¨¢„J«=\$`;y±R¾`ÄM¬$… Â@±¢‘~ƒ¿±õþÕ÷ÿú_þ‘‰ rbàìOÿ™_(ÿr{+V{ef)xG$4Œ¿€idC™¬Æ€Ø7Íùšø´»V„6XËÜÅ%vºP—9É«(KÁ]×HtçA=ž-2ü=¾·f|³æ¾€å+Ìñ; H6c[ ¨‹qL(êcˆãû6KËkBT„ñJCµï ~Ì{ «UãÖˆ{F,…˜ª†p³:`EÌ~†´šlüÇ4…3*° ! Æ-p7þ2À³‹Ï‡à÷°@áø§.I‹Ÿõ¶…‚åØöJž.¨ï¥‘•&%ZV pXæ•&ç8ò± ¦õfŒ2J=^Fìóhæžóa¤¯¼ºs®•ÁZß?jʬ$'! Ë¶h©Ùùxb–QœˆÆYÒÙÊæêÄ\~N~ñiÔllæ »ÕÞ"é2´žXÐå ºèëû·oÄ>ÞË•ç¤ÀòüÙ/–ÿö©èÓÛW²l r/qZ¨¢´%5hxãbW©Åå*‰æ,¶ Ü¡t/#ô¯Ì2!ø½›øEù7ÆódIÔ`'xÕpÍS-ÿÝ´¾T°,1§Ù{056'ß‚»ƒm› )êµ¼Ø<ü‡5€•VÄø ,ß¡îe¬Tf è=•’èHƒd/WIªðk^„œà ûTtÓn üͽ9ÅÓá£]ÊRð#kÑj<…ö¤¶™p]éÿvÌb# +v1l€&£!`šYiÉ3i:í²”‘Të·–þk3(Õšf2bœŠL°3¤<\YÚç¬ÁÀöH0=»4™iT›8գʹh‚p¬6Œ*÷X˜ÀÜU¦~Ü7­x—7]¾jN¬Åû‚^=!¦²-ãž¿\nnÅ>|xŒŠŸÍsR@¯üuÀ""zs#zûô•²Þß‹ã(”N¥¶ ÃbÃÀjql =x›¢‹l“EŽéÜû·”ß1 ¦M`’?Ðd@aı9Q>B=òì­v–?z6(2™`QŒÈ­Çí}õw´ÿB¯Ñ'ªp5<%üaü½šÚç­)X9kÔ÷ADJ#¬ÔÆ+e‹–P¶³:IꞆíG´±" … f^ݸ5“¨+E Ã!gM—»{“\BòhXV$~3Ôû¼û?½!D-M¾¨M\eS "xüÉ"1ÏyízãM>ÆV b*æ@åN~h{íËÜv ž´S/ÆYð¥ƒr§H“ $¦£ž…®ÀM õ9¾m‹5;¼¤æ¢©É#ȯKÚã›´SfËäY±ÍR.[EU hMEôìøJÏÎåÒsR@.üuÀ""rq)Ë“ë—vv.òáèa‰©kôf,°(,é¸UªXÏÎ@ky•Ü ,JxFÏüærU½¡mìIËv3RǤ¤°cìþs]{½Pfkþ»µ7•JuÇá{œ½_¼„ˆ0è_c=·;ÊCɧ+ÖÑ–„-ˆÜ›Áûº£ wÁj~“ŽM\54±ñNA DKûë…,ÞŠ[lÀ•¾¨(£ < ] ÔzfP¢ifMIa3o]6žÉ†ŒðÈÚ«JËÊízî*! 7š–ª­žM÷`BØFA> weÆòþAVòl? OIÌ%´.³ì5ÇlÈ ¯¥Ó9sjû )ž Á¶Óø–è¬Ì_É“¹ ׀ιÑr§•®™Ç‘bÙçG§<ÞÜìŸ/iyÛó¶L¨Ö g™Jsdű²äØBL@ßÍ<¢êÀÓ4v€êÙÙ+=;¥>÷ç¤Àá¸XDdyúTÖ×_¼’³£Øý½¬gÇ<ÖÕCåïBÅ7ì¥àÞÞ² ýÕD ¶õÁ¼‘¯±)PSƒ†„Ò±ÖëÈ“º…MññµY—¶üÅfoÔ†vÀ\ŠŸ]¿¤šÂ}‡þUÎÑ+´å}E·¾¡êæ}xV[u3%‘ ¡d8ÒA[ããGÔ·Ã<)¸©±ëKñ÷Ñ7Wb0XžÖ2¢¿yT5/Ô1±em#‚г¿9®¨Hü÷0ÀŠܼž$VèxP7ÿ¯›ÈaGù5Ï8o6p„Q»õìX«-M]ã%˶¡EjØn`âÈ8æ@^ÔU•n&D°ü]šŸÒ `ýÍö+¸ß™!æ¶XŽQõæþݼíw ÜtùÅœS,r™™JîÚ¾•è•Û7¦q´8dØ&´íp|ezÓºCàó}N ÜÿáüBù×woåþÝ»×zqù½™œ“ÁL£­2ŽñÁ¦•%ï95xë~ã–±*XÞ 4Y’:\ñÅz—@§Å"ð4)vn_ÃêUH£S[½LÔêR2 å¬ü^ã D9pÊ&#Ææ‘ËX›ÆxÆ`±mÿ¢zS:€J/ãÝ$—]Ü廈ohó¥N¼f|B÷z”ž€•2()d<öå(¬.QQ[ÇÅF`aÂ@¡p­P@,LdPÐ% ”»²Á[b0må"“¡5Z 5WŽ(p·è‡J È·eúí‰Y¦i©”%¤Pâ.Åk’Š>šƒï\¯ÉݬhŒ]kϘ‡ ^A¶¼ÇB@Á2hçh{’ ÐL½[Ò\JÿtÊ3Ó(xڲ﹬S„„%˜AÆŠ«mXñQ wºñø:}:ÜYU;zmº†-…SxBü`™£ª9\œ¿:œŸín¾üŸ“wóoýb˜ˆÞ\¿“ë'oW[¿È[ý6¦¼¾¶mãš¹HeCŠc¨ÌÄk• ÊV©ŒxNtË;“±Õ¹d3AÕJ%ž÷×K"¼A¶ÒGL/¸¼w9®†YüéJOÇÊÌê¸a*0#¯IþÑLøÛhS`5\ÑÖÎé•g KൠÃK>ç¹5 €¼è¶'±Ù]DkŸãV ‡û¡Ž“Z4á³1ú¥1÷zðÎLô§­—=8å©t_‘LF3©.Rî¾:L4“s`aXƒÀKd—n’†xJÔI|yCB(ì[ ÄuÃëq”ãA•#6†¼Ú ’°ÆNRµ6XæÈÎôCcÑ “œ>’‰a–[x…žàSC‚Ü$Î4¦É¶ÞVv·æ[—ʉõ #’i¯fÑ÷%PFÀù Ÿ¹Æç Bö®hnÜ7åHD%½“׌©Mb‰ÔÄx²”ZÖs^Pºw¯8MÊïL™4žz!te=8Kc0»Å?̼ÉýÌ3{ìüW™½¼ç<‚Øm)óM ¡½•˜’2—™–­5¼EýÎ0Zú ¿¬XAÙl.^9söÉË7ñ®3`õ9¿ÿ9·1Ü~û88¸ØÚë9ªÿìÐR,3¹…¼Ì×-’ ߟiýÑû^R…I.²­²“ž±,;Îȹ°'#/~|¤;ÄÆÆ/Pa€mmA“í² ’†3å>zÇeó¥P6ç*=L“À‰|ó@iÁÏ›/qì}YA1‘ÌoÑPÛŒ–êg —ó¸';Ÿ­Ì$*LÌbÚó¢¢®m—5šžˆü÷<;–õ»ü»¦wxoåYÛ¨ë£3ßMÔÂzÔM­'¤,njG|~–~«äÿ¬íÌçéï“-#®ú()>Ïv"§u¨£#曀 ñOu2˚̯™ÎŒFŽX“¶rïyFúëmâŒÅ†a¸(»ÍMU¸ÎÜ~ÛsoãÅ·ïåØÁž’‚i<%'©ýaR 1R>—.˜Q ¯r/&BÉ[¬‚`¤wí ”œ˜Âþ76DÝóhHíIeM^ìàH¤2;…!¨Îr܇µ¢ü‡«ä`?2‡À/¨­¡…)Š ùŒ(d‚<˜(–"ÏpOCõ({goø>Дd˜žfx8Ï~ MÉOh_ùÂlÄ…â»6Ö[fv§j *0"mr¢ÃÈ„LP~ä_zÕÃ*èšÄî÷ÉÖGEZVOZf"ùÄ™Ô:¡Û’–ÑÂç¢_MÍøšÕ~Ó36ê7m—¤Ï‘É.¿Sû¨BÅlj>× 3ùh¬¯ûþLmåýJÞ=#Ð|lŠˆs8Ÿ#sn9W¤:øòˆ×çø¨)ËǸ®)d‡á6O7Oà:cä–[ž{ÇÇŽ'¼NqÎ"óH/™’‚pÛ{]HL¬=Vu°#WÃb€({iï÷’ú*««ô—4ÈÌŒ«²í·ró˜7D„ÃñçqL²ÐY[¯Ñ¦ÐçÔÆ³1ItrÁÛ3#9Ø›G{ G.CZ†Ð‰5kB~¢5sAùÎH"£Z/áÆ²K‡®ä³È3M¤_uO‰¾f:c*¢=æï´Ÿ;¥Õ–:s:k¹’8Smʱ@ï0M†”½¬%û˜PSŒþ³æhºRsäÁÿæw(Ígö-¶Hû|•¾—#Ƶ*ÆO툜9a˜?HýN$ìÊ•IëôL1fæÏ¨¦µ¶½™’Ýéç0ÔÍõ«³ïãÙ“\®KÊ.NÒɸ«õÃf»ŸhÛnp¸¾€ísÌ@vc·œï`vÌ1i“dð$õ²ƒ 3Ópd³,27ÙSaœgQ×i½´„léÂî{«Œp±SýÔùGh`îÉ\æe^€ÆÐð¥ŽÏÔ†"¼~ŸÅBêl&$°Û˼vI¢cœÛÿßòÓ8“ UYeC¿æ’çšKJFB{c†ôi{5¤Ô¶#SQ¤Ø—B 3C»’Ο- ‰Ù ¡‘Ær\*G£L¾è®-b剪¯Mäà—¼Î’!=Ï-…ð÷׬ HG ~¯H†ÕÜTW5³èIï8“•Î_Si\ÔAÝ;Ew­ŽJŒ°ßB8*M]õ75ípYÙ gœÌë(ò÷¹ìMÚ?‹4aR>—ž¨’Ñ`™,7ð¹HA“3L©À“}Mú˜~§GÌ4îLe¢e2_n%ß‹â³ÃpA×´­p3ÁõÅÜúÜMÃm/‚¿õÌhO…'Òišì¶N;™ ÐîÁíåqƒZ¦;#c[Sü²&>.%ת!Ÿ©ßíÚ3l϶âEÆíÎ!X@³*VäcüFeT»ê¶‡êöëj".• ¸“­U^9jÇÞalSÁ3àÿ%,~ЉÄ3YâÈR¦í‘6úqPªaô5J9Úmv‰‰èÏT }FFÙ´ æ¬Ö×5;ŠñkFhzøcú¨ dsa‰Õ¶”¦uæÓ¸FSÍÌ …IŠÎ(€C\˜ Y^Ô´fÙkß¶²H˜Ìý#ß+©ÃÈ'#EÌœ4»çuÚ¶Û)1ÒÏñyž'ÿs ïüR3ñKó}>}­´Qåô)±ŸîÕ‘$]1õIš Ï¢%¤Mç=¿Yx¥ÐÕpƒ`ñ¸†¡?÷œÛA «áœ®Ç©GìírǪw¿ŒÄíù!.óÈ$ˆkDÊ üäV§NT-NX£<¦%ù mC1†ý¨bI,ZìŸ\BÕ¤Vk3Í64)Ÿ>K¼ýs *IR:|­áÐÿÎX•ôµD@'´Oæ“~ËcÉÔZ6Ñ@$×qM;ΤÇ%!½Ž•BîqïÞ½•$uA2Áp¿Y²‹ c›§òÄ"-x"¶6LœøL¸gè_HÔâ³óª4ÉX/ƒU­™Œñ¬êJæÍœè&ø4Ѥ~èÿ—<Ê“=;«B걉–Múœ&ÌI-ÝGZ#=â}¤wâóÑ”ÜoÞs¤Ü÷GIرU6æS]ÙåìÖð)cRw,¤h™Y5¤V‘F’W@ìr¤Vûïe3#¶Gé¾1;2ÇêäÙ$|x!80l¶gd·ÃÍ×pémoyÎmȱ´§ž<'·§Ô¹á6•ˆébV5+&D2Ó.ð{UÆ©ê{–jýMBèJÁø1«Ç·–e;r!0ý«À¹Ú‹5öËKŒs¾®AIc©¶xm³Q± Hsµ¶´I¨öéÄ‹Õ]ˆ‘`EÁ…Ù=Ñ BÃÒ0ÍOÕwÇq¨ÙñsTŸK+ö¢äÐKãìñ±h¥¥Ê`Ô_DZˑçtÕbËi^^šÓbHy{J0&+yܵoËÊjÿÜoβ$¤:ŽÚ;ü«LÞç5ªã¯'º†¤åÜ UbޱOõ y+#B#J—gº®y¾Zú †¡îuÅqçæÏ3š;5<ÖzçâæX(™´ÁÚÞ Æ„™ééšX»Óë5ôpöð‘GoªÀuÆàöÛŸ{·ÜŒ´&@j§pY–$ñ…¼tVý¼Ó=H‘3&Bó d:/V­³y*¯YÜy!.<ÐK´[& ‘:.iï—ï*/†Ö~”Ç-ôcT¾o1[Ã%æ¿UÈz€êþüá… Ðvó”®3@^ü[ŽC.=sn?ä°Ã Š d,-ùr D¼\ž(á5MÕ ­„¤ÌD¥:¥MÕ_óN4ö›¤KRk–Wö¤ pÄÄf–ƒ­›Òkú\™ˆL„ ·hq¬ „Ë|}vVä¼õ9A`9WçI!&¨ä¨D6I¹™XTÄç6Í4òŸ'F‚¥J®o¯ *„½ Ìæ!h“e†ŠzԈ͵J˜S^EISQ¶Æ—Ž„ Qq›“fçXŽJ³fÑø‘ßÍÉÐõ¯Úc=#ÌÌÕç'Ú®Ùž¦Ÿ¼Ÿ™6ùLäf‚:ÒÌ̙߄+Ëyœ$£³ä¢÷Ï­~ïD™ï P_Yžl¡Q¿BíÛ}NìÎŒ,ÁÄ?™ì|–»égœž·u`ÓbƘJk4æêð²î“ù«·iŒˆzŸ}’MÝö¬‡ pÍÂpÛñçÞÆñãÐ'o=§«5´=ƒa…î¢0ó¨îþŸTT&ƒ™„=ô]&öñ_öZEÿÆýŠLS3ùY„­| «ö[¥­x›Óqf"È=Œ‰†Ô¿«c—Œz“xǯǂ'ˆLK‹WŒF¿µfRFÔ]ð9²Ó }.zÒq#,1 Mûgecì”f$¢mÄ ÊÇHíäROKh 1= ‘c¿Ÿ”çuÆ`P(òTÂÎç*³£Ÿ>Te=|öâ`™^ÓÉÃd¥æ’Òðª1ù¯LáÜn°9˵í´"|Ž&ÄÐÞ“i›skžÆL É\£ÔgÚßKBL!àðØ‘ûâü%<ÖÉPl}â¨å%ü¾Æw‰Áà͘Y—ºF“„Xå¹t.„µ%5ˆ«íYÙìYL×, Çž{€áØ-n½í,6Dth/ÿ"½RZ©öãB­NY޲Xë@$£J8{Ñš jæ¶vh ¥ x/Ü›ýU¥ Åe»#§Â©ä…W!·Áàó’0{„Ó[°ï!‚(‡j“Х5'º’ÒÃ’ÞX>{Ü#2²æBºŽ[â+W{{¶¾¡Î%O±²>¹æ:‘[z¤©¸ã°Zºg!F‹°¼v¦==òP‘tav2ë•G7NŒ4!&á÷¹â¥SçŒE»ôxüB9 ÑsIãšÎ4¶H“eþÊ~òùz’}HªŒo¤_Óyæ8fxÍâSf2Ùª´‘‰_Z•ÂTÍ ûÂü3ãÀ”0&”‚¶cªt©ö3âç qfœ±%ÍïÔy$-æÏJc÷Ïe},«g*†Xû¥µâ6•¶¸Žƒ‹6ù1±×2—¹~mMh&LGrxsb`0l6çe½)qãÃuÅàø‹žszüàEÏœ“íörkmË<¢•µsR‹¢ac郥ְ™³`ñé#s‘Pøìe€D;vkF/|s^‰¤Eù`«Ïn©Ðï‰ ¨Y{âJ8°ÂŒ”³£¡ œû;¶è¹`{f@ oËÒˆ–‹‰K–²3M=1!ÈŒ›·Öû‘4=MHƾ6Ê’¯¹Õd—ò»ïeç |ïéiÎ'aq> Öt L/r õü•L˜Ìœ‘¤THH>óŒcÎ/`NAÏLF%ïÕá­þ úŒ#>–if +ûÍgA¨g¤ifDC¥>+ÿSÛ¤}a¡"±HšgÁù¡œXëü;Ò®w˜œù¯ÍæÜ"mAÓ¼Z—šÖ¡.‡JOkä5ó¾|]èŽÏ|¶†Í¤Ñd~¬vFö¾‡ä¼×W¿‰àºbögN?ç6äÉ'Ð.]º€Ýîbkí%ƒfù&©îèf ¤¬ ~œÎGI´vÆõ›¹’DN[ ~yÕIØ'=ÑzW41Ëa$ìz£5´2Žæ8ôK¨o1©ƒìæLüg¤õIcâ2©Ž-Ž˜Û°Ò«¶9E.óË Â½âœ´¿|ö’蘙mÁļ©DVZ°:΄ÉTÊ™YZgnsîÕ½Ÿæ}CšßÜIá%™WõJ0ÃtÔutf4ós©züxi™‰dIÓþ“Î]?§ìKâ7¾œ5_gÄB«3¶ßŒCH3IÌzâzag-÷L=c„ M³ö¦æqÒ:—´Ï‘&½ÑS‰bfI“[Ѻ3#2·7±v˜Œµš†QkB§P䲬×guXAo®<@×pé-o¾ ­(äÖÛžÄîàâ¾á%"²7ý^•ò¹ð“rµKœ”îuÁ\<[³l%† ¥Só&°Ê!Ó;ÏÆmÛ…L/ÞœJÒÆ8QaúªÌËy¹ßŠzæ­®­þ’.v ÅPÈÙ°0>2#þ ÊŒH8É‘wš¾á,+Ö±;BQ)OŒ9&¼1ÅD]ƒR—çüqI­§G$ýí œ qFUÆheg‹~(s©òóì¾"©_ëìŸÎ»ÑVžNf²PNÙÌ¥³©G·?ÛO¢JÓ±D“F3¡ïL¶òZάLêÇ4hüdewŽJ´“Ç¿ki%‰ #3èë«Æ~LÌ@äYÔ~û·’~5ÖˆV†HR~5æ»®Ö açuâÿ¯ÕL¶ýSX¥W«ÕE;ýáp-ƒ<×rÀ†Ý~Ivç¡­'ƒhS¤ÜÁÔØ‚ ö,Í{zß~ÔG’S•ŽX1RŠöð:‰T¶M›ܥ\ó.·t¸ˆ"&V¡nèDY¢àNå&úç”Hˆ1!•HW»äˆ˜ ФMr!ÛjI®ç¤Nã³£¶ÈÎDoR1•ÔL_íš.nGmi¨½iÐ:)I½)¾˜Eb cdªâÊÃ…ÈR.«ŽûçLW|¬,Ò”¼&FŠ÷¢ÒöNC.ÅÔAö}¢ü}=¤ö—GÀÌñ¼€–YC6 ågj9[fùjʦONæ*ó2wæËñÏ3«ÎE³ósÄЂao´Ö‹°ý™ç°és÷™©‘“E‰i#º?Š?ÁºŒ•Oø ¡P÷-±zR¦ÂcëgÚ#wb޵X’ò0èj%„h½~çû×Êëœ÷[ø~#ð©ïÅj}áÊùóOÞl9€ëøœ—\•v†¿XqìØy´1´Ñáfžg«# WÍ5>hÏù/= ™#wõ¬|M+ß«ˆU…-,°ë ˜(ad&˜ˆÒÅ÷î&Ò­{¥ÃàUñèQôêƒHRqU×M× 4 šÚf~m$D-;¢‘ ;‘>¼ºÏ9’„p„VDn%â8ŸÂ¹ÿÝUÜ¥ŠOnÎ dHûÇÌ"ûfD4q†+²:ÒÞ(bÊlU¬BøjHo'¥.;`ÏUcjE²GíoÝAfñŽ~‡wNŸ¥µùï˜9˜c&ïÐ=™}r†ø×¯ç# æ/”.c ‰Ï^¹‘ŽQtdá­A óÐòmŠ°ÛªÉZ§´šÏMø:ÉQ=À4¦¦6 _Ö´3B;óý ·4Öø¬©#ú±sAwÆÏ 1>hlÆ«á6›KŸÊi¿ÑàºbV·]…rÀV·ßŽá–[Ϋ6pe4EÏõ_Ñ@?9’íŒ!×t@!ä!/¤Ò²&‡ (M’> ¶†Œ ‰QJBmËH®±ÄVÚã6üR&½*¸[݃š$ÆÑ ©ëÃH+?“ÍÂvh΋=¡n»Kó(2P›%·³#–®•Ÿ3†ÈæK˜Ÿ¹sã`¦Ñúq4’ƒƒûÓ.9ÒT"°æOPý¸fÚëL„æ{€ÑÅÍœI³Ñ’–&W ž% Z>ÅÌ%:JÒoÏÚÃT`Ö#`û´k{ú–âM·¡y î£’‡ž“_ŽGK.„c|~HÉ%1Ý™DÕ€ræ²§NHºWÍPdMMÍNwóýZ&SŸêì;QÝ4ò ðýMj|U?ñYÜj‰Kµ6ržUg†{ ž3ÊwŠÕ0\6Ût?o¸®9xîÕ½cÇÎ4Lcͳ¤T´gäwG©[&™¾ ·p¨ŠbbbõBB#ìÑíúá¦(„aÇUrÖÖ”gÉêÊ"°¸ÔiÒp+\31.Æ` Ô&€ÐÊWUb ©®ÑЉ€0C¶Óñw50ºX¿ÁßÍ9Ì—ÀM¼ð>ò†§ÁֹŚѣÌÀ9ÃÁÈY¦ô…ˆé6Êòó–|IÓemÇÿGô>ÃTâÏøæ‘ „>)š!Þ£aûs kƇÅÖêÙTì±eé¼ÌJæMþÝŸÑ|ÖçDE&öJï²SÌ{6(®¯‰ƒŠó‘eçÙ¡%mJ,N&×ZÏWf&ÄëóèÏñÎ8®|æ˜ä&¦#ý&å÷:)-IjižÙáêyÜì@Ì,¥B™åNÏë0\Àjƒ”é&ëŠX½è¹‡]pÛm§›Œ9û Q!N«eýÌs›íùöxÊõÞ´Ûr‰û.ÍÔüFàí÷ÈfU=3E¾]¬’d}˜¡}þ™äcÉý3n¥ éX¿™f€UÈÖœäÚ “¦öY© Ê#®ÁãÖûÀ ¡ˆ3=Í2á“12Ã0Dö\WÍùæ¦F󷇄æ&™ð“˜P')›—rÏŒ‘¤º™Ñ_;b€= ²~Ch~öìtOD"ªýU#¥á¦qðŒqÇHÇfÝV°Ÿ3ߨp]1Wüª´Ó®\¶vÛ ]å$=Ãq”a× 9ôÿ÷X| už!^Wy‡8çmz?öÁ$+…«ëIj0#Y#\@\mQÉR8y™+*‚´QkûY¤9zBJÏó3Sˆ=›0kðg ù•äì(ÜB/Óâ1™‰ƒâ –$ ’4 V7TÅëÉõXãbÈ“Ç:A»spI©Ÿ™`âE„:öLÑ”Tz…iÝD:,g‚׿ÈÍù=‘Íïٸ¼ölh2ê! 82¬|v&ž¤ÿ8SF-r)ôYkHþ!V‰Õ#–ä§É”¦Ÿb~¹ÐM|—I¯<îÊZd‘8óÓ6ì¿Ì<û™¨þ œÁ±&H›ž„Lœ+ƒ Þ"`¥Ñ«f £ÑOB]H€õṵ́Ù~rEÏ ×ðÄ]o»*íÈz½téüpü8pùrªrgb|° Ž=ûÜÅa{̼òÓE“£ÐÑ4âCGH¤J¤d:ƒt‡Â$õ° ܇ûªu•;”%´à¹[—bC;ã ú[½{§D™¥ÕÉœg˜6/ØâÓÄD(IN¤Â°¾ÙÙÒÇÖK)ƒÞ759«=çü 3°YÍå?CÕQ÷P£‘†DA¤i£´n½HÆÃIœè¡®–ˆ¼¡0°áÄ8àgbÁR(ϾÖ"ÇÿZÜ·. ÒØæ’'åspä量zy¿scÕ·„÷!5zŸL7¸ˆí±‰Åi.Ý£zË~ιV)n #îRÀQ ÃÇ!s‡‰¨*¼„VÅ´ÏÌ8"Þo)Ò?=§pK "§åð t¿D\Ó0¼äêDÈv‡vñÂÙQ…±ÿ‰?ïµò¨‘Œýi” ØׂÄúE0-{#F,}¦üúþ^O6¬q¸¹"aFÎY}g÷º!_</Ô’ŽLŒ¤þ¡X—޲úy°ö‰‰ª©é}f]Ãøh!ʘ٠`½‚žyæ±GÇ‚"7\W Àês®N98Ö«ÇÛj Ù*]4Q¯ÿîR"нî+J&1tn€ïµÄÙãD†mx”L¨¿Ð XÑX É µ0ÒÌ^±¬Šã>øsÙßñ‰À.A º¿øÅö»‚øG"B³«X›žg[û'MC7$5ñÈÝL䬸MÑþ© }­͹ÿyÀBÍÛÚ÷š¥þ¯¡%.2„|òèUê\rÒ)ž“ôcºÅ%ÿ4NÆ8SDBß7¥y•5]¨9#þ.ŸCõþIúaFL>¹¦À_#"å5)R»]cFL%Wî´]Ê;Ê÷.ëÖ‚õ.st‰8ÿÎi«P"’ŠÐH%räƒOkT“GVйwhL©Í£˜@"ȮѨ{G2ƒPÇ>ÉÚ)3[\~\Å·jHèo6§‡Õ º0×6¬n¿ýª´Ó£ Îèf ´'Ðz\”ç¥7ÖtiÖ¥[Ð?:ŒA ù2Iœq>¾¡ØW"d%‡~)JãýE«Èh*ÐVò‚§lƒ÷. …U{=:¬MûXÙt 0G;RqêÌ .„ Í“ˆêèí¯Špø9 Ût»¶FëŽ<5²j´h•÷©ù»~—‡Èµ¿G„è×âåíáÄD%oEê?aÓÂ1Â-Ô3‘ÿ.£Þ9$;I ĨO"Ÿ¿ô‘³œª14Rª#Z«ò>ö]qbbßÄa³ vBdê:Õgf~Ÿ•Ú«4g÷‚$R|®OŒŽ’ÍQÈ1GûÚzô†Ÿú=ND™~f¢£‡K­À„y:Ö,½Pšo:å =b~V!Ò^ªi²}&üBûÃk4 8,á0¦ TÛeÃÓ;ô<ËYVI´u¦¤YÕЀØóv|·$46gpµgP`³>ƒõh‹À5 ÃñãW¥Ùí€au»ƒsûÖþÀÚ9^C€oc/¥ŒÇ/d% ”œÆ˜†þg v懰 ‚о‡Þ®¡ ÎïaùÕœè¨3)¸ _ª©Àˆgh& %±™ª :å„71¶`LàŒC8Æ’Q2ÎP£)±,‡øb‚ÈmÍÌæé—…Þãv\»Ã• •ûȃHiM|a ;à‡$‚ë| ¹:R½þ‰ö¶L2ŽÙZäyÐ*©.G>CôæÞDÙfyLø,3¿ &’pUAç8þìioÒß Á ñ䂈E£•ô3³™3úÍùîÏ, “y>äžÏD6¨?œ1´ùæJ€üM=[š¼ãG|¦fwåÏ-Ý_n×îbþì­Ôohß²1­]Ÿ9yPbvú3MQæGk_´ÄÞĺ «§dθ„w“ÁuÅ\¸ZQÃlwÛf{?`ØÊlÑa‹ÿߥˆ~¸Vˆƒ2Ù <éóþ.JAã1n¿§¦åÖQw™øøàêqë‚/mBâ4&ë'é)Q/N†*•ðß5AR%MVâ–N»š‘(âwGFÄV™¤vŽ\hF„»×=­ÛT3û;”ïF™ÁDÅ\xQ”æÒÝÁœ‰Ì+¦ 4Óùgé2Ç:ó|I2„ëözB‹!¤ÑØ«„Em‰Ýø Ëû?ÊG­¡>Ó•03AgÌ&øvFS࣬Éè|þh4Κ°êñ£šY…Úx"Ÿ&¡ó8«”N—Žs[8a¢='¼rÃÜá–ŠW˜Ì,·±:Îä+› ™:æ›ÈF§F}³Ï¿½Ñ@çÞ[f&ˆ}b¥i“<[]ÇbnÑ…ÒÈ8‡Eü™ùâxö© 8ƒÕö VæÁߨp]1‡O‘´Ìú°z]Ó¡dkgÂÖÿ¿Û¼¥ÆuVÌèÅræùn?Já;#¨93æÄC2j­ô„CBµsÌüH\g"»ø\÷»Ê§éœ¥¯bgE,zÅŒÕ=-ï+¤žl’È+3 ˜ò£˜LÞ›¹ •G½ò#a^ˆëÛÇkS"Õé'4þ($ŸÏ™ÄìKîÏÛ/kâkÉL3¥©‘|±B@ÒtéXçž÷¢NsûËÌMÇdöTbsËy‹5è`L’O…«$Nâ„Á§~ƒìǧ”·ÄÇa¿×6yl±t툵·0EUëõé+O>ù$Ú~†k¸ñáºb¶ÿõsÕÚZ½øÅ¸ò±?¶ßï@ ÄÕ¤œÐÆ$r..“Ž,w SrÀË”_`/$9Ï=¼MBâY`©+)úX PDÀt™³p;!’©È!³þŽe+¬Ñrî„MÕGs` Ó$ð4:‹ŸçS¤^'ÓæQ$‰ªÕ¨)Ž'NƒkÌ#®&öînDüyç2Òœ®ù„Xô}M!O&bj^»i2I^ã³CóåCÕÛ`2'40GâJ¿0#ZûÐÒÌ<ƒ|îçÞ©c¯÷ 3ŸÁmö—âœó“NJbªÓÜÓdB–M*cºO“©ãÓÀ‰¥ ½a¦‘‹YeÕP¾K­v^ï=â,ÕϬyc©žew%†ýz2ëçSÍ”\{B•5&:‰hžÏ"°ÙXÓ$ßéºÙ$šQTvg”Ÿ]±ùæ=UX­Óv½r¹ìÔÍ×°ºýê€Õ‹on½õ±=Ôß é‚ÇatµŒ%|é‘çK.Ú ûçÑžNˆÜÿ+~èÙn².e‹ÖøÝPþ”$h]9iÑÌ£–†6I–†ØËï0k,üriNF3'mr\;¨M»ìÁlÙ¸r÷“ÔÍUë¦.ŽÃ}²¿ÅˆX8OÞs~B§ëlR¼9va넵«T¿P Âa4I•vŽVÏnaa‘ÆÊR­Ð%^À1&þÈi&¢oRëƒU~¯t+–;ÿn¿T 1Åš:S:ÃùœMO “Û+Nã¡ù%b®ù™‰ßÏÏ÷™ØŽ’l(ÒIyóé¨êìo|shA„î´]îO²ö2w%3ï>Vfž´,M4`EÌòû t¥iM•îÙÔ¡:#—TÙÐñ˜BÖëÇÖÇoA»¼ÁÍ×°~ñÕÉ0¶õ¬~ßï»OEœ âjDÜH2ÇÜÇÅŸ^½Lcð¢AA¢ãÒ³Å)ÒWtÀ¨ãÔTC4zpäÝo§…02BËùÞ+ë‘„2 ÁuÆ6ÒåFVŒòºñPYëàj_…{燖aFÄœ¬l‘ÚŒR™iê³##ÑÖlðx(sÃáäIì_ï‹k ô=Ö™EaÉwBŽQGÏ«(%ý{áXYFŒ¦M`}BQ@ÄõBC9…,2¡÷&È…še:“C)/–e©uæõ±ÄÊLHB†Öñ0ƒÌj *s×ÿêòæTÛ{h8‰!/£v³'á¾&ìXh#kå@iëa‰ÝDcZSw ¶¶ƒa¯`õ¢í×·=öû#§®+àÖÿö¿»jmÉjÙlÞyþĉß8óë¿öÅÇW°ÙA[ëˆ2”¬f¿úmŠ0;õï !¯h¦9¶ LzÚÎã/„Üè³yµÆûä7 ™Q1¤8¤ßá¡] Ï›ôˆÑ­ÑØZ*°3þªÆð!Ϊ;‹LŠª¥X}6Ž w*ŠL‰œßžÆ£¬¾íȃ˜%gx\=HΗ…(E¨%%t&¦#þþz+Û§];4  c€b]&ñ“öLÐF{CÞ!g-¬N$ûQ“ŽXR¸5~6ÍÊÛT¦„˜ ïÚö³ÿŽá¬•¤Cµ=2´±']gС±¸&ƒ¸Ì»ÃÇbæ0Z7tVÓÞÙZÚ^˜$\¨mîSJï4.S5wP»5SOT‘X˜ #­sHy¿C½a̶Ðà5uÀ{ÌñO¤­3Aâ¾D[”q§µQ®ò}Šâ*Þýè,SëOÑ®y](µ­WÚ8vË»ßÿ’¯Y­7÷‹2ÇòÝøp]1›íöªµ¥ªØ;¦àó?ÿ+.œ;÷ÏŸúÀû¿áÖ§Ÿ†l6Ý®Î2Bïq÷ÌkÚœ`qÉL&湜'Ò…#yÑÛ©êfØ‘„ÔmÎmìQ?(¿ODÔ‘j—Y—Îi+hü±ò“D3ÁÁg‚͉VÔû¯‰†]þb“É¥-"Hn_”@_A?³¬%*¤1¡8iƒŒ wçDIy]á–8'siª}]ùÜÌØóU ùæ¨ hbŠíÄ¡|Ãë„Üü4?=[^–ÌY›À¬btÄ=’Y±ãhéAl>±1ŽÈa‰™ïpðè?<øÒ•BI½nÍ6Ù%>k~˜Ëøœ‹÷Šî–],å$X,Ä`wBÓý \U˜-ëNMÆ Ø+ªØo~å–ßÿ’× «Õ½ºßGLïMוçÃxˆ®Î?ÐýúÔS—Žÿÿýÿrñ•¯úóÞvۣϴÙ7ìUqØà#qÔÎ}îÕO£ß½6 0'«8Ѐjs)ZÓwñξÿÑYI¦ýV¥Í…ý¨Ùz/R' ²{ʱÿ†œ€Ñ¶¬ÈÿÐÛÇ*„ðij†Å³6.V¸†x2A|EztÂi¤"ìÞ?÷•Ê»&–̆ٙ; }”G="ŽÊST±—Ï꬞[ƒ ±~{Œ¾…Œíë’ûÈÒ[^¤`EC ãx˜Ûuµ\å`ŽŒ£Ã«}­]ð"•µåH>LÝN) BÒVäÊã;*æ_$½ax¬Zb0-SMTܽذ”Ñ®î'óS4ߺ͞@â\gaÒP”ƒÂL²õmwqRÍ®lq+ÇLy]i€Æ7ž+g€&ÚñOΦî³]2qXò+Ç'-n¿ÚgÍÃlx>^¾BÓ©™áSM}Áp»ݺÙbd†žœ=»¾u¿Ù|ù ¸÷fÌý_áºb> Ú O? ½ýEÿêÔõ_ÞùÁÝþ/[¯1´i Í™†Ã~A´_¥¦ëøýHqº­7"õŒ H\.KøaÌ€bd6Œ(°MÍþíéï S&@‘ѤkGS¿Š J~ñ•ÇnóŒñ6 æeš$46$c0:R~rdÄèEiÃ.¹:#0§hgæCIò"DÏÄ¿ô«A²y»9‚ס bôm•Ó87+%lEöë˜vÉæ›ûdFË»ÍEøì… bÏ´oðŒ‰È+XøLîh‘éQeÔ 3ã’~1oÄ µÏÆ,Ù ²´«]$ÒÞÎTÙ{wožèr³vÒ9BÝ»¬ à›Y›ð±ü—NÌ L€<ýµÜ³¡ôŽy+ð}ûŸk0]ñ o¤:Ä9liLã`8ÕñfâߨߦãýçgÆÏ PŠЧxHð¯Ow6 ?.š×ëf†›ž:º¸r»Ãý©ÇŽû ÷¼èö/þÀf{÷Ó û†}5ãùÔ®ÿíuTÏ·þ{ë¿3# þ¼FxôKÀª|tÆ"Æhí2mš†FȨïaB‰)±>l,êãÐtQ“¶ †ç2‘Úû3okcEùÌ^ú åRšÙƒÆ„”ÀZ–Ä‘]˜s‰¢sNI…›*qEL¨UG‰%K×v>²ˆGÒj¿¬¨ÍObcŸ-ö¿R¤dæ³°¶‘‰$xíXYËBa©Z&;¯n¸-Ö(šÇ̇ ÆÇù1!Y9ÙjmÈ(àH?·Óe:˜š8Ÿš .!íÆ©Lß²KÌ„Ç:™{í=XŽÜFå}ìÿ²ç:-¡‚¤a¥àó?tʱT?Dl&ÊL¼ Œ[ ‡ñ¸üyñÿfÖÒY„Ô“33Úú}mþ»®M›3Z &he†£u¼¨´&|웢iàÀƒ¼çÖ¾ü,ÚŸÅI+ƶÀ @ ªØ¶@^÷îÝÁ«~{wì¯ß¿ZŸUH û¾u©¼ÿk­kÚȹî)‰ì¾Ô½1þwÿ½ðPû«s¸Æ 4"ÒÆi q¾,¡šÖ¥)—$À…@ûÄn0 DA °"ýæ7¬Ž¸ƒøgfÀ ¥q*&#v-ýáu:O6ãìEHX> Ѧ´¡kЮNð›¨Û¿mŠ®¾L2VubUUd î „ÁH¼“@lUG¨Á4d†vì::auæNHr'µi^98Îg‚¥3¶ïg2Ä’dÈÅÄ‘Ö&1h“QAùÂãD¸¼çÜ«•Õ×1ö ©BxþDPKD9Ýšèƒç Åî'ñ`M5´<öê`@3agöiü½9ÝY¿Ä¨1¼¯Š†D÷ è;^;´ ÐOàØ[Èk’àóR#þ±~û2[/…­[ ¦«Kù.°ôõ:†»\¾_õï>´o'üÊ… [ÀÂÌÂF­á̰úGo߼쮃ƒŸ;?¬ÆJbª¤‚Ÿù „TªNœGŸÈ•íj*ºZL y…/ÁDr“C˜UÓ6­‚]° œ­ ØxúßfÏç*`1¶P$²Ýߢ Ì3>´ ɆNR݉U{~B§ABHRGy¡X‚›¨wÈ ON¼7 ¡³ƒLØmŽ&µùgd)0Ö†Ô­%DÀ±ÂRê‡ÎŠÉË) ÄÆO„çÁNULõŒ€ ´ö±OÒ+"½k&å™c/²­~ºlsª½\0õárÞ̼VIö×IÓåsPî‰?JŒNïãÔथß9Az¿±FùÌ{»ÊŸ&®ÅÔÄLˆ¤s¡ÔLºF´“ê-Úv ÒF&§5"~î’cp¹nª4mgŸ>ã=û+´HïXß+ÏÈ€SŠ_»wß^ñ¤¶¿³ÁBäž –µ™Ãǵa>þõæëÞ´Ù¼úÃëÍï]Áº;îííÒJ?ŒÆå#¸V¾£6@\½jªY b$f S¶ËÛ³Î(òHFÄN¤Ù†€%¶*¸2²ôKfÌÍÊä:a®„=ÌÍ9 §=O¶Y³‘Ô§úo$yuºc*A-ý޲öæëÐJÛYž¢ìÓ*“²qÈ(1DP”ì÷B -„¤±ZˆFHœBfy+<®ÛÅÆXpñgÌ¡‘¨a¼QsN`O8Ï Ó½¬ÐöY$m}æ*L}iàĈØo±ó¹%¹xŒ¤Ïv*™’Kú¿è ±´Å¶Oµr£M‹™ßœ”Š:)ç/Ý)ê7E–ØšCÜœ ÐXçÒ>Ÿ¤ˆ€‘r¯ÉiažçøÔϬk–è)ukûbfMfy§J–Î°Ó iGL!Ç…µ÷û/*qÎ…Í£ï5P5ÐQùäÔÉÖ¾étÓ/Sà½ëÉ™Z ÂÂ< (F®òU¢½öwÖ«oÜüÀ©ÍúŠX¹ºK݃ßÔú{âNC#`*úQ5~¡-hލÇgŒÀ'Æ€4N$]]è=ÛÇ;ô I2j"fû@IÔ«!ÌNGÜ»sìb Ñø®ÓR¥ê\½õzXÛèµ!kCØ~{T¤p͈ @²eòólrõiL™¥<íêÚÔoÅÑý ¶'ÒÏFÔˆÛ&­È4r¤ÏÅ(Ñ?^ÃüRF{®²/ {ûæ4å‹4•µMýkÄ2f,|ì%m›x^yÙW|z&ø‰¤¹ñý¬LNo+I§ô»ò3ê{êkRȇ½ÃUëRo3“ãóì÷ŽÆ³÷9šÁ¿•¹·®cSF.}Ës´\ |O\kI{Ž}—ã£äÄÌx¾Cªù.äc5aÇžH>-q>ãˆ4gÆhh­›Mû?iá4¸pI÷kû±û_zYÛOíd!lŸ*,ëô)ÂN pé¡ÕðÝï\oO¼k³ù…‹Ã€o01íû£“ 9­1‡q#Faï&_Ø1³˜º–H7 !ÑšsßÜE… Ñ74Èh>¨&b^ˆÓ¯šF$¢qd¿ÇÑÅD iFo¬)?Û;¶îÎàR«zrzm‚8QÙ›Ìö¸)as6&*Ñ’(›Ž ¶åF'¤¥9F |Ô/šëÌ#¤Ùx‚ÿn¤%`à”.7¶ÄjkPÔx§)ÍJëkñŽ•‰ŽIåšöº”5⽩ç.m±æÏ&a“"$Ý úšk:ÔómçxägBÅw‹"VŒ–CCõ>cßW 5~eth·ÓHâ³ N\3©õ°"œþxuíÂf†!Îo£ó(Î’ ¿¿køªÐÜYÙðNa‚›kHãÎíû“ø¨¯ã ‚½ xxë}ûö‡žjí5+àôz‘ù?-X€Oãb¨b£í¿·Ú|õ^ýáÍæÃM$üœP…”žúá¤g®Á%ana^ðw]ZIÀ¿SæÎÙEŒTd>¦¸”Ù!.ˆò€$Ü”Be…³'?sò,¹jöP&þB뀌‰ô»B²kb=뇀’$àjª±þú6eÒéú̦ÆùD’:¶®=2é M€ %fè#iÔ&ÏsLD›/ti¢O(ª(š †Ç¤ùቪŠ$+fÈÛ8øìÙÁ$<Þ”ôù(ЙSšö;VœÙ™Éc§¥kAR¨^Ù—¦éœÅü¦¾5ù¾ò8h7ÈXÓ‰Éw¶½k6O~‰¿CoiW„ž‡õkÚJi'Ø–­tÒf—ê70Î…Ÿ6ñSÒ¦nº³6(Ú0à¬à½ûý·=ºoX·muÿg ðÀà¸*žR¼ö½›ÍËÞppðƒ®VW Q"ØãøéŸE°MŸãø !¡¢kˆ¤°½ Ú´‹H41„8˜Ð:ì½.aj)ƒ)í¦ïzjÓ"$“çDJad">ɻΠPf[3³¥')¹3FäÄP°ÿÖç;ƒ”ʦñïiîÝæJi/Žhƒ™)¾Iì5·#d™¼ð¬“ƒ§Q.Éç-“`)C‹Ïá~ÅÊ#}ÏkòʸqŸqŽògÐr>©÷ôŒô3 ¶F}a"ºÉf3k{ç2ÎÓ™Ì1*œíŸûtfw´¼Ç÷×lá¾}­'95ã©qøúÿUÓ€LÂ(f˜Ÿrq&ZÅþOD(±Dž@ 9‚G¢€q˜ô}R×6xq«þ @ðä0à”âgÜïO<ÙÚ®/j¶À§ ð‚8€b«úÔýÃê»Þ¾Ù¾ìÝ›í/]­°ÒŽ·pØÿYæÀ1DŸË„Rƒ"M’³‘åp_W¯YVAfˆ€r€3ú›;.ªøøMýGšEò#ðïý÷-\:Ð`v’ÃcS¤¢Ñ&2D2¢ *Ð@Zþ«NX5›$!Qsîw>±gÏ >ÛÆ~&—ÛFù¤.me"ELI»©ƒ u}l!å©?#˜“¤leªRpM’§ g²,ÌBý•™Ñ¹g*³Z+KÕ[ñŸê"”f­ô\ˆ3»u‰‰!âuÎßæ³l+–ï|¾/öc]3sx›Ih˜·íñÄÔ{Æ¿¤AÈš¸g1¦FÏ›YÀlôi¶î*âGZFÖøØu\ÛÃAðˆè=Ûï¿äܾ}ÃZäÞõlIÍ>X€ç†dŽ©b§ú¾«¯ü­íöÕÞ¬?¸‡`Ýü?÷׬ °Ï‡ È„#¡]н7ör#¤–/Йˆ¯ ÅkºÔÞI†ÌÜ`ˆoO¾ lg•„pâ³y‰8ä¸ä0$æÌŒ­sØ(Ý\àßGû,]©ÿ7¨§ÇÞÛØˆxY’ÕÚãÕ9r4D£ìœÅDÀ”Þ&IõÞ¿òjY³Ñ¦…ÉÕìýv"ê€ÖÉÈMR¹hÞ áB/ÌP•ÑЀQ5â?e|ò^ÄwUÛ¤©é)‘~&A3Læ”¸ÆøBžOE&©w=Ÿ¦õžc 2‰MÑ6äGSûɉ{˜!P¯¦;ah¼­¬µûh|N ù>÷ssì}´˜öˆŸÆƒöù©Ï ¿‹ŠäÏä8 Ñ—b̧(¡ëÇDpNpö¾¦ÿÇ£ûý+›¶ßØÈ¢î¿Z°0W ,Zà àµï[¯N¼u³ýžÖëgÅXf¸WÅ2B½‡ºF€ë 8’Rö0' i͉P¿¦J¼1ŒÏ·mÃÝ-RB+1!<€1©Á• H²ð¾£þ¥‚i„H€Œà@s ?;oÕPØ› x~©æý3i;§§…3=¨¤~&’šQœ9šIs¬ÎWþWwT%&Cƒéòw}r†z“Ê=¡3ÄÍbÕ¬²fV¢Ž’Ÿ™#ßö+¯_r{äëÄÒ b†ø§êuÄðˆö¢GÑW4_ëUÀ¿eÎi(™d²S«N÷K,aM® :wFÝ-%È\=§R‰y0õá;¬^›˜£bIw\Òr½w¤t®¿ßÝ ròº*[{ÁÂ|–à¸*VÀ?±Z}Õoî¾ö›ÍGö2`«–ß¼^ ã0ß“jCÂ.þÈá‚ÀÔ¡ÏTÞœœÈ ¯°z’¤H‰k,²€ÒK,›?ƒÒ\ª˜›Ôñ°9f¬ÞÅYç¢8Œå²\¨U ¡ñ~ŠØž%·L|XÊã5²ÿÈäÄ}"”J®hú¿\Εö¬úyLQ£Äx4Ê8'7€â„YëÊgbeÖYûÃ^6ðNLÊFT>*gïK½Ò^åÙùú»T\~RjIK³¶öé;:˜N,-¡ú“¥¯ˆã«ü9ž.T¦Ò|Ea¥|I, B+=^:ÖØ×:—× ;gÿ,-æ•»¦TËö}ú"Ú­N†Fö\µ*1*5“’Ö$½™µöd§³¿Gìʳóïøs3kítÉùI­S޾•ÙA·ÑSl¦IÿIá¸þÙæNó-Q›ÚÄ˰Ý'ÄÛÊOhj;Î3§Î˜9OUr÷š)К®ϱ9´|–¬ßt®M;@þ ‘ä¾®9 'gZŒ¡wÜSjqô:`,Üóä—ïoíÄ¥¦k#¸¸îùìÃÂ<°UÅ­ªO<,Ãwÿöv{ç;7›_¾8 Xõ[ê/`„±û˜ÓÌ£¿æ ’ž Bmê;Im%îÑ·;±Õ‘T”Û‰»$Usøw¬Z–htoH†¨nH 6z2?°ÒÛBŠÂ3Âë _BâÖ™U“ó•³b,‘1¢-Ö¹$/gù«/I„R‘*ƒ5Rh•)tmÊ6¦DZ5l¦UL,Tœ ÿµQ;¤b~B˜Ÿõ3¯3By `ôOGIu¼·>?¶¿óû~~²Š_I²LÞþDX¯ÅwݒЈèFN|žI›‰xÉëb oÜCıYmÕt~ý3Ëáý6ý<¦Ù+ a0oÌ´˜tN8™¡UYÙûCÏNèívîž³#ô4ß}Š 0¼Ó™eœùèI•WŸÞï¿b~w!üÏ, Àó#"xï½Ãê+Þ¸Û}Õû·Û÷]³ ‰[Þw"kŽ2¹nwöpfÀ‰­ôï̦šß'èßï…~w¢Äòh¨[AzYbèßUÓÔ&–ŠU­¥( Tm×`w!’İ„S}ï\Ó?þ½n™{_‹ë¯‰Ÿ¦«UÈðú“%qB•àl}bd¬VïRù(ðÚçù‚lÆcÎ GêÛÜ7ïzíGÓØòóÜs~Sk}lnó÷FÄiÏY»ÿGUû‡ŠúÙíúÉò4Ý´øÅ+^×zV+KC·æˆµHséßµôNøÎÔTÌÉWFáÌ÷Ù¨ÀŽJkËý]áýdsb80ÛšfÊ‘†¡~ïcºžÜüÐCM_vEõµKžçày†5€©â¢È/¾s»½ãí»Ýß~p½¾0Èx1]ÚæK/Y…”Kšýà f>É%÷B:j‹³p‚ÒNu"]s„+Úqí;zU?ÍÌ ÅÉ‘L…°{-Ä„Þ_ÛŒ¤böÞ‹·“dúdÊÓ± …Uކ#}5Y3©ëDã3?âŸíJó ¿¾uâútˤÈ9k ÞÌcÈÄ5ì¹óÏ8Yæµ›D¼RÒÔ¤+L¨Ó_ÌŠM9úáC;0®‘GI€[¶õÉ{Nu)ñÓŒ¶Á™2o4ü$êŒÂ ×ÎL1¶tŽ"æa{>γ§þ¶ÙxDHöýÙ[¿Æd«¢ ´–…™ÉZImÀJ€§‡äu÷ïÛ+/4ý΋ºÿ…‚…x@1úÜ¢­ù{¿½Û¸{³ûÙs²ÂZ¸ê_C•6ú¨'òaç>Vé;çMHÌœ9x.Þ?l€¤"4ç2CnGrNdwQ·êÌm6ç–6¾ÊÎM9‚ VJca'X‰¹™’ýñ¥¢•þ¢vc}ú¯…ˆ”ý Œ§Z˜¬¾Ž÷…J†f-ýqLvû>an'ÂÒr¨¡ØƒI<Ôü{}^%!{QaåRkL0’ɉ×@¸ROÔP9åW3+3o¬è¿æÎÛd5Fò#Èx=ðýt‚_òé±n®£ZìÀÿìíœß_S®³ñ§ÂStNÜ<¢a¦po$efKÓ9sšâðÇŽÉ­› BiîÐ,ö"x\äŸhûo<½?übܳ8ù½°°0/Ø¥8P…¨Þ{ï0|ý[·Û¯|ßfóáCVšmþæÈ³‡`o¦º€Ö&b[¼yçØxMHŒ# ’SÿÇ%‡ÃKyD8!•³»=CcLˆ¥ë@sX!wU’r%!±°«r‰_ê_1é7«Å3¡ ÆË$Géÿ2 !òP°Âdâ³ÎÌß½Çi-Œø°ÅnLÖÉ $Mó ûØx$c%Çpç3{ôTÅŸ×(Ÿ\–È kÀÔNçZËóI&¨"-ç¾mÍH5Âg•:ÔÔvv.ä½I˂ЪÔ9‡T_æ!1Ù^oD9mG°ªfgO)½íŽ•pŸg¾iƒÍDH“×÷”9ÄXÛe¥^ìN…Qéü†oŒ;ä*ç,ú°Ñ̃ûÖ“s‹à)< únzâJÛÿô ñ¹`Ùƒc´À‹Tq ø¥·o6wÞµÝýàÃëÕ•41Á‰ß’½~®Œl$‰àrÏ$‡ T–šØÚâ6Ç €4–‘º©À›‡Eò$–#™XRbB ^ª„¾OírMÿ4­™K0 &„þÅ|Õûpë¬EWŠ»ÔçTÕ’•ùûñ;Ê# Lp‚¹Iç„lL¤ØùoÒG§‚yMØØ—¥¾J…Æ–IÇŒ„kBó ‘…†ª˜})|(=™Au<õ_zëÂû© “QA25g+¦Z(ÛñøŽéÐ2ò Ñüêº+F™ÎÍ€ç’ûɧ3ÎD¾7¦Aè™0‰'4Æ3ŠhÜa=Iý±n uf¸‘óhƒÝò8ñfR\ p8 xLð¦ûZûÚþ­àü’ÌçÚ…¸F@lØ©^:#ò]oÞœxëöàµV+l5´´ŠžÁ¯ÇÙz)a ÂÍYùÿ÷ä_´GçöS¹RÊ4ˆ™ð¼B¨“M¿Ï‚} E2‚ ç;$Õo’„mV’ %Óœì‡pl`HŽcÔ'ÛÙÍ©Œ|æû¤?ZÜß”ÖIò؇ähXí·lœ¸pºS&–ՎmÀn˜Ulm8!PFϹ€PZ°ÜU|SáϽ_Ž|0B3T)[˜äÏeÒ²uœMÓqhjÓd”Póà™ÉªEŠhmÝž^¥Ô§Òù<:i•úíDÜÖž©Ú šîèÖ!i.&Cf“Ì|Ì9ßËf ‰¸‡1¿0s„¸€g_œäÌIà¯Qý|U¼uƒ®5X€k cJá¦ú­×¯~Óv÷'w³y÷•X³ðh“TJ™s>#FnèÃÛg Bž| hŒž\ȉ!3 ? O~ ¦ö`ŽÉÍKKôëdgõ휟¥ý²²˜j.JÈ)uDü0 ™,ZÒž“3幓bÄ?…úõ9¥B=´FfZ0?½3&ãS+QÊ€Go>©í]lí›7À‹wÿµ pã£àã2üÐ[·Û;ß°Ûýì™ÕÊ“™äîɃ¤gþ#Qõhß{þÍ5šè„I0$– JÛÒ𾂉ð‡tJøö¡AæÈÈ>ÜžXŒÌlÁ вÊR© Ĺð)½K¦ã«³º6Sצv»4 ÒêÊ´Í05D'ÌÄQ2ÜI˜ßŸ—G}i_‚:FÛ…„&xi:¼û?ñ‘É ¦7¤}v4C™1Km&/~ÎU! t‚t‚õnïôþMS¢š4WêjñÞUí©¢ôÓõÓA;—âï1c¢$4;®­*:~m-î½í, ˜-H”ßµþ­@”Í“†Y12¾`ßbLÀÙaõèIà[iíðÛ‹ºÿú€…¸@ܪ Q|ü}ëÍ׿i·ûÓÜlÞ{YF³€G'’ ¬E ¸C‘È,©¤Œ‚ Ø$ÌA’æÎÉH¼=r~‚ʬ­ßžo`”?þ×Õþl^ i2ÞïmÅÉ$%›1ŒÈŠHÇ4> ¢^Ûw+41"tÄ •šv»{ëºBa\ˆÛAö`ÍÝxWd›NÈ4‚Qº´ÝdD&C×Dïf:Eþ•%ÿÊ`h¬¯˜SƒÂ ɸ3žõ:gX/Ž1—2e›Ÿ;VöóívõJ”57@{lkof´FvFŠ8±½s5̪ÙPàlkG¬Ÿ¾ˆ¦’Ïõ¸ô‘†?G§0Õµwe#cMV# ])8B LE‘O ‚T~òTkw>ÝôÇ7…¨\G°ìÕuŠ1Zàø¨Îÿ÷ïØlîüÍÝÁß¼½¾°Ò1Z€¥ïѶkÞì,Ñꌄ_Ò÷º¦@] !ù HKÒ, E£xèFâL¥‡<6E¨·yœ&ÀMœÐøLKŽzÕ—f3M (Î{¡AH!¤µ$΄uñüê~†¤˜ŸjÚ#$ÔÀüf&Œ•àhÒüX³¡Mÿ“MINNcä4A³šwžÔÔË¡ß&]çÆ)äNÌó<ÖÛ×>¸4’öc-XÊ…4nWi§‘ÆÊFѴ²#)Ié&?kÙ«é¾+1ŒYÙG­Ì@çpœÈ»CaéT„IÙ<ÖÕû’ÛM‘CVw£ã~Eœõ°›éD€+ÀÇüÎ} _zæß<§Öó$ \ð0×!ì8€¶‡VÃ?¸k»½ã-»ÝO]­°éÄLQÇ4ãw{ “@C÷q¢ &¼šˆ»;¦‘Tcµ ²"Dìÿï¶Ç@÷[Bf°^½ÀšŠÖ;3Bb«uŠx ½7´¤ í¿êób©ÕÉ^ht½­ø=÷ñ|ñr›'Ü6Í 'r¥´–-Õ)c¡È6âã­bR¿`†@Óôý £4VSz·œ‰Lì¹O#þêï1éÎz&þÜ®"/n¬—¸c›ç’@§3šbgk.Q‰q’[[Ú+#ô<>WÙsiç ùEh¾»JIªT!ÚÒ^X®˜ºI¢Ï¤Që°ƒŸö±[›fR´3ÊÄü0àÜ OÔö·Ý·?(Š_ßÈ”—^àú€…¸ÁpÆqUlŸøÀjóM¯Ûl¿ø=›Í».ËX|ˆ ye\bèÈÀ|€ æœéŒ“ 9qt§ õ4Ãèm³Ó ãâÂájBíNž3…0À^ÚìT¦]Ó!óãu2DgkÀ~ü¢êíý2Р“€*áEmš c~2ÔÕËŽøAÌ!|ׄqœ0.µÆz¡q&¢høÏ`ÞreAÌíKzUi\‰vOP¡H˜þ™ìÍ¡¨LÿjŸƒ^²+;GÚ¼ÜSWMiÝr› '̓Ý%g1“!¶i¡Büm4Îj¬#3••AQºã‘…"|XÄÏ£Gø)´±OÑ.غA3C*Ϋáàûªã¯O üìÃ{½ãRkÙ å¿®aa®cPŒx«*ž¾î]ëÍ+_wìØÿù‰Õú©AÃ?À.2ö=««ûÍoàT»êï4éÅ‚ÈfÈ^Ñ•0jÊ;ž“‚xI"FÝ"½Í©÷4¼í"©"BÅæhT¬Û€E3‰pA³Ã3CÑß±q ùgÜ—m¦ñmüÁÄsÖü@/äbM™q12Æ^w 1*™ÀÅwÚýF߉ çÒýª¹=ù°]¿·9±§Z2yâAÁó¤Ý®ž%{v”I3á“!ÊíØŸúhj#ûRغÚpf,\:²öÀrõ+Åsæü£Aa—‰Ùɵ¾cÙw G¸˜¯IÊ)aÌ%Ï%2õ»ez+6±Eb˜(,™Ï£ƒ¼ïÕ?u¶í¿~>º^’ùܰ07(€ ûV«ÿë›ÍoÝnîñõh0ÃÐd,Ç ôì}˜G6ÉIAœF‚ØF5ˆi8²$1 ¡óß9!‘„¯Á\f*@ã2/ÎOÌI›ãˆØm¦žJL õÉ„ÒM©-g³`’òü¹ e‡¿ø=äÀîœ)ÜG6µ›–"¾Ë m,ô "yG¨só¼03¶è/Ùø¹ òÝï+F^Ù¦ù,€ÓŽÓY ÆF}B£Ä¿æ ‹y/˜9ŽçuâX«Xòð<‰OaVxÜ"c ‘”kzRóã *­¥Ý!·º•'eëÓ4»RaTcÍÆÎœyú¤â{kúò½êX*öÝX°07"8¦ŠmkýÀzõuÿiwì‹ß½Ù¾í2/9ì]á>cr #úêê]FôIÍ­Hêöp4 5½%r5¤vÓ!d~F:¯±ä›ÿó~µTÛLÜÔüDx"ˆ´jWé’ǵ&‚%6*V×2ðZ›³ õJÔ”MÙYŠÏ’䄨–±¡£°B©^ õ[¾vxŸ‘—ô½+Qè³i@¿ƒÆ—Dvû?ó(ÎQ&6f™sGD#±ÆYJ·vÝ–®…Ó™ñL­¦mÏëÚ9±ýK¨NöF;ìŒCÓò{˜Æ8§DhÙµ[Ø :#®uS^3ÖôðÂýØeÐóú#4fc#þÔ<,òïN©¾ì‰Ö¾o \^ˆÅËžÞ€`Ñ—€×½{½ùC¿¾;øËY¯O£ÝÛMh$ÈêŸ=Ö‘±ŽVH 꿜à®TA8øué£c±F-´ AüR.|« Ð |FpÁ4BJHúЛQú>"²D®=,¢nò=!l²m3–Ÿ²ìà¢qšƒ`EAæ]gŒ óð( +ܤNл Ú(zBÐÇ|FâOúfÂŒ©(Zùì*ýÎD¬è2œbsªaÐÿs2¤ðŸ°ÿãÌŠ<&Ê~®”F`çÚ?¨Çõó™v;›F xÿ̸hœ§‘¡ÐÉœ,ŒÏb…­]|ÑÒ}ÐBœÙ!.еd}¯9ñ×x±í½JJ$†6Žk…Ê€Ç!ï?¹×¯>§û¯Y\cà†(nkŠSÃðÏ^¿Ý}î›·ÛlµÂ=› r˜]õ§ÁIsêÚ6˜‘–©­„°'1Â^óìâtBÎHÐÚ4¢b¾Ûmš‰#j ÷qèý&{tµß æÍœš&‰ÿNÄ[yg|ÑÞ‘>nB΄˜hó»d7•nÕ¤Ð/R¥³œýr-6…ÔáÕøÞ0Û»ögÒd ôûB8Ÿ4*¾ª¦Ÿ¨kçkô±Û¸ó´§3[ÃïkD_ƒÊÌ Û0 óà oD™˜Z7Ù„Þ³sg«yµàδÆ:h߸ħ6«Ó«öcT×9ưïëÁy T\†gPýžÇ[;q¨ú ‹ºÿƇ…¸ÁpÌ­ªØ¨ž¹oµúÖ»6›/|÷zsÏÓÃ0qTDœñÚÕæa7„W‰#Ç7Hg"„<ý9mq87,¡…½4IœL ælªjP©èŠ}ÌÆêmdi‘mÄ’ÙØ)±¢î誖 Ç·àAzë= Î0×XÿíõBÔVzA›¨ç3v:éîàç‰v„—:ôßzcµÀŒúÁÆÖßu3€„mßI|Ã@ó³¶bö™›©Î“&;á¦3æÅ“ˆ ÚÙ ¦€uf:C‚7~×=Ì ”ö.û+Ø3Á û°ÿ í˜QoµE3§B{ÊÇ—"‰Ã3ѲŒÌ³[”c€™!aŸ‡q]Eƒ—ÁÃÀ|@õ>Ùôû·Ã%…ïÍ p€b4 ÜÚ‡Š×ß³Ù|Þ¶Ûï¸w½>À“µ.eì1ªÍSÂN á¡®1½©!CÅi·I˜Xej#©cÙŽmêÚÞ¦%+i½Y£vQÂÿ¿Û?'*lË'4û6ôwylÖтɒü8l/{÷Oâìí;e©šÛ јP¾B]ûb&íoÏØÙäš2Á­§§U©¦uIªsƒQ3&Ò9ü±Ï‰ÇÑ´9ÁÇY$}¹DŸ™Jú>‡d]MJgû ÍVOz·/ˆP·-7, ÀMбÈÐ1U}Rå‡ß¾Ù~îvÿâ±a…µf³0jÑk ˜-Ûs „3Í•Y˜8ë%ý®ŠdÒ ñ{h4©k=¾Z ²$ïö_à4ÔÕ:%|EÓÁÞÞ€tgÅÖ}ªIka½öUóGúÿ,ï6znÃH¶ø´z¦Êö9ËH9¹ :#U¼$͈°’¬È”¨:ôõ I™h칉OCÞ}ÑR”µ™]¦¯¯#mkìÍbúQú;ô鯨z43hAÌ# ¦™¶¦sñ;ÒÌQ1»ö9“¡Ñ~0qž“iŽÆ5¾o9ØÉOÂÇÆ×1ΧŠà‰aÀý¢ÿð¡¦'®¨þôzª?[à&€…¸IápÿÇV«¿øæíæ ޳ݾñIlÔ2æq´º4!Ts@™©·iËóØã©>4§Ž(÷½MnÏe5¬6)…Õ009Ò‹‘l˜*!*¦Îm)Ê¥ÆÔi ¤ÐÆl‰·P1ÐC*åwØAR’N^ÝlÿŽé8°ÉÂûètJ:gÁ%ÌTPîœî8©Û©#³p­þ¬Å4’>³@^w[¡2µ c´¾f’ŸóÖÆÅ0šÚ N-;ë™nŠýš·%BΖ<¾æËûçÌ*ÇÛWGfŒøÄ9ƒ,‘d‰çfÚ„|òF3•Gè8#«v ‚G ¿þ ôó.êþo¬€³‹ºÿæ……¸IA1šnQ…¨¾ñ]ëÍüÖîà/~t½>¥³ÿkªØ‹`oÒ³p^óìÇÚÜFðp›6?ëcÕLFFSˆ¦LÈ é6R¿ѯ"b‘)ps«G?øwŒèÖs!Xÿ}L”¸oû#·Ì¾A<“QTÁ¡yÉ‘ôœ§aŠâBî¶hJì2‘e¦ Ú›‰ëEVÀ¤ÌõoÚO×ÃCíF$€“I[º¹©ìÀíD»Æ)e§¹`[hT,)û ”Ï´ã>·<ÄÙý ‚}ã„X5êКQa†g(ç]‚ùìÔ_»Hœ†OܧúçoíKEñöEê_`aÀcØàùaø÷l6w¼~»ýÇ­VXéx@LªpÁ(œ3 fé]Ë;9º@a7Ù+r„MŸ¡÷+!i9#acHÔuªjöˆ–ØÊ¸mŒü]D°ì¦Nl¹÷ÊéÒK¶ég6\‚cí'øAzgÊ@1-4­—cÎÕ%k XOíÐ2ƼJÇê_ŠW‡„ïç ×€ð%˜[/¯F—æÊëD<—oFô™w°MæZX‰2ÖL³@Ï%Ÿqü‘8+v5ë'Hƒda¹Ê‘0JNµãBÏ1ج·`ÆÃÎI땟èýŠyxôîÿ׋wÿ °€Ã±1Zàñ Ã_{Óv÷‡~g»}ýE‘TrØÔ¡}Vr0SÎàW# Š×½ù9&©§îú»b^ÏDS-{ÚÍůêWrÔzmkuÛÞüÄJ'3A/²r"è>úkò.ŠBó;™±‰É䱂„ØPaÛƒRæìÂ#½ÇËæEƒtú[êSc'Aöïùýe_6 YÉmPË8ißFâG6u™YÛÞ^ìo߷⌠¡Ä\zö$ßeo‹N1–žk¢0Q|Üæ/¡ÑÑžWô9æ©îŸ0aæhó´³¹,‚GT~릯:×ôÛWÀùEÝ¿ÃÂ,à ÄqU¬·ýîzõ…¿ºÛý¥l6:fÔH4"."ä ÄN±ÿ†€kž“´ª&èÎy]âfË’wG€‘é.ŠùïNtCblȉg11õs· [²žHÃ:Õ0˜—63=Þ>ˆp"¯6âÐ0 [#NÍœ’ÇÐ|ÌΞï6“ˆÝ»Çe}jž«?„ç´Ž6¶PR‡ŠÞýŒÂ&µÛûìK`rzÎïm‰BZŒ­®4rbµ}B„öiáhÔ½õGï~K³ëò~à´l ŸChxþ1YGeâ±g7„ÞLœ®w-ĶF6¹ØÄ¥ûtHσ‚¡‰ŒÙaArô€Ú¢ñSñ³ÊŒm–r‰±zäŒç©Pê“SX‹;uŠ3k¡‚'†îùg´öÒg?¾,H~#a9  à@·4}ìã«õ_ûÍÝÁ«Þ½ÝüÖ¥aK›äFªô‘ ‡?À\¶ÁÉß&ÁÛ÷T ˆ 1KC¬Re»1ì{ „¡‰,‘æG{/Ùt“Ä®„ü‘ Š4JÌEŽ%Ã]‹8Í2/*e¯ó'aÛ©ã3Â6ô±ÍL²à3!Ÿn*Ÿ%}èÿóaV½çþh¯u *c#þ+¿“¿sÕ~uÆ~~š×"%´2¾jçè¨ý›žŸ‰/†jr܃"í±¯}/sX¡kO’¿¨R®€q,W†Ã[îW|Á…¦y <²ZDþ> , ÀŸ£Y ‰ÞýÁõú‹~u»ûƬ7Ÿ8„ù´PíKä;·t·£ŠWÉÑÉ„H‹ËN‚¡~EdDØXkq f8!R6À´ g ŸÕûHÅz"n^]­žU´¶Zf20u±©µ#o{Jžd³ ̉G ¥±†„O„”ægêi¶ß‡ÍDYýNkA ^ýÌc°v­Û½ÀÍ °À§ `£££à£2üô]Û͉·îv?üàj­Ò1rfÌ6o ASà°CŠî ÀÒvñ#¾Z¦š„JI#áR0'ÁÑ BI¯þWÒN˜VvY#¬&ùåLlÑ&#ë¯J’6?¸´mW‚i¿¦DI>“7K\˜¾òºiš3Çý˜¨ÿý;Ÿ£µ]Ã%k÷ÑfƒÛ°¿#Ì4üü¶7IÒ% Â>^sT©$æ°k®,£ßÄF¤-ùNùÝÎŽ”KÈ÷“5I6F‹tš¤ß=BLj0 À"8©ò/D;ñŒê­± ô>=XÎËŸ6SÅ­MÏß¿Zǯív¯¼g»ýÍKÀm BíÌŒI&2rf%‰ø}âT‡ÎHÿ3ÇX€>#ŒŒÀ!ðޝVü·¶»oxßfóÑCò^®~Ÿ<t*.âYû’NjŠÑñÐØöì·ßY»àm³£!ê¨ Ï}áž;’ЂPä6l$Š¡70” üôñ†kFÊ|ÜASäÏæó“LuÓºŽïTM*k/¾“_ ‚š×Ñ&Âg]>ÏÄQQ¬Öä±ù~ …ïEg²Â鮲@C´a¢L‰¿A#>fÃ’6ƒx Ù>ÓðÖ0ñLÏ€išMNû~ÐdpnX> ¼æá¦¯R•ß\¼ûx.°0 <'ظ½)ÎÈð3oÚlïøííö\­žYi)9¬¨žŽÖ‹ÕŠe;éžÿfõ)"¥m |u‚•NaLÊŽöåµ%óIDAT~É6Û:#âêñÐB°t©ŽwJmdµsÀž‚ׯøí–„ÒD„Túî¡^™™©€óÿó,gCVºó±ð1ó ‡jø ­$áÂuÖ¾gAëBªÍ„2“76›ðÂFnû:bc1fµcbjŒ‰©ÈK¤IŽª01X>Ró‘'šÍ`!vÓûaÊpÿ‡â৪ñ›[rm »{êɆúsM1@ðôj…ûÿòÁ}»ãim?¶°8ù-ð\aaxΠS ïTŸzX†ïþÍÝÁ‰·m·¿tazm¥d:”ÀÇTúŽM{'ÙaÊÕä IK1¦%î!yÁ`HrücÄqÉÚM]£Ð‰ÎÞœ®@ȤY–è„ÛãJ‡5Ͱª»ºÅªè4¹ ¯·EO‘„]‰uÌ73 L|™(_°C^ŠÞëOÂh¤‰Â=µûkÙÏú[Œ¿“Þäýê½´*Mç¶dää&¿7’öÝá‘M0èÄŸ«Jjœ#¥½·¤ÕAüƒå‘4&KÔ2f8ó ‚‡hö9yÏýÚ¾ìlÓ¿0ªûÊ¿ÀÕ…X઀"’5ȇ޿Þ|åë7Û¯ÿÀfóñ1Z`|ÊJøºÃ fÁ(½j‰ ÈÄ?¢6´•™4²Ý;¥j·—f5˜‰zL¼Lê ›¯9zϳA_œç!bÀžQŽœ¿ªD±ñ Apì}ZêR»o>4!gGwlsIØ Ö¿3ÑWŸ¯kÚ‰É *Y´}0‰x“v…<˜ Û»â çÓ×”J×#ØÌAmxåJåîZ^‰èŸ¾IëZÇfí´”•’ßóïKQ"p^†+÷©~÷£M_¡Š_[Ôý \mX€®*(Æ$B/Ò†‹ƒüì]»ƒ;ߺÝýȩծ¤;«hžý­æ\¿ÎYMUR³„SYQgƒµBª{ÉÏíEÆ´ª$Š3¡s †ÃÑôöx›þ5Mï‘K<†Þ´ÕÐ$V'¨ó…D$ú”X#¥g”}ü½;=˜çû† ”º_Ò'wŠZ«âx8!Ž6&sæLNuâæ˜ìx(y­%æ[Ϩ"´+\„÷Ú`VÇœ­x•÷ec³ýsS’ jSé¬x´†‘¢dƒ.É€‡ ÿöaÕ—>ÙÚ¬WD½Àg–sµÀgÀÀzáÔjøöw­7/÷fûïÏ Cª-’šzÙá°¯S?Šf ¢ ÿ§á1ÏvçFï%B`ýõïЈp‘tLö>‡à‘Ri)±Úcaû6IÕž">^‰Q±Ææ]ÈúX=J¢Óßñ¬†ÎB°Á:Ç.0-wÍF’b§ÁŠü©:Ìñø¹I&€€0[h §smK'˜¶ŠµOSó§ñ%ÍIU·+Ħ'O»+ñ~£‰C‘Ù9{X¯U(;`fcBö2àQÁ{N6ü©3MþÌ øÐzùø,ÂÂ,ðY…c6Á-Ú»>º^ÿé7l¾êÃÛí{žÆ˜Ñ̉8!Xsä3í€}n°ÜçA¸­(Ñã—Á0¨«v“ª¯ IôF,÷{7Œcc 3çTÆ$÷A-;Ø;Q€­Í>Œ˜‰È&qš%³){ŸÒ¼8^_ƒT‰dÂîÙðˆ†ý:Š67R0+Âv~ÐØÜáRê:MY ]"–4'ÿmÊ ¦Ö¬Of:gÄúÚ»b9´&{Í£dÿè¸ß™æª2˜P6a)ö ®]8+ÃÅ“ªóñ}{Ù!ô?,êþžX€ž0: ^ùÅ­7'Þ¾;øŽ×ëó°‚N${öÚWD¡ö`SB 9(¡å@„ bŒ…ÔŽÐL × W5ì°±æEem{o4¶ð$ly\Y»%Ò$ †?ÇŒŠ&³È8–•c&„%W'¼UJw7ü˜œNÆH²93!`0h-"È쬇L¸!òì‚®ŽGô¬y>~Í#6MB³¬?4þˆ,郖ˆ÷¡iaFÌØ¾Éš¨9ÂöÞ›`ÁSÀŸ?…ýËž„þƒ5¤-ûx¾`ax^a Å-­áôzýÃïØî^öîõæçÏÊ* ø…2îõø;/ –8+1ã6²„Ê@ti6qt-Ý(ÜZ–è9©Ä*礲¬~çÜöþ$¯¼D¹áÚ®kü™,¡¡µðoÔTÖ1_@ hÀcäEÜY0îÇR={„g|‰²¾M ñs)½é}pŒ~8á™×åèL¢äÖÐ59ý,YÃäãAN‚^øI•|Ɔ÷às¥àÂG6®ÊŒé}Ççm<6Èï}BÛ«Ï6|íZå£K2ŸžoX€^¸E[ÕŸ\­¾ö»ÝWh³ýÈeÀý8§’þ'Ä?<ês$AH”ŸMŽ…EJ5 ƒÁØoÄ~Gî|Cö:e8({›{î³¹ä1p•<÷IíäÜ}þ[ŠWŸfOt&†ÛÍA‘]=‰P oHµ.ônŒ¢:Ú锡$³FŒ3qLÞ:Kï*6>“±Éqâú’î„ÖÈÚP¢NƒÓ5mƒ (±VŠ™ŸÆýƒÎ‹Ÿ×`Þ¤W$<'Ãþ~àkûWT_»¨ûx¡`axA@Ñý ¸4à>´Þœ¸{·ýþ“ëõÓ˜$ è£Í¿I$ÊEƒ²³`µG7¸~¶×ì4焈l¾æ¨h5Z!† gð8Q”84ÞéQœ¿i½mÔE­ÁÅr"ÜÐ f24Ôò]rµ$7®5q¦Ä<Û‰±)>(WÃß’P¯ð~Œ„f&‡úÕ¢ QbS4'С…4î<ÖÂüKD%ÚSIΆÂÇyr^ž£Ž‰bøãùä6ñìûY¿,NÉðK÷ïÛOîõ»·‚K‹º`6 Ü¢í©Ó²úž»ŽxçÁîç΂AGtŸ²÷Á$±04¡îÎ(°Ä’5Ù¶%§ï5ªoÿãª}æ€ÎthËé…ƒ@„†¡Æãûß°Xr&d‰‰ˆ(…¤kR~‰õ' [ £f ©µÿîÑZ‰ùø€…Á…tÚPŸà± }ÌŒÀS‘™˜.•7$èÉΉÄÈøÂ©÷eçÁ4=æø0×/Tbï5Wþ‹œ áP™Ë"›vBÒú﵎wóJ:ƒ|ìªöœ¶¯Åûuÿ×, À× ¨b€~øõúëÞrpË—¾o³{ÇÓ¬{éÕ‰³^W·šD®=þž%EÖL’·¨`ÏÎ|0B^s!Ň:ØÓ÷þÍ.…Œ¦ÞñZUÉ’šôC=ÍŠeO|„\ ‘ Nÿ¹ûÚk”‚Æ÷ÆtÀ÷Î Ò8‰nšñÏ:bõ;/ë¸i:ñç÷½aóEðÑP>âx)¶Oý]#Òþ±NÚ7ÑÎÑ'로°3sÚÎð×$2PŽvÁÅaÀɦ?tªéË®(þÍ¢î_àZ‚…Xàš3 oЧ‡á×߻ټâmÛíwœÜlÎ FiŠ“™ÄµWB¾°¼l ùM²©€ŸËíˆpST€ýnYºXâÒ3š¿žÿä`ü"¿ÇÉn(„±Ml^sââIÖWÔ¿q¿D"œ Y‹™yVÆ^û£¡µËdxðéøX™y MËû ,Nö|³ÃC碮wÃ̈NÇËNƒµäu xMzÆ„:¡ €ËÀ‡D~ã$ô•çß¹.,êþ®5X€®9P[UoгÃðÃoÙœ¸g»ûW§WÖÚzHUqúSÅ¡†Êw/o €–~ýsÎã,MÃ&,¦ö/Ä?©ÍO!Ëy8e,«‹êÿQ 'Áiè©ÒY I¸ªßc-³“¡ {¶÷lƒbóMDz†è©o"ksDŸŸ™iܘ®E/e]ÝvÎkÛ÷š¿óðÅž‹ÀL âPKŽÈ9ýu²nöZøxÄx#Í0EA*&Î~Ò€6æîÿè'¾áñÖ¾dP½g‘ú¸Vaa¸¦a§ŠAqò¾aõçïÚî¾øw·oJ¤G è$@8ªò¦â ƒR&@ÍžüöŽB:ÓYú"vîD¸W"†F¸;!oÝÄÐMŽrJ$à öœˆHš‘2ß™!þÌ1-ˆmjl>P‰~Ö¼0³‘ w¼a&ñ±ëhæ°ªw9a!Ò¶†…É¢ñs7äð¾àµÜ÷ÆÚ™äª}k¨}ÍsB pÜl7;í»CäDpaÃû?øHÃK/«þÌ ‚]àÚ†å|.pÍà ÀmÚpy^÷;»íç½u»ù¶ûÖëÓP`Ð\hň»j¦×ôh ø¸ZØëÓ…@:9z™ ¢÷cŽv ¶ƒ"JyÏ}`´¸‰i)r‚Æc£ÚpÆ4W‹šV¤‘ÚÂ2³–y¬ºp†G#Üq\7-ó´µ5GKqÆ(V ÿ³e­Q©fAÚ+Z!$˜¡Ä„Ñ>šÃ ñwæMAJ£’Ĥt3?ž‘C^÷€¶W\Ðö]è¥%…ï×, À×(€*Ž©â ÈÞ½ÛÞq÷n÷g†U¯48Mã꿲‡øø+N{ÞdÂê>”ÐbÍÂç„rÔµOÊ×ztLº.I„ÔìùÔ—a‡?SŽY7&Çò„DOÙã!…Æ4u¦Ð¸–&—áéþ›×ö… }Ëf±ó/pÃÂ,pCÀN·¨>ôÐ0üå7o¶_ð¾íöMc´ÀøûÄÖ^jX˜PLóû[=•ìXhalVä…ÛÅo:52"%MG[¸0ápº6Ipñ#&¸ÙdÞ|>“D ØD|E’‰ŸŸ RŠ”ÈˆÜBÚ–é;@Ù‰ÆDÂO@S?âD7­©ZŸ‚ˆ© ÞT} >6ÒT4Z;f¼¤±Dr¤Q{Ówd<1 ¸_†ú€¶;/í÷?µ,ˆs–s¼À ‚Q°Þøñaýùw|óG7›ûU1´ìø7®QCpØ%V3¡90¿—ø%bÐ9ÉÇý{ä@±=±ŒºêêeûùöÇš¾j¯x˺›`›ÀŠêcÊðWÞ¶Û½êžíî×.bë¶5¿Ûá5þÞw5´… Ö¢Dœ/Þ´öôæÄ3¨pØøÅ‰[(ô“tOþFáØÓ¬Í„ÁZ6cØV8ˆyWNkƒÍš *Î#–o ëÃWQ‹ax>ÐØÝ!Òü1Üç¡0hÊa˜Q»!9mvSAëk9ò‚§dÀý*?ŸîO<ö#[@„¸ÀÍËy_à¦Á˜DèÃÝï[­¿ìMÛí×þÞfûÁ+èµÈQpOjÿÖóÝ[b!vÒ3'B#ZNì¥ÚÞÙÉ.¢r"¡\ÐÆ  Ïm_sÔ z ïYâ™ ;äÈI~ \n8lõ½ý ñ·q)QÐû lnhHŒKö±ˆZU«hX³4ªÝÐûܳ/…bàŠäž5ý²Ç›~íòÑ%™Ï7#, À7%(ÆÚÇUñ´àçß¾Ý~îÛvßûÐjs ]Jœ8ô)ä‘ Y´@cé•xs Pƒ7²'âWèÃÖœÈÖ>@DÛ™ ®]Ðÿ+SÇ=P›Bö•÷xyó–gãA˜Æ_ƒ uÌ@AùêãÁìZðƒ>$Ÿ Œ¤Ÿ÷H:÷aã0Nì´Èc÷õm¯ÜCm‹EÝ¿ÀÍ °ÀM[´í_¯¾ïžƒÝ+ÞqpðËç‡C 1ëªçDxûTÀF\=íä±;À¥ª{šÄlæùÇmk/0´ïzÆAø3ø`fRÇw¶ãÔ»ÿŸ%’y›2j”øŠ¢K½+‰q/ýø®øô5ÌÕ hÞ ¾iU-2cà’î~úÖN<¥úO¶ÓI/°ÀÍ °Àèf¦Åû?¸Ù~Å›6Û?÷áõúä!FB³WÅ °KÙ–ZØ%‡?°¹šo€×fà ÉÓÍCÖØOŸ<ùF,¾ÅÚGø‚°{?aCõ;•êÙ™°·NŽ…–gŸ™¹hé;6…hùÄÜý'H_aÅ"ìÏL ÁØþûxDäCkø“çT¿q-8µ~¡Û \#°0 ,ÐA1J…Ç´á²È¿~×vû¹o<8ø{÷¯VW`ÐL =©—ЙC"\æ°—¼òIÍ¿w7™ÈßX÷±ª'°a :Ê ï;Q±°ºFÑ 3ïí2SBžÿì/Ä_°+1rö“9@‹šŸªëä# jÊü΀sc„>˜"ößÙ›‚Aœyæ¤ê÷=¢zç¡â?.É|X ÃÂ,°À ì Ø’Õß¾k»»ó]Ûík/ö$B(ÄÌ]B‡ÛžðZÞ oxPÖ¼©l?[ ¨åöóˆ²O@ªV8ñ;ÐÔ«;æ‘äßÒ3á–Çf¯zˆ›~MœPú#CBÄì÷—Ù¤a€ÆX…×%R`Á¥aÀª?²íO<ÑÚ÷n!O/êþ˜ÂÂ,°À (ÆËq‹*Vªï?5 ¯~ëÁ±/ÿv÷ÞgD°ÑÈfgR´§–̰}¿‚ÿ-Ø‹ºê;Wù îïX1!¨¨')âxyP?žcAtÙ'Á¾'“>ñ"=“‚Á›õæ ƒŒÓ ;}µù›/ ¥;Ò =?ÄÈlœÒÖÜaÔ *8\ xXä½oú'ÎiûZ~hÉÝ¿ÀGÃÂ,°À³€1ÇUqi~åw7›—ß½Ù~×ÉÕæ)óê7oϳT¿çøÍ½}oÄ. ʼn63 \®Ö¥~O¡}5a’¦U½ßçáÍ2©Žöí 2êÁÛR'þœ¹Ðò'ƒ3nðv„ß.|#¤(dœyú>Å÷<ŒöòCÕ_]Ôý ,ðÉaaXàS°ÃϬ†|Ëv{ç;·»Ÿ?3 XiÃ^›;BÉ,"d 5°¢A‘S€“YNþT¹O™h“½½ç'°¤Eé9ËO©x-2Ÿ‰:ç"mì^&‡|"«¿ASÒ@XF?ÊP¦ƒ  ÷gã°rËÄü4õœ "À%ùW}ù“ªß¿uÿ |j°0 ,ðiÂVý½WÃ×Þ½;øò÷mwïzF¬Ú(á"KØûþÝ^"yÐ(ÉSõ<-’¹SK¦Cvx#æ)GÀ„ðemØ¡¬|IýÞÿ¾ BDh‡¾¨N˜«òÙØ³³Þ\zYûd¼ 1%ªÝ±;¢çÙ ð°â÷ªþ™3­ý)(>°x÷/°À§ °ÀŸ¬Üª Ï ò+ïÞl_~×v÷7î_¯ÎÀJ[ dµ»©øGÛ}Øû³j^\ª½ú €$úˆp;»„Ýœ¿·wÃò¨dµ"?Þ?ƒå1gDjÉ^öàFb쪽O™0a÷çüã¿A". réÈw?ØÚ‰C´»…,ˆl>XîÍ |† vª8hŠ‹À?|ûöàÄ=»ƒŸ:3¬±V…hKþfØ‹¥´µÐ¿ î–Pwo)Õœ ¥3ac¯žôBØ(4ÐcãIE¿‡ÆÉ%ŒÝóÞjtbýˆÇ÷EÄCNÎ…Õ¿@]­/žÛŸ‹ÿµÑ¿éÔ5Ï ‚¿x_Ó;žQýàÊj±ô/°Àg °ÀÏ̉ïpÿ½Ãú›îÚn¿äý›í=—0`ÝFB—¢4¼ö›»ÀS‚ ôÄAJæW¥çBC®Þ—6È„tòŒ’É âíÂK?"Æñ6g¬Wõ‹%9²ýè±&²ù}—™1+ ùK¨L’ANÞ§ú g´}YÔý ,ðÜaaXà*€b4 WÅeà7Þ³;xåÛv»o;¹^nªZ G@dÓÀ^‚8B’éÀ4{(•(foME|<\°WÁk4ðFw=ô‰Ð³~’Ú‰°{›>q“âÅ‚èdl{D²$ûG~ #óÓúw£ùdŒ(œ'EôTkw*~fƒi-°ÀÕ‚å.-°ÀU°p Š‹ƒüè;6»wíŽýÄc«Öý<Ü!ᛃ á==c„?;ós`Þù9ìÏíê"Î 1>ɇ Ž †tÿø]èwžo¤áõï”stÿ é÷Tž˜¢‚A€§EðÀ ¿ò€êË/©~Û 8» «¸º°Ü©ø,Á1U ÀŸXo¾åîÍî½w³yÓE°Ò²k’ Ž‹/ùòœŽ„#ô'mpl~е§wÜ· lð"l»Ï€M1b ‰6jEÃ0OHK gA€c(,ÎÀ¼ûcøÐýŠWŸní˼kûBoä Ü °0 ,ðY‚Ñ, ¸e$ø¿ý»ëõç¿awðÍY­ï?D0Éœlä&!7sÓÌ$¸'=dT­sÜ>ù¸^3“àNwþ½Rr¡Çãy´^Z7|r^~ 1D·ók´å& òMÚ.rå~•|HñÒ}í¦‡ü)X`Ï, À <°â˜*ÎÃO¾k·ýÜ»·Û~xX·¢ŠC(©üÃÃÞ¢Ø'àão‡îS`A}AlrôD< Õi¦@UÒ%̵Һ¤ÖGäPÕ‘Aðv5}It§¾>Ò1R1¸<N)~ýÞ¦¯|ú]àÊ’Ìg>û°0 ,ð<€G ¨â@õüã2|ÇÞn_ñŽÍî7.‚M)2”lÿ½ á^Ù)ótæ¡»ñO’ôôç¼^€;þ‘N±øô·e7”Òü;ñ¢<£„5ixnMVÝ×à1Áƒ'›~Óé¦_ªÀï,)|Xàùƒ…X`ç˜hÀ»>²ZÉ[·»¿ð¡ÍöÔ^Â,P“)º3æYÙ_!¦!Âú<œ°'ùQ)€þœ-;ò÷"<Iýìàg¾^è~œÄ'~Uˆ ¸8Ðá=¨ú¹—›þÔ 2Z`ç–;·À/X´ÀmÚð„¬þå]»Ý‰»¶ÛòÈ°Â Š¡ûXZaS¡³ƒß\H¡%è±üûþ,… Z‚þxö™vM„ß+<Ðû¨Üp µ?…2Ã2@qYœ~í¤ê+žPýëk•³«Eä_``^@P[(6ÐÇ‘Õ_}óvûÊ{v»ÿt~0´=´5wž ¬åü3 (r¨]ÎÆW »‰Á+ðad„í÷.óß’¹ƒ¡rE?61þÁcî;Ùô{´é—©ê;6²¨ûXà…„…X`kc¡+"÷¼»ýŸßº;ø3Zoßw8 (ZÀ«RÔÀì?*öãe…uj:H%x)tÐ2 ©Kþpâo¾Ð“„#b¶…‹Üüèª'.+þßEÝ¿À×,÷p®P›±ä0žüÛ{îxÓÁîo?°Z?‰-“Éø¾ç¶X åouíÁà‰ØÑÏ*ðíǯ!0F°O€‡õQ¸âÁ3ƒàô7îƒ~ÞEmß6gïþ¸v`aXà„í-Еáï½m»{Ù]»cÿ漌Ú%üÞBÿ8l°ÿ³Š}MG'A€ý €(=4F$sö<ÿnçD 4 æ=hÌ0&):-¸÷>mßø¸ê—@ñöÅ»®=X€¸FAÜ:ÆÊÿÞ7Û?û†Ýö«?°Þ~øÖV@¨K釈JlÛW-i…ÍPÈ4ÐÚ˜ÈàSÜÁOÜ›¿¹3"ytãâœlúC¶vÇ¡êOo–R½ ,pÍÂr7Xà†1› p‹*žÄð X¯OܽÛ}ïÇ×ë§ö ¬Ø9P³$oDßí÷Ì °# „lÞ¼r%R/-ìLE™}†*žÁÃßz°éç]lúkàâJ™®eX€¸N` Å­Úž~lµú¾7owwܽÙý«Ó2`«£ÀHì¥' ÒTDÈ yv>r"´ØýHÔóô ¥êuC@pÅ^œ–áÔ}ªßò¸êAñöÅ»®X€¸Îà˜*Öª=µþü>Ø}á;7Û·> ÁºgáÛ«9N½þ{öbÚõÔ½£Z?Âù"ohšŽÙùe.È€{}HÛW?±ÆBøXàz‚…X`ë ¬(ß­ª¸$Ãëß½^ÿá·ìv¯ùèzýð^-Z@Ý1o¯5O?°oâ5Z÷ìç@OírÄô_Áƒ ¿ñ€ê«.hû¶ðøz!ý ,pÝÁÂ,°Àu Š1ZàVUœ]ɽqwpâ-»ÝZ­ ªÖ’O€å0×=cL[`Oz®äÊWxLðÑ{÷íëkøî^¼ûXàú……X`vªXCypµ~Í=›ƒW¾g³ýÕÓƒE ôx~äÄ@ŠHª~ö èÆœyêÕ¿ûPk/½¬ú³Vªw¸~a¹Ã ,pƒÀ€Ñ?`£zÏG7Û?ñÛ·|Çכ=`hT¥9@„ Âé¾èè ø$€€wŸâå—Tÿθ´^Dþ¸!`aXàƒÇ´á©A~æ½ÛÍwívßßz}©©bháøwcþsøÛ ÜÎÀÃß¿ÇלÕý× Ð­_è‰-°ÀW`nPتâxkO>²^Ï[ÝrÇÝÛƒÿïáÕ€Öh­çõ7?1pଠOݧúwÜë‡À¿Ûa±ó/°À °À78#>ò‰õú½kwðïÙí~åÑa…KmË*xÀ%<1 ûGeýãC_ú¤êßY—±À7.,Z½¸ÁÁ² nU¡7>°Ý¾ñôv÷ùrxåOî÷ÿÅ!äð‰Öî=‡öËO7|p€b…\\h¸ñ@”R.°À ,°À7üÿ]Ó ¸•7õD%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/tools/icon/512x512/mimetypes/000077500000000000000000000000001440571307300200075ustar00rootroot00000000000000leocad-23.03/tools/icon/512x512/mimetypes/application-vnd.leocad.png000066400000000000000000002250651440571307300250450ustar00rootroot00000000000000‰PNG  IHDRôxÔúÉiCCPicc8”ÏKaÇ¿³(A`f{ˆ¡CH¨LeD宿شmY”Äìì»»“³³ÓÌìš"^:fÑ=*úé*˜“––Í9R»,Ÿ•"t%1)f¨m-’¢ë’ë²%‹ÙÌ*±tìÌ©vO¥žv¥æS¹¼Aç¯ö°õ°\þù¬\ÞzN=¬/õßÀ¼ýE¯Œ°p cHRMm˜sŽò{„Ún”å3'™IbKGDÿÿÿ ½§“ pHYs  šœ€IDATxÚìýi°lÙuˆ}kïs2óŽoª@¡ !‚˜HÅA5„ºC2Ű;l³eE8,Y‰hK 9¬0-ýèè&E0 ‡­Á²%…(†-vS­¦h‰¤8@ÄL€ˆÂPUoçì½üc¯µ÷>çÌ›÷Ý{ß«ª·?àÕÍ›yæ<÷¬é[ß"fÆã ":÷]<ês,(xx|*óó»àô¨õ¼F@øYAÁ㈓þMgÅŠ•+(8`1hÉït̲«ƒyVX¦  à„(Àý2ô‹~bÅß øïsö“ŽYÿ¸Ï z(@Ë þq¯ûÛ(((Æ*N¯ð“VÜVAAÁаÈèëŸú{™bü V£k¤}ï}î-³ì5P2'Fqº2þ„`ì+#ùW#8Ë€â t1d´Áø3'¯ó.ûœ{¯ó„ag`ÕòAAÁc‡âô wßø[c[¶L®Ý²Ò@AAÁ0úÆ[}›ýlä§ë½Ö¹“tZòZ÷_PðØ£8 „aã¯ÑÿÀ…W^yåÓú@ ˜yå^óU—óÞ;ïýÜ{?›Ïç‡óù|o6›íÜÝÙÙ¹uçÎk/¿üò+_üâ¯þ³öϾ `ŽàLå§þž;ê ,*!Üçð« ‰þêÕ«ú cЫàoàÑ|êýÜø„”ÿEϾòÊ+¿ú¨» àaÁ{¿Òr'q†–ÍßןÞûÙÁÁÁ×ïÞ½ûÕ[·n}ùÚµk/ýóþÏ?ñ«¿ú«7œYö¯A×XT.@ïõ#uNë<ûì³êÐ ^(@—ä×ü•ô7p À³/¿üòÿïQwAÁÃÀyDÿ}#ßßOÿ}…÷Æìïï¿´³³óûûûû_ÿßø_ÿÑýÑßpàÁ)˜#d4;°Œ7ýù¨œ€W^yåTë¿á ox‡]ð:Aq†£5ü©þ¯À/>êã.(xXÕx'!7ø‹Œ~ß)Ðe‰D„Ùlvw>ŸùÞ½{/þ£ôþå?ý§ÿô÷‘œÍ ¼ªâúÛZPè|n­…1mÛ^Ïç/ÿò/ÿò¿þËù/ÿûÎÀªåà8Å(x”0§ßÄë CÀÜ(¤É‚Ççe‹ö‡–*(Ú¶Å|>€g×ÖÖ¾õÏþÙ?û7¾øÅ/þ?ÿÁ?øÿ+O"pwÖÚw+tüœç»xè!L +(x5 8C¢?CN€}ÔZPð0p©ÿ!ƒOD+GþC¼ý×4 ŽŽŽ°¿¿¿>™L¾ùÏý¹?÷×>÷¹Ïý“¿ñ7þÆw¸‚ÐÂ;AÒð2þÅ (x¬P€û±ˆX€‚Çgý·­EŸçNÀq¥ˆ|MÓ`wwwïÞ?ýôÓïþáþáŸøwÿîßým'`ÀB6@ÿž9Tœ€‚×;ŠÐÅ@_   à„X…Øÿ¬¿^¾ÌqÛ8<<Ä7Ð4Íú·}Û·ýŸùÌgþ_ï{ßûÞ‚ÅN@ßÄ (Ž@ÁëÅ -Wìgʳ àuœe¿,z×åŽÛ–B—Í×ëoCgfc:¬ÿþökþ³iܾ}Î9¼õ­oý¦Ÿù™Ÿù™~ô£ÿõÏþìÏ~áoZÛ®¢ A" &":r`yž_¶¾rs¸}û6nܸK—.UûoÿíÿáG~äGþ(€Ë6°Ø Èÿæ‹PðºC1h÷ƒ°¸Pþø ;œ…Í[Öò·ì÷~Tß½ÈøçŸë:·o߯իWqñâEúèG?úñ¿ówþΟEhT' FròiŸÅ (x]¢pº ïõ¯;,KÙký´íJúëËPÊ?çxï£s ËxïqëÖ-XkñÔSOÑüÀü_'“ÉècûØÏȦÙÉOåœ+'  àa¢8 4ðûп‚‚ÇÇWÁIRû‹~ú—o§oüsgÁ{k×®a<ã©§ž¢?ógþÌ߬ªªú¡ú¡ŸFøû.N@ÁcƒÑc‘3PPP°ÇøÍžeò×CäÁENBÓ4xùå—Ѷ-žzê)úžïùž¿ö“?ù“ß媥PðºÃãî÷ÇK'\¾ àu‹“»Ç•†–9N8ÿl(òïÿeëâÅ_Œ™€ïüÎïü?ýäOþä_@è(N@ÁcÇÝ(((8GWÓ_Vû_´ü2.¢ȿ¿ï=îÝ»‡¯|å+ØÞÞÆ¥K—è#ùÈ#™€â<(@AAÁ¹ ÿYe}Á ¼÷_ß[tŒÇê Èÿ]¿~7nÜÀ•+W0Ô ø' à1@q VÂY8 9c_ÑúYµÛ ¯"¸ ýŽ€|ˆÐK/½ï=žxâ 03}ä#ùXq    àL°J+ßP4¿ÊÀ ãăò÷ú-‚‹ºtùÝÝ]¼ôÒKØÞÞÆÖÖ˜™>üáìãÿxq ^×(@AAÁCñ?NrxÕHÿ8yá¡×ʸzõ*ðÄOè{Å (xÝ£8 yYm•í¬B ÂÐòGGGxñÅ1™LpåÊ=¶â¼®Q€‚‚‚G‚þ°Ÿüý>†léÐ{«H/ê¸uënÞ¼‰K—.¡ª*]‡¾ã;¾ãc?ñ?Qœ€‚׊PPP°’@ÏqË7µï4X&¼(“°èxu 4Mƒ¯~õ«0Æàòå˹sBþð‡‹PðºCq ^õX5Ú?‰žÀÐòwïÞÅ­[·páÂXk;N@ɼÞPfœå︠`u,›°è3cÌÂ2@þ÷§ËåÃùºùöóu‡^ërÎ9|ík_ÓO>‰Ë—/ãÖ­[¢£@ßþíßþ±Ÿø‰ŸÀG?úѱä´WžPž'%PPPpîèº1|}ýh{«Š-Â;wpçÎlooíO€’ (xÍ£8+á¼l×ð‰C­„‹&6Mƒ¯}íkFØÚÚ‚1D }èCÅ (xÍ£8«²üEúúû2"â*¤@ÅíÛ·qpp€‹/.Z—>ô¡}ìïþÝ¿[œ€‚×,ŠPPPpf2²'µuC­‹Œû²m¯Ú•0ôùÁÁ^zé%¬­­a<Ç €þË3Å (x­¢8Φð$뱯ºÿ!q¡“îghÑÍ›7ᜋ\€>qð,œ€gŸ}¶8 Å(((Xçé$Gbñ/ÛÖqËe‘üà~vvv°³³yù:ùO' à5Šâœ­?H`h½þ6—Dæ 3«v4Mƒ—_~u]cmm-: öSœ€‚׊PPPñ°Ëù{'u,–¥ü—-»ÌiÈ×#"ܹs³Ù ›››÷qú¿3sq ^S(@AAÁ‰ñ ĺeËÖ Ê ½^öùÐöööö°»»‹…ŽCþ¯8¯%   àܰ(_uùeÆ}è½e†}hß¹‚àÚ¶ÅÕ«WQ×5&“I'âïÿÓ÷½÷ôÁ~ðc?þã?^œ€‚W5ŠPPPÐÁY•NÚ†w’,ÀI2Çñ†>Ë?¿wïæóy,ôI€CeÍ' àÕŒâ<TÎwhÝãÚó–Eó=•¾Îzým—úÂîî.0™L`­C‚ò}æë眀’ (x5£8÷á<³«¶ð-Ûß"'`Ùv´[`6›áæÍ›Ç1ÂÏ€~ô' àµâ<0Nã(œDíoÙ²ËÞ?.òÏ÷µ,+qëÖ-8ç°¾¾"‚µö>ÿèuq ^­(@AAÁ κ%𤺫×Þ·hù<…¿ÌiÐå0›Í0Q×5ˆUUÁZ{ßþúÛU'àø@q ^U(@AAÁB¬b¨1èWÙöI²‹Þë¯Û_fHñï8Ž@8::Âx<€X°Ö¢ªªP¯ÉP‹à>ðýØýXq ^(@AAÁ©qR¦ÿqëÇÒWä†vÑòýu—µ .S¼sçNŒúÕøˆÄÀECå€â¼P€‚‚‚¥xØ„Àã”þŽÛ÷ª¥‚“–îܹï=Æãqtªª€Žñ/N@ÁkÅ(((8gÍè¯w–â@ýŽ€E)þEj~‹Ö9<äô;úÛ*N@Á«Å(((X «fNã,ú½ÿš™—î÷¸€ãxCïÍf3uHÇ9‹túÝêPÊ¿ÿ÷8£8+ã¬ù'yYÚ_ßëìzÿ쓇ÔýôwfÆÝ»wï«õëzƘ蜔x' ûYPp"   àDXÅÀ¯Ú¸J)`Õ¨¿ÿù²ÁÐçù¿½½=xï1UsÃ~œÿ+N@Á£@q Ϋ–Ž{‘0´ÞIÒº«òò厎Ð4Mlì;ù{jì9}g 8Å(((81Ί°h[‹Þ;I`Ùþó÷ûiÿeŸa6› üœÐ7üyg@_,(_†™éÛ¾íÛŠPðPP=êx­áq'(†Èxºþ¶ôw}/ÿ\¢åû¶¥ÛÑÏ™9[f†÷>þ®¯u}휃1¦ó¹n—ˆ0ŸÏÑ4M\Ç{ô8s÷ ª*´m;¸]]O·§NÀÿøãG~äGþÅ’Ëçä§àŒ?g? –¢d Î gÙ0´½U¸«ì{Ñöú¿7Mƒù|~_䟷þõ³úS ‚ù2CÙÙ½ÿýï/™€‚sEq gݸìýãŒüquüeí_Ç• ô3ãàà c´ûµþq†Ê4Pœ€‚sAq N…³j Zî$Y€Eë¤c`ÂáÞÞ^,ô×[F |P'àýïq ÎÅ(((85Π8m`Q¿ÌYXuŸùzÓé4rúiü¾Q/N@Á«Å(((8<¨?ív‡–9©F@™eóù<ý†ê÷C¥Ó:DTœ€‚3Gq VqVâ+Wÿ_E)pÈ ˜Ïç˜ÍfKI|ýv¿Ó:zÅ (8K   àÌð þ¤Û9íº«9 óùmÛÞíom< b ü^ˆg†âœ)ÎÊ XeU”ûË.#Ç7 "4Mƒ¦i:ëçäü¢àªN@v|ô­ßú­Å (85ŠPAAÁ™ã4"A‹ÄúËè,wÜò}¡¡eNÅ2Î@Ó4pÎÝ·œ ùäïåâCÎÝkm$æÈÅ‚úËèv¼÷º/-<°XÐÏÿüϳªå×tè:}Þq¨ ³z9fè½e%›Eï¿÷½ï]í¦*DÉï !»|ùU¦". ?.$Zž¦LTP€‚‚‚sÁYtœ–4xR>ÀªëÞ·ü²A?Ëœ€e†ÞZ fî”òãÍdƒÈ ø¾ïû¾²¢‹¤˜OºÎqß˲ï«àô(%€¢Üxg‡EºþÀpAß뿯Û!¢˜&{ô½e)f5ÌšÆ×ßûó´p¨üïKKÑ/ä¯û³òuªªêÌ(°ÖÂ{Ÿ—N5;àû¾ïûè~áNdOÊÇXe;ùl„‚‡ƒ’(((87œ!ð¸m¯ÒÏŸ¿^Eèó¶mïãô3ýÔõ*™€< ïèt ¥ÐÏ"°ì,»ÞêŒáeXN3Lª8 §Gq ΧMõŸ”œ6ôÞ²Ž€|âàqÄ5EÓ4LÁy9Úà>Þ@¿¶~Z'àOü‰?±ô‹:ŽyÚ ÀI×?í$Ê‚â¼J°jZù$­}«îw‘±_ä8ç"«ÿa8ý¬À"¾ÁY:Ë ìYß¡Ϫ(€Ó£8§‰‡¶sm€UŽeÈØ9ç:-‹ÚÖNêää¿¡rÀÃtV½N%ÿÚEq ÎçÙ´lð Ë vå -×}'`Yà"± órV5ì§1âý}”´þÃEq  Nb°W% ÷y^ßï/ßÏ·ÞûÁmŸµPUÕÒÁ‡U8éõY§É$gáô(@AAÁ««ÿÓDý'ÕÈ9ýåÏ¢ðjqþøÿモ¯ª¸ ŽÓ8)£”Nâ¼æ0Äâ_¶œ¾~Ž„ãH€‹–Ë—”NúÀ>pj'଄~ý*8ŠPPPðÐpšˆnÑç}MýãÖ=iyaÞû¨pÜ~^ N3Ÿ‰0„Ee–U¾¿ÓøâœÅ(((xUâ¼ûÊñ¥ðóõ–¥®'àA:7Ϋu°àÁQ€‚‚‚W=Nê +'à$:çá,ûN£ð·ê6 Nâ¼®qGaYïû0´ÎÃÊ+J€g‡â¼.±*û_®2ÕnÂàƒÛ*N@þûiÝfN rN› ø®ïú®SyLÅП/ŠPPPðºÂ2㺬,°¨Î?ôÞYD¡'uý;m& _nY‹àOüÄOœÚ 8ŽÕ¿,+P"ÿ³Gq  ¡¶¿Ïãý9‰Ÿ…1:­°(z?©XÐ2' — ~P'àþÑ?zì—}œñïÿ^œÓ£8¯œù.‘Ð7ôC5ùó8§³tôX9ÖÚÁŒÁ¢Á³rNB \•+Ppr   à5ƒ!ô=áü½ª:».êóp†„†œ€Eeƒ!‡àadr! óEq k, ZÆ 8òÅY;‹ÔO’ È·Õ'>¨ðßù÷]¼<#°¨Kา@ÁÉQ€‚‚‚× N«Àwšý> ÎÂy9CQ}îèÏ¡Âý×gíœÔ—úÿÙ¡8¯)¬jˆW1¦Àýh™±?«6ÀÓ÷ƒ:ý÷Ô 8‹î€|ä#]µ àìP¤€OˆGÁ\.((8JØëOé[døû}CªŸ©0€<>WÃÔ''öɈÇiä2¿Šþïú^.¬’ÂÀýòÂzÞ¹|pæà£ýè‰eƒ?ò‘Ð/ÿò/w.ä2yà¡kSðà(€‚‚‚׆Œò*¢>ù롟}>À«¥°ªVÀ'`Y& ç$öËúЇN• 8Π—ŒÀù 8X<*¸5É(>Šcê_ÿ÷eµ{=æ“8«´zïOíÇ“sGàô(@AAÁc~º}CQõÃÀ*NÀ¢lÀªN€.£­¹pœXPÞ"x'àÃþð‰Ä‚ N⼦p’ü¢¨þ$Ûúœ™1ê9/úýA€~´¯ë9ýõ‡^+1ðCúÐÇ>þñŸ‰°(#P³A!¼f°ˆ ·*Nc8úê€{{{xê©§깯r-Ô@꿜´ fôw­õ+¼÷÷•(˜¯ÏÌ÷½–ýÑ?øÁ}üãÇýИøßñÄÅÂ?” @AAÁëǵî­úY?š‚÷7nÜx$ç™GÀC™€\ÝÏZ‹º®Q×5F£F£Qü½ªªûD‚ò”¿ÿ!!¡þxâ~ÆA»4@¥Ýê¡àXöåër“éÍgå_ –c„›vÀÞxóæÍü¨» àõ‚!xõ#ÜþgÒžÖù]ßÓ¨—™áœ‹ï;ç:³s.~Þí½GÛ¶pΡmÛ¸ý¦iâ²mÛÆeúËé¿|ŸUUá‰'ž<ÿgŸ}6¦å‰O?ý4ªªÂÚÚ.^¼"Â¥K—P×õJ×@<ïüœõ˜Û¶EÓ4÷]=÷þõÌdø×~í×~L2w˜h2^~²üÓN–óXz"gá'<Î6°” ^3XÔVÛ\„! à~I`Ñö¥æsC9ŸÏñòË/Ö¹¿þõ¯/¬÷___Ç¥K—pùòelmmá oxÆã1ž|òIlll`ssó¾ãÓÈ¿ªªŽoš&:óùü¾k’—òC¾]íxÐr•rÀ9¢8¯Y¬âäFzH`gȈ¯²ßþÏEs–Íú™¯sœ®A½ÃÃC⥗^\¿®k<õÔSxÓ›Þ„'žxW®\ÁåË—qåʕιäfæó9š¦Át:EÓ4‚ ëåIùûÅ xõ¢”J   à‘á´%€þ²¹Òßóôt^ÈSÚyª»ŸöÏ ¦óó’@^ÐTžNÏKCéÿü˜ÜIç¿e–MÌ[T*Zö™gžÁ /¼€çž{Ï>ûl,/h]_‰}g`:v®cÿ;È”ù×ý×ì¯þÕ¿zfå€R8ŠP€‚‚G†W‹Яe÷ vÛ¶Zyî$ô€üuþ{ý}öÏa蜇Î÷¸ë–_‹“\ßñxŒçž{o|ãñÆ7¾Ï=÷꺎΀n»m[L§SÌf3Ýçä¿ÿÚ¯ýÚ÷C?ôCÿgààt(@q V‰L‡Þ_¦×w–‘Õòh¼oœsÒ_?zï“ûFÈXæpWÛï_“8‹¶»¬rh]k-^xá¼ð øÆoüF\¸pÆTU9MÓàèèGGGÑiêŸ'ñ¯üʯü·?ò#?òÓîáN@qÎÅ(@AÁ#Ãi€!Ã?ôÙP::Ý7ÈC†~è½ã2Ú0Ô1Ðßߢsr †H‡«¬·lùã®wÝÿöö6¾ñ¿Ï?ÿ<Þüæ7ÇÖBc œs˜Íf˜N§8<<Œ×[÷mŒá_üÅ_ü¿ýõ¿þ×ÿ5B&àÀ Áð¯ìàt(@q ÎÚПC`Øè×ÿ‡ ~Þ·(àœëýüužÈË ‹¢ÿEç¼ìú ùUÒþ«.· ãñoûÛñMßôMxúé§c©€ˆ0ŸÏcV ¿öÆþ7ÿæßü_þÖßú[?‡ Xæxù)‡²8§Cé(((xMbÙÈÜeë ½î/34ùoÙÄ=ý\£ßeÓ±þ—¥äóN…~§Ð›»ìåëeÑø‰yý}Ïçs|ö³ŸÅg?ûY\¾|oûÛñ¶·½ ›››FØÚÚÂx<ŽmüÓúOÿèÞÞÞÑÿßÿ÷ÿ)ÚÏ{Õøkg€þÒp(€’((xd8K@þûP¯½~Þ'.Ë ÷4šgæûH~}@¿ ÐßæP6£o\W¹Ë®ÅI®y¾ÌP©aQKã¢}¾å-oÁ{Þó¼á o@]× ¢ûºŒ1ü÷þÞßûßÿ“òO~)0Gˆþ[ïÆ_ÆlÀƒß}«_×+J   à‘á¬Ä|Îb{Dû×—e úºù{Ë𨒯3dTóýWÛÚÎ2‚d¾ÿþñí¯eÛ’.€~þ•¯|/¾ø"ÞøÆ7âü‘?‚gžyu]c}}u]ãððmÛÒ_ù+åÿþâ‹/þÀüÿñw°ØÀç™ýŒpNÀ㊒8aàÖ­[ÿøQwÁãø€öžX0›~Dß¶ ×óÞ9°!°÷ðM 0À¬ÉPUÅ×–Ô#yÀ½1‹à½˜aˆÂÓš8¦N{ÒVÀe=†üý!æÿPwÀAo‘À¢C‘_ ßfÿ–EØË¢ùEËÖÍï•EÛ:îõ²ïéÙgŸŽ€Êk !ùøø/¾ô¥/} !0CÊ(' ÏœI&à±¶õÉ àÕf€ùXcOÌpÓ)ülŠé­[˜íÜÃìî.šÙî`Ó;w1=8„ßÛ‡o´mj\—H¦­Èîô/ÀË£ÔSø€+‹ºÁÔ#Œ6×Pol`´}õ…-Œê1F—/`|á&W.î¯ÃN&àÇk³æ§}: ¿l¿·~ wr‘žU€!ñ5öùŒ€¡Î‚¿]øØk±ì:·]`qF¥?}°ÿsQæ"wÞÿþ÷ãÉ'ŸŒ“g³˜yþ½ßû½úÞ½{×ì˜h°¸;àÔNÀcmë“/@Á«ᛡ(»i0ßÙÁáËW1½}‡×¯c÷¥W0½sí|Žò-\ãÑÌçpރɄŸÐ§#ƒ`/]n,‰A¬ &àáAÌ 2჆5u]ÁTlk4Ìh­ÅæW°õÆ7`ýɧ±þäØ|îM_ºdjÎ9X" %;„³r†÷«dôX‡ø‹Úqú‘>ˆhQ­~ˆä8t®Ë®Ëq×R?[µtr§ >}§ï|Ó7}¾õ[¿kkk "Ìf34M³ûáø¿œÍf×ì#pZtuúY€Ü8køXŸ|q :Qq>:ÂÑ+W±ó•¯àð•Wpû^î£n[¸ÙS×¢™;4à`²‘(ž’œ=òé™ÈIZ¢|h ˜äs€˜Àâ#„Í<0iû¤­\ Àµ,µ5aÔìh®*ÐxŒíçŸÇ…çߌížÇæsÏ66:\ìÁƒ:ºÝ!â_þÙ"g@³.», ÐWÌÛu˜Nÿý¡râóTôç÷S_­³h?«ò†¶/‹¾ŸE$ÅñxŒ|àxË[Þc Ú¶ÅÑÑÑËüàÿ€ÛöÊýL@N Ð x¬màc}òÅ(xØð¾cìˆó›·°ó;¿ƒ{¿÷{¸ó_FÕ4ðó¦h=Ã1ƒ*žnÎÉ£ŽÁJÀB‡â<ÍN fÀ ru4 eðΓŸ±«âZñ¸š9ð0dØ„L¼‡wD#"¬Ç°ã l¿ípåm—Þñ͘<ûl<~ðÎu¢ÓdÂ¥–îGÞ9û¿ßwôUûQý±ïA|\`QWÀÐùö¯Ï²ë¸*–µ-·¨㸒Š/¼€~ðƒÇpÎáîÝ»ÿù»¾ë»þî d¦HÀ"NpB'à±¶õÉ à!¡oÜÚ»wp糟ÃÍO}G/_…ϰ4Cã<œ•~rfÀ{Kˆ“dPRd.f9÷Ο³tbİÞÈû,¡°1à²öL ØI´‡î¶€ŒzBpl˜h†ÂìF`l¬­ƒ&#˜ËOâ©?ò^<ýÞoÁè™gÓƒØ9ÀÚcÓÖÇ¥¼ §9®çemý2À0PŸØOÿ÷ ‹Cbí¯’ú_V^XtM½¿,;pp™óÕ?î |çw~'®\¹fÆïÿþïÿôŸÿóþ¿Cp°X2ø€ÇÚ>Ö'_€‚óFñÿàK¸ú+ÿ w~û·a±7¢ñ [WðÌð­GÈÐKÔÿ<•ØyK¢w¾Ÿ[ÇÛPì•"I÷ƒS3i-ÍVH;q²ô´±`Ÿ§«MÜÅMS8>ka˜áÙ£fÆÆdZÛÀÖ7¾Ï|ø;pé›ß/×Ë;Z@,<®`Q½U"`ŸÐ/ôÉ€¹SÐwú2À¹ºàРý½ot‡2Ç9‹ŒóI ú¢ÏíÑg‹¾|™ªªðÁ~o~ó›ADøWÿê_ýŸôGôß IiÖ6ð±>ùâœ3šÛ·ðåý³Øûüç±wwskƒ1sòÌ#qHm=]ýÛ¨sªËs¶¬fûsx ‡mZt;ñÚ `|øsð1]ÀÁ1aÄ’@XQŽK8á65"wâ1e™м Ë v-.no£~î9¼íû¿ëϽ)œCPŒK§@×"ê²Ç¥þûË8œ¯<Ê_æôKCéÿ¡ºŸþ_tžúzÑõ8)VÍ 9#Ë‹Îy‘ð¶·½ ï}ï{ADó}èCòðððº¤À¡Î€ÎÜ€9×ÇÅ(@Á"7T·?ñ |ù§;7n µÀBÅwÔÔƒ}ª¯s0Œ]¹³y@`-ª‡gC^ˆúž)æ&, ­Cìy<ê®ÁîÔ@¸ùûÂ+Pç ãB 0Ås0*6`^3Á À [ØÁ´Û/á òãMòO†‡tVNY%Ý=Ô ¸ˆ°¨0Ä!¼hjàÐûC2À‹ ê*„»þÏEFyŽ|œüoÿýeÀPÖ£O^ìŸË[Þò¼ï}ïCÓ4_ù¶oû¶ÿ%€[¤@åh)àø³ ,RÀ'ÄYLŸ*xýBSþ_ûÿ'¼üó?ë;;¨'k`×£E4žžÀä5 ÎØ{ BVRâ<á1æããÌ‹µö’AðºiV:žRâ@2Üb¨ ºá9ËûÄ‘ M‚¦C&à¸8¼öœíðâЀÅ8„uàäD8É ø6´úªÆ{ðÿúg±õÞñƒÿkxkïË„Ó6`¹ü®.—¾ú[ÖÏuº¿¡ýj‰G·¥C€òý©¼p> ¨_VXæôÏ餴ìÉòžBmŸÁ!© Á{"ò± ä3»¯†ŸÓy„²BÒ¤÷ÚÓyr<°Lúé™A–àËùªœ0p»m1ÿÿ³¦Å{þwÿÛh,VíYïOÙ’Ñ[$´“ŸÇ¢÷Ô)È#ä¾ó¿Ömäóòm,Kí÷ßú}Y6$?ÿUy«.³ Qÿå†?7þýlÀ“óå/xÿûßÿøÃøÿâ'?ùIÕªûçµ( —×*H(@AÁ@f»ÿùøú/ün5sX–V>ˆÁT‹ŸJèE3R%=zqlñ3ºŽ„ÐþC¸C”¶KÙSP>”'uwNš!‹›‚#‘´´˜¯„A}+,|]˜œÁ“—m…¬¤0²¡Õ0б 1œgX&ìWøõÿ„ß}ò ÞþçþËú~9 CÌú!ç ?2‘¬s®“!Ú~HPžX¥®ßß;„ܰêò«Ê /«÷ç0çx,«÷÷Ï«_nÈ3ðÅ/~[[[ø‡ÿðþã÷¾÷½ ‰0ÔgŠñ_€âœòð§½=¼ô ÿ_|ýÆmL&´Ü¤hÙ¤iQÔ †=õÏk¿>ËŠAÔmP¬·G;ì»vˆ3{÷qˆÅ ç}ý¡t`’$]ì‘©¦z}¦œŽiYæP.Çí3×&'ÿ‰‘"/×EXÒ ²I8ö ÏØcѯýî¼ï[pù…¢ñÌÑö‡ V’ßÐò}ƒ­QznèÕ(cîs†Êºlž5È‚ãêö‹Œï²eÌ’ÊEX…3ð |„e%E]ùyèïŸûÜçðíßþí[ÿò_þËúþïÿþÿ @í?ÍÒiÝCEAÅ((8%¸÷[ŸÂ¯|f2F ¾¯´®¿„Ú8’æ¾>§ÄÈë²Ô©ý‡:9y‘þái³¤b¾SríÑ wKói}Y–$ÝïÕfÿ¼OzA8Hu2­‘"Ô}:(g@ ŽbðuFÌÄöǨ.¯,˜ì ‹{×®á÷~é?âƒ?øB4 CÆ<ÇÐûË–Í_7®W?SÃ>dЇjÜùzÇ‘æòõ½>Iý~þŒéßOÏmoHÞ¸oôÕ¡ê—L–]í®øâ¿ˆ÷½ï}þýïÿ?ûÄ'>1Cê(¥€¢8§Á8‡;Ÿþ4îîîFUdÞG¡ý³èaln|//ÿ#¼Ðˆ9ä3 ð€7ú¾Dé&ÔèaX‹ñ‘7³ékÛ “Öê9Õ÷±¶OÉqQƒï•(‹jí߇̆®§µý–Hc dçßIdŠ£XJ²«p-^ùâoãè`k›'ú~ú†<¯í‡óà…Yý@ÇØç‘=ÐM¹ÛIãÈèµ#æË­’RÚnyJ}U–ûƒp†ŽoȱÑke…ȹJ·@ÿüôZݽ{ׯ_§üã?öíßþíÿRK ’ûå€R X€âœÚšvxwûÚ¦ ÁZÓÙ)øÈM(g'#üdŒ½ôå“è@Ö#!öù8Õ¯[‹Æ>¾‡¬[aP³ š¨˦2ªæÂO5Š‘f (¤û‰àáCiCË‘`hâÖr;’^s·!‚Ó~ÆÁ¼°óÖ66ƒÓ± Í}úä¾EŸå_‘§ÖóR@þ;:Bt}ýL÷y«__¯btómöqZÃ>tV}=dàsD¾Nÿ÷eÛzñÅñ|à-ûØÇ¾ýÇ~ìÇþg ¯`éˆ-Y€A  à,à[Ôó4;”€ñh ¢`°ÕHQ„¯“ Œ5~ͨGG@ߠĶ×:9Ží~²ÑDÇÏÊ!­®Ñt¤ÆòB.9¬¯Å°r4×±OÅþ”×Û 5¦“ÍÈ„H4dpO­(t!x¤¥õ¬Þ3Ú¹ÃálšÏqpxˆ'| Cuýeb:ý(¨k@ÿâÃN€ròè?OyçÑðP¦ban}Ãy\ô¿¬„’ïg•ÀUÊýsîwôË'ùº}çÀ9‡¯~õ«ôýßÿýÿÍOýÔOýÆîöù9#&ÞéÅ((8 âÃar4Ç^ËÀP×uàdø.×-ÉíÆ–À~wŸ²ó²^~åùÅ!;º=ŸµÙqõþ…xÙ†öîÇ%adÿgÕ 'A"üCž~à!ŸÎW£xGG'ç8ÄS‹ýp"¬×‡mÓ`÷è»óÖ Lw„òIÒܺ<ÎuY 7¾C$¾ü}}  íçýïy¤ÞÜ¥÷ûÀúë.tÒ‘¿Ç}¾ì˜-Ówp†H€ùë!ž\¿~ozÓ›.ÿµ¿ö×¾ûoþÍ¿ù³¥€á¯&'ö³‚✌E=a³m±×6ؙϰ~q£jbC¡ÙžUÐO,>ƒˆ¦þ!9 >Ùé%2™µbj?|¤N‚úÄÒ@ØgŒúó®Œ>À*+HÝ ƒ¬ }Ý Ò‡œmŸL؆:&ŠèLpŽqúÖm3ÃÎÞ>öÚSçQǨëôØ:Žù¿Œñ?Ôïµýêë~) 7üùë¼ÖŸG¶ýè__/‹zûÇ4Ue.ú¯«fË"†Ϋ8ÎúŒˆpýúuûßñ?ðôÓOÿ‡ëׯb¸Ðï‹)΀ 8gÌd‚-k0›9Ì÷±7£¾¸…õµuc¢`W…gTlÇpêˆ@Pø31:NuwM¡Å!ÀY*ž28‘ˆ§­}ž`.8$F˜‘2±‘$Ã@€‹œ<Çšu=— -LÙ $ÇÁåq'®€çp4=ÂÎþ>Ûsc±ËWÆãTƒ_`ÜVéèGøCÂ>}äÑýP€~¦ÛW' ÏPôSàz<ùñæX…ô7´|?â^5c²¨dr\÷ÁЄÃãÈ~«:ý}Þ¾}Û¼ãïxþ/ü…¿ðÍ?ù“?yIXÕ´5 “³ŠñÏP€‚‚Ó@H€d-ØT¨Çk¸0ÝEÓzðì»ÓC̶·±¾½…Q=L Œy—Zò 1œÞ¡D ’±@4´qÈnlóëi@ xf¸$w†ÒÔCª€yô¿¨ï·Eµ÷ã®Á"‡b•uÃPÆB›‹Zóë5”pŸÄrõ·~ë·~À'"ÌtÉÇSö¯ÿ Å((8x-¦®1šŒqy6MT3‡½£›¸³³ƒÑÅKØØÜÄdTŒƒ`Ȥ^~àeP¥¡=Æp0Ƥ©y5Ú' öTCsMós…Xa\s^sðH›åèshøž}FLp”½™Õò‰tÚ`Z=üTÉDø0òwÞ´ØÛ?À½Ý4³ÎSc1ó˜Œ1¯,"óY”¿Läg¹mˆÄ§Ÿ÷ ÚÎÖïÿÏ3jÔÔ öù‹:VaäßI ø²íŸtÙþõëŸG~]†>×ßóÁüý~‰ ¿ßÝÝ]û /¼ÿ™gžÙ¼víÚB@gji& wâ&肽ŽP€‚‚‹V=Qµ¾6¶ÆZŒG#\š·Ïì¬E{k;_¿Š{O\Âäò%lmoc}2­ ˆ¬ôÎK ®?9±—|+ŒôŽªŸüBÁ£Ì|$Ñz,¾w?‹‰R­ È"ƒ¼iÎÖ!À³NèKõ=>"G6arBwÃq‹éÑ ÷öpçÎ]Ü»}-<ª­-ØÉ­50UÊT k`ŒÅdc:†Õ±$°Ì.bùçï-bãqô3]7—î;ùñæûÌK}öý"2`¿ùÏe8Žó°è÷ã¶Ù_§ÿ^ÿûçš_ÓãJý}Ù§Ÿ~úùÈGÞôÓ?ýÓ·L‘Œßð—,@†â¬ïCšÚ˜N¤cÚwÿàpôÕ¯ê`ÈÙXx"Ôã¶ y ËŒufܼ‰½Û7qu´ŽêÊe¬_ÜÆÆú:ÖÇcTu%]6P í1&Øz-ÈçCšz™1ºî>ÚSöK Ë{Ñ=Ýg´ÃÛtûÕ8IûAd8JõÎ:d[ ß:Ìæsì`wwwïÜÁÑÞ^˜çZ4¦±f ¬1€10&Ì$lañ»¿ò«xöùçðôÛÞ†zm=‰îpè°Uµ4 04%0¬ž"ýð•ûû nÝü÷õThŽpäï1ßÙÅÛÀU¦ »«¦Ù{†±[›¬¯0mZLæ¸)ZΰxGW›Ü檭MÔkk¯O°1£ªkÔUª"Xcƒ1ŒD>'mƒòð×Ô;†åL$’Iß/cgp_ZF fC²fÌ PÔ`öðìà<£iZÌ›Óé GÓ)ŽŽq°¿Ùî>˜]à0Z7®ÑZB Œ&¨Ç5¬­Bï{q)Ä9±­s¸³·él†êú5ìݸŽ?øOÿ ®®ñü»ß7¿ó=xã7¿k/ÂHf€™#‘lQÚ?¿ô½¡A@ýõûÄ·\اýÇ+: ô3Ôî6$W¼(3° ýãîÇ2.Å¢í/rTuô—íó–1þuäÛÍföÉ'Ÿü#ù³³X\(à„8‹¾Ú‚W„æh0ªº4;;ØýÝßÁÕO}·?ÿyTÓ)懇8ôl¬Ôÿ ÆT˜îÜÃþÚì¨ÆÜqˆXx º÷ÞqL™¯GX¯k\ôGÎcÞ:L[‡#ßâ=¦û‡8Üßà À.÷PÁoL`×ÖQOƨ'cŒ&cÔU…Q5‚µ•µÁ10 âBD1†“°ñÕA@4öâ3$!A(s_ƒ¼ƒƒ»`PZïÐ:‡¶i1mæ˜ÎÌçSÌfSÌŽ¦˜í‚¹ Ûe†1×ð0h ðdÑÚ Õx„ÚÔ0–À 8Í5h§ƒœg†q¸³º{Æ8ž ¦Ó#`_úÕ_ÇÕßú æ¼áíß„çßó-xã;¾[O^UéQ§Š~Cã{‡† õ•ëú­~ý·/l£?‡ [?*_½÷?Zgl¯k¢¿þò?åÆ=ÇyrÙyG|ºV}2e~JO¡›èÿþ?à1Ï àñ„Ôôµ!E,hîíàî¾€[Ÿú®ÿöï`4Ÿáèð3ÏBð3)læ6¼òÝí¯~Û“5ÀR$ºùÖ£ÏaŒ2$Zf¶²Øª*`-<àZï1óÓÆcêŽæ f̘R‹éÁ³ƒ4ŽÀØG0î\€É¦ÁŽjTu ª*ÔU²•50da‚¥`X L&=¬|€à 9yÈ:ïѶÌMÛ mšfß¶˜ÎfpÍ n:*ÂFÚ©1@c8Ïp„ðÏTબEe+T&t&0¼A$2ðÌð®AʸÔ-à‹[Ÿþî~é˨Û9ö07–ªÂar,ýì=:=å |ŒÖ3ö^¾KÄ4kC[wÀ´…_‰d€ <ÖRTü#l •10¶Âz5†•ˆ¸a\È ´Mƒ™ó˜»³6Dê3‚Æ1ZÃpìà<à<‡”»sp`'ܼÆÁ€Œ‡gdê0s¢ÿÃ!¯*.d0¼ ë6£µ kP™ °ƒÊPHÕK©ÁG€ ~ÈÒò˜ë¶Îç3Ày¸¶EË­kA‡G &ëðÄpB²î…2 ½nˆK„ÖvšptˆÃ½]ì½øüöÏÿÖ/_›Þó-xûÞËÏ?;£’f†k[¢Øê™3Ùñú‘þP-¼ÿÙqŒòuá$œ€eë‡eÙüuò"î R½E× Ÿ50Æô£ÿEiÿB àuï í\é{ƒ—_ÆÏ|7>ùI¾ô20Ÿb6aÆÖVðÁ´gD5Tûâ½*5†*~ë#y–^{æ`­w fP«Ò< æ­C= $7+3xcØŠÀ>HêÅx›Xjâc ÆUÈfŽL§óááÙ8×:ÌšÎy4m %ºÖ££åðGk߸`+©S{ÀQhÏCx YïUL]Z÷ ƒ}èjð•[ c ZøžlŽ6¡ J ^³& ¥8ÌD­P¸vn6…­Fa8‘gxb0ù8eÐ1B:‚à %K©£ò…ð/d"l8;ZCØóþ`{Øé%|éßÿ{˜Íu¼ù[Þ‹7¼ë¸ò–o@½±Žª®£òÎÁVÕ})è¡Ôþ2G á¥ÁORß_Æ#8 Vm \¦”8´ÿEE]ËJ$Çe (ll™áJ ƒâ¼æÑæ!Šõ\j[ì~ý%ÜúÜçðòþ-4×®Ãá°™£a[×ðÖÀx†c¸À–W"³NÕã,.ûÔŽìÁè­¨ô Á€<~ {´M‹jTe=ÃBôd <¡Ña9øÆž'ë„v8S…¨—ê쬃áÑ4-ZïÑÎÛ@ÔósçàÂ1Ø Î·plá]0¢öñFk*™üÔ&´éQˆò 5ûàœQ¿ŸÄW‡2‰ ËäDñN©4‘OjkÀÍ ¾C}…VH„ Àà¤}A5µÛ‚¤R•I„œ™BØ¡uDÇŒC˜ép°?øŸ_ûÕ_ÖÖð¦w Þðîwቷ¾Õ@{¡~µêX,sô]ÖR¸J»ÛÐç}Ñ¡þ~Wq–‰ é{CÛ\äÌô%•ócÒ_:ÎãÚð&Žký+Æ¿‡â¼6±@˜‡çsì~õk¸þ¹Ïâú'>‰öÖmðÑöš9ØXckÀžáœø¤¦¯ú÷Ä /ÏŸ=ä¼ ¬ÈiÂV¡P‹áa ÿŒ°àƒf6G½>†cÊò•Q8ö»qÌaªëáEþ7ì;²cS÷ \ë²6D¿u…ÊÈ{kÑzFã¬÷pq¡¾ñ_æÝç÷«¤ö‡”ó}õ ú2‚ü÷EŽEÿû%•|CÎÏ¢²Šsî8æ?Pœ€ŠPðÚh¯ß/Ìs„ý/¿ˆW>ý\ÿô§áïÜCsx€dHÒÒáÓͬz5:ù.À£¬d`:EÃ!ÁOðdÐʶMÖ/섬À|Öb4©tÞH [š Ôp±²Ô°!eÏ}´‚!Ýî !ên|˜# GÌ>d˜•xˆt®:3ÀHæŽ$ý’+¡LàE™ˆ…lͲ…hðë@é¼:‚<‰dXBÓ´pÍ‹"¢dòg¶² €ŒCN±8¬ƒ-݃§†8dNÂùJ& ;§h¬A3 ùµßÀíÏ|sSቷ}#ž}Ï»ñô7½›O> ªëÝ;ç$aûÛ Ê/2¨ý4yN0ÌqܶVÁÐz‹Œòб7qpYÆcˆÙ_oÑþ>[fô‹ÐCq ^õè¨ñI´ãpï÷×>ý\ûÔ§A{û˜`Ê’27aÚžÖ•uV-‰áÏ•pcy_#N¯*–:20Ú½—™¸!RÒ‘ÌÒAøÃ"FÒiubÌæ0uc…8ç9ÿ²ÌÄ6¨éY ‚$AÚ1ň%º£ÓKO}¬ãs ò&Ìú NgC–QE@yßËTÀê§ñ“\Nè`a€áàaà)”„èˆdüÙ#:NÞ“=£ÍÁÍ @?R׊“‘W‡B"F¢$1œ¾Mͺ„rŒ@Žã!† *N³ lH#đ޾u0&¨:c±{4û#\ÿ­Oaç _ÀêÛÏ=‡7¼û=xúïÄÖ3Oƒ$3Üß^¸ÈàÇÞj¿[Ö†·*à$súÛ[… 8TÇï/ן‰0Äèoc•ãÃrãß_æ±&à„(B@ç‹ø‡ž=<­ó´ûû¸ý;¿‹Ÿý®~òS¨0=Ò}¬ ‚øBÚêØ…hñ¥šOœÇ•±´çiÔ¯¦Ygäˆ ®–$3à¦ë5â(Ô0hÉV¸jQ#ßGã[ÔõF@9 ™CÂcÕZ©¿2@†àdö‹pËN¤yÁSJ±ò„˜8ç“RbÈŒdQ±ChCÔsï\B1þ{‡LJpfœ$¼,ädY†” Äir:K@9 †‚¨Ðt ˜1·°d䣠IÙÝ~È9Xqøô`ˆ(Fõ&:},%–cg8&Xñü‚sfâwNj”é[”)|e1mZàp†Û{¿ƒÃ/ý¾ôs?‡õ7=ƒgßõ^<ùÍoÇֳϢÎ@~?ƒè¾Q¹Ç‘ÜVÕ2„ËJçõ·»ì½¾Á’ÿí¯»J) ·Þ2Â_yx÷P€‚Gîªñå³ùîîüöqí3ŸÆÕO~õì³Ã#̈cÀ ÂìÔ”f“?b}QG覔?ŒŠÏëè4½`l“ðÊ‚ÉKt›DlZ“òµ:fÃÅ °ñð» èJ Ëá}oRJÛyLp‚á•‘»„|¼ˆë\0äìc;#–Öǽ‡s¶Ÿ¥%1E¯%¡‹@Áyð¢¶§× dò–=!"8 ²¬ ÇK^ªúJ„tL 83íl?ŸÂÛpìg=àmpttü±§D,4œ £Œ>Aä„bD$]Åò‰Ç(8 ÒåÁ§Çèý@r“¨á¼|ë`cpضàé G_ØÃÑ—¾‚/ÿü£+—ñÔ»Þƒ§ÞñM¸ðü °ãq¸Wµ£ ÓX–þzoQ„?$ñûpÿ„ya!o \Tï?® "o‘Òâ@(F)ŠPðhÐ3ú¹ßìömÜúüðʧ>…Ÿý,ª¶Est„©g˜ºê ܶ!Rc-ׇñ²jœbÍQŒCŒ^µÐ.˨Á)ý”4ðJPâd 8‹’õÙ뙡#oC]ÏÏ &†3B*Âñ Å|Þ`<®£_ÄwôØU@ n0–m»ÑH¤o‚3ã|(=(¹N±û“$C Y ïÑ‚AdBDŽPÊ`)“8™¡ë$Ѿ|)CŠŸk£B+Ÿùœ× N‚^7„ýÀ˜Ð¹0‚LÀ€­ÐM*XèvÂ~˜ÃyÚä“%ç)cÙ¬y_yr,ð!Ñg–ƒe6AøXh¡µ”‰AÆ‚ áÈ3ÜþìÞæ¯\Å+ÿá—@[ÛxúÝïÂÓï|7.¾åyTëëȼm[TâÈê=y\›]úz´ÙëUG çQ|?¢ï/êZ:wu$úËËë¡ À²¬Àcâ<<,1úóÛ·qý·/â?ãÖoõ¼ÁÑlŠ6¨åÀÔÔ¸P#o¤ï}§ˆ{Ì}0d$­Ê{…Fª^D¸Èˆ€Ê‡*æšÿ¼u/y/»q†Ð²¤œI¢ZJû ¥}BsÔÀ …7F¶­ò)!‚ö0ÆÂ°2ß=@&l1Ä,ˆF£×²„*G^"}9öð ÐØ:°–*+ÆSx @Ì@¸1Ò—ô¿3!Cà qÒ5£¸ÍœBSödÐzæh žµð• )þÖÇù­úué7í3GBê3â°5òÚz5ÄÙ€,—•oïE‘0»§Â/B| ÒQR¡´>z¢p©8ò8<íàåë7pýW~ØØÄ“ïzžzÇ;qåm߈jsµ”·ÁP!aœEìüü½‡‰ã˜ûËø ‹²é»ð÷msˆø€úÅ  à|ÁJ@ Þ¿Éþp¯_ǵÏ|7>õ)Üþßͦ8šNÑ2PUœµ¡Ûœ¾‘>j†<ÔvÓ˜Úø`‡ŠÜDF<›h„™½$ÛÓX\5޵> 䬎€WCºœRkß ÎZ! µl#Q2¥ w ÍTꪒÔ9â]x€+!åÅÖ@Iaë1²ÆÚs(?HÄ1ÃùPð‘”§Æ»u­èx â@€+ˆ;I)Ã$®‚–Xø ¡ %qLbiÂÄrAŒÈ%ÍáØc>›‚gSøºؽƒ3¦ÃÐ ×%edT8(”ðåž0éxƒ[Œµgé'‡S é*áºæ¢N†ÃùP4*úÅd÷™¤<¢÷»Øyi5˜“Á|:…?ØGûnãÖoü\=ÂSßò.<ý®÷àÒÛÞ†ñövt€ fe‰À½áDz¼}Ð’ £ÄqS•?úü…þù 8Z@Ìß+è¡8çç1=£ðò+¸ö™OáÚo} w¿ôeØÙÓ)C¨Läd]˜6§¡bœEÏÂâ–}h:Ÿ¥o^;ã $3N½ó!j§ íS¿*£On6B¤ ¡„¬bq8 ©2ZHû{òh9ôÍÏ%ÛÐB”ñ¼Ge‚MåCë¢`˜ác:oÀ  :'-£ÜzïÁÁŽJpzÀi°—½ÈG0$6‰èÕ({~¼{'û ÆÑµ-ØP] h…¡>•óõRæPu?Ç€7á{гÈH¦!È+Ù/¦ýjòóéüÁ!…v&‚ ¤Œð-)ÙR`ÀQªØpßÊ·Û3“@ä«õ̰…€Ñû#Ë d´Ôc¢3D÷u§$8zñ»aݳ8˜ÂÛð®‘{Πa~8ó×þïâöoþ¦•ÅSoÿf<ûž÷àÉw¾ãK—¢ð!89aî8<Š’ÁP&bQvâ8ÀEË׿XÚ'Gq ÎÞûøÀ""ìý%\ý̧ðò'~ {_~v>ÃÑlŽ Ô5¸ªQIˆ¾)Fi¬¤;C_ÊDZò!*‰¯S+Od>x!‹ ‹> ¦‘ 9èØ\5Tu}̸Ø.§•{'©qÇA1¯¡0C@ûó[TžÐÂa ² r‡cÌš&´.Žêp&kªZÓäñ/0ç¥G_Óþâ9#?5`•R{FÛ2!PyPÿiåÙÃÏ|X¹¶A)8#öù8Ê—YSÿ¡+B³±ôÀŽM"ûA ²dZïÑLа€e!ð¥2× OVÅõœêÿÌ!£’I„z‹vyÄšƒ~rŽ™ýoT2ëhˆCi„÷?öFG&”qBÙ(”e€ð]„mËýªü‘,0m]+-ŒyUa6}‹¿ù ì|ö3øŒµxòíoÇ3ï~žzÏ{0¹|©3©ð¤)ïãúûOãä†yYJY©`H`Ùö†2Kº†~/ÈP€‚3…ÿÃÛ·ñÒoþ&®ýÖoaçw˜N1Ï1Ghë㪹VäàBZÊùjÝYŸîµ¬ÆÞ¡Ï1RëE€æ÷¡:ž•m»´\d­sÚÔ¹ˆ™}PÉöòSˆ”g(’Ø Z0*x~²Ñzs0àmÓbÄ  j‘ÜæE\Ñ r½z„hœÙ£¥PðÊ–ç0DÈ5Më"g…Cj¿e†ƒ·Þ·¡_@Ö ŸàØç!êu€pñ•þõŽUË>fL€yÓÀÁ7ó0eÑ$5A=vé{d ìÕÙcR^ôyH”Mð!+"N¢æPG§0²È—ZÛ÷‹j (oÁEg3ü_ôاNxïŠã¨†)f’S  À»&: mU¡ÏѶ×?ñ[ØýÜçñ™ñ/°ù ߀·~×wã-xÿÒTú*X¥tð Û[•‡°ˆà·ŠQ¾þI²!ËQ€‚³ƒÿý¯ÿÿÍâð¥W`6Ö°vé¶.l#æƒ&>Iú™ØI ?£sš7Žî»ªº%yˆÐ”ЧŸEuÀŽãŸ @XÕI*=ú4RóÑ(°ÿ©ˆ ïi _É‚ìT‰ ‰k1+F6T±ÃÈVã ,3j ©êÆ9ðŒQÕÁPca]0­V—³hÉi×C«%Áá]‹Ö…Ù·e[á4´ž¥|´’Að쟡ñpn8U ®´²^®AƒnK¡W±N.»'¶ñpm7›†i‚&8aÞ‹ãÀô¼‡uD"Á2¦ãå»%!©öGA‡à‚¦¹Ž/Vó›ë Ý+΄¼KGjÿY4#XˆŸÒY¢í†ÉqPåFˆQGvLIeQ³!‚çÔýAíLîgÆ~Ûâê]ܼz»ÿößbòs?‡ÿú'?Ž·¾ï}ðÎÅé„ÀbC¹ª~@ËÒèÇÜãö¹Ê1-J÷ÓÃÖ9x=¢8gþÛÏ~äw¾†Ïûܼ} »_»†[O]Âö•ËØØÜÄd<‚÷¢ rGÒÑèZÁ;pñ± äQœ€jÅ‘¶Í¨yFA³ =€`<´æ«i`ÍôFHª9sˆ8š%J˜‰/¡Ô0ä/lÑÃÀ£R^Š fŒˆa!ĸ¦Á¨u¨Çªª‚‘º¼±&D»øzíD„Ö·p2°iš&Œ"nÁhác?¿#F+ë9 8ºœßZ ™Ä×À7ÞÎX°±ðÆVE~BfCîÌ:$(LçìïàÛ~î„sP¥.ù› ËoLpTC@®³‘?I6ÈÃÁøÀ¯ šÄùP/!˜¨Hñ[£Á.Fùßg…n„´>|âhvª_bRM%%§ê}¢ÄÁ°wŽ&¶Ã²cíãö½]ܽ} ÷îÁ0ÙÚÀ|o·¿úu|ÃþòÝåYíãúèWYï,p\¦bHá8µÃþúgPΈ>Üãˆâœ9&ëxûö6.Ý«qÓÎñR{ˆk×®c÷ú5ÜÛº€ÉW°µ½µµ5ØÊBm~œf¡*NÔëÄjt8¸˜IL¬䣬-Rfuý´–Q¿‰8¦Êm² i´†ÈC`%’ɱY‰ò iŸ~ˆ`5:¶ð`kP‘‡õ ‹Jº*ÉcX"X&Tï7M ëLÓÂUA<ÆQhôÞƒÛ†¡6­w`Ç¡¦p<žS›^ëÕ1 ¤½ÖƒÔJý;±øY$‚}PlÛ`œUáÏÚPþ2 —+ÒŠÐ÷ž=ܼÛ¬~ ‰Þœó`¢q§FQ®»ÊK+Dî!B­·‰DãÄáuh÷ „–ƒ&ý1ZP×Md :ÓÙEcnµ4ì r‘8žÚ9 Ž‚Þ ©…#88êˆ&--„ŒÍ|6ÇÎÁnß¾‹{7nbîXõÖ&ªñjk±6™`ýÒ…•ÿþ–¥ÔO“6_dlOCLì ü¬"tÔ¯ÿÅ(83(Ûßllbn 6¬¯OðF7Á×àêl†Wövq{w7P¡~ö 6.]ÂÚæ&Æ£‘(µ%ò³öÃë8F¿ÚŒåctœ‡Œ<—!ÖŒ4Þ7:‘×­9ˆDE.HM™ûÆCkŸaÚXx€EPô๛…[C°Ìý–5QÈÀÀ€QAF˜-F, †.cq)K*‹eñ¢}à]Hç7#.©~ï …e\ß«B ”ÔvÈf˜Hö,Z ï3‡.ßÌଷ g ηð¶O|mC4o P0BtïÉÄ4¿76HÛ@²óÑ3ðì“HOäÞ‡oÍÔò}Yc’-dÂwg ×K²3uKÔnÅ(Ò\@øÆI~£o¡Nhò?IHÛNµ+RŠ!í:QG3 12Ÿmë1=šáöî=ܽ}ûwïùçµ1&ãK¨« £z:B\ðvÆãq”ÍÃXeøÏ*}Ä)X6ÀèA·¿ª!_uHQÁñ(@Á™ƒ¶·À# n<,*0žðD=Â[š5Ühç¸ÚáúÕëØ»v »›0zâ¶¶/`¼6F]Õ‰ñïMê׿`´H"IÃýYp!rôqÄ,å¥u0„P¦=¦û³È^÷lˆ—Dõ’ ÌÊ®#`*†œ!õ{1Î;T•g‚5!Õ]BËsj&TäРBHo[x!‡,v=hÐÚªqÇÀ+¹¡øà Ð*Þtd‚H;Šççà„Èç£愜ç[o \Ú½÷Áá0;‡B€«ÀOðÜÂöá=˜,œw¡w_´XÓ0~•õ :bhÑà W†ß 2"Ôc²T<°ÚÆ!å"•‹Vç‘ô»‰œŠÄ bXW e Ý÷|Ö`ç`÷îÞÅÝ[·0›ÍÂ}±±Žñh U]£¶"3Ä”Úzc Ö¶·;òÁáÒ/¨³Òßë øÇmg`Ù<ƒ“ŒA.8=ŠPpfÐJ*mnÂãFêô-Ü‹#‹ £u¼ÉMpϵ¸z4ÅÕý]ÜÝÛÁSƒžº‚µK±±¹‰Q]êÀŠ´í‘ñÂó›EÌ_žÑ¤ÏgIÛ#Ñ­½¦¨Ÿ4Ï@ÓµÚ5«Ñ©O·`¨‚A ýÈ ñ.°ï% *£áðÖ̰Ľ†Ô|E$ÚôŒ–7 n‰@΋A2PÃmö"iŽ»Ëå<‹ø—¨> rÞwœ`ËpŽdÙPŽ`iáÌ8»ÊHöÄn@Ep†á ¹¸…tÿˆÀlDOÁ o?¼vؘh •<˜ÚÃ&†ó° Œ@A”‚aåú݉ÁG$èÙøí ¡OßV©ÅAAÆ fT(|Øq:g@æ4ø´m —rQ0Šçpp4ÅÝÝ]ܹsûwï„ÏÇcŒ.l£®'U•dÏ8ÓŸ x_9c0ÚÜü›;èwÕm®BÔË··JëUöøõŠâœb `}-ã<‡‡²J»zy€ŽŒÁ³ÕOT5^ðk¸9ã„[×®cÿÚ5ìoncôÄel]ÚÂx¼†ÚVB )Õ8W]lµú 2vF’æ†ÑÉõY»—^ú]Ã5$ç“C¡‚4”jQ$¨˜ Œ×a&ËUàK!…ß²G-œAà¦ñ@EáZQˆè­8<•Ÿ@›ã%ÚÕö¾¨ZÈjüY˜øŒ06¤û ÄFFn*áò?’IÂÞíj*.$Ú}þž}(k&@jû\{ø†Ã¨_òâ40@Veš Vúò¥…ÒQ¸~k Œ(´ú[¹®†•7!)|-—ˆfÂý'„¾†ÇˆÓàê”ú%¢ç”%Ðï8Ò³ @pÄdœ°l³iìâö½»¸{ã¦ó)ÀnL0­a\Pk¿do´h¡³ 4©c°&€y¥»OšŠÏÙýÇÉ+ÕdÃÇÅ(8s¨ *UÈES¤áZ!©è"\°.lT+ÐÎqµ™ãæÁîîïâöWF°Ï\ÆD²“ª†­ œ §Fq Ž}•〼§yØŒÚO9±0ªÍ° ÿÉà:-N‰Š‘$F2QNy †€ „±ô–3€C5ΨˆB¤BE‚¿Î%^`éW"Àc|È(CAŽ›Iäj9Êת0Np²dkšî—c± ö¹jļQ'†>®d¸¶NÔ­›3|Í@-ë[‰üjþáh Ú¹q$ ×A—e ¬FGAÅЉ#SÃ`#fŒŒlpàÖôJò5«ñåÍÄÆY­^å•S­^5€0¥Qï—LiXĤä>’ËP‚ð˜Îf¸»·‡;wî`÷ö­ùª+TÛ[¨êêªF­"YÜï.Ñý¤ûQË:;ëcxMbˆ¸·,ê? g¡pNŽâœôÁ6ÖÆ €IoÔ'µÖež ¼ FkÍZ¦“t<ŠpB”›ïx˜µ ª­-><ü³çBÌ^K]°N²ö&°Á+\4.\¨ñœ›àN3ǵfŽë»»¸·»ƒ»¨€§¯`ýâE¬ombR× 2ñé<ÁXI7iÃU]MÖ˜ºµ¢cÄž”îÍë™-QŠ.­ sìD—cq L½ÇœÃ•ñ0lBêš¶Èr`·SÎ7$mnÒNŒ°?H&€µR„âÐ Š¥&ˆöDâì"éŒ8 µ‘š¿Ojý.t øŠàÅVB€£ZŸ÷ÚÈ ™ˆ¨âBJ0dXÀyŒLˆð+”;¶&T (‘\#8F5…÷jN2gü©b´¦/%ž¨ïà“3JRŽ0êpoÒ“E^x6k±w°‡»wwpïÆM´i+³±;£ªG°&p(@ÁÙ!ÿßÚ$' Pƒð|ÍÙùb5‚óª²ÈTWÙpƒÆ¶(1¨›µÁf=Ás£ î¸5ܘÏqÍáÖµk˜Þ¸†Ã ¨Ÿ¸„­mLÖÆ¨ÉÒ™g2R7§NTÏZô¢]Fš?Oj„šjéè0 @ÙÚ:›Þ“‡© ŒÑtEµ Úòía 76hZ`^[0 ¬%®@Tí, ŒZy(ÑM»¹±k-;XôÕÇ6Jb @A¬ø–ƒþ¿ ujr¾&!3ŠŒm#S,¥vA•@«f€LËó1ŒüÁQ2˜ýTq:‰ ‡® K„ –-*20º"t\°Ñ/ʳè$dizJ‘¿ŠÿDgê¦k£ÿ”‘ï½ÃÁá ÷övp÷ömíï…ÏFcØÉl]£ªjXJß ¡3ÞWšƒàŒ¬˜Eýù ¤¬3eJŽÀh}Ê&÷³â£CtLÝi{ëIú.ûý¸}E¿G‡âœ)ôAd¯\‚… ä{%^‰5eMÅ¢\ª‰QV$¥‡µ d(L߃* Ê`´=Èfd@ð00õ‡h¹b ƒPÿEÃÏQ¹<€aSböwœ9½ÿdQ"wrt0šÙ{‡¸wïîݸƒ†ePÏd;ž Õ¨L•4'4p7]RhÊJV¡2£Ÿ¦’Gu4µÝ6´-6.]ŠwÜ*’º«~þ ƒ1ÒçÍM(™‚Gq Î1¹t mˆ\ZaR‰Ñϳ$V×çiİ¡¨¬¦Nƒ"#¹vMµ[Ö`{m oMp¯]Ç+³n˜)n]¿Žéõë8ܾ€ñ•KX—¬€5VÚâyMûÃ¥>]/©i}Ȩdm¦Þ×~qR#ÚâàÂñZªa;ÀÖÆ~$+Û 'lkƒzÎà pÓ¾òðs‡fbÃ[ÉãIC¡FOÒR©µ:C/›|7rƒcåã9Dã݇4ÿÄÄîv  ö.(ú‰vCZ ¥nc)L{´Æ€æflQ5-`+·°,˜š@G Z·ùW 6.ˆXZ÷IÒ"Ôÿ5ݯ¤N+/”Ý ?TF8ejô늎¦wJŸ€gÆìhŠ»»{ؽ{û÷îJUÁL¶`«1êQœFÈ„ÇÌðßG‘=šH:L§t,ê|†Á ¦¨›@†/nwþ¶Î£lpÜ1Ÿ¶­¯dÅ(8[hªÑZŒYMf¾aÎIxxðj‘ôI·yží~Å(8S¨ 2ÖÀl­œ’:Æ\£l%b‘ˆê(›><5ɲÛð“”YŽ,ðbmëã˜Ê¯À¸0¶¸PUx3q«ÝÀ5É Ü¾vÓk×q°½úJF´¶>±É4ƒšHålƒèL46±^q DCaŸ“ä5eúм¢êq`™Û‘ ‘ šøRïDðµì¦ ;»fÁÞ€×(ˆ'‹Í[ÀÏ[ 6ðM _WÀ¬Ù ¾õpµœ T:òð3ŠÜ xîA£@ä‘Í[ ©ycj€[€lìv0â?2à¹lø¹nƵ\ P mž· BcÿœÃþZ†±\aÈkðáû³d“…R ßEÖJ&¿‡ìëW‘œ3M÷G( Ï„çp4›cww»÷vpp÷.œ¨2¨&›°ã@ê3¤ËC2#Á !° ?ÅVCK,á«N)ÿÈ wG¼OŒÿijп †‘N¸«ìö*N„ÄWÙ°àìQ€¢x«Ë¡Æ¼¾|lMdû%² =#d.­™“è¼3©ô.#fª` Á;î\ݶhÄMu‡ @̳õOŽjì»5ÜœÏpµ™áÖþövw±c+ì=y“ ±¾±[×R_öAG@9 ²?­%Gć7`Èĉ…$'m\Híê,-q(3=¼OQÅЈyXUº ¼Î]<{ã|`ê3&D«ìBo¿/n<Ð0¨2àÖ–¿sàÊ€âd>íÍd h䀖Á•*Ì=¨²`×€Œ·mpzZ|ra?µÏ=0¶03JÒy@Nè‘^Œ~åBϽI‚>Ì!³`¼$5LðHºÂW¬ÆHÚG”ÿéÖÐì 3|ãppt„½{;عs³éaXpRÃŽ'°¢Ô'ò±e6]nBp@¡Ç@g8)÷hYBKz£(0ÞÅ:@(v"„Œ iÊZ¬on¾êˆrÅ x} 8gŠ˜…ÞÚ‚ŸŒ@‡Áh0Òƒš´å*1¡m(—‡¨ â¡ËÊD:­ÿ{aåC™ðè1ò¨J‹Ì{ŽC×+¼ÁMp·YÇõY(Ü»~G×®ãðâT—/c}s ãñ(L_ƒÅ4"UwFO‡¶i¼l$^ƒÐ‚g´Œ!ëGYai?dI1[@F"WurBßÛäP¥ñÇÁqâJ^סÆÂ“°O^³Á˜Ø`¤'6Ü‘ †]"rTU°vÆ‚¬´EÆuj< ©iSÛ°Ž­ã@Æ‚Çb­'!µcÖl°¤# ò2Ú§oÄ´a]&Px®§(ÇŒQ%ßi*·‡ Æä c™õ}f¼ƒÓÕLçØÝßǽ»÷ppç&ÖXXiá³UKÖ„Kâ83ð„¨O¡5§ü³(/M‰/©õ~ŠŽ¡ÜÐIƒ'QKY)—”Ë'ûð}L¶·ôV;g5!pòn‚0„ÊŸr‹Å(8[¨\é…m´UH÷ºªÛ«ÉS@z"¥ôõù¥ýÚìƒÂ|ˆ°Œ¦u…Q/‚öñaËJþÒ‡!'Aè7­ÅfeñÌd‚·6k¸>opÝáÖ½]ìÝÛÁn=]¹ŒñÅml¬­¡Õˆg ÄD(BµŸ‚cÊÁx†a†ýî]Ê]xö©?\¶¦Óê4è„¡Ž”H®±tE ã'èua1Þ ÀcÀ7^™lÄÒ"´D4dÆh<¨¶@#µ—6¤Èsø"j1ö$‘JTùÀ'0hƒc'©$€Ã6²Ü2L ° úäM¼âÜ%"T¢Eì…ôlj<šEþ†®ñ88:Âνìݽ‹éá~¸Þ“ªQˆömU¡’öR–¾E85òj°Óþã°ÀLÍŠ•½îkJß*”¨Ê¹òPìÔHŽ$²ûŠaB[ae±yéR4¸«ôóÌô·=ÔŽ¸ %kðêBq ÎÚ‡=™ QÅ:ù(µ@qúM°¬›.«u^¤Ñ·$Ù}Iñ†5c oT¢•‚ÖÂ|¦reN=Lø¸<®p©®ð¼ãNÓàêt†ëÍv®]Ãѵk¸}ñì¥ XÛÜÂúx’á81òFz~[£ˆV”ܺç®ÓûŒŠå\°”%ˆCsÒÆuüm"`¼ŽÚaAX1$£P> Òlmè•7¢ðGŒƒ6Æ’‘™„ãÂXd+QN²6ªäa$÷š®@ã`Rù¬„?„²‚î5òGÙGd€:08ÉÑ6@–I1 ‘ÂMF$8Mb4åº4³9v÷ö±³»ƒý[·ã°(³¾S`ë#kC¦IU²’CŒÜ‘uªè}m(±þ]p”ÓAÙ]‹ø_lʆM風©¡K²‰}zŸ;vðd0YÛˆß÷«20Gq.ŠPp¦ˆÓÊ.l£1Aú”ÅÐ¥‘§ëôôÆÞèøPK[g¼‡wI2œ¶ Åý*Û=½Ÿ^³KmakÖàMvŒ§ÇcìhV =­{;8¸wûõW.craëk¨ê !µ *zdmÐ{÷Ùi©“à‚U ‡LÉrÌéúx½J<”²<À&´Çy1~±¦GBDן² ržg‰ükÏ úAƒ·e0H‰Ö3˜„[ ú¶-ƒêÜ2ÈzðœÚZNumëðdãW<1ªq¹®ñ|;­„Í 7›)î\»ŠÙµk8ºt õÅm¬mnb2™DîÕ&ô²ƒÀ–Á­ "¸*‘"ì!ÝLU 壇‹d|2=,“(+}åT„àș°Â*ÏÛå¼h„ú„ ãöÁø@edtoØV4L°µÛ #À&¤û½¬%Œ‘$Â+‰o…5jý!Ó`&Èf$è÷4 XîeÕB`ШD_ú´Ó9ö°{o»woÃ5M8äõ L=J}ÆÂˆâ`l9Í|½Ÿ)5½¯†šÅQ#iIqà 9á/w¶Rf Þ‘êŸfõ.– Ú :O‚`’#špðÈœ5VÉz'áÁQ€‚sÀµ…µŒ6sRp#ªŽ$j†Ø÷¯ÿánÔ¦õá@êB–j £yóÍzde=gëF™äœ(¯ D°Ú`£žàã vÚuÜhæx¥™âÎݻؿw»õ{W.a²½…µõuÔ£ Æ·à®ß‚sæ227H«aW¹ ª/ƘX ¡iy¡Ÿ1"! ÁMñR’@Œ^­ìËaa¯bA*ƒœjçZ6`éÉðzýCZ%¨$/Fß¾± ¿7 ªUƒŸx°7 %+ç•zé$û!îžQc躈]dÂ1€×bíâ6ÖÆÀ1±··{÷p´»Îcda66"©odLÒ^ˆ"M”î¡ÌøGí'H„Ëß“è]JQÈŒßЧmv£üp7‘ú9É b¹#ö³"),3ªÑ£Éä‘ý¿P:Å(8[)ˆÈ€&ë N}îIo_CûTH„©,-J)ÚÄ7ä?SË8Dîù¶ˆÓÖ4ª3ª/|YK°¢qP+k—£²„'íWFÞìÖp³™ãêt†›ó#Ü»zó«Wqxéê‹°¶ukO=‰é{˜ïÄëÁpáZPÚwl „Ø©£«¡’…aFèççP‰Sc ÇsGÖ~f5‰.,uHœË2J–Ô9 œ ^p-ÄtPÅ)°²\-×.R½zbú8­“*ìˆG‚,ûð¿xÇ#[ãÒ“±±¾Ýý`ô÷nÝAãçáZLÆ0ã1l5’ñ»ˆšü$ŽFü¾³Ë˜²KÁû0rèùP%²€‰µxI’Qç~„*÷"¥,V,èfô{W2lVî€ÞD0â2V•…äÞíî†0d OËXV³µàÕ~|¯V àl!–ÀÔÌ…MiLVÉ´ÈtOÕW“E¶úžRúÓƒ´·¹‘ÖhMǪæFF&¬%E’Y8l†SBa–Öã eó m¿IÀf²wgk¸ÖÎqÕÍqçî]Lwîao4†yòIÔ61YŸ ÝÛÇ|÷܈ _e‚ì­¥h¨Âˆ^Š)vbbO"xJH¡N¬ÃÆ †ÞÈ âHšÃr•œˆÏ„s¬ /›7³ÁˆÈ’ñÊÌx^ÁNNQúÝ"|;¹ Kül‡£ŒƸ¶ØÞÞÂx²Žy;Ë_û:ï܆#†© Ìxv4BUרÈJöƒ¥¶Ÿjö@rc'Ç[ ÞáKúûFi>ÝWÌ|[}œ4²Ç$ ì.ìø»HéêÜð§®—àÌq–‚XÛØÂ¨®“,ö#è8‰Á£4¯’ä« Å(8p]‡@ìÑ‚qáç剨åg¥C“OѰ â0Ýoø^ªUä]ÙqȆÈdëvÆæ…ÿ =ê)ÚFˆ0%Eߺ¯Pà鵞Æomn6aÁÍé;_ÿ:Ôà'/Ãll ^_ƒÛ?€Û݇ŸÏ@ãQ0*¬YXñbàI»˜aŒ ¬is ïƒ3`¥T`(\Pf/íbÝkÀ*•K‰Ðk FÈk‡±¹!ã॒M¨ŽB8¦ÈQÐÙÑħºwÔyG$ÝJ¬SãpÛÀ;‡µ ±¹µ…º®0kZÜzå%L÷wBT=¡®F0õu]¡ŽÛ”Sjpõ;'½GÐ9ÁSr¼G\DIˆY' &g4°þã^%Ó’±Zä÷Ž­VßCÆ#~ƒÞ[ÉöªóÀ©q¼½3]wëÕ‰“á±?z àL‘?¤ìOÂ"¨ÄÅîˆ1vМ4XäT£=P@–GOºyÈë8Ü(Æ’€*ÀéQG= ¤ÒC:E8”L>ŒÅ(´ÂÆ×et? \U¸PY<7žàN»Žë³9®º#ܾy3"´[[0ë°OMÐÎfðûûày®B ‹“™pF¯‡Tø½ôÒ³¸|C#4K  ‹é"hªÙ«¡‘È>sx”‘Î,¤ÅŒ±ž%æC^¶œjÛºýŒ“‘™ižd~”¤¨{{xׂÙ`}s “µuØÊâp>ÅÍÛ»h¦afÄÚºýµµRJ¤Ídì•‘~ÏÓïï5N{d™¸'u}`(!$Î@à¤û/f:dC&:;QæšäèˆDáJ÷«c{!¼º8(~±þÄA.ùuˆeÎBqŠPp¦Èÿ¨iTâ’©z™s ²ª$¼7iÉb©Ï“öš“.Ë]V|X;¯‘?å[£†@ä˜ìáÊ1íÊ™‘ʇ¶¤¾ýÃÉøÇgK7;ÆáMv„§G5ÞÚNpu6Ç+nŽÛ{{ØÛÝÃ|2ÝÜ„¹t®iÁÓ)p8 G\YÀYÞ©ùc¥]0\2ì[„(:ä¤ Y0;èÐ5*Qæ­gšåŒvQxáxhò^Ùø€ê.!!" O^ ¯¬#„¾hH‘9ìÀóf2ÆÚæÔã1˜€½é!¦{»ðÎj »±‰jê– v s<“¨‘ÜËŽC7 ÷ŽCJb–[Ûƒ[¯w=ÃtÛT‡Ð:2£/[€ø»&n){¢Gß@7Eùá‹SÙW“M&Ôõ„djó¶xŽ’°k‹íÑ:ÞìÖpg¾†Wg¸:=ÂÎô&f¨€í øõ5`} hæð‡GÀ¬ Òº–£§ÁÞ¨±Lþ‰ãdO9c’Iìb”t<)u‡m¤n£ÚÀɘ Zi}#UËÓá»ÈÊðžDèT t™ò®õ xØÑFW.‚¨B ‡½ý=ÌÀ ص1ªz£z‚ÊØØÑà=§VËìûŠQ>2rgçs9­³ $N¨4Bþ‹+Å©ÓY0ý’nÝÄNÕ{"¶f¥Õ¡0‘.À"N•_/­‰WÀƒ’êÑXîÉó™Xðx£8gu._„5a0YM³g³ÄF*ËrU6'Š~À‹IM!vhôӹݚ4<;³êB—éÄIÈp’ªÍÂ,u_•‡5b*${¬Zÿkx~2Á³“1öÚu\›Îñòü·vwpB3YC³6¹p!HæN§ð³Y8Ç‘ìE&Ä)O¤1]¥Ž «Qx”¨'JF\̳–b4õ™>}8¹½;v02tHÓÜ1Ÿ"r©Ñ-J£èC´_×XÛ©|6@3opx´ ?Ÿ‡c__G5¡®G¨%s¤ï$ï›'£ßybõç2e~Ô‘“ëcº™& sóûP.©–x@±“ÖÊȧÔK=ä÷¤É^3QФÈïÀ88€ð9Â색™\ºÐ¹? ÎÅ(8{Èׯ­ÁúÐÚ‚’ˆIŠ6¯#o |eü*i!§ÐŸ-îØR|ø‡¨­«Ø DQu§ÃÙJki‚ˆë°¡ è—}“å)K9j(ÇŒ’…,W¸R׸T×xK3ÁM×à•ƒ9®N°;= #4Û#øÉìÚ:x>ÏgÀ|ªF¡SBkrî‘›pH[ï¤q=íÔ9”Ø'åÉwÖ!û`ØH ;˜{ Ät·¦ö=4µ/ÜeàO[@µ>B½± TMË8lŽÐj˜­Mԣ毲’M$ŠÐQNâ‹Æ²,(kë*ùE^¿#£·BF M™ е à#e@³%H5ä|Ⱥroލ€*3ÊÊr\z#šhþ!Yèu0Ù܈¿œ5ŠPpæðòð²õ¼½&£_E°Èò­ óSCZ4‡9Q‰-tHÉCÙT܆¹&‹DS"5Eú¤ìk20ꤨW¾ìáyuœ>c=$²ârò@Ï= }¼kÊ OÀZeñæÚâ™Ñ;n ¯Lg¸:?ÂÝ}€1__×€ñÖ;`zwÔ†Ôµë¥ujïB½´‡G¨‹Òûl_H­ä3 À b8)qv„4˜Ú×ÒiFñ ùžCÕ€à[´-P[L67`FcÀÓy‹£Ý¸Ù¨ª&°ë›AäÆÚ,ñ Ùͬ$¡<ùÞ­"QÇiÈídnüéQä!0„èiT/‘ùtößtÙ%"SL{ñ…‘Fq’v&)$9ØŒl–u ¤äC™¥§¿Ór(5_˜r¢—C߬,Öë oZãn³‰ëÓ^ipG¸³5øÑpaã<=‚?˜ƒ1F“p¼„PÇv„žË8…NÓêšb—ãò>~1­\† 8n[P]a|aÕxƒi;ÃÑÁšÃ£`ôêìúvì±µLlä0Ž˜Œì#M44ÈL”IŒgœ–ˆn7FÞØi) _P,—D)èÌyˆçŒÞzHYŸ.G@êùà®!k0dÌ‚ì7‘Eì ©œ…§9‘,ãIƒ‹q’QÀ'Aq Î*YJ—/¢­-ÈyÓw,Ÿ¾AÃßdTo–òYk¤AnIÖWdsà«PS5áÍÀ؇ÈàÆT?Çýë„`çSF YNˆ3Âa¢Ä匘%ª›¦Nƹá´bXóÊHV˃§F„'Fž÷k¸5›ã•£nâÞá!æf„fc´¹‰jË€›ÚƒCøéLf¤S}¤öO&´ùÉʾ …!9VÛþ¤déLÈñƒ¼‡Ÿ7`õæêõu°­0÷wŽ0;:„kæÀhÆïŽFU5¬1ÕsöýšÄáP(êªjM_³C‰p‰¸hXcK`:=…ÏXÿ±;$ÿ‘¿Gq_þm¦âgY‚èÙ¥¬~OÜ!üÇ2[@‹RZ~âH`¢P1òÖ`mû‚¬_ŒÁÙ£8g嘵1‘Z#5¶’ßÕV×f$;æ4^3aþLäZJ†AŠa‚óÚŸ”îWEê¶kü™9|ÆoBJ^£OuL $:MñÅ>tÂÃ9J+¢‘N ~Šü’Á©#ÝZ68Ì3ð’‰ð lƒÍõu¼a2ÆÎ|¯Ìg¸6;ÄíÝî2š ø T—¯À0ཷOÆV ª†òþBIÃwÎAÛÕHZ•™CJ ¸Ù48Tõ“KWP¯Ñáp>ÃþÝ;hfÓpž“ÌÚ¬£ÕÁÙãPÛçÌq˯_¼.zi“M]¨ïyu¤ÎDFÌ–‰F¹gí£à: J4Ôë ?£3Dã¯âÅÑuŒÌý²5s$ïj—€Wß+u§hÛ¦J½ÜôÌ€÷- ã [íï¶àñCq Î:˜«€ ¡I,%¤ÞC@5øs¥¾Ð¯Zêá‘i Q¼& À„óÓfŽq‹´NÇdò°/ì¢)gÕ}ò’=Ðóâܬ„—ž)ô©kÎBSÐãC6èɆQ/NRDª¿`á̃Qᙵ ®Œk¼uc7fs\=˜âúÁv0«j¸í-ÐÆ&ê­-ÐÌÁî£9Ø Ç^AÆÀë°Ɉ„A}ÁÐsœ–Džáf3Àhû"F›@UcÖ6¸==ÂÑÞ|Û‚*­oÀÔ#ت‚µ6\7Vâ'bÈžtŠF/¥|yï…Þ½Ä)y¡™‹œü—£OüT½ÿ(‚DÙr|Zãç¸Ï¼µ1•|¢Ò÷ÊVñD¸#1բÂôœ³./Bt w*+è’(8 àÜ@[[@]ƒÕ÷³òƒñ—JS¡N#ç0ï>Nd# õ +OqUjÓ§zé á`ôÃ8”ô³Üxg9n á!¦Åº²ÖCb€ $ÂÈ —to,M¤“ô ‘:výì¡/,o˜á(c”‹m4`İ,1ö0ÆàlmTxn}‚{óÍØApûÎÐlmÁ¯oÀ\¹ŒµË—Á³CÌîíÂM@JbôÅ8 ß:€€j}믠^Ÿ °?=ÂÞí»hÃINÆ0kk°£ Œ±óÁ Ž*†A.˜ÉƒÔ£Ðm‘¤‰³,‰¨åå0"7"wbb ¾{e#¤Þ{-ÍÈWÔýNùвoŠW¥[Hã¥4ÒGÇèkô3zpÚI¡ß+ Y-ºOš)Ë hVÄ&[›ÿ·à±Aq ÎÊÀ“ ¨ ow$UŒ ÒóQØÞ°ÔQýób(m–CΞý™]u‹²}J—>Y9}éìµ=+-cHбg=éòšyþZöiûôô@¥U ,½ŠÜh-X˜d^ö­™€0"‹gÆWÆ#¼¥àƼÁ+G¸q°Ý½]Ì`Ñ>qfs ë[ÁÍîðó}øÙQ$÷‘dìÚê­ Œ×7@U…Ãù·wîazïn ë×ÖÖ`ë1l]£²6½§kcl"I*7‚£éŒ}ó†Ù/¼¯ JúÑèw‰”y^ÒË›&ABï.Ý¡[šÑcñ9/u@I’‘à—¦v„‡ò,€8ެ%¯¬D”;«PG7[?¦c4åªñãµµGôG\ð8 8gM§VvcÕ˜ií>ªGúvŠØblXJíóyÿ˶4¯ tÖÝø YÞW‹ýbM¢8NÌœ€<[À}ƒèX›~v:Ž2Ë“-§ï©d±OÇa´u1snÔô¨À'F%¤6/ôêêÏ'¸í·píà¯Ì§¸{ûnÝÆtsæâ%Œ.]ÄäÊÀ·hfMÐý¯,êªÙ ³Öaçp;7o 98—£®`Fk0£UUÁ ÿ¢{6!Ú¡á4z £Ú§¯>DýÉ ˆB?Z+ÏÃsJ—.ÿvû×X“ó11”ùz³—ö½n††²Lv¤z>wA²ïˆü]'L̾7BçKÓ£Ò¡™n c#7@ykM&±¶ à,Q€¢°qWlUÁ_܆™X7±.§¢!ÍK7ò`ŽÏ]¯¤;ŽÊt’sÓç< ÇŸ]ûMÝ×@r2_!¼• ¼¦}c2ž?DjåÂKH‹¥ ";V5j½δ/L7k´äI˜&%î}˜AP‘¶Ó‡Tþ¸²x#*5Ê1ú׋JÙ,dïÇ#H—R3¡ÌA]'‚{‰þe’;N÷C8˜˜Õˆ·x/E˜ÔaÊHéû$Óg À‡CBb€ñÖ&ªºîp ÎÅ(8?X ûä%´²h=Í”¦e8áhzUŸÌ$åä/qÀ:.Xã¬M° íDèL`‹¶;7ïÁºy}àK­6Ù ep¬Ýêd:ßq>ñk–ÀçªqÈúÉ!mjœœ”lo"]ÎÍB…Òq‘ƒ‡%àbUa»ªðæõuÜ™­ãêlŽ—§‡¸}ó6oÞÆÉíúŽÑ(?`m ²#غ†±¬ˆ“õ êz!æ6QSØÇ¡L$C)j{A79ýª •}M…»éÿìŠf[C¬ùk$­rź¼f¢ž€:¤2ÅYzB‘Pˆ®Á×3Šó'8¹$ÉᬘWõ@È'9NiMB/^‚Iç„âœ=òHå‰'@p¡¿­AR§íäp)èÄ 0½ï•„×ë!Kæ:ý0¢¶Çì¥Û]:šzq$TÍ-1½ ,ÆmŒØyâ\/‚5±€§¸åéê¨þÖÝï]ª´VH}{†±yZ×ñÈõ÷}ßÑaHV \7/†jL„7­¯á©µ ¾¡ÙÀÍf†W§¸6=ÄõémÖ€]›€ê Lma«†>8¥f½ñ& fë®W,¤õ!¢BÚT œ%•¾ÍóI|ÑïIßS'ú¸€ù7Û/Þ˜ì3].¦ÿï»eM'Õå~)k“ŒL€^¹H"~%/ÞŸ¥óÕÉ•ò=”¹öщ ÷®ÃÆ¥K©•¤ àP€‚ó^Y_G 8Nõ|d$>1úYæQ»a€ GÉÙ®BPl$&ÄkìÏÜq=­ÃFÃß›Ó Y^ ×÷÷FHjiz[ŠÞ(‚–:Ùÿ88F/@¬E  S¹IUƒèá#ËiŸ'δýÓúDˆú ÀI[ãåq…KãoÙÜÂŽaüöÛøô˜qo2†•ké¬1AŒ!êÖëWH&Öðó¨œä8Ër¨Ðé›EÜr™Uì'׆ˆLúüöʾ]ÓÝDÇ)HS£_¯U¬ÝßwóRÆ×ë¨þg ܃aW™é¡,=é‰9¹Û\à Ä2t:EÄk—.õ®AAÁÙ¢¸—牮Cí¸Ž#\ÉÉÜyˆ¾|´(C›`ÀõtùÒ¥AŽU%Z<%#¬á±>ü“ \ò;»¼×[·Ï½wÙìjQ‚l«éPçµd KtkÛ&l'=Û“1÷mÄGÒgÇg²\6 ìr!S!*©1{0ÖGoØÜÄåµ1Öë‘l'DûqÖÒ`ßð})“$ª'ˆ OfÔÑ«•+W@/)çýÿ”k¼†œˆžHíyºLú½W÷gÎø%]Ò 8í'ÔéSM'܆Yö†ã¸§˜ ÈïiÎ#YÎóÏ(ß®œ‡Gdý«#§-q@‘ò4¡66ýœJ à| FéâE!݇‡_<ƒ”ÎÓ²A/…B¼ d4´Töˆdj Ä}Y]Z T4⑟•‚1™ƒR@¡5ã~Ìê¡~a°‹Ô${—mKG ‹ec9¯t‰²)wZ[Cf4½.¯s# M¯K9@Ž!vžP1ÉÀ£îÅ%„9 †€Æ;pëQñqƈ#g€‡w”ö ÙRÓõqž±²Ù•‰§J™P§÷ú ’XÒ^b$^em·ŒßyéÜUŒuÿü ’ßÎ^Æ,2ŠN™ÔŒe#M~Ã)o#fEÒA³hEx)„í •†† “õUÿÚ %Pp.ðêlmc Ã!ŠU”NÑëL“@2 ˆ, D^JJ1QtØ ³\ÓÒšn7žâ;£)c—ˆŒs€T·MÿóÒvh"ŽŒœï>¿£Œ-‚ƾ‹|}]6šaôÒÝù˜™pŒ^JòaZb.)¶gô_Æ༦Â1MHvF%pEÑ0ç½EòŸf&rÖ{µvÔ…)>ì£}îìÃ? ‹»™Ý¬\¥ˆ Ð?R½?»–zXzžÊÚÏ.Oºï8mGÝ?´¼¾K””µ…PEˆòe}~êÔe¦ø½ì›e ¡òTí2¿@Àx{3^ã‚‚ó@q Îq$ðÚ:x­†Ÿ+S?ôºKR9>ä•­Sò”û¥•aîE(FÔÔØ'#g|š˜ÓÄòÐU'ƒCV5 …Ñ4¶]™O'? H&Öƒéel«l# ý;d4“û:פ_–讣*ñº–ÏÄRŠfR kh¨L%6’f¶ºD99}”ÒÚ¹^PµMÊ÷†4FÌH¢Ðÿ®_¤hÞ›ä×Hë[XÁa÷›Dœ ‡ÎÙµIç­Áv^«ïÒG»uÿøÝ¨nC˜ë¶;‚Tñ^ÍÜÁÌcH¾[ú®©,Z®úHî‡(ÓŸ)|NÚÌAÙõÎIܦg ª°¾y!í» àP€‚sA¬¢no YyC£õ8S=¸ê:€8Eb1k´Þ­a®‘%Õ¯ÏiÓ}h2! pÁ‘0ÙêÈ_f'úûÿõâ¸Ðf;mßËMQf6%Òθëy1@M#^õ2hÚ˜•Ñ™£¡‰ÆÒ§­ª#…ÅÐèeÈ®‡É½Öu“2`»Hr@ÉÎè-ãêü ÍîdßwLiиoRhÊÄäFž¬×w½•zUŠ>ýÄ ã}h‰*²8~/š)àì»Ð,~ÊeÇïCy%:±^6Íxõ®M¼>¶ÂÆÖ: ÎÅ(8hêÔ^¸Œ¶ÎнDY¢õ·04F¦óHÔê(ÔYÚéBæ_±ª ¤±«‘mOÔ7gýçde-+FÕR7… ‰`cù6ˆ÷ç†G£õž¢|ØW–_&JѹFƄٽú¸ãÌ|„~Ƶš4ú.–2$‰yáZ ñ/Hv†R1@$„¿”™PR!Ȧ뫜 JÎ:gžÊ‘5Ïyi%H*“çEê®Ï7+• cÇ;Ù‚x¿ey€IËJ”q#”OˆŸ× z’w4ÂW"jVß§ìdt~£°å¢8g%ñ¬%­ùC(u`RA£«ƒ×ÿþ»y§ìÑû®ºßG÷“¬Â€üò†Ë•JÕ+ùSËùý—+¢B ˆYEÇR *ò3|Æ_‘,DµÑ+‚º÷‘w@CÀÚövº Î¥  à\Aëkh‰Ac1¦°±ßœ¢w%„‰½Aþãv%íŸ}¤GÃà@FËŵxB}:…öLÊÀOýÿ¡k¶ê̈ND÷QœÕÃûVú¥[Ñwnñ9Ÿ'«©±…V6(OÔÎ?¤·\Î?#iRs‡×zµžGÐ/0œJ-¡~Åâ±¶ çgº}ÿªŽ§´þ8Àé8“k§¥¾*C–Ú_¹d:t¿Ü]6.¡×¸ç t‡¥å,¥ÒT8FåtÈ·-Ri;Ò–‡$œÿU.‚cÙ"}W¤¢²y΀ô»¢$5­NŽg‘‡'ƒÉ…‹çø—YPP2ç £ åy’7‘´û”šíGÿùO•~E–VhŠ>ž—¦5ZC DCP "vÈg,)î˜z–4³{ÿñ±Ô1î¯0¨QWú6ÊðB¯úV¹¨:.Qè'3Œ>ó|ò¬‡–‚/Æéô8}ÿú/’6ã—¦++Ũçä@æ“Õ'‡€“ÆCG\‡âBÉuäNº>'Y_Ýwì,èì<¶úè- –ïHK4êc²Ôs 8L[Ìî«‚‚³Fq ÎÑT¬¯kc˜Fzæ3“¤ªv) ¤˜¾fO1±o|÷«Ó™¡1éõÏ —÷ÔJĽr–ªÍRÊ”’Èy @‡>„¤„·ø÷˜v¦DlTBXœÇigêT¨áÑ?ÎC‰qßéP#“§!´^Í隦z½nR²ZÆ`–Ãw’—X‘{Û€ØTq°rí½žY D§Ü‘_S=¾˜5 äHhä­ß¿Q)m(2þóÌ™´~ºÊ©t‚< ¯Äàn'GvÍò–Ž? s»W"^Ò}N¤3·U…z2BAÁy¢8ç‚8¾t267a:ÉÄψs‚á–A3yJ½hº› Ž­U@JÝ’¡Ž¡ÒÖ³¨Ÿ‘Ñ:Ùå'èqr:öN»š®«©è˜9@2TÙï‘øÙà¦(…Œü'Q¯EhzðÔY!^¿˜*ç` If¤ésa%’ÈÖeÇ'÷ÉÍ0 3Þ$ Å6Äôª# Ÿ:R”ÀywÏ9ÿÓë~ï{4ô¹““eâ¦èLeDç+äqO_¥))ÖÏËŒ¬öÜï°d±–O%›cž©cëSڄȤ¡WÞîM0! 2 ¸à¼Pó<Àµ°.Àæý÷j I •q)¤+“?Ž™ÕH”©»À#퀆)¦Ó£l«X¶i‡œ‚ŶµþL÷èP°TøE®7wRú9€ñ¢ë–h³@ŠiyNƒ‘á;ZC—có X wU:ÙIFyˆå¹ä5Š5ÑHÐ%XJª[ë÷~@‡ü&ÙÊ®—´¶wŒ^äw s†Ä›Š<î^Ã~äßÍ|t¯s¿æ—!¦Cíi’¦Žc¡ßQî„¦ÑÆ”œ xôrýô¾C×é‰#ƒåêK!J•RŽ"Òm¥öN"ŠóÖ·/`4wîÑ‚‚³Fq ÎÖÂlmƒZyÀjtËp´”ò:Ö`ÁñÕš¿á!óŒW¬÷ë“;ê¯ ó›4ýͱ·Ýd©ùÎp–ÎÐÝSß{Y*;œ{ +sœç¾MzO.FÌNP:?½T C*î“Eò ÐqƈҾއj8i `v`1²Î~áL1¤­½ì/éãÂI¬‡{WE3‘ü@1‚<€Nrå¾ëÕÏÄØ|¼ ‘“ÑFãúý¥$`8 eµò°µ`p‰),¢ÜÂ{IË{/Æ<&+²H2¯gçsè»õèò$ÐæX?Wâû—itº‚§|KÎIXÄþ«¥@„fµéŒÎ%ŠÃzI PÙÅò€n_ùI±0§ÈÏRí}»Õ¡ÜŸÈOŸåbFÈ£õtoE.@–Õˆw¿€Ü÷†FÝé t¿*½»G™/—;{ÜYU?ý$t Üï8°´‚*Ä“yÉ… ï© àè§;©K¸ëÞžú Ò|ônä"pïuz«su¶Ùk5ÔL ekèw¡÷6Qò<(óBòt¾–=Ø$GŽâ-%¥NwÀÎcíÒåÎßPAÁy 8çu˜aÆ“`@HgÖ ¡\Yd&D§&jý‡G¯ÑI€6üŒ¥ÐÂ&ÖÜ€¢®4’FÙØ­³>l)ÏÙ€Y$nÙdѦR÷TÍÍwN‹<§‡·CÇPÅM‰ôi]T£+ŠÇQÙ0’ÀŒ>##g9›„GÝȵS­™ø~¼° ‹ÐE`A¨ÔûÞi­›Ó*!K"S#m.ËmÄRÃ0Ë9™ÙnÔš–úvòoC6Nç1Ä}R—!oeº â ä4(ÿ0¥áSÂ_Ó7”Œ´¦vœy39-)S¥©ý|¾ßP¥¢ø]²×r–L¬|÷€e†×Iý¿8ç‰âœâ •í-PÍwå^ÁÚ¢ö(ì"5U'¿»<Kqe¬¿‚ƒä­ü²`5Kÿ‹²<ˆ|Le¨Bœæ‘{çäÞ„ÁCj7´nVÏR¼”ÿ IËà…º õgÖýºxlùuòš†Ö´E~>¸?«ÐIiSÆ%,‡ÎŠœ>½.Ä¢Ö({Õš?ç¢1ï‰êè÷aôH$íÀ)êÊjç…ž\(I·ê³s£ zDæt~Ù7šÂ(EØœéaFJñ‘Û½ôd‡48Iô¯s`<@΄ù:´F ¯Ì0C’:|ðBbâBŽÏdµ{¤Ø3÷´îŽŒ°t6‘ô‰àe'ÆdÙŽXOÏ·”!2ãÕc Ž—J§ŒvðZ¢±ïqÂ[œ©è„}¨Ã}¬ÿ˜ÜÈÒþ”~v±„“2 ò=¦À^£qöUÐ({ú=þQÍ^ŽQ~bö+Y"ž/u\‹¨5 Õ˜9É”•¼.¹‰ *‹Í‹:ß]AÁy 8çíM´c nô:'›9ùsNûÚ´æÌYš\KÚ!`ÆšdÔ<#iºsÆN×Â~^ÓeŒ¿› ^¬÷*»Ì†ýÔ)9Öè}2d¶¤ 5]ߤã¶Ñ@†bæ ]v\œ†ýP÷´Ò¹ô2!÷W9ÆXÆÈ¤€;Ň—H“ £ṲóÐ(?) Žâì WÞƒ¦št[žRÔßcôJøãtè½  u 6ëe@ÁC@q Îjx×7К"¹˜ Q)Q®}¯ëBŒ½Ž»U>äÁÏaL¯'ÕhNk±ò/Öüd|Mfüä)NÒ¦iôꤔv¬Ý²1|Ù_OîhtHÊŸ%Š×,‚dÔ²:JC‘bÆ &<²¼Ö¤%ô×lA4xÒÉ@±îA©wßgåBLÏÇk®¬~Ù¿ê0¨£2x =A<£dÙ¹kŠÓ÷ÓkïS;h:¿g´A5ô™Ö){ôÎ'µ®ÏqQM‹P¦i—/ò}+Ñ0^•²0ùP#Õž W!f,2Ç ' rìBHµbÂZ\ðPtNˆÒ’sÈÑ^¸€¦²€÷`c` ÁkîœM }dJà=…}d÷‡¾é89(JÚ¥¬.-#¦õÑ/ k(ƒ dbs{@0>’µXŽ©ÐœiµØ,¢SëºÔyà”/ÎZö¢ buëP˜˜ªŽYdb6yn /!\+"›düÎ-–^܄积µgõ­Ò1äÜ „7’ã2㊤ؙ7$ærì×ϳÌÝõô(læBt]¨t"½ZH.×,Ç-DRŠ“ӽǽôE,9díÚV¯‘H§s§xÀ¹à|®mmH «)Ïœ‚sCÉœ4ºp –Âj?¾Òç3]‡kÏ¡# ÖQ¡X ]}•°FˆzÚy`å±ëÉ$ƒ`”3à¥{ S…Òš¼2ù«©¬FíÒO¯)p9þ"öÅpwá LTòÓ¼¶æEúÑcþG›ÞȈ<¯Ö• Õ^èä¡9c?„ ÇÜIä‰C’ùUék•´w¦Ò®“FÍYÄÜëˆöUN‡úO X[ƒJ]£J|ˆ¨¡ÀÙñ¥S ßI'e]Óì²ä%ÔÊG‘_ Ÿ›ÌC‰‚ÕZ2ÐùÈ31ÝoZÏœ8@(­X"8k°¶}çâœ;h} d L˜ã+HÚœ¼AFwžËý:vþÓ$œ¾§SãâzÑ¥ð`vð2û]Õú‚Z dzàû›‡Ü)goDdÚŒ5îDu°ÏdOÞ€í…\Ñh 2mêg=¼(7jBš)kïãܘQÖÔ@i¹S!™mÏ û¥d¬S­!EÂñòQVO×€®Ã];˜m‹}×F’^]'ËhÒB} ýViloþƒ³6ʼ¡ƒµÄÑ‘6Î÷Ÿ®igødX.FTýãÔ˜g :‰/ï‘LG f[$ƒ0ÞÚì^¨‚‚s@)œ´GAhë £LóßdÄ?Ï&ç܉"šü.ÿ‰-wYt«Ës44ù²úP6Z8Ï(àÁ±Hà]ólÔ-ºÃ‰ò× ÄʹºËH0Ôû#»¸Ôñ Òi  c¤™»YiO4†¤Û$LN$Nɀ磒‘ÿì‡2X6˪‹Œ!ö^Ž…¢ô/è`0êµ1ê*dÅLÉœ#ŠPp~‡ a/\91FùS½G¤ÊÇÞÆhîþˆ*&Áù&ºê}a6»ú(í:ò~-<¬cõIsâéptÄr¦¸6ÁàhxË2À(m‚“òžfÐsa¬ÞÍ™1ŠÑnŒSeŠaÖ¦G"—ëÍŒÁ惋tû: —ë¥ÉuùuËHo@G¬'¯ÚPþ^æÛdYðÎ÷›·Ûu¥¿Rz½¿‘n·u ²^–G6ˆÊŒº|÷v£žSèˆér‰äH‘éoAÇ"»^ª ™J,DXÆÚæÆkë((8o”@ÁùÃZÐW`؇Ø)¹ ƒÆ¸›@î"OùæsÚ’MAòQûãg8IDÇ¡I§CÈR y¤é³×=N‚ú”-C±Ð.¢Î.»ÀH½š2iàîIsfŒrŸ)¦Ã‘ JTþ‹çyÿõìgtË*€Î]ªá‡¨›ã¾uÛùõ»¿¿{¼zÍi”p~­Y2&¹ÒcäKHê ú|¨çg%ݹú[ÔÝqLS¤ ½úÏ}mŠèÝ1ʧT H‰—îµ[‘ô!$„ï4]3i7õŒñåK¨Gu÷Ü Î%Pp~ȤÕd Ö˜,¥É÷N«t•‰Æ#Ó’—õâïyš¡Îhï+ ' Û1ZRû ?¥×NBÖ¼µ- Ç–x ]É[íõæèŒt3×.¥œ£ƒ#  ’f‘ûv]UÓþÐø“_c"†‹á|=Çè>‘÷¸{m³ï«SváxI:ýüú¹þî³!JQ+(;Mï›.9ŒU.G+Î$Ë„=6ßg>9‡9NÔ3ÑñÐhÎ…@“Kþÿ·÷našWy໾]}RõI’-a»m°±Ô°qšS°ÝZC¬`c30ã`,›C°!áÅ&A;¶i‚I î„p°dÙ&äÑE&óÌ43Oæ¦}1sãNf.ˆ¬®k.ÖñÛU-«$Uõ¡Ö«§ÔUõïïoï×^§w½ <úZDï$?êd²iT¯ñ XÒÀ< aµviGÇÕôÔèÑâšx›£G“;Õà'äLÖX#N-EŒFS¤¼©…q¾ÂgJ$™ 2Å(©²“s*#Qp:F"ý¥¬W]†„¥óM'R;ŒHš4ûUd€« fUA¹?ìP´$?NNh”ar¹ ·!fG3Åløí8„™ÓD8pèPú¬+þ/쪰MÔäöàLüãÇAXlìf #Ò¿ Þ–`FüéÉY`LÔ•¡oýd“¾Á¢TBGÃDÉzz–Ln7Èc1†DòÖRëzL2®œ©NRû'"ôÆJò"øO>XIdç€h º+èi ^…vº¾ßþ—/w"ä`Þ®QfÚËy!µ>ÂOŒy›·ƒÅö<ØAÿl\67µdŒ³–õñEhÓÚ€”Aàôƒ®£åu'§c¡ äݹcÀj+D¤Å“÷•ÿº¿w “¤ÎJû%ŒÝqOz7ÂÂbMûG–…â³&u/VŒ›ŽßGÚÞç p¶mz²É`[É;—²´Ò…]{›Ö¯ý}ºVÒxÜ. zÊdD,<€c“ešŠ0K¶¼)‹oŒ¾G~…ÁIyIx(}ø…,™—¾¸\)yd+ÌÆz³`‘ %5Doéù8í(IQ~Íõ Æ2Á0k ícàX×,»ÁÉyóŸ™i¡õ\Ø”PØYØøø1ôk‰Ô&_™<׆‚5-vcjÖßÃr &Ç;QÇŒ†n¤Aʃp“Oß[V€hÒ‡~óú¬÷h·0ôjÆd4°­[‡ Ü’Aéw6 Þ‰Þoè\17}´åN߉ìû3(ì-œ9Os|?ºV«ï3šR[ æÛÊÞÏëñ„‰Ì_KSæ¿w^”š“ûâÎPC)"’'é^±•dµ>5ìZ[èˆ Kv<ìgÿ×Í¢wŽT¼- z&²,Ä‚†¶ÂìHšóÅí[ÃÁ›Ö‡¿Ba§P@aWÐŽÇj­—»ÈæÂ2€å{~ÎF*p÷!K@Ô5› Â?D]ˆnÊ ˜“õÈU‰B9‰®uÙ0Ý"ÂÌÜ08‰qÖÈ~Ž8§m 0ܨwo©Ó“í© ÚîRp›2œj×HâAäµ~NEo€àîFG”.FM4KüàšY$œÖwyò”¼¡\ï†Õ$Ø3A‘±ý ŸQÚ‡½ÞÓ ÉVº‚²SÆ ob#š‘·ÏLN'ÎØûð¶”ý¥p62)r¸?×€¶wtÍT­¿ù‰ý‘ ÛD9……EØ7ß,gÕg×P¸±qrszLJëkþ˜ÎœeŒ A­&y‰Uÿ˜Úh](GÉR»Ù]á K²öM",Ф£‰§0{f,ò×öuéPè"Ô“÷Cj=¡M£d¯—<$'çÉ™y1¦zÈGcûuÌA±sv6|ÊXÛ&§Ú¾' RÀºÂX³_·8Z’öq(š’ÊêÓÎ’5ÍÙ Ïè°æ rý Ýc™œge…ˆüËL‚®;ÚAüúøg†ø}1žzT˜ÜtsA22­wô 8tä …Ý@9…]Ø'ÃsšTŸE•Ož~sŠ‹:1f¯‡Kt'µ}}ðzèÛ•·mßdz¹ëÞ9±åzDjnOSË‘¤5³°Õã:s–úE ϲ`aûg½|É"DÁL¤š#’¬C둤lP0òìÛ¨µ«¹1ÇÇIsGy€ÂPY¢ÅÙ„[Ré"ÂÕ, zŒËåt*VÞ0Ú*9 `;vÞ!6™³ß”ÖO!…W1ý3F”|4n8~7ÎA0gbà&$A¦œâ>¸)Ù‡‚;éVÌ<Û¦ƒ1ÏR ¸éÈz|>…¢€ÂÎBbÓ‘£ØX³‘Àñ›©ÓèÔ´ÛOGëúÛenà„¦OÕÃ}HRÿMCÊÉ"Zj7YÏžu¤Hz ¡[Ê›%žöhØÖ`ÿ2Fƒ`çà š˜ _¬äº¢4Æ #îÉ~á€T'~ñž´˜žVæ= ’»—BžÓðš|?xF"©¥ú¶ÕÉsÚÞØô.³`ÖÔ9’Õi £¦WwˆÔ—mcÄoivýiiô7åÏÙ# vŽóÈÛûµNmÍœÁÄÏÈDÈÎî¢y}ßt†”~ÚçRzx -¤R„óR †tP¾ƒ7ùÕ(våvëëÀÚ>`ƒU±®aîM5î˜4r›!΀«´e°Ù8Ô¹E@¸M3®ýoo8Yöpfµž‘¾fžÅAAÔsã=ˆ'8t}³Þšjž<[9@=EÕ‰*gß5&On°: ÁL±¥þŠºqr çcÑxˆÞéb“³Ï)8п6Rã¼Û@ΔéþŠžïøyY¦Àjì™à×Ámä褙º ûIkAöãÁ/Aޱƒ:”ßä©‚¤µ"¢.8þáo±ÏAÑÇoŽXëþéD¼Ár:v8î·BaQ@ag‘&bßZ¤5JwRI/ö ‰ê󳯤,˜•”oí‹ÀSØÿ}`©ujJ>D<÷É W_Hݦ¹Åžð·ÂZÌé=4Ö|¥#@_›äÜ<õëi|q„r´MÐnˆ™UPäüh4r›Ðe¿M+òƪ4‰ô¬ÿÜvØ’êÏRVwËc¤£™K[¬Ð~g6Ð qÞ—}4VÁÉïµO'.°ð9üýþ2d)¬c¼‡–jþF Übý” |&¦5¸“Üü‹¸a‚¡ëØy1ÚÚ>ìKJ€…ÂN¢€ÂÎÂ~­GÖAÍ„ìT|Çÿ'ò½ìß#Eû²½¼6y)Àžû]•vÚPÝDzÔÅ#µŸIZ6¯.Eùö•Ha^ÓåØ¿ ¬µü´O³Çî¢ÀçöC ±”Èß¿4¦Î€7³¦;6•¹¡O]·Ž†X'Áè3Z'⤎çÇS$¥ç-²Î$Á>Ð÷¢;À² cO)*·ûÆ2ìîX>ÿÌp +’OÀœÖ8èÈ,¤4"3⟻gì>¡¡üàŽâå¶?w³#ibKæséUÚÓM8¨“kpa§Q@aWÐöï?†iÕÑ(+ï™!5 Þô&Ý®±Pڜ͞21‹IÉdÂfÃ|Ôp­iZ~ŠÈV~3·d„G‡Ài÷ûÇÍ¡`m ‚ ™0ô ^w–õ7ŸLç¿D®ëš8è Y GJð: Š$»1ÉÆ\"]=ׇ7‡€ŒvaÂ?°}{Z<ñº^_ã ¤dyäÂ6z&(Æ'AŸ\šÉoõû&Ê$ñ‘g§*—[|}ÆñOŸu°÷Ç+¥(zªï÷tÞý’oôä$¸€ò=Öôú‹=HœucuÙuê·hߊžðüŽü­(q,›1óx<³Èd‘µDÿF3 (˼a´jè¬îîKåËQ´’•hD°æ ¢IzòÍȳ©óq4 *‡’³6oJýgÿ¼‚Ù nš˜¶iùu¿4â`Y™ [Cl¶d \2"†&Ùr;blÛ4ý\|ò’3ÍΨS÷%ëQ!!{?sÆÏ„ÃIàÜ™\GJòÆÌ8pø0ÖöíC¡°( °³ÈQÕ­OÇD“:õ^ü–Rð”aM3önùý¬¯€ºX"ù9Y³ñ³I[I§önå!s݉"ž²º›|ƒ,G.@“ S` {^¤¦ToVc“¹ I„(JÉcœ9ê<"eOÃ[MÛ„dד(I†ÌÒÛ°ˆ˜|Ñ`0s)ÞŒavNÌØÃbtÒµõRÍÂ`NoγH³ÙQñóG"Rð2Æ}$qŸ´ÂN‚Jña—#¶¶ŒÁ•È€ƒù—,‰:7Ô;;Š6¥¶’BaQ@açaõÎiBã5̪:7]Ž´>ÞÂØSêË)y4)' õkò,‰Oˆ£ÑôµMýºO»ÂctJiœp3ä[9™œ-ŒÞ2×’Ï%ûá”yö¼Ûüø]ÔÛcïÎSðÏþyçÚ~ÓWJd4AÏj¿CÇEÙ (ÏHÁÏ2~¢tn1ÞÙ§ü¸Ô°z¥«X€Â£€ÂÎ⥛bjš }Žš„(yðêüz@Œ®Y„$í‘HÅlOäã%}P[T®$³k$A‹x“!òе`_!‡Ñ™ÇšZO…s ¤Íœ YëðºsîVÖ.a‡u,¦8£++Pdv­– q¼Œ<ôBÆ#È™¸‰sq#9dK€l©s]ɸêy5]KfÌé¼é·“#PKƒx0÷0P~îð©8+PúûY-¯K§º6÷¼êd”|xÖ!_¦p¸²°ÿrˆþó{x‹¯¨Ýóp}í²»OeøÌÈœû×.oWÇÅÆ.ûñôc%"þcÇø‰næ,ÏÀèÔ¾®%rþJ°–™™Ì;a0ú,^éº*våv&BÓŽÁjÀ«LZX4·p4¤ûå¥ 7MãÛÌ.ÃDª¨¸éC}RKêáôÅ.–P }ƒqŽ¡=0Ž¦È˜óK¶`ëÊØ'È(`;ž­±ÁCüf)rõ}©""ï—cx•€CáÏSÕƒn=Æn7¶qñØ2I×>#œ†ô±-¾²ˆ(?Ÿ¦ï+á–û12m›·ä‰U’¼HÃìÎDz£à+äNËêD aëó’는c¿!å“`†ž|»¼¥Ìc˜A8x4º …F9…]¿—×&˜(J·ž} ÈUY±Ž"ºmÆð >=h9¢?¤ùª›&é±Ä‰XuVí€1¥l¤,ÙMŠÞ¯;†ÂSòúX·¾ó_åd¬ ÀÖÖߥxc aíLÖz—4ûYH€¤²syâ]Øs‹ÞÓµÉFÞ"â,«uôîNLprËŸívièíÀ¯–Æ<í£®Å’Æ}tBr Ä%t9>{Zì°kùcÒFÏ1…Q·hÞ¦JŽF?î ³ÎY”Ì1²iäלH}­wɆT`Õÿ »r ;{˜­MXÍ]»Ô"Ïk#søƒº7{“¦å¸„°ò¬)Úò¬óM"Ã`Ï„µT«×Å·y¹€vÐøšëda™Í¯KÀécz H€æÀ0Àœ f3ë@ X÷Ô(dœ¥žM±®˜Â¸€|çZrié:×Ñ©…>²_~y}rê=¶%‹×2G`I<\ÂÓû„ÁÀ:1)«x9]ïó ÒN(=p ?K·˜s–Þí[IJîÑ9"wJ̈11Fó>¸Ô33>ò˜×¥Px*Q@a×ÐÖ×ÁûÖRÚÙ"o‰Ò™“R_m"kÑÕ4> ©/äÖÃÀe öÑ(† 4õÛIMº']ý`×oÕf‘`NÍ ãL͇e”ýß3!U‘ÏÚÚ:«ŽÂð+©€!j†,ò‡.Il7zZ`¯ÉÚõÈdä¹GÊö3Ââ²¢ÂÝŒ-K)c¾T¾Ë‡­ZÜ®ïr>.ù9™ÎûÞj.7]ºóL ÍXAÙüŽ&ÃdU#"V-}¹ÕQËî`&•¿%Ø8¼œª–(—Ð9‰Ìq ݵû­A “ÓrônClÄ©àÜ“ñYüű ts>B÷DýߺÆ¡9ð³^WK’Gä%VŽFu$ÚÅUlƒó‘™‰oc´½‰»-0âM¼ ]É’øXÙ…ì,ؽdÙ ¤ýȹÇ×ð"%§¢%g#G蛎š h¡Œ,Lr6]Ýü:Ëxlö;Š7Ý´éÚ ;…r »‡iÂô´ãÀJhSc€# |#½ÌF×5tt-4}€“ÿ ¤èÏæ°íµ¹”p¤ m[é—·ßOÔGb „6¦¤=Òê/€&Â2bdHä<éRÎ`x™_kÍšržÄ2q—o‡* Çzòz‘ކ:øæD,küÎ]HFÌjÖy½][>@›÷3œ{îêÀfƒ>8 ÈÙ ;&ÛÆãÙûÚÛd¢¦Ø yKJÖ=NŸCÞ§ü~”>îi œöÕÕˆqÌãyU'f4>еšXØE”PØyäv»cÇÑ.ÏÀ%…5ö03!¤xtZÏÌPWÛ¯¶eF´?zð Üœõ¤èÇn9gˤ§3S–Í™ˆègϵ_" El@~?éëf¡ˆÀm©Í„S1“‰üDÆ>U0'"êÜ¿øì…õ¬ägŽnê9Vë^Zw,²ÊÑȃ~2oÀëÞ©,°Õ¿¹>¾ü9×ÝÇ÷Œ1²}¶´H‹D©']ò¼/#Ú…ÈŽ]Ç8”2­ÒÓû<: ~?ws¸àÛÛr÷pšHîƒÇƒZ=’ »‡ºÛ » ÇŽC›Ò€ –Ô¶7ˆ‘>"I{Ý@ð¡,,µxâ†am°ŽuI:U_k¤c‚mS6?7U6#Ø•uÂ>·¶¤Æ’†lHŒ ®[ÔIR£ÔXÓÎR×§.=JR=r%&’º‘; –†Yç¤÷¹ ¡¼ öîØ»Ÿ%7KÇíZ'Ì: ¡ŸMåfúMz8U,D8YJ°âÑ)°úø¦í6 9g)<ÒN<„Ñ%£P“4§hiœ)ŽÕ-£’S’Ï'%=6-ÔÉ€)ô§ô¯S7”ÈÉ£?âûm~ߊcÿáÃhÍîתÿvåvjl§µ†¶ 9¬ì°úPÖˆ»þ®kË\²Då.¤V)ý uÅ(GŒ–²í)236g!û—tuD¾¾eäɹmç“óËÎÈ#7&Ok/õ¦+l)Ï0Û5Ó/âMá¨]—a¹àÙqi<¹®sÏRê0½z´ 2šþÀ8öÖ8‚(-'_­t:þ}ð#Æ”ÿ²Ç¤Ä'$e'0 —£…]¨ˆ­t1fe\˜ÝßQ9`¿~‹z ?Ø~þšŸ»É7ôT¶aŽÍuÊ3÷XÒš=K ÿI↛×$ÀÂ®À"~:rDÙøúkò Œé{IW]6Ð=$E<üÇÚ²·DlãæQ±L”ÉnÁÝ&͛ӒZîh:ᯩcbÛ(ñ°‡¥\&¤s’p“-nüpKg²àdÆE[ì57ª}4Xœ/¥z ?]¹Ð•-3ÂCä=è"ºÔýRD¼ÙØÚˆKºŒiíxKR i4ŸN›2éä 9A™¢Gé:ä¹BÙAq?ͪ@ƒ Žl•y#öY»Š´•*6¥ü“ó¸½Ìm*êtàС¸.…Â. €ÂîÀ2GŽSƒIüv°ó OGM0ëƒÛ„VrDh„±œ:·š¸3õõA.¼5­×z×é†3b™ödQ¿š3¼*ëYd-Œç¼é mµ8èž¹-ú¦zì¼HQôV:F´. Và%€èuCî5µ¢£K/#À gpŒðhŒŸB˜kíùBxTž¢~)Âf£H©Ó#fÐ[ÚÇ Æç·Ÿ•@ôgUßók§†Û3êØ1ýs¶¬A£{s™Y&;"xÖe=”?ô›ƒ‡ëÏåvåvµ=ŠÕÁ5ô™•H×’}´(טü9¶·ªsÀxÀd·\ 6°·ÐYx05ïh$F¬1aîñ´îžÿ¨±oØú/ˆHôþ‘ÒìV7Ý"5^¡Ñ¿›g1rMf˜”¯1ø™͈â“ßÎÕs% å!:ÚJÈÚ9á­…“¯ÇOÁ Ï@0r a4Ô=CÊ5x §ŒÇ”¾}LË?/²5¦ò?\DY_wƒšË ™¼ØàÓÿÈ2>‹ô¿“ý®a„AÊeŸtûÚ¹².®s8*Ýx X–ÔQ Âá›o‰Å »€r »OÑ^G_khútìÝv"•ÈË3/¢ó¨Á[q ƒ)±XÙþV|°ÖøV>0£&¿·‘ÁäëtŽËä@1rLÒpŽ˜¤'®«íÖ¥ZÔÜ=ÒeP·¢3bPŠ ™ƒ,hÇE'`Ž(™#¿ŒyNiç9 •_c•¦[’ÿK0ƒlC‰ ]‰CÁ WMHrÄ9Áàm~_1-9féúÅ  ÄÏÈ?FÕvåYöb<Š­qÔ)°K’Ðê¦ÏÈ·Ím Ëk¥BO­€i~SìC³Ù be?ÚïõAåpø–cOæO¬PØ6Ê(ì |$ð±›±ÑÚøÐ·±½ú}'`råÀÑ1ú&Øþb L¤ í¦#Zi!!²G®ÝÀæé¶qO;÷t¿ĨµomÓ¤7 ^ŸN‘¬FßN£g–:<±Œ æ04ÜÄAÔèÔI¡I2Ík÷q,¿§¸zñ²µ¾õjÉJºj±ëµôtÚ›ª&î Df¦«wb]nYN8gp<òNõýÌóˆà{³H݃²bÊ…c2¼ŒfÒÄçÙóuôÅq —ÓgšÿñÞ¾Iøi±½;Ö£PØM”PØU´cG°15ðJL@'‘æ]YZ Ŭq`tù‹¥µ$ªôQ‹Y`êCÝÙ”øÄêt7FÐruØRôÝÉ»hx‹`OðÏ=Í”t`³‘Û,c·ÊÔ!‘»2ð½Nï›°ï—4ul|é#3- NòcÚÏýèfD»¾'ÅçúmoòÆæpâÿñfÃkÎ¥_$~!:§ˆ<]g¾âèP\! žÉ[ÌkÜÔ!à÷KJÿë) È–’'ÝÖëJ¼ôqZy$åMÒQå:Û1»f~úâ^é,Ž‚qJ¸°[( °;°hðÈ:Vj`¨wPO´ë\¿m„®¿—Àמ¤ ¹ùϪÁþ ¶P΃`|(çiÉTD~v b-ÓÖ¶Ã\3^†ÁC[]~O³è~¹ÓÅÏM¶µÉ~–VÈU=¥½ø+¦„EïìN„Ôß³doXîàÖ^ܧ-ÏsÁtÏ/1ϯñ(Gœ×iC~¬ ÔKiØÏP bë´ŒeÄOÊFÏ)e¨Í ÈŸU>Msҽ鎡½7ÉöwÚ|ÏÙ{E"&KÚz3‡ŽE¡°›( °« Ú¦xš¾k]4©Ïà,{3¦+«c“H£wÍÄiÄM„ňê2Xû]*š‹ã ’ÀF×FS#›#KB·¨ÙÆðö]Qcè÷§¸>Y³P¼÷È¡š ˜S#^ÊnÌ _ Ùwíbí|Èí‘rµéwNù‡¨`D=;qìµe”šÛ%ÝÏãQ²àb,s”JÂËpiåEÄÛV—;ªæÜûc܃)»b×–¥û>óÌPoæäcÑÈí°ë7h Ä(f+©ˆ#ù$À*ìÊ(ì œ4½~|h?lä¯<ˆmÀÏØî'%sé·Ÿ!F#ÍÍPCÆyÈ­–\&X“ö>ýo0úžø·§úþÌj´ÔX5u0z2] «WÈ;ó’±ÔÒ†‘ùœe®ëè¤ „¦ë´ˆÙ³ ¨±—¨ƒ‰èŽŒ†ÉjÚ™@è9ýfÇ3[œ´žÏÚý¢L±™8„r†œºT‡oË!;Qñ ‚b)=ŸjæD–€|C;(FÅŽ™‡8æëæËé|iuVÈRQpÓÚì˜4: Kß·:R¦`œD÷A¼'>÷ì`Œ·Q0fý|ÖÂÁ#Âh•(ìÊ(ì*hÿ~ì¿õf™yOZûUQa;}jv˜{¨æ˜]¿ÜÀÛh_k©39áüàÖìËÀ ¢øí -‘Á&ì‹#¬ºÕ‰‚ùÝ™@SHôvؘ_ tv%6¸_ŒQC6Gê9mƦ§wÆ(þ3>fÙÍA ¯»{¹!8d¶ŒŠîÃ¥æ ×*SaY®H_é³ÍŸ`ì‡ýÿñûK×Á>]Ë4䚺 3åècKÃ’ ¾}¶Áéë‹VÈ+Û ãÚYVdnBôë÷)aMà7×(àÂ®¢Mpä0¦FšÆ@¤Ä´¥„jjÓ'¬¥ågH&ÀŸô©öm¡e娹 ~@0Ò·ê]÷ð”Ø×1«ñ—ï¿1xÞ\'öÒ@XСkhò:½×ÍMj˜i¨Yç2ÀVit«7‡AS~Cr|,pW=ƒDÖ!Û6„4o§¸®fÃÒ–‘s|žVîI×aì—ÇÏÝ ž1¬cÎëó©#ýÎŒ³~ïe¢Áð/á¯%Ä }ç ºÎ“Yu¿S[2äY=?n:¼Ž}ûö¡PØM”PØä©k·ÜÞè I¢íÀ†šŸÇapåMòeìé,B©›Hœ²l ]vbzºÇ‘ðt7À®%Ô›dì8®H·/™!­}©ogÜ|ÿf¥ÓÚf€gÉT†ñäù}wà1²— iù-jó´p`,Š÷Ù¾ÉÉbD—€ý.¸ì²Åˆ4ýè ‘J]‘Éüò’¸Ç4lÑ™7wdÀ2!´ÜÌ!éØÜÉÑë¸<¾Ž¸Ý"•ŸNÖ?;ï ˜u»Y \,Jù3<‘—>‚išP(ì&Ö®ö®7C÷I@w»ù8hC ¯Zê’hCNCšÖëÔ™ è$Â8.nãN@4ÅuË20ÜØiìF™ET(Ûx[3CæÏA’£&–|ÒQ®ºµ‰ÖØC~V½ÿÔ(Ú° 4å@=03Ë` 6ׄ²ÍÞ”ª6ʃð,«âNNS5:ó"Z\OÒ«Â$’È!UkivNéïl·¸V)_Í!Hžq-à×!šú½ÛåÒçE54Œp,,ŸE {KF»9²sK©›s ÙÚ9Çêý?ÿ¨§k/¼³ôÁqñÖåT¿-›4Rm¢¹Ö{o ¡§ì€Ä.lrH!³fTfõ´¼˜2IöŠ»|o÷¤O·¸-›"ÄÑý5 ¸pP%€ÂîÁ€ãG0¯5Œì7>úäÁK:: ˜z´¥¹hŸGˆ‘®¶Hxf–vAÓ_Æ´‚™Ì0V]……0Ǭõ5v.€í#8,â=SÛmá2e^w?«Îâ2˜mGÅSÇèhÜœ,Ç®¤Æ×¼ HçAãPúóÔ¿§®mÝìFŽý|ÉE‚Äš X´ en6Äñ»8Þæ6OÖÈžB]n—Ë*CFh¸ø¾œQ‡ ýÞ™¼ϘÄÕ"i²)‡’ÇÉ"÷–:1…I%ž>o¡w€p¦BÓ5:|äsþù O5*PØuLÇŽcÞ·†ÕÜU±/‘Мä18M'2\³¿3{{h³T°µØ‘eÎɘCà$.ô-ûŠ ƒÑ.˜™çæ@È4¿æÆnÒ%͈á7º©¬6#L÷À^o 'Û½¦¯/xþÚ8ìbndz=úóñÈÆØ}ZŠÝYþV¿n¤2Åñkë °n¨¹ƒñ‡+9QC¸U÷|; 9KÚÏ3ö°Õnu~ ^£ÉV^â¸þÑ´É›C°U2ßÖhÙ- áØÍ7/?¬BaÇQ@a×AÇŽb5Ix,bºÖ¨j·‘«ä2´]ëÔ+}@zËUwêVD‹Ý°Zëïìz»±Æ˜ÀéXnÔ!¤<+çB9ðÜ»D‡Ù¨ºÃ!ÎÌÜ{ÈËv¢Xp8„Pôô»eEf¯È˜Þä(õ¹mé-W±*”õ¤HÜOƒ‹®€X#÷Á²^‰”‹‹âxÖždÁt¼ÄûCZÇ`œã#ôëåë”jþ_K§ì¥ ;çž½©ä0FÎ:XnSÇF’ "åÉÏÈÜ>éDèvœœg—¢e"Ïr°:Fœ²2ÃõMù~›É`,øÜ¡™£vÏ °7¤ì§k•3KKŸ² ´9ºc)¼y—±N›{¡t T=XîN›MÒ=CyŽ€æZ¼öBƒ“’ë7a;»—ȧ$ɺ̸Œ]4d äè †ƒGj`a÷QÀ6Q=ºOS»µ£‡Ñ§–êÃò ojágfh`0"žRÖùŠ$¥nQß ü¦ˆôwªó7‰Ò&–cn ÔoÙþ84ò»FßÖMnýÿ*ÿJ$šÙˆâÁ÷–5#/Ú±!#c£ã@ÉŒH± Ô„†ÆÚ’ØX9Hû\FÊ*¯lq÷p7'_Ä¢ãÞs6Â~¦äh±§³ýÈC^ž<»c¤@âQóÑ¢gäk€øìM±O®×8÷Á÷Avt3æäÓ¹‹®(^2>%’—"By’Hø79""I­Õ3¦°k¨@a×àÝ„ÕÚä²¹wfé®cÂÊž 7.€¦¶SùÀöÛI¾´[omjôL…Z Ãd]H½_Œ­ž–ÒÅÉøûƒ`Ĉt°cÙž¢¾ F×H†NÁ@·ñ#èãœÉ#r+ €D#À÷™¢Hã Pφ3œ zÉÉòÈFò‹Âà ƒyˆ}6ÿÀjÙ)+-å…4%ÇyH3°·0RJjL†Ý¢ÜNGCvÀ³é¸F> V~ÊhøyÚ ä~ÍÀ¡ôš½]\ÛÿBÔ§gÇOÛ"MFÚJLÖaÁã% å¨j+'™£&œ÷ZÇTL3pÓ±#8¨J€…Ân¢€Â®ÁŸ£­¡=š´–"}"̈ô®Õà¹Ç4?ϨšМ«ùed¬m{ç¼,ܹÈÑå2‚ï,ëšm†„ˆ¸{êð7j=^¢Cï¢@€FéçYþ0­]°/¾· yøëå!˜u;KzܘñD¢jÈiÛLÄ#Ì›Š õGW@´WFk§mc›]jEŒ`¼7€aYÇô lžy«(„=+Ox‹d:Hr`ÌA3 ЏU|êAâ9,´*ŒøhŽŒ;šOj¡‹Ða¤Î>œ¯189жV|ìÂ®!§7§õu©ÅÏj„[Œží©­Šs]wØ€Šqª½RÜ,›`Lr‚ •é¹[þ†D,sD À`i-2&&t–¡?¦BhxIó›ðP"šK`þJw±Ý´…$$Á{‰mâaD™³߃^g¯E6"jÒ–™°ìGÏџω Ài0¯R ~d¶Nï/Çî²ghÌYJœä€4)8M“umæxØù œ„”)`òîN| ¿Í2²^á˜$.Cn5°²ŸC;:ÏÁ¥èjì;ImEÿåtE'"‘WÕ:tô˜tÈ,þF …F9…]…M;£[oÆ4#‘ñ,Jƒ¸Rbkq5k± É.Œ¤ŒÑµ¥\>"žƒÈÌé!»Êö"÷|ƒá½‚óâ¯ÆFèºM£0pÖuàýù­yúa¶÷ÈÓ2O!ä@sLÞx‚Ú_ß.ZÝÜSC4×$Róèc )ÙëD<7”›SþœŠ0°ù‘ //ö*Ίœ”¢®îë[|Y"}-¼À 'jͽkÇ2vÝFùãh¿ô×Ó™Ÿ#:€A2¦ÑX$‚]‡A~rF,³eÁêÿ5¨°Û( °»0"àÑu0äÁÜ{DW$f³wƪGÄOSsF»«äMÚ&cÖE=º'ãe‘i¤®{l§%i=óƒÉCº3KiÀØázr>V#vEÎ8õ§wèù2XòŽNºŽY¢ÈLYœA¯#+HûšÖ@ü5‰„Ù™TN׈7¥æUl ·¨AIyQ“3%vnƒ¶VIsÉôØM³3Ê]Èm…–b·ÅÀ#àø}î<ˆ½[Žó™Ä24½/Ç9¸ ¦M÷ë_ÜökÒЛ¥ù5ëÓÔÉ›Øëþ2»!²D6P9>™îÎìMGË(\”PØUØ ·vàúÁ51™ôPý‘‡¸ømZÿoŒ>›\/¥41E+a‹yï¦ if1Ζ¢Þ$q«émëk÷ß“ ê1b[I@ÿµˆ|P„±1Î7)ÉqCO­„@qk.î#û²ýŒ° H´­‰ÝÜU‘܈-ÊûÍ<§fF3Íã\;Ôn¬æÎé<Ù[òF u„¼ËBåŒýº/HùèN4rÅa!/J29ómñ´$§ßrWB Þs¹KÂÎ$g+üšP÷û…5º·ÏÐZ0­c%œGV’`畦JX?ztÓ=Y(ìÊ(ì*¼Gûèqô}°š10sÇŒŽYIu<'~}“‡ª0óõÍ-ͤSãuÁÚá4Ê#OÍ*á´]ÐÓÄÂRÍiÍK£ó êÓ(F¾n#¢uDS›ü¿kû_sö¸%…-›`ä@ß™ •)Öt߯FEÀ&wû2üyö ãƒ=×ÎÞvÇÉhb0¼cbßþµnJ/¸To* ä 8ÕüEiIç!Ž‘õùÃóˆÔƒ•6:àY˜Y¿BLP6Òžekô32Òbä•âó&)#õt˜¢ûƒíšyé! •²¤Œe;ô£d#6`ý–[Òu-vå® ¦[árkƵ°®2µ+Hß{WugR«±[‘±ÜÃð¤–wX?;[:Ù„`Ü€ŽsíÓ8w˜¥ÒÏ©5m< RÌæ˜Eâä†ÑbdSý3ûÿåçDX4­ýI¦š±¢à˜!°X #G'CVÜ3FDä1ìsz×€ÍéB¬o`u4!éÀƒ¡'tž‡2¨$’²YdBVÊà498»£“DF@• ê(à¢ÿvÕ{RØUØDÀ}ÇoÆå©Ik]—hˆ4»ÚjÌÄ:—‡’q#(£ÑU#غÐÆ–& †))·M°Ô¦íåö:‹Z­vurj„•÷ð‹¡˜†u‹›’‰o!xÓœ5hƒ…B€NŒg8'uÂíªa“Bžõ ­D`Ì{£‰Š âDVˆÈUºÂÀ"âzDâÚ~-s®¶Çl“œIÉ,7x×Dמ>gœ>R¢]B‘s*@³Ýõô àÄF¤).l£šÇ!Oöf»/ìºw wŠ,fÖî¸ócKõy¾SÖ{#â®™×ׇû·PØ-T °«0°vè.3«ê¦²Ñ ¥öARãs¤¦Eí/ÇwúàÖ–+é$ÖÁ4ÐZ¹FÇ͟ϲ®€ñê,Ãà³æÝEn=ãÄè¦x2[6]LG6úê:´†lfGØp8c¿é.³C“9û‘·mT¿mȉ1R¼zi¨ |Ê 6¥Á–L\¿¸ô{µÑYôXI’ùi‘:ùqIkìÎm€È)›(“è¦ Í£~£Ú…±¶’eU’5)è¤ydœƒæÎˆ]Okõì]LŠÓù‘¬õϯAâ’Í ÜtìØpÿ »…r » ËБuôIFèα¢†h0ê½KëVïÚöÇùw~œ‡ÀàL(óÛH€¢Ý)ù®å\#v¨v€ÊšÜ®?ÈSyÈÙ€pG܉xüQJ02c¢¥)9MÛy1x9¿>Ö+o¿Ëu~Ë/ÌdJwš± (/Þå±?YAE¯"!ÖÜ=—k1$Ìý=æYg4R×Òå¡LZ…÷÷@©ëO)ságˆ;b+dÖ‰¬ûS‚{Dáîä°ÿº~ÙF™‘oŸOW‚‰{ë2‰·Yj?œá{»÷¬$¡Î¸é¾ØÐ’.\-”PØU؃{ßá#˜÷í“6³‰”DÕ]Çßêõ6\g5³O|3C—uV°!B¹Õ*bRgÁˆh@ ›#û¨qoÒy°"!Ífì9NDÞjÖ7ˆ‡cì.D4Y»l;KAyQ¼Oz8ÖÒ=¾]Ö³ A€ MþøÃöHZ_˜ÃÔë²)4 hhñ˸aÄûóãB¹Ô%Ð4;Ò`úþ²/‹ÒgåvPr.8‰ì:h Æ2¬wÖs1¤%¼{ Æ´›oö¦Mâ! “Y‘¤ÿs™A¸ÌúG š­6KäÓC ˆã¡¯2Â3cÕ£L$IÛ•3$ÀMâš!°×ó|ù™g]Ðï-e¹a¸iòÞÁÐ ûDaxܨʎݸ©%sÆ9# ­í­A~t_f;º¦Ü…W§“ -­nµl?Ø–4Ý^^œãL,UOìöŸ"ùlÇwŽ9™qB´S’»/IFÉÈçˆýÎ>;…BKë;ÔØçë`û]fŒ„¯é=k¥X 2P¶¯®™.8|ä0ÖÕÃW  °»( °«°‡ôÚþýX;~ èb”gU×››ŒŽŠ:a£[ÔO© Xu¨î¿ìÙˆw<‹hЬs\….=_»q×oÏa4Òî³tŒñ¬FÇæôöXC'ÆÜ°¬’}wrQä÷–ÖÑu M‡ñ‚Ç1VPÌŠ²Ô„î¨ÏX\ëd쬞oˆÀ¨øgŽQ¢2rªv jôö›\‰öÌPüg£î—yà^dŽƒu6˜ÔBÏŸÊÒd©@3ÒÑA F¿1rÍ>]gô/køËû5FC$â#Ì wÂŒ~dqd€¸.’õª$Êpðø18tpÿâ …+£Ú » rZÃô´§ÌØ BkMTðÔX¯ÐfiÇk Ì]Ý– 5õhÄG]gÐCˆt}fùY3ÄÒ‡Þ°¼woòóJ¾lÕ;Ü”df#¤V›'–ù/z~&ƒ›rÆ@ðZ¡¬*huøž6ñ6:‹,F7¥ jh-óÞ×]ëýjø2ÕÏ•ÝS€ËýZjÝ¢¢è`;_îau­yNoìaøÇ»"ç:DÝQ‚ñƒùëðóH»ˆÌ‰­µ þA´ï±qØÓö™S`›Ü-áŒÝ¼X%¥ “@6ç‚HîI¹d ôÁÇ1MÓSøV(<~”PØuØÃpß¡Cà5Ñ -ÑÛ~MƒÝ¦Ñ©×™YÔó‰X”ðL„Åì3Ì1Èdq{­9=ÕU÷Fˆ`acg’á.&|£Ñ'wv‰a›H jž­zg5ÊRìòÞ¨)û"ËPÝìµÉ{-FÎDCIâmâ-ÀÎ%®»wBÚù`4r”¢uKZø ð¢v1@fõIÒ¶y¨R^k8;阾\µ/&†aõ}YÙ€‚ÃÁÝ䣽ÇQÿ»(¢!?jõ€rHì˜i6A”òE ’itO„Raî¢'‘„"£´øàðÍ7;/¦J…ÝF9ÛDý‘>yø¬ø#G´nL˜y–H}¨¨¶K5]~ÒòŠ•N¥sr-‚³©y¤Ñ¾Õë-PÝÀ‰ÈPë¢Zµ`¥ƒxšf º®Ãüªbg5d@)-Ï0r¢hõ¯˜1Q0ÂsQª:;‹×%E/ß5ò8_K’VhPb[ªêÑÂø›³d4¥úw¤Ám[u&t¨Q£žãƒ“ê¹Æñ^éÓ'÷²3àÒ:D:œÇV™K <¬ß;š.l6@Ìà”á #vhùÇ'— œñ¯¿¶ÝÄXh¶IÊ’gÂø#ƒ1­á¦õ£*ÜÝ(v åvú„ßwëÍ"í«é~ë{Ÿˆ"„EÚä©Ý¦}ì6zuê"r#ÑxÞ,?™0q:Ö/h{`&°×§Ù­aæØͺUÄ$iæÈˆÓÒ³S@ÑBhÙ€<;ß@Þ¨åÍ|X]м¾áåqX„+@yçþž¸ì–ñ`&´QëÇÇû.Œ$Èaô@ég3çvÍœcàrQð–9ržF9±1’}œÏÂôkÑ ¨uw¸aµ²EâFÚ½`mˆ„˜C°LõGV ~Ï©ƒƒüœ|–‚÷ÑýØ1¶Ú>k{þñɳ¡1pÓÍ5¨põP@a÷¡»·Ü‚yß~UT“^qš%™=™`PÚ½ªÇÊô:ýÛÔ€wwßš´Z˜Û´} ¬%%;y_î6Â-O{zœg¡°Ë( pÕpàÖ[ñèDظ¼Rr£©ÍÌ³èø“DÛ+X÷´°ñ{ƒ+ô„©èäµó5#ÔuÑŠ'VÔ}ÐMëä-ÞÙ8š‘˜º’ÈìmQ¬¤¼æÜº?ÎÝð¹saÙË6(SŸš•#”0È¿{šÀÍKf98Ð5ñ,,÷¨Gë›ì¼ºÿ©ó¦Ãˆ#Ï ˜³(³ÑEmI–È–2'¬Þ*…Qº²œì Ë'[l½ŒèsVÁ…saÇ^†þ9E§Ù/ŒÚŽóûìÛtM8¯%ýìe€”ñÒ Æ54žÇÓžñy;ú7V(<Ê(ì>ôa½ÿ¶§ã’¦t¢×{ÍÌ]ÒÕ+0¦uÚ‰dˆÌxLj€;¨6@ Ýfˆ õX3úÀ'¾ìgÖ‡ûdiqÛ®E½›“H¹lQ3ƒç”ö®vn€9 ]Ú”uãU¿Ÿs^›Â!i$h¢f?+Ç@öä- J‚ ÔUCÞ£2Òà‰Æ?¢øM1ªZÍLìIwÙàêg™ú8(("Z/‚‚äçoí=‘‘÷΄}6Áη_ó¸­9 © ’ƒ¾p 㾈ôsˆY~‰Y„¨fî8b“‹[T¸ ( °ûЇÝúí·cÕ$Ïkkbœ x”kŒZ”em4eîÌÉd‹A—cê’o¬ íV6ºÆØæ‘f&%³ú䵿T<‘Ð×-í¯á¾%š: “JöfAD³Üb²àXõ–Åñ1ÇÒ–rçÁ>pôXÚÓv#•‡þ˜$oÎÈE‹€ßŽ“ |dái±"ßC\;AÛ÷FÖ0ý‡Ž#ѱ•ô÷z®˜1sÇÜ»n5£÷ŽÞ;æY¨­<ÏX;v ?ö«¿Šg=÷¹’«€ÂU@Ýu…«‹Fÿú¿_öÀ¯â¿ÞíØ×W˜›Œñ½¬FuE„ &ÌDX©ŸY­}’y®¢×¤WfÑYŸ!“™!Dcý}Ê,ÜvÈ<&ÀFÎÍ&-Üæúñ³þåÝ ;8XáVëÎñö‹\‰ƒ ûéÆ8#9—0\%z¯}—sXAÆ#Ú÷õ¯Ðý³„á¾>‹ºM^ÈÙ‰ø¯YF%Þ•3ùšŽ“˜ÉyK©]ãZ˜Á÷ŠžsïéyýU7ÃOÙè ñ‚É ¸­ƒ5’×νÞ;Vb½.çËá¬ÉDÀîê‰3Ë}å“9M aÅDÊm㥯y-þùƒÅé×¾Æ9*…ÂÕ@• W–’ff|É«ÿžõÕ_…ÿøÞ‹ÿöOÀ-sÃgI Ú>m¹ë˜Ð´Ö ÜѾ÷%Ø“ÄÕ““ëH¤W»Pìò>kX¹–†Ž‘½L„I ²óùˆµ±jJ&œåFšÍ3茕2á&vÉ‚-ï‘pÊÁaP¤†§–£eéFð¾tw”iožŵî,WŠ:| Žl ¿"áGrÊlN„O†Ô ©Ãð´ÏÁüäOáë^ùJÀjµÂÚZ=‚ W•(\5JÏ«n>v ¯ùÉwáÿý¿ÁÆK¿ „µ•èù¯fÆ3VÜ%­ ɬ¨IV3IDÖ!3z×öÀ&üLªÛoQ#ë€HTâ5–>WE>2=1WÝêñ¬£mcžšd"º¤w¹3¸÷MÚò+-XÖb ÕÙ†:ªV¥â¡C½ÿ¼›aÍö¨‘ÊÄÆt­ìZ §è:X£aÏH¯…ñï¾®(^GûK Ûi‡ßb[Äuö,Å(Þ“Ë ñ%ù†a2A&ÍÂ$G¡swö>ŸÀÆ€f04Ÿ%I‰6¨c&-S±•qÄAè'cÕ&ÜõÖ·â}}_÷ÊWzI Œáj£îÀm¢ÒuO=Ööí“hªw¼àÅ/Æ ~ÿ#øÓ÷}ÿëÏÿŽÿ×ÿ`&’,€Gô@ëŒI ÚÄ Œžtšvhk åL¢sb`²Á:О&#ê™N<]…Œ5N);\ˆÂhh]Iƒ=¥²­Í"pˆƒbÝnh•Ÿ[ÍÈÈd=Ëù” #fâ>”ƒ^‡Wq|¾9)ùQŽà“`^ƒLêk-Ûº ²·æXQ>¸Y»ß•RþÙf'¢âÀºK…§ö½ü~ÛB#ý‘ø'nŠk¨þDïäþrgƒš_/”„$°—ñÕ’êG¯3£Mh5£7Â_÷×ñÖŸøq¼èΓ*ê/\[¨ @áÚÚ4ažEDõ«ßüF|Ç'>Š£oþNüåì‡×„H2ÞwCëô+î’˜¡5Ù®D:úõáÞI#7MKψיdû•[&­ëêTAéqSÚYÃhá(_5émBœ±òÌ`z[€ Ë"hf€³áˆƒgiën–šÆ}YæC®¥V‚×MÇÀ"äÄ€¦ºF4ñ$æ.„¸»j£ï“’ÙÞÊðóâ_ľ"žm“x ­×ÆŸÝØ[ëhð.äÝT5¿RãÏZKèFôcšÜ©ÉðŸ®÷ ᯠ±T£}áer|þИ±þy·ãm÷ß_ýßÁ‹î<‰Õjf.ã_¸¦P@áš‚MF›W+<ýéOÇ™ŸûY¼ê÷|ê%˜XRV«5’.(ùJ˜3CÍúš¥÷Í0£¿bIóÏÊþŸ5Â7£±ÁŒ•·jú!Í+N@#Ì%‚y’¬…ÔÖ3®¥z3Œ0òŒ¯&JizKïÃùdÆ_ÕþzOÖ›K Èœ».©×-3û³KÀz®fðÈ'NBü×a©hàz ½ÁÄ—2Ò>/gòÛïüg[¿xEÑ©<§÷¥÷â(J)À>GA–òíiMÜIK8ÚE¢Ñ7GR¹½›óE*6%÷Õk¿ï{ñO~ßz÷ëfÌ󌵵µÊ®9”;Z¸&1­­¡+…ÿ…/})^øoÿ þô_|ÿË?øû¯ÿeÆjšîXë"0cµf† ¥™ 2ÀžÆVcÛ´Ø=ëƒ}Ò–€•ôÂȬ´¦ïïIå Fdï}÷ôt7a!ÆÜ¢^Û’·ò±Öý£'Ÿ±"™ŽÀ¬T¶ÉFÒvHM½ÉïI™…}&O¯›‹ß’¤.”`é"<®D˜I€iÂ]>¦¾fíqVϗበž"s’ }Ú±·î)_ί\Ve ¡½¦CŸÿhHY3:Ö]a< ÊÒ¼Fä³E4Y˜ íA·ñÊ‘¹1 àXaC»:—S›œïñÜ9îýéŸÆ—½ä%"Ý_ã~ ×**P¸fÑZËßõF|Ç'ÂÑ7}'þrjØ?Kñü2…ëYÓø3éÏÈ3ÙEˆÆ2]ÙðÝ !iJ®ÐUqo¶Ú½±Â!†hC³+WØñ,Êt²aSr"ft%ØSTÜ#zGS# £Þá£oYSÒ!rÀ:¨¨“®³Q 9Ð݉N‚•̈ÃYx‘`w Ìøwó¥ÜaÕ‡ÔáhÇÓRâ,µœK1Sƒxú@T´VK¤ë¥‚˜2è¤D–óÎBJFØ›;ƒ5ôguØVˆrÈøÕ•ôg™Ó{žqðÖ[ñý?óü‹?ø|ÙK^‚yž‹äW¸.P@ášG. Üþô§ã›áàUÿî_cúê—ö çN$ºßPÿŠ«.%ÞHKʘeá¬5]¶Ò@Û9ƒµ“€±`¥Öä Rʳj x;‚äg΀“Fè­9«žgÙÚ¬pWa™ Ë"´¨”{ ?å´àe~¨QÔ¿p¿›EˆR„›ÓúrÌa²÷ZEKØž"Íž9|.È£YïçÖ‚q­×Â²Èø½n(?@#ÿÐè~ì¾(^týÜz—ô£»Ch ‘»~Vƈ%&ân ¯¸ûoãCû{¾GîyÆ4M%ìS¸.P.jáºÁPøk /ü·¿‹G~ó,þÓÏü<Ö/þ7<Ê4MÚSo=òÚ9@bØz×Q»Ähl,{‰–'VѺLdˆÎ¾Õfd/e‘OÊ«ƒþžšÈ3ˆXÒî`O­S£`œ{*ZÞ?ua¥»¨•ôÜ¥!å fIoK}Þý7æÖ´Gnp-RVQCðô9tö}ä¯î$Z³\±ÅÉŽ§ûÜ2‚§ø Ô8ËZr±$öéÿRþ©oÞQàçH‘æ2¡¬Þ4k ?Õx uü¼Y'F"u(X¦Gn’™65°f£žóe_Š·¼ó]øÊ¯ýZù|V+LÓTéþÂu…rS ׆²3Nýí»ñŸ|Çßüxt­aŸFñŸU­€™ºË›ðÜ´ @ÑKD(†¦é5r»ÌP‰ÿ Ÿ‘ _ÒófŒf pVã¥Ý‚ŽÖ<ï2h¬Jtì|kÿs£Gr]=!’jaV°d¾Ê“Gµ³±Þ-CÀaB%ÅR@€ ʉ8áNëö¿®6:€ˆþõÆž7)]ëp"&‘´)š0“e7Lð‡Ð©%øE)Ræ7°çû6â!ô:̈k%}ÿA0´ì€´JÌØä0îù©ŸÄþèñ•_ûµCº¿H~…ë å®KLÓ$‘Ùj…§ßz+¾ùç~ßøïÓ×¾DRX‘L\cEÝ9f¸W&ê¢*{+M[_KÛ`°ÎP†?ÌŽ¥´²µÐŒ `’Æòå]|¢vÍ0t6Zˆy[^bÆÛ| ! ºQNŽ@*±§%îqû .Ü€NìÝd ¡%`éýx-‹ÿø¹-Kö}^ƒýžL¹ÏvÄé|ÜA{`ÜýœŒcÑSV$Š=9*M³â@RkNüÊ»îÂû?ñ ¼ñ-o‘Ï Òý…ëU(\×Èe|ÅWàù]üdz¿…ÿüžŸÃ‘OÿW|–€Ë$²ÀkÜÑ!Óÿ˜m  †‰ Ô4ùÛƒEo†ËRî¤åøP=üP·›-Ò×v= –Ly^: ‚`01 Nâ40¦.ùýÎMö7¥ÉyM†K·ÀFAÌžäàÞ«OÖ>¨ipÛ‡ ä‚C6­év´–ÎB··z=õ¨Ù/fG¿+G@J1ΘÙK¡Ü—H‘ði½R”p¢ }NÖûÏ~Ž)Ó¶gíq~C‹÷©>MhÕÁÄøü;îÀüøOàk^þ2•î/Ü8(×µpÝcYøª»_/eï{3>Ó€]˜ïRÃ̤éјu@ÐjÒí–f¼Õ ÎDw2ŸŠY×ÀLax|Øð"½Ý¡Ç€´š=Rï¿dæÖ17òÌ‚jËëZè$ R=ƒÞ8RÑfÀ}F/9‰pIºÓd€¿Ím.i{¡½âNŽ¿,¯°q#L)›Œ$Âdƒ=ÓÁAìÓE澋ܙµ´Ã±ž ¿¥ù1Š%IÉ@> çX–‡ÖùÈÜ;Úú!¼á¾wàƒ>ˆ¯yùË*Ý_¸áP@á†Á²,p×{~ßôàïƒ^öU ˆšàj"l˜Ñ0ƒ±¡{†Œò]uÇÛ´†ßEmÐE`š© ²×üóº®5jB£°e]¢bo¬bÍÎä;%‰IDATE$ѶÎH{Ù˜c›ÖÑ[Ǫ MêûÁŠŸ‘Än õnmó[iÙÀ•ëŒ~ÈÝ'Û9Y°m®†Ø£ßÄŽurkõcÀ§‹è;ý„Ñu¢ŸíSkþ¹üÒݰn v’¡ýÞZ"}t0ÅìãôäØ@>Æ—¨¡©&ÂK_ój¼ïãÃ=o{&u.+Ý_¸ÑPwsᆃ•ú<ãyõKñ]¿ûaÜqÿÏá/>ï6T£³AŒ5oÿ²1Á}"× è,?áoÅÀlýöƒÕI¿¬ Ã` F¦ƒ‡3vº|–Þe!*c¾'|žmcÆ*tøM@ítF™¤(ïûü»†éä¡:¼¬U´ƒ®md×GMÞþµHØZð¬lâ‘{nýóã'íü´Mî,ˆ6ÀX@¡·4ž×öŒåм?1¨®*‚Öi¯¯H ?i äi_ø|üý}¿ð¾÷áÄsO¸„o¥û 7"Ê(ÜX–¾ú;ïÆëÿÃÇð´·~/.í›°¿Ü— Xq(»ùLH‰ {¦I´fôYYô™x̪9‰ˆaÙKÓk½]  :*\>¯€ØzÐó$e‹®Ä6©«ìFB´&è÷Ï l°NT±!— ¦ ô±ê0TVx`÷“×ä]žX䥋ð]rß Œb¬c†‚Gþç¬WLYø–©è12™\ɑȤHÛKG€K8³M~4)hq“tÿ¡ƒø[ïíøàCá¯zÕ0±¯Òý…ånhä²À­7ߌ×üäã›úÐ˾ ``ßLà‰°Á*DÊ@´ ÎĘ­,`%klR7žÍ¸&åsìçäTtSÊ1V?¬ÛÀÚ5|5t” íªuÄÁö‡é(OÀÆá -Mãu>Í Xý^Íyk*ï»°{9ÊÏÿv ÷]Tˆ¢ö.$¿îò¹lƒ:̃“áÃtRqsni…îŠc´oCf6¾…½/eQº’5§¦‚G_þ_÷=üqüÀü:„Õj%d¥û 78ê/ì Lkk®V8qçxÓï~wþò/â/žý Шy55¬:yD?3°ê,£ˆ›Œ^107òi„sæ™U†W¶]±!‰ê-ò´”´GÂMîQép›x’>¬zQƒ—L„µåY`¢`íy<àãmÅ@Gê~b‡-Œ½Á#vûÙiä­ÔG3¼¬Þ³•LÒõHksN€^‹•u¨)7ÙfïÕ×ëk ’•0: ­‰| OÂè$föçã¾ÀýúMœxÞ‰šØWØs( °g@D˜ÖÖ¢[ào}Þð'áÖü>|fÿöÏ"ûûhkª 2ÀZÿï-Fò¥ó5}ß;\|¢ŸüFEg,2Õ÷m˜p§úGÃæésË" Œyò(·CF ÷5¨Q×ãš!õzºèõBýÎúø™Ã‘èêTD=¼%/룿sdÌ!U[ôcÛö¶‘ñRÉÃtˆŒ,©«÷”?| ß0dˆâûP$£l×P&öuàÀ¾õÞ·áC?ŒWÓ]•î/ìY”PØsÈeãGâ5ïz'¾éÁ?þ:pÖ@ØXkÒ-À+t1Â]ëþhrò|¥«žº HÚÔ,SÐ)"U.Æ#hH£ÝˆÕ¹™b©  M#ô=ÍH¿:wq\¡°!†æhgiÙÂ2 FŒ$úï-[ÖD꣜Jç¡VDJ0b¤nÙM~—RÄžG û©øÌ7þ©CÁ|l-–Ež› Ð`üÀªw€š—îxù+ðë>ˆ|Ç;pôèÑJ÷ö4ê®/ìY e;^„7~ø7ñe¿öËøì³Ÿƒ] ÷4a…†w‘ÖÒÀÜ¢[`ÕµUmRm€®-‚ÝHgÑ‹•¹Ì¯óH¾s4Ó³åõî»¶ÊÉ@C §­õo•¢jË0ÀöåBGAîËÓúm˜xPZ"õ½ú K²½V¶ðñ©»¡‹Ùî]®­µóA%›Ü×5[ÁêTA÷ǵþ0ü䎀 3¾ùY?ú?ÿ ~å·ÿ%^ðÅ_\éþBåö8–e¯øæoÂ>ñ>ïï¾—ìÇþÎXµŽ ¢nÂJ·(_¢P™ ا˜Ðaóã­/¼?»v[šÞZ%ÊíAðó~vö‰‡6„ˆ»:ÊÎG äMÞ¸'b fLÅ[¿¿‹ù䀮Átô=Íïø Aì3íþ<¢É™¦¦¼¿[ 8(žÆ72$áÏþ@0ýõwDŒ¹^ûýß|üãxÝ·}[¥û …„r Œe£GŽàU÷ýOø–ýÚ7¼ D ûX”û6¸cÅ"&´‚t¬HJ3¤¥p6MKñ3»ú ‹òPôô[Ë ° rt˜Ù¶A==9+ ¬mÚ 8È}ÂP' Y›"+Ïì4u,RdnëÒ„¥à±4bN„+ü%¶¿9­2MGGðE_óÕøµ?þ#¼ýïÿŽ;VéþBaúK(rYà9/|¾ó·>„¿ïŸâ/¿è¹ØÔ0O„•æ™:ºÊ ›œ›_ŠT¿EÅ>PˆÙf öAµžŠŸ]\(Wÿ#*f¨† ½{-€d­€dYqѲˆ4dHt›{û-­î£ƒ-#‘ËÆ^ç‚>fü™b‚9@šì§u~W dw4 ó˜:Þíøá_~/~íww~é—bžçJ÷ [ þ"¶‰JÞø "´ÖdÈ€—¼îµ¸ã•_Oþã‚ÿãÿ2žöÙ—¸S“9ñØ×Ú^6!z÷ _̘4-NM¾šÖ¶­ç~î‘zG‡a’¹¦ †°AÇ›¦>ÌnTeÿª3À-ûúd†“"ãÐS´ÏQÓ÷9®ÀÞï/u~KðC‡ˆÚ{ ä‰È~î]þ†89Fiž€õùÛ>™e΢•6|¿ ÔŠHhèx”€×¾ùÍxËþ(n½å€³¦û …ÂfT P¸,]<¯V8tð ^õ£?ŒoùØ£}ãËÑ[C›;z“:þg]HˆµK@x¥¦/mƒ*4Äò{¯s7)ˆ1VÆ¿ªåÙ`!«‡³Öì]ã>K¢ˆ•Ähü럷çEdŸ‡ú–)ÈÖ“ø© plýëAÄs™Þä,›¹Ñ·6Bß¿eÔi÷XŠ?eE Z "æ#Ü…çå)üÊïÿ>Þùÿ!n½å¬V+€¨$| …Ç@¹Æ…Â瀕ú<ã9/|žsöƒøß?úQüéOþìû¿þ‹©ár—| ,™xC52~˜e„mkzG'Bc`ÒÙÁ½KÊÞSãDš×4K>H;0±ö¸!7 ú¦'è8]mÍI§‚È«¬ JáŽ7äuÂbJÏ;‘1ÍÈC’àTÏ` þAõÂIq e;†µò©‡Ò;ƒZÇÁ§? ÷Ü÷|ÛÞ ï›gQEý…Âã@e …Çëè] é_òÊWâxøðì};þûý8 }þh}4'Þu¨ràš2Ù;ÐùtÁ#Zaìþ”-hð¾÷yat-š÷ß{_~(æ­Œ´§çâÒ¼Þ}@C Î9ì,æãÿªyNšÁM.›žzË{ôÏ©U’1i–`V½£7Â+ßø]øà'?o{Ä·Qû …m¡þR …m µhY`ÿþýø†þ!üÍO>ˆƒg¾“ì ÌBdÆ 33{É`¥½ñn쑤ƒmÈO××L>×úà Þà9m›µ•ˆøY¤pe^Á¬c†½[ …H¥û‘ÖãQ=GäϤÙ­MôÙ¢}-s$²cÄÐAC .èÃÖJêå‡ó!#Hõžó’㽿ÿoñÎ_üÜvÛmX­Vâ Uº¿PØÊ(žr·À³Ÿÿ|Üýþ_ÇË>üAÌw¼ @kÂê¿ –QÃ,#h{Kò¾š¢·!A6Epn!4w©ÿw&ç¬R?<`m|2C`Ö.@ ‰‚ÞlÓü,¾žØSúÖs? Ñ1‡#Iôº×óƒP‘yð¬"ãkK$§ÂÌÁŒ}·ÜŒï{÷»ñþ?üC¼äÔ)Ìóì=ý…Baû( Px‚X–î|Å+ðæÿ_ø®ÅgŽÆ~XW¬¨á236¨«D°8+Ré^Õ°>wW dvñ Þã÷0å;uLs€Y¢{ëéŸUÕ‡(XüÖo|î¬ Df!l»Ífô™\„GZÿHÇìj¢_÷3k:?glÂÌ]jý*å«WÕÉdˆÒ×çñÁÿð ¼áû¾*Ý_(<¨¿žBáIbYxÅÛ~¯ÿäCXÿö»Ð‰°Æš ÆdÐÐu™-ÀC‡\$(æÖÏ“FöÝý´, Ó»jX&`„V>K:}1Þ˜©ÐTˆG'åÁ"þœz7&*I˜{“VF’Ô¾ÍÝ›5@éwƒPqŒtÈ–m`ï~°¨ŸZS?ƒñù'ïÄ/}ä÷ð®ô‹xÆíÏp ßJ÷ Oå OrYà™Ïz¾ã×~/ûWgÑO¾ÄŒ55à`\†¤ýg5â& ´bvÉa›È~3¬³º¶vnTdhÖ>LyŠ~Å16§{"^:f‚§òìÇV®Ðcé¨@fU"Ô}ÎHâD û2Q£žr.2ÄúŒý·Ç›~òÇñ/>úQœúš¯Òý¥ÅQ(<5( Px ‘Ë}žqòå_‡ï~ðñüŸ~'>só쇪ýð(‘Ê w!ÿq êÐéƒ=~ Ž€1íÅàêÕè¹–Þžu² Á MiϘù]™þþ¾Š~>”¹v:€(I€Ñ¹©Àþ3B50úúM'AœFøš¿ùøçŸøÞôÖ¿ƒ5ÓPéþBá©GýE ;€ÖÚ4¡Ï3ÖÖÖðõ?ð|çŸ<ŒcwÿMlL ûYzø/7‰øgî˜[wÙߤ„>·úuÖô¿ŠˆñÃÅ·”r·×æèÉg_ì­uéßAb—¢>ÎΈ¶Br¡!Qì^0AçàHi¡é £ Sk1žqÇøÙÿ6þþ¯þ >ÿ™Ï¬t¡°Ã( PØA´iò²ÀíÏ|&¾õŸü#¼ò#Æüe_‚µ4&¬d¸7eðó0FØÈt2°š5}®f¸%3Àbì[z?¿`fÆÜm‚ž˜ð®“d5l(•d¶AF©là|Ö’Cd/,£ÁšîÇúMxÓO¼ üØCøÚ—¿¼Òý…Â.¡€Ba‡±, ¼èk¾ßóÑç¿ç]øì­Ç°ßˆ|°ÑDxNÞ:ædÐggìkFiä0´c`J­“À&õQÇA³L£À*Îßu`¼À`%Cɘ†yfˆ€l Úm0[O?„Kðå¯{-Þ¯éþiš*Ý_(ì"꯬PØ%ä²@k /{Ë÷ãõÿñã¸õ{Þˆ¿˜€5Ôy”:.¸¬­‚sS¶¿jtó;³pÜè’ ý¨ PgŸèc„!N‚q <ÅßSJ?éðw˜ñ–ò„µ 3û !¦ZmÖ‘@ j*sÜñÌ;ïÀ{þåYüÂûÞ‡/ø‚/¨t¡pP ÛD¥$ Oy¶Àí·ÝŽoúùŸÅùöoÆ'îû LÿùzÑ ™U]P"ö‰H†îXZªÂÛõ_àC$Ó•›'_'aÒl@“ž='é±Ïé_â4ð$ã U€Ñ4¾oÑòG¦!˜$†Yº¤—±<€7¾ý‡ðÝo{ÖLCÀ¾}û®öÇR(ì9T P¸ X–^øÒ—âû>úxáÏ¿Ÿ½ýi8°’^y©ýV Wì:Ød„çç Ì]'ªÐÜTO ‡Æ€Õæg²æ@y °Eí]eyÑ…xØUP³ @Ó1½ú{ÕËÆ-Ð’ÄÜÑZÃZ!¤¿æÕxÿ'?Žï}ûÛ±¶¶†Õjå …Âî£þò …«+ ̳pú¿î»ßŒ»ÿôa<í{ß„Kp@ò† m¨íÍÚoÊ3«&éùUSN‰hÏœêûƒÚ fæ>ò¾LD-J*̤õ|î.dÛX !`£„¨À·>ïyx÷o}¿øàùÏÿBO÷—„o¡puQ@¡p `JÝO¿õVœù¹ŸÁ™?úwà¿~ hZ@CçŽÖ”ر¸ÐÜ+"™,ÈÀLª/`?7IÕÏÚìïšVf>5—ô}‰æ¹“¡] &ñ›ÚÍÁwðÁƒøÖ·ÿ=|àããå¯z•d;ŠÝ_(\3( P¸F°, |ÑK^ŒïùÈïáKÿÉ/á³Ï|öc&™¸w™U£4Dé{ÛŸ:±§ø;I¶€AÊØVBãš0ûµ„й‰ƒÐUü‡Ò,HFZÃDj„/õßÀûÿäxëýO¸é¦›*Ý_(\ƒ¨¿ÆBáÃP`ÆWÝýø®?}Ÿ÷?ÞƒÏa—ÁË:6°w`ƒUN˜u"`ƒ aÕIÅ}4Z'Ù+7&.Ä*/¬Â=] =Ãêý!ìÓY´ûIÿ>ûYxÇoü:~éƒĉÏ«t¡p £€BáÅ4M"±»Zá–ãÇñºŸþ)|ûCˆéLÀ3M˜¹cƒ61ø+ÊÊá zâߪ5Õý«ñ·%{À.þg~³9IЇº°û¿íí?„ßüÄ'ðwÝUéþBá:@9…Â5ŽimM¢òyÆó¾ôKðæýÛøk¿ñO±qâ¯` "Ècj~2iPþ€´î­´ö/Û ‰Ïôfmá›ÙØþ* Õè=fØÈßÖ@šÿ—|Ã×ãýo}ÇáÈ‘#•î/®Ô_h¡p=€h( |Å7ÁwòãxæÛÿþ|jØÏ"'|Ye„Wár“I}+‚«®f‘^QL„v ýÜ•Ò?÷L:D L õ}ö³ñŽöÏðë_âù_ôE•î/®3”P(\GÈeÃëëxÝ}?†¿õðcß+¿<ûXxV½ƒ‰°¡NÀÜÕè7ŠHÞRùlÓúº§ú;‹1&É035Pg¬¦ ßòwïÅo~òxÍ·~K¥û …ëå ×!²šà‰;ïÀ›~û,^ö›ïÃÆ!&­ã¯”å¿AG ‹`ÐŠÄøÏ6ñÖÃ/Æ •ýe¬V’î€Ë`¼èå/ï?ü1üà;ßYéþBá:GýÕ ×)HË]ûý¾ìU߈ï{øñ?úCøóû±»´Bkù ¸Ì,݈vA&£‹’ŸÎà M-ŸŽcÏù¼ë7~¿ò;¿ƒ/¾ãŽJ÷ 7Ê(®s´Ö€Ö0¯V8xà ^ý#oÇÿÃÇpè®Wcƒ bä7`zl¼0cCe|-`Ýè šgl´†oþ;oŇ>þñb÷ 7Ê(nXY`^­ðìç=ßõ¾_Ç7ü«³èõEXJ°bƆΰìa£³È÷Bzÿ¿ø/Ç oû‰Ÿ¨t¡p¢þ’ …YM½ã¯¾üex˃„üôãÏŸ~kÌ:'@þ+’6@&’ ƒÌ¸ùÄsqßû~¿ò;Æ‹î¼óù%€Õj…iš*Ý_(ìÔ_y¡°G°Œæ_ô’—àE/yÉð»2ü…ÂÞAå÷ …B¡P؃( P( …=ˆr …B¡P؃( P( …=ˆr …B¡P؃( P( …=ˆr …B¡P؃( P( …=ˆr …B¡P؃( P( …=ˆÒýÜ&j*ZázÅ¥K—ðÐCùÏùÈGpéÒ¥Ç|Ïúú:îºë.ÿù¹Ï}.NžNŸ>Ûo¿ý1™ñO¤uðFÀý÷ßÝu| ÛE9…Âu†K—.=aãâÄ œ>}úq¶õõõ)oߟ?ŸúÔ§pþüùÏ@lÇ_¸pögæk|2k{à°¾¾ŽS§Níèù W å ×Þóž÷uêΜ9ƒŸù™Ÿ¹Ú—hΜ9ƒ÷¾÷½OˆáéÒ%ÜÿýWû …A9…ÂuëóßNœ8û"Xˆ#pß}÷mû}.\ØQQ¥Báj¡€Bá:ÁG>ò‘mmÛm·áÞ{ï-›„“'OâÞ{ïÝöûö ù±°·P@¡pàâÅ‹ÛÖó¿çž{*òßV®Ø–Ý…€r …ë>øà¶¶?}út ½y Ü}÷ÝÛv޶û ×:Ê(®l7úÌ#| [ãž{îÙÖö/^,ѥ …r …k<òȶêϧOŸ®Ôÿ〵2nån$”P(\ãØnÛ_©×=~l÷Z™ÈP¡p# €BáÇvŒÎúúº á>7N:µ­.‰ .T7@á†A9…Â5ŒK—.m+PÑÿö±Ý2@M ,Ü(( P¸†±]csûí·_í%_wØ®ð©O}êj/¹PxJP@¡p c»úõÏ}îs¯ö’¯;l÷š}æ3Ÿ¹ÚK.ž”P(\ÃØn½¹2ÛÇv9Ofs¡p-¡€BáƧ?ýéǽíúúzÉþ>Al§m²H€…å ×0¶clÊø?ql'sR@áFA9…Â5Œí›Jÿ?qlÇy*@áFA9…BaÏ£²'…½ˆr …B¡P؃( P(¶*µn”P(\ÃØNjz;…ÕÚWØ‹( P¸†± Øé»ƒš´X¸QP@¡p c»íiå<1lWo¡P¸P@¡p c»Æ¦ÊO Û)>|øj/·PxJP@¡p c»:õ5¯~ûØîÀ¥*n”P(\ÃØ.ã¼FÕnÛ%nwz`¡p­¢€BáÆúúú¶†Õœ?¾xÛÄvœ¦'N pà€BáÇwÞù¸·½téyä‘«½äë Û¹^Ûù, …kå ×8¶›r.àñãÂ… Û*lwtp¡p-£€BáÇÉ“'·•v>þ<Ο?µ—}]ࡇzÜÛ®¯¯Wý¿pC¡€Bá:À]wݵ­íx૽äk/^Ü–pêÔ©ªÿn(”P(\8uêÔ¶¶¿xñ"Ξ={µ—}Mc»×g»NX¡p­£€Bá:Àm·Ý†Ó§Ooë=çÎÛV„»—ðÈ#l‹+qòäÉêÿ/Üp( P¸Np÷Ýwo;ýÀ”°Àùóçqÿý÷oë=÷ÜsÏÕ^v¡ð”£€Bá:Áúú:î¾ûîm¿ïÀ¹sçv|}—.]ÂÙ³g¯i‡ãüùóxÏ{Þ³­÷œ9s¦¢ÿ ‰µ«½€B¡ðøqúôiœ?~Û­~gÏžÅùóçñú׿þ)oe³õ˜á¿V£å'’ ¹í¶ÛžÓU(\( P¸ÎpÏ=÷àâŋۖýµöÀÓ§OãÔ©SOª¥íüùóøÔ§>…|ä#×¼òà¹sçžÐ:×××qï½÷^íå ;†r …màر»“'Oâ¾ûîûœÛ™az÷»ß½m{@zß-¶èöÎ;ï¼bfàâÅ‹žq¸páÂ5/4dåŽGyäIÍF¸÷Þ{Kø§pC£€Bá:Äm·Ý†w¾ó¸ÿþûŸ”‘»ZwÒéºî»ï¾ý)Üð(`¡pâ¶Ûn+Cõc}}½®iaÏ €Bá:†¬"ª=yœ³÷ô3}¯;WÂV7Ñž¾Q …Bá:ÁVÏëz~orW2ú˯B¡P(\›x<ÏízŽ+ÊÁWøè櫽ÀB¡P(\3;`+ãŸPÀf\Ƀ\ظڋ+ …±Âf' 2¸W@9WÆ2ò¿ àÒÕ^T¡P(®ˆG!N@ׯ2üµ«½€kù&ÉÞ¢Ý@æüw"z5€C@®ß>Súj(} …Bá‰cùLžÓ׆~}À_øKý}Çø ßê¿çQ€Ü”¾_~å À_èï°bü×ôËŒ¿}•P( OùYl_3$Ò_AžÍæ\ÆÖ€­Ê{Þ (`ÄVÆéqó­á±€B¡P(W €r füs ØÚˆçÔÕ9…B¡ðÔ`+‚öÒÈ%e`É('囿}Ÿ=ÆåövCÂðWô_( ;‡+uh™VËÒ¸’á/'@QÀf,³Ë׬îoÝKã P(ž*ðÿ.€ÏõUõÿ-P@`«›c+æhv[§ýËð …ÂS‹­ÔZ˸’@9ŠrK5ÀŒŽÍìÿ–~%Ã_N@¡P(<5ØJÁïJNÀã1üå €%–|€ü{FDýKã_‘¡P(ì®äØïú¶Éï- €Œlü³³YØšðWN@¡P(ì ®œ}®ï·úwÏ£€WÊ,_û\F¿œ€B¡PxjÁóçÇ2øeüÊØŒe; ýnÙ*˜Q¿P(vå|.g¡€r ù†YfëµB¡P(ìø ¾V@9Oô&«Ì@¡P(<9”!ß!s]ÛB¡P(öÚÕ^@¡P( …ÝG9…B¡P(ìA”P( …ÂD9…B¡P(ìA”P( …ÂD9…B¡P(ìA”P( …ÂD9…B¡P(ìA”P( …ÂD9…B¡P(ìA”P( …ÂD9…B¡P(ìA”P( …ÂÄÿ·ä/̆y„%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+=tEXticc:copyrightCopyright 2007 Apple Inc., all rights reserved.žfÜ)#tEXticc:descriptionGeneric RGB Profile§8Ž$tEXticc:manufacturerGeneric RGB Profile=h>tEXticc:modelGeneric RGB Profileêo®«IEND®B`‚leocad-23.03/tools/icon/64x64/000077500000000000000000000000001440571307300156375ustar00rootroot00000000000000leocad-23.03/tools/icon/64x64/apps/000077500000000000000000000000001440571307300166025ustar00rootroot00000000000000leocad-23.03/tools/icon/64x64/apps/leocad.png000066400000000000000000000126551440571307300205500ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“ÄIDATxÚÍ›]Œ$×ußçÜ[ý5³³»ÜåÒ$ES²dÙCÉŠ^#–„†Èè‡<Å/‚Ø’8æÒ ?øCN ¦œ  PDE‚[¹RBØpŒÈ1$Ê"ER+r?æ»§»«î='UÕS=Û=Ü¥V°ï¢¶?ªúÞsþçûÜ;Â÷a\8>^¸x1µŸÿòñÇt<ž¾§ªÊ$Wo5ÏçȾáz¨åÊEvUãòRÑ ÏØ8ýWïûÈG¾±jÎÛ5ävOè öÿ>ñ‰s;/¿ü/«ƒƒÛlö®~¯ÜÉ9cî˜9¸ã ¢‚ˆ¢AA„YÊ„"|£?ï8û_þáG>rPÀþÎð„OCþ³}ìg7/翟PÌJf©³„ª# æ’EÖ· UÇL€Ð+z2ê÷ØÏVîºëŸà×ýÛ5þÎÐJþ¹?øƒ~õ«_}~¶½E¥ˆuSW•γ«æ˜$fî¢æî¹€^ÿÄå[ßúàåW¾Ö®u;èÖÛä~¸°Ë—ß—·79ȹ•9i±”¼½|ÅEç}ñœ¥—ÜÊÝí-¾sùòûþU½ÖmÞ›ÀAp"à?õ…/ÌΞ;7¹sw‡í¿ù¦^ßÙå »XÎŽª *ˆˆ‹ˆ bˆ"¹¹LDLELU$g¯ ÙÛÝãÒ —ô¹ÍMüܹ)À®×òóÏCt÷7 Æ-ýÐÝ屇 \¼È˜{dòÉÞÅÿû?~°3þé£ÑÏœ|éÅ·m>û§~EG²wê´—wœ­ú}b/R„€R;;©'7²U•©fSöÇcv¶7¹rõ*{³Òï~ÿËÛßñöo‡jöÔ`4üÜý¾÷Ù‡~þç§- ç!rþ<Ï<óL¿YžÞ€–é‹/r±Ãô_þþïöþæÒ?*';ÊeúÇ=á­*ÂlŸøç<ìîÊ0Dw7±"2Qeßœ½œ˜8LUI ÙœlK‰j:c2sP–LCA5<­ÜÜ…ÑÐßùÀƒrvcqÇàÕ^¿8ôžêßý–/ÿÜG?ºÓÒö„Ο— /oà+–à Aø:x×ã~ñ7~ã¤]}í¡j<ý—³ŸÀ=bÆ´,™™e‚Z9ž„øçÏêÀf>Ü8+ýÞ€µ5ú£u$feÉþxŸÝ]öffeÅÌŒYP&‡Àž¦¢Ì€cgsÓu0·¿ÿývbm=÷rÖ‘†°Þ/(Êl×zýâéÁpí©âÌ™/ýì… W:ì„ B–%þwBçÁ?}üñ3“×_ÿ ÆãŸIåìàgÉÆ4%R•’«ºC3É!ÈlzàüÕWet°Ë |xòé¯ é­P,qp0áàà€ýé”IÊ”X­8{»SQªØÛÛñÙl&rêîïù©Ñšôsö¾ˆ÷ G3Ä×bAŒÊ4Ù^¯×ûrì÷?[ ‡ü¡ßþíWVñ¶ üá‡Þøgo»ÿ§7ÊòÃVU œSž3Ó”È)%Ñ‚‚à9{ÆqöÊŠñ_UNïí2PaýäÖNž 7ZC‹‚*'&ãöö÷ÙÛßgZ•ÌbÁ,¦À.ÊÀá`6c|ý Õh Nžâþwÿ˜Ÿè{f„Ò‘žŠY0³(4ÆA A™dŸöúñÙÒõ©¶·Ÿ¼ð™Ï\q®&Ä.÷juI^»öXµ³õ‹/®­‘GkôCH…W‰XFÌ<×î ÇqUÉI…+(7Ö]™L<XB¯OU%&“ ûÓû93ɉÉlÌ,LcŸ‰æLÊ“ƒ}f@eà"D)€A=»®€ªª ê–KŸæ”¼,Ó`ë»{˜íï~`\ÙÀ¿x_¶À£5Ü3øúåo³>›L¾†ý×ÎÝwï8ÃpmDßÜÅìŽÇ ­â¸9æLP¶²³aEb81ʉ wg–2Óœ™™3u˜zf6+™Mö™L3Ì€™„Ú<€5”“CËôÜ)D¤GÍM¨**ÜŒýý½pukK®_yÝmZÎ6FÃÁðž{'Ëü]\öeÊÕ¦Fœ)úñlJòï×_ÿÎ+¼ºq’­sw‰nl0êõ€›csÃr¢;§‚ðp¥JlIÉeäB*''£J‰Ò**KTgŠ3a"NÙè×)1îVá´g†(Ì 8(TРR–%×wv¹~õ {;ÛêƒÁxj¡à ¥í› vtg‡œ2hþp· ÜWVl믆‚ïž¹“ÙéÓôGkôƒÖ¡É7*Ü!0UgR0N3öb!€Ô¹—™‘SE¶’œŒìMHDPœ@/Bß… §UØB6*ñø€ÍÍM¶®]¡œ–ƒ£õ“A0ÓA€Ø½1µq#U[… ®‚¹‘ ¤9ÛßàÎl¼óÚ¾ûúe^Þ8Éõ;΢'ÖõúQ „¾×D€ä™2%rU3˜ó:@›×nI$Ô‰‘HíUj0T”Ák‚S5cgoí«WÙßÙÆE)F#ÖzCÔ <ƒ žÍUGŸË›×_îØ¦BCHh(r gF£ïî/K¶¾ý"ߎ‘˧Ï2;}Š4ÅÉ"ˆ`æubÑšM{a÷ ‚#8jÆp4¢šL¸º½ÍîÕk”³ q8d°v¢&2;BF„È âf€Ðo À£à™È¶â.dsu%'@l‹º¦–EÁ¹^Ÿs–o]çòµ+|«7àåõuÆãLŸL€Q»Þ,}œ<Ùð9²°ë–“jˆV‡zæåÅBý¸€¸‘ ‘{ŠÈÝý>´Æ«Ó)/Ì&¼R•”nô,ÓKމ5|8h„Ø#k¤Ô€Å‚{ÄPÚ¢‰FÕ;˜KÿˆäÛ‚J²œcÒ½ÎO–ÐÞŸ>=‰NÕ}ð¬ˆ4]ˆeèã±uªD„"ò@±ÁÛ×Ö¹ZθTNy±Ll¹-ÑpT"L’„è‡HhÀi•¼ë & “–éEâ¤q²â ¢Ó²ß·úÚ}r©œôvÆ#d”u3lu=¿ØÄš¿´J¡]:1¹CÆè©rßpĽÃ!ïM™—Ë’KÀ«Àþd†)ô‚Îh=Í"{ R^¨nœ–ÀV[£×©+êã;··Ç7´¢!ò®sL‰a¬sµWé>).5²ÞU=m®±îuÌn¤duËÉ^Á»O¬ñÁÜ‘*ªýšy¯‰’FƒDnÀôZÿunµÅåàkïyÏÒLð¨E; ráB "»Q\µ!ªa~.‰#^·%Væ¥ã"ê¸ÁÝIîôŠ‚QìÕ9€;­™u™ŸÓ&Ëm|Õ037ÃUѰûÄOTsU9N¡bè^¨s”¹Í84AeÙT‹HÊûÜ/ø1÷o`Ò<ÜQ‡¹tøü¿›ãÝ]pPeû¦h{ãvn=±†•¤I3MË|ýº˜‘­á0?öŸÜ˜ÒÍýo0)Vú€eNЂÈvÂÁ]¬Uy€…÷«H9ü¶›1.Óó:.GçÐî;³ú ø’ËÌÜÜÅÜ9oÃ¥ðRÚ’ØcÜ-E1PµäMûñ¦Po3§y¥Ì3¬.²`~C8=,k;×Ó>/•Çš÷xê¶ý .-…—ðd t¿¿›ÌŰ|CD2o[Ü}:ngnAØo É )vW:IA« Ý©ÌjÊTUrN6e¶»ˆË1´åØÄ§Ú6-?àÜŠYÖŽg¾ýjUTXõ½/<ሊx#®,LªöW‘¶2 Ìf;cãºã⎥¶yÈ ºR æÄµz¿´†ð..Ç»”ñzSyЦoé*ÔÕ˜ËAŽq¼j‰•üÈ?øÉ‰·…î ¶Z?:›ÓéíÒ:úÛHÊ›4Û©»]]˜ç £WW³:—ŠÎ“Ò¬:~mºŠ’è–Ä.ì6†çÇ©¾-½á7¦±·0¼‹Ñ1÷»Ït¯t4v?ýõ¯—‹È@ó”$×=­½·]ÜúõP>ÞLaæVoŽ7laÛÎBøcQ{œÕ¥ðÊ/iÈmDÉG&?\ð—yEÀâ©;|9ÛŽF‹Lj™£\ò›.ód3ww?¬–åRÚ’Ø%l›So„r‹­“çÚà‚`í¾Ú \¬ö ÖDì®úú¢MßÀ /^Ë%ßæNnvªëwPáÛ°¼^ @[§6M ‹xòfòæŸqÄÜ,æ šB f5m§×·E©ß„ÓX”öa"dî8Ž™4³­.„à˜r gßJ"Tõvô\Åó&óC‚Ž!®‡»MlêuºëbàuŸ½%}!µí€°Ôùu:ÁGUß:bÔ[ø™¼²X @[Í¢nV(™º%¦âmÙÞQŸ’vqk¼hÝ1my¶:Ÿ@›/ÜëÊápcሤ[†»Hµy¼@ƒ_öä‚’†7¯¥±9s#Y×@ln7A¼écH'5o: Í.ç\u¬ÙšP1šjµf¬q’]©íµŸ»‰“7N×i¶×ê ¤l¢ÉÓ±¬òPß:@)]¤¢ÞíI^or&j•KÍ•­uhµ¯ÈsGixkëÞqZGœiWê]æ‹®çhκfõÕnµç††lP&óäPšS‰l\¼ h+ 6÷ÜQ7ñŒ»YƒÄœ]5Š7M uH3Qi´ÙÉó&I§wØŽ¦8®‹a£CWâæàê‡÷-ª¬Þ½ÊÙÜÌÑ §4Ûìüüæh7I¯÷NŠXa¦Iƒ9»‰H‘“›Q©‰UmòØÔÖø^Ÿ @¼ñ ¢u›½j)Հ޷÷Îg“»Ï☊¤œÜ5ˆY¶Ê0t¯Œ++Á•´¿löb•Ó_ß«úîƒ*{A•’hìÕ'ÄnhÛ)z[k¾•ÕìLÖ@º@`¨è\z]‰Ï%}„ñ…,Ï—†y‡”³g"UÊ•©!ªî§ôìø•W.ÀÊ’¥áÅÞ'ï»ïÑQÿÝÙ°\¦à*ýB´äÑ•‚ž]¤ÖuwzÔi7@Ú£0m‘¯ÏŽ'?ÓjLêäª2sD¤ÊÙ]EÊdž±„†"{9ÿÝ”éÿln¾òFÌ¿!í3¿ñ ¨>ñ–»?|Bå·î ½û+szXÕ ¡ˆž=ªQj“¨7B»@Ì5B}ÞâùütÆ7 †âuÍáG$ŽÍßgwÊœ½Ö‘Òrå €ý”^˜ ¿ø•«Wÿ¨¡» ¡ùXæn€v„G€æðtï“÷Ýýk#äßÞê©LA^ˆ¡ðìA †(j¨Í!¦ÐlÿÏIÉ C¯g«òÙk©W©–xJÙ“8.")ç\º»†RJ·ÿxñ򾂴‰p¤;Ž©[ÀŸ¿ñ"TŸÛÝú½ýÁªðCƒXü¨ˆjöªrG]£¸åš{s7Uiã¿7;ÄuÓDx>e6©·*Ÿ¡þÛÜ2ŸÜU¥´Li–<Ä誺S¥Ï_¯ªþÙÖögÜ"uŠrÓ•ö›ÝY0‹ß;wχ6þ[çÂð‡’e OU‹¢°ìQ³ÃMÑúЄ¢*|~VrÉa€×§È¼f>9¤”<7‡ÊœS‰ˆ²ŸóK)W¿ô¥ëÛO5ô·Êø÷ @;ôÆ,â'ßrÏ¿ ¿z6bkýCt÷€¡%â.¢›_(g\r¡ÌRíØªd^‘ATrN¹r7 ±›sÒãÏ\¿þP2ßQ|ó@u+&°ltÍ"}nwïËï>5ú9ßß½w©¨f«*sרîî&*mNèî¼ë.¸e·†yS—*g’Yò¢©†”ÿdg2ùàÿÚÞ~’ðæõ{h¼ÝÞ=ɳøÝ·üÀO’ð;?ûïL^›E$ĨN@ ªDø“ÙÌ/I`É« Y]Ê”RrB‚ì–Õ«S×óÌæÕ'›uÞ´º¿h‡ž½X)OüàÝz|ôÎXôS.sD) …¹Gà‹æò|ÎÞ‘YUYé–UC15g?W¿ùôµÍ_&jëmû£IøÞM`Ùð—ÀÎC| ìs;ûÿû}ëñ¿¹È½½ ¢šr®LL\ }ÑŒ+f`)e4šHçôôÖAú§_ÙÞú5·EÝ—ïÛ¶|;×,þÓ=g~b# ?~¶è=àfñêËe’ç=‡¡ˆl—éµYò_þÒÖµO5¿¿­êþ·@;ôB}%€ß½ïÞ};[ô׿’_«*Èùwþèõ+ÿsx綪ûßú8ß©>yý®s¿÷ƒ÷þ×_xËÝÌéÓv‹·>ó›ÿ«'Ðg:ù’%tEXtdate:create2019-02-28T11:19:20+01:00€¸—%tEXtdate:modify2019-02-28T11:19:20+01:00ñO+IEND®B`‚leocad-23.03/tools/icon/64x64/mimetypes/000077500000000000000000000000001440571307300176535ustar00rootroot00000000000000leocad-23.03/tools/icon/64x64/mimetypes/application-vnd.leocad.png000066400000000000000000000065551440571307300247120ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞgAMA± üa cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFbKGDÿÿÿ ½§“ pHYs  šœ oIDATxÚå›]ŒUvÇçVUUwõØÆÃ²ÆØ†eCL¢d‘Mð:’]^E²"‰6;ÒJ~Élb$^°"¼ñ‡œ—$“ÚKiW ´àH^¼ŽYPvc=<3=3=Ó]uïÉCUõôØx<öôŒö/]u«ëvÕ=ÿû?çžûQ¢ª\ "bXôgßW10 œÚ€ËÊuc1—b700ð—Ï<óÌs+a­ªvŠskms||üÔÛo¿ýÃ^xáo/\¸0hVzs5ãJVV —P©T*_}øá‡÷¾úê«oìØ±ãNÒŽ’A€…¬¬ Tk-­V ß÷ïy饗^{ðÁ7‘vFÏI¸ya?‡Èå·WU’$áܹs:ôÎ>ÎØØccc4 *• QQ­V×8pàøÎ;7^+ KžÝ}V¶¶èîé\ÆŽ;Æðð0ÓÓÓ$IB’$”J%Ö®]K¥RaëÖ­ë8püÙgŸ}àÍ7ß–»n:Œ18çäA†!atOœ˜ššbjjŠááa*•Ê-{÷îý·?üð7†‡‡Ïöj$¬ÆüçÆÚ?eìý“Lü1í‰ âv;mD¡@±¯hãF¢¯|…âÚµHF†ïû”J%¢(ÂZK³ÙÄZ‹sç\g&i­%ŽcÞ{ï½/¾øâÑ'Ÿ|ò€©Œ„ep]àsœÃø>c?9É™þ.ŠM,±s¨:@‰âáaf?8͹×^ãö'ž ~ï½é,L„b±H­VÃóÌÌœç\N‚9}úôïC¤±àŠ*è™_z™ÁñôÿýŸžú ññÿ |ë_1_Ø@;Š˜ñ}Z"¨Sbg™ž›ãÓé)ÎŽœc£u˜b‰/~ùú¿ü%Â0¤P(PJâ8NCü%íÉãBÇ8çh4Pš+O€*ƒg í‰ ÆNbìÄ .þô4U…X„‰O>¦OgèW¥,Ât£ÁÙ‘.6§˜VÇ9¯Àx¥ÆÔÜ#çÏóÓ'8÷ãˆ*·mÙBÿ½÷qË=÷PîëK×øT!ëýnõåD”ËeG:$.ŠeÁ<ÀµÎœáÇG2::J_à#6Á¶cÆk<Î"\˜›eãì}a̬ñh&‹e¦ý€¦Âtk–‹s³ø"Ì´ZˆZB§Løöç?ã£ï}Wïãמúcn¹cSçÙÝ*ÈK±X´,a1gÉAðJ ÌÍùs|õ‡ÿÂ)#ëo£±¦†žs(ʉY8;9A½Ý§Lµf™œb:n1‘ „Ö;¥/Ž)%éI>¹ØàÓÑB„_þ½ß¥ð¥»IâÏ÷;Æw#{5£®IW$ _µY»––çsWÒâöOþ‡É³>g£ˆ³}}´£: k}afv‚±¹&N q›X%B_¸C¶ø†ªµÌLŽsv|‚éñ‹¨SŠA‘¤X ¶vMš$eëÝ ÈÑ­Œžp%˜|S.aðKen¡z’»&.r>Œøyàs±¢I“ªI]8¿kŒrViNL2uaŒ¹Æâyø~ßHêÐê(VÂó†îNÊI‘% ÝËV€Áˆ åÏÆ8§¨¶P¤V4ÔmÌÛæWúûùh¶ÉÍ.Ä-Œ³„‰ø¸0Ä/”™œÄ¡T© ¤Ãªª"~àT* &PKiç*( Œ_.#ssóS,‡ÃOàV/Êüj­ÿmÇœŽg9“8b<ð=Šâ§9Io¡Î¢’Þ'@À+WJÅÏ^Vû¯E‹ ¤\¢‚h:å»Á9Gh|¶†_³žZ¡‚ |ŠâcPŒ€hVXÂE X*Q(•Óg.Öž^+àŠ7Í~÷ŠEü°†/†D\J É,´ ŠbÁxŠf½Üy’€ (ŠðÄT*Åââmº,{L¯¦I ÕAp€Æ!Ô¥ºN§8˜ÌÐ$»¥:fç‘K2ãó+Y|%«©áù3—‰ž,ˆ8—nÞJµŠgÀ31ŠA0â0b0ÙÃæ8ßÛ™š;\jÇìœ Á3’º@­€uËÚ0î-ù¬FêF ð2 g¥Ë¯SóRK…ù%œ…Ú•âvïÅZ¸à™ËEOæ^Ö…¦ZK•Þi8xyÏv·\ú¤ò™Ÿñ!ó*Iã"¸L1¥¨v]ÁnE È5¬QTp" Ä ¸Ž.ǼŒ%ór¥ËE;þ¯@)ª/•€ÕI„º  a%mt®u§Y“.º-ê*Ÿ;è¼ÒUÀ «QOÐÛUáz=#€K|ÔuŒH ë˜8o`FV~D™w§i= ² Ø+ôfÈ?Ö粃=,çÀ¡¨¸…–²àk§×;Æ“¦Û1 ‰¦1 —èM4& ‚õ>fpÄÖv$î<Ò<@X£¢&åAS>rt+BEq@¢µ‚z–r½/•ÿ%¡J@>!"ªÑpà!à#Š'hJB N£U“õ¼gPYè‰s8›Å”Ä)åÚ C>)ÑR…IuQŠ >B /]5:½¯¢¨ºŽ T2—É|=7܉+ˆx´T ²½^íSôfÈ\ X·†ÉRÄúé šs$lš¹ƒ/ Fñ¬óPqY|pX—æü¹ì¬*±1X,T#¢þ[?s-àº;¯'4f¹y1ªóëßý'mg*¶4cÖM§4¶sÌ)$Ö’8ŪŹtØ´(‰@¬Ž6Ž–Sb`ÖYfÚ1wíüMö;F­uvŽ®‚ÞæK!Á9G}óf:t”3?ø§÷ý }##€R2©” ÖâDð5ŠEˆ¥ËßAË9¬:J_¼g¾=Àößù:Àe ¡ËEO·Ç=ÏKWecÓcñèÐëTþ워:KË*M³"Ì-Mˆ]Z×:KŒ!F˜C™SKÃZ¾ñÜn¾óÖ[<øõo`­EUñ leocad-23.03/tools/icon/scalable/mimetypes/000077500000000000000000000000001440571307300206265ustar00rootroot00000000000000leocad-23.03/tools/icon/scalable/mimetypes/application-vnd.leocad.svg000066400000000000000000001643211440571307300256740ustar00rootroot00000000000000 leocad-23.03/tools/setup/000077500000000000000000000000001440571307300152545ustar00rootroot00000000000000leocad-23.03/tools/setup/appimage.sh000077500000000000000000000014701440571307300174000ustar00rootroot00000000000000qmake PREFIX=/usr -r make clean make -j4 sudo apt-get -y install checkinstall rm ./*.spec # Otherwise the next line fails sudo checkinstall --pkgname=app --pkgversion="1" --pkgrelease="1" --backup=no --fstrans=no --default --deldoc mkdir appdir ; cd appdir dpkg -x ../app_1-1_amd64.deb . ; find . cp ../qt/leocad.desktop . sed -i -e 's|\.svg||g' leocad.desktop # Workaround cp ../resources/leocad.png . mkdir usr/share/leocad cp ../library.bin usr/share/leocad/library.bin cd .. wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" chmod a+x linuxdeployqt*.AppImage unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH ./linuxdeployqt*.AppImage ./appdir/usr/bin/leocad -bundle-non-qt-libs ./linuxdeployqt*.AppImage ./appdir/usr/bin/leocad -appimage leocad-23.03/tools/setup/leocad.appdata.xml000066400000000000000000000023231440571307300206360ustar00rootroot00000000000000 org.leocad.LeoCAD CC0-1.0 GPL-2.0 LeoCAD

Design virtual models you can build with LEGO bricks

LeoCAD is a CAD program for creating virtual LEGO models. It's available for free under the GNU Public License v2 and works on the Windows, Linux and macOS Operating Systems.

leocad.desktop https://www.leocad.org/ https://github.com/leozide/leocad/issues LeoCAD.org https://www.leocad.org/towerbridge.png leocad.desktop leocad-23.03/tools/setup/leocad.nsi000066400000000000000000000112141440571307300172150ustar00rootroot00000000000000!include "MUI2.nsh" ; The name of the installer Name "LeoCAD" ; The file to write ;OutFile "leocad-setup.exe" ; Request application privileges for Windows Vista ;RequestExecutionLevel admin ; Build Unicode installer Unicode True ; The default installation directory InstallDir $PROGRAMFILES64\LeoCAD ; Registry key to check for directory (so if you install again, it will ; overwrite the old one automatically) InstallDirRegKey HKLM "Software\LeoCAD Software\LeoCAD" "InstallFolder" ; Icon "setup.ico" ; !define MUI_ICON "setup.ico" ; !define MUI_UNICON "setup.ico" SetCompressor /SOLID lzma ;Interface Settings !define MUI_HEADERIMAGE !define MUI_ABORTWARNING ;Pages !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !define MUI_FINISHPAGE_RUN "$INSTDIR\LeoCAD.exe" !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_WELCOME !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_FINISH !insertmacro MUI_LANGUAGE "English" ;Installer Sections Section "Application Files" SecLeoCAD SectionIn RO SetOutPath "$INSTDIR" File /r /x library.bin "appdir\*.*" ;Register file extension WriteRegStr HKCR ".lcd" "" "LeoCAD.Project" WriteRegStr HKCR ".lcd\ShellNew" "NullFile" "" WriteRegStr HKCR "LeoCAD.Project" "" "LeoCAD Project" WriteRegStr HKCR "LeoCAD.Project\DefaultIcon" "" "$INSTDIR\LeoCAD.exe,0" WriteRegStr HKCR "LeoCAD.Project\shell" "" "open" WriteRegStr HKCR "LeoCAD.Project\shell\open\command" "" '"$INSTDIR\LeoCAD.exe" "%1"' System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' IfFileExists "$INSTDIR\vc_redist.x64.exe" VcRedist64Exists PastVcRedist64Check VcRedist64Exists: ExecWait '"$INSTDIR\vc_redist.x64.exe" /quiet /norestart' PastVcRedist64Check: ;Store installation folder ;WriteRegStr HKLM "Software\LeoCAD Software\LeoCAD" "InstallFolder" $INSTDIR CreateShortCut "$SMPROGRAMS\LeoCAD.lnk" "$INSTDIR\LeoCAD.exe" ;Create uninstaller WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" "DisplayName" "LeoCAD" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" "DisplayVersion" $%VERSION% WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" "Publisher" "LeoCAD.org" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" "DisplayIcon" '"$INSTDIR\LeoCAD.exe"' WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" "UninstallString" '"$INSTDIR\uninstall.exe"' WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" "URLUpdateInfo" "https://www.leocad.org" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" "URLInfoAbout" "https://www.leocad.org" WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" "NoModify" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" "NoRepair" 1 !include "FileFunc.nsh" ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 IntFmt $0 "0x%08X" $0 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" "EstimatedSize" "$0" WriteUninstaller "$INSTDIR\Uninstall.exe" SectionEnd Section "Parts Library" SecLibrary SetOutPath "$INSTDIR" File "appdir\library.bin" SectionEnd ;-------------------------------- ;Descriptions ;Language strings LangString DESC_SecLeoCAD ${LANG_ENGLISH} "Application Files (required)" LangString DESC_SecLibrary ${LANG_ENGLISH} "Library of parts that represent those produced by the LEGO company and created by the LDraw community" ;Assign language strings to sections !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SecLeoCAD} $(DESC_SecLeoCAD) !insertmacro MUI_DESCRIPTION_TEXT ${SecLibrary} $(DESC_SecLibrary) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- ;Uninstaller Section Section "Uninstall" Delete "$SMPROGRAMS\LeoCAD.lnk" Delete "$INSTDIR\Uninstall.exe" Delete "$INSTDIR\LeoCAD.exe" Delete "$INSTDIR\LeoCAD.hlp" Delete "$INSTDIR\LeoCAD.cnt" Delete "$INSTDIR\readme.txt" Delete "$INSTDIR\library.bin" Delete "$INSTDIR\povconsole32-sse2.exe" Delete "$INSTDIR\vc_redist.x64.exe" RMDir "$INSTDIR" DeleteRegKey HKCR ".lcd" DeleteRegKey HKCR "LeoCAD.Project" System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\LeoCAD" DeleteRegKey HKLM "Software\LeoCAD Software\LeoCAD\InstallFolder" DeleteRegKey /ifempty HKCU "Software\LeoCAD Software\LeoCAD" SectionEnd leocad-23.03/tools/setup/setup.ico000066400000000000000000000020661440571307300171140ustar00rootroot00000000000000(& èN( À€€€€€€€€€ÀÀÀ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€pÿ{ pˆzwp‡w îp‡~wðŽ~¿wðxî¿÷™ðw‹·y™€w‰™ ™øw‰™ ™ˆ‡‰ ÿ€™™ˆ‰™ ™ ™Œ€€€€€€€€€àðþÿÿ( @€€€€€€€€€€ÀÀÀ€€€ÿÿÿÿÿÿÿÿÿÿÿÿˆ‡{» ‡÷ðw»ª p€x÷ûºªw‡÷ðx‡wº§wp‡ˆxx÷ºw~à‡÷ðx‡‡‡€ ~îàp‡ˆxxîçp‡÷ðx‡w€p‡‡îzàxxpÿðxŽç®ëÿ‡‡€™ÿð‡ˆzîë÷øx™™ÿðxx®î»‡ ™™ÿðwwŽë»w÷ð™™™ÿðww‹»wp ™™™ÿðww ˜ˆˆ€™™™™ˆˆ€ww ™™™™™™™ˆˆ€ww ™™™™™™™ÿÿøw ™™™™™™™ˆˆˆˆ€w ™™™™™™™ˆˆ ™™™ ™™™ˆˆ€ ™™™ ™™ÿÿ ™™™™ ™ˆˆ‰™™ ™ ™™™ ™™™™™ ™™™™™ ™™ÿþÿÀøÿÀpÿÀ ÀÀ?À?À@?ÀÀÀÀÀÀÀÀÀÀ€øüþÿÿðÿüÿÿÿÿ€ÿÿ€?ÿÿÀÿÿàÿÿÿÿÿ