pax_global_header00006660000000000000000000000064152077565160014530gustar00rootroot0000000000000052 comment=19efc9b8c0762b876d533ca0e8e01d0212696409 imsprog-1.8.5/000077500000000000000000000000001520775651600132235ustar00rootroot00000000000000imsprog-1.8.5/.circleci/000077500000000000000000000000001520775651600150565ustar00rootroot00000000000000imsprog-1.8.5/.circleci/config.yml000066400000000000000000000045441520775651600170550ustar00rootroot00000000000000# Use the latest 2.1 version of CircleCI pipeline process engine. # See: https://circleci.com/docs/2.0/configuration-reference version: 2.1 debian_only: &debian_only filters: branches: only: /debian\/.*/ shared: &shared steps: - checkout - run: name: Prepare environment command: | echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections apt-get update apt-get dist-upgrade -y - run: name: Install dependencies command: | apt-get install -y devscripts equivs mk-build-deps -B --install --tool='apt-get -o Debug::pkgProblemResolver=yes --yes' debian/control - run: name: Build packages working_directory: . command: dpkg-buildpackage -us -uc -b - run: name: Save generate packages as artifacts working_directory: .. command: | mkdir /tmp/artifacts mv *.deb /tmp/artifacts - store_artifacts: path: /tmp/artifacts jobs: debian10: <<: *shared docker: - image: library/debian:buster debian11: <<: *shared docker: - image: library/debian:bullseye debian12: <<: *shared docker: - image: library/debian:bookworm debian13: <<: *shared docker: - image: library/debian:trixie ubuntu1404: <<: *shared docker: - image: library/ubuntu:trusty ubuntu1604: <<: *shared docker: - image: library/ubuntu:xenial ubuntu1804: <<: *shared docker: - image: library/ubuntu:bionic ubuntu2004: <<: *shared docker: - image: library/ubuntu:focal ubuntu2204: <<: *shared docker: - image: library/ubuntu:jammy ubuntu2310: <<: *shared docker: - image: library/ubuntu:mantic workflows: build-deb: jobs: - debian11: <<: *debian_only - debian12: <<: *debian_only - debian13: <<: *debian_only - ubuntu2004: <<: *debian_only - ubuntu2204: <<: *debian_only - ubuntu2310: <<: *debian_only imsprog-1.8.5/.clang-format000066400000000000000000000200161520775651600155750ustar00rootroot00000000000000# yaml-language-server: $schema=https://json.schemastore.org/clang-format.json --- Language: Cpp AccessModifierOffset: -4 AlignAfterOpenBracket: Align AlignArrayOfStructures: None AlignConsecutiveAssignments: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCompound: false AlignFunctionPointers: false PadOperators: false AlignConsecutiveBitFields: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCompound: false AlignFunctionPointers: false PadOperators: false AlignConsecutiveDeclarations: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCompound: false AlignFunctionPointers: false PadOperators: false AlignConsecutiveMacros: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCompound: false AlignFunctionPointers: false PadOperators: false AlignConsecutiveShortCaseStatements: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCaseArrows: false AlignCaseColons: false AlignConsecutiveTableGenBreakingDAGArgColons: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCompound: false AlignFunctionPointers: false PadOperators: false AlignConsecutiveTableGenCondOperatorColons: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCompound: false AlignFunctionPointers: false PadOperators: false AlignConsecutiveTableGenDefinitionColons: Enabled: false AcrossEmptyLines: false AcrossComments: false AlignCompound: false AlignFunctionPointers: false PadOperators: false AlignEscapedNewlines: DontAlign AlignOperands: Align AlignTrailingComments: Kind: Always OverEmptyLines: 0 AllowAllArgumentsOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true AllowBreakBeforeNoexceptSpecifier: Never AllowShortBlocksOnASingleLine: Never AllowShortCaseExpressionOnASingleLine: true AllowShortCaseLabelsOnASingleLine: false AllowShortCompoundRequirementOnASingleLine: true AllowShortEnumsOnASingleLine: true AllowShortFunctionsOnASingleLine: Inline AllowShortIfStatementsOnASingleLine: Never AllowShortLambdasOnASingleLine: All AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakBeforeMultilineStrings: false AttributeMacros: - __capability BinPackArguments: true BinPackParameters: true BitFieldColonSpacing: Both BraceWrapping: AfterCaseLabel: false AfterClass: true AfterControlStatement: Never AfterEnum: false AfterExternBlock: false AfterFunction: true AfterNamespace: false AfterObjCDeclaration: false AfterStruct: true AfterUnion: false BeforeCatch: false BeforeElse: false BeforeLambdaBody: false BeforeWhile: false IndentBraces: false SplitEmptyFunction: false SplitEmptyRecord: false SplitEmptyNamespace: false BreakAdjacentStringLiterals: true BreakAfterAttributes: Leave BreakAfterJavaFieldAnnotations: false BreakAfterReturnType: None BreakArrays: true BreakBeforeBinaryOperators: All BreakBeforeConceptDeclarations: Always BreakBeforeBraces: Allman BreakBeforeInlineASMColon: OnlyMultiline BreakBeforeTernaryOperators: true BreakConstructorInitializers: BeforeComma BreakFunctionDefinitionParameters: false BreakInheritanceList: BeforeColon BreakStringLiterals: true BreakTemplateDeclarations: Yes ColumnLimit: 120 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DerivePointerAlignment: true DisableFormat: false EmptyLineAfterAccessModifier: Never EmptyLineBeforeAccessModifier: LogicalBlock ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true ForEachMacros: - forever - foreach - Q_FOREACH - BOOST_FOREACH IfMacros: - KJ_IF_MAYBE IncludeBlocks: Preserve IncludeCategories: - Regex: '^ - Ver. 1.1.9 - Increased speed of program operation at the moment of chip type change. - Ver. 1.1.8 - Adding support the Intel HEX files format. - Ver. 1.1.7 - Fixed building errors. - Ver. 1.1.6 - SPI erase procedure fixed, deleted unused SPI procedures. Fixed program crash when reading/writing large size chips (25Q256/25Q512). Fixed error diagnostics. - Ver. 1.1.5 - Detect udev path with pkg-config. - Ver. 1.1.4 - Removed debian packaging from upstream (moved to specific branch for official packages work). - Ver. 1.1.3 - Fixed an error when the file size exceeds the chip size. - Ver. 1.1.2 - Added function for writing the Status Registers. Bugfix - Chip_Editor startup error when running IMSProg from command line. Added chips to the database. Added new language translation. - Ver. 1.1.1 - Changing application folders according to Debian policy. Added new language translation. - Ver. 1.1.12 - Minor changes to UDEV USB rules. - Ver. 1.1.11 - Added support for ASUS CAP files. - Ver. 1.1.10 - Fixed program crash on chip size mismatch with INTEL hex file size. - Ver. 1.0.29 - Added: Reloading the chip database after the `chipEditor` is finishes. Added chips to the database. - Ver. 1.0.28 - Bad display of qComboBoxes in UBUNTU, Manjaro linux fixed, display of monospaced font in Manjaro linux fixed. Changed the default file path to the home directory. The last file path is saved and new file operations are processed using the last path. Added new language translation. - Ver. 1.0.27 - Added the SFDP and status register information form. - Ver. 1.0.26 - Added support for M95xxx chips. Removed diagnostic errors and changed "About" screen. - Ver. 1.0.25 - Added `i` key to the interface. Added connection information form. - Ver. 1.0.24 - Added `STOP` key to the interface. Improved interface rendering. Fixes to translations. - Ver. 1.0.23 - Working, stable version. Removed unused C-functions and variable tables in code. Fix translations. Corrected cleaning of JEDEC ID line edit. Added chips to the database. Correction of database entries. - Ver. 1.0.22 - Working, stable version. Added languages. Added font colour compatibility in light and dark interface theme. - Ver. 1.0.21 - Working, unstable version. - Ver. 1.0.20 - Fixed incorrect byte sequence when reading/writing Microwire EEPROM in 16 bitmode (The SNANder program file "bitbang_microwire.c" bad functions - Write_EEPROM_3wire, Read_EEPROM_3wine replaced to Write_EEPROM_3wire_param, Write_READ_3wire_param). - Ver. 1.0.19 - Fixed wrong level on SDA pin in I2C EEPROM. Removed old function "ch341a_spi_init" in file "ch341spi.c", replaced by "ch341a_init" (this is SNANDer bug). - Ver. 1.0.0 - 1.0.18 - Partially working versions. imsprog-1.8.5/IMSProg_database_update/000077500000000000000000000000001520775651600176715ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_database_update/CMakeLists.txt000066400000000000000000000133431520775651600224350ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.10.0) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) project(IMSProg_database_update LANGUAGES CXX) # Set the CMAKE_INSTALL_PREFIX to /usr if not specified and /usr/local for macOS if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "The default install prefix on macOS" FORCE) # Set up Qt paths on macOS # If user hasn't set CMAKE_PREFIX_PATH, try to find Qt automatically if(NOT CMAKE_PREFIX_PATH) # Check for Qt6 via Homebrew if(EXISTS "/usr/local/opt/qt@6") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@6" CACHE PATH "Path to Qt6 on macOS" FORCE) message(STATUS "Found Qt6 at /usr/local/opt/qt@6") # Check for Qt5 via Homebrew elseif(EXISTS "/usr/local/opt/qt@5") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@5" CACHE PATH "Path to Qt5 on macOS" FORCE) message(STATUS "Found Qt5 at /usr/local/opt/qt@5") # Standard Qt path from Homebrew (without version) elseif(EXISTS "/usr/local/opt/qt") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt" CACHE PATH "Path to Qt on macOS" FORCE) message(STATUS "Found Qt at /usr/local/opt/qt") endif() endif() else() set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "The default install prefix" FORCE) endif() endif() # Set the CMAKE_INSTALL_BINDIR to /bin if not specified if(NOT DEFINED CMAKE_INSTALL_BINDIR) set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)") endif() # Set the CMAKE_INSTALL_DATAROOTDIR to /share if not specified if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR) set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)") endif() list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) #set(OPENSSL_USE_STATIC_LIBS TRUE) #set(OPENSSL_USE_STATIC_LIBS OFF CACHE BOOL "" FORCE) #set(OPENSSL_ROOT_DIR "/usr/include") # Option to force using Qt5 option(FORCE_QT5 "Force using Qt5 instead of Qt6" OFF) if(FORCE_QT5) message(STATUS "Forced Qt5 mode for IMSProg_database_update") # On macOS, additionally check the path to Qt5 if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT CMAKE_PREFIX_PATH) if(EXISTS "/usr/local/opt/qt@5") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@5" CACHE PATH "Path to Qt5 on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt@5 for Qt5") elseif(EXISTS "/usr/local/opt/qt") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt" CACHE PATH "Path to Qt on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt for Qt5") endif() endif() find_package(Qt5 REQUIRED COMPONENTS Core Widgets Network LinguistTools) set(QT_VERSION_MAJOR 5) else() # First try Qt6 find_package(Qt6 QUIET COMPONENTS Core Widgets Network) if(TARGET Qt6::Core AND TARGET Qt6::Widgets AND TARGET Qt6::Network) message(STATUS "Using Qt6 for IMSProg_database_update") set(QT_VERSION_MAJOR 6) find_package(Qt6LinguistTools REQUIRED) else() message(STATUS "Qt6 not found, using Qt5 for IMSProg_database_update") # On macOS, additionally check the path to Qt5 if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT CMAKE_PREFIX_PATH) if(EXISTS "/usr/local/opt/qt@5") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@5" CACHE PATH "Path to Qt5 on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt@5 for Qt5") elseif(EXISTS "/usr/local/opt/qt") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt" CACHE PATH "Path to Qt on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt for Qt5") endif() endif() find_package(Qt5 REQUIRED COMPONENTS Core Widgets Network LinguistTools) set(QT_VERSION_MAJOR 5) endif() endif() # Translation files set(TS_FILES language/chipUpdater_ru_RU.ts language/chipUpdater_es_ES.ts language/chipUpdater_de_DE.ts language/chipUpdater_zh_CN.ts language/chipUpdater_zh_TW.ts language/chipUpdater_uk_UA.ts language/chipUpdater_hu_HU.ts language/chipUpdater_pt_BR.ts language/chipUpdater_it_IT.ts ) if (QT_VERSION_MAJOR EQUAL 5) qt5_add_translation(QM_FILES ${TS_FILES}) else() qt_add_translation(QM_FILES ${TS_FILES}) endif() add_custom_target(translations2 DEPENDS ${QM_FILES}) add_executable(${PROJECT_NAME} main.cpp mainwindow.cpp mainwindow.h mainwindow.ui resource.qrc ${QM_FILES} ) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) if (QT_VERSION_MAJOR EQUAL 5) target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Widgets Qt5::Network) else() target_link_libraries(${PROJECT_NAME} Qt::Core Qt::Widgets Qt::Network) endif() install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/IMSProg_database_update.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") endif() install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/img/IMSProg_database_update.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pixmaps") install(FILES ${QM_FILES} DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/imsprog") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/IMSProg_database_update.1.gz" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/man/man1") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/io.github.bigbigmdm.imsprog_database_update.metainfo.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") imsprog-1.8.5/IMSProg_database_update/IMSProg_database_update.pro000066400000000000000000000031121520775651600250560ustar00rootroot00000000000000#------------------------------------------------- # # Project created by QtCreator 2026-04-10T12:21:41 # #------------------------------------------------- QT += core gui network widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = IMSProg_database_update TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 CONFIG += c++11 SOURCES += \ main.cpp \ mainwindow.cpp HEADERS += \ mainwindow.h FORMS += \ mainwindow.ui TRANSLATIONS += language/chipUpdater_ru_RU.ts \ language/chipUpdater_es_ES.ts \ language/chipUpdater_de_DE.ts \ language/chipUpdater_zh_CN.ts \ language/chipUpdater_zh_TW.ts \ language/chipUpdater_uk_UA.ts \ language/chipUpdater_hu_HU.ts \ language/chipUpdater_pt_BR.ts \ language/chipUpdater_it_IT.ts # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target imsprog-1.8.5/IMSProg_database_update/img/000077500000000000000000000000001520775651600204455ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_database_update/img/IMSProg_database_update.png000066400000000000000000000057051520775651600256300ustar00rootroot00000000000000PNG  IHDR@@PLTE𙙙杝֋񑑑蜜䦦᧧οηΠڡ?fedΈA<+9JJBB=OUB=5TZ/ EC>KuB>9/;+S,={?g76+(k)H(@3'(#X]W''x)]M[PR{K5>Vi%2eGNGBR5EڝIex?  &jlpjSsihhhlZ@H(awϞ제鈄yyyuvq_2  qķߔ|Zzw^ee_W<67K),zxonm}gSdZ_rR]QwPI<[8<*+Ӣȧֵɧh5kևHQuk_cYhS+4H $QyB~,tձ;lu>Ki^Z;VUPg390&!5~Zཅ2டή9vQd|͗c|SA\:xCmPhegaaamH*9tgFf١0[h[W-:TˌzÖdM~Nxk4v+[-tRNS #6FY&m9Υywd_ !JIDATXÍu\a v7bFp 2Ma#%DRC@R,Bc6m~{۽V[6*@4۶}TpP_6}U5´ Z 數0-  zX&馞-h4:@Su5֨.2 '^X]tCM輦Oǵuh7[pt #P-Tהw7Іc@7nܴp[:ؐ!A܂aL%p:+:M)_9t:^h;NC/A eoB)۷] 7̙㟏 Z\!Ekӡ͢-)W6WTT|-K@&$M&k{l>ZQq<ĝ9smS_8q\KW t L>y󛢢[Wh"01M@='GPR|쒭[;kݮLv(cDxչ8\۶WBu)hĉ68^ MJf` hj-J={jΪ|[6 )bi31Iw! UOI[Tf ]0P%(k[\MY`Cfޚ4ͯ_gٳO<2]-0k@``7(h/}/>6[f|ēYA4?ަ^ w˧={HyJqR@J056T&x\=x~'P&U3/:$JZ_}ӱYj5-e+Wi/].XV&`s=}~Y뉑WŮ0 +@^Ӧa1-,q/1 xӌ=H46ųFFF~|>[ZZ&!L+ 3W>uA_~{mÕQV>笌H5!`_y ˜${o=+͂39 !C`φƯwm=`2Y` @rxקpIm@Э bm@pgYjZʈ& HAl <zjn),A<ðTA+#YJ p@i>CPoaqz(ILb20rk@s 5@q V0 ,M~.y$ b(?YyZrZW .m1ly@CCVc.׏(Jp列gǥikyR ݈3*[ 2#m (A6QҹF'(})x:4Ce#5IENDB`imsprog-1.8.5/IMSProg_database_update/language/000077500000000000000000000000001520775651600214545ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_database_update/language/chipUpdater_de_DE.ts000066400000000000000000000067201520775651600253210ustar00rootroot00000000000000 MainWindow IMSProg database updater IMSProg database updater <html><head/><body><p>The <span style=" font-style:italic;">'IMSProg.Dat'</span> file will be replaced</p><p>with the new version. </p><p>You may lose the changes made to it.</p><p> Continue?</p></body></html> <html><head/><body><p>Die Datei <span style=" font-style:italic;">'IMSProg.Dat'</span> wird</p><p>durch die neue Version ersetzt. </p><p>Die darin vorgenommenen Änderungen gehen möglicherweise verloren.</p><p> Fortfahren?</p></body></html> Ok Ok Exit Beenden Downloading file IMSProg.Dat Datei IMSProg.Dat wird heruntergeladen Invalid URL Ungültige URL Cannot create temporary file for download Temporäre Datei für den Download kann nicht erstellt werden The database has been updated! The old database contained %1 chips, The new database contains %2 chips. Die Datenbank wurde aktualisiert! Die alte Datenbank enthält %1 Chips, die neue Datenbank enthält %2 Chips. Failed to replace the database file Das Ersetzen der Datenbankdatei ist fehlgeschlagen Downloaded file is too small (corrupted?) Die heruntergeladene Datei ist zu klein (beschädigt?) Download failed: Download fehlgeschlagen: Error loading file: Fehler beim Laden der Datei: Error: Fehler: imsprog-1.8.5/IMSProg_database_update/language/chipUpdater_es_ES.ts000066400000000000000000000067241520775651600253630ustar00rootroot00000000000000 MainWindow IMSProg database updater IMSProg database updater <html><head/><body><p>The <span style=" font-style:italic;">'IMSProg.Dat'</span> file will be replaced</p><p>with the new version. </p><p>You may lose the changes made to it.</p><p> Continue?</p></body></html> <html><head/><body><p>El archivo <span style=" font-style:italic;">'IMSProg.Dat'</span> será sustituido</p><p>por la nueva versión. </p><p>Es posible que se pierdan los cambios realizados en él.</p><p> ¿Continuar?</p></body></html> Ok Ok Exit Salir Downloading file IMSProg.Dat Descargando el archivo IMSProg.Dat Invalid URL URL no válida Cannot create temporary file for download No se puede crear el archivo temporal para la descarga The database has been updated! The old database contained %1 chips, The new database contains %2 chips. ¡La base de datos se ha actualizado! La base de datos antigua contiene %1 chips, La nueva base de datos contiene %2 chips. Failed to replace the database file No se ha podido sustituir el archivo de la base de datos Downloaded file is too small (corrupted?) El archivo descargado es demasiado pequeño (¿está dañado?) Download failed: Error en la descarga: Error loading file: Error al cargar el archivo: Error: Error: imsprog-1.8.5/IMSProg_database_update/language/chipUpdater_hu_HU.ts000066400000000000000000000067111520775651600253710ustar00rootroot00000000000000 MainWindow IMSProg database updater IMSProg database updater <html><head/><body><p>The <span style=" font-style:italic;">'IMSProg.Dat'</span> file will be replaced</p><p>with the new version. </p><p>You may lose the changes made to it.</p><p> Continue?</p></body></html> <html><head/><body><p>Az <span style=" font-style:italic;">'IMSProg.Dat'</span> fájl</p><p>az új verzióval kerül felülírásra. </p><p>Előfordulhat, hogy a fájlban végzett módosítások elvesznek.</p><p> Folytatni kívánja?</p></body></html> Ok Ok Exit Kilépés Downloading file IMSProg.Dat Az IMSProg.Dat fájl letöltése Invalid URL Érvénytelen URL Cannot create temporary file for download Nem sikerült létrehozni az ideiglenes letöltési fájlt The database has been updated! The old database contained %1 chips, The new database contains %2 chips. Az adatbázis frissítve lett! A régi adatbázis %1 chipet tartalmaz, az új adatbázis %2 chipet tartalmaz. Failed to replace the database file Az adatbázis-fájl cseréje nem sikerült Downloaded file is too small (corrupted?) A letöltött fájl túl kicsi (megsérült?) Download failed: A letöltés sikertelen: Error loading file: Hiba a fájl betöltése közben: Error: Hiba: imsprog-1.8.5/IMSProg_database_update/language/chipUpdater_it_IT.ts000066400000000000000000000066661520775651600254020ustar00rootroot00000000000000 MainWindow IMSProg database updater Aggiornamento del database di IMSProg <html><head/><body><p>The <span style=" font-style:italic;">'IMSProg.Dat'</span> file will be replaced</p><p>with the new version. </p><p>You may lose the changes made to it.</p><p> Continue?</p></body></html> <html><head/><body><p>Il file <span style=" font-style:italic;">'IMSProg.Dat'</span> verrà sostituito</p><p>con la nuova versione. </p><p>Le modifiche apportate potrebbero andare perse.</p><p> Continuare?</p></body></html> Ok Ok Exit Esci Downloading file IMSProg.Dat Scaricamento del file IMSProg.Dat Invalid URL URL non valido Cannot create temporary file for download Impossibile creare il file temporaneo per il download The database has been updated! The old database contained %1 chips, The new database contains %2 chips. Il database è stato aggiornato! Il vecchio database contiene %1 chip, Il nuovo database contiene %2 chip. Failed to replace the database file Impossibile sostituire il file di database Downloaded file is too small (corrupted?) Il file scaricato è troppo piccolo (danneggiato?) Download failed: Download non riuscito: Error loading file: Errore durante il caricamento del file: Error: Errore: imsprog-1.8.5/IMSProg_database_update/language/chipUpdater_pt_BR.ts000066400000000000000000000066531520775651600253740ustar00rootroot00000000000000 MainWindow IMSProg database updater IMSProg database updater <html><head/><body><p>The <span style=" font-style:italic;">'IMSProg.Dat'</span> file will be replaced</p><p>with the new version. </p><p>You may lose the changes made to it.</p><p> Continue?</p></body></html> <html><head/><body><p>O arquivo <span style=" font-style:italic;">'IMSProg.Dat'</span> será substituído</p><p>pela nova versão. </p><p>Você poderá perder as alterações feitas nele.</p><p> Continuar?</p></body></html> Ok Ok Exit Sair Downloading file IMSProg.Dat Baixando o arquivo IMSProg.Dat Invalid URL URL inválido Cannot create temporary file for download Não é possível criar o arquivo temporário para download The database has been updated! The old database contained %1 chips, The new database contains %2 chips. O banco de dados foi atualizado! O banco de dados antigo contém %1 chips, O novo banco de dados contém %2 chips. Failed to replace the database file Falha ao substituir o arquivo do banco de dados Downloaded file is too small (corrupted?) O arquivo baixado é muito pequeno (estará corrompido?) Download failed: Falha no download: Error loading file: Erro ao carregar o arquivo: Error: Erro: imsprog-1.8.5/IMSProg_database_update/language/chipUpdater_ru_RU.ts000066400000000000000000000101361520775651600254110ustar00rootroot00000000000000 MainWindow IMSProg database updater IMSProg database updater <html><head/><body><p>The <span style=" font-style:italic;">'IMSProg.Dat'</span> file will be replaced</p><p>with the new version. </p><p>You may lose the changes made to it.</p><p> Continue?</p></body></html> <html><head/><body><p>Файл <span style=" font-style:italic;">'IMSProg.Dat'</span> будет заменен</p><p>на новую версию. </p><p>Вы можете потерять внесенные в него изменения.</p><p> Продолжить?</p></body></html> Ok Ok Exit Выход Downloading file IMSProg.Dat Загрузка файла IMSProg.Dat Invalid URL Неверный URL-адрес Cannot create temporary file for download Не удается создать временный файл для загрузки The database has been updated! The old database contained %1 chips, The new database contains %2 chips. База данных обновлена! В старой базе данных было %1 микросхем, в новой базе данных сейчас %2 микросхем. Failed to replace the database file Не удалось заменить файл базы данных Downloaded file is too small (corrupted?) Загруженный файл слишком мал (возможно, поврежден?) Download failed: Ошибка загрузки: The database has been updated! The old database contains %1 chips, The new database contains %2 chips. База данных обновлена! Старая база данных содержит %1 микросхем, новая база данных содержит %2 микросхем. Error loading file: Ошибка при загрузке файла: Error: Ошибка: imsprog-1.8.5/IMSProg_database_update/language/chipUpdater_uk_UA.ts000066400000000000000000000073651520775651600253730ustar00rootroot00000000000000 MainWindow IMSProg database updater IMSProg database updater <html><head/><body><p>The <span style=" font-style:italic;">'IMSProg.Dat'</span> file will be replaced</p><p>with the new version. </p><p>You may lose the changes made to it.</p><p> Continue?</p></body></html> <html><head/><body><p>Файл <span style=" font-style:italic;">'IMSProg.Dat'</span> буде замінено</p><p>на нову версію. </p><p>Ви можете втратити внесені до нього зміни.</p><p> Продовжити?</p></body></html> Ok Ok Exit Вийти Downloading file IMSProg.Dat Завантаження файлу IMSProg.Dat Invalid URL Неправильний URL Cannot create temporary file for download Не вдається створити тимчасовий файл для завантаження The database has been updated! The old database contained %1 chips, The new database contains %2 chips. База даних оновлена! Стара база даних містить %1 мікросхем, Нова база даних містить %2 мікросхем. Failed to replace the database file Не вдалося замінити файл бази даних Downloaded file is too small (corrupted?) Завантажений файл занадто малий (можливо, пошкоджений?) Download failed: Завантаження не вдалося: Error loading file: Помилка під час завантаження файлу: Error: Помилка: imsprog-1.8.5/IMSProg_database_update/language/chipUpdater_zh_CN.ts000066400000000000000000000065121520775651600253610ustar00rootroot00000000000000 MainWindow IMSProg database updater IMSProg database updater <html><head/><body><p>The <span style=" font-style:italic;">'IMSProg.Dat'</span> file will be replaced</p><p>with the new version. </p><p>You may lose the changes made to it.</p><p> Continue?</p></body></html> <html><head/><body><p>文件 <span style=" font-style:italic;">'IMSProg.Dat'</span> 将被</p><p>新版本替换。</p><p>您可能丢失对该文件所做的更改。</p><p> 继续?</p></body></html> Ok Ok Exit 退出 Downloading file IMSProg.Dat 正在下载文件 IMSProg.Dat Invalid URL URL 无效 Cannot create temporary file for download 无法创建下载所需的临时文件 The database has been updated! The old database contained %1 chips, The new database contains %2 chips. 数据库已更新! 旧数据库包含 %1 个芯片, 新数据库包含 %2 个芯片。 Failed to replace the database file 无法替换数据库文件 Downloaded file is too small (corrupted?) 下载的文件过小(可能已损坏?) Download failed: 下载失败: Error loading file: 加载文件时出错: Error: 错误: imsprog-1.8.5/IMSProg_database_update/language/chipUpdater_zh_TW.ts000066400000000000000000000066331520775651600254170ustar00rootroot00000000000000 MainWindow IMSProg database updater 無法建立下載用的暫存檔 IMSProg database updater <html><head/><body><p>The <span style=" font-style:italic;">'IMSProg.Dat'</span> file will be replaced</p><p>with the new version. </p><p>You may lose the changes made to it.</p><p> Continue?</p></body></html> <html><head/><body><p><span style="font-style:italic;">'IMSProg.Dat'</span> 檔案將被</p><p>新版本取代。</p><p>您可能因此遺失對該檔案所做的變更。</p><p> 繼續?</p></body></html> Ok Ok Exit 退出 Downloading file IMSProg.Dat 正在下載檔案 IMSProg.Dat Invalid URL 網址無效 Cannot create temporary file for download 無法替換資料庫檔案 The database has been updated! The old database contained %1 chips, The new database contains %2 chips. 資料庫已更新! 舊資料庫包含 %1 個晶片, 新資料庫包含 %2 個晶片。 Failed to replace the database file 無法替換資料庫檔案 Downloaded file is too small (corrupted?) 下載的檔案過小(可能已損毀?) Download failed: 下載失敗: Error loading file: 載入檔案時發生錯誤: Error: 錯誤: imsprog-1.8.5/IMSProg_database_update/main.cpp000066400000000000000000000060651520775651600213300ustar00rootroot00000000000000/* * Copyright (C) 2026 Mikhail Medvedev * * * 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. */ #include #include #include #include #include #include #include #include "mainwindow.h" static QString setUpTranslation(const QStringList &searchPaths) { QString localeName = QLocale::system().name(); //QString translateName = "chipProgrammer_" + localeName; QString translateName = "chipUpdater_" + localeName; // skip user-specific dir for translations (first one); try the rest foreach (const QString &path, searchPaths.mid(1)) { QTranslator *translator = new QTranslator(qApp); if (translator->load(translateName, path)) { qApp->installTranslator(translator); qDebug() << "Installed" << translateName << "from" << path; return path; } else { delete translator; } } return QString(); } static void initPaths() { QStringList allPaths = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); QDir binDir(QCoreApplication::applicationDirPath()); QString binRelPath = QDir::cleanPath(binDir.absoluteFilePath("../share/" + QCoreApplication::applicationName())); allPaths.append(binRelPath); QDir userAppDataLocation(allPaths.at(0)); if (!userAppDataLocation.exists()) { userAppDataLocation.mkpath("."); // XXX some sort of error handling that befits the application } qApp->setProperty("app/translationDirectory", setUpTranslation(allPaths)); qApp->setProperty("app/userChipDatabaseFile", userAppDataLocation.filePath("IMSProg.Dat")); qApp->setProperty("app/userConfigFile", userAppDataLocation.filePath("config.ini")); qApp->setProperty("app/urlDataFile", "https://antenna-dvb-t2.ru/dl_all/IMSProg.Dat"); qDebug() << "Ini path " << userAppDataLocation.filePath("config.ini"); qDebug() << "User database path " << userAppDataLocation.filePath("IMSProg.Dat"); } int main(int argc, char *argv[]) { qDebug() << "Used Qt version:" << QT_VERSION_STR; qDebug() << "SSL support:" << QSslSocket::supportsSsl(); qDebug() << "Build version:" << QSslSocket::sslLibraryBuildVersionString(); qDebug() << "Runtime version:" << QSslSocket::sslLibraryVersionString(); QApplication a(argc, argv); QCoreApplication::setApplicationName("imsprog"); QFont font("Monospace"); font.setStyleHint(QFont::TypeWriter); font.setPointSize(12); QApplication::setFont(font); initPaths(); MainWindow w; w.show(); return a.exec(); } imsprog-1.8.5/IMSProg_database_update/mainwindow.cpp000066400000000000000000000124421520775651600225540ustar00rootroot00000000000000#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , currentReply(nullptr) , tempFile(nullptr) , lastBytesReceived(0) , totalBytesReceived(0) , oldRecords(0) { ui->setupUi(this); qDebug() << QSslSocket::sslLibraryBuildVersionString(); manager = new QNetworkAccessManager(this); setupConnections(); fileUrl = qApp->property("app/urlDataFile").toString(); fileName = qApp->property("app/userChipDatabaseFile").toString(); ui->progressBar->setRange(0, 100); ui->progressBar->setValue(0); } MainWindow::~MainWindow() { if (currentReply) { currentReply->abort(); currentReply->deleteLater(); } if (tempFile) { tempFile->close(); delete tempFile; } delete ui; } void MainWindow::setupConnections() { connect(ui->startButton, &QPushButton::clicked, this, &MainWindow::startDownload); } void MainWindow::startDownload() { if (currentReply) { currentReply->abort(); currentReply->deleteLater(); currentReply = nullptr; } if (tempFile) { tempFile->close(); delete tempFile; tempFile = nullptr; } totalBytesReceived = 0; lastBytesReceived = 0; // count of chips QFileInfo fileInfo(fileName); if (fileInfo.exists() && fileInfo.size() > 0x44) { oldRecords = static_cast(fileInfo.size() / 0x44 - 1); } else { oldRecords = 0; } if (fileUrl.isEmpty() || fileName.isEmpty()) { return; } ui->statusbar->showMessage(tr("Downloading file IMSProg.Dat")); ui->startButton->setEnabled(false); ui->progressBar->setValue(0); QUrl url(fileUrl); if (!url.isValid()) { showError(tr("Invalid URL")); ui->startButton->setEnabled(true); return; } tempFile = new QTemporaryFile(this); tempFile->setFileTemplate(QDir::tempPath() + "/IMSProg-XXXXXX.Dat"); if (!tempFile->open()) { showError(tr("Cannot create temporary file for download")); ui->startButton->setEnabled(true); return; } QNetworkRequest request(url); currentReply = manager->get(request); connect(currentReply, &QNetworkReply::readyRead, this, &MainWindow::onReadyRead); connect(currentReply, &QNetworkReply::downloadProgress, this, &MainWindow::onDownloadProgress); connect(currentReply, &QNetworkReply::finished, this, &MainWindow::onFinished); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) connect(currentReply, &QNetworkReply::errorOccurred, this, &MainWindow::onError); #else connect(currentReply, QOverload::of(&QNetworkReply::error), this, &MainWindow::onError); #endif } void MainWindow::onReadyRead() { if (currentReply && tempFile) { QByteArray data = currentReply->readAll(); if (!data.isEmpty()) { tempFile->write(data); totalBytesReceived += data.size(); } } } void MainWindow::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { if (bytesTotal > 0) { int percent = static_cast((bytesReceived * 100) / bytesTotal); ui->progressBar->setValue(percent); } } void MainWindow::onFinished() { bool success = false; int newRecords = 0; if (currentReply && currentReply->error() == QNetworkReply::NoError) { if (totalBytesReceived > 0x88) { tempFile->close(); QFile::remove(fileName); if (tempFile->copy(fileName)) { success = true; newRecords = static_cast(totalBytesReceived / 0x44 - 1); ui->progressBar->setValue(100); QString msg = (tr("The database has been updated!\n\nThe old database contained %1 chips,\nThe new database contains %2 chips.")) .arg(oldRecords).arg(newRecords); QMessageBox::information(this, tr("Ok"), msg); } else { showError(tr("Failed to replace the database file")); } } else { showError(tr("Downloaded file is too small (corrupted?)")); } } if (tempFile) { tempFile->close(); delete tempFile; tempFile = nullptr; } if (currentReply) { currentReply->deleteLater(); currentReply = nullptr; } ui->startButton->setEnabled(true); if (!success) { ui->progressBar->setValue(0); } ui->statusbar->clearMessage(); } void MainWindow::onError(QNetworkReply::NetworkError code) { Q_UNUSED(code); if (currentReply) { showError(tr("Error loading file: ") + currentReply->errorString()); currentReply->deleteLater(); currentReply = nullptr; } if (tempFile) { tempFile->close(); delete tempFile; tempFile = nullptr; } ui->startButton->setEnabled(true); ui->progressBar->setValue(0); ui->statusbar->clearMessage(); } void MainWindow::showError(const QString &message) { QMessageBox::critical(this, tr("Error:"), message); } void MainWindow::on_exitButton_clicked() { MainWindow::close(); } imsprog-1.8.5/IMSProg_database_update/mainwindow.h000066400000000000000000000017551520775651600222260ustar00rootroot00000000000000#ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include #include #include QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void startDownload(); void onReadyRead(); void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); void onFinished(); void onError(QNetworkReply::NetworkError code); void on_exitButton_clicked(); private: Ui::MainWindow *ui; QNetworkAccessManager *manager; QNetworkReply *currentReply; QTemporaryFile *tempFile; QElapsedTimer speedTimer; qint64 lastBytesReceived; qint64 totalBytesReceived; int oldRecords; QString fileUrl; QString fileName; void showError(const QString &message); void setupConnections(); }; #endif // MAINWINDOW_H imsprog-1.8.5/IMSProg_database_update/mainwindow.ui000066400000000000000000000064211520775651600224070ustar00rootroot00000000000000 MainWindow 0 0 500 269 IMSProg database updater :/res/img/IMSProg_database_update.png:/res/img/IMSProg_database_update.png 14 75 true <html><head/><body><p>The <span style=" font-style:italic;">'IMSProg.Dat'</span> file will be replaced</p><p>with the new version. </p><p>You may lose the changes made to it.</p><p> Continue?</p></body></html> Qt::AlignCenter Qt::Vertical 20 40 Qt::Horizontal 40 20 Ok Exit Qt::Horizontal 40 20 0 0 0 500 21 imsprog-1.8.5/IMSProg_database_update/other/000077500000000000000000000000001520775651600210125ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_database_update/other/IMSProg_database_update.1.gz000066400000000000000000000016031520775651600261610ustar00rootroot00000000000000^jIMSProg_database_update.1Tn7}W T7$Л㨒 KXr rVKtI.xѥbn.gΜsflrM? y>~W=hx7`bٯt>-aoVǟPAw5}XZKYC ]˭=kq_כtR4<(Xܷ ge[nmN_v _v!`^ו̹Frr;̭SZl%ffVqWd_//W<_<<]\""KoLu@eJ侔x ' +e,ΰ]߬?SKln;02,0b ݴɸbpq2wX-9 af݆QѕsPD"#IAetT#'ߺ%!LB*n-hsMhqU]џLR970ŴX Zœ &a^QRzEO,|onv}{4;Gp$G+=5(_ɿJ.+X8 9KHA><̂oF"!-XC ZvE[z4dt]-ڑm^yc#0T> 㢷F6%nLBNimsprog-1.8.5/IMSProg_database_update/other/IMSProg_database_update.desktop000066400000000000000000000047261520775651600270640ustar00rootroot00000000000000[Desktop Entry] Version=1.0 Type=Application Name=IMSProg_updater Icon=/usr/share/pixmaps/IMSProg_database_update.png Exec=/usr/bin/IMSProg_database_update Path=/usr/bin/ NoDisplay=false Categories=Electronics;Development; StartupNotify=true Terminal=false Comment=Updating the chip database for IMSProg Comment[en]=Updating the chip database for IMSProg Comment[ru]=Обновление базы данных микросхем для IMSProg Comment[es]=Actualización de la base de datos de chips para IMSProg Comment[de]=Die Aktualisierung der Chipdatenbank für IMSProg Comment[uk]=Оновлення бази даних мікросхеми для IMSProg Comment[pt]=Atualização do banco de dados de chips para IMSProg Comment[hu]=A chip adatbázis frissítése az IMSProg számára Comment[it]=Aggiornamento del database dei chip per IMSProg Comment[zh]=更新 IMSProg 芯片数据库 Comment[zh_TW]=更新 IMSProg 晶片資料庫 GenericName=i2c,SPI,MW chips programmer for CH341a devices GenericName[en]=i2c,SPI,MW chips programmer for CH341a devices GenericName[ru]=Обновление базы данных микросхем для IMSProg GenericName[es]=Actualización de la base de datos de chips para IMSProg GenericName[de]=Die Aktualisierung der Chipdatenbank für IMSProg GenericName[uk]=Оновлення бази даних мікросхеми для IMSProg GenericName[pt]=Atualização do banco de dados de chips para IMSProg GenericName[hu]=A chip adatbázis frissítése az IMSProg számára GenericName[it]=Aggiornamento del database dei chip per IMSProg GenericName[zh]=I2C、SPI、MicroWire EEPROM/Flash 芯片 CH341A 编程器 GenericName[zh_TW]=I2C、SPI、MicroWire EEPROM/Flash 晶片 CH341A 燒錄器 Keywords=Microcircuit;Microchip;IC;Integrated circuit Keywords[en]=Microcircuit;Microchip;IC;Integrated circuit Keywords[ru]=Микросхема;Микрочип;ИС;Интегральная схема;chip Keywords[es]=Microcircuito;Microchip;CI;Circuito integrado Keywords[de]=Mikroschaltkreis;Mikrochip;IC;Integrierte Schaltung Keywords[uk]=Мікросхема;Інтегральна схема;chip Keywords[pt]=Microcircuito;Microchip;IC;Circuito integrado Keywords[hu]=Mikroáramkör;Mikrochip;IC;Integrált áramkör;Integrált áramkör Keywords[it]=Microcircuito;Microchip;IC;Circuito integrato Keywords[zh]=微电路;微芯片;集成电路;基本输入输出系统;IC;BIOS;EEPROM;MicroWire Keywords[zh_TW]=微電路;微晶片;積體電路;IC;BIOS;EEPROM;MicroWire imsprog-1.8.5/IMSProg_database_update/other/io.github.bigbigmdm.imsprog_database_update.metainfo.xml000066400000000000000000000375641520775651600340310ustar00rootroot00000000000000 io.github.bigbigmdm.imsprog_database_update GFDL-1.3 GPL-3.0+ IMSProg_database_update.desktop Chip database update script for IMSProg programmer Skript zur Aktualisierung der Chipdatenbank für IMSProg-Programmierer Script de actualización de la base de datos de chips para el programador IMSProg Chip adatbázis frissítő szkript IMSProg programozó számára Script di aggiornamento del database dei chip per il programmatore IMSProg Script de atualização do banco de dados de chips para o programador IMSProg Скрипт обновления базы данных чипов для программатора IMSProg Скрипт оновлення бази даних мікросхем для програматорі IMSProg IMSProg 编程器的芯片数据库更新脚本 IMSProg 燒錄器的晶片資料庫更新腳本 https://github.com/bigbigmdm/IMSProg/tree/main/IMSProg_programmer/img/IMSProg_database_update.png

IMSProg_database_update - online chip database update from the external web-server. IMSProg_database_update uses the zenity graphical Gnome utility. Once started, it copies the downloaded database to the ~/.local/imsprog folder. The script then displays the number of of chips in the database before and after the upgrade.

IMSProg_database_update - Online-Aktualisierung der Chipdatenbank von einem externen Webserver. IMSProg_database_update verwendet das grafische Gnome-Dienstprogramm zenity. Einmal gestartet, kopiert es die heruntergeladene Datenbank in den Ordner ~/.local/imsprog. Das Skript zeigt dann die Anzahl der Chips in der Datenbank vor und nach der Aktualisierung an.

IMSProg_database_update - actualización en línea de la base de datos de chips desde el servidor web externo. IMSProg_database_update utiliza la utilidad gráfica Gnome de zenity. Una vez iniciada, copia la base de datos descargada a la carpeta ~/.local/imsprog. A continuación, el script muestra el número de chips de la base de datos antes y después de la actualización.

IMSProg_database_update - online chipadatbázis frissítés a külső webszerverről. Az IMSProg_database_update a zenity grafikus Gnome segédprogramot használja. Elindítása után a letöltött adatbázist a ~/.local/imsprog mappába másolja. A szkript ezután megjeleníti az adatbázisban lévő chipek számát a frissítés előtt és után.

IMSProg_database_update - aggiornamento online del database dei chip dal server web esterno. IMSProg_database_update utilizza l'utilità grafica Gnome di zenity. Una volta avviato, copia il database scaricato nella cartella ~/.local/imsprog. Lo script visualizza quindi il numero di chip presenti nel database prima e dopo l'aggiornamento.

IMSProg_database_update - atualização on-line do banco de dados de chips a partir do servidor da Web externo. O IMSProg_database_update usa o utilitário gráfico zenity do Gnome. Uma vez iniciado, ele copia o banco de dados baixado para a pasta ~/.local/imsprog. Em seguida, o script exibe o número de chips no banco de dados antes e depois da atualização.

IMSProg_database_update - онлайн обновление базы данных микросхем с внешнего веб-сервера. IMSProg_database_update использует графическую Gnome-утилиту zenity. После запуска он копирует загруженную базу данных в папку ~/.local/imsprog. Затем скрипт отображает количество чипов в базе данных до и после обновления.

IMSProg_database_update - онлайн оновлення бази даних мікросхем із зовнішнього веб-сервера. IMSProg_database_update використовує графічну утиліту Gnome zenity. Після запуску вон копіює завантажену базу даних до теки ~/.local/imsprog. Потім скрипт показує кількість мікросхем у базі даних до і після оновлення.

IMSProg_database_update - 从外部Web服务器在线更新芯片数据库。IMSProg_database_update 使用 Gnome 图形工具 zenity。 启动后,它会将下载的数据库复制到 ~/.local/imsprog 文件夹。然后,脚本会显示升级前后数据库中芯片的数量。

IMSProg_database_update - 從外部網路伺服器在線更新晶片資料庫。IMSProg_database_update 使用 Gnome 圖形工具 zenity。啟動後,它會將下載的資料庫複製到 ~/.local/imsprog 資料夾。然後,腳本會顯示升級前後資料庫中晶片的數量。

Development Electronics Programmer BIOS EEPROM MicroWire IC chip Microcircuit Microchip IC Integrated circuit Mikroschaltkreis Mikrochip Integrierte Schaltung Microcircuito Microchip Circuito integrado Mikroáramkör Mikrochip Integrált áramkör Microcircuito Microchip Circuito integrato Microcircuito Microchip Circuito integrado Микросхема Микрочип Интегральная схема Мікросхема Інтегральна схема 微电路 微芯片 集成电路 微電路 微晶片 積體電路 https://github.com/bigbigmdm/IMSProg/tree/main https://github.com/bigbigmdm https://github.com/bigbigmdm/IMSProg/issues IMSProg_database_update.desktop application/octet-stream Mikhail Medvedev

Fix: the first highlighted area in HexEdit was not being cleared.

Fix: combobox Operations was not reset if chip type changed.

Fix: program crashed if current chip is nothing and combobox Operation changed

Fix: Operations label showed for all chip types.

Added: Support for I2C and SPI FeRAM chips.

I2C 5v0 images on info form.

Fixed: segmentation fault in Qt6.

Fixed: incorrect interface display on macOS.

Fixed: write error to sector 0 in Windows.

Fixed: incorrect saving of the database file in the chip editor.

Fixed: unable to erase the 93C66, 93C76 and 93C86 chips.

Fixed: the font is too large in Qt6.

Added: migration to Qt6.

Added: universal Qt5/Qt6 CmakeLists.txt.

Added: specification file for Fedora.

Added: support for the spare area for NAND flash memory.

Fixed: If no chip is selected, the programmer was not detected.

Fixed: MACOS library compatibility.

Fixed: MACOS invalid pathes.

Fixed: libusb detection.

Fixed: udev rules install

Added: 2.5v VCC item

SPI NOR FLASH writing speed increased

Changed chip database update bash script to Qt app

The Zenity package is no longer used

Fixed: Error reading/writing data from I2C chips on the CH347T version 5.44.

Fixed: Bit error during NOR/NAND operations in the CH347V1.1 programmer.

Added: Showing the programmer revision function

Added: Erase check function

Added: Filling code function

Added: Support for the CH347T programmer.

Fixed: Incorrect chip page sizes values removed.

Increased interface speed and SPI NOR Flash erase speed.

SPI NOR Flash write speed increased by 30%.

Fixed: Incorrect HexEdit size when starting the program.

Added: When closing the program, the programmer type, chip image directory, and main window size are saved in the ini file.

Fixed: NAND Flash information form freeze.

Added: Programmer type menu.

Added: New images for CH341A v1.7.

Added: support for the AT24CM02 chip.

Fixed: pressing the Stop key did not stop auto operations.

Added: New feature - support for SPI NAND flash.

Fixed: program crashed if security registers was less than 256 bytes.

Fixed: Information in the status bar disappears when hovering over a menu.

Added: close and minimise buttons for subordinate forms.

Added: comparison of INTEL HEX and ASUS CAP with other files.

Added: new chips to the database.

Fixed: when the page size is changed, the buffer is cleared.

Fixed: the code is executed twice and the code slows down the display of the interface.

Added: New feature - compare files.

Added: New feature - fill test array.

Copyright information updated.

Fixed: incorrect uninstall script.

Fixed: i2C 128K size is repeated twice.

Fixed: error calculating file size.

Added: Last version of QHexEdit used.

Added: Hex-functions optimised.

Added: Added support GIANTEC, DOSILICON NOR FLASH chips.

Fixed: Gigadevice status registers write error.

Fixed: Memory leaks.

Added: New SPI chip sizes added.

Added: New Boya, Winbond chips added to database.

Added: Fidelix, Zetta, MXIC OTP algorithm.

Fixed: Incorrect install dir for udev while cross compiling.

Added: Form for working with security registers for SPI NOR flash memory chips.

Fixed: Incorrect block/page size after first read procedure.

Fixed: Incorrect reading/writing I2C low speed chips.

Added support for MXIC MX25V8035F

Added I2C bus speed combobox to the main form

Fixed: In the Save menu, the cancel button causes an error message.

Fixed: Incorrect names of DataFlash chips.

Fixed: incorrect reading of the DataFlash chips status register.

Fedora repository added

MacOS build support added

Uninstall script added

Fixed: On the GNOME desktop, programm does not respond when erasing SPI NOR FLASH.

Fixed: The progress bar did not display correctly when SPI NOR FLASH was erased.

Fixed: When erasing SPI NOR Flash, the STOP button does not work.

Corrected German translation

German translator added to copyright

Corrected chip database

Added AT45DBxx series SPI FLASH (Menu item type -> 45_EEPROM)

The inline images of the chip adapters have been changed.

Fixed metadata errors and warnings.

Fixed: There is a spelling error in in 99-CH341.rules.

Fixed: (metadata changed): appstream-metadata-missing-modalias-provide usr/lib/udev/rules.d/99-CH341.rules

Splitting long lines in README.md

Removed language .qm files - it is generated when the package is built.

Removed unused tags from language files.

This stable release fixes bugs, updated translations, translate chip database update script.

This stable release, updated translations.

e-ink-reader@yandex.ru
imsprog-1.8.5/IMSProg_database_update/resource.qrc000066400000000000000000000001611520775651600222250ustar00rootroot00000000000000 img/IMSProg_database_update.png imsprog-1.8.5/IMSProg_editor/000077500000000000000000000000001520775651600160515ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_editor/CMakeLists.txt000066400000000000000000000130201520775651600206050ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.10.0) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) project(IMSProg_editor LANGUAGES CXX) # Set the CMAKE_INSTALL_PREFIX to /usr if not specified and /usr/local for macOS if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "The default install prefix on macOS" FORCE) # Set up Qt paths on macOS # If user hasn't set CMAKE_PREFIX_PATH, try to find Qt automatically if(NOT CMAKE_PREFIX_PATH) # Check for Qt6 via Homebrew if(EXISTS "/usr/local/opt/qt@6") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@6" CACHE PATH "Path to Qt6 on macOS" FORCE) message(STATUS "Found Qt6 at /usr/local/opt/qt@6") # Check for Qt5 via Homebrew elseif(EXISTS "/usr/local/opt/qt@5") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@5" CACHE PATH "Path to Qt5 on macOS" FORCE) message(STATUS "Found Qt5 at /usr/local/opt/qt@5") # Standard Qt path from Homebrew (without version) elseif(EXISTS "/usr/local/opt/qt") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt" CACHE PATH "Path to Qt on macOS" FORCE) message(STATUS "Found Qt at /usr/local/opt/qt") endif() endif() else() set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "The default install prefix" FORCE) endif() endif() # Set the CMAKE_INSTALL_BINDIR to /bin if not specified if(NOT DEFINED CMAKE_INSTALL_BINDIR) set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)") endif() # Set the CMAKE_INSTALL_DATAROOTDIR to /share if not specified if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR) set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)") endif() list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # Option to force using Qt5 option(FORCE_QT5 "Force using Qt5 instead of Qt6" OFF) if(FORCE_QT5) message(STATUS "Forced Qt5 mode for IMSProg_editor") # On macOS, additionally check the path to Qt5 if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT CMAKE_PREFIX_PATH) if(EXISTS "/usr/local/opt/qt@5") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@5" CACHE PATH "Path to Qt5 on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt@5 for Qt5") elseif(EXISTS "/usr/local/opt/qt") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt" CACHE PATH "Path to Qt on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt for Qt5") endif() endif() find_package(Qt5 REQUIRED COMPONENTS Core Widgets LinguistTools) set(QT_VERSION_MAJOR 5) else() # First try Qt6 find_package(Qt6 QUIET COMPONENTS Core Widgets) if(TARGET Qt6::Core AND TARGET Qt6::Widgets) message(STATUS "Using Qt6 for IMSProg_editor") set(QT_VERSION_MAJOR 6) find_package(Qt6LinguistTools REQUIRED) else() message(STATUS "Qt6 not found, using Qt5 for IMSProg_editor") # On macOS, additionally check the path to Qt5 if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT CMAKE_PREFIX_PATH) if(EXISTS "/usr/local/opt/qt@5") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@5" CACHE PATH "Path to Qt5 on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt@5 for Qt5") elseif(EXISTS "/usr/local/opt/qt") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt" CACHE PATH "Path to Qt on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt for Qt5") endif() endif() find_package(Qt5 REQUIRED COMPONENTS Core Widgets LinguistTools) set(QT_VERSION_MAJOR 5) endif() endif() # Translation files set(TS_FILES language/chipEditor_ru_RU.ts language/chipEditor_de_DE.ts language/chipEditor_es_ES.ts language/chipEditor_zh_CN.ts language/chipEditor_zh_TW.ts language/chipEditor_uk_UA.ts language/chipEditor_hu_HU.ts language/chipEditor_pt_BR.ts language/chipEditor_it_IT.ts ) if (QT_VERSION_MAJOR EQUAL 5) qt5_add_translation(QM_FILES ${TS_FILES}) else() qt_add_translation(QM_FILES ${TS_FILES}) endif() add_custom_target(translations1 DEPENDS ${QM_FILES}) add_executable(${PROJECT_NAME} ezp_chip_editor.h ezp_chip_editor.cpp ezp_chip_editor.ui main.cpp delegates.h delegates.cpp resources.qrc ${QM_FILES} ) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) if (QT_VERSION_MAJOR EQUAL 5) target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Widgets) else() target_link_libraries(${PROJECT_NAME} Qt::Core Qt::Widgets) endif() install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/IMSProg_editor.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") endif() install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/img/chipEdit64.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pixmaps") install(FILES ${QM_FILES} DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/imsprog") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/IMSProg_editor.1.gz" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/man/man1") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/io.github.bigbigmdm.imsprog_editor.metainfo.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") imsprog-1.8.5/IMSProg_editor/IMSProg_editor.pro000066400000000000000000000050521520775651600214230ustar00rootroot00000000000000#------------------------------------------------- # # Project created by QtCreator 2023-05-26T10:45:36 # #------------------------------------------------- # # This file is part of the EZP_Chip_Editor project. # # Copyright (C) 2023 Mikhail Medvedev (e-ink-reader@yandex.ru) # # 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 St, Fifth Floor, Boston, MA 02110-1301 USA # # verbose functionality forked from https://github.com/bigbigmdm/EZP2019-EZP2025_chip_data_editor # # QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = IMSProg_editor TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 CONFIG += c++11 SOURCES += \ main.cpp \ ezp_chip_editor.cpp \ delegates.cpp HEADERS += \ ezp_chip_editor.h \ delegates.h FORMS += \ ezp_chip_editor.ui TRANSLATIONS += language/chipEditor_ru_RU.ts \ language/chipEditor_es_ES.ts \ language/chipEditor_hu_HU.ts \ language/chipEditor_de_DE.ts \ language/chipEditor_zh_CN.ts \ language/chipEditor_zh_TW.ts \ language/chipEditor_uk_UA.ts \ language/chipEditor_pt_BR.ts \ language/chipEditor_it_IT.ts # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target RESOURCES += \ resources.qrc DISTFILES += imsprog-1.8.5/IMSProg_editor/LICENSE000066400000000000000000001045151520775651600170640ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. 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 them 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 prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. 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. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey 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; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If 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 convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU 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 that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. 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. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 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. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. 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 state 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program 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, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU 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. But first, please read . imsprog-1.8.5/IMSProg_editor/README.md000066400000000000000000000023751520775651600173370ustar00rootroot00000000000000# EZP2019-EZP2025_chip_data_editor Qt based editor chip database for EZP2019, EZP2019+, EZP2020, EZP2023, EZP2025, MinPro, XP866+, MinproI programmer devices. ![Screenshot editor](https://github.com/bigbigmdm/EZP2019-EZP2025_chip_data_editor/blob/main/img/ezp_editor.png) Press the button ![read](img/open.png) for open the database file (Depending on the name of your programmer device EZP2019.Dat, EZP2020.Dat, EZP2023+.Dat, EZP2025.Dat, XP866+.Dat, MinproI.Dat). For save the changes to binary file press the button save ![save](img/save.png). For deleting the strings select one or more strings and press the delete button ![delete](img/del.png). You can moving the selected string use the arrow buttons (![undo](img/undo.png) and ![redo](img/redo.png)). You can copying the selected string use the plus button ![plus](img/plus.png). The selected strings may be converted info .CSV format by pressing the button ![tocsv](img/tocsv.png). If you want convert all strings in to .CSV file use the `Export to CSV` ![tocsv](img/tocsv.png) in `File` menu. If you want import .CSV database in to program use `Import from CSV` ![import](img/import.png) in `File` menu. Any cell is editable. ## Building ``` mkdir build cd build cmake .. make -j4 sudo make install ``` imsprog-1.8.5/IMSProg_editor/delegates.cpp000066400000000000000000000145141520775651600205170ustar00rootroot00000000000000/* * This file is part of the EZP_Chip_Editor project. * * Copyright (C) 2023 Mikhail Medvedev (e-ink-reader@yandex.ru) * * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * * verbose functionality forked from https://github.com/bigbigmdm/EZP2019-EZP2025_chip_data_editor * */ #include "delegates.h" #include #include chTypeDelegate::chTypeDelegate(QObject *parent): QItemDelegate(parent) { } QWidget *chTypeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { QComboBox *editor = new QComboBox(parent); editor->addItem("SPI_FLASH"); editor->addItem("25_EEPROM"); editor->addItem("93_EEPROM"); editor->addItem("24_EEPROM"); editor->addItem("95_EEPROM"); editor->addItem("45_EEPROM"); editor->addItem("SPI_NAND"); return editor; } void chTypeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QString text = index.model()->data(index, Qt::EditRole).toString(); QComboBox *comboBox = static_cast(editor); int tindex = comboBox->findText(text); comboBox->setCurrentIndex(tindex); } void chTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QComboBox *comboBox = static_cast(editor); QString text = comboBox->currentText(); model->setData(index, text, Qt::EditRole); } void chTypeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { editor->setGeometry(option.rect); } chVCCDelegate::chVCCDelegate(QObject *parent): QItemDelegate(parent) { } QWidget *chVCCDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { QComboBox *editor = new QComboBox(parent); editor->addItem("5.0 V"); editor->addItem("2.5 V"); editor->addItem("3.3 V"); editor->addItem("1.8 V"); return editor; } void chVCCDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QString text = index.model()->data(index, Qt::EditRole).toString(); QComboBox *comboBox = static_cast(editor); int tindex = comboBox->findText(text); comboBox->setCurrentIndex(tindex); } void chVCCDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QComboBox *comboBox = static_cast(editor); QString text = comboBox->currentText(); model->setData(index, text, Qt::EditRole); } void chVCCDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { editor->setGeometry(option.rect); } chPagesDelegate::chPagesDelegate(QObject *parent): QItemDelegate(parent) { } QWidget *chPagesDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { QComboBox *editor = new QComboBox(parent); editor->addItem("0x00"); editor->addItem("0x01"); editor->addItem("0x02"); editor->addItem("0x04"); return editor; } void chPagesDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QString text = index.model()->data(index, Qt::EditRole).toString(); QComboBox *comboBox = static_cast(editor); int tindex = comboBox->findText(text); comboBox->setCurrentIndex(tindex); } void chPagesDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QComboBox *comboBox = static_cast(editor); QString text = comboBox->currentText(); model->setData(index, text, Qt::EditRole); } void chPagesDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { editor->setGeometry(option.rect); } chBlSizeDelegate::chBlSizeDelegate(QObject *parent): QItemDelegate(parent) { } QWidget *chBlSizeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { QComboBox *editor = new QComboBox(parent); editor->addItem("1"); editor->addItem("2"); editor->addItem("4"); editor->addItem("8"); editor->addItem("16"); editor->addItem("32"); editor->addItem("64"); editor->addItem("128"); editor->addItem("256"); editor->addItem("264"); editor->addItem("512"); editor->addItem("528"); editor->addItem("1024"); editor->addItem("2048"); editor->addItem("4096"); return editor; } void chBlSizeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QString text = index.model()->data(index, Qt::EditRole).toString(); QComboBox *comboBox = static_cast(editor); int tindex = comboBox->findText(text); comboBox->setCurrentIndex(tindex); } void chBlSizeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QComboBox *comboBox = static_cast(editor); QString text = comboBox->currentText(); model->setData(index, text, Qt::EditRole); } void chBlSizeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { editor->setGeometry(option.rect); } imsprog-1.8.5/IMSProg_editor/delegates.h000066400000000000000000000065401520775651600201640ustar00rootroot00000000000000/* * This file is part of the EZP_Chip_Editor project. * * Copyright (C) 2023 Mikhail Medvedev (e-ink-reader@yandex.ru) * * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * * verbose functionality forked from https://github.com/bigbigmdm/EZP2019-EZP2025_chip_data_editor * */ #ifndef DELEGATES_H #define DELEGATES_H #include #include #include class chTypeDelegate : public QItemDelegate { Q_OBJECT public: explicit chTypeDelegate(QObject *parent); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; signals: public slots: //virtual ~chTypeDelegate() {} }; class chVCCDelegate : public QItemDelegate { Q_OBJECT public: explicit chVCCDelegate(QObject *parent); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; signals: public slots: //virtual ~chVCCDelegate() {} }; class chPagesDelegate : public QItemDelegate { Q_OBJECT public: explicit chPagesDelegate(QObject *parent); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; signals: public slots: //virtual ~chPagesDelegate() {} }; class chBlSizeDelegate : public QItemDelegate { Q_OBJECT public: explicit chBlSizeDelegate(QObject *parent); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; signals: public slots: //virtual ~chBlSizeDelegate() {} }; #endif // DELEGATES_H imsprog-1.8.5/IMSProg_editor/ezp_chip_editor.cpp000066400000000000000000000773311520775651600217370ustar00rootroot00000000000000/* * This file is part of the IMSProg_Editor project. * * Copyright (C) 2023-2026 Mikhail Medvedev (e-ink-reader@yandex.ru) * * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * * verbose functionality forked from https://github.com/bigbigmdm/EZP2019-EZP2025_chip_data_editor * */ #include "ezp_chip_editor.h" #include "ui_ezp_chip_editor.h" #include "delegates.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_actionOpen_triggered() { QString fileName, currentPath, userPath, systemPath; char txtBuf[0x30]; userPath = qApp->property("app/userChipDatabaseFile").toString(); systemPath = qApp->property("app/systemChipDatabaseFile").toString(); defaultPath = QDir::homePath(); // QFileInfo check_benchmarkDataFile(benchmarkDataFile); int i, j, recNo, dataPoz, dataSize, chipSize, blockSize, delay, rowCount; unsigned char chipSizeCode, chipID, manCode, tmpBuf; // if ~//.local/share/imsprog/ is not exists opening file from /usr/share/imsprog/ if (QFile::exists(userPath)) currentPath = userPath; else if (QFile::exists(systemPath)) currentPath = systemPath; else currentPath = defaultPath; defaultPath = currentPath; ui->statusBar->showMessage(tr("Open the file")); fileName = QFileDialog::getOpenFileName(this, QString(tr("Open the file")), currentPath, "Data Images (*.Dat);;All files (*.*)"); ui->statusBar->showMessage(tr("Current file: ") + fileName); QFile file(fileName); QByteArray data; if (!file.open(QIODevice::ReadOnly)) return; data = file.readAll(); file.close(); dataPoz = 0; recNo = 0; if(ui->tableView->model() != nullptr) { rowCount = ui->tableView->model()->rowCount(); for (i=0; itableView->model()->removeRow(i); } QThread::sleep(2); ui->tableView->reset(); } dataSize = data.length(); ui->tableView->setShowGrid(true); //Column headings QStringList horizontalHeader; //horizontalHeader.append("No"); horizontalHeader.append(tr("Type")); horizontalHeader.append(tr("Manufacturer")); horizontalHeader.append(tr("IC Name")); horizontalHeader.append(tr("JEDEC ID")); horizontalHeader.append(tr("Size")); horizontalHeader.append(tr("Sector\nsize")); horizontalHeader.append(tr("Type\nHEX")); horizontalHeader.append(tr("Algo-\nrithm")); horizontalHeader.append(tr("Delay")); horizontalHeader.append(tr("4 bit\naddress")); horizontalHeader.append(tr("Block\nsize K")); horizontalHeader.append(tr("EEPROM\npages")); horizontalHeader.append(tr("VCC")); model->setHorizontalHeaderLabels(horizontalHeader); //parsing qbytearray QStringList verticalHeader; while (dataPoz < dataSize) { for (j=0; j<0x30; j++) { txtBuf[j] = 0; } j = 0; while ((j < 0x10) && (data[recNo * 0x44 + j] != ',')) // ASCII data reading { txtBuf[j] = data[recNo * 0x44 + j]; j++; } if (txtBuf[1] == 0x00) break; chips[recNo].chipTypeTxt = QByteArray::fromRawData(txtBuf, j); for (i=0; i<0x30; i++) { txtBuf[i] = 0; } j++; i = 0; while ((i < 0x20) && (data[recNo * 0x44 + j] != ',')) // ASCII data reading { txtBuf[i] = data[recNo * 0x44 + j]; j++; i++; } chips[recNo].chipManuf = QByteArray::fromRawData(txtBuf, i); for (i=0; i<0x30; i++) { txtBuf[i] = 0; } j++; i = 0; while ((i < 0x30) && (data[recNo * 0x44 + j] != '\0')) // ASCII data reading { txtBuf[i] = data[recNo * 0x44 + j]; j++; i++; } chips[recNo].chipName = QByteArray::fromRawData(txtBuf, i); chipSizeCode = data[recNo * 0x44 + 0x30]; chipID = data[recNo * 0x44 + 0x31];; manCode = data[recNo * 0x44 + 0x32]; chips[recNo].chipJedecID = "0x" + bytePrint(manCode) + bytePrint(chipID) + bytePrint(chipSizeCode); tmpBuf = data[recNo * 0x44 + 0x34]; chipSize = tmpBuf; tmpBuf = data[recNo * 0x44 + 0x35]; chipSize = chipSize + tmpBuf * 256; tmpBuf = data[recNo * 0x44 + 0x36]; chipSize = chipSize + tmpBuf * 256 * 256; tmpBuf = data[recNo * 0x44 + 0x37]; chipSize = chipSize + tmpBuf * 256 * 256 * 256; chips[recNo].chipSize = sizeConvert(chipSize); tmpBuf = data[recNo * 0x44 + 0x38]; blockSize = tmpBuf; tmpBuf = data[recNo * 0x44 + 0x39]; blockSize = blockSize + tmpBuf * 256; chips[recNo].blockSize = QString::number(blockSize); tmpBuf = data[recNo * 0x44 + 0x3a]; chips[recNo].chipTypeHex = "0x" + bytePrint(tmpBuf); tmpBuf = data[recNo * 0x44 + 0x3b]; chips[recNo].algorithmCode = "0x" + bytePrint(tmpBuf); tmpBuf = data[recNo * 0x44 + 0x3c]; delay = tmpBuf; tmpBuf = data[recNo * 0x44 + 0x3d]; delay = delay + tmpBuf * 256; chips[recNo].delay = QString::number(delay); tmpBuf = data[recNo * 0x44 + 0x3e]; chips[recNo].extend = "0x" + bytePrint(tmpBuf); tmpBuf = data[recNo * 0x44 + 0x3f]; chips[recNo].eeprom = "0x" + bytePrint(tmpBuf); tmpBuf = data[recNo * 0x44 + 0x40]; chips[recNo].eeprom =chips[recNo].eeprom + bytePrint(tmpBuf); tmpBuf = data[recNo * 0x44 + 0x42]; chips[recNo].eepromPages = "0x" + bytePrint(tmpBuf); tmpBuf = data[recNo * 0x44 + 0x43]; if (tmpBuf == 0x00) chips[recNo].chipVCC = "3.3 V"; if (tmpBuf == 0x01) chips[recNo].chipVCC = "1.8 V"; if (tmpBuf == 0x02) chips[recNo].chipVCC = "5.0 V"; if (tmpBuf == 0x03) chips[recNo].chipVCC = "2.5 V"; dataPoz = dataPoz + 0x44; //next record verticalHeader.append(QString::number(recNo)); item = new QStandardItem(chips[recNo].chipTypeTxt); model->setItem(recNo, 0, item); if(chips[recNo].chipTypeTxt.compare("SPI_FLASH")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xcc, 0xff, 0xff))); else if(chips[recNo].chipTypeTxt.compare("24_EEPROM")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xff, 0xff, 0xcc))); else if(chips[recNo].chipTypeTxt.compare("93_EEPROM")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xff, 0xcc, 0xcc))); else if(chips[recNo].chipTypeTxt.compare("95_EEPROM")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xcc, 0xff, 0xcc))); else if(chips[recNo].chipTypeTxt.compare("25_EEPROM")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xff, 0xcc, 0xff))); else if(chips[recNo].chipTypeTxt.compare("45_EEPROM")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xcc, 0xcc, 0xff))); else if(chips[recNo].chipTypeTxt.compare("SPI_NAND")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xcc, 0xcc, 0xcc))); item = new QStandardItem(chips[recNo].chipManuf); model->setItem(recNo, 1, item); item = new QStandardItem(chips[recNo].chipName); model->setItem(recNo, 2, item); item = new QStandardItem(chips[recNo].chipJedecID); model->setItem(recNo, 3, item); item = new QStandardItem(chips[recNo].chipSize); model->setItem(recNo, 4, item); item = new QStandardItem(chips[recNo].blockSize); model->setItem(recNo, 5, item); item = new QStandardItem(chips[recNo].chipTypeHex); model->setItem(recNo, 6, item); item = new QStandardItem(chips[recNo].algorithmCode); model->setItem(recNo, 7, item); item = new QStandardItem(chips[recNo].delay); model->setItem(recNo, 8, item); item = new QStandardItem(chips[recNo].extend); model->setItem(recNo, 9, item); item = new QStandardItem(chips[recNo].eeprom); model->setItem(recNo, 10, item); item = new QStandardItem(chips[recNo].eepromPages); model->setItem(recNo, 11, item); item = new QStandardItem(chips[recNo].chipVCC); model->setItem(recNo, 12, item); recNo++; } //String headers model->setVerticalHeaderLabels(verticalHeader); ui->tableView->setStyleSheet("QTableView { border: none;" "selection-background-color: #8EDE21;" "}"); ui->tableView->setModel(model); ui->tableView->resizeRowsToContents(); ui->tableView->resizeColumnsToContents(); //--combobox in firsrt colunm chTypeDelegate* delegateType = new chTypeDelegate(this); ui->tableView->setItemDelegateForColumn(0,delegateType); //--combobox-last-colunm chVCCDelegate* delegateVCC = new chVCCDelegate(this); ui->tableView->setItemDelegateForColumn(12,delegateVCC); //--combobox Pages chPagesDelegate* delegatePages = new chPagesDelegate(this); ui->tableView->setItemDelegateForColumn(11,delegatePages); //-combobox Block Size chBlSizeDelegate* delegateBlSize = new chBlSizeDelegate(this); ui->tableView->setItemDelegateForColumn(5,delegateBlSize); connect(ui->tableView->model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(onDataChanged(const QModelIndex&, const QModelIndex&))); } void MainWindow::on_actionExit_triggered() { QApplication::quit(); } QString MainWindow::bytePrint(unsigned char z) { unsigned char s; s = z / 16; if (s > 0x9) s = s + 0x37; else s = s + 0x30; z = z % 16; if (z > 0x9) z = z + 0x37; else z = z + 0x30; return QString(static_cast(s)) + QString(static_cast(z)); } QString MainWindow::sizeConvert(int a) { QString rez; rez = "0"; if (a < 1024) rez = QString::number(a) + " B"; else if ((a < 1024 * 1024) || (a % (1024 * 1024) > 0)) rez = QString::number(a/1024) + " K"; else rez = QString::number(a/1024/1024) + " M"; return rez; } void MainWindow::onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { if(ui->tableView->model() != nullptr) { QModelIndex ind; QString tmpStr; int row; row = ui->tableView->currentIndex().row(); if (row >= 0) { ind = model->index(row, 0, QModelIndex()); tmpStr = ui->tableView->model()->data(ind).toString(); if(tmpStr.compare("SPI_FLASH")==0) model->item(row, 0)->setBackground(QBrush(QColor(0xcc, 0xff, 0xff))); else if(tmpStr.compare("24_EEPROM")==0) model->item(row, 0)->setBackground(QBrush(QColor(0xff, 0xff, 0xcc))); else if(tmpStr.compare("93_EEPROM")==0) model->item(row, 0)->setBackground(QBrush(QColor(0xff, 0xcc, 0xcc))); else if(tmpStr.compare("95_EEPROM")==0) model->item(row, 0)->setBackground(QBrush(QColor(0xcc, 0xff, 0xcc))); else if(tmpStr.compare("25_EEPROM")==0) model->item(row, 0)->setBackground(QBrush(QColor(0xff, 0xcc, 0xff))); else if(tmpStr.compare("45_EEPROM")==0) model->item(row, 0)->setBackground(QBrush(QColor(0xcc, 0xcc, 0xff))); else if(tmpStr.compare("SPI_NAND")==0) model->item(row, 0)->setBackground(QBrush(QColor(0xcc, 0xcc, 0xcc))); else model->item(row, 0)->setBackground(QBrush(QColor(0xff, 0xff, 0xff))); } } } void MainWindow::on_actionSave_triggered() { //creating new QBytearray to saving uint32_t size; unsigned char A,B,C,D; QString fileName; QString tmpStr; QModelIndex index; int i, j, recNo, delitel; QByteArray toSave; int rowCount = 0; if(ui->tableView->model() != nullptr) { ui->tableView->update(); rowCount = ui->tableView->model()->rowCount(); toSave.resize(0x44 * (rowCount + 1)); toSave.fill(0x00); for (recNo = 0; recNo < rowCount; recNo++) { for (int j=0; j<13; j++) { index = model->index(recNo, j, QModelIndex()); tmpStr = ui->tableView->model()->data(index).toString(); switch (j) { case 0: { chips[recNo].chipTypeTxt = tmpStr; break; } case 1: { chips[recNo].chipManuf = tmpStr; break; } case 2: { chips[recNo].chipName = tmpStr; break; } case 3: { chips[recNo].chipJedecID = tmpStr; break; } case 4: { chips[recNo].chipSize = tmpStr; break; } case 5: { chips[recNo].blockSize = tmpStr; break; } case 6: { chips[recNo].chipTypeHex = tmpStr; break; } case 7: { chips[recNo].algorithmCode = tmpStr; break; } case 8: { chips[recNo].delay = tmpStr; break; } case 9: { chips[recNo].extend = tmpStr; break; } case 10: { chips[recNo].eeprom = tmpStr; break; } case 11: { chips[recNo].eepromPages = tmpStr; break; } case 12: { chips[recNo].chipVCC = tmpStr; break; } } } } //for (recNo = 0; recNo < rowCount-1; recNo++) recNo = 0; while (recNo < rowCount) { QByteArray ba = chips[recNo].chipTypeTxt.toUtf8(); for (i = 0; i < ba.size(); i++) { toSave[recNo * 0x44 + i] = ba[i]; } toSave[recNo * 0x44 + i] = ','; i++; j = i; QByteArray bb = chips[recNo].chipManuf.toUtf8(); for (i = 0; i < bb.size(); i++) { toSave[recNo * 0x44 + j] = bb[i]; j++; } toSave[recNo * 0x44 + j] = ','; j++; QByteArray bc = chips[recNo].chipName.toUtf8(); for (i = 0; i < bc.size(); i++) { toSave[recNo * 0x44 + j] = bc[i]; j++; } //next bytes tmpStr = chips[recNo].chipJedecID; if ((tmpStr[0] == '0') && (tmpStr[1] == 'x')) { toSave[recNo * 0x44 + 0x30] = dualDigitToByte(tmpStr, 2); toSave[recNo * 0x44 + 0x31] = dualDigitToByte(tmpStr, 1); toSave[recNo * 0x44 + 0x32] = dualDigitToByte(tmpStr, 0); } toSave[recNo * 0x44 + 0x33] = 0x00; tmpStr = chips[recNo].chipSize; if (tmpStr[tmpStr.size() - 1] == 'B') delitel = 1; if (tmpStr[tmpStr.size() - 1] == 'K') delitel = 1024; if (tmpStr[tmpStr.size() - 1] == 'M') delitel = 1024 * 1024; tmpStr = tmpStr.mid(0, tmpStr.size() - 2); size = tmpStr.toInt() * delitel; A = size % 256; B = (size / 256) % 256; C = (size / 256 / 256) % 256; D = (size / 256 / 256 / 256) % 256; toSave[recNo * 0x44 + 0x34] = A; toSave[recNo * 0x44 + 0x35] = B; toSave[recNo * 0x44 + 0x36] = C; toSave[recNo * 0x44 + 0x37] = D; tmpStr = chips[recNo].blockSize; size = tmpStr.toInt(); A = size % 256; B = (size / 256) % 256; toSave[recNo * 0x44 + 0x38] = A; toSave[recNo * 0x44 + 0x39] = B; tmpStr = chips[recNo].chipTypeHex; if ((tmpStr[0] == '0') && (tmpStr[1] == 'x')) { toSave[recNo * 0x44 + 0x3A] = dualDigitToByte(tmpStr, 0); } tmpStr = chips[recNo].algorithmCode; if ((tmpStr[0] == '0') && (tmpStr[1] == 'x')) { toSave[recNo * 0x44 + 0x3b] = dualDigitToByte(tmpStr, 0); } tmpStr = chips[recNo].delay; size = tmpStr.toInt(); A = size % 256; B = (size / 256) % 256; toSave[recNo * 0x44 + 0x3c] = A; toSave[recNo * 0x44 + 0x3d] = B; tmpStr = chips[recNo].extend; if ((tmpStr[0] == '0') && (tmpStr[1] == 'x')) { toSave[recNo * 0x44 + 0x3e] = dualDigitToByte(tmpStr, 0); } tmpStr = chips[recNo].eeprom; if ((tmpStr[0] == '0') && (tmpStr[1] == 'x')) { toSave[recNo * 0x44 + 0x3f] = dualDigitToByte(tmpStr, 0); toSave[recNo * 0x44 + 0x40] = dualDigitToByte(tmpStr, 1); } toSave[recNo * 0x44 + 0x41] = 0x00; tmpStr = chips[recNo].eepromPages; if ((tmpStr[0] == '0') && (tmpStr[1] == 'x')) { toSave[recNo * 0x44 + 0x42] = dualDigitToByte(tmpStr, 0); } tmpStr = chips[recNo].chipVCC; if (tmpStr[4] == 'V') { if(tmpStr.compare("3.3 V")==0) toSave[recNo * 0x44 + 0x43] = 0x00; if(tmpStr.compare("5.0 V")==0) toSave[recNo * 0x44 + 0x43] = 0x02; if(tmpStr.compare("1.8 V")==0) toSave[recNo * 0x44 + 0x43] = 0x01; if(tmpStr.compare("2.5 V")==0) toSave[recNo * 0x44 + 0x43] = 0x03; } recNo++; } // 0x44 zero bytes for (i = 0; i < 0x44; i++ ) { toSave[recNo * 0x44 + i] = 0x00; } //Saving Qbytearray to file // If IMSProg.dat does not exist in the /.local/share/imsprog/ folder, create this folder qDebug() << defaultPath <<" "; if (!QDir(defaultPath).exists()) QDir().mkdir(defaultPath); ui->statusBar->showMessage("Saving file"); fileName = QFileDialog::getSaveFileName(this, QString::fromUtf8("Saving file"), (defaultPath + "/IMSProg.Dat"), "Data Images (*.Dat);;All files (*.*)"); ui->statusBar->showMessage("Current file: " + fileName); QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) return; file.write(toSave); file.close(); } } unsigned char MainWindow::dualDigitToByte(QString q, int poz) { unsigned char buf, rez; if (poz < 3) { poz = poz *2; buf = q[poz + 2].toLatin1(); if ((buf >= '0') && (buf <= '9')) buf = buf - 0x30; if ((buf >= 'A') && (buf <= 'F')) buf = buf - 0x37; if ((buf >= 'a') && (buf <= 'f')) buf = buf - 0x57; rez = buf * 0x10; buf = q[poz + 3].toLatin1(); if ((buf >= '0') && (buf <= '9')) buf = buf - 0x30; if ((buf >= 'A') && (buf <= 'F')) buf = buf - 0x37; if ((buf >= 'a') && (buf <= 'f')) buf = buf - 0x57; rez = rez + buf; return rez; } else return 0; } void MainWindow::on_actionAdd_string_triggered() { QModelIndex indFrom, indTo; QString tmpStr; int sel, decsel; if(ui->tableView->model() != nullptr) { QItemSelectionModel *select = ui->tableView->selectionModel(); select->selectedRows(); QModelIndexList selection = ui->tableView->selectionModel()->selectedRows(); if (selection.count() <=0) { QMessageBox::warning(this, tr("Warning"), tr("No string selected.")); return; } // Multiple rows can be selected for(int i=0; i< selection.count(); i++) { QModelIndex index = selection.at(i); ui->tableView->model()->insertRow(index.row() - i +1); ui->tableView->update(); sel = index.row() - i +1; decsel = sel -1; for (int j=0; j<13; j++) { indFrom = model->index(sel, j, QModelIndex()); indTo = model->index(decsel, j, QModelIndex()); tmpStr = ui->tableView->model()->data(indTo).toString(); ui->tableView->model()->setData(indFrom, tmpStr); ui->tableView->selectRow(decsel); } ui->tableView->update(); ui->tableView->resizeRowsToContents(); ui->tableView->resizeColumnsToContents(); } } } void MainWindow::on_actionDelete_string_triggered() { if(ui->tableView->model() != nullptr) { QItemSelectionModel *select = ui->tableView->selectionModel(); select->selectedRows(); QModelIndexList selection = ui->tableView->selectionModel()->selectedRows(); if (selection.count() <=0) { QMessageBox::warning(this, tr("Warning"), tr("No string selected.")); return; } // Multiple rows can be selected for(int i=0; i< selection.count(); i++) { QModelIndex index = selection.at(i); ui->tableView->model()->removeRow(index.row() - i); ui->tableView->update(); } ui->tableView->selectRow(-1); ui->tableView->update(); } } void MainWindow::on_actionMove_up_triggered() { int sel, decsel; chip_data tmpRec; if(ui->tableView->model() != nullptr) { QModelIndex indFrom, indTo; QString tmpStr; QItemSelectionModel *select = ui->tableView->selectionModel(); select->selectedRows(); QModelIndexList selection = ui->tableView->selectionModel()->selectedRows(); if (selection.count() <=0) { QMessageBox::warning(this, tr("Warning"), tr("No string selected.")); return; } for(int i=0; i< selection.count(); i++) { QModelIndex index = selection.at(i); sel = index.row(); decsel = sel -1; if (index.row() > 0) { for (int j=0; j<13; j++) { indFrom = model->index(sel, j, QModelIndex()); indTo = model->index(decsel, j, QModelIndex()); tmpStr = ui->tableView->model()->data(indTo).toString(); ui->tableView->model()->setData(indTo, ui->tableView->model()->data(indFrom).toString()); ui->tableView->model()->setData(indFrom, tmpStr); ui->tableView->selectRow(decsel); } } } } } void MainWindow::on_actionMove_down_triggered() { if(ui->tableView->model() != nullptr) { QModelIndex indFrom, indTo; QString tmpStr; int sel, incsel, rowCount; chip_data tmpRec; QItemSelectionModel *select = ui->tableView->selectionModel(); select->selectedRows(); QModelIndexList selection = ui->tableView->selectionModel()->selectedRows(); if (selection.count() <=0) { QMessageBox::warning(this, tr("Warning"), tr("No string selected.")); return; } for(int i=0; i< selection.count(); i++) { QModelIndex index = selection.at(i); sel = index.row(); rowCount = ui->tableView->model()->rowCount(); incsel = sel + 1; if (index.row() < rowCount -1) { for (int j=0; j<13; j++) { indFrom = model->index(sel, j, QModelIndex()); indTo = model->index(incsel, j, QModelIndex()); tmpStr = ui->tableView->model()->data(indTo).toString(); ui->tableView->model()->setData(indTo, ui->tableView->model()->data(indFrom).toString()); ui->tableView->model()->setData(indFrom, tmpStr); ui->tableView->selectRow(incsel); } } } } } void MainWindow::on_actionExport_to_CSV_triggered() { QString fileName; QString toCSV = csvHeader; int j; if(ui->tableView->model() != nullptr) { QModelIndex indFrom; QItemSelectionModel *select = ui->tableView->selectionModel(); select->selectedRows(); QModelIndexList selection = ui->tableView->selectionModel()->selectedRows(); if (selection.count() <=0) { QMessageBox::warning(this, tr("Warning"), tr("No string selected.")); return; } select->selectedRows(); // Multiple rows can be selected for(int i=0; i< selection.count(); i++) { QModelIndex index = selection.at(i); for ( j=0; j<13; j++) { indFrom = model->index(index.row(), j, QModelIndex()); if (j != 12) toCSV = toCSV + ui->tableView->model()->data(indFrom).toString() + ";"; else toCSV = toCSV + ui->tableView->model()->data(indFrom).toString(); } toCSV = toCSV + "\n"; } ui->tableView->selectRow(-1); ui->tableView->update(); //Saving QString to file ui->statusBar->showMessage(tr("Saving file")); fileName = QFileDialog::getSaveFileName(this, QString(tr("Save file")), QDir::homePath(), "Data Images (*.csv);;All files (*.*)"); ui->statusBar->showMessage(tr("Current file: ") + fileName); QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) return; file.write(toCSV.toUtf8()); file.close(); } } void MainWindow::on_actionExport_to_CSV_2_triggered() { QString fileName; QString toCSV = csvHeader; int i,j, rowCount; if(ui->tableView->model() != nullptr) { QModelIndex indFrom; rowCount = ui->tableView->model()->rowCount(); if (rowCount > 0) { for (i=0; i < rowCount; i++) { for ( j=0; j<13; j++) { indFrom = model->index(i, j, QModelIndex()); if (j != 12) toCSV = toCSV + ui->tableView->model()->data(indFrom).toString() + ";"; else toCSV = toCSV + ui->tableView->model()->data(indFrom).toString(); } toCSV = toCSV + "\n"; } //Saving QString to file ui->statusBar->showMessage("Saving file"); fileName = QFileDialog::getSaveFileName(this, QString(tr("Open the file")), QDir::homePath(), "Comma-Separated Values (*.csv);;All files (*.*)"); ui->statusBar->showMessage(tr("Current file: ") + fileName); QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) return; file.write(toCSV.toUtf8()); file.close(); } } } void MainWindow::on_actionImport_from_CSV_triggered() { if(ui->tableView->model() != nullptr) { QString fileName, fromCSV, tmpStr, separator, chType; QModelIndex indFrom; int j = 0, recNo, curPoz = -1, fromPoz; ui->statusBar->showMessage(tr("Opening file")); fileName = QFileDialog::getOpenFileName(this, QString(tr("Open the file")), QDir::homePath(), "Comma-Separated Values (*.csv);;All files (*.*)"); ui->statusBar->showMessage(tr("Current file: ") + fileName); QFile file(fileName); QByteArray data; if (!file.open(QIODevice::ReadOnly)) return; data = file.readAll(); file.close(); fromCSV = QString(data); curPoz = fromCSV.indexOf(csvHeader); if (curPoz >= 0) separator = ";"; else { curPoz = fromCSV.indexOf(csvHeader2); separator = ","; } if (curPoz >= 0) //header detected { fromCSV = fromCSV.mid(curPoz + csvHeader.length(), fromCSV.length() - curPoz); fromPoz = 0; while(1) { recNo = ui->tableView->model()->rowCount(); ui->tableView->model()->insertRow(recNo); for (j = 0; j < 13; j++) { if (j == 12) curPoz = fromCSV.indexOf("\n", fromPoz); else curPoz = fromCSV.indexOf(separator, fromPoz); if (curPoz >= 0) { tmpStr = fromCSV.mid(fromPoz,curPoz - fromPoz); fromPoz = curPoz + 1; } if (j == 0) { chType = tmpStr; if (!correctChipTyte(tmpStr)) { QMessageBox::warning(this, tr("Warning"),tr("Invalid CSV data file format.")); return; } } //add string, ic_type->add cell if (j == 12) { if(chType.compare("SPI_FLASH")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xcc, 0xff, 0xff))); else if(chType.compare("24_EEPROM")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xff, 0xff, 0xcc))); else if(chType.compare("93_EEPROM")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xff, 0xcc, 0xcc))); else if(chType.compare("95_EEPROM")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xcc, 0xff, 0xcc))); else if(chType.compare("25_EEPROM")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xff, 0xcc, 0xff))); else if(chType.compare("45_EEPROM")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xcc, 0xcc, 0xff))); else if(chType.compare("SPI_NAND")==0) model->item(recNo, 0)->setBackground(QBrush(QColor(0xcc, 0xcc, 0xcc))); else model->item(recNo, 0)->setBackground(QBrush(QColor(0xff, 0xff, 0xff))); } indFrom = model->index(recNo, j, QModelIndex()); ui->tableView->model()->setData(indFrom, tmpStr); if (tmpStr.length() + fromPoz >= fromCSV.length()) { ui->tableView->resizeRowsToContents(); ui->tableView->resizeColumnsToContents(); return; } } } } else { QMessageBox::warning(this, tr("Warning"), tr("Invalid CSV header file format.")); return; } } } bool MainWindow::correctChipTyte(QString str) { bool ansver = false; for (QString elem : chType) { if(str.compare(elem)==0) { ansver = true; return ansver; } } return ansver; } imsprog-1.8.5/IMSProg_editor/ezp_chip_editor.h000066400000000000000000000061431520775651600213750ustar00rootroot00000000000000/* * This file is part of the EZP_Chip_Editor project. * * Copyright (C) 2023 Mikhail Medvedev (e-ink-reader@yandex.ru) * * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * * verbose functionality forked from https://github.com/bigbigmdm/EZP2019-EZP2025_chip_data_editor * */ #ifndef EZP_CHIP_EDITOR_H #define EZP_CHIP_EDITOR_H #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); QStandardItemModel *model = new QStandardItemModel; QStandardItem *item; const QString csvHeader = "Type;Manufacture;IC Name;JEDEC ID;SIZE;Block size;Type HEX;Algorithm;Delay;Extend;EEPROM;EEPROM pages;VCC\n"; const QString csvHeader2 = "Type,Manufacture,IC Name,JEDEC ID,SIZE,Block size,Type HEX,Algorithm,Delay,Extend,EEPROM,EEPROM pages,VCC\n"; QVector chType = {"SPI_FLASH","25_EEPROM","93_EEPROM","24_EEPROM","95_EEPROM", "45_EEPROM","SPI_NAND"}; struct chip_data { QString chipManuf; QString chipTypeTxt; QString chipName; QString chipJedecID; QString chipSize; QString blockSize; QString chipTypeHex; QString algorithmCode; QString delay; QString extend; QString eeprom; QString eepromPages; QString chipVCC; }; chip_data chips[2000]; QString defaultPath; QString bytePrint(unsigned char z); QString sizeConvert(int a); unsigned char dualDigitToByte(QString q, int poz); private: Ui::MainWindow *ui; signals: void dataChanged(QModelIndex, QModelIndex); private slots: void on_actionOpen_triggered(); void on_actionExit_triggered(); void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); void on_actionDelete_string_triggered(); void on_actionSave_triggered(); void on_actionAdd_string_triggered(); void on_actionMove_up_triggered(); void on_actionMove_down_triggered(); void on_actionExport_to_CSV_triggered(); void on_actionExport_to_CSV_2_triggered(); void on_actionImport_from_CSV_triggered(); bool correctChipTyte(QString str); }; #endif // EZP_CHIP_EDITOR_H imsprog-1.8.5/IMSProg_editor/ezp_chip_editor.ui000066400000000000000000000150771520775651600215710ustar00rootroot00000000000000 MainWindow 0 0 880 394 IMSProg chip database editor :/img/plus.png:/img/plus.png 0 0 9 0 0 880 25 File Edit 32 32 TopToolBarArea false :/img/open.png:/img/open.png Open Ctrl+O :/img/exit.png:/img/exit.png Exit Ctrl+X :/img/save.png:/img/save.png Save Ctrl+S :/img/del.png:/img/del.png Delete lines Delete selected lines Del :/img/plus.png:/img/plus.png Add line Add selected lines and duplicate data Ins :/img/undo.png:/img/undo.png Move up Move lines up Ctrl+Up :/img/redo.png:/img/redo.png Move down Move lines down Ctrl+Down :/img/tocsv.png:/img/tocsv.png Export selected lines to CSV file :/img/tocsv.png:/img/tocsv.png Export to CSV Ctrl+X :/img/import.png:/img/import.png Import from CSV , Ctrl+Shift+X imsprog-1.8.5/IMSProg_editor/img/000077500000000000000000000000001520775651600166255ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_editor/img/arrow.png000066400000000000000000000051431520775651600204700ustar00rootroot00000000000000PNG  IHDRPLTE[jFF IDATxQRQQf8p6o21]l MkI֧CN^`/c\8N444„iiii x|2.x &L#L#L#L 2r&L#L#ƗKjnn7w0p|0׹ޞǛWw0= =%1O/ZK 󳇹rǧh\xw3M ?eфw ̅c]j\x封L̛៣ 3̷h\)\>s̍ts\x?!0hŒ`n`v0фY`{ 氇`0Cfsh3S=._S=Y)8y5| 9ުׯoէˈ0 ~'x=u 1rz~}GK6I&?{.71?\ϧK.MMg/6'Gh6+|}^ϧ-M4 ׽_{Ss5-6楔`m 3Mh Ef(0#;saV}&H0ф~`FNwф`&k4-5X״Nh`0+/ф81ߢ S4aV0w{c4a&N̗h¬90;̊{M ?1G30 ;-rz'{M`FfsY|&M`ng*sR1,g*<s`S 9frR1N̙Ja0G 00/rRqNYJa0G 0#bN] 90c3`̩Ka0GŜsLˉKa0;1'/5Ӗ`ssR}stJa0ǶssRуJf+̌d ?cf&5aNfrf| f&0K703; -ƉXNw 3yL9 `,a~91O ';;`~91C`~T *}`l`Ƃ sb,fĄ fĄ &ҭ,N0avNL`Ni9X)/`neanea0C=&0C0C?0C0C0;{Lu sL̑.ZNOr+ 3t+ 3t+ 3.c fĄZ 1asbgVvȗ?0C0C0C{Lu fwL[Y[Y[Y=&Һfgy g.e9=֭,Э,Э,кfģ~0׃y>1WY}Vvuw7[a^O@L`޳gc~9iԾi=ny9rya^ *z+Foډ_/yed1S~L?ކj_sbq&Ͻ\/0wcj_0Cc>j_0Cc'TPK2CyZ`4>@K} վ`j_0C/P f3T} վ`j_0C/P#k_>i}A%ڗdj_}If%ڗdj_}If%ڗdj_}If>s/P f3T} վ`j_0C/P f3T} վ`j_1-\IP' B/ վ$3TPK2C/ վ$3TPK2C/ վ$3TPK2C }YNj_0C/P f3T} վ`j_0C/P f3Ti9ڗOj_>i}If%ڗdj_}If%ڗdj_}If%ڗdj_}}Ĵ\pkC3T} վ`թ}|Ծ`wj_0UCswq}scC4t3O;̻RFS_~`aaa4444„iis&L#L#L#L#LFFFe&L#L#L#L#LFFFFZ`FiwNPHIENDB`imsprog-1.8.5/IMSProg_editor/img/chipEdit64.png000066400000000000000000000053461520775651600212460ustar00rootroot00000000000000PNG  IHDR@@PLTE𗗗򑑐㮮㧧ȱӟ񹹹Πaaa૫栠llleedsssގfffzzzwww·ژ؃qqqooo|||vvv  }mfccb:-\iiizuȉ 뵵J^]]* nK m)Ŀ:j 'lJpYYY5%xfcjU}Q3F(/)%z^ oa٫vm{ciPhK^D=:7O.4.*<*%0'e䅲*Ä8s'cV~|sjv^p[QKGHEB4  2p÷ƾuNtڸӷع`7n☈얈Sow{gi`v_`G*%rm@EtRNS!$7 DY%Ky9/޾grppmd_8 ٳeIDATXÍuPm0Ʀ2A%حw9~;v&3gmX1y|gRbs E+P$_.yi4MMtAe[zLL$45MGP[60P1!/d;Zli;Bh?qC4#m|% Ay"nUjh߆hnJ#x=S`hMbs{5ݾ=3a) .N~ߞW*$āH[ j͟BmjkXB:ƉM 5/CPx0Wѓnc3fW.en {,O>A 2lptEqx,z W/\84b݆O0{Hzvk/rgХv h ΛNuD'"׬lh˗QZi-M'{gǢtxo :zď߿9YRI>YێnHpŎ-[*>[$<%hq#{uh.lWn'jn|DikoWZl󫠽Npb앱^sj_xY9{rn|On;5VVwzyiu)#~{-$%w^T)9i'e3 +D˳ҿ[t ?U`k)$ɠ3!qQjSu ]hyi}. 2Ԃ '@xAGQGB`rGk [`qw i*],QG]{``8̍N^][춸 4΂Eh׉mXl\b"g[ܿss-V@mA;HWB~ Z3/zskf7v:S9s LH W̞~oha:+1j3Gl* ԉû'R "p $8ClM'n8QHЩ[wKخ0.]rbe0tf9I1b$Ri(aH#% *$L 8r2ι|:8:6*xz@R]2LQ.{ i+x8I ׀#ނ%ti uQ^b@S͌"]}$l,vo0PEٜI]IE[?e\3?z~ xAu<.CXMbWwwbC5^{ZeuVΓD6inrA?[m0q+Q<6)$IN2IENDB`imsprog-1.8.5/IMSProg_editor/img/del.png000066400000000000000000000031421520775651600200770ustar00rootroot00000000000000PNG  IHDR DPLTEҧoiwkűš .5!zu|C3P@pcĺѱʻɵŲ»lekc ' .=&B/>'3 ."1%@1J=cWYKVJZM]N]N^QɳTH~tynZNٺ7@!): -#= 931*'G$B!S)P(0%!  U*M'K&< uI@O5D,M&C#F!> 49!SHyND}?2D)?)6%H$7#C"6x+@.)'%%"%1'&!& * %    #     y }c\ya\}^UtUN~UMSIoD9wB7J3K0F0}=0q9.A,<%5"1!1!2.42/++-{%4,8"6'!21$t+ '    yŴZtRNSf 阇[V;2!ƬxvolhKJD>86ʿf_^SI>1&hGIDAT8bT<}y4pnWCx<|ZhU lRЉ.ϫW2?|g|\KPyF)qr7_=o^zG9s͍NqA%{lg|qlRlllUݓDy9O %QQQII]eQm@_D pSR@ 6)**1:+rб8=nTrr'؜خhyշRj@@\Bm(,LI**'%mXWWҹZC .KMMkLy;&--&&h*=n]SO}4!hSn|^æmI+d7\^ or|Yuoou3&M*J[2Q B̦o-3\ٝP T $)yb `iTdD_-YYY5uewtSOuu HZvdeggMLS%a999$?] x4fmiiN΄dbffdffȉ5ܾnB_+*I r* J&yFRt UIENDB`imsprog-1.8.5/IMSProg_editor/img/excel.png000066400000000000000000000144151520775651600204400ustar00rootroot00000000000000PNG  IHDR{PLTEr3f!t6]̸(IDATxK{:d)늓V*̺ IB?`[Gas Dft 6  w0a&L 0a&L 0a&L4W0;l&`L 0&`L 0&`L 3@LNL 0&`L 0&`L 0 &&a&LL 0&`&L 0&`&Lab20&`L 0&`L 0&`Li 070a&5r2\-$`\_HaI2HaYM$ceb ok݅͢)ڻ*͙-|&0O] L"rj+`ѧOaGWIvkr|:0SJ `vfDrKD ݁yWE ]9)U̮?"7LasCAr^$` S n˩n0f C18hG7$ Fsl5fga$Y&`~f\k5'?o\azt$}e;Z+0P";EYPfW`FQhY݇WA5Dz]41>!)6L9?$ɰ蝊 9g.|”R 0=gy20Yp0kO?`rt`%` L62OӁ?0C@J59 ji*. 0}:ءL`v420000ӛr~D019 gSfL((0`"f&`&`5 h&,`/m$-dߞeg{On<f?y>+/ ޞ^V s `7jZxm g_]Hft3l#ayw![N?s '`\E906rF0A']N0SUYL',JUN2d2w\ZF;8^OR{9U`:r Ru] 3t9M6u [f364 C[bW&nȴDUlxv o`:Aӕߨvlsؐf/u#2[\y200鴀#Znp-MQ^+{ 99?Ԣ4jAg|d (oBTěV2EK0+/BGUfUެ(Ё,dQmpY7h%je{Q[sɊ[@! eʞl ;~F a8;E- gal52Eknv\Pr e^Z@jY6@lQ03*}z8lB&"̫|}ySk9KeKe9IQi.fP4\&}?|ɛ5 L$9xe%[D+Uf|swN|G0dFO]ͪ، IIhԆ\,p{/¸ېVL]1@0 $n'}nH˚ɃAڐVLۊw韢z5.vkML#uDj5_'7je!}..5YSLJ{;e5*`ݙSObfAFOeZ9mX֝U\x*~,HSVNEeK:.%t76_cWN6h|IxL-ZT\zboʧul/vLt&4|p|Fs"09]rS|*Z&s]?hҏ2'_܎2]D̠G2r,㼼Iv̓&6#uoKALN$ im 5e , w͇gFHц2Ș4ul#LQ'<7KV'ZD9a3Ih<<Lq=e?W҅?ߪ`~x{_fW*2'+c92ߍ{Qu5=6+sκњQ1iFӝR&_¬LgOkgl=h޹tCìzӲ9d mɖ`^ݏ,>Cfrz{>Ny7̬` 4;3PLۮzZgnID0x6L´Z= J!Փ`q#U`&$7bivfֳjh풚n6mLNЅ l8{}t#7a@X0{EV[T5327GųEW}]iMQNSځZ6t*cuC59@<8:DUZL/];LefJNk EҧAgAPAC/im4̢DG/ChaM1iLgsNy>(k%}?<9XTZUD LE@ʄb e|iyjgya|SOkf8dkӝ97"_:|4h6TTٚ)D4~5`^$i2\JN{Q}cY|uCT\!y ,: ˥a:[صnbmF 6f6ޝìwYYڽt_Eb _Գ_~i2,>Sa6+G9wxTRvS*eD DM9LWyLg"]ioI?܅6?<^ cWQD3f-iFp˕h+k<0? {(1GalQ>#n$v6uT\楪J'ȩs3Tb(mgXF_}՞x\i=sgn䏗vVqբ*Y{#-D=-)=&:v67ב"ᔟ8>*iL3NOwfɉqI Pl`eq^LxhH2Y|p 6=r`t3\cv۳f}bكҠ .Nq߷(xd6٬ElSϹt0tiOAn?G+;71@>wݞjeg=вz،ϓ6>f-L􋉬Ni]t$[j>mt<،̀YQSv͟aS}~cOkuyFLٴgg;BDŢ=YJUxxf-LQxp"',^esѫEpicπW5ԝvyxymo\?Lz_49昦:ntxδ9xi9`{^zm*+M0rD8_*Zd)gE\ֹ}XDvHr9@7WTTfv_M{_ۭ͑kl.&g/W/:hOߏ 1f睙ǣQ8Y杚@ b uξr*?+MX&{"Wݝvh8L p8hfCuvڊQ95ycuX'FWc6+F\jp\n}yU17aj wt6{]Q7y V3 N|& L4| WCU^=ހy*˨t_D`9@y6s4W̢T3 L,Y43 Lfh& L`3[ӟxfE*hhQz~] = L4L`dyq˓m/RS'u0)&0I ̎W#Up&0ye}ɛE31U`L`d6 Lfu`&8}t4 ӟHI0o71W'd0{sJ0S/0U LNgqʧ[C]| LfvzۈH ӣxftO `48.+f,<%0{solAp1I3LLoWhCt3J<^mW3t 3 O`:<$HpD&0LD`"D&"0I"iD`"|0D&"0 LD`"&0 F&"0 LD`"&"0LD`RHp& 0LD`D&"0'"Y H)}IENDB`imsprog-1.8.5/IMSProg_editor/img/exit.png000066400000000000000000000025301520775651600203040ustar00rootroot00000000000000PNG  IHDR DjPLTESA6Q;3~T2f>%_8#W2"mD&V?8?T1Q-{N+hA8L8.P?4jq% O#6EoK s ;r$1020oO3\3*LB8J@;**i3u-`-Y(E7 $l''] k0/j#$+-[#10/.`9^;O(X'32|Y:)'`AqG(yO-T4';1kJ-S@3ND9m5p8{AzAu=m6t;s;r:o7|Bq9~Cy@x?w>©l4n6̧j3ɴv=I~GEvĆMKz@s;**Ş{ÜzÙwѓ^Y%U#Ơ}ŌZEo5l-i-e+b)^'f$X$9ѵбyuЗbÊUCz=34_3o1k.T$##""N!>u( ûdzʲǨ{ۦx՝iaŒ_͉TˆR`OGHɀG|@<=f<34i3m212m0-.a-]'K&&&e%[%Z!`;IU IIy&(E$JHtRNSa]]]]ifd3#![RQ; ŷ~vsqoc]ZJF<( |UIDAT8˕ewP)0i4m(ަ2 qwwwNo&)pM^<{ras*úTD"E"цb_D"]Wn mpwmN͎@ m!vTMc# wUMZxK: N'y(Lx'Qa@^r`L^&\x/S8Vsrp"e4'G!_> 0Ol PSU}gsqOlzBM^47_jٌ:'R!1`qo4ڷf#MVh5LP0+;~ßqfջ!.po Z}x$LZc^B,屟&{%GCOh쑷(+!֦y<^+ǼAuAw]liUiY!`(Y'?ԆYP׏J=ޢ)ʢP) #@F~F F3O,m0yAɼ[g^Ff.g?0s2&edP2q̩YY0>2Le5RA_Lz2IENDB`imsprog-1.8.5/IMSProg_editor/img/ezp_editor.png000066400000000000000000000547561520775651600215200ustar00rootroot00000000000000PNG  IHDRyPLTEַ̓vYEDEN')`! """ P֭JII>uZ&@@@Dsa# !o @eN4& ~ ;;;F:pQ.R(((v.e/?^7)̽+M...Pgfb6:DYt;}2 I -v0v_&554ۯp8qzi$QaaŶ8#?<>~1uk#̾+uWMNR:ё2W1Аr'θJuACa2 L I<gjυ8P 08 r2V sK{8'ݖGĖgǠh!مyQ¾7%,uk\&>Y|M:زw,K^`Ƃ?"Ν|3fD[4}ȉW'TҞjX\_ЬKj}ҽOyoҭĪ8Š(|rlrs+M{fIǪ!IB[tkMAgt1i&VIDATx͋@m܊R,=S豧 ^ʞ7.ՒzP_ 9ۃx)RhCI|g1iڴ5.LfbT雙lO2IP?I>Bi?$3f2,`v$EV3ckF>d!ĉdfNh@ ṕSP8f^Pr#( T)QU*s$3? n#sS̅If҄l;4x12ռeħ kĩxˠ7XG!\=s/cGp93|nK"@;x'BGJ$T6/!"# PU!<@$`Ӂy `y_?t׻0Ȓv, "{(¼,'>Dkex&y] ԕ.rӖ]5ń=v - l$?ubKw =HYm`+mH@?&yX%?pvļq |IrJ׽r㛮gҮJNfGU27U?ϦT zy~6K=*V7fQOAА njҠ2dFҖ7Z4vSݑ&:=ZL|W7:5MмuGYL1OBT1՝=U7u 岺Wi\6ڤVxKiS#`,yR\xA&]Zm {=UT^vȩ|xj4fd1 ODTzUL]>bޮӫIx'X׿^{.!qfÒ[=ҮIcQRcML]Yэ6ga *r0, ȢojN5^}gi*z7hRn{Oi((4 tyDX50%!~b Ǽ"!0r⎹X<ڱ@R 2&}+?8uuR*5vV4i5O((03iaٛcyܼʻT*uy敏e\XC!!?gTsvR|9=TNW=.е7/=]AC <:f2|Wsqv|[X(q=^9Á<CfyBRLmx9X,[l9( 2y![D 0} RZR2(((%Z,9O>祢,&X41#2URw7'j`3˺NY2Ӱ?w矐(Px&)h^p(GƐtN wM26xצ˗_?tG(O Q~s>-NQw2@,ϒO'oP=Rlx(j*H)Xme#ږIUq:76,ͯof\W4,i^ncTjXlNj}9P:uCQJP4e٦%S &2Dfyg%6og6'0DZK^kڎK)(N&Șhgrf 6 c* S|˼m~g׳A#ՃXIE->bي=۪y <  =9ykáWBT;<8L@%Nae{)̣"/K_T{]}`'64.\Jdr nA -J&8.iC9 U5O&eܼpXmА9X@a!6lR|2Ra^(\,V/DgH=ՋjYpȉdS'ӕO(n _罋yRtͣ\7Jtk DzaAh ܼF<8gu0/2/'Du5JgSiE3`ދyxyׅ r et2yЬh43d4F0=VMdT;NA<ɰ[ax@Zh@c2e̖AR y'\t<MyXvҼًtMɠ.tZPS"mrФ}(wN? R̤ҼWXOGּ˝,^ *Hy:n4~α]S'kO&CvhHT#mhɨyA0,`&yO\V]TU;YҼ耬yi~9@ȼܻ.M7]# (^.??G"e^J`y [+ &dr diw9˂aʺiCٝQvJgyبl/,X%&Eoo#HDϘ@*>qڔΥy0;lL= HygK'a1^09[^)`PҰ*|wC<UTin~hdO؆,̯*GPy b<@+R)F<# ⷁ ⷁ1BH6 *~Ky(U5O U/]k#GʃMBDYH"R.E Ti ’,6H.}XC2#ac0"!Mi{3+K+rtZ{3ooY̛=țżhb=gf4#/4mΞ_xf1oF3H?OS,f}ِwx++Qz<ߙF6M~Tng;2\OO3yq7'2šY׵OIxgjz25%I9{Ǽɓ1[1n|x/[ (1A y[wW}olR!m,#rXӒ/"o@#zIۉ"|va[# ҳv~jhljyco4oLG֎q/q`n < N0'Kṉ=ynw"fpaA V81KQ d Fy70'`(niӤK BvNjkb c_#u̷zghMiM stlJrF^' nxjۥR'o[xS6|nЛżi>zK22ż&ȽܲvfNG%9"/!S@w/oEs'ZEM^ԗӿ Yf$;6}'c=vc$n߯Oyo9`9Opv)ŷYErOe֌y٢H\?Fm*}i=X`҅XZyCD4f{[} ?ƣ "_/Jk<_S@OghF~a[76ظ3 ՘xiz3&a&yb^(_UraXpż[,]yĸ|IEOh&&dø!O=Fc"}~9!J|chDrZsLB^DN|dP2t" O삐L|;N͟ 6Niwvz*9&M|VGm?q.6<6H^bY XοD2<&`95 ojXyjNyL<jńĖ?vG߈QBD#y@J7:8~Q6dn3/-r 2|Im:vx?R;esrR!1 OZ r&xE0(z\B&Nt UQ$0n}km+؅csOzG=s:}`ΕǢjh8#]\׊L"eUG̮P,j#^ҙ1w<*ˀ.S1ɘ'Y:I#w$wYcW{- {a^&FʖV5[^]xy-g8r0| }ŐcKH"jn_i'%.ݺN4&UZdŎ~bļBߘdž"D:FYLV'[blt.~/T첗+*@7˪ j2+c@Y]<fQNȴ_bl9"p E <:S*x yaYu .7KǤlniQ`[sKAd-Ąy¢bʆ췰 ZvY-o9BQ`sdAvL,ACuDtJ!26Pq .tQWAe*#tWUqaوGUCz=s*;˼,P3Tre@(H_q6$cGWI,ic\ckR|X7UI7rhc[Uܮ%T@d{!5v */:=8w/DrlvpG bԮo0MNLpaV""mEH\܋+Ně|zD|!"oO@(\2ynceR5$lCcJ^ĸeȔ]ʫj~e*@b#/syy)rYnpAa΄_뺣3YWqh=BR@^0*GLCUiƣR:G^C(p;AbTuDr{#v&e ګ[<- FArӘw #ASTbO "۰D.Lgkx h@gyN(>q^t'(1/wF&xaJ {ދ+q`þJi:ȣA^;~r;AE9˗Xd4%myz.&,!](C5f~:eǏytv!CnSNěy zL21WlaO&HHȃu%sU9B~@X*0YLmHJ_#gqN(8C!')sah nr_&H6jO[y;9YIzY<Yb(+i{+\ {'P(BKBz VZ[JCXMT$ V 6Z!j%TJiL/1mbO5~r󐰷oٙ*,5UǼ6M~i ;2)8>z{/(Id'xǒ[@rS[ۍt1%;Rnj|t|yVז,͌3[Cϗw [h-ļx+kMF#O]*"<]9`z<1/Ѕ1yVync#.ooCQINDsık3j Qzؔ({aӉa(KWX gؔqƨKKr\c/6qB9.a}$WZe>8YnbKLN=T$7פԌi[.ȆoFZ/d _`Oޖ|i>4oswͽqc8;;KGb-?GB PooVJzW׏J-:_Kw#2"?͇jyn=@f@^oNl"eQFEĦ%U-XwRq! ]gsB)yƴ:.diQX-O^nԄɳF.t egHQr>;3G^bۥKv_Eb4as61,:5Jy%j届\׵ ~M{vi=cJ˜Wt)ykN $ߢ9 M~W3ah,Q^&1,Dku}Il%.@%74rړƫx>El{W^D5J ZdPnUZ_Zo 5לQGwYb+m /5y7*N.2&Y;F?k.>y$[{aڨņV@3mV܆E9NW2jB$o`PGp|?yۍy|;cJIuNtэK+*."Q_8n2&MOHHܶY0=%/&>VWjّ֓5 ʢA^2Hj#/юF50]e6ՒJٰ"k H%Y[ek.Hs:?PtR9!Wӭ~_Gey0'[֘=W!o/wB̋iiļn!m&׬֌87hJ:d }E9XNvytf"yU#By㗺2}]~m#m*jJGN_7i;cJۜW׏b TgxyMț !T V'S0exך V( }JM[JWpdj'>T4SDv7fj+] ]̓AL~؎ïX BW޴UبH5eZ <?{ AX-7T7R5 ej+^ bޘJAժV@(,5h15. ;Jj:(0zRXc.L bAy25UojVh,:%iSDgCّL bAb^yr5!UG4SsS'ĊWż0â2oa915FʼUD1/,iS`[EјDdL .ow[ s 1sc@wsCXSbPcc1"nySȣ1Gc^ c1"܎aa1"{'H <ܳoHށ1saPk}k3)PV/.5Ad-FPHȭ1kp؈AClc-y*jSs3fnlbރXTҘǓ3"10T"d1Ig[Ek1y*VybL Ǫ[ MTNPE[9zVh25%yr5yV!jpTieV _4ƥ(%єJ1Zbc,#jj߉uV %D, D! >X>B| }^6)39'1^}޿w߻n'\A:8= *?L(4 B\KP,K>:6] c(0BnG42C45N]{*޾ zEHByöD~+oo:ydKm$R;&rٝ+ yG>l+쭛9d+=#cmظQ=W5Y`7aupoI5h,c4O*WM^fIgq9[\ 4paǁ#hyZq7YuO[MvJ(Qsĥ6Bmi9 *B/HC cC6#Rm5*[ RD+1 DP%p&hP~cYr(`^0^g/ZE=-([ ) fi8;Îs- $F 0 b?vLD>ͱ6Xs ʃvzk= %AOv ){;ZX ez'-A84d1Sްs۫!ASFɨѐr`ٸk8 gg3\}Q`!1"AiX y7W082'yLZy'* y"rXy~=I?+Bi[]bh9Zy5Z7* (3?0 0CpkJb4@ _PH^fz-?$2)([  ) gA Z=KAΞtD˃&u4a4*KkXx +aW FypS +;NyKy?{8/B4>|rr 4i<1!ҝp]%UKD0 d*4~I8wڸtDT)CD05ؓ+KO) A6MĮo?nO'R.iO.;jRAvIL= y BŜ7 r D_9A([ ?+IyAxO`׏{AP1}힘tDNyggAKg(I; y^?i_{ipzP EZpG T g$ < Apy& D .ͲF? AU44aRkXB< +9 i[YޠCAxOLD/KADvT=OMsHhŨ݀@/ z4>1q|m4zz/ tOyL\ |A6MM9u@s# |A6 DިM*P.CAr].ANy& b oNUӔ]2sBU;/4i63ijsApmӔS3DcgeD:4iyha-]ahPlAʳzhPlAc ʓ-HyM K -ڴCO:'7[ž(On yIg R<<(-Hy6A6t8%Q^Չ 44hfomN(Q29+Jn] HYYj7 ANyA_{P8 +,PL Ƨ<4[ݦA^p?ۇV:AtkY4ڦIu6&A䊖N YƔ4{AvCe V\< ,o]F4{ AhGE r2+Dfrn3a(4i63hZ141gvЋci{h l<i^4*PlC ®< A@@ l5, yA@y²)/yW4(OV YyA@y)6 sy{zҡ<ق<قg尠'ʓ-Hy4t`M[y-T kҗh OOJd]ˊ;4QRKvܶe9Cj@?uhi-"TPhRAXM43+ͿtdIC)>LՕK>D+. B7ONq,)#짚\}ᨿQ5 4h95‹ cN_96J(4QYoi8Qcy2aXG}(v(Z:%҇K@AʋY4zfcuBi:`պ|$;WdDiI2[4Y~>0{'@atjh> w!2EqkA !BJh=g3,F5fZZyWI^]H$%?;e\s6왟;9~ 1hRp+ k5{6y _4Nŕ4ʾ,R> XC4h=D_>4nbߵ? o4<a^, _ 37I'Fu$#F<glD#)vEڦyep)Ͼو'pĢ[o.^hTub3[dN#|)2/fMghAX$Ļ7n+\;h:%wu Iy컪ɫ"mA,=uhΥAd<$ j7 @?zŭ 3bͦjYb̌h`Y ¹4˞' gԢATs]) yJ~獬gI>>{ ¹4k" bC~N-h} z@hq% g14 gI޽k5 KyI4]SCByMJ 9Uӽq``W9Nxf ࢷG4 ,m& ʁrN׵F-~GϴM 99?ONߩ㡢,߁h [4 | Q[4/˅4oY)b J֭\̪L|A(Bho" ?xǞcA$#WiZ`e e; B  >ڈNu&ylM46s4m'8'=]uDP!԰ ps<9 "r%P:q\& AhLw\x.yڦa(= B'A,E͞7fn}f ԠA=OUi A:=Gʓ :AW Xw "4I8," += .6kOdA@i 4$߁h vozx.s, jXfۼǤ4s. 4z g:ACm{ kyD ʶ4~^AA!9y{zIyxmTq5ܻӷGC(ڏ$<6&<8)Q՘ҢF.](-֌8ZsFnx9wʵn݀L> ZF2v]D4h.LM%u>D!t{M$ҎѷT$. qlEZ-hŗRGlU&f,ֽAT Ǎr/'[FD(ɛtwY anҦkyG[5J>ڢxT<<˩skDO⎇ߡuָ[6U Tr@q+(I+xM"$TBԉ}bQKs&3tLls^ga&"J + Z>@A,E8P~;0",_l¾`ɛ,pO0alҁq0% N9i&[vmR0"m89$Y2o6+Zd~P$y"=l3!f@`] g"eU.,$wf1,IW>¶7QP+;֚>ӊĐɳl0n: dmyaZ$~9ffm1t2{ֽ;>I$17  6]$`DbeUbKmNzĶ+Ӗ7KL<*>:*g<Om": HmJx y (r lLܴ I$y";4{>Z+7 5:d0y>*ͩui50]kG>DnR¤2&fWyE W3RG:|<Ž]3Nz̀NS ׃u..c%*:^|΁]L|WAͷu]/( tY>W誂y 8Plb'rGutC>#y7mo_IqgvYL^JzN=E?퍱B f&W].Ƙh$.D{7|Qg5٦ d]}gixC܊b 7bXOYIF4tUdc-E ȓuU87*'jĵ!NW O*O9CRDERԪ]T# ,w9LR>z:^dT~\zتaP#+:Glϻ yc3yƪJq\\7=O/D+@_$OKK>ȳp릔%޲KК#x lEl:N RuW%ʚ+Ojb2qA=qo_C:ϫ{I?x:NQ7 .E }Et~ITPz|9@'fTHd^-E |~U\n wOP,3WIENDB`imsprog-1.8.5/IMSProg_editor/img/import.png000066400000000000000000000023531520775651600206500ustar00rootroot00000000000000PNG  IHDR D PLTEƣ};fȨή!{!fҾ%6tRNSn+nnlDxgUípol`MA+# Ѭ{z\T74] (ZIDAT8˭wSA/bCG@iֻǙJzi !!=(7{w{Fٛ{y7KwuȤ͵:e5GleimQWEmu!ь$IDD"GKҕjxfQgJ,BK,+Â'7BXB q г ;ʯBAR!)/.O7 䥆%oBħ2@R&`4 4PσGS̬y5ZHDH:0ف(э ΂B9jlP6ɰcd@ /)>k߲ڟBC`:!E#PuF\A~~ jb`Q(c}zý珯>yv9"8LU|~P^jri#-&O!7C^$"$O?2 8/ *{:.Mhh d`2:}hw %ygh@ȇS5"xm蝝+J+JP'r:l^MjtmU OZ0lYDhJ Μ:tpwVv/uڿ ^p~IENDB`imsprog-1.8.5/IMSProg_editor/img/open.png000066400000000000000000000040311520775651600202720ustar00rootroot00000000000000PNG  IHDR szzgAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATXíW[Pgb/nٛκ;{z:vTpuֶT mQB!@Hs$!grB GTx~0X}g/>ߗ]v uH W*e`[ '3">vH~Y2ϭB9DQ臆={XSR,::NI1>I,`]YSMM4 1y`Ż?ū)LOϮ׼tCO3@{=.4W S2^5C`\&K|H$8As''H׻ "U77N,V>V:q,k,'6?F}oY1~ Z{?0L(CF&e-,!4{Z;~m$~CF=5iu?PZlY]/sq 1% cbjC'ݼ-Ӱ;3&SXO!,CPF BBsZ*tȼE lϛ'Ào%Q(/bM$"R-BySt < ] /yƪԳs LŔbK˫#7G<<b~/=/-:C(QNܿ}3i 3Th58 X\3>GelAC'b ER$nPD΋J~ m['Ѡe")(Ȑx5 >c f]KcNzI1N[;|%jJ0("3 t.| J*qQF@7 jH7'@L{RE qAAͷ]lC(N#KQWHoXQG `4QɫgA@?noiқ*/ru)S)+vQŕky8n3cjs@"mDžPt +4X$ |J8aVU;:!z/]&o8=cn*F׃H:381 ^QO`+] 9g=JUmCeS@%`+njǩD9|6ZZ8/95j'zLIdnFڍv9,9=NrG ;Fc9=pOJnX,P(@!F.[! o<<5iEX?7Ǎ: !p5U!4[7*4nI:rsm$Jesp)>|c.2*\"]~M 6tvw䈶"I m2JxLKIõ.|me6Y\Q{ %&6ǝՂ^NEXx]\UPuTA/ rjQCO-H/5z-Wxܯ\u˯Ev2g`§ҩ;P 9 /"mak^2/f_=IENDB`imsprog-1.8.5/IMSProg_editor/img/plus.jpeg000066400000000000000000003614031520775651600204660ustar00rootroot00000000000000JFIFCCH" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?95=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z)Ez)Qzץ''GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn4=|zօ'#w>5|#^ @r1͗_{C< iX8P_5 W#u:ozۥzO*;ZS`Px5\se4=|zօ'#w>5|#^ @r1͗_{C< iX8P_5 W#u:ozۥzO*;ZS`Px5\se<|WKb@i$+K~?z_*”[X'1NOgpWft^߉3Jk1у|ֲ F߽^цV|zֿߊ_^=շmU-u_zu$pn'm&"P )_)x }z0Ӿ!>;WAԯ ,B^d'$g0p_kNl^ibgMovל1>>|CB# Fq>'Q0$p^Pi?DUu߭!~^%s&CHfmh&|4뀞ґW?ªc5 m5v>!]݅oڹ3s2ǝ?ŷWgܚג?+ҥ)~֧='x5m'_zSKc`rx=OcI#_Õ+ѵǕc[˼EլsZm⍢_;*F_VӤ,#H֫ƞXzBޤy>2x*+'m5F9ouDԁ8?৿6S>)5ǘT߰Ai;#+ϯoچ|s:눗PGPQ?eT)vaRY>Q5XTj2F:ȃ?hluh|G~ g{ι|5JxR5-Kĺo;ΉIߖ&2z1÷lF{osּFim~"M/en IIm{= E1 @Ȯ/yI(<^:u*,.wM|y0\НL8g6Pa[JS[旼p,O}i0}k'xv~{Kj~2)?=n2E ࣿ>:GjHV#nDsqG!84mNDK;|w g<eIWSՓva-NգJ(]UQ8^.u|8PyVŬ- _0(ﻟVx5\se4NG'}h`rx=OcI#_C@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}_<9<Iϭ} @<`עx5\se4NG'}h`rx=OcI#_C@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}G:+NG'}h۩I^z|z2Tz}I QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?}^x<TyKGQ@^yޚWZQ QȔxw?~yl_//{@ע?*]@Oǐ:+@$e8Ȕz?4%=}oyz77_w?÷T>@Oǐ@$e8Ȕu=}o KǍ}30iW^!tA VtkI"uY[3O+M?Jҭ^Y`iDH 7Sn.%gWf$diggb 8ъ֖F/K-sh5Oѯ0 X|Zu JK )QXsΕlDgjNtp ǁ>_uMJo Ӭa#KUwHs8P7sjL MVd[>"g#SbO({~_5W:$ZD,Yum6љP/H v? 5_Y_j%zgz顈>t5^ JT2[[?: ~Ydρ9+)xsY2Zh_zT>yjvi&ӵov7i3 _H=gK|S[a=oϧH3_Guk>vߧ|t[O#n^{ csOüRX|6}]5=73"m*f?ɜk|Ra;g6OX$/zOc ؞?Za3+p@xu6d>LH<Շ5W Z%jEv=eA뷱axe Ϫ: U%32Ϧf+3 TO6z[[Gc:O'pS7ק[٬d*2<5z2?=3ٟ~?xS\V+4{1B!ϙy@O*zvy_ěˠgK}&gvKt\)¹{\b0z*R?W<}\99ԝ(ʙv&ma*J򖑼cMw_A1izAǑ>ߧMz_|s/kLʭvZR8ٶѮw~!kZp #To,&AOհu -t֍.V/Χu|M)$Ҝ[Vqs]^zCoGV{2+љQH% p|e9뷁wũM{46ӦLEiB,NJK'\`<r~>4| о"Yjz\Pi.' XJ)e+g ¾UyUpu0*־ɻI4잉)^gท R]L=zW"B,9$w ީAIS\W -!+%ߌ|{,v1׼'oV(g@Dɬi佴T<mnI-E2,RȌUՃ) _SPf𮺓Y#_=ͽva T*LAFCa>oSOx[)3ͭ,/v/:[vA eo엿O&INEVIOXEY9Uh0ug/z*E?NM3^)CN>Y|OrX:8dQecKkMB|EQJ%8zy0:Xbmר_CמA=x?G"WDzyzi_[iG'GG"RqL?}|/;yU>ע?*]@Oǐ:+@$e8Ȕz?4%=}oyz77_w?÷T>@Oǐ@$e8Ȕu=}o KǍ}30iW^!tA=x?G"Q QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?}^x<TyKGQ@^yޚWZQ QȔxw?~yl_//{@>4lzy瀁U6] ẟu=|zր^.]םעx5\se袊ẟt'>>4lzy瀁U6] ẟu=|zր^.]םעx5\se袊ẟt'>>4lzy瀁U6] ẟu=|zր^.]םעx5\se袊ẟt'>>4lzy瀁U6] ẟu=|zր^.]םעx5\se袊.I3q2-u}—0h^~&XuJy"O(f¯5 NVi5/.kXشM,+6v1$-&ѿgx*_X^5)\==*骵'k^գ+ݎf?g %kfYgV*pXNv횔| |[ 558NQ'ɔuN*joǖ?xzyF֞5U_FBxW­l*7Ãx_Uބ̃ArU6/>.>' 7L"{۶f}WrY|9=> ߷mdk(? O~ݻԾ'/q3)+Q[Fh5ӂ0~<2={7c\~W|3^_COoֹY mzMؿ.QŚ5m$ѹ;~?ң̻-qk65ux-8|uiyyoiC/u8fTwi_e_?ʫA#noߋuXOJ۷o!%at)z}8zP]#8E15.&ֵda^w}\")сaq_?R A,+L'3xvev/Imc4si8$?m_*7[[k W:MÎayQ|ՕŻ9ΚH#>1丈br;rnQr\EJ?0nEk'Udӱ'`k~(ZF%ƯxOĶ63ZVѠE}&_#Z6O^Ӽ1 ϩϥVizf5-v,6SZ@]0_Ğ$/ 6֥~栱eͧ3I$i,o9t` :e`A2 C,2#eP̝yթN uiNIʏ$N^ޖ;Ecïp\׏qg.g]W%o%gi uK+,]NG߶uosH[U| ѯJUAneO)ªuS?*irV`cM[­ \a8?WBtG44sL۸N讬5X-.#=h&E=Յxku?Sd?/,">kMߊ8W,^> ~_i7Vk&n?ִ%Li|O}2n<7>n8YSt>+ ~hpoѿ˛AX}+bo}cϠZ>_fMվɛ}O5)cMeѾ_=2_/~<ɾ7Fk.s+[?F{_O'Eg 5׎̶9eдiIB>wֿA?'پ͌}HϿzc>v+&AGU?c˟tC o]-c 9Ҿ5zJ~)fqpk2Lٱc3ױ G>Xcu0 fWA=0~ky|Y\INwh xp}8_˧|뻹Ӧ븷^ jVJI%=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn x^ w✶|>@zdg?kwcMO>r$'4>jeXo>L; 爇g2~!gW5y78E')wSj) T1`Q2zOriH[5xO>o&ֵ'B[EW+V˰kAb,fZvr۶~v7/BΚ96,JOzrFrk}_~DžZϧ,ggq~F1z5Ǘ5? QYu_mJW3kfX۱FlYjϠOZ>f6&l-JʗZReLpr~_a/ʗYsOMixb}XVTwga~m3.:~ѫ"~߇KAk*c?\_?}m3&?1l7YK}y}5S=4ok_ӑ/~Ҳ8_?jJ~}qeMϨYO#ínʛ'#YS?iM?+2c?\s_G(B/. Ʊi_ܮy? ?JS/WO\xZ]ULԷ=7㿊uy:wSH)M=ѴG/S,O C J8maqX8=y|fFG-<#//mK}:~H KǍ}30k|U+#T j9!utPH>5Cu?S(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ)_ZY"mdpB|de#[Ǚl]Y3چUOv)Ǹ lj "TgnX- my_2rֿV\xõ)4fk:Rj]yR.z {oJlj}IXg}ƼBlWa ^_ }(0\Yҽ{5ckSOs {vxO4{~tNykM -[yMSڙIO3IzIKh/s?ΔH=g+"clV}q"S}z?~$ogJG˘SZ3OYW8EsI7~ ɏ}OeFWa㳵>ÙVTg?hy?\>uSO{ ?f_O??]jLx8$~F%8 }¹fEo=7l>?YW?*gWU`ۿf?//_QW>I"lf`-&fq[}{??#,6 Eao/_w%x<'j?]QO?=/]\+՘|3j_R×UIx-ո>?O"Z=> x>k'>s~'C>m_-?Ld?+队'O\>x?D j˯סמx4s{+Cx?Rr9=Gs@{ZLClzyIJ7?Ҽ'f>XSФrz־0}k<F9ouu=$ +J:+猟SU'#w>09<?< j˯סמx4s{+}Ohz= NG'}kjF@c.^^y@ҰqOtCx?Rr9=Gs@{ZLClzyIJ7?Ҽ'f>XSФrz־0}k<F9ouu=$ +J:+猟SU'#w>09<?< j˯סמx4s{+}Oh>_<r9=GsE}O:JѓJOOGDǽ4:F㾙g~_ݿv @vG:xA?=ǽ4@)xf__oy*Q???. ?ڧ]zǠ?J?= ??ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWH9m8ہ_?օuUeLy_'&OG)կ93zdqִlz+"clq rIݞ[[K3?7Ì?{ZzT휟\z%=4Z36S<˔ǯ?8B%n 9ʲ<yݿ_mu?{?ƴQɜ<,ޭZ;k?hϘD?19bf?1ҹ'{ / ʔ\~_є}Z~'V~(`߳OñZb|gL+;!pg>*_٫ȝLŘai#oN<(x5? <~g_Q>Yǚ a{qXFjݭ[R/` q3I >џozHxg!&q^q=2==k?]eHP~{SHJW/;&o?,f6xDj?nu7Q|Ϲ{l2[ +XGQ_#$Cb!e}S<{J+J?= ??ga; eovsJG:O@OKx@Ey?OGDǽ4:F㾙g~_ݿv @vG:xA?=ǽ4@)xf__oy*Q???. ?ڧ]zǠ?J?= ??ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWHƿVAQ?w< K)GofjФ^`3u~(f}sOCOɿZ=~oJb{ $_'#~^7 O~uNٵ_*4I{~'WfYq(͖=}˕'Wenu3`{¾Rn }?V┭>dJxӯZ?ϯVT\{/Ky~l1OpȫzO?eN8sMnǽK#>sUfLyzN?ƯLcex,#E;tlΜ9ֲnIOWnXv?˕'8?I/{hmo/Nݗϕc&Sδgl.9?`:ə^?׏*_֧Vo~(Ϙ?k.:hNyp8\z۷GOK}~~Mn`˓Rn뮕(g/ (ꚿ:&׊<ԷŨ*ӈߚbeSk k8yg5#/Vf)O |,nB"Ozt9|Wc?R>v-j?IsqM[N_q} (?c6ƪͱvGZ!xK~E?ሴz|@}ӭ O}kwW1?¯/O6]5_;?D j˯EP O09<?DMWe<F9outW O'>_t~_F@c.@EP O09<?DMWe<F9outW O'>_t~_F@c.@EP O09<?DMWe<F9outW O'>_t~_F@c.@EP O09<?DMWe<F9out}G>@u?S)[I@y@ҰqOt;?DM+{+ΨNG'}kjzu==$ +J:ҾҀ<'fIϭ6zt=Q@y@ҰqOt;?DM+{+ΨNG'}kjzu==$ +J:ҾҀ<'fIϭ6zt=Q@y@ҰqOt;?DM+{+ΨNG'}kjzu==$ +J:ҾҀ<'fIϭ6zt=Q@y@ҰqOt;?DM+{+ΨNG'}kjzu==$ +J:ҾҀ<'fIϭ6ztul~7o_Z k? "/cG)p_KxH|¿8HWo|c 6<:QǪ)G5UK;uK1Ys^?޿l}C. }gÊ8/xټ~!~/>8n6[–]9ґWmr_xٷ;a?yGp<|F?*V'c|پ"7cA?N_3I;kVϭLUnm]9?ҳ&lƭOϟk2W'z!_37~?rk^2퓏sWVd͒O\=~\Os~\i~pۿO|r??5+rO?sүu3`{¹dݛ~GӯעlR'βl̟;t+*ẏîu7]vn }x>o^q?[}?sM{hmo/Nݗϸnβ98r*3dA_Ok.VğoOɮYCE|O~(+rOzAY37zp ?3pO}dJ1C%Gu'=4vOooo7yS9?Iusuo7.sx_7_p}8n|Pj?:Oxmk^o7qqS9 GW 8S? }?7?˛g۵Ilvo㳟+T_Fbʞӊ~X?^;P}OL Y^$zs<̱I5c?#?'Gj̯/#cߌڿskW1?/O=$ +J:ҾҾpSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:r9=GsE"QE>=?*=O_(hJ~PqqL?}|/;yO@OK]5_C<x<%|z#(~DC@ QȔxw?~yl_//{|]5_!ASCx<%ס@x|z#(~D@+۩I@Ǎ}30???.t~_'ؼ'9foO!1OL~~3nx`Wcjx/?S jv w|FnGZgo#_0?|yI__wf]}} u]e_cO>PwV? [69^N?ֿfJv`gqq*n#ΒÖ&zf^msOE_>ρ9ҾCЭOjRyzW'ӏ,A;v?Z5k-?#UʭN}ӹ˕I~WI7?`ioܩ3vOɛ'OOV~>}}MfJ~u7=<6o)N8𬹛$ Vn ?r}}MfJ<~U7pwL+}lY2$^UY36<iv|w w7~9[d}NOqUٛ1U_*唕{xmUV(tYs6=[5vfx2V>'8kNɾ[Ϸϲnz{O+&cA'îk2VOzA\{/]~t;:n \UwjI`it^)_w&cI~;?AW8'R@]{mdi4KVQ/&;{޸ƫ~z-Fq?zWwh~>:6? 鱐r>_ w([ɑf N3P_F-{n%KY?[?#C?] ڳx\SVOǴ6O#Qt;'>>}ahN_Ǡ?J-ɐ?P@<rx=OcI#_D7S?Β<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQ4Bfohb?pO|H>?¿}??"ο4xM_Moq7+p:p3qp |^-fD>w}$ 8sc?k?jSnjrϏӃJ*bʝJ Ǵ}qd_\3V>i~.>-]@a3YL]tG־Y&>1x}X9?M`8[gkޯ̱r(I7xRe2R js-UOaY>;SI'f[>^<ߒ?HKzvVp??ʲ~p>zs5nW$^?5+9^+Rod{xz{KeY<Vl͓9?2/+6g9y 攷vRV\ϒ}MZ'׏f|p+n}_sOnefTcBel}2}>^1?n?ə=?7iܩ+}l3A[\_W&o>~ʹfmsm-ߧo?)[z˙*d͓9?I=[Smv?KtݟNS7Rg_t?s qFO|DX d3؃޾ߑOvuOx{ӊsH5WejW_swMSM\c%A`: |y~}omN,j_~"k;jx:|wu4ڇ}۟p4}g:\u}y>| ˹y q_J^Mv?"Z=> x>k'>s~'C>m_?Ld?+队W)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JS!ztWOQ@CS?ΒdĨ?=ғ@(M+{+ΫѸf__o C%Qξ<x<%|z#(~DC18?|}oO^'e>F? ;;+N#w>lRk\NMA&)E?ίp򇈼QB1nSuPngKSn[!"mN^0cɜ?OۊԯV̗7O#g#;}yo|w)_=OA?M~;RN*N{H 088w amB:izZz$C3>?͕p:On1Sls׿׷7enKB_ֽ5+O&x0=SY7aVy VlOs~?Z_C߫+>}+.w#8zթzn+$?zS\wv3KmzidVq~_$>2?lρy?9⹤ߩaYRg!YI~sVe|}aY>??sJWmsOn}~*Oϧ[}?A533sW$}ǹvYRW>}?+2Vݹ*_?:̝<7[[G/z?5 pIt? ܂='NO|gOx;~k:2{ W#YJ~MV:Ho`͢J3ܩn8x"ɾdoƭsjQA"MTR pVڶ,$a9A.'L:k8X|y$c*vB\T} /sqqq+if%Wgf>?S_2OG g|?:ŋ~׫n1O8UuͯAS˳YG!"I$$VMC"?ɛ=K-64;sOrd^+XGQ_#$Cb0H_>>+sT:ҾҏOGD㾙g~_ݿvG㇜үQν!ASCx<%^x|z#(~D@(M+{+ΫѸf__o C%Qξ<x<%|z#(~DC_t~_F@c.@EP O09<?DMWe<F9outW O'>_t~_F@c.@EP O09<?DMWe<F9outW O'>_t~_F@c.@EP O09<?DMWe<F9outW O'>_t~_F@c.@EP136w; x|o /~s3Fw# sv1~AW"'PM o?تIĜ{y"J"f9 ֞p ly#\灜 +1ۿB #8}I_F4&dͪϤpmJx=+}haބJ [kRK#xK.Pn9uVX>YO7' ӗd,n,{d&$x?zY;?qYɞ?2^HGm=篒"IfM&I}9}k6WGs男lhROv!Oyf$8J͚L ?kRտj=ۮd럧cAYItʧ ³|3nJ本O-DI>ϰ:t$ӟY1}÷&|簮i+wdWOYrIRj_'²|s>'{#o~5hGſ>yV8|aV3j[cƝ{K$uS1]>[e:E׋Ci,N᳃Qda-mW7|5~o -wc3-qms Mkum,1eK4C >:o5]5^aP[ Xm--b(;r~q3 Tgr^89N8)gNR~2Xڵ٘^noS)ЫNtriӜ*{GUc(J}~5?M{\7a?:Sħ?MM9eGkp ~gau~4۷c ^34ݾqھn|x$nb2ⷎ% o.D}U4zֿ8b*7>ZrQݻη,NļE*jG3 48mz/j[/w^w#^ @r1͗_{t:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{C^?/QΊIJO:JozۥyOz'zi_[i^u@Rr9=Gs_CW }G< iX8WמxVy>4NG'}i}G袊ozۥyOz'zi_[i^u@Rr9=Gs_CW }G< iX8W_z7G^z&i5ז~Y[!{۩"5/$H $Wsl5W>tn(g}9)ͽƧ->mc,Ysg|C9.WkuJs-8!xŜ Fi:._j52szT3Q'iS [VuM?GumFL"i l-A{#(rR+@?c$^!ۨXJ *A]j8$qq$"6HɃwI㞡-į>+G;MIvlm=5FN#u qX~ s~1Hu_MCui#6N5?,MjE{O.UkT^WOm=ֽG?fKf>+x%axz -Pi'*k:V&5Ӵ;p꿮tbJiv|XA!n4 h66?xE {bŘ:Wp?쏄_5 i{췺_|^kEm~ڪ^pXlmRW|f#*$'> v~ߩ,} _o%7];mR)Au~&_Ǟ GO|1P3>(\5~H_xX`iЮVqgcĿ_~ x?wVZ|}}j{[ċF^R?O8h^ |#-WWടMcY/oO?2ω?'KOӿᄆ$ 俋?q#Q?|!/D|Q&fO_˟ S~ğ"?/u_^?DOW՜Ho]v/G|K4 N?r?X>$k)U 'sj#T|DJ`0kz_~C787'g c]# D l|)fw:hf:Օ8RT*Pi68Z>*ȼ+¬ρ<<鼹SrXV?eŵʭzUqZBܶ5/ aI9Y1|z{~I2ڎ΀LK;r>LMF>85Pwog[k]Z;mBwmaE.y4-*0_]-CD,mt=6Q-Bdt&9Unf'Fd("ucHӧ':Uc(Ùs{*YO~[SI+ Âqx8{>QxNc_^;,V_GmȫcpXq)]~hRV+WI+98zz W?q̞N>O^p;WSYI=Gs~ ?a׿Yҿ{߿sJ[vG[_+O V\}'anɟoYMg[>͑ 5bg}~5<s 曲|[eY_$5+O?'קf݇ד\}>EY_ϰw>SYRI>5nw>:V\́?sMnǹ_ϧ駫eY_?ZϤ|aֵKm{+.eWۤovȥAd`Al翈t6$Ksx"Xb 98wIpQm۸qI~%'{[];}eWJG#RHF4d,[hßV˺-ǃW%E5)_-<AhͻqNǖ:<l8xyr(t?lm' #5enj_)} ]Y+BM_.s;yk\?(c#ordŌQ3VE_Ź3 Y+V k9|I|N{ś9W3|:)̿%n|<*v7?b-Js GI?௄PxׇS]WHwIfpz|cP[*Ƕk'WEz?Ob}\ng/(fG\C/˭-8#سX? y|0r%1qMp uƅ'|{uuad9l&)i1Xʼn>񳌺bnR5{L'{|GSZJ~^gpHH/]zs٥x9so|{Cf濎S\\v6 2 ,RMw˨>^W=}:&kjmnj3Zixoѧ`_ |K}+yPVwIӵ!o~w̟r"ozG[?eϮڎ=7 ig}} vUFO:>#jWS~:eC+i%s>3~xg:Xk<ĩ=J+.?菍RmfC1M [H:ѳ+“_r#NO#_P8U^KxOii>ʒ$I7 vfmٳlo9v-'-R#~ k4[CT|#N99ҕ쑭Y7Q#Jý07|랄ZoOۈquD$o`=uPGEt_/*mSu̷/6ENu| kse\_X8T0Yfѓߣ 8 n=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKK (#Y(QY/#8gwf¢,Ĝ 'ߴ$f h:2{/4-1^xf%Y\FmJw! ͳ*F[̱НW]I/v(Z}9}Ƽ59?< ³C Bru1R OԝFoƛ7]_Q a$4bOɕ3q-zQ/>XU/0X?v5NO?@o]ޱl~R/ҾySq /bRYa2[z|'쓥7 -@[?Z'Za`:]"JYN&*mU[m՝g*vvlU.́zi>&@ IᬃuF:)V-yxOp:y=?^ό _xT%vypQ/kҾ#C_R*ʲw{[00onڿC>)q&}3|g3z%LZǃ5h؟q&=sW5_)J۹b!Qmkܯ/e[v~X|{QZk6>ܶ`}  wye sjU7'`@ ;@+> Ƶ 鎙W֟Xq3(\UO)KXMU}NSHѧdGos7EǸ*-j?5O4.-, /SSrX9t'98YxT%]$FGFJ0<`A_:M[FJ$@}/P.G$+؁|o=@Ѿ*] /x;I4 ?{i}Ju fyNO9Q)թr[E΄i$Sx]`jԧLU\.m\dbUu$}>;Ldz{JՏI_sp4[=3_#)_E^_h !ɻ#?_@z|g tqztvABY;>y- ;_vo,?~٥>$=+6I:yzӞrngB_erɀGs}g&zI:y穬$I眯ۯP mm< ̕}}yK,$uW#?_$}Rݿ{Xz[ine~ =OǠ̕I?StjyힿVl#yyKvj=./ĂWs?_'qsgׯ{du{攷okKm;^vy~IVlվڬL?ϯƳf|g +RZW'~j˕sfwɛzpkn/==='V!Cm3&oI4"[kͰn+xTT^k-:xo [O/7]&mRU",WOhX6X I4^7׌E~)x \p-lGfbEJ]K /zR UIyT黾E4 qepxw tcȱY#R`1NL jԱ(x)ar{ )8+}f` =G5>}^â1e},4?xn7 kźf?4@3`_lqE'XUԂB$<jy.vJޛ6w#lKwn1T4MCCGVGɚw9(Zʀ`rjt{#f~-eٳO? >p{>vϾZM@NI5ɲI*YV[M%eɁFݤx.>R;w'Y:7y]:h ؑM5nF= Zbc|>W!:y~Mcڱ{Sk8<$U-hRKQGS3Ly=\fXڭۻy7o  xz-/Fӓm㚙t jRutEP> 1s~' z*RJ.ѧN6z%ό;Vfن[hA{M?N¾|I=~V!8Tta77(bQi6\$?K;<k›~S$NyH'?SPOg,._JJyPK+Z0ӵrVV<ˬیi҈5˟E?j \< .}Iߢ7^P>W=L.)7З=bGqgPkUғO}91Q~ɗViV s~v j[?x=~c=vgj6~jA8S2SᩑdeU?Ǘ'Qg`XOx6ոLjh[k[f1#ZWÚLq.xDaėGձpMxWIx߅91i-RB{<:.nG`5>s~2 >%gFYhTz3יīVܡ]oKG .aJW[5%x4-<fy%Q+crr? l)f먧]M|K$tnGvrq_ğ#h߉Qor<X 3xrYe+K |Vn񷄴{"-6><~8Sg$WMHUC{6BO.O <IO3ˀkFVO)M7Wjbi%(Eo/-EJP »e/0&:rV|_69|I% Oχ~-!ORFZ[I/- hH)!W< t {mͶQG"捶͏Aٿi R3EJosPx_5"\?Z-ׇIkK֬M\o=2_KZ97$budwVKٷ.A| eJ?Ե [v/­c=%Y3ek>0d-Uܲ9yT.X$a'ڕj0=oĪ|gØ%7x=88R&uTR)jѧHE.l~]bq4GQG'GG"WS?Βb?Ѹf__o C%.]סA=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@z<2?jzrEzQ9<?I@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}_ƿ;k>iZ|8qaȷWyw]32xxJIϭW`߶ra<.: < 1GA7?Y$>,C(JZѧ4tQb? i?[߳#x"|PG=)&Sk6 *oOE4HI7S.h}Ms24m:+;r|zkiqc\s~.;g->T)ռWM@.cL x98Ӷg@faNC,* CA,0 &30 )^jc'e8SG>WǕF< ødOC ZԊVR[~mt 7O~W~~-iK^~Kc>6u"|fp?_G~kfB[i7G ӏ R.veOm[*}7W>Կk_[}ZY$۞y{}k:I3OR~oZlu$ dIg.}iɟ}+>I3pJR~yz(wlgç͚M|sޟ4?x+>Y19'=q+hz(~#N_ooAd}jIds=k:Y6z\[=u۲)?l篾O嚒I1O?ǿ?|u$&g.ߟPn|p:Vt`oK#$}_l}A\[/hRO˽[vC+'?ɬ_zL֦NztMgJ$gx+-{8z[|ߢ׻!<}?޲~?SsɫIOqZ͕O`?׿'ڹ+%6{Xz[iӶ̂W$?;rsY[W4k˯O^w{t)lۦ?m_H+fk:x[ߡ4Tb$>BBuCAA^=;=k2gxqtqX]^?mEV6gdX*=V2#6O?li9 JՋ,@~5e韵3s$&LOR$VK3eCLk洼R!Mܿ^ݿ+O)O-K6>>/rPlN|adO?V&g:tRZxdoz-Ͽn?cDzn~'o_G\ݓ9bT>:{NWs>ϯTO:p?+|YҿdYݗl4E='m87{1QurɵoO)G6C|qW=| x&#.?mm|V&A<"2: p\q+?Qw>SY=?gpTn"nYr5]>TlxK'/ CkmbNHo 9u8=XLt>~__cXxUǦ<zWR }~lǓJ૟^sɿqozt}^ O h[xk4k{>vw\r+l_>g#s0hbjofYnh_J o0aD9=}Mx=,5ř7/Ϋ=^ { <ᬖpJ#o2|]wj|Qn񟈮}|FL5^֤ _S|ugtҹϾsֲZ^ORsҤ e8+˰Ih$/cJ$3Jz!k;Rh,$w(}W%Үm&yy׏PM<4}z0wiԍגw+,&UFPTQi%i{8?U)E6&O3O$䪔?*?Ц <>ٱeЪ7&7_Q~)8&mRw'J(l!u2Vk[kim&Gd>* a(KK gOk7<1 neмkg4:崳4heP[q,em–/0a>F+W3(>AxF{H|} &s?̰?/^+>v ǂ9|MsjRe%_ ҥl<(c-B'%>$TʹsL㣷6/pV1WS `rx=OcI#_C_'y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}G:+NG'}h۩I^z|z2Tz}I QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?TIߵ/&s,u>{/e' m_f]W5XwI=B*~6mOqFX͎?gqzS=5eEoŠp62x#Zn-kyˋ?gřpjf9l*%)f}OVas&?ϽXm|/CiQݏ> YeR~T0?Z;4m;~36?Oj?DeVs&vfy^~.Qݿ.?ZaTZeJ=+m</W|)=N?SWi*LO櫴u9=_b:ӯq'/='ڪ~YO[^e<>Z?Zy8UO)=?0ǁJɿ%nwS?}VXysU9'_ӭWy8׷_UG ?_ Rý4ۻbi$I?*1Q<3'TR{V2}~zm7?"Y%}:5JIBvG$}>"I&rIc)7J ?[}II8}ITdON6II9랕JI{/XWmiD:I1FI6{Zl?Ssֳ<ɬ%>/N >ݽI3O$8__I?U$?O[_ѣ_/Y3:ӧgM.8{v4 +6I1O?甭}ztZ_ d'</a5$O?tc$g&2Ig鄥o6֣Gm?lc$?~fe$?Z|n'#OZϖLϯaֹ+i}_(QNj2Y2O<?o$9<z|g t}}{4ۧ?yJ-/ ХSIoS8_9egK&=+rw#ءKnr~QG~5<`}]YIՏ?sVu=ZJzz3YҾ8O~< K#$3y_=OA?Ms]]/SڡKm?rHi00?;eTI=NzsYr}3W4?'~ȆW#<Z͚L }su}y_Ϯ?V\yuivm[A+zǧ9ٟįOaOçOSYS>F~8sM/?N&?_x_*į}|{~:z瓻n-oOm>kEi_t83>N3S^be|?_ǩYKvoOo4v+L}+2grMZ'qYS>IW4{{xz{|Oȭ+Sx&l ?ZI}ӧfJN}q{}+n}_sOm?_բ=?߷eLcujW'N+9^+oKw===m}?]=*8YSr3o_}O+?\S7wnao~߫]J6N~ʨOl߁?ΠY;=QQH(+ǬϾv`uW!#@O#r|U?%752,RNxj/S_5sxuopݙO+g_FbA+<..{_O_Tctr>q~&M>BqNbh7h 4n4Yݚ=jhCdt1H0zr9?ڀ>)|7ԌG'W>_ho<1L{Wt3Dzf*ө~=y}3rq>PS7|+Ԗ9ŭt]O<| !'*z?4%xVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?C#&!_tP7S?ΒA=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{CwiW|bY]>6WI3W~Wi?iOJ#P~|d\?͌;3gT2jmO?G?a~\~➇"|><xKqMc۫ds_=6?gAo1_\g  ql?y;Sv'eC=u2?xfۮO>_T~/j(jN,v u~TԸ}x{3,zz<<9 ?ƚf^GyV^kHU33c/''V۷7޿n&r}5 J{?˟TV$ZiGv>T9EuNEJRO:?`:֢iX P*]N/'Dp^_G/.~]x?1P4÷?~4u$P=3˿j}:aM^Ɣg^ßҩ4뚬ҁ\~Vnk_m_ȶj~~uY'(?_ʳrowe/Oo>p?_玵Q:z?JSǟW_AT >sRoKk|Xy{^* ώM@?_9RKwwB|39=?sSLg~y@zT䗩c RoVGJ_;mII9랕FY?:Y/_^*y_Oe6Z/Ş*io;kc䓻jg$??$RHNy?ְ/oR [O{Rs?͌~K7a5$'{)[E^~;i/?Iy_Y$??$c$QLz?\%+y];i_(^$??~KߩK,=ju{_>9[;i_9=^d>dNLp9'?PL?{sVo=jv~~vHl:[?gI'V?S9'{c$ORQOϷ܆I'V?V|ucg>Y2O<?o٥$;/o~}+RQOҲݑ&I4A\W4e3١Km?}!N?f&~ï?ҦO>k:W'?ӓ本=mݐO&z˕r׷zՉ_~Y<+.W$Oι}_D?z ͙1O?ȩ|gǠ_}q?קs===?;`{ǭew?įI?k6WIg֟&W?_j̝ǧ2Sa}}|{Lֹ۾cOZgw53vON Zs+O?'-}iVw?ڲoՙ_9>+6GOs湦L0t"cE]((6oTv;Z+׿ EeJsW|;d 1[_똮Ç"^?ҷ |/ gZVGP(X~n,mFĞ?ݞ9]O(sӽ}!EQԆ?qY~+֧gfpvg}&tSq_X,m5;p`(-G>D<Q?ZFxĴ~=]5_C< j˯סW O'>_t~_F@c.@EP O09<?DMWe<F9out}G>@u?S)[I@y@ҰqOt;?DM+{+ΨNG'}kjzu==$ +J:ҾҀ<'fIϭ6zt=Q@y@ҰqOt;?DM+{+ΨwSm+|m/3|gsD<ϡ+ jkByjˌuݚ_i[-c޶:_ +n?٧G  Q~qPѿ؊oO q޿ O q3rx0ҿ/ؚmǂWo_' o q-$-Ͽ/x9.$O龚4 3Kxz>WWd>0jh:ϱ/W4P~ضzdz}'e1tzU?9IsX˽;a3~s,{ gWOw԰_֞K֩*3)IUgl:a??.xk ^o'e/3~fzߐ}sj]E?k5y迯E:1c~}Zf=Q4{zEKo 6tOK]iGvsfi?5I_\G? LON?O5I=^{:aO=eƔ?ÜsSiGs~pOӯsθazSBt?ǭSyIjqr?OwbO|(?_ʫ8}UZaڲsom??u<>~ZXy:>*OU9$rrO׽DCT'?e)~,iPYI'v>QbxR:IKg=s~%>=:46>I1rOZ$䜟4%|?aRHI<kI+N EݱIԓg?ϖRI4e,O?S]P^??J~VAI$oɀ{>$rO2Is\գGm?_c<A|nϠ8$y*g_}km;i_(^d9ɞ=)d9;뚡,=kRݿ ;i[uoQKӥgK&?8I&2I>%'q\;i[uoWd#??`8&2O_Oש6Y7{OXJW}^rIgҳ䓫|S Y7g=+:Y3?\Җ [;_޽~8,'wR.N휚Ε??男l(RO{)_$y٤$?sSM&dd}O_=Rݿ^gB/]dS>xlGaSJy?`wEZ =O=xeJ[=n_o^۲#9>ÁjF}O 擻ob9bɅQH((+OL8;]p$q__ToC(Lz9ݏs5p|'?^;ҷ=:8G> ypnj<9F:ȼyLzb)~'iVe7['~q&E2 ]ֽgRԄW/U#ZmZUߵ*zˇwv@=!~H52!(4OlVY=$ +JSOҾҼꘇ)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:r9=GsE"QE>=?*=O_(hJ~PqqL?}|/;yO@OK]5_C<x<%|z#(~DC@ QȔxw?~yl_//{|]5_!ASCx<%ס@x|z#(~D@+۩I@Ǎ}30???.t~_#~G|7Md#'~h?qxm$T@`wM~7>魇mgocԡ%ak7'VYzvl/n?1_ߵb;O'B~3־dSIZת?3Pד =D<{7SL8P7o_Z,]gy}_e'M08 v?g'R_EMwkCD̿_3L3zfU>ߒ4m;~]߯SE<NQ4' 37 T-/t'7˯o_.ӁNO&`:sMBғC9L0^_oկԸ%/o5LO:ҁ!=Gҡͽc}ӯߩm=6:ǧ(NU~>Ǿ>^~u׵m?.sN:_=֪<8nVy?=So[cm?+OS׷7e?Wy=O?|{UW?ڲsKm_C˷bw'O^?Udsǯy@NI19sZRB 뢲'`8˯TLw~C<U9$3I%*i6DJNpp?OS^s{_\TO)=?O$+OiPO۷ЖIB'~C%ݞp?$II.{{a)=:4_6]v/P:ީI(z~L^q{=:zJI?SO[o7ojzh-4yLg{=ϒLp?ҒI3?5FII8?+ Jھ{=:4vQZEL8/QN?ڒIzǩle@?%.nlzh|z z|c$IOsrOFI3p/hOBK'V?U $I8Y$I:{>泥@?Ma)_/Qi~,3_+>Y99&e$?rxyJW=;l#L$XaRK&I+>Y2Ov=O\ߒ{)mieE#$3yd>=~4H? ͕??甮{4)mȊW9?ӷ95+㚖W?Ƴg>˷5)^}dz~Ȇi2q?N1YN;?M+#?gJu?Ͽ5)nu==-忡 }=Me&NïsެM&çsڲ|<~^e|یVl}><{@{l`u}'9o_CNצ^ey#aǭfL8@T==?=Mgv` 2kWTm}?w~~M#keqbjtsھ:>?GXX,?'~![b~ù!ʆIb}U;Gy댿W|W}HA-{S'_C;"nO;5gŦߧx6}wjG9i"Rf\ob:_̸׈3c"3 5'd{5҅1u.RwK65{}*}-y_}FKE9HGH|*ʓ,yr_?Ek*X䟳9o]%-Vz߯zWcu׍Xb!$d hŽ:30S/?1_?؛,~]J=Gxqھ˕|}7PiE|/ꦭS<\| [͞0e'$|OfyM3/~Y#a%[3(X/)e?3t9?OT2m4?Tffǧ3z Tf_s9ƱyJݮ7̽~o}sNPi'u\cOҡ=m7O_3ӏO*o~?MPi^9 =?.}tC _bN??Wi??Qi_PMf~T0Zȸ׏SjM?,jJSp*?!8ǸVnko#}o/Sv }jJSUy*%'}3 vEw9_5RIUW8Vy/};v/u*Nq?nP9'>zsU^R{&磊O}= w&y@NTy1Osy$TR{~E)POmՓ6x<3qT xzO/P>&w SoEYҡo&rI3AT=g>NYwte;hҥB-w$P8xT$'O_lLrO??T'O\z RK}[=*T|%|_2I$ݞ?͎^X[y#ԣCk/ ~&'$ yYJI3p/(OI&rO=}$I<?~'ؒL=}<=qXJWK=Z4vQZBis?oS߷${O:I1rOZϒLgp?ְ/^I&3ܞ>Z,s==d$a|dx~ׯA\[u=z4vrz&rOA5$=OsӤ9SA\[u}סGm?^64ïsg'>Y1$>=g&$ް/У_?>!#YJ v={zjIdQɀOs泥o~$ucgg'V?W<|f-R)d<>8ducxR&IB|_ǩ~_?fLw}ҹe-==-/oDe|{3ZNI>lV =jqQH(((7#ۡһ*FOF|0o칥iz>_`גu~IT9c?@?!/-]gnOI|?Y|%GK-/Կ6:qq";7Ѕc3(ht/.{@|i, ŻvA>ŀޞ1 l|_L^%txtwsxAITl5uQfzߴ_q,E/zg4__\V{ݣ `rx=OcI#_C_'y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}G:+NG'}h۩I^z|z2Tz}I QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK6e?ώVO8,Gwk5? I#˓'c.)>5y 6^7Ŧ&{GBŗQrTǴ?JKƘW㧄a~W.V{MuQϳdI]xRK#Џ3.KgJDH_[Yj8W{jwdB ?ok @/ 3^ou=ӢmcNA_],v#U gJ ՟ӟK\|*O͠M;Z^Jlezz{{75~~7oX+{{Nzyx_ϏAo>0|N|wC:1ꈧp1[)|FIoc$aN+\?BВ[TphGVQv)ׯ9{,5Zz_}L7~??fot3zבk ۧ}37?o?Fe'?+899gTǿ#ߚ责z~QoyvL37=/hἺBLǾ;rC-(E-2Թ0i~^i? J{~T?Rz?nߦk75wY ?/ú̼([9?TP: '?*M<uC>-rP?.櫴?cUP:/*LOOY%vSnKO(,sӁ*'zǶOfhjvZZki_@*NqI3:w>ϖL?!\[_סGm?/K&I=gΚ\briK>d}O+R{(z#Nÿ{V|# }}*Id{qz³\[_ءGm?/?ol̖Lz=ATI}q=B|S 眭߯ХחmJOYI^=K#$3yd>=~9t]7f-m;lH|dϧ>ϑ3ךW>=9U$\ݖgF??](:B((((G?OE?Vn dأ'+|,1eMR|gPQRZ4TW^nT^]G,o5g'>{Yet!?qYH_O0ǷNx?L;i#пh!sc}Ԧa:7\yw'?~)um޿ͯ|?)eǠ?J?= ??>ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWH_t~_F@c.@EP O09<?DMWe<F9outA1:Ih?[N۱#Nm|g}ylAq++ ~_uS״]l c#Y<9/g9=kh xڴW^IwؿEfc/q._)Ybg$ʨ9ۿ1'JWo~~>&:ǿ [\!ִؐoPϙ"~fW?엨 h z3ג`8lW؞TSp̑^<Б$x]I# ~3#⹬ԕ gaKr2%*pt#KեxW*vI=zJlpO@B/&1pFr .ps޵Iڍ*MYeI,ڂ̄{o"7BOpE3]Hy2dv,I$޿JU<Җ21$;?tL+ѣExU*N|xxs-֦M37\OZP(ԼmK\;JL'j~>"ȓlϽѺGb?~X#SO_?d[:X eUզ]WsĎX~yekp~ Z?}3]m4\+Qۦ_hu}S݇ L{rgWտO5_ԏʔ~ۧ *^3 ?&̣1_˴?WgFbzqE@{?&vgOfмB{t4Ʀ_OĘ8Ni'tIX/W cÙm|1[oo=@Ҟ~Wsp~Q4Sd~?7ҏx?ҡ⨿JSӿ߳6E+'Gn4gW[j,ܳaq?G&v?Xai<-ZW^O"n=dyӻE/\÷~5Y'O+#LSV魎 R"qZ1fcsQϿsoEoqs v?{ Z=Qy@s^?:8ֹ?^:FꛆAԬ2=4 y_ᵻ~e 8>YP}c(oŧ ߏSy8U]I?⪼=_SYInvRMv'y@9?5QOឞ?  r_UG$?_ׯ&;aOuٓ<皥$g ~]?$g''=>5=Tک(>}{U $SϧkKez*|x_劥$OaL\~R^~~'c)_/K.'$r}{RJI</6I@<g&rI>JWmvI7g;J$p_ZI%'88=Oj,sXJ}_;iuHYe??YIOI%'p*$+ J-#գGm?I$I9'$??~g$)$a甭?ZA&'ۿS޳䓰>NrOgڨI&8Ұvz(ndnBi{z:YyTv xt=j4v_u$?|u$?)22fbw{a5?4E$dqˈn;wksY6ߓ){ۚ8_zq_}5d'3%$:V4*MF޽6vYCzEpzb#_c(Myv^k]QQ`nl^?:?Fܲg>v$o/C z._*&nW::)UmP(kKA'[3Zi3=95+~'5"Ҏqt =s8_S}sMlsS} Qk]TKס2(:o뮣u^yhieK4h-_2/_$?<3JIMzMgwG9vVS*IOM?imGs]LMϋy.]N?l03n%9=&sz'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{C^?/QΊIJO:JozۥyOz'zi_[i^u@Rr9=Gs_CW }G< iX8WמxVy>4NG'}i}G袊ozۥyOz'zi_[i^u@Rr9=Gs_MށXxhhB2.Y7 -oHү\n3?>XQ;[|DxLڷ{U񅭺k>-7Oא Wc|Ajf1F|$SJj2TܤR? a|=φ& ,8b5alU*NoJt0Y\jՓ(ѕJ.20; Ȋ,u݁15lnk11qӟ~Gx=o^*>#cwZuS"7孮*N%JD~|UAisqk3̭w]c Ik#k[@'d,Q)7U7RnkqM-]_X\G>qBBNZ9T9$ҝ;|S#6]ź|Ay%:ΙZhZxe: x\A

ugҊrΤ﬜wguk ~Y[qUJ>G+)'YM_)`?0}h?HXqs?M,ORh?FyD5!(Ǣ]+)s1UtRM'k4N=ElAo]5ng)s혞>$"\J ~$_~+Э|MǗyhm8Wx))Sծ&o'I*5^Ԫ?HK7/E,MzZ:X?֚HM}k/Oǟg]jlsVgnKO'A_י>aqjSͣ gyE=w8ǹ:a$md876a-tTY%ԧϳ:=+fc+Ck$jZøM!$N1aVuz>#߭jKA>Jk> UI/VMNQ_?(]6[8}{cIuM:Qմ E4{d-a{]$g˸maRw4 xWÈC40۾)I~|d麶R{~uQ:rRu%tӴvwZ.;2qWd>i\'}UyIzzWy<ǞzU7zsۯ]R^oLiޖ_"̓Q_V2ҡ֟$9$$~cr};ojgxOXuc)uoJ ?[}IspqTn@NOv?QLrNOac)7ѡ˾&rI?8)9>$I8,}a)E~zh_ޯA:~Mg&2I>$9'_OQ\rNOSR~oR ݓY$I9'$??~g$>YI${[_QvzHI$oI1FI1rOZRѣ_/I1rOZΒM֫:u6F$(;<֑m7%H>}T~뎻qSRQ~?ԟWNҡZ=:|Wݻ?RJcpzrkaH ;$dhĢF.}UE;ku#9DsV?ҋ $eATsN}#m9DI yz/ahV~(O=-.?ӏ?Zzztg/*]jKz׬f0X_n\=WC׳(QZFO$CJq}s*9*'KS.o?,|cEw1KuÒcf+PU/RgL8k<]YTyǿnÑӟbUn:z}'o`ȠȊ8U/HKnOۚ*_RvrnHqSE5l<%V6`I)?NkMNOa@UحS Q(oű&iҔʢuz^ ̣8N>7,;RJ F7YYoxwvHI]Tљ]y#쬣1[!+ y* 99Wd# KŲH#]^H 犍*RU%ʣVItQNWoDoeT2:ζ.u)K ET]ޫ5z'-9ZQ)oKx>n#2Z3&x$Z{}o]-ܸڗ/χ HwB4NG'}i}G袊ozۥyOz'zi_[i^u@rz֊E>@|z2Tz}I QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??.3qoq\C-ҼSC*r$mhȌ)*A"xn4iM4ӳMjkT5J|G|[?kK't+4STFݎ*e_:\_~xºmok$!i A00]I fWmm紼) 'U),3C"r"1GՕԕ`A"$h#7ï>%=~Gx$~m%ýJqpζb7Լ'ʻ:Vz=|bjx~d7Vytg5(ToSԓ%%y=)s.JpU~O*.bQ,+QsL,-NptcS U*|sB" Ǭ=E_j|WX3&3JX,B82]X|֌r-7`!\-}Gxþ&[z~n}399QO /U%ϠY4n<&`R. 2E&z-R#//]"]i7zχcmMa{*4MPӮ#d鎀ߋp9[UtjF*L.!-7S,ҷe}dYif=kakq<'j2jakZsTtQ[!O|HC{sv}O=N* p @Λ7<|C)A^<LVbXJT5/ |.>C}|Ts(>2}mGh7g?{ucoӛxI~JӧoNhe.Go{{vr}>ܰym~4=y:yZuOb$YCuG.7=q2"n}b[F'iDvc(Tp⛉Kx%1kgԂ}CK?A&||uc;~x^凯)ۏ^vs?)gwBMU5._s˥nl 1\,vN-9=?T )ߗ^?Q,q֒8(J1L5͟+_۽[qbX酨jP]knrUt_3߃>ig5Y  9_GpOQ<>{r7? MϋnI& sƽR]~Sk.[>JVϝ{i|c?zǛ~4gSV3 ~@Cq1nIɃmn:y9k' wL'VQ G kqӗ'~?s^ۯ#R<c,/w}/6PLڿ?HL? [XPr]Dg .9vCm1,R_gvMf?:}}=?AmƮ<m%f{9=:{Ÿ^5]KG D-Aװ :!f1ʓ "(aʭ7V9ߑɦһIvgv2 Bƭ(͸R8&Sǚ~Zy7:o)wkv0gu#MvEځg;k4ˏjZ}pmmgʙ$;nMyUdw+ꤿ[1~1iS:2mun3wgl_9Sy:>O=* c#۞;Ugv9y?J_|rgQ5 OSOΩ8}kM-= T6k99?Qbs?td<ïOCZRJ vMY#}=jcr};oj9&8<'*x>e&o=*46v2I%,N?*@~ڙ$p;RQ{OV[wGF[w.?U)$Ir$nrr}}? $V2[gFEՎR>U %^t=QQ'OҰOVAK{^BIv_I6{ZϒL=}տ(Zi/$޴z1j"#*,= y5'9hgeF-咲Z'4K]U"}~~A#ʷgEkn:X(&j^զ}G$=}?T&@?MQ^erO=?thԸ!=2 >w?纚$؄4[̕$eEg 1^R^NwmS8.[xKq*r\u(B0&Wgm$'{ђN{{{ kFxpTh¯U ݣ2Tdqwħ|kn8>nG$ҏ=W.޾Ɲ%Zk>]4GPÎnWkq.~wIEhI&2O==?ldN+[ϊۯlOG"+<G˜g9=ڹ g-Ї 뿫OO k;`q_[Q+8˧Sc{1s3SC?-;-os!~Gu?|2_𭉿mYwl+G%(t' *?]Oϊ632'Wo(z&10n:Ls?O Gϊ63؟7)_L6#ֶ+OC?Zw [Tο?\د7?_TW$K8QF<)S:x_ޗ?Wb蟮7_f&bSgQ^؟ |ggn0FQdwn|gY` N~y. HԸG78RUa+m.~s}"9Ӕج~:MT8|JX*jZj| u$6hx z qk_fx?7RY"LyY;{RV[Lv]f/)?dHtO 5\<]~1쌅~moW4:/9mCQ<I*w'[UYxz ϐ_b5>#-Z466dᦴQnb)UNzr ttܔ^&J~+'/'k4QԸG+QIFኍ UIzt}*kyo x;O4i>1U4nc1NHeuX]dK =lx^p-adY. ˨(JkY$b+/i^Z9ͤ)݊?O3̸ˉrd]/x4()u*4Uyx|z#(~D@+۩I^xw?~yl_//{S!ASCMWe j9!tHXSФrz־0}k<F9ouu=$ +JUu*ꮤ`GGW?cwdsq+^K$ w75o'fIϭa_ Cp14*uԌSgY%c2,4qYNa˱+ZUhO!c=y:ge!lxVx;WQ^!\,i'`ԛºLoW>Q^n j2<ï*ImeIOrF_ckhq-6jXϚNn9~|>M>>`6x?H%DcWJCzgQZJ iX8W'&۶'g?HkxӾKH_՟>+f<[;.Gco=07ĩNma\<9߭~ܩ9\#ZUrұ~ʯ YZ~&fYo} s#͉|E>1 Ϯ<]c=k|FۼG6<^-g7n7|qrkxKckdY^̈́>}* tf?jvp)a |"qjO'5>9?j pvrut{CΩwoljq$c2Q̟1a YFGyqͻ;;޽6&5oǃ<fL9zHV9ny>52(9.R2"ڏ8x_x OKJ_Ϲ:bh9|:8̺}ԙ?Z`?F;gO>/ogt;Z&',/:G7E!7 JIo> k%i s jGSOft`Ut'USA מx4s{*%է2]a%۽:hxJx|@5S1LgOh-"Ytg欄UN7|u1 ƿ~4QH'KxUp^)q]i+{6'˷5cJ^w[ſJŚ hswo5۴F(-6=K{)/͟m?yt[k:w\__g_"E;\[c'$MyI=97f>(TeAdq\Y~~e'yImMƕ(4_qct3-y 1'Iךs| W=]4 N~G>ý]yz.veSȆ=:Oi'bz~'<L0>QO??oBӁ*$w?~sKm/'},;Om?i3ԓ8T?yP)9<*ˌ_ϧJRKVOB ^rY$$8gtP2I=$?S!XM#ҥCodI$_z)&8L\7[ME/1k.dIGagri<_8nGep&e?P?k$R=#I'>hx|_OZ[#jQֽ'ێyF1&We?=s~~ ?i#ޕ?Övx'Kko(t}6$V;X1Vsj_g^qȳ\W^p߰ SЏ>4zڿb83E|bL]z*ӕLM u䒔!9F0U&~5C^>ɲ9'-+2IQ䙦'-RJ4c1b\Mj՜):1N_z|Q¶%X!*$l =}q9Z< iX8W'#Oyr/c=,e9G91?}OiTOQ' ⿗#?dL|Qmz"O?V=_Q'!xGW[3_ERiM0g7ŮYiWIJ7?Ҽ'f?E<| &7o:gz_䏁?ȿx6~ș?a~)9S_Ywxysg=>([av^,~zLGm񆞿>Ѹt-~מx4s{(S_YwxGW[~`Ñcc -??ȿ}3Jrz֏?E<|Loux'"dS3m3ԟz|Q¶墏?E<|&;o:gzE)ڠ-mi`Ois}+{FS8'>\0``/~x4s{+}Oi/ ˥[Lq6zkToqlχ,O|BU-n$póZ vƿc~_Q&tǍNDŚ`sj OQCx{ %:&W g,<g^T7ŝP3?8jq|OQՌZ41TUH.>e=#}v"tm: IZE $ƫN9W j˯סמx4s{+IE(($I$$ItH¥JNZV:*JSRrms&۔mCx?Rr9=GsL`rx=OcI#_C@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}G:+NG'}h۩I^z|z2Tz}I QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?}^x<TyKGQ@^yޚWZQ QȔxw?~yl_//{@ע?*]@Oǐ:+@$e8Ȕz?4%=}oyz77_w?÷T>@Oǐ@$e8Ȕu=}o KǍ}30iW^!tA'<ŴLxk'E/\_1Aα`HrNO_.zR[z_7bw?Qbs?t^\=!TRzp=_V2z=T6+CJ$y3~ˎ^orII=ߙe;_Rۻ&y'_AU)f?OX?AT9'}/ZS_>ztmu/k$Ny^_o)$I&2I^o)$$XJVo=:46$&rs{~&K7acSe?ԎI(?;V2V=J4/m?ny/d~ t¸rI?zWYFݭ7#'rU֕7cKyz'dŝ̌Ag7¹ Dw;4w]Wõ2|_v3qq\Ğ3Wwó^3k,le[ 3tIjmm?^$Ն3D)5-Π[9:f6xDj?nu7Q|Ϲ{l2[ +XGQ_o ˆrX%E~ >7h5Ozi7I3<{J+J?= ??ga; eovПsJG:O@OKx@Ey?OGDǽ4:F㾙g~_ݿv @vG:xA?=ǽ4@)xf__oy*Q???. ?ڧ]zǠ?J?= ??ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWHynL3d]URs=y ˎXj.V2VF֟ɤ >&y'ӹ~fP3O$?S!YJm_=T<G=:w*^oQ.zp~L]j>>ڱϷ*iZvZI$dO>J[ ?S_?D_Əõgx5_`? SfLy=ϭv}hxK7o3QScttGKec͏ h+yqܚ\䓏lNMk%'zW4СxAx꼗}~ /7e?~uQ?OçUbzp?[U^P2sq8VNm<>oy~ZnXyII&_C*NǏW_AUP;[j'Jt-۲MY;OSOΪ<A\8yuQ@]:RV$zmMY3|_8U$'obP3O<x%-ߏSg_ҡM$S< $֣yqNI19>[5}z4hmuDI$xN?=ꔒp={gLLO?2~?~WDGH늡$'O$$~I'8;V2տSӣCm?{8_6I2 u>Eba}CIG[KgOᾷ_HmJ_7?i'}n7ō.]S?(q[LfvG>O~3O__G3}ǿe~?Ld?+队5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVTNG'}h^?ǣ'%G^ ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??.p~'?g?N~nݦ|tcOS__Ş5~uz^]\7hxaƝcc_6WP0g8)x Ng*w8('zs򨋓ӏQK͟Wx>BQ??j͞?OO*S~N=&v_rOJ_w,<8UQ'=:UOSN}qs-47eŇO៦2.S~']'zv{=qe)%z)a֚imk3ԓ9UR{T/ O?>x)<?c)v= T<z"gsl7 ?ϯ5 ?q&&y'_AV2z-z4m|ȚIҩs^.] C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@z<2?jzrEzQ9<?I@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}_<9<Iϭ} @<`עx5\se4NG'}h`rx=OcI#_C@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}_<9<Iϭ} @<`עx5\se4NG'}h{ !?3x߷C @6gf׿{oK "/cG*nj_5ʜ#{vQwp83?e}y {f~Eg00b?ZJV~en99z]\GT_Wr4;XsӪOR{VS?\!3 oRp:dh<{#^4iI-]ޯ?DFG,0=Lg9=#3U^Q2Y?S̲j')>WVNoo;XyIxO/k~1Sr~?F\~j  x>k'>]vc(/mc]s]+~#.1دQOGi}!㗊ɫ7SԔ_-?z'U6]Ǥ`ޟ_F~6zO*;ZS`Px5\se4=|zօ'#w>5|#^ @r1͗_{C< iX8P_5 W#u:ozۥzO*;ZS`Px5\se4=|zօ'#w>5|#^ @r1͗_{C< iX8P_@Oǐ@$e8Ȕu=}o KǍ}30iW^!tA=x?G"Q QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?}^x<TyKGQ@^yޚWZQ QȔxw?~yl_//{@ע?*]@Oǐ0ȋ:6xv=_5T qx#|O<foO&~~<8nUy?ϵ`_^ZZyIp;zTysZx?*'VNMziջYyR{ׯ0ҠyI}:˯5rzp?_d/'}<=?o瓓?<%v: (((3?'*~)1_Ovݟ/ "^>j,uqzŁ?ޞC"?M| 3|q ӏ_Z-GNz|mN|9*b:o8Cg?QlFswa{k!^5gŅ}4(7[~|z#(~D?fpG%|ԩM'n' 47O3ŧUӿS<{J+J?= ??ga; eovԟsJG:O@OKx@Ey?OGDǽ4:F㾙g~_ݿv @vG:xA?=ǽ4@)xf__oy*Q???. ?ڧ]zǠ?J?= ??ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWH?q89g%礚#۬ŕ1mu5cc֕?ӰaxpQ}c\}}(Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U> ;pJ~pO ^?-K.OCӗm(Y1+ߏ^gW3lmDj?t?r P?NҸ2v닃:R/QΊSѓJOOGD;n%z77_w?÷T<U+: ?ڧ]Ǡ?J:ẟt KǍ}30k|U+???. ?ڧ]zǠ?J?= ??txw?~yl_//{S!ASCMWe j9!tH?]uoFaմ}|+GzJjõ]6_־ $w}6?78IkSI%_aI(6@+K eNqfGk>_=zn7\Y o6թ 6}P#// XדmxWV&}GV֦c 4ۂNI+T>=x?G"WoA?hl| 1 M-@} R@~'K2Su__ /՟GK8` S]el5VGz?4%/7_w?÷9EMWeT j9!utPH>5Cu?S(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ|Q/㦍kޗሼa,|Xx"E86H_vqmtW5 pQW"Of׭:󤎎!zU4#m~U Oo_7]aS=/עGg/ܹuS|SUAzr+BpQ_iE#ҥ^uF*J*/ hS ѽ!kIO3P_?˟º/D^d>TO*O~>@^K>Xl㑑P*??u~Gy ux^ ӡ{Wl 싮=_IXFiƥ ū8֝5RZ9,jZ\a׈GLˋs`j5r6. .߼Mtv>x?D j˯סמx4s{+?0='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?E| ϭ;u?S+OFOJS/)?= ??ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWH02)v*ت3BRsT­*M}ڎZy'[m_HGQQQ"FKµX3s9%g,۴'/%3"Կ"cj#]';d|їFkB:VfeϹqt}c?y?[LG;+SR??aJw&tg)#I9dC[qi?gԃ×qoX#U`iס>ϔq4䶗4iW8OBzơU6#w=ZP۫8ہ?%Jp+>gG߹EO^jU&4b)X- {9֌UN/ ^NJjHZ_Q\*he}6*6MO9$ÁgâXLI#)y "89՟wr~m6L";o,6B`8QWTTp^ޤfpӟdrIc]cĒ0bi) )ԋsWO]Ɣ&xu;5ZK"(i UrŘb1ҿ^~8|4dg:x;{ׇeèE{ p̩}*s_|,4VM#,"Q<:|"*d\ VMDc,`ߏmIZ]KVV<-H.KNZ:Ʒo)OT^%\nq;+̯QBNU1R]N4iQ+B~ sra<1u#Jtft"4y ̫beB>9n>YЫ[5aT* }^x<TyKGQ_Gɞ^yޚWZQ QȔxw?~yl_//{@ע?*]@Oǐ:+@$e8Ȕz?4%=}oyz77_w?÷T>@Oǐ@$e8Ȕu=}o KǍ}30iW^!tA=x?G"Q QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?C#&!_tP7S?ΒA=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&|R ?l j/2O⟇졃,IJďWEƁ,三/4dOf<k&SJn/'=CxOe{Q5âiҶĄK}ep[|F9oux^vyxAKj/m{Mմ[Eua p2qҿ=^,RRf k5:U_YʹUjsU)`?L~1!R*aqTe79cc E*xwRNn^iPZZ_:s$ѼAnLOu+q(=߹n<'F+qd8ch_.kV8*N{q_-|Q5w\Ux|1b$ 붺EF_K6?>9xcXhCRk9nz~?i_;_g/]BIZ$C2x_Ĩ:M=r7 |Yw?<ҿ_r@_]Y5!+x>e՛s:{e|UӯOhsqF|?mPX=1%)p4bE/\!&?|^a0em?gKb'ϟSgM%}Y^ q2瀨~|J*[__ۭ?ǥuДTP=.\!Aoï|>3Ki9 բ@zLktg'cvI°\Qr˛WCgOeF\lR͈=.ͅ)ng5HRiwÏgkh\k^y7|;#cx,JOo-_.oEIVl?iGV_ )>IRgu YU^(w? "?i?|vz|0lx{`gm7xt ͸fPD|tyfyn*]] G|[Irc~R_rZٴDlqHH;;9bO`s` m6^bXU?<qڿ8?_OEy |BpD2VF ljhSWor k>10V߇Mh ufiQIq<ܢe9guyT-ջ+;ḃx{N 9_Ck%on*BQtO< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVTNG'}h^?ǣ'%G^ ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@z<2?jzrEzQI}“aQEz/Uuoj=~El> $9'(aW 5Q[^k=~F?_$9')6QP 5Q[^kC}GQ@?_ I}Š(6Qz/Uuoj(C}Gl> ( I}“aQEz/Uuoj=~El> $9'(aW 5Q[^k=~F?_$9')6QP 5Q[^kC}GQ@?_ I}Š(6Qz/Uuoj(C}Gl> ( I}“aQEz/Uuoj=~El> $9'(aW 5Q[^k=~F?_$9')6QP 5Q[^kC}GQ@?_ I}Š(6Qz/Uuoj(C}Gl> ( I}“aQEz/Uuoj=~El> $9'(aW 5Q[^k=~F?_$9')6QP 5Q[^kC}GQ@?_ I}Š(6Qz/Uuoj(C}Gl> ( I}“aQEz/Uuoj=~El> $9'(aW 5Q[^k=~F?_$9')6QP 5Q[^kC}GQ@?_ I}Š(6Qz/Uuoj(C}Gl> ( I}“aQEz/Uuoj=~E EPimsprog-1.8.5/IMSProg_editor/img/plus.png000066400000000000000000000024061520775651600203200ustar00rootroot00000000000000PNG  IHDR DPLTE:5ٿ5={]ÒCt]j뽄,P}g}꽊upS1:sU" x11dbnyUOcEG`^yrl|xure]Iw!ÅojP(CϝƊXT@6/ ܷد3߼‚gb`=tɏȍňs[,ƍ^zv|s!N:&$ʑtaW7Ðhu~ ;̗˗ʓԨ~S>~uĒL %$z9CGtRNS  ?L?;0 75( oϕ-gIDAT8uwSQoa)J{,R,    H{z2o!r?8%׈ HpACmmIz!ms oݲXc e1\wT1(33){r̰ uUgNɣywZ~ߜ45F7+'P348o <㖖G/Uuvtt>w[aվ (Uybى;ރ:|{k46i ]0<`"%9Sz8]#CjT*,G+t?T#߀C)W ;'ofGJ%N݂J׫ >*4Tx|y%D8Wt*`e=Y_ ?_?r\AV q@8A\6SWd7o1`т8 [*b8姑Mj!zmCQrjyrO@!Rfugd1HE%>y3}#A$$E@؍[LǮIENDB`imsprog-1.8.5/IMSProg_editor/img/redo.png000066400000000000000000000017311520775651600202660ustar00rootroot00000000000000PNG  IHDR szz pHYs  ~tIME 3-T>6bKGDfIDATXmLaJHN:5̲YkYhˑLikaژՇPPDCY#FZ,Eb%EOO[//}뾞#d\O6 CHUϣ k l ~DK2]pu(݆f U8^/vΩ,i"~6}ҿLԵv9EBGcMW NIH;w#ftضPƜjK? = R+_!pBk]({\Ê~!J&'RN t'A$kB\l!FfQo"y=ĺ%?ZOl000u%ğ,$DXmUI[_qJaFtΧxk/Eawu_[I\X&A4d:q#dwTŦBr?nl[>gY Ds|Zx 9ZP.YڰRf!96 h6wY'Z5u1h0 "D\{g/gʜjhgKZVo+;6&XB^9,XWPG4<68J^@`ȑBּpB0{5|@xN1Ϊj7kETS%iQ Ec%l 0ld+.<L.o,""*Y s8 EHIr(Ll0=F8&`,"P7Dp6Kf"8/&ETꔵ !_n&-0_IENDB`imsprog-1.8.5/IMSProg_editor/img/save.png000066400000000000000000000022431520775651600202720ustar00rootroot00000000000000PNG  IHDR szzgAMAOX2tEXtSoftwareAdobe ImageReadyqe<5IDATX͏TE{n@FM4DHČL\.M\kXÎč΂htA\ =`PQ` ^` QVR{:ԩz~6>>]vN5ػ」;v<:̗7XSڠkg|p?0x.ory #ӟd}k@E@xp,#˲m00aP|#%"+Օs΃* ,I Iw:琷Ղv+m(r8 㯼IkFؽ{k놮ZVmQg5 ,# /#&|#!Я'aa%% 4M:ólc V_)Fara-р: TIO4/!g iXvj#wPE x:Tx3x$wh6h߱R^DM_ 8ňKvRPZ0}@Ű&WU.2p}Ʉ-Jsf+7QW?תd~')Ü wl 55Y1{X0+WVU!ѐS,-޸Wj'WڣU<_o|w__sl}5ځ?MKFIENDB`imsprog-1.8.5/IMSProg_editor/img/tocsv.png000066400000000000000000000051411520775651600204720ustar00rootroot00000000000000PNG  IHDR szz pHYs   cHRMz%u0`:o_F IDATxWk={fzvwx/`yB*BCP 4EJXDM)bQ  h  ID JD䑅]޾1.ɭ?vsO{!_x# C}0`6ѫW/yh0R4Be :zS[KS^v(amǑ$Ii@޽faY!p]555\8$I1a&#.CRU㙦aOy(2iGf,^ؔ;qd !}!eA PByBOY?6N=~:7ۿv&f xT$LE+˚ 9V\.qHYPȪ *DكԳיּ}C r-#Գȳ@HʀVf&Z鹮JipptC1[sGښ?g ɀTP GS^~끝JTc @D." }<1 *JLT$P@Wtak^|pڂ P;k,f= bh:i59Xn9Hq륳0E,W=(vhڎ[ {瞁W@ڋ4 oTaI@(=_"u (*GP3i`~G l hKC){DO18( $I0 {OFQk0nd*ڊ96t5a?|o~8)!Y'%, Œ 2"/L@T:grasĮ%k1yX㑩K`:Dt,|랞yK\ǜ>}ݾ}639x),b TPA8 aᆆN4*̟v F7N1[x*YV}=m*$b sY{w}Puln܁NM*/WdÁ/޴_57dT.+{Iu]P9>E!T@LIj盨e3ƙb^ڹD3B bCWEsEҴ0E°ز,*ʞd2% ļg:^x 0UB{G `3Ǜ7۝/^9k+xcѪ7}'|I a:[^ƈup1|*VS{X]?W.PIB03ߥ0q`p=s /`҈~C@f°{&ܲ|̻-)UQGqbm E)! d?`d"@NcE"˄15`PLW9hνX0 T.޴g>uG-}xiAHUr;-DX Ω8WL&oAǓW qPh*f_ LۇvEs[Ӑc iʏ;#fd\^؇Tx˲ ǛwLFhd?1dB@`gTXZ&MOLkɵ:Y$4+xfc UQJӱQpu$Wi3+:Xօg57h'-JHHRH)fg8*FƐ(?m~r/=fVꁡ+fX{B#]IB[MWS(gOP PZ0\X@VP4N؎(ĐT'4SJ,*K^H4&'QΞ1ብ7`$p ?403fuɾQ]7>z2qidER|@"纓{r9pC.w"N@"_;;=2L8vB7mB km7l !T"JiזPĄ"&0n#9DGˮ@Ĩ6ִfu*  Y8D)b!@XTV2dryb^Ή=͟]vpH{W3h0y IE|{ |jZ?L] *sS^L (Pw 2j{GPH.{oj߼rC _Y-v;v#x7ۏXDcKB, @"pY0=!ò,8۶ɸԙ~i'8=W*\X_.C:\ץRNTWW#4MyHӤB`hF((A6m" CaHlFGG2 "$I-̮I{{L&9G\F&A[[jjjP*e!͒ 7$G `IENDB`imsprog-1.8.5/IMSProg_editor/img/undo.png000066400000000000000000000017021520775651600203000ustar00rootroot00000000000000PNG  IHDR szz pHYs  ~tIME 6*-WbKGDOIDATX[HTQ4^2InCt"5pP&O:ZVjIʒ¬({DDBHj)"Vf&""%_g63:7eֿ{FKOO P)\/zW6aPD'ڈu*=|7E8|Kj`>Qv2HTx,rBJ{X7@6  `b_.>Xs1|`c!Q:9'Wc |m]]= "YDx!iB MainWindow IMSProg chip database editor IMSProg-Chipdatenbank-Editor File Datei Edit Bearbeiten Open Öffnen Ctrl+O Ctrl+O Exit Beenden Ctrl+X Ctrl+X Save Speichern Ctrl+S Ctrl+S Delete lines Zeilen löschen Delete selected lines Ausgewählte Zeilen löschen Del Del Add line Zeile hinzufügen Add selected lines and duplicate data Füge ausgewählte Zeilen hinzu und dupliziere Daten Ins Ins Move up Verschiebe nach oben Move lines up Zeilen nach oben verschieben Ctrl+Up Ctrl+Up Move down Nach unten verschieben Move lines down Zeilen nach unten verschieben Ctrl+Down Ctrl+Down Export selected lines to CSV file Ausgewählte Zeilen in eine CSV-Datei exportieren Export to CSV Exportieren nach CSV Import from CSV Aus CSV importieren , Ctrl+Shift+X , Ctrl+Shift+X Open the file Öffne die Datei Current file: Aktuelle Datei: Type Typ Manufacturer Hersteller IC Name IC Name JEDEC ID JEDEC ID Size Größe Sector size Sektor Größe Type HEX Typ HEX Algo- rithm Algo- rithmus Delay Verzögerung 4 bit address 4 Bit Adresse Block size K Block Größe K EEPROM pages EEPROM Pages VCC VCC Warning Warnung No string selected. Keine Zeichenfolge ausgewählt. Saving file Speichere Datei Save file Datei speichern Opening file Datei öffnen Invalid CSV data file format. Ungültiges CSV-Datenformat. Invalid CSV header file format. Ungültiges CSV-Header-Datenformat. imsprog-1.8.5/IMSProg_editor/language/chipEditor_es_ES.ts000066400000000000000000000230661520775651600233630ustar00rootroot00000000000000 MainWindow IMSProg chip database editor Editor de bases de datos de chips IMSProg File Archivo Edit Editar Open Abrir Ctrl+O Ctrl+O Exit Salida Ctrl+X Ctrl+X Save Guardar Ctrl+S Ctrl+S Delete lines Borrar líneas Delete selected lines Borrar las líneas seleccionadas Del Del Add line Añadir línea Add selected lines and duplicate data Añadir líneas seleccionadas y duplicar datos Ins Ins Move up Sube Move lines up Subir líneas Ctrl+Up Ctrl+Up Move down Baja Move lines down Bajar líneas Ctrl+Down Ctrl+Down Export selected lines to CSV file Exportar las líneas seleccionadas a un archivo CSV Export to CSV Exportar a CSV Import from CSV Importar desde CSV , Ctrl+Shift+X , Ctrl+Shift+X Open the file Abrir el expediente Current file: Archivo actual: Type Tipo Manufacturer Fabricación IC Name Nombre IC JEDEC ID JEDEC ID Size Talla Sector size Sector tamaño Type HEX Tipo HEX Algo- rithm Algo- ritmo Delay Retraso 4 bit address 4 bits dirección Block size K Bloque tamaño K EEPROM pages EEPROM páginas VCC Питание Warning Advertencia No string selected. No se ha seleccionado ninguna cadena. Saving file Guardar archivo Save file Guardar archivo Opening file Abrir expediente Invalid CSV data file format. Formato de archivo de datos CSV no válido. Invalid CSV header file format. Formato de archivo de cabecera CSV no válido. imsprog-1.8.5/IMSProg_editor/language/chipEditor_hu_HU.ts000066400000000000000000000231441520775651600233720ustar00rootroot00000000000000 MainWindow IMSProg chip database editor IMSProg chip-adatbázis szerkesztő File fájl Edit Módosítás Open Megnyitás Ctrl+O Ctrl+M Exit Kilépés Ctrl+X Ctrl+X Save Mentés Ctrl+S Ctrl+S Delete lines Sorok törlése Delete selected lines Kijelölt sorok törlése Del Del Add line Vonal hozzáadása Add selected lines and duplicate data Kiválasztott sorok hozzáadása és az adat megkettőzése Ins Ins Move up Felfelé mozgat Move lines up Sorok mozgatása felfelé Ctrl+Up Ctrl+Up Move down Lefelé mozgat Move lines down Sorok mozgatása lefelé Ctrl+Down Ctrl+Down Export selected lines to CSV file Kiválasztott sorok exportálása CSV fájlba Export to CSV Exportáls CSV-be Import from CSV Importálás CSV-ből , Ctrl+Shift+X , Ctrl+Shift+X Open the file Fájl megnyitása Current file: Jelenlegi fájl: Type Típus Manufacturer Manufaktúra IC Name IC Neve JEDEC ID JEDEC ID Size Méret Sector size Szektor mérete Type HEX HEX típusa Algo- rithm Algo- rithm Delay Késleltetés 4 bit address 4 bites cím Block size K Blokkméret K EEPROM pages EEPROM lapok VCC VCC Warning Figyelmeztetés No string selected. Nincs karakterlánc( string) kiválasztva. Saving file Fájl mentése Save file Fájl mentése Opening file Fájl megnyitása Invalid CSV data file format. Érvénytelen CSV adatfájlformátum. Invalid CSV header file format. Érvénytelen CSV fejlécfájlformátum. imsprog-1.8.5/IMSProg_editor/language/chipEditor_it_IT.ts000066400000000000000000000230531520775651600233710ustar00rootroot00000000000000 MainWindow IMSProg chip database editor Editor del database dei chip di IMSProg File File Edit Modifica Open Apri Ctrl+O Ctrl+O Exit Esci Ctrl+X Ctrl+X Save Salva Ctrl+S Ctrl+S Delete lines Elimina righe Delete selected lines Elimina righe selezionate Del Elimina Add line Aggiungi riga Add selected lines and duplicate data Aggiungi le righe selezionate e duplica i dati Ins Inserisci Move up Sposta su Move lines up Sposta su le righe Ctrl+Up Ctrl+Up Move down Sposta giù Move lines down Sposta giù le righe Ctrl+Down Ctrl+Down Export selected lines to CSV file Esporta le righe selezionate in un file CSV Export to CSV Esporta in CSV Import from CSV Importa da CSV , Ctrl+Shift+X , Ctrl+Shift+X Open the file Apri il file Current file: File attuale: Type Tipo Manufacturer Produttore IC Name Nome IC JEDEC ID ID JEDEC Size Dimensione Algo- rithm Algo- ritmo Delay Ritardo Sector size Dimensione settore Type HEX Tipo HEX 4 bit address Indirizzo 4 bit Block size K Dimensione blocco K EEPROM pages Pagine EEPROM VCC VCC Warning Avviso No string selected. Nessuna stringa selezionata. Saving file Salvataggio del file in corso Save file Salva file Opening file Apertura del file in corso Invalid CSV data file format. Formato del file di dati CSV non valido. Invalid CSV header file format. Formato dell’intestazione CSV non valido. imsprog-1.8.5/IMSProg_editor/language/chipEditor_pt_BR.ts000066400000000000000000000230551520775651600233710ustar00rootroot00000000000000 MainWindow IMSProg chip database editor Editor de banco de dados de chips IMSProg File Arquivo Edit Editar Open Abrir Ctrl+O Ctrl+O Exit Sair Ctrl+X Ctrl+X Save Salvar Ctrl+S Ctrl+S Delete lines Deletar linhas Delete selected lines Deletar linhas selecionadas Del Del Add line Adicionar linha Add selected lines and duplicate data Adicionar linhas selecionadas e duplicar dados Ins Ins Move up Mover acima Move lines up Mover linhas acima Ctrl+Up Ctrl+Up Move down Mover abaixo Move lines down Mover linhas abaixo Ctrl+Down Ctrl+Down Export selected lines to CSV file Exportar linhas selecionadas para arquivo CSV Export to CSV Exportar para CSV Import from CSV Importar de CSV , Ctrl+Shift+X , Ctrl+Shift+X Open the file Abrir o arquivo Current file: Arquivo atual: Type Tipo Manufacturer Fabricação IC Name Nome IC JEDEC ID JEDEC ID Size Tamanho Sector size Tamanho setor Type HEX Tipo HEX Algo- rithm Algo- ritmo Delay Atraso 4 bit address Endereço 4 bits Block size K Tamanho de bloco K EEPROM pages EEPROM páginas VCC VCC Warning Advertência No string selected. Nenhuma sequência selecionada. Saving file Salvando arquivo Save file Salvar arquivo Opening file Abrindo arquivo Invalid CSV data file format. Formato de arquivo de dados CSV inválido. Invalid CSV header file format. Formato de arquivo de cabeçalho CSV inválido. imsprog-1.8.5/IMSProg_editor/language/chipEditor_ru_RU.ts000066400000000000000000000240521520775651600234150ustar00rootroot00000000000000 MainWindow IMSProg chip database editor Редактор базы микросхем для программы IMSProg File Файл Edit Редактировать Open Открыть Ctrl+O Ctrl+O Exit Выход Ctrl+X Ctrl+X Save Сохранить Ctrl+S Ctrl+S Delete lines Удалить строки Delete selected lines Удалить выделенные строки Del Del Add line Добавить строку Add selected lines and duplicate data Добавить строку и клонировать данные Ins Ins Move up Переместить вверх Move lines up Переместить строку вверх Ctrl+Up Ctrl+Up Move down Переместить вниз Move lines down Переместить строку вниз Ctrl+Down Ctrl+Down Export selected lines to CSV file Экспорт выделенных строк в файл в CSV формате Export to CSV Экспорт в SCV формат Import from CSV Импорт из CSV файла , Ctrl+Shift+X , Ctrl+Shift+X Open the file Открыть файл Current file: Текущий файл: Type Тип Manufacturer Произв. IC Name Название МС JEDEC ID JEDEC ID Size Объем Sector size Размер сектора Type HEX Тип (HEX) Algo- rithm Алго- ритм Delay Задержка 4 bit address 4 bit адрес Block size K Размер блока К EEPROM pages EEPROM листов VCC Питание Warning Предупреждение No string selected. Не выделена ни одна строка Saving file Сохраняется файл Save file Сохранить файл Opening file Открывается файл Invalid CSV data file format. Неверный формат CSV файла Invalid CSV header file format. Неверный формат заголовка CSV файла imsprog-1.8.5/IMSProg_editor/language/chipEditor_uk_UA.ts000066400000000000000000000240351520775651600233660ustar00rootroot00000000000000 MainWindow IMSProg chip database editor Редактор бази мікросхем для програми IMSProg File Файл Edit Редагувати Open Відкрити Ctrl+O Ctrl+O Exit Вихід Ctrl+X Ctrl+X Save Зберегти Ctrl+S Ctrl+S Delete lines Видалити рядки Delete selected lines Видалити виділені рядки Del Del Add line Додати рядок Add selected lines and duplicate data Додати рядок та клонувати дані Ins Ins Move up Перемістити вгору Move lines up Перемістити рядок вгору Ctrl+Up Ctrl+Up Move down Перемістити вниз Move lines down Перемістити рядок вниз Ctrl+Down Ctrl+Down Export selected lines to CSV file Експорт виділених рядків у файл у форматі CSV Export to CSV Експорт у CSV формат Import from CSV Імпорт з CSV файлу , Ctrl+Shift+X , Ctrl+Shift+X Open the file Відкрити файл Current file: Поточний файл: Type Тип Manufacturer Вироблено IC Name Найменування МС JEDEC ID JEDEC ID Size Об `єм Sector size Розмір сектора Type HEX Тип (HEX) Algo- rithm Алго- ритм Delay Затримка 4 bit address 4 bit адреса Block size K Розмір блоку К EEPROM pages EEPROM листів VCC Живлення Warning Попередження No string selected. Не виділено жодного рядка. Saving file Зберігається файл Save file Зберегти файл Opening file Відкривається файл Invalid CSV data file format. Невірний формат CSV файлу. Invalid CSV header file format. Невірний формат заголовка CSV файлу. imsprog-1.8.5/IMSProg_editor/language/chipEditor_zh_CN.ts000066400000000000000000000226701520775651600233660ustar00rootroot00000000000000 MainWindow IMSProg chip database editor IMSProg 芯片数据库编辑器 File 文件 Edit 编辑 Open 打开 Ctrl+O Ctrl+O Exit 退出 Ctrl+X Ctrl+X Save 保存 Ctrl+S Ctrl+S Delete lines 删除行 Delete selected lines 删除所选行 Del 删除 Add line 添加行 Add selected lines and duplicate data 添加选定行和重复数据 Ins Ins Move up 向上移动 Move lines up 向上移动行 Ctrl+Up Ctrl+Up Move down 向下移动 Move lines down 向下移动行 Ctrl+Down Ctrl+Down Export selected lines to CSV file 将选定的行导出到 CSV 文件 Export to CSV 导出为 CSV Import from CSV 从 CSV 导入 , Ctrl+Shift+X , Ctrl+Shift+X Open the file 打开文件 Current file: 当前文件: Type 类型 Manufacturer 制造商 IC Name IC 名称 JEDEC ID JEDEC ID Size 大小 Sector size 扇区 大小 Type HEX 类型 HEX Algo- rithm 算法 Delay 延迟 4 bit address 4 位 地址 Block size K 块 +大小 K EEPROM pages EEPROM 页 VCC VCC Warning 警告 No string selected. 未选择字符串。 Saving file 保存文件 Save file 保存文件 Opening file 打开文件 Invalid CSV data file format. CSV 数据文件格式无效。 Invalid CSV header file format. CSV 头文件格式无效。 imsprog-1.8.5/IMSProg_editor/language/chipEditor_zh_TW.ts000066400000000000000000000226771520775651600234270ustar00rootroot00000000000000 MainWindow IMSProg chip database editor IMSProg 晶片資料庫編輯器 File 檔案 Edit 編輯 Open 開啟 Ctrl+O Ctrl+O Exit 離開 Ctrl+X Ctrl+X Save 儲存 Ctrl+S Ctrl+S Delete lines 刪除行 Delete selected lines 刪除所選行 Del 刪除 Add line 新增行 Add selected lines and duplicate data 新增所選行並複製資料 Ins Ins Move up 向上移動 Move lines up 向上移動行 Ctrl+Up Ctrl+Up Move down 向下移動 Move lines down 向下移動行 Ctrl+Down Ctrl+Down Export selected lines to CSV file 將所選行匯出至 CSV 檔案 Export to CSV 匯出為 CSV Import from CSV 從 CSV 匯入 , Ctrl+Shift+X , Ctrl+Shift+X Open the file 開啟檔案 Current file: 目前檔案: Type 類型 Manufacturer 製造商 IC Name IC 名稱 JEDEC ID JEDEC ID Size 大小 Sector size 磁區 大小 Type HEX 類型 HEX Algo- rithm 演算法 Delay 延遲 4 bit address 4 位元 位址 Block size K 區塊 大小 K EEPROM pages EEPROM 頁數 VCC VCC Warning 警告 No string selected. 未選擇字串。 Saving file 儲存檔案 Save file 儲存檔案 Opening file 開啟檔案 Invalid CSV data file format. CSV 資料檔案格式無效。 Invalid CSV header file format. CSV 標頭檔案格式無效。 imsprog-1.8.5/IMSProg_editor/main.cpp000066400000000000000000000044741520775651600175120ustar00rootroot00000000000000#include "ezp_chip_editor.h" #include #include #include #include #include #include static QString setUpTranslation(const QStringList &searchPaths) { QString localeName = QLocale::system().name(); QString translateName = "chipEditor_" + localeName; // skip user-specific dir for translations (first one); try the rest foreach (const QString &path, searchPaths.mid(1)) { QTranslator *translator = new QTranslator(qApp); if (translator->load(translateName, path)) { qApp->installTranslator(translator); qDebug() << "Installed" << translateName << "from" << path; return path; } else { delete translator; } } return QString(); } static QString findSystemChipDBFile(const QStringList &searchPaths) { foreach (const QString &path, searchPaths.mid(1)) { QString chipdbfile = QDir(path).filePath("IMSProg.Dat"); if (QFile::exists(chipdbfile)) { return chipdbfile; } } return QString(); } static void initPaths() { QStringList allPaths = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); if (allPaths.isEmpty()) { // do not translate qFatal("Critical error: QStandardPaths::standardLocations(QStandardPaths::AppDataLocation): empty list"); } QDir binDir(QCoreApplication::applicationDirPath()); QString binRelPath = QDir::cleanPath(binDir.absoluteFilePath("../share/" + QCoreApplication::applicationName())); allPaths.insert(1, binRelPath); QDir userAppDataLocation(allPaths.value(0)); if (!userAppDataLocation.exists()) { userAppDataLocation.mkpath("."); // XXX some sort of error handling that befits the application } qApp->setProperty("app/translationDirectory", setUpTranslation(allPaths)); qApp->setProperty("app/systemChipDatabaseFile", findSystemChipDBFile(allPaths)); qApp->setProperty("app/userChipDatabaseFile", userAppDataLocation.filePath("IMSProg.Dat")); } int main(int argc, char *argv[]) { QCoreApplication::setApplicationName("imsprog"); QApplication a(argc, argv); qDebug() << "Used Qt version:" << QT_VERSION_STR; initPaths(); MainWindow w; w.show(); return a.exec(); } imsprog-1.8.5/IMSProg_editor/other/000077500000000000000000000000001520775651600171725ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_editor/other/IMSProg_editor.1.gz000066400000000000000000000014551520775651600225260ustar00rootroot00000000000000 jIMSProg_editor.1Tn@}+F25`Z\xVl($ (%fdhǁvaTEUcf]rB-\J OdՀ%s2-*Mz^mg40tQqI>lU5AhcU&gȲ e VKL:NHj$Z=z4,~) dJ[^aEroM &R}:BM4JŠ22cn7l}ӷB}|R|]0^ Ҳ%G~z@Fyl]vD\=\d/\!w0CD.o,i!+~^rz?Gs(=5q[%eiYR_}imsprog-1.8.5/IMSProg_editor/other/IMSProg_editor.desktop000066400000000000000000000042751520775651600234230ustar00rootroot00000000000000[Desktop Entry] Version=1.0 Type=Application Name=IMSProg_editor Exec=/usr/bin/IMSProg_editor Icon=/usr/share/pixmaps/chipEdit64.png Path=/usr/bin/ Terminal=false Categories=Electronics;Development; StartupNotify=false Comment=Chip editor database for IMSProg Comment[en]=Chip database editor for IMSProg Comment[ru]=Редактор базы микросхем для IMSProg Comment[es]=Editor de bases de datos de chips para IMSProg Comment[de]=Chipdatenbank-Editor für IMSProg Comment[uk]=Редактор бази мікросхем для IMSProg Comment[pt]=Editor do banco de dados de chips para IMSProg Comment[hu]=Chipszerkesztő adatbázis az IMSProg számára Comment[it]=Editor del database dei chip per IMSProg Comment[zh]=IMSProg 芯片数据库编辑器 Comment[zh_TW]=IMSProg 晶片資料庫編輯器 GenericName=Chip database editor for IMSProg GenericName[en]=Chip database editor for IMSProg GenericName[ru]=Редактор базы микросхем для IMSProg GenericName[es]=Editor de bases de datos de chips para IMSProg GenericName[de]=Chipdatenbank-Editor für IMSProg GenericName[uk]=Редактор бази мікросхем для IMSProg GenericName[pt]=Editor do banco de dados de chips para IMSProg GenericName[hu]=Chipszerkesztő adatbázis az IMSProg számára GenericName[it]=Editor del database dei chip per IMSProg GenericName[zh]=IMSProg 芯片数据库编辑器 GenericName[zh_TW]=IMSProg 晶片資料庫編輯器 Keywords=Microcircuit;Microchip;IC;Integrated circuit Keywords[en]=Microcircuit;Microchip;IC;Integrated circuit Keywords[ru]=Микросхема;Микрочип;ИС;Интегральная схема;chip Keywords[es]=Microcircuito;Microchip;CI;Circuito integrado Keywords[de]=Mikroschaltkreis;Mikrochip;IC;Integrierte Schaltung Keywords[uk]=Мікросхема;Інтегральна схема;chip Keywords[pt]=Microcircuito;Microchip;IC;Circuito integrado Keywords[zh]=微电路;微芯片;集成电路;基本输入输出系统;IC;BIOS;EEPROM;MicroWire Keywords[zh_TW]=微電路;微晶片;IC;積體電路;IMSProg;編輯器 Keywords[hu]=Mikroáramkör;Mikrochip;IC;Integrált áramkör;Integrált áramkör Keywords[it]=Microcircuito;Microchip;IC;Circuito integrato imsprog-1.8.5/IMSProg_editor/other/io.github.bigbigmdm.imsprog_editor.metainfo.xml000066400000000000000000000345731520775651600303660ustar00rootroot00000000000000 io.github.bigbigmdm.imsprog_editor GFDL-1.3 GPL-3.0+ IMSProg_editor

Chip database editor for IMSProg programmer Chipdatenbank-Editor für IMSProg-Programmierer Editor de bases de datos de chips para el programador IMSProg Chip adatbázis szerkesztő az IMSProg programozó számára Editor del database dei chip per il programmatore IMSProg Editor do banco de dados de chips para programador IMSProg Редактор баз данных микросхем для программатора IMSProg Редактор бази даних мікросхем для програматорі IMSProg IMSProg 编程器的芯片数据库编辑器。 IMSProg 燒錄器的晶片資料庫編輯器 https://github.com/bigbigmdm/IMSProg/tree/main/IMSProg_editor/img/chipEdit64.png

IMSProg_editor is used to modify and supplement or export/import in csv format the chip database for the IMSProg programmer.

IMSProg_editor dient zur Modifikation und Ergänzung bzw. zum Export/Import im csv-Format der Chipdatenbank für den IMSProg-Programmierer.

IMSProg_editor se utiliza para modificar y complementar o exportar/importar en formato csv la base de datos de chips para el programador IMSProg.

Az IMSProg_editor az IMSProg programozó számára a chip adatbázis módosítására és kiegészítésére vagy csv formátumú exportálására/importálására szolgál.

IMSProg_editor è utilizzato per modificare, integrare o esportare/importare in formato csv il database dei chip per il programmatore IMSProg.

O IMSProg_editor é usado para modificar e complementar ou exportar/importar em formato csv o banco de dados de chips para o programador do IMSProg.

IMSProg_editor используется для изменения и дополнения или экспорта/импорта в формате csv базы данных микросхем для программиста IMSProg.

IMSProg_editor використовується для зміни та доповнення або експорту/імпорту у форматі csv бази даних мікросхем для програматорі IMSProg.

IMSProg_editor 用于修改、补充或以 CSV 格式导出/导入芯片数据库,供 IMSProg 编程器使用。

IMSProg_editor 用於修改、補充或以 CSV 格式匯出/匯入晶片資料庫,供 IMSProg 燒錄器使用。

Development Electronics Programmer BIOS EEPROM MicroWire IC chip Microcircuit Microchip IC Integrated circuit Mikroschaltkreis Mikrochip Integrierte Schaltung Microcircuito Microchip Circuito integrado Mikroáramkör Mikrochip Integrált áramkör Microcircuito Microchip Circuito integrato Microcircuito Microchip Circuito integrado Микросхема Микрочип Интегральная схема Мікросхема Інтегральна схема 微电路 微芯片 集成电路 微電路 微晶片 積體電路 https://github.com/bigbigmdm/IMSProg/tree/main https://github.com/bigbigmdm https://github.com/bigbigmdm/IMSProg/issues IMSProg_editor.desktop application/octet-stream Mikhail Medvedev Main screen. Hauptbildschirm. Pantalla principal. Főképernyő. Schermata principale. Tela principal. Главный экран. Головний екран. 主屏幕。 主畫面。 https://github.com/bigbigmdm/IMSProg/raw/main/IMSProg_editor/img/ezp_editor.png

Fix: the first highlighted area in HexEdit was not being cleared.

Fix: combobox Operations was not reset if chip type changed.

Fix: program crashed if current chip is nothing and combobox Operation changed

Fix: Operations label showed for all chip types.

Added: Support for I2C and SPI FeRAM chips.

I2C 5v0 images on info form.

Fixed: segmentation fault in Qt6.

Fixed: incorrect interface display on macOS.

Fixed: write error to sector 0 in Windows.

Fixed: incorrect saving of the database file in the chip editor.

Fixed: unable to erase the 93C66, 93C76 and 93C86 chips.

Fixed: the font is too large in Qt6.

Added: migration to Qt6.

Added: universal Qt5/Qt6 CmakeLists.txt.

Added: specification file for Fedora.

Added: support for the spare area for NAND flash memory.

Fixed: If no chip is selected, the programmer was not detected.

Fixed: MACOS library compatibility.

Fixed: MACOS invalid pathes.

Fixed: libusb detection.

Fixed: udev rules install

Added: 2.5v VCC item

SPI NOR FLASH writing speed increased

Changed chip database update bash script to Qt app

The Zenity package is no longer used

Fixed: Error reading/writing data from I2C chips on the CH347T version 5.44.

Fixed: Bit error during NOR/NAND operations in the CH347V1.1 programmer.

Added: Showing the programmer revision function

Added: Erase check function

Added: Filling code function

Added: Support for the CH347T programmer.

Fixed: Incorrect chip page sizes values removed.

Increased interface speed and SPI NOR Flash erase speed.

SPI NOR Flash write speed increased by 30%.

Fixed: Incorrect HexEdit size when starting the program.

Added: When closing the program, the programmer type, chip image directory, and main window size are saved in the ini file.

Fixed: NAND Flash information form freeze.

Added: Programmer type menu.

Added: New images for CH341A v1.7.

Added: support for the AT24CM02 chip.

Fixed: pressing the Stop key did not stop auto operations.

Added: New feature - support for SPI NAND flash.

Fixed: program crashed if security registers was less than 256 bytes.

Fixed: Information in the status bar disappears when hovering over a menu.

Added: close and minimise buttons for subordinate forms.

Added: comparison of INTEL HEX and ASUS CAP with other files.

Added: new chips to the database.

Fixed: when the page size is changed, the buffer is cleared.

Fixed: the code is executed twice and the code slows down the display of the interface.

Added: New feature - compare files.

Added: New feature - fill test array.

Copyright information updated.

Fixed: incorrect uninstall script.

Fixed: i2C 128K size is repeated twice.

Fixed: error calculating file size.

Added: Last version of QHexEdit used.

Added: Hex-functions optimised.

Added: Added support GIANTEC, DOSILICON NOR FLASH chips.

Fixed: Gigadevice status registers write error.

Fixed: Memory leaks.

Added: New SPI chip sizes added.

Added: New Boya, Winbond chips added to database.

Added: Fidelix, Zetta, MXIC OTP algorithm.

Fixed: Incorrect install dir for udev while cross compiling.

Added: Form for working with security registers for SPI NOR flash memory chips.

Fixed: Incorrect block/page size after first read procedure.

Fixed: Incorrect reading/writing I2C low speed chips.

Added support for MXIC MX25V8035F

Added I2C bus speed combobox to the main form

Fixed: In the Save menu, the cancel button causes an error message.

Fixed: Incorrect names of DataFlash chips.

Fixed: incorrect reading of the DataFlash chips status register.

Fedora repository added

MacOS build support added

Uninstall script added

Fixed: On the GNOME desktop, programm does not respond when erasing SPI NOR FLASH.

Fixed: The progress bar did not display correctly when SPI NOR FLASH was erased.

Fixed: When erasing SPI NOR Flash, the STOP button does not work.

Corrected German translation

German translator added to copyright

Corrected chip database

Added AT45DBxx series SPI FLASH (Menu item type -> 45_EEPROM)

The inline images of the chip adapters have been changed.

Fixed metadata errors and warnings.

Fixed: There is a spelling error in in 99-CH341.rules.

Fixed: (metadata changed): appstream-metadata-missing-modalias-provide usr/lib/udev/rules.d/99-CH341.rules

Splitting long lines in README.md

Removed language .qm files - it is generated when the package is built.

Removed unused tags from language files.

This stable release fixes bugs, updated translations, translate chip database update script.

This stable release, updated translations.

e-ink-reader@yandex.ru imsprog-1.8.5/IMSProg_editor/resources.qrc000066400000000000000000000006141520775651600205730ustar00rootroot00000000000000 img/redo.png img/open.png img/save.png img/exit.png img/del.png img/undo.png img/plus.png img/tocsv.png img/import.png imsprog-1.8.5/IMSProg_programmer/000077500000000000000000000000001520775651600167365ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_programmer/CMakeLists.txt000066400000000000000000000205161520775651600215020ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.10.0) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) project(IMSProg LANGUAGES C CXX) include(FindPkgConfig) pkg_check_modules(LIBUSB REQUIRED libusb-1.0) if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_INSTALL_DO_STRIP FALSE) endif() get_filename_component(PROJECT_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE) # Set the CMAKE_INSTALL_PREFIX to /usr if not specified if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "The default install prefix on macOS" FORCE) # Set up Qt paths on macOS # If user hasn't set CMAKE_PREFIX_PATH, try to find Qt automatically if(NOT CMAKE_PREFIX_PATH) # Check for Qt6 via Homebrew if(EXISTS "/usr/local/opt/qt@6") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@6" CACHE PATH "Path to Qt6 on macOS" FORCE) message(STATUS "Found Qt6 at /usr/local/opt/qt@6") # Check for Qt5 via Homebrew elseif(EXISTS "/usr/local/opt/qt@5") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@5" CACHE PATH "Path to Qt5 on macOS" FORCE) message(STATUS "Found Qt5 at /usr/local/opt/qt@5") # Standard Qt path from Homebrew (without version) elseif(EXISTS "/usr/local/opt/qt") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt" CACHE PATH "Path to Qt on macOS" FORCE) message(STATUS "Found Qt at /usr/local/opt/qt") endif() endif() else() set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "The default install prefix" FORCE) endif() endif() # Set the CMAKE_INSTALL_BINDIR to /bin if not specified if(NOT DEFINED CMAKE_INSTALL_BINDIR) set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)") endif() # Set the CMAKE_INSTALL_DATAROOTDIR to /share if not specified if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR) set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)") endif() # Set the CMAKE_INSTALL_LIBDIR to /lib if not specified if(NOT DEFINED CMAKE_INSTALL_LIBDIR) set(CMAKE_INSTALL_LIBDIR "/lib" CACHE PATH "read-only single-machine data (lib)") endif() list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # Option to force using Qt5 option(FORCE_QT5 "Force using Qt5 instead of Qt6" OFF) if(FORCE_QT5) message(STATUS "Forced Qt5 mode for IMSProg") # On macOS, additionally check the path to Qt5 if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT CMAKE_PREFIX_PATH) if(EXISTS "/usr/local/opt/qt@5") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@5" CACHE PATH "Path to Qt5 on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt@5 for Qt5") elseif(EXISTS "/usr/local/opt/qt") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt" CACHE PATH "Path to Qt on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt for Qt5") endif() endif() find_package(Qt5 REQUIRED COMPONENTS Core Widgets LinguistTools) set(QT_VERSION_MAJOR 5) else() # First try Qt6 find_package(Qt6 QUIET COMPONENTS Core Widgets) if(TARGET Qt6::Core AND TARGET Qt6::Widgets) message(STATUS "Using Qt6 for IMSProg") set(QT_VERSION_MAJOR 6) find_package(Qt6LinguistTools REQUIRED) else() message(STATUS "Qt6 not found, using Qt5 for IMSProg") # On macOS, additionally check the path to Qt5 if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT CMAKE_PREFIX_PATH) if(EXISTS "/usr/local/opt/qt@5") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt@5" CACHE PATH "Path to Qt5 on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt@5 for Qt5") elseif(EXISTS "/usr/local/opt/qt") set(CMAKE_PREFIX_PATH "/usr/local/opt/qt" CACHE PATH "Path to Qt on macOS" FORCE) message(STATUS "Setting CMAKE_PREFIX_PATH to /usr/local/opt/qt for Qt5") endif() endif() find_package(Qt5 REQUIRED COMPONENTS Core Widgets LinguistTools) set(QT_VERSION_MAJOR 5) endif() endif() if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(UDEVDIR "/usr/lib/udev") if (CMAKE_INSTALL_PREFIX STREQUAL "/usr" OR CMAKE_INSTALL_PREFIX STREQUAL "/" AND NOT CMAKE_CROSSCOMPILING) # /usr and / install prefixes at treated by cmake GNUInstallDirs as # synonym for "system location". In this case we can look up the correct udevdir # using pkg-config. # See: https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html#special-cases find_package(PkgConfig) if (PKG_CONFIG_FOUND) pkg_check_modules(PKGCONFIG_UDEV udev) if (PKGCONFIG_UDEV_FOUND) execute_process( COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=udevdir udev OUTPUT_VARIABLE PKGCONFIG_UDEVDIR OUTPUT_STRIP_TRAILING_WHITESPACE ) if(PKGCONFIG_UDEVDIR) file(TO_CMAKE_PATH "${PKGCONFIG_UDEVDIR}" UDEVDIR) endif() endif() endif() endif() endif() # Translation files set(TS_FILES language/chipProgrammer_ru_RU.ts language/chipProgrammer_de_DE.ts language/chipProgrammer_es_ES.ts language/chipProgrammer_zh_CN.ts language/chipProgrammer_zh_TW.ts language/chipProgrammer_uk_UA.ts language/chipProgrammer_hu_HU.ts language/chipProgrammer_pt_BR.ts language/chipProgrammer_it_IT.ts ) if (QT_VERSION_MAJOR EQUAL 5) qt5_add_translation(QM_FILES ${TS_FILES}) else() qt_add_translation(QM_FILES ${TS_FILES}) endif() add_custom_target(translations DEPENDS ${QM_FILES}) add_executable(${PROJECT_NAME} main.cpp mainwindow.cpp qhexedit.cpp chunks.cpp commands.cpp dialogbbm.cpp dialogsp.cpp dialogrp.cpp dialogsfdp.cpp dialognandsr.cpp dialogsecurity.cpp dialognandsecurity.cpp dialogcompare.cpp dialogsr.cpp dialogsetaddr.cpp dialogfill.cpp hexutility.cpp searchdialog.cpp dialoginfo.cpp bitbang_microwire.c ch341a_gpio.c ch341a_spi.c ch34x_i2c.c ch347.c color_manager.cpp flashcmd_api.c mw_eeprom.c spi_controller.c spi_nor_flash.c timer.c dialogabout.cpp mainwindow.h qhexedit.h chunks.h commands.h color_manager.h dialogbbm.h dialogsp.h dialogrp.h dialogsfdp.h dialogsecurity.h dialognandsecurity.h dialognandsr.h dialogcompare.h dialogsr.h dialoginfo.h dialogsetaddr.h dialogfill.h hexutility.h searchdialog.h bitbang_microwire.h ch341a_gpio.h ch341a_spi.h ch34x_i2c.h ch347.h flashcmd_api.h mw_eeprom_api.h nandcmd_api.h res.h snorcmd_api.h spi_controller.h spi_eeprom_api.h timer.h types.h dialogabout.h mainwindow.ui dialogbbm.ui dialogsp.ui dialogrp.ui dialogsfdp.ui dialognandsr.ui dialogsecurity.ui dialognandsecurity.ui dialogcompare.ui dialogsr.ui dialogsetaddr.ui dialoginfo.ui dialogfill.ui searchdialog.ui dialogabout.ui recource.qrc ${QM_FILES} ) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(${PROJECT_NAME} PRIVATE ${LIBUSB_INCLUDE_DIRS}) if (QT_VERSION_MAJOR EQUAL 5) target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Widgets ${LIBUSB_LIBRARIES}) else() target_link_libraries(${PROJECT_NAME} Qt::Core Qt::Widgets ${LIBUSB_LIBRARIES}) endif() install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/img/IMSProg64.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pixmaps") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/database/IMSProg.Dat" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/imsprog") if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/IMSProg.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/71-CH341.rules" DESTINATION "${UDEVDIR}/rules.d") endif() install(FILES ${QM_FILES} DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/imsprog") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/IMSProg.1.gz" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/man/man1") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/index.html" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/doc/imsprog/html") install(DIRECTORY "${PROJECT_ROOT}/img/" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/doc/imsprog/html") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/other/io.github.bigbigmdm.imsprog.metainfo.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") imsprog-1.8.5/IMSProg_programmer/IMSProg.pro000066400000000000000000000065371520775651600207530ustar00rootroot00000000000000#------------------------------------------------- # # Project created by QtCreator 2023-07-14T12:38:17 # #------------------------------------------------- QT += core gui CONFIG += link_pkgconfig PKGCONFIG += libusb-1.0 LIBS += -lusb-1.0 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = IMSProg TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 CONFIG += c++11 SOURCES += \ main.cpp \ mainwindow.cpp \ qhexedit.cpp \ chunks.cpp \ commands.cpp \ dialogsp.cpp \ dialogrp.cpp \ searchdialog.cpp \ bitbang_microwire.c \ ch341a_gpio.c \ ch341a_spi.c \ flashcmd_api.c \ mw_eeprom.c \ spi_controller.c \ spi_nor_flash.c \ timer.c \ dialogabout.cpp \ dialoginfo.cpp \ dialogsfdp.cpp \ dialogsr.cpp \ dialogsetaddr.cpp \ dialogsecurity.cpp \ hexutility.cpp \ color_manager.cpp \ dialogcompare.cpp \ dialognandsr.cpp \ dialognandsecurity.cpp \ dialogbbm.cpp \ ch347.c \ ch34x_i2c.c \ dialogfill.cpp HEADERS += \ mainwindow.h \ qhexedit.h \ chunks.h \ commands.h \ dialogsp.h \ dialogrp.h \ searchdialog.h \ bitbang_microwire.h \ ch341a_gpio.h \ ch341a_spi.h \ flashcmd_api.h \ mw_eeprom_api.h \ nandcmd_api.h \ res.h \ snorcmd_api.h \ spi_controller.h \ spi_eeprom_api.h \ timer.h \ types.h \ dialogabout.h \ dialoginfo.h \ dialogsfdp.h \ dialogsr.h \ dialogsetaddr.h \ dialogsecurity.h \ hexutility.h \ color_manager.h \ dialogcompare.h \ dialognandsr.h \ dialognandsecurity.h \ dialogbbm.h \ ch347.h \ ch34x_i2c.h \ dialogfill.h FORMS += \ mainwindow.ui \ dialogsp.ui \ dialogrp.ui \ searchdialog.ui \ dialogabout.ui \ dialoginfo.ui \ dialogsfdp.ui \ dialogsr.ui \ dialogsetaddr.ui \ dialogsecurity.ui \ dialogcompare.ui \ dialognandsr.ui \ dialognandsecurity.ui \ dialogbbm.ui \ dialogfill.ui TRANSLATIONS += language/chipProgrammer_ru_RU.ts \ language/chipProgrammer_es_ES.ts \ language/chipProgrammer_de_DE.ts \ language/chipProgrammer_zh_CN.ts \ language/chipProgrammer_zh_TW.ts \ language/chipProgrammer_uk_UA.ts \ language/chipProgrammer_hu_HU.ts \ language/chipProgrammer_pt_BR.ts \ language/chipProgrammer_it_IT.ts # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target RESOURCES += \ recource.qrc DISTFILES += imsprog-1.8.5/IMSProg_programmer/LICENSE000066400000000000000000001045151520775651600177510ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. 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 them 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 prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. 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. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey 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; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If 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 convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU 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 that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. 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. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 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. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. 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 state 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program 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, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU 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. But first, please read . imsprog-1.8.5/IMSProg_programmer/QHexEditPlugin.cpp000066400000000000000000000032651520775651600223020ustar00rootroot00000000000000#include "QHexEditPlugin.h" #include "qhexedit.h" #include QHexEditPlugin::QHexEditPlugin(QObject * parent) : QObject(parent) { initialized = false; } bool QHexEditPlugin::isContainer() const { return false; } bool QHexEditPlugin::isInitialized() const { return initialized; } QIcon QHexEditPlugin::icon() const { return QIcon(); } QString QHexEditPlugin::domXml() const { return "\n" " \n" " \n" " \n" " 0\n" " 0\n" " 100\n" " 100\n" " \n" " \n" " \n" " QHexEditWidget\n" " \n" " \n" " QHexEdit widget allow to edit the data in hex view.\n" " \n" " \n" "\n"; } QString QHexEditPlugin::group() const { return "Input Widgets"; } QString QHexEditPlugin::includeFile() const { return "qhexedit.h"; } QString QHexEditPlugin::name() const { return "QHexEdit"; } QString QHexEditPlugin::toolTip() const { return ""; } QString QHexEditPlugin::whatsThis() const { return ""; } QWidget * QHexEditPlugin::createWidget(QWidget *parent) { return new QHexEdit(parent); } void QHexEditPlugin::initialize(QDesignerFormEditorInterface * /*core*/) { if (initialized) return; initialized = true; } #if QT_VERSION < QT_VERSION_CHECK(5,0,0) Q_EXPORT_PLUGIN2(QHexEditPlugin, QHexEditPlugin) #endif imsprog-1.8.5/IMSProg_programmer/QHexEditPlugin.h000066400000000000000000000016421520775651600217440ustar00rootroot00000000000000#ifndef QHEXEDITPLUGIN_H #define QHEXEDITPLUGIN_H #include #if QT_VERSION < QT_VERSION_CHECK(5,0,0) #include #else #include #endif class QHexEditPlugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) Q_PLUGIN_METADATA(IID "com.qt-project.Qt.QHexEditPlugin") #endif public: QHexEditPlugin(QObject * parent = 0); bool isContainer() const; bool isInitialized() const; QIcon icon() const; QString domXml() const; QString group() const; QString includeFile() const; QString name() const; QString toolTip() const; QString whatsThis() const; QWidget *createWidget(QWidget *parent); void initialize(QDesignerFormEditorInterface *core); private: bool initialized; }; #endif imsprog-1.8.5/IMSProg_programmer/README.md000066400000000000000000000015221520775651600202150ustar00rootroot00000000000000# IMSProg IMSProg - Linux IMSProg - I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. The IMSProm is a free EEPROM programmer tool for CH341A device based on [QhexEdit2](https://github.com/Simsys/qhexedit2) and modify [SNANDer programmer]([https://github.com/setarcos/ch341prog](https://github.com/McMCCRU/SNANDer). This is a GUI program used widget QhexEditor. For setting the SPI chip parameters you can use the `Detect` button for reading chip parameters (JEDEC information reading) or manually setting it. The I2C and MicroWire EEPROM only manually selected. The chip database format is clone with EZP2019, EZP2020, EZP2023, Minpro I, XP866+ programmers. You can edit the database use the [EZP Chip data Editor](https://github.com/bigbigmdm/EZP2019-EZP2025_chip_data_editor) ![CH341A EEPROM programmer](img/IMSProg.png) imsprog-1.8.5/IMSProg_programmer/bitbang_microwire.c000066400000000000000000000305041520775651600225720ustar00rootroot00000000000000/* Copyright (C) 2005-2021 Mokrushin I.V. aka McMCC mcmcc@mail.ru, (C) 2023 Mikhail Medvedev e-ink-reader@yandex.ru A simple bitbang protocol for Microwire 8-pin serial EEPROMs (93XX devices). Support organization 8bit and 16bit(8bit emulation). bitbang_microwire.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., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ------------------------------------------------------------------------- */ #include #include #include #include #include "bitbang_microwire.h" struct gpio_cmd bb_func; #if 0 unsigned char ORG = 0; /* organization 0 = 8 bit and 1 = 16 bit */ #endif unsigned char CLK = 0; unsigned char DO = 0; unsigned char DI = 0; unsigned char CSEL = 0; int org = 0; int mw_eepromsize = 0; int fix_addr_len = 0; static unsigned char data = 0; static void delay_ms(int n) { #if 0 /* ifndef _WINDOWS */ int i; for(i = 0; i < (n * 100000); i++); #else usleep((unsigned int)n); #endif } static void data_1() { data = data | DI; if (bb_func.gpio_setbits) bb_func.gpio_setbits(data); } static void data_0() { data = data & (~DI); if (bb_func.gpio_setbits) bb_func.gpio_setbits(data); } static void org_1() { #if 0 data = data | ORG; /* 16bit */ if (bb_func.gpio_setbits) bb_func.gpio_setbits(data); #endif } static void org_0() { #if 0 data = data & (~ORG); /* 8bit */ if (bb_func.gpio_setbits) bb_func.gpio_setbits(data); #endif } static void csel_1() { data = data | CSEL; if (bb_func.gpio_setbits) bb_func.gpio_setbits(data); } static void csel_0() { data = data & (~CSEL); if (bb_func.gpio_setbits) bb_func.gpio_setbits(data); } static void clock_1() { data = data | CLK; if (bb_func.gpio_setbits) bb_func.gpio_setbits(data); } static void clock_0() { data = data & (~CLK); if (bb_func.gpio_setbits) bb_func.gpio_setbits(data); } static unsigned int get_data() { unsigned char b = 0; if (bb_func.gpio_getbits) bb_func.gpio_getbits(&b); return ((b & DO) == DO); } static int convert_size(int eeprom_size) { int k = 1; org_0(); delay_ms(1); if (org) { org_1(); delay_ms(1); k = 2; } eeprom_size = eeprom_size / k; return eeprom_size; } static void send_to_di(unsigned int val, int nbit) { unsigned int b = 0; int i = 0; while (i < nbit) { b = val & (1 << ((nbit - i++) - 1)); clock_0(); if (b) data_1(); else data_0(); delay_ms(1); clock_1(); delay_ms(1); } } static unsigned char get_from_do() { unsigned char val = 0; unsigned int b = 0, i = 0; while (i < 8) { clock_0(); delay_ms(1); b = get_data(); clock_1(); delay_ms(1); val |= (b << (7 - i++)); } return val; } static void enable_write_3wire(int num_bit) { csel_0(); clock_0(); delay_ms(1); data_1(); csel_1(); delay_ms(1); clock_1(); delay_ms(1); send_to_di(3, 4); send_to_di(0, num_bit - 2); //2 data_0(); delay_ms(1); csel_0(); delay_ms(1); } static void disable_write_3wire(int num_bit) { csel_1(); delay_ms(1); clock_0(); delay_ms(1); data_1(); delay_ms(1); clock_1(); delay_ms(1); send_to_di(0, 4); send_to_di(0, num_bit - 2); //2 csel_0(); delay_ms(1); } static void chip_busy(void) { printf("Error: Always BUSY! Communication problem...The broken microwire chip?\n"); } void Erase_EEPROM_3wire_param(unsigned char algorithm) { int i, num_bit; num_bit = algorithm & 0x0f; enable_write_3wire(num_bit); csel_0(); clock_0(); delay_ms(1); data_1(); csel_1(); delay_ms(1); clock_1(); delay_ms(1); send_to_di(2, 4); send_to_di(0, num_bit - 3); clock_0(); data_0(); delay_ms(1); csel_0(); delay_ms(1); csel_1(); delay_ms(1); clock_1(); delay_ms(1); i = 0; while (!get_data() && i < 10000) { clock_0(); delay_ms(1); clock_1(); delay_ms(1); i++; } if (i == 10000) { chip_busy(); return; } csel_0(); delay_ms(1); clock_0(); delay_ms(1); clock_1(); delay_ms(1); disable_write_3wire(num_bit); } int Read_EEPROM_3wire_param(unsigned char *buffer, int start_addr, int block_size, int size_eeprom, unsigned char algorithm) { int address, num_bit, l; org = (algorithm & 0xf0) / 16; num_bit = algorithm & 0x0f; //num_bit = addr_nbits(__func__, size_eeprom); //printf("numbit=%x org=%x\n",num_bit,org); if (org == 1) { block_size = block_size / 2; start_addr = start_addr / 2; num_bit--; } size_eeprom = convert_size(size_eeprom); address = 0; for (l = start_addr; l < block_size + start_addr; l++) { csel_0(); clock_0(); delay_ms(1); data_1(); csel_1(); delay_ms(1); clock_1(); delay_ms(1); send_to_di(2, 2); send_to_di((unsigned int)l, num_bit); data_0(); clock_0(); delay_ms(1); clock_1(); delay_ms(1); if (org == 0 ) buffer[address] = get_from_do(); if (org == 1) { buffer[address + 1] = get_from_do(); buffer[address] = get_from_do(); address++; } csel_0(); delay_ms(1); clock_0(); delay_ms(1); clock_1(); delay_ms(1); //printf("\bRead %d%% [%d] of [%d] bytes ", 100 * l / block_size, l, block_size); //printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); //fflush(stdout); address++; } //printf("Read 100%% [%d] of [%d] bytes \n", l, block_size); return 0; } int Write_EEPROM_3wire_param(unsigned char *buffer, int start_addr, int block_size, int size_eeprom, unsigned char algorithm) { int i, l, address, num_bit; //num_bit = addr_nbits(__func__, size_eeprom); org = (algorithm & 0xf0) / 16; num_bit = algorithm & 0x0f; if (org == 1) { block_size = block_size / 2; start_addr = start_addr / 2; num_bit--; } size_eeprom = convert_size(size_eeprom); enable_write_3wire(num_bit); address = 0; for (l = start_addr; l < block_size + start_addr; l++) { csel_0(); clock_0(); delay_ms(1); data_1(); csel_1(); delay_ms(1); clock_1(); delay_ms(1); send_to_di(1, 2); send_to_di((unsigned int)l, num_bit); if (org == 0 ) send_to_di(buffer[address], 8); if (org == 1) { send_to_di(buffer[address +1], 8); send_to_di(buffer[address], 8); address++; } clock_0(); data_0(); delay_ms(1); csel_0(); delay_ms(1); csel_1(); delay_ms(1); clock_1(); delay_ms(1); i = 0; while (!get_data() && i < 10000) { clock_0(); delay_ms(1); clock_1(); delay_ms(1); i++; } if (i == 10000) { printf("\n"); chip_busy(); return -1; } csel_0(); delay_ms(1); clock_0(); delay_ms(1); clock_1(); delay_ms(1); //printf("\bWritten %d%% [%d] of [%d] bytes ", 100 * l / block_size, l, block_size); //printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); //fflush(stdout); address++; } //printf("Written 100%% [%d] of [%d] bytes \n", l, block_size); disable_write_3wire(num_bit); return 0; } //static int addr_nbits(const char *func, int size) //{ // int i = 0; // // if (fix_addr_len) { // printf("%s: Set address len %d bits\n", func, fix_addr_len); // return fix_addr_len; // } // // switch (size) { // case 128: /* 93c46 */ // i = org ? 6 : 7; // break; // case 256: /* 93c56 */ // case 512: /* 93c66 */ // i = org ? 8 : 9; // break; // case 1024: /* 93c76 */ // case 2048: /* 93c86 */ // i = org ? 10 : 11; // break; // case 4096: /* 93c96(not original name) */ // i = org ? 12 : 13; // break; // default: // i = 6; /* 93c06 and 93c16(not original name) */ // break; // } // // printf("%s: Set address len %d bits\n", func, i); // // return i; //} /*int Read_EEPROM_3wire(unsigned char *buffer, int size_eeprom) { int address, num_bit, l; num_bit = addr_nbits(__func__, size_eeprom); size_eeprom = convert_size(size_eeprom); address = 0; for (l = 0; l < size_eeprom; l++) { csel_0(); clock_0(); delay_ms(1); data_1(); csel_1(); delay_ms(1); clock_1(); delay_ms(1); send_to_di(2, 2); send_to_di(l, num_bit); data_0(); clock_0(); delay_ms(1); clock_1(); delay_ms(1); buffer[address] = get_from_do(); if (org) { address++; buffer[address] = get_from_do(); } csel_0(); delay_ms(1); clock_0(); delay_ms(1); clock_1(); delay_ms(1); printf("\bRead %d%% [%d] of [%d] bytes ", 100 * l / size_eeprom, l, size_eeprom); printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); fflush(stdout); address++; } printf("Read 100%% [%d] of [%d] bytes \n", l, size_eeprom); return 0; } */ /*void Erase_EEPROM_3wire(int size_eeprom) { int i, num_bit; num_bit = addr_nbits(__func__, size_eeprom); enable_write_3wire(num_bit); csel_0(); clock_0(); delay_ms(1); data_1(); csel_1(); delay_ms(1); clock_1(); delay_ms(1); send_to_di(2, 4); send_to_di(0, num_bit - 2); clock_0(); data_0(); delay_ms(1); csel_0(); delay_ms(1); csel_1(); delay_ms(1); clock_1(); delay_ms(1); i = 0; while (!get_data() && i < 10000) { clock_0(); delay_ms(1); clock_1(); delay_ms(1); i++; } if (i == 10000) { chip_busy(); return; } csel_0(); delay_ms(1); clock_0(); delay_ms(1); clock_1(); delay_ms(1); disable_write_3wire(num_bit); } */ /* int Write_EEPROM_3wire(unsigned char *buffer, int size_eeprom) { int i, l, address, num_bit; num_bit = addr_nbits(__func__, size_eeprom); size_eeprom = convert_size(size_eeprom); enable_write_3wire(num_bit); address = 0; for (l = 0; l < size_eeprom; l++) { csel_0(); clock_0(); delay_ms(1); data_1(); csel_1(); delay_ms(1); clock_1(); delay_ms(1); send_to_di(1, 2); send_to_di((unsigned int)l, num_bit); send_to_di(buffer[address], 8); if (org) { address++; send_to_di(buffer[address], 8); } clock_0(); data_0(); delay_ms(1); csel_0(); delay_ms(1); csel_1(); delay_ms(1); clock_1(); delay_ms(1); i = 0; while (!get_data() && i < 10000) { clock_0(); delay_ms(1); clock_1(); delay_ms(1); i++; } if (i == 10000) { printf("\n"); chip_busy(); return -1; } csel_0(); delay_ms(1); clock_0(); delay_ms(1); clock_1(); delay_ms(1); printf("\bWritten %d%% [%d] of [%d] bytes ", 100 * l / size_eeprom, l, size_eeprom); printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); fflush(stdout); address++; } printf("Written 100%% [%d] of [%d] bytes \n", l, size_eeprom); disable_write_3wire(num_bit); return 0; } int deviceSize_3wire(char *eepromname) { int i; for (i = 0; mw_eepromlist[i].size; i++) { if (strstr(mw_eepromlist[i].name, eepromname)) { return ((int)mw_eepromlist[i].size); } } return -1; } */ /* End of [bitbang_microwire.c] package */ imsprog-1.8.5/IMSProg_programmer/bitbang_microwire.h000066400000000000000000000046321520775651600226020ustar00rootroot00000000000000/* Copyright (C) 2005-2021 Mokrushin I.V. aka McMCC mcmcc@mail.ru * Copyright (C) 2023 Mikhail Medvedev e-ink-reader@yandex.ru A simple bitbang protocol for Microwire 8-pin serial EEPROMs (93XX devices). Support organization 8bit and 16bit(8bit emulation). bitbang_microwire.h 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ------------------------------------------------------------------------- */ #ifndef _BITBANG_MICROWIRE_H #define _BITBANG_MICROWIRE_H #if 0 extern unsigned char ORG; /* organization 0 = 8 bit and 1 = 16 bit */ #endif extern unsigned char CLK; extern unsigned char DO; extern unsigned char DI; extern unsigned char CSEL; extern int org; extern int mw_eepromsize; extern int fix_addr_len; struct MW_EEPROM { char *name; unsigned int size; }; struct gpio_cmd { int (*gpio_setdir)(void); int (*gpio_setbits)(unsigned char bit); int (*gpio_getbits)(unsigned char *data); }; //void Erase_EEPROM_3wire(int size_eeprom); //int Read_EEPROM_3wire(unsigned char *buffer, int size_eeprom); //int Write_EEPROM_3wire(unsigned char *buffer, int size_eeprom); //int deviceSize_3wire(char *eepromname); int Read_EEPROM_3wire_param(unsigned char *buffer, int start_addr, int block_size, int size_eeprom, unsigned char algorithm); int Write_EEPROM_3wire_param(unsigned char *buffer, int start_addr, int block_size, int size_eeprom, unsigned char algorithm); void Erase_EEPROM_3wire_param(unsigned char algorithm); /*const static struct MW_EEPROM mw_eepromlist[] = { { "93c06", 32 }, { "93c16", 64 }, { "93c46", 128 }, { "93c56", 256 }, { "93c66", 512 }, { "93c76", 1024 }, { "93c86", 2048 }, { "93c96", 4096 }, { 0, 0 } }; */ #define MAX_MW_EEPROM_SIZE 4096 #endif /* _BITBANG_MICROWIRE_H */ /* End of [bitbang_microwire.h] package */ imsprog-1.8.5/IMSProg_programmer/ch341a_gpio.c000066400000000000000000000047521520775651600211130ustar00rootroot00000000000000/* * Copyright (C) 2021 McMCC * ch341a_gpio.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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #define DEFAULT_TIMEOUT 1000 #define BULK_WRITE_ENDPOINT 0x02 #define BULK_READ_ENDPOINT 0x82 #define CH341A_CMD_UIO_STREAM 0xAB #define CH341A_CMD_UIO_STM_IN 0x00 #define CH341A_CMD_UIO_STM_DIR 0x40 #define CH341A_CMD_UIO_STM_OUT 0x80 #define CH341A_CMD_UIO_STM_US 0xC0 #define CH341A_CMD_UIO_STM_END 0x20 #define DIR_MASK 0x3F /* D6,D7 - input, D0-D5 - output */ extern struct libusb_device_handle *handle; static int usb_transf(const char *func, uint8_t type, uint8_t *buf, int len) { int ret, actuallen = 0; if (handle == NULL) return -1; ret = libusb_bulk_transfer(handle, type, buf, len, &actuallen, DEFAULT_TIMEOUT); if (ret < 0) { printf("%s: Failed to %s %d bytes '%s'\n", func, (type == BULK_WRITE_ENDPOINT) ? "write" : "read", len, strerror(-ret)); return -1; } return actuallen; } int ch341a_gpio_setdir(void) { uint8_t buf[] = { CH341A_CMD_UIO_STREAM, CH341A_CMD_UIO_STM_DIR | DIR_MASK, CH341A_CMD_UIO_STM_END }; return usb_transf(__func__, BULK_WRITE_ENDPOINT, buf, 3); } int ch341a_gpio_setbits(uint8_t bits) { uint8_t buf[] = { CH341A_CMD_UIO_STREAM, CH341A_CMD_UIO_STM_OUT | bits, CH341A_CMD_UIO_STM_END }; return usb_transf(__func__, BULK_WRITE_ENDPOINT, buf, 3); } int ch341a_gpio_getbits(uint8_t *data) { int ret; uint8_t buf[] = { CH341A_CMD_UIO_STREAM, CH341A_CMD_UIO_STM_IN, CH341A_CMD_UIO_STM_END }; ret = usb_transf(__func__, BULK_WRITE_ENDPOINT, buf, 3); if (ret < 0) return -1; ret = usb_transf(__func__, BULK_READ_ENDPOINT, buf, 1); if (ret < 0) return -1; *data = buf[0]; return ret; } /* End of [ch341a_gpio.c] package */ imsprog-1.8.5/IMSProg_programmer/ch341a_gpio.h000066400000000000000000000020141520775651600211050ustar00rootroot00000000000000/* * Copyright (C) 2021 McMCC * ch341a_gpio.h * * 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CH341A_GPIO_H__ #define __CH341A_GPIO_H__ #include int ch341a_gpio_setdir(void); int ch341a_gpio_setbits(uint8_t bits); int ch341a_gpio_getbits(uint8_t *data); #endif /* __CH341A_GPIO_H__ */ /* End of [ch341a_gpio.h] package */ imsprog-1.8.5/IMSProg_programmer/ch341a_spi.c000066400000000000000000000556541520775651600207570ustar00rootroot00000000000000/* * This file is part of the flashrom project. * * Copyright (C) 2011 asbokid * Copyright (C) 2014 Pluto Yang * Copyright (C) 2015-2016 Stefan Tauner * Copyright (C) 2015 Urja Rannikko * Copyright (C) 2018-2021 McMCC * * 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "ch341a_spi.h" #include #include #include "mw_eeprom_api.h" /* LIBUSB_CALL ensures the right calling conventions on libusb callbacks. * However, the macro is not defined everywhere. m( */ #ifndef LIBUSB_CALL #define LIBUSB_CALL #endif #define USB_TIMEOUT 1000 /* 1000 ms is plenty and we have no backup strategy anyway. */ #define WRITE_EP 0x02 #define READ_EP 0x82 #define CH341_PACKET_LENGTH 0x20 #define CH341_MAX_PACKETS 256 #define CH341_MAX_PACKET_LEN (CH341_PACKET_LENGTH * CH341_MAX_PACKETS) #define CH341A_CMD_SET_OUTPUT 0xA1 #define CH341A_CMD_IO_ADDR 0xA2 #define CH341A_CMD_PRINT_OUT 0xA3 #define CH341A_CMD_SPI_STREAM 0xA8 #define CH341A_CMD_SIO_STREAM 0xA9 #define CH341A_CMD_I2C_STREAM 0xAA #define CH341A_CMD_UIO_STREAM 0xAB #define CH341A_CMD_I2C_STM_START 0x74 #define CH341A_CMD_I2C_STM_STOP 0x75 #define CH341A_CMD_I2C_STM_OUT 0x80 #define CH341A_CMD_I2C_STM_IN 0xC0 #define CH341A_CMD_I2C_STM_MAX ( min( 0x3F, CH341_PACKET_LENGTH ) ) #define CH341A_CMD_I2C_STM_SET 0x60 // bit 2: SPI with two data pairs D5,D4=out, D7,D6=in #define CH341A_CMD_I2C_STM_US 0x40 #define CH341A_CMD_I2C_STM_MS 0x50 #define CH341A_CMD_I2C_STM_DLY 0x0F #define CH341A_CMD_I2C_STM_END 0x00 #define CH341A_CMD_UIO_STM_IN 0x00 #define CH341A_CMD_UIO_STM_DIR 0x40 #define CH341A_CMD_UIO_STM_OUT 0x80 #define CH341A_CMD_UIO_STM_US 0xC0 #define CH341A_CMD_UIO_STM_END 0x20 #define CH341A_STM_I2C_20K 0x00 #define CH341A_STM_I2C_100K 0x01 #define CH341A_STM_I2C_400K 0x02 #define CH341A_STM_I2C_750K 0x03 #define CH341A_STM_SPI_DBL 0x04 /* Number of parallel IN transfers. 32 seems to produce the most stable throughput on Windows. */ #define USB_IN_TRANSFERS 32 struct dev_entry { uint16_t vendor_id; uint16_t device_id; const char *vendor_name; const char *device_name; }; /* We need to use many queued IN transfers for any resemblance of performance (especially on Windows) * because USB spec says that transfers end on non-full packets and the device sends the 31 reply * data bytes to each 32-byte packet with command + 31 bytes of data... */ static struct libusb_transfer *transfer_out = NULL; static struct libusb_transfer *transfer_ins[USB_IN_TRANSFERS] = {0}; struct libusb_device_handle *handle = NULL; const struct dev_entry devs_ch341a_spi[] = { {0x1A86, 0x5512, "WinChipHead (WCH)", "CH341A"}, {0}, }; enum trans_state {TRANS_ACTIVE = -2, TRANS_ERR = -1, TRANS_IDLE = 0}; #if 0 static void print_hex(const void *buf, size_t len) { size_t i; for (i = 0; i < len; i++) { printf(" %02x", ((uint8_t *)buf)[i]); if (i % CH341_PACKET_LENGTH == CH341_PACKET_LENGTH - 1) printf("\n"); } } #endif static void cb_common(const char *func, struct libusb_transfer *transfer) { int *transfer_cnt = (int*)transfer->user_data; if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { /* Silently ACK and exit. */ *transfer_cnt = TRANS_IDLE; return; } if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { printf("\n%s: error: %s\n", func, libusb_error_name(transfer->status)); *transfer_cnt = TRANS_ERR; } else { *transfer_cnt = transfer->actual_length; } } /* callback for bulk out async transfer */ static void LIBUSB_CALL cb_out(struct libusb_transfer *transfer) { cb_common(__func__, transfer); } /* callback for bulk in async transfer */ static void LIBUSB_CALL cb_in(struct libusb_transfer *transfer) { cb_common(__func__, transfer); } static int32_t usb_transfer(const char *func, unsigned int writecnt, unsigned int readcnt, const uint8_t *writearr, uint8_t *readarr) { if (handle == NULL) return -1; int state_out = TRANS_IDLE; transfer_out->buffer = (uint8_t*)writearr; transfer_out->length = writecnt; transfer_out->user_data = &state_out; /* Schedule write first */ if (writecnt > 0) { state_out = TRANS_ACTIVE; int ret = libusb_submit_transfer(transfer_out); if (ret) { printf("%s: failed to submit OUT transfer: %s\n", func, libusb_error_name(ret)); state_out = TRANS_ERR; goto err; } } /* Handle all asynchronous packets as long as we have stuff to write or read. The write(s) simply need * to complete but we need to scheduling reads as long as we are not done. */ unsigned int free_idx = 0; /* The IN transfer we expect to be free next. */ unsigned int in_idx = 0; /* The IN transfer we expect to be completed next. */ unsigned int in_done = 0; unsigned int in_active = 0; unsigned int out_done = 0; uint8_t *in_buf = readarr; int state_in[USB_IN_TRANSFERS] = {0}; do { /* Schedule new reads as long as there are free transfers and unscheduled bytes to read. */ while ((in_done + in_active) < readcnt && state_in[free_idx] == TRANS_IDLE) { unsigned int cur_todo = min(CH341_PACKET_LENGTH - 1, readcnt - in_done - in_active); transfer_ins[free_idx]->length = cur_todo; transfer_ins[free_idx]->buffer = in_buf; transfer_ins[free_idx]->user_data = &state_in[free_idx]; int ret = libusb_submit_transfer(transfer_ins[free_idx]); if (ret) { state_in[free_idx] = TRANS_ERR; printf("%s: failed to submit IN transfer: %s\n", func, libusb_error_name(ret)); goto err; } in_buf += cur_todo; in_active += cur_todo; state_in[free_idx] = TRANS_ACTIVE; free_idx = (free_idx + 1) % USB_IN_TRANSFERS; /* Increment (and wrap around). */ } /* Actually get some work done. */ libusb_handle_events_timeout(NULL, &(struct timeval){1, 0}); /* Check for the write */ if (out_done < writecnt) { if (state_out == TRANS_ERR) { goto err; } else if (state_out > 0) { out_done += state_out; state_out = TRANS_IDLE; } } /* Check for completed transfers. */ while (state_in[in_idx] != TRANS_IDLE && state_in[in_idx] != TRANS_ACTIVE) { if (state_in[in_idx] == TRANS_ERR) { goto err; } /* If a transfer is done, record the number of bytes read and reuse it later. */ in_done += state_in[in_idx]; in_active -= state_in[in_idx]; state_in[in_idx] = TRANS_IDLE; in_idx = (in_idx + 1) % USB_IN_TRANSFERS; /* Increment (and wrap around). */ } } while ((out_done < writecnt) || (in_done < readcnt)); #if 0 if (out_done > 0) { printf("Wrote %d bytes:\n", out_done); print_hex(writearr, out_done); printf("\n\n"); } if (in_done > 0) { printf("Read %d bytes:\n", in_done); print_hex(readarr, in_done); printf("\n\n"); } #endif return 0; err: /* Clean up on errors. */ printf("%s: Failed to %s %d bytes\n", func, (state_out == TRANS_ERR) ? "write" : "read", (state_out == TRANS_ERR) ? writecnt : readcnt); /* First, we must cancel any ongoing requests and wait for them to be canceled. */ if ((writecnt > 0) && (state_out == TRANS_ACTIVE)) { if (libusb_cancel_transfer(transfer_out) != 0) state_out = TRANS_ERR; } if (readcnt > 0) { unsigned int i; for (i = 0; i < USB_IN_TRANSFERS; i++) { if (state_in[i] == TRANS_ACTIVE) if (libusb_cancel_transfer(transfer_ins[i]) != 0) state_in[i] = TRANS_ERR; } } /* Wait for cancellations to complete. */ while (1) { bool finished = true; if ((writecnt > 0) && (state_out == TRANS_ACTIVE)) finished = false; if (readcnt > 0) { unsigned int i; for (i = 0; i < USB_IN_TRANSFERS; i++) { if (state_in[i] == TRANS_ACTIVE) finished = false; } } if (finished) break; libusb_handle_events_timeout(NULL, &(struct timeval){1, 0}); } return -1; } /* Set the I2C bus speed (speed(b1b0): 0 = 20kHz; 1 = 100kHz, 2 = 400kHz, 3 = 750kHz). * Set the SPI bus data width (speed(b2): 0 = Single, 1 = Double). */ int config_stream(unsigned int speed) { if (handle == NULL) return -1; uint8_t buf[] = { CH341A_CMD_I2C_STREAM, CH341A_CMD_I2C_STM_SET | (speed & 0x7), CH341A_CMD_I2C_STM_END }; int32_t ret = usb_transfer(__func__, sizeof(buf), 0, buf, NULL); if (ret < 0) { printf("Could not configure stream interface.\n"); } return ret; } /* ch341 requires LSB first, swap the bit order before send and after receive */ static uint8_t swap_byte(uint8_t x) { x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa); x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc); x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0); return x; } /* The assumed map between UIO command bits, pins on CH341A chip and pins on SPI chip: * UIO CH341A SPI CH341A SPI name * 0 D0/15 CS/1 (CS0) * 1 D1/16 unused (CS1) * 2 D2/17 unused (CS2) * 3 D3/18 SCK/6 (DCK) * 4 D4/19 unused (DOUT2) * 5 D5/20 SI/5 (DOUT) * - The UIO stream commands seem to only have 6 bits of output, and D6/D7 are the SPI inputs, * mapped as follows: * D6/21 unused (DIN2) * D7/22 SO/2 (DIN) */ int enable_pins(bool enable) { uint8_t buf[] = { CH341A_CMD_UIO_STREAM, CH341A_CMD_UIO_STM_OUT | 0x37, // CS high (all of them), SCK=0, DOUT*=1 CH341A_CMD_UIO_STM_OUT | 0x37, // CS high (all of them), SCK=0, DOUT*=1 CH341A_CMD_UIO_STM_OUT | 0x37, // CS high (all of them), SCK=0, DOUT*=1 CH341A_CMD_UIO_STM_OUT | 0x37, // CS high (all of them), SCK=0, DOUT*=1 CH341A_CMD_UIO_STM_OUT | 0x37, // CS high (all of them), SCK=0, DOUT*=1 CH341A_CMD_UIO_STM_OUT | 0x36, // CS low (all of them), SCK=0, DOUT*=1 CH341A_CMD_UIO_STM_DIR | (enable ? 0x3F : 0x00), // Interface output enable / disable CH341A_CMD_UIO_STM_END, }; int32_t ret = usb_transfer(__func__, sizeof(buf), 0, buf, NULL); if (ret < 0) { printf("Could not %sable output pins.\n", enable ? "en" : "dis"); } return ret; } int ch341a_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr) { int32_t ret = 0; if (handle == NULL) return -1; /* How many packets ... */ const size_t packets = (writecnt + readcnt + CH341_PACKET_LENGTH - 2) / (CH341_PACKET_LENGTH - 1); /* We pluck CS/timeout handling into the first packet thus we need to allocate one extra package. */ uint8_t wbuf[packets+1][CH341_PACKET_LENGTH]; uint8_t rbuf[writecnt + readcnt]; /* Initialize the write buffer to zero to prevent writing random stack contents to device. */ memset(wbuf[0], 0, CH341_PACKET_LENGTH); uint8_t *ptr = wbuf[0]; /* CS usage is optimized by doing both transitions in one packet. * Final transition to deselected state is in the pin disable. */ unsigned int write_left = writecnt; unsigned int read_left = readcnt; unsigned int p; for (p = 0; p < packets; p++) { unsigned int write_now = min(CH341_PACKET_LENGTH - 1, write_left); unsigned int read_now = min ((CH341_PACKET_LENGTH - 1) - write_now, read_left); ptr = wbuf[p + 1]; *ptr++ = CH341A_CMD_SPI_STREAM; unsigned int i; for (i = 0; i < write_now; ++i) *ptr++ = swap_byte(*writearr++); if (read_now) { memset(ptr, 0xFF, read_now); read_left -= read_now; } write_left -= write_now; } ret = usb_transfer(__func__, CH341_PACKET_LENGTH + packets + writecnt + readcnt, writecnt + readcnt, wbuf[0], rbuf); if (ret < 0) return -1; unsigned int i; for (i = 0; i < readcnt; i++) { *readarr++ = swap_byte(rbuf[writecnt + i]); } return 0; } int ch341a_spi_shutdown(void) { if (handle == NULL) return -1; enable_pins(false); libusb_free_transfer(transfer_out); transfer_out = NULL; int i; for (i = 0; i < USB_IN_TRANSFERS; i++) { libusb_free_transfer(transfer_ins[i]); transfer_ins[i] = NULL; } libusb_release_interface(handle, 0); libusb_close(handle); libusb_exit(NULL); handle = NULL; return 0; } int ch341a_spi_init(void) { if (handle != NULL) { printf("%s: handle already set!\n", __func__); return -1; } int32_t ret = libusb_init(NULL); if (ret < 0) { printf("Couldnt initialize libusb!\n"); return -1; } #if LIBUSB_API_VERSION < 0x01000106 libusb_set_debug(NULL, 3); // Enable information, warning and error messages (only). #else libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, 3); #endif uint16_t vid = devs_ch341a_spi[0].vendor_id; uint16_t pid = devs_ch341a_spi[0].device_id; handle = libusb_open_device_with_vid_pid(NULL, vid, pid); if (handle == NULL) { printf("Couldn't open device %04x:%04x.\n", vid, pid); return -1; } printf("Found programmer device: %s - %s\n", devs_ch341a_spi[0].vendor_name, devs_ch341a_spi[0].device_name); #ifdef __gnu_linux__ /* libusb_detach_kernel_driver() and friends basically only work on Linux. We simply try to detach on Linux * without a lot of passion here. If that works fine else we will fail on claiming the interface anyway. */ ret = libusb_detach_kernel_driver(handle, 0); if (ret == LIBUSB_ERROR_NOT_SUPPORTED) { printf("Detaching kernel drivers is not supported. Further accesses may fail.\n"); } else if (ret != 0 && ret != LIBUSB_ERROR_NOT_FOUND) { printf("Failed to detach kernel driver: '%s'. Further accesses will probably fail.\n", libusb_error_name(ret)); } #endif ret = libusb_claim_interface(handle, 0); if (ret != 0) { printf("Failed to claim interface 0: '%s'\n", libusb_error_name(ret)); goto close_handle; } struct libusb_device *dev; if (!(dev = libusb_get_device(handle))) { printf("Failed to get device from device handle.\n"); goto close_handle; } struct libusb_device_descriptor desc; ret = libusb_get_device_descriptor(dev, &desc); if (ret < 0) { printf("Failed to get device descriptor: '%s'\n", libusb_error_name(ret)); goto release_interface; } printf("Device revision is %d.%01d.%01d\n", (desc.bcdDevice >> 8) & 0x00FF, (desc.bcdDevice >> 4) & 0x000F, (desc.bcdDevice >> 0) & 0x000F); /* Allocate and pre-fill transfer structures. */ transfer_out = libusb_alloc_transfer(0); if (!transfer_out) { printf("Failed to alloc libusb OUT transfer\n"); goto release_interface; } int i; for (i = 0; i < USB_IN_TRANSFERS; i++) { transfer_ins[i] = libusb_alloc_transfer(0); if (transfer_ins[i] == NULL) { printf("Failed to alloc libusb IN transfer %d\n", i); goto dealloc_transfers; } } /* We use these helpers but dont fill the actual buffer yet. */ libusb_fill_bulk_transfer(transfer_out, handle, WRITE_EP, NULL, 0, cb_out, NULL, USB_TIMEOUT); for (i = 0; i < USB_IN_TRANSFERS; i++) libusb_fill_bulk_transfer(transfer_ins[i], handle, READ_EP, NULL, 0, cb_in, NULL, USB_TIMEOUT); if ((config_stream(CH341A_STM_I2C_750K) < 0) || (enable_pins(true) < 0)) goto dealloc_transfers; return 0; dealloc_transfers: for (i = 0; i < USB_IN_TRANSFERS; i++) { if (transfer_ins[i] == NULL) break; libusb_free_transfer(transfer_ins[i]); transfer_ins[i] = NULL; } libusb_free_transfer(transfer_out); transfer_out = NULL; release_interface: libusb_release_interface(handle, 0); close_handle: libusb_close(handle); handle = NULL; return -1; } /* End of [ch341a_spi.c] package */ int ch341a_init(uint8_t chipType, uint8_t i2cSpeed) { //chipType = 0 for SPI, chipType = 1 for i2c, chipType = 2 for MicroWire //i2cSppeed - 0 = 20kHz; 1 = 100kHz, 2 = 400kHz, 3 = 750kHz). if (i2cSpeed > 3) i2cSpeed = 3; if (handle != NULL) { printf("%s: handle already set!\n", __func__); return -1; } int32_t ret = libusb_init(NULL); if (ret < 0) { printf("Couldnt initialize libusb!\n"); return -1; } #if LIBUSB_API_VERSION < 0x01000106 libusb_set_debug(NULL, 3); // Enable information, warning and error messages (only). #else libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, 3); #endif uint16_t vid = devs_ch341a_spi[0].vendor_id; uint16_t pid = devs_ch341a_spi[0].device_id; handle = libusb_open_device_with_vid_pid(NULL, vid, pid); if (handle == NULL) { printf("Couldn't open device %04x:%04x.\n", vid, pid); return -1; } printf("Found programmer device: %s - %s\n", devs_ch341a_spi[0].vendor_name, devs_ch341a_spi[0].device_name); #ifdef __gnu_linux__ /* libusb_detach_kernel_driver() and friends basically only work on Linux. We simply try to detach on Linux * without a lot of passion here. If that works fine else we will fail on claiming the interface anyway. */ ret = libusb_detach_kernel_driver(handle, 0); if (ret == LIBUSB_ERROR_NOT_SUPPORTED) { printf("Detaching kernel drivers is not supported. Further accesses may fail.\n"); } else if (ret != 0 && ret != LIBUSB_ERROR_NOT_FOUND) { printf("Failed to detach kernel driver: '%s'. Further accesses will probably fail.\n", libusb_error_name(ret)); } #endif ret = libusb_claim_interface(handle, 0); if (ret != 0) { printf("Failed to claim interface 0: '%s'\n", libusb_error_name(ret)); goto close_handle; } struct libusb_device *dev; if (!(dev = libusb_get_device(handle))) { printf("Failed to get device from device handle.\n"); goto close_handle; } struct libusb_device_descriptor desc; ret = libusb_get_device_descriptor(dev, &desc); if (ret < 0) { printf("Failed to get device descriptor: '%s'\n", libusb_error_name(ret)); goto release_interface; } printf("Device revision is %d.%01d.%01d\n", (desc.bcdDevice >> 8) & 0x00FF, (desc.bcdDevice >> 4) & 0x000F, (desc.bcdDevice >> 0) & 0x000F); /* Allocate and pre-fill transfer structures. */ transfer_out = libusb_alloc_transfer(0); if (!transfer_out) { printf("Failed to alloc libusb OUT transfer\n"); goto release_interface; } int i; for (i = 0; i < USB_IN_TRANSFERS; i++) { transfer_ins[i] = libusb_alloc_transfer(0); if (transfer_ins[i] == NULL) { printf("Failed to alloc libusb IN transfer %d\n", i); goto dealloc_transfers; } } /* We use these helpers but dont fill the actual buffer yet. */ libusb_fill_bulk_transfer(transfer_out, handle, WRITE_EP, NULL, 0, cb_out, NULL, USB_TIMEOUT); for (i = 0; i < USB_IN_TRANSFERS; i++) libusb_fill_bulk_transfer(transfer_ins[i], handle, READ_EP, NULL, 0, cb_in, NULL, USB_TIMEOUT); if (chipType != 1) { if ((config_stream(CH341A_STM_I2C_750K) < 0) || (enable_pins(true) < 0)) goto dealloc_transfers; } else config_stream(i2cSpeed); if (chipType == 2) { config_stream(1); mw_gpio_init(); } return 0; dealloc_transfers: for (i = 0; i < USB_IN_TRANSFERS; i++) { if (transfer_ins[i] == NULL) break; libusb_free_transfer(transfer_ins[i]); transfer_ins[i] = NULL; } libusb_free_transfer(transfer_out); transfer_out = NULL; release_interface: libusb_release_interface(handle, 0); close_handle: libusb_close(handle); handle = NULL; return -1; } int ch341a_init_i2c(void) { if (handle != NULL) { printf("%s: handle already set!\n", __func__); return -1; } int32_t ret = libusb_init(NULL); if (ret < 0) { printf("Couldnt initialize libusb!\n"); return -1; } #if LIBUSB_API_VERSION < 0x01000106 libusb_set_debug(NULL, 3); // Enable information, warning and error messages (only). #else libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, 3); #endif uint16_t vid = devs_ch341a_spi[0].vendor_id; uint16_t pid = devs_ch341a_spi[0].device_id; handle = libusb_open_device_with_vid_pid(NULL, vid, pid); if (handle == NULL) { printf("Couldn't open device %04x:%04x.\n", vid, pid); return -1; } printf("Found programmer device: %s - %s\n", devs_ch341a_spi[0].vendor_name, devs_ch341a_spi[0].device_name); #ifdef __gnu_linux__ /* libusb_detach_kernel_driver() and friends basically only work on Linux. We simply try to detach on Linux * without a lot of passion here. If that works fine else we will fail on claiming the interface anyway. */ ret = libusb_detach_kernel_driver(handle, 0); if (ret == LIBUSB_ERROR_NOT_SUPPORTED) { printf("Detaching kernel drivers is not supported. Further accesses may fail.\n"); } else if (ret != 0 && ret != LIBUSB_ERROR_NOT_FOUND) { printf("Failed to detach kernel driver: '%s'. Further accesses will probably fail.\n", libusb_error_name(ret)); } #endif ret = libusb_claim_interface(handle, 0); if (ret != 0) { printf("Failed to claim interface 0: '%s'\n", libusb_error_name(ret)); goto close_handle; } struct libusb_device *dev; if (!(dev = libusb_get_device(handle))) { printf("Failed to get device from device handle.\n"); goto close_handle; } struct libusb_device_descriptor desc; ret = libusb_get_device_descriptor(dev, &desc); if (ret < 0) { printf("Failed to get device descriptor: '%s'\n", libusb_error_name(ret)); goto release_interface; } printf("Device revision is %d.%01d.%01d\n", (desc.bcdDevice >> 8) & 0x00FF, (desc.bcdDevice >> 4) & 0x000F, (desc.bcdDevice >> 0) & 0x000F); /* Allocate and pre-fill transfer structures. */ transfer_out = libusb_alloc_transfer(0); if (!transfer_out) { printf("Failed to alloc libusb OUT transfer\n"); goto release_interface; } int i; for (i = 0; i < USB_IN_TRANSFERS; i++) { transfer_ins[i] = libusb_alloc_transfer(0); if (transfer_ins[i] == NULL) { printf("Failed to alloc libusb IN transfer %d\n", i); goto dealloc_transfers; } } /* We use these helpers but dont fill the actual buffer yet. */ libusb_fill_bulk_transfer(transfer_out, handle, WRITE_EP, NULL, 0, cb_out, NULL, USB_TIMEOUT); for (i = 0; i < USB_IN_TRANSFERS; i++) libusb_fill_bulk_transfer(transfer_ins[i], handle, READ_EP, NULL, 0, cb_in, NULL, USB_TIMEOUT); //if ((config_stream(CH341A_STM_I2C_750K) < 0) || (enable_pins(true) < 0)) // goto dealloc_transfers; return 0; dealloc_transfers: for (i = 0; i < USB_IN_TRANSFERS; i++) { if (transfer_ins[i] == NULL) break; libusb_free_transfer(transfer_ins[i]); transfer_ins[i] = NULL; } libusb_free_transfer(transfer_out); transfer_out = NULL; release_interface: libusb_release_interface(handle, 0); close_handle: libusb_close(handle); handle = NULL; return -1; } int ch341GetDescriptor(uint8_t *buf) { int ret; ret = libusb_get_descriptor(handle, LIBUSB_DT_DEVICE, 0x00, buf, 0x12); if(ret < 0) printf("Failed to get device descriptor: '%x'\n", ret); return ret; } imsprog-1.8.5/IMSProg_programmer/ch341a_spi.h000066400000000000000000000026111520775651600207450ustar00rootroot00000000000000/* * Copyright (C) 2018-2021 McMCC * * 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CH341_SPI_H__ #define __CH341_SPI_H__ #include #include #include #include #define min(a,b) (((a)<(b))?(a):(b)) #define max(a,b) (((a)>(b))?(a):(b)) int ch341a_spi_init(void); int ch341a_spi_shutdown(void); int ch341a_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int enable_pins(bool enable); int config_stream(unsigned int speed); int ch341a_init_i2c(void); int ch341a_init(uint8_t chipType, uint8_t i2cSpeed); int ch341GetDescriptor(uint8_t *buf); #endif /* __CH341_SPI_H__ */ /* End of [ch341a_spi.h] package */ imsprog-1.8.5/IMSProg_programmer/ch341funcs.c000066400000000000000000000411721520775651600207700ustar00rootroot00000000000000// // ch341eeprom programmer version 0.1 (Beta) // // Programming tool for the 24Cxx serial EEPROMs using the Winchiphead CH341A IC // // (c) December 2011 asbokid // // 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 3 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, see . #include #include #include #include #include #include #include #include "ch341funcs.h" //extern FILE *debugout, *verbout; uint32_t getnextpkt; // set by the callback function uint32_t syncackpkt; // synch / ack flag used by BULK OUT cb function uint32_t byteoffset; // -------------------------------------------------------------------------- // ch341configure() // lock USB device for exclusive use // claim default interface // set default configuration // retrieve device descriptor // identify device revision // returns *usb device handle struct libusb_device_handle *ch341configure(uint16_t vid, uint16_t pid) { struct libusb_device *dev; struct libusb_device_handle *devHandle; int32_t ret=0; // set to < 0 to indicate USB errors uint32_t i = 0; int32_t currentConfig = 0; uint8_t ch341DescriptorBuffer[0x12]; ret = libusb_init(NULL); if(ret < 0) { fprintf(stderr, "Couldnt initialise libusb\n"); return NULL; } #if LIBUSBX_API_VERSION < 0x01000106 libusb_set_debug(NULL, 3); // maximum debug logging level #else libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, 3); #endif fprintf(verbout, "Searching USB buses for WCH CH341a i2c EEPROM programmer [%04x:%04x]\n", USB_LOCK_VENDOR, USB_LOCK_PRODUCT); if(!(devHandle = libusb_open_device_with_vid_pid(NULL, USB_LOCK_VENDOR, USB_LOCK_PRODUCT))) { fprintf(stderr, "Couldn't open device [%04x:%04x]\n", USB_LOCK_VENDOR, USB_LOCK_PRODUCT); return NULL; } if(!(dev = libusb_get_device(devHandle))) { fprintf(stderr, "Couldnt get bus number and address of device\n"); return NULL; } fprintf(verbout, "Found [%04x:%04x] as device [%d] on USB bus [%d]\n", USB_LOCK_VENDOR, USB_LOCK_PRODUCT, libusb_get_device_address(dev), libusb_get_bus_number(dev)); fprintf(verbout, "Opened device [%04x:%04x]\n", USB_LOCK_VENDOR, USB_LOCK_PRODUCT); if(libusb_kernel_driver_active(devHandle, DEFAULT_INTERFACE)) { ret = libusb_detach_kernel_driver(devHandle, DEFAULT_INTERFACE); if(ret) { fprintf(stderr, "Failed to detach kernel driver: '%s'\n", strerror(-ret)); return NULL; } else fprintf(verbout, "Detached kernel driver\n"); } ret = libusb_get_configuration(devHandle, ¤tConfig); if(ret) { fprintf(stderr, "Failed to get current device configuration: '%s'\n", strerror(-ret)); return NULL; } if(currentConfig != DEFAULT_CONFIGURATION) ret = libusb_set_configuration(devHandle, currentConfig); if(ret) { fprintf(stderr, "Failed to set device configuration to %d: '%s'\n", DEFAULT_CONFIGURATION, strerror(-ret)); return NULL; } ret = libusb_claim_interface(devHandle, DEFAULT_INTERFACE); // interface 0 if(ret) { fprintf(stderr, "Failed to claim interface %d: '%s'\n", DEFAULT_INTERFACE, strerror(-ret)); return NULL; } fprintf(verbout, "Claimed device interface [%d]\n", DEFAULT_INTERFACE); ret = libusb_get_descriptor(devHandle, LIBUSB_DT_DEVICE, 0x00, ch341DescriptorBuffer, 0x12); if(ret < 0) { fprintf(stderr, "Failed to get device descriptor: '%s'\n", strerror(-ret)); return NULL; } fprintf(verbout, "Device reported its revision [%d.%02d]\n", ch341DescriptorBuffer[12], ch341DescriptorBuffer[13]); for(i=0;i<0x12;i++) fprintf(debugout,"%02x ", ch341DescriptorBuffer[i]); fprintf(debugout,"\n"); return devHandle; } // -------------------------------------------------------------------------- // ch341setstream() // set the i2c bus speed (speed: 0 = 20kHz; 1 = 100kHz, 2 = 400kHz, 3 = 750kHz) int32_t ch341setstream(struct libusb_device_handle *devHandle, uint32_t speed) { int32_t ret, i; uint8_t ch341outBuffer[EEPROM_READ_BULKOUT_BUF_SZ], *outptr; int32_t actuallen = 0; outptr = ch341outBuffer; *outptr++ = mCH341A_CMD_I2C_STREAM; *outptr++ = mCH341A_CMD_I2C_STM_SET | (speed & 0x3); *outptr = mCH341A_CMD_I2C_STM_END; ret = libusb_bulk_transfer(devHandle, BULK_WRITE_ENDPOINT, ch341outBuffer, 3, &actuallen, DEFAULT_TIMEOUT); if(ret < 0) { fprintf(stderr, "ch341setstream(): Failed write %d bytes '%s'\n", 3, strerror(-ret)); return -1; } fprintf(debugout, "ch341setstream(): Wrote %d bytes: ", 3); for(i=0; i < 3; i++) fprintf(debugout, "%02x ", ch341outBuffer[i]); fprintf(debugout, "\n"); return 0; } size_t ch341ReadCmdMarshall(uint8_t *buffer, uint32_t addr, struct EEPROM *eeprom_info) { uint8_t *ptr = buffer; // Frame 1. Program data address, and read 32 bytes. *ptr++ = mCH341A_CMD_I2C_STREAM; // 0 *ptr++ = mCH341A_CMD_I2C_STM_STA; // 1 // Write address *ptr++ = mCH341A_CMD_I2C_STM_OUT | ((*eeprom_info).addr_size+1); // 2: I2C bus adddress + EEPROM address uint8_t msb_addr; if ((*eeprom_info).addr_size >= 2) { // 24C32 and more msb_addr = addr>>16 & (*eeprom_info).i2c_addr_mask; *ptr++ = (EEPROM_I2C_BUS_ADDRESS | msb_addr)<<1; // 3 *ptr++ = (addr>>8 & 0xFF); // 4 *ptr++ = (addr>>0 & 0xFF); // 5 } else { // 24C16 and less msb_addr = addr>>8 & (*eeprom_info).i2c_addr_mask; *ptr++ = (EEPROM_I2C_BUS_ADDRESS | msb_addr)<<1; // 3 *ptr++ = (addr>>0 & 0xFF); // 4 } *ptr++ = mCH341A_CMD_I2C_STM_STA; // 6/5 *ptr++ = mCH341A_CMD_I2C_STM_OUT | 1; // 7/6 *ptr++ = (EEPROM_I2C_BUS_ADDRESS | msb_addr)<<1 | 1; // 8/7: Read command // Read 32 bytes *ptr++ = mCH341A_CMD_I2C_STM_IN | 32; // 9/8 *ptr++ = mCH341A_CMD_I2C_STM_END; // 10/9 // Frame 2 - read 32 bytes ptr = &buffer[32]; *ptr++ = mCH341A_CMD_I2C_STREAM; *ptr++ = mCH341A_CMD_I2C_STM_IN | 32; *ptr++ = mCH341A_CMD_I2C_STM_END; // Frame 3 - read 32 bytes ptr = &buffer[64]; *ptr++ = mCH341A_CMD_I2C_STREAM; *ptr++ = mCH341A_CMD_I2C_STM_IN | 32; *ptr++ = mCH341A_CMD_I2C_STM_END; // Finalize - read last 32 bytes ptr = &buffer[96]; *ptr++ = mCH341A_CMD_I2C_STREAM; *ptr++ = mCH341A_CMD_I2C_STM_IN | 31; *ptr++ = mCH341A_CMD_I2C_STM_IN; *ptr++ = mCH341A_CMD_I2C_STM_STO; *ptr++ = mCH341A_CMD_I2C_STM_END; return ptr - buffer; } // -------------------------------------------------------------------------- // ch341readEEPROM() // read n bytes from device (in packets of 32 bytes) int32_t ch341readEEPROM(struct libusb_device_handle *devHandle, uint8_t *buffer, uint32_t bytestoread, struct EEPROM *eeprom_info) { uint8_t ch341outBuffer[EEPROM_READ_BULKOUT_BUF_SZ]; uint8_t ch341inBuffer[IN_BUF_SZ]; // 0x100 bytes int32_t ret = 0, readpktcount = 0; struct libusb_transfer *xferBulkIn, *xferBulkOut; struct timeval tv = {0, 100}; // our async polling interval size_t xfer_size; xferBulkIn = libusb_alloc_transfer(0); xferBulkOut = libusb_alloc_transfer(0); if(!xferBulkIn || !xferBulkOut) { fprintf(stderr, "Couldnt allocate USB transfer structures\n"); return -1; } byteoffset = 0; fprintf(debugout, "Allocated USB transfer structures\n"); memset(ch341inBuffer, 0, EEPROM_READ_BULKIN_BUF_SZ); xfer_size = ch341ReadCmdMarshall(ch341outBuffer, 0, eeprom_info); // Fill output buffer libusb_fill_bulk_transfer(xferBulkIn, devHandle, BULK_READ_ENDPOINT, ch341inBuffer, EEPROM_READ_BULKIN_BUF_SZ, cbBulkIn, NULL, DEFAULT_TIMEOUT); libusb_fill_bulk_transfer(xferBulkOut, devHandle, BULK_WRITE_ENDPOINT, ch341outBuffer, xfer_size, cbBulkOut, NULL, DEFAULT_TIMEOUT); fprintf(debugout, "Filled USB transfer structures\n"); libusb_submit_transfer(xferBulkIn); fprintf(debugout, "Submitted BULK IN start packet\n"); libusb_submit_transfer(xferBulkOut); fprintf(debugout, "Submitted BULK OUT setup packet\n"); readbuf = buffer; while (1) { fprintf(stdout, "Read %d%% [%d] of [%d] bytes \r", 100*byteoffset/bytestoread, byteoffset, bytestoread); ret = libusb_handle_events_timeout(NULL, &tv); if (ret < 0 || getnextpkt == -1) { // indicates an error fprintf(stderr, "ret from libusb_handle_timeout = %d\n", ret); fprintf(stderr, "getnextpkt = %d\n", getnextpkt); if (ret < 0) fprintf(stderr, "USB read error : %s\n", strerror(-ret)); libusb_free_transfer(xferBulkIn); libusb_free_transfer(xferBulkOut); return -1; } if(getnextpkt == 1) { // callback function reports a new BULK IN packet received getnextpkt = 0; // reset the flag readpktcount++; // increment the read packet counter byteoffset += EEPROM_READ_BULKIN_BUF_SZ; if (byteoffset == bytestoread) break; fprintf(debugout, "\nRe-submitting transfer request to BULK IN endpoint\n"); libusb_submit_transfer(xferBulkIn); // re-submit request for next BULK IN packet of EEPROM data if(syncackpkt) syncackpkt = 0; // if 4th packet received, we are at end of 0x80 byte data block, // if it is not the last block, then resubmit request for data if(readpktcount==4) { fprintf(debugout, "\nSubmitting next transfer request to BULK OUT endpoint\n"); readpktcount = 0; ch341ReadCmdMarshall(ch341outBuffer, byteoffset, eeprom_info); // Fill output buffer libusb_fill_bulk_transfer(xferBulkOut, devHandle, BULK_WRITE_ENDPOINT, ch341outBuffer, EEPROM_READ_BULKOUT_BUF_SZ, cbBulkOut, NULL, DEFAULT_TIMEOUT); libusb_submit_transfer(xferBulkOut);// update transfer struct (with new EEPROM page offset) // and re-submit next transfer request to BULK OUT endpoint } } } libusb_free_transfer(xferBulkIn); libusb_free_transfer(xferBulkOut); return 0; } // Callback function for async bulk in comms void cbBulkIn(struct libusb_transfer *transfer) { int i; switch(transfer->status) { case LIBUSB_TRANSFER_COMPLETED: // display the contents of the BULK IN data buffer fprintf(debugout,"\ncbBulkIn(): status %d - Read %d bytes\n",transfer->status,transfer->actual_length); for(i=0; i < transfer->actual_length; i++) { if(!(i%16)) fprintf(debugout, "\n "); fprintf(debugout, "%02x ", transfer->buffer[i]); } fprintf(debugout, "\n"); // copy read data to our EEPROM buffer memcpy(readbuf + byteoffset, transfer->buffer, transfer->actual_length); getnextpkt = 1; break; default: fprintf(stderr, "\ncbBulkIn: error : %d\n", transfer->status); getnextpkt = -1; } return; } // Callback function for async bulk out comms void cbBulkOut(struct libusb_transfer *transfer) { syncackpkt = 1; fprintf(debugout, "\ncbBulkOut(): Sync/Ack received: status %d\n", transfer->status); return; } // -------------------------------------------------------------------------- // ch341writeEEPROM() // write n bytes to 24c32/24c64 device (in packets of 32 bytes) int32_t ch341writeEEPROM(struct libusb_device_handle *devHandle, uint8_t *buffer, uint32_t bytesum, struct EEPROM *eeprom_info) { uint8_t ch341outBuffer[512/*EEPROM_WRITE_BUF_SZ*/]; uint8_t *outptr, *bufptr; uint8_t i2cCmdBuffer[256]; int32_t ret = 0, i; uint32_t byteoffset = 0; uint32_t bytes = bytesum; uint8_t addrbytecount = (*eeprom_info).addr_size+1; // 24c32 and 24c64 (and other 24c??) use 3 bytes for addressing int32_t actuallen = 0; uint16_t page_size = (*eeprom_info).page_size; bufptr = buffer; while(bytes) { outptr = i2cCmdBuffer; if ((*eeprom_info).addr_size >= 2) { *outptr++ = (uint8_t) (0xa0 | (byteoffset >> 16 & (*eeprom_info).i2c_addr_mask)<<1); // EEPROM device address *outptr++ = (uint8_t) (byteoffset >> 8 & 0xff); // MSB (big-endian) byte address } else { *outptr++ = (uint8_t) (0xa0 | (byteoffset >> 8 & (*eeprom_info).i2c_addr_mask)<<1); // EEPROM device address } *outptr++ = (uint8_t) (byteoffset & 0xff); // LSB of 16-bit byte address memcpy(outptr, bufptr, page_size); // Copy one page byteoffset += page_size; bufptr += page_size; bytes -= page_size; outptr = ch341outBuffer; uint16_t page_size_left = page_size + addrbytecount; uint8_t part_no = 0; uint8_t *i2cBufPtr = i2cCmdBuffer; while(page_size_left) { uint8_t to_write = MIN(page_size_left, 28); *outptr++ = mCH341A_CMD_I2C_STREAM; if (part_no == 0) { // Start packet *outptr++ = mCH341A_CMD_I2C_STM_STA; } *outptr++ = mCH341A_CMD_I2C_STM_OUT | to_write; memcpy(outptr, i2cBufPtr, to_write); outptr += to_write; i2cBufPtr += to_write; page_size_left -= to_write; if (page_size_left == 0) { // Stop packet *outptr++ = mCH341A_CMD_I2C_STM_STO; } *outptr++ = mCH341A_CMD_I2C_STM_END; part_no++; } uint32_t payload_size = outptr - ch341outBuffer; for(i=0; i < payload_size; i++) { if(!(i%0x10)) fprintf(debugout, "\n%04x : ", i); fprintf(debugout, "%02x ", ch341outBuffer[i]); } fprintf(debugout, "\n"); ret = libusb_bulk_transfer(devHandle, BULK_WRITE_ENDPOINT, ch341outBuffer, payload_size, &actuallen, DEFAULT_TIMEOUT); if(ret < 0) { fprintf(stderr, "Failed to write to EEPROM: '%s'\n", strerror(-ret)); return -1; } fprintf(debugout, "Writing [aa 5a 00] to EEPROM\n"); // Magic CH341a packet! Undocumented, unknown purpose outptr = ch341outBuffer; *outptr++ = mCH341A_CMD_I2C_STREAM; *outptr++ = mCH341A_CMD_I2C_STM_MS | 10; // Wait 10ms (?) *outptr++ = mCH341A_CMD_I2C_STM_END; ret = libusb_bulk_transfer(devHandle, BULK_WRITE_ENDPOINT, ch341outBuffer, 3, &actuallen, DEFAULT_TIMEOUT); if(ret < 0) { fprintf(stderr, "Failed to write to EEPROM: '%s'\n", strerror(-ret)); return -1; } /* struct timeval tv = {0, 100}; // our async polling interval ret = libusb_handle_events_timeout(NULL, &tv); if (ret < 0) { // indicates an error fprintf(stderr, "ret from libusb_handle_timeout = %d\n", ret); fprintf(stderr, "USB read error : %s\n", strerror(-ret)); return -1; } */ fprintf(stdout, "Written %d%% [%d] of [%d] bytes \r", 100*(bytesum-bytes)/bytesum, bytesum-bytes, bytesum); } return 0; } // -------------------------------------------------------------------------- // parseEEPsize() // passed an EEPROM name (case-sensitive), returns its byte size int32_t parseEEPsize(char* eepromname, struct EEPROM *eeprom) { int i; for(i=0; eepromlist[i].size; i++) if(strstr(eepromlist[i].name, eepromname)) { memcpy(eeprom, &(eepromlist[i]), sizeof(struct EEPROM)); return(eepromlist[i].size); } return -1; } imsprog-1.8.5/IMSProg_programmer/ch341funcs.h000066400000000000000000000540131520775651600207730ustar00rootroot00000000000000// libUSB driver for the ch341a in i2c mode // // Copyright 2011 asbokid #define CH341TOOLVERSION "0.5" #define USB_LOCK_VENDOR 0x1a86 // Dev : (1a86) QinHeng Electronics #define USB_LOCK_PRODUCT 0x5512 // (5512) CH341A in i2c mode #define MAX_EEPROM_SIZE 131072 /* For 24c1024*/ #define EEPROM_I2C_BUS_ADDRESS 0x50 #define BULK_WRITE_ENDPOINT 0x02 /* bEndpointAddress 0x02 EP 2 OUT (Bulk)*/ #define BULK_READ_ENDPOINT 0x82 /* bEndpointAddress 0x82 EP 2 IN (Bulk)*/ #define DEFAULT_INTERFACE 0x00 #define DEFAULT_CONFIGURATION 0x01 #define DEFAULT_TIMEOUT 300 // 300mS for USB timeouts #define IN_BUF_SZ 0x100 #define EEPROM_WRITE_BUF_SZ 0x2b // only for 24c64 / 24c32 ?? #define EEPROM_READ_BULKIN_BUF_SZ 0x20 #define EEPROM_READ_BULKOUT_BUF_SZ 0x65 /* Based on (closed-source) DLL V1.9 for USB by WinChipHead (c) 2005. Supports USB chips: CH341, CH341A This can be a problem for copyright, sure asbokid can't release this part on any GPL licence*/ #define mCH341_PACKET_LENGTH 32 /* wMaxPacketSize 0x0020 1x 32 bytes, unused on the source*/ #define mCH341_PKT_LEN_SHORT 8 /* wMaxPacketSize 0x0008 1x 8 bytes, unused on the source*/ #define mCH341_ENDP_INTER_UP 0x81 /* bEndpointAddress 0x81 EP 1 IN (Interrupt), unused on the source*/ #define mCH341_ENDP_INTER_DOWN 0x01 /* This endpoint isn't list on my lsusb -v output, unused on the source*/ #define mCH341_ENDP_DATA_UP 0x82 /* ==BULK_READ_ENDPOINT Why repeat it?*/ #define mCH341_ENDP_DATA_DOWN 0x02 /* ==BULK_WRITE_ENDPOINT Why repeat it?*/ #define mCH341_VENDOR_READ 0xC0 /* Unused on the source*/ #define mCH341_VENDOR_WRITE 0x40 /* Unused on the source*/ #define mCH341_PARA_INIT 0xB1 /* Unused on the source*/ #define mCH341_I2C_STATUS 0x52 /* Unused on the source*/ #define mCH341_I2C_COMMAND 0x53 /* Unused on the source*/ #define mCH341_PARA_CMD_R0 0xAC /* Unused on the source*/ #define mCH341_PARA_CMD_R1 0xAD /* Unused on the source*/ #define mCH341_PARA_CMD_W0 0xA6 /* Unused on the source*/ #define mCH341_PARA_CMD_W1 0xA7 /* Unused on the source*/ #define mCH341_PARA_CMD_STS 0xA0 /* Unused on the source*/ #define mCH341A_CMD_SET_OUTPUT 0xA1 /* Unused on the source*/ #define mCH341A_CMD_IO_ADDR 0xA2 /* Unused on the source*/ #define mCH341A_CMD_PRINT_OUT 0xA3 /* Unused on the source*/ #define mCH341A_CMD_SPI_STREAM 0xA8 /* Unused on the source*/ #define mCH341A_CMD_SIO_STREAM 0xA9 /* Unused on the source*/ #define mCH341A_CMD_I2C_STREAM 0xAA #define mCH341A_CMD_UIO_STREAM 0xAB /* Unused on the source*/ #define mCH341A_BUF_CLEAR 0xB2 /* Unused on the source*/ #define mCH341A_I2C_CMD_X 0x54 /* Unused on the source*/ #define mCH341A_DELAY_MS 0x5E /* Unused on the source*/ #define mCH341A_GET_VER 0x5F /* Unused on the source*/ #define mCH341_EPP_IO_MAX ( mCH341_PACKET_LENGTH - 1 ) /* Unused on the source*/ #define mCH341A_EPP_IO_MAX 0xFF /* Unused on the source*/ #define mCH341A_CMD_IO_ADDR_W 0x00 /* Unused on the source*/ #define mCH341A_CMD_IO_ADDR_R 0x80 /* Unused on the source*/ #define mCH341A_CMD_I2C_STM_STA 0x74 #define mCH341A_CMD_I2C_STM_STO 0x75 #define mCH341A_CMD_I2C_STM_OUT 0x80 #define mCH341A_CMD_I2C_STM_IN 0xC0 #define mCH341A_CMD_I2C_STM_MAX ( min( 0x3F, mCH341_PACKET_LENGTH ) ) /* Unused on the source*/ #define mCH341A_CMD_I2C_STM_SET 0x60 #define mCH341A_CMD_I2C_STM_US 0x40 /* Unused on the source*/ #define mCH341A_CMD_I2C_STM_MS 0x50 /* Unused on the source*/ #define mCH341A_CMD_I2C_STM_DLY 0x0F /* Unused on the source*/ #define mCH341A_CMD_I2C_STM_END 0x00 #define mCH341A_CMD_UIO_STM_IN 0x00 /* Unused on the source*/ #define mCH341A_CMD_UIO_STM_DIR 0x40 /* Unused on the source*/ #define mCH341A_CMD_UIO_STM_OUT 0x80 /* Unused on the source*/ #define mCH341A_CMD_UIO_STM_US 0xC0 /* Unused on the source*/ #define mCH341A_CMD_UIO_STM_END 0x20 /* Unused on the source*/ #define mCH341_PARA_MODE_EPP 0x00 /* Unused on the source*/ #define mCH341_PARA_MODE_EPP17 0x00 /* Unused on the source*/ #define mCH341_PARA_MODE_EPP19 0x01 /* Unused on the source*/ #define mCH341_PARA_MODE_MEM 0x02 /* Unused on the source*/ /* End of part based on (closed-source) DLL V1.9 for USB by WinChipHead (c) 2005. Since is largely unused we can replace it*/ #define CH341_I2C_LOW_SPEED 0 // low speed - 20kHz #define CH341_I2C_STANDARD_SPEED 1 // standard speed - 100kHz #define CH341_I2C_FAST_SPEED 2 // fast speed - 400kHz #define CH341_I2C_HIGH_SPEED 3 // high speed - 750kHz #define CH341_EEPROM_READ_CMD_SZ 0x65 /* Same size for all 24cXX read setup and next packets*/ /* CH341a READ EEPROM setup packet for the 24c01 this needs putting into a struct to allow convenient access to individual elements*/ #define CH341_EEPROM_24c01_READ_SETUP_CMD "\xaa\x74\x82\xa0\x00\x74\x81\xa1\xe0\x00\x0f\x00\x06\x04\x00\x00" \ "\x00\x00\x00\x00\x01\x00\x00\x00\x11\x4d\x40\x77\xcd\xab\xba\xdc" \ "\xaa\xe0\x00\x00\xc4\xf1\x12\x00\x11\x4d\x40\x77\xf0\xf1\x12\x00" \ "\xd9\x8b\x41\x7e\x00\xd0\xfd\x7f\xf0\xf1\x12\x00\x5a\x88\x41\x7e" \ "\xaa\xe0\x00\x00\x2a\x88\x41\x7e\x06\x04\x00\x00\x11\x4d\x40\x77" \ "\xe8\xf3\x12\x00\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xdf\xc0\x75\x00" /* please se file /wiresharkusbsniffing/sniffed.txt this is the read setup packet for 24c01 0040 aa 74 82 a0 00 74 81 a1 e0 00 0f 00 06 04 00 00 .t...t.. ........ 0050 00 00 00 00 01 00 00 00 11 4d 40 77 cd ab ba dc ........ .M@w.... 0060 aa e0 00 00 c4 f1 12 00 11 4d 40 77 f0 f1 12 00 ........ .M@w.... 0070 d9 8b 41 7e 00 d0 fd 7f f0 f1 12 00 5a 88 41 7e ..A~.... ....Z.A~ 0080 aa e0 00 00 2a 88 41 7e 06 04 00 00 11 4d 40 77 ....*.A~ .....M@w 0090 e8 f3 12 00 14 00 00 00 01 00 00 00 00 00 00 00 ........ ........ 00a0 aa df c0 75 00 ...u. */ /* CH341a READ EEPROM next packet for 24c01 (no packets!!!)*/ /* CH341a READ EEPROM setup packet for the 24c02 this needs putting into a struct to allow convenient access to individual elements*/ #define CH341_EEPROM_24c02_READ_SETUP_CMD "\xaa\x74\x82\xa0\x00\x74\x81\xa1\xe0\x00\x10\x00\x06\x04\x00\x00" \ "\x00\x00\x00\x00\x02\x00\x00\x00\x11\x4d\x40\x77\xcd\xab\xba\xdc" \ "\xaa\xe0\x00\x00\xc4\xf1\x12\x00\x11\x4d\x40\x77\xf0\xf1\x12\x00" \ "\xd9\x8b\x41\x7e\x00\xf0\xfd\x7f\xf0\xf1\x12\x00\x5a\x88\x41\x7e" \ "\xaa\xe0\x00\x00\x2a\x88\x41\x7e\x06\x04\x00\x00\x11\x4d\x40\x77" \ "\xe8\xf3\x12\x00\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xdf\xc0\x75\x00" /* please se file /wiresharkusbsniffing/sniffed.txt this is the read setup packet for 24c02 0040 aa 74 82 a0 00 74 81 a1 e0 00 10 00 06 04 00 00 .t...t.. ........ 0050 00 00 00 00 02 00 00 00 11 4d 40 77 cd ab ba dc ........ .M@w.... 0060 aa e0 00 00 c4 f1 12 00 11 4d 40 77 f0 f1 12 00 ........ .M@w.... 0070 d9 8b 41 7e 00 f0 fd 7f f0 f1 12 00 5a 88 41 7e ..A~.... ....Z.A~ 0080 aa e0 00 00 2a 88 41 7e 06 04 00 00 11 4d 40 77 ....*.A~ .....M@w 0090 e8 f3 12 00 14 00 00 00 01 00 00 00 00 00 00 00 ........ ........ 00a0 aa df c0 75 00 ...u. */ /* CH341a READ EEPROM next packet for 24c02 (one packet)*/ #define CH341_EEPROM_24c02_READ_NEXT_CMD "\xaa\x74\x82\xa0\x80\x74\x81\xa1\xe0\x00\x00\x00\x10\x00\x00\x00" \ "\x00\x00\x00\x00\x8c\xf1\x12\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xe0\x00\x00\x4c\xf1\x12\x00\x5d\x22\xd7\x5a\xdc\xf1\x12\x00" \ "\x8f\x04\x44\x7e\x30\x88\x41\x7e\xff\xff\xff\xff\x2a\x88\x41\x7e" \ "\xaa\xe0\x00\x7e\x00\x00\x00\x00\x69\x0e\x3c\x00\xe4\x00\x18\x00" \ "\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xe8\x67\x00" \ "\xaa\xdf\xc0\x75\x00" /*please see file /wiresharkusbsniffing/sniffed.txt this is the read next packet for 24c02 (one packet) 0040 aa 74 82 a0 80 74 81 a1 e0 00 00 00 10 00 00 00 .t...t.. ........ 0050 00 00 00 00 8c f1 12 00 01 00 00 00 00 00 00 00 ........ ........ 0060 aa e0 00 00 4c f1 12 00 5d 22 d7 5a dc f1 12 00 ....L... ]".Z.... 0070 8f 04 44 7e 30 88 41 7e ff ff ff ff 2a 88 41 7e ..D~0.A~ ....*.A~ 0080 aa e0 00 7e 00 00 00 00 69 0e 3c 00 e4 00 18 00 ...~.... i.<..... 0090 0f 00 00 00 00 00 00 00 00 00 00 00 8c e8 67 00 ........ ......g. 00a0 aa df c0 75 00 ...u. */ /* CH341a READ EEPROM setup packet for the 24c04 this needs putting into a struct to allow convenient access to individual elements*/ #define CH341_EEPROM_24c04_READ_SETUP_CMD "\xaa\x74\x82\xa0\x00\x74\x81\xa1\xe0\x00\x11\x00\x06\x04\x00\x00" \ "\x00\x00\x00\x00\x04\x00\x00\x00\x11\x4d\x40\x77\xcd\xab\xba\xdc" \ "\xaa\xe0\x00\x00\xc4\xf1\x12\x00\x11\x4d\x40\x77\xf0\xf1\x12\x00" \ "\xd9\x8b\x41\x7e\x00\xd0\xfd\x7f\xf0\xf1\x12\x00\x5a\x88\x41\x7e" \ "\xaa\xe0\x00\x00\x2a\x88\x41\x7e\x06\x04\x00\x00\x11\x4d\x40\x77" \ "\xe8\xf3\x12\x00\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xdf\xc0\x75\x00" /* please se file /wiresharkusbsniffing/sniffed.txt this is the read setup packet for 24c04 0040 aa 74 82 a0 00 74 81 a1 e0 00 11 00 06 04 00 00 .t...t.. ........ 0050 00 00 00 00 04 00 00 00 11 4d 40 77 cd ab ba dc ........ .M@w.... 0060 aa e0 00 00 c4 f1 12 00 11 4d 40 77 f0 f1 12 00 ........ .M@w.... 0070 d9 8b 41 7e 00 d0 fd 7f f0 f1 12 00 5a 88 41 7e ..A~.... ....Z.A~ 0080 aa e0 00 00 2a 88 41 7e 06 04 00 00 11 4d 40 77 ....*.A~ .....M@w 0090 e8 f3 12 00 14 00 00 00 01 00 00 00 00 00 00 00 ........ ........ 00a0 aa df c0 75 00 ...u. */ /* CH341a READ EEPROM next packet for 24c04 (three packets)*/ #define CH341_EEPROM_24c04_READ_NEXT_CMD "\xaa\x74\x82\xa0\x80\x74\x81\xa1\xe0\x00\x00\x00\x10\x00\x00\x00" \ "\x00\x00\x00\x00\x8c\xf1\x12\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xe0\x00\x00\x4c\xf1\x12\x00\x5d\x22\xd7\x5a\xdc\xf1\x12\x00" \ "\x8f\x04\x44\x7e\x30\x88\x41\x7e\xff\xff\xff\xff\x2a\x88\x41\x7e" \ "\xaa\xe0\x00\x7e\x00\x00\x00\x00\x69\x0e\x3c\x00\xde\x00\x16\x00" \ "\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xe8\x67\x00" \ "\xaa\xdf\xc0\x75\x00" /*please see file /wiresharkusbsniffing/sniffed.txt this is the first read next packet for 24c04 (three different packets) 0040 aa 74 82 a0 80 74 81 a1 e0 00 00 00 10 00 00 00 .t...t.. ........ 0050 00 00 00 00 8c f1 12 00 01 00 00 00 00 00 00 00 ........ ........ 0060 aa e0 00 00 4c f1 12 00 5d 22 d7 5a dc f1 12 00 ....L... ]".Z.... 0070 8f 04 44 7e 30 88 41 7e ff ff ff ff 2a 88 41 7e ..D~0.A~ ....*.A~ 0080 aa e0 00 7e 00 00 00 00 69 0e 3c 00 de 00 16 00 ...~.... i.<..... 0090 0f 00 00 00 00 00 00 00 00 00 00 00 8c e8 67 00 ........ ......g. 00a0 aa df c0 75 00 ...u. */ /* CH341a READ EEPROM setup packet for the 24c08 this needs putting into a struct to allow convenient access to individual elements*/ #define CH341_EEPROM_24c08_READ_SETUP_CMD "\xaa\x74\x82\xa0\x00\x74\x81\xa1\xe0\x00\x16\x00\x06\x04\x00\x00" \ "\x00\x00\x00\x00\x08\x00\x00\x00\x11\x4d\x40\x77\xcd\xab\xba\xdc" \ "\xaa\xe0\x00\x00\xc4\xf1\x12\x00\x11\x4d\x40\x77\xf0\xf1\x12\x00" \ "\xd9\x8b\x41\x7e\x00\xd0\xfd\x7f\xf0\xf1\x12\x00\x5a\x88\x41\x7e" \ "\xaa\xe0\x00\x00\x2a\x88\x41\x7e\x06\x04\x00\x00\x11\x4d\x40\x77" \ "\xe8\xf3\x12\x00\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xdf\xc0\x75\x00" /* please se file /wiresharkusbsniffing/sniffed.txt this is the read setup packet for 24c08 0040 aa 74 82 a0 00 74 81 a1 e0 00 16 00 06 04 00 00 .t...t.. ........ 0050 00 00 00 00 08 00 00 00 11 4d 40 77 cd ab ba dc ........ .M@w.... 0060 aa e0 00 00 c4 f1 12 00 11 4d 40 77 f0 f1 12 00 ........ .M@w.... 0070 d9 8b 41 7e 00 d0 fd 7f f0 f1 12 00 5a 88 41 7e ..A~.... ....Z.A~ 0080 aa e0 00 00 2a 88 41 7e 06 04 00 00 11 4d 40 77 ....*.A~ .....M@w 0090 e8 f3 12 00 14 00 00 00 01 00 00 00 00 00 00 00 ........ ........ 00a0 aa df c0 75 00 ...u. */ /* CH341a READ EEPROM next packet for 24c08 (seven packets)*/ #define CH341_EEPROM_24c08_READ_NEXT_CMD "\xaa\x74\x82\xa0\x80\x74\x81\xa1\xe0\x00\x00\x00\x10\x00\x00\x00" \ "\x00\x00\x00\x00\x8c\xf1\x12\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xe0\x00\x00\x4c\xf1\x12\x00\x5d\x22\xd7\x5a\xdc\xf1\x12\x00" \ "\x8f\x04\x44\x7e\x30\x88\x41\x7e\xff\xff\xff\xff\x2a\x88\x41\x7e" \ "\xaa\xe0\x00\x7e\x00\x00\x00\x00\x69\x0e\x3c\x00\x00\x01\x1a\x00" \ "\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xe8\x67\x00" \ "\xaa\xdf\xc0\x75\x00" /*please see file /wiresharkusbsniffing/sniffed.txt this is the first read next packet for 24c08 (seven different packets) 0040 aa 74 82 a0 80 74 81 a1 e0 00 00 00 10 00 00 00 .t...t.. ........ 0050 00 00 00 00 8c f1 12 00 01 00 00 00 00 00 00 00 ........ ........ 0060 aa e0 00 00 4c f1 12 00 5d 22 d7 5a dc f1 12 00 ....L... ]".Z.... 0070 8f 04 44 7e 30 88 41 7e ff ff ff ff 2a 88 41 7e ..D~0.A~ ....*.A~ 0080 aa e0 00 7e 00 00 00 00 69 0e 3c 00 00 01 1a 00 ...~.... i.<..... 0090 0f 00 00 00 00 00 00 00 00 00 00 00 8c e8 67 00 ........ ......g. 00a0 aa df c0 75 00 ...u. */ /* CH341a READ EEPROM setup packet for the 24c16 this needs putting into a struct to allow convenient access to individual elements*/ #define CH341_EEPROM_24c16_READ_SETUP_CMD "\xaa\x74\x82\xa0\x00\x74\x81\xa1\xe0\x00\x0e\x00\x06\x04\x00\x00" \ "\x00\x00\x00\x00\x10\x00\x00\x00\x11\x4d\x40\x77\xcd\xab\xba\xdc" \ "\xaa\xe0\x00\x00\xc4\xf1\x12\x00\x11\x4d\x40\x77\xf0\xf1\x12\x00" \ "\xd9\x8b\x41\x7e\x00\xe0\xfd\x7f\xf0\xf1\x12\x00\x5a\x88\x41\x7e" \ "\xaa\xe0\x00\x00\x2a\x88\x41\x7e\x06\x04\x00\x00\x11\x4d\x40\x77" \ "\xe8\xf3\x12\x00\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xdf\xc0\x75\x00" /* please se file /wiresharkusbsniffing/sniffed.txt this is the read setup packet for 24c16 0040 aa 74 82 a0 00 74 81 a1 e0 00 0e 00 06 04 00 00 .t...t.. ........ 0050 00 00 00 00 10 00 00 00 11 4d 40 77 cd ab ba dc ........ .M@w.... 0060 aa e0 00 00 c4 f1 12 00 11 4d 40 77 f0 f1 12 00 ........ .M@w.... 0070 d9 8b 41 7e 00 e0 fd 7f f0 f1 12 00 5a 88 41 7e ..A~.... ....Z.A~ 0080 aa e0 00 00 2a 88 41 7e 06 04 00 00 11 4d 40 77 ....*.A~ .....M@w 0090 e8 f3 12 00 14 00 00 00 01 00 00 00 00 00 00 00 ........ ........ 00a0 aa df c0 75 00 ...u. */ /* CH341a READ EEPROM next packet for 24c16*/ #define CH341_EEPROM_24c16_READ_NEXT_CMD "\xaa\x74\x82\xa0\x80\x74\x81\xa1\xe0\x00\x00\x00\x10\x00\x00\x00" \ "\x00\x00\x00\x00\x8c\xf1\x12\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xe0\x00\x00\x4c\xf1\x12\x00\x5d\x22\xd7\x5a\xdc\xf1\x12\x00" \ "\x8f\x04\x44\x7e\x30\x88\x41\x7e\xff\xff\xff\xff\x2a\x88\x41\x7e" \ "\xaa\xe0\x00\x7e\x00\x00\x00\x00\x69\x0e\x3c\x00\xfa\x00\x31\x00" \ "\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xe8\x67\x00" \ "\xaa\xdf\xc0\x75\x00" /*please see file /wiresharkusbsniffing/sniffed.txt this is the first read next packet for 24c16 (fifteen different packets) 0040 aa 74 82 a0 80 74 81 a1 e0 00 00 00 10 00 00 00 .t...t.. ........ 0050 00 00 00 00 8c f1 12 00 01 00 00 00 00 00 00 00 ........ ........ 0060 aa e0 00 00 4c f1 12 00 5d 22 d7 5a dc f1 12 00 ....L... ]".Z.... 0070 8f 04 44 7e 30 88 41 7e ff ff ff ff 2a 88 41 7e ..D~0.A~ ....*.A~ 0080 aa e0 00 7e 00 00 00 00 69 0e 3c 00 fa 00 31 00 ...~.... i.<...1. 0090 0f 00 00 00 00 00 00 00 00 00 00 00 8c e8 67 00 ........ ......g. 00a0 aa df c0 75 00 ...u. */ /* CH341a READ EEPROM setup packet for the 24c64 this needs putting into a struct to allow convenient access to individual elements*/ #define CH341_EEPROM_24c64_READ_SETUP_CMD "\xaa\x74\x83\xa0\x00\x00\x74\x81\xa1\xe0\x00\x00\x06\x04\x00\x00" \ "\x00\x00\x00\x00\x40\x00\x00\x00\x11\x4d\x40\x77\xcd\xab\xba\xdc" \ "\xaa\xe0\x00\x00\xc4\xf1\x12\x00\x11\x4d\x40\x77\xf0\xf1\x12\x00" \ "\xd9\x8b\x41\x7e\x00\xf0\xfd\x7f\xf0\xf1\x12\x00\x5a\x88\x41\x7e" \ "\xaa\xe0\x00\x00\x2a\x88\x41\x7e\x06\x04\x00\x00\x11\x4d\x40\x77" \ "\xe8\xf3\x12\x00\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xdf\xc0\x75\x00" /* please se file /wiresharkusbsniffing/sniffed.txt this is the read setup packet for 24c64 0040 aa 74 83 a0 00 00 74 81 a1 e0 00 00 06 04 00 00 .t....t. ........ 0050 00 00 00 00 40 00 00 00 11 4d 40 77 cd ab ba dc ....@... .M@w.... 0060 aa e0 00 00 c4 f1 12 00 11 4d 40 77 f0 f1 12 00 ........ .M@w.... 0070 d9 8b 41 7e 00 e0 fd 7f f0 f1 12 00 5a 88 41 7e ..A~.... ....Z.A~ 0080 aa e0 00 00 2a 88 41 7e 06 04 00 00 11 4d 40 77 ....*.A~ .....M@w 0090 e8 f3 12 00 14 00 00 00 01 00 00 00 00 00 00 00 ........ ........ 00a0 aa df c0 75 00 ...u. */ /* CH341a READ EEPROM next packet for 24c64 (63 packets)*/ #define CH341_EEPROM_24c64_READ_NEXT_CMD "\xaa\x74\x83\xa0\x00\x00\x74\x81\xa1\xe0\x00\x00\x10\x00\x00\x00" \ "\x00\x00\x00\x00\x8c\xf1\x12\x00\x01\x00\x00\x00\x00\x00\x00\x00" \ "\xaa\xe0\x00\x00\x4c\xf1\x12\x00\x5d\x22\xd7\x5a\xdc\xf1\x12\x00" \ "\x8f\x04\x44\x7e\x30\x88\x41\x7e\xff\xff\xff\xff\x2a\x88\x41\x7e" \ "\xaa\xe0\x00\x7e\x00\x00\x00\x00\x69\x0e\x3c\x00\x12\x01\x19\x00" \ "\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\x2e\x68\x00" \ "\xaa\xdf\xc0\x75\x00" /* please see file /wiresharkusbsniffing/sniffed.txt this is the first read next packet for 24c64 (63 different packets) 0040 aa 74 83 a0 00 80 74 81 a1 e0 00 00 10 00 00 00 .t....t. ........ 0050 00 00 00 00 8c f1 12 00 01 00 00 00 00 00 00 00 ........ ........ 0060 aa e0 00 00 4c f1 12 00 5d 22 d7 5a dc f1 12 00 ....L... ]".Z.... 0070 8f 04 44 7e 30 88 41 7e ff ff ff ff 2a 88 41 7e ..D~0.A~ ....*.A~ 0080 aa e0 00 7e 00 00 00 00 69 0e 3c 00 3a 01 1b 00 ...~.... i.<.:... 0090 0f 00 00 00 00 00 00 00 00 00 00 00 8c e8 67 00 ........ ......g. 00a0 aa df c0 75 00 ...u. */ #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) #define TRUE 1 #define FALSE 0 struct EEPROM { char *name; uint32_t size; uint16_t page_size; uint8_t addr_size; // Length of addres in bytes uint8_t i2c_addr_mask; }; const static struct EEPROM eepromlist[] = { { "24c01", 128, 8, 1, 0x00}, // 16 pages of 8 bytes each = 128 bytes { "24c02", 256, 8, 1, 0x00}, // 32 pages of 8 bytes each = 256 bytes { "24c04", 512, 16, 1, 0x01}, // 32 pages of 16 bytes each = 512 bytes { "24c08", 1024, 16, 1, 0x03}, // 64 pages of 16 bytes each = 1024 bytes { "24c16", 2048, 16, 1, 0x07}, // 128 pages of 16 bytes each = 2048 bytes { "24c32", 4096, 32, 2, 0x00}, // 32kbit = 4kbyte { "24c64", 8192, 32, 2, 0x00}, { "24c128", 16384, 32/*64*/, 2, 0x00}, { "24c256", 32768, 32/*64*/, 2, 0x00}, { "24c512", 65536, 32/*128*/, 2, 0x00}, { "24c1024", 131072, 32/*128*/, 2, 0x01}, { 0, 0, 0, 0 } }; extern uint8_t *readbuf; int32_t ch341readEEPROM(struct libusb_device_handle *devHandle, uint8_t *buf, uint32_t bytes, struct EEPROM* eeprom_info); int32_t ch341writeEEPROM(struct libusb_device_handle *devHandle, uint8_t *buf, uint32_t bytes, struct EEPROM* eeprom_info); struct libusb_device_handle *ch341configure(uint16_t vid, uint16_t pid); int32_t ch341setstream(struct libusb_device_handle *devHandle, uint32_t speed); int32_t parseEEPsize(char* eepromname, struct EEPROM *eeprom); // callback functions for async USB transfers void cbBulkIn(struct libusb_transfer *transfer); void cbBulkOut(struct libusb_transfer *transfer); imsprog-1.8.5/IMSProg_programmer/ch347.c000066400000000000000000000262351520775651600177420ustar00rootroot00000000000000// SPDX-License-Identifier: BSD-1-Clause /* * Copyright (C) 2022 Chuanhong Guo * Copyright (C) 2026 Mikhail Medvedev * * CH347 SPI library using libusb. Protocol reverse-engineered from WCH linux library. * FIXME: Every numbers used in the USB protocol should be little-endian. */ #include "ch347.h" #include #include #include #include #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) #error You need to convert every USB communications to little endian before this library would work. #endif struct ch347_priv *priv = NULL; int ch347_spi_write_packet(struct ch347_priv *priv, uint8_t cmd, const void *tx, int len) { uint8_t *ptr; int cur_len; int err, transferred; if (len > CH347_SPI_MAX_TRX) return -EINVAL; priv->tmpbuf[0] = cmd; priv->tmpbuf[1] = len & 0xff; priv->tmpbuf[2] = len >> 8; cur_len = sizeof(priv->tmpbuf) - 3; if (len < cur_len) cur_len = len; memcpy(priv->tmpbuf + 3, tx, cur_len); err = libusb_bulk_transfer(priv->handle, CH347_EPOUT, priv->tmpbuf, cur_len + 3, &transferred, 1000); if (err) { fprintf(stderr, "ch347: libusb: failed to send packet: %d\n", err); return err; } if (cur_len < len) { /* This discards the const qualifier. However, libusb won't be writing to it. */ ptr = (uint8_t *) (tx + cur_len); err = libusb_bulk_transfer(priv->handle, CH347_EPOUT, ptr, len - cur_len, &transferred, 1000); if (err) { fprintf(stderr, "ch347: libusb: failed to send packet: %d\n", err); return err; } } return 0; } int ch347_spi_read_packet(struct ch347_priv *priv, uint8_t cmd, void *rx, int len, int *actual_len) { int cur_len, rxlen, rx_received; int err, transferred; err = libusb_bulk_transfer(priv->handle, CH347_EPIN, priv->tmpbuf, sizeof(priv->tmpbuf), &transferred, 1000); if (err) { fprintf(stderr, "ch347: libusb: failed to receive packet: %d\n", err); return err; } if (priv->tmpbuf[0] != cmd) { fprintf(stderr, "ch347: unexpected packet cmd: expecting 0x%02x but we got 0x%02x.\n", cmd, priv->tmpbuf[0]); return -EINVAL; } rxlen = priv->tmpbuf[1] | priv->tmpbuf[2] << 8; if (rxlen > len) { fprintf(stderr, "ch347: packet too big.\n"); return -EINVAL; } cur_len = transferred - 3; if (rxlen < cur_len) cur_len = rxlen; memcpy(rx, priv->tmpbuf + 3, cur_len); rx_received = cur_len; while (rx_received < rxlen) { /* The leftover data length is known so we don't need to deal with packet overflow using tmpbuf. */ err = libusb_bulk_transfer(priv->handle, CH347_EPIN, rx + rx_received, rxlen - rx_received, &transferred, 1000); if (err) { fprintf(stderr, "ch347: libusb: failed to receive packet: %d\n", err); return err; } rx_received += transferred; } *actual_len = rx_received; return 0; } int ch347_commit_settings(struct ch347_priv *priv) { int err, transferred; uint8_t unknown_data; err = ch347_spi_write_packet(priv, CH347_CMD_SPI_INIT, &priv->cfg, sizeof(priv->cfg)); if (err) return err; return ch347_spi_read_packet(priv, CH347_CMD_SPI_INIT, &unknown_data, 1, &transferred); } int ch347_get_hw_config(struct ch347_priv *priv) { int err, transferred; uint8_t unknown_data = 0x01; err = ch347_spi_write_packet(priv, CH347_CMD_INFO_RD, &unknown_data, 1); if (err) return err; err = ch347_spi_read_packet(priv, CH347_CMD_INFO_RD, &priv->cfg, sizeof(priv->cfg), &transferred); if (err) return err; if (transferred != sizeof(priv->cfg)) { fprintf(stderr, "ch347: config returned isn't long enough.\n"); return -EINVAL; } return 0; } int ch347_set_cs(struct ch347_priv *priv, int cs, int val) { uint8_t pkt_val = val ? 0xc0 : 0x80; uint8_t buf[10] = {}; if (cs) buf[5] = pkt_val; else buf[0] = pkt_val; return ch347_spi_write_packet(priv, CH347_CMD_SPI_CONTROL, buf, 10); } int ch347_set_spi_freq(struct ch347_priv *priv, int *clk_khz) { int freq = CH347_SPI_MAX_FREQ; int prescaler; for (prescaler = 0; prescaler < CH347_SPI_MAX_PRESCALER; prescaler++) { if (freq <= *clk_khz) break; freq /= 2; } if (freq > *clk_khz) return -EINVAL; priv->cfg.SPI_BaudRatePrescaler = prescaler * 8; *clk_khz = freq; return ch347_commit_settings(priv); } int ch347_setup_spi(struct ch347_priv *priv, int spi_mode, bool lsb_first, bool cs0_active_high, bool cs1_active_high) { priv->cfg.SPI_Direction = SPI_Direction_2Lines_FullDuplex; priv->cfg.SPI_Mode = SPI_Mode_Master; priv->cfg.SPI_DataSize = SPI_DataSize_8b; priv->cfg.SPI_CPOL = (spi_mode & 2) ? SPI_CPOL_High : SPI_CPOL_Low; priv->cfg.SPI_CPHA = (spi_mode & 1) ? SPI_CPHA_2Edge : SPI_CPHA_1Edge; priv->cfg.SPI_NSS = SPI_NSS_Software; priv->cfg.SPI_FirstBit = lsb_first ? SPI_FirstBit_LSB : SPI_FirstBit_MSB; priv->cfg.SPI_WriteReadInterval = 0; priv->cfg.SPI_OutDefaultData = 0; if (cs0_active_high) priv->cfg.OtherCfg |= 0x80; else priv->cfg.OtherCfg &= 0x7f; if (cs1_active_high) priv->cfg.OtherCfg |= 0x40; else priv->cfg.OtherCfg &= 0xbf; return ch347_commit_settings(priv); } static int ch347_spi_trx_full_duplex_one(struct ch347_priv *priv, void *buf, uint32_t len) { int err, transferred; err = ch347_spi_write_packet(priv, CH347_CMD_SPI_RD_WR, buf, len); if (err) return err; err = ch347_spi_read_packet(priv, CH347_CMD_SPI_RD_WR, buf, len, &transferred); if (err) return err; if (transferred != len) { fprintf(stderr, "ch347: not enough data received."); return -EINVAL; } return 0; } int ch347_spi_trx_full_duplex(struct ch347_priv *priv, void *buf, uint32_t len) { int err; while (len > CH347_SPI_MAX_TRX) { err = ch347_spi_trx_full_duplex_one(priv, buf, CH347_SPI_MAX_TRX); if (err) return err; len -= CH347_SPI_MAX_TRX; } return ch347_spi_trx_full_duplex_one(priv, buf, len); } int ch347_spi_tx(struct ch347_priv *priv, const void *tx, uint32_t len) { int err, transferred; uint8_t unknown_data; const void *ptr = tx; while (len) { int cur_len = len > CH347_SPI_MAX_TRX ? CH347_SPI_MAX_TRX : len; err = ch347_spi_write_packet(priv, CH347_CMD_SPI_BLCK_WR, ptr, cur_len); if (err) return err; err = ch347_spi_read_packet(priv, CH347_CMD_SPI_BLCK_WR, &unknown_data, 1, &transferred); if (err) return err; ptr += cur_len; len -= cur_len; } return 0; } int ch347_spi_rx(struct ch347_priv *priv, void *rx, uint32_t len) { int err, transferred; void *ptr = rx; uint32_t rxlen = 0; /* FIXME: len should be little endian! */ err = ch347_spi_write_packet(priv, CH347_CMD_SPI_BLCK_RD, &len, sizeof(len)); if (err) return err; while(rxlen < len) { uint32_t cur_rx = len - rxlen; if(cur_rx > CH347_SPI_MAX_TRX) cur_rx = CH347_SPI_MAX_TRX; err = ch347_spi_read_packet(priv, CH347_CMD_SPI_BLCK_RD, ptr, (int)cur_rx, &transferred); if (err) return err; rxlen += transferred; ptr += transferred; } return 0; } /* Set the I2C bus speed (speed(b1b0): 0 = 20kHz; 1 = 100kHz, 2 = 400kHz, 3 = 750kHz).*/ int32_t ch347setI2Cstream(uint32_t speed) { int32_t actuallen = 0; uint8_t buf[3]; buf[0] = mch347A_CMD_I2C_STREAM; buf[1] = mch347A_CMD_I2C_STM_SET | (speed & 0x3); buf[2] = mch347A_CMD_I2C_STM_END; int ret = libusb_bulk_transfer(priv->handle, BULK_WRITE_ENDPOINT, buf, 3, &actuallen, 3000); if (ret < 0) { fprintf(stderr, "ch347setstream(): Failed write %d bytes '%s'\n", 3, strerror(-ret)); return -1; } return 0; } int32_t ch347setSDAandSCLHighlevels() { int32_t actuallen = 0; uint8_t buf[3]; buf[0] = mch347A_CMD_I2C_STREAM; buf[1] = 0x12; buf[2] = mch347A_CMD_I2C_STM_END; int ret = libusb_bulk_transfer(priv->handle, BULK_WRITE_ENDPOINT, buf, 3, &actuallen, 3000); if (ret < 0) { fprintf(stderr, "ch347setstream(): Failed write %d bytes '%s'\n", 3, strerror(-ret)); return -1; } return 0; } struct ch347_priv *ch347_open() { struct ch347_priv *priv = calloc(1, sizeof(struct ch347_priv)); int ret; if (!priv) { fprintf(stderr, "ch347: faied to allocate memory.\n"); return NULL; } ret = libusb_init(&priv->ctx); if (ret < 0) { perror("ch347: libusb: init"); goto ERR_0; } #if LIBUSBX_API_VERSION >= 0x01000106 libusb_set_option(priv->ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO); #endif priv->handle = libusb_open_device_with_vid_pid(priv->ctx, CH347_SPI_VID, CH347_SPI_PID); if (!priv->handle) { perror("ch347: libusb: open"); goto ERR_1; } libusb_set_auto_detach_kernel_driver(priv->handle, 1); ret = libusb_claim_interface(priv->handle, CH347_SPI_IF); if (ret < 0) { perror("ch347: libusb: claim_if"); goto ERR_2; } if (ch347_get_hw_config(priv)) goto ERR_3; return priv; ERR_3: libusb_release_interface(priv->handle, CH347_SPI_IF); ERR_2: libusb_close(priv->handle); ERR_1: libusb_exit(priv->ctx); ERR_0: free(priv); return NULL; } void ch347_close(struct ch347_priv *priv) { libusb_release_interface(priv->handle, CH347_SPI_IF); libusb_close(priv->handle); libusb_exit(priv->ctx); free(priv); } bool ch347_spi_init(uint8_t ch_type, uint8_t i2cBusSpeed, bool version) { int ret; priv = ch347_open(); if (!priv) return 1; if (ch_type != 1) { ret = ch347_setup_spi(priv, 3, false, false, false); if (ret) return true; } int freq = 60000; //Speed in KHZ switch (ch_type) { case 0: //SPI NOR FLASH if (!version) freq = 30000; else freq = 15000; break; case 1: //24xxx I2C freq = 100; ch347setSDAandSCLHighlevels(); ch347setI2Cstream(i2cBusSpeed); break; case 2: //93xxx Microwire freq = 100; break; case 3: //25xxx case 4: //95xxx case 5: //45xxx DataFlash freq = 5000; break; case 6: if (!version) freq = 60000; else freq = 15000; break; default: freq = 60000; break; } if (ch_type != 1) ret = ch347_set_spi_freq(priv, &freq); return ret == 1; } void ch347_spi_shutdown() { if (!priv) return; ch347_close(priv); } int ch347GetDescriptor(uint8_t *buf) { int ret; ret = libusb_get_descriptor(priv->handle, LIBUSB_DT_DEVICE, 0x00, buf, 0x12); if(ret < 0) printf("Failed to get device descriptor: '%x'\n", ret); return ret; } imsprog-1.8.5/IMSProg_programmer/ch347.h000066400000000000000000000106031520775651600177370ustar00rootroot00000000000000// SPDX-License-Identifier: BSD-1-Clause /* * Copyright (C) 2022 Chuanhong Guo * Copyright (C) 2026 Mikhail Medvedev * * CH347 SPI library using libusb. Protocol reverse-engineered from WCH linux library. * FIXME: Every numbers used in the USB protocol should be little-endian. */ #ifndef CH347_H #define CH347_H #ifdef __cplusplus extern "C" { #endif #include #include #include #if defined(_WIN32) #include #include #define htobe16(x) htons(x) #define be16toh(x) ntohs(x) #define htobe32(x) htonl(x) #define be32toh(x) ntohl(x) #define htole16(x) (x) #define le16toh(x) (x) #define htole32(x) (x) #define le32toh(x) (x) #elif defined(__APPLE__) #include #else #include #endif #define CH347_SPI_VID 0x1a86 #define CH347_SPI_PID 0x55db #define CH347_SPI_IF 2 #define CH347_EPOUT (6 | LIBUSB_ENDPOINT_OUT) #define CH347_EPIN (6 | LIBUSB_ENDPOINT_IN) #define CH347_SPI_MAX_FREQ 60000 #define CH347_SPI_MAX_PRESCALER 7 #define CH347_SPI_MAX_TRX 507//4096- wrong data. 510 - 3 = 507 - correct value /* SPI_data_direction */ #define SPI_Direction_2Lines_FullDuplex 0x0000 #define SPI_Direction_2Lines_RxOnly 0x0400 #define SPI_Direction_1Line_Rx 0x8000 #define SPI_Direction_1Line_Tx 0xC000 /* SPI_mode */ #define SPI_Mode_Master 0x0104 #define SPI_Mode_Slave 0x0000 /* SPI_data_size */ #define SPI_DataSize_16b 0x0800 #define SPI_DataSize_8b 0x0000 /* SPI_Clock_Polarity */ #define SPI_CPOL_Low 0x0000 #define SPI_CPOL_High 0x0002 /* SPI_Clock_Phase */ #define SPI_CPHA_1Edge 0x0000 #define SPI_CPHA_2Edge 0x0001 /* SPI_Slave_Select_management */ #define SPI_NSS_Software 0x0200 #define SPI_NSS_Hardware 0x0000 /* SPI_MSB_LSB_transmission */ #define SPI_FirstBit_MSB 0x0000 #define SPI_FirstBit_LSB 0x0080 /* CH347 commands */ #define CH347_CMD_SPI_INIT 0xC0 #define CH347_CMD_SPI_CONTROL 0xC1 #define CH347_CMD_SPI_RD_WR 0xC2 #define CH347_CMD_SPI_BLCK_RD 0xC3 #define CH347_CMD_SPI_BLCK_WR 0xC4 #define CH347_CMD_INFO_RD 0xCA #define mch347A_CMD_I2C_STREAM 0xAA #define mch347A_CMD_I2C_STM_STA 0x74 #define mch347A_CMD_I2C_STM_STO 0x75 #define mch347A_CMD_I2C_STM_OUT 0x80 #define mch347A_CMD_I2C_STM_IN 0xC0 #define mch347A_CMD_I2C_STM_SET 0x60 #define mch347A_CMD_I2C_STM_END 0x00 #define BULK_WRITE_ENDPOINT 0x06 #define min(a,b) (((a)<(b))?(a):(b)) #define max(a,b) (((a)>(b))?(a):(b)) struct ch347_spi_hw_config { uint16_t SPI_Direction; uint16_t SPI_Mode; uint16_t SPI_DataSize; uint16_t SPI_CPOL; uint16_t SPI_CPHA; uint16_t SPI_NSS; /* hardware or software managed CS */ uint16_t SPI_BaudRatePrescaler; /* prescaler = x * 8. x: 0=60MHz, 1=30MHz, 2=15MHz, 3=7.5MHz, 4=3.75MHz, 5=1.875MHz, 6=937.5KHz, 7=468.75KHz */ uint16_t SPI_FirstBit; /* MSB or LSB first */ uint16_t SPI_CRCPolynomial; /* polynomial used for the CRC calculation. */ uint16_t SPI_WriteReadInterval; /* No idea what this is... Original comment from WCH: SPI接口常规读取写入数据命令(DEF_CMD_SPI_RD_WR)),单位为uS */ uint8_t SPI_OutDefaultData; /* Data to output on MOSI during SPI reading */ /* * Miscellaneous settings: * Bit 7: CS0 polarity * Bit 6: CS1 polarity * Bit 5: Enable I2C clock stretching * Bit 4: NACK on last I2C reading * Bit 3-0: reserved */ uint8_t OtherCfg; uint8_t Reserved[4]; }; struct ch347_priv { struct ch347_spi_hw_config cfg; libusb_context *ctx; libusb_device_handle *handle; uint8_t tmpbuf[510];//tmpbuf[509];//tmpbuf[8192]; // old - 512 }; struct ch347_priv *ch347_open(); void ch347_close(struct ch347_priv *priv); int ch347_commit_settings(struct ch347_priv *priv); int ch347_set_cs(struct ch347_priv *priv, int cs, int val); int ch347_set_spi_freq(struct ch347_priv *priv, int *clk_khz); int ch347_setup_spi(struct ch347_priv *priv, int spi_mode, bool lsb_first, bool cs0_active_high, bool cs1_active_high); int ch347_spi_trx_full_duplex(struct ch347_priv *priv, void *buf, uint32_t len); int ch347_spi_tx(struct ch347_priv *priv, const void *tx, uint32_t len); int ch347_spi_rx(struct ch347_priv *priv, void *rx, uint32_t len); bool ch347_spi_init(uint8_t ch_type, uint8_t i2cBusSpeed, bool version); void ch347_spi_shutdown(); int ch347GetDescriptor(uint8_t *buf); #ifdef __cplusplus } #endif #endif //CH347_H imsprog-1.8.5/IMSProg_programmer/ch34x_i2c.c000066400000000000000000000211041520775651600205660ustar00rootroot00000000000000// Programming tool for the 24Cxx serial EEPROMs using the Winchiphead ch34x IC // // (c) December 2011 asbokid // (c) December 2023 aystarik // (c) February 2026 Mikhail Medvedev // // 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 3 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, see . #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif #include #include #include #include "ch34x_i2c.h" #include "ch347.h" #include "ch341a_spi.h" //Initialise and close CH341A see in ch341a_spi.h, CH347 - in ch347.h extern struct libusb_device_handle *handle; extern struct ch347_priv *priv; struct xxx { uint8_t ibuf[512]; uint8_t obuf[512]; } i2c_buf; uint8_t progDev = 0; int ch34xdelay_ms(unsigned ms) { i2c_buf.obuf[0] = ch34x_CMD_I2C_STREAM; i2c_buf.obuf[1] = ch34x_CMD_I2C_STM_MS | (ms & 0xf); // Wait up to 15ms i2c_buf.obuf[2] = ch34x_CMD_I2C_STM_END; int actuallen = 0; if (progDev > 1) libusb_bulk_transfer(priv->handle, ch347_BULK_WRITE_ENDPOINT, i2c_buf.obuf, 3, &actuallen, DEFAULT_TIMEOUT); else libusb_bulk_transfer(handle, ch341_BULK_WRITE_ENDPOINT, i2c_buf.obuf, 3, &actuallen, DEFAULT_TIMEOUT); return 0; } int ch34xi2cBlockRead(uint8_t *buf, uint32_t address, uint32_t blockSize, uint8_t algorithm, uint8_t progDevice) { int ret; uint32_t step, maxstep; int32_t actuallen = 0; uint32_t size = blockSize; uint8_t deviceAddress = 0; uint8_t wordAddressLo = 0; uint8_t wordAddressHi = 0; progDev = progDevice; if ((progDev > 1) && (size > 64)) size = 64; if ((progDev < 2) && (size > 16)) size = 16; maxstep = blockSize / size; for (step = 0; step < maxstep; step++) { uint8_t *ptr = i2c_buf.obuf; *ptr++ = ch34x_CMD_I2C_STREAM; *ptr++ = ch34x_CMD_I2C_STM_STA; if ((algorithm & 0x0f) == 0x01) //1 byte address { *ptr++ = ch34x_CMD_I2C_STM_OUT | 2; deviceAddress = (uint8_t) ( ((((address & 0xff00) >> 8) & ((algorithm & 0xf0) >> 4)) << 1) | 0xa0); wordAddressLo = (uint8_t) (address & 0x00ff); *ptr++ = deviceAddress; *ptr++ = wordAddressLo; } if ((algorithm & 0x0f) == 0x02) //2 byte address { *ptr++ = ch34x_CMD_I2C_STM_OUT | 3; deviceAddress = (uint8_t) ( ((((address & 0xff0000) >> 16) & ((algorithm & 0xf0) >> 4)) << 1) | 0xa0); wordAddressLo = (uint8_t) (address & 0x00ff); wordAddressHi = (uint8_t) ((address & 0xff00) >> 8); *ptr++ = deviceAddress; *ptr++ = wordAddressHi; *ptr++ = wordAddressLo; } //device addr + read bit *ptr++ = ch34x_CMD_I2C_STM_STA; *ptr++ = ch34x_CMD_I2C_STM_OUT | 1; *ptr++ = deviceAddress | 0x01; *ptr++ = ch34x_CMD_I2C_STM_IN | ((uint8_t)(size - 1)); *ptr++ = ch34x_CMD_I2C_STM_IN; //last byte and end of packet *ptr++ = ch34x_CMD_I2C_STM_STO; *ptr++ = ch34x_CMD_I2C_STM_END; if (progDev > 1) ret = libusb_bulk_transfer(priv->handle, ch347_BULK_WRITE_ENDPOINT, i2c_buf.obuf, 15 , &actuallen, DEFAULT_TIMEOUT); else ret = libusb_bulk_transfer(handle, ch341_BULK_WRITE_ENDPOINT, i2c_buf.obuf, 15 , &actuallen, DEFAULT_TIMEOUT); if (ret < 0) { fprintf(stderr, "USB write error : %s\n", strerror(-ret)); return ret; } if (progDev > 1) ret = libusb_bulk_transfer(priv->handle, ch347_BULK_READ_ENDPOINT, i2c_buf.ibuf, blockSize + 4, &actuallen, DEFAULT_TIMEOUT); else ret = libusb_bulk_transfer(handle, ch341_BULK_READ_ENDPOINT, i2c_buf.ibuf, blockSize + 4, &actuallen, DEFAULT_TIMEOUT); if (ret < 0) { fprintf(stderr, "USB read error : %s\n", strerror(-ret)); return ret; } if (progDev > 1) { if ((algorithm & 0x0f) == 0x02) memcpy(&buf[step * size], &i2c_buf.ibuf[4], size); else memcpy(&buf[step * size], &i2c_buf.ibuf[3], size); } else memcpy(&buf[step * size], &i2c_buf.ibuf[0], size); address = address + size; ret = ch34xdelay_ms(10); if (ret < 0) { fprintf(stderr, "Failed to set timeout: '%s'\n", strerror(-ret)); return -1; } } return 0; } int ch34xi2cBlockWrite(uint8_t *buf, uint32_t address, uint32_t blockSize, uint32_t sectorSize, uint8_t algorithm, uint8_t progDevice) { int ret; int32_t actuallen = 0; uint32_t size = blockSize; uint32_t step, maxstep; uint8_t deviceAddress = 0; uint8_t wordAddressLo = 0; uint8_t wordAddressHi = 0; progDev = progDevice; if (size > sectorSize) size = sectorSize; if ((progDev < 2) && (size > 16)) size = 16; maxstep = blockSize / size; for (step = 0; step < maxstep; step++) { uint8_t *ptr = i2c_buf.obuf; *ptr++ = ch34x_CMD_I2C_STREAM; *ptr++ = ch34x_CMD_I2C_STM_STA; if ((algorithm & 0x0f) == 0x01) //1 byte address { *ptr++ = ch34x_CMD_I2C_STM_OUT | 2; deviceAddress = (uint8_t) ( ((((address & 0xff00) >> 8) & ((algorithm & 0xf0) >> 4)) << 1) | 0xa0); wordAddressLo = (uint8_t) (address & 0x00ff); *ptr++ = deviceAddress; *ptr++ = wordAddressLo; } if ((algorithm & 0x0f) == 0x02) //2 byte address { *ptr++ = ch34x_CMD_I2C_STM_OUT | 3; deviceAddress = (uint8_t) ( ((((address & 0xff0000) >> 16) & ((algorithm & 0xf0) >> 4)) << 1) | 0xa0); wordAddressLo = (uint8_t) (address & 0x00ff); wordAddressHi = (uint8_t) ((address & 0xff00) >> 8); *ptr++ = deviceAddress; *ptr++ = wordAddressHi; *ptr++ = wordAddressLo; } *ptr++ = ch34x_CMD_I2C_STM_OUT | ((uint8_t)(size )); for (uint32_t i = 0; i < size; i++) *ptr++ = buf[i + step * size]; *ptr++ = ch34x_CMD_I2C_STM_STO; *ptr++ = ch34x_CMD_I2C_STM_END; if (progDev > 1) ret = libusb_bulk_transfer(priv->handle, ch347_BULK_WRITE_ENDPOINT, i2c_buf.obuf, size + 12 , &actuallen, DEFAULT_TIMEOUT); else ret = libusb_bulk_transfer(handle, ch341_BULK_WRITE_ENDPOINT, i2c_buf.obuf, size + 12 , &actuallen, DEFAULT_TIMEOUT); if (ret < 0) { fprintf(stderr, "Failed to write to I2C: '%s'\n", strerror(-ret)); return ret; } if (progDev > 1) { if (progDev > 1) ret = libusb_bulk_transfer(priv->handle, ch347_BULK_READ_ENDPOINT, i2c_buf.ibuf, 512, &actuallen, DEFAULT_TIMEOUT); else ret = libusb_bulk_transfer(handle, ch341_BULK_WRITE_ENDPOINT, i2c_buf.obuf, size + 12 , &actuallen, DEFAULT_TIMEOUT); if (ret < 0) { fprintf(stderr, "Failed to write to I2C: '%s'\n", strerror(-ret)); return -1; } for (unsigned i = 0; i < actuallen; ++i) { if (i2c_buf.ibuf[i] != 0x01) { fprintf(stderr, "received NACK at %d", i); return -1; } } } ret = ch34xdelay_ms(10); if (ret < 0) { fprintf(stderr, "Failed to set timeout: '%s'\n", strerror(-ret)); return -1; } address = address + size; } return 0; } imsprog-1.8.5/IMSProg_programmer/ch34x_i2c.h000066400000000000000000000040161520775651600205760ustar00rootroot00000000000000// Programming tool for the 24Cxx serial EEPROMs using the Winchiphead ch34x IC // // (c) December 2011 asbokid // (c) December 2023 aystarik // (c) February 2026 Mikhail Medvedev // // 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 3 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, see . #ifndef __CH34x_I2C_H__ #define __CH34x_I2C_H__ #pragma once #include #include #define ch341_BULK_WRITE_ENDPOINT 0x02 /* bEndpointAddress 0x02 EP 2 OUT (Bulk) */ #define ch341_BULK_READ_ENDPOINT 0x82 /* bEndpointAddress 0x82 EP 2 IN (Bulk) */ #define ch347_BULK_WRITE_ENDPOINT 0x06 /* bEndpointAddress 0x02 EP 2 OUT (Bulk) */ #define ch347_BULK_READ_ENDPOINT 0x86 /* bEndpointAddress 0x82 EP 2 IN (Bulk) */ #define DEFAULT_TIMEOUT 3000 // 300mS for USB timeouts #define ch34x_CMD_I2C_STREAM 0xAA #define ch34x_CMD_I2C_STM_MS 0x50 #define ch34x_CMD_I2C_STM_STA 0x74 #define ch34x_CMD_I2C_STM_STO 0x75 #define ch34x_CMD_I2C_STM_OUT 0x80 #define ch34x_CMD_I2C_STM_IN 0xC0 #define ch34x_CMD_I2C_STM_SET 0x60 #define ch34x_CMD_I2C_STM_END 0x00 int ch34xi2cBlockRead(uint8_t * buf, uint32_t address, uint32_t blockSize, uint8_t algorithm, uint8_t progDevice); int ch34xi2cBlockWrite(uint8_t * buf, uint32_t address, uint32_t blockSize, uint32_t sectorSize, uint8_t algorithm, uint8_t progDevice); #endif /* __CH34x_I2C_H__ */ imsprog-1.8.5/IMSProg_programmer/chunks.cpp000066400000000000000000000222531520775651600207410ustar00rootroot00000000000000/* * QHexEdit is a Hex Editor Widget for the Qt Framework * Copyright (C) 2010-2025 Winfried Simon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * https://www.gnu.org/licenses/ */ #include "chunks.h" #include #define NORMAL 0 #define HIGHLIGHTED 1 #define BUFFER_SIZE 0x10000 #define CHUNK_SIZE 0x1000 #define READ_CHUNK_MASK Q_INT64_C(0xfffffffffffff000) // ***************************************** Constructors and file settings Chunks::Chunks(QObject *parent): QObject(parent) { QBuffer *buf = new QBuffer(this); setIODevice(*buf); } Chunks::Chunks(QIODevice &ioDevice, QObject *parent): QObject(parent) { setIODevice(ioDevice); } bool Chunks::setIODevice(QIODevice &ioDevice) { _ioDevice = &ioDevice; bool ok = _ioDevice->open(QIODevice::ReadOnly); if (ok) // Try to open IODevice { _size = _ioDevice->size(); _ioDevice->close(); } else // Fallback is an empty buffer { QBuffer *buf = new QBuffer(this); _ioDevice = buf; _size = 0; } _chunks.clear(); _pos = 0; return ok; } // ***************************************** Getting data out of Chunks QByteArray Chunks::data(qint64 pos, qint64 maxSize, QByteArray *highlighted) { qint64 ioDelta = 0; int chunkIdx = 0; Chunk chunk; QByteArray buffer; // Do some checks and some arrangements if (highlighted) highlighted->clear(); if (pos >= _size) return buffer; if (maxSize < 0) maxSize = _size; else if ((pos + maxSize) > _size) maxSize = _size - pos; _ioDevice->open(QIODevice::ReadOnly); while (maxSize > 0) { chunk.absPos = LLONG_MAX; bool chunksLoopOngoing = true; while ((chunkIdx < _chunks.count()) && chunksLoopOngoing) { // In this section, we track changes before our required data and // we take the editdet data, if availible. ioDelta is a difference // counter to justify the read pointer to the original data, if // data in between was deleted or inserted. chunk = _chunks[chunkIdx]; if (chunk.absPos > pos) chunksLoopOngoing = false; else { chunkIdx += 1; qint64 count; qint64 chunkOfs = pos - chunk.absPos; if (maxSize > ((qint64)chunk.data.size() - chunkOfs)) { count = (qint64)chunk.data.size() - chunkOfs; ioDelta += CHUNK_SIZE - chunk.data.size(); } else count = maxSize; if (count > 0) { buffer += chunk.data.mid(chunkOfs, (int)count); maxSize -= count; pos += count; if (highlighted) *highlighted += chunk.dataChanged.mid(chunkOfs, (int)count); } } } if ((maxSize > 0) && (pos < chunk.absPos)) { // In this section, we read data from the original source. This only will // happen, whe no copied data is available qint64 byteCount; QByteArray readBuffer; if ((chunk.absPos - pos) > maxSize) byteCount = maxSize; else byteCount = chunk.absPos - pos; maxSize -= byteCount; _ioDevice->seek(pos + ioDelta); readBuffer = _ioDevice->read(byteCount); buffer += readBuffer; if (highlighted) *highlighted += QByteArray(readBuffer.size(), NORMAL); pos += readBuffer.size(); } } _ioDevice->close(); return buffer; } bool Chunks::write(QIODevice &iODevice, qint64 pos, qint64 count) { if (count == -1) count = _size; bool ok = iODevice.open(QIODevice::WriteOnly); if (ok) { for (qint64 idx=pos; idx < count; idx += BUFFER_SIZE) { QByteArray ba = data(idx, BUFFER_SIZE); iODevice.write(ba); } iODevice.close(); } return ok; } // ***************************************** Set and get highlighting infos void Chunks::setDataChanged(qint64 pos, bool dataChanged) { if ((pos < 0) || (pos >= _size)) return; int chunkIdx = getChunkIndex(pos); qint64 posInBa = pos - _chunks[chunkIdx].absPos; _chunks[chunkIdx].dataChanged[(int)posInBa] = char(dataChanged); } bool Chunks::dataChanged(qint64 pos) { foreach (Chunk chunk, _chunks) { if (pos >= chunk.absPos && pos < (chunk.absPos + chunk.dataChanged.size())) { return bool(chunk.dataChanged.at(pos - chunk.absPos)); } } return false; } // ***************************************** Search API qint64 Chunks::indexOf(const QByteArray &ba, qint64 from) { qint64 result = -1; QByteArray buffer; for (qint64 pos=from; (pos < _size) && (result < 0); pos += BUFFER_SIZE) { buffer = data(pos, BUFFER_SIZE + ba.size() - 1); int findPos = buffer.indexOf(ba); if (findPos >= 0) result = pos + (qint64)findPos; } return result; } qint64 Chunks::lastIndexOf(const QByteArray &ba, qint64 from) { qint64 result = -1; QByteArray buffer; for (qint64 pos=from; (pos > 0) && (result < 0); pos -= BUFFER_SIZE) { qint64 sPos = pos - BUFFER_SIZE - (qint64)ba.size() + 1; if (sPos < 0) sPos = 0; buffer = data(sPos, pos - sPos); int findPos = buffer.lastIndexOf(ba); if (findPos >= 0) result = sPos + (qint64)findPos; } return result; } // ***************************************** Char manipulations bool Chunks::insert(qint64 pos, char b) { if ((pos < 0) || (pos > _size)) return false; int chunkIdx; if (pos == _size) chunkIdx = getChunkIndex(pos-1); else chunkIdx = getChunkIndex(pos); qint64 posInBa = pos - _chunks[chunkIdx].absPos; _chunks[chunkIdx].data.insert(posInBa, b); _chunks[chunkIdx].dataChanged.insert(posInBa, char(1)); for (int idx=chunkIdx+1; idx < _chunks.size(); idx++) _chunks[idx].absPos += 1; _size += 1; _pos = pos; return true; } bool Chunks::overwrite(qint64 pos, char b) { if ((pos < 0) || (pos >= _size)) return false; int chunkIdx = getChunkIndex(pos); qint64 posInBa = pos - _chunks[chunkIdx].absPos; _chunks[chunkIdx].data[(int)posInBa] = b; _chunks[chunkIdx].dataChanged[(int)posInBa] = char(1); _pos = pos; return true; } bool Chunks::removeAt(qint64 pos) { if ((pos < 0) || (pos >= _size)) return false; int chunkIdx = getChunkIndex(pos); qint64 posInBa = pos - _chunks[chunkIdx].absPos; _chunks[chunkIdx].data.remove(posInBa, 1); _chunks[chunkIdx].dataChanged.remove(posInBa, 1); for (int idx=chunkIdx+1; idx < _chunks.size(); idx++) _chunks[idx].absPos -= 1; _size -= 1; _pos = pos; return true; } // ***************************************** Utility functions char Chunks::operator[](qint64 pos) { return data(pos, 1).at(0); } qint64 Chunks::pos() { return _pos; } qint64 Chunks::size() { return _size; } int Chunks::getChunkIndex(qint64 absPos) { // This routine checks, if there is already a copied chunk available. If os, it // returns a reference to it. If there is no copied chunk available, original // data will be copied into a new chunk. int foundIdx = -1; int insertIdx = 0; qint64 ioDelta = 0; for (int idx=0; idx < _chunks.size(); idx++) { Chunk chunk = _chunks[idx]; if ((absPos >= chunk.absPos) && (absPos < (chunk.absPos + chunk.data.size()))) { foundIdx = idx; break; } if (absPos < chunk.absPos) { insertIdx = idx; break; } ioDelta += chunk.data.size() - CHUNK_SIZE; insertIdx = idx + 1; } if (foundIdx == -1) { Chunk newChunk; qint64 readAbsPos = absPos - ioDelta; qint64 readPos = (readAbsPos & READ_CHUNK_MASK); _ioDevice->open(QIODevice::ReadOnly); _ioDevice->seek(readPos); newChunk.data = _ioDevice->read(CHUNK_SIZE); _ioDevice->close(); newChunk.absPos = absPos - (readAbsPos - readPos); newChunk.dataChanged = QByteArray(newChunk.data.size(), char(0)); _chunks.insert(insertIdx, newChunk); foundIdx = insertIdx; } return foundIdx; } #ifdef MODUL_TEST int Chunks::chunkSize() { return _chunks.size(); } #endif imsprog-1.8.5/IMSProg_programmer/chunks.h000066400000000000000000000053351520775651600204100ustar00rootroot00000000000000/* * QHexEdit is a Hex Editor Widget for the Qt Framework * Copyright (C) 2010-2025 Winfried Simon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * https://www.gnu.org/licenses/ */ #ifndef CHUNKS_H #define CHUNKS_H /** \cond docNever */ /*! The Chunks class is the storage backend for QHexEdit. * * When QHexEdit loads data, Chunks access them using a QIODevice interface. When the app uses * a QByteArray interface, QBuffer is used to provide again a QIODevice like interface. No data * will be changed, therefore Chunks opens the QIODevice in QIODevice::ReadOnly mode. After every * access Chunks closes the QIODevice, that's why external applications can overwrite files while * QHexEdit shows them. * * When the the user starts to edit the data, Chunks creates a local copy of a chunk of data (4 * kilobytes) and notes all changes there. Parallel to that chunk, there is a second chunk, * which keep track of which bytes are changed and which not. * */ #include struct Chunk { QByteArray data; QByteArray dataChanged; qint64 absPos; }; class Chunks: public QObject { Q_OBJECT public: // Constructors and file settings Chunks(QObject *parent); Chunks(QIODevice &ioDevice, QObject *parent); bool setIODevice(QIODevice &ioDevice); // Getting data out of Chunks QByteArray data(qint64 pos=0, qint64 count=-1, QByteArray *highlighted=0); bool write(QIODevice &iODevice, qint64 pos=0, qint64 count=-1); // Set and get highlighting infos void setDataChanged(qint64 pos, bool dataChanged); bool dataChanged(qint64 pos); // Search API qint64 indexOf(const QByteArray &ba, qint64 from); qint64 lastIndexOf(const QByteArray &ba, qint64 from); // Char manipulations bool insert(qint64 pos, char b); bool overwrite(qint64 pos, char b); bool removeAt(qint64 pos); // Utility functions char operator[](qint64 pos); qint64 pos(); qint64 size(); private: int getChunkIndex(qint64 absPos); QIODevice * _ioDevice; qint64 _pos; qint64 _size; QList _chunks; #ifdef MODUL_TEST public: int chunkSize(); #endif }; /** \endcond docNever */ #endif // CHUNKS_H imsprog-1.8.5/IMSProg_programmer/color_manager.cpp000066400000000000000000000102111520775651600222450ustar00rootroot00000000000000/* * QHexEdit is a Hex Editor Widget for the Qt Framework * Copyright (C) 2010-2025 Winfried Simon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * https://www.gnu.org/licenses/ */ #include "color_manager.h" #include #include #include #include ColoredArea::ColoredArea() { _posStart = 0; _posEnd = 0; _fontColor = QPen(QColor::fromRgba(qRgba(0, 0, 0, 0))); _areaStyle = QColor::fromRgba(qRgba(0, 0, 0, 0)); } ColoredArea::ColoredArea(QPen pen, QBrush background) { _posStart = 0; _posEnd = 0; _fontColor = pen; _areaStyle = background; } ColoredArea::ColoredArea(qint64 posStart, qint64 posEnd, QPen pen, QBrush background) { _posStart = posStart; _posEnd = posEnd; _fontColor = pen; _areaStyle = background; } QPen ColoredArea::fontPen() { return _fontColor; } QColor ColoredArea::fontColor() { return _fontColor.color(); } void ColoredArea::setFontColor(QColor color) { _fontColor = QPen(color); } QColor ColoredArea::areaColor() { return _areaStyle.color(); } QBrush ColoredArea::areaStyle() { return _areaStyle; } void ColoredArea::setAreaColor(QColor color) { _areaStyle.setColor(color); } void ColoredArea::setAreaStyle(QBrush backround) { _areaStyle = backround; } qint64 ColoredArea::posStart() { return _posStart; }; qint64 ColoredArea::posEnd() { return _posEnd; }; void ColoredArea::setRange(qint64 posStart, qint64 posEnd) { _posStart = posStart; _posEnd = posEnd; }; void ColoredArea::clear() { _posStart = 0; _posEnd = 0; } /********************************************* */ ColorManager::ColorManager() { QPalette palette = qApp->palette(); setPalette(palette); }; void ColorManager::setPalette(const QPalette &palette) { _selection = ColoredArea(palette.highlightedText().color(), palette.highlight()); _highlighting = ColoredArea(QColor::fromRgb(0, 0, 0), QColor(0xff, 0xff, 0x99)); _address = ColoredArea(palette.windowText().color(), palette.alternateBase()); _hex = ColoredArea(palette.windowText().color(), palette.base()); _ascii = ColoredArea(palette.windowText().color(), palette.alternateBase()); } // read only, copy of relevant ColoredArea is returned: you can't change anything ColoredArea ColorManager::markedArea(qint64 pos, Area area, Chunks *chunks) { // prio 1 selection if (pos >= _selection.posStart() && pos < _selection.posEnd()) { return _selection; } // prio 2 highlighting (changed data) if (chunks->dataChanged(pos)) { return _highlighting; } // prio 3 user defined areas foreach (ColoredArea area, _userAreas) { if (pos >= area.posStart() && pos < area.posEnd()) { return area; } } // nothing found -> standard colors return this->notMarked(area); }; ColoredArea& ColorManager::notMarked(Area area) { switch (area) { case Area::Address: return _address; break; case Area::Ascii: return _ascii; break; case Area::Hex: return _hex; break; } return _hex; // should never happen } ColoredArea& ColorManager::selection() { return _selection; }; ColoredArea& ColorManager::highlighting() { return _highlighting; }; void ColorManager::addUserArea(qint64 posStart, qint64 posEnd, QColor fontColor, QBrush areaStyle) { ColoredArea userArea = ColoredArea(posStart, posEnd, fontColor, areaStyle); _userAreas.append(userArea); } void ColorManager::clearUserAreas() { _userAreas.clear(); }imsprog-1.8.5/IMSProg_programmer/color_manager.h000066400000000000000000000062271520775651600217260ustar00rootroot00000000000000/* * QHexEdit is a Hex Editor Widget for the Qt Framework * Copyright (C) 2010-2025 Winfried Simon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * https://www.gnu.org/licenses/ */ #ifndef COLOR_MANAGER_H #define COLOR_MANAGER_H /** \cond docNever */ /*! The ColorManager class is responsible for color management * * Color management is combined in this class. The definitions for pen and background colors * are stored here. * * This includes the standard colors for the address, hex data and ASCII data areas as well as * the colors for the marking information. The areas for selection and highlighting are defined * in advance. In addition, any number of user areas can be defined. * * The colors for a single area are provided by the ColoredArea class. */ #include #include #include "chunks.h" enum Area { Address, Hex, Ascii, }; class ColoredArea { public: // Cunstructors ColoredArea(); ColoredArea(QPen pen, QBrush background); ColoredArea(qint64 posStart, qint64 posEnd, QPen pen, QBrush background); // Property to set/get font color QColor fontColor(); void setFontColor(QColor color); // Property to set/get area style QColor areaColor(); QBrush areaStyle(); void setAreaColor(QColor color); void setAreaStyle(QBrush background); // other Methods to acces and set internal data QPen fontPen(); qint64 posStart(); qint64 posEnd(); void setRange(qint64 posStart, qint64 posEnd); void clear(); private: qint64 _posStart; qint64 _posEnd; QPen _fontColor; QBrush _areaStyle; }; class ColorManager { public: // Constructor including the definition of standard colors ColorManager(); // reload the palette and adapt the apeareance void setPalette(const QPalette &palette); // Method returns color definitions for data at position pos in area area ColoredArea markedArea(qint64 pos, Area area, Chunks *chunks); // Method returns standard collors (without marking) ColoredArea& notMarked(Area); // Get the selection color definitions ColoredArea& selection(); // Get the highlighting color definitions ColoredArea& highlighting(); // Add a user defined area void addUserArea(qint64 posStart, qint64 posEnd, QColor fontColor, QBrush areaStyle); // Clear all user defined areas void clearUserAreas(); private: ColoredArea _highlighting; ColoredArea _selection; ColoredArea _address; ColoredArea _hex; ColoredArea _ascii; QList _userAreas; }; /** \endcond docNever */ #endif // COLOR_MANAGER_Himsprog-1.8.5/IMSProg_programmer/commands.cpp000066400000000000000000000115451520775651600212510ustar00rootroot00000000000000/* * QHexEdit is a Hex Editor Widget for the Qt Framework * Copyright (C) 2010-2025 Winfried Simon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * https://www.gnu.org/licenses/ */ #include "commands.h" #include // Helper class to store single byte commands class CharCommand : public QUndoCommand { public: enum CCmd {insert, removeAt, overwrite}; CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar, QUndoCommand *parent=0); void undo(); void redo(); bool mergeWith(const QUndoCommand *command); int id() const { return 1234; } private: Chunks * _chunks; qint64 _charPos; bool _wasChanged; char _newChar; char _oldChar; CCmd _cmd; }; CharCommand::CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar, QUndoCommand *parent) : QUndoCommand(parent) , _chunks(chunks) , _charPos(charPos) , _wasChanged(false) , _newChar(newChar) , _oldChar('\0') , _cmd(cmd) { } bool CharCommand::mergeWith(const QUndoCommand *command) { const CharCommand *nextCommand = static_cast(command); bool result = false; if (_cmd != CharCommand::removeAt) { if (nextCommand->_cmd == overwrite) if (nextCommand->_charPos == _charPos) { _newChar = nextCommand->_newChar; result = true; } } return result; } void CharCommand::undo() { switch (_cmd) { case insert: _chunks->removeAt(_charPos); break; case overwrite: _chunks->overwrite(_charPos, _oldChar); _chunks->setDataChanged(_charPos, _wasChanged); break; case removeAt: _chunks->insert(_charPos, _oldChar); _chunks->setDataChanged(_charPos, _wasChanged); break; } } void CharCommand::redo() { switch (_cmd) { case insert: _chunks->insert(_charPos, _newChar); break; case overwrite: _oldChar = (*_chunks)[_charPos]; _wasChanged = _chunks->dataChanged(_charPos); _chunks->overwrite(_charPos, _newChar); break; case removeAt: _oldChar = (*_chunks)[_charPos]; _wasChanged = _chunks->dataChanged(_charPos); _chunks->removeAt(_charPos); break; } } UndoStack::UndoStack(Chunks * chunks, QObject * parent) : QUndoStack(parent) { _chunks = chunks; _parent = parent; this->setUndoLimit(1000); } void UndoStack::insert(qint64 pos, char c) { if ((pos >= 0) && (pos <= _chunks->size())) { QUndoCommand *cc = new CharCommand(_chunks, CharCommand::insert, pos, c); this->push(cc); } } void UndoStack::insert(qint64 pos, const QByteArray &ba) { if ((pos >= 0) && (pos <= _chunks->size())) { QString txt = QString(tr("Inserting %1 bytes")).arg(ba.size()); beginMacro(txt); for (int idx=0; idx < ba.size(); idx++) { QUndoCommand *cc = new CharCommand(_chunks, CharCommand::insert, pos + idx, ba.at(idx)); this->push(cc); } endMacro(); } } void UndoStack::removeAt(qint64 pos, qint64 len) { if ((pos >= 0) && (pos < _chunks->size())) { if (len==1) { QUndoCommand *cc = new CharCommand(_chunks, CharCommand::removeAt, pos, char(0)); this->push(cc); } else { QString txt = QString(tr("Delete %1 chars")).arg(len); beginMacro(txt); for (qint64 cnt=0; cnt= 0) && (pos < _chunks->size())) { QUndoCommand *cc = new CharCommand(_chunks, CharCommand::overwrite, pos, c); this->push(cc); } } void UndoStack::overwrite(qint64 pos, int len, const QByteArray &ba) { if ((pos >= 0) && (pos < _chunks->size())) { QString txt = QString(tr("Overwrite %1 chars")).arg(len); beginMacro(txt); removeAt(pos, len); insert(pos, ba); endMacro(); } } imsprog-1.8.5/IMSProg_programmer/commands.h000066400000000000000000000042221520775651600207100ustar00rootroot00000000000000/* * QHexEdit is a Hex Editor Widget for the Qt Framework * Copyright (C) 2010-2025 Winfried Simon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * https://www.gnu.org/licenses/ */ #ifndef COMMANDS_H #define COMMANDS_H /** \cond docNever */ #include #include "chunks.h" /*! CharCommand is a class to provid undo/redo functionality in QHexEdit. A QUndoCommand represents a single editing action on a document. CharCommand is responsable for manipulations on single chars. It can insert. overwrite and remove characters. A manipulation stores allways two actions 1. redo (or do) action 2. undo action. CharCommand also supports command compression via mergeWith(). This enables the user to perform an undo command e.g. 3 steps in a single command. If you for example insert a new byt "34" this means for the editor doing 3 steps: insert a "00", overwrite it with "03" and the overwrite it with "34". These 3 steps are combined into a single step, insert a "34". The byte array oriented commands are just put into a set of single byte commands, which are pooled together with the macroBegin() and macroEnd() functionality of Qt's QUndoStack. */ class UndoStack : public QUndoStack { Q_OBJECT public: UndoStack(Chunks *chunks, QObject * parent=0); void insert(qint64 pos, char c); void insert(qint64 pos, const QByteArray &ba); void removeAt(qint64 pos, qint64 len=1); void overwrite(qint64 pos, char c); void overwrite(qint64 pos, int len, const QByteArray &ba); private: Chunks * _chunks; QObject * _parent; }; /** \endcond docNever */ #endif // COMMANDS_H imsprog-1.8.5/IMSProg_programmer/database/000077500000000000000000000000001520775651600205025ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_programmer/database/IMSProg.Dat000066400000000000000000001540701520775651600224230ustar00rootroot00000000000000SPI_FLASH,SPANSION,FL016AIF @SPI_FLASH,SPANSION,S25FL016P @SPI_FLASH,SPANSION,S25FL032P@@SPI_FLASH,SPANSION,FL064AIF@SPI_FLASH,SPANSION,S25FL064P@SPI_FLASH,SPANSION,S25FL256S !@SPI_FLASH,SPANSION,S25FL128P @SPI_FLASH,SPANSION,S25FL129P @SPI_FLASH,SPANSION,S25FL204K@@SPI_FLASH,SPANSION,S25FL208K@@SPI_FLASH,SPANSION,S25FL116K@ @SPI_FLASH,SPANSION,S25FL132K@@@SPI_FLASH,SPANSION,S25FL164K@@SPI_FLASH,XTX,XT25F02E@ @SPI_FLASH,XTX,XT25F04D@ @SPI_FLASH,XTX,XT25F08B@ @SPI_FLASH,XTX,XT25F16B@ @SPI_FLASH,XTX,XT25F32F@ @ @SPI_FLASH,XTX,XT25F64F@ @SPI_FLASH,XTX,XT25F128F@ @SPI_FLASH,XTX,XT25F256B@ @SPI_FLASH,XTX,XT25W02E` @SPI_FLASH,XTX,XT25W04D` @SPI_FLASH,XTX,XT25Q08D(1.8V)` @SPI_FLASH,XTX,XT25Q16D(1.8V)` @SPI_FLASH,XTX,XT25Q64D(1.8V)` @SPI_FLASH,XTX,XT25F128D(1.8V)` @SPI_FLASH,XTX,XT25Q512F(1.8V)` @SPI_FLASH,XTX,XT25W08Fe @SPI_FLASH,XTX,XT25W16Fe @SPI_FLASH,XTX,XT25W32Fe @ @SPI_FLASH,ACE,ACE25AC512G@@SPI_FLASH,ACE,ACE25AC100G@@SPI_FLASH,ACE,ACE25AC200G@@SPI_FLASH,ACE,ACE25AC400G@@SPI_FLASH,EON,EN25B10T @SPI_FLASH,EON,EN25B20T @SPI_FLASH,EON,EN25B40T @SPI_FLASH,EON,EN25B80T @SPI_FLASH,EON,EN25B16T  @SPI_FLASH,EON,EN25B32T @@SPI_FLASH,EON,EN25B64T @SPI_FLASH,EON,EN25P64 @SPI_FLASH,EON,EN25Q40A0@SPI_FLASH,EON,EN25Q80B0@SPI_FLASH,EON,EN25Q160 @SPI_FLASH,EON,EN25Q32C0@@SPI_FLASH,EON,EN25Q640@SPI_FLASH,EON,EN25Q1280@SPI_FLASH,EON,EN25F10A1@SPI_FLASH,EON,EN25F20A1@SPI_FLASH,EON,EN25F401@SPI_FLASH,EON,EN25F801@SPI_FLASH,EON,EN25F161 @SPI_FLASH,EON,EN25F321@@SPI_FLASH,EON,EN25S10A(1.8V)8@SPI_FLASH,EON,EN25S20A(1.8V)8@SPI_FLASH,EON,EN25S40A(1.8V)8@SPI_FLASH,EON,EN25S80B(1.8V)8@SPI_FLASH,EON,EN25S16B(1.8V)8 @SPI_FLASH,EON,EN25S64A(1.8V)8@SPI_FLASH,CXF,GM25Q64A@@SPI_FLASH,CXF,GM25Q128A@@SPI_FLASH,EON,EN25QE16AA @SPI_FLASH,EON,EN25QE32AA@@SPI_FLASH,EON,EN25E10AB@SPI_FLASH,EON,EN25E40AB@SPI_FLASH,EON,EN25SE16A(1.8V)H @SPI_FLASH,EON,EN25SE32A(1.8V)H@@SPI_FLASH,EON,EN25T80Q@SPI_FLASH,EON,EN25T16Q @SPI_FLASH,EON,EN25QA32B`@@SPI_FLASH,EON,EN25QA64A`@SPI_FLASH,EON,EN25QA128A`@SPI_FLASH,EON,EN25QW16Aa @SPI_FLASH,EON,EN25QW32Aa@@SPI_FLASH,EON,EN25QH16p @SPI_FLASH,EON,EN25QH32Bp@@SPI_FLASH,EON,EN25QH64Ap@SPI_FLASH,EON,EN25QH128Ap@SPI_FLASH,EON,EN25Q256p@SPI_FLASH,EON,EN25QX64Aq@SPI_FLASH,EON,EN25QX128Aq@SPI_FLASH,EON,EN25QX256Aq@SPI_FLASH,EON,EN25QY256As@SPI_FLASH,EON,EN25SX64A(1.8V)x@SPI_FLASH,EON,EN25SX128A(1.8V)x@SPI_FLASH,EON,EN25SX256A(1.8V)x@SPI_FLASH,ATMEL,AT25SL321(1.8V)B@@SPI_FLASH,ATMEL,AT25SL128A(1.8V)B@SPI_FLASH,ATMEL,AT25SL641(1.8V)C@SPI_FLASH,ATMEL,AT25DF081AE@SPI_FLASH,ATMEL,AT26DF161F @SPI_FLASH,ATMEL,AT25DF321G@@SPI_FLASH,ATMEL,AT25DF641H@SPI_FLASH,MICRON,M25P10 @SPI_FLASH,MICRON,M25P20 @SPI_FLASH,MICRON,M25P40 @SPI_FLASH,MICRON,M25P80 @SPI_FLASH,MICRON,M25P016 @SPI_FLASH,MICRON,M25P32 @@SPI_FLASH,MICRON,M25P64 @SPI_FLASH,MICRON,M25P128 @SPI_FLASH,XMC,XM25QH10B@ @SPI_FLASH,XMC,XM25QH20B@ @SPI_FLASH,XMC,XM25QH40B@ @SPI_FLASH,XMC,XM25QH80B@ @SPI_FLASH,XMC,XM25QH16C@ @SPI_FLASH,XMC,XM25QH32B@ @@SPI_FLASH,XMC,XM25QH64C@ @SPI_FLASH,XMC,XM25QH128C@ @SPI_FLASH,XMC,XM25QH256C@ @SPI_FLASH,XMC,XM25QH512C @ @SPI_FLASH,XMC,XM25LU64C(1.8V)A @SPI_FLASH,XMC,XM25LU128C(1.8V)A @SPI_FLASH,XMC,XM25QU256C(1.8V)A @SPI_FLASH,XMC,XM25QU512C(1.8V) A @SPI_FLASH,XMC,XM25QW16CB @SPI_FLASH,XMC,XM25QW32CB @@SPI_FLASH,XMC,XM25QW64CB @SPI_FLASH,XMC,XM25QW128CB @SPI_FLASH,XMC,XM25QW256CB @SPI_FLASH,XMC,XM25QW512C B @SPI_FLASH,XMC,XM25QU41B(1.8V)P @SPI_FLASH,XMC,XM25QU80B(1.8V)P @SPI_FLASH,XMC,XM25QU16C(1.8V)P @SPI_FLASH,XMC,XM25LU32C(1.8V)P @@SPI_FLASH,XMC,XM25QH32Ap @@SPI_FLASH,XMC,XM25QH64Ap @SPI_FLASH,XMC,XM25QH128Ap @SPI_FLASH,MICRON,N25Q032A @@SPI_FLASH,MICRON,N25Q064A @SPI_FLASH,MICRON,MT25QL64AB @SPI_FLASH,MICRON,N25Q128A @SPI_FLASH,MICRON,MT25QL128AB @SPI_FLASH,MICRON,N25Q256A @SPI_FLASH,MICRON,MT25QL256AB @SPI_FLASH,MICRON,MT25QL512AB @SPI_FLASH,MICRON,N25Q016A11E(1.8V) @SPI_FLASH,MICRON,N25Q032A(1.8V) @@SPI_FLASH,MICRON,N25Q064A(1.8V) @SPI_FLASH,MICRON,MT25QU64AB(1.8V) @SPI_FLASH,MICRON,N25Q128A(1.8V) @SPI_FLASH,MICRON,MT25QU128AB(1.8V) @SPI_FLASH,MICRON,MT25QU256AB(1.8V) @SPI_FLASH,MICRON,MT25QU512AB(1.8V) @SPI_FLASH,AMIC,A25L05P 7@SPI_FLASH,AMIC,A25L10PU 7@SPI_FLASH,AMIC,A25L20PU 7@SPI_FLASH,AMIC,A25L40PU 7@SPI_FLASH,AMIC,A25L80PU 7@SPI_FLASH,AMIC,A25L16PU 7 @SPI_FLASH,AMIC,A25L10PT! 7@SPI_FLASH,AMIC,A25L20PT" 7@SPI_FLASH,AMIC,A25L40PT" 7@SPI_FLASH,AMIC,A25L80PT$ 7@SPI_FLASH,AMIC,A25L16PT% 7 @SPI_FLASH,AMIC,A25L01007@SPI_FLASH,AMIC,A25L02007@SPI_FLASH,AMIC,A25L04007@SPI_FLASH,AMIC,A25L04007@SPI_FLASH,AMIC,A25L08007@SPI_FLASH,AMIC,A25L01607 @SPI_FLASH,AMIC,A25L03207@@SPI_FLASH,AMIC,A25LQ080@7@SPI_FLASH,AMIC,A25LQ16@7 @SPI_FLASH,AMIC,A25LQ32@7@@SPI_FLASH,AMIC,A25LQ64@7@SPI_FLASH,EXCELSEMI,ES25P10 J@SPI_FLASH,EXCELSEMI,ES25P20 J@SPI_FLASH,EXCELSEMI,ES25P40 J@SPI_FLASH,EXCELSEMI,ES25P80 J @SPI_FLASH,EXCELSEMI,ES25P16 J@@SPI_FLASH,EXCELSEMI,ES25P32 J@SPI_FLASH,EXCELSEMI,ES25M40A2J@SPI_FLASH,EXCELSEMI,ES25M80A2J @SPI_FLASH,EXCELSEMI,ES25M16A2J@@SPI_FLASH,DOUQI,DQ25Q64AS@T@SPI_FLASH,Zbit,ZB25LD10A(1.8V)^@SPI_FLASH,Zbit,ZB25LD20A(1.8V)^@SPI_FLASH,Zbit,ZB25LD40B(1.8V)^@SPI_FLASH,Zbit,ZB25LD80(1.8V)^@SPI_FLASH,Zbit,ZB25D10A2^@SPI_FLASH,Zbit,ZB25D20A2^@SPI_FLASH,Zbit,ZB25D40B2^@SPI_FLASH,Zbit,ZB25D80B2^@SPI_FLASH,Zbit,ZB25WQ16A4^ @SPI_FLASH,Zbit,ZB25VQ16@^ @SPI_FLASH,Zbit,ZB25VQ32@^@@SPI_FLASH,Zbit,ZB25VQ64@^@SPI_FLASH,Zbit,ZB25VQ128@^@SPI_FLASH,Zbit,ZB25Q256A@^@SPI_FLASH,Zbit,ZB25LQ16(1.8V)P^ @SPI_FLASH,Zbit,ZB25LQ32(1.8V)P^@@SPI_FLASH,Zbit,ZB25LQ64(1.8V)P^@SPI_FLASH,Zbit,ZB25LQ128(1.8V)P^@SPI_FLASH,Zbit,ZB25VQ20A`^@SPI_FLASH,Zbit,ZB25VQ40A`^@SPI_FLASH,Zbit,ZB25VQ80A`^@SPI_FLASH,Zbit,ZB25VQ16A`^ @SPI_FLASH,ONSemi,LE25U20AMBb@SPI_FLASH,ONSemi,LE25U40CMCb@SPI_FLASH,Boya,BY25Q05AWh@SPI_FLASH,Boya,BY25Q10AWh@SPI_FLASH,Boya,BY25Q20BL(1.8V)h@SPI_FLASH,Boya,BY25Q40BLh@SPI_FLASH,Boya,BY25Q80AW(1.8V)h@SPI_FLASH,Boya,BY25Q16BL(1.8V)h @SPI_FLASH,Boya,BY25D05AS@h@SPI_FLASH,Boya,BY25D10AS@h@SPI_FLASH,Boya,BY25D20AS@h@SPI_FLASH,Boya,BY25D40AS@h@SPI_FLASH,Boya,BY25Q80BS@h@SPI_FLASH,Boya,BY25Q16BS@h @SPI_FLASH,Boya,BY25Q32BS@h@@SPI_FLASH,Boya,BY25Q64AS@h@SPI_FLASH,Boya,BY25Q128AS@h@SPI_FLASH,Boya,BY25Q256ES@h@SPI_FLASH,Boya,BY25Q128FSAh@SPI_FLASH,Boya,BY25Q256FSIh@SPI_FLASH,Boya,BY25Q10AL(1.8V)`h@SPI_FLASH,Boya,BY25Q20AL(1.8V)`h@SPI_FLASH,Boya,BY25Q40AL(1.8V)`h@SPI_FLASH,Boya,BY25Q32AL(1.8V)`h@@SPI_FLASH,Boya,BY25Q64AL(1.8V)`h@SPI_FLASH,Boya,BY25Q128EL(1.8V)`h@SPI_FLASH,PFLASH,Pm25LQ512B @SPI_FLASH,PFLASH,Pm25LQ010B!@SPI_FLASH,PFLASH,Pm25LD020"@SPI_FLASH,PFLASH,Pm25LQ020BB@SPI_FLASH,PFLASH,PM25LQ016E @SPI_FLASH,PFLASH,PM25LQ032F@@SPI_FLASH,PFLASH,PM25LQ064G@SPI_FLASH,PFLASH,PM25LQ128H@SPI_FLASH,PFLASH,Pm25LV010|@SPI_FLASH,PFLASH,Pm25LV020}@SPI_FLASH,PFLASH,Pm25LQ040B~@SPI_FLASH,PFLASH,Pm25LV040~@SPI_FLASH,Puya,P25Q06H@SPI_FLASH,Puya,P25Q40H @SPI_FLASH,Puya,PY25Q128HA @SPI_FLASH,Puya,PY25Q256HB @SPI_FLASH,Puya,PY25Q512HB @SPI_FLASH,Puya,P25Q11H@@SPI_FLASH,Puya,P25Q21H@@SPI_FLASH,Puya,P25Q10H`@SPI_FLASH,Puya,P25Q20H`@SPI_FLASH,Puya,P25Q40H`@SPI_FLASH,Puya,P25Q80H`@SPI_FLASH,Puya,P25Q16H` @SPI_FLASH,Puya,P25Q32H`@@SPI_FLASH,Puya,P25Q64H`@SPI_FLASH,Puya,P25Q128H`@SPI_FLASH,ESMT,F25L004A @SPI_FLASH,ESMT,F25L008A @SPI_FLASH,ESMT,F25L32PA @@SPI_FLASH,ESMT,F25L016! @SPI_FLASH,ESMT,F25L032!@@SPI_FLASH,ESMT,F25L064!@SPI_FLASH,ESMT,F25L16QAA @SPI_FLASH,ESMT,F25L32QAA@@SPI_FLASH,ESMT,F25L64QAA@SPI_FLASH,ISSI,IS25WQ020(1.8V)R@SPI_FLASH,ISSI,IS25WQ040(1.8V)S@SPI_FLASH,ISSI,IS25WQ080(1.8V)T@SPI_FLASH,ISSI,IS25LQ010@@SPI_FLASH,ISSI,IS25LQ020@@SPI_FLASH,ISSI,IS25LP040E@@SPI_FLASH,ISSI,IS25LP080D`@SPI_FLASH,ISSI,IS25LP016D` @SPI_FLASH,ISSI,IS25LP032D`@@SPI_FLASH,ISSI,IS25LP064D`@SPI_FLASH,ISSI,IS25LP128F`@SPI_FLASH,ISSI,IS25LP256D`!@SPI_FLASH,ISSI,IS25LP512D`!@SPI_FLASH,ISSI,IS25WP512E(1.8V)p@SPI_FLASH,ISSI,IS25WP010E(1.8V)p@SPI_FLASH,ISSI,IS25WP020E(1.8V)p@SPI_FLASH,ISSI,IS25WP040D(1.8V)p@SPI_FLASH,ISSI,IS25WP080D(1.8V)p@SPI_FLASH,ISSI,IS25WP016D(1.8V)p @SPI_FLASH,ISSI,IS25WP032D(1.8V)p@@SPI_FLASH,ISSI,IS25WP064D(1.8V)p@SPI_FLASH,ISSI,IS25WP128F(1.8V)p@SPI_FLASH,ISSI,IS25WP256D(1.8V)p!@SPI_FLASH,ISSI,IS25WP512D(1.8V)p!@SPI_FLASH,Fudan,FM25W02( @SPI_FLASH,Fudan,FM25W04( @SPI_FLASH,Fudan,FM25W16(  @SPI_FLASH,Fudan,FM25W32(@ @SPI_FLASH,Fudan,FM25W64( @SPI_FLASH,Fudan,FM25W128(@SPI_FLASH,Fudan,FM25F0051@SPI_FLASH,Fudan,FM25F01B1@SPI_FLASH,Fudan,FM25F02A1@SPI_FLASH,Fudan,FM25F04A1@SPI_FLASH,Fudan,FM25Q04@@SPI_FLASH,Fudan,FM25Q08@@SPI_FLASH,Fudan,FM25Q16@ @SPI_FLASH,Fudan,FS25Q32@@@SPI_FLASH,Fudan,FM25Q64@@SPI_FLASH,Fudan,FM25Q128@ @SPI_FLASH,UCUNDATA,UC25IQ128@@SPI_FLASH,UCUNDATA,UC25HQ05`@SPI_FLASH,UCUNDATA,UC25HQ10`@SPI_FLASH,UCUNDATA,UC25HQ20`@SPI_FLASH,UCUNDATA,UC25HQ40`@SPI_FLASH,UCUNDATA,UC25HQ80`@SPI_FLASH,UCUNDATA,UC25HQ16` @SPI_FLASH,UCUNDATA,UC25HQ32`@@SPI_FLASH,UCUNDATA,UC25HQ64`@SPI_FLASH,Zetta,ZD25D20 @SPI_FLASH,Zetta,ZD25D40 @SPI_FLASH,Zetta,ZD25D80 @SPI_FLASH,Zetta,ZD25Q64B2@SPI_FLASH,Zetta,ZD25WQ80C@@SPI_FLASH,Zetta,ZD25Q128C@@SPI_FLASH,Zetta,ZD25LQ128(1.8V)B@SPI_FLASH,Zetta,ZD25LQ64(1.8V)C@SPI_FLASH,Zetta,ZD25WD20B`@SPI_FLASH,Zetta,ZD25WD40B`@SPI_FLASH,Zetta,ZD25Q80C`@SPI_FLASH,Zetta,ZD25Q16B` @SPI_FLASH,Zetta,ZD25Q32C`@@SPI_FLASH,PCT,PCT25VF016BA% @SPI_FLASH,PCT,PCT25VF032BJ%@@SPI_FLASH,PCT,PCT25VF064CK%@SPI_FLASH,PCT,PCT25VF020B%@SPI_FLASH,PCT,PCT25VF040B%@SPI_FLASH,PCT,PCT25VF080B%@SPI_FLASH,PCT,PCT26VF016& @SPI_FLASH,PCT,PCT26VF032&@@SPI_FLASH,PCT,PCT25VF010AI@SPI_FLASH,MXIC,MX25L512E @SPI_FLASH,MXIC,MX25L1006E @SPI_FLASH,MXIC,MX25L2005 @SPI_FLASH,MXIC,MX25L4005A @SPI_FLASH,MXIC,MX25L8005M @SPI_FLASH,MXIC,MX25L1605D @SPI_FLASH,MXIC,MX25L3205D @@SPI_FLASH,MXIC,MX25L6405D @SPI_FLASH,MXIC,MX25L12805D @SPI_FLASH,MXIC,MX25L25635E @SPI_FLASH,MXIC,MX25L51245G @SPI_FLASH,MXIC,MX25L5121E"@SPI_FLASH,MXIC,MX25L1021E"@SPI_FLASH,MXIC,MX25V8035F#@SPI_FLASH,MXIC,MX25L1633E$ @SPI_FLASH,MXIC,MX25L1635E% @SPI_FLASH,MXIC,MX25U5121E(1.8V)0%@SPI_FLASH,MXIC,MX25U1001E(1.8V)1%@SPI_FLASH,MXIC,MX25U2035F(1.8V)2%@SPI_FLASH,MXIC,MX25U4035F(1.8V)3%@SPI_FLASH,MXIC,MX25U80356(1.8V)4%@SPI_FLASH,MXIC,MX25U1632F(1.8V)5% @SPI_FLASH,MXIC,MX25U3232F(1.8V)6%@@SPI_FLASH,MXIC,MX25U6432F(1.8V)7%@SPI_FLASH,MXIC,MX25U12832F(1.8V)8%@SPI_FLASH,MXIC,MX25U25643G(1.8V)9%@SPI_FLASH,MXIC,MX25U51245G(1.8V):%@SPI_FLASH,MXIC,MX25L1655D& @SPI_FLASH,MXIC,MX25L6455E&@SPI_FLASH,MXIC,MX25L12855E&@SPI_FLASH,MXIC,MX25L25655E&@SPI_FLASH,MXIC,MX25R512F(@SPI_FLASH,MXIC,MX25R1035F(@SPI_FLASH,MXIC,MX25R2035F(@SPI_FLASH,MXIC,MX25R4035F(@SPI_FLASH,MXIC,MX25R8035F(@SPI_FLASH,MXIC,MX25R1635F( @SPI_FLASH,MXIC,MX25R3235F(@@SPI_FLASH,MXIC,MX25R6435F(@SPI_FLASH,MXIC,MX25L3225D^@@SPI_FLASH,MXIC,MX25L3255D@@SPI_FLASH,GIANTEC,GT25D05C@@SPI_FLASH,GIANTEC,GT25D10C@@SPI_FLASH,GIANTEC,GT25D20C@@SPI_FLASH,GIANTEC,GT25Q40C@@SPI_FLASH,GIANTEC,GT25D05E`@SPI_FLASH,GIANTEC,GT25D10E`@SPI_FLASH,GIANTEC,GT25D20E`@SPI_FLASH,GIANTEC,GT25Q80A`@SPI_FLASH,GIANTEC,GT25Q16A` @SPI_FLASH,GIANTEC,GT25Q32A-H`@@SPI_FLASH,GIANTEC,GT25Q64A-S`@SPI_FLASH,GigaDevice,GD25F40 @SPI_FLASH,GigaDevice,GD25F80 @SPI_FLASH,GigaDevice,GD25D400@SPI_FLASH,GigaDevice,GD25D800@SPI_FLASH,GigaDevice,GD25D05C@@SPI_FLASH,GigaDevice,GD25D10C@@SPI_FLASH,GigaDevice,GD25Q20C@@SPI_FLASH,GigaDevice,GD25Q40C@@SPI_FLASH,GigaDevice,GD25Q80C@@SPI_FLASH,GigaDevice,GD25Q16C@ @SPI_FLASH,GigaDevice,GD25Q32@@@SPI_FLASH,GigaDevice,GD25Q64CSIG@@SPI_FLASH,GigaDevice,GD25Q128CSIG@@SPI_FLASH,GigaDevice,GD25Q256CSIG@@SPI_FLASH,GigaDevice,GD25VQ21BB@SPI_FLASH,GigaDevice,GD25VQ40CB@SPI_FLASH,GigaDevice,GD25VQ80CB@SPI_FLASH,GigaDevice,GD25VQ16CB @SPI_FLASH,GigaDevice,GD25B512MEG@SPI_FLASH,GigaDevice,GD25LD05C(1.8V)`@SPI_FLASH,GigaDevice,GD25LD10C(1.8V)`@SPI_FLASH,GigaDevice,GD25LD20C(1.8V)`@SPI_FLASH,GigaDevice,GD25LD40C(1.8V)`@SPI_FLASH,GigaDevice,GD25LQ80C`@SPI_FLASH,GigaDevice,GD25LQ16C` @SPI_FLASH,GigaDevice,GD25LQ32E`@@SPI_FLASH,GigaDevice,GD25LQ64E(1.8V)`@SPI_FLASH,GigaDevice,GD25LQ128(1.8V)`@SPI_FLASH,GigaDevice,GD25LQ256D(1.8V)` @SPI_FLASH,GigaDevice,GD25LR512MF(1.8V)`@SPI_FLASH,GigaDevice,GD25WD05Cd@SPI_FLASH,GigaDevice,GD25WD10Cd@SPI_FLASH,GigaDevice,GD25WD20Ed @SPI_FLASH,GigaDevice,GD25WD40Ed @SPI_FLASH,GigaDevice,GD25WD80Cd@SPI_FLASH,GigaDevice,GD25WQ20Ee@SPI_FLASH,GigaDevice,GD25WQ40Ee@SPI_FLASH,GigaDevice,GD25WQ80Ee@SPI_FLASH,GigaDevice,GD25WQ16Ee @SPI_FLASH,GigaDevice,GD25WQ32Ee@@SPI_FLASH,GigaDevice,GD25WQ64Ee@SPI_FLASH,GigaDevice,GD25WQ128Ee@SPI_FLASH,GigaDevice,GD25WB256Ee@SPI_FLASH,GigaDevice,GD25LT256E(1.8V)f@SPI_FLASH,GigaDevice,GD25LT512ME(1.8V)f@SPI_FLASH,GigaDevice,GD25LB512ME(1.8V)g@SPI_FLASH,NANTRONIX,N25S800@SPI_FLASH,NANTRONIX,N25S320@@SPI_FLASH,YUCHUANG,YC25Q40@@SPI_FLASH,YUCHUANG,YC25Q80@@SPI_FLASH,YUCHUANG,YC25Q16@ @SPI_FLASH,YUCHUANG,YC25Q32@@@SPI_FLASH,YUCHUANG,YC25Q64@@SPI_FLASH,YUCHUANG,YC25Q128@@SPI_FLASH,PARAGON ,PN25F08@@SPI_FLASH,PARAGON ,PN25F16@ @SPI_FLASH,PARAGON ,PN25F32@@@SPI_FLASH,PARAGON ,PN25F64@@SPI_FLASH,PARAGON ,PN25F128@@SPI_FLASH,DOSILICON,DS25Q64A1@SPI_FLASH,DOSILICON,DS25Q4AA1@SPI_FLASH,DOSILICON,DS25M4CB(1.8V)@@SPI_FLASH,DOSILICON,DS25M64E(1.8V)A@SPI_FLASH,DOSILICON,DS25M4AE(1.8V)A@SPI_FLASH,DOSILICON,DS25M4AB(1.8V)B@SPI_FLASH,DOSILICON,DS25M4BA(1.8V)B@SPI_FLASH,WINBOND,W25P80 @SPI_FLASH,WINBOND,W25P16 @SPI_FLASH,WINBOND,W25P32 @@SPI_FLASH,WINBOND,W25P64 @SPI_FLASH,WINBOND,W25X050@SPI_FLASH,WINBOND,W25X100@SPI_FLASH,WINBOND,W25X200@SPI_FLASH,WINBOND,W25X400@SPI_FLASH,WINBOND,W25X800@SPI_FLASH,WINBOND,W25X160 @SPI_FLASH,WINBOND,W25X32VS0@@SPI_FLASH,WINBOND,W25X640@SPI_FLASH,WINBOND,W25Q05CL@@SPI_FLASH,WINBOND,W25Q10CL@@SPI_FLASH,WINBOND,W25Q20CL@ @SPI_FLASH,WINBOND,W25Q40BV@@SPI_FLASH,WINBOND,W25Q80BL@@SPI_FLASH,WINBOND,W25Q16DV@ @SPI_FLASH,WINBOND,W25Q32BV@@@SPI_FLASH,WINBOND,W25Q64BV@@SPI_FLASH,WINBOND,W25Q128BV@@SPI_FLASH,WINBOND,W25Q256FV@@SPI_FLASH,WINBOND,W25Q20BW(1.8V)P @SPI_FLASH,WINBOND,W25Q40BW(1.8V)P @SPI_FLASH,WINBOND,W25Q80P@SPI_FLASH,WINBOND,W25Q10EW(1.8V)`@SPI_FLASH,WINBOND,W25Q20EW(1.8V)`@SPI_FLASH,WINBOND,W25Q40EW(1.8V)`@SPI_FLASH,WINBOND,W25Q80EW(1.8V)`@SPI_FLASH,WINBOND,W25Q16JW(1.8V)` @SPI_FLASH,WINBOND,W25Q32FW(1.8V)`@@SPI_FLASH,WINBOND,W25Q64DW(1.8V)` @SPI_FLASH,WINBOND,W25Q128FW(1.8V)`@SPI_FLASH,WINBOND,W25Q256JW(1.8V)`@SPI_FLASH,WINBOND,W25M512JW(1.8V)a@SPI_FLASH,WINBOND,W25Q512JV p@SPI_FLASH,WINBOND,W25M512JVq@SPI_FLASH,WINBOND,W25Q32JW(1.8V)@@SPI_FLASH,WINBOND,W25Q512NW(1.8V) @SPI_FLASH,Fidelix,FM25Q04A2@SPI_FLASH,Fidelix,FM25Q08A2@SPI_FLASH,Fidelix,FM25Q16A2 @SPI_FLASH,Fidelix,FM25Q32A2@@SPI_FLASH,Fidelix,FM25Q64A2@SPI_FLASH,Fidelix,FM25Q128A2@SPI_FLASH,Fidelix,FM25M04A(1.8V)B@SPI_FLASH,Fidelix,FM25M08A(1.8V)B@SPI_FLASH,Fidelix,FM25M16A(1.8V)B @SPI_FLASH,Fidelix,FM25M32A(1.8V)B@@SPI_FLASH,Fidelix,FM25M64A(1.8V)B@SPI_FLASH,Fidelix,FM25M4AA(1.8V)B@SPI_NAND,XTX,XT26G01C   SPI_NAND,XTX,XT26G02C   SPI_NAND,XTX,XT26G11C   SPI_NAND,XTX,XT26G01D 1  !SPI_NAND,XTX,XT26G02D 2  !SPI_NAND,XTX,XT26G11D 4  !SPI_NAND,XTX,XT26G12D-B 5  !SPI_NAND,XTX,XT26Q01D(1.8V) Q  !SPI_NAND,XTX,XT26Q02D(1.8V) R  !SPI_NAND,XTX,XT26Q04D S  !SPI_NAND,XTX,XT26Q14D(1.8V) V  !SPI_NAND,XTX,XT26G01A  SPI_NAND,ESMT,F50L2G41XA,$,"SPI_NAND,ESMT,F50L4G41XB,4, "SPI_NAND,MICRON,MT29F4G01ABBFD12(1.8V),5, "SPI_NAND,MICRON,MT29F4G01ABAFD12,6, "SPI_NAND,Zetta,ZD35Q1GC-IBqSPI_NAND,MXIC,MX35LF1GE4AB$SPI_NAND,MXIC,MX35LF1G24AD-Z41$SPI_NAND,MXIC,MX35LF2G24AD-Z41$$SPI_NAND,MXIC,MX35LF2GE4AD&$SPI_NAND,MXIC,MX35LF4G24AD-Z415 $SPI_NAND,MXIC,MX35LF4GE4AD7 $SPI_NAND,MXIC,MX35LF2G24AD-Z418d$SPI_NAND,MXIC,MX35LF4G24AD-Z418u $SPI_NAND,MXIC,MX35UF1G14AC(1.8V)$SPI_NAND,MXIC,MX35UF1GE4AC(1.8V)$SPI_NAND,MXIC,MX35UF1G24AD-Z4I(1.8V)$SPI_NAND,MXIC,MX35UF1GE4AD(1.8V)$SPI_NAND,MXIC,MX35UF2G14AC(1.8V) $SPI_NAND,MXIC,MX35UF2GE4AC(1.8V)$SPI_NAND,MXIC,MX35UF2G24AD-Z4I(1.8V)$SPI_NAND,MXIC,MX35UF2GE4AD(1.8V)$SPI_NAND,MXIC,MX35UF4G24AD-Z4I(1.8V) $SPI_NAND,MXIC,MX35UF4GE4AD(1.8V) $SPI_NAND,MXIC,MX35UF2G24AD-Z4I8(1.8V)$SPI_NAND,MXIC,MX35UF4G24AD-Z4I8(1.8V) $SPI_NAND,ESMT,F50L1G41LB(2M)#SPI_NAND,ESMT,F50L512M41A!SPI_NAND,GigaDevice,GD5F1GQ5RExxG(1.8V)ASPI_NAND,GigaDevice,GD5F2GQ5RExxG(1.8V)BSPI_NAND,GigaDevice,GD5F4GQ6RExxG(1.8V)E SPI_NAND,GigaDevice,GD5F1GQ5UExxGQSPI_NAND,GigaDevice,GD5F2GQ5UExxGRSPI_NAND,GigaDevice,GD5F4GQ6UExxGU SPI_NAND,GigaDevice,GD5F1GM7RExxG(1.8V)ȁ"SPI_NAND,GigaDevice,GD5F1GM9RExxG(1.8V)"SPI_NAND,GigaDevice,GD5F2GM7RExxG(1.8V)Ȃ"SPI_NAND,GigaDevice,GD5F4GM8RExxG(1.8V)ȅ "SPI_NAND,GigaDevice,GD5F1GM7UExxGȑ"SPI_NAND,GigaDevice,GD5F1GM9UExxG"SPI_NAND,GigaDevice,GD5F2GM7UExxGȒ"SPI_NAND,GigaDevice,GD5F4GM8UExxGȕ "SPI_NAND,GigaDevice,GD5F1GQ4RFxxG(1.8V)HSPI_NAND,GigaDevice,GD5F1GQ4RFxxS(1.8V)HSPI_NAND,GigaDevice,GD5F1GQ4UFxxGHSPI_NAND,GigaDevice,GD5F1GQ4UFxxSHSPI_NAND,GigaDevice,GD5F1GQ4RExxG(1.8V)SPI_NAND,GigaDevice,GD5F2GQ4RExxG(1.8V)SPI_NAND,GigaDevice,GD5F1GQ4UExxGSPI_NAND,GigaDevice,GD5F2GQ4UExxGSPI_NAND,GigaDevice,GD5F1GQ4UAxxGSPI_NAND,FORESEE,F35SQB004GSS %SPI_NAND,FORESEE,F35UQA002G(1.8V)bb%SPI_NAND,FORESEE,F35SQA512Mpp%SPI_NAND,FORESEE,F35SQA001Gqq%SPI_NAND,FORESEE,F35SQA002Grr%SPI_NAND,DOSILICON,DS35M1GA(1.8V)! $SPI_NAND,DOSILICON,DS35M2GA(1.8V)" $SPI_NAND,DOSILICON,DS35M12C(1.8V)% $SPI_NAND,DOSILICON,DS35M2GBS(1.8V)b $SPI_NAND,DOSILICON,DS35M4GB(1.8V)d  $SPI_NAND,DOSILICON,DS35Q1GAq $SPI_NAND,DOSILICON,DS35Q2GAr $SPI_NAND,DOSILICON,DS35Q12Cu $SPI_NAND,DOSILICON,DS35M1GB(1.8V) $SPI_NAND,DOSILICON,DS35M2GB(1.8V) $SPI_NAND,DOSILICON,DS35Q4GM(1.8V)  $SPI_NAND,DOSILICON,DS35M12B(1.8V) $SPI_NAND,DOSILICON,DS35Q2GBS $SPI_NAND,DOSILICON,DS35Q4GB  $SPI_NAND,DOSILICON,DS35Q1GB $SPI_NAND,DOSILICON,DS35Q2GB $SPI_NAND,DOSILICON,DS35Q4GM  $SPI_NAND,DOSILICON,DS35Q12B $SPI_NAND,WINBOND,W25N512GV "SPI_NAND,WINBOND,W25N01GV!"SPI_NAND,WINBOND,W25N02KV""SPI_NAND,WINBOND,W25N04KV# "SPI_NAND,WINBOND,W25N01KV!"SPI_NAND,WINBOND,W25N04LW(1.8V)#  "SPI_NAND,WINBOND,W25N512GW(1.8V) "SPI_NAND,WINBOND,W25N01GW(1.8V)!"SPI_NAND,WINBOND,W25N02KW(1.8V)""SPI_NAND,WINBOND,W25N04KW(1.8V)# "SPI_NAND,WINBOND,W25N01JW(1.8V)!"SPI_NAND,WINBOND,W25N01KW(1.8V)!"SPI_NAND,WINBOND,W25N02JW(1.8V)" "24_EEPROM,ATMEL,AT24C0124_EEPROM,ATMEL,AT24C0224_EEPROM,ATMEL,AT24C0424_EEPROM,ATMEL,AT24C08124_EEPROM,ATMEL,AT24C16q24_EEPROM,ATMEL,AT24C32 24_EEPROM,ATMEL,AT24C64 24_EEPROM,ATMEL,AT24C128@ 24_EEPROM,ATMEL,AT24C256 24_EEPROM,ATMEL,AT24C512 24_EEPROM,ATMEL,AT24C1024 24_EEPROM,ATMEL,AT24CM02 224_EEPROM,MICROCHIP,24C0124_EEPROM,MICROCHIP,24C0224_EEPROM,MICROCHIP,24C0424_EEPROM,MICROCHIP,24C08124_EEPROM,MICROCHIP,24C16q24_EEPROM,MICROCHIP,24C32 24_EEPROM,MICROCHIP,24C64 24_EEPROM,MICROCHIP,24C128@ 24_EEPROM,MICROCHIP,24C256 24_EEPROM,MICROCHIP,24C512 24_EEPROM,MICROCHIP,24C1024 24_EEPROM,COMMON,24C0124_EEPROM,COMMON,24C0224_EEPROM,COMMON,24C0424_EEPROM,COMMON,24C08124_EEPROM,COMMON,24C16q24_EEPROM,COMMON,24C32 24_EEPROM,COMMON,24C64 24_EEPROM,COMMON,24C128@ 24_EEPROM,COMMON,24C256 24_EEPROM,COMMON,24C512 24_EEPROM,COMMON,24C1024 24_EEPROM,ST,M24C0124_EEPROM,ST,M24C0224_EEPROM,ST,M24C0424_EEPROM,ST,M24C08124_EEPROM,ST,M24C16q24_EEPROM,ST,M24C32 24_EEPROM,ST,M24C64 24_EEPROM,ST,M24C128@ 24_EEPROM,ST,M24C256 24_EEPROM,ST,M24C512 24_EEPROM,ST,M24C1024 24_EEPROM,ISSI,IS24C0124_EEPROM,ISSI,IS24C0224_EEPROM,ISSI,IS24C0424_EEPROM,ISSI,IS24C08124_EEPROM,ISSI,IS24C16q24_EEPROM,ISSI,IS24C32 24_EEPROM,ISSI,IS24C64 24_EEPROM,ISSI,IS24C128@ 24_EEPROM,ISSI,IS24C256 24_EEPROM,ISSI,IS24C512 24_EEPROM,ISSI,IS24C1024 24_EEPROM,HOLTEK,HT24C0124_EEPROM,HOLTEK,HT24C0224_EEPROM,HOLTEK,HT24C0424_EEPROM,HOLTEK,HT24C08124_EEPROM,HOLTEK,HT24C16q24_EEPROM,HOLTEK,HT24C32 24_EEPROM,HOLTEK,HT24C64 24_EEPROM,HOLTEK,HT24C128@ 24_EEPROM,HOLTEK,HT24C256 24_EEPROM,HOLTEK,HT24C512 24_EEPROM,HOLTEK,HT24C1024 24_EEPROM,RAMXEED,MB85RC0424_EEPROM,RAMXEED,MB85RC16q24_EEPROM,RAMXEED,MB85RC64 24_EEPROM,RAMXEED,MB85RC128@ 24_EEPROM,RAMXEED,MB85RC256 24_EEPROM,RAMXEED,MB85RC512 24_EEPROM,RAMXEED,MB85RC1MT 24_EEPROM,RAMTRON,FM24C04A24_EEPROM,RAMTRON,FM24C16Aq24_EEPROM,RAMTRON,FM24C32A 24_EEPROM,RAMTRON,FM24C64A 24_EEPROM,RAMTRON,FM24C128@ 24_EEPROM,RAMTRON,FM24C256 24_EEPROM,RAMTRON,FM24C512 24_EEPROM,RAMTRON,FM24CL04A24_EEPROM,RAMTRON,FM24CL16Aq24_EEPROM,RAMTRON,FM24CL32A 24_EEPROM,RAMTRON,FM24CL64A 93_EEPROM,HOLTEK,HT93LC46(x16)93_EEPROM,HOLTEK,HT93LC56(x16)93_EEPROM,HOLTEK,HT93LC66(x16)93_EEPROM,HOLTEK,HT93LC76(x16)93_EEPROM,HOLTEK,HT93LC86(x16)93_EEPROM,HOLTEK,HT93LC86(x8)93_EEPROM,ATMEL,AT93C46(16)93_EEPROM,ATMEL,AT93C56(16)93_EEPROM,ATMEL,AT93C66(16)93_EEPROM,ATMEL,AT93C76(16)93_EEPROM,ATMEL,AT93C86(16)93_EEPROM,ST,ST93C46(16)93_EEPROM,ST,ST93C56(16)93_EEPROM,ST,ST93C66(16)93_EEPROM,ST,ST93C76(16)93_EEPROM,ST,ST93C86(16)93_EEPROM,EXEL,EX93C46(16)93_EEPROM,EXEL,EX93C56(16)93_EEPROM,EXEL,EX93C66(16)93_EEPROM,EXEL,EX93C76(16)93_EEPROM,EXEL,EX93C86(16)93_EEPROM,MICROCHIP,93C46(16)93_EEPROM,MICROCHIP,93C56(16)93_EEPROM,MICROCHIP,93C66(16)93_EEPROM,MICROCHIP,93C76(16)93_EEPROM,MICROCHIP,93C86(16)93_EEPROM,CATALYST,CAT93C46(16)93_EEPROM,CATALYST,CAT93C56(16)93_EEPROM,CATALYST,CAT93C66(16)93_EEPROM,CATALYST,CAT93C76(16)93_EEPROM,CATALYST,CAT93C86(16)93_EEPROM,ISSI,IS93C46(16)93_EEPROM,ISSI,IS93C56(16)93_EEPROM,ISSI,IS93C66(16)93_EEPROM,ISSI,IS93C76(16)93_EEPROM,ISSI,IS93C86(16)95_EEPROM,ST,M9501095_EEPROM,ST,M9502095_EEPROM,ST,M9504095_EEPROM,ST,M95080 95_EEPROM,ST,M95160 95_EEPROM,ST,M95320 95_EEPROM,ST,M95640 95_EEPROM,ST,M95128@@95_EEPROM,ST,M95256@95_EEPROM,ST,M9551295_EEPROM,ST,M95M0195_EEPROM,ST,M95M0225_EEPROM,ATMEL,AT2501025_EEPROM,ATMEL,AT2502025_EEPROM,ATMEL,AT2504025_EEPROM,ATMEL,AT25080 25_EEPROM,ATMEL,AT25160 25_EEPROM,ATMEL,AT25320 25_EEPROM,ATMEL,AT25640 25_EEPROM,ATMEL,AT25128@@25_EEPROM,ATMEL,AT25256@25_EEPROM,ATMEL,AT25F512"25_EEPROM,ATMEL,AT25F1024"25_EEPROM,ATMEL,AT25F2048"25_EEPROM,ATMEL,AT25F4096"25_EEPROM,MICROCHIP,25AA01025_EEPROM,MICROCHIP,25AA02025_EEPROM,MICROCHIP,25AA04025_EEPROM,MICROCHIP,25AA080 25_EEPROM,MICROCHIP,25AA160 25_EEPROM,MICROCHIP,25AA320 25_EEPROM,MICROCHIP,25AA640 25_EEPROM,MICROCHIP,25AA128@@25_EEPROM,MICROCHIP,25AA256@25_EEPROM,MICROCHIP,25AAF512!25_EEPROM,MICROCHIP,25AAF1024"25_EEPROM,MICROCHIP,25LC01025_EEPROM,MICROCHIP,25LC02025_EEPROM,MICROCHIP,25LC04025_EEPROM,MICROCHIP,25LC080 25_EEPROM,MICROCHIP,25LC160 25_EEPROM,MICROCHIP,25LC320 25_EEPROM,MICROCHIP,25LC640 25_EEPROM,MICROCHIP,25LC128@@25_EEPROM,MICROCHIP,25LC256@25_EEPROM,MICROCHIP,25LC512!25_EEPROM,MICROCHIP,25LC1024"25_EEPROM,ONSEMI,CAT25C0125_EEPROM,ONSEMI,CAT25C0225_EEPROM,ONSEMI,CAT25C0425_EEPROM,ONSEMI,CAT25C08 25_EEPROM,ONSEMI,CAT25C16 25_EEPROM,ONSEMI,CAT25C32 25_EEPROM,ONSEMI,CAT25C64 25_EEPROM,ONSEMI,CAT25C128@@25_EEPROM,ONSEMI,CAT25C256@25_EEPROM,ONSEMI,CAT25C51225_EEPROM,SANYO,LE25LA322 25_EEPROM,SANYO,LE25LA642 25_EEPROM,SANYO,LE25LB1282@@25_EEPROM,SANYO,LE25LB2562@25_EEPROM,SANYO,LE25CB512225_EEPROM,RAMXEED,MB85RS16N  25_EEPROM,RAMXEED,MB85RD16LX!@25_EEPROM,RAMXEED,MB85RS64VY # 25_EEPROM,RAMXEED,MB85RS64V  25_EEPROM,RAMXEED,MB85RS128TY $@25_EEPROM,RAMXEED,MB85RS128B @25_EEPROM,RAMXEED,MB85RS256TY %25_EEPROM,RAMXEED,MB85RS256LYA E25_EEPROM,RAMXEED,MB85RS256B 25_EEPROM,RAMXEED,MB85RS512TY F25_EEPROM,RAMXEED,MB85RS512LY E25_EEPROM,RAMXEED,MS85RS1MLY G25_EEPROM,RAMXEED,MB85RS1MT '25_EEPROM,RAMXEED,MB85RS2MTY H25_EEPROM,RAMXEED,MB85RS2MLY H25_EEPROM,RAMXEED,MB85RS4MTY I25_EEPROM,RAMXEED,MB85RS4MLY I45_EEPROM,ATMEL,AT45DB011 45_EEPROM,ATMEL,AT45DB021  45_EEPROM,ATMEL,AT45DB041@ 45_EEPROM,ATMEL,AT45DB081 45_EEPROM,ATMEL,AT45DB161! 45_EEPROM,ATMEL,AT45DB321B 45_EEPROM,ADESTO,AT45DB011"45_EEPROM,ADESTO,AT45DB021# 45_EEPROM,ADESTO,AT45DB041$@45_EEPROM,ADESTO,AT45DB081%45_EEPROM,ADESTO,AT45DB161&!45_EEPROM,ADESTO,AT45DB321'B45_EEPROM,ADESTO,AT45DB641(imsprog-1.8.5/IMSProg_programmer/dialogabout.cpp000066400000000000000000000022201520775651600217300ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2026 Mikhail Medvedev * * * 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 3 * 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. */ #include "dialogabout.h" #include "ui_dialogabout.h" DialogAbout::DialogAbout(QWidget *parent) : QDialog(parent), ui(new Ui::DialogAbout) { ui->setupUi(this); setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); ui->label_7->setTextFormat(Qt::RichText); ui->label_7->setTextInteractionFlags(Qt::TextBrowserInteraction); ui->label_7->setOpenExternalLinks(true); ui->label_8->setText("V1.8.5"); } DialogAbout::~DialogAbout() { delete ui; } void DialogAbout::on_pushButton_clicked() { DialogAbout::close(); } imsprog-1.8.5/IMSProg_programmer/dialogabout.h000066400000000000000000000016441520775651600214060ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2024 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef DIALOGABOUT_H #define DIALOGABOUT_H #include namespace Ui { class DialogAbout; } class DialogAbout : public QDialog { Q_OBJECT public: explicit DialogAbout(QWidget *parent = nullptr); ~DialogAbout(); private slots: void on_pushButton_clicked(); private: Ui::DialogAbout *ui; }; #endif // DIALOGABOUT_H imsprog-1.8.5/IMSProg_programmer/dialogabout.ui000066400000000000000000000140271520775651600215730ustar00rootroot00000000000000 DialogAbout 0 0 555 440 About IMSProg :/res/img/write64.png:/res/img/write64.png IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341A and CH347T devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. true :/res/img/ch341_green150.png OR Qt::AlignCenter :/res/img/ch341_black150.png OR Qt::AlignCenter :/res/img/ch341v1_7.png <html><head/><body><p>In this program <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget and modified programmer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> were used.</p><p>The page on GitHub is <a href="https://github.com/bigbigmdm/IMSProg">here</a>, the support page is <a href="https://antenna-dvb-t2.ru/IMSProg.php">here</a>. </p></body></html> true Qt::Vertical 20 112 Written by 2023 - 2026 Mikhail Medvedev 90 0 90 16777215 Version: 1.1.4 Qt::Horizontal 40 20 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Close imsprog-1.8.5/IMSProg_programmer/dialogbbm.cpp000066400000000000000000000163631520775651600213730ustar00rootroot00000000000000/* * Copyright (C) 2025 Mikhail Medvedev * * * 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 3 * 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. */ #include "dialogbbm.h" #include "ui_dialogbbm.h" #include "mainwindow.h" #include "hexutility.h" #include #include #include DialogBBM::DialogBBM(QWidget *parent) : QDialog(parent), ui(new Ui::DialogBBM) { ui->setupUi(this); setWindowFlags(Qt::Window| Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); ui->tableWidgetBBM->setShowGrid(true); ui->tableWidgetScan->setShowGrid(true); ui->tableWidgetScan->horizontalHeader()->setStretchLastSection(true); ui->tableWidgetScan->verticalHeader()->setVisible(false); ui->tableWidgetScan->setColumnCount(4); ui->tableWidgetScan->setRowCount(1); ui->progressBar->setRange(0, 1024); ui->progressBar->setValue(0); programmerType = 0; } DialogBBM::~DialogBBM() { delete ui; } void DialogBBM::on_pushButton_clicked() { bool scanResult = false; int i, stCH341 = 0, retval, bbmCount; uint32_t sectInBlock; uint8_t tmp_hi, tmp_lo; QString col_block, col_start, col_end; stCH341 = ProgDeviceInit(programmerType, 6, 1); bbmCount = 0; sectInBlock = blSize / sectSize; ui->label_scan->clear(); ui->progressBar->setRange(0, static_cast(totBlocks)); std::shared_ptr buf(new uint8_t[2]); if (stCH341 == 0) { for (i = 0; i < static_cast(totBlocks); i++) { retval = nand_checkBadBlock(static_cast(i), static_cast(sectSize), static_cast(sectInBlock), programmerType); if (retval == 1)//(buf[0] != 0xff) { scanResult = true; tmp_hi = static_cast(i >> 8); tmp_lo = i & 0xff; col_block = bytePrint(tmp_hi) + bytePrint(tmp_lo); col_start = hexiAddr(static_cast(i) * sectInBlock * sectSize); col_end = hexiAddr(static_cast(i + 1) * sectInBlock * sectSize - 1); ui->tableWidgetScan->insertRow(bbmCount); ui->tableWidgetScan->setItem(bbmCount, 0, new QTableWidgetItem(QString::number(bbmCount + 1))); ui->tableWidgetScan->setItem(bbmCount, 1, new QTableWidgetItem(col_block)); ui->tableWidgetScan->setItem(bbmCount, 2, new QTableWidgetItem(col_start)); ui->tableWidgetScan->setItem(bbmCount, 3, new QTableWidgetItem(col_end)); bbmCount++; } ui->progressBar->setValue(i); if (retval == -1) { QMessageBox::about(this, tr("Error"), tr("Error reading chip!")); return; } } if (scanResult) ui->label_scan->setText(tr("Corrupted blocks found:")); else ui->label_scan->setText(tr("All blocks in the chip are good!")); ui->tableWidgetScan->resizeColumnsToContents(); ui->tableWidgetScan->removeRow(bbmCount); ui->progressBar->setValue(0); scanResult = false; ProgDeviceClose(programmerType); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); } void DialogBBM::getBlockSize(uint32_t blockSize) { blSize = blockSize; } void DialogBBM::getSectorSize(uint32_t sectorSize) { sectSize = sectorSize; } void DialogBBM::getTotalBlocks(uint32_t totalBlocks) { totBlocks = totalBlocks; } void DialogBBM::getSettings(uint8_t settings) { setParams = settings; if ((setParams & 0x0f) == 0x01) ui->radioButton_w2->setChecked(true); if ((setParams & 0x0f) == 0x00) ui->radioButton_w1->setChecked(true); if ((setParams & 0xf0) == 0x10) ui->radioButton_e2->setChecked(true); if ((setParams & 0xf0) == 0x00) ui->radioButton_e1->setChecked(true); } void DialogBBM::on_pushButton_2_clicked() { int i, stCH341 = 0, retval, maxTableRows; uint8_t stringResult; QString numBlock; std::shared_ptr buf(new uint8_t[256]); stCH341 = ProgDeviceInit(programmerType, 6, 1); if (stCH341 == 0) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0xa5, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),1,SPI_CONTROLLER_SPEED_SINGLE, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),256,SPI_CONTROLLER_SPEED_SINGLE, programmerType); if ((buf[0] != 0xff) && (buf[1] != 0xff)) { ui->tableWidgetBBM->setShowGrid(true); ui->tableWidgetBBM->setShowGrid(true); ui->tableWidgetBBM->horizontalHeader()->setStretchLastSection(true); ui->tableWidgetBBM->verticalHeader()->setVisible(false); ui->tableWidgetBBM->setColumnCount(4); ui->tableWidgetBBM->setRowCount(1); if (totBlocks == 1024) maxTableRows = 20; else maxTableRows = 40; for (i = 0; i < maxTableRows; i++) { numBlock = bytePrint(buf[i * 4] & 0x3f) + bytePrint(buf[i * 4 +1]); ui->tableWidgetBBM->insertRow(i); ui->tableWidgetBBM->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1))); ui->tableWidgetBBM->setItem(i, 1, new QTableWidgetItem(numBlock)); numBlock = bytePrint(buf[i * 4 + 2]) + bytePrint(buf[i * 4 + 3]); ui->tableWidgetBBM->setItem(i, 2, new QTableWidgetItem(numBlock)); stringResult = (buf[i * 4] & 0x3f) >> 6; if (stringResult == 0x00) ui->tableWidgetBBM->setItem(i, 3, new QTableWidgetItem(tr("Not used"))); if (stringResult == 0x02) ui->tableWidgetBBM->setItem(i, 3, new QTableWidgetItem(tr("Active, valid"))); if (stringResult == 0x03) ui->tableWidgetBBM->setItem(i, 3, new QTableWidgetItem(tr("Active, not valid"))); } ui->tableWidgetBBM->removeRow(maxTableRows); ui->tableWidgetBBM->resizeColumnsToContents(); } else ui->label_bbm_result->setText(tr("BBM table is not used in this chip.")); ProgDeviceClose(programmerType); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); } void DialogBBM::on_pushButton_3_clicked() { setParams = 0; if (ui->radioButton_e1->isChecked()) setParams = setParams & 0x0f; if (ui->radioButton_e2->isChecked()) setParams = setParams | 0x10; if (ui->radioButton_w1->isChecked()) setParams = setParams & 0xf0; if (ui->radioButton_w2->isChecked()) setParams = setParams | 0x01; emit sendNandParam(setParams); DialogBBM::close(); } void DialogBBM::setDeviceType(const uint8_t pType) { programmerType = pType; if (programmerType < 2) programmerName ="CH341A"; if (programmerType == 2) programmerName ="CH347T"; } imsprog-1.8.5/IMSProg_programmer/dialogbbm.h000066400000000000000000000030151520775651600210260ustar00rootroot00000000000000/* * Copyright (C) 2025 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef DIALOGBBM_H #define DIALOGBBM_H #include #include #include #include #include "qhexedit.h" extern "C" { #include "ch341a_spi.h" #include "spi_controller.h" } namespace Ui { class DialogBBM; } class DialogBBM : public QDialog { Q_OBJECT public: explicit DialogBBM(QWidget *parent = nullptr); void getSectorSize(uint32_t sectorSize); void getBlockSize(uint32_t blockSize); void getTotalBlocks(uint32_t totalBlocks); void getSettings(uint8_t settings); void setDeviceType(const uint8_t pType); ~DialogBBM(); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); void on_pushButton_3_clicked(); private: Ui::DialogBBM *ui; int maxBlock; uint32_t sectSize, blSize, totBlocks; uint8_t setParams; uint8_t programmerType; QString programmerName; signals: void sendNandParam(uint8_t); }; #endif // DIALOGBBM_H imsprog-1.8.5/IMSProg_programmer/dialogbbm.ui000066400000000000000000000251021520775651600212150ustar00rootroot00000000000000 DialogBBM 0 0 640 400 500 400 Bad block management :/res/img/write64.png:/res/img/write64.png 1 Chip scan 0 0 460 0 114 false 20 No AlignCenter Block AlignCenter Start address AlignCenter End address AlignCenter 0 0 6 24 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Check Settings 10 6 10 6 Erasing Skip bad blocks during erase procedure (recommended) Don't skip bad blocks Writing Write all blocks one to one (ignore bad blocks) Skip bad blocks during writing procedure Qt::Vertical 20 40 Qt::Horizontal 40 20 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Ok BBM table (Winbond) This operation is used only in some Winbond chips. false No Bad block Changed block Status 6 Qt::Horizontal 40 20 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Read imsprog-1.8.5/IMSProg_programmer/dialogcompare.cpp000066400000000000000000000106241520775651600222530ustar00rootroot00000000000000/* * Copyright (C) 2024 - 2025 Mikhail Medvedev * * * 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 3 * 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. */ #include "dialogcompare.h" #include "ui_dialogcompare.h" #include #include #include #include #include #include #include "qhexedit.h" #include "hexutility.h" DialogCompare::DialogCompare(QWidget *parent) : QDialog(parent), ui(new Ui::DialogCompare) { ui->setupUi(this); setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); QFont heFont; //heFont = QFont("Monospace", 10); heFont = QFont("DejaVu Sans Mono", 10); hexEdit1 = new QHexEdit(ui->frame_1); hexEdit2 = new QHexEdit(ui->frame_2); hexEdit1->setHexCaps(true); hexEdit2->setHexCaps(true); hexEdit1->setFont(heFont); hexEdit2->setFont(heFont); hexEdit1->setGeometry(0,0,ui->frame_1->width(),ui->frame_1->height()); hexEdit2->setGeometry(0,0,ui->frame_2->width(),ui->frame_2->height()); hexEdit1->setReadOnly(true); hexEdit2->setReadOnly(true); ui->checkBox->setChecked(false); QFontMetrics fm(hexEdit1->fontMetrics()); int pixelsHigh =fm.horizontalAdvance("F"); DialogCompare::resize(pixelsHigh * 122, DialogCompare::height()); hexEdit1->setAsciiArea(false); hexEdit2->setAsciiArea(false); //ui->checkBox->setChecked(true); //Synchronise scrollbars connect(hexEdit1->verticalScrollBar(), &QScrollBar::valueChanged, this, &DialogCompare::handleScroll1); connect(hexEdit2->verticalScrollBar(), &QScrollBar::valueChanged, this, &DialogCompare::handleScroll2); } void DialogCompare::handleScroll2() { long posStart = 0; posStart = hexEdit2->_bPosFirst; hexEdit1->setCursorPosition(posStart *2); hexEdit2->setCursorPosition(posStart *2); hexEdit1->verticalScrollBar()->setValue(hexEdit2->verticalScrollBar()->value()); } void DialogCompare::handleScroll1() { long posStart = 0, posEnd = 0, min = 0; int i; if (data1.size() < data2.size()) min = data1.size(); else min = data2.size(); posStart = hexEdit1->_bPosFirst; posEnd = hexEdit1->_bPosLast + 16; if (posEnd > min) posEnd = min; hexEdit1->clearUserAreas(); hexEdit2->clearUserAreas(); hexEdit2->setCursorPosition(posStart *2); hexEdit1->setCursorPosition(posStart *2); hexEdit2->verticalScrollBar()->setValue(hexEdit1->verticalScrollBar()->value()); for (i = static_cast(posStart); i < posEnd; i++) { if (data1[i] != data2[i]) { hexEdit1->addUserArea(i, i + 1, QColor(0, 0, 0, 255), QColor(255, 0, 0, 60)); hexEdit2->addUserArea(i, i + 1, QColor(0, 0, 0, 255), QColor(255, 0, 0, 60)); } } } DialogCompare::~DialogCompare() { delete ui; } void DialogCompare::showArrays(QByteArray *array1, QByteArray *array2, QString *name1, QString *name2) { data1 = *array1; data2 = *array2; hexEdit1->setData(data1); hexEdit2->setData(data2); ui->label_n1->setText(tr("Name: ")); ui->label_n2->setText(tr("Name: ")); ui->lineEdit_n1->setText(*name1); ui->lineEdit_n2->setText(*name2); ui->lineEdit_c1->setText(getCRC32(*array1)); ui->lineEdit_c2->setText(getCRC32(*array2)); handleScroll1(); } void DialogCompare::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); hexEdit1->setGeometry(0,0,ui->frame_1->width(),ui->frame_1->height()); hexEdit2->setGeometry(0,0,ui->frame_2->width(),ui->frame_2->height()); handleScroll1(); } void DialogCompare::on_checkBox_stateChanged(int arg1) { QFontMetrics fm(hexEdit1->fontMetrics()); int pixelsHigh =fm.horizontalAdvance("F"); if (arg1 == 0) { hexEdit1->setAsciiArea(false); hexEdit2->setAsciiArea(false); DialogCompare::resize(pixelsHigh * 122, DialogCompare::height()); } else { hexEdit1->setAsciiArea(true); hexEdit2->setAsciiArea(true); DialogCompare::resize(pixelsHigh * 153, DialogCompare::height()); } } imsprog-1.8.5/IMSProg_programmer/dialogcompare.h000066400000000000000000000024371520775651600217230ustar00rootroot00000000000000/* * Copyright (C) 2024 - 2025 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef DIALOGCOMPARE_H #define DIALOGCOMPARE_H #include #include #include "qhexedit.h" #include "hexutility.h" namespace Ui { class DialogCompare; } class DialogCompare : public QDialog { Q_OBJECT private slots: void handleScroll1(); void handleScroll2(); void on_checkBox_stateChanged(int arg1); public: explicit DialogCompare(QWidget *parent = nullptr); void showArrays(QByteArray *array1, QByteArray *array2, QString *name1, QString *name2); ~DialogCompare(); private: Ui::DialogCompare *ui; void resizeEvent(QResizeEvent* event); QHexEdit *hexEdit1, *hexEdit2; QByteArray data1, data2; //QByteArray arr1, arr2; }; #endif // DIALOGCOMPARE_H imsprog-1.8.5/IMSProg_programmer/dialogcompare.ui000066400000000000000000000131631520775651600221070ustar00rootroot00000000000000 DialogCompare 0 0 1188 517 Comparing files: :/res/img/write64.png:/res/img/write64.png QLayout::SetMaximumSize 0 350 QFrame::StyledPanel QFrame::Raised QLayout::SetMinimumSize 0 0 0 25 16777215 30 CRC32: 100 16777215 Qt::AlignCenter 0 25 16777215 30 Name 0 350 QFrame::StyledPanel QFrame::Raised QLayout::SetMinimumSize 0 0 0 25 16777215 30 CRC32: 100 16777215 Qt::AlignCenter 0 25 16777215 30 Name Visible ASCII areas imsprog-1.8.5/IMSProg_programmer/dialogfill.cpp000066400000000000000000000035111520775651600215500ustar00rootroot00000000000000/* * Copyright (C) 2024 - 2026 Mikhail Medvedev * * * 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 3 * 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. */ #include "dialogfill.h" #include "ui_dialogfill.h" #include "mainwindow.h" #include #include #include #include DialogFill::DialogFill(QWidget *parent) : QDialog(parent), ui(new Ui::DialogFill) { ui->setupUi(this); setWindowFlags(Qt::Window| Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); QRegularExpression reHex("[A-Fa-f0-9]{1,8}"); QRegularExpression codeHex("[A-Fa-f0-9]{1,2}"); QRegularExpressionValidator *validator = new QRegularExpressionValidator(reHex, this); QRegularExpressionValidator *valCode = new QRegularExpressionValidator(codeHex, this); ui->lineEditStart->setValidator(validator); ui->lineEditEnd->setValidator(validator); ui->lineEditCode->setValidator(valCode); ui->comboBox_end->addItem(tr("End address"), 0); ui->comboBox_end->addItem(tr("Length"), 1); } DialogFill::~DialogFill() { delete ui; } void DialogFill::on_pushButton_clicked() { QString typeOfEnd; if (ui->comboBox_end->currentData() == 0) typeOfEnd = "0"; else typeOfEnd = "1"; addrData = ui->lineEditStart->text() + "-" + ui->lineEditEnd->text() + "-" + ui->lineEditCode->text() + "-" + typeOfEnd; emit sendAddr4(addrData); DialogFill::close(); } imsprog-1.8.5/IMSProg_programmer/dialogfill.h000066400000000000000000000017541520775651600212240ustar00rootroot00000000000000/* * Copyright (C) 2024 - 2026 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef DIALOGFILL_H #define DIALOGFILL_H #include #include namespace Ui { class DialogFill; } class DialogFill : public QDialog { Q_OBJECT public: explicit DialogFill(QWidget *parent = nullptr); ~DialogFill(); private slots: void on_pushButton_clicked(); signals: void sendAddr4(QString); private: Ui::DialogFill *ui; QString addrData; }; #endif // DIALOGFILL_H imsprog-1.8.5/IMSProg_programmer/dialogfill.ui000066400000000000000000000072211520775651600214050ustar00rootroot00000000000000 DialogFill 0 0 272 160 Fill the buffer with code :/res/img/write64.png:/res/img/write64.png 13 All values in HEX format! Qt::AlignCenter 12 Start address: 120 0 120 0 120 0 Filling code: Qt::Horizontal 118 20 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Fill imsprog-1.8.5/IMSProg_programmer/dialoginfo.cpp000066400000000000000000000170421520775651600215610ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2026 Mikhail Medvedev * * * 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 3 * 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. */ #include "dialoginfo.h" #include "ui_dialoginfo.h" DialogInfo::DialogInfo(QWidget *parent) : QDialog(parent), ui(new Ui::DialogInfo) { ui->setupUi(this); setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); pix24 = new QPixmap(":/res/img/ch341_24.png"); pix93 = new QPixmap(":/res/img/ch341_93.png"); pix25 = new QPixmap(":/res/img/ch341_spi.png"); pix35 = new QPixmap(":/res/img/ch341_35.png"); pix45 = new QPixmap(":/res/img/ch341_45.png"); pix2518 = new QPixmap(":/res/img/ch341_spi_18.png"); pix3518 = new QPixmap(":/res/img/ch341_spi_18_wson.png"); pix24v7 = new QPixmap(":/res/img/v1_7_i2c_3v3.png"); pix24v750 = new QPixmap(":/res/img/v1_7_i2c_5v0.png"); pix25v718 = new QPixmap(":/res/img/v1_7_spi_1v8.png"); pix25v725 = new QPixmap(":/res/img/v1_7_spi_2v5.png"); pix25v733 = new QPixmap(":/res/img/v1_7_spi_3v3.png"); pix93v17 = new QPixmap(":/res/img/v1_7_mw_3v3.png"); pix45v17 = new QPixmap(":/res/img/v1_7_45_3v3.png"); pix35v718 = new QPixmap(":/res/img/v1_7_NAND_1v8.png"); pix35v733 = new QPixmap(":/res/img/v1_7_NAND_3v3.png"); pix24x347_3v3_0 = new QPixmap(":/res/img/ch347_i2c_3v3.png"); pix25x347_1v8_0 = new QPixmap(":/res/img/ch347_spi_1v8.png"); pix25x347_3v3_0 = new QPixmap(":/res/img/ch347_spi_3v3.png"); pix93x347_3v3_0 = new QPixmap(":/res/img/ch347_mv_3v3.png"); pix45x347_3v3_0 = new QPixmap(":/res/img/ch347_45_3v3.png"); pix35x347_1v8_0 = new QPixmap(":/res/img/ch347_spi_18_wson.png"); pix35x347_3v3_0 = new QPixmap(":/res/img/ch347_NAND_3v3.png"); pix24x347_3v3_1 = new QPixmap(":/res/img/v1_1_i2c_3v3.png"); pix24x347_5v0_1 = new QPixmap(":/res/img/v1_1_i2c_5v0.png"); pix25x347_2v5_1 = new QPixmap(":/res/img/v1_1_spi_2v5.png"); pix25x347_1v8_1 = new QPixmap(":/res/img/v1_1_spi_1v8.png"); pix25x347_3v3_1 = new QPixmap(":/res/img/v1_1_spi_3v3.png"); pix93x347_3v3_1 = new QPixmap(":/res/img/v1_1_mw_3v3.png"); pix45x347_3v3_1 = new QPixmap(":/res/img/v1_1_45_3v3.png"); pix35x347_1v8_1 = new QPixmap(":/res/img/v1_1_NAND_1v8.png"); pix35x347_3v3_1 = new QPixmap(":/res/img/v1_1_NAND_3v3.png"); pixnone = new QPixmap(":/res/img/ch341_unknown.png"); } DialogInfo::~DialogInfo() { delete pix24; delete pix93; delete pix25; delete pix35; delete pix2518; delete pix3518; delete pix24v7; delete pix24v750; delete pix25v718; delete pix25v733; delete pix93v17; delete pix45v17; delete pix35v718; delete pix25v725; delete pix35v733; delete pix24x347_3v3_0; delete pix25x347_1v8_0; delete pix25x347_3v3_0; delete pix93x347_3v3_0; delete pix45x347_3v3_0; delete pix35x347_1v8_0; delete pix35x347_3v3_0; delete pix24x347_3v3_1; delete pix24x347_5v0_1; delete pix25x347_2v5_1; delete pix25x347_1v8_1; delete pix25x347_3v3_1; delete pix93x347_3v3_1; delete pix45x347_3v3_1; delete pix35x347_1v8_1; delete pix35x347_3v3_1; delete pixnone; delete ui; } void DialogInfo::on_pushButton_clicked() { DialogInfo::close(); } void DialogInfo::setProgrammer(const uint8_t progType) { currentProg = progType; } void DialogInfo::setChip(const uint chipType) { switch (chipType) { case 1: if (currentProg == 0) ui->label->setPixmap(*pix24); if (currentProg == 1) ui->label->setPixmap(*pix24v7); if (currentProg == 2) ui->label->setPixmap(*pix24x347_3v3_0); if (currentProg == 3) ui->label->setPixmap(*pix24x347_3v3_1); ui->label_slot->setText("24xx"); ui->label_adapter->setText("-"); break; case 2: if (currentProg == 0) ui->label->setPixmap(*pix25); if (currentProg == 1) ui->label->setPixmap(*pix25v733); if (currentProg == 2) ui->label->setPixmap(*pix25x347_3v3_0); if (currentProg == 3) ui->label->setPixmap(*pix25x347_3v3_1); ui->label_slot->setText("25xx"); ui->label_adapter->setText("-"); break; case 3: ui->label->setPixmap(*pix2518); if (currentProg == 0) ui->label->setPixmap(*pix2518); if (currentProg == 1) ui->label->setPixmap(*pix25v718); if (currentProg == 2) ui->label->setPixmap(*pix25x347_1v8_0); if (currentProg == 3) ui->label->setPixmap(*pix25x347_1v8_1); ui->label_slot->setText("25xx"); if (currentProg == 0) ui->label_adapter->setText("1.8V-Adapter"); if (currentProg == 1) ui->label_adapter->setText("-"); if (currentProg == 2) ui->label_adapter->setText("1.8V-Adapter"); if (currentProg == 3) ui->label_adapter->setText("-"); break; case 4: ui->label_slot->setText("25xx"); ui->label_adapter->setText("93xx adapter"); if (currentProg == 0) ui->label->setPixmap(*pix93); if (currentProg == 1) ui->label->setPixmap(*pix93v17); if (currentProg == 2) ui->label->setPixmap(*pix93x347_3v3_0); if (currentProg == 3) ui->label->setPixmap(*pix93x347_3v3_1); break; case 5: ui->label_slot->setText("25xx"); ui->label_adapter->setText("45xx adapter"); if (currentProg == 0) ui->label->setPixmap(*pix45); if (currentProg == 1) ui->label->setPixmap(*pix45v17); if (currentProg == 2) ui->label->setPixmap(*pix45x347_3v3_0); if (currentProg == 3) ui->label->setPixmap(*pix45x347_3v3_1); break; case 6: ui->label_slot->setText("25xx"); ui->label_adapter->setText("WSON adapter"); if (currentProg == 0) ui->label->setPixmap(*pix35); if (currentProg == 1) ui->label->setPixmap(*pix35v733); if (currentProg == 2) ui->label->setPixmap(*pix35x347_3v3_0); if (currentProg == 3) ui->label->setPixmap(*pix35x347_3v3_1); break; case 7: if (currentProg == 0) ui->label->setPixmap(*pix3518); if (currentProg == 1) ui->label->setPixmap(*pix35v718); if (currentProg == 2) ui->label->setPixmap(*pix35x347_1v8_0); if (currentProg == 3) ui->label->setPixmap(*pix35x347_1v8_1); ui->label_slot->setText("25xx"); if (currentProg == 0) ui->label_adapter->setText("1.8V + WSON"); if (currentProg == 1) ui->label_adapter->setText("WSON"); if (currentProg == 2) ui->label_adapter->setText("1.8V + WSON"); if (currentProg == 3) ui->label_adapter->setText("WSON"); break; case 8: if (currentProg == 1) ui->label->setPixmap(*pix25v725); if (currentProg == 3) ui->label->setPixmap(*pix25x347_2v5_1); ui->label_slot->setText("25xx"); break; case 9: if (currentProg == 0) ui->label->setPixmap(*pix24); if (currentProg == 1) ui->label->setPixmap(*pix24v750); if (currentProg == 2) ui->label->setPixmap(*pix24x347_3v3_0); if (currentProg == 3) ui->label->setPixmap(*pix24x347_5v0_1); ui->label_slot->setText("24xx"); ui->label_adapter->setText("-"); break; default: ui->label_slot->setText("-"); ui->label_adapter->setText("-"); ui->label->setPixmap(*pixnone); break; } } imsprog-1.8.5/IMSProg_programmer/dialoginfo.h000066400000000000000000000036131520775651600212250ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2024 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef DIALOGINFO_H #define DIALOGINFO_H #include namespace Ui { class DialogInfo; } class DialogInfo : public QDialog { Q_OBJECT public: explicit DialogInfo(QWidget *parent = nullptr); ~DialogInfo(); void setChip(const uint chipType); void setProgrammer(const uint8_t progType); private slots: void on_pushButton_clicked(); private: Ui::DialogInfo *ui; QPixmap *pix24; QPixmap *pix93; QPixmap *pix25; QPixmap *pix35; QPixmap *pix45; QPixmap *pix2518; QPixmap *pix3518; QPixmap *pix24v7; QPixmap *pix24v750; QPixmap *pix25v718; QPixmap *pix25v725; QPixmap *pix25v733; QPixmap *pix93v17; QPixmap *pix45v17; QPixmap *pix35v718; QPixmap *pix35v733; QPixmap *pix24x347_3v3_0; QPixmap *pix25x347_1v8_0; QPixmap *pix25x347_3v3_0; QPixmap *pix93x347_3v3_0; QPixmap *pix45x347_3v3_0; QPixmap *pix35x347_1v8_0; QPixmap *pix35x347_3v3_0; QPixmap *pix24x347_3v3_1; QPixmap *pix24x347_5v0_1; QPixmap *pix25x347_1v8_1; QPixmap *pix25x347_2v5_1; QPixmap *pix25x347_3v3_1; QPixmap *pix93x347_3v3_1; QPixmap *pix45x347_3v3_1; QPixmap *pix35x347_1v8_1; QPixmap *pix35x347_3v3_1; QPixmap *pix35x347_5v0_1; QPixmap *pixnone; uint8_t currentProg; }; #endif // DIALOGINFO_H imsprog-1.8.5/IMSProg_programmer/dialoginfo.ui000066400000000000000000000056361520775651600214220ustar00rootroot00000000000000 DialogInfo 0 0 318 400 Connection info: :/res/img/write64.png:/res/img/write64.png :/res/img/ch341_unknown.png Slot: - Adapter: - Qt::Horizontal 40 20 90 25 80 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Close imsprog-1.8.5/IMSProg_programmer/dialognandsecurity.cpp000066400000000000000000000303171520775651600233360ustar00rootroot00000000000000#include "dialognandsecurity.h" #include "ui_dialognandsecurity.h" #include "mainwindow.h" #include #include #include #include "qhexedit.h" DialogNandSecurity::DialogNandSecurity(QWidget *parent) : QDialog(parent), ui(new Ui::DialogNandSecurity) { ui->setupUi(this); setWindowFlags(Qt::Window| Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); programmerType = 0; } DialogNandSecurity::~DialogNandSecurity() { delete ui; } void DialogNandSecurity::on_toolButton_read_clicked() { int stCH341 = 0, retval, i; std::shared_ptr buf(new uint8_t[4096]); uint8_t curRegister = static_cast(ui->comboBox_regnum->currentData().toUInt()) + startSector - 1; qDebug()<<"curregister="<setData(regData); } if (otp == false) //OPT Disabled { // Disable OTP MODE SPI_CONTROLLER_Chip_Select_Low(programmerType); //Reading status SPI_CONTROLLER_Write_One_Byte(0x0f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),1,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); //Write enable SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x1f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); SPI_CONTROLLER_Write_One_Byte(buf[0] & 0xbf, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } SPI_CONTROLLER_Chip_Select_Low(programmerType); //Write disable SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); ProgDeviceClose(programmerType); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); } void DialogNandSecurity::on_toolButton_write_clicked() { int stCH341 = 0, retval, i; std::shared_ptr buf(new uint8_t[4096]); uint8_t curRegister = static_cast(ui->comboBox_regnum->currentData().toUInt()) + startSector - 1; bool otp; //READING OTP PAGE stCH341 = ProgDeviceInit(programmerType, 6, 1); if (stCH341 == 0) { usleep(100); SPI_CONTROLLER_Chip_Select_Low(programmerType); //Reading status SPI_CONTROLLER_Write_One_Byte(0x0f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),1,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if ((buf[0] & 0x40) == 0) //OPT Disabled ? { otp = false; // Enable OTP MODE SPI_CONTROLLER_Chip_Select_Low(programmerType); //Write enable SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x1f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); SPI_CONTROLLER_Write_One_Byte(buf[0] | 0x40, programmerType); //&bf to clear SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } else otp = true; SPI_CONTROLLER_Chip_Select_Low(programmerType); //Write enable SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(200); regData = hexEdit->data(); for (i = 0; i < static_cast(currentSector); i++) { buf[i] = static_cast(regData[i]); } SPI_CONTROLLER_Chip_Select_Low(programmerType); //From PC to buffer SPI_CONTROLLER_Write_One_Byte(0x02, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_NByte(buf.get(), currentSector, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1000); SPI_CONTROLLER_Chip_Select_Low(programmerType); //From buffer to OTP sector SPI_CONTROLLER_Write_One_Byte(0x10, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(curRegister, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(200); if (otp == false) //OPT Disabled { // Disable OTP MODE SPI_CONTROLLER_Chip_Select_Low(programmerType); //Reading status SPI_CONTROLLER_Write_One_Byte(0x0f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),1,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); //Write enable SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x1f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); SPI_CONTROLLER_Write_One_Byte(buf[0] & 0xbf, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } SPI_CONTROLLER_Chip_Select_Low(programmerType); //Write disable SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); ProgDeviceClose(programmerType); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); } void DialogNandSecurity::on_toolButton_open_clicked() { QByteArray buf; QString fileName; fileName = QFileDialog::getOpenFileName(this, QString(tr("Open file")), curPath, "Data Images (*.bin *.BIN *.rom *.ROM);;All files (*.*)"); QFileInfo info(fileName); curPath = info.filePath(); QFile file(fileName); if (info.size() > currentSector) { QMessageBox::about(this, tr("Error"), tr("The file size exceeds the security register size.")); return; } if (!file.open(QIODevice::ReadOnly)) { return; } buf.resize(static_cast(info.size())); buf = file.readAll(); regData.replace(0, static_cast(info.size()), buf); hexEdit->setData(regData); file.close(); // path must be transfered to mainwindow } void DialogNandSecurity::on_toolButton_save_clicked() { QString fileName; fileName = QFileDialog::getSaveFileName(this, QString(tr("Save file")), curPath, "Data Images (*.bin *.BIN);;All files (*.*)"); if (fileName.isEmpty()) return; QFileInfo info(fileName); curPath = info.filePath(); if (QString::compare(info.suffix(), "bin", Qt::CaseInsensitive)) fileName = fileName + ".bin"; QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) { QMessageBox::about(this, tr("Error"), tr("Error saving file!")); return; } file.write(hexEdit->data()); file.close(); // path must be transfered to mainwindow } void DialogNandSecurity::closeEvent(QCloseEvent* event) { emit closeRequestHasArrived(); QWidget::closeEvent(event); } void DialogNandSecurity::setSectorSize(uint32_t sectorSize) { currentSector = sectorSize; regData.reserve(4096); regData.resize(static_cast(currentSector)); regData.fill(char(0xff)); QFont heFont; heFont = QFont("Monospace", 10); hexEdit = new QHexEdit(ui->frame); hexEdit->setGeometry(0, 0, ui->frame->width(), ui->frame->height()); hexEdit->setData(regData); hexEdit->setHexCaps(true); hexEdit->setFont(heFont); hexEdit->setData(regData); } void DialogNandSecurity::setAlgorithm(unsigned int currentAlg) { uint8_t numSector; int i; algSettings algSet[] = { // id Start_sect Number { 0, 0x02, 0x0b }, { 1, 0x00, 0x03 }, { 2, 0x00, 0x03 }, { 3, 0x02, 0x1f }, { 4, 0x02, 0x0b }, { 5, 0x02, 0x1d }, { 6, 0x02, 0x1f }, { 7, 0x02, 0x1f }, { 8, 0x02, 0x0b }, { 9, 0x02, 0x0b }, { 10, 0x02, 0x1f }, { 11, 0x00, 0x03 }, { 12, 0x02, 0x05 }, { 13, 0x00, 0x03 }, { 14, 0x02, 0x0b }, { 15, 0x02, 0x3f }, { 16, 0x02, 0x3f }, { 17, 0x00, 0x03 }, { 18, 0x00, 0x03 }, }; startSector = algSet[currentAlg].secStart; endSector = algSet[currentAlg].secEnd; numSector = endSector - startSector + 1; for (i = 1; i <= numSector; i++) { ui->comboBox_regnum->addItem(QString::number(i), i); } } void DialogNandSecurity::setPath(QString lastPath) { curPath = lastPath; } void DialogNandSecurity::setDeviceType(const uint8_t pType) { programmerType = pType; if (programmerType < 2) programmerName ="CH341A"; if (programmerType == 2) programmerName ="CH347T"; } imsprog-1.8.5/IMSProg_programmer/dialognandsecurity.h000066400000000000000000000022561520775651600230040ustar00rootroot00000000000000#ifndef DIALOGNANDSECURITY_H #define DIALOGNANDSECURITY_H #include "qhexedit.h" #include namespace Ui { class DialogNandSecurity; } class DialogNandSecurity : public QDialog { Q_OBJECT public: explicit DialogNandSecurity(QWidget *parent = nullptr); void setAlgorithm(unsigned int currentAlg); void setSectorSize(uint32_t sectorSize); void setPath(QString lastPath); void setDeviceType(const uint8_t pType); void closeEvent(QCloseEvent* event); ~DialogNandSecurity(); private slots: void on_toolButton_read_clicked(); void on_toolButton_write_clicked(); void on_toolButton_open_clicked(); void on_toolButton_save_clicked(); signals: void closeRequestHasArrived(); private: Ui::DialogNandSecurity *ui; QString curPath; uint32_t currentSector; uint8_t startSector, endSector; QByteArray regData; QHexEdit *hexEdit; uint8_t programmerType; QString programmerName; struct algSettings { uint8_t id; // Algorithm number uint8_t secStart; // Start security sector number uint8_t secEnd; // End security sector number }; }; #endif // DIALOGNANDSECURITY_H imsprog-1.8.5/IMSProg_programmer/dialognandsecurity.ui000066400000000000000000000156761520775651600232040ustar00rootroot00000000000000 DialogNandSecurity 0 0 661 523 Security registers :/res/img/write64.png:/res/img/write64.png Hex Editor QLayout::SetMaximumSize 610 350 QFrame::StyledPanel QFrame::Raised 0 100 16777215 100 Operations: 10 6 6 48 48 48 48 Reading security register data from the chip ... :/res/img/read64.png:/res/img/read64.png 48 48 48 48 48 48 Writing data to the security register ... :/res/img/write64.png:/res/img/write64.png 48 48 Qt::Vertical 48 48 48 48 Open a binary file from a computer ... :/res/img/open64.png:/res/img/open64.png 48 48 48 48 48 48 Save the binary file on the computer ... :/res/img/save64.png:/res/img/save64.png 48 48 Qt::Vertical Security register number: imsprog-1.8.5/IMSProg_programmer/dialognandsr.cpp000066400000000000000000000771411520775651600221210ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2025 Mikhail Medvedev * * * 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. */ #include "dialognandsr.h" #include "ui_dialognandsr.h" #include #include #include #include #include #include #include #include #include "unistd.h" #include "hexutility.h" #include "memory" #include DialogNANDSr::DialogNANDSr(QWidget *parent) : QDialog(parent), ui(new Ui::DialogNANDSr) { ui->setupUi(this); setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); programmerType = 0; setLineEditFilter(); regReaded = false; QFontMetrics fm(ui->textEdit_buf->fontMetrics()); int pixelsHigh = fm.height(); int pixelsWidth = fm.horizontalAdvance("00> 4F 4E 46 49 00 00 00 00 02 00 00 00 00 00 00 00 ") + 20; int sectionHeight = pixelsHigh * 16 + 6; ui->textEdit_buf->setMinimumHeight(sectionHeight); ui->textEdit_buf->setMinimumWidth(pixelsWidth); ui->textEdit_ID->setMaximumHeight(pixelsHigh * 2 + 16); } DialogNANDSr::~DialogNANDSr() { delete ui; } void DialogNANDSr::setLineEditFilter() { QRegularExpression reHex("[0-1]{1}"); QRegularExpressionValidator *validator = new QRegularExpressionValidator(reHex, this); //searching all lineEdit_srXX, XX - numbers QString searchText = "lineEdit_sr\\d+"; QRegularExpression regex(searchText); for (QLineEdit* edit : findChildren()) { if (regex.match(edit->objectName()).hasMatch()) { edit->setValidator(validator); } } } void DialogNANDSr::on_pushButton_read_clicked() { bool otp; int i, j, pageSize, numBlocks, pagesPerBlock; QString buftxt = ""; otp = false; //Clearing fields clearAllFields(); ui->textEdit_ID->clear(); //READING STATUS REGISTERS std::shared_ptr buf(new uint8_t[512]); QString currRegName; int retval; int currRegister; uint8_t currBit, currByte, idBlockAddr; int stCH341 = 0; idBlockAddr = 0x00; stCH341 = ProgDeviceInit(programmerType, 6, 1); if (stCH341 == 0) { for (currRegister = 0; currRegister < 5; currRegister++) { if (RegNumbers[currRegister] != 0xff) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x0f, programmerType); SPI_CONTROLLER_Write_One_Byte(RegNumbers[currRegister], programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),1,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading register!")); return; } //showing data currByte = 1; for (currBit = 0; currBit < 8; currBit++) { currRegName = "lineEdit_sr" + QString::number(currRegister) + QString::number(currBit); for (QLineEdit* edit : findChildren()) { if (edit->objectName() == currRegName) { edit->setText(QString::number((buf[0] & currByte) >> currBit)); } } currByte = static_cast(currByte << 1); } } } regReaded = true; //READING PARAMETER PAGE usleep(100); SPI_CONTROLLER_Chip_Select_Low(programmerType); //Reading status SPI_CONTROLLER_Write_One_Byte(0x0f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),1,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if ((buf[0] & 0x40) == 0) //OPT Disabled ? { otp = false; // Enable OTP MODE SPI_CONTROLLER_Chip_Select_Low(programmerType); //Write enable SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x1f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); SPI_CONTROLLER_Write_One_Byte(buf[0] | 0x40, programmerType); //&bf to clear SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } else otp = true; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x13, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x01, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1000); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x03, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),256,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading Parameter Page!")); return; } usleep(100); if (!((buf[0] == 0x4f) && (buf[1] == 0x4e) && (buf[2] == 0x46) && (buf[3] == 0x49))) { //Non standard parameter page placed SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x13, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1000); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x03, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),256,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); idBlockAddr = 0x06; } if ((buf[0] == 0x4f) && (buf[1] == 0x4e) && (buf[2] == 0x46) && (buf[3] == 0x49)) { //Parameter page supported for (j = 0; j < 255; j = j + 16) { //address buftxt = buftxt + bytePrint(static_cast(j)) + "> "; //dump for (i = 0; i < 16; i++) { buftxt = buftxt + bytePrint(buf[j + i]) + " "; } buftxt = buftxt + "\n"; } buftxt.chop(1); ui->textEdit_buf->setText(buftxt); // Parsing parameter page //Manufacture buftxt.clear(); for (i = 32; i < 44; i++) buftxt = buftxt + static_cast(buf[i]); ui->lineEdit_man->setText(strtrip(buftxt)); //Model buftxt.clear(); for (i = 44; i < 64; i++) buftxt = buftxt + static_cast(buf[i]); ui->lineEdit_model->setText(strtrip(buftxt)); //Page size buftxt.clear(); i = buf[80] + buf[81] * 256 + buf[82] * 256 * 256 + buf[83] * 256 * 256 * 256; buftxt = QString::number(i); pageSize = i; ui->lineEdit_page->setText(buftxt); //ECC size buftxt.clear(); i = buf[84] + buf[85] * 256; buftxt = QString::number(i); ui->lineEdit_ECC->setText(buftxt); //Number of pages per block buftxt.clear(); i = buf[92] + buf[93] * 256 + buf[94] * 256 * 256 + buf[95] * 256 * 256 * 256; buftxt = QString::number(i); pagesPerBlock = i; ui->lineEdit_pages->setText(buftxt); //Number of blocks per logical unit buftxt.clear(); i = buf[96] + buf[97] * 256 + buf[98] * 256 * 256 + buf[99] * 256 * 256 * 256; buftxt = QString::number(i); numBlocks = i; ui->lineEdit_blocks->setText(buftxt); //Block Size i = pageSize * pagesPerBlock / 1024; buftxt = QString::number(i) + " K"; ui->lineEdit_blocksize->setText(buftxt); //Chip size i = pageSize * pagesPerBlock * numBlocks / 1024 / 1024; buftxt = QString::number(i) + " M"; ui->lineEdit_ChipSize->setText(buftxt); } else ui->textEdit_buf->setText(tr("The Parameter Page is not supported.")); //Get unique ID SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x13, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(idBlockAddr, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1000); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x03, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),256,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading ID!")); return; } buftxt.clear(); for (i = 0; i < 32; i++) { buftxt = buftxt + bytePrint(buf[i]) + " "; if (i == 15) { buftxt.chop(1); buftxt = buftxt + "\n"; } } ui->textEdit_ID->setText(buftxt); if (otp == false) //OPT Disabled { // Disable OTP MODE SPI_CONTROLLER_Chip_Select_Low(programmerType); //Reading status SPI_CONTROLLER_Write_One_Byte(0x0f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf.get(),1,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); //Write enable SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x1f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); SPI_CONTROLLER_Write_One_Byte(buf[0] & 0xbf, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } SPI_CONTROLLER_Chip_Select_Low(programmerType); //Write disable SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); ProgDeviceClose(programmerType); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); } void DialogNANDSr::on_pushButton_write_clicked() { uint8_t regData; int stCH341 = 0; uint8_t currRegister, currBit, currByte; QString currRegName, currValue; stCH341 = ProgDeviceInit(programmerType, 6, 1); if (stCH341 == 0) { for (currRegister = 0; currRegister < 6; currRegister++) { //parsing data from lineEdits currByte = 1; regData = 0; if (RegNumbers[currRegister] != 0xff) { for (currBit = 0; currBit < 8; currBit++) { currRegName = "lineEdit_sr" + QString::number(currRegister) + QString::number(currBit); for (QLineEdit* edit : findChildren()) { if (edit->objectName() == currRegName) { currValue = edit->text(); if (QString::compare(currValue, "0", Qt::CaseInsensitive)) regData = regData + currByte; } } currByte = static_cast(currByte << 1); } } //Writing status registers SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x1f, programmerType); SPI_CONTROLLER_Write_One_Byte(RegNumbers[currRegister], programmerType); SPI_CONTROLLER_Write_One_Byte(regData, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } //Close the CH341a device ProgDeviceClose(programmerType); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); } void DialogNANDSr::closeEvent(QCloseEvent* event) { emit closeRequestHasArrived(); QWidget::closeEvent(event); } void DialogNANDSr::setPattern(const uint pattern) { allRegEnabled(); QStringList r0, r1, r2, r3, r4; switch (pattern) { case 0: //Winbond RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xff; RegNumbers[4] = 0xff; setRegDisabled(3); setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("SRP0 ,BP3 ,BP2 ,BP1 ,BP0 ,TB ,WP-E ,SRP1 ")); setRegLabels(1, QString("OTP-L ,OTP-E ,SR1-L ,ECC-E ,BUF ,X ,X ,QE ")); setRegLabels(2, QString("X ,LUT-F ,ECC-1 ,ECC-0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); break; case 1: //Gigadevice 1 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xd0; RegNumbers[4] = 0xf0; // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BWRD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,X ")); setRegLabels(1, QString("OTP-P ,OTP-E ,X ,ECC-E ,X ,X ,X ,QE ")); setRegLabels(2, QString("X ,X ,ECC-1 ,ECC-0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,DS_S1 ,DS-S0 ,X ,X ,X ,X ,X ")); setRegLabels(4, QString("X ,X ,ECCS1 ,ECCS0 ,BPS ,X ,X ,X ")); break; case 2: //Gigadevice 2 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xff; RegNumbers[4] = 0xff; setRegDisabled(3); setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BWRD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,X ")); setRegLabels(1, QString("OTP-P ,OTP-E ,X ,ECC-E ,X ,X ,X ,QE ")); setRegLabels(2, QString("X ,X ,ECC-1 ,ECC-0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); break; case 3: //MXIC RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xe0; RegNumbers[4] = 0x10; // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BPWRD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,SP ")); setRegLabels(1, QString("OTP-P ,OTP-E ,X ,ECC-E ,X ,CONT ,X ,QE ")); setRegLabels(2, QString("CRBSY ,BBMT_F,ECC-1 ,ECC-0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); setRegLabels(3, QString("DS_IO ,DS_IO ,X ,X ,X ,X ,X ,X ")); setRegLabels(4, QString("BFT3 ,BFT2 ,BFT1 ,BFT00 ,X ,X ,X ,ENPGM ")); break; case 4: //ESMT RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xff; RegNumbers[4] = 0xff; setRegDisabled(3); setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BWRD ,BP3 ,BP2 ,BP1 ,BP0 ,TB ,WP_DIS,X ")); setRegLabels(1, QString("CFG2 ,CFG1 ,LOT_EN,ECC-E ,X ,X ,CFG0 ,X ")); setRegLabels(2, QString("CRBSY ,ECCS2 ,ECCS1 ,ECCS0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); break; case 5: //ESMT2 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xd0; RegNumbers[4] = 0xff; setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("PRP0 ,BP3 ,BP2 ,BP1 ,BP0 ,T/BP ,WPE ,PRP1 ")); setRegLabels(1, QString("OTP-P ,OTP-E ,PR-L ,ECC-E ,X ,X ,X ,X ")); setRegLabels(2, QString("X ,X ,ECC_S1,ECC_S0,P-FAIL,E-FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,DRV_S1,DRV_S0,X ,X ,X ,X ,X ")); break; case 6: //MXIC2 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xe0; RegNumbers[4] = 0x10; // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BPWRD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,SP ")); setRegLabels(1, QString("OTP-P ,OTP-E ,X ,ECC-E ,X ,X ,X ,QE ")); setRegLabels(2, QString("CRBSY ,X ,X ,X ,P-FAIL,E-FAIL ,WEL ,BUSY ")); setRegLabels(3, QString("DS_IO ,DS_IO ,X ,X ,X ,X ,X ,X ")); setRegLabels(4, QString("X ,X ,X ,X ,X ,RANDOPT,RANDEN,ENPGM ")); break; case 7: //MXIC3 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xff; RegNumbers[4] = 0xff; setRegDisabled(3); setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BPWRD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,SP ")); setRegLabels(1, QString("OTP-P ,OTP-E ,X ,ECC-E ,X ,X ,X ,QE ")); setRegLabels(2, QString("X ,X ,X ,X ,P-FAIL,E-FAIL,WEL ,BUSY ")); break; case 8: //Winbond2 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xff; RegNumbers[4] = 0xff; setRegDisabled(3); setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("SRP0 ,BP3 ,BP2 ,BP1 ,BP0 ,TB ,WP-E ,SRP1 ")); setRegLabels(1, QString("OTP-L ,OTP-E ,SR1-L ,ECC-E ,BUF ,OSD-1 ,OSD-0 ,H-DIS ")); setRegLabels(2, QString("X ,LUT-F ,ECC-1 ,ECC-0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); break; case 9: //Winbond3 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xd0; RegNumbers[4] = 0xff; setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("SRP0 ,BP3 ,BP2 ,BP1 ,BP0 ,TB ,WP-E ,SRP1 ")); setRegLabels(1, QString("OTP-L ,OTP-E ,SR1-L ,ECC-E ,BUF ,OSD-1 ,OSD-0 ,H-DIS ")); setRegLabels(2, QString("X ,LUT-F ,ECC-1 ,ECC-0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,ODS1 ,ODS0 ,X ,DLP-E ,HS ,X ,X ")); break; case 10: //Dosilicon RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xd0; RegNumbers[4] = 0xff; setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BRWD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,X ")); setRegLabels(1, QString("OTPPRT,OTP_EN,X ,ECC_EN,X ,X ,X ,QE ")); setRegLabels(2, QString("ECCS3 ,ECCS2 ,ECCS1 ,ECCS0 ,P_FAIL,E_FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,DS_IO1,DS_IO2,X ,X ,X ,X ,X ")); break; case 11: //XTX2 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xff; RegNumbers[4] = 0xff; setRegDisabled(3); setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BRWD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,X ")); setRegLabels(1, QString("OTPPRT,OTP_EN,X ,ECC_EN,X ,X ,X ,QE ")); setRegLabels(2, QString("X ,X ,ECCS3 ,ECCS2 ,P_FAIL,E_FAIL,WEL ,BUSY ")); break; case 12: //XTX3 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xd0; RegNumbers[4] = 0xff; setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BRWD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,X ")); setRegLabels(1, QString("OTPPRT,OTP_EN,X ,ECC_EN,CRM ,X ,HSE ,QE ")); setRegLabels(2, QString("ECCS3 ,ECCS2 ,ECCS1 ,ECCS0 ,P_FAIL,E_FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,DS_IO1,DS_IO2,X ,X ,X ,X ,X ")); break; case 13: //XTX RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xd0; RegNumbers[4] = 0xff; setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BRWD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,X ")); setRegLabels(1, QString("OTPPRT,OTP_EN,X ,ECC_EN,X ,X ,X ,QE ")); setRegLabels(2, QString("ECCS3 ,ECCS2 ,ECCS1 ,ECCS0 ,P_FAIL,E_FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,DS_IO1,DS_IO2,X ,X ,X ,X ,X ")); break; case 14: //Micron RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xd0; RegNumbers[4] = 0xff; setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BRWD ,BP3 ,BP2 ,BP1 ,BP0 ,T/BP ,WP_DIS,X ")); setRegLabels(1, QString("CFG2 ,CFG1 ,LOT_EN,ECC-E,DS_S1 ,DS_S0 ,CFG0 ,CON_RD")); setRegLabels(2, QString("CRBSY ,ECCS2 ,ECCS1 ,ECCS0,P-FAIL,E-FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,DS0 ,X ,X ,X ,X ,X ,X ")); break; case 15: //Foressy RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0x80; RegNumbers[4] = 0x84; // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BRWD ,BP3 ,BP2 ,BP1 ,BP0 ,TB ,X ,SP ")); setRegLabels(1, QString("OTP-L ,OTP-E ,X ,ECC-E ,X ,DRV1 ,DRV0 ,QE ")); setRegLabels(2, QString("X ,X ,ECCS1 ,ECCS0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,X ,X ,X ,S0ES3 ,S0ES2 ,S0ES1 ,S0ES0 ")); setRegLabels(4, QString("X ,X ,X ,X ,S1ES3 ,S1ES2 ,S1ES1 ,S1ES0 ")); break; case 16: //Foressy2 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xd0; RegNumbers[4] = 0x10; // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BRWD ,BP3 ,BP2 ,BP1 ,BP0 ,TB ,X ,SP ")); setRegLabels(1, QString("OTP-L ,OTP-E ,X ,ECC-E ,X ,DRV1 ,DRV0 ,QE ")); setRegLabels(2, QString("X ,X ,ECCS1 ,ECCS0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,X ,X ,X ,X ,X ,X ,ECC-M ")); setRegLabels(4, QString("X ,X ,X ,X ,S0ES3 ,S0ES2 ,S0ES1 ,S0ES0 ")); break; case 17: //Gigadevice 3 RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xd0; RegNumbers[4] = 0xff; setRegDisabled(4); // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BWRD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,X ")); setRegLabels(1, QString("OTP-P ,OTP-E ,X ,ECC-E ,X ,X ,X ,QE ")); setRegLabels(2, QString("X ,ECC-2 ,ECC-1 ,ECC-0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,DS_S1 ,DS-S0 ,X ,X ,X ,X ,X ")); break; case 18: //Gigadevice 1, other Security registers RegNumbers[0] = 0xa0; RegNumbers[1] = 0xb0; RegNumbers[2] = 0xc0; RegNumbers[3] = 0xd0; RegNumbers[4] = 0xf0; // 7 6 5 4 3 2 1 0 setRegLabels(0, QString("BWRD ,X ,BP2 ,BP1 ,BP0 ,INV ,CMP ,X ")); setRegLabels(1, QString("OTP-P ,OTP-E ,X ,ECC-E ,X ,X ,X ,QE ")); setRegLabels(2, QString("X ,X ,ECC-1 ,ECC-0 ,P-FAIL,E-FAIL,WEL ,BUSY ")); setRegLabels(3, QString("X ,DS_S1 ,DS-S0 ,X ,X ,X ,X ,X ")); setRegLabels(4, QString("X ,X ,ECCS1 ,ECCS0 ,BPS ,X ,X ,X ")); break; } } void DialogNANDSr::allRegEnabled() { auto lineEdits = findChildren(); for (auto lineEdit : lineEdits) { lineEdit->setDisabled(false); } } void DialogNANDSr::clearAllFields() { auto lineEdits = findChildren(); for (auto lineEdit : lineEdits) { lineEdit->clear(); } } void DialogNANDSr::setRegDisabled(uint8_t regNumber) { QString searchTextE = "lineEdit_sr" + QString::number(regNumber) + "\\d+"; QString searchTextL = "label_" + QString::number(regNumber) + "\\d+"; QRegularExpression regexE(searchTextE); QRegularExpression regexL(searchTextL); for (QLineEdit* edit : findChildren()) { if (regexE.match(edit->objectName()).hasMatch()) { edit->setDisabled(true); } } for (QLabel* label : findChildren()) { if (regexL.match(label->objectName()).hasMatch()) { label->setText("X"); } } } void DialogNANDSr::setRegLabels(uint8_t regNumber, QString lt) { lt.replace(" ", ""); QStringList list = lt.split(","); int lastIndex = list.size() - 1; for (int i = 0; i <= lastIndex; ++i) { QString labelName = QString("label_") + QString::number(regNumber) + QString::number(i); if (QLabel* label = findChild(labelName)) { label->setText(list.at(lastIndex - i)); } } } QString DialogNANDSr::strtrip(const QString& str) { int n = str.size() - 1; for (; n >= 0; --n) { if (!str.at(n).isSpace()) { return str.left(n + 1); } } return ""; } void DialogNANDSr::setDeviceType(const uint8_t pType) { programmerType = pType; if (programmerType < 2) programmerName ="CH341A"; if (programmerType == 2) programmerName ="CH347T"; } imsprog-1.8.5/IMSProg_programmer/dialognandsr.h000066400000000000000000000030451520775651600215560ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2025 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef DIALOGNANDSR_H #define DIALOGNANDSR_H #include #include extern "C" { #include "ch341a_spi.h" #include "spi_controller.h" } namespace Ui { class DialogNANDSr; } class DialogNANDSr : public QDialog { Q_OBJECT public: explicit DialogNANDSr(QWidget *parent = nullptr); ~DialogNANDSr(); void setPattern(const uint pattern); void closeEvent(QCloseEvent* event); void setDeviceType(const uint8_t pType); signals: void closeRequestHasArrived(); private slots: void on_pushButton_read_clicked(); void on_pushButton_write_clicked(); private: Ui::DialogNANDSr *ui; void setLineEditFilter(); void allRegEnabled(); void setRegDisabled(uint8_t regNumber); void clearAllFields(); void setRegLabels(uint8_t regNumber, QString lt); QString strtrip(const QString& str); uint8_t RegNumbers[5]; bool regReaded; uint8_t programmerType; QString programmerName; }; #endif // DIALOGNANDSR_H imsprog-1.8.5/IMSProg_programmer/dialognandsr.ui000066400000000000000000002166031520775651600217520ustar00rootroot00000000000000 DialogNANDSr 0 0 800 535 800 0 Status registers :/res/img/write64.png:/res/img/write64.png 0 Status register 1 6 0 0 0 0 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 6 0 20 0 40 16777215 Ubuntu Mono 10 SRP0 Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 BP3 Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 BP2 Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 BP1 Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 BP0 Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 TB Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 WP-E Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 SRP1 Qt::AlignCenter 0 Status register 2 6 QLayout::SetDefaultConstraint 0 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 6 0 20 0 40 16777215 Ubuntu Mono 10 OTP-L Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 OTP-E Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 SR1-L Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 ECC-E Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 BUF Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 (R) Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 (R) Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 (R) Qt::AlignCenter 0 0 Status register 3 6 0 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 2 0 20 0 40 16777215 Ubuntu Mono 10 (R) Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 LUT-F Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 ECC-1 Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 ECC-0 Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 P-FAIL Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 WELL Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 BUSY Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 E_FAIL Qt::AlignCenter 0 Status register 4 0 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 6 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 6 Status register 5 0 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 6 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 --- Qt::AlignCenter Qt::Vertical 20 40 Unique ID: 0 34 Monospace 9 Qt::Vertical 20 40 0 80 23 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Read 80 23 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} QPushButton:!enabled { background-color:#ccc; } Write 6 Parameter page: 10 0 Monospace 9 true Manufacturer: Model: Page size: ECC size: Pages per block: Block per unit: Block size: Chip size: Qt::Vertical 20 40 imsprog-1.8.5/IMSProg_programmer/dialogrp.cpp000066400000000000000000000024511520775651600212450ustar00rootroot00000000000000/* * Copyright (C) 2023 Mikhail Medvedev * * * 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 3 * 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. */ #include "dialogrp.h" #include "ui_dialogrp.h" #include "mainwindow.h" #include #include #include #include DialogRP::DialogRP(QWidget *parent) : QDialog(parent), ui(new Ui::DialogRP) { ui->setupUi(this); setWindowFlags(Qt::Window| Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); QRegularExpression reHex( "[A-Fa-f0-9]{1,8}" ); QRegularExpressionValidator *validator = new QRegularExpressionValidator(reHex, this); ui->lineEditStart->setValidator(validator); } DialogRP::~DialogRP() { delete ui; } void DialogRP::on_pushButton_clicked() { addrData = QString(ui->lineEditStart->text()); emit sendAddr2(addrData); DialogRP::close(); } imsprog-1.8.5/IMSProg_programmer/dialogrp.h000066400000000000000000000017251520775651600207150ustar00rootroot00000000000000/* * Copyright (C) 2023 Mikhail Medvedev * * * 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. */ #ifndef DIALOGRP_H #define DIALOGRP_H #include #include namespace Ui { class DialogRP; } class DialogRP : public QDialog { Q_OBJECT public: explicit DialogRP(QWidget *parent = nullptr); ~DialogRP(); private slots: void on_pushButton_clicked(); signals: void sendAddr2(QString); private: Ui::DialogRP *ui; QString addrData; }; #endif // DIALOGRP_H imsprog-1.8.5/IMSProg_programmer/dialogrp.ui000066400000000000000000000061641520775651600211050ustar00rootroot00000000000000 DialogRP 0 0 269 121 50 false Load block from file :/res/img/write64.png:/res/img/write64.png 12 All values in HEX format! Qt::AlignCenter 13 Start address: 120 0 75 true 31 9 Qt::Horizontal 128 20 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Load imsprog-1.8.5/IMSProg_programmer/dialogsecurity.cpp000066400000000000000000000451521520775651600225000ustar00rootroot00000000000000/* * Copyright (C) 2025 Mikhail Medvedev * * * 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 3 * 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. */ #include "dialogsecurity.h" #include "ui_dialogsecurity.h" #include "mainwindow.h" #include #include #include "qhexedit.h" #include "spi_controller.h" DialogSecurity::DialogSecurity(QWidget *parent) : QDialog(parent), ui(new Ui::DialogSecurity) { ui->setupUi(this); setWindowFlags(Qt::Window| Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); programmerType = 0; } DialogSecurity::~DialogSecurity() { delete ui; } void DialogSecurity::setAlgorithm(uint8_t currentAlg) { //init variables int i; securCommands comPattern[] = { // id RDSCUR WRSCUR ERSCUR ENSO EXSO DUMRD { 0, 0, 0, 0, 0, 0, 0}, { 1, 0x48, 0x42, 0x44, 0, 0, 1}, //Winbond, Gigadevice, Boya, UCUNDATA, Fudan, Zetta, Zbit, XMC { 2, 0x03, 0x02, 0x20, 0x3a, 0x04, 0}, //EON { 3, 0x68, 0x62, 0x64, 0, 0, 1}, //ISSI { 4, 0x03, 0x02, 0x00, 0xb1, 0xc1, 0}, //MXIC, Fidelix, Zetta { 5, 0x4b, 0xb1, 0x00, 0, 0, 0}, //PFlash }; algSettings algSet[] = { // id algType RegNum Size rg0add rg1add rg2add rg3add allErase a4byte curCommand { 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //Don't have security registers { 0x01, 0, 4, 4, 0x0000, 0x0001, 0x0010, 0x0011, 0, 0, 1}, //Fudan { 0x02, 0, 3, 8, 0x0010, 0x0020, 0x0030, 0, 0, 0, 1}, //Boya, Gigadevice, Zetta, Puya { 0x03, 0, 3, 4, 0x0010, 0x0020, 0x0030, 0, 0, 0, 1}, //Winbond, Boya, UCUNDATA, Zetta, Zbit, XMC, Spansion { 0x04, 0, 3, 16, 0x0010, 0x0020, 0x0030, 0, 0, 0, 1}, //Gigadevice, Boya, UCUNDATA, Zetta, Puya, Zbit, XMC, XTX { 0x05, 1, 3, 8, 0x3fd0, 0x3fe0, 0x3ff0, 0, 0, 0, 2}, //EON EN25QH32B { 0x06, 0, 3, 4, 0x0010, 0x0020, 0x0030, 0, 0, 1, 1}, //Winbond, Gigadevice { 0x07, 0, 2, 4, 0x0010, 0x0020, 0, 0, 0, 0, 1}, //UCUNDATA { 0x08, 0, 4, 4, 0x0000, 0x0001, 0x0002, 0x0003, 1, 0, 1}, //Gigadevice { 0x09, 0, 2, 16, 0x0020, 0x0030, 0, 0, 0, 0, 1}, //Gigadevice { 0x0a, 0, 1, 16, 0x0000, 0, 0, 0, 1, 0, 1}, //Fudan { 0x0b, 0, 1, 8, 0x0000, 0, 0, 0, 0, 0, 1}, //Gigadevice { 0x0c, 0, 4, 4, 0x0000, 0x0010, 0x0020, 0x0030, 0, 0, 1}, //Winbond { 0x0d, 1, 1, 8, 0x1ff0, 0, 0, 0, 0, 0, 2}, //EON EN25QH16B { 0x0e, 0, 3, 8, 0x0010, 0x0020, 0x0030, 0, 0, 1, 1}, //Boya { 0x0f, 0, 2, 16, 0x0000, 0x0010, 0, 0, 0, 0, 1}, //Gigadevice { 0x10, 0, 4, 4, 0x0000, 0x0001, 0x0002, 0x0003, 1, 0, 1}, //Fudan, XTX { 0x11, 0, 4, 4, 0x0000, 0x0010, 0x0020, 0x0030, 0, 0, 3}, //ISSI { 0x12, 1, 1, 8, 0x0000, 0, 0, 0, 0, 0, 4}, //Fidelix, Zetta { 0x13, 0, 3, 4, 0x0040, 0x0080, 0x00c0, 0, 0, 0, 1}, //CXF { 0x14, 0, 2, 16, 0x0010, 0x0020, 0, 0, 0, 0, 1}, //XTX { 0x15, 0, 2, 4, 0x0000, 0x0001, 0, 0, 0, 0, 1}, //XTX { 0x16, 1, 1, 8, 0x0000, 0, 0, 0, 0, 0, 4}, //MXIC { 0x17, 1, 1, 1, 0x0000, 0, 0, 0, 0, 0, 4}, //MXIC { 0x18, 1, 2, 8, 0x0000, 0x0020, 0, 0, 0, 0, 4}, //MXIC { 0x19, 0, 3, 16, 0x0010, 0x0020, 0x0030, 0, 0, 1, 1}, //Boya { 0x1a, 0, 1, 64, 0x0000, 0, 0, 0, 0, 1, 1}, //Gigadevice { 0x1b, 0, 3, 64, 0x0010, 0x0020, 0x0030, 0, 0, 1, 1}, //Gigadevice { 0x1c, 0, 3, 16, 0x0000, 0x0004, 0x0008, 0, 0, 0, 1}, //Giantec GT25Q32A { 0x1d, 0, 3, 16, 0x0000, 0x0008, 0x0010, 0, 0, 0, 1}, //Giantec GT25Q64A { 0x1e, 0, 1, 1, 0x0000, 0, 0, 0, 0, 0, 5}, //Pm25LQ032 { 0x1f, 0, 2, 16, 0x0010, 0x0020, 0, 0, 0, 1, 1}, //XTX }; curAlg = currentAlg; curSettings = algSet[curAlg]; curCommands = comPattern[curSettings.curCommand]; if (curCommands.ERSCUR == 0) ui->toolButton_erase->setDisabled(true); else ui->toolButton_erase->setDisabled(false); if (curAlg > 0) { for (i=1; i <= curSettings.regNumber; i++) { ui->comboBox_regnum->addItem(QString::number(i),i); } regData.reserve(2048); regData.resize(curSettings.size * 64); regData.fill(char(0xff)); QFont heFont; heFont = QFont("Monospace", 10); hexEdit = new QHexEdit(ui->frame); hexEdit->setGeometry(0, 0, ui->frame->width(), ui->frame->height()); hexEdit->setData(regData); hexEdit->setHexCaps(true); hexEdit->setFont(heFont); hexEdit->setData(regData); } } void DialogSecurity::on_toolButton_read_clicked() { int retval, i; if (curSettings.id > 0) { std::shared_ptr buf(new uint8_t[curSettings.size * 64]); uint8_t a23a16 = 0, a15a08 = 0; uint16_t curRgAddr = 0; int stCH341 = 0; uint8_t curRegister = static_cast(ui->comboBox_regnum->currentData().toUInt()); curRegister--; stCH341 = ProgDeviceInit(programmerType, 0, 1); if (stCH341 == 0) { if (curRegister == 0) curRgAddr = curSettings.rg0addr; if (curRegister == 1) curRgAddr = curSettings.rg1addr; if (curRegister == 2) curRgAddr = curSettings.rg2addr; if (curRegister == 3) curRgAddr = curSettings.rg3addr; a23a16 = static_cast(curRgAddr >> 8); a15a08 = static_cast(curRgAddr & 0x00ff); if (curSettings.algType == 1) { //Enter OTP mode SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(curCommands.ENSO, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } if (curSettings.a4byte == 1) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0xb7, programmerType); // Enter 4 byte mode SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(curCommands.RDSCUR, programmerType); //Reading SR command if (curSettings.a4byte == 1) SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); //A32...A24 SPI_CONTROLLER_Write_One_Byte(a23a16, programmerType); //A23...A16 SPI_CONTROLLER_Write_One_Byte(a15a08, programmerType); //A15...A08 SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); //A07...A00 if (curCommands.DUMRD == 1) SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); //Dummy byte retval = SPI_CONTROLLER_Read_NByte(buf.get(), curSettings.size * 64, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if (curSettings.algType == 1) { //Exit OTP mode SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(curCommands.EXSO, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading register!")); return; } for (i = 0; i < curSettings.size * 64; i++) { regData[i] = char(buf[i]); } hexEdit->setData(regData); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); ProgDeviceClose(programmerType); } } void DialogSecurity::on_toolButton_write_clicked() { int retval, i, j = 1, k; if (curSettings.id > 0) { uint8_t a23a16 = 0, a15a08 = 0; uint16_t curRgAddr = 0; uint8_t sr = 0; std::shared_ptr buf(new uint8_t[curSettings.size * 64]); int stCH341 = 0; uint8_t curRegister = static_cast(ui->comboBox_regnum->currentData().toUInt()); curRegister--; stCH341 = ProgDeviceInit(programmerType, 0, 1); if (stCH341 == 0) { if (curRegister == 0) curRgAddr = curSettings.rg0addr; if (curRegister == 1) curRgAddr = curSettings.rg1addr; if (curRegister == 2) curRgAddr = curSettings.rg2addr; if (curRegister == 3) curRgAddr = curSettings.rg3addr; a23a16 = static_cast(curRgAddr >> 8); a15a08 = static_cast(curRgAddr & 0x00ff); if (curSettings.size * 64 > 256) j = curSettings.size / 4; else j = 1; if (curSettings.a4byte == 1) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0xb7, programmerType); // Enter 4 byte mode SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } regData = hexEdit->data(); for (i = 0; i < curSettings.size * 64; i++) { buf[i] = static_cast(regData[i]); } for (k = 0; k < j; k++) { if (curSettings.algType == 1) { //Enter OTP mode SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(curCommands.ENSO, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); // Write Enable SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(curCommands.WRSCUR, programmerType); // Write SR command if (curSettings.a4byte == 1) SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); //A32...A24 SPI_CONTROLLER_Write_One_Byte(a23a16, programmerType); //A23...A16 SPI_CONTROLLER_Write_One_Byte(a15a08, programmerType); //A15...A08 SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); //A07...A00 if (curSettings.size < 4) retval = SPI_CONTROLLER_Write_NByte(buf.get(), curSettings.size * 64, SPI_CONTROLLER_SPEED_SINGLE, programmerType); else retval = SPI_CONTROLLER_Write_NByte(buf.get(), 256, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error writing register!")); return; } if (curSettings.size > 3) { for (i = 0; i < 256; i++) { buf[i] = buf[i + 256 * (k +1)]; } } a15a08++; for (i = 0; i < 256; i++) { usleep(3); SPI_CONTROLLER_Chip_Select_Low(programmerType); // waiting for WIP bit is set to zero SPI_CONTROLLER_Write_One_Byte(0x05, programmerType); SPI_CONTROLLER_Read_NByte(&sr,1,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if ((sr & 0x01) == 0) break; } if (curSettings.algType == 1) { //Exit OTP mode SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(curCommands.EXSO, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); // Write Disable SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); ProgDeviceClose(programmerType); } } void DialogSecurity::on_toolButton_erase_clicked() { int stCH341 = 0; uint8_t curRegister = static_cast(ui->comboBox_regnum->currentData().toUInt()); curRegister--; uint8_t a23a16 = 0, a15a08 = 0; uint16_t curRgAddr = 0; stCH341 = ProgDeviceInit(programmerType, 0, 1); if (stCH341 == 0) { if (curRegister == 0) curRgAddr = curSettings.rg0addr; if (curRegister == 1) curRgAddr = curSettings.rg1addr; if (curRegister == 2) curRgAddr = curSettings.rg2addr; if (curRegister == 3) curRgAddr = curSettings.rg3addr; a23a16 = static_cast(curRgAddr >> 8); a15a08 = static_cast(curRgAddr & 0x00ff); if (curSettings.algType == 1) { //Enter OTP mode SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(curCommands.ENSO, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); // Write Enable SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if (curSettings.a4byte == 1) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0xb7, programmerType); // Enter 4 byte mode SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(curCommands.ERSCUR, programmerType); // Erase SR command if (curSettings.a4byte == 1) SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); //A32...A24 SPI_CONTROLLER_Write_One_Byte(a23a16, programmerType); //A23...A16 if (curSettings.allErase == 0) { SPI_CONTROLLER_Write_One_Byte(a15a08, programmerType); } else SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); //A7...A0 SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if (curSettings.algType == 1) { //Exit OTP mode SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(curCommands.EXSO, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); // Write Disable SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); ProgDeviceClose(programmerType); } void DialogSecurity::setPath(QString lastPath) { curPath = lastPath; } void DialogSecurity::on_toolButton_open_clicked() { QByteArray buf; QString fileName; fileName = QFileDialog::getOpenFileName(this, QString(tr("Open file")), curPath, "Data Images (*.bin *.BIN *.rom *.ROM);;All files (*.*)"); QFileInfo info(fileName); curPath = info.filePath(); QFile file(fileName); if (info.size() > curSettings.size * 64 ) { QMessageBox::about(this, tr("Error"), tr("The file size exceeds the security register size.")); return; } if (!file.open(QIODevice::ReadOnly)) { return; } buf.resize(static_cast(info.size())); buf = file.readAll(); regData.replace(0, static_cast(info.size()), buf); hexEdit->setData(regData); file.close(); // path must be transfered to mainwindow } void DialogSecurity::on_toolButton_save_clicked() { QString fileName; fileName = QFileDialog::getSaveFileName(this, QString(tr("Save file")), curPath, "Data Images (*.bin *.BIN);;All files (*.*)"); if (fileName.isEmpty()) return; QFileInfo info(fileName); curPath = info.filePath(); if (QString::compare(info.suffix(), "bin", Qt::CaseInsensitive)) fileName = fileName + ".bin"; QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) { QMessageBox::about(this, tr("Error"), tr("Error saving file!")); return; } file.write(hexEdit->data()); file.close(); // path must be transfered to mainwindow } void DialogSecurity::closeEvent(QCloseEvent* event) { emit closeRequestHasArrived(); QWidget::closeEvent(event); } void DialogSecurity::setDeviceType(const uint8_t pType) { programmerType = pType; if (programmerType < 2) programmerName ="CH341A"; if (programmerType == 2) programmerName ="CH347T"; } imsprog-1.8.5/IMSProg_programmer/dialogsecurity.h000066400000000000000000000056011520775651600221400ustar00rootroot00000000000000/* * Copyright (C) 2025 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef DIALOGSECURITY_H #define DIALOGSECURITY_H #include #include "qhexedit.h" extern "C" { #include "ch341a_spi.h" #include "spi_controller.h" } namespace Ui { class DialogSecurity; } class DialogSecurity : public QDialog { Q_OBJECT public: explicit DialogSecurity(QWidget *parent = nullptr); void setAlgorithm(uint8_t currentAlg); void setPath(QString lastPath); void closeEvent(QCloseEvent* event); void setDeviceType(const uint8_t pType); ~DialogSecurity(); private slots: void on_toolButton_read_clicked(); void on_toolButton_write_clicked(); void on_toolButton_erase_clicked(); void on_toolButton_open_clicked(); void on_toolButton_save_clicked(); signals: void closeRequestHasArrived(); private: Ui::DialogSecurity *ui; struct algSettings { uint8_t id; // Algirithm number bool algType; // 0 - default with 0x48, 0x42, 0x44 commands // 1 - with OTP mode and standart write/read commands uint8_t regNumber; // Number of registers by chip (1...4) uint8_t size; // size*64 = size of register bytes; uint16_t rg0addr; // register 0 address / enter OTP mode uint16_t rg1addr; // register 1 address / exit OTP mode uint16_t rg2addr; // register 2 address uint16_t rg3addr; // register 3 address bool allErase; // 1 - zero code for erasing all registers, 0 - none; bool a4byte; // 1 - 32 bit addressing using, 0 - 24 bit address using uint8_t curCommand; // Current command pattern }; struct securCommands { uint8_t id; // Pattern number uint8_t RDSCUR; // Read security register command uint8_t WRSCUR; // Write security register command uint8_t ERSCUR; // Erase cecurity register command uint8_t ENSO; // Enter secured OTP mode command uint8_t EXSO; // Exit secured OTP mode command bool DUMRD; // Dummy Byte on read cycle 1 - enable, 0 - disable }; uint8_t curAlg; securCommands comPattern; algSettings curSettings; securCommands curCommands; QByteArray regData; QHexEdit *hexEdit; QString curPath; uint8_t programmerType; QString programmerName; }; #endif // DIALOGSECURITY_H imsprog-1.8.5/IMSProg_programmer/dialogsecurity.ui000066400000000000000000000176161520775651600223370ustar00rootroot00000000000000 DialogSecurity 0 0 661 523 Security registers :/res/img/write64.png:/res/img/write64.png Hex Editor QLayout::SetMaximumSize 610 350 QFrame::StyledPanel QFrame::Raised 0 100 16777215 100 Operations: 10 6 6 48 48 48 48 Reading security register data from the chip ... :/res/img/read64.png:/res/img/read64.png 48 48 48 48 48 48 Erasing security register data ... :/res/img/erase64.png:/res/img/erase64.png 48 48 48 48 48 48 Writing data to the security register ... :/res/img/write64.png:/res/img/write64.png 48 48 Qt::Vertical 48 48 48 48 Open a binary file from a computer ... :/res/img/open64.png:/res/img/open64.png 48 48 48 48 48 48 Save the binary file on the computer ... :/res/img/save64.png:/res/img/save64.png 48 48 Qt::Vertical Security register number: imsprog-1.8.5/IMSProg_programmer/dialogsetaddr.cpp000066400000000000000000000025611520775651600222540ustar00rootroot00000000000000/* * Copyright (C) 2024 Mikhail Medvedev * * * 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 3 * 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. */ #include "dialogsetaddr.h" #include "ui_dialogsetaddr.h" #include #include #include DialogSetAddr::DialogSetAddr(QWidget *parent) : QDialog(parent), ui(new Ui::DialogSetAddr) { ui->setupUi(this); setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); QRegularExpression reHex("[A-Fa-f0-9]{1,8}"); QRegularExpressionValidator *validator = new QRegularExpressionValidator(reHex, this); ui->lineEditStart->setValidator(validator); } DialogSetAddr::~DialogSetAddr() { delete ui; } void DialogSetAddr::on_pushButton_clicked() { bool ok; QString str = ui->lineEditStart->text(); qint64 inputAddr = str.toUInt(&ok, 16); emit sendAddr3(inputAddr); DialogSetAddr::close(); //return inputAddr; } imsprog-1.8.5/IMSProg_programmer/dialogsetaddr.h000066400000000000000000000017231520775651600217200ustar00rootroot00000000000000/* * Copyright (C) 2024 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef DIALOGSETADDR_H #define DIALOGSETADDR_H #include namespace Ui { class DialogSetAddr; } class DialogSetAddr : public QDialog { Q_OBJECT public: explicit DialogSetAddr(QWidget *parent = nullptr); ~DialogSetAddr(); private slots: void on_pushButton_clicked(); signals: void sendAddr3(qint64); private: Ui::DialogSetAddr *ui; }; #endif // DIALOGSETADDR_H imsprog-1.8.5/IMSProg_programmer/dialogsetaddr.ui000066400000000000000000000057011520775651600221060ustar00rootroot00000000000000 DialogSetAddr 0 0 272 99 Goto address :/res/img/write64.png:/res/img/write64.png All values in HEX format! Qt::AlignCenter 13 Address: 120 0 75 true 31 9 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Go to Qt::Horizontal 128 20 imsprog-1.8.5/IMSProg_programmer/dialogsfdp.cpp000066400000000000000000000465441520775651600215730ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2025 Mikhail Medvedev * * * 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 3 * 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. */ #include "dialogsfdp.h" #include "ui_dialogsfdp.h" #include #include #include "unistd.h" #include "memory" #include #include #include "hexutility.h" DialogSFDP::DialogSFDP(QWidget *parent) : QDialog(parent), ui(new Ui::DialogSFDP) { ui->setupUi(this); setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); setLineEditFilter(); setRegStatus(1, true); numOfRegisters = 3; // 3-not reading, 2 - three registers, 1 - two registers, 0 - one register programmerType = 0; } DialogSFDP::~DialogSFDP() { delete ui; } void DialogSFDP::legendPrint(QString basic, QString extended, QString manufacture) { QString l0 ="", l1="", l2="", l3="", h0="", h1="", h2="", h3="", h4=""; l0.append(QString(tr("Legend:"))); l1.append(QString(tr(" - Basic area"))); l2.append(QString(tr(" - Extended area"))); l3.append(QString(tr(" - Manufacture area"))); h0.append(QString("")); h1.append(QString("

" + l0 + "

")); h2.append(QString("
")); h3.append(QString("
")); h4.append(QString("

")); ui->label_9->setText(h1 + basic + h0 + l1 + h2 + extended + h0 + l2 + h3 + manufacture + h0 + l3 + h4); } void DialogSFDP::on_pushButton_clicked() { int stCH341 = 0; uint64_t sfdpSize = 0; uint32_t sfdpBlockSize = 0; bool sfdpSupport = false; unsigned char i, imax, twoAreaAddress=0xff, manufAreaAddress=0xff, twoAreaLen = 0xff, manAreaLen = 0xff; uint8_t jedecMan=0xff, idSize; std::shared_ptr sfdpBuf(new uint8_t[256]); QString regData = "", VCCmin = "", VCCmax = "", speeds = "Single", addrTxt=""; int retval = 0; stCH341 = ProgDeviceInit(programmerType, 0, 1); ui->lineEdit_vcc_max->setText(""); ui->lineEdit_vcc_min->setText(""); ui->lineEdit_block->setText(""); ui->lineEdit_size->setText(""); ui->lineEdit_speeds->setText(""); ui->lineEdit_otp->setText(""); legendPrint("**", "**", "**"); if (stCH341 == 0) { //Reading JEDEC ID SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x9f, programmerType); retval = SPI_CONTROLLER_Read_NByte(sfdpBuf.get(),3,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading JEDEC ID!")); return; } jedecMan = sfdpBuf[0]; ui->lineEdit_jedec0->setText(bytePrint(sfdpBuf[0])); ui->lineEdit_jedec1->setText(bytePrint(sfdpBuf[1])); ui->lineEdit_jedec2->setText(bytePrint(sfdpBuf[2])); // Reading SFDP. Transfer to ch341 0x5a SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x5a, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); retval = SPI_CONTROLLER_Read_NByte(sfdpBuf.get(),256,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading register!")); return; } //Analyse-parsing SFDP if ((sfdpBuf[0] == 0x53) && (sfdpBuf[1] == 0x46) && (sfdpBuf[2] == 0x44) && (sfdpBuf[3] == 0x50)) { ui->lineEdit_sfdp->setText("Yes"); sfdpSupport = true; } else { ui->lineEdit_sfdp->setText("No"); sfdpSupport = false; ui->label->setText(""); ui->label_10->setText(""); } if (sfdpSupport) { if ((sfdpBuf[0x80] == 0x53) && (sfdpBuf[0x81] == 0x46) && (sfdpBuf[0x82] == 0x44) && (sfdpBuf[0x83] == 0x50)) imax = 127; else imax = 254; twoAreaAddress = sfdpBuf[0x0c]; twoAreaLen = sfdpBuf[0x0b] * 4; if (jedecMan == sfdpBuf[0x10]) { manufAreaAddress = sfdpBuf[0x14]; manAreaLen = sfdpBuf[0x13] * 4; } else { manufAreaAddress = sfdpBuf[0x1c]; manAreaLen = sfdpBuf[0x1b] * 4; } if (manufAreaAddress != 0xff) { if ((sfdpBuf[manufAreaAddress] != 0xff) && (sfdpBuf[manufAreaAddress + 1] != 0xff)) { VCCmax = bytePrint(sfdpBuf[manufAreaAddress + 1]) + bytePrint(sfdpBuf[manufAreaAddress]); VCCmin = bytePrint(sfdpBuf[manufAreaAddress + 3]) + bytePrint(sfdpBuf[manufAreaAddress + 2]); VCCmax.insert(1, "."); VCCmin.insert(1, "."); ui->lineEdit_vcc_max->setText(VCCmax); ui->lineEdit_vcc_min->setText(VCCmin); } if (sfdpBuf[manufAreaAddress + 9] != 0xff) { if ((sfdpBuf[manufAreaAddress + 9] & 0x08) != 0) ui->lineEdit_otp->setText("Yes"); if ((sfdpBuf[manufAreaAddress + 9] & 0x08) == 0) ui->lineEdit_otp->setText("No"); } else ui->lineEdit_otp->setText(""); } else { ui->lineEdit_vcc_max->setText(""); ui->lineEdit_vcc_min->setText(""); } sfdpSize = (sfdpBuf[twoAreaAddress + 4] + sfdpBuf [twoAreaAddress +5] * 256 + sfdpBuf[twoAreaAddress +6] * 256 * 256 + sfdpBuf[twoAreaAddress + 7] * 256 * 256 * 256 + 1) /8 /1024 ; ui->lineEdit_size->setText(QString::number(sfdpSize) + " K"); if (sfdpBuf[twoAreaAddress + 0x20] != 0xff) { sfdpBlockSize = (1 << sfdpBuf[twoAreaAddress + 0x20]) / 1024; ui->lineEdit_block->setText(QString::number(sfdpBlockSize) + " K"); } else { ui->lineEdit_block->setText(""); } if (sfdpBuf[twoAreaAddress + 0x0f] == 0xbb) speeds = speeds + "/Dual"; if (sfdpBuf[twoAreaAddress + 0x09] == 0xeb) speeds = speeds + "/Quad"; ui->lineEdit_speeds->setText(speeds); legendPrint("00", bytePrint(twoAreaAddress), bytePrint(manufAreaAddress)); //HEXDUMP regData = tr("

Hex SFDP register data:\n"); addrTxt = tr("

Addr:
"); for (i=0; i<232;i=i+16) { addrTxt = addrTxt + "0" + bytePrint(i) + ">
"; } addrTxt = addrTxt + "0F0>

"; ui->label_10->setText(addrTxt); for (i=0;i<=imax;i++) { if (i % 16 == 0) regData = regData + "
"; if (i == 0x0c) regData = regData + ""; if (i == 0x0d) regData = regData + ""; if ((i == 0x14) && (jedecMan == sfdpBuf[0x10]) && (sfdpBuf[0x06] !=0)) regData = regData + ""; if ((i == 0x15) && (jedecMan == sfdpBuf[0x10]) && (sfdpBuf[0x06] !=0)) regData = regData + ""; if ((i == 0x1c) && (jedecMan != sfdpBuf[0x10]) && (sfdpBuf[0x06] !=0)) regData = regData + ""; if ((i == 0x1d) && (jedecMan != sfdpBuf[0x10]) && (sfdpBuf[0x06] !=0)) regData = regData + ""; if (i == twoAreaAddress) regData = regData + ""; if (i == twoAreaAddress + twoAreaLen) regData = regData + ""; if (i == manufAreaAddress) regData = regData + ""; if (i == manufAreaAddress + manAreaLen) regData = regData + ""; regData = regData + bytePrint(sfdpBuf[i]) + " "; } regData = regData + "

"; ui->label->setText(regData); } //READING STATUS REGISTER 0 SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x05, programmerType); retval = SPI_CONTROLLER_Read_NByte(sfdpBuf.get(),2,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading register!")); return; } printRegData(0, sfdpBuf[0]); //READING STATUS REGISTER 1 numOfRegisters = 0; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x35, programmerType); retval = SPI_CONTROLLER_Read_NByte(sfdpBuf.get(),2,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading register!")); return; } if (sfdpBuf[0] != 0xff) { numOfRegisters++; setRegStatus(1, true); printRegData(1, sfdpBuf[0]); } else setRegStatus(1, false); //READING STATUS REGISTER 2 SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x15, programmerType); retval = SPI_CONTROLLER_Read_NByte(sfdpBuf.get(),2,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading register!")); return; } if (sfdpBuf[0] != 0xff) { numOfRegisters++; setRegStatus(2, true); printRegData(2,sfdpBuf[0]); } else setRegStatus(2, false); //Reading Unique ID SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x4b, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); retval = SPI_CONTROLLER_Read_NByte(sfdpBuf.get(),16,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading unique ID!")); return; } if ((sfdpBuf[0x00] == sfdpBuf[0x08]) && (sfdpBuf[0x01] == sfdpBuf[0x09]) && (sfdpBuf[0x02] == sfdpBuf[0x0a]) && (sfdpBuf[0x03] == sfdpBuf[0x0b])) idSize = 8; else idSize = 16; regData = ""; for (i=0; ilineEdit_chipid->setText(regData); //Close the CH341a device ProgDeviceClose(programmerType); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); } void DialogSFDP::on_pushButton_2_clicked() { DialogSFDP::close(); } void DialogSFDP::on_pushButton_3_clicked() { if (numOfRegisters < 3) { int stCH341 = 0; stCH341 = ProgDeviceInit(programmerType, 0, 1); if (stCH341 == 0) { //scanning data from the form uint8_t r[3], k, i; int j; r[0] = 0; r[1] = 0; r[2] = 0; for (k = 0; k < 3; k++) { i = 128; for (j = 7; j >= 0; j--) { QString currRegName = "lineEdit_sr" + QString::number(k) + QString::number(j); for (QLineEdit* edit : findChildren()) { if (edit->objectName() == currRegName) { if (QString::compare(edit->text(), "0", Qt::CaseInsensitive)) r[k] = r[k] + i; i = i / 2; } } } } //Writing status registers 0,1 for Winbond SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x50, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x01, programmerType); SPI_CONTROLLER_Write_One_Byte(r[0], programmerType); if (numOfRegisters > 0) SPI_CONTROLLER_Write_One_Byte(r[1], programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); //Close the CH341a device ProgDeviceClose(programmerType); //Writing status registers 0,1 for not Winbond if (numOfRegisters > 0) { stCH341 = ProgDeviceInit(programmerType, 0, 1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x50, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x01, programmerType); SPI_CONTROLLER_Write_One_Byte(r[0], programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); //Close the CH341a device ProgDeviceClose(programmerType); usleep(1); stCH341 = ProgDeviceInit(programmerType, 0, 1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x50, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x31, programmerType); SPI_CONTROLLER_Write_One_Byte(r[1], programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); //Close the CH341a device ProgDeviceClose(programmerType); } //Writing status register 2 if (numOfRegisters > 1) { stCH341 = ProgDeviceInit(programmerType, 0, 1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x50, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x11, programmerType); SPI_CONTROLLER_Write_One_Byte(r[2], programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); //Close the CH341a device ProgDeviceClose(programmerType); } } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); } else QMessageBox::about(this, tr("Error"), tr("Before writing the registers, please press the `Read` button!")); } void DialogSFDP::setLineEditFilter() { QRegularExpression reHex( "[0-1]{1}"); QRegularExpressionValidator *validator = new QRegularExpressionValidator(reHex, this); //searching all lineEdit_srXX, XX - numbers QString searchText = "lineEdit_sr\\d+"; QRegularExpression regex(searchText); for (QLineEdit* edit : findChildren()) { if (regex.match(edit->objectName()).hasMatch()) { edit->setValidator(validator); } } } void DialogSFDP:: setRegStatus(uint8_t regNumber, bool state) { QString searchText = "lineEdit_sr" + QString::number(regNumber) + "\\d+"; QRegularExpression regex(searchText); for (QLineEdit* edit : findChildren()) { if (regex.match(edit->objectName()).hasMatch()) { if (state == false) { edit->setDisabled(true); edit->setText(""); } else { edit->setDisabled(false); } } } if (state == true) { if (regNumber == 1) ui->label_11->setDisabled(false); if (regNumber == 2) ui->label_34->setDisabled(false); } else { if (regNumber == 1) ui->label_11->setDisabled(true); if (regNumber == 2) ui->label_34->setDisabled(true); } } void DialogSFDP::closeEvent(QCloseEvent* event) { emit closeRequestHasArrived(); QWidget::closeEvent(event); } void DialogSFDP::printRegData(uint8_t regNumber, uint8_t regData) { uint8_t i; int j; i = 128; for (j = 7; j >= 0; j--) { QString currRegName = "lineEdit_sr" + QString::number(regNumber) + QString::number(j); for (QLineEdit* edit : findChildren()) { if (edit->objectName() == currRegName) { edit->setText(QString::number(((regData & i) >> j))); } } i = i / 2; } } void DialogSFDP::setDeviceType(const uint8_t pType) { programmerType = pType; if (programmerType < 2) programmerName ="CH341A"; if (programmerType == 2) programmerName ="CH347T"; } imsprog-1.8.5/IMSProg_programmer/dialogsfdp.h000066400000000000000000000030261520775651600212240ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2025 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef DIALOGSFDP_H #define DIALOGSFDP_H #include #include #include "hexutility.h" extern "C" { #include "ch341a_spi.h" #include "ch347.h" #include "spi_controller.h" } namespace Ui { class DialogSFDP; } class DialogSFDP : public QDialog { Q_OBJECT public: explicit DialogSFDP(QWidget *parent = nullptr); ~DialogSFDP(); void closeEvent(QCloseEvent* event); void setDeviceType(const uint8_t pType); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); void on_pushButton_3_clicked(); void setRegStatus(uint8_t regNumber, bool state); void printRegData(uint8_t regNumber, uint8_t regData); signals: void closeRequestHasArrived(); private: Ui::DialogSFDP *ui; void setLineEditFilter(); void legendPrint(QString basic, QString extended, QString manufacture); int numOfRegisters; uint8_t programmerType; QString programmerName; }; #endif // DIALOGSFDP_H imsprog-1.8.5/IMSProg_programmer/dialogsfdp.ui000066400000000000000000001401641520775651600214170ustar00rootroot00000000000000 DialogSFDP 0 0 874 515 Information about SFDP and status registers :/res/img/write64.png:/res/img/write64.png QLayout::SetMinimumSize QLayout::SetMinimumSize Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 6 6 6 6 SFDP support: 75 true Minimum VCC: 75 true Maximum VCC: 75 true Chip size: 75 true Block size: 75 true Speeds: 75 true OTP support: 130 0 75 true Status Register 0 2 QLayout::SetMaximumSize 0 0 0 0 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 2 0 20 0 Ubuntu Mono 10 SPR0 Qt::AlignCenter 20 0 Ubuntu Mono 10 BP4 Qt::AlignCenter 20 0 Ubuntu Mono 10 BP3 Qt::AlignCenter 20 0 Ubuntu Mono 10 BP2 Qt::AlignCenter 20 0 Ubuntu Mono 10 BP1 Qt::AlignCenter 20 0 Ubuntu Mono 10 BP0 Qt::AlignCenter 20 0 Ubuntu Mono 10 WEL Qt::AlignCenter 20 0 Ubuntu Mono 10 WIP Qt::AlignCenter Status Register 1 2 QLayout::SetMaximumSize 0 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 2 0 20 0 Ubuntu Mono 10 SUS1 Qt::AlignCenter 20 0 Ubuntu Mono 10 CMP Qt::AlignCenter 20 0 Ubuntu Mono 10 LB3 Qt::AlignCenter 20 0 Ubuntu Mono 10 LB2 Qt::AlignCenter 20 0 Ubuntu Mono 10 LB1 Qt::AlignCenter 20 0 Ubuntu Mono 10 SUS2 Qt::AlignCenter 20 0 Ubuntu Mono 10 QE Qt::AlignCenter 20 0 Ubuntu Mono 10 SPR1 Qt::AlignCenter Status register 2 2 QLayout::SetMaximumSize 0 28 0 75 true Qt::AlignCenter 28 0 0 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter 28 0 75 true Qt::AlignCenter JEDEC info: 2 QLayout::SetMaximumSize 0 60 0 75 true Qt::AlignCenter 60 0 75 true Qt::AlignCenter 60 0 75 true Qt::AlignCenter 2 0 70 0 Ubuntu Mono 10 Man. ID Qt::AlignCenter 70 0 Ubuntu Mono 10 Man. type Qt::AlignCenter 70 0 Ubuntu Mono 10 Capacity Qt::AlignCenter Unique ID: 130 0 75 true 80 23 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Read 160 23 160 23 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Write registers 2 0 20 0 Ubuntu Mono 10 (R) Qt::AlignCenter 20 0 Ubuntu Mono 10 DRV1 Qt::AlignCenter 20 0 Ubuntu Mono 10 DRV0 Qt::AlignCenter 20 0 Ubuntu Mono 10 (R) Qt::AlignCenter 20 0 Ubuntu Mono 10 (R) Qt::AlignCenter 20 0 Ubuntu Mono 10 WPS Qt::AlignCenter 20 0 Ubuntu Mono 10 ADP Qt::AlignCenter 20 0 Ubuntu Mono 10 ADS Qt::AlignCenter QLayout::SetMinimumSize 6 6 6 6 QLayout::SetMaximumSize 36 0 16777215 16777215 Monospace 10 PreferDefault Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 420 0 16777213 16777215 Monospace 10 Qt::LeftToRight <html><head/><body><p/></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop QLayout::SetMinimumSize Qt::Vertical 20 40 16777215 105 <html><head/><body><p>Legend:</p><p>** - Basic area<br>** - Extended area<br>** - Manufacture area </p></body></html> Qt::Vertical 20 20 80 23 80 23 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Close imsprog-1.8.5/IMSProg_programmer/dialogsp.cpp000066400000000000000000000031501520775651600212430ustar00rootroot00000000000000/* * Copyright (C) 2023 Mikhail Medvedev * * * 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. */ #include "dialogsp.h" #include "ui_dialogsp.h" #include "mainwindow.h" #include #include #include #include DialogSP::DialogSP(QWidget *parent) : QDialog(parent), ui(new Ui::DialogSP) { ui->setupUi(this); setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); ui->comboBox_end->addItem(tr("End address"), 0); ui->comboBox_end->addItem(tr("Length"), 1); QRegularExpression reHex("[A-Fa-f0-9]{1,8}"); QRegularExpressionValidator *validator = new QRegularExpressionValidator(reHex, this); ui->lineEditStart->setValidator(validator); ui->lineEditEnd->setValidator(validator); } DialogSP::~DialogSP() { delete ui; } void DialogSP::on_pushButton_clicked() { if (ui->comboBox_end->currentData() == 0) addrData = QString(ui->lineEditStart->text() + "-" + ui->lineEditEnd->text() + "*"); else addrData = QString(ui->lineEditStart->text() + "-" + ui->lineEditEnd->text() + "#"); emit sendAddr(addrData); DialogSP::close(); } imsprog-1.8.5/IMSProg_programmer/dialogsp.h000066400000000000000000000017241520775651600207150ustar00rootroot00000000000000/* * Copyright (C) 2023 Mikhail Medvedev * * * 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. */ #ifndef DIALOGSP_H #define DIALOGSP_H #include #include namespace Ui { class DialogSP; } class DialogSP : public QDialog { Q_OBJECT public: explicit DialogSP(QWidget *parent = nullptr); ~DialogSP(); private slots: void on_pushButton_clicked(); signals: void sendAddr(QString); private: Ui::DialogSP *ui; QString addrData; }; #endif // DIALOGSP_H imsprog-1.8.5/IMSProg_programmer/dialogsp.ui000066400000000000000000000065431520775651600211070ustar00rootroot00000000000000 DialogSP 0 0 272 160 Save part of image :/res/img/write64.png:/res/img/write64.png 13 All values in HEX format! Qt::AlignCenter 12 Start address: 120 0 120 0 120 0 Qt::Horizontal 118 20 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Save imsprog-1.8.5/IMSProg_programmer/dialogsr.cpp000066400000000000000000000151511520775651600212510ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2024 Mikhail Medvedev * * * 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 3 * 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. */ #include "dialogsr.h" #include "ui_dialogsr.h" #include #include #include "unistd.h" #include DialogSR::DialogSR(QWidget *parent) : QDialog(parent), ui(new Ui::DialogSR) { ui->setupUi(this); setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); setLineEditFilter(); regReaded = false; programmerType = 0; } DialogSR::~DialogSR() { delete ui; } void DialogSR::on_pushButton_read_clicked() { //READING STATUS REGISTER uint8_t *buf; int retval; int stCH341 = 0; buf = (uint8_t *)malloc(2); stCH341 = ProgDeviceInit(programmerType, 3, 1); if (stCH341 == 0) { SPI_CONTROLLER_Chip_Select_Low(programmerType); if (currentChipType != 5) SPI_CONTROLLER_Write_One_Byte(0x05, programmerType); else SPI_CONTROLLER_Write_One_Byte(0xd7, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf,1,SPI_CONTROLLER_SPEED_SINGLE, programmerType); qDebug() << "retval=" << retval; SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); if (retval) { QMessageBox::about(this, tr("Error"), tr("Error reading register!")); return; } ui->lineEdit_sr07->setText(QString::number(((buf[0] & 128) >> 7))); ui->lineEdit_sr06->setText(QString::number(((buf[0] & 64) >> 6))); ui->lineEdit_sr05->setText(QString::number(((buf[0] & 32) >> 5))); ui->lineEdit_sr04->setText(QString::number(((buf[0] & 16) >> 4))); ui->lineEdit_sr03->setText(QString::number(((buf[0] & 8) >> 3))); ui->lineEdit_sr02->setText(QString::number(((buf[0] & 4) >> 2))); ui->lineEdit_sr01->setText(QString::number(((buf[0] & 2) >> 1))); ui->lineEdit_sr00->setText(QString::number((buf[0] & 1))); ProgDeviceClose(programmerType); regReaded = true; } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); } void DialogSR::on_pushButton_write_clicked() { //WRITING STATUS REGISTER uint8_t r0 = 0; int stCH341 = 0; stCH341 = ProgDeviceInit(programmerType, 3, 1); if (stCH341 == 0) { if (regReaded) { if (QString::compare(ui->lineEdit_sr07->text(), "0", Qt::CaseInsensitive)) r0 = r0 + 128; if (QString::compare(ui->lineEdit_sr06->text(), "0", Qt::CaseInsensitive)) r0 = r0 + 64; if (QString::compare(ui->lineEdit_sr05->text(), "0", Qt::CaseInsensitive)) r0 = r0 + 32; if (QString::compare(ui->lineEdit_sr04->text(), "0", Qt::CaseInsensitive)) r0 = r0 + 16; if (QString::compare(ui->lineEdit_sr03->text(), "0", Qt::CaseInsensitive)) r0 = r0 + 8; if (QString::compare(ui->lineEdit_sr02->text(), "0", Qt::CaseInsensitive)) r0 = r0 + 4; if (QString::compare(ui->lineEdit_sr01->text(), "0", Qt::CaseInsensitive)) r0 = r0 + 2; if (QString::compare(ui->lineEdit_sr00->text(), "0", Qt::CaseInsensitive)) r0 = r0 + 1; //Writing status registers SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x01, programmerType); SPI_CONTROLLER_Write_One_Byte(r0, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } else QMessageBox::about(this, tr("Error"), tr("Before writing the register, please press the `Read` button!")); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + programmerName + tr(" is not connected!")); ProgDeviceClose(programmerType); } void DialogSR::setLineEditFilter() { QRegularExpression reHex("[0-1]{1}"); QRegularExpressionValidator *validator = new QRegularExpressionValidator(reHex, this); ui->lineEdit_sr00->setValidator(validator); ui->lineEdit_sr01->setValidator(validator); ui->lineEdit_sr02->setValidator(validator); ui->lineEdit_sr03->setValidator(validator); ui->lineEdit_sr04->setValidator(validator); ui->lineEdit_sr05->setValidator(validator); ui->lineEdit_sr06->setValidator(validator); ui->lineEdit_sr07->setValidator(validator); } void DialogSR::setChipType(const uint chipType) { switch (chipType) { case 3: ui->label_20->setText("/RDY"); ui->label_19->setText("WEN"); ui->label_18->setText("BP0"); ui->label_17->setText("BP1"); ui->label_13->setText("WPEN"); ui->label_14->setText("X"); ui->pushButton_write->setEnabled(true); break; case 4: ui->label_20->setText("WIP"); ui->label_19->setText("WEL"); ui->label_18->setText("BP0"); ui->label_17->setText("BP1"); ui->label_13->setText("SRWD"); ui->label_14->setText("X"); ui->pushButton_write->setEnabled(true); break; case 5: ui->label_20->setText("PAGE"); ui->label_19->setText("WP"); ui->label_18->setText("X"); ui->label_17->setText("X"); ui->label_13->setText("RDY"); ui->label_14->setText("COMP"); ui->pushButton_write->setEnabled(false); break; default: break; } currentChipType = chipType; } void DialogSR::closeEvent(QCloseEvent* event) { emit closeRequestHasArrived(); QWidget::closeEvent(event); } void DialogSR::setDeviceType(const uint8_t pType) { programmerType = pType; if (programmerType < 2) programmerName ="CH341A"; if (programmerType == 2) programmerName ="CH347T"; } imsprog-1.8.5/IMSProg_programmer/dialogsr.h000066400000000000000000000025041520775651600207140ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2024 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef DIALOGSR_H #define DIALOGSR_H #include #include extern "C" { #include "ch341a_spi.h" #include "spi_controller.h" } namespace Ui { class DialogSR; } class DialogSR : public QDialog { Q_OBJECT public: explicit DialogSR(QWidget *parent = nullptr); void setChipType(const uint chipType); void closeEvent(QCloseEvent* event); void setDeviceType(const uint8_t pType); uint currentChipType; ~DialogSR(); private slots: void on_pushButton_read_clicked(); void on_pushButton_write_clicked(); signals: void closeRequestHasArrived(); private: Ui::DialogSR *ui; void setLineEditFilter(); bool regReaded; uint8_t programmerType; QString programmerName; }; #endif // DIALOGSR_H imsprog-1.8.5/IMSProg_programmer/dialogsr.ui000066400000000000000000000347061520775651600211130ustar00rootroot00000000000000 DialogSR 0 0 258 125 Status register :/res/img/write64.png:/res/img/write64.png 2 0 0 0 0 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 28 0 35 16777215 75 true Qt::AlignCenter 2 0 20 0 40 16777215 Ubuntu Mono 10 WPEN Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 X Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 X Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 X Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 BP1 Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 BP0 Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 WEN Qt::AlignCenter 20 0 40 16777215 Ubuntu Mono 10 /RDY Qt::AlignCenter 0 80 23 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Read 80 23 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} QPushButton:!enabled { background-color:#ccc; } Write imsprog-1.8.5/IMSProg_programmer/flashcmd_api.c000066400000000000000000000043231520775651600215160ustar00rootroot00000000000000/* * Copyright (C) 2018-2021 McMCC * flashcmd_api.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. */ #include #include "flashcmd_api.h" #ifdef EEPROM_SUPPORT #define __EEPROM___ "or EEPROM" extern int eepromsize; extern int mw_eepromsize; extern int seepromsize; #else #define __EEPROM___ "" #endif /*long flash_cmd_init(struct flash_cmd *cmd) { long flen = -1; #ifdef EEPROM_SUPPORT if ((eepromsize <= 0) && (mw_eepromsize <= 0) && (seepromsize <= 0)) { #endif if ((flen = snand_init()) > 0) { cmd->flash_erase = snand_erase; cmd->flash_write = snand_write; cmd->flash_read = snand_read; } else if ((flen = snor_init()) > 0) { cmd->flash_erase = snor_erase; cmd->flash_write = snor_write; cmd->flash_read = snor_read; } #ifdef EEPROM_SUPPORT } else if ((eepromsize > 0) || (mw_eepromsize > 0) || (seepromsize > 0)) { if ((eepromsize > 0) && (flen = i2c_init()) > 0) { cmd->flash_erase = i2c_eeprom_erase; cmd->flash_write = i2c_eeprom_write; cmd->flash_read = i2c_eeprom_read; } else if ((mw_eepromsize > 0) && (flen = mw_init()) > 0) { cmd->flash_erase = mw_eeprom_erase; cmd->flash_write = mw_eeprom_write; cmd->flash_read = mw_eeprom_read; } else if ((seepromsize > 0) && (flen = spi_eeprom_init()) > 0) { cmd->flash_erase = spi_eeprom_erase; cmd->flash_write = spi_eeprom_write; cmd->flash_read = spi_eeprom_read; } } #endif else printf("\nFlash" __EEPROM___ " not found!!!!\n\n"); return flen; } */ /*void support_flash_list(void) { support_snand_list(); printf("\n"); support_snor_list(); #ifdef EEPROM_SUPPORT printf("\n"); support_i2c_eeprom_list(); printf("\n"); support_mw_eeprom_list(); printf("\n"); support_spi_eeprom_list(); #endif } */ /* End of [flashcmd.c] package */ imsprog-1.8.5/IMSProg_programmer/flashcmd_api.h000066400000000000000000000022361520775651600215240ustar00rootroot00000000000000/* * Copyright (C) 2018-2021 McMCC * flashcmd_api.h * * 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. */ #ifndef __FLASHCMD_API_H__ #define __FLASHCMD_API_H__ #include "nandcmd_api.h" #include "snorcmd_api.h" #ifdef EEPROM_SUPPORT #include "i2c_eeprom_api.h" #include "mw_eeprom_api.h" #include "spi_eeprom_api.h" #endif struct flash_cmd { int (*flash_read)(unsigned char *buf, unsigned long from, unsigned long len); int (*flash_erase)(unsigned long offs, unsigned long len); int (*flash_write)(unsigned char *buf, unsigned long to, unsigned long len); }; long flash_cmd_init(struct flash_cmd *cmd); void support_flash_list(void); #endif /* __FLASHCMD_API_H__ */ /* End of [flashcmd_api.h] package */ imsprog-1.8.5/IMSProg_programmer/hexutility.cpp000066400000000000000000000154211520775651600216550ustar00rootroot00000000000000/* * Copyright (C) 2024 - 2026 Mikhail Medvedev * * * 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 3 * 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. */ #include "hexutility.h" QString printAddress(int address, int digits) { int i; uint32_t curDigit; uint8_t symbol; if (digits > 8) return "----"; QString result = ""; for (i = digits - 1; i >= 0; i--) { curDigit = 0x0f & (address >> (4 * i)); if (curDigit < 10) symbol = static_cast(curDigit + 0x30); else symbol = static_cast(curDigit + 0x37); result = result + QString(QChar::fromLatin1(static_cast(symbol))); } result = result + "> "; return result; } QString bytePrint(unsigned char z) { unsigned char s; s = z / 16; if (s > 0x9) s = s + 0x37; else s = s + 0x30; z = z % 16; if (z > 0x9) z = z + 0x37; else z = z + 0x30; return QString(static_cast(s)) + QString(static_cast(z)); } QString byteBCDPrint(uint8_t byte, bool zeroPrint) { QString res; res.clear(); uint8_t digit; digit = byte >> 4; if (digit != 0) res.append(QString::number(digit)); else if (zeroPrint) res.append("0"); else res.append(" "); digit = byte & 0x0f; res.append(QString::number(digit)); return res; } QString getCRC32(const QByteArray &buf) { uint32_t size, i; uint_least32_t crc = 0xFFFFFFFF; const uint_least32_t Crc32Table[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; size = static_cast(buf.length()); i = 0; while (size--) { crc = (crc >> 8) ^ Crc32Table[(crc ^ static_cast(buf[i])) & 0xFF]; i++; } return hexiAddr(crc ^ 0xFFFFFFFF); } QString hexiAddr(uint32_t add) { QString rez = ""; uint8_t A,B,C,D; D = 0xFF & add; add = add >> 8; C = 0xFF & add; add = add >> 8; B = 0xFF & add; add = add >> 8; A = 0xFF & add; rez = bytePrint(A) + bytePrint(B) + bytePrint(C) + bytePrint(D); return rez; } QString sizeConvert(int a) { QString rez; rez = "0"; if (a < 1024) rez = QString::number(a) + " B"; else if ((a < 1024 * 1024)) rez = QString::number(a/1024) + " K"; else rez = QString::number(a/1024/1024) + " M"; return rez; } uint32_t hexToInt(QString str) { unsigned char c; uint32_t len = static_cast(str.length()); QByteArray bstr = str.toLocal8Bit(); if ((len > 0) && (len < 8)) { uint32_t i, j = 1; uint32_t addr = 0; for (i = len; i >0; i--) { c = static_cast(bstr[i-1]); if ((c >= 0x30) && (c <=0x39)) addr = addr + (c - 0x30) * j; if ((c >= 0x41) && (c <= 0x46)) addr = addr + (c - 0x37) * j; if ((c >= 0x61) && (c <= 0x66)) addr = addr + (c - 0x57) * j; j = j * 16; } return addr; } else return 0; } imsprog-1.8.5/IMSProg_programmer/hexutility.h000066400000000000000000000016541520775651600213250ustar00rootroot00000000000000/* * Copyright (C) 2024 - 2026 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef HEXUTILITY_H #define HEXUTILITY_H #include QString getCRC32(const QByteArray &buf); QString hexiAddr(uint32_t add); QString printAddress(int address, int digits); QString bytePrint(unsigned char z); QString sizeConvert(int a); uint32_t hexToInt(QString str); QString byteBCDPrint(uint8_t byte, bool zeroPrint); #endif // HEXUTILITY_H imsprog-1.8.5/IMSProg_programmer/img/000077500000000000000000000000001520775651600175125ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_programmer/img/IMSProg.png000066400000000000000000001026331520775651600215050ustar00rootroot00000000000000PNG  IHDR{ PLTExדY}-@ G޶ @e##"l Ơ G111̃ & a(\6675r%IT= r L))) UH*y. A %FFG OB%۾ >ԞK|#e. :fҘXJ VmB"o i[)Ǚvݓ( 2W\\l*"X! 2{Lv陙 "^t:l6Ԯp;yGlf5 -B 醆Y}JݓCYVܽݠ|uiEV5v}BzL>ϪEtOڱ{kkgWRW;2[HC&dCf)IYB:5YΐŎFFЛ!@$7 )ԋ=fͪc<=/RCIbl*ԸQ Sϴ 9dz뮪nW;|gy\>j#(AuUcn_OTOͪF8[Ȁ7[㤳ͯ~|{llu{se喐'O Ayn|pvVIDATxkAY ^h!R{e !^C.(l̵&^rHP.S<^R'L;5U$3ofn{pӎyLcW/<PI|xuC `3Dʣ6"XpƜnx~vXѣ@ga;9xmyގÉ&~H@o R.A ݣ\S?|yM<)C-/]!Y;ox/o܆$=D ta46*e4x)"YL O˴g^! a?9ogca g)=~0D(؉XD0 3~" `cS"2̩@ sjDX@ 0, ÄdkƋ 0cg 4X@/ / X@'K/|,cbܲڃ 46XjF'oJ)dڶ$CWj+ru?fZHjT-aQ-}] vC-ICC0'Er s= \Ąf[S!+{Ƚ^Gg~ 139Y +MY/7kdh֪x|pv{ f6Ә^NjVfkەW+pV)NlzYqިuN0uڔENek~O3(Fѫ/t}W…U &ݠ, 58jfB fR]L/WZfzy|ow<{GJNJ!PN$q"Dlj _pkWxZ@(I\yhZfPmA |  69ՠn33`_eZpUJ%1a&vµ,3M=cO+裈KjS i?܂KkcŲ`eXT?kgf~$GiIAi :Ur RK ׀bch#XLZacL;H@d hw90}L\~Ruɵ$L{d+{|Lߊیlf;3(Fgܮ ΓO' V+&S[/u…\7^"4D@d x A>cIMMVAw sz-(v׶:7 /x+w$ :L? 7寇|5 ޲e 3 =c <6(3}%cvLl0S48gb( czLLclGbSe!a:X@  0, ÄdϋRQ9 b6B\dP"LJfaf2B^%" PFQ`9-j3jj* տyGoGPg|~8^X0H@@$*@@$ ցh(пpk8.OEΥҤ#->8;0Uf1]@pG{U'͏Fs'EMM.'qv؁u TG4 *,Q (Y 6a]@ڱjQfN{[1*^߉(V}"No.X铯gh<{i}Ȑm13eFD 6y82̨Jbyv1onq-Ў 81m,`bl4yT:'J~̝)Ο!͵l$ N/,>  (ٻ֞3;sZ(*$gWNf4 ۼynA7ݿ,^LWDd>#wd@ʩ^bЏ]_M>5bMx9wU[ԯ)"c)p'`7w:FM&<Ξ5Sins*ޜ4 Wu֞$OQ l-~սB@YEJztX)(iO QRJ _mK,kQ 'cTmPpqathme9,Ug4Xju+6 x!r'y(ܖ(`mZw'RÀ+E4OvU_/j H#i}5%MbY2 ,)Իu/m駟SPlF ܈[5, }kHnPp=T\.! ր @@(jCQtlDR{»"Ƞ_hG0TZARXaPV~[]UT:F\1^C")8~3N806;1TlIQ? OA^GSd.E?,ˣ஬SZK .,4qe;3;qoWx~ϑx~cMX$I媭 3y & mhU;H# JOp%#:ebqRYڿtUm1lWa֝P$1D& Cr=sX{&טܐ03r5\U c?:y 0Q>xg翥 0Uqg#Bv-0(BUq'EYrj륱af6SD>S=Cݻv sȶJ9 eroL7pXPPK~F>GLA9bดCR&s\4rԛij^d =v/VQm,wP\|`Mu]8oL{DPή18Gj~F!7"r\6Xm`i7``\tST.t]H,K׳KEEi*!f㦲]1ӡ-QpvvWA}[*0?gϞݻgVVEx#"yEdTlx7FQdP#cDMc#,)hY]oiQS"3Q,bcqܡ2c@ 6%4b٪ScUU7*HW: /IcU /{fSylFHjq+)FAf'q=T{ rId#Ϡ+Ea@q1R8Su?HL>?S_& ]de]ND+b~ksU(+j]w`Ӻe5Zl[oWD9: TH%72NOmN0EN #6ׂp `Sq4^¯1I A}~hQI-!wޙҪXl[8 KT^4W;J!"j3/CD(DpmugU^[:AO>؂ я}/,î* 3I@$h |)ï*r mb{p\ @sӯ:k?$M FҜ“lm2"!vlPW8U#3NQ$3/`qw_*v@$D}Q=yY[޹ ;7n`:CD?jḡ#PP}1ixi$8bmrW_oRlϚ.y62//Wo4aTv5-BUZ7mtY%`5O-$K}l~ki@W ASН!#K栞 ϭ]veOe{V{R,P2]E}A Vm9:lt[`@>c.- My1GU팿w@mc" @ˁ5j<: ؔk Ң6jdbUJmC@`)_qnqj֟#J(+n3[ #1Oc\[Œ** {Gf<6^Bͨmbh(B(7׶i1m)ZTjAz$5H{i[ ɧIB6NlrSЗsHp HVa@ψƨMo0Pv|"y *ϥtF6Ł0,;N\Vl\Q%aR#ΏpЉ`)∷1\4<46O8xee%̍G0 t@Vhkb(j mj& \UXk{uqQ- eA&9Bif7IغCaru@ `CW9 vc 56ԝcư&`9NYQV-Ky{µ@l?G#^?p1\2'4=,.})A(S ߳^Inְ2Pe9zW-5`-=fwʴ&@L_v1=w0"6/aP4G/nvWkAO129>:;\H<YGd+v@?cQ F ={[mJu@l *o߾I/ 4w΁}:(f .8L U06:bFȾeߓ oЈ vvٙ#KXmu a0NAG֐?B_xK(t鯆CeT"CQ[yzyй6F_d'LEqsDva]i񰎱E@8 ,""yQ!ďrO[#Htճi@*o|"Es ?(9 _Agf;j_]05ME])Ʃ6g+4{=]߁3==ßxGr/[]-6]6QFFn?~kvflx; 3d21Cܷ7:2#nF8#6{ v@7@nՖU# ѶS "cj\Pt4<0> G@#F{~,@ a>en#إk:}I W!A,(f3P)ir%\nti hTE2E@ވ>ۥuD/=`2M~( r/.wUqMYѸ?+Ov=cwQ/$ c?n4I(> _2*#@g䞓~t4xL3kUJ{EOr$]L%x$=VnNt'DppPY1aۥj]u[5lmmC(z~0vnxkġr!jcJnc JXHdلǘsYkq4fλc1ɅI(.nj1Ƽrb!3.;bƌd#Wae,Py;ʡ7ܨ;`tL K5#D֡6R5I:Aou ? pX@&yIe< s?^MQQ!" `!~@iߵ'ӣx\|qM#|5Y\Fb^O/@m܂DT7ʌAyB<Ʈ]{F$vA~^x l=O%IiKڕ i)N@q`˴,NUbH6mo`l\P&:)!f߂aNߔE?T02bl**z+`1"|U""Ud*x>o޺yz<=nSgh.Ďz *²(3j-ț߯(Eyk,!;iWe}JWjB*ا؃J<"8)EHH⳯gy1H+lb7Cd@6>PHXy:KL oHGjy5*{ Wk@׌M;(E~h[SR NEQU EIH`Ȣ/WU?G v2?t+µG)EG^#' - `amq`Fs4`R- :~SDo>VE1%mg7gM~"g*ڡfsTAqQ3H#IaG+78{f_OOXc$'g9@C2SA2tzj1j'~.UYĊEHMus,@bc $Ke ( b"1Pkl (Ov=؀;=&fW/"~/ @NzmZqSINA8iHTQIVQ U*Mީ.&M%"ļկ};k~Ol2G xWD:h\EW! C~k[تY)D+BiY #W}GEJ4.i'n 0FQޛf>DgJz4|+Zp)|m.բUeP(kmO@ 8'\pq' ,:6( &ׂ Yk0ÇH;`>  Iu$:BB!Wkwk+-5:' HSXB\:eáPV١fX l8Q1K!w]l_c2ff`۞>˵-p[Η{{/{ιwOj/R*'6 ۯ C `"UC hh_i[~T`u9󴔊{N?M~< W\X16DRy. fmDՆ"yS&w Ҷn@QI” x#UzZbR*ExiߠWR2N^ (qnI TjV|]p@h)Layu2?vP-MøU0h45Q^HN܇V^xc0&v|y*ki7)wH@X9XF:>RH%]C]>}fjee 8h^/ϱÞd0DH;O=~w <ɴ.}|ک48H7~7v]P/$Ƶ)TKثcm~5uD4D7BL `jsN1"6k/(GcAWmA*D l**E $Q*08"9d(9"X:**FlͫD"PHIV\qQjd#L&Gz*Rpr(bqYC `ȂLKN MUꀁ% lPWga)n;(?$H0%b@ z,'SIcIt.&E!K]O㾉?@ {ƾMZ%A_Ak(fG&ՙ%.x7dVeL2(h'qp@uD ]^ MiެlmeG ٭ dgOmق߹7ߐ8jC4ebЕPG*d*jٯs}c!~ߵ7] JdK=6{&*[a>JO㾉0"4tE`Uv,iKGLLO]OI+ºbR<3/q1"7͒eԹwl]'/~f[C&?aXe۝Z(xZa0Tŕ3e2nrb9mx(HpsEk95mEJfPd| Z)"c .;`Pp2;8aV'^ C{AE;`l޶-2J-I 0zfE[yA^3y'DŚ'*Z0#hȀVk} .pRK"i=P*Gjh?#ﺼHI@eRK>Ȍ^duʇGtٌu%8WٻO~Й/ X~63YIt1;QvjnS=&CD! (_%@GH@2=.'rj~h8.|*襋ePuk_/&bq1ߞ;#ikV _HgElX̙q:K섬'HƁܭli/.Mdb5??u0V< >./~VO Yϗ \npd#"."#> ե),.X:h*we[WdiM@~Oyq$5UÏdR'A%24cA#˓q|vɖţE'b h@d)R9^yM+8wI! bq8Nąs2ρxgߐ'A%x^ |4<'ϗ`þAò9$m@m@ k Ӫ/*$Sy 0dحp X"%"'~0l <#\s]c>̊؜ϛ ț 5G r^//LC"ՆĆ%~ǽD/h^^P^|ﴩQ⩂? =*@yA8yߗ6Cnk 6ʓq|I;L. wE 7grS?RArd{|#;эu ;ab8f̸}HoXPb@'@ΊKM5XF\,fAdyw> |p+?8;arA ԑ0t(EYiP@^ * "/#W6R$ш@KNP4" ѠXm: K蘒DPDRّ6$f]qav$7z=i/%Rau+ !ّH3ƮHpݦ`^{m`v$ #TtN㌱-.Rmic&:EBnG2yn1>}u.+T@Z`lX4[3Ʈ:CYm=#\=X]%:sbECܻ<4A#%~gѦXBTJPtro<ųFBOf!'wRzvZ[Dّ+oc-FP4ȑP:- VZTa P㣀]mq+M3xn@~:0/>~Km YDEuDo@ni@NW4=oeȍxxGj фYG#&0\2yé6LuDox:^3ꀥ1(@/f !VIJM\7n\<[8`Rmqˀw@൛eLQhZMOm޼&<5%`K'K3xP$Q:R;`d9ȉ2JTuTmB0>): l霮A Xh44@S5u4{lun,[x948)p㍷ zVAA`ǼqEY!ݰq_mȀl/yxhi-u cvfu@#IBuD##5|/CnSɛSO-cuZ~T:ҿ ~&4" t$cB?#: )-(); NxkG5TրUP1e84rQpP}_>.;`dk8>W#-7\P#;cF^4b^m+= 6nU#Uy/QrA;>|FU~&mB |P:kX}/:ko Ѥ0԰G+p-el7x0Y.p.E`+<45ȅw,zhth"`/~|`dTס|=:kX}n0`PU-0"R}aܳ#sහ@a*|*jA[Ur2vcWG@GjʛHs)Dc즅H6[c'lCͨ@QAE)k^%מvJi`t$z Z`EJ oTQGu(^y-+cs}q^`L\s;̬0ʃy >p:4)ʞDF>,`r W~nZ} HоC XN3`llWd^Wڈ[EC0 'drA ,,m<#ӑޛdBHXFa8 :7O5 /AtAC7)LGjZqʦ3̲?G{Ób3ŕ; A#h0s@_ 1O3 9`Ihfu"4M?̈́eK -$c JVCɵhn_r&VAE 7 ۺ8FN:tRP>ȄܞMOGRGހQR]L⬷g;㯮{V%j 2ZҀ 1¸^(6pj=4K@.(H $x4d8x}b!$ !k}I*(g4.r WґrW{SQ q39+H aY4L$ys{%a(fd@RoT7b9@IL~r.hEa}׵v3 K?#Y.r eAE)Ach 4y pb@Eu:`هw>xl2DG-PV}I:Z_#W>p"1 їJ{#TO€# z@Ōt$IYx' 9.L\tQg\zӑ&8H}&쀠|`؜C#/OÀU,)=s:= ρ4ށQ15x맼w~|Sֲe #tRMߤ{kŝMӄБȡkh+*wGOpgM?nlܤWjמ툎d-9xܬR6c^+%>ʾ>PiƭI{v>|Ր{1 %ۻnT@.*؀W?MWG :k\)ޮegsP m@e}l@煐>Pv@ Q m@i}| zy\- #Àh6ʲ>60:)/@bHGbOG2OȽT]KxZePe_  g/r1 6d t$ !Q/ 2s.(;=ogӑhʀg)^d*WXs/gM|0P##e$J H\d)W&e1miגHHE!kLLMEw_֎Cm֙/m9:RdD)P2`| pmiV #5x^| v;y'. .XhNѝ<5PmDAG"BV_bހ_h--V9 7=޶ݎzvAŚә 8w9+\l]8t>킒(GRp 6U9x^qe.6|O*{g{:r!wq kn$Os>SB7a @GM#y \%ԂBBjBG ΀T R}# Q$`]0Nl턢x=*-rTA7RIdvX2Y(:P& :!Z û.6{L 涔miL߃Zt[*Id6Yv|\2i˔gO+p +πe6/BYkϵJMr\ 5l0!\Bn{fmQNֹiKsdI|tڂfWhH(^Eӄ; jCGAȕ?RK$ !5#.q&$t$3L%J K@8r͑J \H@Bns$RʟKvD! '^pۯ(2#Rs$r͑J)B`rۉB.9P)} B.m#rgK:q l^"#ri>nAQe6׿[$t$|MM MS1xB.?*ZRI_ B#xM|R 4z,Ulm~Z b̊g5p\!tJP i@L΀K@rIjtyLzmݣvw+m, 0"=Z|̪eUђ41 ΀J$J0`㉏JS`js.~<{%լboBё-(K铀zoGj *UxM)!.R!W@2P)!uP)J v B.9P) @mTJr6{D"lTJyrKfr͑Ji &ǸolTJru欈lTJc*䂐p6Rʿ ^uDmBRʿ+nA]Q6G!{GFgwAkG2e `H,ЊA4v!(q+jH 6Fi4%Ƙ4 iI7LB <@>/~w{=ݝٳg9q!j\AtGSѸB(sABr4#:2k9by񖝎l7rtdVr틩1v; qޮ&,ۉw9UޮMXPxl7*;Vr〷PVm-HW `/aaB1 YPyr$:ؼ :^?5.‡zl+K6IUS#P E 1:Pt= .;Ou[UȻ.P!q J w8 įKlm|VfJ O1ݑuFH Wϵ{OA}q ([}" >;E?u J~L¨9'\7s?`wlX +6SA2MQփ<6hZ=o0 q @.bGF)5/68|rc@AށY <Ê[>juf:5ԣCE*Zo-<"1k\IK+*Z BթyD[=$bFj/|NM)fb=:TV; 7^8 W5i> ^ Jx 5ơ9`cj'|Ӆ͇NC|!rM6 )c[bR(L\zH!cY:2ˇ: X,ԟUN1ߨE?(fnX?V4jcx@倓eN@V;D#ǀߦ9 0]aQw j}NB_0vUV:F1 |+̙Zh*Ĥ!ANSmS~~hm#Wo.hٵƌ{~[o1 p[C`U @.~s6ȍ%Upby#`g`޴OnnoѢ i7@.t}"o7*@nmtޯmUdT] .d~ Qŏh':lr򝀶ڰ1d]MBμA~weNG?(fn\:q9)+!ó=SǘLKc]CkWlqcòXW& F\c\&dd%B'Uϔ;Zսզ{eI̗0<bh}%H?~'o)]\B+ڙ=`) +MЛKS@T.}A΄\K+ R=} 1 mЫ7T] C (P@6 2i gYB`rmNED)7ҸS4mub.Aay%E7X ½?b`'47eˈiEB5h4&V'Fҥ8 o Ylp7?T@9nm׍0!06Iܓݥ1-:12 ֚XJ4Lr >8:h۟}p ~inȽTT!Xƀ6 j |@`WB2-K~L&;J \҉) =<49/A2C+EH~K mi"t +" Z8h!2ŁrCd[#I'꭛qJjT#$  ArCn]pyBd[#KI'꭛nYЛrv_BW) Y3!s%! "䠬)C1 Pk%v hvnh2 ֗3 JY,|PŐKDRŐlk) qz)\knY ÏC).ܐK(3jM5ҟ$R^OcD@r:Ӑ4^ ѿ,![0Ծ1ԥ~%HF&+zԛ!J(vEM& 8\>F 3!|` H:rv#(b|-+jPiX6 t]6Ž^!)P=!>\*P HXWoOa%:t)?oz KkK /ƛ~jO!P@ ԃ)1.#G^؆yyi/B@O=~ ئLt)A>c4^V$` yų͂R #( )g$f}dž/z|q9Ѕ D##B^3K@D0M)fLKyZ ڦ|\G} +~j_K ZnEY0ց\HN(~FՐLMR@~=ؼJ6^\ض rF4Eӧb5@f?gAwu*xE۝ Ե >ƀ:䭁ٞ4~K^5F8ثKuX߸5 ޕZnE̘IwKȥTqh3H֚⹥^Lio6rs?ߘ} ~i3H@+Iٓ)%Xa :ړ e/!{!^cKB.U3C.Ir`'Y%:vK݋6:!vx#\@eW4Z,ICB.%RžvMG5 CzО4"! 'ieeU7ˡI R o*<mo# Kkuk8C<͌̈ BtR!O8 =!R o* IG0pz煭U\jrOO{Ll=WYV͂ o* IG0mcE"8{,[ 6u5;± />KAսt$dA򘌀+WGԺ\~Rd\ mN35/|𸌀aL96%^:*/ R4W: t$%1*OR: qn#b5}\ mU(O@nUqqA,k%"_]I@Cn߮wGRҍ) %uJH":l1v-]vP!oemSťniU@_nbXfG=ܨ{?!qݘSTEE<8W H1RR hrBMou,(euZ &'Bt&)j;EtfBd 899ˌ11G#fɎ$K  ݌kKB"%&7ڒ0ES ٫Ws3xΙhs5۷y9Æ\7&`MZoEY>\rِP4t gCnۋ wq0-n0-x WWl.?,K!JB]Jw`L'%hͬ~7Gl GiQ~| D v q;? (vb6@)TD #{ q;sd&nWFBnCB.Aߎm]+z俼YLf[d GnG?4 *RĠˇ{M,HqYhh5)h ڝD\޾/]39vīg!]]YԢl)+OszۮQٯ,Hdxt :$Z#7,;ܕI:P$Kjp;{|>6=,v;p3ciK:*)c3Ml$!@$#N Ogs ?|8zZ7t>)c$G3>FM1N#5^Eܤ2FnjLE;&0 />c#n4xGŪz7/Ԩ"TE ɀ>PE}@?]7񠶚5ݝ-u6FS76QOFFS#}2B@!`a >͔>RPHJ3+Aíɸ: D5] DŏvH/.U!4ɕGLF$Tmkh\E]QX+~uLU+, 4lRO;TU*-υvKi%/'b\ t=ӒϹ;kwG^%G4?2GèQ\F) S:C))Lj)Z } Qv 6.D)j&Q9 <-vo#vD :ҭ1ʱ c] 2 R`4h^Њ6m5ZBfצʉt/]KhxRICKiN1Ϯ!F :9ygMQY{\ԧnM@ơ8S oj2S0ѻA0i2p2t RU6n玲V 0YcrplL%Y, Xt`.NŭpbIE2(oTn2SP~!`5L5S@/dmjaaaFKhzI6yГ*oO?y6^PiUw:@1/$LѮBMsF5ЈYQ/tӝ/YӞ =U+J,,(`"RPim U@6@6K1щK,#S5*.`@9jk,(0$_3h:Dsp\z-H2kᏪثU+r.ăY"B]@i\m %-]пbG?)@ P # ?ov6 ߾Jp4p2`۴eeel!X Y9r$>[K޺@Hy0T50pI=,(,*`Wg_)tIENDB`imsprog-1.8.5/IMSProg_programmer/img/IMSProg64.png000066400000000000000000000155001520775651600216530ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_FIDATxڼ{|\ŕUv~HjӲe[yalِqd@ fB! ,Ç̓! dCX Dƒ YWKUt%KLؽԧus~imH)Z#cƘ)eeYU.~Ÿ|==ZQ T2@'8 tI){*ӟ7 N_1Be\ny1TDaBQڲL  ]Z뗥J)_?}2Xx)T*;۶'$ =557ZfQJ!)gN*EB_&Żwѣqq,a/!zz#׃`ҌjWbJM<,2::JKK , >) s 0\gY}1sL)//]:Kk־s/(bl )0oVT\LMq, c tttŋ={vo [q6Lhu۶m"J|rbJ)_ROUx108kG8L6ƀCfs͢3+u2D!hfӦMtR R8uoPJ=qF"˖-R>%3O8R()0O14?\OӺu\[sJ#=C̲):[xǜ9sR ?/ d2̜Cqi.<-?( s1^><hO,ڶ@9|>G(VIYm=^'=v6r% Sh ɽ(^8y+83ywڵrJf۶kl@h?04hix^1%F2t1` _<2Jkd}݇9Ě['IQ$H2bmctO% : Ce3X Z)J{(N(Oc.LK!NO+#r7Hm 8=qn75Q !i a(PCa?-hl&Cf0[%PQyJ9JsS_܏su_22gsB@ 2 ϣRb|((pw`S\,J1t\鏭CS6M{p {o%6~V  #AWH:ƲW>I&& d8vsaƨ/Z=BuIў.1~r;)_|/;vGX#AP^Z+Jp?yPc y ˡ)tQ Π_`-*~ n6#oڭD/r0 <$G)VhUDtL"`0OiνdGx??C:t0Y(pf~t{iD<+VJץTQf fL9?Ғ|c [lʕ_`fZn7ͥ?]Nx,Auu5;vɐMPlVF窿C`e;ELdFi͛eci4K.KSST&CSvc8z(DbTzoW/%Xi8Rb9²BYXB92C~ *:wykh;0o<~s'"k'B첲L&sҐ!`ҥ o>x饗#Ns1l#DT|͛7#ddd;wpIw}2>#O'xdH&|3᳟,)Jx*sUx{v]XT/u3x ^6͒xj8YmgWA+ ~z~ ln ,_x<~JPOft>,ˢ;s9y166FooPz6l"o Un/ss^H/g_<xJ0/2> D"Yx1555L c@'Þa!s9DWW<e1::JOOVo>4ZA*9%q >3olbsaiub$W^ꫯ2sLѨc8_dժU$I6o۱,h4d2ԔT޽{ٸq#@)%@?08p:P!MMMZnvIkk߰_xq0IO3t+ݝ~Ȼ#<>%#$ ꢣ˗.---h7oh~08Y0 ~j~,"gxxT*E*477CU$}[A}9NL( | ,`|ӟd۶%L꣎S@񕕕kqW`,*6L&1FMM I<'Ouu !į9Aw^̫뙖`p8yd2,;vPQQvl߾8/p]"3dD"fϞ+l2N_N6Jͳtm8(oMD"'Y@Ʋ,m&uq]_M7D<Dz,jjjDMwR:זei&khӺB1XSQQE}_(ZRVw-鴸+EUm]vŊ+mc@D*mnnA"8=SX3fiQSuB0"1۶dݺu,[s$+ 2&fKs5/RѣG˘={8<]dylܸ r?~mۖ1#R*V@)e2Hرw۶m~-ZĢEbM#N\RcǎoŢE ןvi uprmۣ-o/ Μ9s3X ,8U13E~.,bɒ%,ZWmmm7۶q** :D&a¬$ uݨRy&I2RRJYnYw$*aIENDB`imsprog-1.8.5/IMSProg_programmer/img/IMSProg_database_update.png000066400000000000000000000057051520775651600246750ustar00rootroot00000000000000PNG  IHDR@@PLTE𙙙杝֋񑑑蜜䦦᧧οηΠڡ?fedΈA<+9JJBB=OUB=5TZ/ EC>KuB>9/;+S,={?g76+(k)H(@3'(#X]W''x)]M[PR{K5>Vi%2eGNGBR5EڝIex?  &jlpjSsihhhlZ@H(awϞ제鈄yyyuvq_2  qķߔ|Zzw^ee_W<67K),zxonm}gSdZ_rR]QwPI<[8<*+Ӣȧֵɧh5kևHQuk_cYhS+4H $QyB~,tձ;lu>Ki^Z;VUPg390&!5~Zཅ2டή9vQd|͗c|SA\:xCmPhegaaamH*9tgFf١0[h[W-:TˌzÖdM~Nxk4v+[-tRNS #6FY&m9Υywd_ !JIDATXÍu\a v7bFp 2Ma#%DRC@R,Bc6m~{۽V[6*@4۶}TpP_6}U5´ Z 數0-  zX&馞-h4:@Su5֨.2 '^X]tCM輦Oǵuh7[pt #P-Tהw7Іc@7nܴp[:ؐ!A܂aL%p:+:M)_9t:^h;NC/A eoB)۷] 7̙㟏 Z\!Ekӡ͢-)W6WTT|-K@&$M&k{l>ZQq<ĝ9smS_8q\KW t L>y󛢢[Wh"01M@='GPR|쒭[;kݮLv(cDxչ8\۶WBu)hĉ68^ MJf` hj-J={jΪ|[6 )bi31Iw! UOI[Tf ]0P%(k[\MY`Cfޚ4ͯ_gٳO<2]-0k@``7(h/}/>6[f|ēYA4?ަ^ w˧={HyJqR@J056T&x\=x~'P&U3/:$JZ_}ӱYj5-e+Wi/].XV&`s=}~Y뉑WŮ0 +@^Ӧa1-,q/1 xӌ=H46ųFFF~|>[ZZ&!L+ 3W>uA_~{mÕQV>笌H5!`_y ˜${o=+͂39 !C`φƯwm=`2Y` @rxקpIm@Э bm@pgYjZʈ& HAl <zjn),A<ðTA+#YJ p@i>CPoaqz(ILb20rk@s 5@q V0 ,M~.y$ b(?YyZrZW .m1ly@CCVc.׏(Jp列gǥikyR ݈3*[ 2#m (A6QҹF'(})x:4Ce#5IENDB`imsprog-1.8.5/IMSProg_programmer/img/ch341_24.png000066400000000000000000000552701520775651600213600ustar00rootroot00000000000000PNG  IHDR,)nPLTE14:77=%%& #"&45: 029//5,-2!:9@$$*<;A ''-''***- #45<-,/*+1ܽ <76ɩ~˲vbI˹ֿg[Tڸubȭش̶⼶ϸָʭĻ߼rȞzo[QIѦtVyn) )sȯGǏth^(;;K?4/6F8tnk£t7XJ7Ϸ4@5*\J}nTΧA@gV?Hm00¬+ЍBaq$AYEl&c88hLL`>K\s~r\!&}|߽+-7?,[xd]7+/~ K;fo+_ l'oo\xDwI&UU\[\y":x i~eq1Wgq5E𚊓8wdFd ylWWŅk4`Le:#Nfѕ ks_}ӬfJJ@)5#w~?+YZ;pKz.hMc2# 󜬘tVl DLp2ύJ9DZOтҤ$I*,>Yr|tf8Ӯ폀~}|)~ZqKZ8J o^[GVNd!UQ0<dz.9z`ztE=kkp0K+iuRRUUSh3Q,a ɉTˡӲ@IlO1v>$$6ʚ7Squ͞`|F=赵Kc~Z3y=*4VU"kTt T!DQT`BC}(+5`+*2RUeeNfhC8ͦ'&'+>Ύ8!-m+s~zO_r倞FFogTd*9䩊B[:@ |r7%cF>z2F*geb@@3$H=*43=qHa'l'ѕ!=o/e2A]g3KEl xhF "Hٖ,&Lvƕ$IM1qBw3Fϛ́y5+KHd H.X){W܀0^Z%) N#a^EN'3כXPqю %{B,\(!p=7]mcd`PY vB%d*ㅫbL0ۦniV2/#EC*"Iq%*xv-pjg6 6uy $&ɲF zdʱV VM  @ʗHT9^T#'"ChȖ,v)ggF Wk6 g{2%U,f˳fǐ$BѤ33Y]ۥd<{1YHԍ*HU0Omc*B,X(Y25Ȱ3~pE>QZ]g\ %7RmK@D0xexzs YN_Q gI(~{;V%֋vvඨ'8XWEo(8a9bzI +gS}UG!'XVyP"!g jPU},T<-lw?Q\COIR[WTq Xܘ/=~!MUꃭ)ܺp_P|/l)E7 = ngt\?26JsB`#!OMPɝ}cw2߭/8uX,vXr}Уzꑭ77dE8n<^ 9jY#pg$yX]bXh|p$rGY_~32zIƣXmt`r;SrrG^',-b5| :3+l]jZj(TY2l0K])XCK]zpҚʐ,iX L.rK3KKK_=sfw+u*r,gb5VT7f;|vKU$qX,V 5Z2i+ZlhۦVK2)l`F[qf f&f6f8z呑SNew U\CjF3̦+ڲ186VMYs~?޺r{[xcd[װԝg/ZI)&)>V6oh2v|iWіD-p'z:_sY)T4z~oc#[W|ÇDuύ\њ3s LzkN *j5m٫[EjqD7zq=2^92< lvr_wIY4X}uuKN;tt6:>c֍=7Wáy'\l ˍ*cQ#ڤ@_t'Lh|Mlv{%-B̄|sF*>wf*] "A4W;-a/w=u$:'y=XBKuۆbOMv԰\(sHQydan'妸C[k [^.Lc;C {pmpOl᯵PŴEUj*eorH5> =`\Nb'Q޺ƺV uX>>YA/:mwvwtN#8K™" !X3T! 30Hb'2AH OXFOV1Ų,_|}?Ͻ?xh߻;35YT& 8+W@gp&ձm/͗V--XC&V0`مWr>`FjJcVeX]z;\z~vƍݳ}]z5. cc )^2r2 eLW?*omC*ͯ^ꍮP)-뷡R΂\yC >8d-kո[+g۷%ՃG!Hg7."[6G<$m2CAU5_1FTJAa/,,WZZdC+8& wIU^K919"dTjD푦vCO~eo^icdu"blѮ9c-&H U0ʑg_QXW^O]o"V]^ae%VeTfjЗLz`e-inJuXX7}m.^>;7V⾉KTl![L69xuq`RU@KQ=bWj:lذ2 [e2k=0&ꊤRơ&c3rGIKr߿ڵ^ٛ:],ߝrojaEmFhDS΁7g85 SyleZOA V:WK6%HR&F. ք>i{^))Izx?.l2~3/*yv%'6dJ3Ed#P…ǺqS7gP.eՓ3 G"7bq 9U.ݒPx fi{}73WAL9ZҴҸ!ӂ *C 6it?ͫ;6klJ^n^VԪ .g`P*3k[4dOkąZhOA̦m|X#aeP,:@TmhW*ʛT5cbɓ#-wo.%߸ͫGmAEAZ\b-(-1,x>G,<03 |r1LBߋBҊGWZQ.qޅb֧R`-(iܜگ=:xµ ߜ3Er)lRh6TF?ZTJV)i.ih`e{ uasi4(N/I $,R+*9:<^SW1Ia߻}yr< Zo^•Ab6M'%[ɮL79#F RÂW#҃C6Ff2"WFn`*A`%1CHJ c9O$N&VceQڰ]?{n{gPa\[2 7j^+;NU*&L蝂$]8@X$)Wfe75Uu1uCwsw--Rs8T&E&^*(-d+1#vZJ9>VLy90 hqĶ5 g\;7pyh@nՂ\ =q^:JObCz#bJC.,P1.:Rwᮗc 궚0[Vrm.G"kO`<'a}CU_Qa̕|c6RjTEx%ln0!FxىF{OX>oO?ݲNJI)C7? %vSy+9Ajwl(3Zq$ɬe5Z H؛B]]5TRDL/x}FtTxG`p3ƉلX,5YBRv B^0jn- B e#H粞Z[*3Y|4"mjA^^YXWY(]J ZG[RElngdf*IJ_>\~'–&(;X` ɡusY*im-.,jRe5Kj߹@V',XUY2Gy5'm94{7456ZzQm.NTw: ǫW A!V.Ԗ)KInabDB;V+l@84"noKK˭DV0Hg ~w Ss}ᵛ4=}B./nX"?pb?E!ڒ{zg,9G*gn E6 iXi=[ƪ ^~*pțW}T-A8C#OeU*n2joP~UdƼrs(K0hCjʫ@cⲃ:v6.K*F I7ŊDluϩšhҲ:>0Qv Mqb55)jxWJ4f#]HɡqXV,[RC4 e}l~d`l'AcBiQ 5k7&{v/,(*s+nb#{05բ5;`W2RKG{c1K,fĝA2}e?[z;tEMj>3)=CGR{d ¥89vh'ޕH" yRG'& W{^Z@6bfk;%jU vt3̲8>zbʇ* ,?J54$vwF`Tk\Z G)qNѥsV:*,7||ա_hG-iyU /j= QVNPx%D ɍaмIKrK Ce1T4XaM2MǗf._=w:\nw8㑉޷֔ѣ;PLu - $h12 n{h^oXj; 1+Y-!8C(6rZ>B骢/voyjj|,`\/\쑧uC~׻9)x!UKɝWy7Ƽe5Q|iHo61XcOV78KDxQ^*IR%a薗*9ΎS wieGR3Jq L*N~heȡr8͠ey: /zÌ1jx3KχR jՅ!iH8~>ЫZcX05we摉 F>8s:5:NV?P.lC5)GԚuq$2K'B@XӮSOout Ruӗ/O^<ٺgVRSTy;V+.8;B *[h9gV$Zuku3+"ޥqVmLz+H{w$\0N<7a'13;߽z}_~ ǀ#NMycAY[,n 9we4hAϏ_;s|vp׆cxK,y/9JթEG֬lsdEN%chAN,2ghSbP"Z%k0zqcS3ͬGL_tl_~=偱>Npm`P!(&)uX,l,K<lJ-4m.|Bm\ V}@mgƯO@g/\;oCǶ.߻75/p xG+GBtj`騆Z]$SG "?˒'@BL`QVR~&al)̏#ff /_t'MLQe,(yzpׂTRnT"fƲ,U EbN8;8i1Ϭ@^ JK4nťKr|γ;yg}?</e/㶒榖Y O oztiy L~CU.@na.+xzIRIXs/ْm_83+, r5{ aAWƶ=V"5p ho#pș u Hx Jފ+Ʋj{")hBJ-56oxB[IsHm=?~Ojf^ܵ6QF?&$4lBn LU7b&\j.HHZ.B ( T)TZ[JPHEUǶVDU^ƻ8wS=G;gyD3.=;LE59] >r邙nJO"fvlWj0+U:Tb-dR*^MOM7 'B%&H> vA_w ;Μ@U(ͫvJh*9ÏVP}[L%ќ.J-IPA0F"U:AeveZZ h!mJbAr bJ\Ju;{}{|> ^8tLJ%~1w(5(DfAP~eYU^\ `ARoGC7_,U,fOJ#Ɵ4r6Ҥ׍m{ $kVH4*T IYGC i͜Ր[Jh{K aX]|}qp] ⅳ=)J/arU47tr8 Z Ś-*B)hyTWu3fi2i2;?ԩڢ|(00g|Mg/ $JО1?AJYNLpzJDa~_PA:KHAI!V Z5_ \95-#Pj1DZZjCi~W~`9}`!3ՙdm>wX$h{]t(RQJZ#Ly N<\aFXT Wr ,<5Y5 ecUkKMK>2$Be~s䉯X([Ξej~gⱉ䤫ǪGjR7(X*$.Wj械4ICxU2K %(Ê|]Sf2GV}G7}6{rB3ܭO)KYպ[zx>J0{^JdVgUAoT0nF -(UTѠ6HA<jT}M:sma*'L]fpa,JJb6!:r9ermT`+ a$UdeIaYY:䓄JI*3df5"d@CfB;J55 40:A7b>,^z] ғ@~1{af=9WjA1l>s|6IJX(q]Z2IWy_pU(̐YDFzZ$..iPNFV:܈4L1=sQOF%EOG,PUs m &Jcq8,U0k3ECtuiHM)Ȅm~_}NL{{rp҇zn|QUcͤ7\2F;;\Jd%KҮrV)6"rGb4h4Hn\=XX{ޢXUUU#eEPǗ~f8 =lA1Y%8ktVqu{\pT^6L~S.ɗkMl?W9 diJXś# "KRRRnMBg4 Z>ԅ0qF`r6ΰws>{a:+ ;i#nTFӱ!{cTJ-~WwsQ+q/'vzU}{8DXU̦6cllb4ot1=;:b%I zejF-A#-X'卍N6m:Vy%RlD*J.-v1 )5/Rt 01<Kܻ~upa#4 Āݷ<5v wXbo*ɲ Ke+RT4Xs26ٸJ oP 2Yˡ|,:vdH&4R99 cX%XW XmC`X:& Jlkn{6 SgmŹ )[\DEJbyإu2>ɑNu8= ɛ5"!ѝ9p uf( hņ7 S ty&’|sߜp4F~r {9^yܝWTDVx!pՄtD-kvjwU/UKHX Ci3_ikCh؎j 5]ߜZiߟӮWM[~V ]P֫uYkd373Q$eһ%=R#8/9KZkyV莑`xH-2SXRe=Hk` )W%1\eitt^(A@ zqfn՗&Nfn;w]I9Eڴe~#Ot_trO2,߼gb`"0kE kB.p8hV -AfM-Dz,3Bj=dPKCzބ/N bBwK]([>{nƳu>./7$]km0eKjkjQ]%YşbTLY&z(a?l.&V!/&Ub#W*ZK;1>yv 1qZ{4 zBœ֖vkSZ0@Xa ٗƍZ%&S72zDJڻH* }.odlwwMM̓:89?؋mr22цznn帲Z> vWAm PK*/Cj uAec#ׁl@A,ɷҞ6;{&PWdT*,! I3/t'u-)Wek3IX|~({*jiʨlt8SL'u%餏XIYeM|_a}Y0ʩjsqKKQutoW߾VO]]>4]nkcM4#1tOf_[}1[dN®(u&NeEDYM7i,5DLzu555/osV T_WYϲ !2?t8%̅NKl0q̝Ϛ.虅]-V&;DV(ȐBKuɬ+9r{k͎n4h/TX0m.8.w}pLvd{F>0"CrkZ >h;ҋ+C׾Y1#ivQep- EK~\o1-Ϣhxbl6; 9\j']g{ˮ.ύ/'޽JjD>ŮY(0+c $O_*53s5w/;"Pk *=on7DFMs=+Z>5׷62< ӊ, pЁ]JG"RN6xGRs:ǵpdjDQ1,|']Չc=drvQSO:4VdQe eVCs[4#A$(LN[628L3% mMhBIbe9먞:C=88o:ť\}2ςOJe$H5MحSvL/+m3(* HQ)#閠3TgyLd `9]6[2D[J̦т)5_'nHJVD RNm=?vˊq9"aLb@xP:npfr#z(TՍͲE6,n t򭛟/ϦPI?rSZPM= w47&6ߒupti9fod)jA <GS]q0V}JČ VWnǓpV2;тkPӐ>D "REOOF/-4!z|g1uK ꒢".JW;e)MsK>[ f8#Ƽ^(4Q'6Y2:a<"aH*7mŹk=;T1΋EHqW3\\Y+ڼZ$#4 C()Fp1 q6yIWMf0oOU6T}QCۋJKrmZ: X7~Jb@ءbGFmkSҟR)}nV>HLf3K5U 4ES6zDܩ1>ĽtN]|{upWWs&KD  EDJ+FRAE>Fcksk\NG+#hyg|:ݩ}tܑj-^-`5-żrL,b[iAHZ8E.ܼ׉!ZhJ6F]y&N T4P;εqoiVX Cs 낥udC([_jJ"X)`Iԕeg+h`[+befھpv7C=x&̚, K3*XyT$GpG:r Pod|XqTF<^OF_*-"2&MZT D"f*Ak3wO,*Xgжp,gMxuY.UV)A+a֦vxWgʮ-V8s$oD[ (O z1ra|)WrvaMc5~^2PYdxHiZ0b8=%g1,p* ~FnO6>|v}-{affi>),'ֆwsM@вbSaUk]P]vt>/7~XМT\wGMؕ&KXՎ#Z ~;QÏVPjTЭo!Mv+ԝkLSgO[ZZ$df8t9[5ٖgZ)Y1!c6^&S2 ,#ke8Suk0UBΐ.4| ~on*/>9Eir~}/jDn0HB zlC4{4z!܈\]>[^F^~kϽL_aS]_k_/e(2GPX՚8~N ΍ZEa884Pjpo={>5'/ RP eRRb;ViOeT } '//-X VLUVxNVgGG%C nsǔ:U 9kozOK4"|](Mŵ`M%;^v:S`W~;7?_]VU%bU6ZXw+=ʢk=D`ɱ1Il5A 5|~&i SpqQ;{a0,x0,2@D]xbIKť;ˣa+rl)mӑZ;8Áhخ4DVAR$u]I7|s3R{t̑*(Gҟ/4<~<WB+W- =(pZحVT+_)kEG 2>̊QC=ƍe 6x7̚QUNF/l+E*Z),f5c+RU/ 6ࢤh~IޢaCQArUX5ifs2;_1?5dlBX4?F3 B9H"`:p# ] DyN.7Kcc|9N$6U+p9 WYKHW#^ҷҋ8}huITڼ! dYp@l.=k"B|$ݑ+e6za & -vX~)xݓfdt^bW]]+>ڵWTɡ}Qi7 EQBoߚA+ K?5рZ*C=2L<ΎѨ(.PHhq}b+f^춐t"9Nxlfnߡ0և)shcksJ IЖ!c-.,2^dl2,AL)޴v-ZW"` Ap{o΢+s|4ĮzO761[\G: .D}=ِ& êhM56⮐Q@N/#p|Ժ}UpMJ]jO])pŐ꫌ߕ5", /$mz3vM# w睦 G:euH4KN:tJbl ` GP)}@lΞχH|=2 7QnW r9.w;/}Hsg| 8' A|ͼZY\0LyHv=yo1X`iI#O1PPMK訶PhѪ6D ¶.`ZF>Ë\ՏVݑaΆתȧ` tXU>6Ī}^=;k[Sja11| &%YY> r9$S>x^ڧє"Rb{D:d%<^Xt:&GNۘDsh[r!XU vtI8U4e2}]ea4hfT(=o]E_aF^VcGy(Qze6o兲O&'6']-XEfIb?d]_I)G X'1QВEX{{Rtq-\ECۇy7-9:_ q:g%$-Xy;)l[6S@aFJ_+x$ J"3viw5ܪRᾺiVak]>#,$,&'k)`WZ4dR؞eL::ⴏL|T-|O1D*f5C546 ͡5VFJ<܊&:*IXJgÿ0]fE$0,*n:M#PŮTŶ@rձvua*t4 `Le|Z0ed}, DoSiZZCBjfZް?[n EG$/K>{ 3FTjQ,+ 1nȠnW duD^}ț[d"weXdZbgɴZQjKVlt%kUꈮQfTEN^E/.٪s0w-_j>^d5ov0pTFŻːzE|2#S)nC2b@gCs)d!v" veg"W$?ǰ&HBT 쮬HJYAKoRV$I$I?=JPIENDB`imsprog-1.8.5/IMSProg_programmer/img/ch341_35.png000066400000000000000000000531421520775651600213560ustar00rootroot00000000000000PNG  IHDR,)nPLTE w9j2f-bT"[&_*`˺>;܎.}eӾ BӞkw2IZgR! r%U~HdR/ ={Y7M8nN NR6?R\3 $CuSz`j&u C|&wN+^ ч>$sg3+z01: &b ]Oyʭk!T+qa0ujY鬖8cSB:4J]k%%ثYmb +˴?0q/ʢ,F]ˏߛoGSeYuWv?6?ea19{ffc|^8Fy[vcE(6I d+zamr"YA}`tx^ZuOEUryF++~{xj G+ `6ZWp-[uDq{\Ko5"`gwhW`E,qX9/P~ni?NVYg"DgImoӓj\̧مFCx5 u #fի/{{Ow&DM;^nZ#*@ D`ֽO7l%$7B`F1ٮfawbc ѭ6}MY=Q&@O$ǽ ^o0ifrh~zb="dŘR;AEAy?5V&G^ڊO=֐U_m/tD^.IgߣddpՕ(MQ%n$~jcZVnb !A@>hC7ѧ޷iݯ&5)ѷ&`q*Qti:7a|wQr"Jd 2ER!"XlRjҚkcr;TYڕ늫\EAe`d D∬/s{Q"kqΌL4:E{~C&Ġzݣ"@j J!7<,v9nA>}{KK> n!b -SL z/j5\ "ݐ 1fB4=^"%$)h$6#XU!NaC<%X: wB`.&i^x5nΝ͹K$!$TQy s<|F=E(ޚa?iΝ92m P/.!SVg X%IǓ#m Xx /`dY)> nޙԜOeM|-jcA@DB)Ti;me2#uXԭsQ.iX-[K3RuIK xOO''_ιsss\Q“ Vkю'3\=zAbn+!>3X-Np`=*1]zDRh!5tBfUV*6t'H"!z.On#i;eZMs,ZÕH\^;0z~'w..8_ k#+@4twn6 E 80)v/Iiy'KX،o,.OZ WkpB^43QhJ]hӻϭ%tY -,_\;03^ZMXy|/'i6XXPxto#J s/6- fFPKX9=3zESuV'{bmm}J-ʦ||ǣ((+D%`ItҼV>]=~S0l8rfԟ2teLɐ&%q3@TjbN:H:#|Xm\^ #mhኁ D o*)ogֱ˻v;7R*/|QI}6~xu ݝacn0./0gݣ>@3Av9M@-*` +U|ϧDRT$%ʶaћ^ӇN2 >شqW;ls ڊ'ԨHӌ?[_ۙyDRp*YV,wxb1VJV6WN4/çiĥK[ݷFjR`FpH>tՁ7po_s;@rg( p =W-<1'5(J/MAv!",1+>K_}&183Ijۣ*jc^Kb:R!@Ztާ60'XŜu}棙R. XV|bEJ XKnG(i`!vǴ}w'xG=Q_Hﻣzqe|~Xu|Ns#k{{̢E X>{Yѡ(ͪQ5ǩ4q$.Ηfrd=kg(LtζԼQ"F$hXiR*uEV v'Ł@,{e͵ v$ <>%/&sWN t)Q,Blz\4>\S"*:eF[/ITv)z@my^ADbN|L0Y^qU %EǠ 4cr[m{YUYPSGǟLxΪovXSGm`U!֥ .֨}Hddhp21/a|>kq)3WYR7+Z D,)|))] 䔙% ]WqtIl,*5Ss_02q5va4)^+Qee4| 'FYZƍo ,ph+#8DjA(μ0h9^s6٬rEJ$rIUNrމWub{_hL/X6!^@څ XA)p`ڸmzwE;ܼ a`Z$MDٓKqmX|en֏Q$⃲V]MQkL!~V}O.)Ҋgy ۫4A Hb٬l W)$Sp\[ߓX6Z7 =FD^I!z3`z|ʣ%YKd#-è"u,ve%gL,A|Vܓ. #+XȫvÇS@s[YKeȺJ3W.f ct_NyЯ֡-%4%6-JE!Q b3HbgBy,KtB :=hK hVX&QQ"WP9k:٫rIS{r53S'N?̝Oe1T2)22vI@J!\EH+P"*ǵ)$ײv#ݐQ\*0e s=~>S=I_F<~³ ~x-`"(ÑL,,0}33g%JKHJ*"cdؗ_{=#xnT :cGgݳ➿({JX}E-++kam- ?\9YZTNކ=7n^AZa5/U\VheE<'Myt\Oxl\`;k,2<ٓ =(B֩"Qzպnw]Π;e8 aY&agTm|3HX}#,o[owx \4G,ˊ1Xi15i"/?4wȘ^ovzR >G q\*KpXo)4X(ĚZfXÆw'']]iՔ"D"0M9Wh*DAĨIoQ 6Mu*~sqe^Uвcx&(A_%Ι)J  ?W'_tޮyXB)(b1¨(Fg&eƧ0-- +@:mƎd܎Cl37Tn-GMt mq/`q,L:G6 ,Vo,685V))1V(CqSqf봼P)Ȍ/ You{ڢߋj^ʟ.-h9GW-nm+W S|"XBV/P9W`YmrRJ, ch-2ߵMT^2nf@X~Ǝ$OrŗjEKt[!ZVFXtA2E(sf1SŠnMf5˲z $|9 +%a%&P<ξ)kzz|PFfF`T:?пЯ׷umHOe[B]Z8zuvhŢޠ\)8M}hcj~Ab*$ 1¸lVi 0Innۚ7/WoiS$DufoYouDzbtH˻NzEsfzT8@ Ta(A3 X= +8t%8;bORb+/N>7WW/kx´|{eUa0S=b5<68 VK'n: V|!5(8ħ? -5 R[ScKI}pܸ, .HYF6`DfAHټ<~߭*RLwѩƐP`h%H(x (exy姥dg*`Jj-lljКi_½}>hArbaY^ri ?U4 0*\6ȕz`00(&iEB,QRtggJk>Mt :Cex9UED%[QVJB vr gl6Hru!w_4~ q !!B+"ЛĘش9BoNCMg  Ȫݴ¨29ĝ:[!ž1@H٥U6ncR=BC{K>Q2~5кٓl,VWCǤdn&Pa/ޟygPauβʒӠrEYAĿ#q*ڦ^=m^^7پvju: ~Xww^Ȗ$Ǯ7 yISb]k&F{ARGZ]X3loӴ+.PqEr"1xXLd i/kNM)ɞ)W1 IDۄ@ |7hGɞRZ,>}ʩǃΙև$>uvB92Z잏5bN\6]Uc V$ڃdɐ`) .c,+%_4έ?,գ)b5_'jsXV2ųaK'BUMp^_^Wy3Mi1\E"Z|pBfOxq/Liݠ1l4yng{Wk, Zp;g Wm׵x2sHq?_Lgiδvji^nD aXVA un6Y"l(x1,j}zk<\Ιm "gݥ*JḤVխg?" |?@ x7Z^eyK*8*+_|Ǝ]ϟA Y[ɮK,K:Z}OPu$:x"1LBK?JP駟`::8BYv՚ќ_+R\}]Dc&n%r"#G|`2ѭh d_Oo%{n~.MD`AH"Hme5V G766P zZ3<l v 'Yb69__^ A6c:xTu,Sa'N營w`{(prjӠ~4}Wkʩ[ZGyH"MxY9"lA)?u =yĠXٛt gux A7C7z]g3R:[՗ClDU#)7AU7>)Q!V'e?l} ~Fi]]ݸ*WBCf{!Wd*AI|rF>V-SF7-hwXEZxǀhMY9&7~qчDwu%:D_-W %^"E X+/ z3D+xvDc@s+`R{WCtGY}?٘C!=>'XyXYO, 9}R фU\|%%UZ0,WWw6{as.l v&BCfUɓnya1r|04#ptLS,DBn?{2D*["hYգ$**+of/p:˟ yjoDT xJcuM^H1w,"Zfg%OU~ZsSs@ݐ@`#CttKwE㡱'[="*ľ确㭽70.Qpգ7rfYg:ك\l12i]c-E`ȖG vnd0x~Cỉ3 ZE$ޗ, eYSLH7U7,5 FC>k:&-rT=dVa, VMǢ+!?C z N!,LQ=dCʕic8uEYi*2pJ)ol%YoZ #=NDr?l6ۙS薞Z:-ˌ+N\;cڇ\6P:oLzW(4@<*>JF AAm NN]FEpIZޗc̝L7qhuFD ޺_{{{ic-Z*xCT$Q"\C+j:UIQ2ׂz]Z,C):1t *O`RV=C eW'8:};Z`E*Ec1sq gy9pH"1sWZJ5k$^$t zEpHI*nrGLaU#nA~Vs~@ݻľ4B/u343B2:D[TV# 6RV;eIUN"%']KTp-`*еgt1a]5Bἔ5d֎"Ət*)4@hxNި)o1Rca%d$p:kD,gB%rT҆#v%~2ٞvdo9at2qMZd kg\K1VtϽhR6_.e]JBFEpz^(:eBA< ZX@Igp:6dNtL`Jh{g%1y  {Z^[}EL)p`gwSn&{ X!ܒ"T ubZ%ORf5jDf__Ӻ|KC&Hߠ[jH}zw$ j7Os'sJ:o{Z/P4 H)'|K*Vk#kb3iOq|fğ\;yl ~GGGAһz1~nr~Đ'o]1LiV$SrU R8] M5KHqRvj>F"\j= "a3`X|Xm} *\ho #M$«-> Fl1a2)ϣ JH$4҅iQZSȊD)51I"QCA F!eH* ԰2bM]m|.=ӹtJۤŌ/ٙϱm-\<7f&qUǖ+t(q4-*|R%#47K'pUC܉םKFz?G{'KUsfÉHYP09#/wϽn@:٘ŠgWzo =.4БِƓBs;a66}sRMD:w>( X@l6;@8]yBj?Y]!w!OCz Hu6[# N'B!eJA+0,I#6hPi ȍ*R1- MXۮzUGZ}#^DG< u^ϝȵx"W(;;5砏NVmX sKl0F9.P [@%ٖjl^&k C…B\".*DKP K[˫:xSŖc/ud Y\C9/Q8)ɏ5 KeAKЯ2R,,! Fp0N&E!E>yR{;-fUX7S'XbcmjjչQ'jѨyV+: I_.zdE9Tڰ&d􋯓duȲw0' ƉXlygvhz3z,Vdf5{ ;(p淇tGu2/8!_+䌼6Xc9HsyJ!JyLX^i.+yвᆋ7Fc?'gtGc@7ezۺ7d2`3zdR)o+qd2mT*Q70b)Kpű&NzKšh0AcofHOO,lhhz(;,nbk}a}yaj|v1յ>Jp}.nf(CIC fn} 2ŹwgQDnT &Yu;p\CtA2 [[k+Olz6UizԻt6b# sH䎠ZUU0ūEGP-ptcNMj(I֪tX7=0̪_s: : P,vӘLDVϟ:U#iᾁx"u3ԲVBi`ªO|ɝQ\ k"/)J*+T[&PM2H(3 #z`#Q"V^+L/. .4 =U O +C9kNv<G g0Cc8>1 X9j R(d5R \D`ݴPޞTV)Z[xI511í_lm,?1:艢X֒-#`l$/5}&hZ5"Z+{G&.~|O0\¦DC%|~n_ʦNva)o(>b8J= /[*j 8^69 :{;V&+.#ѲL]"1j Gܪ1y |Ȯ:]u ̓`ٞ^JJH7{<ɚlad-,9Fe2x9ׇ3`T)]6+FzƼ+PT+<1}?\\62 7~Z(3X(\6'z8hт\@LO2FFw)HјdӃBCaftˠT[ǫ}pnHi?fxX jX.Jڝ9E'S{ASIQa>vXCո+ɬ(+JPz(UYOxx23А-ߜᱣq&P;=cY8e=/뷵9R[Ueч&i 6r` T}٪)YȻPpC[Zꩪry cmB1A|/ DxΨ' IE;a#¾Z,@b~"j4QRB8T<֨)Q~-^=Kr{ndHYmx-J+[,Tё}p,ZM)_>qi&X xL*I*Hԕ`U| :)|]N"7Nv?~bJH߅˵WX,MBсAoq |خ)VKKbOGg$h(%ŊMUdN ˣ#<Pahb~}vO=啩~OcN*yczO" pl3?37iM#l*URXMHK()2d\?"Li&;qP /:;0aqO%VbsW;Z[[ Iq4U,i̶e2b T:D*Z)g3:bRwv?iqGLVd)AH\*{$6Y|0\jf[Q I&,i/vnvk.qhO~=y\N5yhyxm-*J[ y561LlY9c-]oTZm bFˣ]#M5|a3R*(2gp^KPW8jPJe׆wƧv_utfX$G]퍾 |+{X`e0L؃~늵p5}WyP͛!^gJ.N𪜍}GW&u3Jl%"险No?ZGD  ج iގ>BWiRqpP2;-B*psĠ/hH [G{V$hf髶s5nͅU}.ISA$¾skpA'|Y[qkZX`XY\Ks1ʝ`ζ )+Luً@oor:\3[ [= x? lZWo91Q&p \|xxQ_ J `t`6n~=ׄakV"*Wes6C;$}PR㝃c3]lfaW49Gt3k εکIi~gsPETեj8[_7Ȼ`(i*ra Sahu]8Kmm%Q1*6k2tShAl'8UsʪU)ZHPf9#;(8!>pc䧰+]A\D2 )f\F`BzB8N*i&ٛN}(h_ YU``ZI\ 2۾0ڧ3Bj׋1̣rE׷"32Ҏ1lo15,ܗ()\8d` KF;r%ftWߝ6~֤׿kUWh //LZrNYhTC-;78X#EU2&wS:dC*CRR[jzlƿ󽤬[Z*![s9҂r%[ -YI ,ɮ* F.9*0GC͛[LGa`KC+uFx|DR2t1tҭޛ7Pa^z6 ~Kh}ui+U!sl~]aJ[kaɒblN\-EBD0a(S\!'w]j/By:u/-Ԅ<Ÿ-]pTvn}`qUWk;5 B$"`Gw@tdZSC@v? R蔗t'h+oVQSf]k!s|x !܍-]qW/dW)8AZ`9XjuQ]MFގz״A apr +T]QTW/icڶ!81L(Ab֝oWzy-K6{H8+;6 gT`6?N98J(ꢮ\kGL.eV|eBK0a/m4~`kΓt0M#ku7Gw]ZhR)jݛs36UYi`&0A Hx̣s.+I't١G${|m+WLWd06b TW _vBks&bE\@KhZf:F wa\nf'PT~=qxm.W*οSVfĝ3`NR?yWN`a5I;Ɍh6F#ڜKQ+!>187 zwg@%Rjآ%;\fvu@s?rs`:cVƨeaE!GDe VXB&(#a_CU U^M]T*PW;\a9yyw ]4TDpAN x5ԠF⍟v`˓"B 74y`N-*%~< Mf퍢sXR#8&`Ќ"xfbIsA+hht.Ckܰѳz\V,$F[n}>Qkԇc_5vD\ʎb䄵$rG(@gC6旷ؕ_M$ؐf:+YէF suV<>}#X*DCIWo;k>0fnls/,˥"aA r 6\ {rTT(*ʥ8--H^cӘsGneI P".q+nd23]7gAb4Zij뚀[9h֛OS]IQeQ%rD^^P\,7!o˱Z`9N/*eYKERy+VPgIjAftBUŮTG^% xTe7z2gMYK"\=fiӗU:Z85NDH(Jp*IEπ&PӤMlX2WX*AJqZk L٠ G]_IRle!ڬLuuP0' ޜe1!@[J xp1:q~*/aV^G'> ڝN{gφ%fQq9;>hxxxggU2*-` ;\K11?3rULd0?U fMݑX|[T wHSb.\ s`ǵ6|Ó'Т_`,Hc=|H{KKvX}˽O?=ΖZ*y舚v2"fԩ_‘~P1ŗ\"A K"/+,HjYxJFfnj퓙_VnjdfVҽ0XHBu7zq'W*UuhKǑ;ljnvTW✓DZ,)._ZpVXA)g-/֡EV]fj/'%4c-RWhcg2G[VØVL# Dx2x @b% ˥ q7ve:)hŽ,7kWD}v=Ïv{*N5xh=;N|:ѡX.=YgB2fR9+Jg|\<% +k\2!xD2iMZp/:omjem8p53 Y2V{u6MJY?NgS!afM$ cANc —5jye%층a*Yk#٫\*` d:-,R0`:IlP^F2*+"Eg2kk +k?jٶA1Bߌ16xwʋi_FXwQvTgf22yL=SfZXa9޳uݎpF成5Dcc}kj`0R!H/ltb6 J&)3! ޞt0:A`^^w`ۍ`s+t20oj'^FX̙<,zCe4+ݹ7:i(5Yavmo7ArʃThvۥW}Zn6b0YT]~A ^RJ$`/AK{tRC]IDbGRŖŤ~+DƜ;ߢbUWDZΥ('[ht3?}h8?Fޞ ]g"SR{}QQ²ݧ إP&b15ҩ\ NH,lXcBe7I8YC6p˰KWm*a4W1xyrR!U~يRIQSXRqT;\pM-u[u9U&P2 r1Ju?Rv57 Kr< UkݜJDSTgU_$K$( KZR wJsʥtt/\S>B>Zy2|Uz1] 6XT3d  hZ˦Kzb,1uB *b!UT$Sw=%vR;Тx~\zqK.J s f1"]m ג/r챡IEv54,q ,t Cυy;fAHAF ȼOǗ޾V 9b~_7oa,Sc`^ksP]]bp*?$&CEiob>4ɁvcMjX6zgV} őKTBH)jgcGs%F\Bi()*{ #)7@Z*.gEx;ivh;Զj*=&i>I)VL}淧D(O2CuF9N%xN!K%sYq"p]/yz]f7Q . v'hh58B!xAȪFt S :؍4 MՙsNLD?-EL/*~"6[]&\ dϹ\Z'ȕ WieiNGΟ=wmFh(Mɸ +}NlJhJbC3-TN/ n?z`^iԻzM8Wz\B,TVZN,箛ľuއ'x6e|yi78Y_ [W.^G9pE mm@ZY dl<8bYb[ÜUAO}AQ)` "\e3 ׯV'Wr7ZgЇb޻˺/V!Ge- skmӤr?ī[yEùX`2pQ-B+1E P4#8\j~yvf}`(VOZ%\m%Vڐ]u6^-ݫ@U4e/ ;]B(sRkŨSk4UB:ǽ?6!6ou;QL' >jO.C,h8Wa@ƴUa|Hqιye6hSd2&"dXRjSuS\jz*s@l!mDӮ]()rI6{JUyZH˒y-?`A\Q㓓xm Xf| >VcVsԄDJ>|$>3a,ƪ|_t*ѣǘGP+XaZj>~9NF!sgǒǘII(TFI͞`-_cܓ=gXZAZQc+|O׈;XYsޔ$-bEX=Fj" ܲ 2V 9OBEG r4 wpD7 BWyFDM(y9A`0ܓ'.'|F g1%gk`+ܫ##?0;ZIVZJK:8eϿ"K3/uʧչKܼb!X.X=`㙋+=7 X=,. >!K3= ޽>K dU|*,Ѡ.$بJZ/M+D Z+bd? P7j5qԄ)B0aS"Hp%<`\\Htz;P/^_?`pҪ`eZ^I>WBg, =\"*=d07?@+.$sfۆhVaX@$vS: Sw*XUrVe׋2-J{׫VNbT9L+4W\ Į `ťQ\UCCoZwONMT)^4QH@\}TrS?:YM7V4z&C,N\-;u]Ih20Ur_˻".+;?ÈV(ٵ<;pBf2 Z]l,u1i4좔(=g+ ߝh:i]_(S31v]qȂ ~NfWgg794e6n .NgL-V˨D"B@By׉MhVjhX~jAiT*LSVL P 7۪i$B_Unn E˞n4]@ h<O*Xtg15"XK' j*jud7,&D`AΞ|0]JY5C1 [Ȕ*`Ŷ+҂ @@ PJ`c͛j67N%'VEb+. Z G `8ȯ;ޮc$&*TnPrr$[>} z&D YI+:_BE.$&a2R#׊M)gQWRiݻ62i!@`0-UwjbЁh%"\ۻp>?""RjΡ3kj^mq5LGN4-^Mg0M0mi.PD12u0m"hDMJM~]@DѮ2f14:ER-]7igkOk,]۬8e1/~~{d.%, /VTʠrx|<XM.$4;Zۜ8ݒPr'%>զ]lW d~w-qm6' KhaӶdui9>+-t(ZPDH4JOKq h 74ELe cXV NJf'wɽhsYlq%3BL֊u0]lk)bź=aq%>[VV"8UIf Zv}_g|JX\d9Ɋ+rܖ bGl FzDRڕ!!}eՎXHZi8dZoۃesTqŦJOZ1([[uBxJEUSxA| ,u6.u^ yS6Ԭӫ;ðQ\z[#mMq_}Z UPUU4|&]S<(o[rl lrKg8~DX}Ƌ-۴ȺEdGW2ۿ3Fz#^_V*HZ?h<{Kӧ*s(:UX"Ye.8q mZ7ȶX5jjk#N5C3~3+!ٕ6@o/[.ܵ5j8>{Kh >ל< +)/F?[Z TpX-&KKGW V 'WqpG6C#R+cmz YBA4է,?[v c,Y *"& 4ԸF\Q_8B L&[oq֕BK1DRH Xe+ o~O3ܸZ/9J%yo}(GndM9ܾ†.׹+=J%Z_?#8dxyyPr2#U@XEa՟PVW߾|٣}v>c RX;)Z̼UULmNT{ZP׹Գu\oZY2G.pި$ /z9IÃNs ̦J*,j=GMy/Lv8ӧ/RxI9c0`,i.YqY$yU9Xvb-[J"mA8V{# EXўF Vc_k*Y{Hщ\]vDv#Ym8Y sK{(/Ϊڕ iY/EwW`38҂o63P(⼔Ȑ=2+Nڅe㙊ީ%c:1PP⒊jDW=}gg{ xֆYM[D݅]r'_ɫ8pmNecssӎ*LIĥȾʊk5_|Px(s(P4 V 4{-x.]QQ8,,D3?u` gAfeRcDM\\ R슛ɷJ;5<ɧk|2C#:p8ޚ9!vLΙruSyqV:_I)] Af֍0`gs'hG\ S\ zn¦#!Yk&kn,+m kk]rzwJ#n*f ﻑ9*y'oBBAoNƅ\MURǛ0SUNF=Jfιǂk;@N-W"aCge鷉n8#JhgAcg'Iޒw?& PV4E_צU&j*Tb;3tt_(Ka 1yTF+&aW{WAPˢ'󀉶!aEMMHJD6? ټx!#Hd0dPB#H @O|\/ړ:[W;`\SڌObbzc!?b:DW7.ψVBel/fwsH$]F 焿ld0&tȅ\Ő-슰R# ~S]U]SVxjFНv&my:ftaM]a6]TѰ 5*, j#= ]pY,\GHi+͋zY'>ʶ'ZxU-uuxkdqByν 1TcU!"IEH%jV=HtGjg@ b5|0ZGh'M L.XzwmUwfM̵XC\-W{/ >VjAXt5!QTRydsl~>|}믭 ` ssЅ .QmXb+jWv^WhTqˣ+&~Mu3-WJb 3ylgK㰤g 3|Al.2841LB2EXZRLxڋfJfryEūO-SnUx 䇳/-5k^\pCFLYTVaύm,~cKqc|dN(~TuMmg9d+D%9NXUa9uBM`\t<( ;F<$ܸsv ZrM1_ҫfXճO'8uUljryz!}Q`TVw1Ғed)vbc`Ⱦ\_]qR8y#!14"s^ D8+PXq- {߆]qtۓz&|cT-(SerȪ`H2rb"gb"+ڂ/ PTZjPEђb4n 7;_d bl$ )${TfqIb(RVn6c#b/{=X^>үrPMZlS7i""3dE] ` Xb")|F69,(+鷛2m(t3-8z[{'AHfx?ԇ̀ vS>g ̬4CUyBv !"|[qQxWfA K.trN{*/PV(L%/+o8 ~\cpV+مVPˌmnbf[m.u[}njau4V2`A"{g=#O9sJr_*f\kT5ȯ{ 1 Jl|*wM5nZY &aeAfO7DA$I@7 wTתroRkN`X ոmN,іhK$\ˬƓЂ2׍Єc5uC}g?ePqmԩ`WjWPR2 #))9Xk "ٕdC +Ue(/*zPk7`uؠn6gYMSXjy|XqwWՊvϱGocvM*IUcp4mzHu(Ćyzh~ۚ;zQ$e#U[ z~B[+$WGMVbD2ܯPGCܥ_~r]#7-ه}+.X;$*o*V(8}Щ$ (SX.SWNesA V*ז3Atc5R#<#Yiukѣ_2dca;|gȾ tfk+B`$BdSYVT}BUGf5CV9& \`"ڢYqys܄ 3x<[% Ga;]eDdi(h~Fz^4[QQtVdEU7ٙ1eJ/ Hᣰ> ֌jiP!bɬT+<#pLv_`hus 8,ij},Ԡ^/ I[fQ@7f²9_# &*5jV Rπs_{k8aEc\+2UYiʲЈT[$ ) "| NJףuY{!lUY |RX[\RXMbTb!aM׽?hɤx+`S1PEX8VwJNI[}"ZIDDR)Q´Rվ0+ N2D0+bWcSVva(j']cLNEo`HDWiᄞ-.bU>aR^YͮJ܂ŭd1V,8+[pj9!/V4B Y~DdZ&E"Nz!,3d*799A"јܮ 靳Q+v]cpO<i]bBtr9eυNXϳˉWf% e˒{'dWItCAe_VxNן%iD"Ib] (]a!5ěo˲pdbu]܅V]ԼA *%8Xm?EQAeyoyma9 ObmIps)+lWLBȑ>LV^?!PaV +ybq´_baSBK&fФN-G`9rDݑ?{M@HWhRZ0lW]р{ŝ0Ɔ*0~u .#>:]6q޽^l㈻=3X~)fYENܮ`Wx01t`\F$Ί;Ⰰ e):b-XQ|>>#i&Gݛ_B~#?̊ :Pͬɮ -x̀,51:u]n휖jO0-$Ӓdc>Uo)`$ZZ5H1B|Ӡ;jvldwhMTbQZZh} nS"qĈWQ )J2i𕓱~bW+p+ U%UմeOl#$!ճxc,g1@Q>X\I oZ|āNp&|}1:{M])=Hw2̮c0 1$ (=7J4cVԾ -qbXRoy+V?T(A6?sAggSCa  VԂY;t àJ=c {Qv sfNIJ┘d[ھ}:ZQZ  yyyC ʌEPTFuZ:[; `NW2+j)}h܉d.ܿ_ʶc X(78.ZɑQhPx]a[+܄}j?ffAf zCW8L`>+k./+`dWf mH۳'.sEɃ{bÄ1EY}: \nX͍k32 6|;}7ҾU., VU0˾,sH6P|Ge%tʭpTLWiI7|8XA2{5wX#˞=σV۳ `9mؑ|I-sVm|ɚRbn%UGEjc[P]@m0peI%ܸG lQ[&]LIfFAH(Z( e_ @썘b%@=}?\slvɛ3Zu,$IޭDC¶҂³b1x, v׉9 N:dĴU?0E|,Kpt_JfUդ)T3ojX#F0/ [F :?sLqљg;cƄӀ{Dg;WnLΙpW̶w*ETbj0<ʎ໸L>\se+W\1I.l}@.~hQvWgg{³@ɽt♙f ru6`uꄾ=M_~z!K'6߮J@WV <}[Pvn 2-?D`%Vo ԧɓd`ɵ>^fpRwuvWĪ/W[mD0wBN&wUb z˃O.ۃ%Vkߐ[ /'R=: 3)+ g~K{w{W>߆Rx0d|>R2 B+dM+M*VBs?s8?'ISVlt L RV:Q8 (!72CNfZŒTeP/~ۥuϨCF ?mQ Χ>eg/ROQ+ . `MJ`}^|^ѫfȨV K#~K Bw^bRV X-Nc2M]BULTʜQ͚jF cG)2;OHh1R)-b,Ƈp >W g/WofxgN139nڮդ`fo~$ʡ284F ΅duqB8.[2LBrkO |)|מmSi";i/4fvwDI]1U0MQMpú'ŜEyMS؊h܃5T"{WYjPg CP+(;Ϸiv><\hh5L١UmW)l;߿ VJ ɵ;|_}c &W}w9}XgCs$F݇Y).%ߔfET, O:ֿ̍F8(EiV7t2wT6`Ma1 QKtIT$\S&)jcf>,^4C3تˊPK~d%̣\wrY֙ǐJYV δ N6=C'JGZCKtQEt|WDS[0-5(rKŜ. P Z44 T}4J, Ĉ(h`nJjRbO Ȼ]ZtaYn-D)e16G\eqf'WBWsV#CD'M"Lv\#'Ȏt2*Z% - 3,jހEjDŽ N95O< n.2η,# ׮5BR3/_,X|_D%jH_-J-[>-IVnA> XQU/JYar .C`p衩5IvdSzG]݊ AQa⻨zf m@\XMM]/t=0ZlMG~zqJ3gٔV\|ƃ*eFb6!>_a䁗/+s>}~-2X0V='W: YKVg-YG5P.)aD D+J ʩ)MaLB~UT5 DNThY1T\`ZEѓK먾Cqc\|3RQ T':a;s&iTGV<77m!ٶe :fίgD`Q&hIFgjO} z%bC) GQ@-ɮu<ˁel%H'TJny+'+t Ev hVGU U*Ֆ5a{%V=l[Qj eSD+OjMB34 xLY) `f\. F^P| *uӳ),A+*AʮGCT}o%dW&-؎4vTD%wʫfdAoXUC6O,ЍxIY"'h8උ#ޖUW2v:J45{%4T5^\d-< xXv)[gҢRo" x#'Pԡthh ՗\JnꀽLԂTjLaqh풑qB! A9 ժ))OZŁ9MZ1>p \4lEJթ+ O^P*ֳ Uu,3F8RKTUCtAud+FhɚJ:s\X%"JS }8mpq$M n X5Cz[z59$Z?J3j)* mcXzu}B6CNrHD$e&ڎ#aZ=/d_ghb&=UNE5If%ϊտYeDVǏyWè@Ba5mI&ZTInuAьt+iA*S5[XEKv鹢ſ^㦛U^; ֱXSD381v18b1t[8Shc*QӞʶIT0DYQԬ wq.%= B!=Nw V$Wɮ9e&}*A+(+k˳*Kѭ4Sƒ",+aկD6O\}[,51%ZK'c+Qdzww*+Vp #CCoCr<07DKӢ[|yIPŜPb/[ civ {YEG"P*?kP}X%Nދ]bX_ΉB>:~qeqwWj{~~"pH.'bݙV54':MFί[i³%1ͭk6B;k:DK'o3X> XAکwh`1208h6-o5ے-UmZe׏׊<]=(k_ɖ'VMȪ0ʖ4WKĪPKj#h|1sWyZUr{%&^QWՊoHqm̼`IK~%Lh)5ץf;ԋDE=@bEK"~(T Xhnxll*br@F>7zgzϝ{a}}̜(N>aό[o}DI ˭B0Vvl A5)/5骐 Vw2M@FFf͍GVR:d![GZd/?GG ׳+D7 !Wg|јܶ)-J23L..~8,OOwqG?lQ㊏+){N T&-*С]E~s;-[*-j JBK0Q\S=[}+!jyjeyF\6ߴ1;BLa?qvG*x^ǫbr$쉆q-Yݨ%OIHfJnh[ܫ~2ʎ7ݲsfP]@nlL2᮴w{[" r5r5_,hn=7*hq͎[܄H 6{y&lnn;@"+z8JE0רMSAw+U Ny,̟O/,/@@k4)Tjtqͮ{w^IP(Ts "LV\-I(:HǎXwm/gkO Dޒ.&$Zm s3 >N%L\w Afzrq_3B٘vU84ms~DzzTmeMxNX' vX(C*dӬ;0a;4ZkBi(^JB!&&J B/EBieTDU*A/^6}_;;6۴y$хeBK(r^ e80L~D |u}_>1QJ;IL!*&UUm|[Q<԰]^S`Ŧ{'kJ\T!N[3tvÆfJ Ң ǤMv{۹:㱻|K rDG'/Xb PX M+WX@DU`Ri+q )AEk5'aj K|)BWЫ'Iro44ߒ\U`ͧMx õbbqAӴ2a{ &Z`I^dө8w+ðm ^NkoxU z8\e Rе>|NtM䖨qU 'Uk%`NkV k8I,`PeI%S/쿳 Xu;$WYpy߫ kP{a墈=3,-*U*j^I 8ϖݍ.J/I 2(采$VVϤ@B;ݹgcXa}fLnƪ{Ea);L9pt4wZŵB808QA '`׶a"xYX &&5maQ-y q:v8*q!z]|> Z0EDp@8h5M0 xVT@SKpZkMp2+a3P@/C.)bHP67YTM';owK{m;j_fXE*}bPKmɆTVeA:'0vNUK ¬T(Ș7g_LB% zb5jX^s \7Ջ!gmD>aZDi7J*IA9 A,DKd7pAfPOgs=8ъk"iՃF&H+lƯmWuu0C+cj+RBu3VdI]qSRSҝxyYd2Æ7)/ӳ7:c9kdozvL&Q\ +i&pa߫z"aE,\j@Cy`pR .\NyprR%x H/5 INs8]^Dɜ+- Q&xaKآX߿lև 39Ҋ/zIr%m}{ ,3K& Pxr68.eJ9Qgg_{!Wsl6LV 25쑀mZ@EbQp{nm}x=1P^慯Bëۣ0z~eVI: {m1tDk{GSB"r"p,‰qFiqY2U޻e;cVْ^y3_KrnD by1ZWRlH,ċhUhRȫmUttG``5r*܉NOki~Z~Aw7]Sb=2C=SڛlRȢɂ9xecZ8o5b"ƂI/tJj=H7׷xII0kQigg!,./%M1K~XCXssSf#l l9LL)ʑdZ]ff> #or[ULλC1i,A:P 2>l?׺lD¨fuY) o/KRӔf,ݖk^/uWʳgnaqj$VMaM};Iu":X0Cb{̣"Vf׵SLH!g ji؞驤#Ȃ坃\+}V<埙?aAʪZ9aM5?#awY6{ #Nc ^P@8^5ٷ53R--ZSH45x!4cٙyScq~),}yQ"':y(Z""B1ts B 4O$ \u=uyL-5X);j#~guC`e 9Vx-B$"9)5Аp>a ]}六ν}7/ǃ_0,֞J;2YCvv@’7"u2sVs%J"1ą5>>}41Zt4z`ŅZ{}uڬ[ _nbp00D'ϮC&ޔ2Q'XYObnTǬ\wo߾ͱjA?bkw+Z݀΃ksJDK͆m-?8j/(C^Mz]aAҾ~qGf+WQpnVi%8KkC0`SGJqq|ز|\T0&‰]``}:+:9_h+FZIKvD榾 N{x玴(ܰ%LIv쒃>:6 fC*+amtbs80nUX[=UZAiӘ#!Wm[v7 &EyN0p|R@Us7nn|8C8ܕn]4 S[ NKbM DZn8/C QJ#Ȩ4siWcp0nkkp{]bdnw ;Lh 9QHS0;|Aftϫ36#&ҚN rT6Hz~a_t(h?UÞkk(%JgrFtUE!w-[zn 1̌1 < jpm3v/UY~0]vu -AJ? +Dz4Q`mMfx _О:is$ʀ]dW3w 0*7B`'ODŽ$L!d!MZ,c.bh1pۻUJ=wDX嶍 mBAkEö9f=N}VLlK1l7iwň̿@G/]8RkXk4TTm_Bi)-(::@55:.-2+*/87<%$%!!$%%)(',[Y!<*QWz XǨZY]̰cKJORQT `!"VB4!Opcbed+dQ30/P8uK̼λ¼F1&^IMàsrv7Ϩ|չNEOƮxh5o]y+r5MB*nYR' 4Ozd"ś5©]UG%vJd6fTNB%r4{Frbs[:Cyh*bg]S2ZBrk^?i+TwdK-;yg5J\Q.|>eòUJUWlXf۶wÁ *6Ō$W4;/[b9xkajPƛ$8?&W윝w:[Ag *m4q$M΃޵~<::;EU\zor53use:E6zd0aF31ʐy v3ZJ3@kELcp[](jm$6K^I5~2&{ޗz!}^Ρ/ml;pV^N^ vOkSD"fDe\ ˊ-]lʼyy+-[S;}jX DP.fW3o3]vٲ+WXV+.}V9=R8ࢶ.BUի \VWslK:zzLӖ: jS"qݾREU' h,}cBcW/f6նo(hj]0JE=]g/\p2Vmug^zɗU.w, -io鮞È_͈Up7_WW_"{l)w{zNyF#W3ٟZl曚ܯJeGK=%X\W}^x~EsTY/aK.wҵ^oom|wvw!߾ DL*h UQQ:Z7֟k/ =]_{<#t"s} PfzU.-Ӻ`fT-XF 1ԃ{ ̵t큙Y@%K`|95O=:kXH8̡5kh+,D2**;YNphᮓ幹;gx`Aa,Lh]MD"A5YtY.ݙޥ *Fk+Y%Oٮ\GXΡ.ɺ5pp_ G|]kS=o  @QsߝVW0 T\{ 5ugl(Z7}hYGitս۾^W B%7cUT4ٛBeXZȑ#+4ue_^KRtzߙ,~hkWqM X88onCv*| ubDVdmUAp|lάm}gs" f{;*GwhEBսIYN$`VҪ:n5؟F, l3*"Pn H+vwOkU}kUcxlx|7rtj*>c닄65W"ۂm*j!JQ Dc-Y11}n놊eujlojٙڊ-ف[7(uPϚJQA,@E-^8x}:J. f:l L@Vt!EcV(}U(uIQM/ i8E9﨨{rTX̞(Vtl=W|daQ*fSXc1 I S2E""xBsõ`Aݎ̟-jcKS}jAK̆bڬ` LvPr1#[2+.PQJ"^ͱKS3=ZlPY˾SuQ/2+q63VH5H5>IB]gK+zNC@d4`$ٰjn` BQ/+u.[^ ƛ1JF! e!W8D4)WC7[[$g5ldCqbP5ȠhJͱc(yYzHd$bAF( 47WY"l`#rPs^[hs%qٮ^#oN-QVhHS%ZnI$^y~zزty6K&'#@2Қu>TRpj :7RnAvMc%(JQ*Uֈ[ǡ۫QW  'öak25,D$ z:;CwRg1LDs()0E ZLrcZ]@7### E`9b@$=ZIe 5699\NJʊL(I4V)?T$I:ª}оSdy}ZҙȭhꏠEaNxVWɛ0Jœ@P_b A݊NbItu5&&>X1adHE0Yplvx>Va{dϪ=+ K c$J=eĨIMuc_g[f{}I|-4a1ՔU9䲓kss64EJQ+<,ltbz37`+w" "ծ;NV}S1T+KqJFXM}Վl˗ڛ~;|3Wz}><,pߩTC:ڱ~Py@G8 ]:ԥ$hR;ZN*9]G$1Äx 6,=N>@rI`AM,"T/ G][]zp[mf$LK`x𚠆h]at ޳_.ZԂ/^ H 6[CoV h9)TA\LWR>;a?X+ u?.>NH dCp>޾=lP&7՜^#"-q. x^xkVvE|.P$VWrp℃ͿC!\4On/`ĴhA/ӄ X:g2>8ۋXUfSh|&y pe)Vl+)a-/ /аyyp{GT(+ ^sLdeiJƪ:hp0Z/ V+\Ѯ.K]⢶@E ԔPmɴu AeC^ʸsRxL*cC;^M xrvc Zp: ?J+xD 6")B'i<=J?.D`WG79,u=B|ԩC1NMvv_ϸ[3-i#xwL--XZ_jl`He/#]];8_|V~ٮvx+2h|:9MdY=h4+b>daʙsh6^EJДyhuւX Ő[vx:+v|pH$%eW"ٺXJ+L(50T֛oHI#3xZ1qx0600w;ru|N?X݇v]J w Ƞ.3ZU~o.%`5? 1z/T׏E\WOQ-ڽ$+ yDiqF6;*.=*1zt} ŤT_/Y-Q4*ausrlh^xw4!QҸνۘ'\*\ UaW|߮/AH >JdVD/)ku%]]* fBѹ o<#zK% 4 [n|(BÄ?u~>o-XuK,CNZf֑]552b̝ qyx igڦ%VlReG"FY{ֲMCba-GH<_u5zOb(/ɊP xmxDU؈\\KLgR>Rmv B%k`EZ0 Y1V2;oA p(1FmWEeD⸨x>PMZ}λs\5h<օٽ2ט*$ j(ڛ.L+B[P'T^Z7ؽϨZ#ɒe]DP/&,^UwI|X=؛V,]q*d]`"T`uC/v]#(ZuFˢH!x4Ztpք dbUDC69uv3=Ԃ6Jr'fW]Ђ:J >(::Ҳh-:OՓ`0`qmM!ˌDǀL> [9}% rVdTղg-EJɮ"J8p$ˋouvO0Yq,)lm5&x}[u54Cz*+MV+}Tp{%J$f٢ȊP&0GZ CPpϞ1YaVZ7-L]:†![\ "b0H)2$_ڙ]uu!1hk8+ p>`4`E*P*l*LJ'KõptB40WϷ ߹VmHc&snĝ8C&$Yifզ7| CZ :.ና"X`J͡\fuq/]`Z hsb?F]ug]^J&L8|r I2PnHf !+\dWթS+$1@E֢Iq4`5ÒTUІ,ЖoVxPXjg7۲OOS7u^z|ncbzczt5vV8BU *JG|+_B!JdZl(,,١ Ǎ㴀 *䥦=suw|I+$y/  4?H67dE RqkGiv5jZPoYX>(6;Ka<&z:u8k(Ǘ_nh-mX8L-e%!$QXDb]Z]+u]jDU `YT"8- یr!p]gP XJJ€5k Vi'7љŀau BVXDhW>HWH "gbDbZrUC0VcہSH+ [gnݨ/E 8UWY@Y,Uem T\V7t\")1 Y().EL]. YތOh3D Q+Y>k֗2bx4ݯYvU<&UUP7v|H ]SZӴUȋV`ZsPP ]OP nW}ڛizzBUgu%hxb*F.gx\iK+&-JKI$#i)h9 %rj+I?)t=}+p* 65!1h*$#mᑌs0& lW\/"V3+*`!] qW5ւX d0X1AbHx\`rV=.hոxdo'J0.zemHj̮C;깯ib|꼇{8cŴŊWTq')hY $'!^yitA_+bEGԾ몫ZaWh33O]m>@LYIpm$joVU5KQٶZl?~h%X-4ᘮ*sv"T/qV{®hv55<2h@"X 4|4t[^Z-q%M"RU4JQ̮h$ +B<ݞYc0-3%,*>ReqKŢnc`A[r/lRҍ=]r%o~0"EG]7\U0cFGԶ}|f._ {XzkKX,[TDثD@*hq,)j^X)ERx\Zj=4\cg `_cؤ\[BUVl˳qRX$.I:MִbT@>(9e:}vg.}]Щ醡 YRGO{^rA1;(,IZ)*U87RZA ML/81y NM9PPAK.Li2aWf .:QHv'ZDJ2HX^1T` Df$+1|̋]Ց|j'()zmuWT_+'PU^RTYآ҂saAT2SVatϭd8  Bv J8]}I٠҂˱ ^xt:F kFn,8V+քDH͞;T݄v-Z)jV,NQPy R ZG<; pj4&].pSCWV5Ɯ%_2e5> OI'PEc(Nh̯yK~~XQg>|˨W `^68\ԾCT+ۚ(R9J( UŢ Z,(ٕ9V__~'“buUdWY{s9I `r5;5ȋbKib/6aZэBhgEa:m-+3,fWUuob^bF;fW|f 38||'"?:hٵJH8j)VD^XI$X8q`*]% /w?}_VXvEcWH Xb jV[C7o!:Q3ЉYI x&{1X-S"믶c)ts:QC eqihENpP~(`sY>oif%vѤ{~W+- ( J5 VQ+ *eW#+mzzQux"ҕvo߰F>s#_IѸLn~lpڸkIARTфnz#򓮢RR-tb$vb}Aq ,=uy^,^=Ks*X{BC?R}淗K7޵xko:ڧaW4c_J3^|E@B7-Li5&a(ڂ\GqLKJCD˨Am+`"k`tO?zfsmoߣOî9K uI3MR`A8 P'Y::qm#a,Ai[%kT,bY4^Q/-Lo[õ@ 5vO?w. 1曙:!:E~ȼomԊ^(%ӊZ߱6-h,:V^JM֋j`\aW8>M\]o~Pd<].B fi`98e}x. OxXv֗-%VhgXgjA.5.łs=[5X +e^GϬmnwͶZFzr1Ab\"-)B>װȴJ׉˜34bɫn(uD2ōhI컂wɰ8 > }^}X 7.m6뵽h=޹kKWH @ZGϼLƃXfktլ}bg'/kѲ,(ʢ[J8KY,/#f(Cb67Z][߸٬5wa]zGaWWKͩDK72iݘ7;JSDO JoyVF,ccٺmS+V<q{ (S[÷ok:Ns#Z?>yhA|\."1LB)vcu bU1FmUՋ-AmkTVO-)/ь+mBI%>d~ ZIs/{dWZ-돿^. a8AUFي!XSϩUz^E*+A'\6Iqձ&foS*]kV:Ȱlʮ(h7C?@kvl%ՕSS_˅](4]TͿ:o<\,v=߬w9ů5&Iųdɔ1Z^}6de`WSZ!5(QT`ݦv`kC*~yع%r-O+>:~UAZЖc|Cj Vy3Ol 6UG]-;BJaߪwf:1Jʰ-b)^1Ub&0^RX'zb4bCh!ƛ*t˪*+3=P}5k "B&k$DE'QnZʢ`dũ_p<`!50m]PYe8ܸe9_]rσPvV/êl[\ZYu\jfoeꕅZ`,%L7='ysP$,EWjPbAT5Wӂ.\s|e[3P+;|Q]I ZQEHA$r:xIk(,8acI*UCjms=3vꎋ^t ٕ 8>+[II Y\[]e|.TWj%ۚb0Zc׌!,FOTObQ !!bjV&t'&*h!T@N,Uro?Ԯhݾ= Iۉ|i"9^, @(Uq@K(D>tk46`)N0BMl.ldk۫#a2j[˯.i]ep}[ͺKڪX;ۈPN= {Lu=kNlK90ⅅJ-%Rt\#VyI/ ø)OJ׼3!q.k ("*(-D vBHp!Q."eDm۴,f0{i~X36Co#<996#Lb;TWiQvk'P|{x>dX[‘ϗ[v;UFW}iFH,7b-T$rZ(WMTtȸ8sbAoA:O`R Uug:`v%+l<:Yq>|S+MFB:f2:b%4*+f]Fz)o ]^ZUsz:YP+ս>1It:[Yb1r`Y`;h-:vb z)*'3i`.J%{`@;a:ʊ:Ɨ`P{`%eAˀ%j6[ zř$bH&+9ܬ| ^bcEed3}q9/<۰H-bkff߽{p{H AIXDŐ"qىKۡE]b.El$-y¹A!jK|4Ohƍ0F;Unɭ,C}(1:`ws{u=tnXV7J}y[br.+K>E5p8d!~!/.`G}!V+3MX)Q.g+v,oƐaWj`|E߅]+'tØJ{<57䂬^].ZzLc.D#"E=+n)[|'$VnǢ)6=Kj V?{m3477rV{7Ǖ a^z$RZsq[-lz![,\)my>,7΅J%_47vM$^ `zE#.9m4XbݺwVԄTQFG n0W*<=4/ 0o2 /RmOǃ4I@$U4BNf6Dwz4;@N2uv{; w>!;IZ8d,,s)kꑠ:LÂ'ckBB)d-$j.zP !%1]vkםf4}G@Xa+[zi% xZ@s2MMuu:o|qۯGjCjî ++lz cC5lK! Dl|x$,#*7c)Y\VaWLۻzZ[ $~[,вB8 "Op|5|$T̨4)=m$zI]=ɪvZ }WZ"A=DBHmH:O<z$_XE(CqDvZQj}Y.Uf%q()Eȸ$VOk Ldb?"Vx$Y$J1l%9(u.{{4jȓؖtH{%yEk "dnou5yܡ <^ !S=,lhBsnτlh$mKT'ݍw5|Ty#rְL9tN<+wPWHH(/TʤH''tBVcZcp _N:ev0Â,Z\r.\1/>WJp 6 FCɠ$sf4&*+EbbI&XkZ{4RdzFNRrL~7v@X1\.~? FIC$lK`gRڍl>.cY( tg^Ż/+VI_JUTZՔ\> XCmi2`iG*frrzVsnVLN5rҁcBm%h|Z4*%.aJƙka!Ɵ&y˜ٕz]XNRoV> dBOq=KU\&WO˦ճJJm^YD4v8Nz&:'RXq9Y$7X)+M0͇jYn`g J9) vV_1XP>DB@,٬M*2E_pNaeT<v~r޷%|"a>E-[!,vlaY`W^oЏV{}>KLK0ӰT] %~z 4N95% ᦋM_5rp\G LdB6nDyliȆzEB-2zyB{jz?Hfe",SdB1$Yi,B(dQe+iOt ԨP1,z| c鍰+۩QSN"V˧jMƃUgJ +#ǐ#W)@ϋP]4.~Czeĩ `Ҥt Dj&)$1VQgiv%SԸiS Ì(*-Ʈt  ‘f;HWw~<{ .s| G d:A]u㵏UZHf&xtvFM]XHәa0B&F [8:ꜝZk?r)RgtRt#X'cﻚb>*a;aidk 6gEAjtpKl9g5dvտNO/ZVךC^" øܧs2ٕ0]Ġ5Bx X*z5C V ߱_%RuCȬ cW]Ʀ4직̶OBt"dN7jS̘{c1TZLǟj+TU4{vH hC&j(;_:G'ǃu" b1}_b|' ,ԣnl vǼQR9 OeN˜ЗES|Z68~+286QT,Q3>,|0Xq9vke ZC:B]VjɹLT(khNB8a$ ZqR.WBBԔΆx xkfo5Q$/.cur{ss.f!]G'VY)-EjVC6[kNG|1Tȱ!`[FF+9kW-j~FEn`9u  l-[]5 -Ub1DyhLr|ނՉmLKq)+iZ)7**el{/\ctU/zD}l=5'J!oE }.A c2>0 DK XҪߌ_pS 22Z,:&/dN(4fWys3ѕA\."6f`W̮rv%<,F Z`EHA8pމ.Udi `ӏ%O,2ђM F+(Ga}Evu TO`$ qNߌآ|6bc ɲ;7S I+vrGTDmgI۵:Dw&BYhXh.h9$r,p shuS>m 7j<][ - $zyYuIz Fz~Ӵ(ߖdWkhWϥ{C`fh<=AO}Sԩ!X̮N8j51lqB-kBgAc5*fWh,YF`:hepd}cj`:D(蘅r.Xz]&]cUWAwO:9@kWNAJ)?LM3X_@j^?|^m]2ru3yCP!QiO͸ȕ)vxVm5$9aI$.I+Z%a\XXUϑz5xV(f=Ond&QxΨt츰z5xc{K=,.j8I} \Ws=N0?W"X%ڙ1(beV , _,}CЇ>/H\=IENDB`imsprog-1.8.5/IMSProg_programmer/img/ch341_black150.png000066400000000000000000000203071520775651600224260ustar00rootroot00000000000000PNG  IHDR ߁PLTEǽֽȼٶ½ſžϼ_]fus{ΩrqxyABHfehĬٟۉWS]GHR``lKKSAEM11455*+0FGM9:BNMS:=D>=C68@EGPGIRLMVYY^DDM538 !%&&+QPZ>AK779GEJMKO0/.BCK\\c`_fӃrrxvw~ijoffkDBEй-*)ÈnovҲ}~ÿίA>@վhee½¶ĵ Ѻ'$#{{~qnnaKCA߮UQTYOGȲwmc"Ο?95}]VU2-ťѻEG>9`ckG=#ٝRӷF=5"E630RD#8/קnYB*%Ĩֽ[Ēʲ}bi]QEţ;޺}vqbd_]OHH둈{ѻzNeP$mUrOVH8zg,|pĬOB3Ö#rte͸`Pi-oeY<# -zeLtn%=82J7tRNS j5#GI˜]}k@֞FвԇсèiBIDATxMKAI>P`բ*Vft'ɰDNˢX6ҘkZDZ0'/E"} =W=d@rPM۝ PJkM:+mog I;PF྅T6M1oRs!ϧ8"@]s㖲YӱD7PDĥ~gcܨ*br~vm^EGۀ- 3յ$,rޓ =Y E ^qxhh`41499I(л.7L'{ s?;j\iVP힞A9\M6j,93!p.`YBh`lM71TyDVBiCeg]]GF$pN %rrYn99Pʈ0HvPg֦j@Y,3PYFɴRb}&]Gop\( ,&gv\G3 Ü 65Jںm ǔBJq3MjyrH J9}9gӈ@&e!i\T^@Gtt5}Zgŕe=_L3*aB kD/5Qh ߲0Dv 94=47]+po]_^\JZIP e7\pӻ´؊] Kta@iA1a#k!:/מ_fMqW/Fz׋ջ^^{׻2]uMfŵ&F6uscellD D Yny>o5KCEEy?JZi@ue  Ö8h@(QX1U ET n:@Fm‡yxQj00`0ZX)%^IY#82oCDZH_IIֻ˵d;J YM5H\\S@a7D貽D9c0ʘ-Ghc{)ϯf:RzW)?yplA6A%gÔ,U /2$`{{ocM-O3^Z&T%MyV)Bcz M&^ZFWȶDӮaIڽ/AGh L[ò ZY=8E)3X v 4Q|}g! q\Q<֪lPaⴏbN j`9x@9)6 Mˠv/R',pRϑ[} e0唠ӛ:[2U|43{}{cպ$ax' ko<͛o(doY"U' ypc+ & *#t"l0FRv⹡z}Wn޺u`Cܺ&᠉Ƣx쪨Na8+%AZ-0/̌AQpC$D;'Nuk"|sz$MrGjLarEJ:ʡHeo/hEX*HҸnWa-=r?e? !uMQ: B_R,rd :h%>*T5I̺H?2'X]pHHv.d(ddqɊ869 jp’* 6KP"ejѳ[a[ے#K_8(/#DTa)1 4,bl1z_P89š̗G9xF^r|0VGE>CgJ-ɪm‰ %s:#4w QFQXN:C`BzҞŲPV(Dly6\8zp{OG_=zHTr8^QH4Uy~:(SDeT[YUHhS1WO@#W4Ra$TqU`9f,.We9:>wo,#0%JzY`+ǚk^GB ,Ffs- \|.I:Rk12,',Fg i+{6-t\d ?J[W:1skO?$qBQ̛u#+(5 P&;~yCwfE&Wj%ͅύ;Y(aYK$=ɫa)hгT$Wql{S9|um~T֘bnMk֮\ B-K>/]RqdĞc-U ;{sg**XolTS.l6cNSӓ&`I3r>5|k槊.'Ү*e^Ɩ^>."~F8:Ke&`X[ qxč=zNOL~:Ժ߽a?t\o+[Vtk:a-&h`BFIJ޴1?yiȞ 7jnumpFV~[h0|hnᐟTC:a `@SmuC??gHϮǯMl=aݼnܢ3)}rbyKrU }bKP\ "^MAն^y[Ѽ{ux{֘W>ݧgl}&ero& Mie2}]q oѝV-ivb H%$_V4~в^]$B,CCG'fݔbSgXOi]EÏ7 lDJ. ,ԗ(P`H`C! +2*8n9cWzeꏭGwY|/F1ދz/c6E f&!qwXdiHcnKeBB )!$6 `CQ[Pj"*R-R(qԪzq[r`|or罐 ÌH \hezF525,Tֈ@PLgj&~_g΍.rPtKT;:U*Uc!F $rO&'utTM5+n~`],8pK.VyC.|):pXP[tK/i0FrK(DB<5bYG4X Agm~uEPY&+/|z:t@@tgm*ȅpF=_-p0 lp=Kc`ٶу-e@U☵/ϯ}/ˇ|ͽ*Fp XmJrmіV(.\B6:zC'+z>>yr{_[-Wp")g(x #{eSAl-Mjv 敳OO} w}f[Bg2E7R Xr +}i**&VV+ؙ8߁_fVeAA4fszyx=g{WZYѥl 3zywqe4фIદ(x8MDb'Yef|7!Vn, ~asDeHU`_=bIl,J^w1JpԌ4D=ĩXꮛ UIDdsxk݉P(C}G<KaR`IbBr2d2c4ԋهVr`x(ot{V pg}YX#$d>xRy|z}]bod׌$èWϏ} gjZ-*Oa/XQp4׹@.MG̱U$5l(Jp(¬xÙabK\kTM\t͟,wevY}$V%(N Grrsٍ6'a.z1(`6־}gK hР疂-ibx?ݗT,I7Qw$>$bi̔ee쓘) ~2 kspk*e~F"Z XB$ :|OLcٍm;k*,cJˎF2 YO*/?|#yU;ۏd vY"m+ak&Ġ4gIQ\<+xٓR#l; Hh zR`X4[JpAÎ@(]!X$"O(n4윹<}`cVkޥ`I1c/azM|(/ͅBK+p<'Rl  =:S@52u?X$NӸc69E  SrTt4V"iE)~y[u?uwsd?y{7qjMq_ϬӡȏH%) /kC\Y \|db[k1OOwhߜg~E,gBtܬEOk>r)!8=7?=4(IWqk/~X6Ijm ch:d켟F5+VMM9~|`k%`5{'c t,KT}2N'hT?v%ϵOwy*xmWfDz%Q[#6-? D("8?|@W '着* vY]bIHe,jeW4HiyOrٙJ6G< er]{ROt(","&ԄhM`tᒊ"F5Řf8[]ghʞl̔X ŢimrE|XΧ"KZJvgOJ6{ڧUG[ϫ;n(DL1R$ $c|~|꿙`QmuOo3U਼)_[M4bbaD= Ql.$}A~W6;zÈյsnMCq2:/Ud(HJ&RL_SCU. 댶Վٖx[f22>TD,C_)~-wOrNrc) X fsc[)e0vt֚PI3%*;=UnԷRMGaF{m@A3J\!\f8K-Z}}K뽍B s~{6PiQA=CP$%W|W*T0D ӋV^d)%Պ:efOYWUX|>J'_m{"-.ׇ{n"M"MHɛHH/K\; EdD4Sѥ(sqA/v6w[O5W< AT;HJGpdA8L/]yv-ë ~\מ+(Rv̻: ī~su@,{Uq$l"pD; i]D`ʭ*'"yqE89}syԞI H)] ^͘y_QNoO_2yVj*b_*5 YTN7*ɧ="gW~SjeTc*G̚af%m-rjzeQmG_+Ϩm_έX}{⨔}%}pqzIIENDB`imsprog-1.8.5/IMSProg_programmer/img/ch341_green150.png000066400000000000000000000177341520775651600224640ustar00rootroot00000000000000PNG  IHDR ߁PLTE݄Tºz[ޢnĽݭȤſzhľő̘M˅þȥso:XKqd5nH¸wM_9eC\PQYd +żùļqU1l_Y6xaeX32!}x~rk Ǿh[]foMBGPAx(f?;F)"e]oR('.$)_jVW}t1syjˑrNQB 4A (3m2>^_ݹqw[Ǜ]#-F?D~qHRW3OJUB> F<ۇ"'εZzTnifP̋͟iBhfl5\QFGjĽDƦh-trj9!󨩱3tf HG׻W,îRyDl`P`[f^['/osu{ ԽC5!NZVOSKBFwfdrtBkr$mB;O.*6tRNS $D3ThtژeJވ̉`?ȭƁopK7^[IDATxmLu[X@D)Dea>?4i%&^GLN1obk j a*%Vf+0,1mT&U2p:<wfL2~5,-'g<IFD,M&<$ SrAYWڤT7{Ja_po/)~rYɱJU`Lidp-:^8CuAGX,|sIvEցJH)R>%weeS[2ZJaB!UsĵF"\Av i8xX^W+Ԟ߫ ~FnI ݾemG,ͤIya h*H9":Knwj˝Kc`Ȝy%l6"ogu9@U(Bɔڙϕ>h=4rf{vؙ;{zX]J c.1gc~1Uc gZ۾7bH>c޽{cS[ʧnˮxXΰlE&hH 0mj;.$Z9udy {w^_OcGV?n(]͙+Ex/~}u!m4a]& ,-*l:̜ZٕUkwMȠ~a>F,I K;sй//{vAp&5<0| Z?X{\VywoSʶF Zg*<}ZzOLNQDoX84Z(f=  HY\Yb#^Y;:駇 4~M[+[-``p8={⢜b1}\sl>MO_b# 5vv;u6k,=,UZlfS:TxJʓM"LZZJpk,3Ju e {LD8 x{G;a4o7(:KZzXQ=ڦ~~pk" Q6P#9(8`@MP@R";;Wgz>^"oVX'\_;j3t Nn44Dso1wpT,x?1bZJ!]/w`$uH?3q=vQZ)L2 Wؒ$N4J*#%T<җ}tcSQK#zuJP=Mzl2H=l DycX!6eQ߅ :v\o1աXu0 iţJ*E,8PJuSEhww" _-#`5B F-Zn- 2LDvꁒUЮCy]c/[0 -:`S岪Aސ%ą r~ꄥg}|va>?Lt &iN`-?cꪉx.6Uc@ BFlz=C2>>>toV@`]0T4:k*:U60Ot2e}NՓ{ '''o)_Y_k`nAv᜜]ًǸz6qn(y . 'g^oÂ+_wOЋz뤃D2pjIһI|nc:-1sVף`ժ7&MO/>ݹUU\]oE o- .13b▔\SO׃ 3w;yKn׳O朩g 5$p0f9Rim- hsJ//c|ê+ j |Z{yf~9=\m NkhUg}xX#첊CXWS0 Wd2&_R{tg6`3v޼RSTY:=wk=6##S &łiyM9Mda;*ŀCbr3LAkbޡi J[#U]N&PaXކ+jrZEj2%pe`?_Y`a(D*9w끚X,esΊp9Z#Ey XJsr] wz3=Vu(>̲pUKmйZf<PҼ1d\[ X%_P62hS*[ <ާ᛫5oM-7O'.ED"|"GF"XB,O t_p U_lY5uma4]G 'h x'S()<x5맴J\к,}VLz˾CWoK þv1Y&!Sj8 b&sbCoD쬤z25JV&]>dRݝzWhY5^#@J;#Ʉa.إ)yC=(sJ:W"u3ulgr!/JuSZ0 <gsU7444+sA.LxшnST\(a=$UUBF!>{➓Vۦ@؄{ =H(#}\(P @ި6 +UB[w+AQbץL8fxy"Yڥ#i#\6k+5{CceXn,0m ]+FV!2@5S,I4vM^٭]R\]KCʹa= DORX80*hMlhY7l/.ٸig\y`Kx;xV 9Es^:렫ܦUtKIWtwOg/O6KA@j`Qi?iHŚ,E94v]RMX8F $L TЯ%d=IBSIFx PQEE/Nh1dV$(֏fTLc?-rA$#H2J<9XEG i|A25ama%}^h F(?Մ^p!ɥΔ+׬P$EHI9/Rs9s@ "$`fe$Zf$ R`f7Ϡ I XIENDB`imsprog-1.8.5/IMSProg_programmer/img/ch341_spi.png000066400000000000000000000554041520775651600217250ustar00rootroot00000000000000PNG  IHDR,)nPLTE35<14;""%$$)!;:@ 87<./5 $$$&55;('*+*.((-57<;;D*+1-,156> 99>,-422:79?9:A028/08ٺ //2>?Gܾ?=B۽215&%$$&,447ԷCCIGGM׶')0`_cbej"tuy[Y^QQTFRSBMN4/0npuUUYܷgjo/+,ѶƧֺCADӲMWY֞KLS>;?0ȱٰtf}{{fZRtWzKDCЯĭٺǹŝG?;6-'Ȇ{oic`+04⿊ڹE$qǽϳpԾ[QKԝcɒ7ɧ<5+ ٷyuj_ٱDյ0{g+YL:C:4}oV|*gVAGPA0YGq߮iʧt¶Kϝ'{SOWhTZ[>!"衚c}|G օptRNS@h!S/е>WIDATxAj@9A1#glזql0!ppdz(t܂ I4^T4dwǿyaw[~"ܵӅ:ҙ\#eQLOc-r6dU@+$6vO^%&#[cgYklԙB 4ػGY䜵Κh~(X$+WΜ L})*$\GrѴS{GJ)4U2.̗rI6O%o%e^1K{!Jva[97!s4 @ݥ 0 H3!8K4O,x 198 &&1& &D{`01366s앻-].c3-gdzZo1=Y* .!Í-٫W MYq !('~[b D9 i+OGmfʏĘ-6l5.0>sj -MoO@v̭. 꺄z%`!856|Ďf!ϯ|`BI@pI`-?=$73K, <(T& , ndžwX>" w6%3gW٦ &uhDA18 ʘ@eeѡcOML-&b' x K$Gh<}H]*9BCE_xirreM8w}cqE&²r]׋yNq$(ѽ/I DW`s¥B,Ctl& \딂%#aG˓-qii l&aXa6ҐmEBP(N\!SBڇ)EL\D^[`Z2MG=UsehDd `\' ^i1A@Hhf?rj"/M( Y$Ks )lƌ &V_. ˲IP*] 0jP,&sM۶Y~u/obvnW%Ia;#EԤ  GqwLwGԚkfL%h&, F# _,e %CSPZ`0%A H.41MBRlX&ӯ1Fd`!>`J ĠQ"K. BJ2vɛ;__Y+jVQAhy!ENrbαA$ӕ,5u!|[e:~&iEB)5( L D.M5VǜyM(1Ui-AYnnR*-YUOVJWhCcG(`L4y!Dip`>B ٶiSϭM罁AHHMIPU(T'1뒓 E$?::u \leG6ϯe"C* }ƲDK&tq,Q  O:ܓ,+]Á޹g =*]ͅ+ؕqo=#߮AbJ"քąXbBBЃvbE7)SQ=u#!MHPBPBHX GFjȍZcS}}6^]|x鎷gtSR_k ND)Q z-Y?pAk-p% \ݬj~zm[g?lI7NꩂRwpCAmB{ˠT "(CmB`bz[ RK>s׵-?هxo4O4L{ǁj:U8N)YIRTUmGT=ـ!2<-JZ͓U9\Un}Њ-CG^ Yׁ 2p*Q9~m]E2,Dh-p%I a 1",lKg*U"z;^Vufnf.`mZ}srrc{[KaaAu<MjݮTǟ߻~}=[ ZW͍ϼ2S2^2^,0*T!HYNr9Z=vT[xBҙzl^24/Eus;J[ux?%38XܛlprT' THa|4,0b/`Νdx2 W1c=׷/ sof41$dBGIJXAM!GAQ(.X ˆ#.nuXتU;3tynFs>6n/޼tvtR8wP-[ȸztg5Xr-tY?PXO">`I>[ndV{fmw뿼3@ξKejJ%AyBTբe@;!egWFh .5 q JЁq1RT邜XWo__oݚM<[Fⅸs,_qZ>{a/+(@Z)6Pg-'*,STf_]XQL&"M €پcoD9ƍFޮL0d1E(EEٟ#9m AR$ubB ZXy33+`bE[WcQ4e{F|/ ?xzɿ|_ת 1zG*jEZ?s08`EQ ~mc 5KǠ,DzzER%C%]Mj&$c)];j; ?Λo{+\>i_gH-_{YJz !%Z{B<>a^N~bݺLB,8'L>R=AB,NzjGVmVzõ7۷oz_̓10 [PeUʟme2hQ 4RYʌub gD9JX@6߸w{;lܸO/vɓ9F(s6,W;dϞ>";PȭB-Ȅ5 a;QB̊$@^iX(:\x0#q;?pw~ ÷>NlbNǩe{ s9+=H)nαz+Qq"`\p+0+UHؑڦőnunKeee G%ܹՋoߢS0EAkWC t_ѧ ͍FBO79TC,o0"T2|zgV_]Ka;v;/{pvE}a J8̟qX|,[D-./o-h(qh=[V1ty]Ajr֕k,ˍYkkv:?{2\ X֒hXhR;}EVxέrX3͘^iύSBbj5kN+|/BE*+$vw˙A3ZJ/5 wX/, hX(+DX!|E`ߊm.(J,VkD:-I`wUzzCGbPii2SgNơكm wX׿(!]m8pL.0dϲЀC{ ؚN6?u:)h7,L Gj*P1X h0p [{zKSGLu%|mNk;¸ ߲eCA .*dZ@by+B3gmDcnUO"G-QN#䪵5kN@">%@?%4sAH[}"G^TT k?p0âG_usa =ybH)nZ{(~sKR:fm/C=0AJcbxL(;r͚52qIaGHo.R;;SRG=5xtAFacTDo?V9t,JSRQ|Ǯf|y<+_i +XDˈc`{zJ59Rޠ)y:{aXmξ{[/*P B[A( e9tp% f=:k-m)gt!ue_l 1 "`P8%NLPtt:z// }&5\+z_fGW%PC) Cv,jk8"Ok8(sxYnY}bwhXL&^3H>hksNS9_>~k{Aڷ Co?6tB!Be"%DJK0@t֞FBɱ#p$\kK֬ Z*??? ԗvEJ[=;u I]^VW Ů;y$0ʴBKB_hGQ,Xszflm*3Ez%RZkb*iUK. тT:ќC^!6Iu"1f(j WV[>j8<i_1p| R,D [F6L%Jm@H\^^o09=b K\IZdi)b$mlKHO;Ռy#]:]+Zr`tpB˵ ۫thpVChǍd ]i  7$+pq2$ ħɁT5^TEgm+B MbS▸$~&hs)n\QiG{}S}Y992D Z9`ՆY:;Q+FFa6jLM5))ԍatx[#ia\BpI22 ][QtI~)s008;tjwzxB0*<jv촀4h *\Bi0T eH_nI2_0IH@"qB @ٿ+گ8l=-^G,yk??r_lha$WP8b Sj;ԪaGG$` Bd=cL%$Wc͓e\j9aD1̓X,:z 5O`+?y^aÆklɑ WãvԔDY 994kD})x b55Lƒ BxoF(Ad4*Zf0.=l%M Xq@׭=_2;{`mpFDEi(z }aMIxfU[wee_^A3Y&K*RalkJRThk(TҚ );J ~I!(ֆϽ:3.fC{l]AB6D 8[Mxb]f!#B.R#Sq PhXpK7R8ֿB`@m7n\X׹wY)I4r.ijγ<9{h [xf-: SF=T9'r7>ZEKW>xxnzeWUGm}$YٷW:V+Wg!\\/ƕ[6ns̀,-PZXF˜qyqB0.73D?X)ى=cw| vNM= r^hKL y-vr#`1URcbJ!&G$ВifP:3P %p놺f޸~~Rs琴?:[g<9 Oj߲냆鬜ǵ+!Ps|` HX&vu0!6ہdyR>hXfHJY-Y .[(}AњGnx:޽sg䛋O55uuPOUjx`t>mZp8+ *PV "O[LI-V1L"oQj#jB.Q"R(!U( ׯڽt7w<}}-Tl8+W^uʱkkRӯ2ʩ=9L)[,9B>\R Db4mbi*Ɏdck*Đȋ4iIiK,*}$z|c iZwu Wf.@1h 5d5dgH C"-a!ug]5[Bhp&Gaަ:5F唞M!Z |KJp") `-M~K檈dk_|pw5ẁ_\u؊2heVDQXC TERPVȱXs/0$1,bD|'cLD t6i hK^i#WpFPȋ;_yγWBv50 6g:BHjly: 2 CV( U;K(H f52q5#iF%f VYPtgkHny PofW|yO)V;|ٮ զ8"'<yP}"nzdXJ(DJ/0mcd1t OT>'kot][3ajh_{ F!vIJwfxXi z`2,*mEzJW"#%FD4>ZUbdSxs !eGે̢dǮV{x.T/ۏxB=f+HĥB\!=gp$ ,|,.IU a$K-k1p&@UhC‰8Fчܫ;ןo?rŅa.('p `(]*H`| HUj.2ZT0IXtQdnB\ 1 5&dk FFnlpwe镫Sϟ_}rmU5,׏ jNYp[k 5Dm[=SlwSh;&X9B^(dXB<C'-N`x ТD T@A)p>IwG@ ~x,]ue'Oo* Oiw|tIVgۺI"#/,AW0ol4TP#Sefa&+ {r9(Ҹr5$+r>d}z؀HwJɏGPN%p~Ӧ+HDC>׿=1|H[molZ\ASf+r2̶j֐\j[t gj.P!L&Z!b__JKDN%l(t Jڼ԰, ~~~xAm;|l=j..@- Qc0l@LdS%KnD?ye*/, 2o7xM1}8DT7,[eu7؞u&m4ƶW7KDxJ. W@ T:.uk`MYè^oa@ff\J%"A2ܔ;q|ա WtvO2\/g $i5Fy}5h$HPh2Z&E'6t+ VCɵNUZLBS12p&t n,fS{ާioۿu-@F&''?V6?)ۙ^JSyPfQJ gw)%-ŖX4\tq"qQ!-Cl @# &fjÐk __W߿ve^QNNNN_9vTjUx^Xz+qRIFJd]5"b܃LD#Zkjq`J3 Qhh*N6Ĕ!뀕LFTr?yw-C 33zw+Ax(k_W]WjʋS%v{3 ۇ35&KH. u]L& F '䋅,.L[!cqK!Vj?F>9wKahb/\™V R|+MϿO{R 1R)qHQq'Nj2;BeҹtԦjs"D:JUt c&wb`MDnbRi{~~/Du9cV4jɳ˫տO%|zjguIcЗgVVj܋+40. 2f=a W\˥}K$]Rqf8E+I Hp"4İ=v֚KT8wW!FTVVE Jqi(þcYF^QK 'a|ZY&@#kbLq1w:Gbta2ZZb,)} um-o38938=} ,&ޚq~~ "el֐R%:RIc5Lu8*bX"y YNHޡjV49"LzStxhɹ| ˈ #T~QXrBH~ ԵT4E{1QnKa`:N@HGxueBH|e2c$+ݹ4 Q\2ÒxUf!S6' 媮+ +}lXI(3(Wun+<-'fKGiRss2c`xhbiɁɫMnQ<.6Vg eeL!F5B)~'i.łOɓwrĒG&]ػ&/<|!+~*3Tss;sUQòfϒ3Qptee040)we& ٘qsɳ )YNE$Ő bh(@ 3]ӈ˟u k1g%cCLj\PnO-WiHFzcI#6.)%-YΥX7"j9 CٶLwaի y[, VsG!D uL^X>kP^Mxfb#eG6@__耑``GYMLӨOU%A@\[& \|nw"VoE~` [\M½OZy{tԔc1fm5q̀Ф%6,4AXXWQlγY\M<6CU!-h`WbR"Q o9]* +ӗl9ur, >饏F''aMtZ8zi.o8>u Y鬜Fs7OŒW|WUttKFU{˶F;A,H:Rm+;Z)S@EQekiV2]P]헖UOteY"H7\ƁeHxґZoy9?6QPACAJ^UT]Z“ F] 3" &fݻV ۻ.LBm]9pa) ,w&)Zu5פ:52kSSdύAocK--ѕy H)Rix m\ۯخ:]'b!ԅ .<N][}E+ Ul]/?K9)ez[ygKFDGIF10׉RbֶB.M(%m ,c"$04XI]Ө3~훏w||?BWa^FXJ'+,{O~o.itE]7^V:W67r9eJ$g ;RuFR3ZSPw?Ma_PnVvvNBrZ(g6k_؋BZF6bY &BAxtYH_b[]ؕ%wW<<5&r: cMw>}tz3=>w&.m~~ojlEoZ%(cz}:4Zevq p ^T,g>8݌cr(4fZ8x^fLm~Xܕ{bxRҵQzl۲w 9g*81 D)vɑdoEM_;+q[պʃrq籟:H;cjy_N{®۽{Z]^^DPRb,%,Ɇ2;Lyo8 :ZZgdOʓE hivk()$hbLIig U/y Ԇwmj0(H) 4jZG)Gd ح<͆Dbqޞ=Py`Et1ZEE͡ٹ=wN>($+]mk)GB*Rx`-E}J̑pnmyGvvzަdԔuuݗHX,Y@t6!!CòGcbۗ<;7uJ6=w]L J,IXJSMCC~4|x(;Q.;( I٢#D"uO 81 #z.K,ܛ_npTWCۻڄ+Pț+&`ֵ:<8C=|5Τ[~̊ie!-e>EEEBKK:+ڱ-<ҽGWm`YĊV$xya`]VKgz RgI!5Z-GjGQ( }  W., '֏< }drWO}Qv. ^ ! E{ƚjen3lPP?Nxrˢr"3oK%)I;'վIYqU@ FJ&sHFb;f`c[ bXXjDCtRzn ۤc,Ek(uZ@\)k[hgV ݹť+X{epJzƤؓKGuawhAc\& Ѿ9wNJs]JC E؀Ȓ+>Y2^j\2"VDÐP Gj4JO4tRݙI HUS5/pvz| R0=g~Qzŀ(F3~zǦ&k‚=}j[2h)rr ᡣ[mgWָ>~u/ښSpJ^/pI"ϋ@@`# 铵Oc(RBOYwFdS,aHTiToZ"fCgJ/NݘD| 2:Eil .S2JC,j,QޥX*Z-|*>bd6[-vU#wgw:O˦%Vwdu?=k,nGI)B8X&@;lԨ~ KI+Z·qWb%1A@aL“=6Szcۗz*MU2u$oZW{ g%CIFԝZO'pu\OUR-9"?:Vo 7')zv9,'aWSDWL;B/hA@{ s8D$R'a}& p5>+xUEY4\rpЪQ@tcr 8gYZ[^Xڞpmd098%wֺd6 lKBKdqwM4ZWRy8ۻr0T{+a56*\ZXȱ{ 6bW905/¶M EӂylXØ0n*;Zo()^*'n`3h]?Xڛ2?cle0G8.m?2Iy,L\6x|&j!!j YQ^W(uˁ^Q4L,_E-3tVD ! +eHZ\11rGR[eQh5xe*2Gɕѡ] =މqZOWl),'Άm|˴rv%KerHp9]`!H$ D'H+k?宨U )= -2ʱ+k:Q{Wk;Ĺ-e2l_/ܶ ʾI"TiKuL|:o6D6PR!Chqu̧mhȶfY6aB9d8ӄ-&AgM&*/;$ߵw,Ǿ XApqqmq|H "zxgeeX?mxf*Zq"8>:L9tU˂ĊBok:X<^Y81p, )Bx,V<NLɳ'wc$3j!p?55{y8[\L5&4udR&g[ V# s30Y FAzeZ]1leYo*>;>.OQDANQU\mٺ3i,]wk3} ~Kl}j6G9=wo[FX1ZpRfN`0zx= G_`,I1 `o50z1_1tIJU{OyE`yŘSp Gr /rF)Y>ww:2~ eyu 3'ٓl/] JF&.xE6p)XVƂ2P2iZq\7;ZYo0Ğ=2990{.b$db,J(@R ]kVV.?eu*!_MѾ7MuhtŤ_!r+e.j%1n0L5+4)5'5ks 3[/}TWAiZA3"qte2ҷjrddeۑuEM!n Ha8!\\v]Wf 1vŰDga6d3^ZȊ\O_J8!p!R|Š ՖnN쥯G^*S@L|dA|v"AUDbpW˔Mw5mzzg-=ż 3Qll%U ZrH[  _ʨ:.Hƺ W"CX m,R0!Ez|uS.FXoc+PEdC%W:#T"IpWGXHOXHta6upyR3w||q>̇!wuDNFu@MZYY5^] q\h{VO-C#.^)5u`Z m7^ehhzוwxx'ĠW&p<  $s`U79BQDYj'uuO;VCڼ7`jDCGw߱V K1am+e $,ZUX6;9X>9~*u9P$+LMN#Uy,yһFFOTSt!w_yc}k7у/o C 2+vFŔeE^Ih yL\yk s>A{hH3'ԝ*DhFX GS9wC?f`SJaY!,^@ׅޮ$ EK‹H6\<b)8e11M4=vjJK2p!yu2]`т_HC-i8h koh'=Dz!6cd[Ɏ|* )g:z,x7Z3#1!윁*A9J0Xl}k3 =F mkVnd!X9Vg=C]-3]-~ j]qZ1WMj=e}0$+ok[˵?3Ȱą~hY + ѾdmȰY_t;ʅ%nzN=3Z 8pp}xu}F^wsDpu:bApQ! 'zXmt{JT8\5 aH֌pg Ҫvs0X):LR=ֲW4Q#-&Kej`1\m(*'BUѠ`E2*d0=?\cն+ڷ1=zO䥤87P\dedT]X|%J4ն%+*7zBJ?"`I Rq EhkrW;O}r.jZ.jBOO6X V ǖK*w V7OV7`M b6ʿ`'ZtKG+\2avRraUSt?x-fqWoCbFb%IH3"RqARyByY\McMXKaBaL ^-+1^Y"G':TTNPi=E* 1g=o V{b,r:qXKJ6# .ŕ f3k0KV/hbnT0t$ M _N;=hjpF_[#V?۹a Mj]K:;ܨe,x#"bU4M즔 GĨo8ޱsƅNUX~ =1!3xA,$QՓRXf:ea?K֚82SX{XD2{y-am} ,Mi|L3ܿe3ú S{`V`}$ŋ]vi(( ՗*bCIENDB`imsprog-1.8.5/IMSProg_programmer/img/ch341_spi_18.png000066400000000000000000000640541520775651600222360ustar00rootroot00000000000000PNG  IHDR,)nPLTE  MsŹ G}ueľļñs?o_Z}Rszl-.4029$#&56<**/pA''*PaTYg:XuBշi@ڼ!K\OR`Uo;ݿGXK^vI<;?&~M[_9)oh[I_L~DRBSFXDCIZ;OAv=ڷ9}VhZ#uPU7P-\[1%uo-|x O0[)Sf5(rHmgѱ8# J)|V-#haR"c]71/A7I;fONST/wrg%X𹹿[Y]¿7cɫ D>7tN$/j`#7*ZW5U6tinG/B5FGedhE+ux| 63VO'gBп=_NH%[< ,&æߵ@k{d#J@IѶ|Ϳ:nNiȸ;lPκdcmms8azhh ʿi2kkHI ѹiQo[5RRqFs2WA]R+54nͮq7shw"rjt퀵fU~|MAWIZk OL ED`wUM7k֥ _ZB` V|np#. LeEE_`?xi%:R_Vq`arHZdEƍg26: KxD WxtD@xX:I;N+Z SJn3PxWUnxKR jDV<`UV€=vG?Kvip|XiLN?isHZBce A0{/"ʍyΤOlQမѢ \v" DHMhknF0\K#EE_8eQ0 V-M5230V<);H!-YҾ@uiooh T RD+|ơb#X>1X{Xw8=M*qvM V0o)[!VDQwJd<svM+-E+QV|BDcEz7-ke:׼uc&?dS^f)ck y Ubr2Hܒz+~&ɧV7?ܮ"s X QtaM~VСYIxۼ?V5ͦ݅-Vł%q%P(`V+SEM$64s&zM.4%g/Z&~m*4waMyD 4,|US#HgSY69%Mdɓ|yLEHZ-E.)*c֬4T,hfo c54ZUUۖ6Y抡P&${&|1F&h)Z"uݴq=F]]ТUi s;Y @czop8i8욞U޲tJf, &ɾܭ&WYZaYVm揾bz}Lb3"]Y$n:t%~-pZ{߁@?jo߮zTD~ժ4CUÓ#7*2G|vȒcPvIҞ={z˴ EH`ѶDL,dl>GjI{± + x[H8XX=[{ZٗdV+4:6f6vxH󽇧;&9opF\HޥFj 7&&i`4su,i0J*6  }Vq!1R VUv3lHVέ' Z;GPҊ" au(s0 S# ?sf<={чա[9 ʺ7>>I &bEcH()KMS*ДwShZ Q*"NB(%^w+heBBdMxFN*Tb<^RtGN"LDyݡoOD&&h6d%+Dk; z,-"CT2+q`UYPl]ci;TxGֵ5_[+LP|B* `H$0p [xՐ]p*? G(]QB U4?p4j[mwnh$3+K6i]AeW O gԿI2HE~W&(Q\^kz:XOiDߍ dž2|J>b!Ygu-LCV+hi1LQ/YIQBZe=>Qlj=R*UЖM%+ 5+,CjA8B"LVNXs;P!B*zwe(JSeR˸46?K^s-omiiqT9zwG.:MH66 ~Ü1!g* stlR A%1`,˻H{D"ͻ{^#(^`;"*v4Mb1>hn޲/*V =HAt rںPhCc:;EJ2*d"'B aRKTm\'+v%-P=GjlG yf ]\XH&'~n0D$=huh[/tHFE3{1u xêB垒`$+!Xv;Ė阝,CjF5ؽ:558ZZJ DaX9{]!դgƳjGxSKpFn2yWk!-<%^zhSq i |8眄@ebŒeX,*; ߨ%Y58_vdZvNT* WRf>Z$'Y}3v92(VsT[6E=뿏%u5=h+4ow0WPDe p恊OWFVH_=* HEnESalEH'R,, /<Z5D tX኶$/u3uВJ.ZL2Km__ǖLH B0ѣ9Q DES34T8{Ya Y᎔EV箁թS>} -n{?9'^5u$χ]=%`h9y)]TYj7LǦG%FF z1b~%~hJ,}?:{Bc$btV`@r潋.203*@~!80Y% +{rn2h1&d@m£|̮WqQԚ?,v Uj4|&eFFCg uP`eVe %Rl'`2ctY'ZZn jk#O9 5W(bxoXm%+ψ-q|V[*3DN[.IC(^H<},x(s`mísrB%h WRRUЂc'}_bQnު/-U"1>L#Q!RqVep &N_ϴ rYVgyLE 3%9 *+RW C,BeوWõ?|Qhk,XyT:88`(Vk,qqpI `mUZRo߮|x$Dj^XYhF[m2ṡLf2.)湶O f^#4Pl&A5H-(~lPW󇟽~Dh` 3=+zVDt(KG'Xlxxffdh,A뉡X=2>b, ^=7`BmӚK%撲|x~['p.4pܨs˫96%"C1sb v6* C#~_ q~I={VU= *=fAs,/.?Z>+͖ԛXp<%Fc)`JMj˜^jFy[81r`0ZcOz`D<++6 j@a*V )aE?ۊS4hPU1J(;?R|J-]'QmpQVfV̳0{<3#@aTbtI-29숺 GKsjԃu-HG_!Xb^H[Ug)h"nȴV;L>+k+O_u![d._f;Poo/7)^]ѕom,/jIQl8M9oCJ\.n$x.ZV;\hn.t)47{옑7n57D+i*:?"IFf0yO"AHZ-rgz|wJ|Tvx%Z1TSL ^:},o(Qt_<<33*AOyga@Z̭JL( 9Kbn_#nnKK8+w]h)qqyW`[A Z =ٗɊTu Kj )>ĉjOƵocA#7vO4is^@ S+X\Ps]SݾC=1kllؗ͟.zKzjC]tId jezFoF]ee2SެP(?VIw4{)ZeO/ZRho'hbXAWbTք(EY|ѷrllΙ'8V̭j0]$7zR RUO\~mSݾT*|% Vٳn FzOJvW !2{tv mq25? KydVuV"bma,MLPA (vS%.YZrK=eBhH) >o/\X/`iTD讙=xƦ.X6ĭx6]Bir+0))1XVR9r̺.;g^-y`H[uXV/]D xUۉI'j[sՇ7mwfAmWQf}qGghDBlJA6,"i !@B)["( b1leH"[hЂw?XQQ~;]vZ|g/ +SSϭsAgcq]0;I  x.^})00FĪPrsmtXxWddStȴZ=!'ҏ K . #6/{ta!}6.vfZ[P%/ڻ:lūaA\A׊`!XZGqj/6u\lX1:o]Ů{&.)Oъո8ޢ,Xa!r$,DiMF^GCUٟKsQ*Efb8Z+8Ww1 V\@TϾukDz=PĵC@ȬKz>H+LD +:3jDM!-B^-$ ETDv0*JmƢ"!f6]B@kB>ӭ,9 8 $ )]؟b됷3Nzk/Cn O77DnM Xb_qMр[[Oj?T<۰Hdk+ؐezz":;֮bO -$WtC\\t--v(Q:9lJz@5%z\y}iLֺ2xx?-YYXǖcR}2J[qufY٧'N LZ\iPa  hhz{,/\jř_OA&^EyK^bY5%:<>\ZiV6X8@:; n9a:4G9Vb~Ўq]{YuvL'A3q|CqDn1X6n9Z\oY|t|1|,--@ܦ%Kx9UK.C:@@*TUWn/.UKp#Ue2|Y\{mӂwm/aC7;5ÛC/nl\?QXD}DʊHdXY!z玚t%N9Zdǁ7Q!O\sxL/4ȁʞZց-ZU[%FGԔVpXeX0I{fj}?MFjƏ4EnѡVrQM=t=bhܰ1[_IAW3I{Rh%ڢ9Xp8)*0Oh3F(-몺H|S.ru3nB@*w=jI&t#H4L-E.IJayYZ5Qh @TATUSˤR3L⹩Wۧ_w/yc6,kVpƍBTBF+07YSlgʢ,3? ZZ6OK+RHB [))u]]^&ɧŨfȜ-֢SW>xŢ㙻W !PpC5oÕ8/C\ˑBNhEh=._l*/Q: or'oC9q49Ƚ81ɍWhvTm,A5FDR+e05@=p:;svӀW)Cᢙx&-z".%g DR:2ʆ*Ǽ@7Y 3^yN.خl-`` xG{rr{PYYYՄ WQȯ>NP-7[:201`ɜȭq-$#̿F0܊õ܂yH CѓKcaᅂp,xwAs|֫^. j𶂺?i/4۱'zgqLj9[KH{C0xMoKKA46 Z{bϞ_hNkF[_SmHDq"hrtu츲ԊEV1.jTK\3 ZhNYLСOI?e MGESya-r8Ř, 2 <^Pߡү26=dXf-Xw2V|6˽=A5BN kJYYT\¿k|Mھ=dDk7ZaX Т:1uE(wAbMzEW~6$NVȄN#[s#Ѫ9݁1XL|*+wfpؿh^ ۅwx9`7?L= =$=(ݽfVՔwVף_s:VX D\'Х `SR9glIKBfABG_ݴ ОqAiZbBf>̞ZѬVK"P !Xff<; رǯµwtxj:G"tV#wp>:1&G)}8QE?Ugn> ލtB|+`Ur9&:<krkAtF %kW8&ľ4E0X( &_{+Z`kK (ҨKCKsᅅu$W4V vɼq8/Paġ`ãhάv̈r(Oߵ"ӡg_{3=ZF9tmRQr;ơ}`E jqI|KhuW#O( cw|ž9 X\ c30Vϊ|Vr Ѽ~ Ngr ڗNΪ2~x|tXAQofҏhVp㵎~_Xbd q%bKDj!.,j~rp>f"  @bEjqsF`}r+f/AՕhX ZGpvr]S{uN!ɧi)D?5E8ope[ߕՕ[4tty&Ӭ9`VК"Z-ug9e'\"j sPOH 2-b$Rv-xQᛓ\_]1}SFs#q&ҍZa7ܨ -k-INߤ22ŋ¬!W( ގ8{͌-3~ I71wኧm_(:} {zh9rhڦmiU Q\|g|"TJhB!Tp*]n)LDwZzv2ۇ S♹v\lB:-WI^^* rgϧ;u)OłD?뽳g 9=-buO^r+]_ƞH{ѴkƉ;j^!E2]om7s{ #I0.A9~ka0ؓwĘaȦu2u tzE_PE>3ʻx; *+*,}^y5zsoFk&,X"UvD6Ŷ|ƽb&Zb0ZP*YLj&cU*A`%^:wCPء&D Ka!dɚ`!P¨I(9Rd5ו&M ]~-++vdW}kgy q}"ϑŠ*>b2_vph(AXDtBc82\L9!rT&5_R8ʂDv "҂h,hz ƾY)h"XdqUNj6`&'.N Z.Qvv#~]%bwX[*ܿ\-oν{>z aJá5ۢ-qgSݫS %,s2R-:8Z$Y섾岭3DT 4ibdBp7<+Z8ۢKUE.zI_H8 <i]%U^ޭ+f#+U sfEEe"[ED %VXf39UO7H-1`a)L7ʙnQU Rd$ηO92/Z!3 N"uںSeAHj\zO>, wB^r\]ΐ+H{jSEřS="X|lV"D>&>HDܞrHR\]?   I AՏ} V(]Kj5O[QoոVbqRY:qs لjt'45b=?\7ν۔NN_~ VxhX-V%RC-n޶:{lJ3*ʋMR gR3<~FJkQ !Wmm1Zבtݧ3gf5Щ_'-+rK5h!DFuJi,"agdtAPF*hg2j0;+ pfB`O⥠gSIܼ60L,*B^5B&8 ;<39էSOݯPwSS1zZeCr*e6G. ZBE8\aiKN^@VV`[KZ\n"Z\ }Se8A !~ug&[5x[;4ĪZ[vqʕ yb;&@n/=WB>,%oJu8ܚHĔYپ(j?˚o1𠬒Ĺ U^,Uh3Za۴JEb^8D UYJX\Sm{x&%٢9cln{&4Q* X uc1-)LJ2Hqw*\OoX=J`i\i0}f{E M>DDL fӏe^b*h1V$dbu 77˞0VvY&X fzcTbT<8(#"P%Zq-8hwRӳD@Skh*c=EH=aD^ G>cK ݧE1~w<|)l$&X)V[v^JbaOsO~cpBK<QŢ8yiJ_BM|il,N>$ ː+vQ$rɒ[9;d&BKr̆؂VoFynsؐG " bp#SU:бbX /ȕH\I!WG>_|1zk2aXVnIa(\/E#F"jqա2s:f*GD Y䩾Րop쓢]>QhIh!'Zn[ztAbQEtABMRb_iʻhzk\:}{IL폸ǃ]a5Ȗ#Q ؛w=U̩5.o\rNf%[fqyˋ#P$B I;!".9(zq+h`5؝0;݀ x)t6{GWM8N/PKvKh鱥>V,hTTa;%s?bEftqw_-.SPSDKqK_lvc-IK&pKǢ>ןR^}#7y hś3,(T"?G%b\Λ"/V9R% LwnTd=F0)'߾^|Ƥ:Q8xu4I3rUC򍻯[\sRk"♉ת Yu1gφVusD֊xb]L'SIbHŠ3Z2́I'N[ Ei[5}:]6lߺڟ_CŠ[G_WɠnJV8CՂ^Zh-WR -O`Z|Ė*4Uv@20X&)]wX9B7.N?`M 6 *X_3K}4+` vi\' >[T)SC97Ky+Aђ Cl -pNc/~qۊvVx驩|金Z|\cRt qν]MO ZҜ`(7YORTR=J618uch L K{& ^RFLOv)B+Zԫ۾ :(SPPM+/YiٟfȉĖ Ҹ[# t\|3dX|*~Ix\N钒6Ƌz\ NW߀7ckALyxEc'tR4n͗4^T>w 3w1maGcL#F5L5s^"MpzM`Ic"Gck& 9pS\ZftVdmEb FD%ygp#тfT2I΂p!⾁:x+.t,-J]Ή_`<Й4}aщ8X7\*.eS%~w qtlS`#(ȳH>mCy"NES\yL]hUtv:ҊfT~pb >47dZu(F]yVU\\X8獕Whn :ʗ1Z;Dkd/,t*SFjbEᢼrtj'{N=6$\Ul*0)ϬY~7HIFkkv%.0sL䩙ԧTx)Edh)*epW+-ـp+zԩQ/tW*PD?bBcKS"ApZ -4cSҵB(:'+~CݓuTX!o#c8jy[EjKjFKLUL^و тnsXkASGpARqV^}1"i 2m簀 *a\,rܼ͛馛6JV۾>$(M- $S#ʺ0 MD;r~!@`CӚl}oGK ūR*VC{hpp"X/v/É~4X6D0͐GD;0O?766%8 QX@|)YScgr( i-FNz -ANXcӻN_PxM 5G16ydCEs/Gv; iLqhaaH Cd@<<60rqg#8]-zEg=mE#YZO+ʫӸõo5ٳ`9ZT++^9NBPc%BbQ/A+|Nb(6pV, W.Wu-Il%TpP5[TipdA+y&(ݤ!V\Ǚ^1b<vup ]?T[&\9V4\+PhqC)6 , OE.,AK5Ep nVmSXBjd KpU:] 8+hVZc5`Xnݑp~ &n 8p ɤ)ݚH8K+0֨1vK bޝhPiĚ̇l%f"~.ʉLv ,U{hfff`rYXՀZ \Dk6:0X/ps0xQx+H(Rb&Pd1jrV$+YY;mx1dqǰj]zj%^K[7kڲ>%ѫ!K~oIQYh1%]2D%+hߟNn}?]+#E#-05\DJ,=(+Q9]վ8933kFpAh9ɅGUp%Y a@HBխtSPb>RU *1r]VXd@tudc+]hF1@+t'Nmru~br: [0 "ZgV9.KܞeM+vUxtJ,tUd mV]/msr8DrZXJ]S=D죆 ZJA +P מuWpK unUEn>*q"`(]T Ӑ|lgs8.sZ1VN-ǣ8,=8rj7lZEW$ܶ 7A[蛽|Jld0(2/6*??т̳J2\`X.H|NBs $]Q̏Sb4G!-LӕrA@$h=kq!8$3RQ3144ު!SDӆt*XdhĐr!!q >{rD"q&.]xZqp3+Q|z-`jAky\WIF(UgX7f8%Xݒ&Ɨ[qD ,A\K@KnĤ'{XA&#_Bf"7-EA+p # 2bX\[[%-SbCX;C'*Yr)3>2CuK./N\Jy!!zď!B 8iH0'bb %Uy񯞟'u Uiİq'M=ЃiOJX}HF;y@(,D>T߿MZ@֝ceه]43&|zjXK}P_^նL>Q%S/-)jMؔ`ɇ:g}p5W &?erF@EZb>+8!O磚¼aOEf田MZ9E`U _ܫ-/c*)Ui ' b-˳Owf U[S-aNqp"=<䪾·¿qN@dps6lz~XRe]&RZI_-ڭǎ=:ytWf;V-SXvfQ'fADg.5&auψFJ~9!uk.&^~]vOs%j0ʖeK}C%H ozhiT5 xyu^mVHPtWA?9xDr IFd&ac<JŮ{_jiV3#n2߇Sfǯ?*S&3C1b05] Rvڋ # Nܒ-CZ6d~f>÷&^f xTK]Tջ+Xە" * %΢!U" ,pA뺂!XQ&pbJDev~r rrP.x-iYх3T\\nW=yO D~ Vr ˹ݬKAyÕ+wa LcnF~AFǰ"TqUQ ] SQ#fq+ʁ:%<Hڠ7?#XM槧D%1+ݨW䁌zHUTYHnŘ,p*~K1]WԨ\\L Ŏ4 Xs,,  aW`tq'xSLS/O3vyFh a`T.i _ J:8LscS,aHV7@ -?G骒ϭ9|ZV[n96.?B:MpT4QY/ jNiJD%s)p5QmVhUߧ!8 f.aV~Y[II [N+S31qްծI'EU>ih;X7Hxɳv V$ael1oMaY@IKc~5==`Rp:n ZtLŨEg/Ѣm>q4Tm +boƐag,j ޜRz)V_LO1^S™Ψ an.W.**k=ji2s6%2RاmDS"=Poho+a +Ut5!X2uEq9.K5yDYI>6`'fRnD"jIr| t&_$s+L^;*%sNvFV`w鼫Ma1," de%`k5O$qvs)!#s5+óp[dW){C]=F'LsruPp(qJv +rpN.=u*(]glؕmzQK4l Hls/ !`u3uiS(J\f#z|d!}kXQJ :BN5,.(nJ",kDPqCtz~mu$i9"7nьe Ō5w>5FQ [2M-lKXf,d_8Jt-?O,pC;ę@@+&~kX#mV4w3*]xVL L +bjHXQ6@R-9XAryk:Y z4P9zc5u5\6πU!x}{XhB[D혦a0TLWtօ[Jq.ݢxc4Q+m1-ΨuԬs®|oI!]vm l +fX %,'emNeǸʤ" j.`VohUD+ewҾ®JHW,قP! Vh-B%%HA?i ?#ҮZowj+)']vu_tvt#;ت7MPѪ@k)5A߼x79tz{|#VQPҢ$ {ORX<UU]cFXa`}lU(<lU0ny~B BR?@H&/9y;CVisϝL]֊D${ug,c;#o$+,w]u"X9LHOJj&w3UZDzOGhJ=j2vON8,Lh f FZVNR#=JMIN x 9A!\oj2y>'(?kIT +ILtM,wN9ׯnrī"yχ4rC7Dk"l}ncϛ%KmwjF@ 6#]zLIU&bnXhX[ BqƏ&=yS{).r [3k°PP❝sWn\%g4KZU6gnrCW9P:W7uބE" :/ uRIf"h!/dp7I}jHPDpZJ84!^}ϟ"si 2,u nD3|bC[y)5G"Cc;Ť!) +Šzl/X6[Xd;vvWͩo~с0nT, YwgV:qEt>$+dwq?h0=>ؖe˪]pDr'Cbn;ʰT9X!džiNΠ鉚` 軒O*ƟȪLt*U1(,bbJy!H*&D)Z*wUkUKɥHkZIahYU k.8gV~5K ZIc`wjZQ/U@+YqlyHB+5~u' kEضRUA(>UM }+ZF!HP_ qecyUԧ4%cY,y jMP ke`#JXT-PbƮ0,0,wV 5 FW535IE'\S /F`=ALIwW`ulh`uԩSN:uz 8O0hHIENDB`imsprog-1.8.5/IMSProg_programmer/img/ch341_spi_18_wson.png000066400000000000000000000645431520775651600233070ustar00rootroot00000000000000PNG  IHDR,)nPLTE ZyĸmǾŪrźqHl_XvˣXuRssRzj6^Vƺ#\Uwjh139$$'./5,,1((-67=UܾrBعQm@g=[K1)&# xHӶx?f6_9r>$L'tm=<@]1Z&h@C'71/6 FFK+md NTQ.aEv\m8μW79K=/ytEVI6}D.nH'$"TQT)_7P-]¸)~S%T8^[_2cL7c8$qI_tukba?RC>aB&^BlAng)SJ\Nญh%vQ1XAgήzz<2YHt_ByppOaS 'ҟǪ4si.E5I=zRV)~y1f@@mGU|g½tjhŸ$e\tؙѿI7F(S-@kOfShX>iU*X^pȾtv|]m;0yIghoزTʹh~j~=bk\KBzbwʽŀ_{kT\OnJYLWL@d}™p4rTI@:/\MuLP}vrLs%:)w˹uOA[t^jz B8opD7+R¨^SvwfN0z C(tRNS4|+W1ovNŃAqԹRȆŘoseIDATx1ca0C[$]>!`2ȘV堣FlSХ 5l]n'3Z:@˲#H$՝CӁErpA-] !(mXyuVO $Y9N 4JX:rC? a,r z|ZBJX  k/@T8׻Џ%_K)Sa2f/A\fZd*7 {:!+?tpN,ɱl&lh>;)\9\*yqe ٮȈvx[Ke!ZTBJk)!dRn=YL;~O]\6V*{C%B}Tj86xۏ커t3P23X6K`a1`*|㩻ݣ>[{;7s}W]JpuZͱd1 QWHEU_uÝ{^>Pwrh%+9[m-ͿFUUN''F.H%t{CHAm{bQ.bUXCr_[GfW .b1Dɖ%B cJNqT xɼK\|};@NτvB䭫aU2.[V#:8bQ䌌S:C2?k0B{/!V7;Y[[f5ymcaId&?tQ+lWtbhhxvј+):/ IDt=eN4-׌v$ڑuOZXE@,UNPd&_A*RƿF+'OА~KezLerjMVs,ƕu/go%Vӫ~=f /̍iGVH_prB?nhk+1Kş|KA>*1$?)4Ƽu0PmlNs"t$b^x|^x E:?pQOAznop$g]y߃7YMz2Y˜ZSvvvL/2W^}6ʨ0mD"fyrUZ.,t*!U?Cn &􆉽'^?uLβ2ZVSH)l텍YNgXN#KU,?VÇKS3.Z Jye-_VB{cxĞp "^_%jɓq(Z&P-S׀V8Z$x,(4l~'XQƒA*`!!${Rjw[O8w x+vH`+@/lFukKVy_aD9pfau T]`{N\vP$ Fo Fd(a Boc2**AoC3 D5 W|չXոرS.YZdY~7.KyJ~n٬nP Ep ))Yg\ Z[c?`-S{ 8)GҐB\*7h"ph+:څ+2`Q($cK  At PRcs'WRj$1:ծ%ZL---2 2qvO **9-Z[ 5ɐ=iiiuQ pQfPqEGRDY,E%Rqq7Cb8NKX1$EZcI$ZtZZ*ظ08D0kmg ~9zS؊4QZhi5!{^"I%Q #^ENF;Dߴk'k)e=[9q"vH"=/h1$'/`g|Aeod"KD2*C YTTREdG}.&_YXZ2- 3 ^Iy< U'DV`tfXő"HwDTQr,ݓ!(8>ҋiPA.>|E XRYߞ\;$1ZQ>%QPqyr>׈V%rdр/l?,ВY ]9:Kx?&r|R^Bv,!a"8xx0lyH/=yǎE; oD NH"rЖtn5U*Mo`4<} =3ԭم@(WI' Q YC$`?y߄u]O;d))e Zg4)43zzw>es*{㰍les _5Jt .38yY(P*`"?Q}B|(nB<"/'K'V[`1ZxR3_!Il\@ݵ^S34h9uL"X  1ͮtX8I2D/0A56<jȱq.-d0wj֕7eCO>cՁVfDX1Z dxqx.ޙ)|mk,G-f+jhb\ŞUQ4ᯪʩ:U RDB0ΩW>Lj6:o׮SY{j.b֚iy 5J"1ZX*[و Tf kԦpP,B|]VUu3aH7-2 q0:ޞCKF>x͎&kUFD?3:f {zD.,.L6iºkxc/hA^,i T|,ޯ0 K 3d `Tz|Ǡc0PuxEoBd2FKfxgrѦSG3^nSb*h%+{ROQ d֢=I~ ТVVٙ[bê-~ Fŭ6*ٌ_sfU/ x ڂVU`@" 2[ݞUCZ`054*,8g@vCyFLOIDlG(H\|mQ?w?Yzw{Dzִ1|ac\,tXA}j {@jsdZ 1^˞ KbTmEx D<,o}3_WQaF=["`QsDŽ,|J'ZJ6'W| Q)e%Mv/Oq}hWuWƳKZD˄VY,,V.ĬEF6,Ԣ] p0"U8lAs >C, `$"ɭoan`Vp fd~?3 ak|OPPpgRb@)KzMho+k]=u/[/ZhM5c5erha(봽f&UHS=RVL/x| OT49<>fx#d,bxt . $?n\3+N4'$*K36$KD5O_ٛ}Kf|pֻ}㕡d,>ak}ho`$0 bwhbr8:bEvDm}CS\45㽹T|u2uao M],pukevj=A`(m2ZX@qZ X}KoKM(/ٽ {Roh/Rhcޡ8-[53뮶5!L4ƘW-e&}Ȣc$JDž^t)Y$N͘k,ߟsYq#9 &~8o|?m"^[pnRQRfٕjK XQ+{`=#< E"se }Lĝ]Te:թ9EW@I`q$i'| \R3c˹KRc1@y5´{۲6G|~yb?Z}_~@BU28/ҋM}ӧZ7tLϭY^>D'/x}oJNFZX(RdSKKS8"C8Tٻ>,K.)gy6&ϊe9!X=TCyElO?1 N6h(:/g7 b77NDM35(j2ӕQVpp--=-e-XNL~$N݆^Q#'@ĚP(d"pITpi+{K*/y(=ecFuV4eHk|G_?|Ӎ Z^}'ֲ(!nxTDMMa'C`YXVZ5~4e |UۂedZ2O?F9|- 2{ AFD[ uhh5;0ş<0jacLj2ՒnmC-l`johA'[cvFЪWsp?33%%ոd}Rzj(`H1X^tWA"Ճ6zbh~S bPuu R[XOcX8}/2[V3h-dq (Q-h#XT6\G"Y)tO@Ӧ/i[˯[=N Կs h$Bʈ< OH֗JE3)Dᢔ,aW@+ϡa0R,NW*"d贎bH唵'n?yB^,q|q֊/ Y&Y ko Ԙj͂vm7**^<\4=iyљNNZt`71Q\*CޮHHNF"Ap.Q#p+tV 8Rɩ+;VFSVaQ~%(mE<RE{vυV Lmu֦j@xaL*3jZzu |S5"GzPx.Ak~}iD5íEs( [[$n6\2{|䕷t!j&+pTŁ".V>:`kw|0 iA[ϟ&FKe*pfD\5ӓPJ8eT4p&~:0viE[xee< ; kJP4)@ a vɂ!"?''-fj- \Er1'OL*d\K tpv?pэN꠩)*)OYZN%ȯ~BzRyёձsWq,u-[.9JQ2577X~ 9ܵ(-Zދ^ЄT&E 's{ j#z;`%{qS&32E 9+F=xX /- 0N/ fR`QEgE|:Vl=v,jeL;{ֿ92 |aZx4GC q _ OPF,ѲH烚7.-dJTբ~BU#uPLfTO9n犽3W;tv* K`LLh'38KD4``: [r劮cYPXAԎSʊ9( k֚w7?SrX-.Ћ0SRUUODha(eioU+әX6쀅~F"h݄LJ ZmO,7hBWTE4r=ތN$SOLY[ [@VtiWԻR(Wl2+ή+W*1 쓱/vnemQ'M1Z_ʥXz ڂ#ĪC^*Ezh *Q-uw|{//drBڰt.W!628cߣVgDFŠ J$Zئ;|5$3"1[aŹKUk|(k#NJ"~6 GV,%jUiGvFE&_h|_*E5Q;8w27Wmw!I[@ ɡ"w4{j{unN&H.qiր?g.B&v$e:hel7LVrF{}Zme Us'[Ͷ'kpeaw/wNNV5*X]t/WgrTyn7)?%^I:q)bP=VЁ;g޽:ՙ֒eV^3'Bh!{Ew-Eyj[(*%dpO]̻^$-V5r"۴f+ Btr3hMI駧^">zdF*+B,Yv`QFE*'WJJ{\ AnЂҴhu R*w45?{|S`~˴"ZVUUWc>fڵ4]ZMcY{o4pB&0Ǐ=jP¤BgU ._~rQ 'k tTl!4Ex$,E#|/xjt\ "<܄ge]ش/q̵3 _,ucYcGJ{A+Wz5ĭlM<&mIZWOOM4ms'Ee\yET"ql ӳ\U[*1C#{Ϋ/M.7T9vdHi * S&K>k{տT"ت`q2_ڥJVa;ި^oFΉ"x%,1WA-N[I'MDKjrYN9$|ޮ[Ve:H[am ` !=Q4|};"&`4Z <>'7A|T#w"#VXrlڭ E!j <⏵(x,XyvO RROrW^ɉڶi}xbUA>Ж=вU'Vq&o{J)Ghj 5`7E"cY ڀhMU=a&&uIkX=Nx%Fd}]i}Ɩ? W]Íg*6a䴷)Kρ9A kZPTE@hrhV1YFEveJrU Z*<Vj5ڽ_Z+ 'x2"E_Jtޚvè3:16%\WwK3Z?]6쪩nh9gpn09/- []IY B4mvkn1߳S\r-f~ϗ{n9N~q6Łu +&D X-E=jx>;wyHBu]vp]2xifzi7?X#fZG:J'Z%t[A[BvcYΚ*~^/$|9f C"'ɇW q8XRa}t]"3JK+2܉+5:G AԒA9P+dA jmbSͮMe{(%0ie,,?@ȕϿ*)y" RT2jߺX=r-&LH*ۓvq&oKZj񖧃K2+.E-MVYd7 w `y;2yе/,q9=n6NHZ0X s8uCqi[OV}SXp"/adWv[[X%w2Zhʃ->GQĵNkCh []r‰oOUTbC"m|d&ՙXAWeUW~s;DQGOBbP^a?$Z&mj̀2 Bwaq{-|כjnWYqizp ŪիVo_M"m!xunnHFݾĄ~Ɋ R)pqPc/$K .Z\+/"++vdVQ<>|{_iUQæ-.5i[$CA" 6ׂD j$ZS@k3T]*w^;I(0޾=nhő%AY?Dv% GHcaQjԃ)8W=XjWKЎb`Pvhog< 9jY*joTi-H6FƞUbt/WeRkC@'TpdOR70'buZS(+qo&ZܵJ-> =V!= "\E?kn|DhMHZO-JN1yQssTgzڠըPTK`4jwub ?W/sĵ/Ml;[G b: /\pK 8y`-8m?'pb;֧:Q^: ijFˉTޠuyI$82`>5 oGCw?zvA=nu҆8WXu^]~SCsr/7/m]./A;d6N?2Z\ͅ/m^dh2񬩶h[eփPXb͓uo]l)q.z|§>qZ6$ܾ};"t)*_d,HKް+oۑ,00j/Y Jr^"B;9vV}I['C\NmXk6SܲB~jiM|,yb/"cZOb*"a1#ZS%tC,$.SA>KVz# `+ђLlBZ*-o!pd~rog*OUaoVQ* utD[ξk`E9֥E"E"iY&bϥ' Fd?Yψ0!1Ry f<"-*}P&rfzFj~iF%$U [ Wo UξK8\|`!Z2)<8R;d Wh ]^`% VK@+"Z$6S&鬷hC1Aa GGh> #GDB#VD+k *Jt/,.Ъi[:'Xog: \W  v>D"Z~W O=[~ED"d J\&R!a7* c'.UZ [D1`^"Z6.bWdJ[(woۼsfibbf[xKRN`6]t Y:cl(N;#U)v)`elʠ\'Nα1 ʦ1C6yV~=+hb{yjW$!bqFô`Qh \%``D~FXF6z78rցb-uZܶ@ 6 |!/CW%h%3-T0-|Whpc/򊥢m[0etQ[F,P!V 8"PW֕}{Lk\:zN9N d ]edP3۰X<[Iu:K- 쉳֖Rޯy x5mzz\aȷzS쉂־OY)'_H =њȮT~߭}- H:bD ,ZAk-vnD^YX%:*PPG{|m|TNy|VC T"8.|$ijwN%mi-c3``5v~̧P7hGEo(Н-2cZZDyWp5nWښuU`C#}u"N{z-*m#ek#;VOy* âBCD0 2'-VYk3IGf6|`ኋ+&-_QҔ~:Un|#GafThp x DM.4XuaB}u8lou.o@pAMj*7ʇ51&-\ $mϺ|6F_OkUlm #şY??|zbXB;=a+'ϝb@+/m3 7ZB[Z CO q<Ī84 XVaZG1Fͮ@VBW]WpACJa!I4lX-3Lk`dJ!R+NE{@F-Xƻl/cBL**>Ўy_i]l OhLKZ O7區OJA'+Ԧ%/x$+56ke#VP9wn5^KjgDrS)ɠRGAJV-6?a|CEТ) /3+r7G ~}t<ș-kHpx#X5Q# Y{11<ۧl)K#^]h+Iۡ-UôJY[Dw;&P!1_NTօ]/T{+0M1l"E\+|N{fN1 $2SnSɃY'x-|h rvrQ7CNx R@`YY}S]ݻ>R5\b:UY;']AXjEvV1@Y_N!}.$'SrZ@h$lґe*QW!t_/*޳pЊ6fUm-hy?>y3`{a+>znZD=CK^7yYp8SWJdZpGThBqz.YĎ=7_r?SٻZ5qì`ڳmKxSe;"\44V%9L[GY߻)B79 VZci2!ELĆ:s{O[ܡ V_}U@#'&ue~6fy({ /ޝy(f9`64Ywn|pؚ6-h1H˂[\ERYEQ}z[b#=;UF|m|`δô'R(\!: ̺=^{2{tv}lCr0[1%ZtE%Xc)(X7s,ΊVxYծXI|0M5S"~d! ò;X["f`Ju8 6d+ 00pdm`glJ*tLb1kIF\q'_L}ɡV"ʟނt K|F{V[ Z1\-BO[oDvȪhU%"X@wۖ_UPcEdyl5/- oraO].3R[Ufik 0bXIhAD*rBEXZBZ "+HX%߯hϬM{&n+oK.Y(f!&'>s l⠷2`IӦLD? I_L\@- XV{cMB侮g6-@qٹwgsZe-3ە{b!  v]S)k`XL X= :Ж#RrG&VF%\0c!uĪ/!)Rw/JAઽ:UUA[bkW;dqa / qB]Ty#V-|\|8+Eb 2J nMRd$U YNNjk}E%Tڛv=`;؞sgт<>8gi8 X TX+"HjĊgbP-qba몈nqO': cufK:VTf,j]:gjl$>3.ܽ Z5>mC.+zrh(&XeJ_dNc.ru)+MO᪦=||3pLJyXh f ZA4YG %zrFT"hŷZHKSzދո凞/vARJʮwaD2ѬDӽ"V^mI?fqE@S0R t8/*ppڅ6A$ U3C` W>e n8lIpr٢S{_\<]2vL%J.NmVLU*h7Z&H Z)_x%؁1Iib˟iiťh]%")gОLI BZ>Z,-kx/LS_cdN5B:Lf33y̔j6ݽ*3^&)L~G8M.hivCTTİj2Lt$"2+E~0iJ 0u:ZP9 :ڬꜦ0^ƮӅNTցn(`ZhvQ+b:ϺP w;HᏰZv2R*!&A)`V:UZLu`9 {"72:oE4 ڥp1K+hIڂIo~̠r(UٵZB<5t.RihaTZ5UKc0XS٧%k.*Hbd%=u;gp,t:M4㈠e'ZPa}Wؓ(fWOL-Pxlmֈ9HO'ZkV+=tTKbX`+pfWjگGK%R[ -?}ʎ,4xa׹NyXL̓_׆e!8Aު|*XNUϔ%lј%d5+z\ԅp€Y&X&GL=@"\"`_엨%haN\6&fI{ %ֽ:LJGؽH ;+p AAov/8|owf^H;~Ȯ;Tf[. x2󧨠ŰuZ>R2w EXH3uqV2it}Z.jPgt3ϤV3OC(;˓DdpG" o"*|y  {Vkkb^=4 ieX}#a%ZXEbgi%zM}Gǩe6- @q%]@rtNlRN\~8QO#[iHqYޝ_Ho1EϣZ Z(]vb?I p 'cblcJ1M1DԂaXTn=E9C,bӍ6\X儥Aud8@ՌՀJR}D*Au9f܎vo ;lA`;-$HwnFKit2x@PvVΩya&*h@$ :nͮhFutlWLr*8C&nwEi$!:8TkEuU4g^9s]W_EkV=Ŝ0%ot Qca \.`ycZ SN;qkfw]Eq DY¬uaE`C)Wjje,jGM晠53QD#k9aGo~ЦbÙǷCFx%@Vi|S "VBċP Jwb'{y2)ܻ\ 1؊ZhQAu\陴#GW Z Z`I57W_lif4%#h8˜C7}r<~H|yޘxa @˽clWC ki W-7(sN%LGBl)Yi7 ?咴|5Ts7oGm6J'Z ),s߆*\R"55& K\ Rºb/DL0T-&yФ/ݙ[N5^lga*XjrX~r"&^RC}JIEGy}fz_;%8;?Aq29(,34SK 4Ey趥"Kx(2w !H$$A`|,Z}7~"s\pl+t-cV Ƙ+Ei-4d%]m95d#$5ch!Xz3w&b}| %vW'޼zyú_5j50tnoÂ!V>~V Tŧ醮`WV )( -ˍL3fruPpxFF'|J7FǷ&Kʊ;ns+X{Ent7db70T_(D.@_Bmd|YWeKj!dPu/\NQrٽi8&ZD-ȀU;4\x?B?NOۓ`^BV>۪[PZrpM*(_U YaT'H2*hxt8ZRrDŰ:uD ^  :pǯ޽Kx_Y4w+ jd}OЃpuA$7b[ ecǰ+zLJz, }0ril:7oĒ* XL .ZAKKί+޻mGhrgl;}ю)Y±ȮT wK} }Aa ++kX&ǫ ]ڕoH|2ϯںЉ8zN]A+JdX,,=a$~<W)`23kFґ.G>m8N=)6WOW!:#>|*\Ə`Aj=Qx>3?f)*`EL1yŨȶeiGgnَlO;,U[A~X([ζS]9])㗼6,/>:~`WmYTio6o;mϣ:Q$+.x==G0b:渘չHg:[^w Պ (w3m$C_Uaq0D Zoa9D |н #0|7.wa g e9bD .pA[& ak vB6:'6+bdWર~o\nfCaE"[Kѝ;#55Fǰ RewIwY9LOd3DI=33EoKdW`W#gmeޢ`qQy^;987UiRy'rvr&+ pE=l;A(֨N4y 2,fY<<5qtL< |+CbEud tÃ\B6=8(Y?º9rtW) $5$ۉ]xܻAih w잇ͣ_vtte(~2mU<3?@hxF|Fe&KNl|B hH]{?Ar1@/1"W Y.UYO 3:2P~z/%Zb)lhaLk> FSDmlnF Sryvc13|0plcO )!շP>uMՏtEA_~Lج;Ƞ8 +fOfa {ʊ쪓jt(O:,T3! 釹z⩅:}ab]_ 6,ETïQVЬ˯ X2k -B=[BGM89 OЋB0wRJղZX⎈oʰV!eZLqF_̵jAOˏDzr^G$hnr6=-o^?8 JW8VB<`]:HyM+>g` Ki KQ͟‚ -ϲD`:͘JzJj5=H!ʥw~߃A7D}Q/꠴p[G'w؟4 骱Jk <ڰMioQ<8nh;`/ ^:-5p.˘V^=ۅDlX^bU1"+#NUSECJ@U5 ŴK3?Q߼?Ea !Vk;lmR؊| b ilfKsd$;M@~{Ι;Ye_lEV\kRd~]EV ؕrz]Q[M/>..j: <8ϒўNҚڣ+qMӂeΩW?+v(ԠVu~= mS#VBZ;b˅bzܹV_uAngԾ'֮F+{xސڣSy?ò<+"px\|ݤ2+N, +)DU^n0wuڰ@B>Xou)vʳU9Y:i3V"AI?4"O+6Ώh>TkJSMRe"oWWERњbUE={Sroٜ^$\4|j7Z|儂*BC<_)[ OotWr2ؘRѺ[Vԑu;X!JӚfJv&+Ft<:0:vQS4.{}+V\Xs Ez`kXN ha[Ѯ2YFYF@sU˰|p@0SZ!Y=Z??XjT:.1\:urA'B|x--oW$ewfFő娹DQ-M\ Awp{/jV;xeՁiG/tyĬ*VW/H*A'zj5%E'zj&'êQXL{*_b̜hvm$cAXr۫;ʰLc5ZXIbbS ܄U䈾m"$ai<"hŠ<,>]uX,3pwN``X aYfM7`;wശ2ó ˳fL T 2 u|*mڔnȣ:'9npGX:`AL7ZX[X-,QJZ{ UVZjժ]/ȮJ'IENDB`imsprog-1.8.5/IMSProg_programmer/img/ch341_unknown.png000066400000000000000000000024411520775651600226220ustar00rootroot00000000000000PNG  IHDR,)n3PLTEtRNS@` P0psFdIDATx 0 !@VQG;g W'r?[ ] 5ofVхR#[>[Ksdz=gIK7K<5On֍Wx~LRj_IfJ=&_#WW qoB\/VK}lhSW_<25-SV4uk$B0$-ɑ#!aR2+BrI\VD)DHfV2ӒĴvKZZAszWV3Q[HZoō.%ۃt_Å5]zbaX+y#åm^/?\z;˫̋W8h._~lMo^Eo;֒¦MɫkZtNYr=iIلt=Nb)P#oo[WtQ+knÕZḣnF{R2hI8RZr]gzet ۀ= SӇа:Ѱw4=D+u_cnaU] z82eX#< = WRc3JYp!(â잵EEtYRuߘh7B/dg5ׇȊDX~uS`畾W /2G`bq~t[k7a06['H׆_`q0 ]PLgR&鲪Y1v=֬fjeU8ō>֬hg&.V( DC{.8pul3sҗ";M4 W,YogFvm]L5ӽ@OTʸQqe+hVl;_-`{=7lg|/vthaQY"HJK:,/00;/E(i;zbk)TVMTD7W."+iqZN?"<:P$!uuweT&MOk\FB[Tka+H7{9imalf,X:AXSIyxVdM`\лmyO^TO9$i~lkzjkSE^@V½Vz_\eV0LF#+`fkvAr\8L*ݯ,wy{tJkmfP8.1bHzc@R}|]C-賤?fNɺAɨҙzy|j.霹ڏ9st )K0~J$,Ae3>ng K/;GxBR$IN}}O޵9#+HB$)id<ư{-L#/HqX&w:+, \m#VCJ< ~ҹ_Feǁ20.@YqV|u_I~r8PI:D,A '*lMċ/RV}ٿc f%IM ދ?|F±qޯ%„LP .:qFbD@$G_j%wEAWeHGHV`YJ Gưj;#*KAI2@24,JT(/Swε׭7+à|ޖjPha A,Qz`@]XG'F:b#eUN ,@9 &8יnUYV}rM|r-I %(1,\&v㧷~)Q4BK",,M|J. Fu00   &ud['AtMUjÖKm$’IYN{($ʎu2F 8Uuq@Ξ+of_O0$QX,Űҩc*`/χy_Di?He6Y(Rc`ӎpaǦX?AHUf:CBs Df,G0gl\undYU군bડh"']/R qEWecc>ltB-EIU}f\烒PBd%^YJ8R/3L)C/!'2r" wE_~g(LJ+%jՠ*h i!0\v:Hd&yC`+$sX)g}Y<oʩf2RFcE.qQ}%s!i*EO:r0Bp*#|>˾f",@ivpQUTE1 Tg8u~۞uaۈJ_>uj_%\6d˼\t.K 8 xC g\TmR@T,n>Jft1(EUu|utf R`"EQ~S$ zzG,'mw!UdF?YU7٥dMJRD̀=yCDguQ! 7Xq[[uwl#Ծ$Hq敠;(˒04/WJљX3aIL==rkhߦtLWCMTz 3` ?Jd5+|%f)΅Bq,&[/.2[,ӏڦ(kGͷgA/YM<3hOe!Fa>Ogfj-n]$EQzywZe "5!(dQ 8oˋ5\x)z'}G1\oGAw: Zb5 Q/4-XbBW Te=b: AkrᩐjמYfsCtlb&1*/f˫|g#AYhRd~=j+3J:C1 FáȔ'v{/Y@wݴ\/3qݶtP:*k.$\ILKu% ~3oŠRyG|{h 3G4+V[\`w/UՌT!PZ, yz@e`X-6盏LCkEq %@: /*"sv>1Xy}nCW!fjv ۱sZbPLD08 4cxU3qZ_^Wh@C);8mhDЭ/ |PH=kp:# X@QszKR@ 9_fvY`Cq>ͮ#|̎'L@ҹ@*@mm5$HUI @#S^nVre^h:VmLONNޣO,qAͬ`0Uҥ)o,RA/Y.X 7ol}kɯ&!V8 j6W&04y=S *qkbX=4|Gӱj97ZGGz뫛&&Bck Pb9Q)?i/:x5(Fp$ y^wn`g>ӣ׽83s+O|5=7Ӏԡb^_%U\ٛ6\ 2Z|1:<~+z!d *"JlƺRm VM8z/ %&zzz"x隷F? T0ҫ)_"[6V@gY{ls}M?ڹҘV(Ÿ=. ΌL Ҙ*Դ6}MJmiMY""5x-BhxwixZ:{oȨ::mm-=+qR|\ <(\{g?{}ɚ:JJY]T 6BY:ZzvvV; ^⃱^y蹇~O]3 R YTH1,iv+g`ǟ^o|OL >' ߮is|l U@J5^y?Objh$bK깍%85wC¬u!r :0g+߮ydU.DTnu?WYZ@W V⑹|lϿ뗤z@qA/BLmYoBd6i,EmEoΗcoO 5ӧ{ⵐj)3'xzDw> NTUZKXX,Q660a>7?>mLbЂZqXi ]+-T~k6 Rӂzae39˛:a▤- Y j^B8xb)|J"7 F\,,MOB|s`*UKC257UU(Ld`v=^%P/TNܪ$Q\GWgdž#Hо!eʐ8ʼnbl!RTqGa* L>.*3t(T"'l㍅58 66:,VŦ2:MM5^P0H Q7]&VWWD0r 45llOL\;|U(хϳ' X*N>z߭;yc)J]Cf8"Z޸rE#ޔǔ<>syUɗG/PLR'W[t C[*ĭk*Ƥp?Sm [XbK"}!A-/ݟH P ڂ= ȪUxz{R7WZb+V)9fꪪzQ(U]]ų֗_ AKW\r/Pڨ5 έ D h]ɉ_U'Ow~gʁ]¹՘(.H+gNLtfDfno~lIGDբ'}[W JJ ?(`y6*[X$ mE #EX$j9qѻ !6UW 'ͰiwnU@(+O[҆JW w/ڊ)רrddlJ+kN`Uܸ\Rk.uYh3a}"0kd!g_Z+ٍq׎;6^ɇ :@:@VN>V1=|k a< ɛFZ@doFTv}}?_nt֟eUp\mwM&*ja`0h EW ү=j{p]g0FKƧ\h\r=d&&zj++W1wwrq*3`qv?;^\;ԞLjy'zn|`dUp\z3abL&F21 ҫmu1rP-XY&rJ.&f:k+3I68L nUp\k2*()@#ǢG21e6Z5 B+4. T*t<pɽr\>>E:~AXu;"S92C40Fe&BAfӊFңnI<`Pp2dr9à*J(bsȦ@K/;!ސhxyCW6gO @EhLQP*~ϞI̶C./5)ci9<=0X:7a 8P S(E)z>1[zy9G"fϩSSQW%AV:T( @(bPIAXZ>nd)]sLJ9|/j;wyVr暂:f;"%PE)L`Ii\6$! Ʊę`(r1>LeuFE pͲ~%ej .sFpcrW4[;veeu9h%Ơh910jGbɻbz-$^xsϗ񧽮cأ BL>[ΜM8'H+RuX8P{l 8N$ѓ,> EENL(dRԤLFʘ[^ \\)̱k @/e1 N|v6A 8"th2&e, djt 3kSQG7zLevOlRF3g4NK0(Ѹ5b5$1V[[sP0qZ'trl% .gSk@7ν7ooϏAλr[UDQ|?<;JNд4Pid6'JxY<~>oץbSјfh$}hDI1 05EzQO?malOzG k3Ǯ(xo)B,홸{10Q eid 'S,^ވɕh<3s!N?% cG`4Qpcj7K@^2o7w~97;m:NԷɷ; /+8Z*!Nj?>01,N5 l.1BضzSƸ2. [3_[hR@E3rRB4IQ XhM#3c4}g:aH@V $ !C~J2E|λ/Gv['Ӆ !P 8%|C8TLy?U%+iͬIo8pl9̑xjͅI@¢$"|ݰ(cYd1-hOvc{`z du( (h%EA'YeeE˲Rlr ;Gׄ!ۄJ%(lPo̥6}ZȀQաRh#*Jp!ޥaa4׬¸ 7뵙A!"JP$%9;O {qRB\%n 6YpP)\!= OYF&v_|FpqɝRE icp hjd4Է_s@^$RpU i bRF/7B^(!%`Q,M:wtrI  7K9XlK˨)H^d/1NtnWi4 W@)HGPSYK9y͞)#eRsn&9wN8蟴*H< #y#&i^tyG7N;1+M@#NZB<# Nƛ0#!\*#"_q `##?ǤBqdM\d??@+stn IENDB`imsprog-1.8.5/IMSProg_programmer/img/ch347_45_3v3.png000066400000000000000000000505741520775651600220660ustar00rootroot00000000000000PNG  IHDR,)nPLTE  #/(w6e/8T@{`QzNAb@+j23a6ǽw΍`sõ3n8:QBŘzOktɢ˾j8vђo@evhvIvkcZM) y[|^c 2]ZWR 3W4uViV 4 aHR_&F7< H49& +\GNķ [c8I )k@ f$B+%TB´ O; y2q>n]~ʴ 3, ʽý.G=+&qH|Dud?\JG@6" H{k3bOF4.r+FôʽL.mZQ 89iU (xPʾ{mD>2we_KjQBl[x=gYB7/e pĦArhfB14-Q41$|;stFa-Ar/!*"2 qZyGzŷ7x Sz_NNUKoJ hYVk1QaQ];IABul}mĿ͋sϝ߽HMIDATx1KP33r%w{ NA&QAD+tK%@29'[H98Ci\"NoNTu<9ӟ9a蚦(* buwLmWZɲ&<Վ`+nTNϫSk?+i6+֜3 V򶒨ڎazw`Ѭ'`ukvEPyd4 |< ֿSa0bكe4c'ڧ~ݻ3K#*To?[&ӯ(qP#?][Z q/qPrXOFz.}pdtϕΛ:1`i+g/=c'._paȉNJU9[Ӑ.[cND?x@AŎBİ'dPtPX}{G*18,yVk ,tR )Uo|dgI6B 4"ZkkyT򡡰~/`~7+V\CPW@JW|y _i[ɶzSScgqkjz^%RX2x^X 4آw?jڈ|Ȧ1zSh ƹbQGQrA5MD˨{hiŖqͭT`^x45ǝMLa AиQ%Zfi,zb\N}Pa8a6@SmH!c 9au˙4+4RJIT(k2z(VI2c-JK6>[Q:Az"X`*G|9:Õ~Lou/f7t^7>#j||̅cٌtLd'"5W^ƀy^J) 񺽭׎,O6ED2VS|[E}ti2<BM@KE"l"@}<(#BR?^޽;YҵtzVeVk;ZdQ܍ PcHvY]@_Sd*x]h'lq8 wZ3s98"ZNU|(<73d;ZTQ,?A402!|R_,BXi566  Fyύ[WڹIpԇe`8,dDW l3TCŢ*yXJ5kL*PZX|q1 ׄr8]^:R\c)|'pgV@XXVwh\Q"C>J|0{4,_ oڙjQbX:a+o#tE -z 9wq% X O52!Z<9j挺@keN;gjZ6 ۘK$,ITV=,GBаBuAZR#{q 7 LMsZ:к5qVmr+J!ɈK*N{?nk}%~:+((} y,(V_02_X'94ѕ x*)#EE>IK)~mD]8h$^ TM hrnYUa0=/q4ӡ/2vSD`3Z./+,rfA*4pp%h…u&4ӚC%VՇ|`zbBJvƒՔQ[(bp o+~m'q8T^7ph-<+[eA}p/"n"VAAU{ʓJ?㒝]e!y|+kQ)rH6}8=}OZMkn Xv]L5k=K!3R֏Y)n~8Nh+pȼ 9Co8}zlhQXL76:7ԅkW,)/+eۍq G5ʠZ厏tlp/)(GJe\oqj-8QQbfYTnn;J#X_3O`vňVUGI`'wnjd˝y#E1XrML(pVWL˙#z|Ffw~cE˫$|]Vg+B3F#`%7&L[ ]33sqmB^^ZZjisdi@Z\^VlК2ĥh~Y"dQ@gS"5y_՝ZlM9* 'A<+mR`۽o/9+ 3aai#M JȗD6 Ŗa!_)2!_B8G8 WOV!1'`A*2dƼ.ݵ/c8H5i%}UۛS>ovIPbtU] ⹼ݝ+,eG{!&)Kܹ'\4{ $D֎*rW ZղnݓrTVM$1d \!),n̐FOx61 ®ibpw.?;7/ij#;.ZX\lAd\IPòڇYʔVX2Mx jwS 8Vb B ըmEXQrpL %E [MR)"[V\;슰e(rr{’hnmB2"Ao{qR1X1mZ:࠯]AN*FAl`D`嶌$uϴC3Y+$Q/+lqDa ݖnsےC%RkoklFh'3v51 xW]L=xmmmn;'+C+ ~LYFMH^ X,(!iaQ}.)]WD$HPC%Abf?m n?[fW4ȃ=/H,Ȯ[`w: `k)^6׮7L,1CJV6-L2 ޻ wPp2?yo&SehXTeT]l]ĤE:H¤._VnkL#0)HUIMXĄBQXOxJ-[Р3Rqe 󮖋 @嵫%e;ȗ0vH 8Q~`x};/}VB/hMnJ==aW FјM&J(+ٲKxw+zwd`@U)8J4 `w4]YsAICJa: Y"P @gNYy\ nXYVJ/)e *.5^ViEh A7]658O/辈v}xX_O?E7 "I[gk"S6S\J_=,RNpz|z$V06@z)Hav\3L& (;(JqӅĀ c'O oZ.&tE I-Y\K$:;D!P箯=XCnbAVe5#Tp(+3vun."XVhb@&o+x|{y:&Qe%\N%@"1DxJ7IȜDZL4BM+W aX( XJV2Eѫ؊Cia4u]jŘ V`CYyB3_r-u%>!(Yr9ݹ ș, W8mcW֘J?Vr(IJztU ~E`pV(R+XI$(0H}V.0 b=WCvx/ၔ@0L\HDzFQ^VzN'B%ՠʟIwTyHKjWrE%b>&hhj `ew/ ]Ff#!oIe[#%Wt5Аkdf91,f}3a0Ჩ|cC-k|T1 ɉ[P_65q\Wz&\+=h <+ B6OڅkxBf[s8"$1yjDh}'f E3>,+V̄1@_Md2rB_|~ؕ=*ayBP"\R\׃Kуst|xtKgV%#[ : QMY D-YY êr$9THZ;+,Fv A%JePk֢"O,8ZL xG&WRTz *l#ꖰ7e SDUr>H^Vd!U2+B `xib@_V[^T|ۅ gc+Y"^QCa{@b7Us"$ Aˏ;!yukl"f(Eӗ "?,eU*c!= WʂkK|Wb˙ab+^`++Vdp17TD..ry'OpYZBeAE(슦2klLtxj! _zeEBv3] ]Q *$u{O>|$ÕqHqq[-FBOAz,:wu85ZcؾLɊ| a@= ~Eد:YpBֱ 7*8˧6OqQ`%EŠ*6:$ﯼZ$bBvRxL@|=i|ˌav|N*+V;B/ؓ-h&^哳~Ph\YmY'Ea7k aBКAa +GӃL.YtS<7Yfݑ$e dŤ+V`vڡ/=_|{O̺p2Ǵ͟=wV+k[xhsQT ZTG#í [!;\*>Dez;2A*v f)Zq4;1L{)u'yO=U;Aiyq$`l8EސɽjThYZ 3 qJvE8G PԮdc{-qX3<_x/:33?d ?V+*A$V_|3O?X}{/Oz3)3Vq3deӢHULظLxU^,>\,WTɴ13]^,e ]M"X_fi]X'xƥ!yu=0貺 NPMQ)+:8cg+g 9ZƐ`"Vp+JPh OZF?OU:+dJ;xš5-׳\x鲯>u[_?}D7ߋo5MWYb$LYډ mACѶZl/gUuZ XhM SL4)#VQu`yEi]v≗g0QXXaï*PQVRV|37Bhp'ٕoj%wk|tvz+p /Ɗ~KaE [,p^: Y78ϴkfWxCn_'dAvd*m`n'r`UC>BZ]j$/Ēm\~2PB܊Y-fzlc8V=rŦ4zٌ.On˵v,(+Đ AqG-p-(a8U'2TbEY_oXXzŘpm&)0f EY+Z_H-<}-Yy+ϮڕԾ!)9H XaŰ3R-AUz,+F^Uz{J/vt,"n\˅Y,ޔ+u^9@BQ^5v97VHWm=f^v!Q ^h/@GU}˓Xc;5=;gƬuF])R>/%ZKY!*(Fd5o4<[(Š ^t27##+euDIh4l)hcښZuVeĒb5:F=p8E]+$%j>Eο%W{'`}5y]Hؽ~g{xp?hD`އ-ϯ@Kgh_8021)AtaLRuTٵaPsB7􂎓uޅ(+Œ]a8?՟zۍpTP{ȣ$Xu}2%4L[LmZhP-~.-m^`}pe!JCJi).*DĮQO@tQ e.b3 799 =XxGƗ('DǵLGuf "-&"JSx毥|dXnDLմP%Ő7C4\)JyCo}Yo\~2uXI8uY[ѮW2$('~$K:dִnX('}.b<;jVYJ'xjԫF++myDyN"Z>P,/C^IA lHa?jg]y j~Ԃ!$8YK 񠩧kQ󰅿/Yź(;Ś(51kQgyo!r`o)<Ú2mG}leƒ8Ir? `U_$g>4xt[cEꫯn=g"XI2YoSt2BčSv%^ y,b$TAY$DX6r= 5v1U۫IdhQ (XՁaDiWkx<$)r&bj5htFu+=ؘeCS B Jh8La+m-m;`XqO}X?6eEyZjS۸BǓf3L'' А[jUlߨe8*}}g@Ӷ6 +"qoc._QInp&kڃP!dcbyZ턡s 7-9/uib$DPۣcS/COcUoW)oI0nA{PJJ8ETX_r!I1;9`e,J|92Xok]Zq: _5a@Q;kho]u\w1|«чЇd_!n@+4䆷l*@uL.ckUznG3ZԽ*dKC+e9oH2AaA$Uu \+V6 SN!ϼj<ޗ&!+V|r Aه_hMè*\)A &Syr&Œo(<<'|ГC2o;dr<}< jO;o}Vۖ#w͏:`!\ՓPBu咢 *,.EaWXVb T-+]A?վ C_rYʥg=Ym v e4se2aYQIQ3Z lXkfcL؊m/"JJ4C!/Z.jZkm/QX+Ȫ;_Y0q^ cmxԵ xW茝dTQbȹGl)V4ߗfЙ/^\$D _ 3Z%jZ;/A}E߲Z^,KĬ)aÔ^Y/۰w>d~d&`YekSJ2Caqa9I4V';w,X-Nb 3jǒECq>/.h hi*/[ 0 Ÿ;LN‘l-Vmh(bn$,.~]eSPЮme5ni v+Z-*ODkz Cj:x`dL,"WǃiC>lY*&'n#\koZ?\^$ݗv}7lh6~HK]1xaS !&5cb=w%u*Ngà"*djg }E]@l%IٔL"hM-]X¬AΕhjuTpmw7?i1\IZrrRn(XyGt 3G} *Y ӗ?={Li&|.BOkP:~"ZSeS:iG /`wԥ/̩9?ByT aO҂~_E,#炱T T1m$ضjF$G 0oUm4$4uQ%CvFX}XgJZ">_~+HA,(4w-}Y-rWm ع2.t`4КjK#+6--=cl҉phY_zy# qOAxmg8O۷֨葤[*>ĉiixC͓P3XbMsռ1#`EQVN?mWB=U4zPPbW7iTK||ouMMl[5F[aʐ }Lճ^zX$LUlծq568|ԝaN d3VKI0yPJ@l\[7S{,#SH6)#R1T+{ڽsx_&jTcլU+8[,JFo欢l2ܸ y,h֗7b!}*Ѻ*T pf!B';rA+̃cU䍤3s}1*}YRQ^Įdc S0MA)'wr{U7}Xd9znd_2J~34l(՛2f%)VU .R:@x`e5clW2*f)`7⋭?v'. ?Stc{k O#RtRhL[ҫV/Vy;d)}&ڤ?|YX՚es asOY={q)A*͆(lVmm hA0Vl[= 9X˸ϹJa@Z;M'!N7aʦp>Pɉ`5 k@4ZYRg2Kf e~oY!cgckjFF'rh'PTU%kNUNyV,0,ò{k$yЉ#+6EQ lunC4g"-Yy2+Ex]nUrS燱ϓF ^\9b8 щ0BH%#IeP ְ:FFWiƷZdz 86?e>+"a}u΂|^f_V _թNG`hC\k悰JV8uhdQ';\`m%)Wf\;mX|UXfPd/P0x%ìvӣ?WYX6O}@4 *;,wW3.ʌFQ(o۵Nŗ5BGHhuÖK][G2 kW8ۆ}vo-Dc,E3/N#P1- ] 4uQ ВƀEVT4h(S }K|~q=Xq! L;]QcBjX"\Oɓl(iS *`K>g M@fnh]$I+EE):T~`,c}ff\bZQJ"NJ/ےK?aaB,1g97 DF n־I kg]_7$oEX>l q tI\ʓ=["ᕵ4J'X3#O8΍JZJ0U*] y+(pA͸~߆#`R_W]ji<,[ξ,5D1 ok8Hl,LT^!4A6XT}uvXta))le"jG1,Z"rg2'$bGzl=j PVosip\VULYNr y,o/`ѡ_ߤ`5,ڡ:Jpy=6b+J@6gIwUu7ܩ_CCЇb+W,G7+_:NHlzxŰP$NNTSV rZһ`EaiXj si걤iN*/ơb([5{6P}gwݝ6`ѡ֋Uj y4)h#+XS`%YU/㜼Ʒ.cSU&=]a[E:HqoD Oq)Z3-𫜥p9I7}W М7nGv `%sX$%ۀEJ$$/$B*T0ڨV5ZXDIוivy@rIحlej+U^roFuעbm(w+_EQ+OQA )Z]6\뙦s",r `UlPэiyʒ5e=kX8NoV`ZG *SYUpoCsS6hȨ!& 禱\-ej_|;ZdLny?#iQ"yB!1{v8l['\StD2dL:i@y-QG1+̂Wk5ME,E4ۋ-6ĝw]\CXR+bZ3ɫH!K.}vipBQ<ݹsQG[dU^'n/~MB*Bj%@l)ؕW}'7yf OF0d4K=H1|ywi7Hr{yH ]QǶ鮤qXdٵb)q 㳄M`eW&XQk{[vQvuwXx  E6=AWZ=DHb6~3mh fM1vvK׶X$`w 4xKEhNw5 c7O"[*N 5Cs;q/%^@v`=M< [8zjj0xTW+T e!<<; '$kف %w PYhsT\n9 WiQj"\kʭlj`V܉ΰNs1WdŰpߎS{-c\NMMY퐘i·ki*/ v<!7l!a{<:U /1̝6E%ҾYltP݅r~ĩ'P-U#kCźV=UsBl:=}(^&KU{761x=N[/'翗.@n8Y[I3, 鷏HWP W=Dzdm<K't%ꪛV* b&] j4=/+H.?Id艗]yTI"CX.؜@Tv~5; {+Xߨ@!D1VM[$c*7ԡD gث&ElX( !x~N'Q ?쭚4+ASEcd(-Fp(0:1gzGD!0Y &:ت03)q(BFΙP6IwD&bW diykwB\My^bܸAV )VՔ tEWaP[ödd1Zꄍx%E-ZhѢS?5a4zfIENDB`imsprog-1.8.5/IMSProg_programmer/img/ch347_NAND_3v3.png000066400000000000000000000460231520775651600223500ustar00rootroot00000000000000PNG  IHDR,)nPLTEɿa. аٞfXõj6ܵ`QXp=xIȺzJҘǪq`Hpڮ|ծǼqWDXC3{]`fxZ! чx}F (M,̵g<g2U3qZ,˙tU]8/µ p7:ƺI95:-(E!KWVhNyn, XJFˮ+"!gApC BQ_\wO&ºfRGG2*8$ ~: ӥS@6Ĺt^PjY[gd;II|#^e{m/yrC˽e[T><<#RP[ <{664h%wpxqe!~NL} Nq!e?r`onqGZcDRNq=Wq~k,L+kfh4Jzwp^[teY[4ku3^=UCrs\~IWaF:\ð?DC_^BA[.R^zD %$ў¸ؿ77@ʹBujySÆ&$4tRNS{?'ټX$=uV4`pQ㾊ٺ¼w͊HIDATx1J@TC {W҈93Xn*1}.cl҆' d~fߩ/Q;R]4GjHpj.jZ9dKx+#CF^BYa_Em/>aboMOG,1îq\P$Jj]wj%7Ͼb)Z[+u?a,ײV,aNu<k\_QH[W>1|ng9^878Ca :}p8f[t ͸#Ŧ(E*Di斘&("%$n1vqJILbԱھ3ަۏsއg/]<{ZY*nu^z|v=3>~&òjLX/Q󻮳uΌ_YNML R6[kX_TT5"E,O?밙ZZ^edQ%Zh$Uj}C!raW&ʜƑKQ8+ ]{[/^BLV -Ɗ0&@Z-EA htwYͪE U aqt6eYJhauHURs *'55V&,Ae$McTUɑchhD_) N]P(l|?LY5zZ(Ah&)P Zޑk\Ulm:H Qd ӨaH;C׹. ]k,u[-S%]gDxD&-w #jIŋ_P`(Nuس J&ޢS"ʕ]G>5D̂tJ#qڎg@K4PP -JH6}ï]#ou# 3V^6B*` "E "Ѳt:edjݩ)EWr9J0PH+/#g` `. PI4U_5MQyAfhi^J LeOۺYH0wn`PQ)K%$K&+aLuT,D0}~a!Ɵ(5:*(@ JfqCͳPA2{7^7D. Dp@O]ANtp05sH$~6PCY4[ ^-n$cuйZɐ " ź]"3cps|X'cA4{?I79so;\Df%\/S"05 _{JJMV|JtzCR,1Q,FKDjpN*aVVM[o=~} Z:)y1ohZάZ l0$ ."gETݑòrɲɊluZUm7@ cyz0.l!!N~~ `vrtrN=`Uw&+&i . SYlɡ=3 GG|"ݛsz#sfAAsD {i0ĝ%PzZSpWWk`m-`+XC{ZCQ@Nie4(#Q)s~G֚3V ==&U^#9KIA%4Ϊ*A\ɋYKdk{ 잸 &*C$%}E@2J Zsjy 6c-Ywd2_"3HPyZWRfq6iə %SbA"BauǮ_ݛw[:hU1 >jnpFqSENKEJrيQ; x?~mK^9ԖB|BU* Fd(b\"$2T({G骢rрkrрnk{UPR2T\JTF l#Z$KXrm(` Ѿʍ;UY][_-}/iEB-nyZ #V͙Irxտ6" Ju ;uJDRlaЭ;;;#1aQUVp /"Z^,XC$*:1 RIľ~i-GwL_ۨ8.1!hNA 00~IX4$ &&T+$ZxYNÉ%Mİia]rj\/Lt!-m(u:|._~ {ڂ*=^:wIM1Rqdc*yyR;֏+?]gP^}mʶ#Lء-hSC@J(zJ, HN\/w zgȑ!UIL:Ng Tijߡ ⾛ރKnE*+0*V8=qkefXg'Gw>ݯkJWce{e%y]Չ (:0Cq"AV:;jK.$ZVhA(+JK m?ɛnvo@Nh#j=J:o RmX>_7LJ6EXIFDbzx,[̵o2+r9o֮Ǻ]E"6t#wu,meHia:8јQdPEs_SYD֒YRQ"Yuӭ-=/*c;5(RIj)!|aX"}qHfqGke Ƭ&fo2MKdfnѬUW)i,Me9x\̤^-?zY}C~"m3YG5j`uQ eAkS3Ƴ;®XU/K,# Vg(5=Pe6g~.ΏA݂**"t$Y ꤅g͇)Fk+Ѹ#K;cZ2%"J+W< LQBoL>O}:{ڭˏSY?aWYt&b˙ / uKpE)Vb$]*"Ak83\ QBGQɤ9׷uA|XH^e!y`y!9:.8c4d|)լ)NP؀C` |;Yxӛ8`&ʒ(Q&+X} +Ripq`5CVDJ1oXe|8pT#]52tKp u^Vŭ-t+!pmVE(\JaΊв˂6ɾ,j¶U-VR5U]tCg0g)NE ,e®H*A`ǟؠ^יwmBsкޅPMԷ}3qƘ<vm'@. 2h O9bت۳Q)pR?# "ITv7յZ-UY *P7.dg|g 6v׬4b@- +]^y>$\)[F\JE>ZW }t՛0w* ;ҼR'z{{r `Epmw"aĄDl$잡GZ^,.F#G"]Sp%w̝N$fЦaTh,+P`ahl w'+X-٪ $T<(Sz'VkUJ5q,߆tal: ^ci.8-͍ Yl_hXPPv d2JdmW( N $_"TX`HiEqkϷqIjǟi&7p% kMxT۲f|;1gO=?>4;88XȹH\`,f]"irz5qggFÒSD -JYeF}(2 p,>}y.zs.+ey4yUY`E폺 =1hA Ento,@őb^#i\-jqt<5/9 cM)[{>uz-h99x`[Wb*`P(KԈMûHں:U˩ΎIݢժoݗլhX:Ծ訞/@Y=&gN_ ܱCr{=x` V-ݪ0k*iꘊzM!qE@Us NUO^+ \bAI 4^9:pPF NM8iAT.zZp7.3bf[n#{&z &D5BϾxÕMG`=`[E-]'kK;_)I{z tˌ|u]]V EyCPЌWkX+naO׾C4|/[Sc;PEc=di]4\-iG&U,+"+W',a&]ޱ_FJgyB3N ->[|Þi[rrSPw-VBXSQzOfP/RY8opyoJ] X-ysfLZ5v ^8`ܶǭo:$Ψx59F:Ni3Dl;PNX E(Qv!XZN tt` cqq #^F8Li Cۄ<zܢxr/kNTc鈳 }Ƈ2V+Ntl8og7tT{*)+5>|r[;EW|A^&2EP 2 XwAWR@dC8?ڸ،a5+ŠBu´.|/󶙬.haxʓ&vh?'cn^׺,d VXpnk,UQpWs%nhjP7qRN {8I~nCט)sJwKrkOj׬h׃"ä tA>u;`B: ]X}$Y)ŻR[uvvN]}{3!g{;V rrV8X;`}ɴ{^<**]7WDe p>tE]. (kvvhzʷ Ewڮ$X@YPҴx܎t~5뜜SꡧҒ|9hnPXn+bF]H\ 9ZQvLE2AKɵXqɶFhf_[++ ^pFP+ؒyhfk,m%{=X!m7jث7EA*NKv`W`E" Z`Uh+4y1jɞ`ufU#W֎ MTv6^3j(Pq$eݞ-ǒ?8#ȂD]Qk|x`~lv(@x"EXÌIc(E.+wW13\zgu׳y6?AI j V24DM >ci#M fpL]NF`mV]jV6}f/GDօHdB_}+FOzQnߵkh,Bð߉]9h+T:5W,,f7ťC/,- sNNF"WEl(S$(=-дz٭Ԛa%COEJ p F1 ,KO]U%SyBkCvhI.xW+ZV;rߵiAdIխ[gp Jn%(ڊb- r,O3(32)a]2r{X+(c dwAfSj /CtFjS52"ręcyp'^Dz5aɋ_؋>{/ˑ?>ۘp~4fʺn0fp%asx }مV?>U)P;EVWQ;:z V;_e2(AgW/Pҏ؏?kofluҮA@Ql$-Dƽ#)Xrkj=Sf ꅻO뛏> ?ਜ਼^E  %K2?~٘({2:0q-yHR3pcW yq j5t2$CqPᏂ{I} IK>£w?W6CZ^z >$p䄕(IɄC|mp!+J0W mVCHZsQL2[Mv\MTcKQ'"ۓ)J~أX]}Mgi;Ale;%"6r8j.g_t83p DZ0 iYlnͅ ~ l)2iDgoXO^xyl+:FQ2C0 b3ֆ]Qxm6ii[GQSK}kbh;DuŬoy['N8֠ q:?ὦ$IM,IK5d s6 ʍ@6e5!UIrS U[+l<*ZnČN ApWv/Þ̗0hwY4Dpzbag Fc(D"iJ0L8ͮnփR%*+w_C̮wAgn?~y/wf5S~yE.X3@ڇ}9%hЂ{w}Wk?~Xӷw+Rd%#+F?ًo}Nӟ~|$oxJL MPp ^rB$lKapP6yxn}ꋝH46@\sYb"`VX݊n}|KoZ#I,٣{@h6,>f y`Ͼks8wi=262`P?:fZ<.E}l\`#LhA^ےڽgAק3,0ڏX؉޹vY}ww8@CpW!K {-VW[ϙ:>STȯR]rg';K|tu& z#"3Cns Wg !mß?4#SQmhŠ2<'Z07[E]2~ 9[t8s^B*эgcaj"A0ݯoh` hI_XוUUWlJ]8[6JpfEZ  64i=isOuxscZoӹuxE))BDyFaC|~aH-iY9u5  cپ45|<%QǗsFp ~OPoĢрrc\m>WΏe""^RxqºI)ޯڳ@J[Gq+R=É6xa۴ aj"7jUQLV-ߍf]Htd--nuVDn+lER64IEgdA-v@+Od8P5epjȥ%8`eiy@))8Q5j[Քe1eo~L`1vA)UdhgnW FQ |AָVh>?eK(޸2 V|67J'y55wtIkq\''gZ,XV͊nT셊ŃE@)(G )5%eVi-<," z^妮:a . Ojj=rS&J"T~w`ZfzD$"}aG **~9 VdEyZu1N,MV, &\qQ Qn[P{ΐdՠ#;HY)qiU4%E-}zEWKADT(RЬHbEPأ|~t(}$VRfNh$YvaO%k' [Ͼ ]y5(ApdYuRkv_cRcQg&ar|}_0T-"v]Fv! k[ Wc% &@hI~6XBY,c snbiyNSOg2 sf)lqD^?+"%n U+/게Ţ$KeIHb@ n^a"w)]5d,K6E[tnob$D@l+KuE2bkr:B$]#d\{ ;Xae>HjUdZg'uiH'U AMvaop 6b}kccƷﭮܢ&0^_x*\5qG8{^XzܑRap)j*=7[6@Ni }YsV?HpAp+K](;n(xV(QX[aK7[ |X?b#ї$( X%F@~AS\-,m q8˅ f;`q_fpݱei H)r^)Ecp̢/]@n75zm$?㢂||IkLt*$!L 9C-ĴX \e`egY٭fwsf-ҙ="t]WM2iލ[BBm6;-̞BLㇸ{8@ sֹX` ٷQ|h9zг$5Tb)%K &0O+]aE^Oe?X%JfW:Ŵ~8auPc\P;i}z_:]Š!_W㪘ٲ:SN1 z EwےPK[毬(<إHr}syZ-+X!?ùgTq97v}-]j$N'wQ\eN^/0`hVEXj" f}SoBjþ:E+jWe-!5]b0I7lAi&Fr{ Or*{`[ *y;5muUxf\nu狕} C|VuKz15 nFo-Du2` տ2<1&2KS[KZr}Eg!y}4˱.bmʉ`|-.J)#jTL/g9bLM rq(,ÊXэIP;}\_fj.6W9 ŕb|&_ޒ$. {@% ⺋6]dp/z@Ej#7wmm(;թ{HBG}'K ߷ 8L+O76krba;0hذJdadOiݍ[oMj;uΏaVUB6? .1NO|NFb$9r&5J-qc0I*$'456,zJo%g ʀrxM{$/ttZvi+~$v 8a7!AZZslΘS祣2!S#Q ̴!qtnnxz֒qݯxpO8+y, RC,ө&+ J['sƆMSk0Cko;-pF'fR8>=>>@UHi\0m2YB-;rk0+]e\{qDGnț^5'M!#ݡ\_l Lr2"lC¡?lBf~Z/՗r1Ϝ5I&]AUB+u_v*hI5@e617l%TX̞C +jíAYhҎ_j>W\ٲ"]ZGC KVhxtQeKe7?5=sE=8wv3;>QmL '3ɪ-$ } ?BFc8I%b Թֺ1_)Ѧ.Rd8+8HXW Y`X7&]-0+!}' V_=qdt16v s: [ya/7, Xrؐq KXEYq5挖isFvb[9 % UqllDU3ǵsD*Ԑؒ f6VV$` ÏLy%#485]uX3F#v~`s65kk!W*!`=y: HdO*zZ|9aɘ&HgwY9qc}1#EN4Ss/ }wXL8uyGWmC%X q[;o4E1ʆ|sI@!f=&+[-EK~m MrqM8c0Oh#5A. O(ȔA }@&)_P #3\w@2rţ3xr91mA^!&=һDPG3k e:,"vKd'4'r\?·du󞯟|ͪ $ΎV} ̺}7WۣX'h9FpRl/&+'xKM kQNL qz΢kDVrZ ԸXT:Uǹ ҫ v.<  #fSb]yov"3eJAuL$zc% hLUت#Ԥ,ǔB2A؜^Mw]G^LMXGZt\V•"cT^ >Ϻht~{쟩'aAȞNd??,6^ _@*lykF"ZXg|8pBh®<W ~pEPᢽt9h.c+9)\3Oci$Wɍ5К<$y"q6dZۮѫB٠[6+=ApCj0\=u/x̖=_Y|Y>P8n<'JvsCLrQJ\^mV3DxWނ ut y"ʂ>=yFhQfСM<{8T븐ptJ~($HD<Н< oVႺ :%u1m!}44癬D|%(IVRJAQH\=<5ѵD`fVvm\VUgܙ˿tA$@5nͫx(K#+lL ښ?,-,T_h:~8?}D]ILc~]upz2  8֪6 `ꡥ;o>HmM‡gN|RSW#&YN;Jvvq@ƭ k? 5RŁÇH?Jd!9hxWV)׌ s9lřd⟾ɁD-?ùbuƵ $G_z{.;_AuS: ͪveOQcM?V@.$EwFÝu>K$ZQ1? T>"}+jHԯQ:"4jlvakM]7G鯾O18}StsZqXGc hebyUΪ #6w6}<,4<1KnYVdܥZ2K../wjƽPk (AknWv YG$b}`s sY'v(1W>YJSū~ > _+®w-ojx8U]yj%6_$O8t֓}7hW q/q S)nZ׈Qse"gsIvb+"|`iIݛu` LGVpe69uYpyTRy~1Ϩ \-D-Yy[T,˪W7|I8?!qh;k?qJYme$ xplFi4BȟL- w?Q0~Xm/B`-eYbhw ާǖrv& -ck4![$lSEKB{ _OϛuJQfӀɌ:x,GIONkX(X13.8h-֘ғp/`OE[C R<_T)neCwٵ .n'Ǯ>~]st:0BZ,>j#O~H;UWՋx9»áʮ{\8meЀ(G|$sP-JInºa$U碸 7j.g7Ua=RY9'B񃣩ܳqxX5>I]eҥ74}+%-f٦|RxxJPɕUjKc^-HJhOY•Yd2nvQjZ=;{mΛ O8Yzqw|H>d˒ ufrjw^&| X7y*OwȔn+}_dғQц66H%PuX'YHc'D?f斂OpmU䝲fYv;{Vw3`"?+2y`{~XCCz%eLXH"lZInMBn|Edy).F|ieߠGj"HTPo!-ѣB>H?DߛDNKݬGf6y6kX xTt=͛\E'Z9eocgEKpi'nj0hwyD|-3D4HFchێA|Gfۄh?y|Yeod Nӓ頽xuJ "Hc{ )b}$40UO;E(7awRQ,} +Ph͖lEw.\eX,a"\5^amV~g-A2P,d> );r*˸\a l2!1:%n?sBK⤽$!EZBSs MKRJ{ep ŏ4-c(=,pyLf/EfI>*L#XH>B$)!,/CcXP ,,I"TpXu`0,^Q!tVfi ,BKMK '&RkHFu%D ghеgֽt %*miaժUVZjպ 4p~IENDB`imsprog-1.8.5/IMSProg_programmer/img/ch347_i2c_3v3.png000066400000000000000000000454171520775651600223130ustar00rootroot00000000000000PNG  IHDR,)nPLTE OB.׏i5ɟ^Xo:wHrC|PUcµi3кĸ^zrΪΏoLZE4~bMT@0|]yZc!h`H *XكTIvYNĿ yg.|wpDylZdeķyVOL510}˿ùv\!8kVNZB7m\I;8}pzaQeM21å %%̩lP50.>?ÿxh`"U[eBr\YqfNBxRsunid}thſ Q]F*&AA_lCWpVsS\i{v?Rm%C_,23ѯf}sr*_c.F{/rC`mJAZf8MMCCv_XU6i[Dv`].AxwU?9|'JfmlRr5nnмKͼmUjwD;gmՀt\zzpm}-4tRNS3Z/2uJYqJtƆlQ۞ڲɣᶨoGIDATx;N0Fa7n"ф, AnǴ֬Vce. .RaC$'PΗ4]8o{3/m 985 8w*RRW%h w&s+ޡ1U,ŴURɡr6tsetpPmnR)7se%s)Lu4IJni>^N\+Eͮ8W[/.43Ʌ77(X?n9 #A[8]z3ɦ6B" j BuXӋU==P$b=s Ғvzᬸ{^]p2X"# K`%s$q٨"*n* oNW} Y#~xHvex"@ᬨ[8)ثm6zxXUW%;X^)ҥG3cւ('*hDKQ?_ zxk~i,ʼ%7%\RDJN~>Œơ'*  %I@&JDg~k]~Ɂݐ+@4Qomƨf֒(R(J|u47wk,GΘ C1>&nMcApc^|?],$k=U6E!Ea>ꝙ鹁+.i,-dzN¬Ȳ((Qet:T2nׄt̶V#YZSN񝕻VH V#&XzCU՚bi6|>{A"K7%̧F9,4+bI7*h"ϛ % D[S#c UԨe[vDC//A2CX@̧,A*;N:"$Hx ykĈ{j}`v()Uˠ%M҈7†/H0i,d{kd̴\4QG-eh,yR $Y4qGPq@`vt> =pСe^|bR3^}KxE5 Y#{ Ue#ĺ_LʊoX,`A4cu$(;^P(s!;`#2Nd8Kx NA!Ⱥ]GA;=(oP*Uh((d—CeKe>3)(+C䧠ݨ U(hBzhXɃ !)~Ϧ(iv- 9) vB)6f)ҀJ(n`}[M*NR *G!A৏ƛD.&n|QH7Xmm026U+*p$Բ?ESAEoƜNՇy|rypaMDrq,>'q[ES)S8-6?_ c}S_Q1D"KU ϰQƮ^"\.oŀF _Q* KUWꂼ !Z.A#lvp@KV Id"QXBNF^~xpxӄ]q<:5g'XPsV(]i⫫CZ1riKV[ժ-E@+낼vpUfFEЫѐ^-8ܪfsA*TT'<˞~W&MA"^>'awQU9hZTOxiːVjz<D뙓3A\`?疷QvCg UIo3]KbX+s,UwBdPy쬧_./1]F_"H. ́bi.lh((|t},7^?wk+jUZVR{<5xFv8ջEYv%#R5.4?o5paQ4lxN;rO׻EGaB_2J6V%j~u{Z袌,Xj(X*t):}PͶU iNks1Xh-~d[{Z^t;|Z!rch^/O,ѺR!! o= 5·UBs+Zϟ*ܜwM+ Hb<ޭ  ZG>4?sXM$0?ctڠpea;­ljnj6ڻ}gQkxcߢo5vphXxY/ӝTa"FX*%" ?* 5EJeBvLz[Y˶K75Y 5cbx&a4r?sۏ&=S/zś_w`A]%h]dž4mj(VEQZp~{šXҵ!Т{0M½E读{o7Ŀ7%0w` DE/^ "X]$\9e0H$%s0hjdJ/-ԪR†Z!F[f/H/ ͔wuXۇ>oGü &>yb]"&NWnbe(76ԡoݮ>roݞ6cydnƌk_hX|7ʂU,z8{nco)gOQAF<"jOZ}>C۽ݰ 3H:@+.Ҫi_3ośBV &m߬3$QQ>2$m7X)&XW}2,ֽM5~*7KӁk Viz74x3o17D#Ą~+ -Orɮxͣem֌ڊZJXATBL'&_}C&׭:s5D "ɋ勣d^-B#9eZpSyV߾`=UԆT9RpHxB1RqA1m9+nŠ.ڛb"n[kl1Ѳll8WoΣ'vE$"iX)4 ''~YPh*(RD =?]k~J]Dڃ5{@:)! WyBɲ$9I /'M6,VUhYG_V)5 U[[~ʫ_YEfEn]BWLXtlR&CƁ̍eZmꠉw(%1JSBJ,eF X)B̩.%݆e JXN16,qB kIWDRaQ`X$ d,i6ɕ ?_  aЬ~҇Vp;e;REeo˼BpP҄X{ߪE/X0ӭw @yG}üs]14o[JceQ=l`Ifo|rV{j/mv8qn٫ .c܈9?rwbد<8!بm3aVC&hKc>J_> Ʈ{PkZ?=ߘq8awj-.A,4DZ~ߵn 898 >[T`%'~ ;#Q߽Z<-@h씿5-+gi@]0ߴih'OXe,9L {^)jX*EߩLqW1~gd2oW. )xsrNĈv܏,򛪟E9!6>1b•Wx+E$cԽC_{pxTō78wAd]Xp/1.Ȣ]}#Nya^VZ'VP/ ]]me&ƃLu={-ԝO[ui,jƗ腉zo=B4&V6ֵ@WJ0*mf1dR@ pQX@Y'-u VXe^w 缔n>wRh fr$$Ye AB^Q)t8FjZd:"^>8w_ 1̵l[G`VJ-^^Fv|jwB L@ͶNI%_[v :h4t<~OX>c;)u5O)'lp ^_v)' UӬâIJYj"\e5c I "bq'b]xv b}wSu>%ɅZ31AXDZpvC0tWe%E9$! Xڋj$ԯRBj@ (JH5pׁ:ɃNVmJ#"p*JNu ڥSv&WsK"Bm=j5Oޑqu߃(AJ`2 ẖIYo#RJ,< ZLuj+mY!Yh^&rR!`UљYݠ5Ҥ ag} h1V+g]" !v pIgiI(P|ʿ-W :Ξ+nC;le3sĪCx`ɊxuJaR{{hVT^/XUPRU%H(-o ka+9vҡ a>MۡCo69c*"ӔlGo*#l[+[U TIH &D @ iJJ5 Z-l7A|PF^fk\5H &+ g}qD{{@;ݩ)7IRK`+r$ o!+Cv2sab$tJZU`<9= NH[|l=UICk/0+d2 &> }lf\0VS]Юuvzzf(]f9.G/l(UQ譲ǻ5a$5W%PJhrT۸hu\qTn7~m1#|86:0wja3_SY̳͢ DeD"rFKR-`X^D{@6 }MR2#غhD++tXDh> 诪m#ȑE~ZQ\V;ԻAi|@ŏ E4g MR29E EI X 箧P+9i\|JDք3Wv9\y5h Ѡn%ophOv^/b:&!(gery`>+{4fw~ g~ :G뮎 (jیn.t4'COk|:ZDX>(uk ^=0)$Q%h}i)ACx3/u_xW n<mV[\XP\;o"U' (7Dcw[Ͳ^. ٥ϧ,5%8C\QsqgD* (EգmHB"7tW硄.i[Lt\!?&[k؃Z5s ٞ+YTyno?ڂÕE(j]=++{Rì^#{eIcCZd &FK+{ǧ,.t)jQc ^G8"& z2{ bje *l񳰠~xWVIo޲ګiCX,s4]k>4yOV5w?xѳOeU0[k]ՠX '5fqY\9^IMNN G*z_2/N-|fo44 +Cjg7p1HF_g_ h6 a ): ZTb`ɦ'[F~UeGL]!5ZIN^mv es9%4_N\k;ܲJs7$(JKq5wZۿ\Ñ^4J uv@ˡ>1ғ֭őZS$X!ép/ȱO=;5d伷4m"s6ʢQ8co8 <@1$ѱgNpn'zlߏ|¹+%03㇇+PPյ7jjl-zi:ua0$T_G_{ُ f}=K%D8c]mf B ^yLŕC5Cw4ao(Z0ݞ!b.Inh7;7Ƕ9XIb鋚TYJ|>VZgA"PX=G L,CMqdM}?~}-:Ե845LW [+W=-_:oLPs%rr0kr9 hA ++%2t;@<n{%aH@X!]5ͦnuk=eئԢb[WxEWL[9^FF{3^4ObgF8JKEkofoށ8믿Ԩ AZ` 0]mmG=\,ܨ+N_Up؈Ї[4*N/Z\hc^~Ng6hw5ߡ6:>o>v\c頤I,KsP0VCr~P|\5E.Br<v@Ew2x}EiV'anO륻ӽŭ 5 }443%{}"pj4?0R' ]؈yW{*$f|Zg$m#c-ߞ2-V)cbew ӽcӛXr7d'*Jގ%PZ`baz %RX Зթ8;(64Ԏ|pN+9];611qm yi{+scѶ2 Ķ3NϚchТ{T:Ђ5ȉb>xM9Ek?uYJen##j~82eƇ>xCH6&='q Τ&|xO9'2MӵO9V BiqЂAI4T5dẋj]0:vG$Zܬ3y+eF x_1p=v8K&jjd.ۍ{/e?[b+$Q26%bX*vpbl` 9X;3lVw?j&+׬+*^u>0EWv;De'qwZnw=#2 XtV₴~+- ?QVZ ,X}84 C՛F<\`Z eR(v'^ uz98YhbiX]dzXGȜRrcܒ`*5'NKJ`W_ ? seM橛F|ܬ?Y,i,ئ'^ye`Ff#MB}2GޅغT`&ezZ2,}E"iIK%X߷ U`4拉 L[nqkaC-:!]l&uq—}ac;fJƂ>E~.[hؕN}_ )#ַ CBUg5mkAغTfOgPWCW^מS mƛH4yy&G mKs_X}X2,;Y/Ҏ:1D(Ei~ѮTCVo-h ЂnV4Df}«D\Jf#ƨշ 52XL~} !jAf $Q`rڬv;coqk٣RZv#tLxXʯgbaMOI  W8Tm2aph{GɨYy&HC *~EQc% :B팕~"M7v¹VAҦOK2`1PP#P˩l>[''6N]_FZUZKZ)-<RPwJ-ϴp3Wȣk1پ3MV9E 2\$cYu)nZsݧX, YZt`PNbW}V҅^vF`>2PɀJǴ gl8(zlAm-BS֏B'x@Ɇov[Ờo\m|="hEe(- ꌋnc:Y~*@iZC i9knc@5; `V&OLics!)$BH4pŷipu|ȨZ /8|ڦ^@Foew PV&+?ƞe@ 6B5pbYa!D$1KZ͛4Jl e5F [ꁆgZ"E1 h/LV&Lnn./Ϛgb;u';ͤhoDP0=rxCkBB 5]><3Kx7'$I'- 3jS;śvGگh`p&rTVѲW?J$ُy4J -5יK &jj=#ML껩#<"@+-)Hsdg@v=zh'A ¡V]dBiq4,{\yqVJam8–SF~]u^\rFEXʡr䯰цEcJSPvדF{N /D77B4ƤVC|rGdLdU6rP䯢N{E1Utsy`'!feƑfȪ GpIaeoNB:5xB\   G X{JM4Z"-nLiIC]9<@Ke.V(fQvp,ܦ" Moһ1k+†Z=9a ȸz,gBDfya3w:R_`!a2 @rūPp` xN8(HROT7/J^p(jY2>Z /`\/+PP#@@렗ǴTXY*7uuaxR7x} I&}y^ KBW$}gg!L|4By2nѢQF߄g7\]}գD@i W쎶 zVd'ɤ?mb X)Mþ"NW!7Z_iwFQ_jM-X,w2pvi!WXYgg`,xCȁ G'FWw,R$?!$!^eBNnOEXoG-At7l~6i\fde'?A< Tv'i 8QYvv0 Z0#N{$6-&~KZܨiDK3WZc h^T0Lꦑ_;zl/'*sRo6z!u[^qv}`!iAQ$ق9{v{@sˈ'iO0$Sm-P|mf=:pDKkbF k o .X,ǻL1<c,T:__[T#<]nSBj\u9C&R;\z&HTa9Eh-`b-D[tQj+ii7eiV$mW4cpMtqxWkَ) g{4(/$N>dP+;&}'nY_'ֽ D%":M`bn76<IJtKNir"ef%*K@6$;Y`/r=e)2!HzSQVhیQ*.S,C_nս+bƾsjmsv4Wr 빭1mX*cӚhBbQFW]uOt'J0) 15\H; cbzOn05i?`G'&cVƝRj¶0[ָhƚ5չh|cyR!g=upA!sTY\;flbc-\pM~vʰ"$+gLkq}Jw7DH;r#  ?&S$;vV,h OԎ .WV٫*cMË]+?E0/J]2Xps+MDzt$!H5S~ۧձְp!!_¨W<[[C>-:03Z14MPi9Gp]1m1)} InEfG3?_vu+( HXRʚYԢy12fˈ=6@y.6>턷=od-h q6LlŌ< GFt!!N X,-RcD#˄eB\bWw9l .3oǰQoCd6\}ل)OΚv";Ft?"΍(,gaciB[VbHfZ i,=>]YĴ;`x8m<|R|Nr}647D KxГgh /@Rw*@uK-ޕInISD?X6wS>vzmMCiǀxxrۃ޽B*nXm`3|n2a%IWd7LQIgaS.H'fp؉ 06!9 A[KtA_GM8L;wc{8O A6}܂̾fj bnGj=g^kuD9M3ɺW>udys@tģ`ڊ=J֥\n4mLLIhY3 LE2UT+*HlZWZ^сqfw6A\m~33A Pےp3O^F/Kl "YR T*]0:Gf}|?oMh{/9J/VZ!2 :[A"?+Q:u}Tzԯ+spH7}HZ_U6_ =8/~ѳ^ZFpv n׋=~GSg+BKsEZE5tXq(ZdpH. -,+pICjaC~ z\ \Et2T[QAr,ݙ\eS;ð,@O`?({e4 AB4B)f(%PY'њ#̴BYRniqʟn $*BMg]@~hpgU?NNDp'~<4YBA![F $*Dj18XK8a*)Ð{1W73P\ /;z0ӻ8VXC]",I:$ Y!ZcVQu9+DX0JUlii{&6>WWTسV̬ǡ`p*wPTyQ-:٣w>V?{n_VIuⶹEHV!`2"2_I!(ؽ!+g-Cj3\c[? ,xxpaȇd]T(r_C`ݢw˨f :+CP91O]@zNS~,jh+Q!rWGո+cc%zɰ13ƭDguuQͷRMԥ@?>eMdMN6㙺<W0#BHivV ~7Xh>: ҆U 8O<8'R\5p[p@.U Ka5uoi/ T d8Oٳr` wxzS] ]wc`_3 U'r۽J?rcuzcs ̲ YհEX2f$QTʎBR_izRf aa Jt3ClRrbDl~t4.UXUe:pjmZIx67QG2B\ӫ4D?Lq7 xJxŌEujl 8B\Uþ}C|aP;xZtPDHH\uMXPW['9ʜ +X Mw:_ag2dM1@3vn{j@7iYd gg^ !,[ڰeT3bk]>]T Gu4k5o*IYu47Ko-XmX{9+Id<뷞L…;ՙzH :t0/Bhy[ sG_l?Y}U$9& V9 _&'&Q:g%Id@URo(0g)cļC4tuWb#|pgbHdy3a5=_.j(ML(!DZc9WTe-[,YTwGwBP*~فG2<U =CC%³Mgz30JTG`5SmTM-ucf슌E?) j޶5AXbD/e#LLsMuSmDDOuv.{ŖBMbYZ.4+Fk|WV%TWHWWJ3\Eqt{8]Ttm._wa!Y0.3h IaJaC{EU٬r " [ > 1d.c'E-<V7zszV>X3ۚLf9DwЧ/դ3:-uĻ}E*qOwYePEz*^<սkNSjMjnYmg1EB_u;^Meknf }`V Jyn~H aWJEo~ϢÒ͖hG]1cݟ}%VtX7;º*~r*ƫ5uZy]+yKLB;b!VP$߆)܎ƭC-${ib a9MǼc>}XQ\7Yòp9Xê:, GkVM 14N1w}<^1 ii~ ZXE{^A'5oR!gܠTa}^̰B!QZ՞X PB.)mrk |>r-nsh4_WS3duwFP7SH+}U)ڙZ>9tӏ03eT ݼc2klC#K r˲ǴbMX@[%݇ydjJg9nY }M\\*|9,7sTƯ"{aCЅbPV0VSYEkgƏph`ϲd@M"Oiy7|MY#)+e}HY)+I$I$J~ulȺIENDB`imsprog-1.8.5/IMSProg_programmer/img/ch347_mv_3v3.png000066400000000000000000000466621520775651600222630ustar00rootroot00000000000000PNG  IHDR,)nPLTE   g7Hv~[CjC_ԺɾȽV>]>3o9k6;o<4a7{Ouƕq=}ͺkֈŲJzOlGZOs:RTaO^vzcO{iX{\a).(wY[ѥgV 4a]T~U8J, eSFRR/Z ~5< !F '] ^" ,j@1 $UBZ6,eRcķ&E9{v85#ȼK95 ;@e9dļM}n v/E02m[']J<(wi*XLG 4O:ސiCJ̾rP;/*mWB8j⺮o`W~m\)kVNtGŷ[$:l\nԭCtda0I1*KHXy˿̽LeMADƵS|aSE)v8txg~l_Pw &!T̶roGj\!$!k2]QeVD@~}'GTU0ܬkAz">-08I#ElPgiEZ0LWO>u] !IR412Z UXl =}]eՕcuppP$TWkuql{ 2<$*J]=h;igp3ZYYbLV+% AQz~㆖¶+'/?'V2rB k\o2v7sBT>j. lNJ^p8Z M(o<ҷYZ;<ѣ7=::j>k ]ߪG݈'׶І?@(Gh<{b_u|zrAJ%)҂P ԕy#qW&Z)L}W@߿vsϽHrḼZn?9PEmZ72> n#Og򫜫n㑇>n7׶+c@?oh\=}vp*rvIM+ 2/sϽ}WG<@c)q50002*)|=/AeË6WhsZ!C-q? J@uE{cmWgggWhK[(syG*^de?TQWc'{'o XF}5R@mj.JҲ`bt<X1e6STdit8\~W|]O=7kjļTUxZ<7J ! IJVe);KC{b&o2͗B:1 dr^P,j2d)ˁz)iY,+ed"[q+{BL REv5RX*dlаF!ՕK)$,n.[K]MC}NN`wj83 2m}&(DC߈vHx33ꎡ_.BvUByhtq=5H"BֳVꃮ{[1U:L'[pDxvaGvbqTZV# \B,,I).qo^Q8ϰ J XxCס(+11{@&]Ma j5 U2B`b^`.NH$Ɉ/89kIq;0c{L\ūBF]N'R:\|Z̸y@E0vGj`-8)Ed,K ,Ё+v[s棚z{jLfbnbBZXPgN0TYU\\ƞ#(+C{!.Զ]{aoU)W)b@=Ӊ˻QX)ioEqYxIQ"HM$$a}iW'WǽS侫Ujqv;5,RW(\M?V @M!S,OK544-4)7Cuõ8b)W>acOKomD`R8 5PSxPkbTS̭+OlF2UYZP)V/.3T wG'9҇Vb DJ '!(#R*>e! iZhFYF/ˠ7؝ g00*U49h\-^#EmYmD))Βqg;"I):6_?8fPϷ]v+s*<llw\Öƨ%]Ay q%X(]haR}?l{6.ڭy 0cks'׃T{OFs)%5Cr\+Nbqb5,Jp 1f!Osݦ[\*w;5rH*6caiN~2TUzG_-4O` NAm!Xڷ???uFĽ)LWdfqځ8\rH\y`$>:Pf Ѩ&" -'2.%)'I3*Q؂v}S~lq fQY;\  WQ's<_2+Є Ya$Xfo{:>|#34v4W8[;~{t4p! X_I>*ieX`c57^|>߯8JA ^pfk`:m&@?lJ"a+ÕƝ~뚇cH\DAX/ rLmAk0 U'׃;/p'rcSUBŢ Ȱ S y* qp4,}=uZyC`Eρ,8ԕ/f,1 L9'#2K"da'ɾEҍ mIJ60\%pbN3A+-+GVˋޱN VFhTTCZ0^\ C=0 6gtMg~vمI"(yvP~ S_6AQ)qZ768 i>ǯ57e0l8*o_l8IX?db6+4&Vc6 #- :p/#~B:8.2*[]Aac{@D&RĒ@| 9nd&15+2EȪ,P7Kb$X1qDD45h&ʠ٩)[꯵k@5`Vn,l;R!î.r;f-97 U fp!/T&e? uERUTq5F!A5r)xpfS~)5Xx0pҖAJRѐHzL"*C(-~:Ω7 AʄH+adCqd[ +)*|Yicg#f ;kRvEdzk:l5 0\2ޯuLK"8w r{.|c탡+Bʪ|L|q)X6V偼t^$}SP&);w=(-}ɚHZqp8ZHsN8vUzzl v|+"v@d/?#BtVuUQGΌSu`+,XH%HP"%DCXͦ-UHRI.[i^npO|ߡoAz:̤r0V;Z%$Œv5+ؘ1r{}o%(i3'Y@ "cR*Sr[2ep$lʷH)ɖn7X! g?,C.syVE($68vFSN H$)LqA^Jl:nIHuOYa|PV ,q}䞈hŕSU7b`ޛ'h5Z,rZ|Jc1 DbHtPzyb!$>(g ru˳ |>g$,fEvZ)o*89>bvvm'iE7? *48T2bW`+ hnv8R.`rOpg#ď_1D [~"l(m[Vcsfp<*qlx ;صЪuObh Ǹ'E1_sP|m4*;z0ByFXmm75'aW})nt,(y3)%VGH_%zv\VFP(pvwiM?AXq,xV̀VϟD U$ lP05X|^oWnA>qaw[S@ĠL[Z ;HN^EӭhlfUIWFBQDèDGP#[,$#i|`(&ŠV Ybqܬj/ #Icz V RR+f)V6X\z^v͎%9< pg۲,$(>zd{43pT:28&bcI|8&֮҃"'NRT4 28 ,8/EXL^! O 3RYǑiUhTʭL1FS[ +{@Ua{̪gVU4#7]p8>k KDm- ͺř'3 tu $HA#pRh5r+FY _vm!+s>YݫU}C5=G/H1SXmӽř5m3Y%dX񨾊 R(~?K4geښ ޮ/kmI?Aj TŅ%]\䠲w/h~]}r/bJMGrrVU  RTXmQ E$x7]ed΅`ʰa'Zj~}o^;>G[ 4TOq8:!#%Rw\ebLh z$@˫EYa*j :pϟ]߫<1QI.~<,S𼐱?K}\؃Y:'ZRbW]$|Zge3ܹƶa "!!|WTJӜaҹT6 ZQ,XŴT;nLc0lV]-E]l ꖹ'ϭ~ޞяZ5Y%q+hZ%jW;EB&1t+hئ^򓂖QdE^ɯT=`%-eTD>d5MkX纉ZV]TcW]ble5A=/،Jr)ɿesV֣qkWԱ6d7bw`bJd]p:'-8]-vջ6faY6%rhӊѰhE6];oڲnV*W} 7\V+p"jnJ7!1`XZ쪿pdz7y(Ғ?pHBE^|CǬRqV:8kAfODLەJvbW|,ٕ*tw9ViA\uDrۉd'*kW<71m` e#FVǮa+EdZp؂EαDWhAʩbY[/h  q䊫W}};S0pq`W`EZpڛgsX͕Y-(:1܂2f%-^0#``~>ؘQy`Eq8aOvCͧxUYmڄw RRý|!jVlEoVL⍂TF%qĺ/ ςqipt%Ў"-IWrJL *]B 5JX4z㕺b(kV8Xu WADj+ܹG vrVseV1tJ-8-{y7wU$Z`kK}K"D^/l9  pL+0V);ŽAl۹ ~+UbWشbtaE^nvi2- rhuiBFn@U1g#_WW+M -NX]"vBWJ++!1ǘYj+W,.V0|'*kkKvܹW%Ʌ ,EVZϡ,KqI, }jZ:*,ԫۏNiԪTuyĵLȊY]IvZPŢGx1re5deP8hϸwxZ4? WA>|u#cPiM_Hۭ_R9m-wvJWn]V;aW VtǠ`SvEZBfk寍jflh2Ul64 [T֝?~>nN,&T,MtD,=>b FpJib[Pd}LX]meҐq ^3pF[2ϚJ%fjXf҆hZC+}`VNZ LomUv*SWN%FJ-v5Uq3rp e2~lF5[N]o2 z}PHhV%h\DV7n͚uc8Gzf)qqqQc7G[ f+*BkO1P! - V=VxKv%'iCeq÷n#}@kdl^Bf__p3cMakpI e0S X;}@4ROKlAa‘Y-R(4֕1!AH_eN0Hi̘ΨvdTZv2-e*mm F$EKb33oܞ߷.=XG^qǂlnz>vN AU Tu z ׃P,xK9Ʀu֓?|Vf9κ^y֯E\6-k]bu3AZF:|(>kj#s&1Wc*ZLfmBE2ɲlZo<8~_`e˶owZEWq1|`%}=j7#3emԱ^9vثSx qX6)gMnn>ߞ%!Y$πtX;u"~6+GeE@ĕjQ{=PAV(rre(fFKHP(7qv(A!)z?haU<Թ e-wa*z8qu2l[*AQ4o* lRV#w#!Eja5n$UR%0GYAkWTRW-Z`u hw5cnu#Oбhk)j%:mja"}gP24҂E-Zo\6%d-[גfW"c7Z^LJ0Z-TVw/Y.bc_Q[b}s$zSɀ>X,ޱV'M94'1adzObXVh&,ii"%} eû~uHA7Bu6. YauZ4D{$ZnZz׻8աҹPx[]{i\ ?hDS]4m3V[?ZR l F}?o{ˆSAт,THbϙ'8 >#Qe${` =Mmn׫uMX,hB,4)h:P Y]?; / ьkY I/0xnnW]w=7 :y[6HB luu9av4jfəj|B72' [a-řq*ZHD$ƃvDǠ-zq%)Bj=H{{ d#15J,]X  E1 6aMw>O_Ƈ裿z7X`s<k;/Vh_Ӯy/Ipm,K7}EiK<Lr bH\%K )2*P,"^PCEϼp>7XoZlV_x2kw ~j^@J0V!(f:0b6e9*`ų`} JhA$Z XİAqEH[6"ߊ#?h=,zϼbZWd3WPd 2 /l5&-VgfrAUbڬ\BiZJ%%Ob\KP¾P2TϫʦEVӳG$cY_ݷ_W;U # pe*sۣ(CPEzNznGIBogG۶ ?iZ+J%JjAXˏ 0\tt(^ ֻ6+g& Vv Wk]iO8R4bu,^g! &dydgxx@%Wi57,I+:ZtA,'Dg)걯+4:|V 68p?fiVT3@ L]4L<Sj8f.i,494M$-Eg5yW(U?͌j$m- %0`}*Nh}g8H ՚tW(- <`ӣZ|JxY1&F)(X"${Q[x4i 6dC!1i~~=ʎ+VOǰa&[iV=o]i׍ 3ix<'Rl# Hw?xG*C*%U`QX"A 3c_r exǛO}%B b|E܏vj"(Z%x,?˅v'!r;>> $|T 2Hj-M%m!Rkg( ?M$вz,}E\9֤cVOk9V5 6xMe%d]6ӑ.!Tbx\} K S,sC(IQ}qj%~VLS=ֵ6+'PX:x"aB ΫJ54[֊ogi^E!rYh֖Z.ͷѧSI:/(ib`kR2vV8)R.1Ho4zϴA+7ZºbuC+'۟\BVJZ/Tย ,|rΥ"hqb+qA_8kEDHBĒH,a X|XW^_o3>}Yv{r-J`.au>}¬کleA(L 5s'1E% tgfy"`NoO蠀qU+\rh1Kw9˥iݺOv)V'k"?8;qv%eÊnm Lu̲lbi ՘Ht)qݾo)46NfE~XM~*XK{=|=`n{x9()ZJa^G|sD tpZhfbZEUiM*mj2 8R TiV ib;H:?feVcI\qOܰ}H_ot2A6nyr68hф|n>>`œ!Xtf9Վy4|=6" x;ωHsD+΋};/ڌVhP@E&I27N''m JpKhlo5󾳏?,.}ja ;<_cUӹDHتx;CdhSqYie鳱H2Xi>{Á0.-/{5(AXaEOꮛF(\Qdpo'KjZSF`VSp@QA܏,~_`4턃aśmNFhj}fJp .iٸοmMXgP5Ts.3Yͭ(M@FfD])Nf(6uhZN&`)N,V+QxƎ3feHX˕|`Š ?qekAY(ܡB(\pR0qJq[q)iMD h4 XAˑbFCK\sKo-_y8'!ߧAqeCJ CBUIۭblR :u,1k*NRRk!ޕ4߱7Xh׫%h.6Xժ,a61ӹk1T*Zʣv,kL圸 -rT~޳Z4о~ 68g;nƚY6dӨ*ƔfGN_h9qhŋR@ D!vmա8VH` 'B.qB54`(L2~tSвC]\%_T[4D"TFt3PVg0C دn~ܨK`t5)#5 VG~ݞGAwV{h4c[49Nmm2v"C1^t\x 1P2*r FiH O1Vitv. %ʠڼZ֞GQ\--߷2^⤱1ozn1ʹ'.lŎ|A jE1PJ0='5N>ZAD\ BPw_UGK\}ܞiWSUlp\{uTX JZtH$y!A :=q%T D[w$MD)r|.knle6ptH1j_|=an1OAiJgT+JȢ'v+5#Ucou׈5;>7n th߱B>].\>`fӛ½H^DӥYOL3<C3F!.%_*Qˉ1Cgqgs"CFюn0ct vu@*Dm'66pimMw1ɛqnu1X]7i%&Sh ob &FJ-9LNqJѲC0>Xs}y?~BKrVH tJ>>.#:zΉSNAt*Wx5ϊ)K/gbcdK2LDbD6['0 fj5چIrn] ÃQ|pY%T:?w#{DCh9K\w&~Gɐ6R NdSSҽBVqox/«pYckǭ DQy!1.ig19`>IIRiǚJQuV 9k Gaw&47O֗3hLQGb_$}я$ O˝YEskAl%GuĮVV>iJ1WunV/l٧q+Xu]NSȾd},p8\I&?gVFMy(9N h"f5vW4@j1 U(LY`NJfItf;WKǟ&F-bHIf9@Nxl25 -NNVjWI DZ2uv FD|:ho6sBΜXV’|"}4=dM!Ϲ}4!%Xap>eXѫzhMvoq>6R8ev{_BS4fcj}Ԛ.|P70.>/Ji 8өQ+籹f:ƚB:B&54Ci2Il 4\R3ЧhThQ\TRl-Z-n3W. rYuŤ.K* cJ+YJ5N)ÒHLܻ~3 V~m!<R^sdqZ99u4z F3U׻)p3kl4sEߒW7Q'B{\`X+o"~[J ؐ[bw]`cT)e33iAk֤7Nɒ*B.2wwÎޥ@kE3Ȳ>_eL(ؘ G>_` ۢ%WSJX- >EElUJ>VDdŐ5/uQ3QؐUd5U/gw_ a!/h!U$[i\!E J3}]?-2}ROqkg(tߦXA~V 'nl$늪vr/W s[i#@zݶgpw9,4&eTX򈩸0; vU"v}հ`-?`+įtOwTJ 3P˨ DpPqZgD}&KB;x2YN(`hB+݌ k'Ͼ#qdl.w) !uGq^,1ߗ8?,~WP^:mn?eKE^p#wחv/|ؗ+ހv{v"[_!I(*n:ʼne7@5c\i:RPgeqxzƎ+ER7b8]jH› Gv6‘p`k+XGˏ-"q`EKFv"Vdg/Ɵ XMuw=$FZY ljEȲU1N'?Φe]p;鎯l0y ־E`{`/C Z/F/sXA᭍Fhgoͭ %z~H:Z_\$ERf} ޮHyĕ(s +}Z}&;TbX* 9,mcoa!H6ORH+*p4wEV>),GVqe%CIŲ}0 !o + ^U4zUcΊªW_^5t27VggW.Zҁ?$vuiîM=gh-!_Hc u V;;\ +H^-KWgS+*ziV/v%fB .-d4SSGqBX{8l̦qȴEi~k$"+ϱ,u0I^#:Ձ^Rɿƒ),z^'V'+Ȯ aEBf6_*TE&Iz5ׂ_ 0`MFC!VޣBE Vof{Gi]Ձ*h빇ԯ//mvD˷-JGcG؈d K 3>9,x[ u<Q$ɤM[]+?7X1nRͫ \P R~k29+]¶8Nq +TW+bX{.V AvGbrr=L }5~o?XI1IΪ_X-m Z] BBE A^*?_;c0w8Il~ Eš[CBӢCͩ`DG~~GMΓkL5JyRO=_jx7ڿjUc6&G^/y^Gݞ 2?l[rD46W%bU厰 Cʺ=V(Z10C);x#;iR<>C>*4C™((x&/ٹ#KQIENDB`imsprog-1.8.5/IMSProg_programmer/img/ch347_spi_18_wson.png000066400000000000000000000571311520775651600233100ustar00rootroot00000000000000PNG  IHDR,)nPLTELsǿ h6ٶˬQlgۦןȹwƽXu@b{]ՏmEhuOrNcpƸhSBkS@l>Qt@a5J*]Ρ}^&ph'b>U{G%R=xZ@U70,{vz\BTFbIxX'zR2(%Yh6eP8cA:f6wOofdOQdU$LLYP@1Zfsg `Vʁ9K=ωvxU.nHu\m7%qI~tuqƳiѢcĹ61/1XA:d{˧yopzz)U{h5rijʧbQ~?:tVYJ@m[N@mG-D5MCŽ %""Of΄{gU]m'҉h~jZ8L@9D4)ʺy=b&5*_[]F *qvr[t]͸l] 8 и{f?˷yXx:;>R4M62ƹlS0ԬonwP/dQH̻҄tj&lE칱^Sw \FHI[$R{kfb4Ih}^kmNF"/jL:w zw`IhIs4w6tRNStUR iP>?_߼fZMv`EZQY:eb<&ޘ7אf0ž}'*Pt -^ ٣MfϦmtct2ݫ1rC&0\b` TFg"PDG6_?}nkjݵ<(`K/8u8WwWgW'2VقLG/f2AUZn|wmm>kodtj,֐qkQKn|jI41dN+zq_X%X;Sߴl5? 475?Ub)-MPHidBxgeP*5BIp]|KՋM_?ux) PͶ:[!G׎/r8PkjWp,-Yb UO]|5_^w 󻞛/ kN f[ZEm Ak.s?_@ (,8)b^V# W I4諅lK.5:-^qo>i:K[o)b傱 ARp퓢`o՟W-*:]Qꋮ3l>Ϝ7zM~ R%A歷E ÒR^c5b$˫0Ccy몿TgL6`~v2ٲ B}VTLsssPyG Y ,:h$ij²U,R*2D7D{5CVfoo$PJjIN'^ާR l!& UTO.XEVhUgX3^h.?m!Wlk$:|jMʴsfF Ya'p-Ji=(AQɟ"eV}p}Z"PlUԶ0W3dU Z@*qH/H D+`+@"B  -j. FM@S0"3. lD0!Z@#1bC\-[T3WQ~ ܲ*͘c0=}.ddS+&ց$+CVSx !9~jEVb2- tER_mu"U&â{B|:!.& \ZIv h`ykH/lKNL SRmȢѺfTUiR#M&顡O&O#E-]}1HN"BFDfx0Ќ#V%;ҁCg!܁yʃUvo7\̀E@j!{mKJz@Y6vz O$Jzk.H<%O+ %Z*' ՘۟4yP`5B6jn:y>>U9P-OG-UW`͢e-3oYDҊ,~QqoU>n٨d՚lZ `*|6}S͞7o?0/cްLEso0Ki h ++z[^4!mE/,^)㨇hŷ!mj+"Lnk᪶|?osz?9FasZ-/)'PUji9 ףQo_ґ 2Ɖp›_ϡ0&ww۷6jc^kCm}n٦祽r ~TEZ.8>0)5|AG;&G|RENJգpu9rھЂJm2nww}}oq|2gݼi3_hyȁ-&NKF ML={1Tt}ZZ*OjX!pZoB@ָ AoۺkM0 *B̌+7qzƄpb^lcㇴQo N QP+i( :)rb}e/mEq!uM_rх<>~-XAv߰s}QT |`X=>?Pэr`%{ WDzGJ;fHOݽ D1[L.}"[_y%wRjm,:Ps}ZHzҍfT$ ?rߜ|;H7Q &ZBAh3`ज़sXֱLV7w!P;JEwv68jp8Z3P>B04H!6_!-x"7S͡RŁ@qZJoԟ/?P"*"GH#p-h]$XWIFh b%`S5OfCSXCkf#Jehy|iY5>h.9,` 쮢sB1ևuѾB)'L&qeQnYKw_AC NkFYl|D̉d#JeYF FeX2#X-,oTpB;aĢBǸ,(B~ÔX{Mk⠡ premQ~C4x3x j "F[*et6llh{Qz}g%Rg~oFX-`qX?}ľ(ơHޑ4Jybx/jr[_[?BLT.xyl}:7lj b"\n %W!(uRzA21TՈJd:DRl oEd|u5Xu;ƙrU1TlaD&jgT D&bzF?⭽#ĵn<PqXcSaݔ``ĚZ=Qerc~X݉)U"hyG'`2P FS ֈg's  y}h ia&bkhZ22 j\)2ZhTVp)+ƳgV &$ Jm% O1 qVn{6jMWEGqVsWT\Rnn/E}N؂OY@?&hlW*AShnS Yt_[wg97g6*帲jBl+*D?OԖ]]ԮznaK֩uLa>wACTJhyUҋa paW#J$[zF-8,nCYP[V!8K@TU-T"hmoׂ(h=hַUB@i$|/RP4*LR}&X5{,Oz58 {@ˋÐFO3=aO@d&>7n?[UeS! CKh%toCWù55ea3 | +*@x$ ւڟ.,TrZK#C#:VrT3hMAiŷtxp)BŀIgz bVX$Tgg 1V( ;*ReUK8s. 0\D }"vkjjh A.HuIaoT2"s&4sVVieFvNU xu)z1r@Rűwb3' ADVO*RX o' &X5A-'Mkhk+k) `-wLV , UIEfWG@~ǵ:?G(ZEFfc7+fI[,q#{Deg t k j5laͅY`Zbm}}A݃a``ى=X>U%|_w`C2߷!ZӲ'W:mЋ Vng<; {~~~54R:bA-Zf୕;+ S4F+]*5N(Lz*xm0k'O1цge>,>| ľzsЉXkRJ-D|gZ͍FM־PcQ/QGY}0lǼ7*o[cw[+[0nriDю˚1<(LɫoH"X=okFVa >mBygQ6s>wwb֚}@-+:m6,bmB<.4f_z99GFffV"1вt.zs~EFf1# Gz,w\ݩՑ \6קG}2?{`^֣Ņ (GFNJy검 ZFZAј_*•Pk'D€5Sb]gL%(gDF% %Ē 5zk٪I ` v)=9:/<\G(CZOPMX?O*a}}!Z 8kc#XLVIKr,bo8J[W;(B _U8$>!L+,0Q||'ez){R^ZP,g| TqHq_xh%-c41FlԩS-tmRԭٮЮX&51č]F|ߴ蛠^Ͳ?sof~d 2Wո/t= uF 0Ӄ̑`6AU٘&`Pn\h aۚ %#f SHbwn  Ѯ_|9L ygC]I-=_%Y)π k]]KNŐyրR YeY ~`*rD`U~К,J\|hQF[V _k `\Vjsp@k.gO ~΀[7X! _V~`mi))똇A\:'7PZ$e^@<2z63龉؞g9Yh! Eۊ*[Bft64YTK?:E@_zҠ@ ^ V =/v*J[^0ZrZ右JGx  }bWDb01n+wzىێfˑ?j ǀk׏_vBd(,> W-QFyA4*YbdխOǶ~֋Oϼ9Xm_-"`ՔrR*zD}?BiU@ 4IV" C Z7}x~잉@-Ϝ_6H$bB/x|= jEưHqX>&"hv3phNkh݂?b ׯڃx{1 Z[9-ub▟/xLLfrӳlBa` ^XCLr2'(i+I0u$氯aEy2 s3-_ ZNDTc6Wy=0F"γ:kZ(i2hQ8EUE3ӋPNȴ^r ƫXСTdT!B%0'p='Qì*w~,l-Zq ߪo}رOgo_n "͎d2JcNH7 <:[ĖSܰ aHEVib KR38<`* 80lRע?̅ja-X1@DVk;ͼo+=*,:?hi# Pm loem-a`Wf߷^uljVђ˺R)t ) "mɆ,7l_#Z8[ '[$7l{CYɵŠKT :V%ڵ{LӂVAm-hLmbh--4ܜY[U5Bϣے+%JU+dTK~>J( ;5<ϬiZ.E\N\wA):.*tȋ.B8~䑏ޛyoÕge>;WkTVEtD - Z↉q;ەȲո mQl VBAPPl N43 l>ā[TUEHRxV~R\,J+Mcs)LRa< mu&h 1\>hin7Ċg" lV Z.A#P~9T3-yKu<29y.ôԐd1 Ki};&cD.ښ#',h6TĶkCV5o=>55u~~ G%am3@ |L[aᢁ=D,T680KM2Le[+kV9 ngmكoz V-}L:^vFwl=]_-\]ڻ?Ey1khqXNJX5Ih`ȷhؔ 9)"@ {+-"s%0R*h Lr\pN*kpq"XC_PRqˉ~xť-^ž>ׇ;~b/q3hY1VXdZD %¢X#%e3U=1Mľ]"$eb2u]55Q5M-Qx6{hϳUxTX tڛ栩rDAVEoF/Vo'HQtBZ<+f ˯^ ]m'$QK-^omV%0 Ơ aw}n`C%*E6|FWW;MBDFY99/Ͱp."HjEJ%½a;k/}bop ?'ZK @KT;D%m=ސ@){(leѺ񣷿>4;˾yIΊh|NDa7>XW-+dFH PlV&]-DYIUH5}d;'VRo!'"EZe./GMBeKkQv1ZEqda &Vqu(Ph&EP苑p*$PX؉ [S\tX;piן:ؙR~Xr2n[\[hZ\΄8 zZBE4#% [N+$m5d}V ,EsJ1hKl>SY786Ĕ5Xh=rv )rζmckBFsh с}q]'Zugץ"IJ!jn @kq@5⸠(ήU+,4P?mjdz5%owŅ']sNuqZ<=2ZJv0r+5[y>R9§J2};'{j+|Y7( I3ʳ;* ˣ`6}+m o\yNj2`9"eS P]WN3.8.;cw;D{q\%BW'Rz@1 N+-ۥXACB %bof ص`L \k|E,Rh S-,AT:t(U #Y>聤zzC6^kUV DK?uyCIu ]P E7dy*[v,NMpDTC=pZs.SeEd>xGi@K])\V܈#Dz)_jI1-BPXB#/`2A9$pY[ӳ3j5FGyF][`ANBH`F7'aY"Z 쭢dpaAW~o0798LfNx+략& WWbDEڲ :_3 u"͗7zβ-dH  Z [!*xL)K2ihID+dcXQӘvkLQ w1H^raP)`clq= [ZC^-VC3{:a|Z\ZrMDӢ'2Q3eDU)(XRʫ*ʠFsAFm̊WWKv0ѣPN!j,w]#\RJ ~ah޼X%bXCޝF Mr"mME[0X)o䅲bcdQ0[F-zzqht~n- u<,̢u5E1.]6ktp$Q'ʌ5b'%[ou{O ZCMAʭCq'5>-͐ehq!Oώ?ME(yq#C(BzWK99Ѧ Gd)JLfg?2B߄]t 67>M |In_I[U-UT9 FZU=sb!vuui9xm5AK t]Ll$_Up/ɪ PeT(P' mF$tqQq&eWlZi ٣G?! ۲8uew=<#: CVmTWwXQ0 R,`QmTMjʹ8,J+iMzr-в6g+X9 J|fbid*$ҁ_E}%=8nc:ʴ\w.fU{EiBVaqk': k/YqZtӂk.h5V!LNR0ua;yxU8<(Ɋ]@ D+AO JA^hĥZnR`jfjjG.#ʹ\&AV3-*1ނ"FQ ErG<lsn ֝siz!W)hrDJK+j Ya; 㵻eʮi]Z XnzHk3wLԌTDrenždX*:h!gEѠc*CfDNj]bk##zfNFsA-ZU?" B2樚'Vx*&+ mVYT8* |+G/yux԰ -rhLa\ RJP1=uȊ=p d+"-2Ίde)~g뫕ͷ+N=Sfl|ʭo-qY1<,n7ZEq `Ɔz= /8.G[Ii69V-k amHcZiȀꊚڛi{%rZ0-.$E[iNŠq1Xk `z{݁kpViKWeF`!tFE E.﹏eb4 e3 )sw4dE2㸐cCtAtN+XX vQXM~ۅ@ :ˊӊ8DkT@8ūVѰ]em/c/]h#!J+,qV:*,q-M;S`h}}K QpaqVYŴYa|7ʛ. MM4SqR1V) s $˚B XۤFCm &) XB6B" W q1wèEy{{wi{?Dho,Νˈh1h`y\M=rC"25eEyg NCW~Ij ׯVe\<Zrs!ghDzX*H+YrAh?UٜZ/Q*}zK'0`)hUUL,I>~ed%[pj]2NA8Z(1, c÷Bs$#'1 ՙq%ץԧլx+~v<().|ˡG]VL01.NJ *%yģV=hl.HlhYzKd'_ޒXuW*]U]E%X))|C[ۻdkx 1,FOJc XL"PRYYOW:i =yU  [B6\qGP.i=Xj @ tj/9Y9L!1PփjZ+cZ3\tpheX[_o9gċ16 *)pI_^"o ]=UǴxKdGmI>^LcSsd6+Wَ;N5^tܞTE^v u2tp:s3[{j񘚈eb+7hʘXͬșrŌ7ƪFQW"+ދ"Vω+tW\ rfU NOOݾ[ii%t>̼GXtpL6fuf)LU4Z8HI#g!|vcs1*fsCf6JR7AL.E)YqdkgAʭݕ%U1W?AQfm`)Dsd%jyCbTNӉ ,'?߆fm|sGO\s>o}(0!c +Zvw;G Sr G O[HL -R]oK2ZUl >FX_C *t>yH[9DKkђR%sLvp7ɴ*JDi SQ ί\S>7`7fj;I_6ģQi2-֛K<WȰVVӭ'Of[s=t\ҭhJk, \#dӉ hޒJb>c[(AIY4D3& zR[qKؑX7<ۍ4 JVARvuccrCuZ48zd2QRqKG;~(evmv\Ub,m1".A;߈޺>|sq7t}#iA-ɺbTp`DQ13f%Eteci #y"Zc1.%qפkccCSD4x=Be/ahm-˨VыK[1*|K[]@͟Ѵl+¸Lu`'B5y" ՝K-LN,, /|uVMT"IoEӇw}"êA`9Kg-i4mՎ@7@q5)v`:iozqibhadjfrмsP'K?6jvr~6`҅hTVJkg66oCi ͼ7^2m,p-M}գ)-qXձ7.[<m)iQ,ѕIb_ч:q}.^9 3(a[ѥuwh 44-;Y߾s}碏:i؏U_5y';gA7+/ї{8L ZԦ%mU$Y\9=WS?`}D4ۢ[zx}b}¬ߍliOgCCO$~GGMYQ%-vN$+% 1MSWXi \Q;؈R..OMMv.,/@%/ڗ| w[sn_7S+_geZ^ <ŕeːbV-AO1&Jj`EҒt}-z1&¼c-H3䟷9mI 5Zq5_#[i%`%+ٷ.HVj\bZeaZ+BժMhBu n%8 CU(Z_-]]uVGv:egq\q0+GodvTV`v-&XAjgqvub946M\Cl-L$Mvw~վ/oMx:&Vv[WPp/Z@s6C<5Բ,#.%>h RrqqjZzH[Jq﮾^ڇ¬o?;O@rIZ0l_2(!]UT˨E>H1zB!{```ݻ_mox;|{}M >숳P"p{nmZ"偌Ŭ,2`%(AW޿6Ÿ2FZӃXt8ovpemo_W{vc}~v*͉M>7y7ě@nb;ZbӇభ:d4VTvY z6`E3QvgmYvVVҗ"Qn]1J[dѮUix"XPcΈ30p~j}!F·~Ookuv'/)߂Bв1-ĐuWh=˴heqwcOo<xRY{E;8`?\x҅7Trh(NkQD1Ɨ@ _ڋJ/ 3{7hi-"]Z[4touҘT_ln7B!Zbi%HvaIλ1Qݑl!̭. j4r2Baf=w>v^#: f|L h+P#J)+eV0 z3LVb\69yHp D~ *R½JsQXCqOICPGLO)edfCjrW4s ZZb:!w;Gxq(AC /YCCʮv~/{qQaKfBS0G%~(4\4D򀥍]A?Pv^=AVХXw|^zkU :B.ǦrMsqw)E'r7Z TZ u 5-ziwqןYMd]b(? {NTdśJzTȥZF4sl/2;ޜ} :]Yݺ 7HoyNܣ.d8QWE ~]!:)UZt\A4C)o'&ѓxFr[>kXvge%˅GhUZ=zvtj@_% Rϰe08T:㢰VHʅ/dRz@9UY -McL^Ţ%newVpWQNRJPtPf9@)jkx*0 Y:XDm/ȏh@KGR*%8돗|8@=lM&&WBw3}JԂXOKk |(AxF mW3Ņ? NXO5ҙKa҈)7u|'>< ~܃ Nԇ'"H(06? 9a30\N%ʣ<[K&KKX1HBf;~X_RQ@ҏ*, ͅlm ZcyJ³SLɕ֓238e8>,0g;]?f^H+.L  %%*hX,29T!"˭= tlcilۉ⮷|S8j1,ykB?x zK/,׸wJå"5|m-i {cd IMS|D*J;1X+n~RUav^2/5._th~:TZZn/fr9KD~ɇ>v4^Ot+R{zA 2h{֓oK <#X%(('H CSw-̇+Y:P. 5IB\hMM0߱2֏߿{j4*G%.vmeXݰ%=TPEgX#z'sXR(9B0}Mnb6Q~2&s&f||ᮎLf؍~;Vaa'&{^{,ŀ0 vGYQV>H:++ XKp7)R2U9bfXƎ"WSѐB7Ű狄~ XO0 c٬ [:,= >C嗚͌dc Fc3?-AװKUsח{rRwkx_*r)ʈdg*lbM(`2Z }qQ6%4`7 RHilVun0ٌD$RQsGz$]W0SPKc% BMȲr!VNkutnyLTO[VXe rigsbWO=`aZ{(`(ydWX h*z8U`>ɲE&P\HbjY9Wא[\񧍟a% /833)tX>`W!QvƵx T5 V)&δUN9tR֒RA$=e!]LW֟]][2/Db\hYUQ,d$Gm?G+>>||Xb'^Jk`,=1zXQwb @iꡨ6Jx')'kBz!]\[ >9;ŵK3iX}a)\jadbڬ6}džUͲke:P060ͨ,=¡;r4$Xe$,m\[]|o*W11D| $LjDz{kJkhgBdڝH#t)ӥ!iBi R<'h*3r`J\Dž/)" ab2`c>P-(YcC@r =R .Z#]Aޓbئzm~?/ŵg|+ݥ|5!HqX=p'EZ7,ZA-'4E(h s kӳ}#v#F >ZorQa k`^@X~Z&,/"WPfLA HJkt>>s`9bV!/me8;$T(=`\=ZL)Lb D(x\^,fY@?)N=Ԕ:z) 1 nHpqA"/lq+BܻCXE"jU',Hacvc79Ƴ>EVt/ᤐۋD>Y7WbD;O7#aNB&xҤ~~ Xqéը4FQ㯄k*bEMr=T O-S!VgF>J"z;MGV4pR&SX!;  f||C'4[)=TV.5vk['zG zj{&Vnm0hQDj[ m 6pzFb<Ӌ4ò]b4_2h`pZ+QDݫK\ZQj1yd>CO7.&I/Fz&5`42fbV,#%~ `kTeY+ %-Bg멢˖JB}st;ֈp롴ct^mp븰JAh+)zɁ>i,}|ysl<$ yjP$j'-_TXQL&+DŽS`1 fKE\%?]®Ӂ}'+qYUXA۫U6I }.Cm2S=+*yNƸnʼn3v ᐸf~TUj=!CM}Lf} oXv3\Ch4qbNW̩BQc<Ffl4{ˎ202]t,[pzJU1xuu:q$';<Xnc'/*-9g\taxl' Q酡 a F8/s4JSm"~7\#|6_<.TI J 7t14 (l!ʾN{tuUpd: x$gEeQ'qe_"Vp; jl*炒Ĕhmr-,Lt]qpQgN)SPFOAYeчƇ-EYkj V$e rm*8k>$reӞO. ND-jN{AF:thd4uq!p(~_!/pUa "֝t7FUN()5 &T,&_G\<15~k˥t|Cn>1Tvms#{'W+*/WT$1T^tyR'*8O-<OeF݀ ![8+GzRrIӦE6m%L,ʽPDY6Ni<˒J9td42gd5Wo#udO. BR,IT:l=O19blB&f^8G; ^UN+WkG5vmkLW);mb5yPxbaùG.B3 +##V|mK 304+&cBUKlƺ5WUٷs`n?h9&!Ϳ= #?qM"JD?5au5kJZ%w3`z%`F|]ZzaS4kcJ91AmUlJsļjTH{N}Ŋ`wgtPa[LG)U;÷֌gnrl^Z741sOjİXA;Ʊutn=TBuObqr5XS4x^GbXkH{tWzK)1e2s9tRNSC%%79^PZqooۅw]ׅ֯Ű~õw=]xIDATx/O@;yY'*LijY$j*qnE/!BL f@ 6: }L`GO*y2wڮb +5.t|F3؅V1ءgeI=ZV0T 6}xo=I3Z~YM6B ߾+\JuPXJ}jda,di"C$S.&mk,[P$Z'jo҄fǺ 0ᙱZޖu*z|yn%eEQVcE*Z}3td!Z]yH^QcJ?bߞow΢nhWܻ׭dӊa~SV~PgIqW%fP0$b@B3 ]/Ρa18i8ʼnjDː\̑ Lk-km@ BEۺߨ(t<񜫇лghT3+ją$։6o.Cɽ.\5ر= VfYX]vǛHU_VwyʽnK>MGP]0N my^ luEԉ7ADbU 0 p6Wi2$ײ M}Tȉ|ZeA9X\h $ƌ>k|7GQ%]U}eejr bPx&/S$ISGPh|j0`f25*>X W-U]`]/A$ ;}8'8*,҉ߕ[W:;ZAPPba{PC!u[]R8+th?<K r|벞MgGeLAN7n])D$8&N+o'GclZU+DB+grLۍ׫/l=¯D7{%aU%h-si3}*iJ& {KLf~׻zup` \RG, :/rܵeeaD(V"~ݰV39`7ޮ"z [idN>ؾdrkRYSYٳmw3N#s|xlՀ}s&lEltJF;waݺWi ͯx#*Rk+CKw^IV7E. |jzOl*9-IbP `ݹ-w=Q5o.6aXch[Uk4+kOKE6*﾿U^$ZW^k[!rV@[ CS8,,),w7콽ۻPFbU )dÇXlP=;L>G[pZP=FQ "Pxӿ7 ;"I& }`*|F,1w44>ȨG:Rc3`2xkrXi*kH_<[+)'V$EX-tY(<?Pg=%;$ojޝݍ[j`ib0N4Ċh)Q~67|*@01[U,&,.F,xk׶}gQH>y!Ī]*J i--;4x)?׼ԪqP⤈AscTZ/2X4X<辁fg,2y -s[DV:g·l%t$={$j(v{Zm- Jj\ì ff9B+ٙ[4mE `-[`b$ZҗrPҒzV(BXI띲(К@Fvv0J۵_)ڊsh$z;e]! X# ^ (TW(-;\[W-yAn-SL4*RONL@Ą'@(ADhīǏ9д%K)"V(x7An|`9/+τ"DŽ_!y! }GټNx_?3VCNDS~ʕ5 =raˣOG7h%3_kjjG7%7tSf%HX'}bϻŴYaX=k4$&z&zP X~KA fݾ~K- iҮ?5 !HZZ$H#eDܘ,~-Is~~^m{n{#Ťo|ЃT!E;J#JX,돰Z}k"ୋPiV(AWYI=XvFk ==._Ar>'6 ֓ڜ) !HzA(,-_R*H@+joէTr3Q\nܮ ۫խhJkt:;,Q(`)L)gSAx cl^CbG P9]FSXXM>YDxٝ+Ntcx<:>ޞg«AD[A~&1<`>hy^ nb"gUvH^I)+uG`+^|ֵ֑U%AoL-0SO`u8 -Ŏm40,9y+⸨<;)1<+q,8{!bq 7S笧ѭ0/P__J& V}>xfAZ} 1!YxV,Z޲N⩊Lh'ԡ _<<`d$X4MC\ V  NjP[V⮕ ]86"ާξlzE2wn99R۷X,VwQU/^iK%%ҜkxJFrUPJMG'0P\2-ss6PZ<QAJkVR LFP퍠uďުը,{UPbH]~>ƚ"Us eGgf#>Wz؝0iNX"ViXogk  5:^4-ڏTli{~Ƙ#-TjT9{\j+- nZa؊?\x OInPй~EҐ\;:A ]D 7[)4|XՑNQޏ&77cqXcG*R8 :C@zX N+}#V<iL|@=ipd=;};D-dWHr74XᡡNhNɄ59yg|x٦#\TNTlџC}jX W:i;m\1-V`o9|ArttpF2IMx+ԓ3lLZpE%&{x(jThkW*m"AMTځL.ǎg*mԊNTbJ ThUc|e4XR*=yx-I44?WekĪnbh -VW"pj|7Zd  fRVVr|gZZ9<]3aea^-G_Oeܯk#l V[x(KeV7ѪpB&2"b>Tb4âWkǃ+MqQ{bbǍ&NZR _IZJ +*K\䄣xK|6KAOKЭ[nw{[^{)mZ GF47,8t+_NZ KJ*ԣF7FG76FE-uoO'!F"}8ӏ˃i%!YM0lc)Dcqq &\ _+`ݚzQ'y0sY9"z5-޸`vS:rA4_E]gD7rZ7LRbb9TU{{#,bQ,X=v(s dMLNOO/lmLV= lE [Հ~)ny1*ÈNC~MM[Ͽ =ֳ̳/>hqfxVt_n׳e6UMX;{4x-ao]Q&R˕B V{{/'w66э#hMv=+AbުKT|y`ջCkn˯ݧ:`ҙvl94ɒ1As&|^+|ń+xnЧ8(AJ,cn+F9e`Qڌ9hsr%v#e~8nz&lt;wVY g)-k2OWkj> bAjk9͟k޻Z珂{{C,o* /x1M[ -@@ :ib*Hu-iB :{NMMZHtq||<=C=@O5*맏cbϷ&7!z-3+!:f} Xuk8-hcBnF"<3%e1X)m&sK252HQٛV]e\*xw-_``uIwz3gaXۊCZ>[?}A5Vlg]uJo^[:-CҚHʢWM X!5#z<\4gW%8g#C\T_ .ES"]AH$2e|JUe[E Jn/ȹ爝:u/-j#kǐikLg@[7gYafqZd@WyЂXԎ9Y82>Fp =Z*WS) )۩P(lS~6f:`簵Xuܨ/kssX wӘ,.N+дbҚ4.-[;x1BNC[uh`>GZf-P[ښp!EQ1d8f=in|f\]D`Tބ{)aB<j  YRk_C%qr*+<ڤ+'JJOEQeA?&Z(a>'gNZ_]XOEXNg?H6_%|sfd(Yކj7lK#B|2sL ǽٳo6Zg}I=Rpۛwa _8ҸYYP] Y'Uy4 b( z-#KzZMЊy{F@klޟŁ e7I?pf0fD)İmSX.!݀  L#i]N q6F6cV\Z%fswarn}YñO҉VTyA? ݘ3DQ9 ܏~Lb*&{r ut h1`)<1kҺǐbæ)ł$ce6X֡p:چ[;Q)۳**[/ķcFMs%N X뱡uu>Tf ٽCQI->vB U)6HqH$:<~hj?\?ڀZ0꣋EgX~VG9YmАX]UU,x~ju~h@쫾u\ UWl( ?L[>umҐma*&=.j|xU'+Yd@KZXJ\]8 O6ѐPXYPUF`[ $^Xz]( C2CiFhv$RBuv5Qj0mj{6<<%|y83E-J?h7h2ZHũ 8N*߶x}g`nXjt?^s".6;`UњXXȎ }|N~`QV}B޸j[t\zrb,Z],bBoؽ=@}Am\28C5d7NR 2~N (zWS;|Yi!6dkw&^ L5[lSSPu!,Ѫ Z(>!o ]=p b#^=DLt|ɏ>Ak0iS-Daφ?~==ebŠ,4oz5W؉*Z փkaa$b9ނ0sP9- 'WBuCb6E))jL zʨyX1LY4zwoߝ]kkۄ'd Ӛ-T|l]5|b|2hB6<jwלe5hͿH%xK F L$Ob3tI$\9oI eEM3*:BJ(TN)\GJo,L}JI ++58FkK#"(5z0wyR;sͿ@]{OD:Zv"VZ,QQVVi D64KХ!ܻGk(O!H$.VxPMi֫ܞE8<*B+jM<%-JQm,XZ\жPƀ%FW/^/DR՗u2[`4КʌJDN4 US$raTM\E?ڑ'e"VIxT— Q  V`7zY K-meG!xw!q {9 m>cWpXb1Fw)hX"!aI҈afv<`sZqMD e+֧ G臢w|j$`-J (IF"yQhGs:B fX: ]-95Zf薖afY>L1bE*.77m^o|gh5'P1#QB&9?Ŵ|}2tqjuWObkkziǪ T l >w%D*7 `̶iҕe7'"*{}}[l tfvviidAZT [[ 'eV&u@pFWɃ; KX Q>pz:7Wb|F,~P1& ҍ\-jap-X"ol|g>z|oH>,  Zeb2y\B57"6/Lѕ%֊@ XRҀ:O_sh~* 3huIB[ZCꑜhLhbxoV)훎ޤ7m+X3pwCVXi?qZӊZI RCZC8ce ڂ9-ٮ.$ ~JNuʺ@ piXb=MGˆd9[ԃbMR+68TgA+b 6eΊ`TaK :46pDI&1MS?`-HSiE>`" h=W%1mE@V_]7J&7T^R)L ͢?n.s6A[ߢ2v# 1IKfy"BS[944eТm93 PQs7e`o=s✎i")Kvu6VE*VO,Ꙉk9+Ң*OJbC&Fd-dbM!s~n 8`!bjŒ|%TXXNdy 3I?d<ڛ&V ǥ~ӗ-V)jVT}$;;ekѪ!؈'֎޸*\z{y0|Uf"A.[iMgվoԅLc%ܓTc0ȳ=:˔J\$6dpM\ pk%|2/B,Ue VbZ()y:.Vur0N 3*|?:K,&V]e> QpxxBGt:QԈ}FyS &ĆY25)R!{Víl>Y-9–gheR&zh6E||oEiky<8$FKXHE5{OP廪gfr"Je"B9ѯ1"imtnr[ݠERCw0 (H%-DRElji`sIp$Rl/9X:]};+t}u1$ŖAR*]T[s+yuJ8ci.T?JR`AI,_WAZG 5lLfU`sTc|#ZX'-iG .FL D2DhIv`-#nX@ cYAʸ/> Z6>.ۂS/)z|TXf, DOIٰvz'"-dbS!z{˖.o1nQr"Y ?*-)&kh?_?O\?x&J$-MЈ.J$TF~mwYfiP;K_2(%3rZ E5H[Ww5l-/$A>Au3PW90 _0Z\` ߠ/~g1@!ce9)HOi!EBg&ZUkb)[GoܜEԐ&,(7׋JbfIHo Az XEFtq/0Tu (`Hi]Ah|<@D53)gql19AK"Iqܜ _X"fٸ@@U]b,Uʲ؅.(Y+*N 0h,LRFGQ ZvOBH6c`wZf :=p8>ӋSs;BJ] cc8,*7GDx|VQ*&h\^Z;d2v+]Z-%ơRT-DeEbnxc5a?B YQVkH}hJ^ "\#ӤIf-oFoznL i4Axʓa2YylZsskAb St4Šnoqm+e4(Tł`Хi 1X0*;ZRi +ć;>JiuW9K(m-O,q0$BG1(ˣ0TVא MSP||DSdeoooI?5-c~857Ϗ@d0f6`TcccÇrJDDk=a`O˙<`-y)Um A I-k2X)bt0hz78LtkM5ub\[?bj*h2Xn@[t/ no鮿% sy^Y]oI5>|izY}~ŐC.[Θhl7-- 8q\D#FMY5#S\BVT[Vdkkz~uH}Sf!;K;k2#bęOn1!kV.4kObUݟ}r)  -(H-;+' :%g֖PAxiK+ fSiCy|),hly`eh!S8Nݗj[A* GZ@:,B-`I$!DR PP4mTDI,* `eF,?~w1d,}Ͻ|y!1vjؔ5O^e>5"PkOY(X𾂚'@aXi2jPr,(h)6&W?#ZgDTE= yXþ@i_|Ii Ѱ '.>u-zb gbckl2zPE4ώL?zR}hcB&o{zСUZXXmUT6 +!j7\SNZLD*)aZJjcV'2ԅYGpN]OMC!XA[oŴ %ʄWV.xկ hyx#!'%4<6na7qQZ0U? mhł}{XN';P x 4fEW/I1o-Xҏp "z5U_Z 5b%)31h7~i߾3IKArd &7; pWWiLqL!ź?*bMNJhxڣ*OV֊JD |m|Wv16YH23NLIDB$2T|ܟ}(~)VN<ۺ?SeXiT,|TpJYJ+3*gpTC$V?,x ~[2SbsJ"]##p7]v o@cm!@ v&2u+)Iee9&;x X!q"̢ OB~CTv? sW^ҍ][ZW@ }yW#32 | 'JPꑭJJvv%4E_ck`%hq iorW+E0ahf@0sA LxP1+Ű #QaOUiURIEXȣeDi:}U]NqM\%ZfsZ7N-t=&h3-a ?.\!ҕ̙ߺs2}D `ܼ6lwo\ҙ _a콺tc}qV2L ovTI> Z.L̏3 -͏""Է ٳ .+JRpWnti}4h$T"{?-a4gZB[ɔH[lU,3DA"[w vvUC]A%>7GN{SR5v+Δ"m)c@ˏm8!T_ }Oo̴_,/vOWvɻo IC{J T .qIsZAӧB2/A[uœ3x5<#A?RܾUzsw}94l=1 sA[#L+}4.rǖHp[r}Os(X=[/dH܄ } OCf[g\+++Vd65~<48=m,/]1NdT97DS?ΝSA=j`uM@tg- & ,Tn*4u})0 XѨ71mPagti p1(Rf ^~ Aix)Xh)I[*Nei YM6/ u'1@Ԥѷ=U PSK '-kN7l[Y]Xnln7W洍0] !2h,%1h iIp2ٳ}ax0ǚ Paŕ%}dt (WVV:#P a#QM:~".XT3-:2 gZ,{,+_~K{ ;/|۩ J K8Pp9NDE))W3biό§!Z Ҳ@ V>B%$aQhpъʜ@J  W|LJY٢k Hxgig]m`e.,,LH}Yd1-h/r&3-kRПŐVXH=BA/$)•媬+E&;SPX&iRo/>1yt T"Zy V SNAPBf+1O3炃j8K[ax( H5aJQ@K,i_B-[-ؒ_okC/@ J!BT~I i]XFT9X &lЛ$,:qaxlxjٶnI# oKV1!tfzT^/9U%R0Y X0]whհ.'e)(f<0,)JHV[@ÌDkn|IJʋE ҳI %Vx-JacF}[ׯ;[-X,oFr`xwjmax-[Ĝq$"h)A‡Fjk X3D1Y JC( ҲZZuti]G4]zjQvbn5`􆖦&YR`/CL$ZH2z'Tvt>F rUGV`EXxXV2Ki@U>kwh2r6o=I#k3~;e=`4-6:6_?.TbS@PuahVF4=q)Xa]Mg摪Ud".[x˝2Yw={dQFf6, \] …WqqyiѸt=&2Qm+‚ժ?\Ж~kMk2 _/̸qtl1fZ6G k?w?(hV^!dc%J@ŬTY`U;{* tG"ƯV6JDgTOϖ->]t^nq:5-&y[[9qAvSGV%z  &Xv 7cUDj1bX@Wh*pW$10ODX+VŚ-LR b7͖B -:C ^p'G 6=L_ RuǺShkg Qr̐b] ȉr-y6h!@ !kk{`B Y<*x3$Vjw7-;:ahJ9]|ƺQW<Jm=+ ;pWZG汩dZWܙ 96oAwZ ՚ Z5n[N4T6cu\ТO;hg;J?!Z6Ea/&XaHAf+,JX+ԯ"⪕zZJ ;==y! _yEW1L4,~ISǂa9ht (hʓhp*"DDj)-%+|}϶ͫ*K2wM"ڲUΰr `7HVX40ttNfH#X)0 HA~ Rʈ Epws3h%3.'1("~`]tCO}}@ZVTyGua:֭3on1Voj;<1iD B ~lB'8>~ԏ"(z: TDTWŃA+Q$`A8(x.%2ytT+NxIwܯ#ܵEw hq G9~ʕg[s%H+T.Z]w-mW49$I%J9:3 #tZB_tD ;'` _y`:u><ޤ:{"gH.p V F$Y?G=y/oC g {- - <-|@ 81Tȫwr\+h.;^tf2 %(Fu^`xxWXhZM-rJYDM3Z,b劳돞{jډV!\ׂ+?B VT*ۈVETqHWW=f4c#~[ADtAcaRX"i^sZ"7 XBD"X%fKkugHf01ZEH K^-%t ]Hr Ica(g %.%Pc9[Z7B YuC+P: -ѕoSZ1X}ZnJ5#^πbFXPmHlۺ]gMih6w]mǨ T"8C?%Y}g"-g& X+.Zc{5 0Cq̻U3bv,c%Z@ UrW?;prK_?guQxvp)%xںY˨vS LCs6Gq}yP]GnBS5q~mЯ%}A؝hu#~:/Y(8iT,Abj7b_.A!hY;3y hR#> q%8W= kp[)nT9jGwNh`b ϪƼǃBNg} N^gzM`{$Z4$&bdtp {LEגg; TfCq'd$+=Cz N괺cx\&]2讎EW9`33JK I.f7266 nMV˽w/ӕK \]`,ԞWޅjᵔlsOVۑQ`1cfc/MIi VpWs:/LzaK`y-qGxd7U˲H8.sc6Ac=C#O;]՜a?pah%$4.lQ ?`XC-u[~1Bsm}I\Jk~9Ê)ےhQ\ |QH(pQUBBpj}~ziE;,K/{լ FA3~bIqF#L@}(:5jrYU:WaHqm[;{GDũӐlg>O#ͦa8D "chQX1K$`d%נpU RZ$MN"v S9:u+K$)J1/b_fB^oPY5` Z険#SЉ<v)rJ&#Iֽk: /y?C2 IB^RrE%7mC^c8LBITAxT&*cjsٻFWFZ.#@G^ՒsZ)sEc.?"~EJ%^ +d҂],1Yy%GἙZTGM*Ykc{ڌN%g* oD;;Sh6W 1zuq7MB}/h=߁"E[+0lX$Q,M/eCy վ)m^A|GkȖc]}BV_dl- 68U9c]uS!}> NhȺroM{zǫLklԶk,7KCRl&hC!WHfu bGW92Ku^2!_I/I`X!86 ^ Y [y axPwf<,P@ Kz=1{{͖^ʕ+˚r,JC{ x}`GBggX% ɥ\+J{3RbP_1lchܰ.+# (6}o->Y2W2f( nECaL <=dl9&Xֳ2Ij.Mh#E`’cem,F"J%k0XN**~XEsl"Z`Ĵf9L+6,"\GemfWnJSede[s-+Ja\%`ԛ-N:uԩSNoAi3NIENDB`imsprog-1.8.5/IMSProg_programmer/img/ch347_spi_3v3.png000066400000000000000000000450431520775651600224240ustar00rootroot00000000000000PNG  IHDR,)nPLTE˿`-#ýԬԟ]Yk6dq?UzN~NǪpҸoBvGǫwЬjShP=R>.y[}^b hH+ ~ڇύљuWTXJOĿJOpf:Z6x ::wƸP2Q -3#! :+'CNPyQƺnCUu. ӮB #ʰ|mú%HFŹhhN9!\#:K63m¹!]HSTf<^ǥz.wg_'+~w˿H1)C'R_a`ÿWHDn]932[ef8NWZ RVlJёx̙#sm--p&o\RiSGL>;'Y_WU_MJEEqnPW?4zqfb3Zy%^}wiWͿgy`Pvc3G1n9Sp%DvETR\Cs]cZV(;;=u{r^g[D#*-D "#ǸgPvCKur~|=jweSY|zle15tRNS<X%"7WN|V94޻ׯ_ٹZ++H9{8vj<ԋ `iҐ{˲̺yz(?uVk"aAE1DAbRL˲'/޸ّZl|Mp!c%ç/|uƷ_=S69ֶЀ+9R4b#X3_:u JYiHJh+h;He, 9swr?ܟ638׮gpoYM6GW1 ],p/վq|`ej?<ʪM-@L.6IG*e(q 4bp/Ι3Om6C uR$Lm#lZ2+ bT4J*ΙEe`~j0?2C=THNnlf,i?4 6fK14pZ++a! V?qh X4bH^ iAdt 6NgDD=`9?ͮˉh4pbBlW>_i nZ`*Dv;<9:us"]:ӐqKPeu4ށ:XAK}o'|nV?-H¯,$5f+t ;wOö>Ēg\0_ "aLϊ[xY<`e:4< iXBT ZOЂ~ LH~)KCi=cSWXKrXgSv?; SY&1{Ӥ\;49DN-ALEf'*z?3Xhoi~9/`~e4tz mAX pRym~>_D SX^8܉׋U(6Y=7к&|uPUϤ9ԫ4i9$*-i+]2VGtFk{ R2wu>ۀW^M.)ꮐ\ǯ+ "+$҂l[i V0y5pt NĖyr"DD^r]X@htVԈ>D=OLn.?Cjė|*.nV,0T.XjV?;~q(tO,ĖFS_zp;([L U, Zdf DkVe@LTgts"+ uo956:$P +%-?gVD|Zzx||4bdpI:+q4|nJFcCrC Xq2hã`fZŒT+ir$~|S6}'.Y AV͟S[s˫@\WP]]i7 V4Ùcmzl6#QZ=w˚TVhyl,N>+*`ez?Ƚ=ͻٚEI X_95?huFiS<$BsT͇7FPb!^ yU@j+X,֘|flkۧ;z|}ߟОtc)V[J*.ӘcqLؕ'K>٨?Vk1`-{ gk~92HADk͗펁Uщ'wʆRRa1Rѩ~ =_R9>\,NpXG^ꍟL-VFOTvPT`0h%D -T,,Nd?_ۧ#C/{Mu G|JTcGe)-˰Rv5p}-4$fU1OOO܃k;D{S 5Xx$ͽ1(n=|Ie?^XK5c%/؋+?,o.A?*^UAH/B[%Y%n5a.U,:!YlJk>~mG.E >[DIV5Fi\ ~H2ڋקT=y`^|'ơ~ͮŧ]x388ᅋ,B8+ % 3VQE)Xl8J\aSg@ EM[|@`Eɔ VFCH>Ύ! X+TӁҢkKpX5a!*v8sY`{u+PMDDmͯшϴp@:u-pX Yŷ!pt(a摥z3|q]V$li&dZ^te-sY8@Fdg)n3m v=ǐDwRԕ!cZ]%ﷄ"f6ʬdX|4fv]*XA4MIJqf̻yHtx8TAc8Ye 5v({[0io?%?B⊧kW_q#ːjЦہzːN Pr/[UiAz2RjG"#<0Z`e^s@E%)k3uv˧ 6cv0/F7rB*˨U*U#B)I?hn Ȩ0bvD{̂LuB*: ]GYm;cKhVIު[!פfMjRh==r+܇꥓m41\>ou/&xY:@U *3Uu.˳aR |qUƖ;n\㒡Tk~ѺTn6 Ӯ(eg~d8gZ&2@o*p{YB>6j0˴VѮBNMSjQQ:h {@YEY!뙢5h\,Z&VGisn.&( GUD\"A#ͻ(~Ȋ榑xST`[<(h/fT4Ic2/+7Ț9o= Y>|jl5SEX[7Z{S$ =;Lbj"%xu=qE }~s+.c)h BLj{mS%L%+ -L%WQֿ2V9l;]Gn֦jǃz>e!+4W ƚTs}aCK+hfzWL+FZY&dE'jt9Uq+81Lc͜w#``uE% n70֪5؉%FE_ mW8;594>JEgRL9X]" Ջ*E${-,`:7<[tN5̃ 9ՑYz*D0T$#TETUJ*mv~oZbW'dH?gZAtki,]֣opczarNv@'8UJꎭ/^2%jƒ^ ˞D!5Yt$$IiC1KWp8IU0,k2;S*8nr?Jplmǖ+ϾK !MC6Lvˊ₦:( i;Ib1/՛x06&zɭQ=0UUREGeq^ٶ]:^9}+ty~ЂEyV 6Ͻz,#gΜ#"b)f"r'W5#\ w]{Y.k=~҂&ic 8Јon^xAi(, DYAJ1NYy;GzEPnݜD9}Ly^gJibovCag%vFjPG4jR"lҪ՚cP?&XMZ%w]e zYaĬsHm Э\xu>b11:ɥ#|HMJIpD5ZZ >g ""+Zxp.G~0 9q?OԀYdJOeUzG_msUEE[ TZ DV ` T;Z+T6h]>CnNʣN?+8WN'0W2daٶ& _*Cyl[=sL^$)%Bj+Ƭ"F%iM) nFo` |N' jxD Q \^=/m(HVC-)v`V+#gRMecA0)\ӱYXXdw +ꏮ,;O]ZI |Ex J 4,uZ%#C=](ɺ2P~^IwqүGB@zI%%CvCpiK)ʦJaƨ4Pwڳ vpYQ-Uqo1wV$z$9+ ±\@BZi )U IR "mQl7 2&>' isʫj]0bag ~:i,L+YO;% @nqsmR$K(DI*UQ%Rv7*CD3B,-bp]>r-oQ5$[~'f%@; U5jUsWbʭHQ%f:J];Apq̨3' iىEis}y\?񔨲$4Ŵ0"Zw´&Ca`wfLZe;cr,/ M jrY^|lTjT=iQ ÅX"-py?ʽX^,Q"98m[ݰn ҬFQv̶H5ב0$(Qz$CuBqH;gJ)=EK͋es,[n1\K.k5ޔHzZ@ kB(YA4K9jIL>KjbX6xl``Rbss^yJZ.׸'"wz[ޢHKdl.둨*tE*9Z# {;00+=,jjR-İr,KFlF]HOr\RMAF|ޛ{mV3JVfX_j* Vb-8dx>*ɷQx>Ԑ*R(9Rɚ{_)}@Nد|rѯ'1smhR|,0Ʃ$-t #C!Gi ΌQ#!kI,a%ŝ*2n_Tp\^=t@Y^p9`ʪ7YzC`2`aa5/)?\BĜ0+4]B~QS_";`fiԄ2~cE6H8vg/QsɕabA_DFQAt*sGsz9j疵jifl66 Fu^?<﹮IeteA-xGǴ+tJUuj `VٹWB %}W/2+<b&sL'+AkXs2+.yWkL9,85uU6ySװ$ţog({/ XO_=hڧ k 4D$xrG@ XY{ޡ_o6kyWVFG1ޓ4UV>*`T|]2mm 3 VBE ǎڨk +dO^ןxL8 Ы@:&S j AuZݛ`W^؊wK+ XTkH(8sĨ*GC]땷Nn`_'/:e+bh,h2!B]Y~kح;ќMՎhWVzB/8"eibհb4B,QZ.J)9Ie"^L{?! ɹǀ Ʋ[6v9֎ZpFWhPVk`كe ԡOI7jȥ0J_fc'"8pItiu׵`!VYe3 &B;ʉ] 콝ˇnnxNn+[Q -8 16"8U9X}g>ssLޥG@'2к+'h\|+b07M)C0.ڡIylj‚l-ѢeawnXKqxW7R>mҡ3!qF.-Y>;א~u>L "PX\tXۇZ=}M-4#/86V49 6\)x~Sm`u$'Ai AĎݳ|I*2rvM8@wxkrV7>nԹ7PyhD (tֵ^9U՟9:J.#ʃNI!DU̞~㰳h!'٪AZAap<M pr'an6/㣺C}~t㖃 ;:'w]Qvs,Y; 1NNN?À['̊E|e1fu[Fǵcx.|tC/~MoW;DcCD t3|/W(,s G?LHO:K٨5E+X28JGXv9΍{jc`=V8΅Aɻ\<\$5u2n'q䫋ϹpC%dĹ-O Po!AV ` ܝNxp.ۇ|o 0Z陵 A{~,vud;ILs?ݞ& Q5TF5Ai $->@ 3eP +L|"beefg Z{~BvE@2BE|UW[}DTe•Y.醡^u ~޷"Xhn(;ihX/p.k-?V`虪C^ Y9#F+RfhX״_jxht:dhGD5`1wogwզmhDWCb(_ioH/jur:[9idLFQKIDf6#]} PӧI&t] {la';:6$KNtk/8 izr Mf}yJˉ1" 9-1s\2LT[8bOc_9; Nis ZV/ Cn XM(aLJ(s[Qc[A^?%*9|pIҏG?4MTW!1%&,=z UiDy[;Aڅ:j*#*Kcm]}},FnOD- ^FQ4{av9wԀѺ%cli줔 }؊g@Mp&1...Z(iȀu*?E)ҋ[%Z)nVp/7߿v2;-dIFkᔩ6Ow1, NmFo;]PNlZ&&jDj+":3[O)>t":^Ee Ճ7 Phya8&#hv;|`7{66Ȝ> l%8E$x|\t5oZq2q0ˠ#S-NcWv92yooii\<&> 8֢pd=D]gO.G|R/6#M!Fuq_м~^ER FoD-ޫ.}~2QneWٟr%9TDRIYѩ}bu'b:m}1FA^yB_ @n mЂ@ w:ٽ'[JvMSF4z~tۓ湭B0;K$l}R= bLIL9! @u>ù;`v hAGn|nvjs \uj?{R`)ת3HHȒ&\byQkH)]̳\03?]޲!VȐO8 VZ0}hq/M*Jhs Q$~S@:zTQqdddJ6F'LSB⯬"Ѿ@T~gGHM@r8!4,Pb0wCib4{a!uۙLnȵ䇔27hPMaFX] Chu'PX2b`N &$xH#GB#]Ejk3DFD~zටDir]M2n8.7οx7Iw ['X@<8o2mߣZlf2ioi4 RzM3)5b^_g܌?petg;F"&HlHR<3HRĩ/j0C6ogP[NA|nd4IgcӁ_=|0[3Hͫd*=:&XG#-MmP'qxPK7W7SZ4)>gb}'3GPI#Qk+# s` JHR!Z|2êm9D _$anx\(u2_$wKJ*syؚMʔL 9S GWx™R XWtx{`.s:]ёKb(8\XU ':\3!FGUH\а|3,|Sz} ee*Am.k* *&o}[uV+78]`T~[!j YT` " Q, mn8\V{xZ~}5݂%ի A⬟2Hl Bt= b¢ fZiQTޝƂai<8ǿGx@~}%R?JH[ha 9]̿6 t;s]sk $Up3G4Ṍs*xhzz+NLkj~X%h/a\7 * [H'X>PPDkq?&M * qʏT]sB;CѫjOA|]kk YST D9G~&F# b}H$IyXxXM `0M%L/Æ2_ u7?buy!J6,a^ ~$ֵqGVFZjk'~:)䥺&1 @Ca⎰@_0~b3,1 AYlX'K1cSMT@`{j(pym ,V 869 /R gg= b]"pD|҉gCa( ;Âjŗ}% {3>z@t)yFS@u]6& <>wg5Z߻d [uv!F ,dBaK`Ek- ;3, EGi0˨Ct+jR r p;pVczdա/=V^Ñ6? ŗX$&>L"#^ۄ5'S-V?\B[[t$(' $ VړAt˹w|eYi+/,51 ˤ~9EׅQYY^߾  Jup2Cp'3D'ӳiؘ;^n7PWT8E;Q3eH"L GC t K!Lt_VgH0`;0.˳g#^2_y!!Eta6o`kZ9y 0&]oP0㕎G%({AF"|z x+iOW=M-=1 *F]p@V7K7S7@&¾w1")89\tRz\np?]i [!2 >wTXZ .Q&3`Uzy4E"W;޼LfZVAo<ӛ^SV@HCu]r?,Ëx4Q-H_>^1\{bZp_.Z 苕RMX/+o*dž V[ţǙ'l<X^OЇHrn85}ȑ3u9X < &F/9mܜMt@oL#C@UI$}=8!ViTD`G̮Nb~5E as*)lƩy [@jg$frJNqx\ҞHZYCdD 1oEh`te4、'^Ү7Wmɰ8fP}&e* ^FJAls>dk0/J)WU2X7zCiP xD>,`ɆDrfV ".K HLA8g\wru8]S|(® k:j7[&aX]X?DÕY@)x޹U||LCX@O’B}> aׂx2 J!\:]J(t2MZ+p ATF1i(Ї.~3XR |x \,]m %R+^ajT.dh(Ll-!jU,H@ blX"v3f"ɰ [AXXiomc,"Ap,X\HXgHO`|ofnMPIvC6'nof(XbP ;f ݨ7O_~AVvoxn3m<Y-ph R2bVz"mDh´5#b%b.Z:R͹.KW9,dlOY _e+p0] }7*&]حrXx8XԻʎV1/Tᆭ6ɀ4&[KբjtueeUY!rgYN8 5[o0cJ!Dm `4XYT {6] lB3p H J1nK !&«,j;x])3LmJ JֆS=I.}xX PyXs1U$]Utߴ Y|m - qHEi/p P#pڠby^ʖ:F+8H\ĭⰼ ,P,zoT95e;}Ш),nx9x`I4'`5WBF6? X)g)46OJ `jڪ)RJ-hfJ@ĩpF5$ԆXR ֕H@jԨQF5jt x IENDB`imsprog-1.8.5/IMSProg_programmer/img/checkErase64.png000066400000000000000000000061431520775651600224330ustar00rootroot00000000000000PNG  IHDR@@PLTE񗗗֋勋򐐐䛛১¢Ʒ蛛~Gի塡eedο68ⷶȞ25A"+(Q(载M&:8 7fIF#1$?:< ^(+,)'*H%қISBMC;̎V -/E.(*񗖗nnohhh'  ՠ[PI@7+4+)*Ũߍwy|sjyhOzDlBN=C8?1&͡د쭪}|}]TQGT9E8M4))A#9妣ywvvzr{qgqYJDqA(*2( ˵Φlbg\fZsaP[MjLKAU+A%/( ظǓspcYOR<3sS1%(-% Ὺzvphuh[`RhUM~^;6Ŵs@Afv<)+1tRNS 6$ &mJCך]9纓W٬mh IDATXÅw\gؖn#!$.&1ah *&A$dɔT A@pQ֪u[Gk묫{>wp(7y(|11xY3&0k<^+l5{lK~]_+0D/=ñ ,8UUm4Zšv_#/LM[ YAΌwREBWWVU2lлnS~ *nSJ3؊ޠM8ǓЏt(YQ0&WdG5kQ98,1p /,J<:|@[M|> " ]봼3׊u\W%%%A4l7X_fr kWmu|Tv>)ИO}@<e$0[w&R۴1|D|ETTi)=Vq+݂@jܢش`G w>.)50d :פMgKă\(Z?gO>}uW =VO |"a&iL %8\,7,.Xzu-־paErrrE8 OPtE\tvpi沔EKV] \P0dc/OZczkBHlfyiw2c&üwPp1Y3GtďMDT̙ woXU=8 ;GDD 9+cW`RRQE7$%.Y*o{ $bs7c H)#l'32ң885[RF$qqCȭH0@c /(E@I#Gz#xht({>V\_`1{2(:>mkWb}Cqc+U05HRia1HCI N7ܽK0? K &_r߅\cG2 El9{ҳF‘G6Z&@W/2EhD{ђ07%-bHBlVN'HUdXJR0)FIʖV\J9 " :`|#cBV>\ Pm ~&8C =<`>C-"%-~L`)Й2lm#fmt gfhJ $TE3fHjh $~m30}6YoXTR B2QlZZJ'@/ 7`G qXw:uj9#)^~C4`tG9d&9>A@#%xe\x<J6Rd7|'%V`DU(i uW RV,%$Jɼ2ŋyY*WB#%`hV!!MNz^A BP 8a -ݤl!Vm0AA@7@#CJ-(P$LI/?zRP1X H1b0Vΐ2I0/}agiY#(+m|×/1^|?gFxzp>'Gx),@kIENDB`imsprog-1.8.5/IMSProg_programmer/img/checkSum64.png000066400000000000000000000054101520775651600221340ustar00rootroot00000000000000PNG  IHDR@@PLTE𐐑ߛ֔㋋ꛛ괴޲ؿι#$&ۡ"eeeG=O226𫫫ffi!؟RRSa`e ")$֏imqʼYX_%&"lpughiUT[ ehmdbh\\bWV]QXY9:< :7/&!.-,)( &## !#hjp=5F:2B-2&ѷtw{abh[Za">:`]c7.?%%*ptxWdc ٓ }}xy|cej?9H=i۫&EEATO0"ah|7'qڪ{7a5gd{oiT: 8J 9:ʌ—P)F ` hz%#_KX%1-T Upˉ`k9i=9N |L%`@ߛ($GD(8 PV}1LLt|@FgS$TYlФE g~|>%6L0]tR 1ˆ0%Ӈ5^UːJ04 "`a/Z -Ԥ(}#B#VeD)e~7kb[;eۘ*kf]+1؝;b 1lƂ+K9>0 Ta4M@@)aΙmID&u RFR 3dX+ajI!w9''v-Á>@y1j-{g 9+^1>;jV`fVJjϻܜ+SQM:~Db~CZŚ;Rhl?ENq`bt%e>|#, Bd!)8X~jr"ß@R> 6tm łu88xi׮KeΧ]p`1>bDo|a G[[G@7v:(׮]|f\hH?_hJ/w xRxh>hBjotlH|g;vxS^iwv|3gX6-{er*~W0 ePӽSY˕rS(rlA-I5NZl.#V j#Zz_Xsk ëk+W&#b&/t8mOK'G"sZ|sčrP\9gIIM88ɪ$a;wL2h4h"@ F9kelJ;!X"`("mG6훮<\D.VDkst{Jep/ d|ҝD=2'aHopIENDB`imsprog-1.8.5/IMSProg_programmer/img/chipEdit64.png000066400000000000000000000053461520775651600221330ustar00rootroot00000000000000PNG  IHDR@@PLTE𗗗򑑐㮮㧧ȱӟ񹹹Πaaa૫栠llleedsssގfffzzzwww·ژ؃qqqooo|||vvv  }mfccb:-\iiizuȉ 뵵J^]]* nK m)Ŀ:j 'lJpYYY5%xfcjU}Q3F(/)%z^ oa٫vm{ciPhK^D=:7O.4.*<*%0'e䅲*Ä8s'cV~|sjv^p[QKGHEB4  2p÷ƾuNtڸӷع`7n☈얈Sow{gi`v_`G*%rm@EtRNS!$7 DY%Ky9/޾grppmd_8 ٳeIDATXÍuPm0Ʀ2A%حw9~;v&3gmX1y|gRbs E+P$_.yi4MMtAe[zLL$45MGP[60P1!/d;Zli;Bh?qC4#m|% Ay"nUjh߆hnJ#x=S`hMbs{5ݾ=3a) .N~ߞW*$āH[ j͟BmjkXB:ƉM 5/CPx0Wѓnc3fW.en {,O>A 2lptEqx,z W/\84b݆O0{Hzvk/rgХv h ΛNuD'"׬lh˗QZi-M'{gǢtxo :zď߿9YRI>YێnHpŎ-[*>[$<%hq#{uh.lWn'jn|DikoWZl󫠽Npb앱^sj_xY9{rn|On;5VVwzyiu)#~{-$%w^T)9i'e3 +D˳ҿ[t ?U`k)$ɠ3!qQjSu ]hyi}. 2Ԃ '@xAGQGB`rGk [`qw i*],QG]{``8̍N^][춸 4΂Eh׉mXl\b"g[ܿss-V@mA;HWB~ Z3/zskf7v:S9s LH W̞~oha:+1j3Gl* ԉû'R "p $8ClM'n8QHЩ[wKخ0.]rbe0tf9I1b$Ri(aH#% *$L 8r2ι|:8:6*xz@R]2LQ.{ i+x8I ׀#ނ%ti uQ^b@S͌"]}$l,vo0PEٜI]IE[?e\3?z~ xAu<.CXMbWwwbC5^{ZeuVΓD6inrA?[m0q+Q<6)$IN2IENDB`imsprog-1.8.5/IMSProg_programmer/img/compare64.png000066400000000000000000000063071520775651600220260ustar00rootroot00000000000000PNG  IHDR@@PLTE䊊ۏ哓ө汱ᄒߘ꼼Ȣ쾾Ѳ잞췷cofrdpIU14M|{ybnonlؽhhg`mZf_l25JR^]i^kdpLXrqqdpfp\iR_COfrUbNZyyxCBCbn?Jjjjiih/5eYYW03IKJG9:DpzWc@L;F6A34C᷺‚yal1;vvu.7ullk-4kggf*0X??@۲ь/8{bb`,2_,0RΪ͠_l.6p27]^^[@CZSSOOOLFECךu~^i:E8B3;w9=\;:<۹ɖƒjuv~4>=Dv_aq8>hQS_JK\ٺԧGS[c~CLaf]^eYZa*/L¡[elrwxGGS9:NɄcmrvJQpsNSvVXhy@tRNS A! )YFqPڭ\2{;jA5 =&@{<1G3K0lw4aLwkUeb/' WV>X;|M%*T6Cu\6 rvpvƶrֺ5D(#ShVȲ_ul~(tE,wھNZlͰ.7Gj+ʰn$ ,{+Q_WuH7$H*@s!iXSW )mL@1:}O+V,P$e-W#=vYfW0KgCn"k`w=J_Gj>Ulw&SqMmמ~-Vp;`U\Wt1_kt@Zc @u!ibv4ahWl>IҪ ZcGZ4D~6d8iySe)wmN}=&O&Esj9?>wK80 v3*eA;B1Ǘ_~u`mت"b vfe\xZaE+ǔh,)7bۖ&3]4߬e)`rhP`I&` =tKGq `Qu1GGwՏ8.ڝ*}<\{c2G )Rx&~Mݍ4zdB))PI5Tj!&?>?eS.ń偢,FM\uءL6h~%.~}{S0%ŦfJN3f @.yl 9MKٖ<;vS 0RHHi,1%A PG&\\1'J}%nLJ 6:s+AC?# MePR7g'm}%E e8uO#QC:B'HtRA*1a<]jZ)! K&:&`T"sﳮ. 3ERJ,3on^(mAv5b|# l6"@*LP(P@K̗O\<= PR~Z^JW9NZDScwqC#Owf%KDy~s1Vҟ+{iM)Ѡ9gN Nx p!c+Z:g8 WlMp G{e 0^yJw5(QիX}KQnpkOBm {/<An&'1@sp1IENDB`imsprog-1.8.5/IMSProg_programmer/img/copy64.png000066400000000000000000000045651520775651600213560ustar00rootroot00000000000000PNG  IHDR@@PLTE⊊򍍌ꑑ𢢢ꥥ睝螞𖖗ȱ֗羾ؿι譭ėcyΖ]][[::44ޓbbشּ׷kkѾ2د2ݕSS {eedffe̸ʼnɺ~FFȶļǛ9 ñ~~hhhfffǮR)eee_O󗗈#www//Bx````AAFݚF*}}}ttoonaaaWWMM''ν͙åĴxW`RWޔ8ggJJ88ر׹ﷷصخNݖ/=ለ {zxxooommmVV-LtRNS!6 $ D%kWK9]$̶qh-wd DIDATXÍu|a:ؔ윢X(*(S7lƽ#<_KȞh,~蔇'KryKP(LF@2Y.ZIEL;9x]CqqVL1NAwJK+Qіuf]HұfTJ%V]_h* $!B;튢=\&2 $JMO"U'AvUKa:/ջW/ g^ 0nF秐<}gOLp7'*h@_[4~}(qiF@X~1i} | t)3Z eL*h }8|o X8h*  g~ c;J{ pœ>>ѿX[/Ay}v?<餟h:a]AjL2tAyglٶܪJHAXNeULZx3][Ky- u?*s AonV`,aO$.l!XpvgE\P sKstc"=vI DΝ;mF )f4hiO bFMI` D!Uk%:B4{q}UL˫=I Bn_^]3LG|WN>\\-[nByß8+!B2JBG 镈se\X_Y0 %ň|ǑIώ;H$Y&orR3*g}6$ꫯ2:>mIIN )F`A)CլS5KuF8-+P_4 W}1w~?_R][[K*BJq"y^4RVV6c;ȓJ [$΃UœU eX.kUȢʪc4/3ŕhÖoiGZRJK**<ϳ(LyJ4#Z.c?~ #&%'S^% Y6Fh3%u1D]MK zVF 2X5͟%m|8C>G),laݟgϷ}xsi0е.`@iWUi[DZDQxio rr?wIO (,Is6 ӼW壏`qz2>C٠}UPk(JWRe`golgK 5Yz;%*}cʹC9B|wLP2_V]jLJΗ m>8rlITm]"C v2? ~| 75(mD%9XCN› 9k}7bQTWN `cny 1kgs$?яظq# sFi{D~MulA:_psNo3::J,cu԰jhICZ@C@K$(e2 0|P 9 GVo9sޯޱȷW}Ynf/f,]zuB`h۬SIXZ{ TiJ]uQg0̙3L&Cձ6deZ!xQk! r9HNxy%6 ʘW1 Y ٲOqbK{\:*p1u;۶k&ܓ4dE0aQǶHT YnK)/u.ˇ092tu06XB*^{A뵽|~BYu%ܠπ'O288yAab4oJgQxSضm*+B>]6Fs9~Eq4dw2Uq@xgH M1LF p^)Vt|f },+++BpWj*ɤ'~@/mx!,WW[ \L] 46/Tw~5ϟcq҈`bҥ%R b /p[JyQCٶm֭qy+P?(cE!$ (V B\rl]5ͭ"V32";4r*62+e4Qx_yW}x67?0AJ+e1.o'ΑOp3yPXYYǍ)D5`G2RĕYCj|xy9lݺǏ 7p͜}v1Ut:ͶmAJ8ӧHI>G]2 #m qOi?rQ~`YUUU$3 lz5j8}x=jɘe8Fb 1l~[,qB)iN8AKK Abɜ3Be||>OEE,[lapp۶-KzFN}o+2.H~_T8a2KJE"prdْ@K&S=pxOee%DQٳgDH$¾}<l?Su`c-7oR3>U/}K|ߠ,8GBPG>˲fǎc6Zs,d2| yd2??/6c)ҏK-B_!qP&''3gXz]tuB$P(-ض}fll,N ť6x6lʕ+I$q1.ZkjjjX|9xJ>xL&9.-}naJl,}Х 966VPHhDmCаRh+!Dnll 3`6 XECChǬ[!RT0L&s=ݟt8Geڵ .z<z KNN9;ҹ}`pVo8;̙{n{|8f͚5Ap}vz{{qR+?)w}7D{'+vAaXkww_ub1.\ȼy󨨨, ,Tg1~yN>Moo/Xիퟱm;y򸌔L&SQ\}#TPHis}WqBٻ$ 4 *)\13PJS|RjPKKӤR)ömΝKGGǙϯX?ǣJ)[)YeY&0ꓓ"iO?t'SCCCMO<@hht(I <X3X&U[qjkky(L~/?R ؘ,˲ MXHJi!Jd\׽h>qTyLi]pLa”aMdjA_ ۝ "P( *iX,#N)%eYM[5;IENDB`imsprog-1.8.5/IMSProg_programmer/img/exit64.png000066400000000000000000000134041520775651600213450ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_FIDATxě{\u?>f1C\q)|H6)IשBqD$Eu_  4"Tۅ#S*YUhY1cQ\h].5;{?cܙ]RH03s=+z-!Zx휛R#[)5 s!_WC1tb/?s+U`E,J)oߕ F9wlǵSƘ1!ʕⱃRFg_R.!@)jR>tq!5&" :N޽{BpM<_·E?FZU𣔐#"wݥ%}Y>̃>hk'&''A5F#U@ (VslZf3<gΜ)DJx5w )%qsyx衇Zc& Tn y&B?=)%J]&!u798ƓC' B<$B 2<$9G0>^k-Zo<#oA8jqv׮]CZR(+`dD̓7ME(8)X#Du(޾c::v0Q!I Xphc}G5?8w=\ܯ}k={C}ZXV^yE/_!B>yOL#:Y!0IB09?E3tRC}cCH5&iDooѝ&Q{ $$ Tp]\KP`O- CN>ͅ طoǂ x_x^fW_}={h4Zyސ}D\{K yzDʼnEV掾)ح%8EX@uWCu g"{%:01D7W?No̞Zk>̥Kv횸~Ws.E@zq?0I ; |Qk$ jt;1ϰj5z%1sm:Hz5p5)qHdPx4^_#$YRgLkĉ\r#Gpx vs+++jϿݔ&| ĝ:Gq"zQDl\!j6ZkS[P:c.DmuPȠF$[쬹c8p.\`cccjvvg2"!x78p#-zxg |Mi{\XSEkpց+!AzcD9h3;;ιI [~c̽LOOy;BWu`Ǩ5pB*4֤›L "t+2zZH,*gRTkk ) B8cccLLL`{$Ipy93 [v5ukSbM %8R>§hfsI1XkH)441^^Ȕ͝"B s`̥LJ{ Jp7%D]ټυ /2ev:}NRFscA!YfLvF`_|SxZB'%ژ,TQ` LNw‹!XgqDU+Ό R1YT9J#]@=ڦW\ i ̅NHv$s+7T[9 PCc(Ȅ/J߂b;lܮmLM1O}i2,n§Ӥ;!3"7 ed5ЍRem1ָ LStn%aok,Z2?7*w3bFd0ǧuR\.QqT?\\aSc퐢4hmn" P"#6y-8aA /ˎRޑ+;ne_BNU8HJ ¹,l9??u;sϱ˗\0pٌՀ oQL"w hMnv*tE~Ղ-&2h JE"<+@^|lBq7.+u@Yxc`ިn#,g>C+$6.12z l5 z=zQDh-C1Z5(ǸQD$eU{;99G|=LEj!\Bӿ{MacܥIc,f/,-Ju8c "[΅eWX1 ծY9"v0ɗq*|N:OI*17 aC~@k ͫW,W+t] Bvkԛt>9~^2(QCZh--P߳2I'ǟ`, *!-M?s^mFĔL>n.$[[ 3mtvW6sAEo7cnYp01w@'vMV BxgĊϻM,P5ܑ&?C67ikK9ɂJb3a ce k>{gҁH-~?rPcNts!p_ĥKt:s3$ '( mfgY'LfOq<)±a^@7X>FyMF!`+XR)=x2Ŏ.0;9B_=W?&'b`rofјDLOa >8}aޠ軌`q-2Cw| e=qz tBZAX7Xsx*ap!D~Wb;_' !\}\]y7#I SFY`XRYV CP Y}eCL ?԰FEUcw)BP6a; |ᶘcCaBE6YZ椵6vM$#-^}v WL:1t;T1ϋׇ4UFVm ?bV~1QIRJ(tP$q`N\i T RóY8iSd{I t̹677יoK)/JaX Xkzj[./.[`|ݘgEZ~3tV#HB"@)xt{,=9! {|WA0 _6112j"}%Q$9}+?_SNqi#nb;p~,VWWp:us}ðk yB IȢD'N9ƹ\v#Gh4ð uԼ((ezS5Ԭ-)-OQk"RJΝ;ӧC~hM`NgZ묵Zk\MFJix?^{oySSSLOO355E_11 rAEu:&lnnyx;8~xsaa=z?z:H)EvRn Z)%oKKKXkJSf+++t:$IQG奨QN A8{宻j}i||F㍙LR)+>R t8}nN2kkkdD$Zf։p\,1 < ;K+GO%RJ<]}0 2== sss| N3z $Ihlmmq-Id3i]h Ҭ@DkݺN/Dah Ќ3;; ccc1FJ)'RAFrIENDB`imsprog-1.8.5/IMSProg_programmer/img/fill64.png000066400000000000000000000054571520775651600213330ustar00rootroot00000000000000PNG  IHDR@@PLTEށڅؒ󖖖霜촴”ԦȢױڞǷ٪çզڨ̽hhgמyyylllnoofffppp___===ѶSSS hiikkkNJ}||*$rrrjjjGGG tuu:1 vxxbbbUVVUHJ>A7"ĮIII0)ʟOC4,,, Z\\DCCF;蝝zvvddd__MMKKKK@@77444! S麺۸橩ܢݏ~~jrr]][[[[YYTT]9944##̾ɩ‘쀀sskkkkiihhggdWWPPLLKKKKK??;;99//?++%$  o!flDtRNS@ ! )HSq\ ڥ2丯¶jaZYIDATXíuPp;Q'A塀A޻M᝷~x1rVU _$}MBdzYȩi~¦H I in9+OB?k_ҹ0Ro`0B&n?w~Dǐ~P~1\[iӲey"!eƍ1NLc0|;l3upr|A/`ٚn+TY, `O!_A/h0%AWffa fV Bډ}A|%}`G ^j޵P Zc@85sW;v nyd6 D7ݦ т !6{V^O0z܊G.%PM"l;N9xVw&8Û¾68oJxH+a<|st]scm#! '!vgnXi &}{\'ՠ`*Ҟ#8〄E{szg$#YN@AagmL=Vsaɂ#GQ 0B :fC_`j%!(z |0WH$$Ә N @ȕG׀i@h(,Z%tf)Zl0yR̽ZP5XЗ@씕0K@ӮB sKe$V!PX$Q3HiAk BopZZXc<,Z%cCD]LmT㥮B'.]`HEӇ))b/ s%孧3`[م+'Λՠw`AiESq(p#)# fNrĉۿlq^:W@J>yn>/saVRxfȀ#'SwO,2TY^?cE^,ZnģQ#YuW{GMb @#( b|wQӱIENDB`imsprog-1.8.5/IMSProg_programmer/img/goto64.png000066400000000000000000000035531520775651600213500ustar00rootroot00000000000000PNG  IHDR@@PLTE𔔔󊋊늊֌𢢢掎ꮮ蝝㞞Ȧ֗¾ؿ߹譭Π֡૫QQQΞffeeedҾ///qqqAAAaaa̟hhhoooǥ¶www===|||в~~~kkkbbb^^^A[tRNS #77 % έKFB9$W̬qng^Y0wqd_+# z>l9IDATXŗ{@Ì]`` Zs}w Rh<{ChH{wI{|%KLkw]Ċ%wމaz8mDl%yxz+04qi[X0- ( 1 [rd/u:F h/8].p먞?LWG>vtcbѵ˴}swB ..vNQ]Fq^v;*']kY맅jDC$oQ)䆰uHސ oI KBQ B)+z|7"#>.%2l ~ d p=x E@>@$ 7LOQBdU`LͤR8_/'N0ôhCMГ8:Wl@ C\Icp*w%"!H!P`EJXkP GVSozPB&ڳ 3Dlqp51G&AȮ}`9B"ar( C$MQ @FD6  (QȤw^k!T`S(51 L܃RۘB RfY:]`"Ltq Yw"+d@}@ (Vo&Ţx"*08G@^8&ON"Hc*.叫.X>  ˖3X0RIm<e|x{aP+J NBװ#kqʼa #+U%xe!S]hUZ/HL6p: Hػi6X羅Bj$:tdRerD aӁHI/\;2Qo/V,dh<%8<4|˱_$OR" ĦMap\8T \1L|)yg/8OW-fT+<\2$;,'?a\ G<%ҙP( ΅?",6"'o=PNJx`,ٴb"j$X̕?q$2R+~0[f(@8>62|+ l~cQ/JccߋWA;|]K㵓Dl67xnk֬1Ga3oذaǎs=ܢEjcJ`&VF(^ _ZIENDB`imsprog-1.8.5/IMSProg_programmer/img/hexsearch64.png000066400000000000000000000066701520775651600223550ustar00rootroot00000000000000PNG  IHDR@@PLTE𗗗勋񐐐磣ᮮﮮў엗羾ιΠ~Gࡡ'*Νرސ𳳳ffeeedH󸸸ǛĽyz}ӪnmoePII׽ʭhhhǢ~~’Kɱ]yDlCɵĿwwx{jaYͧha`bRqA콿qqsvi[qX|fN6?Ba=ӧÚgps}tkiOX[Wk_TtcQCLOfYM*36sT3fTBrQ/&)3:tRNS!7 #Y&JC$įyqi9ҷ0d_ 0IDATXÍ\SWR鲶{'#$H d4$@{qmA@TTQujVZUv==/D m^^Ϲ{yKsn{t;w 7\JϞ-A젙Ŧ^lGϾ& C.-d9|4H^_ݧaDHD ybqה̝e\ƫ=|d}` N_7*ϝ쯩(:*_^( !ճcshGwXX(6E0a?Ƀ:sBY,lA b[{ܫO! 8 WiA4"Fp ZdZKC v& 4 XtBpd#ڥK֬=Ytƪ=j; [2ꁽ[?d~/:*,YTnu{ւ%YE6q~Dجwc67]gO9 3ؼS6ZCB&5wDHŒ%KFgp]δYj%4RȡHx%`З3B vqg|S!߬<i]ҹ45 `" p-56q5Gڞ>*&}fe%li8 ۿE_nh8En@d<pGdB3ϮĀ0`ial%, /ZWхQSX&8uAJ_pVT?*Q-5ᭊ+` cw@&- 7* Hk 9_V]>!T*SMh Gʓb*·!*uEɸZUe$r9\P;}$D nY3ؠ]:ܰ` nMеQ߆ Rᐐod O'{ڦ:W(&ypa(E*o ST t#o% j@M&{DCj*?iz0D=RuX5 Joub4|5nwANC -1UHc1&ejE.لVs";Zj]j2xe=pv/pi0AB.QƸ\v.\'yTnqR*Q- Tr ΒCb>\Dky*%x|)WQ^^vtQR`}m 3`mMJ `pנ'/TBۯenΟ${}D7Iө@Wr[AH[ f?;Z Tq[]xV/4,$-T8" vB!glpwDwH`?]fl7uJ$Sb{sۂ1uʡX\uV:={ [_P''f́.ٝ,âM[0̕wGX< r}|}n 17fHs$7F(%--IkQ .E0#݈'ږ `EcL"ƌ/S imwhI8S"nH+xf$4 A_dd"hPA^x=\8*;TF]8ɔ Ғhg>ss)qa8D(W|=$\6萩7_JnsKolc]=bQuS%m4Wp=5ƾZ, ;O. |UG1_yvu&tS?~ox6||PAVz_IENDB`imsprog-1.8.5/IMSProg_programmer/img/info64.png000066400000000000000000000056471520775651600213410ustar00rootroot00000000000000PNG  IHDR@@PLTE씔򖖖׎죣ﳳ詩О몪񼼼襤Ѡ{333ա٭jjj///Ἴ444zӾiihw˂EEEuњsѰ;;;---&&&oooBBB888((( ƪ|||___*ASFFFAAAȷxxx???==>666qa]V:. ~ tp`RRR*** }Թtttfffbbb\\\耺fjNHE=7'YYYNNN###臾焹3yϟ\["PrIII08?县ol*ȀijW!U{!Qu(G^LLL->K'CzNtRNS # 77%˟ B8\H$ËiWJ.京pürqh_%HIDATX}exPa@ ,YٲbCFswwwwwwwww~-e{)OCܤ,ŊTi.%萮S"dhuSf*6f2֭ht*̓H?K? x:'pnW5UZ>*M ^ ChGL^d! G-dq(cUW;9Ѥl\8JxjvXn=[b:& %| qسrxU Iהj(Zsa/a0VUj;!**Iѻ4M#?߈)%A>Tߐ]"ɾ}Ń{H1T8$hqsFT y,%EWu{a6D ?kϛw&~%E#JQn HV!u`p kXq~R-JObDAtTDpʚ`}=0yCt ׫cdaUD0LL"QO1+ٮZ+xh&)P°eip1r,7n $f0=aO*C $~5gN87#zLFK]k;0 X;Tl X=7!auQĥhl@;8뛁). $@79~(*pq0T0[HO[ը mW6E0opWB q 2uhp@`xE ΀ܙ`K!8-KtV1r+:3aI >*>c![~+|x̧sl X6 VY7!R|G^1i?{A¼]NG"enRH*u`KaA G\ݻ' }<"/穾d~x|L0fhCv=@INkxl2HD'x2Wi*F{& nٱ=T5qHV(ze8k@-E#GFQ+Sy}^: ;zg, :n|,o|:ho{`_dFi|ACaR/өԸPPLJ='$L> Z ?ok4 <jLF-Ω#}Aai}e0>g0L@kޕ#HtpvR,:l1PXfI`]chC綫1=)͠11/ p< 9ʤ]q 䝉vL㓽c;,q@a|$L̇[@͟Z\LG4f81)#sTRBYAFRষVan;̚sk09Ŧ81 y8D:̗UǢј{ Z.'7U q0/@MI,,OizRZ*l0Tǩ{}8qF5DB`Di5t9q`F`PP#iVt?P{jTr3z@ ,I‡D.Ta%논fml2yN- f`%HƆe0<=ĥr YZ Az=&3:J. Tl@P& 0au\/Ldsx$ 8FqwȔJPY3Vkhh' +SdY$('~ӎe- ua1h" {aLv21g7L HJ$%oQbRQzN7xwI/?]!7(?mCc[ݱ)1cFB-WlٲY$2E()WeեHJzi@PP2뀈rIENDB`imsprog-1.8.5/IMSProg_programmer/img/loadBlock64.png000066400000000000000000000056221520775651600222710ustar00rootroot00000000000000PNG  IHDR@@PLTE旗ߛ֋񦦦ꫫﴴؿιȓeeeпX^TZGE7-/4(OV=5JJ&ž[91b8Aޛ֒AIB?B=@:1$lSWHO=+3 ̰LMҍr𿻶+4۔q便hhhPVOR# Ήz ڙ\嗏vcX938Dž⇇wwwrsvqcT"ߏnnnibr\XI?=.35 - -~Ѻ涬ɩըख़ܔԎ}|mӶiehLOֱ7lj4C0t&*" ՔA& R!ϼěːԈɲxuæmaaaVSR[B:9O1(ÎЈJ  ܫ g[\CA]@k<Ԝ76v,bnޟ կյ• vr/*1tRNS 7$ [D%rKڽqi9.OUIDATXÅuTSQ vwcLPN&9JAABJ@얰w{k΁]v9wF:4ogٻi=UѴeF ѷiLF=h-w޴o}\.Omi\Klb&sL:M+ IW 6wQJ^Rʰ#xlrHHbCe˕i}.vL*f`D!! D*fcHYjrյYA$y2f*,_k#ɍ3dPY4nM, D)ˁGRJ;6!ʜK#}k "}0(~Zf ,b|"Лd!_NM!rje+d !@3W a-YNCT}\`뼔 =G^\ZJEiGTrT5ly.X`؆ =0 =X9|<2e fn`|ܒS_x@r:$?07ĵQȖH$ȑHN?Lܚ?{v ;"Jj!=55 6C_($=.l z7 % $„M1N.x'|yuQNO,>}*bSBft4_$5.mҙO:v((s<<<& |YڄLlafBuR%3bf~6 ^=+# `$ડfΥ$xPO`#*8 L7/!/33/a'bު/~zGWzy99C?ٴ8!|؀bsЍ 4i [W9xy~%AmX De&\"@sU<NFD-^|aoOHvuwzo` 'Hrv'gpp⇓tva y.@#ceoAwvvr.2 Шޅ _ ܸ&ϋO<0vGz`iUGo/h.~v+B;yy;:RM`qpȏ\ƺ۝a `Gv2Un8Hnڷvak&4 lR b=!O(A 6 6փňf  .ϝ{F(@3 qt7DAAt1npƲUh]`4jnd6 #zxzGl&עNi\.M q}67=-]f  fpҗnpM/{m TsbMٝ)FfMT&ɂ??ϡl;e(F=6mQ9KXG-}(0g^iJ, , :֞my(B1^c98A@:~T0s\2ptX[(pWlsL (&nHl! _ Ƒ9-vL{؆cj`kGO8q~ ia&LlQHc!<84#; p1 .NEE嘌6,L̈.VTn2TZ iDW)FC =L t(JfiCNVNIENDB`imsprog-1.8.5/IMSProg_programmer/img/open64.png000066400000000000000000000127101520775651600213340ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_FNIDATxԛ{]U}?9sL2$`KbU >j"ЊE,oTyQWE, _# !0Id2guǹd<9g}u-z{{k OqR)Vi_s[UP(aB2h8PV)9s0{lbO>@)Lt:^4662gZZZD"(*>ڵk !ؙ &ٙ~:!^^6vwZz7 ݸq#tax(X ԇ˚5k*TG/$fj".Di w踊zo㻯!k* B$aŊϕgG/m,xCJlb{z3ǃ^(4r0œwW= )Ee5#h4Ypܨ6`ycLjF$I0<υ_g; ֺf# v13nF؟ +h8̧_~(6\Ƕ}0fϞJ6559sLIa'WOiQsy\CiO0 gX,80"FIu%$VXTe=“oؾYs')/.VJ)miPb1<ϛ` @<=? #OJ:0{X9}\HV<#`JPN,fb5+r `H!8PhH| %ٗһXZy 1s-dh8@YT$$RAn|#C+}|~=oQѣ[LWVS~:7v,(y'b(|*MG|8]E cC\@P%("1J>O\좒{|qK3hOa#srk92pv| [8pHdCƝ?)@gٳX-m WDbJEsd?}5})~R¡g}f]ϋ#;cͬ jVx UJslVZJ6b(vt8ݍ9ʵ](Q>5ij`pee=:ue|&=w3*FM(ŋ:R\/^l\u) ?bfL"yq:iJo\8e~'nGl35)b{e_YuS@- MF8Gg? Ɉ4Nz1ή/ӻn'YKpO.EbY^F \V;Y 6(\nxN(vi yJ=00aKUJSX''J5 3Iӎ=qB A^~m߂u.+=3 "Ɗ,!9)1Mizu.f0T3@ ; #+F&5C͎G ܯ ҙj8 #[E}7rN1 d)4LVr`z g3y Mq|bQzFz?l84-3 P\k=99l@fSSd֒h4$P t0 k̀:ͫcA)2Xk J>BztxxL&32rŮ0y|]Ejs.mBZg|?aahZ c ,@o`:1EWill$GI)sRk=LOOOϨa&O0N|;Fgg'B#yc̲eX|9TjJX]xop&zpXk9~8۷oe˖q饗n }?mW(%D I!gϞڵݻwYd /&LV<?ZA@>gpp}ՅR+W|;/zXk=!vI6m08c眳9tuX/c ɢ!!@11װoo٩ȸhhh裣ڞ眜 {tNNȅʻ蠠VzͶgwwwPPڦž癙8$nnn44((նͼ`襥dd]]VVPP/0̴Ŀ|ƶخ٤`垞PZXĞԾú״ݲkbbb;:ѭϰ”ݿ뿿游s腆|{|{aa```MMEEGD13/.'(LOtRNS!6 # C%WJ9qi]$ķm-$q_LIe9 IDATXÝu|ak8;Q@Ď51"*3c=<?|y/! *s©$h)HE3$ȗb\?Q;w|RԪuzDƻNcݖS<̥ GaHzK R)rjZyߝZ)9!Mkz8DwZׯPq!2N'R0zҮ*Ox|<M qQ>D,h8^)DLy\Hq9KSUh؎6R\*/,6܂S`A 2xlx+@@ hz]R(BYQA _/J)R=&}>hfڶ}d2yeww7!u(g,m2j7K&qQ[[K C9i"!pi(uuub1LD4o\cekXRlRضM&^FGGijjP([)5k6gR7kHGGGF,X@ii)J)\םB;َ$}ks_%S駦̙3300ŋinn5 k͘>*$+W$8Gl!4_5`#<\^(ȫnOO;wd,]7|W}_Ȁ3gL[ю;,_~RJ< fԉhΥk:buGl=B.qdYmF$aٲe)4?dBl6KAJ)pkk+~+WzP4syF2d2s {S xv1IXC*6/ۛ%9q-&˕sUDd9{9m"!Mu5qsmeezu>|ٳg)Ftqp]wM__@H$mJ W5k^ E 8dc̉s8:--\> V0bß熑;({z<]=zx"ǡ{244)//_ <++/&(~i K.ԩdW2;I;)\\P8.RhRU MH\K,Ez~#s׼x|S|k7zHI=OBﱱ C h)) E2_E>.a< 19d,I+E,:W歴$#t?aR$/s'6X. :8rF2e Mch_OH)ߪ ?2ht2qs̩b Jq퍧>%fl`9Y )MG(3_8dU])F2nj>Gknc4Wwfe$Sjk׮ettRt]=yֆ@ENgqpqƵU FeP=Evs5d}ށV %Z$igr’$GObxtwzϭn9WgqSe){~?pu_#LCOOvBJc…E^,9 jƍ x-7phٳg{B4#(3-K oM{~{>澍2]Yp=vLGb̝;h4: T>|>H9y$cccR[[; U2Bȶqe99უMؔKϳ'vy7Ƒ0%" p Ahii4Mb9 b  m@.h4Jgg'<1::ա&$h5I׾ih1}9N2`0K/ěoʕ+ua>OigO8A}}\23TڐRRSSiTUUb nV֮]˪U8ueMAQ2laJ: 9ȰFOߜgcijj1z)6ns=wN/{9I'I6o̙3gR0Mӳ---FJ֭[.s?SƠ1LZJT`l 5'p[0 ȺuH$ڵ={iP˲H<Ԕd:Ć FJiD"Ǐw^,²,Xn\pGГatdD']YwrP(Dee%SQQAEEMMMrWr%xu֭[QJy ]twjp14M0 /^L,cxxd2I2ĉ444xHxƠًa|:.>8Tn&? |CB)d]ש0 G|%%%8p&.r0MMMJ)͛G,DQbMp2.? P ҊR9/f|>p`0zL&ikköm***TWW3k,~9S~ztM_ J2+Ɛ15|$.Or:x[fiE 7 ضM:&xFTWW{9Eqf (HlڴSN7q>pQ$eee$I.]J07 h5FI:Kru=LJi,cth)ez~4|~&!N{F':'~4͢(P^^ Νaܹ3r+?eYtww{1jJ퉓S)) 2z""c("{NRL&=R)l_2?<Ӫtg5k*6,Cq饗RYYɅ^Hii)\œ9s|lذT*E2ĶmuHW%O`_Xat>q ~ߋ,4tz‘}k׮o& 87#0B@FYz5a+2QJ144D6555[V"~}}گTb8OSr>e #dnY'|Y˚5k[\01-&<Ŀo~lٲ!皪w^QQmۨFuMiOshKRdYp۶IR,_{wϷ🜻](RU0 >Ϸ۶ͦM8v>˲<(j8lذ~?PJi&ϟyqXvqH&\|}ݼ] dl2 ٶXA!C^~e/RJ`fϞ!&{z[__ς (++# 166(dY ͣGGREo[VXA__eH$y=N [uMkShjjB:4 c{]]ݧv=Li,[ rlBgg'a8eeeD"&W!x'XnH;||ٝbϻ` @}}}BJ 逿dWUUU8G .@t'B6oLss3i2k,.=3a?_BR.Ta]9p`m_]z 87ϟ?={L|m˲:o޼L&ë Tly&"~DQ4M#QQQ1aiϯpkΝ;1{'Ǔn>4G-Zt׋/Huu5^RTJia+B tI:mG1d͚5TVV~C1dr(jhhx<~yOO5< k֬jL+Ph$;VvWDyl˙;w<B)QJ&HڷootiV^Ms j])ܿضkƎ;Xp!^{s ,RJ<8q$hR&_=v-bѢED")RE⽍{3P9W#yWdѢE\}/\xᅟ2 #ol8M?yV Y`s!{w らO.z|~1>288Hgg'hƒ%KXhc۶Ŕ{NT*<.}H|N2w= te+d4MsMhH&S$N̙3qRTeYm]׽ʶJ۶Rqx>0:ׅr[UR +B\Ra~\.0dNFQ***B^U d"NSy!x<Xrܶmm۪0ιM& arɷRʲm{l&9}ͩV"Lt|>_4M' yi`0#q),47J&(LrpIENDB`imsprog-1.8.5/IMSProg_programmer/img/redo64.png000066400000000000000000000137001520775651600213240ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_FFIDATx̛yp}?=3px --:HA莔uyIJrYQjomevRެd[^'vul$IE2EJ/EA@\?@hT3}GwF P۬8c RʵvZ;GJ@) Yk-BXuo!&}F4ci8e9BRʓoYp=B 0N !T Ѧ (<]Js)i8v5ֲEa8"Q*R~>ϯ̙3!p.u&ZaS?k1R!c޼yRcM&R c MMMX,477+eLRx4u:t3gikk#HLr6PhΰdG&)'hbZL0 )J 2008-L&Jx|M:uH$u]ie||^)z{{3ǎc…ZFc&ibZ){9 GQR"K?UܲyVZܹstwwdɒuSJ`q#@6UABZ^yQ(ذaluEjg?Kdw[zy|Kp{!fDؾ};K.媫2d^!.pܹA0 }vR^{mRʊгZ#t^mX}lyr?ͦ_^6wVTZkZ#}nJSS===D"d0 +H{czWH$\wu+*0Zp{snCH-PEM}z\Wjǩ7n8r gϞe޽0 }q5C'>v옗ذaAzW3d ! B %/<LJI]nk |l ?ſ;Jߪ6@{뭷r1N<9_k$T R#GS -SzgLuR`-߲c[}7вg17NZPR`*H2 INOW첹ɫlww_IZP322r8Blt:MCCƘJ~1m/,Vs\lJ$"~1CB?!:4>F>AÝq8(iI< 7\y >a sdy/q]#7fUk]kacYRֺ) C'J;6ZF :.fOTWkFabB 5)%V"AHHx@ponyK:,_ҕ<ՓL">1u}BqH@Ŷ >M&AKB\gl_ PX<%Hϑ(%PJ"U9a'(G~H Nec8{7!SKw5w?\!Ok6!L˘&9j*i )96.$%HGh$AQ8J⨲R D˩A7. 1(@xiZ^xj/۟>@~4`N>W˛Â:7,kCL80nd\HO աH"ck1I G)U M*ܴN0,n/?7 LBK[UM|RIH(p$H%4XeGFYBǚUKHqFWTI+I6&9389k}>R,3%/vf<|G{2ҴWF@AEZcM[$dQ$兟΋?Me7,Y< >{u$x J+@fl] "@H@ HMz˓m,n8: ?>bp>< \8TB.P}J W B l 2M$ Ξ74 -o_Ozz.O+I*p(qARTyoj4ZcCnVNS1TS U]nC"1ο3B+@KYD^>֎`\N@ Y Xe5\W,{y^<7WqӴ3*)FBDڏXV@ďJDnw↧5@Yp-FCX \wZm5n{g6,h=n3RwY',J#,r*ډ[lR-SROLh(JdB /)[V-}Ad>,(UÒ4VbŇ:";7`_}W^|ܸaQ|ptg:'Z1D Oڊ-[LLYk*Zq*6ĉX5 Ly,cb?Bhpe~9N9ciJsޚzNCCCcPK o$XdemmZS%|{=8s[଍׶0J45&ëY W?R נbR)k+WP5J D2`uu]֑m&)ig64u. ΟɗzpFp`X;+S塍5h%qPn(1Ԝϕ(I2C.|F"lRV_[{m\byq'hkN3EuvAh*፱ƢM7r#q)ZŀoKT0xl6͵7bAg3A=s{/ܻ{4 U@ΠT h\Ipd2֒AMœ֖!rq=x C9]\a9-.gr8f|{:@5(Ɗ YX{榨h]( XВ+$e4)L:3"lYx1XKU\=ѽxѝ\c3ѽh-ϔ8,IhN#"Oo-`}m"e(97XY౨IPzZ?m\b BECK!W)VбRzr_2+MM[=Ch@[,ۀ)qS~h,928}s7{hSNGQ@R -FkR@犹r1&s9~9z.m3-Ztc&Da1B#%KnsX630zAh=ɺNpd {[Ȥ anD9Y"k{k A>3'3 ᵭG|/_NȒhFz9 [Xth)jP䱛E @9Zŭ44=O00o\ k49b!!aa:mIGZԂEӥ9-qbq]Aenp9w_X?Wp 3 1XSmNZ % 9KOGXZK(]D+еt! yOII.{}{_>㤢{lݢ|XO\~֔ܐϣ?~?t::.[y=RF,^ߌzRJ_Rz"B DItr*=)- o(B߂4?rZ") _o=.*޷0RC?4>7jrЦ{,Z"@L&|raX[73252iHg~&ch :yRQpgtxx|>_!'ŕ\>ʪ\^=9Y.?է1xI {wFkp .9sBc 4DE6̳ x?zlS _G*ȸٳ'E8θ8?ZcB ^:Ȅm?|Bw] @Yx1Bt]W ,A0ixUY@Jຈd,;g'^z1#/ ߭ NX`ANJI644KּX0 ZmM00ZVY|b3's1^KZO>yСCiOܼkS+&&2m5*=#NGGx[[cL毛sJ)W) "OʲbMy9w### ~/ czPa NM T M!]J!>)VN_±4$IDMuxYx1k֬1Dr)Pi?a)7mD2dݺu9)eڢde6己G3͸xՅ;+C BO@)21 yWxHFJIlذT*ڵkKx}=ZOF 8x|1!gy&J)8sP $Ur/M &ppA Pb4JG _(,(E a>˹̽͹jnÃ>Ȃ 8uB[;N_{v矏1q" PO Z>ߎOĪEu MAD>(Qgܒg E@ Z w\~Oz$Xk xN; ?XcL$4558Χ|?a۶m[.r-mTb,w.#NµqD/ꌣ`Z( |?9& aX)?s?UG\._Z.A@*g[n۶nR:hf!ߒ$n D4|,hVhcȋ4m7W?+93t0c4Rj<9J)QJdرCc>_={pG[^<o,hI:`eSBY6 _q;ռvwz} S& &I3i[kͱ믿Rl|5RkGFFH$RHff30b9if2,TJc U(mPVAi&g'8Q_s\?Z\c5$wrUc#ɐNSZӵHcN޳gCCMeWQk0jZ*M9 Mt&&Uwsa3g|d!yEl2mXN݋a"\L&C{{;Ƙ7ڐg,rPHb@]w6eB M`X@!,JA3p@ȗJ(kH$+?eV uUPFhBpw}y#f[. ?}oЗBk9SxG,ۦSk-/2˖-l6BDL:|{7*Sn"f9|ԉ&P-{(i?Õ}ײi_z+>Lh)tttJxW⭵3/Ko߾`!˂y|&q+_z&4-?G'0!JnVAڧK8y_w}"H6嬳{yKPliii˘dǎddd$ ֪2%?`om;;. 4%U&.7%Ufai|-Cly_P qGNgX|9oRi8`& RJwqF֯_QtM˯%+f(4tIbn#s_掮)fCTVwdRXkYjO?> _לs9nnA )y pܴ쫴6~*Q ˔Tu }eŧ]wp>u-7Дm%B@Fk]ab"I'=sD_㵲~0B0::Jkk+LLLP. À0  Q\,Lpқ)rPVƋ^eG}_&\A(1FTL)YRDWWW%9;# yzs=(m^Y85=b3n(|gދ(*~@ɖB&qòrϟ Oq!(K]o!ҡ*~дrt*W7 s/=#{7p/i9b&WVI7?unAAM@1ֆ\.DZZQ^b``)%b1"H)LZKhe|o2ڱw0-&ᚥ͉]k_/zT!SYʤVmm-hmPJXK_>9FFF&bֆxk?ǚwn\y/0GVN(bU!OՉyմvy\uӟ۬`rr1pI.}ikkqjQI\v W \Ν#;ӭG NTwIkk+}H)ٿ *| EC%6<guB ӊ'| hobdr\Gy'$z_ٲU)'q1K/4( 7R Tvxֈ5+]_/˔J%<#HL&&de.{֌f&' U+Yc!^gjaVÀv.]O<mdų>˂ 6yTz[PtWF\.TSݜƘ:Ō oߏO9HRtttA&ຮT|>O:dB+a׊ixr[Tf]Zj< ѱemU8FNt3ypt("$DOTĿS`]Wv~2LJ)e|ߏz4W;sc 9s^̙KKKkt`t3Ssa"P(DqMJA6exx311A&arrB!W,hiiEkMssKuߊ1 @VVXkq/!%usL&b<#hDUZyԼq^&C,BX,_kM:&booj3ƿbVOߙt^]-c]Rʲt]wu-]]]ٳ'"@Mg MWW͑Lōip]%riGFX`B ͻ'  IGG;RV1 )*F#x$QES ӣȌ\4ɦ&͛WR> 8.hiimooz;XlYtFQUfM,x *JM33PTDJzM>]}k-ApJU[L&Od2+V|駟f``5lݺ֖(&Fr ԟ2鞞h@kMkk3b1xJ9Z<óg&lWG|زeKs= 'yя~!A L'vKq:;;XRj /088%\BOON-Z5}A lrc=~׮]\|Fgzs;>V_M=]epp￟O?{ѢE7 !ZkSu oܸq} Xx4콁_pAUE_dƍwq}\򿻮XkH֩ q tz?ߓO>9sNV^իioo?oo q.ZkFGGygd՜y晿>裯EcLl HU)'#l6O_|3_~e$+WdҥRƩ G? nh}gbbAq5kְzYd_bZW_)%T*iZccz׮]rhhL&sj5v#BLVS(3DeW,fi2 dVX;ꨣ>B&!DqQNEB RK)ٹs'CCCca\.}͟X,a5ګmHqt R#f `r%mhnnsNvuuζ9IqrsGv8ܶÛ[* hhh& ̉µ魺ڛ{|aj&e# Ԕv⾰wwwmN^F3C^4o/)Ą꺷ڶɤԏnnnreVc[_WI44&#"\K УҤ~nkND7*7Ya۬ / ͜ϼӳӎɲ|ujsӶmiaaa\M3ֱ1)ǐyHFh]SMٵJC;$pϰ}Գ  Ƚյ<ɵ% x4 ' ~ڨj3tRNS!#7 GɟY;,ݺyެqngd_XIDATXÅXRQ(2{'pjjZYZRQZ P)TJsTZVf{{~9W^}8?^N JUذ +дmX|)RBX?$,Q-ͫ( ,?1-wJXPPnVZ J~d%QL$&RZ ?.*\mWbш*D$].oibYZўoLq-XQ^2M?tz(-l5%d"+; = WWbQVCbt)J%qVGτ=O l䦜tV5EyvD3W?u:(J dv1(znG'Dy PDfM%[Œ" 5mIt|zppp>}WO׭pP_$2v>6#`δiv=4G>cW4GsMbB/d/ۭ`޽z0ju9P\C[%x Y1#F Գg/R&_" \1paZmp0cG-^4/D"(]RHAo h%`1lqu帰ya1` P }&Z<~eʼh=n aO~xL @}u|V~F вt+ypm45: @XL۰TfIVYqᐷ pN4oB*5>.&U`,#lwݍ[wȓxB( ٓ0É`6vleȤbF**Jcƌ#GNZh6fDzE=.e"Sf@ U sܜ9(77C0;bC,U<o0GrK:ȕ] Haag<9!?)U?kC##@qh [ MG{mI Ay$Kv $h4eBؼ$}nԃ[s?5 [P QDϼ7{!5x8͖[ aGn]`[BB|$ |qǻu{#UA %q<0hr+PM؇R*B !"s )J u\A@åLp-!E &a)'٠@\3=^y\ɭ́4Rwf z\eO>?jc( Et4nzW,'p]w^bEɓ<,_K/TR(gx?s=G&aӦMuD'ZN@)}V@c\GB_wɫ1RJ*>,\q%~q%.\![l!XuVKBJ4QAC,}F>+/o=6Zkz),Y%\rMBpĉ>oȑ#\{h,$H?3;}hK222ɟxwHy޳e]5_?֬YӔ_)U'|+K~ߎ#BPV.gꪫfo@ӌ2p%ˁ;8v}tف<x?ٿg/e~"\DݻB$@k\޹cǎJM6A1333ߏӒe+9c,=Lo3j ʄgT2'ugq{w&Nvڦ\}l'dpp۶}1;Uryٲe |揉';Xz zɭ_΀A@t >WB'făLH6nֱ{Nvź|xg)%J)֮]믿ΪUǥR oJhoo9%͔]ziaKߋmULc *q`Txƨy{U+5ͅ]DXdϞ==]ץ'N`Y>\.)OMMZ73be3ܾbh[G+k#szDtƀֆLCkC78\RĮ]nR^8R~:r;gf9u4= zCwprX~VyYD|P '$ޘ1#69%+P >>ԧר:k^@Ra޽MQkkkC)zҒJ t:8u2+PwwwcӼsp'K!w]6#]/$^7wLnzLCFY>yQu\xAMO*EqV( !% bѬ+v1Y|@WlFN= @53d?ћ~hLFVOxlY ^ ͸@;H2#cdbctww#S)Ňv[5@וW!k^눏At1s~@Տ} J{D7: RTطo9-d$Zrctuuݜntm+INhmyCaLh L}>\Ia.c?gcmWRp!hgg=|?("_]p=L#VSjI`}4WjU b]K`*G3EC=Iá*!>bK\M\fdddhsPԱmqlAF͒7[-jynza#X8TJSbJh(Fx1 tJBd>^> S)5|њؔb_eh[Oזk_# ' `*Ut)ѕJ'Zpd6) LΦt7F==Sy7/h`fz{ϡ㽗cӨrc\z~DdJ)1zf=;.EńZ6" iVR }*]ǔ(Hg: 3}=}}=?rl V&֎+`%Ry//A@k)J/3/a|!Rh - 3v '1"֪A߸l%²ѧG#A!u7!T*eP; qbc0*c沾F^)vzMC gʞxs~8Rb9J}ax݅q&/ ?QL,"C ̯\@jgZaNTfg''-Fb7} +et53Σe4*ԧ?$jtita{pͯc%t*qfX8߀{C1 DΗUV,99$-t@:b5C6mhiHH:CthA+Het?1=;P*! #Z@)}lL-'}-8 tHq0^P8|}z- PB`iRTz q~_|z1X1_ _qг^}BOoh#B6 L:F'8A7t"7mF hB@"Z8͢C{^` "sJS޽33-~ 39GPj>A;o߯ޡ1#Dx Z' %F03Sˊ W_J{vr^Byyl_&mX9]L#6mAگh2sQ]-P:N(?@=Әn: !Y 0t HV "C(֭P.#Ej$2N.,9 g>mpR 4vkPanMg漆,K0]>x@- 9谦:|TՏ8'W\Yw gQ1%ScJdD=poMɬA@·` R T&9 ff&,$A.R]dTh}\g۾J5҆NaUiAxF L88AH ex, ͟1F œ @4_!e4Z!B`ˁ154K_Mh,zt'pRZh׍6h&%4y! x{1X <31Qł < *PK\cN W\B݃|+pR?02R*B:El.9u }ͅ/48!1S.7/K1ؔpPikQvA#X6tt`l Q,!xи2'KG7t7BG'FJ,al̟R'̖3AƻI~K|@McU !%Fafm3-02ʣ) r)#82 5pr85)!KM!@X Z45BU8T GId3y.V: *YHE.dl'T:%{U8#LїʂS,]uy>mz|GɪM¨R=tKI%Й뤽}ސx^R,YAݽCFsO~2M[(Ⱦ2K,Ql%#{?² 줧  tteZ94 "0gɪ*eW(6ő`wtSGO]p@v.~WTH)ɤ3,_4|wV*^C/w| M~FnԽa 袯> OPe?J TjP 5wLU˖0>ɗ< dD^`yeKtᅮcQw}}1KZb !JmOOMMuE<ϫL&êw@Ũp[$,p2>ŪޙQsSSShqS$m.{Z)dBøkf|ݹz>~'.[ؔO~ 02_B7%&`g;kYܽg 9сzǤeim8~x A1d2_\; qzԴݪF/ۦ(1\+C,ƹ}xd%K ( Hq]p!Gŏb$э d3V/_Iw{;KrzT$x9C1Llo!;X~-z믛R*4}&''ɤ,\ |$jiiIooR#G =ڽ1l6ꕫjpz+%1Hyw]XTa* 8ن],\wl$<ɽg˲ؿ?L^H tvӷ`ncڵ!n&zzz>c,zVUo߾'~_}1nFz#6kV5ޘe-8*#Tffy: r.西H3g'ömx'ؼy3W_}_-[>!DIcY]v=m۶\wu,Nh$$T*OLP ||q1i z֣2qRwf۶m_ke۶ej'ՔReYw/ѣlذ 686_;=7vN5;V8NW^ahh 6e˖YCnU9Rxt[K&app+W^;3(\Oxv 6~'+  144eY\zlذ+V뺾1MQ*ڔRF)cʶmu1y>yСz ۶rr5 1+YTgE333UJuA $FS `c8$+jz'"Dx\{,tttdm)ղ,0"`IM+{IENDB`imsprog-1.8.5/IMSProg_programmer/img/test64.png000066400000000000000000000156341520775651600213620ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_F"IDATxěit]Օo{O<#`Kx£)*C-B*NV*(V*ɗ":+StˡRS *!)b lc3,cIe˖d֛߻cC%zýܳ}}3($I8$IVIuRIeY.|[uB !#E>g).0800($I?kr~5Mu Ȯ6 !1߲m>!W̡(G嬪5Mrg$I$I:zMZeY,%Iz0Ncxx!̪Yz2578C.ömTUUQYY}]YoB[*ZrID"TUUQZZȲ\k?\Ų,r H$c…$IneY?}4,X`08sd(Yq]Q:::aɒ%444 E]|dw:$4mmmB!l.;UOZٔGDtٷoXx}ZK&[4 T!_l>N3U3y$9}4/^,O*dYj.[v)֮][XZ檳 d&rv׫JuKof?faHAu?uB+l~c\ʛm2$I²,$3gqGrf٦/~zLӜfs OOOCÌbaRĔ0WL-ImxbinnnjdDu ^P(eYWuvccc>ts(B8BYY)`YL.uZh BlۦGrPqqqseppPE,21~ E71<$###$Ih)52wƲ,>u(+/DPTAQ#Zs%VHTǩq+ݻvukBpD~$ n\m8z-Nt|+ %aTE\eb"5RM q˖26>[_j'< qdY%۶,R^/N#˲WVYIqI =?y;q zjnJ.D뺨aض]#(Uf'[ola,[FPvp I(Ͷm^yv؁CGg'uhɆ67)ض뺺$I>%py/sV$I_;dͪ[&c ?! ۶͞={x饗p]Wstdޡa+I$,nY/%gпZQf..]"zs+۷Ȓ5XrΤI™)p'luٻw/>,4S]ݴkbhdh)\gR^Qi3C ڵso;0]m(TYuיþ}ؾ};m)8,) silPQZZ[xG`arJ֯_?(; "ͼ?@8q[os-xu uv>tvgEӴ ?1`]=z4$E&Hm066ٳg ^{߾}l۶;v(3##dtvvPm;0yݴm>~3,^HD? x,΂yghoox<Ή'8|0x˗e҅#I9w巠%w'$z4.I$qbm;zoQ0H4-gdIEHYY4"f׮]755Q]]='QyGmJKK|Z~ .L~7N}xxX,0}XtB:;"pۆ lܸ]yhvUc&ъJ}#  _*@rؾgq"PK6B GQbz뭔x$ ^|E9eR)hjjTUݚ M3˖ԓO>§s 0+ۻw/xTٖEu}=wn MQlx yұr-!8s4# m[:z9v6NezPU^{5xR7De~?ifQڡp~$I~^'Ore&L×%~?/͛۶e%˖Ӷbd6I<6MSOS]S#5yˬ YN$'Q쳸5Z$S):Ώq+ᥫ0M:ǡ_~6*y7eܹSx2t9FI8HMU%hnn&Nsjjj5 qWfrjYF H .Kkk+rz~/c+p\ Y .!kz@ ӊXYa ×ccۿNyyy/)B4EUiU'G3 @WvzF$ BЇ/;o#KL:Moo/K`,lC$dl6CiIp8/~,{^ۃS_˱bUc۸8BȊ(~>."kʖ֮95ԩSȲLKk 7tY.s ^Љgstt-Բh<^222F"ulEAnhj$OsϡMgKCtvmj&1)D pHIQt'p5EMyc_~_8! ><<\922}IҥKQEQȟLnY#z!zjB;C(pWl]xu'?yb+w/jb9s31T݇\8i.u]dI4 EQ%>>>I> %+Ɇ Xd POeee!PZZJKK ~p8̹s +K&!LN{N*~M6Mmz^7yv^}᧔ghOٶ\ e'pm3FIQimŦ hvNt+WRZZB:@6(BEE,SQQ駟AbXQL4yٵkwqGq33@,Y7#4l;L#I*B IEM222B$A$e%EQt_|m .,}yQ]]u]Ξ=ˏ~# QXa [AL$Jq{n kkj`a(P䳼!2Wv:֮]ŋ}qpϞĈ *ޒZ_*>$IY<@`4rn >NlΝ444:477O$LE"WpB{1>3wks19QRQQ=4櫢( 9ڳ-ųM.D:FMu >w"8ylٲh4$̽bm;v&N+&-gvj7k2(BWW*WnH䕼uݐ@Bdt_ܻwo06m~gZK 3_|'ؿ?---_~?(캮\m!#P]$DÇz{{immYg7Qg}6ZksmfddznZ[[ikk۳p/+286-/0h Yxĉ?;sNDc#G5-4M twwݍ,,[?dYa|Dd2"It@B؀+E Ðx㍿ӧPp8LQQPhZ\$I.숙l?"Dħ[P4XX,8yhѢf2eYaYe-8T*%|> ̙o u,`tBp 9S<:M1fF$ TUF)++KF_DG-Z;r-YeeYt#?CtK.1::J,#LeYw9ڲeu)^-(@IN??p&ⳚN*%>p"JZ*rZUu]._D" 1Lԁ_UUD6eWΧ,abo$0MoveY˲ܙ҇iSVӲGIzW1Ȳ,t]5Mn~D"|B<2lۖ$I ʲ(BIENDB`imsprog-1.8.5/IMSProg_programmer/img/undo.png000066400000000000000000000140771520775651600211760ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_FIDATx̛y]}?ޛZ;-$5H-$Zmlx0& 9q2Cćqcf|l3Y3/`'pC12AD "o揷ׯ$STխ[o}KU룲8Z#Z97WJ@J9O)½9ž +!r+Y8pB tI){ ʏدUǡyQιDŽ0 1q!*Q *Ҟ e*|^J ]`@kkDd2Imm-xI7I)SN!@k]*ʰjV_e֒d0 `Μ9̙3X,;Rʟ( lD"R0 f+Gd9u ̝;f"Jϴ$-}CY.̪fx&@0 d2 ,D">!DLUUR)1d2y{]]]nϟϲe˨9u^<0J)s! ,Z󼻅/cl,3ge@*Cc_رCR)֯_O}}=ƘTɬŋ|`ђ<ϭm<'P`DxuV.B֬YcZ'MAH$*NL&a>uVb֭+6R/=S|oEla9q;1{l6˖-[cڵH$ry(NfY,ZkjǎD"6lPR @R iZk6oof, Ǭ KAZ5j^wwL&Y~=AT}@5KRg"m}|plvJJ;OKL"$ * `JUZJp mj9~0 [Yh4J,Z{o&u]t@JUb|~2>w|qK/E*nv<h1@)FLcnb D"VZݻIӷ ι?줹):_i}k!n:6_̍w]Acsl{ǎ $"O $#o(UT.$ CڐR-hk-A|8N/aƍAR꜅MNnw=KVbBx~~ y=%VTh0qbX ߥcKbɒ%ǵ1c̍'N R__O Z>vdVfls4+[=j}chmme׮] 755mZ\yq̙3%Ue1ЏX+|A1odb,CMm)(-QJsH!1kV-QƑR!gyd_tʹwf"r3bAMMMظ2 't:nRֆBɡ7ݷC#:.M}w{ D$'H%2W$'Ҍ}5@0:T0  VCDX_RFGGR^yZQA,SSSߟ>m,\;4͎3:a篻xфO4  zHPFDb4x$u݆_7[d:FFF^RSbh*upv#]VpA^yS"x*\JӀA &%N Rh_yD"-hN(QJ[]CQylc|`l`Ge#>Ņ+Z 3xma'V !2'pHQ!Y% f (OKIs "SқdHs~8Hy҈ů>wS27*as?'a xٳ~q9\s3~ v~X?So!r7 r(UT8 ٦@ < >N;\-A}恐Dj3ʚڙ/jklX?{_&Wlr-s*a.i&%.R:eqJ9Jܤ(J%x:p- sXT߻v{x5l\f.M;&Z)[Y!9ua%Y鸐 He h!@uansT8:HYlތlt%-n?9ô̯cYMǕB2clQlsWk-~̣!N6J&F4EG}RXYc #,飔Y:pڝU]z> TCn:>w+<ϸM\2]19&4α m.K.ƲK硵-r#48jcy?p,ȄӕSC@'bh~MïqN[.c%hje׶C j SX:F=<_3>bx8ED>@w<097-BXl~ 310 y3gZyB~擤9Ɠ"=4+G?kɆdan&CKXq()8}#5kG9؛b`<$krTA((c%β,Efeak=_Ǘ&?||Yk/;#GQp_[dBdž(cq »!ێ 8:jhQ4ZH'rKSd^33YYyZWq~.e'sfzzFc>NH|p:<+fiV{y[CB"7"sgQ<7rɏb44GvVG&2 rud*x_lM:Ʋ6AAgAdl6ZeX?XSlg+GRb|>rR r b\=OhYxN`lNx! .^u9P8PR})HiFFF,k\@L̿Dͮ~:灵TɗWS.c?]Ohxx iՒ5J n_͹sqsC}en7'?00@cc#?rTJZ fzzzK;DD=1;#oDQڪc/Ծ~.\mH@zyqȑ ] j0ZǁCCt|Fj A2CP=a022B<c޼yI)k-l5kV1weɒ%e0$d)eJwa, n$vٳv{6b>$x>u8y5%wG~Ν;fI ðκkDK@+ȧτ.;_ec-s yc?Bd[# ?Xtg_seaqK-iH$\svB݁ 7ܿ'}9+Ȧ8/CS@)Zk^~ei[ܶBzF! fKK#Vb֭.RT+a/\>Ԭf<_!,'GS4McWOai)J)z-Xn---ZObDse^^d >,}}}EwXj\ ;['!1D$anYn^e%J):;;y+Xx466TKRRŋ811§z㴵*7tɭ$(v":^ڢ@H6ĥ0i{a˖-\/s~M-{S[B(km2J-}7~}=JGG444WR_N.h䦫fu8gdV&A6H@8'''8p۷o㴷xb T0fHٌh!d2 EWWJ)֬YCGGǏ/^%uJ)SvI*38 *\&H'Oʃ?<<ծǏ"ek)R䟝1 ,'Mr)qtIFGGadd5mmm-X+]tѣL&;@V)夔BɤURJ9Boo/ 866v' 199IU+`DYӧQfҔO"։O$߮;XTJyJ)sE(SbLMNN R n zk04-aJ5 ?we9U  S=)%P1RJY iJ&RIENDB`imsprog-1.8.5/IMSProg_programmer/img/unprotect64.png000066400000000000000000000051161520775651600224200ustar00rootroot00000000000000PNG  IHDR@@PLTE𖖖닋ާўޢ¾ιΪޢeeeο۩! ֤!Ӡ ϛެ ͚$"٦! 祖" hhh&ў!ǒqǜ$$ʗ"g!ߧp n y È ̘Ȑ{ `ۛwwwnnn)֟(Л# ztϕ lӧʺپěXݥ'$ιÜ̸˓aaaKC'%סƋe טRвð̝Έr\:93͘1(ޟ~ڙq=ͭ|||zݼųla}NL;ʣ6߭4xU3jB&$r"}Y!Xҙ{k{kvHsa(Y:,hp>bߌWm#$W̋Æa󐿁U{P/C  yǵ#YS(V3*$}NjsHBPY16,0PPBMw"I "Oom:LSǣMļYa0^O{kcTۦR9TJRr/dk! )XQ^@x?CP08asa!ktd~bCU5*[ĎnW` J" -ڕ x/3 3p`ljjjY1A5oF9i!Gb1G6QRR ȸ@3ŭecW?|fІd#U;jT!`ޟb8\|bYu'2feIwqk_tEܱ bbBVl67ԩ?ISC4fO?$񾄘x?~R fO[>u#vN@Ya(WaS l陙kˁ&q_1}/6'OT;n|b2኷j*P'g\3^+9A2Oow3/z7=t{.F~00s 9U&v 2Qi4{?\."!>Ϙrlۧ|0 ]}:lMt>C@I"1^Í󃬰i;)>0R_LUj#!@@)B_J~d聯.XlW-`57iR {?~ivz6=b>b N>r|HT5)",aÆk6\št/05d 4{mOaDL*T1h%I pps8t (Ѩ|H C h$dP(d)9dOk.@IMmM @ z`й֥0KUnb1 2T@uAS,@FRz&%8 :z-k"{W`dq{GM |`JBd5Me#$yS$΀Eݮ/MMEF)pܦe=}Ync:lu 5qp^z0@[NIENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_1_45_3v3.png000066400000000000000000000501151520775651600217730ustar00rootroot00000000000000PNG  IHDR,)nPLTEb81 P5#*4'Y@.AWD 33f7kuS` 3d 3=uJ 3&3" 34xnZ 3 3tNxlzg0j7 2myPCW]<6Y5L=3 3hZ]Rn{fze 3gvʚ~Rnǔ\hemzа 36" E5 3XS`@. XD]NV` 3\W!M<  (^J"$P:lZ~ a! 5I4cPzu?! zuqHxh}pkCqa(3&z1 i#svke9 r-#WCvod]W99/WD .gYOIƷm^ 7#v4z`L?8H7, /TC#U+gCJH=J'A J;FTXLḳD2ƻ _R W5}ma$xk.ryn=^gZ׏~que7̾<^yf)`F(P n@bʾ:pKgRk(&RGH{X/i߸0v{fTFJosW?~#X@jF(˫CLϒоkǕ~&mPŲͳTvZnj|p-x)Xa{orζѳnFßÙ[}"+ ItRNS D#$~f!@K7gGfpha6ˑw|ïn|LIDATx엱n DmVZA4$Ǝ9'!nfj)TeN9S9'fk\bЄ% 隅qU$c`YI~Zb,T6C%1fLS'Aq dBlIl{*>>W\p-9*Ռ5YlO2G7fKWm݉FR^  DaXvc ꐩAP #bt %M`t0t)%K)S-K4xC s!K7C))dNb?{Z ValJL.^fʺ~f~tE)X%(JqwAY|mi(REa2uH7‹9bmeDM}?"eJ([: ,de;@@TZmdKB8b0٘^jXܼԪM.v EbCfƪ}GhZt:i>,ئtyk#CCVz Xʎ:+\[9Zֵ#ʃmkv؋ ZKXfSqƲ+ߘaZC*&+0"ʿ ejAX8$.[S+ZV +Pz#UXV,+ Q+ץ}GH*x]XG%oP6ݽ&quRXl|j >U]w>I2;voOÔuM{$IƄwFY,Z3g+t???PZ<+Y;v$džPVnaw"z{ܜ{lZeƋF] Qk62beiT(V%!تZjL) @lj8))Rʰ#X-A9*m v~Zg%<N~y{;lw?zύw,k-˫wmPCVUk4?zA[ѱ[n)Gಖ{ovZj}G79/s+V^}ER&}9*emZ^l!׃h?g0h07Ul,?lܷw;44}駇ɲUۊTvV.7mK81g_mL%^zF jj4o}isrF\!}7nu>BY!VU5U+. .X:e޽HQ WK(dwQ r<` ,X8!)07. P-: Eo[Vk'OFO XK̲2&vŚO~ 'n(D.>B* d y B8:aܱ# :޼y[Pd8W$PWf4@3"F1ἋhU ‰O, &y<߀&x(Y׈g/$ŅS-KD,^V4`ĩ?+҂(sz3DhoDTQD(զTlٗvjPCŊ@?6fEں?*XdPB-$cVQ \<=*5uP\( -ӳc($+Ҙw07!$g HDGefzpx&2dmaDg*w2jDҰ÷;'6W/UVMDO.Z5H4p[ZPb`D5f 1MnӉ쭭>Od9tHki= '.V%P"s5Z ABYA]]X!dx77#C;n}͇{w>i4c$6oSx ÊOHEFEvvOX.w|X5 Z2Y&ή82VVJ$hÕH*_b}ZAmAq$˵gCZ/PV'B>!/"Cr{Ԑу!`䐽T,Dbb>(:MJ@=բFmz9sw6H]Vk0 hCYFAC\,)޾[,`E}>;Xiq;VS `ǃ TVc(*z Vli20*o(L ŠJwۊXAm55 pRf°!B0ϤϽDzᄾ~`EQҌhZ`Q`jj~jkkVɲ{QgNh{jA0HEst:q<騩W9"*_v _Ltaa,!vԢΕVm\OU!& ~w!7gѩI*ɊO`LSWg^j!`-J yIY>Jj+TئIuOu4:LReeNQz{S^UavQ<*@вg `r$R*PJ}*Kf{*;fPZ)+QҎ|E`P> $+v!U"%qe'HYSOՕ&uʚK=Z|~SBB(f V?E 2M3STJveR..bJD|ulaf'ww- GDmB#L)}#\0%R~d%@7ٞ=DxX2|P68Vuا61UdE0!V⺚hfmw|0̎0 ՟KmkGfMwҁ z F" UW"j˘vM,H*+;Jjr&N%,HB>nTSAfu[?͊xΚeA`PIVXD"#ytJ@-T h k4/4NqmWR)Ѹ( 49XXpN01:3>D,qw/oJS^W*BoF2jc:u%X|#/`.=XN zJɗ䠔"nCU 1X ١P- E{FuѲhAbdcRiɌL:U@sqnXCNV_6)+aSSZۻB#V7I KRYQfV(bF`h$@ Ѝ†$&0H96N<ԙL.Xau}t9YWPq!#XU~1+p[1艤#A pHX^OE9a+˓ɬ949''Mb M.?p*rCnpF@rЬi"`_;F( 1QI&cc5ƨ_ m-UZ j+ 2-H-`QB-gY,R@Gx}E=={-CnqvY[{ U 9EQX<'Z=(NW{7g7{o.}rt유*x㌀eEٍv<0~62\Tͼ\MA.rwWb$=;]0 4:b\qT%%K!zNm믞~KڷOLO/̍oOME(hTUj=Rr!;=hqAS#AVY&fk6dwbᵭͶPJ+WPaVZSTT cM%ZD g}+>}݆@p>sc+0; ,>Ov|cltw.NcM\Yi[:}V#p<@!+*P{+RU<*qyNߍ.?^0e~AoQrIJByYlsζy9Z+bLhf2"Pe0l$f4~O8d UN[.~MgdԛL&a!HSQ@W&NM߻=hջt(3_ dV諯<1l/VR"$5SV;,Jtgv$~2b 푑˻#M *-k6QtQLnƇN$=K> !*d2yĔzQ},|}0Z^8\ru R_gˬTXUXR(Yf{ kϐG˻O~F}Zk69v2bJ6w>03 V®)HK,Zղ::B Ǘ4o>zsjȪk;|5ckD.-`1>Laxo i$zZ8YvcV* +gUj7Z{ A`ؽɻZ&;*r vEPɰ> ސi}"qV~+;dK|n`v5ˮf̲+9ԌzU,lzWY5+.߂H 9+FU3f܌d\ˋU-Aj߻+ P9r!2j7x0 !ȱ4ozfovit3otlC zC"UPV+ Nhe}^(IEË S,\(!S sE)7d5zSy^gS\ʄ8]k)ՉW^0ށXEX9J V~\h̲+NJTiYq{@*l|:w*HNAPC>Bt$%ǎ#]NҊ+R^[ݧz2oDlm-l>'t ~j\ml2XX]R}{ 9XdJ]~ڏ*bqKQKXjow?Ԯ,wԮ]* "-ˀWZ2DW"*0gFZ7=Pƈ=~ԕ܍Xw˳[Ni3D"(h)k&UVLJmbʮJ 'lV*LNLTiXU]WȜT>Bʍ#6WǙҬ^Z=U튰 . FH+#ڪYSE} H$A5cs)Щ TVPCbeekKEjCEyEf Xv6V⪪ pnrvF 4bp ?Zz 1dhm, E>L?8!kϮZɬV cKAbЪωT<˕n7^cGVlيw`%h3h/Lt2R2jlKdXŊK(eT`E+RZ[S"wg@ݛ$QZDGXBwi"`ZU]idLW=BήJaWe@E3h56Fb13)F\uT]iB4VDeX, am_~VA 릇\u!3/MD a%H:s(,SmE>ck尫2V@Yiv P31>ʊHK]TXzEQաY8s dtU]'ˋ 7ݳɖɹHA2c&K;1 (T=F-bess /JpbԶ\]*4x]_~Yxq vދnUm*$6;vh`ob%R+8PAX팶}c @xX4Ӳ^2RX\ Į8V\ WnanvR3G().#l'vXrɀϧaU@L.UI3+`١NedTZ@Ll!!Z@tzh&68V\[U7+~th 3h<@EY)AB' Jr`{2dh_NO*%n&a!̆T:h + {XzBa21o×>γ`5?yhL1*8&G3!  2#= 2/yoc)@ @ tN.ͪUCQCv0{K?p2xR V-g0>ӣUD[Prh [`aeQ(pjuB)4Nz]NcPReW"*+PVlW( #qϟwxZ^<+7,V+ /}x/zђ$2RCzLgP,Wp`efŢjSAYu]}vU)'¿/{%֓aDPR|luJ4{Ԯ2FMj ('6v +ñFƚRvEX]]uAı +=iZnc%I %:zI"j,5 v1X }Pr~LKOPex*X@%z΍ fFv86{V-);Z*=v~ɟXղG%4VԮ+V8WW,bW'va4:G38\D_ +yXR`e0DQ>SzA (,e@ L-`2ȲWg_|;vlxǨ4",nZip!0ɤ!=c[R9Hrv%bxobfo¢jIAJ+++PQV48kkkP%Hʢ\@lT(qoye_tcYDoW `J*+Ց,V?d8;3NkְhlJH|q8C+kL)I3S2hu%# j([Xˊe0' )]#א@{MmGjSϒwҴ&))IVR+%_1V4ĩ+/1pVY3v@d׮o,՞+amdDDkMFiZ5I֢)mpW9V+a&p$?M+.D{$+LJ[{?IA{Bwj-CA%vJ.t+3`e2M P]n ^v{RbmaX(ܘLó~ŵ>QCuU~T{u"@XdǎףNM/:B2WC]pyxnoo7\= ™ٍYA< >jzuwtuH6ρ2Gtkbii]e#Kf8TPQ]XeUaNTWܘk~s-86ktNléÑ 6yګAוseH'aj0#. {4s]ͤu/o3X7ޞJ&M xW+ÕfӮ GpA~OLvCZ(;/8V359$e=@u2pt3ͪgW95X&¼#M?g *Q8}8?T18H3S`n^ Zi\ÍEiO?utvN-Ğh|HhIiNRg0Adz.X'+D!PsgVqԚƤĘ8Yf+FJjkp܄,(9t1=`*d Ռ!jϑ2ehy}H}hO~?96Πb;fwWB:02,|;+B~ bK;ui}g CzK+ oYWd, VR3+Y +t?f5 :|u)ܤ7v~G!_xp_pL-YM]k -n7F&_ b-.5޿p4.)@[gڛ}KhIvum̑`8qQX;).X{h)n ,#mO7gRƐŞOJˍxvZx-TLS=3TVf$ɓ[)X7 U vuzNqzcַ M/S:]ƹQ·5L훻e!ke?|u>8ͣՉYUhWr 7RR %|AiҰcK5ɑf+0:}?՟rljdYOGRϗD\LUW↓ޘg~Wzyx o.S_WR *PUv>Hdt>2$ /.~:q%!WVy=^O&=^}Em?L4DZ`W4 V3*Z]fByE]U埢!cF2a[1_x̧ՂUzh~/̎| XX߆ush|% EhxRXobHN*Xى]!Ȫh3(Ņ8bڏ}G`?It굖DKC8cєI<[DLKB%r[~> v% V~V*io.RXG|Ak0$>B8WWWqD=|4ѨZĸx-(+$ Pjj]ة]ɺrD+=֥t At7ndzhYj%n !3L^[~2aQ[@ .HoYAW{fW.]ET|u:JE}F,'-o F{zH1݃YJӠJaI"gX͊ؕ2ΊBAhI1'6u!8_D~ytkn-\N$]ڕ9(58/~oU1yQ/JI_=ƪZ0͔V;U(D(Pps`Y_/؇p즦@ `Y4(.GBEkh+b vEYaG~Ϥ"Xt+kkw{,gCPiN.pDpG1Q VB87-~`}c_0AHf%BUj'ĕ$V}]Ik>*GImiֶj̔~ ֵ00ecm^ia ZE2}@GF4u.ߖJ eu%ԮD^ޑ:鏍%Tsss5c8`gp5hz8^0Tr]sq X +yIL iIU;4.ٕ 窰+'|z!ϲJ=Wq鴘ccp,3e|he|=.^uN8akLDZ]BA3:'8 R6NcO,>Mһ2\עt!9$5|oYJ הahxOAV sy͢oYQ+ >]E)(֋   r\'cRJfhC)8h޹\G!4^ 4p| ^3HE@gl)RڕvU"Z'sK4HA'')K˥0>.V]h)->_>zc@KL> )7IΉs )F󨜂`'ڕjFCܿr@|h7owr“e Zh߷2aM6Yd@Ko&Įj]]EwW8D ԑ$a12&q0{XG<myʫ21/>a<23]._DYuvX~RSZqR `TW9nY8.K TxgP9%ˠݷ2QZRew|;[icHk"Cγol'ؕRpOCVBĶA?ovX0ɕ^BV[\c! h ƀ|p ຊVKg|~ ogxec$ժV5 j]Lw~? E=53bccU^>*>iめfr֜ c/~Vdpha5ru#=p6+fqZЍyCӅ_C+u8o1ά mX(O*7cz~wO>=CX~uɇ:K)w\=_NWm}G+ˬ Gj8-"B#\v5,[|jL9h?Tb~@nln|ifǢX+/Xic:ѻUvBzʒO5䆁zC#R `bRi_oi/Xx1J@:SxTNJ}'Κ>{E9*01 "<1UpUk!Pu~f!.M X|eqR+tnZk|V=ΝZKs`~Z:vc`s v\]t\a DQ4 "6RReThyHw芹[7:6 *Y=c}z{1KxKʡ13ۚǻrRq.rnDu_:eT\ul|<Nb,b"F1-*XV.S] U){K\_g~m֮PɣX3 :y5V])W>hW$"QǨ&q⋔FJ3-§Geٲj=n.JQz|ժpҶ}ȂˈiXﺼw6=/>:fuW: v*)";BDGQ5J/x"T)L#̗Y[Vm71tsy]o  ͉^FzBoO&\;.XtS n6fVpaG7V/^uw\0a|\̔D qIyb]l6fooCy*Tx1,p`M}5;V'_km-{i/:!X]8K}B3G~ĵg:AueKw=f+{T"|8IGqEtQ%P oF\#JJl1mqpMIFdu}2VJw óW=1!n~9%?r< 0rՕ{I),+S]Da㈩0$' @ {%*˦jiYUQ˲҉ӷuG^xJ]>1 lX x2XAz ov0f;C(z4̛Lr|zYEKL%2S)lf2?aGm]jrѣ3Y14#Zpy :wwӉ>n;h<xუ\N-Q"T "uP-edT!.&[bɪetqnrn3\jۗ&کH;^=0Xy -:*Xu'z*Lep#O^ϝEA<0AF 0 [2BJKUfU*44׽Zbd^V(W> ǀ/eMRV)&n2B!D9CXle U` ޫWXxA:|={/\ii)Z((mYA-Zo#i[fBPYy0]NlEydL]Rxj˞l<3<(jh҅r5VD UrFdMBMs`CC`#ADENӵ|>74.-JY3k /T~0{vl62nYׅrb-LKYxZLy3>f( ( ML(+\Y "PC i0͡Q,rFQ=|(}R0mZլZ\j I՘+"(݆+UBVQE,`5tr(:nDۛ,FsjVGo=eVNδGZvQL(LtpDϛ*scrZ6#j:惄OO2F{N?P*}(zQ2?}0\lc)e\2$B!DYj *CL23V@m|* w<|UrUN%ws}Hԟi",)sKX7ФBHk2M8yxbUʤBrE(fSf- x:0L;UlO2ˍ]-Qnܺ6>1vujR>4V5] n i+Tϸ`}1l)O!)D`YTz?ŋx÷.4N&T*zshuÜlDA|~L7a-ʹ+M((f[(&f:\DW9ҿj+'/F1ʣn~OC8 VLPr)gAnKplkxGr6ޚ ӧ5Li(t!FfbDAҕe+b Ho6; d! ^@ǦY6Iur _ rm/A} ` ҙr nq4H-N-Fl8« cH zH3 `zO{v|_yqs$jhqJ,2K1-fp tDT$D:Whƃ`dk߼sqJXZJINZJDC4IGJbK9q,d~4)Zɞ;MGC0gl Yl m`e.%R>E7\ ) Hܟ6|W6#ajg@7A<lz3»`SeC%ْ1Tslˎ%,)d33XoWmTyWBJ{;@t???N`ڮϵ"\  WoE,S$*MM}SSqWam .6&v|D򫗧g\rgd^ZS# !oZ2eHHi[ۨ.3`>+7`H(`EsYbZ2eׁNKp{﫜OKz?{π5u`EN䜂Z=O*J#g̢iTHБvfH,c?^ `hnRD_{ =jXyt:ߗIЖ!VO1?V'WXZ\Xqd, 쟬O+-e*E|\{ !ZBX$'+Y+`?RY0 ZZ<С[)t*khgoTyp T2M%:Y@(P :u߫R.<%eȁ~{d5Sd22є/u6MY9* 5!.\ o/Uzcd*˫ jVāEVkGs =w8#c[E.i)ODjD]q"j|aUdI.3zJ\0hLG:-a5Mq`[d[L{1 pc$<*SgePa \n0b 4DZ6 c1-`1#O:gd4/+yHArgv`߰6M`ȉUPQ.OS/}APwV6ƋeFX-aG)- >WN:<~5A9bXWg'v9VvVX`5MԵ/:䓼$ᚐb<|RaаEVӔ{_W5׃x8-V:ZDq7h;Cbc[aQOźO.O?dI+FF8I?K*QtA?څ[X 2;`M3>gWI ޮn9,lR? X|*jX$:VO`uaYwB,.8V,o=,>ZeM̯ <˄iM ۂ*e_.6.eڷk)ͼP.˫4h/hY4q9;N~sg~9`55[K|Ka^Ԣ(ғE- *Y=L>+v־]Kܘ%uèɶ|_1 ҇Y5:VS ;@fNk#a0[/SĪymj))soZ`I 2rxj-`5~6eLٱ>2ie`!.&*O7,l VO/JPoV-#:> ,~Xl]e_`ez-˴(_|0,g{gF CQB$F ]g(Om/M=O;UAqgbb= hꋲpY e9A(귟?L.W"(ne% d\mtNˀwϣ}_OGh!|̼ $"~_:O#ֆ϶{bٺSZqbI3EsS.)d׃W/!%h&ihlu|TTH"ݤA*,!j6( F&jŷn@irBB _4PFZjn~UM,eͤ_ģĢ.@Ŧe팚C 4:40abqwד鳐 4NCܓJHv9mj .4EZ5g5Y:XUhnݤljMOC@ 6SFv&a٦yVXj>uk z^}m8rXW0źAf&-{]Vux36&M dڣ-zn/J[^WpU*0z|M r3l/*e1%InKDQ]RQ+PBXn_¤ƳJ_s6fXY6󻀌Z6fXa twJFhUM"B!V>l]5ҜhA4[8YӢ(sm~)Cx'wڧXd2L&{/ j|_8IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_1_NAND_1v8.png000066400000000000000000000447661520775651600223050ustar00rootroot00000000000000PNG  IHDR,)nPLTE00( 3 3 3 3x 3 3XıX7 {zh4 3sTR{bl|P 3gfKf8 3sg 3p~yV 3Q>5rn]}g{YSIfPR>zm_me_N3&Yh˿ծ€ 3Xó\ Ua {u M$ f1upZ+{{nh p7!7HUTOsg`IB$')Y/O\[jb9mp38Wfd'Z[|CLO`l ~9 (*saomAwy"L+/1 Q`K/eft?BuCl^U297H* [CKJ@n|zNH=eUKaL>h=ĉwh<@@~м[B1$I.J)a<ľ4^A=1 j!Pzd-;xW=J,sI^L6&?`h7SAu+%UsĢRVLAsvlQ]]^8fI4S.W|Onp}piw91$ͯ/m[Ƕ"Y/cKmS΁fk^rV=%:%DsH' ʷsU\cNxbMkS66hϧݐ|'gпJ~ذoAS}" ,hmdLtRNS| @&%D0ܙMi`=mQ[VtqI݈߸ܢ~پɤ^FYIDATx10 P Y+SB]k, w3Xyg%1glMR+Zb1NJ[#YIċD9=Y;;Q3UsMrFNtKJu"J;Lw*/8$7߱{"S;^G}[TWN}{eKm-ދ)zc &sP/?h~ZeTl+lEi_m0ъl'WaX&'dm [J@tveU-vʃIy_pX.5kƻu Z(-,,.v߇^eFL.x0)N`7aǭM+X9G k,\aEvX9m~ Nզu Q9:[B/ϽR}bX)5_웭N@75$?@*h>C}'ؠy ̘WEB]t']XTt/g~ٙ18,-k %[ƿ:<ꀗRY3sD ;C@ ҶDC.-фIɚM[XM[V&喕äR rQil"X@pŦmɲ0| G 79HJ|9XԣuKMȼfiemeb0'Qϓzݹ:c>Bttz}RVY|e {{4J9\,g?kAe/Kexi@0!F Z? a?aBU#J,${[<(JA EE$$&BU,P=>dfe/5OV[o kW2XXwpƃۻ#v\k.m%zMh+ti4^ښJtl]? ,Uo_?dti;ZS*J!e3Q Wo į-f^toUi}΍n)fg])y+Zf.zgEY_ f6(-T<(Y6?-|ӛCMO[==CYob78߿BiABYI?~\~Pؔ$}cʹyt~L}eW_AX\|0+JDAuko“ AX1Rzuߣɴ3qk&gW: lkŐ(m++x$XȺNȻ7bG_nJ˘t7Pi? pue!- JZ48ƙkifKrL%'Q}SJU3u^ ~^Ⱦ8pj$b$R >ӅƸֲ97$)If׫KҞgz^=u틮 4j :8dn ˰,ð(eEJ L) ʒ(;NSZuE;? 8g̟U3O+a[dXFڂaY+/Z\*Γ-/w=GwWV$=plAH8^[y=.OA).@Q6eF{O5}*H8mymq+{E))ITl8VQG*aWi#N*qT=Ip X$ӹ[7o]V zW˩A)5 Cg.C3:ʓ80t)wt4r4El^1âu`Ig/ݸqӺGd6[WcEGl*Jܙj!=PZ3L.Yn#q5XUv.KnqYq'.X[>"ha0`(nXhtMCYZ\hȌ%SVJu/)޺w,?z߿?héqtX^Kj9`ϷHyױH2rB!s Ǟ=1eUs{jx3}q2>Xu쨣:m8xeGU -.#hjH&F\c&)bH1I &&` hhfDjOpPs~O[ȫ.R V&&r$W5ջ0ʿϽb|Z{:tRZ2S7OP`eXM RЪx%󴵪L3*Ϛ\5SZc+{k =۷o_g=zOvg_w[٤3WQ6_|?4#Ë##+rƳ>_D[W\\fS+$;,׎<];͡>{B2'}wN zye8^.deZ}DYim !Lgx.mh5¹Rvy+ kG^T,$j7U yT/`1)c8_Ifq=֖e29Qr:hC(Z MQ ;⿆\I-Sδ%L5aXz!䖅w)vdף5SWy9e9k]귻]fCSN*S+!g&}0)D놮|2.ϾfAkG^ˆW0 j;>Tgׇ_fg\fmj,aTu_fN.ZU\ũdVr.d+g[C:+0\[b,7bӇZ{O~Lz3 oJkBxO <ò4#$+pC>ۿ-[q{肺-M#CA)UP-p. b-#=Š:u祭8'Obfw bŲ 6'Uirmamw-X.D(xb~*Bf;B. _U2 :4让 ySȻPvx,L?5Q;9nbDxz'br/+KoFԞm rK> mlabe"--O.-Vb!bcOF-JբT'UbHT>a8ehf0JҮ鬒5=PmW7aعNf].}968FS FB ښ oBĈUC:nPy(F`j-^)T>(1z/.׃4:#6ڞbH leyzp2Ysk8`U΀)K}v#VVg>& ׎ Үq[( V0Sn{''hT!+eATbh)ԥxZEMp%[V?$׮K'`EY ZXN\;.\p<R;ߟU,t4:/6g:.1s) S'@u3-]Vp@tiZٺnnq9vNN.Zr%r{C YcSJ::@6,dCpp\/c#ȬS^*.WZq]-h= ]?JfhÄcchq\{o>_Ps*Q16AJgi yV-lP(F}_ Lz%>&֤{uɌܙ9d >}liBH^qH jxt:@k*i 'Zj(|$;լe5jVZgEQԞM:ͱS?TBt )A^ VB b+_ѯ^<123Ц9r,4Jj{o)d<)Im/1AbB=&мHA]:Mmp3) +&>P\24Ee Fi) o+p屶4;MJ4X(oBڵ}m0DqH*)K/-dil|8K%H.hhQJxZ{3 .MHz.k)GgjzɄkGZY]I7sfoӳ\-pC!FK0 )C JjDF|jq{ϣK]cS$8OU(oFJ|$}+€ ,f2kh屺,,k!WWf+F@BId)^ &Sv Z++;w$k_%! -Fyyտ]$vɢ3&(*b@]PAh53REzPSz_;#rKv86u(եZ$W'8Kq, &SEI(thvr`Be-޿UiDâm}=mv74M]pL`^=R$ZUj3A91H^O!kX4he7sC$8kAE4S<>U6dOvZBŨܟC#CHm%>inMczYVm%߿?=J** ,TyĊ"Z34{]o,F \*R[J-ea]"mCQtӳ&#V[.د'>\)\EUL>BQXQc3=nS=ٴr`MB%2ɀIjOocwEd<7lY9YR.WU&%U։=pAZ/.՟7٨A8Y!@ẉ)pN4rqJK\pXwk~XvUG/dfe.)duIykRS+gaL53 <] 9DPwo%ڑRNhX(ǘ h#iR|l;$>?~B&fP븪K;.̂.auT+{f)IVXU{{>b mQ}bX^^irŗ?\Qudz)ҍ°Mr.ڻ\}wnffd1m=8@HnDq1i3?Gs=D3s n87ɇ;o\]M)<j'#AȂae!%|qfq02 b#q;{4e>lϙjЛdx6<'2iP.c)E(0U?#"Qa)q``Z*. .S+ ,>Fڵud_7,G'lS< 2C,G/A-Ϊթ7W,Q!VV-&l3#3$ΐ/? |XAPڀ+*qW}/>K*jzll&WgVa‘;ش('h>i4Y5ƨ&F#*Hhmv,pD]Z4u{b/WXK p8j?8;GZ׹^6{}r~w~|=ӉdtjLnRΗα4'\00XY) ܂fsc)n5<:X!Xu~xO-39MZ>|W5|͢7/ܾ.PVÜfh2چ։ Ss֯3ѭqS*_9_UnB-NmF#$ҭceDUEr(hG#ۃj}qV7us!FԾڢDJM2m{%Raw Ά-SBtW8ŻM3d~V2Ym %y> _P(t-u:r_um9-TUp&(,TC@x;•zg]J/QD22ky9/ ":Xsǫ3[LD!yo5 ^J#ˡp9, gG컂}+KբL/he`FC;we;xBSI 8Q,:sM/Ϊ\s:ub6 ӎ~5Z;0Ha@.W9HALۉўɖ!w_X\v|߳9Zc^]ԻbMQ/&z|Rc٫3";S("_; } >#LOw*e(+ LCrN<mC" Ϲ% y`i) DvڅCKRx &TW5 n,nኇՋ}<,HWk\BZJ۳ B>w 5X,bD"nml|nnbdePwOwx纍_ٓ[ ڟBw$`!>!k7Zӭq+&C:DoPD䇰bg 7P,:wxn[̜tpУ |,p ]ڣgd?ЋXJꨆڨEgX$r;v@K 6pG6-q% >AN)a8Z@ :`6O}kg$X A]'߶-bLX(Uƍl0)ɇgj\T ^ -߁\_ts _N\K%z(X[Ή5wZUXÉXy5joh(LMNWl@")d AxXZ fJw;fH۔'!EB_Ek@j.e7Khg. 'A u `DRRᅜ{=QВF0 XU_+CZk~ uiX7;X\v}q=X7ax:ԔKKG#m~Lܢtl>L}r^x^Řb]S,LPiY}(B)[jm#fɐ2x48 bqbMuu{k2Gj& f&ضJ馨19/l-m7*+~ֲ[~7|h'%A庱 A7𞥝yvuhyqOf`Z*/nJ#V4|g'+._B\N<+%Y f?s\*CDMMLz<*LxXSdQ(FMM3!5LZ!|g_R+sٷG]YcjBV[|࿶- y=PPS|ѬJ$r)鳬e@5 \;۬^{31*!oe@λ"H50ڻ &kˇUjdk2Zi:ll&OvV}[s }on÷߭ex\:ӂJ R) @" M5M9hEl|\cnksuߗizdu{]_ "9/}[Y[Ajup A()PEW**(JE!lGqH돺xzeOO͔ǝm 츳l5 D_[נ dN"cE ]$"C-^>{oǿ~J;kN(V'm/o_>St[묟\ɰX}?@ `:J#&,ӂƲXͰ,h*'ˣJ$}4t|σn'KN4/~Uz:W?+ mV`),Yi!TEњ1N@Ȁ%.jwWA]Ǒֽζ['&YOkqɮ^?奕sw^{\O,zy!A%*qVD4DDn~,waZݱ>m.N-kl# 4 {2cg8 ÷1i@Ej4vK&ؑпtmIүf_L+8ZՖk^_ zmthgu)#`Z&XT4UK4 O޴v6no?U'uݼF.`Y( E: -N(iKZQ+bA"fn(&gѱQ5m毟ˆ>ivUF"Nhq6v|s(tqVDc󜩆EhTH6JGdGNx4rYFmopՖB"i\T^ ^}u5ЂNQ(,u hs/ jxG!ie+E8x"Ss`ju{:7 RX.HƉuyC0/c@sn) PCf5S$ Ʀ*1@o&1g$iZ۱+1{yi1b(^`=JAYMf0l ¸Þ)()H9RĘ&!")IXH(dHR~oWJ./rECQy{G{s@h*A.;{z9UAFY#DSLxe1Sbq;Wysm[Kq'rqpN袹2`2ʔ@W^ȥ)/h.X?3" !"(Q05QJũ)7?9YTߛ[V'_iv${#13>i4w\_6,Qs{g]>GsPքSf@ :E0Mz9[3VX/m5V vyw.4eW&[rͲ)sfPXQMLEX j * `V\8asRΗ"0snͅvyuzɉX 7a7"* 1h̲êH,b8kYHaT,h,{:Xa`u_mB,JNh:v=]_s 2/?t~f~)JD3Q,wu 0٬+EBY{-óֽa&(OZ-Gnf`5k_. hJ(^ӳ:,EG94QfbSs m"( ^<ŃQы+;ΌDۭ'6]5BRLl@ VT0(T`x 'B%?o&C>uf{nx9Ňmt WipQ aINeu 9J@fIė6aq)S*ųn:usY2=4-rM 5tclX&E٠Η'>OPjIJ,$2x)R&a?4a0Xoc9%J=tCw .\)'l;ڙEA%!Ār}@fѡFy3$^|lοsLwboUolnZ>37)%6$ um}6:Io2 i/}*{ݮ=lگ62|? n?+ \力؈#8ϟ['ލk\`IK2 T* +B *nIO1Kՙ%] d`&eXs$ #6g'&Zl!̡&KQ- "%Brj{qa;p拭{pӴZ{4SV؄.L,ErA#[Y+H4kcn) K6GhYI3 AwoQ>XA(G|B嶵fWE"Wv-U ~ľXPɲR`S#[TL"j SWf)ʘ\r<IZM?$컣=PO‰V/xAfo4M_֙ =PNgOMM \`ƀd+nV 9cxfQfȞ-K T*y5upBP* )x|}bh*b ak}ܬŞ47odVFmXP*""֨+*L$ g_@u>G&F. oFPECA2FF ZԩaJv/,!ӗJ(KJ_y j#{w_x{zZB ĸ5{*J!fQ,%f/FDKRHԃWnշ[Nvoȥh\BdĴ M*Ʃ@)IJyJ 賎x}BAq$QOFvcy(:ieCw eO*) WlQ_R՛l8how2 6~ߣ9rrI\vȓ͉Q'uJz]4-''<|jܚ,e"LPTDŶ2))BJm/z>6];I6a͊-[^AZ%B;\g~Wa119KZ9VôRXwҴH( i:=9x_ӆ!+3Xi<K.ae,F\)\)ZP*ΫˢܭYbL_yi &pR腢,w.eRVW)ۣ*϶hgR۴}}n<2Pj}rwX,L=KyVø "\m @zb9JX1׍FpEYSƠr\ %`a}{V{~#Fy>Z@?iJ" ~Y!YζTz`~(>ip@ 5a-V'C_28XVGY*k<-`FblW8[}7 Kg8d3fb(eQBkEbneE5[Xu D7eE^a+5MFx¹bdBhW%+*Lr7Z+is R]Tm@2! Y7ĒbʖUQͤ*v6dڅ!q!,( ,ɹ nEY:OǶ~ㆌ 7+,%OX-u+'UUUUE cg};UW <ɠt%BIFN3X:t>BOGӳč+,װ Xd[ew6Gџ&uC`bKI檛`16Xm_] !򌢛 ]a j0 ͥ2q\nj=v5qOJ-Ls={{n#7P$ Lfhz@[`đr>Lܮl$Iy%\}eŃ%lq&)\K${OL!{ÈCBjVoE]+;98Ћ<#=fz ߡe!3F5)rܝf=aD89[6oXk svYq@3gUVz&ʊ=pr*bݔDVYڏ+wY8;jɉ\<0*+7ggƖ\2T0F,,Ye1zԝ0.z]O~#ysd "`좳E{Au؝kJs^X^E(oõ^[GYL|Hy-x. SX E)^IvQ!I,¼d))K#:]HV6d>rCղr!Yg8"KfҚ%>Bn&nm>+ɂr/ E7e{QZl?L^Ěr"dT𯆒2zǙǑ!k/?ȧ]ڇ`0 g/P}?=0IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_1_NAND_3v3.png000066400000000000000000000452051520775651600222670ustar00rootroot00000000000000PNG  IHDR,)nPLTE*+#S4 W 3V 3 3 3 3 3 3z 3 3vuc@rIT4i{Nn}aqFb1 3}g~ 3 3}MјWSGgsqQQ>TFdrd\=Cp |8wjd |HC$(*I Tb,/0socnT^^bM(Yfe<)[\>rv49Z/j\RNH?;`omWի@6(I277Nvf.dfHK +/~AGGl|zN^ODV>.}~p2-D1e:,&D{}"RTAsdhUGn4lI)_;7R? 9!xƦ%mE*WX]N,%úHobG4utjyV\d;cŵbf[,S-Nze.zRtvo᝿@q\kUB_H&]CRm\pTPoNG'|ŴiR|ζг{aEjmffqS9?'gmcĭzrњŮiֱ^̍Pƒ"`qUItRNS @&*z EHi`>NӞQ`q1qVo؃˲ܘŵP:FIDATxA D{5B[0-bE"'R^ʘ~+^hJ`F9$ǁdM ؤS=' 5Fj9d2L{L~)6_Y)JFOf$s6c6<]*2u˥bW] K#6x2^v]QiiRT}[WI.%`qt(E` aj(ASiD)P&` cT7i9nRwW1ӄjIc@9u9kebƈuY6HD.Fr@9-7M DL 2] Ճ*k̡*J KdFpds`z`V bQs:?a3mͲ0JޟhemJ `Q;XHA!-zXffqza[[Y/l+S2<@rfp`AX RKѲ?pFFVVy2~ 5i`]$aAb2!#aN2 `,r4 i9<4,lA"@v gMb\ VW>+cm8G־eHmFXmde UYѲJ|Ȗx%xRhVBuSv!%@ KEQ,:]~PҰ/0W5vx<{f\,g& Ez = f顇lgxL 'ssFapK=QzAQQ +玍猖e|g[gV׮f}~ǿ8sWk]ԲyV̉Y[[vޞxQF[m 8+![OWwM˲:be/ /׊wLW_+ tgfjǟJb_A/o (f4?Ɨ?}H@Ru2-V@ZR-lVXEVBb ~k9dEyxC"Z]{aqE*^bgjH;`_dɟh5jKA39}F$7F=K`W>V$) 봛BlaD]HQa3#߿'ĀO("}a"/H)>\^06Tt /B&b2DF322$SӢD4h*YaiEEw/|s~י9gϳ?~2(jU&XMh(\Lz>9չ)" 0!Ӊ'\5g#G~>1ǠI`TAuD H/5 Ol"8wF0#<#?tjڨ`UٔtxzeƎQ  R,_5IOwޞ틔.`TVK9jtSyWe88oQcUuO?^]:55ZQׯMV*(0rwʁ8Q*HP4&BC} /:u*;54Za:F*Zuj(< 3ֿ8X!h ]z=Qם⓺-BCU AR9C̢8C&4F/\Eq*i787GKnO ,c(R  <4i ex:f3 kԆMVΩ֤EAV6,ՠpIxy:00[ߎ#28iE[;ju!e%>XKn (AHP(D)"x<ɗ3ur`Zg(Sj{3SU>rz7V\˳ "T:Ƴ 1,5V7(([Zme^Ҥ܊"zP0V<VX0FϬwhɌļ%ʧ~[X~O+]X*s@n :1V noFL3HY$Ii%$8?=,iq]9\+Ѳk8"V?yG$|v,R'?8q -P<yUɉDo҈ ۷\P'AT;![Cn+] }XY=qJᲠFJ:,QwpeM$Jj4:ıK;F&ZO(W ],N}Z.BĴrU(m GbM d%f@%?xXrՒQJCZUV.ht=V}BGyBR+6ƗbVޠr*b%rҝ7^qLWZJ۝ ̜ yG,~јrQ)byUM˼pbjڶę 2 NXQ&-Kv\udb%3u1ոxyuo 4bGUIfhVG2VIKpA1 Z}Uax+M`:}n=-[W-dD7FcE;6 ?\yUD#"H<3TB.$T*â3w.7uVq&&bHbxMK4x=Spql֮ŖR[z*:V RWZGr)L*t fQ&&}}WWFpī/$\2Y?b9%EZpWOÀG|ڵordm ֑S$A#鵻]I3-g,KQ.R<"'5c-:q \a Yo͆IQ=,wxۄVX&0Uʞ7qW9 ҺN>ӫ krA1c0|c8 Ő VRF8v\ñO;q8lk;(;Fp,ҺL=Ǐ}qmVG5PY'id⮹@buz}&ûqTT\)4>\ۊ3e3_O|PaeG?{੎K5ݏoG28to`Z2<`)h}*Z(g^/+K닫!/|Ux8IhbkN ѵL sS- u;bwͧMMǾ_2{h,2yn@Ju)hn145rwyBzيƊ3,Ea>YZpZum!X6g8e#H !ՓG~Ãp " T|ϫ&YT*/ĸޔOQJ}:EȕB=3Xfx8'3>u5pvrrF!b*Vr,b 1+}g-t~f;p\,8Aؘ#ՙ6+x]U2REStKgJ4~m9{ya-C43L.FSLyf tcqsBV Z-oM)aw!WĈ>aYyͫEԊb{fQ2ϴ=^k󙷫e ՙ+x 4ĚFkOa=T ׹w7$QXE];&f,R C)흛 o۠}`Ҁ?a%AM4jLl9C.U L=X&ΗrZjϕN5* NEX#mEFPiِgt A,^z_I?o36<*Pء(pWQD6La1:g^&+omEy[5D77uFVXp(vc#'Jf'%d}>:+-FAxw~3\/Fsuk'{u;&E OkBf$rp `@1{_JQBuKko²sŭG}U/u:r>E ѻV[8!jM= +5ʞd*\b*DoUֆY,A-VɿXs*}CxEВh 5 .xAO>NXYPaw~ٚvuuup /,ylRpGFQ{fe:I,>0MO}ru2*ǰΦӡP6`YuCƣɭhr 7X{tt`CDU?0iDC+s7K֛ >.F6y6t)+h&h 4Lw"-N,NON_E3$Ob0r:J"*gހZ KAt5ҵau9#@St6prJg$vh4 >fN]HɲSiX:p 53OjAGWD#0=pcH;0=(FW'4a0jBV%*U.G8(L&*VW ĵ3P,C+5 s8%fyk@B_1P2qY*]]6KCuCq&ra8^_FGeb)=yü-WGv9]Uei #Ųvn})N? ~i+&rBFPN+2+S g|ĉhȐnm%˹DKH[s"C+?XNGhZe;/ B|xsL+L*G$ 33K!4sf5 m WE0耴^EA K*W ag^ ٲsKC$[8)NAoWu񈧢ʢYMZ&U~28^o$I_%q 1+I{>2Pvl I32uprsWKUA&Ii'Zt",# W`Eb(ϳ@뵩D z+e7YFT(='nJb28xH;.?7Î+Xl,{= Q֒& 5^ND86ށQq̤ůrTAz뺩)Hy0^h⃏' Vc;E#;+4 ͈Ւ61*ۢbfVyNnRтbl( xp;Q)w+-y:|XT~x'ĂCA䢸+'}_҆:F.cK*u8exu_^IJAp V$P3KyV0 "!oAdWȂR EiS~w[H|e -죽Y ymY(#@Jɼ ZA V}85X9bf7 ᮀ Xps"Tw,pq X9?'f +.A<xn6 Z NCo_eJ.WPz|{VF0".8`Bc_3OR"Y Wg-Kܾ Zyk3.y!4W&Zv\)U} 43"NJ$}%.8JW`6F,ª}u؜C/Ͻ  B6Bgt Fpf7D H7k{uD"+}3,'9VY:؜5}ZLuq4ـ){& -ˆ mb*`ccJr5CCVG~u/cl}=FI;K3dmetYN]gitV l6ZZ—H f`Efj}7P"+\V+^Gx <3fAn3FEJI*`.||+Z4Zqg[̭}7]X)>۴uwė _(Mg^3b4zBs+% oW?M$eyYh3v*f Ȋ+?Jo٩F8Jci+ܢ*|N0H"XlaЙ*_soUUh1J C@ 2@a`՞4׈NQ N/%*%b5; p .y'wK>}΅6 x~*"*&vM,C{ XY;?n D:'p bA@{VÝ*RT@;,M֛&Y򮝞}ϐml^i$yg}ku#y㇛|;t{7iG"bH O'|j2,.g\AߺM|?f8Zź4NAeB::C^]eTW=7'tigcRߘ?]\q9B|ޟcNϦ0@ WܢEp+Jzkv@l8H?ԝ]LuǷr ܊jZZua妭Z9" |IhKs gThjpΡ =Q"( XYzҬ.=ɥ={~}~^sf85hZL -z3tlsѴV,"7չ\M_M܊Ldlmhg(aw6r]*fD0fZM1/s*5 K;n+tuÃLJ,fOGLL#_ۈ e65'*IYFN#B/ѹj3i#YF_t!{Ld~uߧ]Vc?Ugqn'#5ͣhh5.cÙχVݿ~)$MŚG⑋S e?ttt#e 펚G<ͱ*L!"l\?0.mPLI :-4_ńXt..1x ͛aP(D/`)5W*_K~TN )h~KfYSƉT˜'.< Wth$iQPh==b(?bl;gf bͽcqb>}(`?_\V"*v˜deN'G*Z0pL椏xX7O*KG'@'A8aHڰ{8Μ=>~ulE‚'e'͒7M]Ui2GHG|~=/ /VKF1mjGu۫AӤ|iNg2Vw{ol~&MDΆ?w8WD-<.F^kCC*qT<ch>vsN#+3DD '6le3S*15fj.(n+Eh'sFy\yͼN"pFxnܷ03GZslI¤R鳗WWWg񋜱$Ɖi*g\e)q{A':68zVP28&Di)BrzHoF@"S^L +bQgG8{{ s63o[kvXqSZC3a| BշߎY%@kPZ a{,SGa8&W`/s< YBJ'.4:ϸ]։6&֕'sʳ{?`` VxyѤMB`U''<)YߋxiOu* ,PܿBcapwyӧ>(`ABF[񮬧(caa!ZD/ X{$8t|9B$¾BȌ8H2η?5gYb}Yb^nZJ~RXH~Sz** or]4q_|utJΟtU',R;~24E '*9#>YV΁ǪaM@* hhj-m OX\-%niP&2lPk2i5 ,.`+zuھ($Ў-B-|BWl+' 'pzG`]xwk/kAW^Kb" !m,V"^O: MdQ;g׃n-49ZJh뻧Ofi 7F9ͨClZ$C=_O]]ss$q Cp]e|¾=i @+d0S̚]jkc >Ӕ[: UC=ݩ Eʋ_v[p &-%[BD %%`МVl+KM*Fϧ}gܓ>*rѡll c4FC9]pIIͮ1)igGڝiwA$InQ&ӺChW2B[\5F) V&k/v~W>w_E2E#%WTZɤR%&ޝΕB'+)ėZeyВQ\|u߽ݪZ%KRfbG}xg;Yo/ޒ`=6Y##dgF#SAJ`!q~X(! Z`oT\V'\ZY8/J羾5|Y(?U.*5JejW(aA蘘:3erI܀\ Z @,Q/9k|qE5o ){&s[:CcbӷVlڔ&¯^ m8x0HABNJXTsփ%g&);vFN" dȬNdPݡMt Nb&6[v[)Ң?BZr}{*;騊+fU} " T -xi8q攧sr3ƍUGم `JM@3<@W^x55QKbrQ-a˴;Hf¶n#Z[SfY3|#af16[> fWPT18 exEP.h5,;0 ڥo6^2LJ_*0~e$fo߆Bp~g߁ ekW!z XUK>2jbbE]0SËuvvX7(OVd6L|krfXf4=R;j~yG> ?qϾi璘.ÓbIXrTIn}{X v|RF41A`EfVɪjIU`]K.|Sv6'mLw?^#vzDjݫ?epY=8D4)RNTΝd1pk6T薓\,קM8rL)ceoh^qSu{p/aH`F<,Dg F@P %K*.듦9nМQV^N@\v%+Ѭ> T<:4ЬVg8i2poY޻Д%>?Hyv:rs]{RN1 GӘF0ɐFƅYː!`XQTj3l7רH~,`lr{gy={;Bd 鹸}]C5'hӄ΁49Xc?2&`$ 6UFC6_߆fr p%eΦK%IAhUIst! 1 T.5Ӎ,yk40@aXtGW&`x\`pyKY{p2^_ZUٷ0'%u>oN*abH홄 ީX dɊ m}RmեO_^wU"N?xwU5 3ba`MBDNܩUS{|0q9us|cÃc*gbm[aWWob"KYB<>+Z=l. 0x DonD3PK?_lG`ܝ`y5@А!p :Pn%Ҧ@!`DΡCEI}Z+HLrS9~I;:>=fl]2J# q%c7*3/G[{0:*qY PJr΂{XjՋ[Jq,07<A+8E _M?d[[{p[]=bV"pIr [1&԰a‚oi+u~u,zP>}8d+N(݂O^w6 [ U8ssܤ0Zs r1-LX;7g2p!]ScU+ۂP%ILFZ;Ho[AJ?n }Bb̟OGf yֲڷo5,M4t`l%1-p/Z@xDVxm Xe[5>IB(JpnyPUCbuo-i- Xa%1NPV8a+wGcH{bwXS@UqYư4γ~q%VH 738.,<˰5꿇? 泬y^< XCoɨ0\Iι+[WiYYβx<±6#&t[sXҰngpJpUS4y|,^Ow!i̧$[6sKs]9%|&\]*`yAgV>}!Vゔ([~r',N^ۜriPS3t1K?.Xu7E0c ٢.,}GUrN`Il_)ؘxw?n< v">̲hT]Xa):`AVY#  % O`¨k^Q]vv6Ȋ`c!/ܺ,ltK&LnWmè(_wf+lPqh n܆(@DH`S4"B7y#e#i`l@π<3e * $il$>}\y+Ob%ﭲk(tu[^~\/ VnwDGK7meW,?}w-ko Yǝgb\&G'^&**5 %V7m9(( pGukeYY5곞bwY'pkDiA8r]V{ӣ3˒(2<$l$^eavgK^z.0Qٳpn!`+YuEĄ0Ş@]w? dP6Tڦxbu}ZäcY CcwGTjY}1.rYp+'Y a(5WnQʙd)tIe|gu4YjirH0n,=,'Bc\VH`:7YvUô,ÙY9EY" d5ʙd!K@YcWHnIIfUFLCؐ5daC`0 # 0/IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_1_i2c_3v3.png000066400000000000000000000446701520775651600222310ustar00rootroot00000000000000PNG  IHDR,)nPLTEky34+S 3h 3 3 34 3 3 3 3{sEb3}q·HwJwuc|a 3 3ĭ~U} 3axLä‹lf 3wi|xdqm\}zs{OnQOBO;1k^VM0!R?7NI:CpJ"!" 3af̳^ZY TR]naHQS $&E $&{vwrIBLM{nhbmZ+-- Wb{8;rn T!KJe 8nw)\],@:LYXwib 4XeeADU]^-5G#SU.-pd\7lo&0dg156$x=AA?;.&%Q$S6#RwdUJaL>\-cE|~|p{w7P>ǽ?NJ?SA4;rx'Q*j]Sufjj)MnֈIվG j.CԶT6ZE| W{lZm#)8i9Qi;%9@IѶ!Ri&M\WӚ@ [_:.ۢlN`$8RYeZA j$䮾էË£ܞ$ډX:⻏~(g$8$FR`H;4 q+ ,  2Jo/PHC  l vߢH~ܧ[ w26 ;uot:RW@tWX(EC ݢs)l¼6haaT8xƼ aa[Y\KPV^ *X8&P߶pF GabcYZCQX=!UV)`^H]U#b.t!VJXr V{(J**2!eə. t|0,UJ$+_l6ۅ2#߰([Xߛe`CtU8ZFDv4%_OuFUR?wژ.9MY8t:;^=ª.a g~]ig\/#L"8Ό~968P!!o bYE >T']br/Nsؾ(IHu5A% ajdͬ`CSW^PĵSwMi ]ﻺ웫ϥxlyY_H]c{d=yLjktw9/t@g5nslvg3uѻn5x庫5m[گGvDѫ]}IMNWߴS}}iЫ C/_=xwP7W>h}u$dC˫'7(eM:WUsCyY rvF46}zY&g:Ӿx=RFS/+^6Od"̥!FsTV_`a ѯUQD@E<&VKKrҺ{|Eh~*i ZZ)2oPoOX`+^=U Cѫuwg٦לDQ1cq~+璪؀ԕ7lfۄR01DΚ<CQpNfΛ_eѺjeg|/H B{Uk2RI`5DrT82VC,R2 %`/uTP'Ā$I| GJ V$[eS JL_jWV i JG\a\)-o${8)"L*㩮џv*{{x-\9I\LP"5mE] /*f*{;? S% $Uwd0'+~ p\[\cZm@U 1RwS U( ykaӂx*x<o XxUڮc %d:UHq/`f숧"z^Pk_t7X_I^3jG@J!U>) m̉.PcaPLe|\u:W4cRv!(pA_xn,va>+ hRE}]z®p4 `%'\*j`6[[| t1Zضup_ʠijQy.8e˜wՆn;y/JI 2'ȢXiAh|\AW֡奨\A^U yD cyXKU;oH<ޙ6 ,#x ATh ŧg.:XD"Z t.m wQNY 63LB=JN$SI_{P Aഹ#1PXCvFkc7ۓ[,.ik KŬ$.f,ӵzj)Nã3HYƣNb*$Q%dp`wW ĥ| {GSO]biaDoAKҊ-cX[BFG9w`a}NÕ5b3S?`YTk_oir\-w֋ :Z1S%s C!J&GRӇH4V3ɲtE3~P<8VOOۧFD#GK(bԑ!A$B 'Ĵ~6#@lb.΁X*,fΜe#-/5 ʞm se'{XZdx^TC^Έ*dž]׍$~GlMfgb/ah$AF"X徔t^jFg7A^\՜p\!7wc"TӮPώBkArvZdnW tj6D3[(W\R@ ZqgAuicW_A `!X] pJeA.p9Vi|j30 osRd$z,yI"iHL+TXDȊRa՝DP(;K\7(JX7knn`>'B͛i#oe I^.`ŀ섯j%wH+GRy2ZݼYvHC+#ˢ9N87.;^O*? ;%{!6i|r+>1AxdxLHPjJG3 WC48ȭPH-+JҊS\բ \ދZ`6o| zqR,VFIe /}2 Pį,H[ݟ}ae!_7DHfqph6Y= hG`3ЂTVpc/< oC\0@ _S_ywXY~OkAYw'%= TOGubu%'ȡSutR~]YZ\mXYK<`-/GeYLũ_|g^dUsr4CׯEU8kU,v-2OЧ5Yb^ι(biZUD>!1|2)m;?C/yv4Lz9hcPt`+#0RÍ+YIIY5%6sŃJ Ҿ\{Mׅ0 $Tׇ|>6s;Pcc)*<Z6r±(_Gt7)@j+Y>#W^:*%dcgUa8ڄ!-4jaE`K &kʇG7?8$CǬt0$AyJD\ 0*qM5$-540I<.~so8NT*4.AX}V~ dyEcvO\ #P(9VoFPS-;R4C!W*VD>'QoW b51jB%Mqr*+bI\s}kt|dh)1T4ןl4+(m]ϗg/v}S4."ď4TkiTJDGhV1eF!ZE+yoG}-Qϰ0{}jGe_S0t2i.t*x׈(9wtdfC 71VT` y`$ XBN=6v}GeW^BgLin̋fWA; Pv:q'7[8=QpvvJ%"ug@3(%c}a=}XCQq,^$YOY@>XqƧ&&pvѭj8Zz_v]:=pEN+%rk_l-:,IN@#ư1;z$U! h~oZ_/AFXnΉZqvӯ1mNy P`12,-:c*C D-.M<*99ܝg.lȝD{cuW=33ˀFBj`U/ ƈ^uA`nZemuFJgG ɒStv|{SWo1ׯf2P*ȥAo#2g [,ݫnpׁ ЈCJD}S#ah4̦_>9꣰UP!hFK x7Ϭ=op%,H]?ӀјQi 7[2{LE$!VQ_lG*}䅣8ʑV* XC>V@&oubDøx-ٕp_P" ڵ'1#[T-emfUPN(F6ψ1/3J!qD}8˴\A:H3B" 6؀PrXkMІZ9{Y0<,%¼?t.Ǽ1``}dk`tkn[)Z 48 J\p8\+n/+ j}ȲHF' T `dQ"Qw%C-LK@iEqHVed\C O][pmr NG7%4Ac{h2xїpX@Hd̋R?,'$ _DAY8 pfoW[]Fp!xD JUT2W wx8闤fY +V~(aP*9ձFcׄ┍į Io4yU2<փדqx' Gdc]$d i#& X:K6-Bq8}lp'jG¯ʮnP{Pvg Z6Lo;"V&bWz]،Ê 9('(Gf+++:ЂF;)\ bDxa N]gm%-#1cF(Ǐ v8j*h/=v$*YV<'%4:ߗ\I+c-;QZ5 $ ˄hu@KRC2Gl" G`yJo$g|CǔJ6fU,yfjgjXYصfz& I h ^9!]a`$F#$k> VdakkXfZl`8­O|#3o \V~ldhᚶ_\|Ej'14jTU޾UyXy֋ ='::4g";;v*KGAL3l ںl2(lpP-&hI\xGԬRr[\Ί,^n6+n'$RVϭĭo:)샚hT<^9]<5%s#3OB$h]6NaeWVfTmda_!Zj"nf/'hTaڱ >ҀqmN& Z(^G F/J}ÎW!D /[JmLѭ;`6Bvϰ eJJhʂŠq;t՝njoy_)][bIJ"Ia&]qXolI9]Nтqmv-5YR7fٗ,0kALo1*pd7TL0-aSOķ&MG\zAK zy#87G5W;c  1gf,\}dƜB%]ٛ7' S8NT,2621+MOk_4h]+ ݳu& Zl9ySá Ѯ>|KmPLn +Ld 9WMЊ9[>MU6RYI0' D +W$WK].1qe[og!ӗq\[VF+#-9+hJQKK2VN%C07i?pY$;;w'giojkJBВ3yj kmyx׊{꾳5*iX`3L`2rAU QHk\+A16H)PEivC%xboP]ěh{L`5p '\.O(-W!QZWC%hbTZ+ x&9e_^u0w uPF iv)EBW}X 3"cT&14 ʬs%VljKKuoSZ" ܻZAkKz>ixl&"YB!4jN}vWbg=!oNN6 fAX`iK^4kvT TQu#\E"719/9)߯FB--W_m vLJUB7\mR`fpHXE]lk%n%p ;;;uٔ2F+֔;`,G\>&1>A W{'tkXNZ'jڣ2t%Iq7M&F7  ?OqȉP:]){j!m%f|5KԨHlDW;k=znw:'0TE'm&?-6sn!MqMSrS;[ẶM60N=>Z<7ejڕluݞx>;!,~5I$ 2ޯ߻JӨb]Z>G@iqn4zfb"XKBV|Ou]k[USegdI `1Hc 5BuUV%$E]>GO$0%6B"фJNZ\5-ҥ4"ff~=t?.D+DvZcE(~SbJQD;9dBreӱlsw~C<9]ÉmR!*-nzъ6n.@YKxdxIp!&@*"ip']O+2?5dA+S鋳!V:\BOݑ8A~{TOVM^x?GgށpՅ\ZI8ajy/-˕Nha?r뗅r&Sne1.M⌿[s+\B ^N>es @+451kD$rK$"/n(!n@8M7:Pn*t}v^O~YONM > #_܃s9eP RրWld %N'"@?\JI}R J>iVti=뚦'۽/G΂`fb5P9B l瀻JQy0 Xq"]|~EXz:.g-eLiYp1r[g qXeEB'cB UeBࢉ2N܎LVwx>0m~;Z,9}A>Zvᛈ~r>5.gV;wӻX2JpN( 8N"kB6ZM s')24gE9\-dQڻ;{>&{g׍HR6A̟\|qyzBb2!D)8YE <)D8 fN<q^^_a&k}v"vѫwl9ؼ_]N4ؑB;LcD,JðE9P˲Bh\qfV/!.A ta$bs=3jc{^?Һ`zRŢØ"k:t"`:bB&q_ "9'aI\X,?j-B_C< .+ TAV(CӢC:P"4tDS!8%f}Q~Ybcr>;[opil50|m1ˇ=\_L 4Eq"iZD!,xN\(:&VxtT]EIжd0s٭͏^E2F~)mٺL6o]U!3"cB(abZZaX8ȅjYO>_$r&l~zyx?1툝7kmONc(J`)FXܨ@!C Ю01(:ej*jo~^7fM|܇f(l݋o$.whiPsz~|C#HHKW"Y cp4qCR"I p?Gl٢L{g[۟rRј fڟEa)v‹'G ϊjJey%x Tq\;^13t}k4X]gޅFr5o ϼZ.,$f1XmpτSRSTJ *xB0/[nݝ.l]vfz+>f@lڑ.OʝjKZt%Del+0,0/Ib cR)Y1ՋjvA2랑4ݗְ=ϋwŸDiG]cR)JXbcK ’)MYVTRo-T( #+{9I!Oȥ$<Bۺd]veM'aș6a'eԤC.-I΃oߟPcӜg|}{tm6muWԒ3g7t ) n(4uo\[,ktr[pL{qkL>4X>T_@)EQKW{,r_xA|u_)l>215Dnk.*zzG2Bib <8+ S.QHBPiaթk--VO*'6Zq}N9-_|(u{JrxCQ^g"1͚sv|=Վ+,/Ybź{ <{hf27B1p !OݪVRJb Ϥng_JT-j~zϥusW;iբxŅBDڻ*Lhf4:qG{\k͔p=kS xۚQ& q|H@E!v" g 'q7J޺ɓzZNp#1+S4DRGQTc{zZDQϓ\K_1X󔂏$,#9{G!<R-~(sr/.ltw2ݭ w<{V3ynm $<8 Ӕhmp#H23xC:(wE_SGy~2;ѱtUzuglPepT{E[Ieˤ <4;7#0\H0m31Gw t}<׷;p:> '/7ȴ]ˌuib3lZS/TAQZr ^7LRLԡJ W``4<tQ Ə‰Vw8 q?aƅ-;n4ʕ϶oOI4 a@DGp=9`uͽJ"pRB\- 5 V=5s؇ h뼼NrXPMh2vF,hua pL`*AY x3i:.vVR5#{gckogfÚWۛX?%bKJ(SLBre \@f Q4߽ܺ/r4;5 :fO6s:;]X?asNkɤWYsZ9.3J]zzvI1jvq2g Q +hU$5Ɂ&L!hyEBL+(QnvQ19+BÖn0䦐Q5`2u$qLAŸւZ,E\Ji4ԐDrvʕ3Q2?TVuy{cீtV侜VnCiߥc+X[Kn\9Z|~_4_k%˾:[xٿ xs$#BJ e8U)"W(\{x:NAY 䟀*P=z8cv\uoڊ;01GBN̐ 'u NqJ{6`1pBR!m`<' N8('UA%⑤}4 ӧyM[{<_Z_]ۿ}uzuX.GC`Yj\%x7G?~}9c,Z:dMjh;D7Dw`55tZd8Td6`(H!ih߃x Vg?%ȏw3fu`-ȴv Gl ~+`.8k$](x ,Je[arZA壈=/4Qp3;0XM `=&iB‚"ãbX /S&4w*e[@X0& ޮdkLJ`a&)丈 aAx̄ ^3D qӊP´. G!3y< ek{StjvLVa&GgbZ]MYvGC? / ]]h+SU):_0hZdT ױG"Ό%k>E[p^o8|#vqҤepjKM+ KM rϲ{Ge)<ken/$YչY(i llQnr| Gfl+ Yhrqw;Hn *&`u rd 62Ňh]@bhm+L,CVD4ہuF`tRX^a&1,(@v|2ֿ[iu%(2 %,2vQYO;,q2"$R P$M1aX%k2C`%,O d}fuaSTt+|.]u)*Wi[b))ŋ4ϘƬ唔S<,R I%VSTR)bzɣYo2mK$d[MIFY)<`k"$Isůeun7(Lt\Der\Rө;UIϟv1 \/ UHkT$MT&RQ|Ȭ}Nئ*h2=az u >`|T>ʠ\zUpt.*uI9jouyUd1eX2ϟݣ6փoR6iת`f-m}ku0< ˅}U؊-R oy9$i(xf&N8D;Ǯϟ"y/f<㓺a})6`or K姹|zK]hXRfvtֆzRW{:qDzߵ1d>PJQ"CMxek.VoP2{5Er&+3b,v:US4D̵3d]S4VYRC9F_jƈX׆i]SY5EJ{[93DuKѸfY gpyK-ErgVL6METrMsXA ;[4;d ,gzC#OuG~%$$HL..1Y"бU}c9l1rC(W,VYX.l[Z!ȔLJdU.y3jeռQ^,udBP5" Bbp,a*Kdݲ3} @ QUgL[@VACZ#b^LS,} N: %d5e%R{*+aC_&e)Kj-J}ڼ,#LtvMCJQ65IGic)dm a#LC!k'$+Y`0 Յd؃IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_1_i2c_5v0.png000066400000000000000000000451411520775651600222220ustar00rootroot00000000000000PNG  IHDR,)nPLTEU=.K3"345, 3 3Y 3glU 3 3| 3~pEc4 3ns 3sOzMt 3wrƝ 3hhvM~b 3xypn]sP<3kY[Lg 3b[VJXQIgsԀ 3_c]ųXhYRzuoПWupCNOz|pjI %&TJJRSwje^^i.?<.23%),CF"$>=6Ycdqf^u T` 9LYYK 4: h"T]^+^`'WY`Z;<..1gin_U:mo?GEUzfoygqMH=* }H@Z,vgfWL&MJeCwyO^jj8!>#x^OD+3Ǿ/#~D43'NR<\M%)ftl*M*&7_ֆ(_>B̠5[ ]1#fcS Wqttr6+}lE䒟q޿+ZdoY6x/?J9dQY=w| !4heM$2C?^YLtJ+3ʢrrk@, DߕTEh*+ B˜dQ),I*B<],[VP(++E{YTOZkS @SCE!]&D KP~EƕZ=X42ll-,W EpIc*3nVpz2W:W\ܭYƪ1WJi ΕLDP Dp<8WYtK(xTnDp :]ΖF7Th.Bf\ NW\Ù9F@b`٬?Κݽ}opUj.g M/a$TI2ҐE$YtmZEY+VۄV^ɓmP^ݜqX$ؓ5wSW>Ι7'l'ݵі2ggÃ;p;omhmډp}~ENW{϶n3-Áh2h\}zk5^~j 4rd^YCjTzÏݢtȖ[ 6.=[wDݳh1^Dmg;zNǁSRժ$@@bsU:[:jJeuTqn!45qFg=ۗYGG(z"amW=b%O{* Y;>0TfHWE [B 2ӂzhyq0HeTU~: .\0;MY;'HD|>?O0׶uPuMOTnUTeYdx0{…?LSƆ^{K2yW8Z0A"Ed9qȫBvO5 XH`,J ċ<kp隞eks4 Gi'c HQ\ :XBG+VK"mR8'UBԂ"Ey1(, x&-]W0 0VDXKdRV;f p> YD<.<%vy SZ"!|x:UU81\Q͉i4&"0NH7A5єGH"2cƋ fp? A 'kQ`Y."P4mr; x%\!T-M5I<$LU22iIg{+& xfhQ25\бBWiYD\l ;0ѱ9LHwm[DS\9DX$H8gLMU_[,}#G#|pE7Z&ihlL-Q 2VsQĊqǰ6SXd7ZM8 Fo LDROUk6j硬ҟFeYqv٢v:` 抖+HܕsJ$l^/N箄,Aݟ6O(uRºyZh t?TSi(p;7ZwHHPE"s?`>YZUS&O?ccPqG/p.4&#mց|ZJٷ A2 g:i5BJC[TK^]ׯr@YkKK6d:֏ p~mrê8wt%zass*әJ`9:ӿ{ߩ9F(> EH A""^Q`Cf cjԘX 3i.PYf$qʚ`$L1"&>,f!e75BC`࿐tJ/pw{8Hijkz^}w~7{*BAhrXعqZ|Pk4ii_Q80nX32rqTǗ7_y+o1 ){`|}-@壴8X ?&Դ/[PYwhu].Wh:' ˲dze-(_<f,5 ʎ0ΝU:{g}7ch+aNxU6jq`;T6e B#Nl6!zԂyB 6{E2< eǵG=D6]>fQ{2*P*"ʋSml~y0o&[-/Z9?pEn*it z;n^4 Qzn'ͺ|=ZI@=zĿuSp0>PPH"kE~<ȒxH&)9-q峄YŀWsxֹ T)QBw DRf'eWQ_*歩,74t54KaШy|X 8fuK.Ub Uг`$ :u=/Q#ZUUPggYv:*ֲϚg:){oXt!>AV:Zm˫Y-=\+11+ύWp C$#*WJ{F̈&?t XPTȒY;9{`kh[#bfNֲTC㺆c0ǮbZA%SzGت#$UobضZ*$8`eCȗoȼ;Xdir(ԽfvjNzv}9(XͲ=cw=A2+tQ35V>fsB` 40qwz*K,q-7zw5T}qb8tl-9r+ȬX}Ꮕk~X|ї* Ȩ*bXDKj5A4Z)hl Be|Z6*jEt7V53Bqs]'i_^~Q?0c_k=0.H8>/qj0"&r;\aX*?Sʣ7LNe驷8yT6Rk`ʘz<6gš*]\1.tǀQ"bj(Ԟ ЯxtGVT4alp_Jl$Jb1qT v-f#KFːFt像xx/pĊbT#q`9ߣ<)4yVV\kkRӮgЉze96/l\n~enݻWTGb /׊/Ps[uńZ!h:jjeԵ{><:t+\v>7f1/$Nrm((E1|2AWm?ȚEY'kπ K›v/Z=⸴ wS߮#$Zh; Lp!xubȭl=GbEW&u}QC>/U/h" oǎտԝOwGL [Lh\H f 3Ym DsaZNQ`BkJmjVz0W`j!V` 6F09h <^A;3( A *$HY>HA?0uEňbᄁQ"J 2Bj:F_ܕ5=G=%"WwjzEѱ  A+8хd>eEis_j޿^RB}lq〰# ,d^[S3c hoqmb9G ҮDѹ `a#Bvc,ʋJPTG=ÙY1p-IJ>v|g4it0+JKLV;c M" Վ!Ҭj;qBC;zzz/V|;-<4I@ٌf _ޕj/R Ҏp.[*2nGE CT*֯X ibޕ:Ʒٕ 4f]lVvRE?xۭmD,ېVFтѼgGȼ7>u7zAt'Jw:U/1+ș:@`hbIۼ(z9[]<- "oi>r"pJ1QPݱoU\8^gGq=;Z2j21Y UqkrKX'T'Bm^IEo#j5[E7aa!@jץΓ_;uEGXh p5,zugx#*K 1"8R[uYa3,6]YŦc} ͎`@Ɣ!EIҠۍEj0XNט-U b"њ ~j\И5VTn᡿}f֭CiQ!?ũGbIǁ4qZw-5:sb)" Nl=%Ŏs^I6xCp=~#^ZSڳ^"F~b8_5690GfΤ7Bp3!iPM6.xY[_OO^Nv^˿.&T-ڷ[x;|(+>"A'`1r!Wz|(ǟsL>4!c3zA՗ sRDleeÏ_xac 4:)kQ𿟻EE :)zU buPt#:&TQؑ.ܕT|%ODŻs |m'zt):T]HN&؂]UrYhRdX0rBX-~ m\4WY(AW-ͥdMK< `74G͖˩x<kv)IɣCbY(,Uۺ5D}ɨ8u ZY*Qki|1];d%O kdjXa NfV+@hlaJdix(/M&im", oTo9TJSwh,$Hv[y3a1@břYf@ST r+7$JvrlGj諑QO/uHhS_b6ѐ/IQ>}0΋.6DS`*m3 ")2) iIz4[5<F&ͼs_x\((IlWpuvθh7&J#ݒ2>Ӳ# Ѱ(B<  xU+D-|[W4=NE1IP QF^̊`U? FC~fTi坙n뾛4n?5+ A2AAґ:Gp᭪S6w5eVWQx;!ͽRa(K‡Zx]b,T|5a:0gqW0@$z&Lte>We=UEQEiR5| yT.q T-Sա+˅[jr{ƏbjJ&Tj]:*xFYN*t[k/fe45HLb{OG>_ 壠(|V:nua_sà\05PcavN/ 6kr~eCGJ1+h&q99, #96!Ų[oWq !.Gl8ٝg2ps@!A2 Dkk9:^&,n$j~0N4K]*rƠ-$Y4dYdz٥h]Z+`ȇˬpL:zXéYIsuHxCYK˚wwd`z#*+qC!iqw0f8U_>lX|c +x @La궠L** g4`|pV€+uVXdRT85~d~aw(e2d($e@"G:h%?~!yXcUU-5S*ThXT3B_[],޼raTbwrg5 k֡!Ci?Z5OnlVHE1Gn1,D5,ߨ%fRnYOS WPլS m6+Yytl ArD(իTfXcs(h"mTGGgOm䫯zP%\V ܥa h*-+= `jkhҒjf~:=i)dĻ:Y$Y5ݞ˷]T.QZZ`a@rnlhk{[Cz\heFxXAyBQedV? I`t{>͛w~S C-1404ZO7s{ZKZId n2cMGKz?u̇#,6}YC4{F,v;`mYܹ o %Bk0=c.X[-m*ąo?xX)OnF x냐{YEA@j 2C,kjIӅSvX\g?`Uͫ YL|lVuGz,L|ti)}p2{~ 0qmp!Zދm8T$ZvT%2LxVSSޓG%-F+T§v rW_.G)gMm0Ar3@l<ٽ4Bv;YC7#);Sn$WLޔ;+52ŶD;Wy~nx8G8 xX<78.Y @ | j&sNkձ?_}}$lV1&FE(\i^=//YRN۟QC +- />aur''ћw{/lXmuYa4bB biDhfx*WݪL:@w7 ՂZKܐ83y{fPd0yyڻA|Yj/AZa-xz*ph-xaPsJU9HglotՄ%Bf!9B{Q84c;4NT%m<*&3 Ek0xBɜԧeSn=:_UŴSugnCI笫Lwbl?Q r$M?؟ib\<{AqIR=dF]KNԹΥ8n}rkWasJP5gFs;ax1(}DT @M;!r0ʺS+c+' 2 +ey7$'9numN)g7˽[CJ yƘiQ"c,0fL`KLv[':Nh2yheSPJB7uzWԐ$BkH("Z0IX]7W&WÓL >1<>2{i)^N"6 %%Io!Q ` !y]X^_׿uRVpnf/oi(PS`yt<@! YEA\˧ ZDD,`HVGx=ːYEe;Q谻Fy*) U 1GO=`1d$`Lq@ G"lLiqѶ% # # Ɖ 'JZ+{办*^ݝu.OF֫;`WՄ-H %vh724RDGXǷq&A 0OnN|V}c_eLlQ ow?ʊ(<Kc7HM`M#xIK"(mGDA_!Xkn&~Y*/{Y8s4, <}5Rr }0>"}pkjTyc;*+H‚9 PKqM_K8hLc1.=xU4G7IfYE0d5D t|@pCUxunڈ&02|xY " a$,E8a"F`"c ppHйǙ#sw_U cMONԃL%q"vT6Uʤ<,E -FQ45ɗ=5|>Lt򃽃#C-7bcUy~kс'#TMnvDީ%X+"]T1-ڠn kO :/Ӹ7pR*$l\V;Q#$D&O*b\T!ӒBl*bD1\*2B`ץ$Ƒԓ#=J՛PWPPBf¦۝cSr ù+p:m nGtZ"p v7 4׎{ 2qk?MZrhޞTg7<5~REઍpe.X[p41U9"HVFDQnJ_ O2tf/ %/t],uuy}n=Յp2 т(+ny)c&/{C`m(h;J 4'l|`|j2/KϞmj;|#ƙ@ﶴ84x.IvKy/7&]WW2jSuue̲' k@TJRc6|(:Ow"0q+ ^ smiжVk+SQunٛ+9@Vh6`ey+ІBQp"1(RJ$SłJLph۾ԛyS2J,0`rWJS9 .\SV6(KP1K{ݢ\ӿDtm )dҳn<ʿ]^+\V';rWA5(;0 T0tPk76|0X{ Ԟu~8 w[NqT JkƸeA2p׵EING A :}ßЌ!Cmg.%_h=]d6 `౰S=[ PKR}!{Ѣ\yBJa^]pz7 +#m==9@[#,ŵwUES5Łng\8#9KõW]c[Q{rgnTkzw#Qǵ-. gЊUD`vhH' p}>^[19;~^_o?JӖG8NZM98 1Ɖ(G9/'0&Y>֕=!XY+}Ɗ@[%X-.4 !1( *M} E$UV©ijȍ-6oz \PY3ց~xyv*F >J;+3 ?7Ю,HM_VuemsŬt6|>Xr1'ExTޫBX7jOغ1݃V?uYk}35?Ҵ5x,A8`2 *buܔWj˖! jˮ-dpz{pǡo/`a86!,n)F JM)5X}}9}-wq &4C_U,>KңW4: w)]z8;"C-".NnV,I*;h {}1i>i]EF[iKCBal{pL'}HPh>}o{`ڋtj>P] :!r}[`9!["m,=D.a?@rV_>/F{34[ OEQv Gmm~+{qIgm&!9l+M8d C74ڸ w~bV ~t2ܼP+BX$E‚tzXM(@+(İߩT²'IR$nvPKMҹ6 '=IDC>zzX"t0̄  _iB6!>h̠Erlj<;0 ֥(5j=,+DVi+UKl`$vQTƻ.rz¬ZkC`$P`ɦ&K- UKNKjU-tMa}ΒdW|niX"rB2VYM~ǻ>lc[wkeA(-p"rWUVEN-w(r@BU :Aaw`XXp\]֑:'zQz D0ohMݏ/M aP_햿npED1kvow߫n"eMG-> *W=cYu-7XUgW />ՍÙA셚KS8)hI,5>͊2#Enk?OIK֙qp*Kl=B9`,YGm=f۠ \R$jHd(Ygfw,+ڂ fczJĔy͒g*)E PQ >2J%+E [42SVezSKE㈢=$TFf-{H+_hZes 1"J#b[RrG!)4-l# b_ Ϛ!bvg`ڻZi E x"FYcʇ,6ry? AʿB o3Y<]Ԣ8rV*S[hoY+0V%NUVHU7iRd Ǐ]R+,[R=*2 G_鵯C ae$<Ո) D/d#4ν)v5e}&d2L&cb)eIENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_1_mw_3v3.png000066400000000000000000000462561520775651600222010ustar00rootroot00000000000000PNG  IHDR,)nPLTEN6'/:*4C0 3ljwd 3doX[ 3 3 3 3?MiF`Co~Q=m; 3 3Ͽo~n 3kΈ 3znJeEo5 3Q=3b]U 33a;pGpJ8R3E|M` 3wƝw} 3njҼ 3).( 5]ӳZaUUe 7Gwr`Uf|oj |4P}x~  Y"TC_YXz ` \Ǚ,eRA1NνN~o=%tib2l\##9>i&'\J%G>ujM8ݪ& A1KscIgZobX&@15SD=V 4cTy s.JG<rb^NB!o3\C1r/)weDȷhWN9:2;ti #IULJO%7H9<]R0}C2h(s!zCY^JET`/W.H_e\F]-=`xi4gBQǰ-?G4szp~FvTvÔRݚ˸4-WƿC|81#ű}UgpSسNN:lp헖5߹=Km}Orzs8L NY Vڋ+7ew-?8Ӓ-l**yRC$+I =U\N#C^Ľj.'v}ٮmnnZaL*%:ˬMzRduG{5`Z0X*X"6l9c~ƽw5l%@(ScM__jus\~|GjCJL*IǒɊ餸jbֽlC]VwK{*+"r$2mjZU7#ddܡ]Q١\U+b$̕Ni ȨO_1RO[vF2Ʈ(6xp;39Ko1deO}$3$Z ̅cQ㦩g?Y)L%ݳgvݍz3LYr0J~r:5Hy Np\B1M%RrGvCg.+sV-U^ڋIO0=˚k`,NzAb E ,JQQޔ^7;uG۲2 : h-]ln&/LQXE/aGjEb @*Ȋ IѐBpM9qc8"YԸ˿ܻ@7j1EGZƁ. Zx )$d!GrTeAB($*D:ٽ{,./hvLmckTR~R2 ƾƜVa!bb rpC1Y",xp*s*7ow(j૤m> tb2s)כ j` M8x DHh"8Ucr0Imk?ϴ3Urp$C`E 7brL)!0!JpnrPYR qպff+s:7WbPqY+SXxqX F剏?/ZT{"DCNFH:/pbj\ WV#fAdr0YԼlX@/'{ @@ L "2Yi6eڬG5W2?)4,2_K#W D!Y#& %/ ĤZ즡4uK.S^}_ؤ(X4& !XNiCtH (+ FLz^ sp a]1y+L+W<9YY l{j͆7{D-;!W}-_WP%pd C^ WVU+&:2PTQ%5+N 373-鎑(.`1"A Qt,Uyz@PmЬwԙaMmMJ`M?TME(Nƥ}6V!% bH2[ 1SX!z%E/GN:h2!ʊKYjW""!ֽJ0S d1$+px =4ʚWvh:>4$Hd(jeVuL&Gɛ!kxƂ8(. zg:WUK]l imw."ݙ<)A~@!$/7 j$7oﯥemb);_JN mݴSS" dA;PວĎt l"BSO)IQԩ8inJ Tm֧yՏupӥf8@dMp^Ew߇ 3WAAT B;/WYm:*Z@FK1MWWZ^z4jWh3XN ߇'N8v!X_q "or2!T~zhI ֫s o}>[^;hy:/&_&E&:'M|kMNA)'f)WhK?OEQ"U?e3+sVqиO&~̢5^HUA"mFgH[Z[[Ύ3-VіR  )Q x}ϡpc/>^9kD7 bkSKp%cD@K&-KGZA?X{OzTE("NJUcNRO%"S KPk/ylfDiVɥ⧃~] J0c+pp]]'bTv MTҌ@ |~Uʫi"q7xF4=&혁64NUV J EVFIyz(qi*v ݶ'T*-䊈ĊGZf2\R[Yr{RKIQ{{C5;W5P+\cv\E#U&#6U#!eAOK;It-0 jTjN"+ZpYWɺv $AV0.3wtކMʩ\R ?wS+o'Ng_.Gqx-ܾ\(+w,= 77\duҊ+\W~K+8D >"%  NYA+rLk*WpXh s MiO؛ BQ|Ѓke]z &h\u7 | A,Ão}X%fw-*|ϫTZDJ ΢Ig~ֵE`h-- zv\ LH yV Bix$S'%wW*ᵹ` 龾Q2#ԯ>w`UydeZXfy>[p1WTch{+5Զ5Rb^ Pe1hp,&gMJZIIJKmf"x9FdcD*x\,Ⱥ-V& Cd+7\M>Tm=VrShphZ!wF⿍Gr`HdM'aB, X<:s]1e3`RM(SYU}Mw/P@ݺ½|*}gNpJDutkm6^%y6,gLF"HaعG}7&~10 ź\&ԳK0聪zcz (e"&ĻZ2Y+-ËZ2q@] [aZf&_$,!XX gY傼܀Z{oc"}3 FwrHTo O8|C+·ZK*V ȐSNh~vd#.m0B]V V֞ڛKL;TnNЕ͵yjh &z,Hbacȱz~V&3/cb^׀~ᠨ= X Ec\+f,! Ɏɷ?ݐWcredPL+g1SBhK pLıה4tMmQUU$ air: %X2\q,XeGWm4=03 |-P2Vb{at$X{M+dηL8X̓iQD=E R^D% f8QѼÃ6GsDg Z)n.+: 6bel#?LŴUBQV!1`a%9Ɋν62GVyv/ 7E {A$V1h9k(+]kӐMl>}Hi%?>RJ6فN#93;ʗOYhԻ0 ŴU(I;5VN E(ɕ ]Kۛ'7_$yELںBd[o2 M*:Q1VY}k(|6flA`,5zӿ7?ts]8K:ԡr1,ئ k:BN8D j1XQ`U#8 s !8-AۂM&XD_tmaoS2T)M`+՞fUP /E((+7 )#nnK,h0k71qaR[oiG;v/DfĮb^ ix4$XU=7, y%,ֿ]"|^$Fm xfw-87V=>CbҊaP3AL{lȟ %(w%^V^TT8: `VWvC`(-85EZU`űb% T(d۝p 5,=7G.:h%ɞ|Zv>) KK\ql( ,T^03+A+zn1sPn859V+\\w.8طVk$Hi.X6•.Tʹs2+ϭ*p,/"i+X9c]Iå)P6[["-I%Z,1Hn*b>Vc~ʠ` Ve=XC~֨OV; L* 0APZY\ XUJSh\xr4f 3TKBڷ.:;?糒c(Δ"|3 ,+'X4y*+16<>I3 P$CM0FHZ˕.k۝N XT#\)3Dgoc6֪ːC[J;`C ~>qy!ŏhȔwVZ +]^ uVҤ]>rZba_@Y4|ZÆ?HV ة\ +Du ZOsuF=`*~⥨x=Xj%Z-/DIv 20LŮ uW*UV\Z|1nQ@ -'(< /"e N\HŽqTV< ,`zf$}Rf Ts5rʖ`lVH nS(>^oE}!hY5ۗwh:o_}5;V*KD %ǻZب$Vk!*MdrVrKny?j[38`Z64)GKRrc˲" 3dw \~ `KS+bF\ف~|bd'C&sc 4iY2Rni+pT_ᄚ/NEhcȬ6;=elbaV>*|bU]f*|iF.S?;( DŽHbҕIkfq+߅[M CTR$d-@+P%@@5`)uF0vL8:l|{/0)Oyysw#/`"% gÄ1Mq3xhT1jM: 8 &<_}Ӭ,B ~a'i %x[^Jh/BG5Ϥw#≏K9ISX/.Ʌ:-.5)hk%BmXcsU׼kY8OG~v~4I"i|t[ỚQTr>> ȭE+hMtIn}D0ZweɫNt!3prJ%閁#ObjqA-W[w:ET4!O7 sLU?8hΐTB}_u+p-iԫ[n>"nFomRf6wr+zfv4}OUO-ՎNRaQUgVu:BπZ1Ijׂ=C<>vgMݲ˹܊mL){MꛫWo*ol8Ev!rNϖ>tV1SFPD~gTc%wZ|Jz1݂ պ~̣O ћG[ΰc2'olb{mD^S۳`ؑ[+fM`~ sb$n+VN]iİ}.AU xq5I-W.nr Utq֍!אj$zyOr0t]ZIArVv\FKA=_-i]MW"FJ$mϭr.\11αbiB+$ -F̧wҶOlurZR'+q V Qn+{3wEVݹu"NϗhGbD-l(.w2Q !KE*!\V;O/ ji&85-W2d-e/^UqTn$d2L<[#,çViq_4L٢ \+Y-hAJa`@`Keb-W.m6w߿VXF׍\,v'њO"{F=*0GfU~iPU+Ǯ[_PkOpxVҏ9d eo_s*c$ls.Qx)kN'h]zԿ}ޗϤ4@aN{z~T+{~Z e]&8]hU֫Hc,ȡPF/JӜ%hHkp?ix0|Xve`fȬa j[Q:VNڍW"-#^ݽvZ4^5l{/0#21fJTmN/:MRn/˵F`2"JS*Cg4(];jo+}xdxd$lzxqe0UdZP)i_*Xú?x]76[&IfSXXghu4 20x2Xq.ҏ9뮺 dzB WV=W0Wh/F0?t~ %-̉<"o+Nи1ϟG>`U`ܱ)ۓ%޷_ni e?lCFThߧiXv6: Z *̢L8Z%x T_m4+%B8ր&̎->6-dJ  :߃#YX/`yۍT!lqҬt eQZŒuryjh4<)'Z%*R]3ps`ceiw$#S !na7*d6XFL/9Z{5A3~z{wXt~ަ#eRVWeWD@@cf We>ntWaugΛJ!hvNRQ9ɯ@m yłS>>R#IGȷygMfEycՁEk\7`g]< p)7z1Fʌh>,P9J?m,b>o"J>[eWQJQV-S6`R6EˊN``!r+G`-G_\)妉lqOf= ~P*%]HfY2VۏhF̴rf0wֶ4o\_(V~g֏_~gP%(n|X9Mj},S  %,$\h.^WZo-Mgv~Y+`PE#Vʒ!r%b W۵/pCi\T+כR4^Uf3\v^i᛾Z[zm{)gM}gb/b# ,dǧ@fiV 98]J$% ǮScb5\fׁ,b<x=F$T_bi>V=+_R)`r!?ASEr"ei4pi4Ls7ïo q߬!;vh.:Ųq޶GG=zg/"w{NvBd>Λw\r<ϲ,G8 )*RRK֬r5p}gvv<1pqܓsɋ\c`x3l1־9=wc`:\݃=d9%2ϧ5IgMNXVQ"b"(t b /2b3:IDq3`%vcl5,Mf&qPlƌ^tCp\ypKO(D@S懝fXV⬾ۙ܈.1vn+y"i',lw_ DB+0*̈́^<;W@CbbWc3)Щo>cfiW~f^3]qMP,~?P$ #1Bh%Ȫ|:N%yStV tr=Xn5 pN]twAm<M߼슛x50A. C8ޟPCq -wATI!-NMHDPUj#'鑈oxvq094q4wWXu )N+[(q$ /˿vZ+-U9XK ERӼ Mc[?L 车"3\Wbط3d dY>4UTI4ȺU%(4\I3xn/CF}ۊCs`Iw2 4ks)%BYKUeSeH TO *8|~؊*rF7J|{Ǔl<Y}og'JdD Y) jDyo&W! k$ cʸQWm| k[x4[gs][X6=z]3c\0L Dzv/\$xQN(0zBa%(DFuKT Cb™q-%LvZcaiʴǻI{xyݝkfTS2P|'"qh Z40[edKH*Ȁ%(,M$ E.crq+14/f|= ®bɈ-??4^uz\!gO h%x" ~;JqȎ<%TRSPȣ+V X˸-W|r&̗"LЬ0x߹+4~awu$eaY ȉD$@u!]8703{Eb Y鬌XPۚ_ f3^p̓pA19y~v1lP'Df C^P[ST$qw.JDa/.赈6-" "jDl.Y Cd4LDT%鱐B+u +PD7E \ą~gz?W>?a rpnT#ՃǛG8vp&w[W^4~mj[8ȇf&5bZ~%M! וm)w9^,Ėzė2a^!+Nj҉='6ǒgG'Ϸ_=[n\2HTnHKDL)VќZ?N}Ҷ<ݱV_f !#|F VKSGFxko+a.L^(:76\[C:M"zG<1d\"R{!X*uocXYf͡dcE4OLlVsZ33f#/z~ojr # !i!5-IH,CeL҅'6t<[豗l^ rL`\Aw-x0AXyCBo6V/cڱT 7o.^{Qqε9ȕ*2 >n!G~U62e`L1HMrjCLh;!:ss37 {/nz|,7 kjFt>Q2Rnqaa@aN-쵅R94м8OI ?UwMkGgqݾ]O 1t&(Szes RU0vtV@q-filli;A$]رחȽ!UwY5c֢N|ҽ[ʼnpUjūXڧm H e{+E|Zy0%<!xe^?Sk'a5.mt77b/s=@f,@"+E_V+P֚[o/.2 L5yOޠ㶴=76uX_%N .JƚYg2!7zխGoo679B('J(Rtp" ZR"KAkXJ*V\ iW8L6^ܺ}'s ~5Ha@'ty4π(e YÎZ *]Z3ePbf{Zgwmk VV$!p,A\>ta WSWw ip^ڒ+k2ȻAL84: k =p_Z.-޵\"S)Te'߻uוrw`el$`A!IrVɷ&R!)M)&wx {?9k+=7Xӗǁ%U>nUZ3Kl84D_:MK#ƕ)5`(w`Ag4  ymóIS6326>i&j#V:֍=Ŕ+PC۲-r *>T&`5jqrV`4onG,b)\|& ,d=w4%8%H!qqq{]:t(::D:N!N%УQ 7)n.n."y}/k.O~~KYfe`8oXLN?5̄rp={=F仮m]oXιR2Z=Pڔc[t K!ݞy21ӗdij/Ecw4رAqT:^#v>;JR‰C ޺:U (0mbL \(}zIF<;[M2{6iV:g)װ:JE# |lGH+o*{8VQ)ḑ B2+3Xd-Z37ϙAV_b24=Wui]!e 事 BW;rMp&qT? rZa!<T  Vӱ6~ WӽA\~+”gӽŰwV[fZlD:䱐嶆%8{ cɆIN66Cp jw|(?̝7T8V~i"65pBPEڶ@ez%"YlZ7OZ MXmSkBߴ^3R ٰ&4_Z yKˬ?UQg찮Xe%ã,EXe\SBUu;z9=g#(:vua9- "hUr{]5Y]~GؖWZjh^j )=mahm tumqղO^?zkO 8-Ra LSU<ѽ7g,`X%7,~㴇<`5f-)%oGiw2~ .`%j t),)w3ch~RJ,M$^AM[{VHp@L#eshvVP 8a=,6%C3ʻgCbX4yQQ*BxBtio 05H(Ҡcѵwc-(Ph=D/Pr Fa> PȇؒM$jJis^jivaL>7:YFRSMp0gz\{mBV|_Iq_aB+qŲ癹OcU0Dss;^X,SKpVAjVξ$pyj5xO~ra]bM}GҿxaJɵJrDC^mZُwڸߍoDN^9\{W4ʂ"r;QtRNS @hE !-i=.RcYzB1НVMqʓ~èĘtܿΣo#ݬFTIDATx , J{kS N 3iS$_ڢ쪙Y6oD-+'XOҶqtq)Tz~r4UrnYSINU s1SoMۘuP!Nb`'O)L)]:AWq9U{dV)qe3@mмG\! 8xEUVڕ= Hţ2Mze5$#CCD Xz)\~,hհ8} MI!:RMpO&zcFsi*lDc )>dU+M "]dl9d0/uL&Z,BW, G v@3,݀ec'xt\0sOXa)Nwåox$ޛ:.cKHOH3vfp_io @vȀ֑ v*M5(6P)$$a diI%~ISIe%QuW`'BB?>~Hlc缗mY6x.ǖ⡥W)ՁKps?9du!ݦheMʆ"x|[M](iq&ǧYeѴr$qF+}O-X$9+5ؚ!0Yf sYd"kj0qW&/3ȢTYtAYO-r,[poB5@i9:Jm9Jf5y޺r%m8"GU^q&9,TU«j\IpeUբаSed$eBk TD2xdz Q7ǂ##N׷۟g ;YD;Bws[_V83Xoq+| m r!ȰB/D/Dw?[LjrHIpJ[0$P`T 7cP9::^Z/ ELziڎx{;OW|T5[-u-O_֡j]7\t_w;r:bv?w؝Yg^;wX;OG YEʩounPsy_ ,CnD$,|68N.+Ja\Gq9t閃)ߦuص+pr`Y{]]-5G:z )矷>2LY(-?G.7x[;meNkMIxeQfqޮ,MWy+iw>Ǹ}#3~r@q]#h8ܿ:tsR2鸕ʑu--m.^F oP(z CeUEN뇐O\zp4 Ol1jSjՔQMDAdYE 3gn8Bwt4=[ɦ)(%f3U+e'*=ǎFQV&S%0D ( d.䗯@7Fma?Sd4y,(yrєV.U<<4ɔ.*Gy&2xA4MDym.f"Bt8Ve;)ªѡK!J~#6Tv#rr{ToAT!EqVUߙZ2 b%IMOUCs6fwj<>+!"^I1Sph>.+i"d"hDFQCqXr~TIRFCL6]7V 5r!N+]y(R*(jGz$Ũ*{ Bq`$UӾ H6+fºdG5"$E`a&a#:(gŲܭUl5-o,J-DI [L QL юlDA*B-$2;\M/LDR~n99/Ȼ;TƋڰ Uי޻Dx]Bg&Wc Y9Eۘ @& )byƼ,+5ɉ`0-N Hh0RSqDbR'Zxwv * ˉ[qLI-0$sP(IZk..0&XhݽtuJ|ťqT5{: {xM/ZH^r$Ju)1e@V>&u4<4pR94"HtJEIVo:3;33[)˳Ӄ u2'D'w}c3'DWU bZawS%#Cg 48MVWgcU'=v˻zή`,`^+Dܧ~GkD\aФ+E~[w7l<\*KPH1`Ǫ3,Wٵ͂ h MU+OGSħ_-8Sk1㐯,BIv.AKRjdǪcccsǫcHY}<T|sVxO7}n<Z%9AijhA*nnjij!Zp2S|%E*jxbpn:zh' ή9uվAn=f5ſ50PTUPE]dZ* ڊZp .`WGGGw)Ђ@FJur F ^ `d@)XKf1bgMNCRe_e|:3Vw{#B8;/ͮ#DBJ| >u9@k^7LKU&qͭ1)àeA˷TH2`Ia F"ݹzsi(`31.Ff{ikoE.+D[=쩥) J:kqv6RG)P\ &଺xKNoy8=t{d<~Ř[5y4:GJәtlbjɬG(VWPmgCj<`hMX\߸v?Ov݅U$v}g|)HL%I U(; )~ajunT-[EujroXA;R6^JE ?q,5kבc 1\k+qy C{ ;|@aG]W2g+ E;}FQyի/q#o)$2|!رqm@ Le0*fXxw0ZV5] +E¨sՊ"]?2^OnvC!נAUƹV%uȸ؍Au`>1| Bf%03k&fĵknjcԖB۝ Փsoq[Tf 2T  .Ji\n9_r>yLhlЗIX.AF4݃pe%Ľer"IA]%X+/"1 C_wȁw0tXE,K8]naj"` x$N1hE Sĭtaih2a"tBIY9Q΍v,,yZյvuIYN|l#.y1p!7v-I<񵢙G|^Ch)LZ XH lvbsǾ63B0uWW9LI X4*DMOwezWaMhueXEgҠU&Fwv&-Muj~[{,d`e4"Ȏ8U4f5+JJ,i#˭]H\mVPrWyk.҈zfg&ґasX?-#%E{ki,xJVJ6Yr+@YE( ,k *]*pBq!;2 sZ7_]Zi:T~L1(SB4> q.a96cP>5DPQ@kh-+=a+":F7@Lޱ{fFf6y mCU" Ǎ 3,Gq,i:sH2m9 -`*'p%!z7 dM(V233QͧoiXj7VexH?駧 qji8LBYe[of%szתKWsh[GNaS$ iPs}fE-p)T8lR.jFa3u+^#[77c2oB; DvI\>YĊV [jЪ.̍ +X}5܃/I{^iRTyeR dR9ٵ7N'C۱L&< &˴?Ui,ɱjVmaNQoҀ`Us\Ps~$A+,+Aɘ'NIW%I;͚C%?]/cp7f23h1W*d\H>{%SGhuፍ 3#tTx&Fj:IBz۴yw,i2p 9y.EQw1%rZjy;Q+2"h|k,úXT]{s(trŌW^1 Z$Ų.ovoN_!|a^ƀHo҆IrR+$ xDM(;"'X*]T#r+`(KuF-Cr0Z.Vjq{ױOcM+Y#R{w.)*A^OK8V8~Ky ZS:?\//VGnL$.IsXFK^mO]ع X`sU2 ݝUd@eWpDTp4d.:~W5xMiq'+D27bߝ.X) û`S 6m\TA5]=(pP "k7b#HT,"U u ^+\4bxc,oL$t͈#hÍֱ #Ņ˷`])ϱ0 Z "+oAU"u?>Vq.T8RWTP2Xi8% s@%=-/\83rsB_\#b]MZ9kP* ƟV*5&79Eo2j K!XMZc'F g2#`[Yt…7OjWH 3dcӓqɂe!A4٩a 4vA!~^V dԂwYn,> &MXFkPlίfzW[QBJj{tnwNA$-~jܭp4oy qhrrj _|䑤uc?zTok,^cf3DbEk+֫IN ! ZXuꪁYe` V8wX7+I;i  {O}thX"m0͐w#4g>y ^WX[ Fk[b3Wq=XqgFX]}9mt"\4LdcΙ)VIM #׮nN`H@Ǭ͸p 0rF\)dyd_o݋g_pzpsEN缮gRm-iHeB{ňQ;@8YED^i53 b.bA^)õ 5 ێ}$N&z2I|MDjVT9+,+򬖍@*P,y-*$8r f8iT8?#VRwn?Qm 1d  FL>fvb|)3^6QW*;܌ M1)vVVJZe@ B)6&`V;9=+?֕,@*޾jp;~g̊qLq8Un7502rz@_Au7$V=s+c>,\fVJaǹjbaP{#LӨ <3j5+ [ұQսݔhWc(`4c1e%z:;{&o\B+DNAj-`&2Ocm6Evc>Nr̅mC&yݑݷc lmmAj׿wNqK4D:w4S|K+Ww_2襠1(˅ת0BdQxǺA:F<8\x{dkrkeerrd؀O\!4Diz~/%$Z@{˶{_Tƅd@hE-,!aV޼85jkv;(}4)  d,9"'M5GӕED+)B;UˎٰJL@+_CCg^Q= ˌ SAC\ Cp,(L𮟆sKd֙YSQ!?]'D)|K&coOhk7.l oq&hxrW˄,E=bXVH7d'5Wȯ:c#~tLtiZ=mo4%uYt:AAtrZ`eCkC&?o70hlh?VyވXIvLȂ"t7o7_A%COO&f)<ϷmFLR΀ 3 QeH#{⇽ᨐx/ Q7tvֈyC=֭څ1КiIS')or:pr~T)T[^p@Dk\&m{LJɢZI:l<?XZvخ v :7O)#hsX&%9JNR ZFKflrY FCP`,L!‘>MQiCGfmO>1S(쉇(2pr>啞2&EPT7<áq`xX`AgG^ܿ6mԡ0nfy:g%َ3x >oȨGFyU4BNDeF,FCK]6f{y;F9yack盥ΎPPy?oZJ@?{N&a|Vp,XAP73mj\bhvM^c\ ovy~Y#|czIgA9mK(s(VOI:h ~eG)Ǡj'ޤdzpxإzMAE@0A33ӦlÃ1Ky0feSlq(%2Pfy<F_ +W E#2_)`hW6*4g=83pOjm+ E`W\^^ Fw`cW!d8HS }Aы͍@Z\`'*i0q- ])6nꬰWcyyAP\sKSsJҘi V饪jYY.ݧ7'k 7`az92u jq$,{$<;XDHG-@R5 9+78?mV2wh$ ^##û`4p63ɗLP]N36o ^w817GO&c > L4<c}i?,ޑ@KB?*X'ZbP˻ru  eo\2*l\=H<2 U8/m$BNTy>rY;YXXOϗx^smNyZ٧ 88v"F;#/7/g3HDKg|~>  ,843,#  m:uUNS09sN㨝ڮVzm'ƾ^c"Vǝҗ|m]WA4p~'w"O,fL3XU3 Y@ KHpQ A6.e`;mׅ3wSlN禾]npf.)m&9:C V`lW"0G1 UhNrXl. 3#Bg+)h}V[Ժ~v"тL5w+]YbaWzK~woqBF C!DefM21B\)4 )B %.=&*+_/6_@KQdV4+Ƨf0kѷm+˻Z2zz^7M,Dhe%Xah,ƕ@#M aUU{|ߵu}œnOjѨ7yreup~+mGA\KqV1 f! E RBHH5T`je$ѝWl᫹.썵TNmLU3ى4{:D *Mq R B}ABƈy<=]DPUF #IH7LG\ f 2yD{k_VjnjYgd//Fý|C%Y4 .HD#(g9C4+C BhIdtYMd=\ڇ}r*6/+=_K%2 <_5/rC xYsq@:DEpllTu @-A7T$IozPRExgJ䲽Ud뒛:Zz7xL8c]WfAF`hAfwgΡ ܧb$cV0̃ _[?Yܰ\mu 1 )A/cf2J< "Ա$ bqKBJj3+Յh6Cʃ]\mVnpf89 ӂJ8AYΟ;"J X#J(hJ0^N dvy2Ю!*Q $u)h:@eL/){aKKU@Ì |2 sdcaX04 fEzKG ꈀ*I CukUg׷SEON}R{Q7o@iqOۍI- # IΉƈAy  _]MhAUP("=zD<%(,ΌӬ2Àxy(2=M#Cm.C{;&Rң<)IKUʝqع&ćd(mgՎHeh.aZO*}ocpL, 5s[jZ<*Ias#vjGIyxp2yz~4y/7T>ɑDxn_~7M  Zcb"T Ds%l DxZB*Iy,Ɛ,9c&'||cѭ}'6< [仫c&f_4d( CI"8;*]R@ZAtih c1s:;ƖjC[sD_ػHqK3g\&ҊrKR4SJRR+1yh,i$*GǖL \>}gɮtg빧n}T,`Er& a #uX7`gN@Jr]ad$okU˻j2IzA$jcHq>xՏwMHDm0X[__יOkJ pԀm #LyLٛ$k*fPc'' _I? d ٮ%fJ-jw>?iL[̐«v*Z13:܀=9͓W5iD5u'.(`BH"D2J6{ʮ\ PrR}6a t-j;`3ڰu@/Fm{Ȁ埝^u* .lN2nNe#A`ф1߶ҫX,pEei*XC#E`5'dy:p1x! S ,// XܝA_[,K@BFQ ,$1[,,-[<+6bc%\"Z~=T"EK.|ߛ7YW*<`mxɛnٔw?ڽkK:+I{:A0~E!~N]a[XipR"eJfBƜ^rN~rN rRe$0ZZU`X}0Y]&ݾ=NFg#f| V*6Q)_crc2W/e8k~+4}2~h('l*,eG$FM-ѓ +@-XIUq3d&,#zr6ĤrT:aʶ(JĔgy W ΰ`ߞl#־=kH V8ȸStFe|ٰН=tGa9#0 q c+۪zz2+;`Br2~V>!rp .\ V0ٰ\%ѥfUwg5)!Xi~)p,ޅXYoŮVj'`י~VlL9,]5#/"ƣ4ζ禿q_aZM{(U-,wZRS ]_1.Hֻ0 -f}1^ r8v@.tP r^" (ki[}\`2!-29#yvmcψX(1 Tʨ9ZZd ŝ^lpʂrpcXsWU XU8XFYW+Ok>#h^X ۪aq*JVyu WW|b7USVM(Jه[Cauxka9|ijjl[־`5p_7ރb'Oq%a[P147+1Yb% aqveORGiKL5ȫo_;\RFI%amRN䧰R[P] %]6XNsG]d2[XJJ$nV[<`W>' Y]O@bδe KX*ȍmX ']+rtyр%| pklaEA ˠ%~;VkPZBZ߇!OmX-,lop.s,K3L嶰tV 0nMJtеOɛ{}kx]X-jS͔ SXs8n0%H"uU)*9@nZ-s&uJΛlf==m(.LN8I|rW?>;O0OX!S&筲{RqmU8I=!}[_>|޻xQ%=h~R{|>O?w[u;X~|Z٘[ǔBO íQW. ) }- k[GP\]Vo8H<3+z|WdŬMՐ굞_e]jT("1+˵7^eaY+L"X@3F K~Y+R+VJ+^)"V41[٘:GaDg7TQʰ ^â%46so8e570e=f%xQ$Df?m5@ $(G|tX'3:,Eڜ,[VdI֭e׈Ёd@"Kd`$(Ve&rHkVTZ)#JI8ڜr?) d_L:hDUߌV>2e=NBƒK/)k2L&d2*?{-|&IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_1_spi_2v5.png000066400000000000000000000445621520775651600223500ustar00rootroot00000000000000PNG  IHDR,)nPLTEU<,()"U 3 3I2# 3 3mf|P 3vnj|4 3 3 3z~oHsF 3vuc\3t]h 3 3iyxvzerO:/ZTIp^gZSjR?7|bϥ}IJ:gsYCpJռƴ 3a_ƳfYZ\U TkCMO xsJTTL $%}x KIbl|oi| /4 )) VcX`b "m`CE:QZ['-/wjd!LM' 93%S+TF;/D1szv j!0de>\O1TA/"|Bn320$#=v{sYB30lFŸ}Yv]Ng\L~fH1»|[cJ{İ~hUdz/ţG'dopFr_J[͊Zmlsfj?_0tʹGҾIsrmnIʷ~S2TشȽss[ŢåuҀ]1} ,ONONtRNS< h"" >=phy)RPQ\?{xŠiˡԤݠN,/EIDATx얱r EKV[PPÿH7I`%JfŷPB!P3XDBJDJlľxNM,LZM]BOQoPڧ0w4k?M=*;+EJ,}\~v 92v]xTG.U}_̽S|\ !jV16`B(dbʻTZtrud/,G@ֵlm3ײHvUT"Mf+( 8$k9+-F4S ViͭD=>}$,8iǗy0sXkj5ԕ7ȲÀ(xjVeBVB.CDDRVf1lN dE&\ !=b&, YSSIwӐsuM'3,auV kp!N.km{URIiUpASzPHSVE#(g (TFԳ^VfEmeqjjjW  ,FSQ ~ۢQ, ?ר [4eEQJ ,Lh|/"XThԢŐh1DKD?',Q+X͕I^EmW`,sBl@VE 15Y&(1V.pJɲ(qU\&Xi|Nձ@V qBskIsQNgGY)`湪't{GEJ;wonq| mx X.@c9MTӝ=mss%-B/NfarTdhĠMqvJZ'K QkQ5l֗}{~Ie3l2/ForVkn:z|aK=).uUv ]y[[C B/|[/t4Է4]igk?Pq7w BUqw?;뻻=iv*>&:'P_vjBixwToQsHO+ԸKߺelYsBjwJ@FjUh߾Pbu\j 56ȅĞMu5Е~{rtj^~OWpޡٜ t5Mi};מmBJ[u 9kR=zrխm/jB"|~J܊|WV l۷O.RreVp;gfinxd涶:Hl.6S8gԅ S֎ǁ s:X,_d" 6.J]ԛoN'>kJLOAl8!g 5Z!?_\tQFt.l):f!sW;zĖCߟ8vAU7t*VFSpDB7a̖PN]Vx7/\]޸5HlmL3C)AK Oj)t츂u|K8}si]V}P^mk}0g2 ZF*IWOH&RfԆ0it}SgBVWC _sFE ;d2$)Shs&93k®zxZyuᑂS U>}[1*;6lGT^dchC0maL-(!`.*g *?hG%.*ٝ{d$74ZY~~jV%:!X¶HBR:7 &dUVnQ@$V潏ƣ=Za"|UyBPIX *W ƶiI+o2=CNZT lCMfQB BdRDb:9ZX*]tΦ)N!C[zV]A[UY?,.7Up)Dt UT%t$ףhkuf'̤)X%Ҹdd- c=uդ XlJŐ=D b)!SdM|OTvyhIdlŕ 0PUæfAuzt&6tv1X,=.idai 1E*\ŒUEnj rJf8_ItuD;zz:yF'y}TKJyL%V2Qǖ\(R[gF NF~C?h5xhR9|vBW*MOѩLgTí+'T׃론"-@U=-L :D=@AxkӵS l5aZ@V '`ge՜AKJwtR+V#LjY*hHvJ Zz*wЮɮS{=8QMChya+6-uTkbSʫ;)!${eq> wlrrW:N-qnd6ui_pVv7l_ h!$W#;|8;k7AW^ၯtKbCOa vu\ 0i6'^ W0'3*++6 VPhnttXnt0 }PY@`{ z/Nuu)Z,'1:&{Mx,ꬬ)m>æ(VEV#}}5uޱC+Ըν}@ KE3>c&IHWѸMiWт쒩E\?8000x[6ggtɞݓ yBx!B8Mffp V\Ӧ݉*gYpo.Ǐ D ~·75F*[<<g:[WP֩Ҝ٘ @43hȪ Kc㹁=h@_t3h{d~w7:ߊ&oԨیɼ[xcJXiRh8ڣZ9F,) fPWDJmKoЋk;Y/BWJg%1^;8Cil'}g Q+ Wh4#xIt:/7C}D\~Vm]ԙP ՙ}̹Ȩg#hJJت.#P(l׻oLZ&im~FQjBPQvx qC@m6׺uyDSZvIUVCUvu0;ɔH;$ϐ!~N1ӚJo`eQ>N:4aLC2q'ڮá`\wDo+Z˥hrK_Mlv` ,y _N#nVC >q+km"s>}p(0==s3zx]M\G8({ [t^ir>"nCȡZ611*\f5hٙ^R ޵MTv$`TZ J]'@my!T.yM nCejsbh5;cΪF]dQ-4.fcsipw'M|q*v`d5P\(Y;LE(,RO!d.Aw̩$\oy/&%(;O9h\o/,vhmҩՐ=!CZ,=~始CseuR#"FՄ֍!CsȢ٫㍅ZkgZƵɉf38f1AJ"Rw|[F9b:B s)[kw)0Tp,V0j )WԗZ rT+RA>?oҐ%+4tGma7 T֥^9-Byt5'EC,WGFxyih/v+Jѹt"_SZ,RIΔaq!C%` b]25S]W+;tk5T%l|@o9gu#SX j{(mDj{Ksi#JVߊ^RF1w^O_q"AZx -nz 5J *Gӑ:Nh&c9OvȼW(K9{/,lؚ[_ c{Ӏ J1fqHagμJo@b?&'.K{BYkp.'ŻcT__]\SRZ* aWa[ "A=FJXAک_QE m=?4ADR &]xˆ*aqLۮȘ;de!,?Zy5iFNEi* 9ZCe̊5nqkHŔ/'[iPjC;)A3#ccؤڭ&betgPC1ma8`Uz0U$Ll+N(9Q\X{lo9Uj-_S A9' ܄:Rax^R^m iP<=D^^(V^ "R)YR!Gr,dJ1^=! 3Ѿ Qv!/<倴" ^ML(P D 6@"@)Qsa0"Qki=f1F; Rt ռb%f` O":XQX]MTvŽGE0C0V%JUlDLJ >\25iBP#H;qe@ɀ럩i*a4s֌]8J KE|'a+=B5Zs E}>DbWMG1` hcΚګDS2lGI{5XlÍV p/LّSX>H8y Cnt8A"X-Z2C@; 2ESgH^^{y2yB|&[-K9ܾsKR;TaCɗƠyj<4+*q++`.D+P uEZO“*tuYOl6( o><} a.:ּޯwR7לAF䍉Ս`8EB4hP-A:-O4S׉ܾZIe] A#-ABE>߾q%9 R$A *Uߠ20'c(D  czԼQܘN\-G'Q_]Xޓ[SQfNOoůӛ8N(HaB38e5jH6 !{(H~e>Ĥ[TBC׉+ ^ȉQρVb&31.ϣt0Y`gL\8~o0#A-:6]lg3^,DI!7WܤWp4XMUXa۬s.9sBS՗[)48r7>6lg7V0_Wƾz5 R Ři:[T%*l2$ݝ; AVP|:j__~i"Z1P=$A{ nIXL3f 1d?dAԔۮ|6o}3Э b67r-WSs,/"¤58F$b GeTv'g%bJ]ԉ;x]?~Ooj~w"Fߺs~R1+"ct9ojjJQICd/(t84XX(7S̎d~mO9rcg0(*{$bQ3tRT+dO5PM~;tǓId=[GlD:.Ъ[(>Uқa=ż2{ QjGJӔ!Xs8KX혞s֓MxR鳿ۯNң!b=>[5f BdCکX2SWu65W?v݀g+jǎ/WNzݵs#5V?}vzsZ}KPX.l!]`17:gc;yIu؁wkObϾէJΙ_g -\.hbr\Uaq W֒\2_~53<4θcbZ~JX=ɏZ7[+mfTaݍ*ejDFG~#?Ma4;TUI U< -ʫiqͮzC~Yg΢ùNѤ98'&T/SiDԐ4ꥉ;΅9zԓ"-N[ }=VJzö@aVmT6l b??HӋ^}{yzfG#+ߊGUmhv;4 C bhu V}!}%V-Wڵmpz8# G՗OdXϾ\.\ܲrv"7.7W ZJhl `==V@rRp@^w7W/jj1GS{ٹЫv64{]Jl>_Q|ja-[مxPv,֋t=QDn:d[8hA%3;QFͨѵjRM&ЉyIzFر}ԣɝhV|Vرƹ=B|gҞ{e+f{1;}w.)6L0W i;ԝg.Q>k5MӯM\|'^XIi)Y07sZH9B%BpT({{DIm .}(Vio ~_iA@|hrnȡs|ds2h|PYefn-~]OݮbړIWڬ6w@25ǾI@-i mB=-]P>{t0=jQ>} IZ[qi/ ET?NLD'rr-TcK=߹xS>DAJ:8N8drMSj<6SnjS_j!G@ui  (˦|xDsrdj,#,kB&cK ;P=/}Jgo2Dk2V4]~`DBx%"U2+~᠉4-ᡗaD*?Q +Inzzzll+gLI( Vj&ZٛhoT߹53WB5|5 ыCPV V*SDOʩ fXTX=ܗùn ϻ:I@ m+=bC7εl]' >P X4xIDc1b +*0H2-zǽ{>-L+d_!X=  wYHrU4 S Wdpݢ3L@E6ϽZ.aԡDdQ#tccQ䪲zeY^jP,]ၡ.k3DpkfiLdzu*ӊG7ߎQFد7/bˠE aU,V>f52CX] 1\lDYΛ:mRSVe5G'$>xXKnjSX,/T BѨ?kh;6+ex:jBCokJ&hLծ& ĵ:OQ8t+UTݞh,}O4\Fߊ}h*6}?fvqX)Vۻ0?e56'yA\ћOY:Xչ\,V<>hhK7BV%,qf Ly\ҔF^[@+V7`/blJMܹց zSM$ʨ|@"`[Z")0ี5eIon1hPXb*ijK(o\y~cZv.-$ʧ|zd]u_`;Hs}# O5n`DxٛȖ]y pM n$z~^ʘ]Z?W{~OyFBCXdԎ~ڤHqɃXRSlἜ'uLj RFHpy1[6m7I+V,_|p ҫBpH2qRV3/,g38zVz=^/ƨ,*׬Ze|,Lh+g,,7Qb@3¯ǣݡPciv lܬE/__rZz<ܕ)rq>Ͷ~=hS͂ aߊL .\Ɏ9ukydxW,G 㳘 rSNM˝ϻyLܓ=k}e2R %T=.'0kz{"ve8XXKq֌gS6lVk]Rw=aKNb@"bAUn^uΞ׳4񮝷8fTYYjέuӚ. _[ZW0G2=B컁@ Z,ܫ2%,ˬGU[: s7A.+JAμQfVp R kd|D!t`ERY1ACLb/_U-+[-{ 6)1e+ n65lkbP`|)OqQZ+ K 8>@sgz-3u¬w9VՍEsJ#{}* B *2~1$Kޯ⻮nlRVhQxVRo- !\.NՍn4aFj=VO@’X 0DcRRɧRjrUZX1 BSZXxrUYrbXw&Z͍k/O>70/KOD"p0Y-$љ7, ѻ6 .?1wnƗ;[HZ:gk.?*XIIb!/ 2 =|,9ݿzhLlU8oʙFJ9GW׶oU/^tVk{|e( rVRqhtsaE5 wΎ'4I듪'@e+T o Q8HL^%ۭf$xc}'g1b91(0STD>vu͗#S"lW&̿5حO;KX<{bۭadNkw BƙOd '&%Lx?UGR(Iw b(e^E4.LiZ1cwOkrf iֳ)Smw׫`8<'+LX$I Dt|VqcJORˉ򝉥 }n=u-w3/gf !=T k||&/c4hDB,ȥ`FZ)gBPJ,tn(#l y <͏Lkk[fd5P$`5֭gC|&q/%Ɋ'N CbL  5F,cqB O<-jrX} Nٝ |!3P#!bرw&H q(xjv D>~صvSMN4!p"ccM;lwl(!X;=@kg,5FXۡ@c9/Xp+B5m"w~S5o]/1ُ#4гlJL"diV<'%NcYM!İ,9j&, dcˆa 0*1qj}2T5j= WH?72 SSLxAέ{CTQd1/~V&L5J ,ac0` qfn+3DTn`_kǰSɂ[Ge*Pcl0xE'W&;ʊ5ن/ǐeMUbGj庽rBѴY(7yfe@x&Opz1\ c^$'סGQʲ?ِ_ a5 cAh667onol1_j F2skT6Je lr~8%E^$PG2Шt:iCYb#LLhyp?) QKhl,ku7c Z8o||,-q BS!gx` F uVGlJR\02Oe=ʩͦ`V?MPQΌ1Gd*S֢1GI"9`@{mˊA[LeMK#6AȘΧ~fyDkj Wj뎵exP8JSnv% V8+:ِ6OzZ{g)?kBI\ 1+@=^QrU>ܜDo=ѹuW6ʱ7.ؿi'5r4i@b}҉&9q9,gax0+XB@ӂ*/*yP;wgCK罾Y5{6uv`8 B})s[}pc\M8Gg.=j"4*!f%ʶh MlLmsŋkF.#)6A}nNɣ+&W"!ttRe; =]DZRZI4ah`zWʣz3ueiYuk]\6r8 q¥yᡂ* qED`na品T=ҽ\Q>@k(w_OĔulѩ{jg6rD F\aRpHl> q@Sg`"t,4NBHyx41t5{6ԍHnǗIOjjgیS>#GW_q!*1iHPugPgwR״$Gz}]z"[Ulp܎.igw0vA}1U\ӐӗU&0ИApxI'@QvyVF̤zVg%6 S]rpo멞{}HJ ΀c8|&Ġ6h4tJG$)}|ʼs 2nV W#V:׾`EufO'NbMiY 8 K&J!RA)ט %MU RY)7Y*Y}˦1`v놃ݘg7rTDm6Dpׇ4q7qpCHX s˦]?52xp8YZ8Xm>uTv0)vk@F[ԇY.uMBu) ƅk$T]G 'ʉ>~8d#ar GG 'FX-cW߱o]o{mok ^ J89?#RaxF8ŕB;@Bi:W ^-~nWyl_?e˚8nNuORm%]j(Rpr&+W{A*z"B U+MV$nڷ.6m1861LT0 e( qIJ5>W{:@ tDՅ _tG7'"2WEj`m\a7wmlِyV޶ 8 F4=5oH } ~$LeGF( bkhun8 a#k,1BBOξz4HQY{Ln]Yq]j]gq"XСRO&+uVYZ!W! 'yj>, "1N`븝~r<]( TbhCRȖRTv`Вakꢡ'AIqVs2jEc.Ŝ*K1b} tn5lpr%8ǩ/*ۋa1{IK⺂s2+#JY)F ~vz1 *':#bXq{P-e񀶊 KF ^,#%AHF7nYs Vvn`A6wyX-w1zg7|7O*AF)Vū W gbu} vdEBo+ˆ*Z*-KU F`R-@lfd1-_#k_v\ } 2uI`>ȥQݡ%˝N g j'lD1V˭.+*hHjku|*ըeb9 ־Et/"/i'g-MaWz+ c* E >5vC wa@2 c+_;hYX֚Jb'Ɂ ϰW]%݇g8^Թδ9,C壃~a^YB@EYӫR .c%nh "Z|`5#}%޶q3ˢ1aj[bSZ~U6c 1:r=?aê~c]/C_YnE 'Ju%X˴b*L\dC湡,Yȹ K6疑nSwkԎ46v)7|WrUd ,&q)Ӊm]EzotfۛbX"H: ),V=O10pK`3IնgθEKBno؞Gg2z,lA*'1wsX" /-Sݲ8Ia)n,!~]ƄnLv/gW;R0CghqaJ* 7 /GޢMKumJJ)Tnb;zHC>$E[3eSFbjqMo9vxSVhKUz9s[?xv,S<-/.@w<Ń O#|ˡ>qzhYGc: )%b8`\H<:l^@IA;''q?F3j(Y2|nX̑5pea3I lTVzb.ɩyH7% roYplLh QYq~IԒ*H"bIe%2c؝%kaUZMOGWK=%Ks^̧Zp {5Bn,*> h;B Vl:#zX0X_õ{)1e)1_.Rg" nB9Yzȳq)%I^IZQVi9ں+*9"c*]V|ojx!Y"& %1i"WU^ȚY1,dyXv)_iRK%7YDd>+6'a,'xS"R(S1AQ_ u gG)뿠 vi&d2L&_!CǨIENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_1_spi_3v3.png000066400000000000000000000445231520775651600223440ustar00rootroot00000000000000PNG  IHDR,)nPLTE~z  T6#V 3 3 3 3lx 3[ 3}tq 3Mn 3 3 3KpAvtkxMy\s~Wwg 3ȅjO9. 3}zfg`TpwtgZS^WRGyR?7iu΁zZXMCpJbFG4Nc 3__ZijcVSjfZ FKCNP /4-// J '(!&(HH:=~nV`a {oi uʄwra9mp{u :wjd SaHSU^jqe]' ~y([^NZZV+{\sn#RTAHE-:9fq0egdTI8!?uy7>?>pzl^S&ǾYzh y$@h_aPȲ]Kd&6:A(=0IK;Emq3aB;x<ɹ 14yI[.9zE#eU:@SqҊ\4r<5Kn ȯ kWCesDbp<*ݼj+^_ThSm =n],ˀ0T@X COkZy1ɞaG%z!L:\Ϙ !U35cgt*5^.ϽVBW PZ?웡n0]8),0'U%Yҭ!C_O186$S 3R.LޒN ߨᡖ=)JI`u(5Xx؇4< =,E 41e԰is ^L m+GXAJs4,HZ1@X1$+75~A\Qo\*J,5*S> Dnf;J*LZIb(fE*o؊7HbYL hxʳLXP"Y^@'BD y? ^G~|m%֒퀅(EsMe|9fzR!_0rf|s mx C|`l}`UJQ_͞39cf;qhZk[0 HVӇ8,>h'֭wՅvcq%UEQ;35Ifه?/8x{9yHg{nxG7WWtnٿ? w) ál|w7/+/h |:wڶuOwwޅtyE-.P!t6=66{*q񴏿n_VuoN85;}ᵏolܠo ֱ@7o`m%/}cS,~˶ ߶N[B50h-~PhߛcC- Ȇ4ysC7+ pu_d ;V۹?'uItk#1լ1 `q{S-M wL%n86=}qbcc&+!f3;I`=ܹ3L̾x`ْaH\lp(֖4\[Us2+7ٶ ɸ dɌԆ5Cd2ٓH DTU|DM.˲FQYTkM!t3$Į GTpx)Rjk-;K;J&=,CeM4LNeQ~0txرًhx*V7⊬3[B 2粍2a~e00puݮT"9e+ã0f/J8X/:6aJMv\TH&TH#P.j @^NCI2XN>yrzFǎ&Ro7{&*LH5*SKBčLd獵?n~Ś(p_ZX|()1L&͔]ӲaRȜ*/ǔ?ccM|zE)5 oԏ%ߪVB6q&%z*D>أU  _xqq %/f_#S0U ;qmPe&Tff$c;?̇:^?D1 Y(WIgrMɪQt{*"EP])myFO\;LPȦ{KrFxQ1ӇB)@A+hV>rnc竈pWt?2VUM zB o1x5t< uU}+T1pSP_?X;l`QMq@ }jsX*J4,`1a,qCXC=UP+DWŠSR)kY'BVMZ׸ 38iכTQ$sM*3(=1FlKVTaćJ.$hFV8R' V'V׭g#%iRtd[[ N-dY,0 e[#$ TΞPÓ +%Ĭgs%_ZVLoytBL7bxkHR= wTH%fKÉtN{=}iWHUJ̲pK0MZ 2 ÷vp V=鑞t)kkAgR*;(q@@ pŗVm]Mb8Eb&+%7-/r*,\S0*ŬC"&:KGtіҎB3\&#:\+lE {@@hr;E2X3e TAR$mo _W}VrSLFFU~tLe5M jEURP:P#hv]Dg4rSNv?7+ґɚI &"e+b&E  S#RX̓V Bנ5 TW*{+CCSM:ʜ15~`}^tu-ZL'78j42%X7PGggBpJVg-hYtxA{ |UdP 6C徒sЬ119%XĎLA0[+YܜC-x'[9jU+ycFa )dFL~j>*RVv߀!TUʡݯw]{?dј=-fs]KK[S]>.JtMOg3V~-IP~gWQ9u3=P74Ի(cD'L9sB|_.eAK f%'` Ҳg(_%瀵w詽GUZ#3EWWcD\ޢ?*bf/GGGGǑW&'T( 2XAu4-x\WLƙe&QU0έ hb^ƗD~_ۥnKbC_=X?8Hx;)dH K٠%*H cԮW3={>kw5dv]LMPn@?8P`A&1K?g2VC&$Ǘ334` >#۷ C]L|VTd5=? D-_OUL[c +f]OSRA9'Z-?>:חN6_7ןF(KI?bjVD&ޯ(t˔QLZkLTiAK F;RY@n.YwZtZi6_ys{q뭬q:@sX)p8\>qAPbPصcUzBTXtBܭp򩎖@v=6\ zt}t&|ʑ1c5w5q>Z*[iڙ dRSM NfDh{Ӫ8zQ5/: CFѹ!>'~xh? 8"WFA-\1Kv֣H{8DשP/yHSFج:Twu]aaއtf3>d\AٻBErd. :į\mF90lEI4 (#v/P]DmJ]gI&f?VXTAMCqrvTt i- \xDݡ+.PS2 y7CS5pLLq+(K'}CpSA6 h! I;RPotab8Qrk2nm\~yw' +E!LxeT g玗CPb#+}^9v aw[\U$Jg_47eHC]\(@ժnDB惘x˄\$;tRO̎6ehiA;nneUV-1X mv+ӣS)=#EBD1B*Cf^CvyCezɦsd >{gm-xÉDM4ek"hzكh*V ~wBf_=g\}xswnL\ 0CP. +kI/?iSыtDQ:ZO?35F^iO,vZ߭A&z*kV07k+cdOd^"9=5;hNNvv$ruOS%ɴ rEXiDt"%&#QGY;qa5HbX[`yAX㽉Ҟ&?=7[5J8<%|u[ ,ωM9` 2"Nüy \Ta"+\˪cuX@B1BOozGTmioIVf~ 0`AcJ=Iyو`rQ(?v槻ԑ2G-@t OI Fn41-yts5z'WH$a4?N;Ac$*g씢y,?OI-ɉbRIZBC֭J/4]tw{J9YN#.z;!X$5fc{fhXCkoPMʰ-A0_V"t_ ]@к69|44Ր*<`t V-2-RXɱ<Ber7~<%MgcPq.%$jnz{ ;ח-_%rEVkRpv%魞65i?iM9s+Փ^){=f_sGgaA@$ $)J Te!h00d1F=Õ yJX XQS=C-CHD(Ji^]\bu}` W%@E.*Lb6)ZۅT*9Zzz h qv|%&Iۉ$ )F\/ F2] JU` N&"?~Äx5e%cўw .(f@lT }>͸Z1>&&hr rԳOQwc̕ rZtDھjsmxq>( 7"w iG$珜D@~#*uv:ȥiZh{vYiϓFߵs!_&}lDѵ$ B}z7_~lT8fټ8h6[>jidMv*ggdϼShkG.EEDp~phc?ODkv tka+rp3EpuaN#UK_ޕ0Xe ӧ=[@D,"P4EșoWS|AΕ@cp0(v>@mXx_^q ,>gi~Z]ee#Հ[Lγw)]LR11? QY5xɝ`&&d˱5agW~¿ Վ2\o%|#wK)Ǡ& i@&g ~ KN;B˹T`u=&5 1K_t~A#2 mHY{W5ָe_"A('xqGֱT8F]Q9]U`Ν^;R&6FP"afH3sί?_9Z$Rs5AX)9>R8cCaXTdӻ4N>]]RQY ;@};}PקhGMN+(!%śTJ(/P#< wtV E"!V,١wR<{M0wh"tu4[ Y&YKB׉ )%F /(ՠZDAڃcЏ3ϛ#j9+vwLs1C[cA[ܙyW$BS8+9mB Fr`kd? (p,=i2Jv7E y,cq Fר)ex|Mᚚ:1 &ckѠ{o/4C "%sD,)#˲rC+d(bN|b/˳A䉄)zzX͍p9(\Y &ˣ'G|G> h1H%Bxeaey!#:nuE:Tdhqj r>f:jcS`xL;9Vy Za@(x(/^|ڌXІz^LpX#>{i vxܾrO}yߘ^OcGG40xOtsK}ܗ{+==+FZ,(`@UGƜeΘt?4SQ'ψ,OxjOrX=U sYT:By(o'ǞywCb/f^ҕ$K^42)Q`){բu>mY3{ 7Qx Ot1Q]mo u/eшyi B8 zBR~(BKXINܿ#Edel{ſC>jh^xjXMݙ4Rq<&7 3x0M;#00ň%ؙm0҅SLXHrmVp _3Ї-o?yczCL#q&ޤI9ڷ S[s:h zP=}4޴Z-]]A*Υ^"ښ/Цu`Dd`K7 V3GYUr1o_T@+&u }5h%7}dg(r567]B]t]ݎ^ 2іJM`i Fjz +\dgh~׼y'f5Q#"~mha1"`]aim]pMjAji-mG\tDjMO0B6%gDlSZ̸WfBVwJO|,)o7hl-ӵ0x`'G][D5,W_\QBTη>F73VW[;DNӳdJȎ .(:zZ!@f}LVh{ &MZZ萵S.ה": FÆνS9D e cUP,;ˀlDS=dOC!({.w|E2:==X76bO8KAi)wtS[N:r$ ~³:um-8Ғ!KTk0Y5M}T?ZCp Y)³!!hho9YugsZ%vh)+uaOtj߯[=5zGXckow JgxJzn8ݻ*ܵ9MKsQ*1:DQI!bbѺGdV_ }*>dh[L|ϰ)#0 fVG yU;A?W-wS?_usLEDY(]^A},\+Α7m`X_1Pgvh0Gkի3y2!?s.?xд]Ob>1Upn(%Ip/MRvZŠlג{'41a*]3XUhJZHXd2<=v4A+<HKi1)%.t3gƻn )άսy?g-¼Obb2X BTfqtPҺF主!.H}ĕw 5KM'Z#X%Lںl?^A%t;Lq.٫j3;5y ,,Vi^b~DtI< VCfddd{)?* -)R},J<}1eI;FGK̳o 5` BI~Oo7q gXE$WƧ Q2Sꃃ\|!~B"!jfEZZLp^b3(-o,jie]AS9T2^X+hx@pfAG#&=:2lU/yZswj:W9TW^~$Bpz>0KĜ4Z7uAs0]^8hN7Zx<ۍr>MLĻt\ZKkWtM"2I g -+YZI%zڍřgց D9۫56ʧߙ/t1jk?wHW!U02 QdXqfE ,PÆ=wgL} G>{ZF4BcH`{uռzݗ5c<T3"`² - .mkP uG4nnRp]yr$5p |Iϧ//AAEJa dHJ1:bS")hߵX];)_/34z߯ÿvgޯT^y E4JNj,ѻa˿2>5[?,6@Z^<j!'7{CjV2Ba!! g,'d/qg$X8у-9^y׬W߭sNy,OUzYL}48zSonEfLF,e$x XA$.N,aaY(O%by2 lof'0|gnvZHq`8߾ Ӄ8WOHIV T"C .J$?aF|O3`\Q:8+` \sxm4̡x fw|*IUyKsA`! o[po΢t*allֵr&h <}YH4JeV[5US*S)w|H^K"(Đ 249pvUYJ)yV >=-2>V[=\ȩ{v?Z˽joh4e+Ӟd)R2i1bV ID v hM2Hd %3I.-dC`UbrD"OxP >etN 6谓JhK'^-óon‡M'xFEȠJ'Me!M )Ab6tzj]N~)CmlqB]PH(M<grV11 A>GbDLFn]8Rq'rjw^cTy}X9?"A@Qf9U1X[Dt1M)/l`VgFꟜs͵~7-?W0f{homC0--.* E*4~ *JJ,Jm> ( Pұϵ\Y:iNTLǛ~|ل*x߻ s| Ea-xYaY)ZF0XxÀJ 21 6KF:~s<7Mx~8g`Y֛a ?+MSd<тYFT IVE*TAPb.ǧAfAS( -~L[<_8ܠ9ky_pm~ B0M(RS*I(D9ܷI^U?€Y ZBݹq![g WɦE=2 # FG\I0Ԫ¤%Vc*FZc-)4?ՂE+(%ӬzsϽ/9]]Y3LOkxZ$n%ZTGZ'[O37r< W~|}*v@)c*yBQ@,ȟ$|4DZ*-7[Jxq\O/>u  -^>cݪ"^Pʼnɱ*z 2QY¢TA6(0X#*{ +=11f=P˒X\eV3&ؤ:5tΧ˧]aUMd$Ge_%jY+d o,Pc/zlr6\eK|ѹ w"h Ҩ`/$w;[rΤ;+^>v4e7dX*ǸkO׍Le7qf0Brϵ\yGT㚦GUD@u0G/{3g,!0XtPmĐ,O]F+|i) K8 _4ТIJP@3]s߆Vgכօr+H8Нw8uRzgqV3JؒduͮVˑ7up-3~9+DDPc _g[gpK1myPRA=`<[l*OrBBJ#·,3b4Cg$V?TD/y_?ױhp9pL:DtePaĸoءh=INuAe켁[M ί |6@N4RzT2eɎiDSՖxW`],I[&h[&,r-ݵ92YXL:!4bڋc( ,_v" Xܝ?Psː!2 KbtHP pE n GrSv;:=k܏K{}^J% :I}+l0|]yzaʻ >XVW`0/~ PP򁀛fyVEQrTȠ|[5z]Zʕ_h?VjEzsq^>+˸Ƚ`I<ӻay䞶9>Әj񈠒lE$AG~עVؘ?__=^FҾm~xHkm6Q4pm|Xǯ_?&TaiMLcLslyTͶ<b9 <Ǎ네oB}Lh|KwȻ a̢5yThB z!V}6< X1y:f.,uXLXg,K1"TbZjNMvqHe!3aaiM3Qj;,.Tw6EjjlHpEtէ `8 OVJ92t@s%8()IVͶNG *u'.fҾ+hsny#>]2Ϣ?gV Vc`UfjyI olX g'}SG9e1x+cVk2A%y~`^\Y`}saaKfdIeye ǢpCbu{i:/seX$Hjv[ÃxX6G<ᘶ:FF`wS)AE&Vz0OGl^_|![4.u,I}. !iZP7 S P&S r|r,#W;)iIV== °h/%lVz?ayHVݛZTaal$}EX[6m:\ Yz/#:GavuXn;3o\3F( fN9B{ N$O@uuq$ovAmߌ8 Ie)wYT8yź&o_ ϘQ RིʰQ6՟AK1JpKO%j[?zo#=*_uȡe)5L˵H;07YURV #Tq=Z&Gl @n GRq䐭I5N痹 SVYi,I֢@2 43̨* 25 -8촓,ZN'2-A,J(Df*S?>Mg k %KsN擘YDrhHGE/I!M&3x* qLf Δ8=,)pRc4k./$.!mNce{R0[$KnM3 %yC$+kiҐ~C >f'Fd dYr9Y1,G,RɊMtꚯf)V].9hYz%Y]V-_L Ҿ+*efF>S)k/A>>eM&d2L>E`7?IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_7_45_3v3.png000066400000000000000000000501271520775651600220040ustar00rootroot00000000000000PNG  IHDR,)nPLTE  ?K:&[8%/j8 3qaȺɻ 3 3]hT 3 34v 3ƅt~jQz 3 3ĭ 3?Z:H]DVs~Sj.n6 2 3}ze5f;ZND: 3Vh= 3n\VO~ˑi4SAՄča} 3 3Y5"U^XYPG xt_P'[H&E6 3 cB1~y$R@]ŏAp`|qlGyiK7 z3Mô>)! x=Zxjda *8iWm!1aOIɼ 5u)1 Eoc\#v4fXN15*o('!OigXHwFϺaL>;C4A6 :Ǽ@+dFL?I6'B>?%zp[eX_ujLO& k0:[hrd6V?:q(zbF}m,W,Sʷm+]2qq¾+ASP~]%TEbKȺ[h>x9gEuRSTL rD7ǹ/**6TC6 [NJýߩRto^PYG(ƭ.sewaOyKwomPnWh{rU=Vjշ_tq׷+/\D;7;uя]Ǜɍo9ڱAtRNS(Df+"ߘJ¿6`'8j +NKW1kq\ neφcٻ(8Al#taa;"UD䫋Rœd&mRS9f2=Y}]nLQ5CX W/Nl2]MM}Mwr+ 'jg/;U?ҵx[ i+h?GJݸU6FLϹdlJJCS7inu1Lmp?__:7-F-1 ߘ@)M^ȾG}7\ڡF{t 1FOG_h2lC8CZbÌLthџ/Ӕ4unGley\^VWxǹF+`2=Q^W{joR7WkUZP. KLN Kl&b)o‗ Y;!5)4{%f}m~!/VbWu,^b41@ Mbp СNZ;w M"Ip)3H ~`l hUnuxUO&Ivd|K0uRX%,wBV lVz,*|,'Ȅ!->t[3Vr$@c^0F=,rSQ[-ܐZrv aV㺑R6T0ߤ9P =, bhbYgoA3.X^rZ٣XQF#2ȯ֊ *'(& 0b9ZF [}>3'[ k}Vt HE8kk7n UK>c8A"-0*s:+]^Aj*@y&U,~QO_7ݢ B6y w.]%`de>!N_^> WvvŎba[{uT ]忋as ôj Xh ܜLuǏ jf9kvmyin"N+Gfuݒ뢌ҳFIc= Z Q y5 R eZ][y O{yFc_s~ej|nJٶ͋ƂQ3nw`CV~rVHI%gO1g-Bc'>t"+ ae\nܼ#}kM&jo-G?q]ɱ/5@k{oJq<vUr6'0'iaDt Vֿ)wefWN&u]l:H8⾲hOОޥ_˓ܗ7ѸyN>+7#+o]uГ2raM#-X?žE/Ix]{yMMݖ}U:qCuwHye1#,~1CFw}c,U%]t!p.ij[»*{}2Ip9 GH  eX}.N.~ &Ν<b 'm6L: 1fˇzz+X>dҴZQR eF`E%dw J2æ9S8?vkVrrr]oCeIӧnKxJ֬v"xq[!55@KA،xSS [͏A |NKeUQ2nb!4Ъ!a#0Wh_;?ӻU#H+PZzreA‚e0u2VoqY4WGRD8HpkjZF3M~w7JW˜|{b}S ThAaX \SM̺>pIe&JUTdݥ[׿(@V h ;&A+.Xi9JubX='% y$|GiiHTd++hʽG]J6D_ j٤DZrwb"%ʄ&`vW0Ev.WADW EA;FVZ@ۭgt"g@ a 0nkXx0bojWWq&Iȏq8- T`U6[(5UA&Rf0Q"@=c/J:,&ձLN/BV蕓:Gж'͢.:sN<"졢z r+ ,4QA#L"-c Jh}U$n6s8ygٴj+(ڑ>ʺ'8[` V1CR؉hԎW@uf_ g]5*5Vw]C \L}s缻a93Krvr.E[] ]U- 8&Dk+WA9Q4I[;J5`-E<=oɩ9us~aaJ$Y.g(Ypx{H;pɏ#7 VuYeo'c\SkJ ĩ:}j`ȩ9Z\G3q3֋@˱Y`!$B)9D"-#֎r v|C?m3bTW /53"Tu>UOC>3o ԏčQ.a0n¬[\E$ccy >ϼX`.F.X An&mp%4=:9/oS$ʎ'7.I-,c`5Ÿk,|5Lv:9h*ʔQns˜x_C^ MWBWJeILoIV8(%˽4EQKYm UyO<"Oq32n,jawN_]i`biWYgzT)Z0]n`]&)[ q_-N{k2r7;rV `\ &nsizin_'xS)ox1S#E74p ibUYlNJ'W^$p'8R\uu!@EǰGxGddžh\guXO<{J(W:Լ0Q$|PPWԂ?[W@Ps1mQd\}/k&FezkRhAaRa JEn+ZRQˠ[ef@e0Do[}n=m}9gr8cZx4Q/\yRn؉m`FT`PEsp_f(;U{F{̲}})QL#`%ף1Z ฌo[ƌƱBP#T+&/UcC bdm-$C!˫y\Yp!;C+b:1ߙt{$PA^01`<,`Z+=M܍i&6Җ;'Υ72iR/¾\!hpQLaͰ3d؏lElKK>;4'C~ʕHV2Ɍy]496XmLvsyI@9ݱeo:mŒ0FdoXAfZLd~03=yj>!gKUӐG4)W#Nuu=ӴۛՕr!=5va͕ O+#'jOv沢X7 eӔF41yѨ\ )A7H&ې\!u±F⋑TB BeXUAVRNìk3Ϯof; AɣRif2`˃\EPvu}٩Xȼ"zڋ3KKΪ:PEB n0lWAVu4uwt$V<&eZHAW빁cw55qOb XD(Af,J) W3ęFM%fЙ %#jE%(|TKiGiuPSSSfUR X9J0}<#†qx('1%ܫh,ٍ1cQ̀V{JıjQkᅢ0qӎ#(UjM}}f~~=C.TbYt)q}^_Z>`:? Znunٚ´B +.0FmFD[Qav2Wy۫뛞yXq{E"V(y4h MVۦ\T}[eG$*Ī0+#(yMRpIkN76WAV5S ,2.0& $T&WYw8 ̍KH~lxhww q7"W -N؉c+2GjuCwHv;I=yAstƧ<+9^t(AYPVCDxzw(Ep\AȉӪvKE7<#WA nv5wn655sO,/aAR I"} xf!Z3s>>shuX_-\‰cE1Pg+;gN򷕸4M;Q0dUT%t!H>w s&9C#(rd?͞9W:=V?]ec5\JɑRKq8|2V Vr[,ٵóh i .&j+hY3ePH)"o'{t4wvv~O.&(K?ml9F× cTU`UP&CTL WDXn]gPq Ny:3gַ:x8Y"ɕᜫհ~Z"(3hޞ]u8`ӊ*“(V c`%8%x-Zgb mjNgU22oz"Ab5o:x85 {T&IgDG:kP>ǠCV1RTBGV` ZyQQW{ bmm;z.찳"oymjX E%IDY̸H'\LvLMvjI;X@R+g 8Z'@ˢ Öp"ytUߔ@Ҫyy bGܕBsJ]TP7d33)ѢUqvV"g ]YZAR ;*%KP|b,qu^KWloTΌ(\;]*4"Xo:DܼvljauN‚A,tZ,4qO|bLŒkOJ9CJ!\*G+;OFco瞛[F[1hDt2kوUXAmsZ 584y8Ը<@%.gf'I$Ć\9trT SBp)+[理XaV"Q_7#OiNYo$|z/38^Eϡ\< +)| %,H \L$pAFc-E3c#pJ%V6wrx6 g3!X`HdP5 -h<~Էu*q[ $%˫\U\g1iO*ԇLZ*~Zk87RC XY[Zc [Pt-[#VBY:E(I X]X%0VWWJVl醯>p) E7#^ƃF\+r ݧ%@vM13TyѹpX!5R!W<*:!VBT^<+ O'.ܞ'rZ$ytf{@ P5a8V+)%cE_j4,W, W+"BnQ|h\-D B%2<+bYavPP-$0IpV]]#BEWdX9"N =gre%HqҪe~>>t(ĉђ`w/b }X|X+ٶAZ {ZTg\ Z͚\%@"Dd%Y&B+H,'⃉S00)"pF@rure1⪙pj< ӣ@ ,VYY WVO`JD@ _UXNR4hɋL}rEsLr'lBlr W{*̊`][ vz6nc kipH£ âpB4z̷8Xa̖Z,N4\ 2Va ;U 3J|;n8ҩc.G#ʮ"'b,^ ړGX3?Z<dM-n Ϥ9r[4ΡĂklKck7(xd_Z<h'+AҚ_ϹƱ)5R+AqHڳrb_ Fwd~KCÇa|yԵd<TvfmI.LwVQ-=W3S3RqRl+J=rO`!ZwvW\2vixZh_) 'LTtx _PR`"$W슗+4<X ,^jixGZ7Qʻ01;44ʭp)Y,"T+e-!fBIv~'3D hUkP-=+{dA ?hy-`UJqi!vNtպRsfNȱdg+"ă4-LLl(P+VE=)D**Jn*DZC{ٟ].}Xwa2Er v8Rٱg?jVMQN:*6O En蒠TJEV>pJ=shɾ'*0+^q̠*G;±7ʏz mcK+W;/ m/8s (Epun2`.vumtȸ^bN0T+eص\Ud?;ט8wxыeլ|ѫ. ѡqʘ]!! E.-T3E2mmQ]fi=XZ= <.IA'Mhʽr|"-ecK1٭_I1J8|G=OkРP*j?{[UXbec:m¶ XrZ L $kERg~d:e+uu'VGc +>Q(9ZJXO@XEumB0SA BxۣGf ѭ{>x,R]UYԡAeIgwC?/tj]I>rBv|`23hĭrd/P|/g-ZOү&+RI ixpU5^ѳfsoݢZ{?UY=r]ͣb vu1RO xuhw~CNO--Č8g#֯?Z׏px^?eP -p QuӣG d2HvuAVh!+ GUV Pl՛XZnkx&J=:}cw7nJ^4JUW Ͽ/ξE1,ĭUVu3C)*UͮOk(؋}إ?{hT^Y[ʎoW_:|eyynėț/֨;#љG /(ڇBJ+(V VT߫3νzx׎%.?qG>oul/!9K䶜qL+PTrL R) wu/%!-ª&-OU |.nP;`kjju?4BR!z$3>wp%TNuSf_/h?Uu@?*.BKEؽ*Ͽ[d VͧϺ;bܑNVW34狱h y -{&7u!R@}:pK=jo3UU`EW=sOksO*Y7zEXz|~JJq&A\ٗWӞ&s՟~]j `ƪnW#'QklV't.JM@g6;kRSS=|"bNbnoew깟&~Ch(o'UB`Y> Vm+CuYb2HW%`ՏVue?~=rϽՏ7;G֦!ё#vpcS98IxE5-.S(:L_V]]O*vUG]J(:sDЂK>VvZ48 =i|$rڽU7Z%1d^B@“"aZZ!ì]6AV͍t+i[F z=f(1{"ZbaH s A*$5#]x6AE`U SXY ]Q%ԪVHCv8j8W3)=xyzzSӦLf2HCS0)tʓOcu񒎋p)'y2*,=o^RKQT?"TAUpWӝ?s^'F%*&Kieb+m.tr%3 mR5d'KDިB>UǮCbX|i3'ob _5t]tk=0hKHRЊVtfAOާeP-s<>V g*{SZ]AUdVeWNt)9e9'&\e7؃H汴(6`eVoj1e #=ȭ Z$H(\ "MdXI{Ffk'l |2rb2.&Pv̦D)-h9R*t:B.4+`p7z V}#?@VjtpAU8îj_hvUeYmxs%y~hA<&)H'wQR)p=ïH,޴ ϻ>ϾK&5–ƫqj@"q)*m'eYp\.ցRu<᏷lv`^ X+F,S:\`ˆb SdNjxG~ g~; j N6]rI֞cdL2 e`V(*i3>n56VG*@$`,#Dls(ndhፍ1iXW#f=j nW^o 4kݓ¤,FӦMstEW4BTv"= _^5m5xhha[e=j&5ծ!)]F9S2d)PdQRQM>yK3úz>1NHȟ-lK3C-q\dX[ܓJS5F:,TzY5]a+^BSe]N)^-6a- C12vT[#Ssy~H{ bK cŭ9)?n^-nPfp}%2+vՐ~HA/mciD& F@ccy20C 4;;1GRsӝn=8=3\u j;v8|3`)ud#?Š|[Jk1Qz=PTr0a Ffi",8,xP]Z>4Jb %#l6-?TxTCf7.9y=?zY*TX%Xq+e7X5d%zq?Y-F89,V'rS6ƼMBg(>T8.&nN P>l{޴d_YYX\~{Xhy<:ܖ~?*h}L^xRP&!ܫHnR,u,qM ]Q+ G RQ[xF1ۇ@4}KGŵy3?|Ȭ:|z/d6$ʪa튤`kQxXdtc7xӴ3uQó8܌VtbYMGnݚ9>:McX> ~ǧqcwuTdՐgR1T2 * EsWn,#6X1LoŹ8  -vCX(eb/oe_MRj=K}&h+a:1FX!fiڥ? kWW++fA2&#eX1jqs!mØ8-1,7qBx܄i2;cKKsr[+j-}6f-g~`ܨvG :^>١]aH.GԈvWHA n]+2b;"8 t w.7J;^Vuvdijdz\m13-W^iuaV(CP-i7hg]X[Y7u7Ǝ%ݘݘ;M)1]ɷaio6])W:NbmdKΎF`3-a H7fp&isbuEWv};6{e4^I{ǖ(LUύiW^^^ˢ'#NnnQKF 6c(Gi9byх9nJ$Xv~vlI)pnlÔJđZ^̷]r9 ¥x8q>bW^7Sm+͢Gb1a̻q.mTrqE-%-^h Z3낎֭GΥ"Ah}e#a~TZ@h\Z(XX]YK,M85b"'g.h\6NZ8:T%@ݵ,EDD- ZDOHʈkvq۝ -qfZHHd#(n6B`sANѓ:|ι1H]p@6Үٳ%ѐO[U.N/>⽴ _b;fn]cQaB%'R-*xGU@E> &̡䮒A7/z nZx`~(J;L; q[fBZ!dt ͂kY6LS V\Ol7i|̕o^G;Ҽ~)vM`uy%w1\J,*jĽ0U!vqE1߹ FJO,PCOj7Kv!rx>F7W+qE]YBs0GoAKu8یJiG+ݰbZԀq7DV%}iz:'4$IV*u%?FiӐ+m&Q"f^Hoo@,f8R+5LXah64BBH'ؑh7k!'yΛ'N'̛WFP~1t]xNnn;'E)E6ҶMjGE,1 !tlJr܁ ;D473IXyOJR}QF)':+2f@aڥB3=Ot$L)ZA\I]T|`**BCB%xڇbdkFrϮ6C2R+uj/(TN̄ *X^|ًQ>KiE +?&/yx4V0 ۯ#L *_eq!FX)QS/3=S5d hJV?' {} ~ٮ*|IE,Sprբ='Bced=Wc0 nXTՐ἖Ҵ/i)кk;6zZ./RH>ʁB$U5 Ast6<~n,\1 ~[D'1k/(0r)HB"0ts9bID%e̊pS!P %z`7aH>7_O1y-,‰LWRLJN&f#B 21~:chAn=(^2`aӚjz"fԉ z*(eTpb 85H)2m$?@m`>י?֬u.(A CEOv V| !ι:u2{,E X@8X r[( 91ܪMVPwSY<kI(Ll%6S< ʬ̟,tk #,8 \CñCp\A g(2A~[-D@IW׫cvݘXMYQcuӱ(:= |vxV*sp0mQUʢvMY/4DTT%vˠE%|B|:+u.s lhdZD]N+)-.y*'ghfuˠU38>DLؖ(U0m+J0ǧmH_¹=+XUy< ClK41hUMV|Ux6eFʍxՇbGAdH1)&|"WAc["&`B!ぱlkb`[!'LIZ/>ɟ7YmTҚHS1pBgc/ÿOa7  z'$bN/.g{Fr %ۊVN0%ƋzR4ܙ?B+! 7RO,:#Vױs_!)Bj]cgN(aDK1teN[;z) ަ`[DI1Pr\Z^J.ȨB 9\m;\ZIƹOU-[a/Q\׆]Rպ"lHB  ry`ZKeڍӗ?+oH !E).ϤԸ'].Uqю>qz|y#ENڏá:.WL,R,(둚Io*I J6>0w7,,MFЀLFaU4Pj@vhm,$h^r|[bKSJIRox/GDWL PդX)m3 рX!w- M}+e{2´+>Wl^K3b4;EjŨ2hSsM8i?r׸> 1PK-$'w&'dz R2_Y1?Y˽Sb݈(63{]OS5}ͤa_ P!0FAI]j%]TkPFr%z6[/)ey[,Ѻ×=aY, (M)Uh&K4=62敆$H!46`5f%sk@jlg'-XB$}W9IɉNlz(eGSufsQ[ ffM'zzx5zWr}5L&d2~U3#+IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_7_NAND_1v8.png000066400000000000000000000450531520775651600223010ustar00rootroot00000000000000PNG  IHDR,)nPLTE 321) 3 3V8$Y 3Nv 3 3rlS 34{zjdk.ĭ~oiZY 3 3 3h 3O;1so^rxe 3rqu 3ۀ{h}_aNJ=YIBb½gZS}6u>?vIY^ bT g2R[, CO%yuupo<{pj $& 6J~xKXXGQP:or 37 ~9l wke`l(+.^ ')N([hf t*|1fh Q`rf^k045cpm)\]+ OR`_tʰCy{>A`waM?$f@n{z AzI3IILk`WNJ>Mƿ2@hWLAGFZ3C>2s¡#SUVA3ЪrK9<>1P:A=Jvs?g,uI*#Y+W+A+ĴWYtdSfQk^_]B\A61${kɾI2"+cY\VLEo|9|Z̮_M&]"~;jMʸ?qkZ5Z+sV=xaMn|Q~^ֽErdH&q^e\rqlBUvDώxpGk=)7rدʋHqItRNSC'"E_i'+?@K`V\q䫤y4jْ܅ݞרŵ FIDATx1n Ew3HL$74pΚ8ٵEM KqɕE)-,vK0OwǛ%ȝiiODk$K1߲>Gj_:j1-_*]^.ɝUhR讪 ]jl)m+dCK-m3O\M-kچ~:v.:FtpRY#xpD65@S4IJ)! L\!]2,L+ @Rŗ}l[APĬ;# iȮd5%\/.%W =婶%>&b3|fR4q4*޸z [}AGZX0sNfbN+PhWWy*i━pa I3?|%fI\5+ -##hjFR%_#Q؅c!?7%0w"xك] CPuif<4i+L6dQL˂4@H6>JQ}fg"|xyk?5/c=RIE<")^-٨W`e~׍N8] nΧ8E92n|ְ*b(tɓߐ"'`E3xz3ӰFjNHTU$/^P5hyZ-+b)X ,}㦩JcpܩV6)*[A%Y VT<]C1IM<@ffӞޝYiui eYNee-:eDw0ރH%'Wd{fϳJal/)ЪiOM"TԐqx^yXP$a,P?Qݼy'rSNAC]*MeVZiȨ4f)*H m-Y9ۦ8)*km`ISY^Q;EZ6{+Tƻh@p PSL!]I"t :n/AEZSp$/,Y KI_$ՍWaͫ]&J[߼ἓ2k;,f!-J\GAΔAR>+: cccAzٕz~WӒssh:HPv9w(-`$Pdh3j+8ujP6&:|[1*ܥn%G.0cۼINUΥ}ZP".GgFkZCd_ J0h}=%Ix|s[؝6Gs܁k=1ˆB-bZ֒Q[I^5??>ntn9 З2Gjvv$q*aj$beh<,i< -D$H%znDW޺u0^o4|F%ʬbz4+glZ5JdOU ȼOu[I7>գxv4\ j]!ڊJY:=VLrjBj{=VcLԞR= 21U n F.J+c ̖&'J_dH$ Fe|q㯪`EVF2Ȏ;UshnRreiM*dT)e-l]<aXU,~ WaY$h{^Kؑ9JH9 DVk| "@̼}bYH KA)Yc i;zc%b5dR2s+۟\ڪ8ސ͖xw&j oQpZQ, z tζ[v^pR[1т E r2D|wʦ#qY|~'dWJQi^yPhAzjj*ba+$/dRy2#f/,Zp8Ҋ늦|jf6[(̽Gmi/ 𠀅G{4ΟLU XXW*3laf3MODu/M4yuY3NR@ pJ'O <\;4=%69M~XqR\-AөT8zW"حTt(:_ kGl]L3Öcy%B@6(gO0'hVVӣJVV)ƫ 4XiCVG&wZqEÐLZ[ª ;+D3ɂ@1`FόJ ^x4W9lG 䊃J ljK)Pusy^UW_[T̚kjZ/rx4b z\pUB, c 7?]Em!/v yJ H+ R*ݥ /۫څ] Z",%GÕҫt>dmlzD٭Y62品Ur% -*{.7{4Z)*foE p"|N[wH<ނB! %:-vz7ہ ܊ǫ,FV}~Vy$w|?!{Rx3& 4H5IXϺ6v Q\:8j|WzLlW"2לDXÇ*̋t63&oh!_QC[oAvq9TBq*uH >38SeZ L=pNe)qn+dtyb&Ri!ңdw`%mPq@}n^xbQqt,E"a%PDwLT!xǐ+26P%ig7{r0\?|G\A,k H%Zj"fnM_eXGǠۺD(E(/kW?EĦO ¢v HR ,5TEnVU4Y×jDKjz+ XQZWi`?%&VU)KtW8E=3mL΂˖ev!1IT`;OXDzB9i:}iXo}$)Agrd{SEhY NJJZcKjE3, r5tgvT8ѴCz۶`3IAiy`㊌4,ö{;8,fHsL09-2=?"\Z*x^o\ͱ`DK@JF JVh[AZtV"mN/..BBtoA+7*V(z'Xv չ쐫^[fpm o1tz:!]O1=PvA hw̮Kdrv'"zi/mZ.65:vAEv_MtpkTuWjhc'.p|x5[n^rբqs$%X!bY;{MzcrDUBJh=vlθXs|h/ :݋FfR]GfҀwb \ >CqVsHE[&~ X<82VWߋ\#c+\~a{1 &|) WQCqJ] dvе|@ vK2O:2<|M՛Mɩ y?T)Fl&Vܜ(W='՗tXa͠r `un 7C#+p^IP^c-˴C"4rImpώL=r7cK=cΩU]|Y7Z/\]n+iy>l'/br.X5qKFO3,iiњV) K7J =.׋xxh&J[te, Zs . >q߈w$]CJfur&E)6Hgj"8dTk#S ބ2oMrb*whd'LɡOO(XJ#j;P[9GS[Eb-_}augVq/LL 77&/w*M6*ÊeCAR@ic9ƶ$ !RZ(-i-VQ#"&&~Sg4p~t,~'#sR8 { HWkkэg'VI]`{O??Yv;d\>, ]$V=睽XwS^A )AB(:FB"tu_c4|!.vJ_?u$u]*Kam4'ָ щՃ)!/­ũeD /쁕Ne) yoTT > Xϯ* $P1#R6 q{~NbȑW34TO֐Lt$G0#wZ{zo.讈7p̞qF xiQnVND­42-iL׋]n\Vj{zd'f"+a.£HN½g輹Aר]̑FLcA"a|au+ A[Xb@KζxKjКh8S!BoϣKMNʝwV@t\߯ mt.DC 0;N&kkZ!'?x@)*MQ9vTeZOH"H疗MZ(L0gVڄP~fX4%˻>d!YMMuv|3?7`dsUmo?TɹP 2[D1^r2S@%Ihpe"yaOE1&r u^?,{,TnaMMcų_|\Dފgޤw>v'u݌=k{^eŋ;811Zg YnZC|&#tfna7#cum}zmY E:}e$'g 墫ϯHPsy;?gXیWX6uOgQk:#o]`dT#h ӽ- : G'ceեϲ+h5v"",ķFHH֓s\.ڕ^ZYA];oeP){ۃ̹t:,Y5ȾEBoq~ 'l5Vy7񡁟7}G)+5SYeL!z QGߒ+jb4fV}#_)K`$B|Ke(]|:x!$XFFG˂bV I9W쎻<1tWg/֡_$Q%ނsճϬ`;t9` 9ѳg+-KWE7ۣߢ2wVEE|`pNr~ppb#`!I*q$W Xvm6G<6+[ky^V.>BdTY)8R0@Vị.c9vcry|O}ш>U?3WA#YDY}N3>s߆U# :e0'[Mek%ӿ*Ս<0N҃| `|_-_)t[~PCk Pu}v0wϲ>M(MĻ#ڒjK cLѝ{AVA*%tx>ƲL%(vP! uN 34{T4Ѿ>ʻB~ ̂s)(dAdpAE<t^KK_*VBۇҥS_إx'3̰3 ]dGf;de*EL!fBcHBĬƘ .>$D/v`?t_xT|8{Ι#hbլ 5a4b]dZCQkw-`=֞8 [W>v8ٷ \,A.ji7̍cz.D v1aO}pבOUo_7\B:wXB+8v%0WFP*v{h7Ct\Cz%n=^-;nPڃ)/,R#\m?n&pp; 9V9\e 6B{v WU`(Ǜn:v Ɖ` h nQlZ}cC+~iF~few^L|ȩ s# \q,m Xq ] LJ5lS۷&FI(~WzQTj;tq Ch3@22U2} ,1vKHfnλ#{u0ձk:uA^)ݪ\x*ss,<]=2*2VaDQ$P@hd2 ϙe|L'VNNtYIj1zpळz]Oc0R~  B :),GB00HQ$JU5fssg<g\߭e8|'˱pAdI.驽DI_{-92)8L!4Rk S P1&6f؍7oB{>Y.-/<æX]Xc\ɼ?ؿ؟/rmpzcGS 1Mp 1P"$a4 &2utV1n?n;[ӳzEPĪ:c1q a o^nW|>F9b* B,xV5 !TEiuM9tg3Oj*bl^n$vZwmK@Wag:+S$D)4|4y9 JĈ(Ք f"?Eg{eupcl+=vK޹jwRjIyyzϦlМ,KXa L+C$b5$BDZQ4-*g:)y=_ʍB!U?Tugoivek^O.XRV& CIw-;M![/(b #8aBEˆ_Zb)d/w*SqE)/^a0#@S[w }]kD{Kܕg.=Tz4Y wJLCop5DBYV֐w[[G: ;XxRHєrau>kOZ¯n\+ݹԩJYVyTj28p̄&B1yqyQ]M i&ӡM2Bˬ;#[R5Le-P۶w5j$E qeT!ksy9 !h~x>Vy!;!4eIK>C3t1Biq_~xۮҸbW^-|ʥmZ "omP9玐>r3fpm{T .R LG tjkʓ㽵R)?m_vz[ buc!7cVP8G#)y(Ldڶ-he `g||+9ޮ[bOC~6'b׻*C[yd. 98$JpdȶÇhLQoxȽ`D3j-:8VCRK~綮R.ŽՋKC[2z᪋sټyh, wN"Pj JG)\k&Gk{OȵjSm+ o eXUH6rst:()LJE#4e[D:}? +| Y^*ҖV]@&AP9.I-mV|gaaGk@p7kN_0ό;d:ٽҖq0o[ I!\3&4ّ=j+i\@ږ`8߬?H]bރS'^{ZTwko 55jeyr[I(lD,b|fgf2ZJB{z"? V1ν˗yҥ|_1yOP[ R2t:Җ(nٶQD_A(\V$s_Go~w`A3:!""n6ƪ~4Tl zU;ݿ tVkX&{s5!{79:U. Ɏ_͑[=߱š8tX-Xk/Z婺hȖ pXyd`Q1ݸ Vn5ȼouǙ&,C>w1nB,p>?8Kgdw5xd8)8طQN S99S\C`A 7HmvzVZ<޻*}$'&Iqa1Wuԉ7||^pG pr^-ՖsqJϸ^8}/|}rsyqk5"QQ#VkJ4o"F NYѧNow{ƬT@cQґ  kK`́y(ڗѾx< 󴈣V@)*bQcV VGm0ۡ08SFb$(7i-*X5÷2̜+w<0ӆ9RONQՅCR(z .J[$B LܿM))\'υᑁÒýq^v%lQ$)2jRHl t~.-%+k#=b5GOaG0\x7/Ow>,G!f 'M*ʣf, Ct?ʏ wap֦].q] i.N&~)q'E Y&5|G)3ŃN}$VSK=, TZlaO^h,p)ɽd[A^tn˯&*Q3u@J@4uzn<[\ zNÛz=F)1;tHjW[O2 $8d*K7h|~n|:#0T[PhHc ߾jիٸ͟|lvt{ f{YҞe{g]SqgRzSp{r]Y:YO$D~> UaxUptY1AKTY)X,{'uSY+$WY:R!Vi\d/=:z=h"a#YJ؝%}eY^eIH~dx&$[ɒ3BDBhXgV:mR}h0jbbu}l!r#?c3{)3euG-ZZH-r p @ ,PLY62oQ&HD$qY5 dy:iFnY HVk+Qm!t]wY h  Ȓd$&f7%)ʔ,bou4f5Q_/J|aqK"efpvu;2eMY/F}ʚL&d2~i@O~IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_7_NAND_3v3.png000066400000000000000000000451331520775651600222750ustar00rootroot00000000000000PNG  IHDR,)nPLTEU\S7% 3 3Z4V{T 3k 3 3g}Q 33[,{ziuwra 3v_s 3 3ì¤z}kP=4]яrmo]pvYQHwddrrkVcWN6u?IH6g[xphVf 3Z^ Tdˏ~Rxs}x >K"znh h2 n"Fsg`  $&`-V*3HRQsnI 26),-KYX_ x2o9H#m_Urɼ055T]]aol7lp)\]P']dVKx ') >@Xfe^j P_q@tw A g?0eg?úHLBGGitB\3QwgTC7/G}"RUo#}N€=Jù9?4%VaND>3CYKx-&X6~Yj2&J0$;#IJ,tF6XBiuۀo^pjxx6atyotX@s~Gn^mRUMC3H(%8iL6I4˹wyȩAscbbPd&^ERī϶)̛"|o @LM@hCk fp -t/} CjpO%c.3[C%驘`-z70 J5\WكmJb`SJǝX=8A)VtEÊU '&2f:Ţ˿Yk|Z&EE 6,*X#EDhQ) JaboC-nQZS b ZT}h<ZUI+R54ƢƐp9Ċ++gZƋZ`ZeVH*K{3h^XZJT#Vɲl`ZIӀ +nR(^(Aalrd!U1Th X}ZWlHZəQ&9j$@L+'t7p9zZpu[5|oma/TpRi bz0q9jj5DY㜭ۢ&ێhUJĤ橚DkRK:DYZuc:o/$ "&rNl~<{ ?.r@:Z\>pyYW6X:֒[ BhT7&SmM-/?jjs2YS}:O0v_~se͗n*lZZzok+bc==hۦ-sN:OK2=˪cLU=^ZS:kz+SinEo~ OD6-5vт91UXzVx Fn%Lo5Yd$ΪnmY2L.6"H(KUӪ?痭\f3Mo۞6kw( ,"`ƚE֭[p٬5d2-֎#i=c3EԖ*}t]5apmp~aaK*eLe))bvYҺ_~qu\owף`"k)U8l@Zs T6ux@dYyfE%̖g,fj\BWen F[ POx靘/}4B\r6bbRxH@Ȋ@xw64᥯Ita%pd`uDռe{6"UH]֎Q/P)AS1xϛ_ɜ8>.3WLea ź$EJd ZRf2noOswDZi"+.l̾o%?%YA# ["~Ddel읖]AZZ+\1zAlh Xag ;cUE AN+2T"- Ȥϣ{w}+X`%0oe6sJbYubZ-)[p0QA~q0G"f@Jڪ _)9qY2zZn?)EUAz,n/JDpJ{(o2>3ׅRJ}ԁnkW"SJQ ˠ;IdU-LFb%3*p>ԍY1JQa. T[H[@EfVLU2榦Y:J4_*ZWOE**d$/D/&k)ŗ+8pUf=IbXa*Ϭ|i.zE^.AFUb]k!dNWP <*Ru˖֛v\H]D+Z[wL& hD)[DlȪyȸZrqB +A 8BbuGX 爵"钘V%- Y#*(CkEY &^oPZ>"T#|ăykwZ~:+S臭("-@yJ|>_9uKp8&z|G/U@!(hTNʴmOx0օт;ccwnSgWA[/lJ!jOʴD#Z:@P>Rv؂Jy39> Qꛓ'B:!'O)IQ\ ,I5B|{Me؂FfB={iB:@Y-+]4P!a٨P\K3j-DFyJY OxdǃP~Otۻκ庡Xl%A˦hQ=ҙ@S0w'J)ԖD.0z+YO H `E{&'n/w܂ -/x>S*Rv٠?-ezve ã@u}5Xm u~N{lnnt|-l*KT&Jbp(hyy1[EX|&I%= > X9)/twwy{y}~nrލ_á046 Rc8EtE[ʴp=z}}Amm`*`N5y#u {ϱ0Fё)&W`#i9c[^/ Duvǃ@,۾7Ck;`tshnjG]M VาZ -@KCY)S[jTE8d__ !Vッ_o:Ү[6lނF8G>ZSsv{,B+?-q(EZ†DZKk@%H` _9ן0/.K c|FcK/p/;u ^8^(n[uc-eeVL*kKz0 >pΡYb?l˜|<<ϯ1?oS`UU!W OX7Zi`}rolo[x>=:yV3z> ۔0J1rQ`-(sUrWBL*rv6 Z/˯\rB̧;:XA09kjlr\W_';x7`8~H{Ȃ6Ao1 D!+Xt֐SΒQ ι>nJ/7Q@Ν|uPיX'wZgZ=$?|ø> sMu~ws 汵`! 8y"e޴S!g{RM@;8s`MQ^Z(v4Wh ;;Tqja,O a%Y1<VU+z/wkU<8Q_P"vcHZ-DPqw#X ܳNU"WX1o1rˏ$ e]#bg ՙv7߱`(V^a"'pӆR7)tɁ[{JLƱ@_7ng*g־Brrp(,t*mUR1n&cw< f-'w|F.0Pi7?D=8Ic+ b2H 1UR`UE!WpY\.XJrEE4`~ti,D.EJ&&_^Yyss<3v!%VZXm ϊf²T(OO rT8NQ:}LFl }^ rs(5 *bA ӹGz{wӴA-C`h%FYtka~p%fqܲ Z_&v@psBԋH8.<қ$J%eχsCǡo!W`CJL`%(2jb2-eS2TmV+§]YdTҙva\vWćnje(=)O/,ڡܛ}槒 :ِMV%J,i{PeYARo)r{ݺjJ(ҊJ;`aGL;wYNe1aD.._]ݩV7J:TRTPLX0XdڛcFљޞbKUd#5*z re`GJ*;w.c'<^DʲڡS;oSex),7 1$jF2XhW&12Z`xυR*ģkQ'aԧ-ʼ:axL8~ >cY3W ?ua$ނeU'xVoꊀWOjVq[t?ƟHh6WUB^h!z$Xn4{XֆO &˫6ܹz2,Ã1| 0U .h 3H(< Vճ$X6`9HZE99ѵّ}4Y)~vb=f,3^4=2Dx+&VJhnU}84i U/#LY/b&eokv|Z1sxjKJWS (wpfcp0zϓ3*~ic+O*Aڷ/5YU)a - h9–9a,IoxDzZwm5'iY %J^467Dr:#ȡ+%L1 pb`uMNz7Khd%6‰Ewaqn$q:|amm!N!յ"0F4(wCķ_# xʥ{ꖇvBMZgIĴpahPVKQ"Jh2,Ɂ\n+P}z3v ɸ8#ä<]R|;/{&² L ǐYFDZ/1]0 KS|Jj _<9yOJ6lOnEVX,]91 ;Rj8l3X"ߔ+ꌘ{XwxEXZnrmw 0iyڛ=dra/},89AZ^RDD "gؗI /dJ4K"a p 5(NTO VY(Vjyގ34(뱨[Q9کe;-Awd#gtD\tV f!-}1/p,Xm%Dx%h4Ӏz,vIB dE/^6xOaؠE^VK2f!L̠+F?S:ij|ڒBԩ?!5v %{cyEWbi{cg)aW0`8mFZЮpBa{FA5obh|>>oo1<ˍW1o~,I)+V4-r. CU<;X囜 ?Xb+\Llnlxᲈ`{v1'YUA3GS5܁->h<:I.h]ٵ&*J&懷@!W~FYm i6{R-i6@]ؽEJB(2la$~|̄BjҚ]V 1ىAkk\QV XmA9OHʪBn9; X>P" z`}.|lι }{$1={?XoےvTδ7{̰rH;vW+ ?.]h&P&eLny,İ+xRjw.9V○j5-AzYW )W_-o^W  W ׻ȓ4^[Ukb՜);:#tzEEҖŋS9Pyi.;`D f&|_WuQ찐V:j3qil,g%xLcyp~dm՝X o~)=xqbiqC{i+S i?E(ì3>vVV >،ra)gi2=LT8IEFY{7I ?Uz"PjDfru/:}vmd>qج]$rV {p/(J?,!w+[+Y=+T^KiKemytBWx_Y籦\I8+Jx\rjmre#7 {dFL9Q 1rXMݹŴUqDL" x@HP1>`Oiae#Ph4EM l,력JhR:J3T{mREhrYanc))3ϯt${w6UFe<2rZ[l~*F\[;1­Mտ,ݲZY2m@.|S#]VUG[Q;ϛ3ƒ!oǕx q~wx.WFQ'ND9˱ŀ &65ew7ˏ"`L,~:*+ vc `%pj$rvdXMo})jWmXq a]GG5/鼕Hl~?sʅ Z&3:`i?L*9&θ*>҆JF[U%24X*AĦ Fzw LjUUS=WPGX6Ox9{޺j+:m-I$D[>>zwUJc2_DPa0u]$I"ATcaEDs[-~PfS -:T8xvtǩSji4ZfuLbnL||SU~hȮXL\i@ktՂGK6LjII)v֦9R9Q2 jz%z*]Lc"PU-]gԌgC!u(z6wŅS?|$Haƞ5W &HѨ 4Z}TO=\[/[F>gt)U약̪ >&h;&xxDO'.y*8hdk{EWm% q4*UJJ؎}g_ K J}=/ϟξA2EMՅ=FX$iAd7J7yM-ARu +4*pPs|,'0 A0 TzNh|kGr%qރ B~؍VKWlA$HYGAOVd8@ù *&(Nlz:ESB&C$ uƶxXu ׶m tu%YMuY2)22*UV tA@ROTpXEyQ̣TFOl"d*糴!ͤmo JjnֶC  ++B߃X~iѥ a*Q3ncih*_NXCꫭ.$8?~7IX%mѨR)ۚS9T9sCbѮk4X?kqsFMf0,9IV%& X/n&Iy>CQTo9.t=9&I:QZ~,S~U0)UnЪ-d"LVV0Pj$XZy1flPVpaT?ɔrw>G Xg^3T*IhFlqZ>õ`a6 C$E4i;uptfecCM$-UPV:#9ZcqL.ZBiGaN]ȫZO W^[vIc"xx}BPaS֬9pzt {-U^8]4&W䱳v'2:jj42g+ܜi`FKx" #nbYch)WO:'se|hrr2\naJN?fXPLĜSi>hpϩׯ^[kvײH7% wOOī{R Ep7Y 2O;ڵ3M2P)W6 Fd>g~lK"$%XvUW=]zC͡ Np&8: Fa|"0GbXZ.krFMvSd&3Yg+b--n%[U暈Ԇf}gCs'/.߅^`ƗrFHCJ(1 Zb{,C#R7Ļhz|U0W1A.VK>f)$ Q\ t-f upa:4)+kOs;sНT.룞 Wٓi)+k p5 lG`3oStX G\/oqrqjʵkkW7Ts`Ζ%OO`~ d5WfC4 P#㻼1t$wtwϋ׷& lB\ V:geyW_}}P0O54 MCSM#MAɹtwʭXtwo=g uhי*Fa ]ݹٗ/g?6yoID h*e"5Xp!0Y@3(;}n{e_PS9Qg6ږu\`Ʈ7g<sA0&òK3MȔeJ8ȱ8pd?D`&NE_y Hy}n#xX:=~ItH͂?oF`Xa#(,"XI= kb#A!H`"/H\7rnXXwo.|rkKc'9deIE"Y BJ5edbbJic?~Ʒ-WB#]v{n*[wwGChNNN+N ힶ Or)&MM$)8B8$0:!3"s元%mhY 괝pQqr7,fGz*P QLcJ&W2"tl ѱ#Z0n=VtODi8:~pڳյ˛rÅ;E8XU <JPSE\I+weasz#JKDDogŨkÕOO+t߮h'‰buOK|ɘ%Ś*EHk#Gѐ-ᨸD6H%T_jNZG81$`SLjr)Y|;skKjVИ8IVOc4P0ѲYlrzBFAaxA7.X$ 0)sdRF]8aGtt0O; qPmVAPAlŷנ/A1N(:kI+6&.yѐ$邎I ebʡ="Zvh܉Fi#m ^ C QD:2rl.?j xL'5ILaĽ<+NvYP&NxzMO1h.Ʊ,G"ݼtr(O$b F*lݪ]KvWP"2[{9 cp/P1%Ӯ9'5`♸@HŦuE"c3oT}w݉DƆ#cٱ۫Vu9fU{? p :]M*11jfY$) )ב&]@XM Õۻ.0Qi).N/zo=Ԡ-zVYIpK"Fdj@@A 1&y- Hx1DZ,qdx4ŽR81ճ3/|^< RxbY,\t^kTUKc bJ$Go4do2y6ӣQ8-1rxemú2e6pv\b5bTUTY JC 41//D()xQ?/P)R)8p=!pQѴ-S5]&[akciʟVȚRmg 5ٙNmͷ3=\eJ]-W:rrcoƍ3, .ϊ|P:ups]p3Hƥ m϶t]a:Ϭ]yTi݆'NMlF68rRyI|eOc `\j"K /  TRd<%KY\\s%-i7Ĝ*Ww>?q-rzncF<&$~O0XcZ.wU8*80b85qjv:r6il?/`r.wfy͇ś-gZbZSȢ$䇮ު V F=;Ñ.3F.twB13qX2c)dҞ뻟{{5_˿ dq N= ֝я󪃃/QGD))G:ZbqCV#-=v{:s;Wgv䃶\ǎ/G?>aGRBPju0Zl(΅b(% A|ٕe8*I zSϧf?Uhu[xvmc^|Qmp֒rg.X}stZC%:mI2тtM #()ge'JS@Ǎ}o:#1+]{^s9c.Gr}!xD03*Ԍ JqsƐށ,P/p~坷7X/7"Buk*y ', 3!1@'% 9RtQsb"kRh٥Vh7eGv-FgB&v3tkz Vb/Vќău]aT% Q$+$Jl\9lĂM__]Q>IH(</Lp n\糥΂k(?eT{=H-%p`cΨ9[ûG!gYC+HGT“NIXM?h#@=q?ݫ?׵PZ>eg̅`=}rp3T4qvGw= 6{8*?P.,`CD-۵UH.+NhU=u߮ 4h8}Mh Wh?ĽdjX}? ;G֖ilbD\=Ͽ6ġ4fΙH)LY\e5[6oĂ:[]uov^,`@C&">daS647_k-z<4X6>]N -q gbZsאkw,lei:1A0wr5II,R{b@Z- 4⿈l}]03cYVAM!X8 ]"l&`%KX)JltÕ6E 5~o *w&ww3xޛIBODJrڜ܌X'F翼aL mye΀X D53&_BK{8;|xO#~Һleb,z]oc&l+OLU0e(ȴPO>Nvi6IaWJhj:tj m`[+h;uuQ@_Wng[9̽EiyQS?q) gA۸zYF_I*ᇸG_ [[!'#Csme[@@pVF{xۣã$wwm\^}/i|0 z?}Z`9F? pR8g0-hٗ4Gzf3׎'dZY]t.rV/`Aau2,Pt15E$D  ^؜ `e}e]+9q)\{@+g,,-##OVakKLsN-#(^LWSL8 d}r[XPXCy{V]۶ IhmYFi"c_MRi#)d/fj 5eÚmgeiLQ"LYv{jkasLoq)ݔX]XտcB̊Q$N8ǩd$cҶ!ٟtG!VX#UhuPL`]k:be14S|<{ vIUPV2B9x\)K*ˢ4^&J#uSiiP OA/w?`1Bt9Nlmu sMͩ]XB{@Aue )R5X*oK*r[OiK=}:W4Xd[Ÿh6:eA%C?,W[[l}YO"Mp \W^,Y+ڟcqnGfc3]`nm;cݶ j!pZ dM] ;S"}>Tywrܡ)o0pp&iQoؒ ;RL #l ٝG`ڀ~_1,P#b$PrIAH@Iy*Ȋ0l"Kt3K1KTed|$ uORe/Jg|a 5" W {.zwi.t:NT PDIENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_7_i2c_3v3.png000066400000000000000000000450101520775651600222240ustar00rootroot00000000000000PNG  IHDR,)nPLTET6" 3 3d 3 3M 3 3 3 3Vr4|k:gFqŰyfa~ 3uq`fmTfN 3{bz 3xWrn^ 3Աg 3{yxfulR@7~gZSRL?pN;3N3&o7u@Ҭ׀ 3bȴf\YT`^TZmup~ znizuyECQQ`juha )+ #XabN[[CDJ /5#&lvKST"ML T`J%+-/349;+]^AIJ s& P]#wrmaZ&%UW|:gWM_OC7lo0egje=MH<S$ƾ==<_ij->>W@2݌yk.%;qw.E/RD7*?/1#rzvY_Q;Ec)(#*Az}-+/Z.vetlǹŬŶѨtW=G(8 FRLNqbeH3xbPt5cybz^VzƋr~Om`oGum_b=LzQnQ{u}Yh-uDFuǰPi;\{?`[æu!Gi7ʂx 'MtRNS;|&Z">޻yEi9ɅO`VzVp4z~˘ؾuŪFjIDATxˊ+!E"GNAC͍+JzVAHZ}跢|p$`dv+c:xCWxWB0!!2FUC3':_f0VL&jʃK9GOŇ0eIP0\t TWԹ]eBB#X4Sx iiBT}[W .&:s)gqRXj0jZJs/ y l%%` .)7iysJw:/knt+eejH8nVl @*^M -vˑcW A5:=j3i1Ŕ3ݞJcLDv";k:2S,jb:fYJ\<$ϲ@Q4o65vY.ubr2BTx1DDmbP5mnMd߉sI._- ۲p#m_nv:K)\JCC"6Ձ@S4IJ)B==ɿcL+´rV-'2;X ZsR,,e]EQY\Tr/-,S}.nO-l _6 >h9KV(1;t, țz]mfږʲu)Wfz)%UҀZjV l]%3l;{Y-Mh-~ &Z ma:zee=e)B1trv|&K}G?~Bڗuj"9ж8| RD重eBe)Vh>iMlKv(Va1PlkDM֥(B(XqsnZW_-yv 6sK󯧮;;ŔY~oRS}yቕcQeA4]`00CSμ}]{U_W{pD[qk״B3o/):m_4N5WE;m^O>~bD$jGQۺqlUdJӞ,%YrT_XmFa pF >LtI(T.KeSBiL*Bin<;@29r־=^IQXK"UiW״yrS6kcJk$`i$*IRϞ];jVGmzH䢵{F4dKCYJ$$ZMX; } X_+?aJR@0Q]Z`o ?-Nkzڔ@i,XwnU[o49&m'JP`(X5O̜ț,h>تz\ADe(mY!1V9af1`iMZOvjV$ig=Ң@-TxD%M D/P+UA 4RW8n1P?`\]ց"J2lh1B36A K2[مsOLtVA, s(E'"p3 "rU(2Hw$W0U<;кPtE$WyC@aD<^}۞]-Q}2V~3|P&mmn^}vG;K7H 9uZunwhr}$T-IUoGгyqav"lBxJ QSl6WŨ] ekL5 ^UGNSf?:;m6x!/4;"o, R5,={$²1hflm]n=7Ym*-͆UDT(zehp2WEWgѭ|cƒƙ帢{K B\\ -e\<4H4eŌ!5 C;EMIN[<.4,-O!ay#UCySuz#<jxNe+JjnxbbP) v@kC~]B+p-tBA964+9Z[.o[K<g-#9b=d5Oql1,J=RVw&2]X%L0$ApgG+3j2tdp4Rh鲤5QđGRsfw^yh5-FQ~;F ƶLJ ~07՚ˍNbIL?iW`hC*upjPA, ZTcPFCD-9پd Ѹ}#󯯮xVH<VԑC]]M?xMP`صG+8ɵoO/̸uo&e?O'cR~$ݹyKl×_]זOG7i%1!Bj%?J>u yl,+T}ɵ̴ꢴNk~lqGo/wl1o:X}Kvi$YƉTRtСXܾnܵ[ qiU{9|6D&ь3aoEq,# lBW&ѕ E"hY[Đ]/PV=n|w>lvj浕2 ..Bd"EQTDD'錌M5jffƤ)#&) 42 -%Ā6$D 6mx5hc.9L.͏sQ>/uAlirՉkr:˲==b5㋵_>kaX6jx?=l*,Hatr逕Yc#+O8*.Gj~'fB(=?;׿6ݾL+V3u?HrjDi4"z9 4fVCe5w7Z0;!Y^X Z-Y뎻7^h' ս}UV Ap~7҉k;2ޛ!8v_+?30g]pۓfM,N|=]Ӣ^`R|> ?߸v]qw !wY`폗ԸS_!=A!(#NdV38EX`H+4Mŏ./ewڷ CL0eOM݈-<%PM# Lc2crgdz$JfQ5S# eWhpG}I;-4KwmfF>ޕKdٌˆrR\zuQƀkGŕ]HP!P.jM?h^87bCkZ;gz ~zY<;%0lbD*=] 5AL $<,p3.B7ft-lfe5z c]D9m)!|*Hݍ2@/Nz򯚯Vӝ|b-[$Em=IrAzY+XTYƙbYlz^4Y=I"ۗNєCzlVJR&є wϰ"}nL=1gPÑTѲ!_9,xY΂Al/B\gk^h98,t[M3iMV4XES(IgP;qJH8y!eeG YkƃFF:Y=כ7|q  pm]d[JfX kɌw xђ)lhyloV<\ .yVޞ>9y~g,%XudՅ }jtA g $juo-9fjS^rLQQf% zDM0:Ow 4egoRhFCWpL;vG ~A :E9?xshɨDܣ7%=`ϞW"jJ4oaZaЧy(=|VK1u1ߊtD 5\-' *K0zR w'WoqB>39D!/`hf+~GUfeYoݻ8< ZJR?YmV|:/.<ܜm'WGpG@ S ̆ElUh*6)E| b#A{p_ܹͣj.Nۦ]C+B5QfO^j1bo2נ}<+H ibYn=#V|?8:͒iOk#"D-Z|/h{lFw a"y SbZ3N$Ll,fN`J<&+5MZiJ0$q$ &1me{G?1"JCKj4 "E?҇[89zXh2Z 8@.t: V*UE)iPW?` XUm)mxdsۦ8?r!NcŴx{{l7V y!q,Y4D""G<PzTR,IZZ}6VW{ rqg; fdb-д9"`AYWQ#c@ B"*vϻ[w p}mϏ]yt6$,!= V-BRQ;][1@0-fm0T$,!춲f?_hpC`5:vB|OgY oQ[w +G=w.}a|鄣s4.iɠø/za~8x3Xe{vG#gquٙi[J-t96EVlSlJ9؂B =0,hy,i܌#d9P ?yv,/.,.=A+WAdg#J\JPn_$Z7.^j+9_m\ EYGY&5aEt"ZZ NV ~0ѱ.򶶱$7!b+0*x-l*n_÷.^_""ΑyvDŕr%= &] Ӻ8h}^%B i=FVhhtuឬܤ}DkR?m. *,2a99|7+ohC<c,ϿzOlG/mÛB҃/h-\{RlDC$nώv=ϊ),6=VcPb{1(ujnf!; ŋmǃT*(>שX!LnZ d&#MH!I;%hُ J]a[{^۫sFxŧF{b K \ ԍBM 0c 5[z%~ő~S??&%w$VG*x! MgG|qNAvJWO'9_yi/BF^0>LKh'ќxT/;zk`v# KOꑧ 3y9-w|pJ5{Cо/^4zxiqJRo1=BYJ<;bd>M% <a=*ҫY_t#n;9W,sjC )wy%Nl\7m5(: N /E/!B0Ju;+ 2YףlG`ɁogEEq*?chn\I)wM788嶄ffGhH=zPE"hh(+l8LZNA+ "#:)@[CѬ9Ip%o YNy!WCCC3ik%ۜE݊ h*H( "\z= ue C[Co@Etu蜅X\=ʯkJ˛ݩHHШ"fΠJA/2ry(6. J *+ƠP͎ëdOQr\kcYOg4ܗ9X*H&n{m ,,Y ۚ%Cpg Ү5vuigP#zG8Lh1]e?F79wyy|L4kgǜ{-E: ^e(NQV]4P1xmD.K1щtf)ܗ%.\=rta_MMI`h2N:= |w$WxzzR\PӲPJ\NfԞjЮW Z\ZY;V/Z5W:C·J2-鱕ޯ|*|k@di;V(cX71`QL4Q…FwLԅh, Z k)hNǡܖҢ>i#M*mo[V "z b%X,1l}=44~9| ާ9+Gzu]^NJAp_6҄iJH4sH(>099tB $g":ÄU}N*tR,TZU(zw%d8Pe-qZ;x Ѻ{puuW$uo݇F**,(*ɛi( \|#Dњ] ~;R)1}PIܩѢ@v,Qk(L"k2= cFjY9-g[miMb .Szed--H9'v;o \X2FzL& Q?tJEw`4"\Q!ROUE|ViLVk.%^?/6Ż]3

˅ρT /3nξZzt^I[2ߩ1O4TU4!-N+~,_fN]NQr9ٴ/&Y85UdNiwT \% :P+u5ܩ KpZ#M`ƪll8Id[,bt5xCZT-LKA5e诰ԴPUPqC|(z=2$4yRԏ?7AZ>*3?V'%i\OBtrGu^Y?RkU ^Ӄo40/h3¯Y'uIfkC0AL-@pD3>>ly4*d^\cmu>Rϫ30-* .`̌A!VHRRј80lYNZ$h.v4jYN\DT7Vs{H:-ζ>WRMK ~2ba=2SQ'̰9bꊸƦP6rJ>[q+II)n^DԎR|*:z$J6RV+=:uፒI@Hh1'&J1G,&taM H%2<ښ&#`tv4'ͅ5^n ?:4Dm"u5ԛⷚ]9cFͧ^ w.:,awJ(Ǩ{1zG"gjV7V<ͬ>Ǿ|#pc HހвWhml"3"XUv! $ZYfuU[(͒~W{wbj7;x>]~&%,E |b:9Ԙ,DP^ /Zp]X۲厘tkVN﫦?ݏ1%1? 0D8DX-8 &vwsК[mI<7z{~LB:/mgg6]lثdRg^vJ;Й.$f/ nat`sE.gF<6~w4*ancr֟+`Eb ѭDue,?YU3OP/ڨ' P@6E/X:i4\݈2?zI7&Q~ɴkk{3]ZP/'c?&VFO֓NJp_~n,8QMubTMcr.wC&OB\د~V 4JyO'ԈZ7^' ֛&@aԉ[M])G뻯W4#^եH .w*!CF>ҿ uHq>(ՂPAY8q.af]G(quY3dp!n30dҐR$m ئA% [=xI&!=&4#Eo>>3aV^.`psU-[+"Z f[OO.Q٥[ωD*/:O.+e`S#tMN .`hjwmn}&*TfVr\  榃n|ymy9TZߨ ^/Ͽg  pԳ5ۯu֥WnJn]1%~E:+1 t5j5 .G{WGN6wS,/Z2 ]eۦp݌M^\vگxPxVZ4q,ۅz--:pwX FKKW rZ2ĀV*pmd)J׆LBg hyn9?^.M׸ۿ\R~wKa{Os` 4,6/d,pmjT;SE׿"tE#fXY8xkl׷rkKJ)VLXi.z4/tdl#PN 6a`^0Ӓpt+3^hA G1fb쓇KsGq' xQGFfU0 ̯TkӼg^/ϾU3qEXVg)ǪQ$L%q,VlyUO<:g铣iZ0)ryx0_ZH<@<a%.\ * U :nAs93,Fy:H:/l}~&=gj[u`hW L;xN`IJBELM0:XŃ4ZC>MVj^NCJWa_8پ1}߷**ax2vN[*.]xx|TA9RY$TVP h/PaIRSģYJ&(͚&jpp Yι|t3mɭH!r+ <'buߨɑ.U6ϭ,ʥ8" /nY*XR5IW!Y%mTRA_ Rqʕۡݥ֪iݵ|TgW[eVt޺N4>_[/ R" `rV"i4)C=0VtTe X˭[V/uNzIנ Vex1qylqb%D `9Q$" aEM(:Y !I@S$D13w v`^9i|6qq2S=/3W,L>掏exAV3ZQ@S#pq  #"H /5*KB,RHrw.MaW'bAB}(|"r]gauS u "AzZPPC&UU1UZ?ߏגqG*>+ك-QL TӱޫQWHA48A@6Փ)\a&ƹa6]AvAle! լ˷eGORW{ٙ'邏sb2-yΆZکm.He7zթrm &\W %BA~TI e+ZO4>i|̕S ϣ'_u^o(btE|F Dn"i|ba 6 0fQ+h݆\?xlwāf4;%ᮈԇdaot05:UutU#ldcL\,1DHC) VϋG>2117i =w<[Y+wWA^=lw^9הLΞ͎?Ht2ѦӫM<@^M,A ߜ)83A$EcVJvUKţk1Gr58:Dzbol\U4 sn ERf)(_Ws))!0+$'- )1W!= i8APX1v:{BR.B(W'_H>-jcVs$84 Ǖ2P*P r5) ׊. AѷRv2[pW̓lTr_.~ƅǓ[M\/ +aS0K248Dk+ɖ2qu"3Oi)a]FJWّM3g͍VIx68Kdڻ:\epzOq V4$'6%*$06BYz)T!c  Nّe-6\ {<~hk'ˠsf&ihP0C9d @L(aZ`%;W:R<5 pp!ElS`֗G84NssFt(̂.zy̖\15TTh'zfB*' VV:{^[62bժ bRpFK$x3r1z:W aT:ڞo{ٟn4mQ1kOvXJ5۾~+B  L)N ❽^(^k/\3CJi8 gZڿ-}XZ1ͪ;ԓ5!mav!!Ьn(ES-)KoCfS`Fkm]?Ƒđ>HNe%,d&YX,:5)RFeްº $zX Ɛ-C|Ga)[B`EQ~k&TqARKajےY9N2`6vvˠd!XBLxbݻwf"hi$9YjZ. tZR__ZnaAm F />IJC;3ݎcF"tc5d Vc߼:_ҲE,%(c&(\yLgjX,raP8Oep`}R{wJX-wBhSLi21]Tw6#w4$%7$EPQqpNNմp͠ܡ 7 f+#Wu8)i7PoQ𚤂7Yy<ڙN;f֖R?b0%ayږF>:Hu2-&.d=~z_nY)D3lGOkw>'r:Xc@ex+ʱ+PðBNF#cKshܝcuE5؈,Qm^@ o%W ~CXBy\%a*q}iW_N4fZ@֧w9w<>iU/>{[־zwgVgce!=u#2|1*lC9c1ۢ]}qE[xw<Y|!'@*Xkò(jx( iRV}ŗb|S&ebɋQkRFW1!B*-G9-׃sk#q֟ݘِ6 V8KWՖC@!B>kt{j99♦|P  ,%&eo!:Ջ>\ E܀~e.V&qaegAߒeS~ϳYm "MC"v̽¹޻ROm|oi.6. єs:Nqӥ9*WloI8$XѰ$RQ^Ǻ/Ϯ*'n;cy QtͷD!Y]8 ܜL9b,KMFXUC,7EO<^QUEj6jy)AN V:#PlѤFhSt:m+/6!ªm)˔6bUVˋWY 7[X+`ʘXݲeapV^*{ V/qlk{gF CQ" Tlr4N#>P.&WI9FHj5XGFˍyd 1~̀~>2[b;%rwFqY{aN˷__O!DsM@w'u5҃F><ꖅC--&Lqbߨ)5ESG#HѠdܽ*C k^L5Eo0֒R4x}P%H6|!TEhQYMs+ aXi)YIjeEOks1vY,?\S4$tnlE);+zIрhc_nYΖu[S ߇o#$i0p Rb0,<7Ec3`{&&Va1[ 9!eHʒ6#<["2wˎ`ɲςݗ;̌:FZjkfu֊1y /@SU~IM0Y &z#"=mT C(tCVSĠ1,.+FK(Eeq,de2ad)椲 6]532vVk֝iԀV(h i_ܲ,cw^}߲6fl6kT@IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_7_i2c_5v0.png000066400000000000000000000447621520775651600222400ustar00rootroot00000000000000PNG  IHDR,)nPLTEL5% 34IV 3|jW%$V 3lU 3 3yudp| 3që!e5Uk@~bq 3}X?^. 3 3 3æmg 3\SKnN8,`R@8tgaiQK=mgX8wA\k׀ 3_Y`]ųeTYi  ytCMO~ypУup %'KUJITV_j#"Q[\k }oiWdejs T`b8;$(*(Z\ADbRF KJL^uib;'A,02 s(pd\5jm00=qt#QTm]Rv?&Z&wnh-ceƽ0ozwKH>+?:,5@?2QĶWC6vf:@C-ckkt~EK'z@y|~n(P,µV:E477ܻĽ9Q@]]R$9#,3."´vX@[:%&gK5QTK_b_}ͩ FR}]yj3mF_~iWH(Ot}y=\Qbӊmxz:AjтHжοMlVV~R/ə-XmfζG~enN1TߋBhcƆq᫐[̵ܸj5" ,t1JtRNS |'@oZ)*E ImJPXΏq/ҍtԤ bFZIDATx옽 E' D j$[,8$8+li{FxxlGyx춐SB%6,Qӱj\twӵ10 *bomh}h]Ha={0[|u*EtWy ۤ}(Fm fYR Yw)z}׵e޲WZ٦Fǰ U^ƭ^4?U_5n b7M=:)Z=$=) j?tJW7=M]+)*ceǝώW.^W_@+~(h%~o* A}X(A!iTXakwpŰ"&hqoaJI.s1;7q:N upx(e5Է;,Fi0ь2T& xaoY^4VfEceK @WI .XetT9\-Z1U6<+O $h#Xʁ'h}2WeUiYCEƐ q Av-GⶱՃg`%Q̖rXzV6.lb*ŲB{7Ā+M 멮EIXn18Xx,#Y]Gr Xo&-Ѵfb_9&1j{hiqĪCO/'+θb8[h#UǛ7a`a/V\ݭ녕Ŧs8IR,arB)>ti5&4V $4]j(5iV²`Klw&^PɿgB ?fr_>t&G"&=up+ 1pfurݷ_mb3dyaʗ1~םwn>tt^5?v1۟QNA XX5N.f󬿩&3==ӶPj,\r[g/OO6Wz@"BH/NijlR{k~3{)B *\*StC4{oD| hLBKg?eho?b};LeFvdk aa= 7}Je2JJd 44-]lkީƜ)DQKDFex{egGM#(t7)Ab]!x,t/\y08WHL1zl *2 Ѿ~s:e-,#}N{g|Ӎy8aW ;͇6of)r:v26 MsHXXD ˆCT,46Wμ¸iNyiwfXF#Tf8瀝@ir^8siƣuD>nV'T5!G9-3 4R;؋g.}V>l|йhE1Yd9 GHLyd$`k~yG?;HFj eXe{/V)M 9`pCM#8/}smZ%Lh Z'nW/]Sٹf 1I> []]<ƬK`(]6@UyuV,rʞ}a%뤪.:hM`8}jAի=5yXQ" x^e~ ߗ DM`Xt0U E{$<͟~-}=3by8sTkA+<`DӴDa"͑Xe=RJx<jHX!20!faIjAaRenj\0T`2 )8ww/umaAOAMX1a(bÑV#YJ&`ُ @ꜷ8={'!E"r7`1F|)/h ]P &hbIV>YjKy`ۡNk+KS}x hX%'ec]D4SQVCNj c$'h!%Anjr jyd8e.&:$Iח~>:a"{{8xLxXp4\ UVC5-K][+Bɜrq=sݱբ!>^ZAkq2 $N*;@2yK=,;aEW{cn\)1D{JiiC^QB< H&kb)VyK̭F&N%6YG}ǖ\ YRqdΛ-YyX0/uA)Z|,RA ߅Ҥ J~/[\ZIo2ﯖ+<6]wͮ },IQ"5,KiZI2TB\<^ibDPX,-UieIu%Jl{"{ݟ]-dGǒ7֛ZQq@7hO gR#)H#M&A0@ Jd2\ZDGq4__)lѥ.J8}~t*Z0pUSfx89J,`t ]-_U`OX˟N o*'%˲Z8":&8m--.V9{ T  1 ʌz9 cx,ym xףbJ`MtAqtȼq q&M2I(BrJm4; 4GuiiT8[!A,0OfgCɥ~OȪaZšV𖺤%ɪ_5OP;X~ewfoOzL+F#k3[\͡v`=8Ѹ(늕arEYz8_ە}M+尟g^`?QotS\Y*gNo)[8[F(e&qqOj5Wb'́2QjYE{_b6Q G {Ool֧uksmXrGWzDͮX{W!x (;~yԳΉ}[%~ | $AKa<\Ya] ]Z%JleJ1?뺰D dZ<DE#3>9mjűsmp4W5o~,R/}[:MlRxs횞q-!3[spEV{qͶm[A*YdIy{ׯBM-=ٶymam*_U/&>5ŷZN_ oVysșm?zA.) p>98OgQr԰(+]~ux8ϯ~W/]Ew//N5pB(`3VTڻj䤷 Ի\^#gDk)i]iϬ/B2͚ gXH.1^ `Ո,CVAKL^Y r0y 0`tYLaaUN4ԫrEY?tvfTBD1zq8ȗxQVY(bfp &ޚ@^a`FW ;?xi9MxrcXlM+AN%Eёa wU>=Mœ/z~EB(>::; Z+(J0Q,/BqPytt uVp)Y ´Ӈl$-.k=J*/a,aJ+y)"g>c@nMN\GXz{qz,BSzzrQIC 5M:A[tD\Ƿ VM+48t%]f +cuXs\[n?Ҿ xD*(8q/Z!Ì]'~`!pfIВ3r.Kb zտԜOSgŮedIi۲nY]ll 9REGJ&iSFVAK݁r0@ZRai)E*  $ˆEoy=ibϲNV`mb!b0M^*ӿ^uM %O)˼)ۉN 8]j Y9STd2}lV1:ƕLR^0EZIn51UWFu&f}^uu$MsLT h\ChlBkn^֙qϺ)R(qtTFE1 b9B"D"aX^/] eR]2qϫ.V)z=%<ȤA!$XRMWe{jb+Q9Qx޺@FDIZ="6c(ڻSXw=GGnvRaa. 6ܐ@7R;Zcv-@26z5|)ުo N,+MڍW dNkKW!wNѩh=y;=-=1$R;BZ0ʋH$;૵+d/Q7Bq5ƈ8<H"F:f`K{U;ދ )Q%eCg^=[Q?.*0.3u,&RVG^ X)R [Wx2HZk@W lM8&Sb -$J+:HBm'\"8AEθb.g4$Wɉ?D0M23˽.$Zd|lAc2uZ-?v >S"ǂDd0^fqZ CߎD)-}7y#?>|4Mz+2ίё*6Z:M&ep=Te@;hp^3HbϪIH .[tZǿ;03¶Ҳj3;|QR[P@T± MPA^EA0](5D+w; ƁD#LPC [  m?lz~awUIYyRZ4'qNc</OF KgUY{ Ai\>yva>0)t+Oef*>8 z0nv8 Neijo/ Q @ oț#}OsJ4V=2>f7r5DՊ4@8.CjqRTa!9l+ d!* Kku=x@EJ jYGKh7Q#9EJ;F)+2Uݬ2ʙR) _M +:3c*(5|n>6!Vړ"#FtE3h&x$w-AP| \|ϰG*3 m6~QygcDpeVӆRihnHb\Lb[aOY,gZ!Ex P&>9dw@,Fk<,0u=;K:g&}+.+t | 3}Abfa")d'j~ KcrjK ö}X@Z1r#u$}גǞ';\Z+K1Z- XmjQ)U=]kɕ-8W"q!+ `@\l 51(]X ϭTԠ.`(*!V~p:/v%fڇ,'B3sWw_u3 i8 3|ᡆ;-PAJl1322,6e@'e|cH.$dw8 "*6x;zQ9h;ZqH-w].WhHEau 6ߝ Ý-MW~fنCj yS"Qd[x_"2Hxfp`o_ ~)ux&6:OpF.cx^3vvi3yn1TW*0XӟO;F(kbh"Ɔ}"/O>Ą8θD+dɔK] Z( vvjݖ.i)([,`i(XW>Zэ=K9}'_ڄA_\mNv@h.;ZNIK49Dl"?n+1vWf^׋v-Idc^XwNWOꄶ6ds}P6U0[VNB͆Gw4q)*.j@$rCZ͓Wh/RjXu큕hr/!4GXYO7(ZwUQl//eCRb|kf&KdSC?0Q_T7TC,ۅ$V@9z$p!D8c}dz2! r&\Uo'!֖kۥ5x~ OljxYORNmo$O](ܿۉo_ܣVv|$iLL;©L}lŠ2B:>!(ՂZW#OhRl٨~<|hb7jfW .41R{ur*u)M0GsqʭP tw6￿JY^wR8)`Op{+䏫k9Cˑq4FF./hQ%n56Wy`fz) -{E3sUQ@}EU}~cky-W,d F"mQh mmoa/w~ ­pUED)3WVZUzsUoG/r䇾\S A3* !b!!2ڟ*lbFZq,8|Uc\EjO<8\Vzi>~ S6j.+6nD Z-k7F޻B ^A4}EP27[w?G SFŽGnBaBH+v@Rbh&ek!ZU~#Ag|;_}$xVJOU+Ъ;V;ʚʴH4 +) \eʴr7NOonZ[yyhd*.~_.1 X,gq9s%l?r7ZҠTVҾ',Gg*zR/aJ渖 ?ӑfJ ߢV[VBHմs*K%4nx"'xʴFjIr*ph$vs(XS{wKN60Dn,pB5iȿ*Zx);@`aAd}ϩzx/l{zoz\/vS~$566u`5EQyojYn"JUXUE?iUH !pHR鴼̋=^6kk7JJPpWPjaW IX+ιD0W:V ~N,]=/<Nwg`3/QyMxeG%n4ESdjla;$%$ V-w<LG 8wM9| 7FmsLo¹:.DS[ͅQ$`V#:gucـwZb- <}ɾ@B.|R{&֚L:B -ZQ)lddv}!hz]4nSat˂9n]x{§;U`#G,[UcGl=L!X9%n|sKd}VY$NzlLO7 P`JhdUZrlpw):cǫzKOdK˚]%߸Ng.ƛr$:}Py{B ε7YCV]^|9=<5ꃦ\zn=嫩| {eX^hZ^<ΰNGhi#)7&˾vC%݋/xEJVrOC7`eNg鳦bkճsXaa@sΚ+6. RH:\YGlY46cbޢWKuf?n'6sT}yζ֭N5oaO?+[δgOQ׻!?XڨLnT; +S|O\,." 4&Me?[p[_VX |7uLlj]^i8 $I5 WV[?$igٳg c34J ,%p`dGVsmf"]VOMBn"v-W$۽ bh Xjü7ZMkXtpX|"eŒ뿰IQ)ΨwL)R;B$ҼbbuL O.-@ w{LFNq\/z%(l^;\)xWr`7%7iF]M1R2RIz,zζG9;9dxJw=';z$_|}v4Hq]on6go ²&u˟no9o5|2wkC}\"Z}d8`3\CTHTV*6;zzòjʿXibp6ɜ-~W;7Ex ]XL^|UfIg0$gxs#Ήg ml]Mo5b?"Dc!9*Ha$e,L$X+9+C,)edpVT`bzV!P je*%!/Кh}6$?*G3rݫA*axNzPs&Al\#FN TXbsd=mTV`ݳTlm}=?vρ9?:69Yܙ^J_$OmPp Y'B" aJh$[B* 07 .{e9VYdbn2X .w/{vUБo 4h%J`Fh=u̽8W؀S{K1ژ>ݽ_4@QxJHot5#S,ۍ U!Kq !ă_͋z:$'Gv'Xƻ7診yVXI-/>*n[WH$N ''~ Vw|byLTRU4g8†՜fd$Ú`jll~~ʱc̼D|xm:bYGz# `Ȫ2A+ibUW-c8B@A%YCA|h̷q~kn淃pNZ{lh+v$n`heEQb˜ 8 "jѐ躆Qr!_'qKoՊ j+=]* S#zԡp ?6g2,KQ"9TTBHe& ©& fi@dGzu{ɣh֏ԢTO`lV<%% ![q8kqZ,֜1@:|u%5{{qsz8K+J 4_ Eq(LH Խp_C,#1\ytcXLl`d<(wj߶cG!K#zYٍ㟜߂B84=`F`2DI Oո|숱RIņko _/;(oǵݮ5"]%V?v2I,9g@:VC߀-Pù& TӰJnFc?ɟw_넏W}` B;U(<3h(sibz|JHh&?d yiWK:XڋP3(OVA *β,/T*;Y4\B$|^V3:+!Մ ! E ESf 0H$;N@A P BOg/4UTT\gGnA? Xs%<AIފ<*{3cm:u;{ z|60L#L?`1# ^+blERApa/\Ϡ p :t}Jtke*%'2(J rCR& OQoN\A8H)K%hWJ@Ĕ0.xу3* }0\R]^wX뫛Y~?`;V'"%-iRy I)J yM8 N_5Q"sc#Iyk>zôGǻNt(Ͽ`Ljn1n CNehc@)wS)RÃ"%uT0xzKfq=4c*32ʛ2RX.߶&[fs p0<ÃxqB>qʓRR4ץT8CuǵŃbn_h];Vw ,4Hon2))LEx| )IHA|iDaNJݵ6a_=  _`O=3 sYnfW,TV(&RhcKmi@(R6qBJMhi6žThaFPaX8Zyy%u^ReA#S)52l;A1]0@KAALn_x 뗮ݽ=2Q{'-.MKbcj*ԫo_JPD5*_ONMJ#:uku8|a s[WWҹHDy@><{a5kůǏ j* .RԕJ}k&?V=Rn(<2͢W'3]pssx$Vܳ+ KZڣ7X`JnkV!7+E}Ҵ(񳋭}>p83,:tCӲuEPtSYC"w׏bM-ȍl-d+[)I*"(ѳ{:* @1"QCu^ ՄbPéBuuaw]]{>8nce jFW脒 ɉTm% M 00l>ᠡ#O~&rPپSOn(FWsJd{_^Z^mpY12H)M0[d'TCfs F4u 0f`8W2 %0'iS|m W+WL)TZEVDh:scWʸх;N_i2}#iFVK.61&䝻 TRɕR j ki՜&qt'\{TP7nK - ڞ?ۿx! 50S,o|>]zPT3[-ϭ\F+c6j:eMֵo/*˖@3}^ MW&QX#\{6O j!uOl( 81{<qDGgi( $y,] 9a6RCcMWB BB,0Y΢ (NVY IQ)XT409?1}~0vnmJB0e)!~S[6ۚ!"n%9LmOx+GS3ղ4)+%hC$UQ{5ΊoO̧X,$I jX0ggٹVͯ[fi)D)L&fi8;>U{љ>ƄF[BVj5,2qJd4pwGTqJ. zXybGb0a$R/*L)(95`J S"^`]*]y2.}QfkoMU +/&,(}T<+ /tۖҼz5?(+^1<ͭzvޢ\ $+րV_3_\|zS/|bqP3օ%l+(yR:) 54:*!)n8e:,WYƇ>~ V7ְ keu*3@[98U'>F1_zX½OUOO4fV08 4$2 iζrTVqY,YmGS<`}X", b٢)%*nl-833l |rnR `>q X$ESW9kߏ8 gsI1,`d)AoKSr,[zw06r$w)Elr;$!GhL`fu} ρǭF`!<[Tъ6Q۲d<+~kߜ$Urex6Y(=>fտ Ǡ,AIcM 'jY{@`_d FVUaKu3rV_fQAAp$.CUw8e6~Z{.>MgItTp8b$J`X[<.W٠RSM@eՔD?%\h]:g~3C@@,{-8ݩzUZyR ަGY$4(+GV) t>֣(~JU_L9JRQҵCuҿidac.Yqi 4&(.+% gRUVH-~%$^|(.Ki8(i ,#_  AD8ims> O'oYO-럀D}l6f٬O;k_Sʼn/IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_7_mw_3v3.png000066400000000000000000000463141520775651600222020ustar00rootroot00000000000000PNG  IHDR,)nPLTECO; R5#V@2 3 3 3 34 3is\ 3 3 3f˻_hKfHo~RH^CYgBV{Ưy 38j;lψv~i|O=3~ygֲϟ2l8=nBCGVRHvý_^Useg^~Ugsc" 3)-'\ 4XaFX]T \Q8 6e݅xsf}x ~,dR{nfc&C2_˜=* s%sm*F8tg`VYj'L|l##u[@Y|9']HVC80m\Mͼ v27O:t .cS(PGrb07-þm0RuibX:PBMVgWM_M@bE}Fqa@=1OKJ>BZOCǶ:ui-(T(xdh*v;d;H?eY&tH@Te[1Y/ "3H/E >ߎRǯUVM4xnrV=gbQCȯATvʹo刋nzunL}ѢG/`.i@+¬ErIttU)zhGtRNS(C~-طcĥHDF haem0̲ׄĻՄܭٹלMrCI4IDATx]0XP?Pd 5G̥Asқ0b,d_Nj3 ,nS%Tº9CfmZ?,>3nd07Է*k _ȫ(aG']*0/qPx/VRiv/_)%@qpgb[s p9%ٔtI+eѶw9}ׁU𼶪ϸB>R€t1>V#ujjەhz1++3>/4 tK,rЫylAۛ>_(`_>d˭*WdE"F!&cfd`W)Zt9X:V駬J]Ko iLA`_yS Ă,\cw&;~ ^iLaߌY<햷6aE9. !#ΐ4<$Z,v"BN -]ie^8tAāqauv=f{nww'زvi+mhtO? ptCi^Y8u'\w"WV.آ1"+E(5X6KUb=V6( N L1X,Gl] QH]-_pjDY]1rZsހ,߻TM:ĩ(M!?[.8 )`XJC2(8=brKAZ,T#-bpd&V2o\GJ%fU\EQg#b$KȚG}@mv?V*Y- * L(Wխ*w~:VCb WK Us&KkW՟&XG |UbJHػzU_WG6L?G)UF\5vy'P p5omeデBmI劔zvix )98_'֑ ݃O?>~Jg-WN<^>ڸzvGgcӪ8^UMH+m_|h^n &Qoj8ՈT6_\_WQ70-H@tD d5ccsݪ=pU;F[H9rY]۬g2sT=׌aag1n|xߦ:LWML~97.X׈Wl_Yv}IӎXj8|OoojZb?d2RkuW1Z^/\h]{^]ӟ=t 2Uaט#2l|So{1zH۝+mu]i?WZsB&}lxpF'~GKݫl^v/Yj__6ީA5Q/6]b/KRi]VܝckOy' d)DeH( (:W ǗZ_YE+pm , pR\eXԄg=瑧^ ;phtV V hAJ(S1t:BՊnӃzSו uPg+~Pe˨ #H]Lu W2`+ )\uQTyYfs?\l:֬s^p4 /P2t=TB&$KNjzFZK8<<+b~W]GY S[d=lD 3CCVj h)8_h\Zp,Lk"[FdO +1k`.%ׄm;wSqř."03=8کg/ rCl5JGIk.R2[ Dɀ|awZ e%eL9[Ek:]&|EF+ah,l$R\Jhڭ[_/85ڜ*s]roԂV7[V E>*"7fL-!RWsc<=3h6nR_"tMxa+o&])b1@CH fBbJ,O 먭(-+3Xs3b᧹ \k.:ilA/(v%* ʐ %l"X ǢO>~l DV~K_~tubG`]%Oz1`9n-DJ0XR) ,"䭹(Gߡm*α FN3n^yRR_ V}:(ɕ]lA^OFw"(%s,q,GF%8b>޳ym@)5t-i$3*hPv{!>se{%l$1Qt7KX/,>MKċ,k4MXP8v 5l^+See1$Scw0 k;q4B8t NEqf$rX+V[U6* Codݥ0C?D݋.1iy2a"$S<>(1X2֢T[a|BQ֘&,dK$RVhYs͢.FX OM}V?%b=@"ݱG }xo*[\Խ+8+V9M.*DxP,HAC۩Ւ{f8VٷzAi[ ʹcK!ǂ['1Vtu@[5O:KP28`(ShevML8ThX'UHV2ae{EѸCyQrư%N)ᠬC厼3VDAU?0 .O".|G.YDlxhe$}ئjH\y!Үr$rV**Jʞ&JLWc#'g /| bE {Dv  ^FrirIŰ % ,3~ZnI8A1qHUV yFFd}<)" *U,~pxk YQNVP43&Š-7@rj BfY6eH< m T&{jxmCNHm!+`!LY)~q%#(nj:%#8TAt3Ęq$4J RA)Y 렯<~Mnp6$wOA+D`rrPSxGHjJ1e&`+oS 1X*V*('`[G75O%#ȇjeZ偠 \?\5٩Fa EѠC+99PV<-3 x(,cFv+8RbՒK+X2Wb-:;UF58J- ߄!bXZAMW@~:( al2 +VY-ǧ&%mB\_A5Ȫ[ԽXᘏ\RpgOoq eUIU~$;"{|j|l3nˏ10o2aoQ0O#W=2 f1O[&^kIE(C8ktj*`BR(r(i rB-CNf66,l:M|ޯ=xI_ݨ1}{h;P`WXPp5וe)!R/3FUTdŪvN c 4ZBhE,UՕ;D Y?;g4fPԈͣ; i*09إA{U1{k>*/Du`6h5*t"])M+ĻeXw*oxOǙkW2kSW#X3vg鬉V;:9S(%%yht?O%߁=M1VX8v`-y`KjV$¢{kt(Np=[%J]Z-8Z,Eҙ[Om #!_aB\V+SmORkގ(avF |q0/ bߗEiٕwvfHc4dt9UQ^N/7B )1c*)Yl,mk+(hc,hA6 c]EHq 89AbUU)dުbD?UClY 7`U3.[aLs Xnh-htZ87& ͠Y: L<:0Er)>%;+*ur -LM[\KJoRF roRJ%Z`q =qI@W* g3w2Vtƀ V*'-on+FWݭmW  A rЈ> UΥ yFi(ݓ]Aue B1vs|>KQڱ Rbh~%g^Ӌ$V(aB;[ު 2SK$#Χ$m2MZ9=/hAwQeӇHT{茔$ Gr $j #TԶx:.8fMYm,33fFQR`-q7ܪPPb+TiijSt @Y.*Rrr}L;ӄql.fm eEaJCq]u?cJ\ |p8b(D,LLL( #n\>~l̞}bh* ;!_(\Vv(/vdU@\BljU^G֮=.\N桡ƼTZ\I\L&Yy Yȡ:{)[לN]Y]@^ZNf@,ֺ\9 V#X ZQHU {HW՞U~`WTXGNGH(NgwJ.XBҹh*oҟ|)HX8dzABVZwI+^ Tp+wl 4_ٱ0ջ+XMеᒉ铔1A Ac,ƮIü,^T50QAȚF2B絖X `~g]AV8Ss]wJ ]A ѽK=='D]QsWTYG/ VY# ABXMBXGZ4t(QXVA7c/8Ci9c*X&&_62r.S $q'^PU$+dV\}HJ5$*W 6*on7 j:nhJIv-a;Xd t'㈏cHV^:uiA%#XVkl veUX71TVSmc*bWN-P`B]ڡf<;]sp) N7M5*\jV[t~!>R-B BW"+cBAc.'w,juN6(JO(VWNO df:DŽ\H yYvgY 2U=u$1*/+86GRYI+>;a&~&=gZIvU]Ů@+u-661UCScԞvx6_+j(+X;(gbiUc,Z|ӶD\ l_خu]YFʼC>*슱rFYdM1V,`tvuO Ro麠-N\ a&'rB Uh`i)lq+jB[a芵X +AVTUGmc~kA%yڦdJ- o(^S#o\hvs.`gnGO"-AHcJɮDVhOW;i?/Qǎuօ[~eX+Fp|l:MFr0@lL?9`AqIejFT®no).?oi&w5NW!' 6qgVwd1he4gHjAؕj+_zЈ[Oo2hovdrMZ"/%b& \S2Zee~uCvMvUtb`]l쎊2@Te~X.%gb%j뛤41JЖ8ڍyǣPxCm D hNT`ATU.2T?}W}ϙh-gDq;+Ѷ2X_6Z䉖9fW,x/NJ Yp{TUKva wj,opb =aIYf:e]-H._1JcDZx|v eA fBY%qdt9Y PJG1kC Ff h HgLs`wY+ MrƳTb?bK X4u/-3fWJ`E=(_W-?'!&*|ŰrmuSE~epҫwEXdxl$2Zm6KbvAWhWSL~ku\  Z6deM&M6hEq7"6"/A\5'X꺾U3 ;s2gO XECVb 8+Qe~jqbZ}'XvG`Emo.?WM2 {wr+y$jx= R] +BZhdpO6t Za$`-U+V.Z1e!5E%$`nU^R# 6jC 2g`< 2kb1 T`da_,gss4h, -A[GX+ЂNٳ?RvHK-ZZ$V`bƊ+%`Wq`Wwg< 9tc,v^ @cfTzҫX?~jvD:yy ,n.͠ޑb2hbH nբKvz XuuUr3;CW&+`A]0/ʻn!Z z2`_~LX5a8څ/?SIp!NW @WdWQV+1mUG'"͆q,"EF -2~lv޽O4#x^Vg3Z0-VZC]˖jW;bvgPxIs+ښN=DbСvEcv5Hv%ꈃ@jEp`Qg?0NxA'X h-hjt-p`$t>Z Gstk*®eͬVp  }|vuO6yV\Ɩι9ݮ[:GgiV)_`hu ]N # %FaB;1bE n;*`Yֻ #u2ʏz{~ OS6[eЖmG~x˯3\>/^E+ g ׎t8-bZG89KdWDK\v57j76,W'5|d۹qÓNP~p8~kgfHWZj㹆։,J;2,}*LYEZU$joh(3sZD#>!dCe7ބip׾hת@xA^%FdQOEomJH b ~PQ5+g:򃞍Xޓrղ\ #7^DZ>"Z*B/`YX-HOuqlC-(&xĞ:%-TK :կ`|z|KٞoPokiijj˖.=v6]/SȸJD`D$]a-h9's_ l`)>}zf]@WsMD$42M:%+~>6D+|3җ؂dWqQb*8nL(K0,,?&451ECVi1 ArjBY 5=;;Sl M3/Jn$ X>nQ9@yy۾OlF6.A8߄\wne8 kK46μb{O[fɰ@8 ?ǵ?t Gr9# D[[ƅ,㳙+;ڃ@c^9Ei(-Y\!b kX}x$#|I ZZvJю ]r aF2,M9\r쁤O46 gWL`2!͓O?hI OEs՚V"+ÉZb" Lן5B+s@? W';?ܱ373L^M>EWץlpXؾ ɭh]|!$ R:[aIҮtWY^iଶR|n~rTvo2\eK߽4y٠qᥱ9h"`CZf}/5Yn2(|_@6玑2 $֮- v/ ZXI`(iة)#Mw?|,R*BlRG+ 2+Y< ,*ᩗ ֍v|b}Ѵ\pm33 <5ZRR >A@IĈ HKaaPQFYHZy򐫣C| qa#7o( ,ə3W&r!ɝt_Suw{iK rN![-P‹$Y\<^+gjC/FϜA"DIXo%u4`6ZS}A;VY)+h of6mZ;Q-)n,2 Bx!~A #ƣo!P$FRPRXlΠBܛH{>dӶhmnOz:y~#[auqKCUG7XT+t Iīe#W"WTG"FKa$׏>Nzg3lb R77VGg3|QY(%@‹Br ZRZsdۮ?V!VFdY5{k//{XbjwuU }ܚNr\,]K-H>PIh4/J)A)%(>Idl$V."!j]-" èՠXWo8prQVTA)݇n:?IA{{%X`dZ`u{K%]tAJ gQrXI3jTH+AX13XT$fRt-zV>S {zM+V[5vEVp # X`URxy%R+W#e/J0 MRgذ ŏ{JzVb]>D.%MsKH:\v."Wq\A,Cf׫7+Ѓ˕lLYQ*+t>p^>@ctوi{"k+ĬBzZdz},ʳ:O=RVffLMMЮBK1uGWư= Bl ]zY-֩xRDg$qEp}BC_9 OruAqc,7M< cǛIV5S-ZzEK!^P={;T9ţ,[ia5\{ nrcذy8 &ѺX֨\)i/? ASS Jlnbk5Pwa 2ؘݮv8v͙;L6$ Dq`~;1ȰR^r%_䊔M f[o5zCa*li*|`n~2MZnoˎ,Rb%Вa}FXrtY? 5>ifƧ~lC[8.~`Z $(UBSÉ AZp":SVs{ь10ƌ0Fg;R6(ew/lȮL'*}ζ^`<$De=2`o彼7ԉA{@Y܋ʔLc}{栞h lە|8@yE0кM7-^qn+^VsxiS ,P,l<^km$觞ٿъ5:(WFveԁz=m6O6^zzhAs Gn:rcuU=ZpiJ4x6O@ZusLe_3@^O[Vr18tzA*Vb0X`%OfbvwH4{vy_;y+K`9(^p M4Zb5Z+YXJbKȂvʩ|pܡF©guIK,vJJ&T=(HݓZ3@Mmï\zp቟߇szÓ'WV{CPEʢ&DPKc)ZB^B_znZ5`b4M&Ƃ ,ھq%2}ַ_z k.ꫯ Fzy"gHWρ]*\rLP};š,^7̌6 r]JQ)X{ f:Fq[>3z͕-ؗ~Wρ]Ab%SGhV,**PEABh∊gہv*bnL!PIQеNGJ@vk*p+Ξ޹oWg%+1 qX %B(Ҝ`A*!ɊӪ+zvIb(!v/V:Q`}_/I׬ֶB捭蓁G ?h.P,0HatAs"30bcCh(Qsrmkm 3ʱr(9ye^`e3^} |X=Zwp}Jcn G8( %䩊RpId(ZFHcEAN/~o: thOcd7w DP&85Sٵ|`і:+8E@dJQ+1YBMW 1![3)/N~=bV33qCòZ!nYpB4#"aEqhsٷ:8:# BeW-kvIkb4!n;m}A,'V5 .,$7_۬.K҂pu}b6M3 hq s %cclB \R<3č޺\Wml)#%V˞tUmb>c4.<~񛮷=@q Ą.4%83&_uY 9AyZϓ1F2uy`fi8ih3 Zk#Jl6qg#w]lDahQQxЗBt Ȳ,u`I#`ɴ#*9d_n]\t]:@ uݡQOp޵K5\khJ+ը:Q]ay#b&ހK42pdwԪz"wՙ]\+N%CX| Lz4(@pכ*j"8W[H6 ^tj/Pܘ ł{ Ǜ^%*VnfJ; 3&BHtT1@h'gY:e 4h5A&H˗۵h+i/^en-8*Yڽ앟8^@p>, XU FcY?@doɦg]}jY75i7+"43 H̔>;<]uJVdRԉ 55BHyl*& rFvl} ҊD$s᫳7әD̴OP{Y7_Omp"rn(Zxqjp.=-1a*@@G @k,ؘܜçGޱe8Y|w֋Kzڇ NbS"2PR2D5랡D™jLS!'aJb{~M_-r8Gqihn Χʹk=ܢU?1F) AL$?X:p.)W>;)"ÕV1 YPbtϽ mzyvTlN?|?o!0ETǹВ ㌋ ¤~I $ɕP& ad#=_|Z#kݣvy#Ç1;T';ʈk ć0/}:Rl2tZ&dZ-p"G:`]tcE޻(Vl WAb ŔB'l=[k9cB!HY&]dc:^n_.$ 5$4s1m5X*LofF$ˠ }YHtY}H@u8}qoϜ.n_4S4i9J %1Aabc_i4oʱ[ad]dHՃOmw,Y]T] v!wTb=2`3AaTcXTB,Q I/F/XȐC]ИD &/>]V\R0)E&^AdHHa j)VCXܝ`lb 5@!{fzKe$҅p?`bM!j LM p#\r/6~Xڎٽo5'Oh.KV|dIcffvS6Ɇ6I 7"uukoZ=:{ Ԙ߸iG{ [TPL>Of1ogdċ(o4X-i[ֱc91w7,'U*XPزXrڋ dIb1CalP2Cf`1^Xh"ZVl`u++t7R^t Z HveߗD UΛV c C2t ^,հ^其e1u%Qq#2^yK~e1?3VX{RZ]#¸+aag'HjXVɏ0myv*$@˰/L3zx[٠waYp\n -,0p1C;' ի"!RBd ?Ww] fҠ!/qmJ‚ ,r܊ՖI8J'aXv=z> (7!W]$6zʝjP7Wm%  } /ٲLi?67#ae5#d)XLr+âϯl+fCmuq-,`=ƈIhtޙfZ4VaJxC?MAbvYg)m-,"F,Y1ʂ!iVma턗J8\4%}aY D`\,MfthVukedhLNeY<9kipke˜8?7|HG{Ye1 FEN卝}m %sNL,Ap@-ݱ䌪 ˕)w;5Sx;%)Rx4 ˑ RZ(bQj;5SmA)<~785ńXo tdۑv8cU` sj-]mm m,aUX۩ZX~4du44,:`E&m~}4v24-.Ya &XAmIX+5ai³k|5WXax^BH)(-T ~o8 @^gƢt5\Sp Nuxvl-H$g>i5I Kyڟg.[Z?!W[l UOZX8Ңf6Y!-l:'uM)q[=/p ճ\Uqk밼a]qB2+yimS\%:V4.h )oEゾ*sE%,-,J^\I.ջ< :W4GEdRW7?͈}7@#V%q %@z :La< Ԭ]dmd1=l,Fj0u~m2Nw5̚{2sY28J46ąXŸi3aq4%!S%frp5#U^6YHw5_Rm/0oLSjPS}x?)R]  CߡS@oOy,66\И.:"@v$7"g"  6^3IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_7_spi_1v8.png000066400000000000000000000451111520775651600223470ustar00rootroot00000000000000PNG  IHDR,)nPLTE=@V?/ 3U6! 3 3 3|V 3 3 3nĭ 3b~]c|ywmvN 3Um@4uE_2zmgY 3qn]wl` 3j}g{pO9/WF? 3mWPF̭j2s<ȿ>uDXc 3a^Z fZVSj]G|wDPQ}aˣxso"{ojcnKUVJ "$l Xe8mqR]^tnYde$'*wjd-13AC 7=r@JIM^!KIt* AuAuy)XW.5**dͻre^@?Ln{xûnxd%Pdrm$S+?;9;<0fh)^a^'O\m^U]fWL4 !w2޲OTaPC´HE;ʲºyjE7).N(})$ľY`S@UI>璠V32%z-uW>df`42":#ƹ$v?8I4G({eReH3S}UqbQ̰̿wt:iG-\,POuh3VAم:mxf?bZik\p2WmNXIjpQ|H3V2ɇsӱĭXi8}IcItRNS޼hBqm̐EUf/MqW߰KwɨFIDATx1n0DeA`%@0R>C E4-O3KoEpyJ"x"\#Sc#X9RݝpMDX1ej>s)ηdLLzMu|5xQ:E}hhnkS%3uW e3ї0^P]VWUJ_FW]hhԩиv@N}lxV@- UԈy5!\һ9Arƪz .%kB=-k+D *@RUv-`q[#6B pSmzJ4R\YuO5v3Q Fke1"9k^F5Q ]B^r.+?yh-dJ._uH=mٰkT\z&x,RG"g HΕ웯O@o3d( !) CvI,B*&H?!gQ N՝nz풑]ŵf{?Omiٰvpw,u-)ՀA'V`5 )X (wB>,1C\VѢ lѴPR#hYe6IHFVVl+wXFBcX؂e,'u*Gav`0*th`CVxj e[2t ,1d+X1ObEf%ݎM6LQsVx|Y'z1GFY6 ~ IMlD~ǰBnˋ< DJ!?}(V4ppH::p"@%P>l-:]}}/9״++triȹnwz\OV3ۿ[hUzݠ Aw"^*qgjCX"uH_lΤڰlMED!TjYB,jziևKH"3zEelZ!?73tӣk3^};]o/Q ͛V][n|yQAWYޞׯ^?7+u5G+m+~O+t퍍pd鈰_. s-t]׳N~A߻ןw޳To 3 WQXϺ(kc]8V'2b /:]rvm˛njF[zpy6ޱi] |/m)&4G-Z=hA Vpy^; QW=xCD<o uw5G|#>5P,l\7^۱Auك'm]b\F@TdbD+zJ{2ޗHL$b_6Ş=x.IAeA.0[ـyeY۞HV__ʊ򶦢GrBT\ eFΚBEs|cҺ>z~^+H&\s&@'HZ6uo{žDT,XB5"xm}}XVE !QUƙB34/|}rۯo=MM\q$%X\Z+U4e-9(VfM"4zR8b-( Lx#-?Ӂv#Z037m]{b1J:nvZ\V ¨$,5zaLZσܴ:͒"jVt AKx)28qOݙ^xǟwl0zSy:>fKKfN*N <xj$5j2L&Zm>LPrT\a{O`DTD/SP)W(bh"YQ1E]ѢlX`Ωؘ>ORG.%Mih.F*jK82sKz. I Vٗ#SЉJ֔lVTQ$xܤd (m[Zv6*~*Sp"7P^6"ߚr|*N@ȧ̔tqfTUj_mx Nr"bX-gc{Jt1("dTKxWP].oJϾS8y 8*;}k^N 6Tp|!&U.p X<ږ#"eV)g?@˂T5`4|iueX=uH-&2Y JE1xS'Ba`%ĩɩZa Ipt6(dT4QupՠtJRڞ-tuZN]9[vjWVjK.,S Ћ}nP٩$z')>>4s8 3Q[ռ4XݩV˂Ui:PWi47,e!=?WoGNl4d>Xk{.^U*L/ܩ[b1I2fT&Ttg 3dRI+c=|`:|# -XR};(O,{v8L -eVmj#v0P(`gӢ7)j â*|-?XCi!eoB "*hAC;yv.\jݱL]zB1]ZvW-뜸nP^_#X iG |k1{AU 'ҕNW߾whxxR;Ua4;Mt!|V]%V|~pgǟٍ غ~5+`pqv=>ZCRBt̃b q/#||>ndَj=ݙA3+ !CӸF VЎv1M8<ۤ: gGb 2IWu* NC*D"3Zmf0211ٷ=tGo^?}1{N-50U*agz6Փ(RٞR Tʨ=>XO k祣J.D RUUPV:jЮ]_gZ4 h|J 2m_UKdƒga#RibHa wcmBݹUq\__^`k,j4^񞘴GYS9vѾ^p-Hme j0eXFE˜l-B¼;P4Y>׳]~W-_1(mc*?AoѢmAߧP`O@Fm~ -KK% `3FKSΪVKaZLG_h3}󝘑 % OMǚɯ+Jr ڰU tu[Ȱ Y0L3>/;+3꛺{ 0k{1"oBeA'Jv'kl xwU *("-Kw=W^Uӭ FQVi-\$4yD]ʥJs6J0݀SڈjNrIۗN tbg'fT|o16ti(›.=xgg q,%&W@'loSFY`uu]砷e5R Urt }`5uȿV,ɽX4=_$(@VB(܃P0 ̨MM * NLgLe//EO`^exQFU&%PFs{e~hP2ϵ*n c> AWxʨ)6;sj966JO t[3%਷fޢjdQ%QHxήJ"/ AfonIj8HPZL4flXPK(KCzK>|KMww0Vft 0@2VZMY zEkZĈ4ZR"fY8BE=cdVw6V{\2@V+ BL(^xCIĢX`Idu uH/M[ٛeCPr|*`lcj'4vm|%ً!C"PcXZ&h.q:T`ԩ-z "Ux2;rhlcs`$ז]ၞF) hY Ŋ4q"Ϫ:ZL!!V]cB6:{|ʍ*omT j3\ Ml9M]՝"ii:^oʰ>J`bH59/V;n:b<2BcfbJfB@Hmјa(`⩤XkcPTw [ yfRYZ vUN5{ {M\l?8YY)CNe$sHd-ﺊV]2Im3i3XYtVCҍG7'ci+W7^\j//$3 C݀h3OAf7P3Kt3j.rPmWaMLJ@yxѪN=beYޥU%'F}l) 80qP&N6d;8>09]=Xn!](ҏխ: MZϫ+ف=%"픖'J2g#<ȗIKcñ͞@k?)Smقbtog]:朎M%w[sZ၃N  }TztL# {Y-+jĪ篼N%w8_) 泋g*^j%ijxX`UrXڹZbB)ķV{ ]+L.5* f$phht8A+w|Cӻ&jfgH%Y*IY^[\G Swb,Dbgґ &Xtxm{2:j0샴[H#p" '{T rٙy _ikʊlwhѼh2=A c`x G_.%WIHu+=,9}f^ %}j C}6 _}h2M. sӕE"аs*^6y<]ǜXӉKm2ʴǫ! )*{xdd%Y9/;hok/Rd^\l"EĽ}Wp[*t7FT),Ehp6tBQN2e Aj?v8,k@zXìPo2@s'uŹŎNz+~?Oe+ev.Zrɛ}JMRlƍX`cC ,MbEZ:9)4x] 1H S_{nv~qq))ꔅ*8TᴍZەô{qcbynqj~ A%fWHȃq/-cC/Kd`i"p0;! ~ SG~rZ\)v}6:RRH糔ȃjkdȀٽc@~e&V+`;h{rs)ao#CAg5n&Y) Zi ^9~鴒%-R9=UX]ݙt olT^f 2q hT$ J "Usb&AxH:8CޏRljѤ3+֎;~hIQH==i܀;ֈ3jвw  !4٘Ȟ Z-ee &7I[!P0X=sSVlzLJe㿟@nNlx1e&ibРY3"eDi-@M%N b p^8־g>1f  Pp lpú@JS"9xj&yW%ֲ2d%,xRi{O8F9{1^t>o6"..ݷ ERpQt̄ B Py=A#9?`9A;mQ*:5qjH?"K<QE}&cu)mETC)aRLGSqe8}%%j/,/eq^er,/?s骑Zl!Tly~nL:2mܹȜįoWNGjū"?5BvʢomPZ'G(~AcZZKkPb#a|Î7N~I.?o_8rg?[?L^N8? q5Қ4Vm+6%kCPZ%:Z(m2qJa)rbcNT_ ܓ:-g%쯾=*1x<|2w FE+2eCgL{FBv(ʲ2!i˵[9_rϿXKE8ώ;K1gi|"xz  Of VȕHSmPc"r.PAC:[{׿OrF gw GG?WRZ[:V->x?tX?PO[ y$u?9(J2;]ؠHHF7&FTLA)-s[;mt@!5;}ao[ۡcK)"ТTE1@56Ȭ}=s)_wCle @*,ǣ0W ef86mO⮄T,NJ N&5I4n :j1`57#J%ox!vX0Ơ+Y~~q-O?o5SX~80N֎*azB6|ZtFޙ%uf0X+tmb`'rN*xYK7HK,,L5$Gq&h>;ؾ8'ƖWʇi Bqx!!3CWEbݒbҼuXyҘx j%GO%GLoh]+]a@o\{1c獘E<ۺ΄k'8rZo^=(y^z]~B.G^CxwX&Y͍+W'dIU㇕oҎ߯ގ9[ȹ93Puߎ&]<$q'563{ϓg޺u..52-),Ee獴6L6*VW|[JAei?SVZW(m|DzUȓjb`_C:>*96)ņH=TUut!dEo!zu>>>N42x#B~<+_ 򜕤i?6 XC-@맟>} 抰ш5#ce#PY*SZBևmV7vډ Q+[|A$RWmq:b$@nOrQqm'g }&Xʖ7JـN݄'v99 %ĐI-yhS P j˗0~Un#ƝLӚi徭 U#Qj=5ΌCJ/N\keMn7l0cFsW$-u:ȥjQufqε85{} X1V:W2+ 9Fq\j[qBQuXkBKV4!gzVQ9}Q#<ɫ!|sN/V2 )v7sN{Z+7X:W=j;#1̧ Q-{4l _]Dta)IֲꥯjJdnS 2ݩ>Z¯]KkV+$PPZ(mW7ݨ^]zu DґRjH ROc A1.5a=.FV^};4uJq(JީC|nS[/׾k#1V:j>Uj5xNwSʭ5W~8iM߾jN (XXkI%@R/!@lBH6F5R]ojOgg˛NV~]>:- [pƃP1+([P,=gRv.@%&?8kK3SP"p(f7w~ |]1kz7:հKWl0(qH)ℒS& oE&wwg< F<|WOlz{b3vL}ëLKY) R+Gkuaw4&8E) t x'ď*D"Q#J?ؠ. 3Z[ ^C'߸uY?|Oφ]rj;>ZV/PJAp C$)l!c#8CNQA %qğNjަcmvo6~P)/|=W]JrGګ[Yp1A6A0K1) &/-55)hb PzSD'd6p@|=/U;؍DxD3nQ+EX-hVA+=y.ӵJmƟnT{@An.c8xwH 8QE̳γ~~GADٖ)4*i/ -h|f>K틮u\NvA{HٵہNi&7. $<^EQ<^>:Z_ تM(J!P-D5hY/v@uw.,x4:$Ė<{Oowdn=*ӝsy4we9t㠞T5"* lcc(?vUׇsϏYNu>(UVy6Vvv֋zU6+F p  a8QM#u؂B.Eѽ/~ j?LNQ zP/",WׅEۋB VJRPM(D|$ۦh "*V{Z?>` _og&0aU[M۶nOzޗnq s6rؠǛ2;]ѱOJ!mC9TJ0=7}_pnIAKG. u?W>մ'zpb\<嵅XQ$I;jF?"SC@eRQW kA IX-ټxϓv4{odb/vwgUj:RжBF>} xho OaK}?¸r͐ iO'ӓݷ΁='8=껛K<=28m+,$]uaƆST1ᰝR.t)L!T5|PX=6f^l߾ŏo?g7{vx`Q5+j W'Qc#3cuy5U00U6>BJ_5NކϼtA{\g:["uF.Ydw/rwUs\Xq bm18.~zNJR"иTfBHZB A= ౑G鮻7ʹgCwjKz^.cmΝU]iE3"8j!u#BʉeQf@r._3 uLE(7sn9satPtmصuog߉%uGd/*Bs&ܶ90)hh%~@{ef?0}C`Zwm疷TDlsU]B6:H> ZF-y:%ufYܹQ$O@B\)əUS&-:Cjf_,28izBdEe lHC41 h|Rh~D|H@)8k"fܥj*҈ wOJĻ7r}u篺"vi"91b3|OjBsCyK2F`ςU*.k`ud716it"[eP١2 6-cJoɸ+Mt" =}8u mt3a;鈂慩Z zbo5ݗK_TCZ@yD|Ϥd _$L>F/$*@,bOVj!p| 5O_ VLDa(l[|!ZqKRgHJczqIݜ(".Xm1~D*X=_PCoS,\rKr\C8(d!ܴX#13:L0oE 3#W8u;<*$"ej*uc\Cn1<~;_a運I̕kF@q[X{-zn@ЃU}u7, E0n8! ZyM`P*ԎL!(N4VXJ"koyVվCF8RjC\'FBB!_3=Y࣒֬X]ӧ@znX?[ƭ?zDB+tR/VIbe0VLoOB3m |tEOd-np`٪rlTC)C#  Vga`߼.`mvY;Dš jhS8wQs#PMjG}]C#bڊG7Zm+e P'oi?/XJ|+8)B@귲zrP"QmXWIbDڳmqo`!a .Zb`(b72{զlS{,i= iwObi.5y'Χ5j $|=@/+xҡ%da!JoՋz bi.*zrA{ykaaeUtM_ygfT QAi`3?~5EEdKa#݇@u{lΛ#i:Z+$֙2o_"YA,j#Z$ Xm|> og9Y ZG*% \bM<ؽEZB%k+ٲ VqP1DYa7aM~X})C[ېvs*NpI-%bLJ Xs |^!CjN8JRJc<ǔ'p >TӍƛAt[7~iVH)j}@p}AIBLR[[aqJϖ$k a%G_C2O NQ=G,'X]A*60\bX$ӗ$TaYEږd9*R)2kt3gwDd4] 0\a1Iir~w))U RT,D!%C,q]+ {~93|)guXr ^Mrc@: QO`)2=LJwo\ W͡vOV1=YmemYLI!1MӲBGwn:?B0T1 pM5t,̸- shm`8 $6(n+M~3M7$YTdx\vww?9__sFRYQ,s9 _?W}d"==h::6|џ:S֔58J暴7D 䍩9٬.{SNN~Lb X67lp,o9,2Cą̨;*z[r;Ն)K"vY-Sm]XQVeNN`Ho2Ybδ,}J}'2%D.LЊT2*6(>%KK|3+&90[J$nIJD&G6qdu{/΢cNYqzZL #s՛/οNe &58EWGoW%hJuH!K$]VHZq%YJՆGV\HVTs? wYG\NF Df CI$uYb,Tg)R.!k)!;J(I!I=)ff/&?ʹ H'ϱ)kLY3y]5L&d2y ]c¦IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_7_spi_2v5.png000066400000000000000000000454261520775651600223560ustar00rootroot00000000000000PNG  IHDR,)nPLTET6"**# 3 3j 3 3Y[ 3ëS 3x4j|O,d9v 3h}ar  3 3z 3 3xvctoj[~kyn_ 3ikhYoO:/WE=SH>ӳ6u>MV 3aZ_eR\jW]ɐXzyuDNPaˁupnJ #%IUV 38"#'* +/S[]yJf r$}oi>@_dovibU,/0Wcdpe]?IFR`aL>i6kodUKy̏~rwoi R\hl^T(XYFIP@`fe[B0mwNI=)=9p+^`7>@* o{xvg;GBD{~CH u484´/eg8aA_CȚMSbCo199s#;0Eoɷ|^d"/a.UjV_-ORE6% ]!~jv.n]*}v7}DD{T]yٗPinΘ)Կi0|lWٶf3{5))ʛ>i/Ѕ,#g[Wy_[]%33ՅAfk&EM d#@qu#j܄ vl6#Z3Ñ@v+b(Kz^ =nwS>Ŭe]&{ZڨZ^ղKWEV6{3xJ@V.'j C ]mvf0 `(11c+"K ԥS窽X= R+@,LpOALeoS_9eu[V h;t׫|P!AOw0du 4$PA,ќtDeAoY2MI2,(+S)*$$t|U4,F-x0$Y ib#pBB(:`s|k!eFv朗5 ւe` SZk;"Yj:W|"Q>6l׮48q(V Qe Vpi[(3+Urϰn%Z8ZW$*Жh`KKʚ29 ni%PF9<Xt:>Y]!T+fex]I768%`BC9Zش́w]gŽ>.%g@eQ8COdaκta(FB1t:TZ+>ɷ׮WxVTz4ϯnk:ʅCٞwf?Mu/V/^=n[znttQm{">{mGz*Ni[v8y]Qho}fX>ܳ-ݎ\&_zwp2TU~3}5 _[k\voRf[UZxVx VWkbw8HQ X%M{owhmݹڀ|F2bU؆CPm?i`pQ\<9~|BКr 9Bp {U,~䶅M50WthX;op0E 9.[(UfΥu~# jf4ep. y^{W'9MXO}w( )II" }ԩ^_ҺE](De&` 1bRh2Bj3j8Zll;vh }ZT!PYuYX!&!ⓖI2`|HS9U4fRP2OMSKfWߝ߃A$sI+iYٱp\(h jL,=3EՠB:&. 3A%h%t240-U5$E2LYSx*7a Jbv7\h[WŀlHv˲*c!ʂҫ/LB"x*ԹZ2uu{TnGXp+]MWU.4"(WDŹy+S-\MS}FXr@^Maxymm}~)lML& LQ$E  T Xe+05n7,Z|&QQf%i'pz(,:[V(;_H$2\ =MĖە^voεdgD=3Wʁ?!)dUR."`5T5vղ 4$=]9<f3 w3DTDADC)*cjSjXWfZP"F\SN-ws* 5a[zsQ#%!¨J ѳr,\9;-_`V ^yQ]zJ6MLf 3V:k.,>b]53YfU _Px#KA#Q03o!@4œ59 [p(t,SO-hJs8<zkB xז gQD*'F*v񙩱 Z' U#L8EqɲMƔVznU߭ȒK$Nh1 kFЬ*%X3R"Ae X (=׵hW`d̹kc٬UИl0rNYTI֐äDR\&(QSn Heۿ.o[AʐZEpnm.,[eTPZQ85ѵ Za " ItimI(R[q#cSa/p(F*k%9a|&%ш ZU;H%T ?+`A$$]:Xg˵X@l(wR#lDjBWMXjy  Z;+X$ y4wl-"$4ߙj^2hT. ssu̎X _UEGE) I ?WtY;TW(8++p@ fyjD \Pk(Xh)N=] 759+ VT+79p$A3N*)W 4ݠk CkS!>͉$kt`"<)B16+(A#H3_:?c^+LMjJe5i)f2K;}P~t~G__`w-ͱ(O `>9v |䣙cOĖff&ubhĒ˯Vf!MMU)C:,}O-  VñX=1hET6LD>b=lg}WI+gR1BKXMG'ǟ;$s׾=Ht!妯oՕĕMV6ٿRIF 5A%[p4|KsXBw1RpWGCЉKGgKg7Zepd * DOA Xњ%@ M!9\E4gxtjaa ?~ݞo|pVkkKjgc58t@:V_03̊ Zl*ԙx<)X''CϞ޹эZԝO[uǷF 1&/,1n$FmIuGm=TsN4ڢ1Q[Bi]%*tNiiIn(1xKNxJ/KFO~?FjR QvQcz.]PZyjCC"6YS=-vWeO^fvA q(i+pYFNk?f759֭PZ#Q.v<Ũj+TxhR)nVgM> $zd_f P'9hk4tUu,^{ ˪(8bYhR *trMmjb&_7876U1mV*D L.O+_/AjY5Ijpkdj{*Ҫ,J2]u^+(ݱ1B67(W[EXUGmI1O)XU{fuVb` z{GڕYYN< *EGL3D|Lx\Sfϓ>m>ra4M_GZDX0 Qv]3G7iZ)ELt+'IH";81'daPa߁*5bs֦CF$_7StY7w쑔mn (;%twNâLt+7ʋGWclypq'"s@nUS"Д6GF*)ТTr[bLajL|Ef]СWFlp djYt}rLGh1C&au4BNQA))\G4hM#!{Vc!_tԜ<6_- rNJtϖ.dΝ }xΏEC{nԡB͠jvsS+WB 78`U(&W S1s9<Eo[s|i~t {b;1ZѻTI 2Y]VF#)D۟psB>9n&#öU 2酡V?x֎x |'܊-E6=K>Sp[\X`+B-H:=Gų4巰R9eDԐJq˨a$,~G֭6sev%wsFc  d'0gKS HR) n8yf! g\cYcIj0TDMy: 7d%=vS^a%į auk ,BVz `7 Wnva$jUQCLDFhulmowitƣC+Ҫ(WnS*NE7ޥXvg{I"2XiYj:: +C5`؇٬$ڮM咸sw­J0'-lot2Y*%#O[$tHKz[T<MӚ 7zAkgpTm6"cѨ@ Q-}- V7ܹ),!'5< O8jIZ{*c g< T Zӣ]ˆ;ҡ\ސkbUm(f r}ȡ`yg]f+$q{U 2D 8bp uI8ܶy ՃBɍ4#y\m'wƞs)gU@u VD7q.m戴sْI:1"H{ b,&ةrɌX6 aџ%`"S.DZ*OKxg GUޱd|}g. jjFf vH˕SJ)V%@L(VY K,v FX >^f3],_菍UU4gv:#îc Fj'pp,^q=Zi/{PMrQX] p0x>TP :676 1=| cfxJ]X:򰜇["+#*Q1r3X;撧o\s7@.-r`5H# tDP𬊜`r– f{c:h s>Lxtʞ+0}MxQ+țW.=RKpU? cC Uphb6DSnT VP|zA9©P1(YDZ0H{oS/~P&DD#eC|ũ}&5:8:8Ŵm~vXA.+[f#QfR;8L K0-ZmvQL T ^Osk_L WkoY"9ôK3&?"7.ªwfe#ūۄXuPU#͸yDcëq4D㍭VJ m=d )}JZGW]:N?VDj4KM)eYV44f?ɾfy3qZ[o[['o8!ڬD,o۾b, c‹v4x&f5Y~s{ /"QUP 'uh8Ipxނwcg64x0›Xchmk~DZiv~߾?Sgjf7BqlF{7riPwBA Wv`~3PJ6γ8^g7_35bOxݹprmmmd}?ٗ & <\m.ANdG:w ȍ| y+"zEui*YPIęD|mĭ ~%n꣏>Lz\kҠf_O|RkKS1Z%է0^݋'ϔgH=Zd(DW;zqá0w14:+p1)A'fq&N'~=FÈ 51 RRd55 {ȄVy̮5r>=<},DzJ"6͝Z BNP%ZIъ>wΆ!bFo%=o`/}:/'dg 'p_f0̓vf ~,nQp \I$I T@nyN~7h~#=k[x~|Z8u"'t5`i>%?)co9><ױfkI !( @j_TS*վqq|tƐhŊ* Hevv~v *Z^.w! RnD u S>.7,v^p&π՞]r3="VȆ䥾%cex}>Ah!TLUdl@(|eQlGf_uy1v`/!J;A:%+uKn:B4 /Mw-OO~koLHd eᰩTtQA+[83RXX[cPVmHd1u\s;\F" X&~N) {>^$R[b_Z҇^~CGJzg?fXt9qhD\ H<\ n3j#t.23@Mˇ-iЍygwJ! b?;VSGt*fSJ&ׂ[+zָL  ΟlUo(BJP78!#ȿS" ҏ?e1۹0'mߢkaA9{^5_TJlSв2^_H3=eUAJP8Yl.=jX#=`iuQi +h4lUGw[U$?NEϜez/2Ob:oSMg TjT .U`)9JkG(D[]U'+$1@=6jPX+/ f#ZQ~(?1@^0D}W*p+Q +mЫέؒ\\Dxm~gD'@) 啞SʞeK!|O g4+KȘO9].xl Gt0h & 2x`oz^qAcq6KvTgQPJ{;yus+?]ݥ0'B>^a~{\q%/׬w4]u|qLZ8wuGu0+"^- |/1|dAt_}4^*奼/VN. {{;ӥSK3͡M[8@x/ QۚR3- 46_i*pS5<3pD^/A9~Rx)*-J4\`TC͢Q^ t)e,;)\@YK) mjjjꛙoF4w|F"U ܆_FB{ǥS hZ 4j@O@uƭ^ 0:SM*=(F+7.-WӺbxj@cr3 CĐ+x.iHcJ|.-:saVF}&L!wYvTyE D #9 Mu+HhA#_ ߙϾr8I*GMrY$_߾P ?hbbrZ7YMM0p~k ę`7n`qTR| Ȱʪ[vռ9Vϣ:Vina{v=4gк䖍DEm S/_ˍ`aʅ `ե8X9~R V~W\?l[EѮX@ˣbSfQW^^}r"5 ƎTj|:6w[(A . 9q UʓQnԨnz.+l0&ޕםqZ,:on:c>>͟nܺwЬD"RU)̜_Pf#VY "̘=ʡNTx>a|<8+sQ77byA9M?6AH 6T:gK( =$"+ͥ;w6szϦW{5Y,N u5>9͇=,:[!%D69/ƋzcZL > $bc9QF5eMB0C۪]vEZ0,TMQ^C!%vG1 s87q/o$ƾXR# %T {Oۯi 4-TY~ES&,-BO3l&uh*sѷ#-ł^dY~iGdJ=>f޲s"AOзBuB۪CuDlP)cAh|*+C>@`re8"!荙?mJ^4֏󮆮֓I[̠$f-QXH z3nJrf#9-J,g|֕mxga}}R.X2=#F.хҙ<ҚiY:+Ji-Ӳ8Dae+5nѬi1}+7qpQNMSᚱYltͭ_(?Y=_Vk&T9MLLjHWgsG dNMLO>Y&[84 4R{ ikzr)o-ȥsewzV4kZ*,K$&&'J/4;ĝB'?BuPi84OwR`X/JdwVLMnK6AO ȶthny˅,ߥ`#Qĝ!eѽ~NF Q֥ ~&o?T4۵ix Ыz{1?4Ŕ1%Y9βE%R,n3#E-^OFL[Q:K/&h؄LW ^8x[`AEQAУ⡔=aDwd eX3M1!&h0 ieS$KB4%le)6-mvt*K7ۇ~0KiDĉPgw+͚@˚MD RٕҮk|s?6^lNݮMV#ߞR0 ѐ50 rh9u |\OJuD"W,䆣eW9eҮ^l\90Ҧ4QG214.A9**څKw혩qef5-ѝ8ѹ9% Cp6;U.jW{怺0)9`<I HVU22Š",Ŕ~<*͚`N5hO[{`,s EθbP\ml<GPv`3(ȠQC,`N0̺c2i@lv#9U=[}l.6z8kw`||c@Hb I.Rt lf3ֱ3k3>3uznAԘ]hL\z >-mI/lw8Q{qՍ W^cPD 1@n2f~l;= M͡[`N۟4MŻ/~_^^s~kxqVcY †,c@9DO4M$2jG`$*WB p`eW=oZUW}nwn'P (MF!3,=}- rBB"xUiD'/JvmV*s kfKިRYeuo=W,`bJcT<ėt"CՄ6QB/ă ?x҃ x]î"nb%%"h*]M)&b Ѫ(VbS+O=Y!Ch }|}{;;!o^~_D|4Q~~YgՖG5=9K b¢Mj~|z&962 т) Jc `PQp@  8:hxUr3(r[c;:\쳡ԇt 9(U&+#*G5]נ) p0Dz`<]Q!d(4**sՓ۷>bt#{÷׍R6l6tv> 32*JR(YWL~: BªC=]hࠇƍ`M[MCOwI4k+=x rn´8 j׺o|T>MU&-%'U 3 ⊆PMO,E}3M?|T*vR>̦C/nU @2asJW/ܘ|7%p cU/HI)16 F `}rɟwnl ,xs'祫Z ͶJ !G&+SXb&ș*Ӄ2-мHG"in>u:vUL?xtF2*ϊ Żk :frMBPI'' REaBJ4Fҵ0 g0[ArBz勏]ךI#C|[V'yKn>u L6맦FmBi2!NUTӥr r7 p8鑘FJzf޼3ZN?̶k9=|mjaC o'Zue$$PU0"L㑜ũBlshpZp .+Q葈.,CӹovE_MI'vR>5q=~[]Rmp:3 TT 1$PrV[sz=B@r8s$[%FiJ剁x5mCC Y3@6`ڂ+!@C/(#Ƒ'@ #i9*!qRl`qkJ~hho_w_q۠L8".0Fk1x+ULQԎ[[MDE"$8!G5N7h7}?*b4ƞfSoj ʵ愐j$0LS5(DV:$K@S8ﮌY GN*\_ufЉ fpVYR1Ϝt{RA1\x|`.)BH{nPwjN73N-h`v+<[miJ'*LFVIWkxF $d 럌Oe H±2dMKQ7轻?XVRabTI`2CJPP? oy:mY~-Xgs&i F4\Sdq;) *y!7m0zm7wKǏqL3֥`]`aӚDIXm1&e(r4`Eܕ]M#HMhԍ9=ج8x mwrw&] N_~kXضb %$\S$(oRw$CnPY< :t1g?v3mpf:ھjf,ȋt[U arRF/W\E՝L2cQxQ u U<ՌշcgߴW;wpM!X3T@ᕋ7]~PDհu p.c,F ݋:`09c8C !.(pŶСzCW{/Ɋ"M1-^bz ޾z]YNh;ۇ+g #c׾vʴ䝧kZOH/:+7P0&=Pm`]Hyjyf_;IoT#^̊{<|7t_[d6V% 7roW0h2T=dSd7iˇq|F!MK/bKȪ\hXͶd bO.pemYJa):" tQ^X}:A|Ak6@B̅<-!̳- KDYE[H{RQfF(T5h0M6 xwVإ-P9=B5+if/,(|$ Ђj)TBa{iyk/!ripXͥN d]L2 7@z)9̷6aTwQ 'ݗyߐ\%p93CX,msSa1}(z0a/HRѦW >gպp]jk_ԇ q]NUhig>˕I⠙q!\}_Wg]oԷVۈdŎ9LFsY;a$A#k+~#5Qz %ym6vvm@ PueQ($%ŕO0ej#v˿hf#1Mɵřrn &v^SniWuu?Fp]]WE_^e]!=&!Zp04QH$ts4 f8HP]V;pd %(ytg|TVLaObLlJNj:ZUeWY@"5aT$I.Kn9S0Qb&}EoGF+ΒU"V5!ol{XǷˆkKy-VW&.L]SߌU#HAسH-[H\Q>^ kO9RcBlaYM'Y[#e.rUϑɪ>@"d`$N0w$KMYqў欈%h5i%atBI8:1I,xQ LމIBIL4q< p!LC!k/D<ȧڇ`0 g;}غC'IENDB`imsprog-1.8.5/IMSProg_programmer/img/v1_7_spi_3v3.png000066400000000000000000000450261520775651600223510ustar00rootroot00000000000000PNG  IHDR,)nPLTE 3V?0 3T5" 3VtVk 3 3 3 34[ɹ{ξ 3d 3ivMpj[ 3;X}bvP=4sol\ 3lulmqqa 3~tcXKB 3{|]MH;ϲ¼7sAj`Yv 3\c 3z_bYóZ jUEPQR^ˣupme Fzu`Ð ') 04 "&(J|pjdnxkeS]_~yZf q$?@KWX'Z\II@KI M=rvqf^w6kn*/2Yef BoyP^n_U 8A_`M@QD|~-cf"PReWL$LF=vZga'ޢ4 BN/}n466ufD8+%#x S)*>.Ln[K{جqVˏ딤ºޅuڦVۤF|IDATx엱j0E炛4P'tb? ?Eb-B^HjWԼRfF9y@tD% 89S#O𻿳01D[5,DH☹얾u])u{|ӥ’S{L,|a/E_Uv']erT'4Kddv]XU } uey ùe } $*0 8%iNHL@`iKZZImkPO$ Pcky}tkkqt,&&EWH`7+OqL ֥TM l[c-:wUd:P3(ǥآ6b+M<0g$~ޑܛXC cU"&tE ڎX;:AL6n- `K,Q%ە4WW\$bhぶ ϬvU'rUF]VR&/g3tW^|͑;w8KO@3}Um xĹmqjԤU;9SDىʽ+U%lfP{Xa\ZYeN~$|l0\gYuކQam^JAdRjY-w\ +8BHA!R4S4~%@eɿ`5(NBN۸2,?|;0(`\J_qE{![$/ŤRrEVY~5&=V8S˕!dxXj&J^в\cƐhTJb\1 rt㖣N?Z4ˌ-ZR\:4uqn\eE1ɨT:$K)E2mUqϰܨY2ƴ1jЭ`.$ƔRZ ߀MX@kzr񪋚8n&E%^PӀt׳y./q5/?G袇vؼL_Rfμ#B0^!1B]FpEWf8̞`IёPRZj>o`tW(kY/vƇbLvԷ_n?7grc|]镹ob{\~B:۷_|౯/9+~v-OԷ:{t5=t]v_tɟnz84QI?~`.WX֤u"~kW!ҹ)(_ I |-K?㺽Vh(0 {{h)C6`+6W=[PxRWhW 1(S1-2bȲ׹T4_ mQZW=V CQ4frS2;H}?(v|%+D6V4EE!WDx ia(  n+*piu5|7EuskpfSV* tP3y7lyk͍%L8@QAwdCKznmzxԷGW/?lBeneٲA "fiJE_Bf_;~ڸ fz[VuW@ʦTa-sSV4E&x}.V]x9͢x db%n4ʙ\2ZZJC粢a,@L&w@'i2HQJ"3Hr$곳LJ!<"&c&g*QO2ŋx7Җcq!'heD[Ucb*=8e!}5ænTEGu=?ɿ :xMXCa+u,VÅ$CJH0E N'$ipFQU\TH4۱m&WQ $;+[Bk5NϮDͪQdA ZƂlaMZhI=wHːAA;Ht$iUXٹdl N\+ 嬼DHv0W0$orp>;[N4<3%sV٩]ƙĠ^h<`}UUqD\6=y[)ˋ+9'd|W Mfq<̀*6ҝ*e+*Epbju+i,XR|m E%Z<DX&dՅ\\DB+pu^8)53kh<=V6q;ES^A.cDWdUV=tU^֖0|K eQLwU@;$VP`X4Ȝˆsc(ˇhlRî4j#hSUn0X kk^DZ,g)Zx4c.ƷL'bM}@(WdX:=<9w2\`(\`67s֚ai-k+re3gt .oS MTJVû';\Z+/DeaB dL]Z^ȟUBWtn 733:cn;)ԑW'հ{RȚ+|,l*M2Q; T{VɁ臽sNa/W8YLM=v=2UWKf逫嬌'K#12QtwM#fݺoO!:;U(W_'iw欄@bç:#>WA1 -/޺#7Ԟ(Wif|490'}OvlRB͹6UqDFWQƻF Ww;VN\ 2֥Һuv:51*nڲ^%ֱ7v+$xC^xzZ d<߮-_^FLx@r rP1ͦåɠVG7J$F p8W*$@-ig8WtNHw,U {nux> r?Q Oph۶7 r5lH)m4]]918AI&ò@܄0v)%aZXZʨjlý:ԪtwV|͟k`+lR$_ݡz!b䀻_'uF2ta︘N;4-KKN3PtR1 ru"1%; ; 2V%Th'_>}~ Z6[eiTcUڽ&SǙhl0/5k81عxVu2W+4{/|Tg~> NVCz54 kbw˲ lj Wsm6 d nEꋥ#bܭiHUXjL2yKץ?K?g1!}p`/z9:ycU-aq\%/zAkuyyS7viRjL<2 hJGER#*``1YQ6,O5Z*V*7!"W:r!k'wOh]UcjmA{[k6󬀙JJ9ϨYcmpSi;mLiu&.[V[qQeegK!Ծ'~NA qboI6+ip,%LߵGgNm-W6Vw+X,X)@(rndY[hz+1NUjg{CvM!ӸZZTWDe3fA8fݠE(E6*eXe]c~ݢ8^P@_=[̬6+4(I(BC:uכ {Դ JRe| <:m+NhMfų&TQ Ni/L|Ýb^~0@(;JGB,zg(sYOVB&*V^dojutMjl &pmh^t8hA#E8X sKm_ !kȇ@K-ZVxѼ55pp{*6pb9kǠ(HSPZeX?+u)mwd#\/_4Ky 7+X%ƹ,א5pbmEvjo,`( BY|w V?Αĥg.(R"$1G"?Y Lj̹B$̉j]jNYM^E ʞ!T0pdx5Nͬ7;4ҷ-/'Y^!DaYFGAo(Ar! HRTW`P6. od 7Uafqtusx879ҷ%e?h6uHI8s6 /_K_(*RYn0=(ohI<ٰ~Q` XA :jcQU!FU~&8:87 g#5EԱ +/^J0./v)qƷj /CmMZonm nLlB-ip<+Aکٝu`A9…_AP$!b]ѣE`nu5])αW#So @ZܧKMj5?MY^D * $Q8á_`u`RA! S`".PG~]) bkV};}V0*:< q*L{@E]_Zn,&:U:˝bHp+N=߮xtqـ>ߧv_rD%p,)W 5pxMS-~|LA( U/ĂR yőo~=jx/ѓ{_F{81VxϮِ FSU's6:Ԯ[M^iPTiUtᅗIb ]ATF髯2-c{&ʕ-7NU9"D[i C׭HΙ*N$+jݷ۵|#b#:}\dw~,qVy:kdQ^ee8U[Ԅ"g/B ڏRb~؋a(wf2pTZ!A5Rdv15! 2HDȱacrbq ]kWv9*+2:|E?͛("FZ-`Z{=N ð\^)boy֡ g8pa"6">DC 7F>,?< e @~+1܇19m%)Q\tw+2Pr(k,G%yR_XPTd{~ %%!v99;szb 4~| GѨh@#Ȩ+vDNC!s <ФXȼ=ÞC1?\5nߗ3Ξ8saOo~܂i;Lh1 |۰$UK9* Vz0*2pP38,lCQZow?Gv#>3.ٷ'_4[b~L}>JOXjBKV+ke:z>( s]QdrC+đ"s]];#ccc_3|WzOrߟ %>Fw6DQ,7NRaJ\ #=8M^M&Hv;>MzksO-ޟ_=V,f&)˞؆=*pd{rBKk6U!`#sBbzŁĠ_?3pZTny>ꦮOWC EL.J;JIsHX-^X4% kG7וPuu] %ˑkƹ8o4-6ߚn0zUM㾗y Nc%ݦF)w@Q4TR9 %II [E;nytwLMy9.>Nj RmY6lH5kp:^L7T}͚n+VPi/ r3XG+ޅ`}EQdlu-Q602RlqRٱV-rҭIBky(zٞSX|/~ "Zux?ͬ /@:?bŵUu~SO>2, n4׋.Ub=X@ĝq̬9h/( I.w@z@eX  ͱ[ܑ K1B+ ;yA6҆3mj>__W'I;c=6.p#`>}-X lHHVp$VהjKZ -S@|µLu`X&yoilF2t揞9?gq{չJ,C,#Jۍ6[ tgaXlmR(tUiȭNY=Lgh+Ӵe0z|TIe%Yeq|v|o|_g݄^i"o6byghe6U8Q*NXnVXX6+zGfzU FۅU: U"M#əhY+Vziʤ;,ӲIy>=2UU R]ѩRȨL$W+'F"+,/Ǧ0';ctwV"9e0ΕF'BesbmmDwY0,Y & 3?ShBQz++8;VS}a+n=hINZU J'8`YMn:S(8D"o/TX ر++p>/vJGzU0'`d8[F+"eY8T(ԅZ@Pff2zl9dE.|χ1ԋ %  ޵}hnm>~5⧴했Bf7m-8%;mҦvTy4]AqXXWSAwX֮d2~l(4eƔc}%\"˃;xdiN@I> Q J #-{a(aO}$fIJ+՝Ϟ;Wű[.{I NcWjﵑ* VP/">Hf0;lq@^!PL:50&2bw;avfBLҔM-+ݶ W=4|;?n*%o1??CۛR[b2kvq*OVȻQ >e0 ^4s«`biZ+XzR@jߍO/xndN=-Rq~υ7nNɭpewcJvU4 .͓а[F@ٓ&d@ML͜scQ:_BޣXVzx}FO*J Ӡ^hu85<3Yh`SȅcflvvBP"n4jCT]/Ͻ7ݓ.]&;{7 >lq #IYӬ)Ԓ[Xbkl;L4xm׀n`LK[R϶.&&1٪L {|LȈiAcK5 r)q-8e)t峱)/=*xzt3n&}p㽢hޭA^aff<7hu was 8p*g+(=XTIXzoamo {ص:pZPׯ);֌Ϲ`x` `< b)*Vqd4uL1yj:c&TZM3h\n&]61+5#cWg͑Z`5AbFTaAe,9q,VWaYER#nn`e;u`uI_X5Oq0* &i9X(peL-bْҜ #M{dnf`¿5JHnm)7ehmAye[[-4!F45jD^" 6-*` R,/M"^иB+Lׯ{{SSݔn_tZau3XRbXDDQc)b՛rA">D J (tlΓr4Τh֨ULsuD<2]5z=Po$cq)2 Cr,q.݅徬U/j O JN\r8L ~•_vSnӾzmzIX$U1Xi.YskG Ͽ usRc O8fkgMFSED N$"D_y?#H6fF&aE?6J˝C.Vb6te.p[+ǐLα jEEDժBXFDG, xw|TFSxyhlV7G:oQVZރ,/uOzK W0 UYMMaDxDx,' 6Dij|4G_l%ϳq5jsEHFu޽4Ǡ͕| !,#AIDD"/GxJL@3D!SGxX]+Os?}T CôZR[Ì+oAH2~Wdb "DDG?AbDDH 4 "#20)=\Vew[e\U eN;$B ¨dU_ZY ($MIDb!  `D_>7wDE.Х?r!"(v( "7a`kTmGBDVjil0hAOK-jQڪJx)%@!{=OPVÅ΅^-Ɗm+_og=.ÂJn(DSW̏OU9=Sr)2a+p YZPYqlšr6MWǶnW4~x}mцtI-mpA%Y"*suCNJR}sdba\LHum Ι354h:R n>znoΒ @R<\Sa_MurN|"}lnr丯la"La1+л`\(K ]քZ5v+j?]svF.CFrgt:rm'4\UJ+Bƙc(PQ뇶FX*uR).RoKafŽ}ߤucK`ѳ'+y*_U0s>2V=9nr"=(wNtZvKy5疲 [鶴kp-=O$UڡK9@_z_68wV D̛%gʡ NɄ%Q.@[(Өߖ mHd'Ŗbя ;I";w .D3-]\QIg&/|P)C"CICJř lRF|Ž]XC[O8sJj2].>dI!(C1H!J57L9+B^e%=X/72tݑtnhgwr4pA,2cT!ҥ13:#xg XJ:.WWI.@jJtc:ژK`ct* <ڞ~UђAHPAzP ^S`+ e" ,á۹u̡H٩أוm Xj*.<:xDQ0/7ukzR Y+133b{pnw _mSL[e9>S4MlkB=wż8vxmf Ѡ&7 *67+h{̓PPPF*U Pun~u@j~{wbXg|1x(vD ;\__`OKB)X *!ߔDڇfw6KaAӍ'xI|Hs35`ÌD=@jzsŞsaY~wJ]f(!& pB2I2aAst+T2VfX\$Sv Xx&I[ҨG'X=V%k2:\|nVC9_ V݋Ԗ?Iϔz{/lja6 !΍p$Qs g-oi| LL JT2,SuA%z1jlyX%2R;ʬ`ԅ埽w@ _ay+0@g:ZgcNjl%^yByLA'*q'%4Z9,/?V؞_ ,Ȗbk]w#?2KJ$<2+ (Ǚ>FJ)wDS/N`v2cEȴԣH&"}ks]R+ju_T L-]ԆsXT0 B80U)^Z扝ǫ؁2$$ȺIiX"ex,a>-(6>alRo$6knE ImÌ`p"[_j`=$a̳RV,, 3X-l!ha1݄!5 9(tm}Ѯ a;Hn&Y6 sXk!r""ʶ\e[ʰz-T2QA_=0 F dB:U9B9Q-:9S>8Eٵvak0CH`\vY9P??rg]vzF J4Y݆Mm՟B0OR~z7Aܺ|Ϳ|Ed w>~v_։Y!kp͚H(*끸{]Q1ݴ{G;!_zxPHzK/3 5ãEUwYuE6)GeA?0Z՘gLv5eɹIDMDnqΒ=K/VY8M/G:%O=̒9. M4hNsW%YzP`FPcajgt0ZBA FKd:d}/]Km--$N䚓@gEJ-钴bfj?J$hʒ.Α+!2&NCe 7uyYe!YpNU>7Y46ԔWzf'cM&H\f<+r& M~1yG6\/sq4d=N Y!U(   _nnOt3IENDB`imsprog-1.8.5/IMSProg_programmer/img/verify64.png000066400000000000000000000056131520775651600217030ustar00rootroot00000000000000PNG  IHDR@@PLTE𖖖߰񐐐᧧便Ι螞ߢۛ𻻻333ա۾iii٭O///FFFC***BBBL=SHE=@555K:999xKJI'''ѷKC111~ÖRF:|zLJlllggg@5)$>?><<<;ɟzzzppp;7/-~RaaaXXYW21/.- LzӦVRRQMML4 `YKv׹ߠfh_ZXG>7'#uڛيuly~khhdWQKII82 h Gq须̌oeydrxc^_^]SWJGC;;;6n1s ɹǟꋰukoa_akM@?\m=tRNS!7# Z%JC9ԾǛqj/$߾hÚ~{h^[IDATXÍXa7c:ֽ1<'S6M]MA0hTn}vlJ?a~w;h>RQbGd6Xŏ_kUH.;rEk*V-/ڿb}y#a ,0DFFR?|TFL"K}ÇX,P6bC8vKr zo$Bsm!ͫp^!YЦ'd. uዥ8 6߬;lӯZr {T,9j!׿+U,@|Hm!9|X&d:L"&yVcMZt<2D `HQӑ/r+ K*op*tB-`Y+_Y@"RUGgC(XOP0ojsf A,PKXH"MȎ_/3LH s(DbӚF$[ 7 YY^ATXM$Ɛk?:~nBVOn/h*_@:;!6+{G7h\Ah6'ϵw"'M>J+-N-xkdc;2=Xfg4:.ZS 1zcѺjجn NRbuӝqq_ 0e~v&P0nO~q7&Dl>Fg4^EA840(zz~&0nj(C?ChKI_>;0p`PЫp AH֪B@7,%(,=e;uzi >}5 ^'2O!! 7ubd@7>lvJA" ro$_=qb; roH+ Do/O B  F _IᡀkCj !rOF>1 :)D}^}wFB0jЊɶAHgxgCGr% ޵dWc' ~3p\丠R0Ŵk؍`K>SŹwgJD 8ǫ@7ȼ\mIz9> 8/z  ʅa"|fM A0thB r-X$YQ:\LU*dr!mλA`.ܲ@ \p:52cu׎Yrd ׎OD(\ߏdcGpn)zpOQ6"° c-1uA"EJY!M !$ȰoǶ! ߹) s 0\gY}1sL)//]:Kk־s/(bl )0oVT\LMq, c tttŋ={vo [q6Lhu۶m"J|rbJ)_ROUx108kG8L6ƀCfs͢3+u2D!hfӦMtR R8uoPJ=qF"˖-R>%3O8R()0O14?\OӺu\[sJ#=C̲):[xǜ9sR ?/ d2̜Cqi.<-?( s1^><hO,ڶ@9|>G(VIYm=^'=v6r% Sh ɽ(^8y+83ywڵrJf۶kl@h?04hix^1%F2t1` _<2Jkd}݇9Ě['IQ$H2bmctO% : Ce3X Z)J{(N(Oc.LK!NO+#r7Hm 8=qn75Q !i a(PCa?-hl&Cf0[%PQyJ9JsS_܏su_22gsB@ 2 ϣRb|((pw`S\,J1t\鏭CS6M{p {o%6~V  #AWH:ƲW>I&& d8vsaƨ/Z=BuIў.1~r;)_|/;vGX#AP^Z+Jp?yPc y ˡ)tQ Π_`-*~ n6#oڭD/r0 <$G)VhUDtL"`0OiνdGx??C:t0Y(pf~t{iD<+VJץTQf fL9?Ғ|c [lʕ_`fZn7ͥ?]Nx,Auu5;vɐMPlVF窿C`e;ELdFi͛eci4K.KSST&CSvc8z(DbTzoW/%Xi8Rb9²BYXB92C~ *:wykh;0o<~s'"k'B첲L&sҐ!`ҥ o>x饗#Ns1l#DT|͛7#ddd;wpIw}2>#O'xdH&|3᳟,)Jx*sUx{v]XT/u3x ^6͒xj8YmgWA+ ~z~ ln ,_x<~JPOft>,ˢ;s9y166FooPz6l"o Un/ss^H/g_<xJ0/2> D"Yx1555L c@'Þa!s9DWW<e1::JOOVo>4ZA*9%q >3olbsaiub$W^ꫯ2sLѨc8_dժU$I6o۱,h4d2ԔT޽{ٸq#@)%@?08p:P!MMMZnvIkk߰_xq0IO3t+ݝ~Ȼ#<>%#$ ꢣ˗.---h7oh~08Y0 ~j~,"gxxT*E*477CU$}[A}9NL( | ,`|ӟd۶%L꣎S@񕕕kqW`,*6L&1FMM I<'Ouu !į9Aw^̫뙖`p8yd2,;vPQQvl߾8/p]"3dD"fϞ+l2N_N6Jͳtm8(oMD"'Y@Ʋ,m&uq]_M7D<Dz,jjjDMwR:זei&khӺB1XSQQE}_(ZRVw-鴸+EUm]vŊ+mc@D*mnnA"8=SX3fiQSuB0"1۶dݺu,[s$+ 2&fKs5/RѣG˘={8<]dylܸ r?~mۖ1#R*V@)e2Hرw۶m~-ZĢEbM#N\RcǎoŢE ןvi uprmۣ-o/ Μ9s3X ,8U13E~.,bɒ%,ZWmmm7۶q** :D&a¬$ uݨRy&I2RRJYnYw$*aIENDB`imsprog-1.8.5/IMSProg_programmer/language/000077500000000000000000000000001520775651600205215ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_programmer/language/chipProgrammer_de_DE.ts000066400000000000000000002633451520775651600251050ustar00rootroot00000000000000 DialogAbout About IMSProg Über IMSProg IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, and M95xx series chips. IMSProg - freie Software I2C, SPI und MicroWire EEPROM/Flash Chip Programmierer für CH341a Geräte. IMSProg unterstützt Chips der Serien 24Cxx, 25xx, 93Cxx und M95xx. IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341A and CH347T devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - freie Software I2C, SPI und MicroWire EEPROM/Flash Chip Programmierer für CH341A und CH347T Geräte. IMSProg unterstützt Chips der Serien 24Cxx, 25xx, 93Cxx und M95xx. <html><head/><body><p>In this program <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget and modified programmer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> were used.</p><p>The page on GitHub is <a href="https://github.com/bigbigmdm/IMSProg">here</a>, the support page is <a href="https://antenna-dvb-t2.ru/IMSProg.php">here</a>. </p></body></html> <html><head/><body><p>In diesem Programm wurden das <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> Widget und der modifizierte Programmierer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> verwendet.</p><p>Die Seite auf GitHub ist <a href="https://github.com/bigbigmdm/IMSProg">hier</a>, die Support-Seite ist <a href="https://antenna-dvb-t2.ru/IMSProg.php">hier</a>. </p></body></html> Written by 2023 - 2026 Mikhail Medvedev Geschrieben von 2023 - 2026 Mikhail Medvedev Version: Version: 1.1.4 1.1.4 OR ODER IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - freie Software I2C, SPI und MicroWire EEPROM/Flash Chip Programmierer für CH341a Geräte. IMSProg unterstützt Chips der Serien 24Cxx, 25xx, 93Cxx und M95xx. Written by 2023 Mikhail Medvedev Geschrieben von 2023 Mikhail Medvedev Close Schließen DialogBBM Bad block management Verwaltung fehlerhafter Blöcke Chip scan Chip-Scan No Anzahl Block Block Start address Startadresse End address Endadresse Check Start Settings Einstellungen Erasing Löschen Skip bad blocks during erase procedure (recommended) Fehlerhafte Blöcke überspringen (empfohlen) Don't skip bad blocks Überspringen Sie keine fehlerhaften Blöcke. Writing Schreiben Write all blocks one to one (ignore bad blocks) Schreiben Sie alle Blöcke eins zu eins (ignorieren die fehlerhaften). Skip bad blocks during writing procedure Beschädigte Blöcke während des Schreibvorgangs überspringen Ok Ok BBM table (Winbond) BBM-Tabelle (Winbond) This operation is used only in some Winbond chips. Dieser Vorgang wird nur bei einigen Winbond-Chips verwendet. Bad block Defekter Block Changed block Geänderter Block Status Status Read Lesen Error Fehler Error reading chip! Fehler beim Lesen des Chips! Corrupted blocks found: Beschädigte Blöcke gefunden: All blocks in the chip are good! Alle Blöcke im Chip sind in Ordnung! Programmer Das Programmiergerät is not connected! ist nicht angeschlossen! Programmer CH341a is not connected! Das Programmiergerät CH341a ist nicht angeschlossen! Not used Nicht verwendet Active, valid Aktiv, gültig Active, not valid Aktiv, nicht gültig BBM table is not used in this chip. Die BBM-Tabelle wird in diesem Chip nicht verwendet. DialogCompare Comparing files: Vergleich von Dateien: CRC32: CRC32: Name Name CRC32: CRC32: Visible ASCII areas ASCII-Bereiche anzeigen Name: Name: DialogFill Fill the buffer with code Puffer mit Code füllen All values in HEX format! Alle Werte im HEX-Format! Start address: Startadresse: Filling code: Code wird eingefügt: Fill Füllen End address Endadresse Length Länge DialogInfo Connection info: Verbindungsinformationen: Slot: Steckplatz: - - Adapter: Adapter: Close Schließen DialogNANDSr Status registers Statusregister Status register 1 Statusregister 1 SRP0 SRP0 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 TB TB WP-E WP-E SRP1 SRP1 Status register 2 Statusregister 2 OTP-L OTP-L OTP-E OTP-E SR1-L SR1-L ECC-E ECC-E BUF BUF (R) (R) Status register 3 Statusregister 3 LUT-F LUT-F ECC-1 ECC-1 ECC-0 ECC-0 P-FAIL P-FAIL WELL WELL BUSY BUSY E_FAIL E_FAIL Status register 4 Statusregister 4 --- --- Status register 5 Statusregister 5 Unique ID: Eindeutige ID: Read Lesen Write Schreiben Parameter page: Parameter-Seite: Manufacturer: Herstellung: Model: Modell: Page size: Page Größe: ECC size: ECC Größe: Pages per block: Seiten pro Block: Block per unit: Block pro Einheit: Block size: Block Größe: Chip size: Chip Größe: Error Fehler Error reading register! Fehler beim Lesen des Registers! Error reading Parameter Page! Fehler beim Lesen der Parameterseite! The Parameter Page is not supported. Die Parameterseite wird nicht unterstützt. Error reading ID! Fehler beim Lesen der ID! Programmer Das Programmiergerät is not connected! ist nicht angeschlossen! Programmer CH341a is not connected! Das Programmiergerät CH341a ist nicht angeschlossen! DialogNandSecurity Security registers Sicherheitsregister Hex Editor Hexadezimal-Editor Operations: Operationen: Reading security register data from the chip Lesen von Sicherheitsregisterdaten aus dem Chip ... ... Writing data to the security register Schreiben von Daten in das Sicherheitsregister Open a binary file from a computer Öffnen einer Binärdatei auf einem Computer Save the binary file on the computer Speichern Sie die Binärdatei auf dem Computer Security register number: Nummer des Sicherheitsregisters: Error Fehler Error reading Parameter Page! Fehler beim Lesen der Parameterseite! Programmer CH341a is not connected! Das Programmiergerät CH341a ist nicht angeschlossen! Programmer Das Programmiergerät is not connected! ist nicht angeschlossen! Open file Datei öffnen The file size exceeds the security register size. Die Dateigröße übersteigt die Größe des Sicherheitsregisters. Save file Datei speichern Error saving file! Fehler beim Speichern der Datei! DialogRP Load block from file Block aus Datei laden All values in HEX format! Alle Werte im HEX-Format! Start address: Startadresse: Load Laden DialogSFDP Information about SFDP and status registers Informationen zu SFDP und Statusregistern SFDP support: SFDP Unterstützung: Minimum VCC: Minimum VCC: Maximum VCC: Maximale VCC: Chip size: Chip Größe: Block size: Block Größe: Speeds: Geschwindigkeiten: OTP support: OTP Unterstützung: Status Register 0 Statusregister 0 SPR0 SPR0 BP4 BP4 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 WEL WEL WIP WIP SUS1 SUS1 CMP CMP LB3 LB3 LB2 LB2 LB1 LB1 SUS2 SUS2 QE QE SPR1 SPR1 Status Register 1 Statusregister 1 Status register 2 Statusregister 2 JEDEC info: JEDEC-Info: Man. ID Herst. ID Hersteller ID Man. type Herst. typ Capacity Größe Unique ID: Eindeutige ID: Read Lesen Write registers Register schreiben (R) (R) DRV1 DRV1 DRV0 DRV0 WPS WPS ADP ADP ADS ADS <html><head/><body><p/></body></html> <html><head/><body><p/></body></html> <html><head/><body><p>Legend:</p><p>** - Basic area<br>** - Extended area<br>** - Manufacture area </p></body></html> <html><head/><body><p>Legende:</p><p>** - Basisbereich<br>** - Erweiterter Bereich<br>** - Herstellerbereich </p></body></html> Close Schließen Error Fehler Error reading register! Fehler beim Lesen des Registers! <html><head/><body><p> Hex SFDP register data: <html><head/><body><p> Hex SFDP-Registerdaten: <html><head/><body><p>Addr:<br> <html><head/><body><p>Adr.:<br> Programmer Das Programmiergerät is not connected! ist nicht angeschlossen! Before writing the registers, please press the `Read` button! Vor dem Register schreiben bitte die Taste `Lesen` drücken! Error reading JEDEC ID! Fehler beim Lesen der JEDEC-ID! Legend: Legende: - Basic area - Basisbereich - Extended area - Erweiterter Bereich - Manufacture area - Herstellerbereich Error reading unique ID! Fehler beim Lesen der eindeutigen ID! Programmer CH341a is not connected! Das Programmiergerät CH341a ist nicht angeschlossen! DialogSP Save part of image Teil des Abbildes speichern All values in HEX format! Alle Werte im HEX-Format! Start address: Startadresse: Save Speichern End address Endadresse Length Länge DialogSR Status register Statusregister WPEN WPEN X X BP1 BP1 BP0 BP0 WEN WEN /RDY /RDY Read Lesen Write Schreiben Error Fehler Error reading register! Fehler beim Lesen des Registers! Programmer Das Programmiergerät is not connected! ist nicht angeschlossen! Programmer CH341a is not connected! Das Programmiergerät CH341a ist nicht angeschlossen! Before writing the register, please press the `Read` button! Vor dem Register schreiben bitte die Taste `Lesen` drücken! DialogSecurity Security registers Sicherheitsregister Hex Editor Hexadezimal-Editor Operations: Operationen: Reading security register data from the chip Lesen von Sicherheitsregisterdaten aus dem Chip ... ... Erasing security register data Löschen von Sicherheitsregisterdaten Writing data to the security register Schreiben von Daten in das Sicherheitsregister Open a binary file from a computer Öffnen einer Binärdatei auf einem Computer Save the binary file on the computer Speichern Sie die Binärdatei auf dem Computer Security register number: Nummer des Sicherheitsregisters: Error Fehler Error reading register! Fehler beim Lesen des Registers! Programmer CH341a is not connected! Das Programmiergerät CH341a ist nicht angeschlossen! Programmer Das Programmiergerät is not connected! ist nicht angeschlossen! Error writing register! Fehler beim Schreiben des Registers! Open file Datei öffnen The file size exceeds the security register size. Die Dateigröße übersteigt die Größe des Sicherheitsregisters. Save file Datei speichern Error saving file! Fehler beim Speichern der Datei! DialogSetAddr Goto address Gehe zu Adresse All values in HEX format! Alle Werte im HEX-Format! Address: Adresse: Go to Gehe zu MainWindow File Datei Open Öffnen Ctrl+O Ctrl+O Exit Beenden Ctrl+X Ctrl+X Save Speichern IMSProg - I2C/MicroWire/SPI CH341a Programmer IMSProg - I2C/MicroWire/SPI CH341a Programmiergerät Chip Chip Name Name Page size Page Größe Block size Blockgröße VCC, Volt VCC, Volt 4byte Addr. 4 Byte Adresse Detect Erkennen Read Lesen i i I2C bus speed I2C-Bus-Geschw. Erase size Löschengröße ECC size ECC Größe: Auto Options Auto-Optionen Erase Löschen Program Schreiben Verify Überprüfen Go! Start! Hex Editor Hexadezimal-Editor JEDEC ID: JEDEC ID: CH341a: CH341a: border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; CRC32: CRC32: Message Nachricht Programmer Programmierer Help Hilfe Operations Operationen Check erase Löschvorgang prüfen Ctrl+S Ctrl+S Ctrl+D Ctrl+D Ctrl+R Ctrl+R Ctrl+E Ctrl+E Write Schreiben Ctrl+W Ctrl+W Ctrl+T Ctrl+T Undo Rückgängig machen Ctrl+Z Ctrl+Z Redo Wiederholen Ctrl+Y Ctrl+Y Ctrl+N Ctrl+N Import from Intel HEX Importieren von Intel HEX Export to Intel HEX Exportieren nach Intel HEX Extract from ASUS CAP Auszug aus ASUS CAP Goto address Gehe zu Adresse Move the cursor to the entered address Verschiebe Cursor zu eingegebener Adresse Ctrl+G Ctrl+G Security registers Sicherheitsregister Ctrl+U Ctrl+U Fill test image Testbild ausfüllen Filling the hex editor with a test array Füllen des Hex-Editors mit einem Testbild Ctrl+L Ctrl+L Compare files Dateien vergleichen Compares the results of the last and penultimate chip read or file open operation Vergleicht die Ergebnisse der letzten und vorletzten Chip-Lese- oder Dateiöffnungsoperation Ctrl+M Ctrl+M Copy Kopieren Paste Einfügen Bad block management Verwaltung fehlerhafter Blöcke Ctrl+B Ctrl+B Show programmer version Programmiererversion anzeigen Check erase chip Chip löschen prüfen Ctrl+J Ctrl+J Filling with code Mit Code füllen Ctrl+K Ctrl+K CH341A/B v1.2 CH341A/B v1.2 CH341A v1.7 CH341A v1.7 CH347T v1.0 CH347T v1.0 CH347T v1.1 CH347T v1.1 CH347T CH347T Save Part Teil speichern Load Part Teil laden Find / Replace Suchen / Ersetzen Ctrl+F Ctrl+F About Über About IMSProgrammer Über IMSProgrammer Ctrl+H Ctrl+H Checksum calculate Prüfsumme berechnen Ctrl+A Ctrl+A Edit chips Database Chip-Datenbank bearbeiten Ctrl+Q Ctrl+Q Stop Stop Forced stop of read, write, erase and verification operations Erzwungener Stopp von Lese-, Schreib-, Lösch- und Prüfvorgängen Ctrl+I Ctrl+I Chip info Chip-Infos Information about SFDP and status registers Informationen zu SFDP und Statusregistern Ctrl+P Ctrl+P Current file: Aktuelle Datei: Type Typ Manufacture Herstellung Size Größe Opening DAT file DAT-Datei öffnen Error Fehler The end address must be greater than the starting address. Die Endadresse muss größer als die Anfangsadresse sein. File 'IMSProg_editor' not found! Datei `IMSProg_editor` nicht gefunden! Error loading chip database file! Fehler beim Laden der Chipdatenbankdatei! Parsing DAT file Parsen einer DAT-Datei Reading data from Lesen von Daten aus Unsupported chip type! Nicht unterstützter Chiptyp! Programmer CH341a is not connected! Das Programmiergerät CH341a ist nicht angeschlossen! Error reading block Fehler beim Lesen des Blocks Before reading from chip please press 'Detect' button. Vor dem Auslesen des Chips bitte die Taste 'Erkennen' drücken. Please select the chip parameters - manufacture and chip name Bitte Chip-Parameter - Hersteller und Chip-Name auswählen The chip is not connect or missing! Der Chip ist nicht angeschlossen oder fehlt! Saving file Speichern der Datei Save file Datei speichern Data Images Datendateien All files Alle Dateien Error saving file! Fehler beim Speichern der Datei! Erasing the Löschen der Error erasing sector Fehler beim Löschen eines Sektors Opening file Datei öffnen Open file Datei öffnen The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file. Die Dateigröße übersteigt die Chipgröße. Bitte einen anderen Chip oder eine andere Datei wählen, oder "Teil speichern" verwenden, um die Datei zu teilen. The ending address must not exceed the buffer size. Die Endadresse darf die Puffergröße nicht überschreiten. Cannot find a chip database file. You may want to run IMSProg_database_update Die Chip-Datenbankdatei wurde nicht gefunden. Führen Sie gegebenenfalls IMSProg_database_update aus. Before working with the security registers, click the 'Detect' button Bevor Sie mit den Sicherheitsregistern arbeiten, klicken Sie auf die Schaltfläche 'Detect'. There are no security registers in this chip or the current version of IMSProg does not support this algorithm. Es gibt keine Sicherheitsregister in diesem Chip oder die aktuelle Version von IMSProg unterstützt diesen Algorithmus nicht. Intel HEX Images Intel-HEX-Dateien Not valid HEX format! Ungültiges HEX-Format! The address is larger than the size of the chip! Die Adresse ist größer als die Größe des Chips! Checksum error! Prüfsummenfehler! Writing data to Schreiben von Daten in Programmer Das Programmiergerät is not connected! ist nicht angeschlossen! Error writing sector Fehler beim Schreiben eines Sektors Veryfing data from Überprüfe Daten aus Error comparing data! Address: Fehler beim Vergleichen von Daten! Adresse: Buffer: Puffer: Chip: Chip: Please select the chip parameters - manufacture and chip name. Bitte Chip-Parameter - Hersteller und Chip-Name auswählen. Ok! Ok! The operation was successful! Die Operation war Erfolgreich! Saving block Speichere Block Save block Block speichern Opening block Eröffnungsblock Open block Offener Block The end address out of image size! Die Endadresse aus der Abbildgröße! Connected Verbunden Not connected Nicht verbunden Operation aborted! Operation abgebrochen! The chip database file was not found! Die Chip-Datenbankdatei wurde nicht gefunden! Error loading chip database file! File: %1 Error Code: %2 Reason: %3 Fehler beim Laden der Chip-Datenbankdatei! Datei: %1 Fehlercode: %2 Grund: %3 Info: Info: Device revision: Geräteversion: Erase checking in Löschvorgang in Error erasing chip! Address: Fehler beim Löschen des Chips! Adresse: Need: FF Erforderlich: FF SearchDialog QHexEdit - Find/Replace QHexEdit - Suchen/Ersetzen Find Finden Hex Hex UTF-8 Replace Ersetze Options Optionen &Backwards Rückwärts &Prompt on replace Aufforderung zum Ersetzen Standard headers: Standard-Header: ZIP ZIP PNG PNG JPG JPG GIF GIF TAR TAR UEFI UEFI BIOS BIOS GPT GPT &Find Finden F3 F3 &Replace Ersetzen Replace &All Alle ersetzen &Close Schließen QHexEdit %1 occurrences replaced. %1 Vorkommen ersetzt. Replace occurrence? Vorkommen ersetzen? UndoStack Inserting %1 bytes Einfügen von %1 Bytes Delete %1 chars Zeichen %1 löschen Overwrite %1 chars Überschreibe %1 Zeichen imsprog-1.8.5/IMSProg_programmer/language/chipProgrammer_es_ES.ts000066400000000000000000002634731520775651600251450ustar00rootroot00000000000000 DialogAbout About IMSProg Acerca de IMSProg IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, and M95xx series chips. IMSProg - software libre I2C, SPI y MicroWire EEPROM/Flash chip programador para dispositivos CH341a. IMSProg admite chips de las series 24Cxx, 25xx, 93Cxx y M95xx. IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341A and CH347T devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - software libre I2C, SPI y MicroWire EEPROM/Flash chip programador para dispositivos CH341A y CH347T. IMSProg admite chips de las series 24Cxx, 25xx, 93Cxx, AT45DBxx y M95xx. <html><head/><body><p>In this program <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget and modified programmer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> were used.</p><p>The page on GitHub is <a href="https://github.com/bigbigmdm/IMSProg">here</a>, the support page is <a href="https://antenna-dvb-t2.ru/IMSProg.php">here</a>. </p></body></html> <html><head/><body><p>En este programa se utilizó el widget <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> y el programador <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> modificado.</p><p>La página de GitHub está <a href="https://github.com/bigbigmdm/IMSProg">aquí</a>, y la página de soporte está <a href="https://antenna-dvb-t2.ru/IMSProg.php">aquí</a>. </p></body></html> Written by 2023 - 2026 Mikhail Medvedev Escrito por 2023 - 2026 Mikhail Medvedev Version: Versión: 1.1.4 1.1.4 OR o IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - software libre I2C, SPI y MicroWire EEPROM/Flash chip programador para dispositivos CH341a. IMSProg admite chips de las series 24Cxx, 25xx, 93Cxx, AT45DBxx y M95xx. Written by 2023 Mikhail Medvedev Escrito por 2023 Mikhail Medvedev Close Cerrar DialogBBM Bad block management Gestión de bloques defectuosos Chip scan Escaneo de chip No Número Block Bloque Start address Direc. de inicio End address Dirección final Check Comprobar Settings Configuración Erasing Borrar Skip bad blocks during erase procedure (recommended) Omitir bloques defectuosos (recomendado) Don't skip bad blocks No omitir bloques defectuosos Writing Escribe Write all blocks one to one (ignore bad blocks) Escribir todos los bloques uno por uno (ignorar defectuosos). Skip bad blocks during writing procedure Omitir bloques defectuosos. Ok Ok BBM table (Winbond) Tabla BBM (Winbond) This operation is used only in some Winbond chips. Esta operación solo se utiliza en algunos chips Winbond. Bad block Bloque defectuoso Changed block Bloque modificado Status Estado Read Leer Error Error Error reading chip! ¡Error al leer el chip! Corrupted blocks found: Bloques corruptos encontrados: All blocks in the chip are good! ¡Todos los bloques del chip están bien! Programmer ¡El programador is not connected! no está conectado! Programmer CH341a is not connected! ¡El programador CH341a no está conectado! Not used No se utiliza Active, valid Activo, válido Active, not valid Activo, no válido BBM table is not used in this chip. La tabla BBM no se utiliza en este chip. DialogCompare Comparing files: Comparando archivos: CRC32: CRC32: Name Nombre CRC32: CRC32: Visible ASCII areas Mostrar áreas ASCII Name: Nombre: DialogFill Fill the buffer with code Llenar el búfer con código All values in HEX format! ¡Todos los valores en formato HEX! Start address: Dirección de inicio: Filling code: Código de llenado: Fill Llenar End address Dirección final Length Longitud DialogInfo Connection info: Información de conexión: Slot: Ranura: - - Adapter: Adaptador: Close Cerrar DialogNANDSr Status registers Registros de estado Status register 1 Registro estado 1 SRP0 SRP0 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 TB TB WP-E WP-E SRP1 SRP1 Status register 2 Registro estado 2 OTP-L OTP-L OTP-E OTP-E SR1-L SR1-L ECC-E ECC-E BUF BUF (R) (R) Status register 3 Registro estado 3 LUT-F LUT-F ECC-1 ECC-1 ECC-0 ECC-0 P-FAIL P-FAIL WELL WELL BUSY BUSY E_FAIL E_FAIL Status register 4 Registro estado 4 --- --- Status register 5 Registro estado 5 Unique ID: ID único: Read Leer Write Escribe Parameter page: Página de parámetros: Manufacturer: Fabricación: Model: Modelo: Page size: Tamaño de página: ECC size: Tamaño ECC: Pages per block: Páginas por bloque: Block per unit: Bloque por unidad: Block size: Tamaño del bloq.: Chip size: Tamaño del chip: Error Error Error reading register! ¡Error al leer el registro! Error reading Parameter Page! ¡Error al leer la página de parámetros! The Parameter Page is not supported. La página de parámetros no es compatible. Error reading ID! ¡Error al leer el ID! Programmer ¡El programador is not connected! no está conectado! Programmer CH341a is not connected! ¡El programador CH341a no está conectado! DialogNandSecurity Security registers Registros de seguridad Hex Editor Editor hexadecimal Operations: Operaciones: Reading security register data from the chip Lectura de los datos del registro de seguridad del chip ... ... Writing data to the security register Escritura de datos en el registro de seguridad Open a binary file from a computer Abrir un archivo binario desde un ordenador Save the binary file on the computer Guardar el archivo binario en el ordenador Security register number: Número de registro de seguridad: Error Error Error reading Parameter Page! ¡Error al leer la página de parámetros! Programmer CH341a is not connected! ¡El programador CH341a no está conectado! Programmer ¡El programador is not connected! no está conectado! Open file Abrir expediente The file size exceeds the security register size. El tamaño del archivo supera el tamaño del registro de seguridad. Save file Guardar archivo Error saving file! ¡Error al guardar el archivo! DialogRP Load block from file Cargar bloque desde archivo All values in HEX format! ¡Todos los valores en formato HEX! Start address: Dirección de inicio: Load Carga DialogSFDP Information about SFDP and status registers Información sobre SFDP y registros de estado SFDP support: Apoyo al SFDP: Minimum VCC: VCC mínimo: Maximum VCC: VCC máxima: Chip size: Tamaño del chip: Block size: Tamaño del bloq.: Speeds: Velocidades: OTP support: Soporte OTP: Status Register 0 Registro estado 0 SPR0 SPR0 BP4 BP4 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 WEL WEL WIP WIP SUS1 SUS1 CMP CMP LB3 LB3 LB2 LB2 LB1 LB1 SUS2 SUS2 QE QE SPR1 SPR1 Status Register 1 Registro estado 1 Status register 2 Registro estado 2 JEDEC info: Info. del JEDEC: Man. ID Fabr. ID Man. type Fabr. type Capacity Capacidad Unique ID: ID único: Read Leer Write registers Escribir registros (R) (R) DRV1 DRV1 DRV0 DRV0 WPS WPS ADP ADP ADS ADS <html><head/><body><p/></body></html> <html><head/><body><p/></body></html> <html><head/><body><p>Legend:</p><p>** - Basic area<br>** - Extended area<br>** - Manufacture area </p></body></html> <html><head/><body><body><p>Legend:</p><p>** - Zona básica<br>** - Zona ampliada<br>** - Zona de fabricación</p></body></html></html> Close Cerrar Error Error Error reading register! ¡Error al leer el registro! <html><head/><body><p> Hex SFDP register data: <html><head/><body><p> Datos hexadecimales del registro SFDP: <html><head/><body><p>Addr:<br> <html><head/><body><p>Addr:<br> Programmer ¡El programador is not connected! no está conectado! Before writing the registers, please press the `Read` button! ¡Antes de escribir los registros, presione el botón "Leer"! Error reading JEDEC ID! ¡Error al leer el ID JEDEC! Legend: Legend: - Basic area - Zona básica - Extended area - Zona ampliada - Manufacture area - Zona de fabricación Error reading unique ID! ¡Error al leer el identificador único! Programmer CH341a is not connected! ¡El programador CH341a no está conectado! DialogSP Save part of image Guardar parte de la imagen All values in HEX format! ¡Todos los valores en formato HEX! Start address: Dirección de inicio: Save Guardar End address Dirección final Length Longitud DialogSR Status register Registro estado WPEN WPEN X X BP1 BP1 BP0 BP0 WEN WEN /RDY /RDY Read Leer Write Escribe Error Error Error reading register! ¡Error al leer el registro! Programmer ¡El programador is not connected! no está conectado! Programmer CH341a is not connected! ¡El programador CH341a no está conectado! Before writing the register, please press the `Read` button! ¡Antes de escribir los registro, presione el botón "Leer"! DialogSecurity Security registers Registros de seguridad Hex Editor Editor hexadecimal Operations: Operaciones: Reading security register data from the chip Lectura de los datos del registro de seguridad del chip ... ... Erasing security register data Borrado de datos del registro de seguridad Writing data to the security register Escritura de datos en el registro de seguridad Open a binary file from a computer Abrir un archivo binario desde un ordenador Save the binary file on the computer Guardar el archivo binario en el ordenador Security register number: Número de registro de seguridad: Error Error Error reading register! ¡Error al leer el registro! Programmer CH341a is not connected! ¡El programador CH341a no está conectado! Programmer ¡El programador is not connected! no está conectado! Error writing register! Error al escribir el registro. Open file Abrir expediente The file size exceeds the security register size. El tamaño del archivo supera el tamaño del registro de seguridad. Save file Guardar archivo Error saving file! ¡Error al guardar el archivo! DialogSetAddr Goto address Ir a dirección All values in HEX format! ¡Todos los valores en formato HEX! Address: Dirección: Go to Ir a MainWindow File Archivo Open Abrir Ctrl+O Ctrl+O Exit Salida Ctrl+X Ctrl+X Save Guardar IMSProg - I2C/MicroWire/SPI CH341a Programmer MSProg - Programador I2C/MicroWire/SPI CH341a Chip Chip Name Nombre Page size Tamaño de página Block size Tamaño del bloque VCC, Volt VCC, voltios 4byte Addr. 4byte Dirección Detect Detectar Read Leer i i I2C bus speed Velocidad del I2C Erase size Tamaño de borrado ECC size Tamaño ECC Auto Options Opciones automáticas Erase Borrar Program Escribe Verify Verifique Go! ¡Arranca! Hex Editor Editor hexadecimal JEDEC ID: JEDEC ID CH341a: CH341a: border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; CRC32: CRC32: Message Mensaje Programmer Programador Help Ayuda Operations Operaciones Check erase Comprobar borrado Ctrl+S Ctrl+S Ctrl+D Ctrl+D Ctrl+R Ctrl+R Ctrl+E Ctrl+E Write Escribe Ctrl+W Ctrl+W Ctrl+T Ctrl+T Undo Deshacer Ctrl+Z Ctrl+Z Redo Rehacer Ctrl+Y Ctrl+Y Ctrl+N Ctrl+N Import from Intel HEX Importar desde Intel HEX Export to Intel HEX Exportar a Intel HEX Extract from ASUS CAP Extracto de ASUS CAP Goto address Ir a dirección Move the cursor to the entered address Mover el cursor a la dirección introducida Ctrl+G Ctrl+G Security registers Registros de seguridad Ctrl+U Ctrl+U Fill test image Rellenar imagen de prueba Filling the hex editor with a test array Rellenar el editor hexadecimal con una matriz de prueba Ctrl+L Ctrl+L Compare files Comparar ficheros Compares the results of the last and penultimate chip read or file open operation Compara los resultados de la última y penúltima operación de lectura de chip o apertura de fichero Ctrl+M Ctrl+M Copy Copiar Paste Pegar Bad block management Gestión de bloques defectuosos Ctrl+B Ctrl+B Show programmer version Mostrar versión del programador Check erase chip Comprobar el borrado del chip Llenando con código Ctrl+J Ctrl+J Filling with code Llenando con código Ctrl+K Ctrl+K CH341A/B v1.2 CH341A/B v1.2 CH341A v1.7 CH341A v1.7 CH347T v1.0 CH347T v1.0 CH347T v1.1 CH347T v1.1 CH347T CH347T Save Part Guardar pieza Load Part Parte de carga Find / Replace Buscar / Reemplazar Ctrl+F Ctrl+F About Acerca de About IMSProgrammer Acerca de IMSProgrammer Ctrl+H Ctrl+H Checksum calculate Cálculo de CRC32 Ctrl+A Ctrl+A Edit chips Database Editar la base de datos de chip Ctrl+Q Ctrl+Q Stop Stop Forced stop of read, write, erase and verification operations Parada forzada de operaciones de lectura, escritura, borrado y verificación Ctrl+I Ctrl+I Chip info Inform. del chip Information about SFDP and status registers Información sobre SFDP y registros de estado Ctrl+P Ctrl+P Current file: Archivo actual: Type Tipo Manufacture Fabricación Size Talla Opening DAT file Abrir un archivo DAT Error Error The end address must be greater than the starting address. La dirección final debe ser mayor que la dirección inicial. File 'IMSProg_editor' not found! ¡No se ha encontrado el archivo `IMSProg_editor`! Error loading chip database file! ¡Error al cargar el archivo de base de datos de chips! Parsing DAT file Análisis de archivos DAT Reading data from Lectura de datos de Unsupported chip type! Tipo de chip no compatible. Programmer CH341a is not connected! ¡El programador CH341a no está conectado! Error reading block Bloque de lectura de errores Before reading from chip please press 'Detect' button. Antes de leer el chip, pulse el botón 'Detectar'. Please select the chip parameters - manufacture and chip name Seleccione los parámetros del chip: 'Fabricación' y 'Nombre' del chip The chip is not connect or missing! ¡El chip no está conectado o falta! Saving file Guardar archivo Save file Guardar archivo Data Images Archivos de datos All files Todos los archivos Error saving file! ¡Error al guardar el archivo! Erasing the Borrar el Error erasing sector Error borrando sector Opening file Abrir expediente Open file Abrir expediente The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file. El tamaño del archivo excede el tamaño del chip. Por favor, seleccione otro chip o archivo o utilice `Guardar pieza` para dividir el archivo. The ending address must not exceed the buffer size. La dirección final no debe superar el tamaño del búfer. Cannot find a chip database file. You may want to run IMSProg_database_update No se encuentra el archivo de la base de datos de chips. Es posible que desee ejecutar IMSProg_database_update Before working with the security registers, click the 'Detect' button Antes de trabajar con los registros de seguridad, pulse el botón 'Detectar'. There are no security registers in this chip or the current version of IMSProg does not support this algorithm. No hay registros de seguridad en este chip o la versión actual de IMSProg no soporta este algoritmo. Intel HEX Images Archivos Intel HEX Not valid HEX format! ¡Formato HEX no válido! The address is larger than the size of the chip! La dirección es mayor que el tamaño del chip. Checksum error! ¡Error de suma de comprobación! Writing data to Escritura de datos en Programmer ¡El programador is not connected! no está conectado! Error writing sector Error al escribir el sector Veryfing data from Datos muy escasos de Error comparing data! Address: Error comparing data! Address: Buffer: Buffer: Chip: Chip: Please select the chip parameters - manufacture and chip name. Seleccione los parámetros del chip: 'Fabricación' y 'Nombre' del chip Ok! Ok! The operation was successful! ¡La operación fue un éxito! Saving block Bloque de ahorro Save block Guardar bloque Opening block Bloque de apertura Open block Bloque abierto The end address out of image size! ¡La dirección final fuera del tamaño de la imagen! Connected Conectado Not connected No conectado Operation aborted! ¡Operación abortada! The chip database file was not found! ¡No se ha encontrado el archivo de la base de datos de chips! Error loading chip database file! File: %1 Error Code: %2 Reason: %3 ¡Error al cargar el archivo de la base de datos de chips! Archivo: %1 Código de error: %2 Motivo: %3 Info: Información: Device revision: Revisión del dispositivo: Erase checking in Comprobando borrado en Error erasing chip! Address: ¡Error al borrar el chip! Dirección: Need: FF Necesita: FF SearchDialog QHexEdit - Find/Replace QHexEdit - Buscar/Reemplazar Find Encuentre Hex Hex UTF-8 Replace Sustituir Options Opciones: &Backwards Hacia atrás &Prompt on replace Preguntar al sustituir Standard headers: Cabeceras estándar: ZIP ZIP PNG PNG JPG JPG GIF GIF TAR TAR UEFI UEFI BIOS BIOS GPT GPT &Find Encuentre F3 F3 &Replace Sustituir Replace &All Sustituir todo &Close Cerrar QHexEdit %1 occurrences replaced. Replace occurrence? ¿Sustituir ocurrencia? UndoStack Inserting %1 bytes Insertando %1 bytes Delete %1 chars Borrar %1 caracteres Overwrite %1 chars Sobrescribir %1 caracteres imsprog-1.8.5/IMSProg_programmer/language/chipProgrammer_hu_HU.ts000066400000000000000000002634561520775651600251600ustar00rootroot00000000000000 DialogAbout About IMSProg IMSProg névjegye IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, and M95xx series chips. IMSProg - ingyenes szoftver I2C, SPI és MicroWire EEPROM/Flash chip programozó CH341a eszközökhöz. Az IMSProg a 24Cxx, 25xx, 93Cxx és M95xx sorozatú chipeket támogatja. IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341A and CH347T devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - ingyenes szoftver I2C, SPI és MicroWire EEPROM/Flash chip programozóz CH341A és CH347T eszközökhöz. Az IMSProg a 24Cxx, 25xx, 93Cxx, AT45DBxx és M95xx sorozatú chipeket támogatja. <html><head/><body><p>In this program <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget and modified programmer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> were used.</p><p>The page on GitHub is <a href="https://github.com/bigbigmdm/IMSProg">here</a>, the support page is <a href="https://antenna-dvb-t2.ru/IMSProg.php">here</a>. </p></body></html> <html><head/><body><p>Ebben a programban <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget és egy módosított programozó a <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> van felhasználva.</p><p>Az oldala a GitHub-on <a href="https://github.com/bigbigmdm/IMSProg">itt található</a>, a támogatási oldal <a href="https://antenna-dvb-t2.ru/IMSProg.php">pedig itt</a>. </p></body></html> Written by 2023 - 2026 Mikhail Medvedev 2023 - 2026 Mikhail Medvedev készítette Version: Version: 1.1.4 1.1.4 OR VAGY IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - ingyenes szoftver I2C, SPI és MicroWire EEPROM/Flash chip programozó CH341a eszközökhöz. Az IMSProg a 24Cxx, 25xx, 93Cxx, AT45DBxx és M95xx sorozatú chipeket támogatja. Written by 2023 Mikhail Medvedev 2023 Mikhail Medvedev készítette Close Bezár DialogBBM Bad block management Hibás blokkok kezelése Chip scan Chip szkennelés No Szám Block Blokk Start address Kezdő cím End address Végcím Check Ellenőrizze Settings Beállítások Erasing Törlés Skip bad blocks during erase procedure (recommended) A törlés során hagyja ki a hibás blokkokat (ajánlott) Don't skip bad blocks Ne hagyja ki a rossz blokkokat Writing Írás Write all blocks one to one (ignore bad blocks) Írd ki az összes blokkot egy az egyhez Skip bad blocks during writing procedure Az írási eljárás során hagyja ki a hibás blokkokat Ok Ok BBM table (Winbond) BBM táblázat (Winbond) This operation is used only in some Winbond chips. Ez a művelet csak egyes Winbond chipekben használatos. Bad block Rossz blokk Changed block Módosítva Status Status Read Olvasás Error Hiba Error reading chip! Hiba a chip olvasásakor! Corrupted blocks found: Megtalált sérült blokkok: All blocks in the chip are good! A chip összes blokkja rendben van! Programmer A is not connected! programozó nincs csatlakoztatva! Programmer CH341a is not connected! A CH341a programozó nincs csatlakoztatva! Not used Nem használatos Active, valid Aktív, érvényes Active, not valid Aktív, nem érvényes BBM table is not used in this chip. A BBM táblázatot ebben a chipben nem használják. DialogCompare Comparing files: Fájlok összehasonlítása: CRC32: CRC32: Name Név CRC32: CRC32: Visible ASCII areas ASCII területek megjelenítése Name: Név: DialogFill Fill the buffer with code Töltse meg a puffert kóddal All values in HEX format! Minden érték HEX formátumban! Start address: Kezdőcím: Filling code: Kód feltöltése: Fill Töltés End address Végcím Length Hosszúság DialogInfo Connection info: Kapcsolat információ: Slot: Foglalat: - - Adapter: Adapter: Close Bezár DialogNANDSr Status registers Állapotregiszterek Status register 1 Állapotregiszter 1 SRP0 SRP0 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 TB TB WP-E WP-E SRP1 SRP1 Status register 2 Állapotregiszter 2 OTP-L OTP-L OTP-E OTP-E SR1-L SR1-L ECC-E ECC-E BUF BUF (R) (R) Status register 3 Állapotregiszter 3 LUT-F LUT-F ECC-1 ECC-1 ECC-0 ECC-0 P-FAIL P-FAIL WELL WELL BUSY BUSY E_FAIL E_FAIL Status register 4 Állapotregiszter 4 --- --- Status register 5 Állapotregiszter 5 Unique ID: Egyedi ID: Read Olvasás Write Írás Parameter page: Paraméter oldal: Manufacturer: Gyártó: Model: Modell: Page size: Oldalméret: ECC size: ECC méret: Pages per block: Oldalak blokkonként: Block per unit: Blokkonként: Block size: Blokkméret: Chip size: Chip mérete: Error Hiba Error reading register! Hiba a regiszter olvasásakor! Error reading Parameter Page! Hiba a paraméteroldal olvasásakor! The Parameter Page is not supported. A paraméteroldal nem támogatott. Error reading ID! Hiba az azonosító olvasásakor! Programmer A is not connected! programozó nincs csatlakoztatva! Programmer CH341a is not connected! A CH341a programozó nincs csatlakoztatva! DialogNandSecurity Security registers Biztonsági regiszterek Hex Editor Hexa szerkesztő Operations: Műveletek: Reading security register data from the chip Biztonsági regiszter adatok kiolvasása a chipről ... ... Writing data to the security register Adatok írása a bitzonsági regiszterbe Open a binary file from a computer Bináris fájlt megnyitása a számítógépről Save the binary file on the computer Mentse el a bináris fájlt a számítógépére Security register number: Biztonsági regiszter száma: Error Hiba Error reading Parameter Page! Hiba a paraméteroldal olvasásakor! Programmer CH341a is not connected! A CH341a programozó nincs csatlakoztatva! Programmer A is not connected! programozó nincs csatlakoztatva! Open file Fájl megnyitása The file size exceeds the security register size. A fájl mérete meghaladja a biztonsági regiszter méretét. Save file Fájl mentése Error saving file! Hiba a fájl mentésekor! DialogRP Load block from file Blokk betöltése fájlból All values in HEX format! Minden érték HEX formátumban! Start address: Kezdőcím: Load Betöltés DialogSFDP Information about SFDP and status registers Információk az SFDP-ről és az állapotregiszterekről SFDP support: SFDP támogatás: Minimum VCC: Minimális VCC: Maximum VCC: Maximális VCC: Chip size: Chip mérete: Block size: Blokkméret: Speeds: Sebességek: OTP support: OTP támogatás: Status Register 0 Állapotregiszter 0 SPR0 SPR0 BP4 BP4 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 WEL WEL WIP WIP SUS1 SUS1 CMP CMP LB3 LB3 LB2 LB2 LB1 LB1 SUS2 SUS2 QE QE SPR1 SPR1 Status Register 1 Állapotregiszter 1 Status register 2 Állapotregiszter 2 JEDEC info: JEDEC infó: Man. ID Hers. Art Man. ID Man. type Man. típus Capacity Kapacitás Unique ID: Egyedi ID: Read Olvasás Write registers Írj regisztereket (R) (R) DRV1 DRV1 DRV0 DRV0 WPS WPS ADP ADP ADS ADS <html><head/><body><p/></body></html> <html><head/><body><p/></body></html> <html><head/><body><p>Legend:</p><p>** - Basic area<br>** - Extended area<br>** - Manufacture area </p></body></html> <html><head/><body><p>Jelmagyarázat:</p><p>** - Alapterület<br>** - Bővített terület<br>** - Gyártói terület </p></body ></html> Close Bezár Error Hiba Error reading register! Regiszter olvasás hiba! <html><head/><body><p> Hex SFDP register data: <html><head/><body><p> Hex SFDP regiszter adata: <html><head/><body><p>Addr:<br> <html><head/><body><p>Cłm:<br> Programmer A is not connected! programozó nincs csatlakoztatva! Before writing the registers, please press the `Read` button! A névjegyzékek írása előtt kérjük, nyomja meg az `Olvasás` gombot! Error reading JEDEC ID! JEDEC ID olvasási hiba! Legend: Jelmagyarázat: - Basic area - Alapterület - Extended area - Bővített terület - Manufacture area - Gyártói terület Error reading unique ID! Egyedi ID olvasási hiba! Programmer CH341a is not connected! A CH341a programozó nincs csatlakoztatva! DialogSP Save part of image Mentse el a kép egy részét All values in HEX format! Minden érték HEX formátumban! Start address: Kezdő cím: Save Mentés End address Végcím Length Hosszúság DialogSR Status register Állapotregiszter WPEN WPEN X X BP1 BP1 BP0 BP0 WEN WEN /RDY /RDY Read Olvasás Write Írás Error Hiba Error reading register! Regiszter olvasás hiba! Programmer A is not connected! programozó nincs csatlakoztatva! Programmer CH341a is not connected! A CH341a programozó nincs csatlakoztatva! Before writing the register, please press the `Read` button! A névjegyzékek írása előtt kérjük, nyomja meg az `Olvasás` gombot! DialogSecurity Security registers Biztonsági regiszterek Hex Editor Hexa szerkesztő Operations: Műveletek: Reading security register data from the chip Biztonsági regiszter adatok kiolvasása a chipről ... ... Erasing security register data Biztonsági regiszter adatok törlése Writing data to the security register Adatok írása a bitzonsági regiszterbe Open a binary file from a computer Bináris fájlt megnyitása a számítógépről Save the binary file on the computer Mentse el a bináris fájlt a számítógépére Security register number: Biztonsági regiszter száma: Error Hiba Error reading register! Regiszter olvasási hiba! Programmer CH341a is not connected! A CH341a programozó nincs csatlakoztatva! Programmer A is not connected! programozó nincs csatlakoztatva! Error writing register! Regiszter írási hiba! Open file Fájl megnyitása The file size exceeds the security register size. A fájl mérete meghaladja a biztonsági regiszter méretét. Save file Fájl mentése Error saving file! Hiba a fájl mentésekor! DialogSetAddr Goto address Goto cím All values in HEX format! Minden érték HEX formátumban! Address: Cím: Go to Menjen a MainWindow File Fájl Open Megnyitás Ctrl+O Ctrl+O Exit Kilépés Ctrl+X Ctrl+X Save Mentés IMSProg - I2C/MicroWire/SPI CH341a Programmer IMSProg - I2C/MicroWire/SPI CH341a programozó Chip Chip Name Név Page size Oldalméret Block size Blokkméret VCC, Volt VCC, Volt 4byte Addr. 4bájtos cím. Detect Felismerés Read Olvasás i i I2C bus speed I2C buszsebesség Erase size Törlés mérete ECC size ECC méret Auto Options Automatikus opciók Erase Törlés Program Program Verify Ellenőrzés Go! Rajta! Hex Editor Hexa szerkesztő JEDEC ID: JEDEC ID: CH341a: CH341a: border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; CRC32: CRC32: Message Üzenet Programmer Programozó Help Súgó Check erase Ellenőrzés törlése Ctrl+S Ctrl+S Ctrl+D Ctrl+P Ctrl+R Ctrl+R Ctrl+E Ctrl+S Write Írás Ctrl+W Ctrl+W Ctrl+T Ctrl+T Undo Visszavonás Ctrl+Z Ctrl+Z Redo Ismét Ctrl+Y Ctrl+Y Save Part Részlet mentése Load Part Részlet betöltése Find / Replace Keresés / Csere Ctrl+F Ctrl+F About Névjegy About IMSProgrammer IMS Programozó névjegye Ctrl+H Ctrl+H Checksum calculate Ellenőrző összeg kiszámítása Ctrl+A Ctrl+F Edit chips Database Chip-adatbázis szerkesztése Ctrl+Q Ctrl+Q Operations Műveletek Ctrl+N Ctrl+N Stop Megállítás Forced stop of read, write, erase and verification operations Az olvasási, írási, törlési és ellenőrzési műveletek kényszerített leállítása Ctrl+I Ctrl+I Chip info Chip infó Information about SFDP and status registers Információk az SFDP-ről és az állapotregiszterekről Ctrl+P Ctrl+P Import from Intel HEX Importálás Intel HEX-ből Export to Intel HEX Exportálás Intel HEX-be Extract from ASUS CAP Kivonat az ASUS CAP-ból Goto address Goto cím Move the cursor to the entered address Mozgassa a kurzort a beírt címre Ctrl+G Ctrl+G Security registers Biztonsági regiszterek Ctrl+U Ctrl+U Fill test image Tesztkép kitöltése Filling the hex editor with a test array A hexaszerkesztő kitöltése egy tesztmezővel Ctrl+L Ctrl+L Compare files Fájlok összehasonlítása Compares the results of the last and penultimate chip read or file open operation Összehasonlítja az utolsó és az utolsó előtti chipolvasási vagy fájlnyitási művelet eredményeit. Ctrl+M Ctrl+M Copy Másolás Paste Beillesztés Bad block management Hibás blokkok kezelése Ctrl+B Ctrl+B Show programmer version Programozói verzió megjelenítése Check erase chip Ellenőrizze a chip törlését Ctrl+J Ctrl+J Filling with code Kóddal való feltöltés Ctrl+K Ctrl+K CH341A/B v1.2 CH341A/B v1.2 CH341A v1.7 CH341A v1.7 CH347T v1.0 CH347T v1.0 CH347T v1.1 CH347T v1.1 CH347T CH347T Current file: Jelenlegi fájl: Type Típus Manufacture Gyártó Size Méret Opening DAT file DAT fájl megnyitása Error Hiba The end address must be greater than the starting address. A zárócímnek nagyobbnak kell lennie, mint a kezdőcím. File 'IMSProg_editor' not found! Nem található `IMSProg_editor` fájl! Error loading chip database file! Hiba a chip adatbázis fájl betöltésekor! Parsing DAT file DAT fájl feldolgozása Reading data from Adat olvasása innen Unsupported chip type! Nem támogatott chip típus! Programmer CH341a is not connected! A CH341a programozó nincs csatlakoztatva! Error reading block Blokk olvasási hiba Before reading from chip please press 'Detect' button. A chipről történő olvasás előtt nyomja meg az „Felismerés” gombot. Please select the chip parameters - manufacture and chip name Kérjük, válassza ki a chip paramétereit - a gyártást és a chip nevét The chip is not connect or missing! A chip nincs csatlakoztatva vagy hiányzik! Saving file Fájl mentése Save file Fájl mentése Data Images Adatfájlok All files Minden fájl Error saving file! Hiba a fájl mentésekor! Erasing the Törlése a(z) Error erasing sector Hiba a szektor törlésekor Opening file Fájl megnyitása Open file Fájlmegnyitás The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file. A fájl mérete meghaladja a chip méretét. Kérjük, válasszon egy másik chipet vagy fájlt, vagy használja a `Részlet mentése` lehetőséget a fájl felosztásához. The ending address must not exceed the buffer size. A végcím nem haladhatja meg a puffer méretét. Cannot find a chip database file. You may want to run IMSProg_database_update Nem található chip-adatbázis fájl. Érdemes futtatni az IMSProg_database_update parancsot Before working with the security registers, click the 'Detect' button A biztonsági regiszterekkel való munka előtt kattintson az „Felismerés” gombra There are no security registers in this chip or the current version of IMSProg does not support this algorithm. Ebben a chipben nincsenek biztonsági regiszterek, vagy az IMSProg jelenlegi verziója nem támogatja ezt az algoritmust. Intel HEX Images Intel HEX fájlok Not valid HEX format! Nem érvényes HEX formátum! The address is larger than the size of the chip! A cím nagyobb, mint a chip mérete! Checksum error! Checksum hiba! Writing data to Adat írása ide Programmer A is not connected! programozó nincs csatlakoztatva! Error writing sector Hiba a szektor írásakor Veryfing data from Adatok ellenőrzése innen Error comparing data! Address: Hiba az adatok összehasonlításakor! Cím: Buffer: Puffer: Chip: Chip: Please select the chip parameters - manufacture and chip name. Kérjük, válassza ki a chip paramétereit - a gyártót és a chip nevét. Ok! Ok! The operation was successful! A művelet sikeres volt! Saving block Blokk mentése Save block Blokk mentése Opening block Blokk megnyitása Open block Blokkmegnyitás The end address out of image size! A zárócím túllépi a kép méretét! Connected Csatlakozva Not connected Nincs kapcs Operation aborted! Művelet megszakítva! The chip database file was not found! A chip-adatbázis fájl nem található! Error loading chip database file! File: %1 Error Code: %2 Reason: %3 Hiba a chip-adatbázis fájl betöltése közben! Fájl: %1 Hibakód: %2 Ok: %3 Info: Információ: Device revision: Eszköz verziószáma: Erase checking in Ellenőrzés törlése Error erasing chip! Address: Hiba a chip törlése közben! Cím: Need: FF Szükséges: FF SearchDialog QHexEdit - Find/Replace QHexEdit - Keresés/Csere Find Keresés Hex Hexa UTF-8 UTF-8 Replace Csere Options Beállítások &Backwards &Visszafelé &Prompt on replace Me&gerősítés kérése minden csere előtt Standard headers: Alapértelmezett fejlécek: ZIP ZIP PNG PNG JPG JPG GIF GIF TAR TAR UEFI UEFI BIOS BIOS GPT GPT &Find &Keresés F3 F3 &Replace &Csere Replace &All Cserélje m&indet &Close &Bezárás QHexEdit QHexEdit %1 occurrences replaced. %1 előfordulás lecserélve. Replace occurrence? Előfordulás cseréje? UndoStack Inserting %1 bytes %1 bájt beszúrása Delete %1 chars %1 karakter törlése Overwrite %1 chars %1 karakter felülírása imsprog-1.8.5/IMSProg_programmer/language/chipProgrammer_it_IT.ts000066400000000000000000002650611520775651600251520ustar00rootroot00000000000000 DialogAbout About IMSProg Informazioni su IMSProg IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, and M95xx series chips. IMSProg è un software libero per EEPROM/Flash chip I2C, SPI e MicroWire per il programmatore CH341a. IMSProg supporta i chip della serie 24Cxx, 25xx, 93Cxx e M95xx. IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341A and CH347T devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - è un software gratuito per la programmazione di chip I2C, SPI e MicroWire EEPROM/Flash da utilizzare con i dispositivi CH341A e CH347T. IMSProg supporta i chip delle serie 24Cxx, 25xx, 93Cxx e M95xx. <html><head/><body><p>In this program <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget and modified programmer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> were used.</p><p>The page on GitHub is <a href="https://github.com/bigbigmdm/IMSProg">here</a>, the support page is <a href="https://antenna-dvb-t2.ru/IMSProg.php">here</a>. </p></body></html> <html><head/><body><p>In questo programma si usa il widget <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> ed il software <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> modificato.</p><p>La pagina GitHub è <a href="https://github.com/bigbigmdm/IMSProg">qui</a>, la pagina di supporto è <a href="https://antenna-dvb-t2.ru/IMSProg.php">qui</a>. </p></body></html> Written by 2023 - 2026 Mikhail Medvedev Scritto da Mikhail Medvedev nel 2023 -2026 Version: Versione: 1.1.4 1.1.4 OR OPPURE IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - è un software gratuito per la programmazione di chip I2C, SPI e MicroWire EEPROM/Flash da utilizzare con i dispositivi CH341a. IMSProg supporta i chip delle serie 24Cxx, 25xx, 93Cxx e M95xx. Written by 2023 Mikhail Medvedev Scritto da Mikhail Medvedev nel 2023 Close Chiudi DialogBBM Bad block management Gestione dei blocchi danneggiati Chip scan Scansione del chip No Numero Block Blocco Start address Indirizzo iniziale End address Indirizzo finale Check Controlla Settings Impostazioni Erasing Cancella Skip bad blocks during erase procedure (recommended) Ignora i blocchi danneggiati (consigliato) Don't skip bad blocks Non ignorare i blocchi danneggiati Writing Scrittura Write all blocks one to one (ignore bad blocks) Scrivi tutti i blocchi uno a uno (ignora danneggiati) Skip bad blocks during writing procedure Ignora i blocchi danneggiati durante la procedura di scrittura Ok Ok BBM table (Winbond) Tabella BBM (Winbond) This operation is used only in some Winbond chips. Questa operazione viene utilizzata solo in alcuni chip Winbond. Bad block Blocco danneggiato Changed block Blocco modificato Status Stato Read Leggi Error Errore Error reading chip! Si è verificato un errore durante la lettura del chip! Corrupted blocks found: Blocchi danneggiati trovati: All blocks in the chip are good! Tutti i blocchi nel chip sono integri! Programmer Il programmatore is not connected! non è connesso! Programmer CH341a is not connected! Il programmatore CH341a non è collegato! Not used Non utilizzato Active, valid Attivo, valido Active, not valid Attivo, non valido BBM table is not used in this chip. La tabella BBM non è utilizzata in questo chip. DialogCompare Comparing files: Confronto dei file: CRC32: CRC32: Name Nome CRC32: CRC32: Visible ASCII areas Aree ASCII visibili Name: Nome: DialogFill Fill the buffer with code Riempi il buffer con il codice All values in HEX format! Tutti i valori devono essere in formato HEX! Start address: Indirizzo di partenza: Filling code: Codice di riempimento: Fill Riempi End address Indirizzo finale Length Lunghezza DialogInfo Connection info: Informazioni connessione: Slot: Slot: - - Adapter: Adattatore: Close Chiudi DialogNANDSr Status registers Registri di stato Status register 1 Registro di stato 1 SRP0 SRP0 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 TB TB WP-E WP-E SRP1 SRP1 Status register 2 Registro di stato 2 OTP-L OTP-L OTP-E OTP-E SR1-L SR1-L ECC-E ECC-E BUF BUF (R) (R) Status register 3 Registro di stato 3 LUT-F LUT-F ECC-1 ECC-1 ECC-0 ECC-0 P-FAIL P-FAIL WELL WELL BUSY BUSY E_FAIL E_FAIL Status register 4 Registro di stato 4 --- --- Status register 5 Registro di stato 5 Unique ID: ID univoco: Read Leggi Write Scrivi Parameter page: Pagina dei parametri: Manufacturer: Produttore: Model: Modello: Page size: Dimensione pagina: ECC size: Dimensione ECC: Pages per block: Pagine per blocco: Block per unit: Blocchi per unità: Block size: Dimensione blocco: Chip size: Dimensione chip: Error Errore Error reading register! Si è verificato un errore durante la lettura del registro! Error reading Parameter Page! Si è verificato un errore durante la lettura della pagina dei parametri! The Parameter Page is not supported. La pagina dei parametri non è supportata. Error reading ID! Si è verificato un errore durante la lettura dell'ID! Programmer Il programmatore is not connected! non è connesso! Programmer CH341a is not connected! Il programmatore CH341a non è collegato! DialogNandSecurity Security registers Registri di sicurezza Hex Editor Editor esadecimale Operations: Operazioni: Reading security register data from the chip Lettura dal chip dei dati del registro di sicurezza ... ... Writing data to the security register Scrittura di dati nel registro di sicurezza Open a binary file from a computer Apri un file binario da un computer Save the binary file on the computer Salva un file binario su un computer Security register number: Numero del registro di sicurezza: Error Errore Error reading Parameter Page! Si è verificato un errore durante la lettura della pagina dei parametri! Programmer CH341a is not connected! Il programmatore CH341a non è collegato! Programmer Il programmatore is not connected! non è connesso! Open file Apri file The file size exceeds the security register size. La dimensione del file supera la dimensione del registro di sicurezza. Save file Salva file Error saving file! Si è verificato un errore durante il salvataggio del file! DialogRP Load block from file Carica blocco da file All values in HEX format! Tutti i valori devono essere in formato HEX! Start address: Indirizzo di partenza: Load Carica DialogSFDP Information about SFDP and status registers Informazioni sul SFDP e sui registri di stato SFDP support: Supporto SFDP: Minimum VCC: VCC minima: Maximum VCC: VCC massima: Chip size: Dimensione chip: Block size: Dimensione blocco: Speeds: Velocità: OTP support: Supporto OTP: Status Register 0 Registro di stato 0 SPR0 SPR0 BP4 BP4 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 WEL WEL WIP WIP SUS1 SUS1 CMP CMP LB3 LB3 LB2 LB2 LB1 LB1 SUS2 SUS2 QE QE SPR1 SPR1 Status Register 1 Registro di stato 1 Status register 2 Registro di stato 2 JEDEC info: Info JEDEC: Man. ID ID Prod Man. type Tipo prod Capacity Dimensione Unique ID: ID univoco: Read Leggi Write registers Scrivi registri (R) (R) DRV1 DRV1 DRV0 DRV0 WPS WPS ADP ADP ADS ADS <html><head/><body><p/></body></html> <html><head/><body><p/></body></html> <html><head/><body><p>Legend:</p><p>** - Basic area<br>** - Extended area<br>** - Manufacture area </p></body></html> <html><head/><body><body><p>Legenda:</p><p>** - Area base<br>** - Area estesa<br>** - Area produttore</p></body></html></html> Close Chiudi Error Errore Error reading register! Si è verificato un errore durante la lettura del registro! <html><head/><body><p> Hex SFDP register data: <html><head/><body><p> Dati HEX del registro SFDP: <html><head/><body><p>Addr:<br> <html><head/><body><p>Indirizzo:<br> Programmer Il programmatore is not connected! non è connesso! Before writing the registers, please press the `Read` button! Prima di scrivere i registri, premi il pulsante `Leggi`! Error reading JEDEC ID! Si è verificato un errore durante la lettura dell'ID JEDEC! Legend: Legenda: - Basic area - Area base - Extended area - Area estesa - Manufacture area - Area produttore Error reading unique ID! Si è verificato un errore durante la lettura dell'ID unico! Programmer CH341a is not connected! Il programmatore CH341a non è connesso! DialogSP Save part of image Salva parte dell'immagine All values in HEX format! Tutti i valori devono essere in formato HEX! Start address: Indirizzo di partenza: Save Salva End address Indirizzo finale Length Lunghezza DialogSR Status register Il programmatore CH341a non e' connesso Registro di stato WPEN WPEN X X BP1 BP1 BP0 BP0 WEN WEN /RDY /RDY Read Leggi Write Scrivi Error Errore Error reading register! Si è verificato un errore durante la lettura del registro! Programmer Il programmatore is not connected! non è connesso! Programmer CH341a is not connected! Il programmatore CH341a non è connesso! Before writing the register, please press the `Read` button! Prima di scrivere il registro, premi il pulsante `Leggi`! DialogSecurity Security registers Registri di sicurezza Hex Editor Editor esadecimale Operations: Operazioni: Reading security register data from the chip Lettura dei dati dei registri di sicurezza dal chip ... ... Erasing security register data Cancellazione dei dati dei registri di sicurezza Writing data to the security register Scrittura dei dati nel registro di sicurezza Open a binary file from a computer Apri un file binario da un computer Save the binary file on the computer Salva un file binario su un computer Security register number: Numero del registro di sicurezza: Error Errore Error reading register! Si è verificato un errore durante la lettura del registro! Programmer CH341a is not connected! Il programmatore CH341a non è connesso! Programmer Il programmatore is not connected! non è connesso! Error writing register! Si è verificato un errore durante la scrittura del registro! Open file Apri file The file size exceeds the security register size. La dimensione del file supera la dimensione del registro di sicurezza. Save file Salva file Error saving file! Si è verificato un errore durante il salvataggio del file! DialogSetAddr Goto address Vai all'indirizzo All values in HEX format! Tutti i valori devono essere in formato HEX! Address: Indirizzo: Go to Vai MainWindow File File Open Apri Ctrl+O Ctrl+O Exit Esci Ctrl+X Ctrl+X Save Salva IMSProg - I2C/MicroWire/SPI CH341a Programmer IMSProg - programatore I2C/MicroWire/SPI CH341a Chip Chip Name Nome Page size Dim. pagina Block size Dim. blocco VCC, Volt VCC, volt 4byte Addr. 4byte Indir. Detect Rileva Read Leggi i i I2C bus speed Velocità bus I2C Erase size Dimensione cancel. ECC size Dimensione ECC Auto Options Opzioni automatiche Erase Cancella Program Programma Verify Verifica Go! Vai! Hex Editor Editor esadecimale JEDEC ID: JEDEC ID: CH341a: CH341a: border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; CRC32: CRC32: Message Messaggio Programmer Programmatore Help Aiuto Operations Operazioni Check erase Verifica cancellazione Ctrl+S Ctrl+S Ctrl+D Ctrl+D Ctrl+R Ctrl+R Ctrl+E Ctrl+E Write Scrivi Ctrl+W Ctrl+W Ctrl+T Ctrl+T Undo Annulla Ctrl+Z Ctrl+Z Redo Ripristina Ctrl+Y Ctrl+Y Ctrl+N Ctrl+N Import from Intel HEX Importa da Intel HEX Export to Intel HEX Esporta in Intel HEX Extract from ASUS CAP Estrai dal CAP di ASUS Goto address Vai all'indirizzo Move the cursor to the entered address Sposta il cursore all'indirizzo inserito Ctrl+G Ctrl+G Security registers Registri di sicurezza Ctrl+U Ctrl+U Fill test image Riempi l'immagine di prova Filling the hex editor with a test array Riempi l'editor esadecimale con una matrice di prova Ctrl+L Ctrl+L Compare files Confronta i file Compares the results of the last and penultimate chip read or file open operation Confronta i risultati dell’ultima e della penultima operazione di lettura del chip o di apertura del file Ctrl+M Ctrl+M Copy Copia Paste Incolla Bad block management Gestione dei blocchi danneggiati Ctrl+B Ctrl+B Show programmer version Mostra versione del programma Check erase chip Verifica la cancellazione del chip Ctrl+J Ctrl+J Filling with code Riempimento con codice Ctrl+K Ctrl+K CH341A/B v1.2 CH341A/B v1.2 CH341A v1.7 CH341A v1.7 CH347T v1.0 CH347T v1.0 CH347T v1.1 CH347T v1.1 CH347T CH347T Save Part Salva parte Load Part Carica parte Find / Replace Trova / Sostituisci Ctrl+F Ctrl+F About Informazioni About IMSProgrammer Informazioni su IMSProgrammer Ctrl+H Ctrl+H Checksum calculate Calcola checksum Ctrl+A Ctrl+A Edit chips Database Modifica il database dei chip Ctrl+Q Ctrl+Q Stop Ferma Forced stop of read, write, erase and verification operations Arresto forzato delle operazioni di lettura, scrittura, cancellazione e verifica Ctrl+I Ctrl+I Chip info Informazioni sul chip Information about SFDP and status registers Informazioni su SFDP e registri di stato Ctrl+P Ctrl+P Current file: File attuale: Type Tipo Manufacture Produttore Size Dimensione Opening DAT file Apertura in corso del file DAT Error Errore The end address must be greater than the starting address. L'indirizzo finale deve essere maggiore dell'indirizzo iniziale. File 'IMSProg_editor' not found! 'IMSProg_editor' non è stato trovato! Error loading chip database file! Si è verificato un errore durante l'apertura del database dei chip! Parsing DAT file Analisi archivio DAT in corso Reading data from Lettura dati in corso da Unsupported chip type! Chip non supportato! Programmer CH341a is not connected! Il programatore CH341a non è connesso! Error reading block Si è verificato un errore durante la lettura del blocco Before reading from chip please press 'Detect' button. Prima di leggere il chip, premere il pulsante 'Rileva'. Please select the chip parameters - manufacture and chip name Seleziona i parametri del chip: produttore e nome del chip The chip is not connect or missing! Il chip non è collegato oppure è mancante! Saving file Salvataggio file in corso Save file Salva file Data Images File di dati All files Tutti i file Error saving file! Si è verificato un errore durante il salvataggio del file! Erasing the Cancellazione in corso di Error erasing sector Si è verificato un errore durante la cancellazione del settore Opening file Apertura del file in corso Open file Apri file The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file. La dimensione del file supera quella del chip. Selezionare un altro chip o un altro file oppure utilizzare `Salva parte` per dividere il file. The ending address must not exceed the buffer size. L'indirizzo finale non deve superare la dimensione del buffer. Cannot find a chip database file. You may want to run IMSProg_database_update Impossibile trovare un file del database dei chip. Si consiglia di eseguire IMSProg_database_update Before working with the security registers, click the 'Detect' button Prima di lavorare con i registri di sicurezza, fai clic sul pulsante 'Rileva' There are no security registers in this chip or the current version of IMSProg does not support this algorithm. Non ci sono registri di sicurezza in questo chip o la versione attuale di IMSProg non supporta questo algoritmo. Intel HEX Images File Intel HEX Not valid HEX format! Formato HEX non valido! The address is larger than the size of the chip! L'indirizzo è più grande della dimensione del chip! Checksum error! Si è verificato un errore di checksum! Writing data to Scrittura dati in corso su Programmer Il programmatore is not connected! non è connesso! Error writing sector Si è verificato un errore durante la scrittura del settore Veryfing data from Verifica dati in corso da Error comparing data! Address: Si è verificato un errore durante il confronto dei dati! Indirizzo: Buffer: Buffer: Chip: Chip: Please select the chip parameters - manufacture and chip name. Seleziona i parametri del chip: produttore e nome del chip. Ok! Ok! The operation was successful! Operazione completata! Saving block Salvataggio del blocco in corso Save block Salva blocco Opening block Apertura del blocco in corso Open block Apri blocco The end address out of image size! L’indirizzo finale supera la dimensione dell’immagine! Connected Connesso Not connected Non connesso Operation aborted! L'operazione è stata annullata! The chip database file was not found! Il file del database dei chip non è stato trovato! Error loading chip database file! File: %1 Error Code: %2 Reason: %3 Errore durante il caricamento del file del database dei chip! File: %1 Codice errore: %2 Motivo: %3 Info: Informazioni: Device revision: Revisione del dispositivo: Erase checking in Verifica cancellazione in Error erasing chip! Address: Errore durante la cancellazione del chip! Indirizzo: Need: FF Richiesto: FF SearchDialog QHexEdit - Find/Replace QHexEdit - Trova/Sostituisci Find Trova Hex Hex UTF-8 Replace Sostituisci Options Opzioni &Backwards &Indietro &Prompt on replace &Chiedi conferma prima di sostituire Standard headers: Header standard: ZIP ZIP PNG PNG JPG JPG GIF GIF TAR TAR UEFI UEFI BIOS BIOS GPT GPT &Find &Trova F3 F3 &Replace &Sostituisci Replace &All S&ostituisci tutto &Close &Chiudi QHexEdit QHexEdit %1 occurrences replaced. %1 occorrenze sostituite. Replace occurrence? Sostituire occorrenza? UndoStack Inserting %1 bytes Inserimento in corso di %1 byte Delete %1 chars Eliminati %1 caratteri Overwrite %1 chars Sovrascritti %1 caratteri imsprog-1.8.5/IMSProg_programmer/language/chipProgrammer_pt_BR.ts000066400000000000000000002627421520775651600251530ustar00rootroot00000000000000 DialogAbout About IMSProg Sobre IMSProg IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, and M95xx series chips. IMSProg - software livre I2C, SPI e MicroWire EEPROM/Flash chip programador para dispositivos CH341a. IMSProg admite chips das séries 24Cxx, 25xx, 93Cxx e M95xx. IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341A and CH347T devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - software livre I2C, SPI e MicroWire EEPROM/Flash chip programador para dispositivos CH341A e CH347T. IMSProg suporta chips das séries 24Cxx, 25xx, 93Cxx, AT45DBxx e M95xx. <html><head/><body><p>In this program <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget and modified programmer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> were used.</p><p>The page on GitHub is <a href="https://github.com/bigbigmdm/IMSProg">here</a>, the support page is <a href="https://antenna-dvb-t2.ru/IMSProg.php">here</a>. </p></body></html> <html><head/><body><p>Neste programa utilizou-se o widget <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> e o programador <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> modificado.</p><p>A página do GitHub está <a href="https://github.com/bigbigmdm/IMSProg">aqui</a>, e a página de suporte está <a href="https://antenna-dvb-t2.ru/IMSProg.php">aqui</a>. </p></body></html> Written by 2023 - 2026 Mikhail Medvedev Escrito por Mikhail Medvedev 2023 - 2026 Version: Versão: 1.1.4 1.1.4 OR OU IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - software livre I2C, SPI e MicroWire EEPROM/Flash chip programador para dispositivos CH341a. IMSProg suporta chips das séries 24Cxx, 25xx, 93Cxx, AT45DBxx e M95xx. Written by 2023 Mikhail Medvedev Escrito por Mikhail Medvedev 2023 Close Fechar DialogBBM Bad block management Gerenciamento de blocos defeituosos Chip scan Leitura do chip No Número Block Bloco Start address Endereço inicial End address Endereço final Check Verificar Settings Configurações Erasing Apagar Skip bad blocks during erase procedure (recommended) Ignorar blocos defeituosos (recomendado) Don't skip bad blocks Não ignore blocos defeituosos Writing Programar Write all blocks one to one (ignore bad blocks) Grave todos os blocos um a um (ignore os blocos defeituosos) Skip bad blocks during writing procedure Ignorar blocos danificados durante a gravação Ok Ok BBM table (Winbond) Tabela BBM (Winbond) This operation is used only in some Winbond chips. Esta operação é utilizada apenas em alguns chips Winbond. Bad block Bloco defeituoso Changed block Bloco alterado Status Status Read Ler Error Erro Error reading chip! Erro ao ler o chip! Corrupted blocks found: Blocos corrompidos encontrados: All blocks in the chip are good! Todos os blocos do chip estão em bom estado! Programmer Programador is not connected! não está conectado! Programmer CH341a is not connected! O programador CH341a não está conectado! Not used Não utilizado Active, valid Ativo, válido Active, not valid Ativo, não válido BBM table is not used in this chip. A tabela BBM não é utilizada neste chip. DialogCompare Comparing files: Comparação de arquivos: CRC32: CRC32: Name Nome CRC32: CRC32: Visible ASCII areas Mostrar áreas ASCII Name: Nome: DialogFill Fill the buffer with code Preencha o buffer com código All values in HEX format! Todos os valores em formato HEX! Start address: Endereço de início: Filling code: Preenchimento código: Fill Preencher End address Endereço final Length Comprimento DialogInfo Connection info: Informação de conexão: Slot: Slot: - - Adapter: Adaptador: Close Fechar DialogNANDSr Status registers Registros de status Status register 1 Registro de status 1 SRP0 SRP0 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 TB TB WP-E WP-E SRP1 SRP1 Status register 2 Registro de status 2 OTP-L OTP-L OTP-E OTP-E SR1-L SR1-L ECC-E ECC-E BUF BUF (R) (R) Status register 3 Registro de status 3 LUT-F LUT-F ECC-1 ECC-1 ECC-0 ECC-0 P-FAIL P-FAIL WELL WELL BUSY BUSY E_FAIL E_FAIL Status register 4 Registro de status 4 --- --- Status register 5 Registro de status 5 Unique ID: ID único: Read Ler Write Programar Parameter page: Página de parâmetros: Manufacturer: Fabricante: Model: Modelo: Page size: Tamanho de página: ECC size: Tamanho ECC: Pages per block: Páginas por bloco: Block per unit: Bloco por unidade: Block size: Tamanho do bloco: Chip size: Tamanho do chip: Error Erro Error reading register! Erro ao ler o registro! Error reading Parameter Page! Erro ao ler a página de parâmetros! The Parameter Page is not supported. A página Parâmetros não é compatível. Error reading ID! Erro ao ler o ID! Programmer Programador is not connected! não está conectado! Programmer CH341a is not connected! O programador CH341a não está conectado! DialogNandSecurity Security registers Registros de segurança Hex Editor Editor hexadecimal Operations: Operações Reading security register data from the chip Lendo dados do registro de segurança do chip ... ... Writing data to the security register Gravando dados no registro de segurança Open a binary file from a computer Abra um arquivo binário do computador Save the binary file on the computer Salvar arquivo binário no computador Security register number: Número do registro de segurança: Error Erro Error reading Parameter Page! Erro ao ler a página de parâmetros! Programmer CH341a is not connected! O programador CH341a não está conectado! Programmer Programador is not connected! não está conectado! Open file Abrir arquivo The file size exceeds the security register size. O tamanho do arquivo excede o tamanho do registro de segurança. Save file Salvar arquivo Error saving file! Erro salvando arquivo! DialogRP Load block from file Carregar bloco de arquivo All values in HEX format! Todos os valores em formato HEX! Start address: Endereço de início: Load Carregar DialogSFDP Information about SFDP and status registers Informações sobre SFDP e registros de status SFDP support: Suporte SFDP: Minimum VCC: VCC mínimo: Maximum VCC: VCC máximo: Chip size: Tamanho do chip: Block size: Tamanho do bloco: Speeds: Velocidades: OTP support: Suporte OTP: Status Register 0 Registro de status 0 SPR0 SPR0 BP4 BP4 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 WEL WEL WIP WIP SUS1 SUS1 CMP CMP LB3 LB3 LB2 LB2 LB1 LB1 SUS2 SUS2 QE QE SPR1 SPR1 Status Register 1 Registro de status 1 Status register 2 Registro de status 2 JEDEC info: Informações JEDEC: Man. ID ID Fabr. Man. type Tipo Fabr. Capacity Capacidade Unique ID: ID único: Read Ler Write registers Gravar registros (R) (R) DRV1 DRV1 DRV0 DRV0 WPS WPS ADP ADP ADS ADS <html><head/><body><p/></body></html> <html><head/><body><p/></body></html> <html><head/><body><p>Legend:</p><p>** - Basic area<br>** - Extended area<br>** - Manufacture area </p></body></html> <html><head/><body><body><p>Legenda:</p><p>** - Zona básica<br>** - Zona ampliada<br>** - Zona de fabricação</p></body></html></html> Close Fechar Error Erro Error reading register! Erro ao ler o registro! <html><head/><body><p> Hex SFDP register data: <html><head/><body><p> Dados de registro hexadecimal SFDP: <html><head/><body><p>Addr:<br> <html><head/><body><p>Addr:<br> Programmer Programador is not connected! não está conectado! Before writing the registers, please press the `Read` button! Antes de escrever os registros, favor pressionar o botão `Ler`! Error reading JEDEC ID! Erro ao ler o ID JEDEC! Legend: Legenda: - Basic area - Zona básica - Extended area - Zona ampliada - Manufacture area - Zona de fabricação Error reading unique ID! Erro ao ler o ID único! Programmer CH341a is not connected! O programador CH341a não está conectado! DialogSP Save part of image Salvar parte da imagem All values in HEX format! Todos os valores em formato HEX! Start address: Endereço de início: Save Salvar End address Endereço final Length Comprimento DialogSR Status register Registro de status WPEN WPEN X X BP1 BP1 BP0 BP0 WEN WEN /RDY /RDY Read Ler Write Programar Error Erro Error reading register! Erro ao ler o registro! Programmer Programador is not connected! não está conectado! Programmer CH341a is not connected! O programador CH341a não está conectado! Before writing the register, please press the `Read` button! Antes de escrever os registro, favor pressionar o botão `Ler`! DialogSecurity Security registers Registros de segurança Hex Editor Editor hexadecimal Operations: Operações Reading security register data from the chip Lendo dados do registro de segurança do chip ... ... Erasing security register data Apagando dados de registros de segurança Writing data to the security register Gravando dados no registro de segurança Open a binary file from a computer Abra um arquivo binário do computador Save the binary file on the computer Salvar arquivo binário no computador Security register number: Número do registro de segurança: Error Erro Error reading register! Erro ao ler o registro! Programmer CH341a is not connected! O programador CH341a não está conectado! Programmer Programador is not connected! não está conectado! Error writing register! Erro escrevendo o registro! Open file Abrir arquivo The file size exceeds the security register size. O tamanho do arquivo excede o tamanho do registro de segurança. Save file Salvar arquivo Error saving file! Erro salvando arquivo! DialogSetAddr Goto address Ir para o endereço All values in HEX format! Todos os valores em formato HEX! Address: Endereço: Go to Ir para MainWindow File Arquivo Open Abrir Ctrl+O Ctrl+O Exit Sair Ctrl+X Ctrl+X Save Salvar IMSProg - I2C/MicroWire/SPI CH341a Programmer IMSProg - Programador I2C/MicroWire/SPI CH341a Chip Chip Name Nome Page size Tamanho de página Block size Tamanho do bloco VCC, Volt VCC, Volts 4byte Addr. Endereço 4bytes. Detect Detectar Read Ler i i I2C bus speed Velocidade do I2C Erase size Apagar tamanho ECC size Tamanho ECC Auto Options Opções automáticas Erase Apagar Program Programar Verify Verificar Go! Ir! Hex Editor Editor hexadecimal JEDEC ID: JEDEC ID CH341a: CH341a: border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; CRC32: CRC32: Message Mensagem Programmer Programador Help Ajuda Operations Operações Check erase Verificar apagamento Ctrl+S Ctrl+S Ctrl+D Ctrl+D Ctrl+R Ctrl+R Ctrl+E Ctrl+E Write Programar Ctrl+W Ctrl+W Ctrl+T Ctrl+T Undo Desfazer Ctrl+Z Ctrl+Z Redo Refazer Ctrl+Y Ctrl+Y Ctrl+N Ctrl+N Import from Intel HEX Importar de Intel HEX Export to Intel HEX Exportar para Intel HEX Extract from ASUS CAP Extrair do CAP da ASUS Goto address Ir para o endereço Move the cursor to the entered address Mova o cursor para o endereço inserido Ctrl+G Ctrl+G Security registers Registros de segurança Ctrl+U Ctrl+U Fill test image Preencher imagem de teste Filling the hex editor with a test array Preenchimento do editor hexadecimal com uma matriz de teste Ctrl+L Ctrl+L Compare files Comparar arquivos Compares the results of the last and penultimate chip read or file open operation Compara os resultados da última e penúltima operação de leitura de chip ou de abertura de arquivo. Ctrl+M Ctrl+M Copy Copiar Paste Colar Bad block management Gerenciamento de blocos defeituosos Ctrl+B Ctrl+B Show programmer version Mostrar versão do programador Check erase chip Verificar se o chip foi apagado Ctrl+J Ctrl+J Filling with code Preenchimento com código Ctrl+K Ctrl+K CH341A/B v1.2 CH341A/B v1.2 CH341A v1.7 CH341A v1.7 CH347T v1.0 CH347T v1.0 CH347T v1.1 CH347T v1.1 CH347T CH347T Save Part Salvar Parte Load Part Carregar parte Find / Replace Localizar / Substituir Ctrl+F Ctrl+F About Sobre About IMSProgrammer Sobre IMSProgrammer Ctrl+H Ctrl+H Checksum calculate Cálculo de Checksum Ctrl+A Ctrl+A Edit chips Database Editar banco de dados de chips Ctrl+Q Ctrl+Q Stop Parar Forced stop of read, write, erase and verification operations Parada forçada de operações de leitura, gravação, apagamento e verificação Ctrl+I Ctrl+I Chip info Informações do chip Information about SFDP and status registers Informações sobre SFDP e registros de status Ctrl+P Ctrl+P Current file: Arquivo atual: Type Tipo Manufacture Fabricação Size Tamanho Opening DAT file Abrindo um arquivo DAT Error Erro The end address must be greater than the starting address. O endereço final deve ser maior que o endereço inicial. File 'IMSProg_editor' not found! Arquivo não encontrado `IMSProg_editor`! Error loading chip database file! Erro ao carregar o arquivo de banco de dados do chip! Parsing DAT file Analisando arquivo DAT Reading data from Lendo dados de Unsupported chip type! Chip não suportado! Programmer CH341a is not connected! O programador CH341a não está conectado! Error reading block Erro ao ler o bloco Before reading from chip please press 'Detect' button. Antes de ler o chip, clique no botão 'Detectar'. Please select the chip parameters - manufacture and chip name Selecione os parâmetros do chip - Fabricante e nome do chip The chip is not connect or missing! Chip não conectado ou ausente! Saving file Salvando arquivo Save file Salvar arquivo Data Images Arquivos de dados All files Todos os arquivos Error saving file! Erro salvando arquivo! Erasing the Apagando o Error erasing sector Erro apagando setor Opening file Abrindo arquivo Open file Abrir arquivo The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file. O tamanho do arquivo excede o tamanho do chip. Selecione outro chip ou arquivo ou use `Salvar Parte` para dividir o arquivo. The ending address must not exceed the buffer size. O endereço final não deve exceder o tamanho do buffer. Cannot find a chip database file. You may want to run IMSProg_database_update Não foi possível localizar um arquivo de banco de dados de chips. Recomenda-se executar o IMSProg_database_update Before working with the security registers, click the 'Detect' button Antes de trabalhar com os registros de segurança, clique no botão 'Detectar' There are no security registers in this chip or the current version of IMSProg does not support this algorithm. Não há registros de segurança neste chip ou a versão atual do IMSProg não suporta este algoritmo. Intel HEX Images Arquivos Intel HEX Not valid HEX format! O formato HEX não é válido! The address is larger than the size of the chip! O endereço é maior do que o tamanho do chip! Checksum error! Erro de checksum! Writing data to Escrevendo dados em Programmer Programador is not connected! não está conectado! Error writing sector Erro ao escrever o setor Veryfing data from Verificando dados de Error comparing data! Address: Erro ao comparar dados! Endereço: Buffer: Buffer: Chip: Chip: Please select the chip parameters - manufacture and chip name. Selecione os parâmetros do chip - Fabricante e nome do chip. Ok! Ok! The operation was successful! Operação concluida com êxito! Saving block Salvando bloco Save block Salvar bloco Opening block Abrindo bloco Open block Bloco aberto The end address out of image size! Endereço final fora do tamanho da imagem! Connected Conectado Not connected Desconectado Operation aborted! Operação abortada! The chip database file was not found! O arquivo do banco de dados de chips não foi encontrado! Error loading chip database file! File: %1 Error Code: %2 Reason: %3 Erro ao carregar o arquivo do banco de dados de chips! Arquivo: %1 Código de erro: %2 Motivo: %3 Info: Informações: Device revision: Revisão do dispositivo: Erase checking in Verificando apagamento em Error erasing chip! Address: Erro ao apagar o chip! Endereço: Need: FF Necessário: FF SearchDialog QHexEdit - Find/Replace QHexEdit - Buscar/Substituir Find Encontrar Hex Hex UTF-8 Replace Substituir Options Opções &Backwards Voltar ao início &Prompt on replace Perguntar ao substituir Standard headers: Cabeçalhos padrão: ZIP ZIP PNG PNG JPG JPG GIF GIF TAR TAR UEFI UEFI BIOS BIOS GPT GPT &Find Encontrar F3 F3 &Replace Substituir Replace &All Substituir tudo &Close Fechar QHexEdit QHexEdit %1 occurrences replaced. %1 ocorrências substituídas. Replace occurrence? Substituir ocorrência? UndoStack Inserting %1 bytes Inserir %1 bytes Delete %1 chars Deletar %1 caracteres Overwrite %1 chars Substituir %1 caracteres imsprog-1.8.5/IMSProg_programmer/language/chipProgrammer_ru_RU.ts000066400000000000000000002755101520775651600251760ustar00rootroot00000000000000 DialogAbout About IMSProg О программе IMSProg IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, and M95xx series chips. IMSProg - это свободно распространяемая программа для программатора CH341a, поддерживающая микросхемы типов I2C, SPI NOR Flash и MicroWire. IMSProg поддерживает работу с 24Cxx, 25xxx, 93Cxx, M95xxx сериями микросхем IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341A and CH347T devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - это свободно распространяемая программа для программаторов CH341A и CH347T, поддерживающая микросхемы типов I2C, SPI NOR Flash и MicroWire. IMSProg поддерживает работу с 24Cxx, 25xxx, 93Cxx, AT45DBxx, M95xxx сериями микросхем. <html><head/><body><p>In this program <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget and modified programmer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> were used.</p><p>The page on GitHub is <a href="https://github.com/bigbigmdm/IMSProg">here</a>, the support page is <a href="https://antenna-dvb-t2.ru/IMSProg.php">here</a>. </p></body></html> <html><head/><body><p>В этой программе используется виджет <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> и модифицированный код программы <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> .</p><p>Страница на GitHub находится <a href="https://github.com/bigbigmdm/IMSProg">здесь</a>, страница поддержки - <a href="https://antenna-dvb-t2.ru/IMSProg.php">здесь</a>. </p></body></html> Written by 2023 - 2026 Mikhail Medvedev Создано в 2023 - 2026 годах Михаилом Медведевым Version: Версия: 1.1.4 1.1.4 OR или IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - это свободно распространяемая программа для программатора CH341a, поддерживающая микросхемы типов I2C, SPI NOR Flash и MicroWire. IMSProg поддерживает работу с 24Cxx, 25xxx, 93Cxx, AT45DBxx, M95xxx сериями микросхем. Written by 2023 Mikhail Medvedev Создано в 2023 году Михаилом Медведевым Close Закрыть DialogBBM Bad block management Управление плохими блоками Chip scan Сканировать МС No Block Блок Start address Старт. адрес: End address Кон. адрес Check Проверить Settings Параметры Erasing Стирание Skip bad blocks during erase procedure (recommended) Пропускать дефектные блоки (рекомендуется) Don't skip bad blocks Не пропускать дефектные блоки Don't skip bad sectors Не пропускать дефектные блоки Writing Запись Write all blocks one to one (ignore bad blocks) Записывать один в один (игнорировать плохие блоки) Skip bad blocks during writing procedure Пропускать плохие блоки при записи Ok Ok BBM table (Winbond) BBM таблица (Winbond) This operation is used only in some Winbond chips. Эта операция используется только для некоторых МС Winbond Bad block Плохой блок Changed block Блок для замены Status Статус Read Считать Error Ошибка Error reading chip! Ошибка чтения МС! Corrupted blocks found: Найдены дефектные блоки: All blocks in the chip are good! Все блоки в МС хорошие! Programmer Программатор is not connected! не подключен! Programmer CH341a is not connected! Программатор CH341a не подключен! Not used Не использ. Active, valid Активн., использ. Active, not valid Активн., не использ. BBM table is not used in this chip. Таблица BBM не используется в данной МС. DialogCompare Comparing files: Сравнение файлов: CRC32: CRC32: Name Назв. CRC32: CRC32: Visible ASCII areas Показать области ASCII Name: Имя: DialogFill Fill the buffer with code Заполенние буфера кодом All values in HEX format! Все данные шестнадцатеричные Start address: Filling code: Код заполнения: Fill Заполнить End address Кон. адрес Length Длина DialogInfo Connection info: Информ. о подключении: Slot: Слот: - - Adapter: Адаптер: Close Закрыть DialogNANDSr Status registers Регистры статуса Status register 1 Регистр статуса 1: SRP0 SRP0 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 TB TB WP-E WP-E SRP1 SRP1 Status register 2 Регистр статуса 2: OTP-L OTP-L OTP-E OTP-E SR1-L SR1-L ECC-E ECC-E BUF BUF (R) (R) Status register 3 Регистр статуса 3: LUT-F LUT-F ECC-1 ECC-1 ECC-0 ECC-0 P-FAIL P-FAIL WELL WELL BUSY BUSY E_FAIL E_FAIL Status register 4 Регистр статуса 4: --- --- Status register 5 Регистр статуса 5: Unique ID: ID микросхемы: Read Считать Write Записать Parameter page: Страница параметров: Manufacturer: Производитель: Model: Модель: Page size: Размер листа: ECC size: Размер ECC: Pages per block: Листов в блоке: Block per unit: Блоков в микросхеме: Block size: Размер блока: Chip size: Объем МС: Error Ошибка Error reading register! Ошибка чтения регистра! Error reading Parameter Page! Ошибка чтения страницы параметров! The Parameter Page is not supported. Страница параметров не поддерживается! Error reading ID! Ошибка чтения ID! Programmer Программатор is not connected! не подключен! Programmer CH341a is not connected! Программатор CH341a не подключен! DialogNandSecurity Security registers Регистры безопасности Hex Editor HEX-редактор Operations: Операции: Reading security register data from the chip Чтение данных регистра безопасности из микросхемы ... ... Writing data to the security register Запись данных в регистр безопасности Open a binary file from a computer Открыть двоичный файл с компьютера Save the binary file on the computer Сохранить двоичный файл на компьютере Security register number: Номер регистра безопасности: Error Ошибка Error reading Parameter Page! Ошибка чтения страницы параметров! Programmer CH341a is not connected! Программатор CH341a не подключен! Programmer Программатор is not connected! не подключен! Open file Открыть файл The file size exceeds the security register size. Размер файла превышает размер регистра безопасности. Save file Сохранить файл Error saving file! Ошибка сохранения файла! DialogRP Load block from file Загрузить блок из файла All values in HEX format! Все данные шестнадцатеричные Start address: Стартовый адрес: Load Загрузить DialogSFDP Information about SFDP and status registers Информация о SFDP и регистрах статуса SFDP support: Поддержка SFDP Minimum VCC: Мин. VCC: Maximum VCC: Макс. VCC: Chip size: Объем МС: Block size: Размер блока: Speeds: Режимы: OTP support: Поддержка OTP: Status Register 0 Регистр статуса 0: SPR0 SPR0 BP4 BP4 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 WEL WEL WIP WIP SUS1 SUS1 CMP CMP LB3 LB3 LB2 LB2 LB1 LB1 SUS2 SUS2 QE QE SPR1 SPR1 Status Register 1 Регистр статуса 1: Status register 2 Регистр статуса 2: JEDEC info: JEDEC информ.: Man. ID ID произв. Man. type Тип произв. Capacity Объем Unique ID: ID микросхемы Read Считать Write registers Записать регистры (R) (R) DRV1 DRV1 DRV0 DRV0 WPS WPS ADP ADP ADS ADS <html><head/><body><p/></body></html> <html><head/><body><p/></body></html> <html><head/><body><p>Legend:</p><p>** - Basic area<br>** - Extended area<br>** - Manufacture area </p></body></html> <html><head/><body><p>Обозначения:</p><p>** - Основная область<br>** - Дополнит. область<br>** - Область производителя </p></body></html> Close Закрыть Error Ошибка Error reading register! Ошибка чтения регистра! <html><head/><body><p> Hex SFDP register data: <html><head/><body><p> Данные области SFDP: <html><head/><body><p>Addr:<br> <html><head/><body><p>Адр.<br> Programmer Программатор is not connected! не подключен! Before writing the registers, please press the `Read` button! Перез записью, пожалуйста, нажмите кнопку `Считать`! Error reading JEDEC ID! Ошибка чтения JEDEC ID! Legend: Обозначения: - Basic area - Основная область - Extended area - Дополнит. область - Manufacture area - Область производителя Error reading unique ID! Ошибка чтения ID микросхемы! Programmer CH341a is not connected! Программатор CH341a не подключен! DialogSP Save part of image Сохранить часть прошивки All values in HEX format! Все данные шестнадцатеричные Start address: Стартовый адрес Save Сохранить End address Кон. адрес Length Длина DialogSR Status register Регистр статуса WPEN WPEN X X BP1 BP1 BP0 BP0 WEN WEN /RDY /RDY Read Считать Write Записать Error Ошибка Error reading register! Ошибка чтения регистра! Programmer Программатор is not connected! не подключен! Programmer CH341a is not connected! Программатор CH341a не подключен! Before writing the register, please press the `Read` button! Перез записью, пожалуйста, нажмите кнопку `Считать`! DialogSecurity Security registers Регистры безопасности Hex Editor HEX-редактор Operations: Операции: Reading security register data from the chip Чтение данных регистра безопасности из микросхемы ... ... Erasing security register data Стирание данных регистра безопасности Writing data to the security register Запись данных в регистр безопасности Open a binary file from a computer Открыть двоичный файл с компьютера Save the binary file on the computer Сохранить двоичный файл на компьютере Security register number: Номер регистра безопасности: Error Ошибка Error reading register! Ошибка чтения регистра! Programmer CH341a is not connected! Программатор CH341a не подключен! Programmer Программатор is not connected! не подключен! Error writing register! Ошибка записи регистра! Open file Открыть файл The file size exceeds the security register size. Размер файла превышает размер регистра безопасности. Save file Сохранить файл Error saving file! Ошибка сохранения файла! DialogSetAddr Goto address Перейти на адрес All values in HEX format! Все данные шестнадцатеричные Address: Адрес: Go to Перейти MainWindow File Файл Open Открыть Ctrl+O Ctrl+O Exit Выход Ctrl+X Ctrl+X Save Сохранить IMSProg - I2C/MicroWire/SPI CH341a Programmer IMSProg - I2C/MicroWire/SPI программатор для CH341a Chip Микросхема Name Название Page size Размер листа Block size Размер блока VCC, Volt Питание, В 4byte Addr. 4byte адрес Detect Поиск Read Считать i i I2C bus speed Скор. шины I2C Erase size Размер стирания ECC size Размер ECC Auto Options Авто опции Erase Стереть Program Записать Verify Проверить Go! Старт! Hex Editor HEX-редактор JEDEC ID: JEDEC ID: CH341a: CH341a: border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; CRC32: CRC32: Message Сообщение Programmer Программатор Help Справка Operations Операции Check erase Контроль стирания Ctrl+S Ctrl+S Ctrl+D Ctrl+D Ctrl+R Ctrl+R Ctrl+E Ctrl+E Write Записать Ctrl+W Ctrl+W Ctrl+T Ctrl+T Undo Назад Ctrl+Z Ctrl+Z Redo Повтор Ctrl+Y Ctrl+Y Ctrl+N Ctrl+N Import from Intel HEX Импорт из Intel HEX Export to Intel HEX Экспорт в Intel HEX Extract from ASUS CAP Извлечь из ASUS CAP Goto address Перейти на адрес Move the cursor to the entered address Перемещает курсор на введенный адрес Ctrl+G Ctrl+G Security registers Регистры безопасности Ctrl+U Ctrl+U Fill test image Заполнение тест-массивом Filling the hex editor with a test array Заполнение шестнадцатеричного редактора тестовым массивом Ctrl+L Ctrl+L Compare files Сравнение файлов Compares the results of the last and penultimate chip read or file open operation Сравнивает результаты последней и предпоследней операции чтения микросхемы или открытия файла. Ctrl+M Ctrl+M Copy Копировать Paste Вставить Bad block management Управлен. плохими блоками Ctrl+B Ctrl+B Show programmer version Версия программатора Check erase chip Контроль стирания Ctrl+J Ctrl+J Ctrl+J Filling with code Заполенние кодом Ctrl+K Ctrl+K CH341A/B v1.2 CH341A/B v1.2 CH341A v1.7 CH341A v1.7 CH347T v1.0 CH347T v1.0 CH347T v1.1 CH347T v1.1 CH347T CH347T Save Part Сохранить часть Load Part Загрузить часть Find / Replace Поиск/замена Ctrl+F Ctrl+F About О программе About IMSProgrammer О программе IMSProg Ctrl+H Ctrl+H Checksum calculate Пересчет CRC32 Ctrl+A Ctrl+A Edit chips Database Редактор базы микросхем Ctrl+Q Ctrl+Q Stop Стоп Forced stop of read, write, erase and verification operations Принудительная остановка операций чтения, записи, стирания и проверки Ctrl+I Ctrl+I Chip info Информ. о МС Information about SFDP and status registers Информация о SFDP области и регистрах статуса Ctrl+P Ctrl+P Current file: Текущий файл: Type Тип Manufacture Произв. Size Объем Opening DAT file Открывается файл базы Error Ошибка Programmer Программатор is not connected! не подключен! The ending address must not exceed the buffer size. Конечный адрес не должен превышать размер буфера. File 'IMSProg_editor' not found! Не найден файл 'IMSProg_editor'! Error loading chip database file! Ошибка загрузки файла базы микросхем! Parsing DAT file Обработка файла данных Reading data from Считывается МС Unsupported chip type! Неизвестный тип микросхемы! Programmer CH341a is not connected! Программатор CH341a не подключен Error reading block Ошибка чтения блока Before reading from chip please press 'Detect' button. Перед считыванием нажмите кнопку 'Поиск'. Please select the chip parameters - manufacture and chip name Выберите параметры микросхемы - 'Произв.' и 'Название'. The chip is not connect or missing! Микросхема не установлена или повреждена! Saving file Сохраняется файл Save file Сохранить файл Data Images Файлы данных All files Все файлы Error saving file! Ошибка сохранения файла! Erasing the Стирается МС Error erasing sector Ошибка стирания сектора Opening file Открывается файл Open file Открыть файл The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file. Размер файла превышает размер микросхемы. Пожалуйста, выберите другой тип микросхемы или файл или используйте `Сохранить часть`, чтобы разделить файл на части. Writing data to Запись данных в Error writing sector Ошибка записи сектора Veryfing data from Проверяются данные МС Error comparing data! Address: Ошибка сравнения данных! Адрес: Buffer: Буфер: Chip: Микросхема: Please select the chip parameters - manufacture and chip name. Выберите параметры МС - 'Произв.' и 'Название'. Ok! Ok! The operation was successful! Операция успешно выполнена! The end address must be greater than the starting address. Конечный адрес больше начального! Cannot find a chip database file. You may want to run IMSProg_database_update Не удается найти файл базы данных микросхем. Возможно, вам следует запустить программу IMSProg_database_update The end address must be greater than the buffer size. Конечный адрес превышает размера буфера. Saving block Сохраняется блок Save block Сохранить блок Opening block Открывается блок Open block Открыть блок The end address out of image size! Конечный адрес больше размера буфера! Connected Подключен Not connected Не подключен The chip database file was not found! Файл базы данных микросхем не найден! Error loading chip database file! File: %1 Error Code: %2 Reason: %3 Ошибка при загрузке файла базы данных микросхем! Файл: %1 Код ошибки: %2 Причина: %3 Before working with the security registers, click the 'Detect' button Прежде чем работать с регистрами безопасности, нажмите кнопку 'Поиск' There are no security registers in this chip or the current version of IMSProg does not support this algorithm. В этой микросхеме нет регистров безопасности, или текущая версия IMSProg не поддерживает этот алгоритм. Intel HEX Images Файлы Intel HEX Not valid HEX format! Неверный формат HEX! The address is larger than the size of the chip! Адрес больше, чем размер микросхемы! Checksum error! Ошибка контрольной суммы! Info: Информация: Device revision: Версия устройства: Erase checking in Проверка стирания в Error erasing chip! Address: Ошибка стирания микросхемы! Адрес: Need: FF Нужно: FF Operation aborted! Операция прервана! SearchDialog QHexEdit - Find/Replace HEX-редактор - поиск/замена Find Найти Hex Hex UTF-8 Replace Заменить Options Опции: &Backwards Поиск назад &Prompt on replace Подсказка при замене Standard headers: Стандартные заголовки: ZIP ZIP PNG PNG JPG JPG GIF GIF TAR TAR UEFI UEFI BIOS BIOS GPT GPT &Find Найти F3 F3 &Replace Заменить Replace &All Заменить все &Close Закрыть QHexEdit QHexEdit %1 occurrences replaced. Заменено %1 вхождение. Replace occurrence? Заменить возникновение? UndoStack Inserting %1 bytes Вставлено %1 байт Delete %1 chars Удалено %1 симв. Overwrite %1 chars Заменено %1 симв. imsprog-1.8.5/IMSProg_programmer/language/chipProgrammer_uk_UA.ts000066400000000000000000002753741520775651600251560ustar00rootroot00000000000000 DialogAbout About IMSProg Про програму IMSProg IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, and M95xx series chips. IMSProg - це програма для CH341a, що вільно розповсюджується, підтримує мікросхеми типів I2C, SPI NOR Flash і MicroWire. IMSProg підтримує роботу з 24Cxx, 25xxx, 93Cxx, M95xxx серіями мікросхем. IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341A and CH347T devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - це програма для CH341A, CH347T, що вільно розповсюджується, підтримує мікросхеми типів I2C, SPI NOR Flash і MicroWire. IMSProg підтримує роботу з 24Cxx, 25xxx, 93Cxx, AT45DBxx, M95xxx серіями мікросхем. <html><head/><body><p>In this program <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget and modified programmer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> were used.</p><p>The page on GitHub is <a href="https://github.com/bigbigmdm/IMSProg">here</a>, the support page is <a href="https://antenna-dvb-t2.ru/IMSProg.php">here</a>. </p></body></html> <html><head/><body><p>У цій програмі використовується віджет <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> та модифікований код програми <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> .</p><p>Сторінка на GitHub знаходиться <a href="https://github.com/bigbigmdm/IMSProg">тут</a>, сторінка підтримки - <a href="https://antenna-dvb-t2.ru/IMSProg.php">тут</a>. </p></body></html> Written by 2023 - 2026 Mikhail Medvedev Створено в 2023 - 2026 роках Михайлом Медведєвим Version: Версія: 1.1.4 1.1.4 OR або IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - це програма для CH341a, що вільно розповсюджується, підтримує мікросхеми типів I2C, SPI NOR Flash і MicroWire. IMSProg підтримує роботу з 24Cxx, 25xxx, 93Cxx, AT45DBxx, M95xxx серіями мікросхем. Written by 2023 Mikhail Medvedev Створено у 2023 році Михайлом Медведєвим Close Закрити DialogBBM Bad block management Управління пошкодженими блоками Chip scan Сканування МС No Номер Block Блок Start address Початк. адр. End address Кінц. адреса Check Перевірити Settings Налаштування Erasing Стирання Skip bad blocks during erase procedure (recommended) Пропускати пошкоджені блоки (рекомендовано) Don't skip bad blocks Не пропускайте пошкоджені блоки Don't skip bad sectors Не пропускайте пошкоджені блоки Writing Запис Write all blocks one to one (ignore bad blocks) Запишіть всі блоки один за одним (ігноруючи пошкоджені) Skip bad blocks during writing procedure Пропускати пошкоджені блоки під час запису Ok Ok BBM table (Winbond) Таблиця BBM (Winbond) This operation is used only in some Winbond chips. Ця операція використовується тільки в деяких мікросхемах Winbond. Bad block Пошкод. блок Changed block Змінений блок Status Статус Read Прочитати Error Помилка Error reading chip! Помилка при зчитуванні МС! Corrupted blocks found: Виявлено пошкоджені блоки: All blocks in the chip are good! Всі блоки в мікросхемі справні! Programmer Програматор is not connected! не підключений! Programmer CH341a is not connected! Програматор CH341a не підключений! Not used Не використ. Active, valid Актив., дійсн. Active, not valid Активн., недійсн. BBM table is not used in this chip. Таблиця BBM не використовується в цьому чіпі. DialogCompare Comparing files: Порівняння файлів: CRC32: CRC32: Name Назв. CRC32: CRC32: Visible ASCII areas Показати ASCII області Name: Назв.: DialogFill Fill the buffer with code Заповнити буфер кодом All values in HEX format! Всі дані шістнадцяткові! Start address: Стартова адреса: Filling code: Заповнення кодом: Fill Заповнити End address Кінц. адреса Length Довжина DialogInfo Connection info: Інформ. про підключення: Slot: Слот: - - Adapter: Адаптер: Close Закрити DialogNANDSr Status registers Регістри статусу Status register 1 Регістр статусу 1 SRP0 SRP0 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 TB TB WP-E WP-E SRP1 SRP1 Status register 2 Регістр статусу 2 OTP-L OTP-L OTP-E OTP-E SR1-L SR1-L ECC-E ECC-E BUF BUF (R) (R) Status register 3 Регістр статусу 3 LUT-F LUT-F ECC-1 ECC-1 ECC-0 ECC-0 P-FAIL P-FAIL WELL WELL BUSY BUSY E_FAIL E_FAIL Status register 4 Регістр статусу 4 --- --- Status register 5 Регістр статусу 5 Unique ID: ID мікросхеми: Read Прочитати Write Записати Parameter page: Сторінка параметрів: Manufacturer: Виробник: Model: Модель: Page size: Розмір листа: ECC size: Розмір ECC: Pages per block: Сторінок у блоці: Block per unit: Блок на одиницю: Block size: Розмір блоку: Chip size: Обсяг МС: Error Помилка Error reading register! Помилка читання регістру! Error reading Parameter Page! Помилка під час читання сторінки параметрів! The Parameter Page is not supported. Сторінка параметрів не підтримується. Error reading ID! Помилка під час зчитування ідентифікатора! Programmer Програматор is not connected! не підключений! Programmer CH341a is not connected! Програматор CH341a не підключений! DialogNandSecurity Security registers Реєстри безпеки Hex Editor HEX-редактор Operations: Операції: Reading security register data from the chip Зчитування даних регістру безпеки з чіпа ... ... Writing data to the security register Запис даних до реєстру безпеки Open a binary file from a computer Відкрийте двійковий файл з комп'ютера Save the binary file on the computer Збережіть двійковий файл на комп'ютері Security register number: Номер реєстру безпеки: Error Помилка Error reading Parameter Page! Помилка під час читання сторінки параметрів! Programmer CH341a is not connected! Програматор CH341a не підключений! Programmer Програматор is not connected! не підключений! Open file Відкрити файл The file size exceeds the security register size. Розмір файлу перевищує розмір регістру безпеки. Save file Зберегти файл Error saving file! Помилка збереження файлу! DialogRP Load block from file Завантажити блок із файлу All values in HEX format! Всі дані шістнадцяткові! Start address: Стартова адреса: Load Завантажити DialogSFDP Information about SFDP and status registers Інформація про SFDP та регістри статусу SFDP support: Підтримка SFDP: Minimum VCC: Мін. VCC: Maximum VCC: Макс. VCC: Chip size: Обсяг МС: Block size: Розмір блоку: Speeds: Режими: OTP support: Підтримка OTP: Status Register 0 Регістр статусу 0 SPR0 SPR0 BP4 BP4 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 WEL WEL WIP WIP SUS1 SUS1 CMP CMP LB3 LB3 LB2 LB2 LB1 LB1 SUS2 SUS2 QE QE SPR1 SPR1 Status Register 1 Регістр статусу 1 Status register 2 Регістр статусу 2 JEDEC info: JEDEC інформ.: Man. ID ID вироб Man. type Тип вироб Capacity Об `єм Unique ID: ID мікросхеми: Read Прочитати Write registers Напишіть регістри (R) (R) DRV1 DRV1 DRV0 DRV0 WPS WPS ADP ADP ADS ADS <html><head/><body><p/></body></html> <html><head/><body><p/></body></html> <html><head/><body><p>Legend:</p><p>** - Basic area<br>** - Extended area<br>** - Manufacture area </p></body></html> <html><head/><body><p>Позначення:</p><p>** - Основна область<br>** - Додаткова область<br>** - Область виробника </p></body></html> Close Закрити Error Помилка Error reading register! Помилка читання регістру! <html><head/><body><p> Hex SFDP register data: <html><head/><body><p> Дані області SFDP: <html><head/><body><p>Addr:<br> <html><head/><body><p>Адр.<br> Programmer Програматор is not connected! не підключений! Before writing the registers, please press the `Read` button! Перш ніж записувати реєстри, натисніть кнопку `Прочитати`! Error reading JEDEC ID! Помилка читання JEDEC ID! Legend: Позначення: - Basic area - Основна область - Extended area - Додаткова область - Manufacture area - Область виробника Error reading unique ID! Помилка читання ID мікросхеми! Programmer CH341a is not connected! Програматор CH341a не підключено! DialogSP Save part of image Зберегти частину прошивки All values in HEX format! Всі дані шістнадцяткові! Start address: Стартова адреса: Save Зберегти End address Кінц. адреса Length Довжина DialogSR Status register Регістр статусу WPEN WPEN X X BP1 BP1 BP0 BP0 WEN WEN /RDY /RDY Read Прочитати Write Записати Error Помилка Error reading register! Помилка читання регістру! Programmer Програматор is not connected! не підключений! Programmer CH341a is not connected! Програматор CH341a не підключено! Before writing the register, please press the `Read` button! Перш ніж записувати реєстр, натисніть кнопку `Прочитати`! DialogSecurity Security registers Реєстри безпеки Hex Editor Шістнадцятковий редактор HEX-редактор Operations: Операції: Reading security register data from the chip Зчитування даних регістру безпеки з чіпа ... ... Erasing security register data Стирання даних реєстру безпеки Writing data to the security register Запис даних до реєстру безпеки Open a binary file from a computer Відкрийте двійковий файл з комп'ютера Save the binary file on the computer Збережіть двійковий файл на комп'ютері Security register number: Номер реєстру безпеки: Error Помилка Error reading register! Помилка читання регістру! Programmer CH341a is not connected! Програматор CH341a не підключено! Programmer Програматор is not connected! не підключений! Error writing register! Реєстр запису помилок! Open file Відкрити файл The file size exceeds the security register size. Розмір файлу перевищує розмір регістру безпеки. Save file Зберегти файл Error saving file! Помилка збереження файлу! DialogSetAddr Goto address Перейти до адреси All values in HEX format! Всі дані шістнадцяткові! Address: Адреса: Go to Перейдіть до MainWindow File Файл Open Відкрити Ctrl+O Ctrl+O Exit Вихід Ctrl+X Ctrl+X Save Зберегти IMSProg - I2C/MicroWire/SPI CH341a Programmer IMSProg - I2C/MicroWire/SPI програматор для CH341a Chip Мікросхема Name Назва Page size Розмір листа Block size Розмір блока VCC, Volt Живлення, В 4byte Addr. 4byte адреса. Detect Пошук Read Прочитати i i I2C bus speed Швидк. шини I2C Erase size Розмір стирання ECC size Розмір ECC Auto Options Авто опції Erase Стерти Program Записати Verify Перевірити Go! Старт! Hex Editor HEX-редактор JEDEC ID: JEDEC ID: CH341a: CH341a: border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; CRC32: CRC32: Message Повідомлення Programmer Програматор Help Довідка Operations Операції Check erase Перевірити стирання Ctrl+S Ctrl+S Ctrl+D Ctrl+D Ctrl+R Ctrl+R Ctrl+E Ctrl+E Write Записати Ctrl+W Ctrl+W Ctrl+T Ctrl+T Undo Назад Ctrl+Z Ctrl+Z Redo Повторення Ctrl+Y Ctrl+Y Ctrl+N Ctrl+N Import from Intel HEX Імпорт з Intel HEX Export to Intel HEX Експорт до Intel HEX Extract from ASUS CAP Витягти зASUS CAP Goto address Перейти до адреси Move the cursor to the entered address Підведіть курсор до введеної адреси Ctrl+G Ctrl+G Security registers Реєстри безпеки Ctrl+U Ctrl+U Fill test image Заповнити тест-масивом Filling the hex editor with a test array Заповнення шістнадцяткового редактора тестовим масивом Ctrl+L Ctrl+L Compare files Порівняти файли Compares the results of the last and penultimate chip read or file open operation Порівнює результати останнього та передостаннього зчитування мікросхеми або відкриття файлу Ctrl+M Ctrl+M Copy Копіювати Paste Вставити Bad block management Управління пошкод.блоками Ctrl+B Ctrl+B Show programmer version Показати версію програміста Check erase chip Перевірити чип на стирання Ctrl+J Ctrl+J Filling with code Заповнення кодом Ctrl+K Ctrl+K CH341A/B v1.2 CH341A/B v1.2 CH341A v1.7 CH341A v1.7 CH347T v1.0 CH347T v1.0 CH347T v1.1 CH347T v1.1 CH347T CH347T Save Part Зберегти частину Load Part Завантажити частину Find / Replace Пошук/заміна Ctrl+F Ctrl+F About Про програму About IMSProgrammer Про програму IMSProg Ctrl+H Ctrl+H Checksum calculate Перерахунок CRC32 Ctrl+A Ctrl+A Edit chips Database Редактор бази мікросхем Ctrl+Q Ctrl+Q Stop Стоп Forced stop of read, write, erase and verification operations Примусова зупинка операцій читання, запису, стирання та перевірки Ctrl+I Ctrl+I Chip info Інформ. о МС Information about SFDP and status registers Інформація про SFDP області та регістри статусу Ctrl+P Ctrl+P Current file: Поточний файл: Type Тип Manufacture Виробник Size Об `єм Opening DAT file Відкривається файл бази Error Помилка The end address must be greater than the starting address. Кінцева адреса більша за початкову. File 'IMSProg_editor' not found! Не знайдено файл 'IMSProg_editor'! Error loading chip database file! Помилка завантаження файлу бази мікросхем! Parsing DAT file Обробка файлу даних Reading data from Зчитується МС Unsupported chip type! Невідомий тип мікросхеми! Programmer CH341a is not connected! Програматор CH341a не підключений! Error reading block Помилка читання блоку Before reading from chip please press 'Detect' button. Перед зчитуванням натисніть кнопку 'Пошук'. Please select the chip parameters - manufacture and chip name Виберіть параметри мікросхеми - 'Див.' та 'Назва' The chip is not connect or missing! Мікросхема не встановлена ​​чи пошкоджена! Saving file Зберігається файл Save file Зберегти файл Data Images Файли даних All files Усі файли Error saving file! Помилка збереження файлу! Erasing the Стирається МС Error erasing sector Помилка стирання сектора Opening file Відкривається файл Open file Відкрити файл The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file. Розмір файлу перевищує розмір мікросхеми. Будь ласка, виберіть іншу мікросхему або файл, або скористайтеся `Зберегти частину` для розділення файлу. The ending address must not exceed the buffer size. Кінцева адреса не повинна перевищувати розмір буфера. Cannot find a chip database file. You may want to run IMSProg_database_update Не вдається знайти файл бази даних мікросхем. Рекомендується запустити програму IMSProg_database_update Before working with the security registers, click the 'Detect' button Перед початком роботи з реєстрами безпеки натисніть кнопку 'Пошук'. There are no security registers in this chip or the current version of IMSProg does not support this algorithm. У цій мікросхемі немає регістрів безпеки або поточна версія IMSProg не підтримує цей алгоритм. Intel HEX Images Файли Intel HEX Not valid HEX format! Неправильний формат HEX! The address is larger than the size of the chip! Адреса більша за розмір чіпа! Checksum error! Помилка контрольної суми! Writing data to Запис даних у Programmer Програматор is not connected! не підключений! Error writing sector Помилка запису сектора Veryfing data from Перевіряються дані МС Error comparing data! Address: Помилка порівняння даних! Адреса: Buffer: Буфер: Chip: Мікросхема: Please select the chip parameters - manufacture and chip name. Виберіть параметри МС - 'Проізв.' та 'Назва'. Ok! Ok! The operation was successful! Операцію успішно виконано! Saving block Зберігається блок Save block Зберегти блок Opening block Відкривається блок Open block Відкрити блок The end address out of image size! Кінцева адреса більша за розмір буфера! Connected Підключено Not connected Не підключений Operation aborted! Операцію перервано! The chip database file was not found! Файл бази даних мікросхем не знайдено! Error loading chip database file! File: %1 Error Code: %2 Reason: %3 Помилка під час завантаження файлу бази даних мікросхем! Файл: %1 Код помилки: %2 Причина: %3 Info: Інформація: Device revision: Версія виробу: Erase checking in Перевірити стирання в Error erasing chip! Address: Помилка стирання чіпа! Адреса: Need: FF Потрібно: FF SearchDialog QHexEdit - Find/Replace HEX-редактор - поиск/замена Find Найти Hex Hex UTF-8 UTF-8 Replace Заменить Options Опції &Backwards &Пошук назад &Prompt on replace &Підказка під час заміни Standard headers: Стандартні заголовки: ZIP ZIP PNG PNG JPG JPG GIF GIF TAR TAR UEFI UEFI BIOS BIOS GPT GPT &Find &Знайти F3 F3 &Replace &Замінити Replace &All Замінити &Все &Close &Закрити QHexEdit QHexEdit %1 occurrences replaced. Замінено %1 входжень. Replace occurrence? Замінити появу? UndoStack Inserting %1 bytes Вставка %1 байт Delete %1 chars Видалити %1 символів Overwrite %1 chars Перезаписати %1 символів imsprog-1.8.5/IMSProg_programmer/language/chipProgrammer_zh_CN.ts000066400000000000000000002607021520775651600251400ustar00rootroot00000000000000 DialogAbout About IMSProg 关于 IMSProg IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, and M95xx series chips. IMSProg - I2C、SPI、MicroWire EEPROM/Flash 芯片 CH341A 编程器免费软件。IMSProg 支持 24Cxx、25xx、93Cxx 和 M95xx 系列芯片。 IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341A and CH347T devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - I2C、SPI、MicroWire EEPROM/Flash 芯片 CH341A和CH347T 编程器免费软件。IMSProg 支持 24Cxx、25xx、93Cxx, AT45DBxx 和 M95xx 系列芯片。 <html><head/><body><p>In this program <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget and modified programmer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> were used.</p><p>The page on GitHub is <a href="https://github.com/bigbigmdm/IMSProg">here</a>, the support page is <a href="https://antenna-dvb-t2.ru/IMSProg.php">here</a>. </p></body></html> <html><head/><body><p>该程序使用 <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget 和经过修改的编程器 <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> .</p><p>GitHub 页面在 <a href="https://github.com/bigbigmdm/IMSProg">这里</a>, 支持页面在 <a href="https://antenna-dvb-t2.ru/IMSProg.php">这里</a>. </p></body></html> Written by 2023 - 2026 Mikhail Medvedev 作者:2023 - 2026 米哈伊尔-梅德韦杰夫 Version: 版本: 1.1.4 1.1.4 OR IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - I2C、SPI、MicroWire EEPROM/Flash 芯片 CH341A 编程器免费软件。IMSProg 支持 24Cxx、25xx、93Cxx, AT45DBxx 和 M95xx 系列芯片。 Written by 2023 Mikhail Medvedev 作者:2023 米哈伊尔-梅德韦杰夫 Close 关闭 DialogBBM Bad block management 坏块管理 Chip scan 芯片扫描 No 数字 Block 区块编号 Start address 起始地址 End address 结束地址 Check 检查 Settings 设置 Erasing 擦除 Skip bad blocks during erase procedure (recommended) 擦除过程中跳过坏块(推荐) Don't skip bad blocks 不要跳过坏扇区 Don't skip bad sectors 不要跳过坏扇区 Writing 写入中 Write all blocks one to one (ignore bad blocks) 分别写入每个扇区(忽略坏扇区) Skip bad blocks during writing procedure 在写入过程中跳过坏扇区 Ok Ok BBM table (Winbond) 坏块管理表(Winbond) This operation is used only in some Winbond chips. 此操作仅适用于某些 Winbond 芯片。 Bad block 坏块编号 Changed block 变更块编号 Status 状态 Read 读取 Error 错误 Error reading chip! 读取芯片错误! Corrupted blocks found: 发现损坏的区块: All blocks in the chip are good! 芯片中的所有模块都运行正常! Programmer is not connected! 编程器未连接! Programmer CH341a is not connected! CH341A 编程器未连接! Not used 未使用 Active, valid 有效,有效 Active, not valid 有效,但未激活 BBM table is not used in this chip. 该芯片未使用坏块管理表。 DialogCompare Comparing files: 比较文件: CRC32: CRC32: Name 名称 CRC32: CRC32: Visible ASCII areas 显示 ASCII 区域 Name: 名称: DialogFill Fill the buffer with code 用代码填充缓冲区 All values in HEX format! 所有数值均为 HEX 格式! Start address: 起始地址: Filling code: 正在填充代码: Fill 填充 End address 结束地址 Length 长度 DialogInfo Connection info: 连接信息: Slot: 插槽: - - Adapter: 适配器: Close 关闭 DialogNANDSr Status registers 缓冲区: Status register 1 状态寄存器 1 SRP0 SRP0 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 TB TB WP-E WP-E SRP1 SRP1 Status register 2 状态寄存器 2 OTP-L OTP-L OTP-E OTP-E SR1-L SR1-L ECC-E ECC-E BUF BUF (R) (R) Status register 3 状态寄存器 3 LUT-F LUT-F ECC-1 ECC-1 ECC-0 ECC-0 P-FAIL P-FAIL WELL WELL BUSY BUSY E_FAIL E_FAIL Status register 4 状态寄存器 4 --- --- Status register 5 状态寄存器 5 Unique ID: 唯一 ID: Read 读取 Write 写入 Parameter page: 参数页面: Manufacturer: 制造商: Model: 型号: Page size: 页面大小: ECC size: ECC 尺寸: Pages per block: 每块页面数: Block per unit: 每单位块数: Block size: 块大小: Chip size: 芯片大小: Error 错误 Error reading register! 错误读取寄存器! Error reading Parameter Page! 读取参数页面时发生错误! The Parameter Page is not supported. 参数页面不支持。 Error reading ID! 读取ID时发生错误! Programmer is not connected! 编程器未连接! Programmer CH341a is not connected! CH341A 编程器未连接! DialogNandSecurity Security registers 安全登记册 Hex Editor 十六进制编辑器 Operations: 操作: Reading security register data from the chip 从芯片读取安全寄存器数据 ... ... Writing data to the security register 向安全寄存器写入数据 Open a binary file from a computer 从计算机打开二进制文件 Save the binary file on the computer 在电脑上保存二进制文件 Security register number: 安全登记编号: Error 错误 Error reading Parameter Page! 读取参数页面时发生错误! Programmer CH341a is not connected! CH341A 编程器未连接! Programmer is not connected! 编程器未连接! Open file 打开文件 The file size exceeds the security register size. 文件大小超过安全寄存器大小。 Save file 保存文件 Error saving file! 保存文件出错! DialogRP Load block from file 从文件中加载数据块 All values in HEX format! 所有数值均为 HEX 格式! Start address: 起始地址: Load 装载量 DialogSFDP Information about SFDP and status registers 有关 SFDP 和状态寄存器的信息 SFDP support: SFDP 支持: Minimum VCC: 最低 VCC: Maximum VCC: 最大 VCC: Chip size: 芯片大小: Block size: 块大小: Speeds: 速度: OTP support: 支持 OTP: Status Register 0 状态寄存器 0 SPR0 SPR0 BP4 BP4 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 WEL WEL WIP WIP SUS1 SUS1 CMP CMP LB3 LB3 LB2 LB2 LB1 LB1 SUS2 SUS2 QE QE SPR1 SPR1 Status Register 1 状态寄存器 1 Status register 2 状态寄存器 2 JEDEC info: JEDEC 信息: Man. ID 制造商标识: Man. type 制造类型: Capacity 容量: Unique ID: 唯一 ID: Read 读取 Write registers 写寄存器 (R) (R) DRV1 DRV1 DRV0 DRV0 WPS WPS ADP ADP ADS ADS <html><head/><body><p/></body></html> <html><head/><body><p/></body></html> <html><head/><body><p>Legend:</p><p>** - Basic area<br>** - Extended area<br>** - Manufacture area </p></body></html> <html><head/><body><p>图例:</p><p>** - 基本区域<br>** - 扩展区<br>** - 制造商区</p></body></html> Close 关闭 Error 错误 Error reading register! 错误读取寄存器! <html><head/><body><p> Hex SFDP register data: <html><head/><body><p> 十六进制 SFDP 寄存器数据: <html><head/><body><p>Addr:<br> <html><head/><body><p>地址:<br> Programmer is not connected! 编程器未连接! Before writing the registers, please press the `Read` button! 在写入寄存器之前,请按`读取`按钮! Error reading JEDEC ID! 读取 JEDEC ID 时出错! Legend: 图例: - Basic area - 基本区域 - Extended area - 扩展区 - Manufacture area - 制造商区 Error reading unique ID! 读取唯一 ID 时出错! Programmer CH341a is not connected! CH341A 编程器未连接! DialogSP Save part of image 保存部分映像 All values in HEX format! 所有数值均为 HEX 格式! Start address: 起始地址: Save 保存 End address 结束地址 Length 长度 DialogSR Status register 状态寄存器 WPEN WPEN X X BP1 BP1 BP0 BP0 WEN WEN /RDY /RDY Read 读取 Write 写入 Error 错误 Error reading register! 错误读取寄存器! Programmer is not connected! 编程器未连接! Programmer CH341a is not connected! CH341A 编程器未连接! Before writing the register, please press the `Read` button! 在写入寄存器之前,请按`读取`按钮! DialogSecurity Security registers 安全登记册 Hex Editor 十六进制编辑器 Operations: 业务: Reading security register data from the chip 从芯片读取安全寄存器数据 ... ... Erasing security register data 清除安全寄存器数据 Writing data to the security register 向安全寄存器写入数据 Open a binary file from a computer 从计算机打开二进制文件 Save the binary file on the computer 在电脑上保存二进制文件 Security register number: 安全登记编号: Error 错误 Error reading register! 错误读取寄存器! Programmer CH341a is not connected! CH341A 编程器未连接! Programmer is not connected! 编程器未连接! Error writing register! 错误写入寄存器! Open file 打开文件 The file size exceeds the security register size. 文件大小超过安全寄存器大小。 Save file 保存文件 Error saving file! 保存文件出错! DialogSetAddr Goto address 转到地址 All values in HEX format! 所有数值均为 HEX 格式! Address: 地址: Go to 转到 MainWindow File 文件 Open 打开 Ctrl+O Ctrl+O Exit 退出 Ctrl+X Ctrl+X Save 保存 IMSProg - I2C/MicroWire/SPI CH341a Programmer IMSProg - I2C、SPI、MicroWire EEPROM/Flash 芯片 CH341A 编程器 Chip 芯片 Name 名称 Page size 页面大小 Block size 块大小 VCC, Volt VCC(伏) 4byte Addr. 4 字节地址 Detect 检测 Read 读取 i i I2C bus speed I2C 总线速度 Erase size 擦除大小 ECC size ECC 尺寸 Auto Options 自动选项 Erase 擦除 Program 编程 Verify 校验 Go! 开始吧! Hex Editor 十六进制编辑器 JEDEC ID: JEDEC ID: CH341a: CH341A: border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; CRC32: CRC32: Message 留言 Programmer 编程器 Help 帮助 Operations 操作 Check erase 检查擦除 Ctrl+S Ctrl+S Ctrl+D Ctrl+D Ctrl+R Ctrl+R Ctrl+E Ctrl+E Write 写入 Ctrl+W Ctrl+W Ctrl+T Ctrl+T Undo 撤消 Ctrl+Z Ctrl+Z Redo 重做 Ctrl+Y Ctrl+Y Ctrl+N Ctrl+N Import from Intel HEX 从英特尔 HEX 导入 Export to Intel HEX 导出为英特尔 HEX Extract from ASUS CAP 从ASUS CAP移除 Goto address 转到地址 Move the cursor to the entered address 将光标移至输入的地址 Ctrl+G Ctrl+G Security registers 安全登记册 Ctrl+U Ctrl+U Fill test image 填充测试图像 Filling the hex editor with a test array 用测试数组填充十六进制编辑器 Ctrl+L Ctrl+L Compare files 比较文件 Compares the results of the last and penultimate chip read or file open operation 比较最后一次和倒数第二次芯片读取或文件打开操作的结果。 Ctrl+M Ctrl+M Copy 复制 Paste 粘贴 Bad block management 坏块管理 Ctrl+B Ctrl+B Show programmer version 显示编程器版本 Check erase chip 检查芯片是否已擦除 Ctrl+J Ctrl+J Filling with code 正在用代码填充 Ctrl+K Ctrl+K CH341A/B v1.2 CH341A/B v1.2 CH341A v1.7 CH341A v1.7 CH347T v1.0 CH347T v1.0 CH347T v1.1 CH347T v1.1 CH347T CH347T Save Part 部分保存 Load Part 部分加载 Find / Replace 查找/替换 Ctrl+F Ctrl+F About 关于 About IMSProgrammer 关于 IMSProg Ctrl+H Ctrl+H Checksum calculate 计算校验和 Ctrl+A Ctrl+A Edit chips Database 编辑芯片数据库 Ctrl+Q Ctrl+Q Stop 停止 Forced stop of read, write, erase and verification operations 强制停止读、写、擦除和校验操作 Ctrl+I Ctrl+I Chip info 芯片信息 Information about SFDP and status registers 有关 SFDP 和状态寄存器的信息 Ctrl+P Ctrl+P Current file: 当前文件: Type 类型 Manufacture 制造商 Size 大小 Opening DAT file 打开 DAT 文件 Error 错误 Programmer is not connected! 编程器未连接! The ending address must not exceed the buffer size. 结束地址不得超过缓冲区大小。 File 'IMSProg_editor' not found! ¡未找到文件 `IMSProg_editor`! Error loading chip database file! 加载芯片数据库文件时出错! Parsing DAT file 解析 DAT 文件 Reading data from 读取的数据来自 Unsupported chip type! 不支持的芯片类型! Programmer CH341a is not connected! CH341A 编程器未连接! Error reading block 读取程序块编号出错 Before reading from chip please press 'Detect' button. 读取芯片数据前,请按下 '检测' 按钮。 Please select the chip parameters - manufacture and chip name 请选择芯片参数 - '制造商' 和芯片 '名称'。 The chip is not connect or missing! 芯片没有连接或丢失! Saving file 保存文件 Save file 保存文件 Data Images 数据文件 All files 所有文件 Error saving file! 保存文件出错! Erasing the 擦除芯片 Error erasing sector 擦除扇区号出错 Opening file 打开文件 Open file 打开文件 The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file. 文件大小超出芯片大小。请选择其他芯片或文件,或使用 "部分保存" 分割文件。 Writing data to 将数据写入 Error writing sector 写入扇区号出错 Veryfing data from 从芯片中提取数据 Error comparing data! Address: 数据比较错误! 地址: Buffer: 缓冲区: Chip: 芯片: Please select the chip parameters - manufacture and chip name. 请选择芯片参数 - '制造商' 和芯片 '名称'。 Ok! Ok! The operation was successful! 操作成功! The end address must be greater than the starting address. 结束地址必须大于起始地址。 Saving block 保存块 Save block 保存块 Opening block 打开块 Open block 打开块 The end address out of image size! 末端地址超出映像大小范围! Connected 已连接 Not connected 未连接 Cannot find a chip database file. You may want to run IMSProg_database_update 找不到芯片数据库文件。 您可能需要运行 IMSProg_database_update The chip database file was not found! 未找到芯片数据库文件! Error loading chip database file! File: %1 Error Code: %2 Reason: %3 加载芯片数据库文件时发生错误! 文件:%1 错误代码:%2 原因:%3 Before working with the security registers, click the 'Detect' button 在使用安全注册表之前,请点击 '检测'按钮 There are no security registers in this chip or the current version of IMSProg does not support this algorithm. 该芯片中没有安全寄存器,或者当前版本的 IMSProg 不支持这种算法。 Intel HEX Images Intel HEX 文件 Not valid HEX format! 不是有效的 HEX 格式! The address is larger than the size of the chip! 地址大于芯片大小! Checksum error! 校验和错误! Info: 信息: Device revision: 设备版本号: Erase checking in 正在检查 Error erasing chip! Address: 擦除芯片时出错! 地址: Need: FF 需要:FF Operation aborted! 操作中止! SearchDialog QHexEdit - Find/Replace QHexEdit - 查找/替换 Find 查找 Hex Hex UTF-8 Replace 更换 Options 选项: &Backwards 向后 &Prompt on replace 更换时提示 Standard headers: 标准标头: ZIP ZIP PNG PNG JPG JPG GIF GIF TAR TAR UEFI UEFI BIOS BIOS GPT GPT &Find 查找 F3 F3 &Replace 替换 Replace &All 全部更换 &Close 关闭 QHexEdit %1 occurrences replaced. Replace occurrence? 替换发生? UndoStack Inserting %1 bytes 插入 %1 字节 Delete %1 chars 删除 %1 字符 Overwrite %1 chars 覆盖 %1 字符 imsprog-1.8.5/IMSProg_programmer/language/chipProgrammer_zh_TW.ts000066400000000000000000002620371520775651600251750ustar00rootroot00000000000000 DialogAbout About IMSProg 關於 IMSProg IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, and M95xx series chips. IMSProg - I2C、SPI、MicroWire EEPROM/Flash 晶片 CH341A 程式燒錄器免費軟體。IMSProg 支援 24Cxx、25xx、93Cxx 和 M95xx 系列晶片。 IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341A and CH347T devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - I2C、SPI、MicroWire EEPROM/Flash 晶片 CH341A和CH347T 程式燒錄器免費軟體。IMSProg 支援 24Cxx、25xx、93Cxx, AT45DBxx 和 M95xx 系列晶片。 <html><head/><body><p>In this program <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> widget and modified programmer <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> were used.</p><p>The page on GitHub is <a href="https://github.com/bigbigmdm/IMSProg">here</a>, the support page is <a href="https://antenna-dvb-t2.ru/IMSProg.php">here</a>. </p></body></html> <html><head/><body><p>本程式使用 <a href="https://github.com/Simsys/qhexedit2/">QhexEditor2</a> 元件和經過修改的程式燒錄器 <a href="https://github.com/McMCCRU/SNANDer"><span style=" text-decoration: underline; color:#0000ff;">SNANDer</span></a> 。</p><p>GitHub 頁面在 <a href="https://github.com/bigbigmdm/IMSProg">這裡</a>, 支援頁面在 <a href="https://antenna-dvb-t2.ru/IMSProg.php">這裡</a>。 </p></body></html> Written by 2023 - 2026 Mikhail Medvedev 作者:2023 - 2026 米哈伊爾·梅德韋傑夫 Version: 版本: 1.1.4 1.1.4 OR IMSProg - free software I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a devices. IMSProg supports 24Cxx, 25xx, 93Cxx, AT45DBxx and M95xx series chips. IMSProg - I2C、SPI、MicroWire EEPROM/Flash 晶片 CH341A 程式燒錄器免費軟體。IMSProg 支援 24Cxx、25xx、93Cxx, AT45DBxx 和 M95xx 系列晶片。 Written by 2023 Mikhail Medvedev 作者:2023 米哈伊爾·梅德韋傑夫 Close 關閉 DialogBBM Bad block management 壞區塊管理 Chip scan 晶片掃描 No 数字 Block 區塊編號 Start address 起始位址: End address 結束位址 Check 檢查 Settings 設定 Erasing 抹除 Skip bad blocks during erase procedure (recommended) 在擦除程序中跳過壞區塊(建議) Don't skip bad blocks 不要跳過壞區塊 Don't skip bad sectors 不要跳過壞軌 Writing 寫作 Write all blocks one to one (ignore bad blocks) 將所有區塊一對一寫入(忽略壞區塊) Skip bad blocks during writing procedure 在寫入程序中跳過壞區塊 Ok 確定 BBM table (Winbond) 壞區塊管理表(Winbond) This operation is used only in some Winbond chips. 此操作僅適用於特定的華邦(Winbond)晶片。 Bad block 壞區塊數量 Changed block 變更區塊編號 Status 狀態 Read 讀取 Error 錯誤 Error reading chip! 讀取晶片錯誤! Corrupted blocks found: 發現損壞區塊: All blocks in the chip are good! 晶片中的所有模組都正常! Programmer is not connected! 程式燒錄器未連接! Programmer CH341a is not connected! CH341A 程式燒錄器未連接! Not used 未使用 Active, valid 有效、有效 Active, not valid 有效,非有效 BBM table is not used in this chip. 此晶片未使用壞區管理表。 DialogCompare Comparing files: 比較檔案: CRC32: CRC32: Name 名稱 CRC32: CRC32: Visible ASCII areas 顯示 ASCII 區域 Name: 名稱: DialogFill Fill the buffer with code 將程式碼填入緩衝區 All values in HEX format! 所有數值均為 HEX 格式! Start address: 起始位址: Filling code: 填入程式碼: Fill 填入 End address 結束位址 Length 長度 DialogInfo Connection info: 連接資訊: Slot: 插槽: - - Adapter: 轉接器: Close 關閉 DialogNANDSr Status registers 狀態暫存器 Status register 1 狀態暫存器 1 SRP0 SRP0 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 TB TB WP-E WP-E SRP1 SRP1 Status register 2 狀態暫存器 2 OTP-L OTP-L OTP-E OTP-E SR1-L SR1-L ECC-E ECC-E BUF BUF (R) (R) Status register 3 狀態暫存器 3 LUT-F LUT-F ECC-1 ECC-1 ECC-0 ECC-0 P-FAIL P-FAIL WELL WELL BUSY BUSY E_FAIL E_FAIL Status register 4 狀態暫存器 4 --- --- Status register 5 狀態暫存器 5 Unique ID: 唯一 ID: Read 讀取 Write 寫入 Parameter page: 參數頁: Manufacturer: 製造商: Model: 型號: Page size: 頁面大小: ECC size: ECC 大小: Pages per block: 每個區塊的頁數: Block per unit: 每單位的區塊: Block size: 區塊大小: Chip size: 晶片大小: Error 錯誤 Error reading register! 讀取暫存器錯誤! Error reading Parameter Page! 錯誤讀取參數頁面! The Parameter Page is not supported. 不支援參數頁。 Error reading ID! 錯誤讀取 ID! Programmer is not connected! 程式燒錄器未連接! Programmer CH341a is not connected! CH341A 程式燒錄器未連接! DialogNandSecurity Security registers 安全暫存器 Hex Editor 十六進位編輯器 Operations: 操作: Reading security register data from the chip 從晶片讀取安全暫存器資料 ... ... Writing data to the security register 向安全暫存器寫入資料 Open a binary file from a computer 從電腦開啟二進位檔案 Save the binary file on the computer 在電腦上儲存二進位檔案 Security register number: 安全暫存器編號: Error 錯誤 Error reading Parameter Page! 錯誤讀取參數頁面! Programmer CH341a is not connected! CH341A 程式燒錄器未連接! Programmer is not connected! 程式燒錄器未連接! Open file 開啟檔案 The file size exceeds the security register size. 檔案大小超過安全暫存器大小。 Save file 儲存檔案 Error saving file! 儲存檔案時發生錯誤! DialogRP Load block from file 從檔案中載入資料區塊 All values in HEX format! 所有數值均為 HEX 格式! Start address: 起始位址: Load 載入 DialogSFDP Information about SFDP and status registers 有關 SFDP 和狀態暫存器的資訊 SFDP support: SFDP 支援: Minimum VCC: 最低 VCC: Maximum VCC: 最大 VCC: Chip size: 晶片大小: Block size: 區塊大小: Speeds: 速度: OTP support: 支援 OTP: Status Register 0 狀態暫存器 0 SPR0 SPR0 BP4 BP4 BP3 BP3 BP2 BP2 BP1 BP1 BP0 BP0 WEL WEL WIP WIP SUS1 SUS1 CMP CMP LB3 LB3 LB2 LB2 LB1 LB1 SUS2 SUS2 QE QE SPR1 SPR1 Status Register 1 狀態暫存器 1 Status register 2 狀態暫存器 2 JEDEC info: JEDEC 資訊: Man. ID 製造商識別碼: Man. type 製造類型: Capacity 容量: Unique ID: 唯一 ID: Read 讀取 Write registers 寫入暫存器 (R) (R) DRV1 DRV1 DRV0 DRV0 WPS WPS ADP ADP ADS ADS <html><head/><body><p/></body></html> <html><head/><body><p/></body></html> <html><head/><body><p>Legend:</p><p>** - Basic area<br>** - Extended area<br>** - Manufacture area </p></body></html> <html><head/><body><p>圖例:</p><p>** - 基本區域<br>** - 擴充區<br>** - 製造商區</p></body></html> Close 關閉 Error 錯誤 Error reading register! 讀取暫存器錯誤! <html><head/><body><p> Hex SFDP register data: <html><head/><body><p> 十六進位 SFDP 暫存器資料: <html><head/><body><p>Addr:<br> <html><head/><body><p>位址:<br> Programmer is not connected! 程式燒錄器未連接! Before writing the registers, please press the `Read` button! 在寫入暫存器之前,請按`讀取`按鈕! Error reading JEDEC ID! 讀取 JEDEC ID 時發生錯誤! Legend: 圖例: - Basic area - 基本區域 - Extended area - 擴充區 - Manufacture area - 製造商區 Error reading unique ID! 讀取唯一 ID 時發生錯誤! Programmer CH341a is not connected! CH341A 程式燒錄器未連接! DialogSP Save part of image 儲存部分映像 All values in HEX format! 所有數值均為 HEX 格式! Start address: 起始位址: Save 儲存 End address 結束位址 Length 長度 DialogSR Status register 狀態暫存器 WPEN WPEN X X BP1 BP1 BP0 BP0 WEN WEN /RDY /RDY Read 讀取 Write 寫入 Error 錯誤 Error reading register! 讀取暫存器錯誤! Programmer is not connected! 程式燒錄器未連接! Programmer CH341a is not connected! CH341A 程式燒錄器未連接! Before writing the register, please press the `Read` button! 在寫入暫存器之前,請按`讀取`按鈕! DialogSecurity Security registers 安全暫存器 Hex Editor 十六進位編輯器 Operations: 操作: Reading security register data from the chip 從晶片讀取安全暫存器資料 ... ... Erasing security register data 清除安全暫存器資料 Writing data to the security register 向安全暫存器寫入資料 Open a binary file from a computer 從電腦開啟二進位檔案 Save the binary file on the computer 在電腦上儲存二進位檔案 Security register number: 安全暫存器編號: Error 錯誤 Error reading register! 讀取暫存器錯誤! Programmer CH341a is not connected! CH341A 程式燒錄器未連接! Programmer is not connected! 程式燒錄器未連接! Error writing register! 寫入暫存器錯誤! Open file 開啟檔案 The file size exceeds the security register size. 檔案大小超過安全暫存器大小。 Save file 儲存檔案 Error saving file! 儲存檔案時發生錯誤! DialogSetAddr Goto address 前往位址 All values in HEX format! 所有數值均為 HEX 格式! Address: 位址: Go to 前往 MainWindow File 檔案 Open 開啟 Ctrl+O Ctrl+O Exit 離開 Ctrl+X Ctrl+X Save 儲存 IMSProg - I2C/MicroWire/SPI CH341a Programmer IMSProg - I2C/MicroWire/SPI CH341a 程式燒錄器 Chip 晶片 Name 名稱 Page size 頁面大小 Block size 區塊大小 VCC, Volt VCC(伏) 4byte Addr. 4 位元組位址 Detect 偵測 Read 讀取 i i I2C bus speed I2C 匯流排速度 Erase size 擦除大小 ECC size ECC 大小 Auto Options 自動選項 Erase 清除 Program 程式 Verify 驗證 Go! 開始! Hex Editor 十六進位編輯器 JEDEC ID: JEDEC ID: CH341a: CH341A: border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; CRC32: CRC32: Message 訊息 Programmer 程式燒錄器 Help 說明 Operations 操作 Check erase 檢查清除 Ctrl+S Ctrl+S Ctrl+D Ctrl+D Ctrl+R Ctrl+R Ctrl+E Ctrl+E Write 寫入 Ctrl+W Ctrl+W Ctrl+T Ctrl+T Undo 復原 Ctrl+Z Ctrl+Z Redo 重做 Ctrl+Y Ctrl+Y Ctrl+N Ctrl+N Import from Intel HEX 從 Intel HEX 匯入 Export to Intel HEX 匯出為 Intel HEX Extract from ASUS CAP 從 ASUS CAP 提取 Goto address 前往位址 Move the cursor to the entered address 將游標移至輸入的位址 Ctrl+G Ctrl+G Security registers 安全暫存器 Ctrl+U Ctrl+U Fill test image 填充測試映像 Filling the hex editor with a test array 用測試陣列填充十六進位編輯器 Ctrl+L Ctrl+L Compare files 比較檔案 Compares the results of the last and penultimate chip read or file open operation 比較最後一次和倒數第二次晶片讀取或檔案開啟操作的結果 Ctrl+M Ctrl+M Copy 複製 Paste 貼上 Bad block management 壞區塊管理 Ctrl+B Ctrl+B Show programmer version 顯示程式版本 Check erase chip 檢查晶片是否已清除 Ctrl+J Ctrl+J Filling with code 正在填入程式碼 Ctrl+K Ctrl+K CH341A/B v1.2 CH341A/B v1.2 CH341A v1.7 CH341A v1.7 CH347T v1.0 CH347T v1.0 CH347T v1.1 CH347T v1.1 CH347T CH347T Save Part 部分儲存 Load Part 部分載入 Find / Replace 尋找/取代 Ctrl+F Ctrl+F About 關於 About IMSProgrammer 關於 IMSProg Ctrl+H Ctrl+H Checksum calculate 計算校驗和 Ctrl+A Ctrl+A Edit chips Database 編輯晶片資料庫 Ctrl+Q Ctrl+Q Stop 停止 Forced stop of read, write, erase and verification operations 強制停止讀取、寫入、清除和驗證操作 Ctrl+I Ctrl+I Chip info 晶片資訊 Information about SFDP and status registers 有關 SFDP 和狀態暫存器的資訊 Ctrl+P Ctrl+P Current file: 目前檔案: Type 類型 Manufacture 製造商 Size 大小 Opening DAT file 開啟 DAT 檔案 Error 錯誤 Programmer is not connected! 程式燒錄器未連接! The ending address must not exceed the buffer size. 結束位址不得超過緩衝區大小。 File 'IMSProg_editor' not found! 找不到檔案 `IMSProg_editor`! Error loading chip database file! 載入晶片資料庫檔案時發生錯誤! Parsing DAT file 解析 DAT 檔案 Reading data from 讀取資料來源 Unsupported chip type! 不支援的晶片類型! Programmer CH341a is not connected! CH341A 程式燒錄器未連接! Error reading block 讀取區塊時發生錯誤 Before reading from chip please press 'Detect' button. 讀取晶片資料前,請按下 '偵測' 按鈕。 Please select the chip parameters - manufacture and chip name 請選擇晶片參數 - '製造商' 和晶片 '名稱' The chip is not connect or missing! 晶片未連接或遺失! Saving file 儲存檔案 Save file 儲存檔案 Data Images 資料檔案 All files 所有檔案 Error saving file! 儲存檔案時發生錯誤! Erasing the 正在清除 Error erasing sector 清除磁區時發生錯誤 Opening file 開啟檔案 Open file 開啟檔案 The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file. 檔案大小超過晶片容量。請選擇其他晶片或檔案,或使用「部分儲存」分割檔案。 Writing data to 正在寫入資料至 Error writing sector 寫入磁區時發生錯誤 Veryfing data from 正在驗證資料來源 Cannot find a chip database file. You may want to run IMSProg_database_update 找不到晶片資料庫檔案。 您可能需要執行 IMSProg_database_update Error comparing data! Address: 比對資料時發生錯誤! 位址: Buffer: 緩衝區: Chip: 晶片: Error comparing data! Address: 比較資料時出錯! 地址: Buffer: 緩衝: Please select the chip parameters - manufacture and chip name. 請選擇晶片參數 - '製造商' 和晶片 '名稱'。 Ok! 確定! The operation was successful! 操作成功! The end address must be greater than the starting address. 結束位址必須大於起始位址。 Saving block 儲存區塊 Save block 儲存區塊 Opening block 開啟區塊 Open block 開啟區塊 The end address out of image size! 結束位址超出映像檔大小! Connected 已連接 Not connected 未連接 The chip database file was not found! 找不到晶片資料庫檔案! Error loading chip database file! File: %1 Error Code: %2 Reason: %3 載入晶片資料庫檔案時發生錯誤! 檔案:%1 錯誤代碼:%2 原因:%3 Before working with the security registers, click the 'Detect' button 在使用安全暫存器之前,請點擊 '偵測'按鈕 There are no security registers in this chip or the current version of IMSProg does not support this algorithm. 此晶片沒有安全暫存器,或目前版本的 IMSProg 不支援此演算法。 Intel HEX Images Intel HEX 檔案 Not valid HEX format! 無效的 HEX 格式! The address is larger than the size of the chip! 位址大於晶片容量! Checksum error! 校驗和錯誤! Info: 資訊: Device revision: 裝置修訂版: Erase checking in 正在檢查 Error erasing chip! Address: 擦除晶片時發生錯誤! 地址: Need: FF 需要:FF Operation aborted! 操作已中止! SearchDialog QHexEdit - Find/Replace QHexEdit - 尋找/取代 Find 尋找 Hex Hex UTF-8 UTF-8 Replace 取代 Options 選項: &Backwards 向後(&B) &Prompt on replace 取代時提示(&P) Standard headers: 標準標頭: ZIP ZIP PNG PNG JPG JPG GIF GIF TAR TAR UEFI UEFI BIOS BIOS GPT GPT &Find 尋找(&F) F3 F3 &Replace 取代(&R) Replace &All 全部取代(&A) &Close 關閉(&C) QHexEdit QHexEdit %1 occurrences replaced. 已取代 %1 個項目。 Replace occurrence? 要取代此項目嗎? UndoStack Inserting %1 bytes 插入 %1 位元組 Delete %1 chars 刪除 %1 個字元 Overwrite %1 chars 覆寫 %1 個字元 imsprog-1.8.5/IMSProg_programmer/main.cpp000066400000000000000000000057171520775651600204000ustar00rootroot00000000000000/* * Copyright (C) 2023 Mikhail Medvedev * * * 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. */ #include "mainwindow.h" #include #include #include #include #include #include static QString setUpTranslation(const QStringList &searchPaths) { QString localeName = QLocale::system().name(); QString translateName = "chipProgrammer_" + localeName; // skip user-specific dir for translations (first one); try the rest foreach (const QString &path, searchPaths.mid(1)) { QTranslator *translator = new QTranslator(qApp); if (translator->load(translateName, path)) { qApp->installTranslator(translator); qDebug() << "Installed" << translateName << "from" << path; return path; } else { delete translator; } } return QString(); } static QString findSystemChipDBFile(const QStringList &searchPaths) { foreach (const QString &path, searchPaths.mid(1)) { QString chipdbfile = QDir(path).filePath("IMSProg.Dat"); if (QFile::exists(chipdbfile)) { return chipdbfile; } } return QString(); } static void initPaths() { QStringList allPaths = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); if (allPaths.isEmpty()) { // do not translate qFatal("Critical error: QStandardPaths::standardLocations(QStandardPaths::AppDataLocation): empty list"); } QDir binDir(QCoreApplication::applicationDirPath()); QString binRelPath = QDir::cleanPath(binDir.absoluteFilePath("../share/" + QCoreApplication::applicationName())); allPaths.insert(1, binRelPath); QDir userAppDataLocation(allPaths.value(0)); if (!userAppDataLocation.exists()) { userAppDataLocation.mkpath("."); // XXX some sort of error handling that befits the application } qApp->setProperty("app/translationDirectory", setUpTranslation(allPaths)); qApp->setProperty("app/systemChipDatabaseFile", findSystemChipDBFile(allPaths)); qApp->setProperty("app/userChipDatabaseFile", userAppDataLocation.filePath("IMSProg.Dat")); qApp->setProperty("app/userConfigFile", userAppDataLocation.filePath("config.ini")); } int main(int argc, char *argv[]) { QCoreApplication::setApplicationName("imsprog"); qDebug() << "Used Qt version:" << QT_VERSION_STR; QApplication a(argc, argv); initPaths(); MainWindow w; w.show(); return a.exec(); } imsprog-1.8.5/IMSProg_programmer/mainwindow.cpp000066400000000000000000003377351520775651600216400ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2026 Mikhail Medvedev * * 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 3 * 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. */ #include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "qhexedit.h" #include "dialogsp.h" #include "dialogrp.h" #include "dialogsetaddr.h" #include "dialogsecurity.h" #include "dialognandsecurity.h" #include "dialognandsr.h" #include "dialogbbm.h" #include "dialogfill.h" #include "hexutility.h" #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); max_rec = 0; isHalted = false; lastDirectory = QDir::homePath(); //"/home/"; grnKeyStyle = "QPushButton{color:#fff;background-color: rgb(120, 183, 140);border-radius: 20px;border: 2px solid #094065;border-radius:8px;font-weight:600;}QPushButton::pressed{background-color: rgb(115, 210, 22);}"; redKeyStyle = "QPushButton{color:#fff;background-color:#f66;border-radius: 20px;border: 2px solid #094065;border-radius:8px;font-weight:600;}"; timer = new QTimer(); connect(timer, SIGNAL(timeout()), this, SLOT(slotTimerAlarm())); timer->start(2000); //10000 ui->actionSetProgrammerType->setExclusive(true); ui->statusMessage->setText(""); ui->actionStop->setDisabled(true); ui->statusBar->addPermanentWidget(ui->statusMessage,1); ui->statusBar->addPermanentWidget(ui->lStatus,0); ui->statusBar->addPermanentWidget(ui->eStatus,0); ui->statusBar->addPermanentWidget(ui->jLabel,0); ui->statusBar->addPermanentWidget(ui->jedecEdit,0); ui->statusBar->addPermanentWidget(ui->cLabel,0); ui->statusBar->addPermanentWidget(ui->crcEdit,0); ui->progressBar->setStyle(QStyleFactory::create("Fusion")); ui->progressBar->setValue(0); ui->comboBox_name->addItems({""}); ui->comboBox_man->addItems({""}); ui->comboBox_vcc->addItem(" ", 0); ui->comboBox_vcc->addItem("3.3 V", 1); ui->comboBox_vcc->addItem("1.8 V", 2); ui->comboBox_vcc->addItem("2.5 V", 3); ui->comboBox_vcc->addItem("5.0 V", 4); ui->comboBox_type->addItem("SPI_FLASH", 0); ui->comboBox_type->addItem("24_EEPROM", 1); ui->comboBox_type->addItem("93_EEPROM", 2); ui->comboBox_type->addItem("25_EEPROM", 3); ui->comboBox_type->addItem("95_EEPROM", 4); ui->comboBox_type->addItem("45_EEPROM", 5); ui->comboBox_type->addItem("SPI_NAND ", 6); ui->comboBox_addr4bit->addItem("No", 0); ui->comboBox_addr4bit->addItem("Yes", 0x01); ui->comboBox_addr4bit->addItem("Winbond", 0x11); ui->comboBox_addr4bit->addItem("Spansion", 0x21); ui->comboBox_page->addItem(" ", 0); ui->comboBox_page->addItem("256", 256); ui->comboBox_block->addItem(" ", 0); ui->comboBox_block->addItem("64 K", 64 * 1024); ui->comboBox_block->addItem("128 K", 128 * 1024); ui->comboBox_block->addItem("256 K", 256 * 1024); ui->comboBox_ECC->addItem(" ", 0); ui->comboBox_ECC->addItem("64", 1); ui->comboBox_ECC->addItem("128", 2); ui->comboBox_ECC->addItem("256", 3); ui->comboBox_i2cSpeed->addItem("20 kHz", 0); ui->comboBox_i2cSpeed->addItem("100 kHz", 1); ui->comboBox_i2cSpeed->addItem("400 kHz", 2); ui->comboBox_i2cSpeed->addItem("750 kHz", 3); ui->comboBox_i2cSpeed->setCurrentIndex(2); currentI2CBusSpeed = 2; ui->comboBox_raw->addItem("Data only", 0); ui->comboBox_raw->addItem("Data + ECC", 1); current_programmer = 0; currentChipSize = 0; currentNumBlocks = 0; currentBlockSize = 0; currentPageSize = 0; currentAlgorithm = 0; currentChipType = 0; blockStartAddr = 0; blockLen = 0; currentAddr4bit = 0; currentECCsize = 0; filled = 0; numberOfReads = 0; nandSettings = 0; cmdStarted = false; chipData.reserve(512 * 1024 *1024 + 2048); chipData.resize(256); chipData.fill(char(0xff)); oldChipData.reserve(512 * 1024 *1024 + 2048); oldChipData.resize(256); oldChipData.fill(char(0xff)); nandRaw = false; //Reading ini file QString iniPath = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("config.ini"); qDebug() << "Using config file " << iniPath; if (QFileInfo(iniPath).exists()) { QSettings settings(iniPath, QSettings::IniFormat); settings.beginGroup("Chip"); lastDirectory = settings.value("ChipDirectory").toString(); settings.endGroup(); settings.beginGroup("Device"); current_programmer = static_cast(settings.value("ProgrammerType").toInt()); if (current_programmer == 0) ui->actionCH341A_B_v1_2->setChecked(true); if (current_programmer == 1) ui->actionCH341A_v1_7->setChecked(true); if (current_programmer == 2) { ui->actionCH347T->setChecked(true); SetItemStatus("comboBox_type", 2, true); } if (current_programmer == 3) { ui->actionCH347T_v1_1->setChecked(true); SetItemStatus("comboBox_type", 2, true); } settings.endGroup(); settings.beginGroup("FormPosition"); if (settings.contains("geometry")) { restoreGeometry(settings.value("geometry").toByteArray()); } settings.endGroup(); } // connect and status check if (current_programmer < 2) ui->lStatus->setText("CH341A"); if (current_programmer >= 2) ui->lStatus->setText("CH347T"); statusCH341 = ProgDeviceInit(current_programmer, currentChipType, currentI2CBusSpeed); ch341StatusFlashing(); ProgDeviceClose(current_programmer); QFont heFont; heFont = QFont("Monospace", 10); hexEdit = new QHexEdit(ui->frame); hexEdit->setData(chipData); hexEdit->setHexCaps(true); hexEdit->setFont(heFont); QStringList commandLineParams = QCoreApplication::arguments(); QString commandLineFileName =""; if (commandLineParams.count() > 1) { commandLineFileName = commandLineParams[1]; QFileInfo commandLine(commandLineFileName); if ((commandLine.exists()) && !(QString::compare(commandLine.suffix(), "bin", Qt::CaseInsensitive))) { lastDirectory = commandLineFileName; cmdStarted = true; } } progInit(); if (cmdStarted) on_actionOpen_triggered(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { //Reading data from chip newFileName = ui->comboBox_name->currentText(); int res = 0; uint32_t numBlocks, step, sectorsPerBlock; statusCH341 = ProgDeviceInit(current_programmer, currentChipType, currentI2CBusSpeed); if (statusCH341 == 0) { ui->crcEdit->setText(""); if (((currentNumBlocks > 0) && (currentBlockSize >0) && (currentChipType == 0)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 1)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 2)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 3)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 4)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 5)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 6))) { doNotDisturb(); ch341StatusFlashing(); if (numberOfReads > 0) { oldChipData = chipData; oldFileName = ui->comboBox_name->currentText(); } uint32_t addr = 0; uint32_t curBlock = 0; uint32_t k; switch (currentChipType) { case 0: //SPI step = currentBlockSize; numBlocks = currentNumBlocks; break; case 1: //I2C step = 128; //step = currentPageSize; numBlocks = currentChipSize / step; break; case 2: //MicroWire case 3: //25xxx case 4: //95xxx case 5: //45xx step = currentPageSize; numBlocks = currentChipSize / step; break; case 6: //NAND 35xx, GD5xx, W25xx numBlocks = currentChipSize / currentBlockSize; sectorsPerBlock = currentBlockSize / currentPageSize; if (nandRaw == true) step = currentBlockSize + currentECCsize * sectorsPerBlock; else step = currentBlockSize; nand_ECCEnable(current_programmer); break; default: //Unsupport QMessageBox::about(this, tr("Error"), tr("Unsupported chip type!")); doNotDisturbCancel(); ProgDeviceClose(current_programmer); ui->checkBox_3->setStyleSheet(""); return; } //progerssbar settings int currentPercent = 0; int lastPercent = -1; //ui->progressBar->setRange(0, static_cast(numBlocks)); ui->progressBar->setRange(0, 100); ui->progressBar->setValue(0); std::shared_ptr buf(new uint8_t[step]); ui->pushButton->setStyleSheet(redKeyStyle); ui->statusMessage->setText(tr("Reading data from ") + ui->comboBox_name->currentText()); for (k = 0; k < numBlocks; k++) { switch (currentChipType) { case 0: //SPI res = snor_read_param(buf.get(), curBlock * step, step, step, currentAddr4bit, current_programmer); break; case 1: //I2C res = ch34xi2cBlockRead(buf.get(), curBlock * step, step, currentAlgorithm, current_programmer); if (res==0) res = 1; break; case 2: //MicroWire res = Read_EEPROM_3wire_param(buf.get(), static_cast(curBlock * step), static_cast(step), static_cast(currentChipSize), currentAlgorithm); if (res==0) res = 1; break; case 3: //25xxx case 4: //95xxx res = s95_read_param(buf.get(), curBlock * step, step, step, currentAlgorithm, current_programmer); break; case 5: //45xx res = at45_read_param(buf.get(), curBlock * step, step, step, currentAlgorithm, current_programmer); break; case 6: //NAND if (nandRaw == true) res = nand_block_read(buf.get(), currentPageSize + currentECCsize, k, sectorsPerBlock, current_programmer); else res = nand_block_read(buf.get(), currentPageSize, k, sectorsPerBlock, current_programmer); if (res==0) res = 1; break; default: //Unsupport QMessageBox::about(this, tr("Error"), tr("Unsupported chip type!")); doNotDisturbCancel(); ProgDeviceClose(current_programmer); return; } // if res=-1 - error, stop if (statusCH341 != 0) { QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); doNotDisturbCancel(); break; } if (res <= 0) { QMessageBox::about(this, tr("Error"), tr("Error reading block ") + QString::number(curBlock)); ProgDeviceClose(current_programmer); ui->pushButton->setStyleSheet(grnKeyStyle); doNotDisturbCancel(); return; } memcpy(chipData.data() + addr, buf.get() + (addr - k * step), step); addr = addr + step; if (curBlock * step < 0x500) hexEdit->setData(chipData); //show buffer in hehedit while chip data is visible curBlock++; qApp->processEvents(); //ui->progressBar->setValue(static_cast(curBlock)); currentPercent = static_cast((curBlock * 100.0) / numBlocks); if (currentPercent != lastPercent) { ui->progressBar->setValue(currentPercent); lastPercent = currentPercent; } if (isHalted) { isHalted = false; ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } } } else { //Not correct Number found size of blocks ProgDeviceClose(current_programmer); if ((currentChipType == 0) || (currentChipType > 4)) QMessageBox::about(this, tr("Error"), tr("Before reading from chip please press 'Detect' button.")); else QMessageBox::about(this, tr("Error"), tr("Please select the chip parameters - manufacture and chip name")); return; } hexEdit->setData(chipData); ui->statusMessage->setText(""); ui->progressBar->setValue(0); ui->pushButton->setStyleSheet(grnKeyStyle); ui->crcEdit->setText(getCRC32(chipData)); newFileName = ui->comboBox_name->currentText(); } else { ch341StatusFlashing(); QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); } ProgDeviceClose(current_programmer); doNotDisturbCancel(); filled = 0; numberOfReads++; } void MainWindow::on_pushButton_2_clicked() { timer->stop(); //Detect button - searching the connected chip in database u8 sr; statusCH341 = ProgDeviceInit(current_programmer, currentChipType, currentI2CBusSpeed); ch341StatusFlashing(); if (statusCH341 != 0) { QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); timer->start(); return; } ui->pushButton_2->setStyleSheet(redKeyStyle); ui->crcEdit->setText(""); int i, index; // print JEDEC info unsigned char bufid[5] = {0xff,0xff,0xff,0xff,0xff}; if (currentChipType != 6) { snor_read_devid(bufid, 5, current_programmer); } else { nand_read_devid(bufid, 5, current_programmer); } if ((bufid[0] == 0xff) && (bufid[1] == 0xff) && (bufid[2] == 0xff) && (currentChipType != 5)) { QMessageBox::about(this, tr("Error"), tr("The chip is not connect or missing!")); ui->pushButton_2->setStyleSheet(grnKeyStyle); ProgDeviceClose(current_programmer); timer->start(); return; } if (((bufid[0] == 0xff) || (bufid[0] == 0x00)) && (bufid[1] != 0xff)) ui->comboBox_type->setCurrentIndex(6); if ((currentChipType == 6) && ((bufid[0] == 0xff) ||(bufid[0] == 0x00))) { nand_read_devid(bufid, 5, current_programmer); } ui->jedecEdit->setText(bytePrint(bufid[0]) + " " + bytePrint(bufid[1]) + " " + bytePrint(bufid[2])); for (i = 0; i< max_rec; i++) { if ((bufid[0] == chips[i].chipJedecIDMan) && (bufid[1] == chips[i].chipJedecIDDev) && (bufid[2] == chips[i].chipJedecIDCap)) { index = ui->comboBox_type->findText(chips[i].chipTypeTxt); if ( index != -1 ) { // -1 for not found ui->comboBox_type->setCurrentIndex(index); } index = ui->comboBox_man->findText(chips[i].chipManuf); if ( index != -1 ) { // -1 for not found ui->comboBox_man->setCurrentIndex(index); } index = ui->comboBox_name->findText(chips[i].chipName); if ( index != -1 ) { // -1 for not found ui->comboBox_name->setCurrentIndex(index); } index = ui->comboBox_size->findData(chips[i].chipSize); if ( index != -1 ) { // -1 for not found ui->comboBox_size->setCurrentIndex(index); } index = ui->comboBox_page->findData(chips[i].sectorSize); if ( index != -1 ) { // -1 for not found ui->comboBox_page->setCurrentIndex(index); } index = ui->comboBox_block->findData(chips[i].blockSize); if ( index != -1 ) { // -1 for not found ui->comboBox_block->setCurrentIndex(index); } index = ui->comboBox_addr4bit->findData(chips[i].addr4bit); if ( index != -1 ) { // -1 for not found ui->comboBox_addr4bit->setCurrentIndex(index); } index = ui->comboBox_vcc->findText(chips[i].chipVCC); if ( index != -1 ) { // -1 for not found ui->comboBox_vcc->setCurrentIndex(index); } index = ui->comboBox_vcc->findData(chips[i].eepromPages); if ( index != -1 ) { // -1 for not found ui->comboBox_ECC->setCurrentIndex(index); } ui->pushButton_2->setStyleSheet(grnKeyStyle); break; } } // 45xxx without JEDEC info if ((currentChipType == 5) && (bufid[0] == 0xff) && (bufid[1] == 0xff) && (bufid[2] == 0xff) ) { //calculating capacity int capacityIndex = 0; if (!at45_read_sr(&sr)) { if ((sr & 0xC0) == 0x80) //45xx chip found { sr = sr & 0x38; switch (sr) { case 0x08: //132K capacityIndex = 1; break; case 0x10: //264K capacityIndex = 2; break; case 0x18: //528K capacityIndex = 3; break; case 0x20: //1056K capacityIndex = 4; break; case 0x28: //2112K capacityIndex = 5; break; case 30: //4224K capacityIndex = 6; break; } ui->comboBox_size->setCurrentIndex(capacityIndex); for (i = 0; i< max_rec; i++) { if ((chips[i].chipTypeHex == 0x05) && (chips[i].chipSize == ui->comboBox_size->currentData().toUInt())) { if (!QString::compare(chips[i].chipManuf, "ATMEL", Qt::CaseInsensitive)) { index = ui->comboBox_type->findText(chips[i].chipTypeTxt); if ( index != -1 ) { // -1 for not found ui->comboBox_type->setCurrentIndex(index); } index = ui->comboBox_man->findText(chips[i].chipManuf); if ( index != -1 ) { // -1 for not found ui->comboBox_man->setCurrentIndex(index); } index = ui->comboBox_name->findText(chips[i].chipName); if ( index != -1 ) { // -1 for not found ui->comboBox_name->setCurrentIndex(index); } index = ui->comboBox_size->findData(chips[i].chipSize); if ( index != -1 ) { // -1 for not found ui->comboBox_size->setCurrentIndex(index); } index = ui->comboBox_page->findData(chips[i].sectorSize); if ( index != -1 ) { // -1 for not found ui->comboBox_page->setCurrentIndex(index); } index = ui->comboBox_block->findData(chips[i].blockSize); if ( index != -1 ) { // -1 for not found ui->comboBox_block->setCurrentIndex(index); } index = ui->comboBox_addr4bit->findData(chips[i].addr4bit); if ( index != -1 ) { // -1 for not found ui->comboBox_addr4bit->setCurrentIndex(index); } index = ui->comboBox_vcc->findText(chips[i].chipVCC); if ( index != -1 ) { // -1 for not found ui->comboBox_vcc->setCurrentIndex(index); } ui->pushButton_2->setStyleSheet(grnKeyStyle); break; } } } } } } if ((currentChipType == 5) && (ui->comboBox_size->currentIndex() > 0)) { //calculate buffer size if (!at45_read_sr(&sr)) { if ((sr & 0x01) == 1) { if ( ui->comboBox_page->currentData() == 264) { index = ui->comboBox_page->findData(256); if ( index != -1 ) { // -1 for not found ui->comboBox_page->setCurrentIndex(index); } } if ( ui->comboBox_page->currentData() == 528) { index = ui->comboBox_page->findData(512); if ( index != -1 ) { // -1 for not found ui->comboBox_page->setCurrentIndex(index); } } } } } ui->pushButton_2->setStyleSheet(grnKeyStyle); ui->crcEdit->setText(getCRC32(chipData)); ProgDeviceClose(current_programmer); timer->start(); } void MainWindow::on_comboBox_size_currentIndexChanged(int index) { currentChipSize = ui->comboBox_size->currentData().toUInt(); currentBlockSize = ui->comboBox_block->currentData().toUInt(); currentPageSize = ui->comboBox_page->currentData().toUInt(); currentAddr4bit = ui->comboBox_addr4bit->currentData().toUInt(); currentECCsize = (ui->comboBox_ECC->currentData().toUInt()) * 64; if ((currentChipSize !=0) && (currentBlockSize!=0) && (currentChipType == 0)) { currentNumBlocks = currentChipSize / currentBlockSize; preparingToCompare(1); numberOfReads = 0; chipData.resize(static_cast(currentChipSize)); chipData.fill(char(0xff)); filled = 1; hexEdit->setData(chipData); } if ((currentChipSize !=0) && (currentPageSize!=0) && (currentChipType > 0)) { currentNumBlocks = currentChipSize / currentPageSize; preparingToCompare(1); numberOfReads = 0; if ((currentChipType == 6) && (nandRaw == true)) chipData.resize(static_cast(currentChipSize + currentChipSize/currentPageSize * currentECCsize)); else chipData.resize(static_cast(currentChipSize)); chipData.fill(char(0xff)); filled = 1; hexEdit->setData(chipData); } index = index + 0; } void MainWindow::on_comboBox_page_currentIndexChanged(int index) { currentChipSize = ui->comboBox_size->currentData().toUInt(); currentBlockSize = ui->comboBox_block->currentData().toUInt(); currentPageSize = ui->comboBox_page->currentData().toUInt(); currentAddr4bit = ui->comboBox_addr4bit->currentData().toUInt(); currentECCsize = (ui->comboBox_ECC->currentData().toUInt()) * 64; if ((currentChipSize !=0) && (currentBlockSize!=0) && (currentChipType ==0)) { currentNumBlocks = currentChipSize / currentBlockSize; } if ((currentChipSize !=0) && (currentPageSize!=0) && (currentChipType > 0)) { currentNumBlocks = currentChipSize / currentPageSize; } index = index + 0; } void MainWindow::on_actionDetect_triggered() { MainWindow::on_pushButton_2_clicked(); } void MainWindow::on_actionSave_triggered() { lastDirectory.replace(".cap", ".bin"); lastDirectory.replace(".CAP", ".bin"); lastDirectory.replace(".hex", ".bin"); lastDirectory.replace(".HEX", ".bin"); ui->statusMessage->setText(tr("Saving file")); fileName = QFileDialog::getSaveFileName(this, QString(tr("Save file")), lastDirectory, tr("Data Images") + " (*.bin *.BIN);;" + tr("All files") + " (*.*)"); if (fileName.isEmpty()) return; QFileInfo info(fileName); lastDirectory = info.filePath(); if (QString::compare(info.suffix(), "bin", Qt::CaseInsensitive)) fileName = fileName + ".bin"; QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) { QMessageBox::about(this, tr("Error"), tr("Error saving file!")); return; } file.write(hexEdit->data()); file.close(); ui->statusMessage->setText(""); } void MainWindow::on_actionErase_triggered() { //statusCH341 = ch341a_spi_init(); int ret; uint32_t curBlock, numBlocks, step; statusCH341 = ProgDeviceInit(current_programmer, currentChipType, currentI2CBusSpeed);//ch341a_init(currentChipType, currentI2CBusSpeed); ch341StatusFlashing(); if (statusCH341 != 0) { QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); return; } ui->statusMessage->setText(tr("Erasing the ") + ui->comboBox_name->currentText()); ui->checkBox->setStyleSheet("QCheckBox{font-weight:600;}"); ui->centralWidget->repaint(); ui->progressBar->setRange(0, 100); doNotDisturb(); if (currentChipType == 0) { snorUnprotect(current_programmer); if (currentNumBlocks > 0) { ui->progressBar->setRange(0, static_cast(currentNumBlocks)); for (uint32_t curBlock = 0; curBlock < currentNumBlocks; curBlock++) { //config_stream(2); ret = snor_block_erase( curBlock, currentBlockSize, static_cast(currentAddr4bit), current_programmer); if (ret != 0) { QMessageBox::about(this, tr("Error"), tr("Error erasing sector ") + QString::number(curBlock)); ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } qApp->processEvents(); ui->progressBar->setValue( static_cast(curBlock)); if (isHalted) { isHalted = false; ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } } } } if ((currentChipType == 4) || ((currentChipType == 3) && ((currentAlgorithm & 0x20) == 0))) { uint32_t k; int res = 0; step = currentPageSize; numBlocks = currentChipSize / step; std::shared_ptr buf(new uint8_t[step]); config_stream(2); if (isHalted) { isHalted = false; ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } ui->progressBar->setRange(0, static_cast(numBlocks)); for (k = 0; k < step; k++) { buf[k] = 0xff; } for (curBlock = 0; curBlock < currentNumBlocks; curBlock++) { res = s95_write_param(buf.get(), curBlock * step, step, step, currentAlgorithm, current_programmer); qApp->processEvents(); ui->progressBar->setValue( static_cast(curBlock)); if (res <= 0) { QMessageBox::about(this, tr("Error"), tr("Error erasing sector ") + QString::number(curBlock)); ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } } } if ((currentChipType == 3) && ((currentAlgorithm & 0x20) > 0)) { ui->progressBar->setValue(50); s95_full_erase(current_programmer); sleep(1); } if (currentChipType == 2) { config_stream(1); mw_gpio_init(); ui->progressBar->setValue(50); Erase_EEPROM_3wire_param(currentAlgorithm); sleep(1); } if (currentChipType == 1) { uint32_t curBlock = 0; uint32_t k; int res = 0; step = 128; //step = currentPageSize; numBlocks = currentChipSize / step; std::shared_ptr buf(new uint8_t[step]); config_stream(2); if (isHalted) { isHalted = false; ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } ui->progressBar->setRange(0, static_cast(numBlocks)); for (k = 0; k < step; k++) { buf[k] = 0xff; } for (curBlock = 0; curBlock < numBlocks; curBlock++) { res = ch34xi2cBlockWrite(buf.get(), curBlock * step, step, currentPageSize, currentAlgorithm, current_programmer); if (res==0) res = 1; qApp->processEvents(); ui->progressBar->setValue( static_cast(curBlock)); if (res <= 0) { QMessageBox::about(this, tr("Error"), tr("Error erasing sector ") + QString::number(curBlock)); ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } } } if ((currentChipType == 5) && ((currentAlgorithm & 0x10) > 0)) { ui->progressBar->setValue(50); at45_full_erase(current_programmer); sleep(1); } if ((currentChipType == 5) && ((currentAlgorithm & 0x10) == 0)) { numBlocks = currentChipSize / currentPageSize / 8; ui->progressBar->setRange(0, static_cast(numBlocks)); uint32_t curBlock = 0; for (curBlock = 0; curBlock < numBlocks; curBlock++) { at45_sector_erase(curBlock, currentPageSize, current_programmer); ui->progressBar->setValue(static_cast(curBlock)); } } if (currentChipType == 6) { uint32_t sectInBlock; int retval; numBlocks = currentChipSize / currentBlockSize; sectInBlock = currentBlockSize / currentPageSize; if (numBlocks > 0) { ui->progressBar->setRange(0, static_cast(numBlocks)); for (uint32_t curBlock = 0; curBlock < numBlocks; curBlock++) { if ((nandSettings & 0xf0) == 0x00) { retval = nand_checkBadBlock(static_cast(curBlock), static_cast(currentPageSize), static_cast(sectInBlock), current_programmer); } else retval = 0; if (retval == 0) //skip bad sectors, if checkbox enable { ret = nand_block_erase( curBlock, currentBlockSize, current_programmer); if (ret != 0) { QMessageBox::about(this, tr("Error"), tr("Error erasing sector ") + QString::number(curBlock)); ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } } qApp->processEvents(); ui->progressBar->setValue( static_cast(curBlock)); if (isHalted) { isHalted = false; ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } } } } doNotDisturbCancel(); ui->checkBox->setStyleSheet(""); ui->statusMessage->setText(""); ui->progressBar->setValue(0); ui->centralWidget->repaint(); ProgDeviceClose(current_programmer); } void MainWindow::on_actionUndo_triggered() { hexEdit->undo(); } void MainWindow::on_actionRedo_triggered() { hexEdit->redo(); } void MainWindow::on_actionOpen_triggered() { QByteArray buf; ui->statusMessage->setText(tr("Opening file")); if (numberOfReads == 0) oldFileName = fileName; else oldFileName = ui->comboBox_name->currentText(); if (!cmdStarted) { fileName = QFileDialog::getOpenFileName(this, QString(tr("Open file")), lastDirectory, tr("Data Images") + " (*.bin *.BIN *.rom *.ROM);;" + tr("All files") + " (*.*)"); } else fileName = lastDirectory; cmdStarted = false; QFileInfo info(fileName); uint32_t arraySize; lastDirectory = info.filePath(); // if ChipSze = 0 (Chip is not selected) IMSProg using at hexeditor only. chipsize -> hexedit.data // if ChipSize < FileSize - showing error message // if Filesize <= ChipSize - filling fileArray to hexedit.Data, the end of the array chipData remains filled 0xff QFile file(fileName); ui->statusMessage->setText(""); if ((currentChipType == 6) && (nandRaw == true)) arraySize = currentChipSize + currentChipSize/currentPageSize * currentECCsize; else arraySize = currentChipSize; if ((info.size() > arraySize) && (currentChipSize != 0)) { QMessageBox::about(this, tr("Error"), tr("The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file.")); return; } if (!file.open(QIODevice::ReadOnly)) { return; } ui->statusMessage->setText(tr("Current file: ") + info.fileName()); preparingToCompare(0); filled = 0; buf.resize(static_cast(info.size())); buf = file.readAll(); if (currentChipSize == 0) { chipData.resize(static_cast(info.size())); } chipData.replace(0, static_cast(info.size()), buf); hexEdit->setData(chipData); file.close(); ui->crcEdit->setText(getCRC32(chipData)); } void MainWindow::on_actionExtract_from_ASUS_CAP_triggered() { QByteArray buf; ui->statusMessage->setText(tr("Opening file")); if (numberOfReads == 0) oldFileName = fileName; else oldFileName = ui->comboBox_name->currentText(); fileName = QFileDialog::getOpenFileName(this, QString(tr("Open file")), lastDirectory, "ASUS Data Images (*.cap *.CAP);;All files (*.*)"); QFileInfo info(fileName); ui->statusMessage->setText(""); lastDirectory = info.filePath(); if ((info.size() - 0x800 > currentChipSize) && (currentChipSize != 0)) { QMessageBox::about(this, tr("Error"), tr("The file size exceeds the chip size. Please select another chip or file or use `Save part` to split the file.")); return; } QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { return; } ui->statusMessage->setText(tr("Current file: ") + info.fileName()); preparingToCompare(0); filled = 0; buf.resize(int(info.size())); buf = file.readAll(); file.close(); fileName.clear(); buf.remove(0,0x800); if (currentChipSize == 0) { chipData.resize(static_cast(info.size()) - 0x800); } chipData.replace(0, static_cast(info.size()) - 0x800, buf); hexEdit->setData(chipData); ui->crcEdit->setText(getCRC32(chipData)); } void MainWindow::on_actionWrite_triggered() { //Writting data to chip int res = 0, badResult = 0; uint32_t numBlocks, step, sectorsPerBlock; statusCH341 = ProgDeviceInit(current_programmer, currentChipType, currentI2CBusSpeed);//statusCH341 = ProgDeviceInit(current_programmer);//ch341a_init(currentChipType, currentI2CBusSpeed); if (statusCH341 == 0) { chipData = hexEdit->data(); if (((currentNumBlocks > 0) && (currentBlockSize >0) && (currentChipType == 0)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 1)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 2)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 3)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 4)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 5)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 6))) { doNotDisturb(); switch (currentChipType) { case 0: //SPI step = currentBlockSize; numBlocks = currentNumBlocks; snorUnprotect(current_programmer); break; case 1: //I2C step = 128; //step = currentPageSize; numBlocks = currentChipSize / step; break; case 2: //MicroWire case 3: //25xxx case 4: //95xxx case 5: //45xx step = currentPageSize; numBlocks = currentChipSize / step; break; case 6: //NAND 35xx, GD5xx, W25xx numBlocks = currentChipSize / currentBlockSize; sectorsPerBlock = currentBlockSize / currentPageSize; if (nandRaw == true) { step = currentBlockSize + currentECCsize * sectorsPerBlock; nand_ECCDisable(current_programmer); } else { step = currentBlockSize; nand_ECCEnable(current_programmer); } nand_unprotect(current_programmer); break; default: //Unsupport QMessageBox::about(this, tr("Error"), tr("Unsupported chip type!")); doNotDisturbCancel(); ProgDeviceClose(current_programmer); ui->checkBox_2->setStyleSheet(""); return; } ch341StatusFlashing(); uint32_t addrSrc = 0, addrDest = 0; uint32_t curBlock = 0; uint32_t k; ui->statusMessage->setText(tr("Writing data to ") + ui->comboBox_name->currentText()); //progerssbar settings int currentPercent = 0; int lastPercent = -1; ui->progressBar->setRange(0, 100); ui->progressBar->setValue(0); ui->checkBox_2->setStyleSheet("QCheckBox{font-weight:800;}"); chipData = hexEdit->data(); std::shared_ptr buf(new uint8_t[step]); for (k = 0; k < numBlocks; k++) { memcpy(buf.get() + addrDest - k * step, chipData.constData() + addrSrc, step); switch (currentChipType) { case 0: //SPI addrSrc = addrSrc + step; res = snor_write_param(buf.get(), addrDest, step, step, currentAddr4bit, current_programmer); break; case 1: //I2C addrSrc = addrSrc + step; res = ch34xi2cBlockWrite(buf.get(), curBlock * step, step, currentPageSize, currentAlgorithm, current_programmer); if (res==0) res = 1; break; case 2: //MicroWire addrSrc = addrSrc + step; res = Write_EEPROM_3wire_param(buf.get(), static_cast(curBlock * step), static_cast(step), static_cast(currentChipSize), currentAlgorithm); if (res==0) res = 1; break; case 3: //25xxx case 4: //M95xx addrSrc = addrSrc + step; res = s95_write_param(buf.get(), addrDest, step, step, currentAlgorithm, current_programmer); break; case 5: //AT45DBxx addrSrc = addrSrc + step; res = at45_write_param(buf.get(), addrDest, step, step, currentAlgorithm, current_programmer); break; case 6: //NAND if ((nandSettings & 0x0f) == 0x01) { //skip bad block enabled badResult = nand_checkBadBlock(k, currentPageSize, sectorsPerBlock, current_programmer); if(badResult != 1) addrSrc = addrSrc + step; } else addrSrc = addrSrc + step; if (nandRaw == true) nand_block_write(buf.get(), currentPageSize + currentECCsize, k, sectorsPerBlock, current_programmer); else res = nand_block_write(buf.get(), currentPageSize, k, sectorsPerBlock, current_programmer); if (res==0) res = 1; break; default: //Unsupport QMessageBox::about(this, tr("Error"), tr("Unsupported chip type!")); doNotDisturbCancel(); ProgDeviceClose(current_programmer); ui->checkBox_2->setStyleSheet(""); return; } // if res=-1 - error, stop if (statusCH341 != 0) { QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); doNotDisturbCancel(); ProgDeviceClose(current_programmer); break; } if (res <= 0) { QMessageBox::about(this, tr("Error"), tr("Error writing sector ") + QString::number(curBlock)); doNotDisturbCancel(); ProgDeviceClose(current_programmer); return; } addrDest = addrDest + step; curBlock++; qApp->processEvents(); if (isHalted) { isHalted = false; ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } currentPercent = static_cast((curBlock * 100.0) / numBlocks); if (currentPercent != lastPercent) { ui->progressBar->setValue(currentPercent); lastPercent = currentPercent; } } } else { //Not correct Number fnd size of blocks QMessageBox::about(this, tr("Error"), tr("Before reading from chip please press 'Detect' button.")); } doNotDisturbCancel(); ui->progressBar->setValue(0); ui->checkBox_2->setStyleSheet(""); ui->statusMessage->setText(""); } else { ch341StatusFlashing(); QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); } ProgDeviceClose(current_programmer); } void MainWindow::on_actionRead_triggered() { MainWindow::on_pushButton_clicked(); } void MainWindow::on_actionExit_triggered() { MainWindow::close(); } void MainWindow::on_comboBox_man_currentIndexChanged(int index) { int i, index2; QString txt=""; if (max_rec > 0) { txt = ui->comboBox_man->currentText().toUtf8(); ui->comboBox_name->clear(); ui->comboBox_name->addItem(""); for (i = 0; icomboBox_name->findText(chips[i].chipName); if ( index2 == -1 ) ui->comboBox_name->addItem(chips[i].chipName); } } ui->comboBox_name->setCurrentIndex(0); ui->comboBox_vcc->setCurrentIndex(0); ui->comboBox_page->setCurrentIndex(0); ui->comboBox_block->setCurrentIndex(0); ui->comboBox_size->setCurrentIndex(0); ui->comboBox_addr4bit->setCurrentIndex(0); ui->comboBox_ECC->setCurrentIndex(0); ui->statusMessage->setText(""); } index = index + 0; } void MainWindow::on_comboBox_name_currentTextChanged(const QString &arg1) { int i, index; oldFileName = fileName; QString manName = ui->comboBox_man->currentText(); if (arg1.compare("") !=0) { for (i = 0; i < max_rec; i++) { if ((manName.compare(chips[i].chipManuf)==0) && (arg1.compare(chips[i].chipName)==0)) { index = ui->comboBox_size->findData(chips[i].chipSize); if ( index != -1 ) { // -1 for not found ui->comboBox_size->setCurrentIndex(index); } index = ui->comboBox_page->findData(chips[i].sectorSize); if ( index != -1 ) { // -1 for not found ui->comboBox_page->setCurrentIndex(index); } index = ui->comboBox_block->findData(chips[i].blockSize); if ( index != -1 ) { // -1 for not found ui->comboBox_block->setCurrentIndex(index); } index = ui->comboBox_addr4bit->findData(chips[i].addr4bit); if ( index != -1 ) { // -1 for not found ui->comboBox_addr4bit->setCurrentIndex(index); } index = ui->comboBox_vcc->findText(chips[i].chipVCC); if ( index != -1 ) { // -1 for not found ui->comboBox_vcc->setCurrentIndex(index); } index = ui->comboBox_ECC->findData(chips[i].eepromPages); if ( index != -1 ) { // -1 for not found ui->comboBox_ECC->setCurrentIndex(index); } currentAlgorithm = chips[i].algorithmCode; } } currentChipSize = ui->comboBox_size->currentData().toUInt(); currentBlockSize = ui->comboBox_block->currentData().toUInt(); currentPageSize = ui->comboBox_page->currentData().toUInt(); currentAddr4bit = ui->comboBox_addr4bit->currentData().toUInt(); currentECCsize = (ui->comboBox_ECC->currentData().toUInt()) * 64; preparingToCompare(1); if ((currentChipSize !=0) && (currentBlockSize!=0) && (currentChipType == 0)) { currentNumBlocks = currentChipSize / currentBlockSize; chipData.resize(static_cast(currentChipSize)); chipData.fill(char(0xff)); filled = 1; hexEdit->setData(chipData); } if ((currentChipSize !=0) && (currentPageSize!=0) && (currentChipType > 0) &&(currentChipType != 6)) { currentNumBlocks = currentChipSize / currentPageSize; chipData.resize(static_cast(currentChipSize)); chipData.fill(char(0xff)); filled = 1; hexEdit->setData(chipData); } if ((currentChipSize !=0) && (currentPageSize!=0) && (currentChipType == 6)) { currentNumBlocks = currentChipSize / currentPageSize; if (nandRaw == true) chipData.resize(static_cast(currentChipSize + currentChipSize/currentPageSize * currentECCsize)); else chipData.resize(static_cast(currentChipSize)); chipData.fill(char(0xff)); filled = 1; hexEdit->setData(chipData); } } } void MainWindow::on_actionVerify_triggered() { //Reading and veryfying data from chip int res = 0; uint32_t step, numBlocks, sectorsPerBlock; statusCH341 = ProgDeviceInit(current_programmer, currentChipType, currentI2CBusSpeed);//ch341a_init(currentChipType, currentI2CBusSpeed); if (statusCH341 == 0) { if (((currentNumBlocks > 0) && (currentBlockSize >0) && (currentChipType == 0)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 1)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 2)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 3)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 4)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 5)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 6))) { ui->crcEdit->setText(""); doNotDisturb(); switch (currentChipType) { case 0: //SPI step = currentBlockSize; numBlocks = currentNumBlocks; break; case 1: //I2C //step = currentPageSize; step = 128; numBlocks = currentChipSize / step; break; case 2: //MicroWire case 3: //25xxx case 4: //95xxx case 5: //45xx step = currentPageSize; numBlocks = currentChipSize / step; break; case 6: //NAND 35xx, GD5xx, W25xx numBlocks = currentChipSize / currentBlockSize; sectorsPerBlock = currentBlockSize / currentPageSize; if (nandRaw == true) step = currentBlockSize + currentECCsize * sectorsPerBlock; else step = currentBlockSize; nand_ECCEnable(current_programmer); break; default: //Unsupport QMessageBox::about(this, tr("Error"), tr("Unsupported chip type!")); doNotDisturbCancel(); ProgDeviceClose(current_programmer); ui->checkBox_3->setStyleSheet(""); return; } ch341StatusFlashing(); uint32_t addr = 0; uint32_t curBlock = 0; uint32_t j, k; //progerssbar settings int currentPercent = 0; int lastPercent = -1; ui->progressBar->setRange(0, 100); ui->progressBar->setValue(0); std::shared_ptr buf(new uint8_t[step]); chipData = hexEdit->data(); ui->checkBox_3->setStyleSheet("QCheckBox{font-weight:800;}"); ui->statusMessage->setText(tr("Veryfing data from ") + ui->comboBox_name->currentText()); for (k = 0; k < numBlocks; k++) { switch (currentChipType) { case 0: //SPI res = snor_read_param(buf.get(),curBlock * step, step, step, currentAddr4bit, current_programmer); break; case 1: //I2C res = ch34xi2cBlockRead(buf.get(), curBlock * step, step, currentAlgorithm, current_programmer); if (res==0) res = 1; break; case 2: //MicroWire res = Read_EEPROM_3wire_param(buf.get(), static_cast(curBlock * step), static_cast(step), static_cast(currentChipSize), currentAlgorithm); if (res==0) res = 1; break; case 3: //25xxx case 4: //95xxx res = s95_read_param(buf.get(), curBlock * step, step, step, currentAlgorithm, current_programmer); break; case 5: res = at45_read_param(buf.get(), curBlock * step, step, step, currentAlgorithm, current_programmer); break; case 6: //NAND if (nandRaw == true) res = nand_block_read(buf.get(), currentPageSize + currentECCsize, k, sectorsPerBlock, current_programmer); else res = nand_block_read(buf.get(), currentPageSize, k, sectorsPerBlock, current_programmer); if (res==0) res = 1; break; default: //Unsupport QMessageBox::about(this, tr("Error"), tr("Unsupported chip type!")); doNotDisturbCancel(); ProgDeviceClose(current_programmer); ui->checkBox_3->setStyleSheet(""); return; } // if res=-1 - error, stop if (statusCH341 != 0) { QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); doNotDisturbCancel(); break; } if (res <= 0) { QMessageBox::about(this, tr("Error"), tr("Error reading block ") + QString::number(curBlock)); ProgDeviceClose(current_programmer); ui->pushButton->setStyleSheet(grnKeyStyle); doNotDisturbCancel(); return; } for (j = 0; j < step; j++) { if (chipData[addr + j] != char(buf[addr + j - k * step])) { //error compare QMessageBox::about(this, tr("Error"), tr("Error comparing data!\nAddress: ") + hexiAddr(addr + j) + tr("\nBuffer: ") + bytePrint( static_cast(chipData[addr + j])) + tr(" Chip: ") + bytePrint(buf[addr + j - k * step])); ui->statusMessage->setText(""); ui->checkBox_3->setStyleSheet(""); ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } } addr = addr + step; curBlock++; qApp->processEvents(); if (isHalted) { isHalted = false; ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } currentPercent = static_cast((curBlock * 100.0) / numBlocks); if (currentPercent != lastPercent) { ui->progressBar->setValue(currentPercent); lastPercent = currentPercent; } } } else { //Not correct Number fnd size of blocks if (currentChipType == 0) QMessageBox::about(this, tr("Error"), tr("Before reading from chip please press 'Detect' button.")); if (currentChipType == 1) QMessageBox::about(this, tr("Error"), tr("Please select the chip parameters - manufacture and chip name.")); } doNotDisturbCancel(); ui->statusMessage->setText(""); ui->progressBar->setValue(0); ui->checkBox_3->setStyleSheet(""); ui->crcEdit->setText(getCRC32(chipData)); ProgDeviceClose(current_programmer); QMessageBox::about(this, tr("Ok!"), tr("The operation was successful!")); } else { ch341StatusFlashing(); QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); } } void MainWindow::on_pushButton_3_clicked() { ui->pushButton_3->setStyleSheet(redKeyStyle); if (ui->checkBox->isChecked()) MainWindow::on_actionErase_triggered(); if (ui->checkBox_1->isChecked()) MainWindow::on_actionCheck_erase_triggered(); if (ui->checkBox_2->isChecked()) MainWindow::on_actionWrite_triggered(); if (ui->checkBox_3->isChecked()) MainWindow::on_actionVerify_triggered(); ui->pushButton_3->setStyleSheet(grnKeyStyle); } void MainWindow::receiveAddr(QString addressData) { uint32_t ee, blockEndAddr = 0; int e,t; QString endType; e = addressData.indexOf("-"); t = addressData.length(); blockStartAddr = 0; blockLen = 0; endType = addressData.mid(t - 1, 1); blockStartAddr = hexToInt(addressData.mid(0, e)); if (endType.compare("*")==0) { blockEndAddr = hexToInt(addressData.mid(e + 1, t - e - 2)); if (blockEndAddr < blockStartAddr) { QMessageBox::about(this, tr("Error"), tr("The end address must be greater than the starting address.")); return; } if (static_cast(blockEndAddr) > hexEdit->data().length()) { QMessageBox::about(this, tr("Error"), tr("The ending address must not exceed the buffer size.")); return; } blockLen = blockEndAddr - blockStartAddr + 1; } else blockLen = hexToInt(addressData.mid(e + 1, t - e - 2)); block.resize(static_cast(blockLen)); chipData = hexEdit->data(); for (ee = 0; ee < blockLen; ee++) { block[ee] = chipData[ee + blockStartAddr]; } ui->statusMessage->setText(tr("Saving block")); fileName = QFileDialog::getSaveFileName(this, QString(tr("Save block")), lastDirectory, "Data Images (*.bin *.BIN);;All files (*.*)"); QFileInfo info(fileName); lastDirectory = info.filePath(); if (QString::compare(info.suffix(), "bin", Qt::CaseInsensitive)) fileName = fileName + ".bin"; if (fileName.isEmpty()) return; QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) { QMessageBox::about(this, tr("Error"), tr("Error saving file!")); return; } file.write(block); file.close(); ui->statusMessage->setText(""); } void MainWindow::receiveAddr2(QString addressData) { uint32_t ee; QString endType; blockStartAddr = 0; blockLen = 0; blockStartAddr = hexToInt(addressData); ui->statusMessage->setText(tr("Opening block")); fileName = QFileDialog::getOpenFileName(this, QString(tr("Open block")), lastDirectory, "Data Images (*.bin *.BIN);;All files (*.*)"); ui->statusMessage->setText(tr("Current file: ") + fileName); QFileInfo info(fileName); lastDirectory = info.filePath(); QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { return; } block = file.readAll(); blockLen = static_cast(block.size()); chipData = hexEdit->data(); if (blockStartAddr + blockLen > static_cast(chipData.size())) { QMessageBox::about(this, tr("Error"), tr("The end address out of image size!")); return; } for (ee=0; ee < blockLen; ee++) { chipData[ee + blockStartAddr] = block[ee]; } hexEdit->setData(chipData); file.close(); ui->statusMessage->setText(""); } void MainWindow::on_actionSave_Part_triggered() { DialogSP* savePartDialog = new DialogSP(this); savePartDialog->show(); connect(savePartDialog, SIGNAL(sendAddr(QString)), this, SLOT(receiveAddr(QString))); } void MainWindow::on_actionLoad_Part_triggered() { DialogRP* loadPartDialog = new DialogRP(this); loadPartDialog->show(); connect(loadPartDialog, SIGNAL(sendAddr2(QString)), this, SLOT(receiveAddr2(QString))); } void MainWindow::on_actionFind_Replace_triggered() { SearchDialog* searchDialog = new SearchDialog(hexEdit); searchDialog->show(); } void MainWindow::ch341StatusFlashing() { if (statusCH341 == 0) { ui->eStatus->setText(tr("Connected")); ui->eStatus -> setStyleSheet("QLineEdit {border: 2px solid gray;border-radius: 5px;color:#000;background:#9f0;font-weight:600;border-style:inset;}"); } else { ui->eStatus->setText(tr("Not connected")); ui->eStatus -> setStyleSheet("QLineEdit {border: 2px solid gray;border-radius: 5px;color:#fff;background:#f00;font-weight:600;border-style:inset;}"); } } void MainWindow::on_comboBox_type_currentIndexChanged(int index) { int i, index2; ui->comboBox_man->clear(); ui->comboBox_name->clear(); ui->comboBox_man->addItem(""); ui->comboBox_name->addItem(""); ui->jedecEdit->setText(""); currentChipType = static_cast(ui->comboBox_type->itemData(index).toInt()); ui->comboBox_size->clear(); ui->comboBox_page->clear(); ui->comboBox_size->addItem(" ", 0); ui->comboBox_page->addItem(" ", 0); switch (currentChipType) { case 0: //SPI ui->comboBox_size->addItem("64 K", 64 * 1024); ui->comboBox_size->addItem("128 K", 128 * 1024); ui->comboBox_size->addItem("256 K", 256 * 1024); ui->comboBox_size->addItem("512 K", 512 * 1024); ui->comboBox_size->addItem("1 M", 1024 * 1024); ui->comboBox_size->addItem("2 M", 2048 * 1024); ui->comboBox_size->addItem("4 M", 4096 * 1024); ui->comboBox_size->addItem("8 M", 8192 * 1024); ui->comboBox_size->addItem("16 M", 16384 * 1024); ui->comboBox_size->addItem("32 M", 32768 * 1024); ui->comboBox_size->addItem("64 M", 65536 * 1024); ui->comboBox_size->addItem("128 M", 65536 * 2048); ui->comboBox_size->addItem("256 M", 65536 * 4096); ui->comboBox_page->addItem("256", 256); break; case 1: //I2C ui->comboBox_size->addItem("128 B", 128); ui->comboBox_size->addItem("256 B", 256); ui->comboBox_size->addItem("512 B", 512); ui->comboBox_size->addItem("1 K", 1 * 1024); ui->comboBox_size->addItem("2 K", 2 * 1024); ui->comboBox_size->addItem("4 K", 4 * 1024); ui->comboBox_size->addItem("8 K", 8 * 1024); ui->comboBox_size->addItem("16 K", 16 * 1024); ui->comboBox_size->addItem("32 K", 32 * 1024); ui->comboBox_size->addItem("64 K", 64 * 1024); ui->comboBox_size->addItem("128 K", 128 * 1024); ui->comboBox_size->addItem("256 K", 256 * 1024); ui->comboBox_page->addItem("8", 8); ui->comboBox_page->addItem("16", 16); ui->comboBox_page->addItem("32", 32); break; case 2: //MicroWire ui->comboBox_size->addItem("128 B", 128); ui->comboBox_size->addItem("256 B", 256); ui->comboBox_size->addItem("512 B", 512); ui->comboBox_size->addItem("1 K", 1 * 1024); ui->comboBox_size->addItem("2 K", 2 * 1024); ui->comboBox_page->addItem("16", 16); break; case 3: //25xxx case 4: //95xxx ui->comboBox_size->addItem("128 B", 128); ui->comboBox_size->addItem("256 B", 256); ui->comboBox_size->addItem("512 B", 512); ui->comboBox_size->addItem("1 K", 1 * 1024); ui->comboBox_size->addItem("2 K", 2 * 1024); ui->comboBox_size->addItem("4 K", 4 * 1024); ui->comboBox_size->addItem("8 K", 8 * 1024); ui->comboBox_size->addItem("16 K", 16 * 1024); ui->comboBox_size->addItem("32 K", 32 * 1024); ui->comboBox_size->addItem("64 K", 64 * 1024); ui->comboBox_size->addItem("128 K", 128 * 1024); ui->comboBox_size->addItem("256 K", 256 * 1024); ui->comboBox_size->addItem("512 K", 512 * 1024); ui->comboBox_page->addItem("16", 16); ui->comboBox_page->addItem("32", 32); ui->comboBox_page->addItem("64", 64); ui->comboBox_page->addItem("128", 128); ui->comboBox_page->addItem("256", 256); break; case 5: //45xxx ui->comboBox_size->addItem("132 K", 132 * 1024); ui->comboBox_size->addItem("264 K", 264 * 1024); ui->comboBox_size->addItem("528 K", 528 * 1024); ui->comboBox_size->addItem("1056 K", 1056 * 1024); ui->comboBox_size->addItem("2112 K", 2112 * 1024); ui->comboBox_size->addItem("4224 K", 4224 * 1024); ui->comboBox_size->addItem("8448 K", 8448 * 1024); ui->comboBox_page->addItem("256", 256); ui->comboBox_page->addItem("264", 264); ui->comboBox_page->addItem("512", 512); ui->comboBox_page->addItem("528", 528); break; case 6: // SPI NAND FLASH ui->comboBox_size->addItem("64 M", 65536 * 1024); ui->comboBox_size->addItem("128 M", 65536 * 2048); ui->comboBox_size->addItem("256 M", 65536 * 4096); ui->comboBox_size->addItem("512 M", 65536 * 8192); ui->comboBox_page->addItem("1024", 1024); ui->comboBox_page->addItem("2048", 2048); ui->comboBox_page->addItem("4096", 4096); break; default: //Unsupport return; } for (i = 0; i < max_rec; i++) { //replacing items to combobox Manufacture index2 = ui->comboBox_man->findText(chips[i].chipManuf); if (( index2 == -1 ) && (chips[i].chipTypeHex == currentChipType)) ui->comboBox_man->addItem(chips[i].chipManuf); } ui->comboBox_man->setCurrentIndex(0); ui->statusMessage->setText(""); ui->comboBox_man->setCurrentIndex(0); ui->comboBox_vcc->setCurrentIndex(0); ui->comboBox_name->setCurrentIndex(0); ui->comboBox_page->setCurrentIndex(0); ui->comboBox_block->setCurrentIndex(0); ui->comboBox_size->setCurrentIndex(0); ui->comboBox_addr4bit->setCurrentIndex(0); ui->comboBox_ECC->setCurrentIndex(0); if ((index > 0) && (index < 3)) { ui->pushButton_2->hide(); ui->comboBox_block->hide(); ui->comboBox_addr4bit->hide(); ui->label_8->hide(); ui->label_9->hide(); ui->actionDetect->setDisabled(true); ui->actionChip_info->setDisabled(true); } if (index !=0) ui->actionSecurity_registers->setEnabled(false); if (index == 0) { ui->pushButton_2->show(); ui->comboBox_addr4bit->show(); ui->label_8->show(); ui->label_9->show(); ui->comboBox_block->show(); ui->actionDetect->setEnabled(true); ui->actionChip_info->setEnabled(true); ui->actionSecurity_registers->setEnabled(true); } if (index != 1) { ui->comboBox_i2cSpeed->hide(); ui->label_10->hide(); } else { ui->comboBox_i2cSpeed->show(); ui->label_10->show(); } if (index > 2) { ui->pushButton_2->hide(); ui->comboBox_block->hide(); ui->comboBox_addr4bit->hide(); ui->label_8->hide(); ui->label_9->hide(); ui->actionDetect->setDisabled(true); ui->actionChip_info->setEnabled(true); } if (index == 5) { ui->pushButton_2->show(); ui->actionDetect->setEnabled(true); } if (index == 6) { ui->pushButton_2->show(); ui->label_8->hide(); ui->label_9->show(); ui->label_11->show(); ui->label_12->show(); ui->comboBox_block->show(); ui->comboBox_ECC->show(); ui->comboBox_raw->show(); ui->actionDetect->setEnabled(true); ui->actionChip_info->setEnabled(true); ui->actionSecurity_registers->setEnabled(true); ui->actionBad_block_management->setEnabled(true); } if (index != 6) { ui->label_11->hide(); ui->comboBox_ECC->hide(); ui->comboBox_raw->hide(); ui->label_12->hide(); ui->actionBad_block_management->setEnabled(false); ui->comboBox_raw->setCurrentIndex(0); } } void MainWindow::on_comboBox_addr4bit_currentIndexChanged(int index) { currentAddr4bit = ui->comboBox_addr4bit->currentData().toUInt(); index++; } void MainWindow::on_comboBox_i2cSpeed_currentIndexChanged(int index) { currentI2CBusSpeed = static_cast(ui->comboBox_i2cSpeed->currentData().toUInt()); index++; } void MainWindow::on_comboBox_ECC_currentIndexChanged(int index) { currentECCsize = (ui->comboBox_ECC->currentData().toUInt()) * 64; index++; } void MainWindow::on_actionAbout_triggered() { DialogAbout* aboutDialog = new DialogAbout(this); aboutDialog->show(); } void MainWindow::on_actionChecksum_calculate_triggered() { //Refreshing CRC32 ui->crcEdit->setText(getCRC32(chipData)); } void MainWindow::on_actionEdit_chips_Database_triggered() { #ifdef _WIN32 QString programPath = "./IMSProg_editor.exe"; #else QString programPath = "./IMSProg_editor"; #endif bool programExists = QFileInfo::exists(programPath) && !QDir(programPath).exists(); if (!programExists) { // if does not exists on realive path check another QString systemProgramPath = QStandardPaths::findExecutable(programPath); if (!systemProgramPath.isEmpty()) { // exists on system path programPath = systemProgramPath; programExists = true; } } if (programExists) { QProcess::execute(programPath, QStringList()); progInit(); } else { QMessageBox::about(this, tr("Error"), tr("File 'IMSProg_editor' not found!")); } } void MainWindow::doNotDisturb() { ui->actionDetect->setDisabled(true); ui->actionOpen->setDisabled(true); ui->actionSave->setDisabled(true); ui->actionLoad_Part->setDisabled(true); ui->actionSave_Part->setDisabled(true); ui->actionExport_to_Intel_HEX->setDisabled(true); ui->actionImport_from_Intel_HEX->setDisabled(true); ui->actionExtract_from_ASUS_CAP->setDisabled(true); ui->actionEdit_chips_Database->setDisabled(true); ui->actionExit->setDisabled(true); ui->actionRead->setDisabled(true); ui->actionWrite->setDisabled(true); ui->actionErase->setDisabled(true); ui->actionCheck_erase->setDisabled(true); ui->actionVerify->setDisabled(true); ui->actionFind_Replace->setDisabled(true); ui->actionUndo->setDisabled(true); ui->actionRedo->setDisabled(true); ui->actionCopy->setDisabled(true); ui->actionPaste->setDisabled(true); ui->actionChecksum_calculate->setDisabled(true); ui->actionGoto_address->setDisabled(true); ui->actionCompare_files->setDisabled(true); ui->actionFill_with_code->setDisabled(true); ui->actionFill_test_image->setDisabled(true); ui->actionChip_info->setDisabled(true); ui->actionSecurity_registers->setDisabled(true); ui->actionBad_block_management->setDisabled(true); ui->actionStop->setDisabled(false); ui->actionCH341A_B_v1_2->setDisabled(true); ui->actionCH341A_v1_7->setDisabled(true); ui->actionCH347T->setDisabled(true); ui->actionCH347T_v1_1->setDisabled(true); ui->actionShow_programmer_version->setDisabled(true); ui->pushButton->blockSignals(true); ui->pushButton_2->blockSignals(true); ui->pushButton_3->blockSignals(true); ui->comboBox_type->setDisabled(true); ui->comboBox_man->setDisabled(true); ui->comboBox_name->setDisabled(true); ui->comboBox_size->setDisabled(true); ui->comboBox_page->setDisabled(true); ui->comboBox_block->setDisabled(true); ui->comboBox_vcc->setDisabled(true); ui->comboBox_addr4bit->setDisabled(true); ui->comboBox_i2cSpeed->setDisabled(true); ui->comboBox_ECC->setDisabled(true); ui->comboBox_raw->setDisabled(true); hexEdit->blockSignals(true); timer->stop(); } void MainWindow::doNotDisturbCancel() { if ((currentChipType == 0) || (currentChipType == 5) || (currentChipType == 6)) ui->actionDetect->setDisabled(false); ui->actionOpen->setDisabled(false); ui->actionSave->setDisabled(false); ui->actionLoad_Part->setDisabled(false); ui->actionSave_Part->setDisabled(false); ui->actionExport_to_Intel_HEX->setDisabled(false); ui->actionImport_from_Intel_HEX->setDisabled(false); ui->actionExtract_from_ASUS_CAP->setDisabled(false); ui->actionEdit_chips_Database->setDisabled(false); ui->actionExit->setDisabled(false); ui->actionRead->setDisabled(false); ui->actionWrite->setDisabled(false); ui->actionErase->setDisabled(false); ui->actionCheck_erase->setDisabled(false); ui->actionVerify->setDisabled(false); ui->actionFind_Replace->setDisabled(false); ui->actionUndo->setDisabled(false); ui->actionRedo->setDisabled(false); ui->actionCopy->setDisabled(false); ui->actionPaste->setDisabled(false); ui->actionChecksum_calculate->setDisabled(false); ui->actionGoto_address->setDisabled(false); ui->actionCompare_files->setDisabled(false); ui->actionFill_with_code->setDisabled(false); ui->actionFill_test_image->setDisabled(false); ui->actionCH341A_B_v1_2->setDisabled(false); ui->actionCH341A_v1_7->setDisabled(false); ui->actionCH347T->setDisabled(false); ui->actionCH347T_v1_1->setDisabled(false); ui->actionShow_programmer_version->setDisabled(true); if ((currentChipType == 0) || (currentChipType == 6) || (currentChipType > 2)) ui->actionChip_info->setDisabled(false); if ((currentChipType == 0) || (currentChipType == 6)) ui->actionSecurity_registers->setDisabled(false); if (currentChipType == 6) ui->actionBad_block_management->setDisabled(false); ui->actionStop->setDisabled(true); ui->pushButton->blockSignals(false); ui->pushButton_2->blockSignals(false); ui->pushButton_3->blockSignals(false); ui->comboBox_type->setDisabled(false); ui->comboBox_man->setDisabled(false); ui->comboBox_name->setDisabled(false); ui->comboBox_size->setDisabled(false); ui->comboBox_page->setDisabled(false); ui->comboBox_block->setDisabled(false); ui->comboBox_vcc->setDisabled(false); ui->comboBox_addr4bit->setDisabled(false); ui->comboBox_i2cSpeed->setDisabled(false); ui->comboBox_ECC->setDisabled(false); ui->comboBox_raw->setDisabled(false); hexEdit->blockSignals(false); timer->start(); } void MainWindow::on_actionStop_triggered() { hexEdit->setData(chipData); ui->crcEdit->setText(getCRC32(chipData)); isHalted = true; QMessageBox::about(this, tr("Stop"), tr("Operation aborted!")); ui->pushButton->setStyleSheet(grnKeyStyle); ui->checkBox->setStyleSheet(""); ui->checkBox_1->setStyleSheet(""); ui->checkBox_2->setStyleSheet(""); ui->checkBox_3->setStyleSheet(""); ui->checkBox->setChecked(false); ui->checkBox_1->setChecked(false); ui->checkBox_2->setChecked(false); ui->checkBox_3->setChecked(false); ui->pushButton_3->setStyleSheet(grnKeyStyle); ui->statusMessage->setText(""); return; } void MainWindow::on_pushButton_4_clicked() { //info form showing DialogInfo* infoDialog = new DialogInfo(this); infoDialog->show(); infoDialog->setProgrammer(current_programmer); if ((currentChipType == 0) && (ui->comboBox_vcc->currentIndex() == 1)) infoDialog->setChip(2); //NOR_FLASH 3.3 if ((currentChipType == 0) && (ui->comboBox_vcc->currentIndex() == 2)) infoDialog->setChip(3); //NOR FLASH 1.8 if ((currentChipType == 0) && (ui->comboBox_vcc->currentIndex() == 3)) infoDialog->setChip(8); //NOR FLASH 2.5 if ((currentChipType == 1) && (ui->comboBox_vcc->currentIndex() == 1)) infoDialog->setChip(1); //24xxx 3.3 if ((currentChipType == 1) && (ui->comboBox_vcc->currentIndex() == 4)) infoDialog->setChip(9); //24xxx 5.0 if ((currentChipType == 2) && (ui->comboBox_vcc->currentIndex() == 1)) infoDialog->setChip(4); //93xxx 3.3 if ((currentChipType == 3) && (ui->comboBox_vcc->currentIndex() == 1)) infoDialog->setChip(2); //25xxx 3.3 if ((currentChipType == 3) && (ui->comboBox_vcc->currentIndex() == 2)) infoDialog->setChip(3); //25xxx 1.8 if ((currentChipType == 4) && (ui->comboBox_vcc->currentIndex() == 1)) infoDialog->setChip(2); //95xxx 3.3 if ((currentChipType == 5) && (ui->comboBox_vcc->currentIndex() == 1)) infoDialog->setChip(5); //45xxx 3.3 if ((currentChipType == 6) && (ui->comboBox_vcc->currentIndex() == 1)) infoDialog->setChip(6); //NAND_FLASH 3.3 if ((currentChipType == 6) && (ui->comboBox_vcc->currentIndex() == 2)) infoDialog->setChip(7); //NAND_FLASH 1.8 } void MainWindow::on_actionChip_info_triggered() { timer->stop(); if (currentChipType == 0) { DialogSFDP* sfdpDialog = new DialogSFDP(this); connect(sfdpDialog, SIGNAL(closeRequestHasArrived()), this, SLOT(closeSFDP())); sfdpDialog->show(); sfdpDialog->setDeviceType(current_programmer); } if (currentChipType == 6) { DialogNANDSr* nandSRDialog = new DialogNANDSr(this); connect(nandSRDialog, SIGNAL(closeRequestHasArrived()), this, SLOT(closeSR())); nandSRDialog->show(); nandSRDialog->setPattern(currentAlgorithm); nandSRDialog->setDeviceType(current_programmer); } if ((currentChipType > 2) && (currentChipType != 6)) { DialogSR* srDialog = new DialogSR(this); connect(srDialog, SIGNAL(closeRequestHasArrived()), this, SLOT(closeSR())); srDialog->show(); srDialog->setChipType(currentChipType); srDialog->setDeviceType(current_programmer); } } void MainWindow::progInit() { int index2; ui->statusMessage->setText(tr("Opening DAT file")); QFile datfile(qApp->property("app/userChipDatabaseFile").toString()); if (!datfile.exists()) { datfile.setFileName(qApp->property("app/systemChipDatabaseFile").toString()); } if (!datfile.exists()) { QString msg = tr("Cannot find a chip database file.\nYou may want to run IMSProg_database_update"); QMessageBox::about(this, tr("Error"), msg); return; } qDebug() << "Using chip database file " << datfile.fileName(); QByteArray dataChips; if (!datfile.open(QIODevice::ReadOnly)) { QString msg = tr("Error loading chip database file!\nFile: %1\nError Code: %2\nReason: %3") .arg(datfile.fileName()) .arg(static_cast(datfile.error())) .arg(datfile.errorString()); QMessageBox::about(this, tr("Error"), msg); return; } dataChips = datfile.readAll(); datfile.close(); //parsing dat file ui->statusMessage->setText(tr("Parsing DAT file")); //parsing qbytearray char txtBuf[0x30]; int i, j, recNo, dataPoz, dataSize, delay; uint32_t chipSize; uint16_t blockSize; unsigned char tmpBuf; dataPoz = 0; recNo = 0; QStringList verticalHeader; dataSize = dataChips.length(); while (dataPoz < dataSize) { for (j=0; j<0x30; j++) { txtBuf[j] = 0; } j = 0; while ((j < 0x10) && (dataChips[recNo * 0x44 + j] != ',')) // ASCII data reading { txtBuf[j] = dataChips[recNo * 0x44 + j]; j++; } if (txtBuf[1] == 0x00) break; chips[recNo].chipTypeTxt = QByteArray::fromRawData(txtBuf, j); for (i=0; i<0x30; i++) { txtBuf[i] = 0; } j++; i = 0; while ((i < 0x20) && (dataChips[recNo * 0x44 + j] != ',')) // ASCII data reading { txtBuf[i] = dataChips[recNo * 0x44 + j]; j++; i++; } chips[recNo].chipManuf = QByteArray::fromRawData(txtBuf, i); for (i=0; i<0x30; i++) { txtBuf[i] = 0; } j++; i = 0; while ((i < 0x30) && (dataChips[recNo * 0x44 + j] != '\0')) // ASCII data reading { txtBuf[i] = dataChips[recNo * 0x44 + j]; j++; i++; } chips[recNo].chipName = QByteArray::fromRawData(txtBuf, i); chips[recNo].chipJedecIDMan = static_cast(dataChips[recNo * 0x44 + 0x32]); chips[recNo].chipJedecIDDev = static_cast(dataChips[recNo * 0x44 + 0x31]); chips[recNo].chipJedecIDCap = static_cast(dataChips[recNo * 0x44 + 0x30]); tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x34]); chipSize = tmpBuf; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x35]); chipSize = chipSize + tmpBuf * 256; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x36]); chipSize = chipSize + tmpBuf * 256 * 256; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x37]); chipSize = chipSize + tmpBuf * 256 * 256 * 256; chips[recNo].chipSize = chipSize; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x38]); blockSize = tmpBuf; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x39]); blockSize = blockSize + tmpBuf * 256; chips[recNo].sectorSize = blockSize; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x3a]); chips[recNo].chipTypeHex = tmpBuf; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x3b]); chips[recNo].algorithmCode = tmpBuf; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x3c]); delay = tmpBuf; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x3d]); delay = delay + tmpBuf * 256; chips[recNo].delay = delay; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x3e]); chips[recNo].addr4bit = tmpBuf; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x3f]); chips[recNo].blockSize = tmpBuf * 256 * 1024; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x40]); chips[recNo].blockSize = chips[recNo].blockSize + tmpBuf * 1024; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x42]); chips[recNo].eepromPages = tmpBuf; tmpBuf = static_cast(dataChips[recNo * 0x44 + 0x43]); if (tmpBuf == 0x00) chips[recNo].chipVCC = "3.3 V"; if (tmpBuf == 0x01) chips[recNo].chipVCC = "1.8 V"; if (tmpBuf == 0x02) chips[recNo].chipVCC = "5.0 V"; if (tmpBuf == 0x03) chips[recNo].chipVCC = "2.5 V"; dataPoz = dataPoz + 0x44; //next record verticalHeader.append(QString::number(recNo)); recNo++; } max_rec = recNo; for (i = 0; icomboBox_man->findText(chips[i].chipManuf); if ((index2 == -1) && (chips[i].chipTypeHex == 0)) ui->comboBox_man->addItem(chips[i].chipManuf); } ui->comboBox_man->setCurrentIndex(0); ui->statusMessage->setText(""); currentChipType = 0; ui->comboBox_type->setCurrentIndex(0); } void MainWindow::slotTimerAlarm() { statusCH341 = ProgDeviceInit(current_programmer, 0, 1); ch341StatusFlashing(); ProgDeviceClose(current_programmer); } void MainWindow::resizeEvent(QResizeEvent* event) { QMainWindow::resizeEvent(event); hexEdit->setGeometry(0,0,ui->frame->width(),ui->frame->height()); } void MainWindow::closeSFDP() { timer->start(); } void MainWindow::closeSR() { timer->start(); } void MainWindow::closeNandSR() { timer->start(); } void MainWindow::on_actionGoto_address_triggered() { //HExEditor --> goto address DialogSetAddr* gotoAddrDialog = new DialogSetAddr(this); gotoAddrDialog->show(); connect(gotoAddrDialog, SIGNAL(sendAddr3(qint64)), this, SLOT(receiveAddr3(qint64))); } void MainWindow::receiveAddr3(qint64 gotoAddr) { hexEdit->setCursorPosition(gotoAddr * 2); hexEdit->ensureVisible(); } void MainWindow::on_actionSecurity_registers_triggered() { if (currentChipSize == 0) { QMessageBox::about(this, tr("Error"), tr("Before working with the security registers, click the 'Detect' button")); return; } if (currentChipType == 0) { if (currentAlgorithm > 0) { timer->stop(); DialogSecurity* securityDialog = new DialogSecurity(this); connect(securityDialog, SIGNAL(closeRequestHasArrived()), this, SLOT(closeSR())); securityDialog->setAlgorithm(currentAlgorithm); securityDialog->setPath(lastDirectory); securityDialog->show(); securityDialog->setDeviceType(current_programmer); } else QMessageBox::about(this, tr("Error"), tr("There are no security registers in this chip or the current version of IMSProg does not support this algorithm.")); } if (currentChipType == 6) { DialogNandSecurity* securityNandDialog = new DialogNandSecurity(this); connect(securityNandDialog, SIGNAL(closeRequestHasArrived()), this, SLOT(closeNandSR())); securityNandDialog->setAlgorithm(currentAlgorithm); securityNandDialog->setSectorSize(currentPageSize); securityNandDialog->setPath(lastDirectory); securityNandDialog->setDeviceType(current_programmer); securityNandDialog->show(); } } void MainWindow::on_actionExport_to_Intel_HEX_triggered() { int addr = 0, hi_addr =0; QString result = ""; chipData = hexEdit->data(); int currSize = chipData.size(); uint8_t i, counter = 0; int ostatok = 0; ui->progressBar->setRange(0,chipData.size()); lastDirectory.replace(".bin", ".hex"); ui->statusMessage->setText(tr("Saving file")); fileName = QFileDialog::getSaveFileName(this, QString(tr("Save file")), lastDirectory, tr("Intel HEX Images") + " (*.hex *.HEX);;" + tr("All files") + " (*.*)"); QFileInfo info(fileName); ui->statusMessage->setText(""); lastDirectory = info.filePath(); if (QString::compare(info.suffix(), "hex", Qt::CaseInsensitive)) fileName = fileName + ".hex"; ui->statusMessage->setText(tr("Current file: ") + info.fileName()); QFile file(fileName); QTextStream stream(&file); if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text)) { return; } stream.seek(file.size()); while ((addr + hi_addr * 0x10000) < (chipData.size())) { if (addr < currSize - 0x20) ostatok = 0x20; else ostatok =currSize - addr; result.append(":"); result.append(bytePrint(static_cast(ostatok))); //number of bytes per string result.append(bytePrint(static_cast((addr & 0xff00) >> 8))); //one address byte result.append(bytePrint(static_cast(addr & 0xff))); //zero address byte result.append("00"); //type 00 counter = counter + static_cast(ostatok) + uint8_t((addr & 0xff00) >> 8) + uint8_t(addr & 0xff) ; for (i = 0; i < ostatok; i++) { result.append(bytePrint(static_cast((chipData[hi_addr * 256 * 256 + addr + i])))); counter = counter + static_cast((chipData[hi_addr * 256 * 256 + addr + i])); } result.append(bytePrint(0xff - counter + 1)); counter = 0; stream << result << "\n"; result.clear(); addr = addr + 0x20; if (addr >= 0x10000) //command 04 - setting the high address { hi_addr ++; addr = addr - 0x10000; result.append(":02000004"); result.append(bytePrint(uint8_t((hi_addr & 0xff00) >> 8))); result.append(bytePrint(uint8_t(hi_addr & 0xff))); counter = 0x06 + uint8_t((hi_addr & 0xff00) >> 8) + uint8_t(hi_addr & 0xff); result.append(bytePrint(0xff - counter + 1)); counter = 0; stream << result << "\n"; result.clear(); ui->progressBar->setValue(hi_addr * 256 * 256); } } result = ":00000001FF\n"; //end string stream << result; file.close(); fileName.clear(); ui->progressBar->setValue(0); } void MainWindow::on_actionImport_from_Intel_HEX_triggered() { chipData = hexEdit->data(); int chipSize = int(currentChipSize); uint_fast32_t lineLen, lo_addr, hi_addr, command, i; unsigned char currByte; uint8_t counter, checkSUM; QString currStr ="", strVal = ""; ui->statusMessage->setText(tr("Opening file")); if (numberOfReads == 0) oldFileName = fileName; else oldFileName = ui->comboBox_name->currentText(); fileName = QFileDialog::getOpenFileName(this, QString(tr("Open file")), lastDirectory, tr("Intel HEX Images") + " (*.hex *.HEX);;" + tr("All files") + " (*.*)"); QFileInfo info(fileName); QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { return; } ui->statusMessage->setText(tr("Current file: ") + info.fileName()); lastDirectory = info.filePath(); preparingToCompare(0); filled = 0; hi_addr = 0; lo_addr = 0; ui->progressBar->setRange(0, chipSize); while (!file.atEnd()) { currStr = file.readLine(); counter = 0; //parsing string if (currStr[0] != ':') { QMessageBox::about(this, tr("Error"), tr("Not valid HEX format!")); file.close(); fileName.clear(); hexEdit->setData(chipData); ui->progressBar->setValue(0); ui->crcEdit->setText(getCRC32(chipData)); return; } strVal = currStr.mid(1,2); //Length of data in current string lineLen = hexToInt(strVal); counter = counter + static_cast(lineLen); strVal.clear(); //low address strVal = currStr.mid(3,4); lo_addr = hexToInt(strVal); counter = counter + static_cast((lo_addr) >> 8) + static_cast(lo_addr & 0x00ff); strVal.clear(); //command strVal = currStr.mid(7,2); command = hexToInt(strVal); counter = counter + static_cast(command); if (command == 0) //reading bytes from current string { for (i = 0; i < lineLen; i++) { strVal.clear(); //get current byte of string strVal = currStr.mid(int(i) * 2 + 9, 2); currByte = static_cast(hexToInt(strVal)); // Checking valid address if (hi_addr * 256 * 256 + lo_addr + i > static_cast(chipSize)) { QMessageBox::about(this, tr("Error"), tr("The address is larger than the size of the chip!")); file.close(); fileName.clear(); hexEdit->setData(chipData); ui->progressBar->setValue(0); ui->crcEdit->setText(getCRC32(chipData)); return; } chipData.data()[hi_addr * 256 * 256 + lo_addr + i] = char(currByte); counter = counter + static_cast(hexToInt(strVal)); } counter = 255 - counter + 1; checkSUM = static_cast(hexToInt( currStr.mid(int(i) * 2 + 9, 2))); if (counter != checkSUM) { QMessageBox::about(this, tr("Error"), tr("Checksum error!")); file.close(); fileName.clear(); hexEdit->setData(chipData); ui->progressBar->setValue(0); ui->crcEdit->setText(getCRC32(chipData)); return; } } if (command == 4) //Changing the high address { strVal.clear(); //low address strVal = currStr.mid(9,4); hi_addr = hexToInt(strVal); counter = counter + static_cast((hi_addr) >> 8) + static_cast(hi_addr & 0x00ff); counter = 255 - counter + 1; checkSUM = static_cast(hexToInt( currStr.mid(13, 2))); ui->progressBar->setValue(int(hi_addr * 256 * 256)); if (counter != checkSUM) { QMessageBox::about(this, tr("Error"), tr("Checksum error!")); return; } } } file.close(); fileName.clear(); hexEdit->setData(chipData); ui->progressBar->setValue(0); ui->crcEdit->setText(getCRC32(chipData)); } void MainWindow::on_actionFill_test_image_triggered() { int addrSize, txtSize, i, j, divider; uint64_t curPos, fileSize, jj, hiDigit; char k; fileSize = static_cast(chipData.size()); if (fileSize > 512) divider = 9; else divider = 0; ui->progressBar->setValue(0); ui->progressBar->setRange(0, (static_cast(fileSize >> divider))); addrSize = 0; jj = fileSize; hiDigit = 1; while (jj > 1) { jj = jj >> 4; addrSize ++; hiDigit = hiDigit << 4; } char digits[16]; txtSize = 16 - addrSize - 4; curPos = 0; chipData.resize(0); k = 0x40; while (curPos < fileSize) { //String chipData.append('<'); chipData.append('0'); chipData.append('x'); //calculate digits i = static_cast(hiDigit >> 4); for (j=addrSize - 1; j >= 0; j--) { digits[j] = (curPos / static_cast(i)) % 16; i = i >> 4; } for (j = addrSize -1; j >=0; j--) { if (digits[j] < 10) digits[j] = digits[j] + 0x30; else digits[j] = digits[j] + 0x37; chipData.append(digits[j]); } chipData.append('>'); for (i = 0; i < txtSize; i++) { chipData.append(k); k ++; if (k > 0x7e) k = 0x40; } curPos = curPos + 16; if (curPos % 512 == 0) ui->progressBar->setValue(static_cast(curPos >> divider)); } hexEdit->setData(chipData); ui->crcEdit->setText(getCRC32(chipData)); ui->progressBar->setValue(0); } void MainWindow::on_actionCompare_files_triggered() { DialogCompare* compDialog = new DialogCompare(this); compDialog->showArrays(&chipData, &oldChipData, &newFileName, &oldFileName); compDialog->show(); } void MainWindow::preparingToCompare(bool type) { // For comparing function // type = 0 - file reading // type = 1 - chip reading if (filled == 0) oldChipData = hexEdit->data(); if (type == 0) { if (numberOfReads > 0) { numberOfReads = 0; } newFileName = fileName; } else { newFileName = ui->comboBox_name->currentText(); } } void MainWindow::on_actionCopy_triggered() { QKeyEvent* keyPress = new QKeyEvent(QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier, "C"); QKeyEvent* keyRelease = new QKeyEvent(QEvent::KeyRelease, Qt::Key_C, Qt::ControlModifier, "C"); QCoreApplication::postEvent(hexEdit, keyPress); QCoreApplication::postEvent(hexEdit, keyRelease); } void MainWindow::on_actionPaste_triggered() { QKeyEvent* keyPress = new QKeyEvent(QEvent::KeyPress, Qt::Key_V, Qt::ControlModifier, "V"); QKeyEvent* keyRelease = new QKeyEvent(QEvent::KeyRelease, Qt::Key_V, Qt::ControlModifier, "V"); QCoreApplication::postEvent(hexEdit, keyPress); QCoreApplication::postEvent(hexEdit, keyRelease); } void MainWindow::on_actionBad_block_management_triggered() { if ((currentChipSize != 0) && (currentPageSize != 0) && (currentBlockSize !=0)) { DialogBBM* bbmDialog = new DialogBBM(this); bbmDialog->show(); bbmDialog->getSectorSize(currentPageSize); bbmDialog->getBlockSize(currentBlockSize); bbmDialog->getTotalBlocks(currentChipSize / currentBlockSize); bbmDialog->getSettings(nandSettings); bbmDialog->setDeviceType(current_programmer); connect(bbmDialog, SIGNAL(sendNandParam(uint8_t)), this, SLOT(receiveNandStatus(uint8_t))); } else QMessageBox::about(this, tr("Error"), tr("Please select the chip parameters - manufacture and chip name.")); } void MainWindow::receiveNandStatus(uint8_t setParam) { nandSettings = setParam; } void MainWindow::on_actionCH341A_B_v1_2_triggered() { current_programmer = 0; ui->lStatus->setText("CH341A"); SetItemStatus("comboBox_type", 2, false); SetItemStatus("comboBox_vcc", 3, true); } void MainWindow::on_actionCH341A_v1_7_triggered() { current_programmer = 1; ui->lStatus->setText("CH341A"); SetItemStatus("comboBox_type", 2, false); SetItemStatus("comboBox_vcc", 3, false); } void MainWindow::on_actionCH347T_triggered() { current_programmer = 2; ui->lStatus->setText("CH347T"); SetItemStatus("comboBox_type", 2, true); SetItemStatus("comboBox_vcc", 3, true); } void MainWindow::on_actionCH347T_v1_1_triggered() { current_programmer = 3; ui->lStatus->setText("CH347T"); SetItemStatus("comboBox_type", 2, true); SetItemStatus("comboBox_vcc", 3, false); } void MainWindow::closeEvent(QCloseEvent( *event)) { //Storing parameters in ini file if (lastDirectory.isEmpty()) lastDirectory = QDir::homePath(); QString iniPath = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("config.ini"); QSettings settings(iniPath, QSettings::IniFormat); settings.beginGroup("Chip"); settings.setValue("ChipDirectory", lastDirectory); settings.endGroup(); settings.beginGroup("Device"); settings.setValue("ProgrammerType", current_programmer); settings.endGroup(); settings.beginGroup("FormPosition"); settings.setValue("geometry", saveGeometry()); settings.endGroup(); QMainWindow::closeEvent(event); } void MainWindow::showEvent(QShowEvent* event) { QMainWindow::showEvent(event); hexEdit->setGeometry(0, 0, ui->frame->width(), ui->frame->height()); } void MainWindow::SetItemStatus(QString comboboxName, int itemNumber, bool setDisable) { QComboBox* comboBox = findChild(comboboxName); if (!comboBox) { qWarning() << "ComboBox" << comboboxName << "not found!"; return; } if (itemNumber < 0 || itemNumber >= comboBox->count()) { qWarning() << "Item number" << itemNumber << "out of range"; return; } QStandardItemModel* model = qobject_cast(comboBox->model()); if (!model) { model = new QStandardItemModel(comboBox); for (int i = 0; i < comboBox->count(); ++i) { QStandardItem* item = new QStandardItem(comboBox->itemText(i)); item->setData(comboBox->itemData(i), Qt::UserRole); model->appendRow(item); } comboBox->setModel(model); } QStandardItem* item = model->item(itemNumber); if (item) { if (setDisable) { item->setFlags(item->flags() & ~Qt::ItemIsEnabled); item->setForeground(QBrush(Qt::gray)); } else { item->setFlags(item->flags() | Qt::ItemIsEnabled); item->setForeground(QBrush(comboBox->palette().color(QPalette::Text))); } } } void MainWindow::on_actionShow_programmer_version_triggered() { std::shared_ptr buf(new uint8_t[0x12]); statusCH341 = ProgDeviceInit(current_programmer, currentChipType, currentI2CBusSpeed); if (statusCH341 == 0) { getDeviceDescriptor(buf.get(), current_programmer); ProgDeviceClose(current_programmer); QMessageBox::about(this, tr("Info:"), (tr("Device revision: ") + byteBCDPrint(buf[13], false) + "." + byteBCDPrint(buf[12], true))); } else QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); } void MainWindow::on_actionCheck_erase_triggered() { //Verification of data erasure from the chip int res = 0; uint32_t step, numBlocks; statusCH341 = ProgDeviceInit(current_programmer, currentChipType, currentI2CBusSpeed); if (statusCH341 == 0) { if (((currentNumBlocks > 0) && (currentBlockSize >0) && (currentChipType == 0)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 1)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 2)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 3)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 4)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 5)) || ((currentNumBlocks > 0) && (currentPageSize >0) && (currentChipType == 6))) { ui->crcEdit->setText(""); doNotDisturb(); switch (currentChipType) { case 0: //SPI step = currentBlockSize; numBlocks = currentNumBlocks; break; case 1: //I2C //step = currentPageSize; step = 128; numBlocks = currentChipSize / step; break; case 2: //MicroWire case 3: //25xxx case 4: //95xxx case 5: //45xx step = currentPageSize; numBlocks = currentChipSize / step; break; case 6: //NAND 35xx, GD5xx, W25xx step = currentPageSize; numBlocks = currentChipSize / step; nand_ECCEnable(current_programmer); break; default: //Unsupport QMessageBox::about(this, tr("Error"), tr("Unsupported chip type!")); doNotDisturbCancel(); ProgDeviceClose(current_programmer); ui->checkBox_1->setStyleSheet(""); return; } ch341StatusFlashing(); uint32_t addr = 0; uint32_t curBlock = 0; uint32_t j, k; //progerssbar settings int currentPercent = 0; int lastPercent = -1; ui->progressBar->setRange(0, 100); ui->progressBar->setValue(0); std::shared_ptr buf(new uint8_t[step]); ui->checkBox_1->setStyleSheet("QCheckBox{font-weight:800;}"); ui->statusMessage->setText(tr("Erase checking in ") + ui->comboBox_name->currentText()); for (k = 0; k < numBlocks; k++) { switch (currentChipType) { case 0: //SPI res = snor_read_param(buf.get(),curBlock * step, step, step, currentAddr4bit, current_programmer); break; case 1: //I2C res = ch34xi2cBlockRead(buf.get(), curBlock * step, step, currentAlgorithm, current_programmer); if (res==0) res = 1; break; case 2: //MicroWire res = Read_EEPROM_3wire_param(buf.get(), static_cast(curBlock * step), static_cast(step), static_cast(currentChipSize), currentAlgorithm); if (res==0) res = 1; break; case 3: //25xxx case 4: //95xxx res = s95_read_param(buf.get(), curBlock * step, step, step, currentAlgorithm, current_programmer); break; case 5: res = at45_read_param(buf.get(), curBlock * step, step, step, currentAlgorithm, current_programmer); break; case 6: //NAND res = nand_page_read(buf.get(), step, k); if (res==0) res = 1; break; default: //Unsupport QMessageBox::about(this, tr("Error"), tr("Unsupported chip type!")); doNotDisturbCancel(); ProgDeviceClose(current_programmer); ui->checkBox_1->setStyleSheet(""); return; } // if res=-1 - error, stop if (statusCH341 != 0) { QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); doNotDisturbCancel(); break; } if (res <= 0) { QMessageBox::about(this, tr("Error"), tr("Error reading block ") + QString::number(curBlock)); ProgDeviceClose(current_programmer); ui->pushButton->setStyleSheet(grnKeyStyle); doNotDisturbCancel(); return; } for (j = 0; j < step; j++) { if ((buf[addr + j - k * step]) != 0xff) { //error compare QMessageBox::about(this, tr("Error"), tr("Error erasing chip!\nAddress: ") + hexiAddr(addr + j) + tr("\nNeed: FF") + tr(" Chip: ") + bytePrint(buf[addr + j - k * step])); ui->statusMessage->setText(""); ui->checkBox_1->setStyleSheet(""); ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } } addr = addr + step; curBlock++; qApp->processEvents(); if (isHalted) { isHalted = false; ProgDeviceClose(current_programmer); doNotDisturbCancel(); return; } currentPercent = static_cast((curBlock * 100.0) / numBlocks); if (currentPercent != lastPercent) { ui->progressBar->setValue(currentPercent); lastPercent = currentPercent; } } } else { //Not correct Number fnd size of blocks if (currentChipType == 0) QMessageBox::about(this, tr("Error"), tr("Before reading from chip please press 'Detect' button.")); if (currentChipType == 1) QMessageBox::about(this, tr("Error"), tr("Please select the chip parameters - manufacture and chip name.")); } doNotDisturbCancel(); ui->statusMessage->setText(""); ui->progressBar->setValue(0); ui->checkBox_1->setStyleSheet(""); ProgDeviceClose(current_programmer); } else { ch341StatusFlashing(); QMessageBox::about(this, tr("Error"), tr("Programmer ") + ui->lStatus->text() + tr(" is not connected!")); } } void MainWindow::on_actionFill_with_code_triggered() { DialogFill* fillDialog = new DialogFill(this); fillDialog->show(); connect(fillDialog, SIGNAL(sendAddr4(QString)), this, SLOT(receiveAddr4(QString))); } void MainWindow::receiveAddr4(QString addressData) { QStringList resultOfForm; resultOfForm = addressData.split("-"); uint32_t startAddr, endAddr, length, fillingCode, typeOfEnd; startAddr = hexToInt(resultOfForm[0]); endAddr = hexToInt(resultOfForm[1]); fillingCode = hexToInt(resultOfForm[2]); typeOfEnd = hexToInt(resultOfForm[3]); if (typeOfEnd == 1) endAddr = endAddr + startAddr; length = endAddr - startAddr; if (endAddr < startAddr) { QMessageBox::about(this, tr("Error"), tr("The end address must be greater than the starting address.")); return; } if (static_cast(endAddr) > hexEdit->data().length()) { QMessageBox::about(this, tr("Error"), tr("The ending address must not exceed the buffer size.")); return; } chipData = hexEdit->data(); char *point = chipData.data(); std::fill(point + startAddr, point + endAddr, fillingCode); hexEdit->setData(chipData); ui->statusMessage->setText(""); } void MainWindow::on_comboBox_raw_currentIndexChanged(int index) { if (index == 0) { nandRaw = false; if (scroll_connect) disconnect(scroll_connect); if (hexEdit) hexEdit->clearUserAreas(); } else { nandRaw = true; scroll_connect = connect(hexEdit->verticalScrollBar(), &QScrollBar::valueChanged, this, &MainWindow::handleScroll); } on_comboBox_size_currentIndexChanged(0); } void MainWindow::handleScroll() { if (currentChipSize > 0x3ffffff) { long posStart = 0, posEnd = 0, i; posStart = hexEdit->_bPosFirst; posEnd = hexEdit->_bPosLast + currentECCsize + 16; hexEdit->clearUserAreas(); hexEdit->setCursorPosition(posStart *2); if(posStart > 0x40) { for (i = posStart; i <= posEnd; i = i + 16) { if (i % (currentPageSize + currentECCsize) == 0) hexEdit->addUserArea(i - currentECCsize, i, QColor(0, 0, 0, 255), QColor(255, 0, 0, 60)); } } } } imsprog-1.8.5/IMSProg_programmer/mainwindow.h000066400000000000000000000132651520775651600212720ustar00rootroot00000000000000/* * Copyright (C) 2023 - 2026 Mikhail Medvedev * * * 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 3 * 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. */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include "qhexedit.h" #include "dialogsp.h" #include "dialogabout.h" #include "dialoginfo.h" #include "dialogsfdp.h" #include "dialognandsr.h" #include "dialogsr.h" #include "dialogcompare.h" #include "searchdialog.h" #include "hexutility.h" extern "C" { #include "bitbang_microwire.h" #include "ch341a_gpio.h" #include "ch341a_spi.h" #include "ch347.h" #include "flashcmd_api.h" #include "mw_eeprom_api.h" #include "res.h" #include "snorcmd_api.h" #include "spi_controller.h" #include "spi_eeprom_api.h" #include "timer.h" #include "types.h" #include "ch34x_i2c.h" } namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); public slots: void receiveAddr(QString); void receiveAddr2(QString); void receiveAddr3(qint64); void receiveAddr4(QString); void closeSFDP(); void closeSR(); void closeNandSR(); void receiveNandStatus(uint8_t); private slots: void progInit(); void on_pushButton_clicked(); void on_pushButton_2_clicked(); void on_comboBox_size_currentIndexChanged(int index); void on_comboBox_page_currentIndexChanged(int index); void on_actionDetect_triggered(); void on_actionSave_triggered(); void on_actionErase_triggered(); void on_actionUndo_triggered(); void on_actionRedo_triggered(); void on_actionOpen_triggered(); void on_actionWrite_triggered(); void on_actionRead_triggered(); void on_actionExit_triggered(); void on_comboBox_man_currentIndexChanged(int index); void on_comboBox_name_currentTextChanged(const QString &arg1); void on_actionVerify_triggered(); void on_pushButton_3_clicked(); void on_actionSave_Part_triggered(); void on_actionLoad_Part_triggered(); void on_actionFind_Replace_triggered(); void on_comboBox_type_currentIndexChanged(int index); void on_actionAbout_triggered(); void on_actionChecksum_calculate_triggered(); void on_actionEdit_chips_Database_triggered(); void doNotDisturb(); void doNotDisturbCancel(); void on_actionStop_triggered(); void on_pushButton_4_clicked(); void on_actionChip_info_triggered(); void on_comboBox_addr4bit_currentIndexChanged(int index); void on_actionExport_to_Intel_HEX_triggered(); void on_actionImport_from_Intel_HEX_triggered(); void on_actionExtract_from_ASUS_CAP_triggered(); void resizeEvent(QResizeEvent* event); void slotTimerAlarm(); void on_actionGoto_address_triggered(); void on_comboBox_i2cSpeed_currentIndexChanged(int index); void on_actionSecurity_registers_triggered(); void on_actionFill_test_image_triggered(); void preparingToCompare(bool type); void on_actionCompare_files_triggered(); void on_comboBox_ECC_currentIndexChanged(int index); void on_actionCopy_triggered(); void on_actionPaste_triggered(); void on_actionBad_block_management_triggered(); void on_actionCH341A_B_v1_2_triggered(); void on_actionCH341A_v1_7_triggered(); void closeEvent(QCloseEvent *event); void showEvent(QShowEvent* event); void on_actionCH347T_triggered(); void SetItemStatus(QString comboboxName, int itemNumber, bool setDisable); void on_actionCH347T_v1_1_triggered(); void on_actionShow_programmer_version_triggered(); void on_actionCheck_erase_triggered(); void on_actionFill_with_code_triggered(); void on_comboBox_raw_currentIndexChanged(int index); void handleScroll(); private: Ui::MainWindow *ui; QHexEdit *hexEdit = nullptr; QString grnKeyStyle, redKeyStyle; QString lastDirectory; int statusCH341; QByteArray chipData, oldChipData; uint32_t currentChipSize, currentNumBlocks, currentBlockSize, currentPageSize, currentECCsize; uint8_t currentAlgorithm, currentChipType, currentI2CBusSpeed; unsigned int currentAddr4bit; bool isHalted; bool filled; bool nandRaw; uint8_t numberOfReads; QTimer *timer; QVector chType = {"SPI_FLASH","25_EEPROM","93_EEPROM","24_EEPROM","95_EEPROM"}; struct chip_data { QString chipManuf; QString chipTypeTxt; QString chipName; uint8_t chipJedecIDMan; uint8_t chipJedecIDDev; uint8_t chipJedecIDCap; uint32_t chipSize; uint16_t sectorSize; uint8_t chipTypeHex; uint8_t algorithmCode; int delay; uint8_t addr4bit; uint32_t blockSize; uint8_t eepromPages; QString chipVCC; }; chip_data chips[2000]; int max_rec; QString fileName, oldFileName, newFileName; bool cmdStarted; void ch341StatusFlashing(); QByteArray block; uint32_t blockStartAddr, blockLen; uint8_t nandSettings; uint8_t current_programmer; QMetaObject::Connection scroll_connect; }; #endif // MAINWINDOW_H imsprog-1.8.5/IMSProg_programmer/mainwindow.ui000066400000000000000000001336411520775651600214610ustar00rootroot00000000000000 MainWindow 0 0 950 631 0 0 900 0 IMSProg - I2C/MicroWire/SPI CH341a Programmer :/res/img/write64.png:/res/img/write64.png 0 0 221 91 400 16777215 QGroupBox { font: bold; border: 1px solid silver; border-radius: 6px; margin-top: 6px; } QGroupBox::title { subcontrol-origin: margin; left: 7px; padding: 0px 5px 0px 5px; } Chip Type 111 21 250 21 150 0 75 true QComboBox::AdjustToMinimumContentsLengthWithIcon 22 Manufacture 111 21 250 21 150 0 75 true QComboBox::AdjustToMinimumContentsLengthWithIcon 22 Name 111 21 250 21 75 true QComboBox::AdjustToMinimumContentsLengthWithIcon 22 Size 111 21 250 21 75 true QComboBox::AdjustToMinimumContentsLengthWithIcon 22 Page size 111 21 250 21 75 true QComboBox::AdjustToMinimumContentsLengthWithIcon 22 Block size 111 21 250 21 75 true QComboBox::AdjustToMinimumContentsLengthWithIcon 22 VCC, Volt 28 QLayout::SetDefaultConstraint 0 0 0 95 22 185 22 75 false true PreferDefault Qt::LeftToRight QComboBox::AdjustToMinimumContentsLengthWithIcon 18 22 22 22 22 75 true true QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} i 4byte Addr. 111 21 250 21 75 true QComboBox::AdjustToMinimumContentsLengthWithIcon 22 I2C bus speed 111 21 250 21 75 true QComboBox::AdjustToMinimumContentsLengthWithIcon 22 ECC size 111 21 250 21 75 true QComboBox::AdjustToMinimumContentsLengthWithIcon 22 Qt::Vertical 20 6 Qt::Vertical 127 6 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Detect Qt::Horizontal 28 20 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Read Operations 111 21 250 21 75 true QComboBox::AdjustToMinimumContentsLengthWithIcon 22 221 41 400 16777215 QGroupBox { font: bold; border: 1px solid silver; border-radius: 6px; margin-top: 6px; } QGroupBox::title { subcontrol-origin: margin; left: 7px; padding: 0px 5px 0px 5px; } Auto Options false false Erase true Check erase true Program true Verify true Qt::Horizontal 40 20 Qt::Vertical 20 40 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Go! 9 0 11 16777215 20 75 true Hex Editor 611 401 16777215 16777215 QFrame::StyledPanel QFrame::Raised 90 320 100 25 100 0 120 25 75 true border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; 20 320 67 17 JEDEC ID: Qt::AlignCenter 40 290 61 16 CH341a: 90 290 100 21 100 0 120 25 75 true border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; 20 350 67 17 CRC32: Qt::AlignCenter 90 350 100 25 100 0 120 25 75 true border: 2px solid gray;border-radius: 5px;font-weight:600;border-style:inset; 40 390 315 16 315 0 16777215 16777215 Message 24 0 0 950 21 false File Chip Hex Editor Help Programmer false 48 48 false TopToolBarArea false :/res/img/open64.png:/res/img/open64.png Open Ctrl+O :/res/img/save64.png:/res/img/save64.png Save Ctrl+S :/res/img/exit64.png:/res/img/exit64.png Exit Ctrl+Q :/res/img/test64.png:/res/img/test64.png Detect Ctrl+D :/res/img/read64.png:/res/img/read64.png Read Ctrl+R :/res/img/erase64.png:/res/img/erase64.png Erase Ctrl+E :/res/img/write64.png:/res/img/write64.png Write Ctrl+W :/res/img/verify64.png:/res/img/verify64.png Verify Ctrl+T :/res/img/undo.png:/res/img/undo.png Undo Ctrl+Z :/res/img/redo64.png:/res/img/redo64.png Redo Ctrl+Y :/res/img/saveBlock64.png:/res/img/saveBlock64.png Save Part :/res/img/loadBlock64.png:/res/img/loadBlock64.png Load Part :/res/img/hexsearch64.png:/res/img/hexsearch64.png Find / Replace Ctrl+F About About IMSProgrammer Ctrl+H :/res/img/checkSum64.png:/res/img/checkSum64.png Checksum calculate Ctrl+A :/res/img/chipEdit64.png:/res/img/chipEdit64.png Edit chips Database Ctrl+N :/res/img/stop64.png:/res/img/stop64.png Stop Forced stop of read, write, erase and verification operations Ctrl+I :/res/img/info64.png:/res/img/info64.png Chip info Information about SFDP and status registers Ctrl+P :/res/img/open64.png:/res/img/open64.png Import from Intel HEX :/res/img/save64.png:/res/img/save64.png Export to Intel HEX :/res/img/open64.png:/res/img/open64.png Extract from ASUS CAP :/res/img/goto64.png:/res/img/goto64.png Goto address Move the cursor to the entered address Ctrl+G :/res/img/unprotect64.png:/res/img/unprotect64.png Security registers Ctrl+U :/res/img/fill64.png:/res/img/fill64.png Fill test image Filling the hex editor with a test array Ctrl+L :/res/img/compare64.png:/res/img/compare64.png Compare files Compares the results of the last and penultimate chip read or file open operation Ctrl+M :/res/img/copy64.png:/res/img/copy64.png Copy :/res/img/paste64.png:/res/img/paste64.png Paste :/res/img/info64.png:/res/img/info64.png Bad block management Ctrl+B Show programmer version :/res/img/checkErase64.png:/res/img/checkErase64.png Check erase Check erase chip Ctrl+J :/res/img/fill64.png:/res/img/fill64.png Filling with code Ctrl+K true true CH341A/B v1.2 true CH341A v1.7 true CH347T v1.0 true CH347T v1.1 imsprog-1.8.5/IMSProg_programmer/mw_eeprom.c000066400000000000000000000031121520775651600210710ustar00rootroot00000000000000/* * Copyright (C) 2021 McMCC * mw_eeprom.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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "bitbang_microwire.h" #include "ch341a_gpio.h" #include "timer.h" extern struct gpio_cmd bb_func; extern char eepromname[12]; extern unsigned int bsize; /* 25xx 93xx PIN 22 - D7 - MISO DO PIN 21 - D6 - PIN 20 - D5 - MOSI DI PIN 19 - D4 - PIN 18 - D3 - CLK CLK PIN 17 - D2 - PIN 16 - D1 - PIN 15 - D0 - CS CS */ int mw_gpio_init(void) { int ret = 0; CLK = 1 << 3; DO = 1 << 7; DI = 1 << 5; CSEL = 1 << 0; bb_func.gpio_setdir = ch341a_gpio_setdir; bb_func.gpio_setbits = ch341a_gpio_setbits; bb_func.gpio_getbits = ch341a_gpio_getbits; if(bb_func.gpio_setdir) ret = bb_func.gpio_setdir(); else return -1; if(ret < 0) return -1; return 0; } /* End of [mw_eeprom.c] package */ imsprog-1.8.5/IMSProg_programmer/mw_eeprom_api.h000066400000000000000000000017621520775651600217400ustar00rootroot00000000000000/* * Copyright (C) 2021 McMCC * mw_eeprom_api.h * * 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. */ #ifndef __MW_EEPROM_API_H__ #define __MW_EEPROM_API_H__ //int mw_eeprom_read(unsigned char *buf, unsigned long from, unsigned long len); //int mw_eeprom_erase(unsigned long offs, unsigned long len); //int mw_eeprom_write(unsigned char *buf, unsigned long to, unsigned long len); //long mw_init(void); int mw_gpio_init(void); //void support_mw_eeprom_list(void); #endif /* __MW_EEPROM_API_H__ */ /* End of [mw_eeprom_api.h] package */ imsprog-1.8.5/IMSProg_programmer/nandcmd_api.h000066400000000000000000000021021520775651600213370ustar00rootroot00000000000000/* * Copyright (C) 2018-2021 McMCC * nandcmd_api.h * * 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. */ #ifndef __NANDCMD_API_H__ #define __NANDCMD_API_H__ int snand_read(unsigned char *buf, unsigned long from, unsigned long len); int snand_erase(unsigned long offs, unsigned long len); int snand_write(unsigned char *buf, unsigned long to, unsigned long len); long snand_init(void); void support_snand_list(void); extern int ECC_fcheck; extern int ECC_ignore; extern int OOB_size; extern int Skip_BAD_page; extern unsigned char _ondie_ecc_flag; #endif /* __NANDCMD_API_H__ */ /* End of [nandcmd_api.h] package */ imsprog-1.8.5/IMSProg_programmer/other/000077500000000000000000000000001520775651600200575ustar00rootroot00000000000000imsprog-1.8.5/IMSProg_programmer/other/71-CH341.rules000066400000000000000000000003671520775651600221100ustar00rootroot00000000000000# This file should be copied to /etc/udev/rules.d on GNU/Linux OS and derived # Add permission to all user to have complete acces to eeprom programmer CH341 SUBSYSTEM=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="5512|55db", TAG+="uaccess" imsprog-1.8.5/IMSProg_programmer/other/IMSProg.1.gz000066400000000000000000000013771520775651600220500ustar00rootroot00000000000000jIMSProg.1SYo@~WxT%҄IJ=ƫzw=8^;#$}i%l||;_H}#w_?_a| >{ĄY߬^wq:`i+i&jȕ& c$@T__gW#LɒK ݞ>=Od%1ԇ۹X=N20dҢlڅvPUq;wpI*&|O?TɴX6uHi〡K.T5M=41t6](z 8sʁpƂP֠nquBR*hu403H2 B$!UI/ə*7qfnrZ\ tF`L]GaaEr)/woQGp6[ / KXav@"Ԃ㗒A9dTUd4Ϛ'+R/.XD@i-MQ]f(Q%5VZu $'o.\<]|J˦҄h9$[@uYimsprog-1.8.5/IMSProg_programmer/other/IMSProg.desktop000066400000000000000000000055371520775651600227440ustar00rootroot00000000000000[Desktop Entry] Version=1.0 Type=Application Name=IMSProg Icon=/usr/share/pixmaps/IMSProg64.png Exec=/usr/bin/IMSProg Path=/usr/bin/ NoDisplay=false Categories=Electronics;Development; StartupNotify=true Terminal=false Comment=i2C,SPI,MW programmer for CH341a/CH347t devices Comment[en]=i2c,SPI,MW chips programmer for CH341a/CH347t devices Comment[ru]=Программатор i2c,SPI,MW микросхем для CH341a/CH347t Comment[es]=Programador de chips i2c, SPI, MW para dispositivos CH341a/CH347t Comment[de]=i2c,SPI,MW Chips Programmierer für CH341a/CH347t Geräte Comment[uk]=Программатор i2c,SPI,MW мікросхема для CH341a/CH347t Comment[pt]=Programador de chips i2c, SPI, MW para dispositivos CH341a/CH347t Comment[hu]=i2c,SPI,MW chipek programozója CH341a/CH347t eszközökhöz Comment[it]=Programmatore di chip i2c, SPI, MW per dispositivi CH341a/CH347t Comment[zh]=I2C、SPI、MicroWire EEPROM/Flash 芯片 CH341a/CH347t 编程器 Comment[zh_TW]=I2C、SPI、MicroWire EEPROM/Flash 晶片 CH341a/CH347t 燒錄器 GenericName=i2c,SPI,MW chips programmer for CH341a/CH347t devices GenericName[en]=i2c,SPI,MW chips programmer for CH341a/CH347t devices GenericName[ru]=Программатор i2c,SPI,MW микросхем для CH341a/CH347t GenericName[es]=Programador de chips i2c, SPI, MW para dispositivos CH341a/CH347t GenericName[de]=i2c,SPI,MW Chips Programmierer für CH341a/CH347t Geräte GenericName[uk]=Программатор i2c,SPI,MW мікросхема для CH341a/CH347t GenericName[pt]=Programador de chips i2c, SPI, MW para dispositivos CH341a/CH347t GenericName[hu]=i2c,SPI,MW chipek programozója CH341a/CH347t eszközökhöz GenericName[it]=Programmatore di chip i2c, SPI, MW per dispositivi CH341a/CH347t GenericName[zh]=I2C、SPI、MicroWire EEPROM/Flash 芯片 CH341a/CH347t 编程器 GenericName[zh_TW]=I2C、SPI、MicroWire EEPROM/Flash 晶片 CH341a/CH347t 燒錄器 Keywords=Microcircuit;Microchip;IC;Integrated circuit;BIOS;EEPROM;MicroWire Keywords[en]=Microcircuit;Microchip;IC;Integrated circuit;BIOS;EEPROM;MicroWire Keywords[ru]=Микросхема;Микрочип;ИС;Интегральная схема;chip;BIOS;EEPROM;MicroWire Keywords[es]=Microcircuito;Microchip;CI;Circuito integrado;BIOS;EEPROM;MicroWire Keywords[de]=Mikroschaltkreis;Mikrochip;IC;Integrierte Schaltung;BIOS;EEPROM;MicroWire Keywords[uk]=Мікросхема;Інтегральна схема;chip;BIOS;EEPROM;MicroWire Keywords[pt]=Microcircuito;Microchip;IC;Circuito integrado;BIOS;EEPROM;MicroWire Keywords[hu]=Mikroáramkör;Mikrochip;IC;Integrált áramkör;Integrált áramkör;BIOS;EEPROM;MicroWire Keywords[it]=Microcircuito;Microchip;IC;Circuito integrato;BIOS;EEPROM;MicroWire Keywords[zh]=微电路;微芯片;集成电路;基本输入输出系统;IC;BIOS;EEPROM;MicroWire Keywords[zh_TW]=微電路;微晶片;積體電路;BIOS;EEPROM;MicroWire imsprog-1.8.5/IMSProg_programmer/other/index.html000066400000000000000000001263571520775651600220720ustar00rootroot00000000000000 "IMSProg"

IMSProg

IMSProg - I2C, MicroWire and SPI EEPROM/Flash chip Programmer - is a program to read, write EEPROM chips use the CH341A programmer device and CH347T programmer device.

CH341A/B v1.2 CH341A v1.7 CH347T v1.0 CH347T v1.1
CH341A black CH341A green CH341A green CH347T v1.0 CH347T v1.1

The IMSProg makes respect to QHexEdit2 hex editor and SNANDer programmer. The format of the chip database is based on the format used in EZP2019, EZP2020, EZP2023, Minpro I, XP866+ programmers. Warning, format is not the same!

IMSProg is a collection of tools:

  1. IMSProg - the chip programmer (it’s the main part).

  2. IMSProg_editor - chip database editor.

  3. IMSProg_database_update - update chip database using external web-server.

CH341A EEPROM programmer
CH341A EEPROM programmer

Compiling project

git clone https://github.com/bigbigmdm/IMSProg.git && cd IMSProg
sudo ./build_all.sh

System software requirements

Linux

For build are needed: - g++ or clang - CMake - libusb 1.0 - Qt5 or Qt6 - Qt5LinguistTools or Qt6LinguistTools - pkgconf or pkg-config - udev

On Debian and derivatives:

  • for Qt5:

sudo apt-get install cmake g++ libusb-1.0-0-dev qtbase5-dev qttools5-dev pkgconf

  • for Qt6:

sudo apt-get install cmake g++ libusb-1.0-0-dev pkgconf qt6-base-dev qt6-tools-dev linguist-qt6 qt6-l10n-tools qt6-base-dev-tools qt6-tools-dev-tools

On Debian >=13 and Ubuntu >=24.04:

sudo apt-get install systemd-dev

On older:

sudo apt-get install udev

:information_source: Debian < 11 and Ubuntu < 20.04 are not supported, you may unable to have it working on them.

On Fedora and derivatives:

  • for Qt5:
sudo dnf install cmake libusb libusb1 libusb1-devel qt5-qtbase-devel 
sudo dnf install pkgconf-pkg-config qt5-linguist
  • for Qt6:
sudo dnf install cmake gcc-c++ libusb1-devel pkgconf-pkg-config qt6-qtbase-devel
sudo dnf install qt6-qttools-devel qt6-linguist

On OpenSUSE and derivatiles:

  • for Qt5:
sudo zypper install cmake gcc-c++ libqt5-qtbase-devel
sudo zypper install libqt5-linguist-devel libusb-1_0-devel
  • for Qt6:
sudo zypper install cmake gcc-c++ libqt6-qtbase-devel
sudo zypper install libqt6-linguist-devel libusb-1_0-devel

macOS

if using Homebrew then Xcode Command Line Tools will install by default, if not then install manually from terminal:

xcode-select --install

install the required packages

using brew:

brew install qt@5 libusb cmake pkgconf

if not using the build_all.sh script then make sure libusb is in your C_INCLUDE_PATH

export C_INCLUDE_PATH=/usr/local/opt/libusb/include

How to use:

Note: for macOS use CMD instead of CTRL for keyboard shortcuts.

Chip programmer

Launching

Can be launched from Terminal by running the command

$ IMSProg

Connecting

  • Insert the chip into the appropriate slot of the CH341A programmer. The 24xxx and 25xxx series chips must be inserted directly, according to the markings on the PCB of the CH341A programmer. The 93xxx series chips must be inserted into the 93xxx adapter and the adapter into the marking 25xxx programmer slot. The DataFlash AT45DBxxx series chips must be mounted in a SOP-8 DIP-8 and this adapter shall be inserted into the 45xxx adapter. The 45xxx adapter must be installed in the programmer slot marked 25xxx. The SPI NAND Flash chips must be mounted in a WSON-8 DIP-8 adapter. This adapter must be installed in the programmer slot marked 25xxx.

[!NOTE] In the current version, the MicroWire (93Cxx) protocol is not supported by the CH347 programming device.

CH347T V1.1 - a device with a lower speed than the CH347T V1.0.

Adapter
  • If the chip supply voltage is 1.8 volt he must be inserted in 1.8 volt adapter and the adapter into needed programmer slot.
Adapter
  • Plug the CH341A programmer into the USB socket of your computer and running the IMSProg.
  • You can plug and unplug the programmer device (CH341A) to the USB port at any time when basic operations (reading, checking, and programming) are not in progress.
  • Read more about adapters here.

Chip type selecting

Select the type of chip used from the Type pop-up menu: SPI_FLASH when using SPI NOR FLASH chips of the 25xxx series, SPI_NAND when using SPI NAND FLASH chips, 24_EEPROM when using I2C EEPROM of the 24xxx series, 93_EEPROM when using MicroWire EEPROM of the 93xxx series, 45_EEPROM when using DataFlash chips AT45DBxxx series. When using 25xxx series SPI NOR FLASH chips (Menu item type -> SPI_FLASH), or SPI NAND FLASH chips (Menu item type -> SPI_NAND), or AT45DBxx series SPI FLASH (Menu item type -> 45_EEPROM) the Detect button will be available. When the Detect button or Detect or <Ctrl+D> is pressed, the JEDEC information is read from the chip and all parameters of that chip are loaded from the chip database. Any parameter (size, page size, block size, VCC voltage, and 4-bit address length) can be changed manually. You can manually enter the Manufacture and Name pop-up menu data - all other parameters will be automatically loaded from the chip database. When using 24xxx or 93xxx or 95xxx or 25xxx SPI EEPROM (non NOR FLASH) series chips, it is necessary to manually enter the Manufacture and Name pop-up menu data - all other parameters will be automatically loaded from the chip database.

File operations

  • The Save or <Ctrl+S> button is used to save the computer buffer to a file.

  • The Open or <Ctrl+O> button is used to save the file in the computer buffer.

  • The SavePart or <Ctrl+Shift-S> button is used to save a part of the computer buffer to a file (the start address and length of the part must be entered). This operation can be used when splitting a binary data image into parts.

  • The LoadPart or <Ctrl+Shift-S> button is used to load a small file to a certain address in the buffer. The data fragment in the buffer will be replaced with new data from the file.

  • The Edit or <Ctrl+Q> button is used to invoke the chip database editor.

  • The menu item File / Import from Intel HEX is used to save the Intel HEX file in the computer buffer.

  • The menu item File / Export to Intel HEX is used to save the computer buffer to a file in Intel HEX format.

Basic programmer operations

  • Pressing Read or Read or <Ctrl+R> to read data from the chip into the computer buffer.

  • Pressing Write or <Ctrl+W> to write data from the computer buffer into the chip.

  • Pressing Erase or <Ctrl+E> will erase all data in the chip.

  • By selecting Main Menu -> Chip -> Check erase or pressing <Ctrl+J>, you can check whether all data has been correctly deleted from the chip.

  • Pressing the Verify or <Ctrl+T> button causes the data in the chip and in the computer buffer to be compared.

The progress bar shows the progress of the read, erase, and verify operations.

  • The Auto button is used to perform erase, check erase, write and verify operations in sequence. If one of these operations is not needed, you can uncheck the checkbox for that operation.

  • The Stop or <Ctrl+I> key is used to force interruption of chip read/write/erase/verify operations.

  • The i key show the connection chip to CH341A device image form.

  • The Main menu -> Chip -> Chip info or <Ctrl+P> item shows the Serial Flash Discoverable Parameter (SFDP) register and the status registers of the SPI NOR flash memory chips.

SFDP

If the SPI NOR FLASH chip is detected normally, but is not read (gives the message Error reading sector 0), then in the Chip info window you can change bits BP4 and BP3 to zero and press the Write registers button. Then repeat the chip reading operation.

SFDP

If the SPI NOR FLASH chip is read unreliably (with a different checksum each time) and Status Register 2 is available in the chip, you can change bits DRV0 and DRV1 to zero and press the Write Registers button. This will increase the power of the output stage of the DO pin of the chip. Then repeat the chip read operation.

For 25xxx, 95xxx and 45xxx series chips that have only one status register, the Chip info form is as follows:

SFDP

For SPI NAND FLASH chips the Chip info form is as follows:

SFDP
  • The Main menu -> Chip -> Security Registers or <Ctrl+U> item is used to work with SPI NOR Flash and SPI NAND FLASH security registers data. This form allows reading, write, erase, save and load security register data from the computer.
Security registers

The buttons at the bottom of the form (Read, Erase, Write, Open, Save) perform a similar function to the top buttons on the main form. The Security register number: drop-down menu allows you to select one of the valid registers for the current chip for operation. The security registers can be locked for writing forever. If you want to know about this, please see Main Menu -> Chip -> Chip Information item or <Ctrl+P>, data fields in LB3, LB2 and LB1 in Status register 1. Please refer to the datasheet of your chip for detailed information. For NAND FLASH chips you can scanning bad blocks, use Main Menu -> Chip -> Bad block management or <Ctrl+B> key.

Bad block scan

For these chips, you can also change the erase and write parameters in this menu.

Bad block scan

[!NOTE] In this version of IMSProg, damaged blocks are not skipped when executing the Verify and Check erase functions for NAND Flash chips. If your chip contains damaged blocks, please do not use these functions.

Buffer (Hex editor) operations

The hexadecimal chip editor (right side of the screen) is used to display and modify buffer data.

It contains the following controls: Undo undo, Redo redo, and the Search search/replace. The [Ctrl+A] key used to update the CRC24 checksum. The [Ctrl+G] key used to move the cursor to the entered address. The [Ctrl+L] key is used to fill the hex editor buffer with a special test array. The [Ctrl+K] key is used to fill the hex editor buffer with a user code. The [Ctrl+M] key used for compares the results of the last and penultimate chip read or file open operation.

compare

Programmer type

The Main menu -> Programmer item is used to change the programmer type.

List of hotkeys:

Hotkey Function
Ctrl+A Checksum calculate
Ctrl+B Bad block management for NAND chips
Ctrl+C Copy selected bytes (Hex editor)
Ctrl+D Detect chip
Ctrl+E Erase chip
Ctrl+F Find/Replace (Hex editor)
Ctrl+G Goto address (Hex editor)
Chrl+H About IMSProg
Ctrl+I Force stop chip operation
Ctrl+J Check erase chip
Ctrl+K Fill the user code (Hex editor)
Ctrl+L Fill the test array (Hex editor)
Ctrl+M Compare files (Hex editor)
Ctrl+N Edit chip database
Ctrl+O Open file
Ctrl+P Chip info (SFDP + status registers)
Ctrl+Q Exit
Ctrl+R Read chip
Ctrl+S Save file
Ctrl+T Verify chip
Ctrl+U Security registers
Ctrl+V Paste selected bytes (Hex editor)
Ctrl+W Write chip
Ctrl+X Exit
Ctrl+Y Redo (Hex editor)
Ctrl+Z Undo (Hex editor)

Chip database editor

Chip editor

Chip base editor - IMSProg_editor is a stand-alone program that can be launched from the Development menu or from the IMSProg program by clicking on Edit.

All operations in the editor become available only after loading a chip base file with .Dat extension.

Menu File.

  • Open or [Ctrl+O] or open allows you to load the data file.
  • Save or [Ctrl+S] or save saves the chip parameter table to a database file.
  • Exit or [Ctrl+X] or exit - exits the editor.
  • Export to CSV format or [Ctrl+X] or export allows to unload data about chips in CSV format for further processing by spreadsheet software - LibreOffice Calc, OpenOffice Calc, Google Tables, etc.
  • Import from CSV file or [Ctrl+Shift+X] or import - loads a table in CSV format and adds data from it to the existing data in the table.

Menu Edit.

  • Delete Rows or Del or delete - deletes one or more rows.
  • Add Row or Ins or add - adds a row below the selected row and copies all data from the selected row to the new row.
  • Move Up or ’[Ctrl+Up]` or up - moves the selected line up.
  • Move Down' or[Ctrl+Down]` or down - moves the selected row down.
  • Import selected rows to CSV format or import
  • saves selected rows to CSV file.

The most recent version of the chip database file can be downloaded from this page in both .Dat and .csv formats.

Chip updater

Once IMSProg_database_update app has been run, the downloaded database is copied to the ~/.local/share/imsprog folder. The script then displays the number of chips in the database before and after the update.

List of supported chips

I2C EEPROM

24C01, 24C02, 24C04, 24C08, 24C16, 24C32, 24C64, 24C128, 24C256, 24C512, 24C1024, 24M02

I2C FeRAM

  • RAMXEED

MB85RC04, MB85RC16, MBRC64, MB85RC128, MB85RC256, MB85RC512, MB85RC1MT

  • RAMTRON

FM24C04A, FM24C16A, FM24C32A, FM24C64A, FM24C128, FM24C256, FM24C512, FM24CL04A, FM24CL16A, FM24CL32A, FM24CL64A

MicroWire EEPROM (only for CH341A programmer)

93C46, 93C56, 93C66, 93C76, 93C86

Serial SPI Bus EEPROM

  • ST

M95010, M95020, M95040, M95080, M95160, M95320, M95640, M95128, M95256, M95512, M95M01, M95M02

  • ATMEL

AT25010, AT25020, AT25040, AT25080, AT25160, AT25320, AT25640, AT25128, AT25256, AT25F512, AT25F1024, AT25F2048, AT25F4096

  • MICROCHIP

25AA010, 25AA020, 25AA040, 25AA080, 25AA160, 25AA320, 25AA640, 25AA128, 25AA256, 25AAF512, 25AAF1024, 25LC010, 25LC020, 25LC040, 25LC080, 25LC160, 25LC320, 25LC640, 25LC128, 25LC256, 25LC512, 25LC1024

  • ONSEMI

CAT25C01, CAT25C02, CAT25C04, CAT25C08, CAT25C16, CAT25C32, CAT25C64, CAT25C128, CAT25C256, CAT25C512

Serial SPI Bus FeRAM

  • RAMXEED

MB85RS16N, MB85RD16LX, MB85RS64VY, MB85RS64V, MB85RS128TY, MB85RS128B, MB85RS256TY, MB85RS256LYA, MB85RS256B, MB85RS512TY, MB85RS512LY, MS85RS1MLY, MB85RS1MT, MB85RS2MTY, MB85RS2MLY, MB85RS4MTY, MB85RS4MLY

DataFlash 45xx

  • ATMEL

AT45DB011, AT45DB021, AT45DB041, AT45DB081, AT45DB161, AT45DB321

  • ADESTO

AT45DB011, AT45DB021, AT45DB041, AT45DB081, AT45DB161, AT45DB321, AT45DB641

SPI NOR Flash

  • SPANSION

FL016AIF, S25FL016P, S25FL032P, FL064AIF, S25FL064P, S25FL256S, S25FL128P, S25FL129P, S25FL204K, S25FL208K, S25FL116K, S25FL132K, S25FL164K

  • XTX

XT25F02E, XT25F04D, XT25F08B, XT25F16B, XT25F32F, XT25F64F, XT25F128F, XT25F256B, XT25W02E, XT25W04D, XT25Q08D(1.8V), XT25Q16D(1.8V), XT25Q64D(1.8V), XT25F128D(1.8V)

  • ACE

ACE25AC512G, ACE25AC100G, ACE25AC200G, ACE25AC400G

  • EON

EN25B10T, EN25B20T, EN25B40T, EN25B80T, EN25B16T, EN25B32T, EN25B64T, EN25P64, EN25Q40A, EN25Q80B, EN25Q16, EN25Q32C, EN25Q64, EN25Q128, EN25F10A, EN25F20A, EN25F40, EN25F80, EN25F16, EN25F32, EN25S10A(1.8V), EN25S20A(1.8V), EN25S40A(1.8V), EN25S80B(1.8V), EN25S16B(1.8V), EN25S64A(1.8V), EN25QE16A, EN25QE32A, EN25E10A, EN25E40A, EN25SE16A(1.8V), EN25SE32A(1.8V), EN25T80, EN25T16, EN25QA32B, EN25QA64A, EN25QA128A, EN25QW16A, EN25QW32A, EN25QH16, EN25QH32B, EN25QH64A, EN25QH128A, EN25Q256, EN25QX64A, EN25QX128A, EN25QX256A, EN25QY256A, EN25SX64A(1.8V), EN25SX128A(1.8V)

  • ATMEL

AT25LS321(1.8V), AT25LS128A(1.8V), AT25LS641(1.8V), AT26DF161, AT25DF321, AT25DF641

  • MICRON

M25P10, M25P20, M25P40, M25P80, M25P016, M25P32, M25P64, M25P128, N25Q032A, N25Q064A, MT25QL64AB, N25Q128A, MT25QL128AB, N25Q256A, MT25QL256AB, MT25QL512AB, N25Q032A(1.8V), N25Q064A(1.8V), MT25QU64AB(1.8V), N25Q128A(1.8V), MT25QU128AB(1.8V), MT25QU256AB(1.8V), MT25QU512AB(1.8V)

  • XMC

XM25QH10B, XM25QH20B, XM25QH40B, XM25QH80B, XM25QH16C, XM25QH32B, XM25QH64C, XM25QH128C, XM25QH256C, XM25QH512C, XM25LU64C(1.8V), XM25LU128C(1.8V), XM25QU256C(1.8V), XM25QU512C(1.8V), XM25QW16C, XM25QW32C, XM25QW64C, XM25QW128C, XM25QW256C, XM25QW512C, XM25QU41B(1.8V), XM25QU80B(1.8V), XM25QU16C(1.8V), XM25LU32C(1.8V), XM25QH32A, XM25QH64A, XM25QH128A

  • AMIC

AT25L05P, A25L10PU, A25L20PU, A25L40PU, A25L80PU, A25L16PU, A25L10PT, A25L20PT, A25L40PT, A25L80PT, A25L16PT, A25L010, A25L020, A25L040, A25L040, A25L080, A25L016, A25L032, A25LQ080, A25LQ16, A25LQ32, A25LQ64

  • EXCELSEMI

ES25P10, ES25P20, ES25P40, ES25P80, ES25P16, ES25P32, ES25M40A, ES25M80A, ES25M16A

  • DOUQI

DQ25Q64AS

  • Zbit

ZB25LD10A(1.8V), ZB25LD20A(1.8V), ZB25LD40B(1.8V), ZB25LD80(1.8V), ZB25D10A, ZB25D20A, ZB25D40B, ZB25D80B, ZB25VQ16, ZB25VQ32, ZB25VQ64, ZB25VQ128, ZB25LQ16(1.8V), ZB25LQ32(1.8V), ZB25LQ64(1.8V), ZB25LQ128(1.8V), ZB25VQ20A, ZB25VQ40A, ZB25VQ80A, ZB25VQ16A, ZD25D20, ZD25D40, ZD25D80

  • ONSemi

LE25U20AMB, LE25U40CMC

  • Boya

BY25Q05AW, BY25Q10AW, BY25Q20BL(1.8V), BY25Q40BL, BY25Q80AW(1.8V), BY25Q16BL(1.8V), BY25D05AS, BY25D10AS, BY25D20AS, BY25D40AS, BY25Q80BS, BY25Q16BS, BY25Q32BS, BY25Q64AS, BY25Q128AS, BY25Q256ES, BY25Q10AL(1.8V), BY25Q20AL(1.8V), BY25Q40AL(1.8V), BY25Q32AL(1.8V), BY25Q64AL(1.8V), BY25Q128EL(1.8V)

  • PFLASH

Pm25LQ512B, Pm25LQ010B, Pm25LD020, Pm25LQ020B, PM25LQ016, PM25LQ032, PM25LQ064, PM25LQ128, Pm25LV010, Pm25LV020, Pm25LQ040B, Pm25LV040

  • Puya

P25Q06H, P25Q40H, PY25Q128HA, PY25Q256HB, PY25Q512HB, P25Q11H, P25Q21H, P25Q10H, P25Q20H, P25Q80H, P25Q16H, P25Q32H, P25Q64H, P25Q128H

  • ESMT

F25L004A, F25L008A, F25L016, F25L032, F25L064, F25L16QA, F25L32QA, F25L64QA

  • ISSI

IS25WQ020(1.8V), IS25WQ040(1.8V), IS25WQ080(1.8V), IS25LQ010, IS25LQ020, IS25LP040E, IS25LP080D, IS25LP016D, IS25LP032D, IS25LP064D, IS25LP128F, IS25LP256D, IS25LP512D, IS25WP512E(1.8V), IS25WP010E(1.8V), IS25WP020E(1.8V), IS25WP040D(1.8V), IS25WP080D(1.8V), IS25WP016D(1.8V), IS25WP032D(1.8V), IS25WP064D(1.8V), IS25WP128F(1.8V), IS25WP256D(1.8V), IS25WP512D(1.8V)

  • Fudan

FM25W02, FM25W04, FM25W16, FM25W32, FM25W64, FM25W128, FM25F005, FM25F01B, FM25F02A, FM25F04A, FM25Q04, FM25Q08, FM25Q16, FS25Q32, FS25Q64, FS25Q128

  • Zetta

ZD25Q64B, ZD25LQ128(1.8V), ZD25LQ64(1.8V), ZD25WD20B, ZD25WD40B, ZD25Q80C, ZD25Q16B, ZD25Q32C

  • PCT

PCT25VF016B, PCT25VF032B, PCT25VF064C, PCT25VF020B, PCT25VF040B, PCT25VF080B, PCT26VF016, PCT26VF032, PCT25VF010A

  • MXIC

MX25L512E, MX25L1006E, MX25L2005, MX25L4005A, MX25L8005M, MX25L1605D, MX25L3205D, MX25L6405D, MX25L12805D, MX25L25635E, MX25L51245G, MX25L5121E, MX25L1021E, MX25L1633E, MX25L1635E, MX25U5121E(1.8V), MX25U1001E(1.8V), MX25U2035F(1.8V), MX25U4035F(1.8V), MX25U80356(1.8V), MX25U1632F(1.8V), MX25U3232F(1.8V), MX25U6432F(1.8V), MX25U12832F(1.8V), MX25U25643G(1.8V), MX25U51245G(1.8V), MX25L1655D, MX25L6455E, MX25L12855E, MX25L25655E, MX25R1035F, MX25R2035F, MX25R4035F, MX25R8035F, MX25R1635F, MX25R3235F, MX25R6435F, MX25L3225D, MX25L3255D

  • Giantec

GT25D05C, GT25D10C, GT25D20C, GT25Q40C, GT25D05E, GT25D10E, GT25D20E, GT25Q80A, GT25Q16A, GT25Q32A-H, GT25Q64A-S

  • GigaDevice

GD25F40, GD25F80, GD25D40, GD25D80, GD25D05C, GD25D10C, GD25Q20C, GD25Q40C, GD25Q80C, GD25Q16C, GD25Q32, GD25Q64CSIG, GD25Q128CSIG, GD25Q256CSIG, GD25VQ21B, GD25VQ40C, GD25VQ80C, GD25VQ16C, GD25LD05C(1.8V), GD25LD10C(1.8V), GD25LD20C(1.8V), GD25LD40C(1.8V), GD25LQ80C, GD25LQ16C, GD25LQ32E, GD25LQ64E(1.8V), GD25LQ128(1.8V), GD25LQ256D(1.8V), GD25WD05C, GD25WD10C, GD25WD20E, GD25WD40E, GD25WD80C, GD25WQ20E, GD25WQ40E, GD25WQ80E, GD25WQ16E, GD25WQ32E, GD25WQ64E, GD25WQ128E, GD25WB256E, GD25LB512ME(1.8V), YC25Q128

  • Nantronix

N25S80, N25S32

  • PARAGON

PN25F08, PN25F16, PN25F32, PN25F64, PN25F128

  • DOSILICON

DS25Q64A, DS25Q4AA, DS25M4CB, DS25M64E, DS25M4AE, DS25M4AB, DS25M4BA

  • WINBOND

W25P80, W25P16, W25P32, W25P64, W25X05, W25X10, W25X20, W25X40, W25X80, W25X16, W25X32VS, W25X64, W25Q05CL, W25Q10Cl, W25Q20CL, W25Q40BV, W25Q80BL, W25Q16DV, W25Q32BV, W25Q64BV, W25Q128BV, W25Q256FV, W25Q20BW(1.8V), W25Q80, W25Q10EW(1.8V), W25Q20EW(1.8V), W25Q40EW(1.8V), W25Q80EW(1.8V), W25Q16JW(1.8V), W25Q32FW(1.8V), W25Q64DW(1.8V), W25Q128FW(1.8V), W25Q256JW(1.8V), W25M512JW(1.8V), W25Q512JV, W25M512JV, W25Q32JW(1.8V)

  • Fidelix

FM25Q04A, FM25Q08A, FM25Q16A, FM25Q32A, FM25Q64A, FM25Q128A, FM25M04A(1.8V), FM25M08A(1.8V), FM25M16A(1.8V), FM25M32A(1.8V), FM25M64A(1.8V), FM25M4AA(1.8V)

  • UCUNDATA (UCUN Technology)

UC25HQ05, UC25HQ10, UC25HQ20, UC25HQ40, UC25HQ80, UC25HQ16, UC25HQ32, UC25HQ64, UC25IQ128

SPI NAND Flash

  • ESMT

F50L2G41XA, F50L1G41LB(2M), F50L512M41A, F50L4G41XB

  • MICRON

MT29F4G01ABBFD12, MT29F4G01ABAFD12, MX35LF1G24AD-Z41, MX35LF2G24AD-Z41

  • MXIC

MX35LF4G24AD-Z41, MX35LF2G24AD-Z418, MX35LF4G24AD-Z418, MX35LF1GE4AB, MX35UF1G24AD-Z4I, MX35UF2G24AD-Z4I, MX35UF4G24AD-Z4I, MX35UF2G24AD-Z4I8, MX35UF4G24AD-Z4I8, MX35UF1G14AC, MX35UF2G14AC, MX35UF1GE4AC, MX35UF2GE4AC, MX35UF1GE4AD, MX35UF2GE4AD, MX35UF4GE4AD, MX35LF2GE4AD, MX35LF4GE4AD

  • WINBOND

W25N512GW, W25N512GV, W25N01KW, W25N01KV, W25N01JW, W25N01GW, W25N01GV, W25N02KW, W25N02KV, W25N02JW, W25N04LW, W25N04KW, W25N04KV

  • XTX

XT26G01C, XT26G01A, XT26G01D, XT26G11C, XT26G11D, XT26Q01D, XT26G02D, XT26G02C, XT26G12D-B, XT26Q02D, XT26Q04D XTX XT26Q14D

  • Dosilicon

DS35Q12B, DS35M12B, DS35Q12C, DS35M12C, DS35Q1GA, DS35M1GA, DS35Q1GB, DS35M1GB, DS35Q2GA, DS35M2GA, DS35Q2GB, DS35M2GB, DS35Q2GBS, DS35M2GBS, DS35Q4GM, DS35Q4GM, DS35Q4GB, DS35M4GB

  • ZETTA

ZD35Q1GC-IB

  • FORESEE

F35SQA001G, F35SQB004G, F35SQA512M, F35UQA002G, F35SQA002G, GD5F1GQ5UExxG

  • GigaDevice

GD5F1GQ5RExxG, GD5F1GM7UExxG, GD5F1GM7RExxG, GD5F1GM9UExxG, GD5F1GM9RExxG, GD5F1GQ4UFxxG, GD5F1GQ4RFxxG, GD5F1GQ4UAxxG, GD5F2GQ5UExxG, GD5F2GQ5RExxG, GD5F2GM7UExxG, GD5F2GM7RExxG, GD5F4GQ6UExxG, GD5F4GQ6RExxG, GD5F4GM8UExxG, GD5F4GM8RExxG, GD5F1GQ4UExxG, GD5F1GQ4RExxG, GD5F1GQ4UFxxS, GD5F1GQ4RFxxS, GD5F2GQ4UExxG, GD5F2GQ4RExxG

The latest version of the chip database can be found here. You can download it and copy it to the ~/.local/share/imsprog folder:

cp IMSProg.Dat ~/.local/share/imsprog

Packages

  • There is a work in progress for add IMSProg to official Debian (and derivatives repositories)

    For some Ubuntu versions you can use this PPA by adding ppa:bigmdm/imsprog to your system’s Software Sources.

    sudo add-apt-repository ppa:bigmdm/imsprog
    sudo apt update
    sudo apt install imsprog

    Is also possible manually build deb package using debian/latest branch.

  • For some versions of Fedora, you can use the official repositories.

sudo dnf install imsprog

Project structure

IMSProg _files_                                   _folder_
================================================================================
IMSProg                                                  /usr/bin
IMSProg_editor                                           /usr/bin
IMSProg_database_update                                  /usr/bin

IMSProg_programmer/database/IMSProg.Dat                  /usr/share/imsprog
                                                         ~/.local/share/imsprog

IMSProg_programmer/other/71-CH341.rules                  /lib/udev/rules.d

IMSProg_programmer/other/index.html                      /usr/share//doc/imsprog/html

IMSProg_programmer/language/chipProgrammer_ru_RU.qm      /usr/share/imsprog
IMSProg_programmer/language/chipProgrammer_es_ES.qm      /usr/share/imsprog
IMSProg_programmer/language/chipProgrammer_de_DE.qm      /usr/share/imsprog
IMSProg_programmer/language/chipProgrammer_zH_CN.qm      /usr/share/imsprog
IMSProg_programmer/language/chipProgrammer_uk_UA.qm      /usr/share/imsprog
IMSProg_programmer/language/chipProgrammer_hu_HU.qm      /usr/share/imsprog
IMSProg_programmer/language/chipProgrammer_pt_BR.qm      /usr/share/imsprog

IMSProg_editor/language/chipEditor_ru_RU.qm              /usr/share/imsprog
IMSProg_editor/language/chipEditor_de_DE.qm              /usr/share/imsprog
IMSProg_editor/language/chipEditor_es_ES.qm              /usr/share/imsprog
IMSProg_editor/language/chipEditor_zh_CN.qm              /usr/share/imsprog
IMSProg_editor/language/chipEditor_uk_UA.qm              /usr/share/imsprog
IMSProg_editor/language/chipEditor_hu_HU.qm              /usr/share/imsprog
IMSProg_editor/language/chipEditor_pt_BR.qm              /usr/share/imsprog

IMSProg_database_update/language/chipUpdater_ru_RU.qm    /usr/share/imsprog
IMSProg_database_update/language/chipUpdater_de_DE.qm    /usr/share/imsprog
IMSProg_database_update/language/chipUpdater_es_ES.qm    /usr/share/imsprog
IMSProg_database_update/language/chipUpdater_zh_CN.qm    /usr/share/imsprog
IMSProg_database_update/language/chipUpdater_uk_UA.qm    /usr/share/imsprog
IMSProg_database_update/language/chipUpdater_hu_HU.qm    /usr/share/imsprog
IMSProg_database_update/language/chipUpdater_pt_BR.qm    /usr/share/imsprog

IMSProg_programmer/other/IMSProg.desktop                 /usr/share/applications
IMSProg_programmer/other/IMSProg_editor.desktop          /usr/share/applications
IMSProg_database_update/other/IMSProg_database_update.desktop /usr/share/applications

IMSProg_editor/other/IMSProg_editor.1.gz                   /usr/share/man/man1
IMSProg_programmer/other/IMSProg.1.gz                      /usr/share/man/man1
IMSProg_database_update/other/IMSProg_database_update.1.gz /usr/share/man/man1

IMSProg_programmer/img/IMSProg64.png                     /usr/share/pixmaps
IMSProg_database_update/img/IMSProg_database_update.png  /usr/share/pixmaps
img/chipEdit64.png                        /usr/share/pixmaps

IMSProg_programmer/other/other/io.github.bigbigmdm.imsprog.metainfo.xml /usr/share/metainfo
IMSProg_editor/other/other/io.github.bigbigmdm.imsprog_editor.metainfo.xml /usr/share/metainfo
IMSProg_database_update/other/io.github.bigbigmdm.imsprog_database_update.metainfo.xml /usr/share/metainfo

Chip database format

IMSProg.Dat file structure:

Chip string length: 0x44 (68) bytes;

offset   Size   Value
00 -     2F     ASCII Chip type, Name and Manufacture, 0x00 filling
30        1     NOR FLASH Chip Size code   / 0x00 - other chips
31        1     NOR FLASH Chip ID Code     / 0x00 - other chips
32        1     NOR FLASH Manufacture code / 0x00 - other chips
33              0x00
34        4     Chip Size
35  
36    
37 
38        2     Sector size
39 
3A        1     Binary chip type:
                - 0x00 - SPI NOR FLASH 
                - 0x01 - 24xxx I2C
                - 0x02 - 93xxx MicroWire
                - 0x03 - 25xxx SPI EEPROM
                - 0x04 - 95xxx ST SPI EEPROM
                - 0x05 - AT45DBxxx SPI EEPROM
3B        1     Algorithm code number:
                - SPI NOR Flash always 0x00
                - I2C (24xxx) 0x?1 - address size 1 byte 
                - I2C (24xxx) 0x?2 - address size 2 bytes 
                - I2C (24xxx) 0x1? - address mask 1
                - I2C (24xxx) 0x3? - address mask 3
                - I2C (24xxx) 0x7? - address mask 7
                - MicroWire (93xxx) - 0x1? - organisation 16 bit
                - MicroWire (93xxx) - 0x0? - organisation 8 bit
                - MicroWire (93xxx) - 0x?7 -  7 bit address number
                - MicroWire (93xxx) - 0x?9 -  9 bit address number
                - MicroWire (93xxx) - 0x?A - 10 bit address number
                - MicroWire (93xxx) - 0x?B - 11 bit address number
                - 95xxx ST SPI EEPROM - 0x01 - 8 bit address
                - 95xxx ST SPI EEPROM - 0x02 - 16 bit address
                - 25xxx SPI EEPROM  - 0x?0 - 8 bit address
                - 25xxx SPI EEPROM  - 0x?1 - 16 bit address
                - 25xxx SPI EEPROM  - 0x?2 - 24 bit address
                - 25xxx SPI EEPROM  - 0x0? - fill erasing
                - 25xxx SPI EEPROM  - 0x1? - The third bit of the command is used for the high bit of the address
                - 25xxx SPI EEPROM  - 0x2? - erasing with use CHIP  FULL ERASE command
                - 45xxx SPI EEPROM  - 0x0? - ATMEL command pattern
                - 45xxx SPI EEPROM  - 0x1? - ADESTO command pattern
                - 45xxx SPI EEPROM  - 0x?9 -  9 bit sector address number
                - 45xxx SPI EEPROM  - 0x?A - 10 bit sector address number
                - 45xxx SPI EEPROM  - 0x?B - 11 bit sector address number
                - 45xxx SPI EEPROM  - 0x?C - 12 bit sector address number
                - 45xxx SPI EEPROM  - 0x?D - 13 bit sector address number
                - 45xxx SPI EEPROM  - 0x?F - 15 bit sector address number
                - SPI NOR Flash - algorithm number for working with  security registers
                - SPI NAND Flash - algorithm number for reading status and security registers
3C        2     Timing parameter:
3D              3000/1000/500/300/200/100 - NOR FLASH, 4000/2000 - 24xxx, 100 - 93xxx
3E        2     SPI NOR Flash 4bit address type:
                - 0x?0 - Not used (3 bit address data)
                - 0x?1 - Used (4 bit address data)
                - 0x01 - Default 4 bit command using
                - 0x11 - Winbond algorithm
                - 0x21 - Spansion algorithm
3F        1     0x00
40        1     SPI NOR FLASH block size in KB (64K = 0x40)
41        1     0x00
42        1     - EEPROM pages 0x01 - 0x04
                - For SPI NAND Flash - ECC Size / 64
43        1     VCC 00=>3.3V 01=>1.8V 02=>5.0V 03=>2.5V
The end record is 0x44 (68) zero bytes.

Licensing

Copyright (C) 2023 - 2026 Mikhail Medvedev. This project use GPL-3+ License, some parts taken from project SNANDer are GPL-2+ and from QHexEdit2 is LGPL-2.1 and CH347 parts is BSD-1-Clause.

Translations

Anyone can add or improve a translation by making a pull request. Translations files are located in: IMSProg_programmer/language/ and IMSProg_editor/language/ and IMSProg_database_update/language/

You can also add translation to the desktop files (IMSProg.desktop, IMSProg_database_update.desktop, IMSProg_editor.desktop),

and to the appstream metadata files (io.github.bigbigmdm.imsprog_editor.metainfo.xml, io.github.bigbigmdm.imsprog_database_update.metainfo.xml, io.github.bigbigmdm.imsprog.metainfo.xml).

imsprog-1.8.5/IMSProg_programmer/other/io.github.bigbigmdm.imsprog.metainfo.xml000066400000000000000000000531201520775651600276720ustar00rootroot00000000000000 io.github.bigbigmdm.imsprog GFDL-1.3 GPL-3.0+ IMSProg Reading, writing and erasing EEPROM chips Lesen, Schreiben und Löschen von EEPROM-Chips Lectura, escritura y borrado de chips EEPROM EEPROM chipek olvasása, írása és törlése Lettura, scrittura e cancellazione di chip EEPROM Leitura, gravação e apagamento de chips EEPROM Чтение, запись и стирание микросхем EEPROM Читання, запис і стирання мікросхем EEPROM 读取、写入和擦除 EEPROM 芯片 讀取、寫入及清除 EEPROM 晶片 https://github.com/bigbigmdm/IMSProg/tree/main/IMSProg_programmer/img/IMSProg64.png

IMSProg is a free software for CH341A and CH347T based chip programmers with graphical interface. With IMSProg you can read, verify, program, erase i2C, SPI, SPI NOR, SPI NAND, MicroWire EEPROM chips using the CH341A or CH347T programmer device.

IMSProg ist eine kostenlose Software für CH341A- und CH347T-basierte Chip-Programmiergeräte mit grafischer Oberfläche. Mit IMSProg können Sie i2C, SPI, SPI NOR, SPI NAND, MicroWire EEPROM Chips mit dem CH341A Programmiergerät lesen, verifizieren, programmieren, löschen.

IMSProg es un software gratuito para programadores de chips basados en CH341A/CH347T con interfaz gráfica. Con IMSProg puede leer, verificar, programar, borrar chips i2C, SPI, SPI NOR, MicroWire EEPROM utilizando el dispositivo programador CH341A.

Az IMSProg egy ingyenes szoftver CH341A/CH347T alapú chipprogramozók számára grafikus felülettel. Az IMSProg segítségével a CH341A programozó eszközzel i2C, SPI, SPI NOR, SPI NAND, MicroWire EEPROM chipeket olvashat, ellenőrizhet, programozhat, törölhet.

IMSProg è un software gratuito per programmatori di chip basati su CH341A con interfaccia grafica. Con IMSProg è possibile leggere, verificare, programmare, cancellare chip i2C, SPI, SPI NOR, SPI NAND, MicroWire EEPROM, utilizzando il programmatore CH341A.

O IMSProg é um software gratuito para programadores de chips baseados no CH341A/CH347T com interface gráfica. Com o IMSProg, você pode ler, verificar, programar e apagar chips i2C, SPI, SPI NOR SPI NAND e MicroWire EEPROM usando o dispositivo programador CH341A.

IMSProg - это бесплатное программное обеспечение для программаторов микросхем на базе CH341A/CH347T с графическим интерфейсом. С помощью IMSProg вы можете читать, проверять, программировать, стирать микросхемы i2C, SPI, SPI NOR, MicroWire EEPROM, используя устройство-программатор CH341A.

IMSProg - вільне програмне забезпечення для програматорів мікросхем на базі CH341A/CH347T з графічним інтерфейсом. За допомогою IMSProg ви можете читати, перевіряти, програмувати, стирати мікросхеми i2C, SPI, SPI NOR, SPI NAND, MicroWire EEPROM за допомогою програматора CH341A.

MSProg 是一套 I2C、SPI、MicroWire EEPROM/Flash 芯片 CH341A/CH347T 编程器免费软件。借助 IMSProg,您可以使用 CH341A 编程器读取、编程、校验、擦除 I2C、SPI、SPI NOR SPI NAND 和 MicroWire 芯片。

IMSProg 是一款針對 CH341A/CH347T 晶片燒錄器的免費軟體,具備圖形介面。您可以透過 CH341A 裝置,讀取、驗證、燒錄、清除 i2C、SPI、SPI NOR、SPI NAND、MicroWire EEPROM 晶片。

IMSProg is a collection of tools:

IMSProg ist eine Sammlung von Werkzeugen:

IMSProg es una colección de herramientas:

Az IMSProg egy eszközgyűjtemény:

IMSProg è una raccolta di strumenti:

O IMSProg é uma coleção de ferramentas:

IMSProg - это набор инструментов:

IMSProg - це набір інструментів:

IMSProg 是一套工具集合

IMSProg 是一套工具集合:

  • IMSProg - the chip programmer (it's the main part).
  • IMSProg - der Chip-Programmierer (das ist der Hauptteil).
  • IMSProg - el programador de chips (es la parte principal).
  • IMSProg - a chip programozó (ez a fő rész).
  • IMSProg - il programmatore di chip (è la parte principale).
  • IMSProg - o programador de chips (é a parte principal).
  • IMSProg - программатор микросхем (это основная часть).
  • IMSProg - програматор мікросхеми (це основна частина).
  • IMSProg - 芯片编程器(主要部分)
  • IMSProg - 晶片燒錄器(這是主要部分)。
  • IMSProg_editor - chip database editor.
  • IMSProg_editor - Chipdatenbank-Editor.
  • IMSProg_editor - editor de bases de datos de chips.
  • IMSProg_editor - chip adatbázis szerkesztő.
  • IMSProg_editor - editor del database dei chip.
  • IMSProg_editor - editor de banco de dados de chips.
  • IMSProg_editor - редактор базы данных микросхем.
  • IMSProg_editor - редактор бази даних мікросхем.
  • IMSProg_editor - 芯片数据库编辑器。
  • IMSProg_editor - 晶片資料庫編輯器。
  • IMSProg_database_update - script to update chip database using external web-server.
  • IMSProg_database_update - Skript zur Aktualisierung der Chipdatenbank mit Hilfe eines externen Web-Servers.
  • IMSProg_database_update - script para actualizar la base de datos de chips utilizando un servidor web externo.
  • IMSProg_database_update - szkript a chip adatbázis frissítéséhez külső webszerver használatával.
  • IMSProg_database_update - script per aggiornare il database dei chip utilizzando un server web esterno.
  • IMSProg_database_update - script para atualizar o banco de dados de chips usando um servidor da Web externo.
  • IMSProg_database_update - скрипт для обновления базы данных микросхем с помощью внешнего веб-сервера.
  • IMSProg_database_update - скрипт для оновлення бази даних чіпів за допомогою зовнішнього веб-сервера.
  • IMSProg_database_update - 使用外部Web服务器更新芯片数据库的脚本。
  • IMSProg_database_update - 使用外部網路伺服器更新晶片資料庫的腳本。
Development Programmer BIOS EEPROM MicroWire IC chip Microcircuit Microchip IC Integrated circuit Mikroschaltkreis Mikrochip Integrierte Schaltung Microcircuito Microchip Circuito integrado Mikroáramkör Mikrochip Integrált áramkör Microcircuito Microchip Circuito integrato Microcircuito Microchip Circuito integrado Микросхема Микрочип Интегральная схема Мікросхема Інтегральна схема 微电路 微芯片 集成电路 微電路 微晶片 積體電路 https://github.com/bigbigmdm/IMSProg/tree/main https://github.com/bigbigmdm https://github.com/bigbigmdm/IMSProg/issues IMSProg.desktop application/octet-stream usb:v1A86p5512d* usb:v1A86p55DBd* Mikhail Medvedev Main screen with chip connection form. Hauptbildschirm mit Chipverbindungsformular. Pantalla principal con formulario de conexión de chips. Főképernyő a chipcsatlakozási űrlappal. Schermata principale con modulo di connessione al chip. Tela principal com formulário de conexão de chips. Главный экран с формой подключения микросхемы. Головний екран з формою підключення чіпа. 主屏幕显示芯片连接表。 主畫面與晶片連結表單。 https://github.com/bigbigmdm/IMSProg/raw/main/img/IMSProg.png Main screen. Hauptbildschirm. Pantalla principal. Főképernyő. Schermata principale. Tela principal. Главный экран. Головний екран. 主屏幕。 主畫面。 https://github.com/bigbigmdm/IMSProg/raw/main/img/IMSProg_1.png Form of chip information (SFDP and status registers). Form der Chipinformationen (SFDP und Statusregister). Forma de la información del chip (SFDP y registros de estado). A chipinformáció formája (SFDP és állapotregiszterek). Modulo delle informazioni del chip (SFDP e registri di stato). Formulário de informações do chip (SFDP e registros de status). Форма информации о микросхеме (SFDP и регистры статуса). Форма інформації про чіп (SFDP та регістри стану). 芯片信息表(SFDP 和状态寄存器)。 晶片資訊表單(SFDP和狀態暫存器)。 https://github.com/bigbigmdm/IMSProg/raw/main/img/sfdp_unblock_en.png

Fix: the first highlighted area in HexEdit was not being cleared.

Fix: combobox Operations was not reset if chip type changed.

Fix: program crashed if current chip is nothing and combobox Operation changed

Fix: Operations label showed for all chip types.

Added: Support for I2C and SPI FeRAM chips.

I2C 5v0 images on info form.

Fixed: segmentation fault in Qt6.

Fixed: incorrect interface display on macOS.

Fixed: write error to sector 0 in Windows.

Fixed: incorrect saving of the database file in the chip editor.

Fixed: unable to erase the 93C66, 93C76 and 93C86 chips.

Fixed: the font is too large in Qt6.

Added: migration to Qt6.

Added: universal Qt5/Qt6 CmakeLists.txt.

Added: specification file for Fedora.

Added: support for the spare area for NAND flash memory.

Fixed: If no chip is selected, the programmer was not detected.

Fixed: MACOS library compatibility.

Fixed: MACOS invalid pathes.

Fixed: libusb detection.

Fixed: udev rules install

Added: 2.5v VCC item

SPI NOR FLASH writing speed increased

Changed chip database update bash script to Qt app

The Zenity package is no longer used

Fixed: Error reading/writing data from I2C chips on the CH347T version 5.44.

Fixed: Bit error during NOR/NAND operations in the CH347V1.1 programmer.

Added: Showing the programmer revision function

Added: Erase check function

Added: Filling code function

Added: Support for the CH347T programmer.

Fixed: Incorrect chip page sizes values removed.

Increased interface speed and SPI NOR Flash erase speed.

SPI NOR Flash write speed increased by 30%.

Fixed: Incorrect HexEdit size when starting the program.

Added: When closing the program, the programmer type, chip image directory, and main window size are saved in the ini file.

Fixed: NAND Flash information form freeze.

Added: Programmer type menu.

Added: New images for CH341A v1.7.

Added: support for the AT24CM02 chip.

Fixed: pressing the Stop key did not stop auto operations.

Added: New feature - support for SPI NAND flash.

Fixed: program crashed if security registers was less than 256 bytes.

Fixed: Information in the status bar disappears when hovering over a menu.

Added: close and minimise buttons for subordinate forms.

Added: comparison of INTEL HEX and ASUS CAP with other files.

Added: new chips to the database.

Fixed: when the page size is changed, the buffer is cleared.

Fixed: the code is executed twice and the code slows down the display of the interface.

Added: New feature - compare files.

Added: New feature - fill test array.

Copyright information updated.

Fixed: incorrect uninstall script.

Fixed: i2C 128K size is repeated twice.

Fixed: error calculating file size.

Added: Last version of QHexEdit used.

Added: Hex-functions optimised.

Added: Added support GIANTEC, DOSILICON NOR FLASH chips.

Fixed: Gigadevice status registers write error.

Fixed: Memory leaks.

Added: New SPI chip sizes added.

Added: New Boya, Winbond chips added to database.

Added: Fidelix, Zetta, MXIC OTP algorithm.

Fixed: Incorrect install dir for udev while cross compiling.

Added: Form for working with security registers for SPI NOR flash memory chips.

Fixed: Incorrect block/page size after first read procedure.

Fixed: Incorrect reading/writing I2C low speed chips.

Added support for MXIC MX25V8035F

Added I2C bus speed combobox to the main form

Fixed: In the Save menu, the cancel button causes an error message.

Fixed: Incorrect names of DataFlash chips.

Fixed: incorrect reading of the DataFlash chips status register.

Fedora repository added

MacOS build support added

Uninstall script added

Fixed: On the GNOME desktop, programm does not respond when erasing SPI NOR FLASH.

Fixed: The progress bar did not display correctly when SPI NOR FLASH was erased.

Fixed: When erasing SPI NOR Flash, the STOP button does not work.

Corrected German translation

German translator added to copyright

Corrected chip database

Added AT45DBxx series SPI FLASH (Menu item type -> 45_EEPROM)

The inline images of the chip adapters have been changed.

Fixed metadata errors and warnings.

Fixed: There is a spelling error in in 99-CH341.rules.

Fixed: (metadata changed): appstream-metadata-missing-modalias-provide usr/lib/udev/rules.d/99-CH341.rules

Splitting long lines in README.md

Removed language .qm files - it is generated when the package is built.

Removed unused tags from language files.

This stable release fixes bugs, updated translations, translate chip database update script.

This stable release fixes bugs, updated translations.

e-ink-reader@yandex.ru
imsprog-1.8.5/IMSProg_programmer/qhexedit.cpp000066400000000000000000001044751520775651600212700ustar00rootroot00000000000000/* * QHexEdit is a Hex Editor Widget for the Qt Framework * Copyright (C) 2010-2025 Winfried Simon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * https://www.gnu.org/licenses/ */ #include #include #include #include #include #include "qhexedit.h" #include // ********************************************************************** Constructor, destructor QHexEdit::QHexEdit(QWidget *parent) : QAbstractScrollArea(parent) , _addressArea(true) , _addressWidth(4) , _asciiArea(true) , _bytesPerLine(16) , _hexCharsInLine(47) , _highlighting(true) , _overwriteMode(true) , _readOnly(false) , _hexCaps(false) , _dynamicBytesPerLine(false) , _editAreaIsAscii(false) , _chunks(new Chunks(this)) , _cursorPosition(0) , _lastEventSize(0) , _undoStack(new UndoStack(_chunks, this)) , _colorManager(new ColorManager()) { #ifdef Q_OS_WIN32 setFont(QFont("Courier", 10)); #else setFont(QFont("Monospace", 10)); #endif connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor())); connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust())); connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust())); connect(_undoStack, SIGNAL(indexChanged(int)), this, SLOT(dataChangedPrivate(int))); _cursorTimer.setInterval(500); _cursorTimer.start(); setAddressWidth(4); setAddressArea(true); setAsciiArea(true); setOverwriteMode(true); setHighlighting(true); setReadOnly(false); init(); } QHexEdit::~QHexEdit() { } // ********************************************************************** Properties void QHexEdit::setAddressArea(bool addressArea) { _addressArea = addressArea; adjust(); setCursorPosition(_cursorPosition); viewport()->update(); } bool QHexEdit::addressArea() { return _addressArea; } void QHexEdit::setAddressOffset(qint64 addressOffset) { _addressOffset = addressOffset; adjust(); setCursorPosition(_cursorPosition); viewport()->update(); } qint64 QHexEdit::addressOffset() { return _addressOffset; } void QHexEdit::setAddressWidth(int addressWidth) { _addressWidth = addressWidth; adjust(); setCursorPosition(_cursorPosition); viewport()->update(); } int QHexEdit::addressWidth() { qint64 size = _chunks->size(); int n = 1; if (size > Q_INT64_C(0x100000000)){ n += 8; size /= Q_INT64_C(0x100000000);} if (size > 0x10000){ n += 4; size /= 0x10000;} if (size > 0x100){ n += 2; size /= 0x100;} if (size > 0x10){ n += 1;} if (n > _addressWidth) return n; else return _addressWidth; } void QHexEdit::setAsciiArea(bool asciiArea) { if (!asciiArea) _editAreaIsAscii = false; _asciiArea = asciiArea; adjust(); setCursorPosition(_cursorPosition); viewport()->update(); } bool QHexEdit::asciiArea() { return _asciiArea; } void QHexEdit::setBytesPerLine(int count) { _bytesPerLine = count; _hexCharsInLine = count * 3 - 1; adjust(); setCursorPosition(_cursorPosition); viewport()->update(); } int QHexEdit::bytesPerLine() { return _bytesPerLine; } void QHexEdit::setCursorPosition(qint64 position) { // 1. delete old cursor _blink = false; viewport()->update(_cursorRect); // 2. Check, if cursor in range? if (position > (_chunks->size() * 2 - 1)) position = _chunks->size() * 2 - (_overwriteMode ? 1 : 0); if (position < 0) position = 0; // 3. Calc new position of cursor _bPosCurrent = position / 2; _pxCursorY = ((position / 2 - _bPosFirst) / _bytesPerLine + 1) * _pxCharHeight; int x = (position % (2 * _bytesPerLine)); if (_editAreaIsAscii) { _pxCursorX = x / 2 * _pxCharWidth + _pxPosAsciiX; _cursorPosition = position & 0xFFFFFFFFFFFFFFFE; } else { _pxCursorX = (((x / 2) * 3) + (x % 2)) * _pxCharWidth + _pxPosHexX; _cursorPosition = position; } int pxOfsX = horizontalScrollBar()->value(); if (_readOnly) _cursorRect = QRect( _pxCursorX - pxOfsX, _pxCursorY - _pxCharHeight + _pxSelectionSub, _pxCharWidth, _pxCharHeight ); else if (_overwriteMode) _cursorRect = QRect( _pxCursorX - pxOfsX, _pxCursorY + _pxCursorWidth, _pxCharWidth, _pxCursorWidth ); else _cursorRect = QRect( _pxCursorX - pxOfsX, _pxCursorY - _pxCharHeight + _pxSelectionSub, _pxCursorWidth, _pxCharHeight ); // 4. Immediately draw new cursor _blink = true; viewport()->update(_cursorRect); emit currentAddressChanged(_bPosCurrent); } qint64 QHexEdit::cursorPosition(QPoint pos) { // Calc cursor position depending on a graphical position qint64 result = -1; int posX = pos.x() + horizontalScrollBar()->value(); int posY = pos.y() - 3; if ((posX >= _pxPosHexX) && (posX < (_pxPosHexX + (1 + _hexCharsInLine) * _pxCharWidth))) { _editAreaIsAscii = false; int x = (posX - _pxPosHexX) / _pxCharWidth; x = (x / 3) * 2 + x % 3; int y = (posY / _pxCharHeight) * 2 * _bytesPerLine; result = _bPosFirst * 2 + x + y; } else if (_asciiArea && (posX >= _pxPosAsciiX) && (posX < (_pxPosAsciiX + (1 + _bytesPerLine) * _pxCharWidth))) { _editAreaIsAscii = true; int x = 2 * (posX - _pxPosAsciiX) / _pxCharWidth; int y = (posY / _pxCharHeight) * 2 * _bytesPerLine; result = _bPosFirst * 2 + x + y; } return result; } qint64 QHexEdit::cursorPosition() { return _cursorPosition; } void QHexEdit::setData(const QByteArray &ba) { _data = ba; _bData.setData(_data); setData(_bData); } QByteArray QHexEdit::data() { return _chunks->data(0, -1); } void QHexEdit::setHighlighting(bool highlighting) { _highlighting = highlighting; viewport()->update(); } bool QHexEdit::highlighting() { return _highlighting; } void QHexEdit::setHighlightingColor(const QColor &color) { _colorManager->highlighting().setAreaColor(color); viewport()->update(); } QColor QHexEdit::highlightingColor() { return _colorManager->highlighting().areaColor(); } void QHexEdit::setOverwriteMode(bool overwriteMode) { _overwriteMode = overwriteMode; emit overwriteModeChanged(overwriteMode); } bool QHexEdit::overwriteMode() { return _overwriteMode; } bool QHexEdit::isReadOnly() { return _readOnly; } void QHexEdit::setReadOnly(bool readOnly) { _readOnly = readOnly; } void QHexEdit::setHexCaps(const bool isCaps) { _hexCaps = isCaps; viewport()->update(); } bool QHexEdit::hexCaps() { return _hexCaps; } void QHexEdit::setDynamicBytesPerLine(const bool isDynamic) { _dynamicBytesPerLine = isDynamic; resizeEvent(NULL); } bool QHexEdit::dynamicBytesPerLine() { return _dynamicBytesPerLine; } // ********************************************************************** Access to data of qhexedit bool QHexEdit::setData(QIODevice &iODevice) { bool ok = _chunks->setIODevice(iODevice); init(); return ok; } QByteArray QHexEdit::dataAt(qint64 pos, qint64 count) { return _chunks->data(pos, count); } bool QHexEdit::write(QIODevice &iODevice, qint64 pos, qint64 count) { return _chunks->write(iODevice, pos, count); } // ********************************************************************** Char handling void QHexEdit::insert(qint64 index, char ch) { _undoStack->insert(index, ch); refresh(); } void QHexEdit::remove(qint64 index, qint64 len) { _undoStack->removeAt(index, len); refresh(); } void QHexEdit::replace(qint64 index, char ch) { _undoStack->overwrite(index, ch); refresh(); } // ********************************************************************** ByteArray handling void QHexEdit::insert(qint64 pos, const QByteArray &ba) { _undoStack->insert(pos, ba); refresh(); } void QHexEdit::replace(qint64 pos, qint64 len, const QByteArray &ba) { _undoStack->overwrite(pos, len, ba); refresh(); } // ********************************************************************** User marking areas void QHexEdit::addUserArea(qint64 posStart, qint64 posEnd, QColor fontColor, QBrush areaStyle) { _colorManager->addUserArea(posStart, posEnd, fontColor, areaStyle); refresh(); } void QHexEdit::clearUserAreas() { _colorManager->clearUserAreas(); refresh(); } // ********************************************************************** Utility functions void QHexEdit::ensureVisible() { if (_cursorPosition < (_bPosFirst * 2)) verticalScrollBar()->setValue((int)(_cursorPosition / 2 / _bytesPerLine)); if (_cursorPosition > ((_bPosFirst + (_rowsShown - 1)*_bytesPerLine) * 2)) verticalScrollBar()->setValue((int)(_cursorPosition / 2 / _bytesPerLine) - _rowsShown + 1); if (_pxCursorX < horizontalScrollBar()->value()) horizontalScrollBar()->setValue(_pxCursorX); if ((_pxCursorX + _pxCharWidth) > (horizontalScrollBar()->value() + viewport()->width())) horizontalScrollBar()->setValue(_pxCursorX + _pxCharWidth - viewport()->width()); viewport()->update(); } qint64 QHexEdit::indexOf(const QByteArray &ba, qint64 from) { qint64 pos = _chunks->indexOf(ba, from); if (pos > -1) { qint64 curPos = pos*2; setCursorPosition(curPos + ba.length()*2); resetSelection(curPos); setSelection(curPos + ba.length()*2); ensureVisible(); } return pos; } bool QHexEdit::isModified() { return _modified; } qint64 QHexEdit::lastIndexOf(const QByteArray &ba, qint64 from) { qint64 pos = _chunks->lastIndexOf(ba, from); if (pos > -1) { qint64 curPos = pos*2; setCursorPosition(curPos - 1); resetSelection(curPos); setSelection(curPos + ba.length()*2); ensureVisible(); } return pos; } void QHexEdit::redo() { _undoStack->redo(); setCursorPosition(_chunks->pos()*(_editAreaIsAscii ? 1 : 2)); refresh(); } QString QHexEdit::selectionToReadableString() { QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); return toReadable(ba); } QString QHexEdit::selectedData() { QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); return ba; } void QHexEdit::setFont(const QFont &font) { QFont theFont(font); theFont.setStyleHint(QFont::Monospace); QWidget::setFont(theFont); QFontMetrics metrics = fontMetrics(); #if QT_VERSION > QT_VERSION_CHECK(5, 11, 0) _pxCharWidth = metrics.horizontalAdvance(QLatin1Char('2')); #else _pxCharWidth = metrics.width(QLatin1Char('2')); #endif _pxCharHeight = metrics.height(); _pxAreaMargin = _pxCharWidth / 2; _pxCursorWidth = _pxCharHeight / 7; _pxSelectionSub = _pxCharHeight / 5; viewport()->update(); } QString QHexEdit::toReadableString() { QByteArray ba = _chunks->data(); return toReadable(ba); } void QHexEdit::undo() { _undoStack->undo(); setCursorPosition(_chunks->pos()*(_editAreaIsAscii ? 1 : 2)); refresh(); } // ********************************************************************** Handle events void QHexEdit::keyPressEvent(QKeyEvent *event) { // Cursor movements if (event->matches(QKeySequence::MoveToNextChar)) { qint64 pos = _cursorPosition + 1; if (_editAreaIsAscii) pos += 1; setCursorPosition(pos); resetSelection(pos); } if (event->matches(QKeySequence::MoveToPreviousChar)) { qint64 pos = _cursorPosition - 1; if (_editAreaIsAscii) pos -= 1; setCursorPosition(pos); resetSelection(pos); } if (event->matches(QKeySequence::MoveToEndOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * _bytesPerLine)) + (2 * _bytesPerLine) - 1; setCursorPosition(pos); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToStartOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * _bytesPerLine)); setCursorPosition(pos); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousLine)) { setCursorPosition(_cursorPosition - (2 * _bytesPerLine)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToNextLine)) { setCursorPosition(_cursorPosition + (2 * _bytesPerLine)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToNextPage)) { setCursorPosition(_cursorPosition + (((_rowsShown - 1) * 2 * _bytesPerLine))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousPage)) { setCursorPosition(_cursorPosition - (((_rowsShown - 1) * 2 * _bytesPerLine))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToEndOfDocument)) { setCursorPosition(_chunks->size() * 2 ); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToStartOfDocument)) { setCursorPosition(0); resetSelection(_cursorPosition); } // Select commands if (event->matches(QKeySequence::SelectAll)) { resetSelection(0); setSelection(2 * _chunks->size() + 1); } if (event->matches(QKeySequence::SelectNextChar)) { qint64 pos = _cursorPosition + 1; if (_editAreaIsAscii) pos += 1; setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousChar)) { qint64 pos = _cursorPosition - 1; if (_editAreaIsAscii) pos -= 1; setSelection(pos); setCursorPosition(pos); } if (event->matches(QKeySequence::SelectEndOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * _bytesPerLine)) + (2 * _bytesPerLine) - 1; setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectStartOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * _bytesPerLine)); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousLine)) { qint64 pos = _cursorPosition - (2 * _bytesPerLine); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectNextLine)) { qint64 pos = _cursorPosition + (2 * _bytesPerLine); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectNextPage)) { qint64 pos = _cursorPosition + (((viewport()->height() / _pxCharHeight) - 1) * 2 * _bytesPerLine); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousPage)) { qint64 pos = _cursorPosition - (((viewport()->height() / _pxCharHeight) - 1) * 2 * _bytesPerLine); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectEndOfDocument)) { qint64 pos = _chunks->size() * 2; setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectStartOfDocument)) { qint64 pos = 0; setCursorPosition(pos); setSelection(pos); } // Edit Commands if (!_readOnly) { /* Cut */ if (event->matches(QKeySequence::Cut)) { QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); for (qint64 idx = 32; idx < ba.size(); idx +=33) ba.insert(idx, "\n"); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(ba); if (_overwriteMode) { qint64 len = getSelectionEnd() - getSelectionBegin(); replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0))); } else { remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); } setCursorPosition(2 * getSelectionBegin()); resetSelection(2 * getSelectionBegin()); } else /* Paste */ if (event->matches(QKeySequence::Paste)) { QClipboard *clipboard = QApplication::clipboard(); QByteArray ba = QByteArray().fromHex(clipboard->text().toLatin1()); if (_overwriteMode) { ba = ba.left(std::min(ba.size(), (_chunks->size() - _bPosCurrent))); replace(_bPosCurrent, ba.size(), ba); } else insert(_bPosCurrent, ba); setCursorPosition(_cursorPosition + 2 * ba.size()); resetSelection(getSelectionBegin()); } else /* Delete char */ if (event->matches(QKeySequence::Delete)) { if (getSelectionBegin() != getSelectionEnd()) { _bPosCurrent = getSelectionBegin(); if (_overwriteMode) { QByteArray ba = QByteArray(getSelectionEnd() - getSelectionBegin(), char(0)); replace(_bPosCurrent, ba.size(), ba); } else { remove(_bPosCurrent, getSelectionEnd() - getSelectionBegin()); } } else { if (_overwriteMode) replace(_bPosCurrent, char(0)); else remove(_bPosCurrent, 1); } setCursorPosition(2 * _bPosCurrent); resetSelection(2 * _bPosCurrent); } else /* Backspace */ if ((event->key() == Qt::Key_Backspace) && (event->modifiers() == Qt::NoModifier)) { if (getSelectionBegin() != getSelectionEnd()) { _bPosCurrent = getSelectionBegin(); setCursorPosition(2 * _bPosCurrent); if (_overwriteMode) { QByteArray ba = QByteArray(getSelectionEnd() - getSelectionBegin(), char(0)); replace(_bPosCurrent, ba.size(), ba); } else { remove(_bPosCurrent, getSelectionEnd() - getSelectionBegin()); } resetSelection(2 * _bPosCurrent); } else { bool behindLastByte = false; if ((_cursorPosition / 2) == _chunks->size()) behindLastByte = true; _bPosCurrent -= 1; if (_overwriteMode) replace(_bPosCurrent, char(0)); else remove(_bPosCurrent, 1); if (!behindLastByte) _bPosCurrent -= 1; setCursorPosition(2 * _bPosCurrent); resetSelection(2 * _bPosCurrent); } } else /* undo */ if (event->matches(QKeySequence::Undo)) { undo(); } else /* redo */ if (event->matches(QKeySequence::Redo)) { redo(); } else if ((QApplication::keyboardModifiers() == Qt::NoModifier) || (QApplication::keyboardModifiers() == Qt::KeypadModifier) || (QApplication::keyboardModifiers() == Qt::ShiftModifier) || (QApplication::keyboardModifiers() == (Qt::AltModifier | Qt::ControlModifier)) || (QApplication::keyboardModifiers() == Qt::GroupSwitchModifier)) { /* Hex and ascii input */ int key = 0; QString text = event->text(); if (!text.isEmpty()) { if (_editAreaIsAscii) key = (uchar)text.at(0).toLatin1(); else key = int(text.at(0).toLower().toLatin1()); } if ((((key >= '0' && key <= '9') || (key >= 'a' && key <= 'f')) && _editAreaIsAscii == false) || (key >= ' ' && _editAreaIsAscii)) { if (getSelectionBegin() != getSelectionEnd()) { if (_overwriteMode) { qint64 len = getSelectionEnd() - getSelectionBegin(); replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0))); } else { remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); _bPosCurrent = getSelectionBegin(); } setCursorPosition(2 * _bPosCurrent); resetSelection(2 * _bPosCurrent); } // If insert mode, then insert a byte if (_overwriteMode == false) if ((_cursorPosition % 2) == 0) insert(_bPosCurrent, char(0)); // Change content if (_chunks->size() > 0) { char ch = key; if (!_editAreaIsAscii){ QByteArray hexValue = _chunks->data(_bPosCurrent, 1).toHex(); if ((_cursorPosition % 2) == 0) hexValue[0] = key; else hexValue[1] = key; ch = QByteArray().fromHex(hexValue)[0]; } replace(_bPosCurrent, ch); if (_editAreaIsAscii) setCursorPosition(_cursorPosition + 2); else setCursorPosition(_cursorPosition + 1); resetSelection(_cursorPosition); } } } } /* Copy */ if (event->matches(QKeySequence::Copy)) { QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); for (qint64 idx = 32; idx < ba.size(); idx +=33) ba.insert(idx, "\n"); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(ba); } // Switch between insert/overwrite mode if ((event->key() == Qt::Key_Insert) && (event->modifiers() == Qt::NoModifier)) { setOverwriteMode(!overwriteMode()); setCursorPosition(_cursorPosition); } // switch from hex to ascii edit if (event->key() == Qt::Key_Tab && !_editAreaIsAscii){ _editAreaIsAscii = true; setCursorPosition(_cursorPosition); } // switch from ascii to hex edit if (event->key() == Qt::Key_Backtab && _editAreaIsAscii){ _editAreaIsAscii = false; setCursorPosition(_cursorPosition); } refresh(); } void QHexEdit::mouseMoveEvent(QMouseEvent * event) { _blink = false; viewport()->update(); qint64 actPos = cursorPosition(event->pos()); if (actPos >= 0) { setCursorPosition(actPos); setSelection(actPos); } } void QHexEdit::mousePressEvent(QMouseEvent * event) { _blink = false; viewport()->update(); qint64 cPos = cursorPosition(event->pos()); if (cPos >= 0) { if (event->button() != Qt::RightButton) resetSelection(cPos); setCursorPosition(cPos); } } void QHexEdit::paintEvent(QPaintEvent *event) { QPainter painter(viewport()); int pxOfsX = horizontalScrollBar()->value(); int pxPosAsciiX2 = _pxPosAsciiX - pxOfsX; if (event->rect() != _cursorRect) { int pxPosStartY = _pxCharHeight; // *** prepare background painter.fillRect( event->rect(), viewport()->palette().color(QPalette::Base) ); if (_addressArea) painter.fillRect( QRect( -pxOfsX, event->rect().top(), _pxCharWidth * (_addrDigits + 1), height() ), _colorManager->notMarked(Area::Address).areaStyle() ); if (_asciiArea) { painter.fillRect( QRect( pxPosAsciiX2 - _pxAreaMargin, event->rect().top(), _pxCharWidth * _bytesPerLine + 2 * _pxAreaMargin, height() ), _colorManager->notMarked(Area::Ascii).areaStyle() ); } // *** paint central areas for (int row = 0, pxPosY = pxPosStartY; row <= _rowsShown; row++, pxPosY +=_pxCharHeight) { QByteArray hex; qint64 bPosLine = row * _bytesPerLine; int pxPosX = _pxPosHexX - pxOfsX; int pxPosAsciiX2 = _pxPosAsciiX - pxOfsX; // *** address info if (_addressArea && row * _bytesPerLine < _dataShown.size()) { QString address = QString("%1").arg(_bPosFirst + row*_bytesPerLine + _addressOffset, _addrDigits, 16, QChar('0')); ColoredArea addressArea = _colorManager->notMarked(Area::Address); painter.setPen(addressArea.fontPen()); painter.drawText(_pxPosAdrX - pxOfsX, pxPosY, hexCaps() ? address.toUpper() : address); } for (int colIdx = 0; ((bPosLine + colIdx) < _dataShown.size() && (colIdx < _bytesPerLine)); colIdx++) { qint64 posBa = _bPosFirst + bPosLine + colIdx; // *** hex values ColoredArea hexArea = _colorManager->markedArea(posBa, Area::Hex, _chunks); painter.setPen(hexArea.fontPen()); QRect rect; if (colIdx == 0) rect = QRect( pxPosX, pxPosY - _pxCharHeight + _pxSelectionSub, 2*_pxCharWidth, _pxCharHeight ); else rect = QRect( pxPosX - _pxCharWidth, pxPosY - _pxCharHeight + _pxSelectionSub, 3*_pxCharWidth, _pxCharHeight ); painter.fillRect(rect, hexArea.areaStyle()); hex = _hexDataShown.mid((bPosLine + colIdx) * 2, 2); painter.drawText(pxPosX, pxPosY, hexCaps()?hex.toUpper():hex); pxPosX += 3*_pxCharWidth; // *** ascii values if (_asciiArea) { ColoredArea asciiArea = _colorManager->markedArea(posBa, Area::Ascii, _chunks); painter.setPen(asciiArea.fontPen()); int ch = (uchar)_dataShown.at(bPosLine + colIdx); if ( ch < ' ' || ch > '~' ) ch = '.'; rect.setRect(pxPosAsciiX2, pxPosY - _pxCharHeight + _pxSelectionSub, _pxCharWidth, _pxCharHeight); painter.fillRect(rect, asciiArea.areaStyle()); painter.drawText(pxPosAsciiX2, pxPosY, QChar(ch)); pxPosAsciiX2 += _pxCharWidth; } } } } // *** paint cursor, _cursorPosition counts in 2, _bPosFirst counts in 1 int hexPos = _cursorPosition - 2 * _bPosFirst; // due to scrolling the cursor can go out of the currently displayed data if ((hexPos >= 0) && (hexPos <= _hexDataShown.size())) { ColoredArea curArea; if (_editAreaIsAscii) curArea = _colorManager->markedArea(hexPos / 2, Area::Ascii, _chunks); else curArea = _colorManager->markedArea(hexPos / 2, Area::Hex, _chunks); if (_blink && hasFocus()) { if (_readOnly) painter.fillRect(_cursorRect, curArea.fontColor()); else painter.fillRect(_cursorRect, curArea.fontColor()); } // We have to repaint the current char because the curser destroys the char painter.setPen(curArea.fontColor()); if (_editAreaIsAscii) { // every 2 hex there is 1 ascii int ch = (uchar)_dataShown.at(hexPos / 2); if (ch < ' ' || ch > '~') ch = '.'; painter.drawText(_pxCursorX - pxOfsX, _pxCursorY, QChar(ch)); } else { QByteArray txt = _hexDataShown.mid(hexPos, 1); if (_hexCaps) txt = txt.toUpper(); painter.drawText(_pxCursorX - pxOfsX, _pxCursorY, txt); } } // *** emit event, if size has changed if (_lastEventSize != _chunks->size()) { _lastEventSize = _chunks->size(); emit currentSizeChanged(_lastEventSize); } } void QHexEdit::resizeEvent(QResizeEvent *) { if (_dynamicBytesPerLine) { int pxFixGaps = 0; if (_addressArea) pxFixGaps = addressWidth() * _pxCharWidth + 2 * _pxAreaMargin; pxFixGaps += 2 * _pxAreaMargin; if (_asciiArea) pxFixGaps += 2 * _pxAreaMargin; // +1 because the last hex value do not have space. so it is effective one char more int charWidth = (viewport()->width() - pxFixGaps ) / _pxCharWidth + 1; // 2 hex alfa-digits 1 space 1 ascii per byte = 4; if ascii is disabled then 3 // to prevent devision by zero use the min value 1 setBytesPerLine(std::max(charWidth / (_asciiArea ? 4 : 3), 1)); } adjust(); } bool QHexEdit::focusNextPrevChild(bool next) { if (_addressArea) { if ( (next && _editAreaIsAscii) || (!next && !_editAreaIsAscii )) return QWidget::focusNextPrevChild(next); else return false; } else { return QWidget::focusNextPrevChild(next); } } // ********************************************************************** Handle selections void QHexEdit::resetSelection() { _bSelectionBegin = 0; _bSelectionEnd = 0; _colorManager->selection().setRange(_bSelectionBegin, _bSelectionEnd); } void QHexEdit::resetSelection(qint64 pos) { pos = pos / 2 ; if (pos < 0) pos = 0; if (pos > _chunks->size()) pos = _chunks->size(); _bSelectionBegin = pos; _bSelectionEnd = pos; _colorManager->selection().setRange(_bSelectionBegin, _bSelectionEnd); } void QHexEdit::setSelection(qint64 pos) { pos = pos / 2; if (pos < 0) pos = 0; if (pos > _chunks->size()) pos = _chunks->size(); if (pos > _bSelectionBegin) { _bSelectionEnd = pos; } else { _bSelectionBegin = pos; } _colorManager->selection().setRange(_bSelectionBegin, _bSelectionEnd); } qint64 QHexEdit::getSelectionBegin() { return _bSelectionBegin; } qint64 QHexEdit::getSelectionEnd() { return _bSelectionEnd; } // ********************************************************************** Private utility functions bool QHexEdit::event(QEvent *event) { if (event->type() == QEvent::QEvent::PaletteChange) { QPalette palette = this->palette(); _colorManager->setPalette(palette); } return QAbstractScrollArea::event(event); } void QHexEdit::init() { _undoStack->clear(); setAddressOffset(0); resetSelection(0); setCursorPosition(0); verticalScrollBar()->setValue(0); _modified = false; } void QHexEdit::adjust() { // recalc Graphics if (_addressArea) { _addrDigits = addressWidth(); _pxPosHexX = _pxAreaMargin + _addrDigits*_pxCharWidth + 2 * _pxAreaMargin; } else _pxPosHexX = _pxAreaMargin; _pxPosAdrX = _pxAreaMargin; _pxPosAsciiX = _pxPosHexX + _hexCharsInLine * _pxCharWidth + 2 * _pxAreaMargin; // set horizontalScrollBar() int pxWidth = _pxPosAsciiX; if (_asciiArea) pxWidth += _bytesPerLine*_pxCharWidth; horizontalScrollBar()->setRange(0, pxWidth - viewport()->width()); horizontalScrollBar()->setPageStep(viewport()->width()); // set verticalScrollbar() _rowsShown = ((viewport()->height()-4)/_pxCharHeight); int lineCount = (int)(_chunks->size() / (qint64)_bytesPerLine) + 1; verticalScrollBar()->setRange(0, lineCount - _rowsShown); verticalScrollBar()->setPageStep(_rowsShown); int value = verticalScrollBar()->value(); _bPosFirst = (qint64)value * _bytesPerLine; _bPosLast = _bPosFirst + (qint64)(_rowsShown * _bytesPerLine) - 1; if (_bPosLast >= _chunks->size()) _bPosLast = _chunks->size() - 1; readBuffers(); setCursorPosition(_cursorPosition); } void QHexEdit::dataChangedPrivate(int) { _modified = _undoStack->index() != 0; adjust(); emit dataChanged(); } void QHexEdit::refresh() { ensureVisible(); readBuffers(); } void QHexEdit::readBuffers() { _dataShown = _chunks->data(_bPosFirst, _bPosLast - _bPosFirst + _bytesPerLine + 1, &_markedShown); _hexDataShown = QByteArray(_dataShown.toHex()); } QString QHexEdit::toReadable(const QByteArray &ba) { QString result; for (int i=0; i < ba.size(); i += 16) { QString addrStr = QString("%1").arg(_addressOffset + i, addressWidth(), 16, QChar('0')); QString hexStr; QString ascStr; for (int j=0; j<16; j++) { if ((i + j) < ba.size()) { hexStr.append(" ").append(ba.mid(i+j, 1).toHex()); char ch = ba[i + j]; if ((ch < 0x20) || (ch > 0x7e)) ch = '.'; ascStr.append(QChar(ch)); } } result += addrStr + " " + QString("%1").arg(hexStr, -48) + " " + QString("%1").arg(ascStr, -17) + "\n"; } return result; } void QHexEdit::updateCursor() { if (_blink) _blink = false; else _blink = true; viewport()->update(_cursorRect); } imsprog-1.8.5/IMSProg_programmer/qhexedit.h000066400000000000000000000402771520775651600207340ustar00rootroot00000000000000/* * QHexEdit is a Hex Editor Widget for the Qt Framework * Copyright (C) 2010-2025 Winfried Simon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * https://www.gnu.org/licenses/ */ #ifndef QHEXEDIT_H #define QHEXEDIT_H #include #include #include #include "chunks.h" #include "commands.h" #include "color_manager.h" #ifdef QHEXEDIT_EXPORTS #define QHEXEDIT_API Q_DECL_EXPORT #elif QHEXEDIT_IMPORTS #define QHEXEDIT_API Q_DECL_IMPORT #else #define QHEXEDIT_API #endif /** \mainpage QHexEdit is a binary editor widget for Qt. \version Version 0.9.0 \image html qhexedit.png */ /** QHexEdit is a hex editor widget written in C++ for the Qt (Qt4, Qt5) framework. It is a simple editor for binary data, just like QPlainTextEdit is for text data. There are sip configuration files included, so it is easy to create bindings for PyQt and you can use this widget also in python 2 and 3. QHexEdit takes the data of a QByteArray (setData()) and shows it. You can use the mouse or the keyboard to navigate inside the widget. If you hit the keys (0..9, a..f) you will change the data. Changed data is highlighted and can be accessed via data(). Normally QHexEdit works in the overwrite mode. You can set overwrite mode(false) and insert data. In this case the size of data() increases. It is also possible to delete bytes (del or backspace), here the size of data decreases. You can select data with keyboard hits or mouse movements. The copy-key will copy the selected data into the clipboard. The cut-key copies also but deletes it afterwards. In overwrite mode, the paste function overwrites the content of the (does not change the length) data. In insert mode, clipboard data will be inserted. The clipboard content is expected in ASCII Hex notation. Unknown characters will be ignored. QHexEdit comes with undo/redo functionality. All changes can be undone, by pressing the undo-key (usually ctr-z). They can also be redone afterwards. The undo/redo framework is cleared, when setData() sets up a new content for the editor. You can search data inside the content with indexOf() and lastIndexOf(). The replace() function is to change located subdata. This 'replaced' data can also be undone by the undo/redo framework. QHexEdit is based on QIODevice, that's why QHexEdit can handle big amounts of data. The size of edited data can be more then two gigabytes without any restrictions. */ class QHEXEDIT_API QHexEdit : public QAbstractScrollArea { Q_OBJECT /*! Property address area switch the address area on or off. Set addressArea true (show it), false (hide it). */ Q_PROPERTY(bool addressArea READ addressArea WRITE setAddressArea) /*! Property addressOffset is added to the Numbers of the Address Area. A offset in the address area (left side) is sometimes useful, whe you show only a segment of a complete memory picture. With setAddressOffset() you set this property - with addressOffset() you get the current value. */ Q_PROPERTY(qint64 addressOffset READ addressOffset WRITE setAddressOffset) /*! Set and get the minimum width of the address area, width in characters. */ Q_PROPERTY(int addressWidth READ addressWidth WRITE setAddressWidth) /*! Switch the ascii area on (true, show it) or off (false, hide it). */ Q_PROPERTY(bool asciiArea READ asciiArea WRITE setAsciiArea) /*! Set and get bytes number per line.*/ Q_PROPERTY(int bytesPerLine READ bytesPerLine WRITE setBytesPerLine) /*! Property cursorPosition sets or gets the position of the editor cursor in QHexEdit. Every byte in data has two cursor positions: the lower and upper Nibble. Maximum cursor position is factor two of data.size(). */ Q_PROPERTY(qint64 cursorPosition READ cursorPosition WRITE setCursorPosition) /*! Property data holds the content of QHexEdit. Call setData() to set the content of QHexEdit, data() returns the actual content. When calling setData() with a QByteArray as argument, QHexEdit creates a internal copy of the data If you want to edit big files please use setData(), based on QIODevice. */ Q_PROPERTY(QByteArray data READ data WRITE setData NOTIFY dataChanged) /*! That property defines if the hex values looks as a-f if the value is false(default) or A-F if value is true. */ Q_PROPERTY(bool hexCaps READ hexCaps WRITE setHexCaps) /*! Property defines the dynamic calculation of bytesPerLine parameter depends of width of widget. set this property true to avoid horizontal scrollbars and show the maximal possible data. defalut value is false*/ Q_PROPERTY(bool dynamicBytesPerLine READ dynamicBytesPerLine WRITE setDynamicBytesPerLine) /*! Switch the highlighting feature on or of: true (show it), false (hide it). */ Q_PROPERTY(bool highlighting READ highlighting WRITE setHighlighting) /*! Property highlighting color sets (setHighlightingColor()) the background color of highlighted text areas. You can also read the color (highlightingColor()). */ Q_PROPERTY(QColor highlightingColor READ highlightingColor WRITE setHighlightingColor) /*! Property overwrite mode sets (setOverwriteMode()) or gets (overwriteMode()) the mode in which the editor works. In overwrite mode the user will overwrite existing data. The size of data will be constant. In insert mode the size will grow, when inserting new data. */ Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode) /*! Property readOnly sets (setReadOnly()) or gets (isReadOnly) the mode in which the editor works. In readonly mode the the user can only navigate through the data and select data; modifying is not possible. This property's default is false. */ Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) /*! Set the font of the widget. Please use fixed width fonts like Mono or Courier.*/ Q_PROPERTY(QFont font READ font WRITE setFont) public: /*! Creates an instance of QHexEdit. \param parent Parent widget of QHexEdit. */ QHexEdit(QWidget *parent=NULL); // Access to data of qhexedit /*! Sets the data of QHexEdit. The QIODevice will be opened just before reading and closed immediately afterwards. This is to allow other programs to rewrite the file while editing it. */ bool setData(QIODevice &iODevice); /*! Gives back the data as a QByteArray starting at position \param pos and delivering \param count bytes. */ QByteArray dataAt(qint64 pos, qint64 count=-1); /*! Gives back the data into a \param iODevice starting at position \param pos and delivering \param count bytes. */ bool write(QIODevice &iODevice, qint64 pos=0, qint64 count=-1); // Char handling /*! Inserts a char. \param pos Index position, where to insert \param ch Char, which is to insert The char will be inserted and size of data grows. */ void insert(qint64 pos, char ch); /*! Removes len bytes from the content. \param pos Index position, where to remove \param len Amount of bytes to remove */ void remove(qint64 pos, qint64 len=1); /*! Replaces a char. \param pos Index position, where to overwrite \param ch Char, which is to insert The char will be overwritten and size remains constant. */ void replace(qint64 pos, char ch); // ByteArray handling /*! Inserts a byte array. \param pos Index position, where to insert \param ba QByteArray, which is to insert The QByteArray will be inserted and size of data grows. */ void insert(qint64 pos, const QByteArray &ba); /*! Replaces len bytes with a byte array ba \param pos Index position, where to overwrite \param ba QByteArray, which is inserted \param len count of bytes to overwrite The data is overwritten and size of data may change. */ void replace(qint64 pos, qint64 len, const QByteArray &ba); // User marking areas /*! Adds a user defined marking area \param posStart Index position, where the area starts (including) \param posEnd Index position where the area ends (exluding) \param fontColor Color of the font used in user marking area \param areaStyle Color of the background in user marking area There is no limit to the number of user areas. The areas are prioritized in the event of overlaps. The areas defined first have priority over areas that follow later. */ void addUserArea(qint64 posStart, qint64 posEnd, QColor fontColor, QBrush areaStyle); /*! Delets all user defined areas */ void clearUserAreas(); // Utility functions /*! Calc cursor position from graphics position * \param point from where the cursor position should be calculated * \return Cursor position */ qint64 cursorPosition(QPoint point); /*! Ensure the cursor to be visbile */ void ensureVisible(); /*! Find first occurrence of ba in QHexEdit data * \param ba Data to find * \param from Point where the search starts * \return pos if fond, else -1 */ qint64 indexOf(const QByteArray &ba, qint64 from); /*! Returns if any changes where done on document * \return true when document is modified else false */ bool isModified(); /*! Find last occurrence of ba in QHexEdit data * \param ba Data to find * \param from Point where the search starts * \return pos if fond, else -1 */ qint64 lastIndexOf(const QByteArray &ba, qint64 from); /*! Gives back a formatted image of the selected content of QHexEdit */ QString selectionToReadableString(); /*! Return the selected content of QHexEdit as QByteArray */ QString selectedData(); /*! Set Font of QHexEdit * \param font */ void setFont(const QFont &font); /*! Gives back a formatted image of the content of QHexEdit */ QString toReadableString(); public slots: /*! Redoes the last operation. If there is no operation to redo, i.e. there is no redo step in the undo/redo history, nothing happens. */ void redo(); /*! Undoes the last operation. If there is no operation to undo, i.e. there is no undo step in the undo/redo history, nothing happens. */ void undo(); signals: /*! Contains the address, where the cursor is located. */ void currentAddressChanged(qint64 address); /*! Contains the size of the data to edit. */ void currentSizeChanged(qint64 size); /*! The signal is emitted every time, the data is changed. */ void dataChanged(); /*! The signal is emitted every time, the overwrite mode is changed. */ void overwriteModeChanged(bool state); /*! \cond docNever */ public: ~QHexEdit(); // Properties bool addressArea(); void setAddressArea(bool addressArea); qint64 addressOffset(); void setAddressOffset(qint64 addressArea); int addressWidth(); void setAddressWidth(int addressWidth); bool asciiArea(); void setAsciiArea(bool asciiArea); int bytesPerLine(); void setBytesPerLine(int count); qint64 cursorPosition(); void setCursorPosition(qint64 position); QByteArray data(); void setData(const QByteArray &ba); void setHexCaps(const bool isCaps); bool hexCaps(); void setDynamicBytesPerLine(const bool isDynamic); bool dynamicBytesPerLine(); bool highlighting(); void setHighlighting(bool mode); QColor highlightingColor(); void setHighlightingColor(const QColor &color); bool overwriteMode(); void setOverwriteMode(bool overwriteMode); bool isReadOnly(); void setReadOnly(bool readOnly); qint64 _bPosFirst; // position of first byte shown qint64 _bPosLast; // position of last byte shown qint64 _bPosCurrent; // current position protected: // Handle events bool event(QEvent *event); void keyPressEvent(QKeyEvent *event); void mouseMoveEvent(QMouseEvent * event); void mousePressEvent(QMouseEvent * event); void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *); virtual bool focusNextPrevChild(bool next); private: // Handle selections void resetSelection(qint64 pos); // set selectionStart and selectionEnd to pos void resetSelection(); // set selectionEnd to selectionStart void setSelection(qint64 pos); // set min (if below init) or max (if greater init) qint64 getSelectionBegin(); qint64 getSelectionEnd(); // Private utility functions void init(); void readBuffers(); QString toReadable(const QByteArray &ba); private slots: void adjust(); // recalc pixel positions void dataChangedPrivate(int idx=0); // emit dataChanged() signal void refresh(); // ensureVisible() and readBuffers() void updateCursor(); // update blinking cursor private: // Name convention: pixel positions start with _px int _pxCharWidth, _pxCharHeight; // char dimensions (dependend on font) int _pxPosHexX; // X-Pos of HeaxArea int _pxPosAdrX; // X-Pos of Address Area int _pxPosAsciiX; // X-Pos of Ascii Area int _pxAreaMargin; // gap left and right from areas int _pxCursorWidth; // cursor width int _pxSelectionSub; // offset selection rect int _pxCursorX; // current cursor pos int _pxCursorY; // current cursor pos // Name convention: absolute byte positions in chunks start with _b qint64 _bSelectionBegin; // first position of Selection qint64 _bSelectionEnd; // end of Selection // variables to store the property values bool _addressArea; // left area of QHexEdit int _addressWidth; bool _asciiArea; qint64 _addressOffset; int _bytesPerLine; int _hexCharsInLine; bool _highlighting; bool _overwriteMode; bool _readOnly; bool _hexCaps; bool _dynamicBytesPerLine; // other variables bool _editAreaIsAscii; // flag about the ascii mode edited int _addrDigits; // real no of addressdigits, may be > addressWidth bool _blink; // help get cursor blinking QBuffer _bData; // buffer, when setup with QByteArray Chunks *_chunks; // IODevice based access to data QTimer _cursorTimer; // for blinking cursor qint64 _cursorPosition; // absolute position of cursor, 1 Byte == 2 tics QRect _cursorRect; // physical dimensions of cursor QByteArray _data; // QHexEdit's data, when setup with QByteArray QByteArray _dataShown; // data in the current View QByteArray _hexDataShown; // data in view, transformed to hex qint64 _lastEventSize; // size, which was emitted last time QByteArray _markedShown; // marked data in view bool _modified; // Is any data in editor modified? int _rowsShown; // lines of text shown UndoStack * _undoStack; // stack to store edit actions for undo/redo ColorManager * _colorManager; // holds highlighting, selection and other area colors /*! \endcond docNever */ }; #endif // QHEXEDIT_H imsprog-1.8.5/IMSProg_programmer/qhexedit.sip000066400000000000000000000042241520775651600212700ustar00rootroot00000000000000%Module(name=qhexedit) %Import QtCore/QtCoremod.sip %Import QtGui/QtGuimod.sip %If (Qt_5_0_0 -) %Import QtWidgets/QtWidgetsmod.sip %End class QHexEdit : QAbstractScrollArea { %TypeHeaderCode #include "../src/qhexedit.h" %End public: explicit QHexEdit(QWidget *parent /TransferThis/ = 0); virtual ~QHexEdit(); bool setData(QIODevice &); QByteArray dataAt(qint64, qint64=-1); bool write(QIODevice &iODevice, qint64=0, qint64=-1); void insert(qint64, char); void remove(qint64, qint64); void replace(qint64, char); void insert(qint64, QByteArray &); void replace(qint64, qint64, QByteArray &); bool addressArea(); bool addressWidth(); bool asciiArea(); qint64 cursorPosition(QPoint); void ensureVisible(); qint64 indexOf(QByteArray &, qint64); bool isModified(); bool highlighting(); qint64 lastIndexOf(QByteArray &, qint64); QString selectionToReadableString(); QString selectedData(); void setFont(const QFont &); QString toReadableString(); QColor addressAreaColor(); void setAddressAreaColor(const QColor &); QColor addressFontColor(); void setAddressFontColor(const QColor &); QColor asciiAreaColor(); void setAsciiAreaColor(const QColor &); QColor asciiFontColor(); void setAsciiFontColor(const QColor &); QColor hexFontColor(); void setHexFontColor(const QColor &); qint64 addressOffset(); void setAddressOffset(qint64); qint64 cursorPosition(); void setCursorPosition(qint64); QByteArray data(); void setData(const QByteArray &); QColor highlightingColor(); void setHighlightingColor(const QColor &); bool overwriteMode(); void setOverwriteMode(bool); bool isReadOnly(); void setReadOnly(bool); QColor selectionColor(); void setSelectionColor(const QColor &); public slots: void redo(); void setAddressArea(bool); void setAddressWidth(int); void setAsciiArea(bool); void setHighlighting(bool); void undo(); signals: void currentAddressChanged(qint64); void currentSizeChanged(qint64); void dataChanged(); void overwriteModeChanged(bool); }; imsprog-1.8.5/IMSProg_programmer/recource.qrc000066400000000000000000000047061520775651600212630ustar00rootroot00000000000000 img/verify64.png img/erase64.png img/read64.png img/write64.png img/redo64.png img/undo.png img/save64.png img/open64.png img/exit64.png img/test64.png img/unprotect64.png img/saveBlock64.png img/loadBlock64.png img/hexsearch64.png img/ch341_black150.png img/ch341_green150.png img/chipEdit64.png img/checkSum64.png img/stop64.png img/ch341_unknown.png img/ch341_24.png img/ch341_93.png img/ch341_spi.png img/ch341_spi_18.png img/info64.png img/goto64.png img/ch341_45.png img/fill64.png img/compare64.png img/ch341_spi_18_wson.png img/ch341_35.png img/paste64.png img/copy64.png img/v1_7_NAND_1v8.png img/v1_7_NAND_3v3.png img/v1_7_mw_3v3.png img/v1_7_45_3v3.png img/v1_7_i2c_3v3.png img/v1_7_spi_3v3.png img/v1_7_spi_1v8.png img/ch341v1_7.png img/ch347_45_3v3.png img/ch347_i2c_3v3.png img/ch347_mv_3v3.png img/ch347_NAND_3v3.png img/ch347_spi_1v8.png img/ch347_spi_3v3.png img/ch347_spi_18_wson.png img/v1_1_i2c_3v3.png img/v1_1_45_3v3.png img/v1_1_mw_3v3.png img/v1_1_NAND_1v8.png img/v1_1_NAND_3v3.png img/v1_1_spi_1v8.png img/v1_1_spi_3v3.png img/checkErase64.png img/v1_1_spi_2v5.png img/v1_7_spi_2v5.png img/v1_7_i2c_5v0.png img/v1_1_i2c_5v0.png imsprog-1.8.5/IMSProg_programmer/res.h000066400000000000000000000000251520775651600176750ustar00rootroot00000000000000#define snander 128 imsprog-1.8.5/IMSProg_programmer/searchdialog.cpp000066400000000000000000000105301520775651600220660ustar00rootroot00000000000000/* * Copyright (C) 2015-2016 Winfried Simon * Copyright (C) 2023 - 2024 Mikhail Medvedev * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * https://www.gnu.org/licenses/ */ #include "searchdialog.h" #include "ui_searchdialog.h" #include SearchDialog::SearchDialog(QHexEdit *hexEdit, QWidget *parent) : QDialog(parent), ui(new Ui::SearchDialog) { ui->setupUi(this); _hexEdit = hexEdit; } SearchDialog::~SearchDialog() { delete ui; } qint64 SearchDialog::findNext() { qint64 from = _hexEdit->cursorPosition() / 2; _findBa = getContent(ui->cbFindFormat->currentIndex(), ui->cbFind->currentText()); qint64 idx = -1; if (_findBa.length() > 0) { if (ui->cbBackwards->isChecked()) idx = _hexEdit->lastIndexOf(_findBa, from); else idx = _hexEdit->indexOf(_findBa, from); } return idx; } void SearchDialog::on_pbFind_clicked() { findNext(); } void SearchDialog::on_pbReplace_clicked() { int idx = findNext(); if (idx >= 0) { QByteArray replaceBa = getContent(ui->cbReplaceFormat->currentIndex(), ui->cbReplace->currentText()); replaceOccurrence(idx, replaceBa); } } void SearchDialog::on_pbReplaceAll_clicked() { int replaceCounter = 0; int idx = 0; int goOn = QMessageBox::Yes; while ((idx >= 0) && (goOn == QMessageBox::Yes)) { idx = findNext(); if (idx >= 0) { QByteArray replaceBa = getContent(ui->cbReplaceFormat->currentIndex(), ui->cbReplace->currentText()); int result = replaceOccurrence(idx, replaceBa); if (result == QMessageBox::Yes) replaceCounter += 1; if (result == QMessageBox::Cancel) goOn = result; } } if (replaceCounter > 0) QMessageBox::information(this, tr("QHexEdit"), QString(tr("%1 occurrences replaced.")).arg(replaceCounter)); } QByteArray SearchDialog::getContent(int comboIndex, const QString &input) { QByteArray findBa; switch (comboIndex) { case 0: // hex findBa = QByteArray::fromHex(input.toLatin1()); break; case 1: // text findBa = input.toUtf8(); break; } return findBa; } qint64 SearchDialog::replaceOccurrence(qint64 idx, const QByteArray &replaceBa) { int result = QMessageBox::Yes; if (replaceBa.length() >= 0) { if (ui->cbPrompt->isChecked()) { result = QMessageBox::question(this, tr("QHexEdit"), tr("Replace occurrence?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); if (result == QMessageBox::Yes) { _hexEdit->replace(idx, replaceBa.length(), replaceBa); _hexEdit->update(); } } else { _hexEdit->replace(idx, _findBa.length(), replaceBa); } } return result; } void SearchDialog::on_pb_png_clicked() { ui->cbFind->setCurrentText("89504e470d0a1a0a"); } void SearchDialog::on_pb_jpg_clicked() { ui->cbFind->setCurrentText("ffd8ff"); } void SearchDialog::on_pb_gif_clicked() { ui->cbFind->setCurrentText("47494638"); } void SearchDialog::on_pb_zip_clicked() { ui->cbFind->setCurrentText("504b0304"); } void SearchDialog::on_pb_tar_clicked() { ui->cbFind->setCurrentText("7573746172003030"); } void SearchDialog::on_pb_bios_clicked() { ui->cbFind->setCurrentText("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5AA5F00F"); } void SearchDialog::on_pb_uefi_clicked() { ui->cbFind->setCurrentText("0000000000000000000000000000000078E58C8C3D8A1C4F9935896185C32DD3"); } void SearchDialog::on_pb_gpt_clicked() { ui->cbFind->setCurrentText("4546492050415254"); } imsprog-1.8.5/IMSProg_programmer/searchdialog.h000066400000000000000000000031571520775651600215420ustar00rootroot00000000000000/* * Copyright (C) 2015-2016 Winfried Simon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * https://www.gnu.org/licenses/ */ #ifndef SEARCHDIALOG_H #define SEARCHDIALOG_H #include #include #include "qhexedit.h" namespace Ui { class SearchDialog; } class SearchDialog : public QDialog { Q_OBJECT public: explicit SearchDialog(QHexEdit *hexEdit, QWidget *parent = 0); ~SearchDialog(); qint64 findNext(); Ui::SearchDialog *ui; private slots: void on_pbFind_clicked(); void on_pbReplace_clicked(); void on_pbReplaceAll_clicked(); void on_pb_png_clicked(); void on_pb_jpg_clicked(); void on_pb_gif_clicked(); void on_pb_zip_clicked(); void on_pb_tar_clicked(); void on_pb_bios_clicked(); void on_pb_uefi_clicked(); void on_pb_gpt_clicked(); private: QByteArray getContent(int comboIndex, const QString &input); qint64 replaceOccurrence(qint64 idx, const QByteArray &replaceBa); QHexEdit *_hexEdit; QByteArray _findBa; }; #endif // SEARCHDIALOG_H imsprog-1.8.5/IMSProg_programmer/searchdialog.ui000066400000000000000000000355261520775651600217350ustar00rootroot00000000000000 SearchDialog 0 0 526 382 QHexEdit - Find/Replace :/res/img/write64.png:/res/img/write64.png Find Hex UTF-8 0 0 75 true true Replace Hex UTF-8 0 0 75 true true Options &Backwards &Prompt on replace 0 0 0 Standard headers: 6 6 0 6 0 5 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} ZIP 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} PNG 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} JPG 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} GIF 0 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} TAR 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} UEFI 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} BIOS 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} GPT 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} &Find F3 true 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} &Replace 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} Replace &All 90 25 QPushButton{ color: rgb(255, 255, 255); background-color: rgb(120, 183, 140); border-radius: 20px; border: 2px solid #094065;border-radius:8px;font-weight:600; } QPushButton::pressed{background-color: rgb(115, 210, 22);} &Close Qt::Vertical 20 40 cbFind cbReplace cbFindFormat cbReplaceFormat cbBackwards cbPrompt pbFind pbReplace pbReplaceAll pbCancel pbCancel clicked() SearchDialog hide() 360 134 364 162 imsprog-1.8.5/IMSProg_programmer/snander.rc000066400000000000000000000014351520775651600207210ustar00rootroot00000000000000#include #include "res.h" VS_VERSION_INFO VERSIONINFO FILEVERSION 1, 7, 8, 0 PRODUCTVERSION 1, 7, 8, 0 FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_APP FILESUBTYPE 0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "FileDescription", "SNANDer - Serial Nor/nAND/Eeprom programmeR\0" VALUE "OriginalFilename", "SNANDer.exe\0" VALUE "CompanyName", "-= (c) 2018-2022 Igor Mokrushin aka McMCC =-\0" VALUE "FileVersion", "1.7.8.0\0" VALUE "InternalName", "SNANDer\0" VALUE "LegalCopyright", "Copyright (c) 2018-2022 by McMCC \0" VALUE "ProductName","SNANDer\0" VALUE "ProductVersion","1.7.8.0\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x0409, 1252 END END snander ICON DISCARDABLE "snander.ico" imsprog-1.8.5/IMSProg_programmer/snorcmd_api.h000066400000000000000000000061471520775651600214150ustar00rootroot00000000000000/* * Copyright (C) 2018-2021 McMCC * 2023-2024 Mikhail Medvedev * snorcmd_api.h * * 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. */ #ifndef __SNORCMD_API_H__ #define __SNORCMD_API_H__ #include "types.h" int snor_wait_ready(int sleep_ms); int snor_read(unsigned char *buf, unsigned long from, unsigned long len); int snor_read_param(unsigned char *buf, unsigned long from, unsigned long len, unsigned int sector_size, unsigned int addr4b, u8 progType); int snor_write_param(unsigned char *buf, unsigned long to, unsigned long len, unsigned int sector_size, unsigned int addr4b, u8 progType); int snorUnprotect(u8 progType); int snor_erase(unsigned long offs, unsigned long len); int full_erase_chip(void); int snor_block_erase(unsigned int sector_number, unsigned int blockSize, u8 addr4b, u8 progType); int snor_write(unsigned char *buf, unsigned long to, unsigned long len); long snor_init(void); void support_snor_list(void); int snor_read_devid(u8 *rxbuf, int n_rx, u8 progType); int s95_read_param(unsigned char *buf, unsigned long from, unsigned long len, unsigned int sector_size, unsigned char currentAlgorithm, u8 progType); int s95_write_param(unsigned char *buf, unsigned long to, unsigned long len, unsigned int sector_size, unsigned char currentAlgorithm, u8 progType); int s95_unprotect(void); int s95_full_erase(u8 progType); int at45_read_param(unsigned char *buf, unsigned long from, unsigned long len, unsigned int sector_size, unsigned char currentAlgorithm, u8 progType); int at45_write_param(unsigned char *buf, unsigned long from, unsigned long len, unsigned int sector_size, unsigned char currentAlgorithm, u8 progType); int at45_full_erase(u8 progType); int at45_sector_erase(unsigned int sectorNumber, unsigned int pageSize, u8 progType); int at45_read_sr(u8 *val); int nand_page_read(unsigned char *buf, unsigned int sector_size, u32 sector_number); int nand_block_read(unsigned char *buf, unsigned int page_size, u32 block_number, unsigned int pages_per_block, u8 progType); int nand_wait_ready(int sleep_ms); int nand_read_devid(u8 *rxbuf, int n_rx, u8 progType); int nand_block_erase(unsigned int sector_number, unsigned int blockSize, u8 progType); void nand_write_enable(void); void nand_unprotect(u8 progType); int nand_page_write(unsigned char *buf, unsigned int page_size, u32 sector_number); int nand_block_write(unsigned char *buf, unsigned int page_size, u32 block_number, unsigned int pages_per_block, u8 progType); void nand_ECCEnable(u8 progType); void nand_ECCDisable(u8 progType); int nand_checkBadBlock(u32 blockNo, u32 sectSize, u32 blockPerSector, u8 progType); #endif /* __SNORCMD_API_H__ */ /* End of [snorcmd_api.h] package */ imsprog-1.8.5/IMSProg_programmer/spi_controller.c000066400000000000000000000063231520775651600221440ustar00rootroot00000000000000/*====================================================================================== * MODULE NAME: spi * FILE NAME: spi_controller.c * * FUNCTIONS * * SPI_CONTROLLER_Enable_Manual_Mode To provide interface for Enable SPI Controller Manual Mode. * SPI_CONTROLLER_Write_One_Byte To provide interface for write one byte to SPI bus. * SPI_CONTROLLER_Write_NByte To provide interface for write N bytes to SPI bus. * SPI_CONTROLLER_Read_NByte To provide interface for read N bytes from SPI bus. * SPI_CONTROLLER_Chip_Select_Low To provide interface for set chip select low in SPI bus. * SPI_CONTROLLER_Chip_Select_High To provide interface for set chip select high in SPI bus. * * DEPENDENCIES * * * $History: $ * MODIFICTION HISTORY: * *====================================================================================== */ #include "ch341a_spi.h" #include "spi_controller.h" #include "ch347.h" extern struct ch347_priv *priv; int ProgDeviceInit( u8 deviceType, u8 chipType, u8 i2cSpeed ) { int ret; if (deviceType < 2) ret = ch341a_init(chipType, i2cSpeed); if (deviceType == 2) ret = ch347_spi_init(chipType, i2cSpeed, false); if (deviceType == 3) ret = ch347_spi_init(chipType, i2cSpeed, true); return ret; } int ProgDeviceClose( u8 deviceType ) { if (deviceType < 2) ch341a_spi_shutdown(); if (deviceType >= 2) ch347_spi_shutdown(); return 0; } int getDeviceDescriptor(u8 *data, u8 deviceType) { if (deviceType >= 2) ch347GetDescriptor(data); if (deviceType < 2) ch341GetDescriptor(data); return 0; } SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Enable_Manual_Mode( void ) { return 0; } SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Write_One_Byte( u8 data, u8 deviceType ) { if (deviceType < 2) return (SPI_CONTROLLER_RTN_T)ch341a_spi_send_command(1, 0, &data, NULL); else return (SPI_CONTROLLER_RTN_T)ch347_spi_tx(priv, &data, 1); } SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Chip_Select_High( u8 deviceType ) { if (deviceType < 2) return (SPI_CONTROLLER_RTN_T)enable_pins(false); else return (SPI_CONTROLLER_RTN_T)ch347_set_cs(priv, 0, 1); } SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Chip_Select_Low( u8 deviceType ) { if (deviceType < 2) return (SPI_CONTROLLER_RTN_T)enable_pins(true); else return (SPI_CONTROLLER_RTN_T)ch347_set_cs(priv, 0, 0); } SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Read_NByte( u8 *ptr_rtn_data, u32 len, SPI_CONTROLLER_SPEED_T speed, u8 deviceType ) { if (deviceType < 2) return (SPI_CONTROLLER_RTN_T)ch341a_spi_send_command(0, len, NULL, ptr_rtn_data); else return (SPI_CONTROLLER_RTN_T)ch347_spi_rx(priv, ptr_rtn_data, len); } SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Write_NByte( u8 *ptr_data, u32 len, SPI_CONTROLLER_SPEED_T speed, u8 deviceType ) { if (deviceType < 2) return (SPI_CONTROLLER_RTN_T)ch341a_spi_send_command(len, 0, ptr_data, NULL); else return (SPI_CONTROLLER_RTN_T)ch347_spi_tx(priv, ptr_data, len); } #if 0 SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Xfer_NByte( u8 *ptr_data_in, u32 len_in, u8 *ptr_data_out, u32 len_out, SPI_CONTROLLER_SPEED_T speed ) { return (SPI_CONTROLLER_RTN_T)ch341a_spi_send_command(len_out, len_in, ptr_data_out, ptr_data_in); } #endif /* End of [spi_controller.c] package */ imsprog-1.8.5/IMSProg_programmer/spi_controller.h000066400000000000000000000150431520775651600221500ustar00rootroot00000000000000/*====================================================================================== * MODULE NAME: spi * FILE NAME: spi_controller.h * * FUNCTIONS * * SPI_CONTROLLER_Enable_Manual_Mode To provide interface for Enable SPI Controller Manual Mode. * SPI_CONTROLLER_Write_One_Byte To provide interface for write one byte to SPI bus. * SPI_CONTROLLER_Write_NByte To provide interface for write N bytes to SPI bus. * SPI_CONTROLLER_Read_NByte To provide interface for read N bytes from SPI bus. * SPI_CONTROLLER_Chip_Select_Low To provide interface for set chip select low in SPI bus. * SPI_CONTROLLER_Chip_Select_High To provide interface for set chip select high in SPI bus. * * DEPENDENCIES * * * $History: $ * MODIFICTION HISTORY: * *====================================================================================== */ #ifndef __SPI_CONTROLLER_H__ #define __SPI_CONTROLLER_H__ /* INCLUDE FILE DECLARATIONS --------------------------------------------------------- */ #include "types.h" #include /* NAMING CONSTANT DECLARATIONS ------------------------------------------------------ */ /* MACRO DECLARATIONS ---------------------------------------------------------------- */ /* TYPE DECLARATIONS ----------------------------------------------------------------- */ typedef enum{ SPI_CONTROLLER_SPEED_SINGLE = 0, SPI_CONTROLLER_SPEED_DUAL, SPI_CONTROLLER_SPEED_QUAD } SPI_CONTROLLER_SPEED_T; typedef enum{ SPI_CONTROLLER_RTN_NO_ERROR = 0, SPI_CONTROLLER_RTN_SET_OPFIFO_ERROR, SPI_CONTROLLER_RTN_READ_DATAPFIFO_ERROR, SPI_CONTROLLER_RTN_WRITE_DATAPFIFO_ERROR, SPI_CONTROLLER_RTN_DEF_NO } SPI_CONTROLLER_RTN_T; typedef enum{ SPI_CONTROLLER_MODE_AUTO = 0, SPI_CONTROLLER_MODE_MANUAL, SPI_CONTROLLER_MODE_NO } SPI_CONTROLLER_MODE_T; int ProgDeviceInit( u8 deviceType, u8 chipType, u8 i2cSpeed ); int ProgDeviceClose( u8 deviceType ); int getDeviceDescriptor(u8 *data, u8 deviceType); /*------------------------------------------------------------------------------------ * FUNCTION: SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Enable_Manual_Mode( void ) * PURPOSE : To provide interface for enable SPI Controller Manual Mode Enable. * AUTHOR : * CALLED BY * - * CALLS * - * PARAMs : * INPUT : None * OUTPUT: None * RETURN : SPI_RTN_NO_ERROR - Successful. Otherwise - Failed. * NOTES : * MODIFICTION HISTORY: *------------------------------------------------------------------------------------ */ SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Enable_Manual_Mode( void ); /*------------------------------------------------------------------------------------ * FUNCTION: SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Write_One_Byte( u8 data ) * PURPOSE : To provide interface for write one byte to SPI bus. * AUTHOR : * CALLED BY * - * CALLS * - * PARAMs : * INPUT : data - The data variable of this function. * OUTPUT: None * RETURN : SPI_RTN_NO_ERROR - Successful. Otherwise - Failed. * NOTES : * MODIFICTION HISTORY: *------------------------------------------------------------------------------------ */ SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Write_One_Byte( u8 data, u8 deviceType ); /*------------------------------------------------------------------------------------ * FUNCTION: SPI_CONTROLLER_RTN_T SPI_CONTROLLER_WRITE_NBYTES( u8 *ptr_data, * u32 len, * SPI_CONTROLLER_SPEED_T speed ) * PURPOSE : To provide interface for write N bytes to SPI bus. * AUTHOR : * CALLED BY * - * CALLS * - * PARAMs : * INPUT : ptr_data - The data variable of this function. * len - The len variable of this function. * speed - The speed variable of this function. * OUTPUT: None * RETURN : SPI_RTN_NO_ERROR - Successful. Otherwise - Failed. * NOTES : * MODIFICTION HISTORY: *------------------------------------------------------------------------------------ */ SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Write_NByte( u8 *ptr_data, u32 len, SPI_CONTROLLER_SPEED_T speed, u8 deviceType ); /*------------------------------------------------------------------------------------ * FUNCTION: SPI_CONTROLLER_RTN_T SPI_CONTROLLER_READ_NBYTES( u8 *ptr_rtn_data, * u8 len, * SPI_CONTROLLER_SPEED_T speed ) * PURPOSE : To provide interface for read N bytes from SPI bus. * AUTHOR : * CALLED BY * - * CALLS * - * PARAMs : * INPUT : len - The len variable of this function. * speed - The speed variable of this function. * OUTPUT: ptr_rtn_data - The ptr_rtn_data variable of this function. * RETURN : SPI_RTN_NO_ERROR - Successful. Otherwise - Failed. * NOTES : * MODIFICTION HISTORY: *------------------------------------------------------------------------------------ */ SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Read_NByte( u8 *ptr_rtn_data, u32 len, SPI_CONTROLLER_SPEED_T speed, u8 deviceType ); /*------------------------------------------------------------------------------------ * FUNCTION: SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Chip_Select_Low( void ) * PURPOSE : To provide interface for set chip select low in SPI bus. * AUTHOR : * CALLED BY * - * CALLS * - * PARAMs : * INPUT : None * OUTPUT: None * RETURN : SPI_RTN_NO_ERROR - Successful. Otherwise - Failed. * NOTES : * MODIFICTION HISTORY: *------------------------------------------------------------------------------------ */ SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Chip_Select_Low( u8 deviceType ); /*------------------------------------------------------------------------------------ * FUNCTION: SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Chip_Select_High( void ) * PURPOSE : To provide interface for set chip select high in SPI bus. * AUTHOR : * CALLED BY * - * CALLS * - * PARAMs : * INPUT : None * OUTPUT: None * RETURN : SPI_RTN_NO_ERROR - Successful. Otherwise - Failed. * NOTES : * MODIFICTION HISTORY: *------------------------------------------------------------------------------------ */ SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Chip_Select_High( u8 deviceType ); #if 0 SPI_CONTROLLER_RTN_T SPI_CONTROLLER_Xfer_NByte( u8 *ptr_data_in, u32 len_in, u8 *ptr_data_out, u32 len_out, SPI_CONTROLLER_SPEED_T speed ); #endif #endif /* ifndef __SPI_CONTROLLER_H__ */ /* End of [spi_controller.h] package */ imsprog-1.8.5/IMSProg_programmer/spi_eeprom_api.h000066400000000000000000000017411520775651600221050ustar00rootroot00000000000000/* * Copyright (C) 2022 McMCC * spi_eeprom_api.h * * 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. */ #ifndef __SPI_EEPROM_API_H__ #define __SPI_EEPROM_API_H__ int spi_eeprom_read(unsigned char *buf, unsigned long from, unsigned long len); int spi_eeprom_erase(unsigned long offs, unsigned long len); int spi_eeprom_write(unsigned char *buf, unsigned long to, unsigned long len); long spi_eeprom_init(void); void support_spi_eeprom_list(void); #endif /* __SPI_EEPROM_API_H__ */ /* End of [spi_eeprom_api.h] package */ imsprog-1.8.5/IMSProg_programmer/spi_nor_flash.c000066400000000000000000001132071520775651600217340ustar00rootroot00000000000000/* * Copyright (C) 2018-2021 McMCC * 2023-2026 Mikhail Medvedev * spi_nor_flash.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. */ #include #include #include #include #include #include #include #include "spi_controller.h" #include "snorcmd_api.h" #include "types.h" #include "timer.h" #define min(a,b) (((a)<(b))?(a):(b)) /****************************************************************************** * SPI FLASH elementray definition and function ******************************************************************************/ #define FLASH_PAGESIZE 256 /* Flash opcodes. */ #define OPCODE_WREN 6 /* Write enable */ #define OPCODE_WRDI 4 /* Write disable */ #define OPCODE_RDSR 5 /* Read status register */ #define OPCODE_WRSR 1 /* Write status register */ #define OPCODE_READ 3 /* Read data bytes */ #define OPCODE_PP 2 /* Page program */ #define OPCODE_SE 0xD8 /* Sector erase */ #define OPCODE_RES 0xAB /* Read Electronic Signature */ #define OPCODE_RDID 0x9F /* Read JEDEC ID */ #define OPCODE_FAST_READ 0x0B /* Fast Read */ #define OPCODE_DOR 0x3B /* Dual Output Read */ #define OPCODE_QOR 0x6B /* Quad Output Read */ #define OPCODE_DIOR 0xBB /* Dual IO High Performance Read */ #define OPCODE_QIOR 0xEB /* Quad IO High Performance Read */ #define OPCODE_READ_ID 0x90 /* Read Manufacturer and Device ID */ #define OPCODE_P4E 0x20 /* 4KB Parameter Sectore Erase */ #define OPCODE_P8E 0x40 /* 8KB Parameter Sectore Erase */ #define OPCODE_BE 0x60 /* Bulk Erase */ #define OPCODE_BE1 0xC7 /* Bulk Erase */ #define OPCODE_QPP 0x32 /* Quad Page Programing */ #define OPCODE_CLSR 0x30 #define OPCODE_RCR 0x35 /* Read Configuration Register */ #define OPCODE_BRRD 0x16 #define OPCODE_BRWR 0x17 /* Status Register bits. */ #define SR_WIP 1 /* Write in progress */ #define SR_WEL 2 /* Write enable latch */ #define SR_BP0 4 /* Block protect 0 */ #define SR_BP1 8 /* Block protect 1 */ #define SR_BP2 0x10 /* Block protect 2 */ #define SR_EPE 0x20 /* Erase/Program error */ #define SR_SRWD 0x80 /* SR write protect */ #define snor_dbg(args...) /* #define snor_dbg(args...) do { if (1) printf(args); } while(0) */ struct xxx { uint8_t ibuf[512]; uint8_t obuf[512]; } spi_buf; #define udelay(x) usleep(x) u8 programmerType = 0; /* struct chip_info { char *name; u8 id; u32 jedec_id; unsigned long sector_size; unsigned int n_sectors; char addr4b; }; */ unsigned char algType = 0; //struct chip_info *spi_chip_info; static int snor_read_sr(u8 *val); static int snor_write_sr(u8 *val); static int s95_read_sr(u8 *val); static int s95_write_sr(u8 *val); int s95_wait_ready(int sleep_ms); int s95_unprotect(void); extern unsigned int bsize; /* * Set write enable latch with Write Enable command. * Returns negative if error occurred. */ static inline void snor_write_enable(void) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(OPCODE_WREN, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); } static inline void snor_write_disable(void) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(OPCODE_WRDI, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); } static inline void s95_write_enable(void) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); } static inline void s95_write_disable(void) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x04, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); } /* * Set all sectors (global) unprotected if they are protected. * Returns negative if error occurred. */ static inline int snor_unprotect(void) { u8 sr = 0; if (snor_read_sr(&sr) < 0) { printf("%s: read_sr fail: %x\n", __func__, sr); return -1; } if ((sr & (SR_BP0 | SR_BP1 | SR_BP2)) != 0) { sr = 0; snor_write_sr(&sr); } return 0; } /* * Service routine to read status register until ready, or timeout occurs. * Returns non-zero if error. */ int snor_wait_ready(int sleep_ms) { int count; int sr = 0; /* one chip guarantees max 5 msec wait here after page writes, * but potentially three seconds (!) after page erase. */ for (count = 0; count < ((sleep_ms + 1) * 1000); count++) { if ((snor_read_sr((u8 *)&sr)) < 0) break; else if (!(sr & (SR_WIP | SR_EPE | SR_WEL))) { return 0; } udelay(500); /* REVISIT sometimes sleeping would be best */ } printf("%s: read_sr fail: %x\n", __func__, sr); return -1; } /* * read status register */ static int snor_read_rg(u8 code, u8 *val) { int retval; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(code, programmerType); retval = SPI_CONTROLLER_Read_NByte(val, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { printf("%s: ret: %x\n", __func__, retval); return -1; } return 0; } /* * write status register */ static int snor_write_rg(u8 code, u8 *val) { int retval; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(code, programmerType); retval = SPI_CONTROLLER_Write_NByte(val, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { printf("%s: ret: %x\n", __func__, retval); return -1; } return 0; } static int snor_4byte_mode(int enable) { int retval; if (snor_wait_ready(1)) return -1; //if (spi_chip_info->id == 0x1) /* Spansion */ if (algType == 0x02) /* Spansion */ { u8 br_cfn; u8 br = enable ? 0x81 : 0; snor_write_rg(OPCODE_BRWR, &br); snor_read_rg(OPCODE_BRRD, &br_cfn); if (br_cfn != br) { printf("4B mode switch failed %s, 0x%02x, 0x%02x\n", enable ? "enable" : "disable" , br_cfn, br); return -1; } } else { u8 code = enable ? 0xb7 : 0xe9; /* B7: enter 4B, E9: exit 4B */ SPI_CONTROLLER_Chip_Select_Low(programmerType); retval = SPI_CONTROLLER_Write_One_Byte(code, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { printf("%s: ret: %x\n", __func__, retval); return -1; } //if ((!enable) && (spi_chip_info->id == 0xef)) /* Winbond */ if ((!enable) && (algType == 0x01)) /* Winbond */ { code = 0; snor_write_enable(); snor_write_rg(0xc5, &code); } } return 0; } int full_erase_chip(void) { timer_start(); /* Wait until finished previous write command. */ if (snor_wait_ready(3)) return -1; /* Send write enable, then erase commands. */ snor_write_enable(); snor_unprotect(); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(OPCODE_BE1, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); snor_wait_ready(950); snor_write_disable(); timer_end(); return 0; } int snor_block_erase(unsigned int sector_number, unsigned int blockSize, u8 addr4b, u8 progType) { uint8_t *ptr = spi_buf.obuf; unsigned int physical_addr; //addr4bit transforming algType = (addr4b & 0xf0) >> 4; addr4b = addr4b & 0x0f; programmerType = progType; if (addr4b) snor_4byte_mode(1); physical_addr = sector_number * blockSize; /* Wait until finished previous write command. */ if (snor_wait_ready(950)) return -1; snor_write_enable(); SPI_CONTROLLER_Chip_Select_Low(programmerType); *ptr++ = 0xd8; if (addr4b) *ptr++ = (physical_addr >> 24) & 0xff; *ptr++ = (physical_addr >> 16) & 0xff; *ptr++ = (physical_addr >> 8) & 0xff; *ptr++ = physical_addr & 0xff; if (addr4b) SPI_CONTROLLER_Write_NByte(spi_buf.obuf, 5, SPI_CONTROLLER_SPEED_SINGLE, programmerType); else SPI_CONTROLLER_Write_NByte(spi_buf.obuf, 4, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); snor_write_disable(); //if (addr4b) snor_4byte_mode(0); return 0; } /* * read SPI flash device ID */ int snor_read_devid(u8 *rxbuf, int n_rx, uint8_t progType) { int retval = 0; programmerType = progType; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(OPCODE_RDID, programmerType); retval = SPI_CONTROLLER_Read_NByte(rxbuf, n_rx, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { printf("%s: ret: %x\n", __func__, retval); return retval; } if ((rxbuf[0] == 0) && (rxbuf[1] == 0) && (rxbuf[2] == 0)) { rxbuf[0] = 0xff; rxbuf[1] = 0xff; rxbuf[2] = 0xff; } return 0; } /* * read status register */ static int snor_read_sr(u8 *val) { int retval = 0; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(OPCODE_RDSR, programmerType); retval = SPI_CONTROLLER_Read_NByte(val, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { printf("%s: ret: %x\n", __func__, retval); return retval; } return 0; } /* * write status register */ static int snor_write_sr(u8 *val) { int retval = 0; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(OPCODE_WRSR, programmerType); retval = SPI_CONTROLLER_Write_NByte(val, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { printf("%s: ret: %x\n", __func__, retval); return retval; } return 0; } int snor_read_param(unsigned char *buf, unsigned long from, unsigned long len, unsigned int sector_size, unsigned int addr4b, uint8_t progType) { u32 read_addr, physical_read_addr, remain_len, data_offset; programmerType = progType; //addr4bit transforming algType = (addr4b & 0xf0) >> 4; addr4b = addr4b & 0x0f; uint8_t *ptr = spi_buf.obuf; snor_dbg("%s: from:%x len:%x \n", __func__, from, len); /* sanity checks */ if (len == 0) return 0; /* Wait till previous write/erase is done. */ if (snor_wait_ready(1)) { /* REVISIT status return?? */ return -1; } read_addr = from; remain_len = len; while(remain_len > 0) { physical_read_addr = read_addr; data_offset = (physical_read_addr % (sector_size)); if (addr4b) snor_4byte_mode(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); /* Set up the write data buffer. */ *ptr++ = OPCODE_READ; if (addr4b) *ptr++ = (physical_read_addr >> 24) & 0xff; *ptr++ = (physical_read_addr >> 16) & 0xff; *ptr++ = (physical_read_addr >> 8) & 0xff; *ptr++ = physical_read_addr & 0xff; if (addr4b) SPI_CONTROLLER_Write_NByte(spi_buf.obuf, 5, SPI_CONTROLLER_SPEED_SINGLE, programmerType); else SPI_CONTROLLER_Write_NByte(spi_buf.obuf, 4, SPI_CONTROLLER_SPEED_SINGLE, programmerType); if( (data_offset + remain_len) < sector_size ) { if(SPI_CONTROLLER_Read_NByte(&buf[len - remain_len], remain_len, SPI_CONTROLLER_SPEED_SINGLE, programmerType)) { SPI_CONTROLLER_Chip_Select_High(programmerType); if (addr4b) snor_4byte_mode(0); len = -1; break; } remain_len = 0; } else { if(SPI_CONTROLLER_Read_NByte(&buf[len - remain_len], sector_size - data_offset, SPI_CONTROLLER_SPEED_SINGLE, programmerType)) { SPI_CONTROLLER_Chip_Select_High(programmerType); if (addr4b) snor_4byte_mode(0); len = -1; break; } remain_len -= sector_size - data_offset; read_addr += sector_size - data_offset; } SPI_CONTROLLER_Chip_Select_High(programmerType); if (addr4b) snor_4byte_mode(0); } return len; } int snor_write_param(unsigned char *buf, unsigned long to, unsigned long len, unsigned int sector_size, unsigned int addr4b, u8 progType) { u32 page_size; int ret =0; programmerType = progType; //addr4bit transforming algType = (addr4b & 0xf0) >> 4; addr4b = addr4b & 0x0f; snor_dbg("%s: to:%x len:%x \n", __func__, to, len); /* sanity checks */ if (len == 0) return 0; /* Wait until finished previous write command. */ if (snor_wait_ready(2)) { return -1; } if (addr4b) snor_4byte_mode(1); /* write everything in PAGESIZE chunks */ while (len > 0) { uint8_t *ptr = spi_buf.obuf; page_size = min(len, FLASH_PAGESIZE); /* write the next page to flash */ snor_wait_ready(3); snor_write_enable(); SPI_CONTROLLER_Chip_Select_Low(programmerType); /* Set up the opcode in the write buffer. */ *ptr++ = OPCODE_PP; if (addr4b) *ptr++ = (to >> 24) & 0xff; *ptr++ = (to >> 16) & 0xff; *ptr++ = (to >> 8) & 0xff; *ptr++ = to & 0xff; memcpy(ptr, buf, page_size); if (addr4b) ret = SPI_CONTROLLER_Write_NByte(spi_buf.obuf, 5 + page_size, SPI_CONTROLLER_SPEED_SINGLE, programmerType); else ret = SPI_CONTROLLER_Write_NByte(spi_buf.obuf, 4 + page_size, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (ret != 0) return -1; snor_dbg("%s: to:%x page_size:%x ret:%x\n", __func__, to, page_size, rc); len -= page_size; to += page_size; buf += page_size; } if (addr4b) snor_4byte_mode(0); snor_write_disable(); return 1; } int snorUnprotect(u8 progType) { int ret; uint8_t buf[2]; programmerType = progType; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x05, programmerType); ret = SPI_CONTROLLER_Read_NByte(&buf[0],2,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); buf[0] = buf[0] & 0xc3; //clear bp0 - bp3 SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x06, programmerType); //Write Enable SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x01, programmerType); SPI_CONTROLLER_Write_One_Byte(buf[0], programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); return ret; } int s95_read_param(unsigned char *buf, unsigned long from, unsigned long len, unsigned int sector_size, unsigned char currentAlgorithm, u8 progType) { u32 physical_read_addr, remain_len, data_offset; u32 read_addr; unsigned char algorythm = currentAlgorithm & 0x0f; unsigned char a8 = currentAlgorithm & 0x10; snor_dbg("%s: from:%x len:%x \n", __func__, from, len); programmerType = progType; /* sanity checks */ if (len == 0) return 0; /* Wait till previous write/erase is done. */ if (s95_wait_ready(1)) { /* REVISIT status return?? */ return -1; } read_addr = (u32)from; remain_len = (u32)len; while(remain_len > 0) { physical_read_addr = read_addr; data_offset = (physical_read_addr % (sector_size)); SPI_CONTROLLER_Chip_Select_Low(programmerType); /* Set up the write data buffer. */ if ((from > 255) && (a8 > 0)) SPI_CONTROLLER_Write_One_Byte(0x0b, programmerType); //read command + a8 bit else SPI_CONTROLLER_Write_One_Byte(0x03, programmerType); //read command if (algorythm == 2) SPI_CONTROLLER_Write_One_Byte((physical_read_addr >> 16) & 0xff, programmerType); if (algorythm > 0) SPI_CONTROLLER_Write_One_Byte((physical_read_addr >> 8) & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte(physical_read_addr & 0xff, programmerType); if( (data_offset + remain_len) < sector_size ) { if(SPI_CONTROLLER_Read_NByte(&buf[len - remain_len], remain_len, SPI_CONTROLLER_SPEED_SINGLE, programmerType)) { SPI_CONTROLLER_Chip_Select_High(programmerType); len = -1; break; } remain_len = 0; } else { if(SPI_CONTROLLER_Read_NByte(&buf[len - remain_len], sector_size - data_offset, SPI_CONTROLLER_SPEED_SINGLE, programmerType)) { SPI_CONTROLLER_Chip_Select_High(programmerType); len = -1; break; } remain_len -= sector_size - data_offset; read_addr += sector_size - data_offset; } SPI_CONTROLLER_Chip_Select_High(programmerType); } return len; } int s95_write_param(unsigned char *buf, unsigned long to, unsigned long len, unsigned int sector_size, unsigned char currentAlgorithm, u8 progType) { u32 page_offset, page_size; int rc = 0, retlen = 0; unsigned long plen = len; unsigned char algorythm = currentAlgorithm & 0x0f; unsigned char a8 = currentAlgorithm & 0x10; snor_dbg("%s: to:%x len:%x \n", __func__, to, len); programmerType = progType; /* sanity checks */ if (len == 0) return 0; /* Wait until finished previous write command. */ if (s95_wait_ready(2)) return -1; /* what page do we start with? */ page_offset = to % sector_size;//FLASH_PAGESIZE; /* write everything in PAGESIZE chunks */ while (len > 0) { page_size = min(len, sector_size - page_offset); page_offset = 0; /* write the next page to flash */ s95_wait_ready(3); s95_write_enable(); s95_unprotect(); SPI_CONTROLLER_Chip_Select_Low(programmerType); /* Set up the opcode in the write buffer. */ if ((to > 255) && (a8 > 0)) SPI_CONTROLLER_Write_One_Byte(0x0a, programmerType); //write command + a8 bit else SPI_CONTROLLER_Write_One_Byte(0x02, programmerType); //write command if (algorythm == 2) SPI_CONTROLLER_Write_One_Byte((to >> 16) & 0xff, programmerType); if (algorythm > 0) SPI_CONTROLLER_Write_One_Byte((to >> 8) & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte(to & 0xff, programmerType); if(!SPI_CONTROLLER_Write_NByte(buf, page_size, SPI_CONTROLLER_SPEED_SINGLE, programmerType)) rc = page_size; else rc = 1; SPI_CONTROLLER_Chip_Select_High(programmerType); snor_dbg("%s: to:%x page_size:%x ret:%x\n", __func__, to, page_size, rc); if (rc > 0) { retlen += rc; if (rc < page_size) { printf("%s: rc:%x page_size:%x\n", __func__, rc, page_size); s95_write_disable(); return retlen - rc; } } len -= page_size; to += page_size; buf += page_size; } s95_write_disable(); return retlen; } int s95_full_erase(u8 progType) { programmerType = progType; timer_start(); /* Wait until finished previous write command. */ if (s95_wait_ready(3)) return -1; /* Send write enable, then erase commands. */ s95_write_enable(); s95_unprotect(); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x62, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); s95_wait_ready(950); s95_write_disable(); timer_end(); return 0; } static int s95_read_sr(u8 *val) { int retval = 0; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x05, programmerType); retval = SPI_CONTROLLER_Read_NByte(val, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { printf("%s: ret: %x\n", __func__, retval); return retval; } return 0; } static int s95_write_sr(u8 *val) { int retval = 0; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x01, programmerType); retval = SPI_CONTROLLER_Write_NByte(val, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { printf("%s: ret: %x\n", __func__, retval); return retval; } return 0; } int s95_unprotect(void) { u8 sr = 0; if (s95_read_sr(&sr) < 0) { printf("%s: read_sr fail: %x\n", __func__, sr); return -1; } if ((sr & (SR_BP0 | SR_BP1 )) != 0) { sr = 0; s95_write_sr(&sr); } return 0; } int s95_wait_ready(int sleep_ms) { int count; int sr = 0; /* one chip guarantees max 5 msec wait here after page writes, * but potentially three seconds (!) after page erase. */ for (count = 0; count < ((sleep_ms + 1) * 1000); count++) { //printf("sr= %x\n",snor_read_sr((u8 *)&sr)); if ((snor_read_sr((u8 *)&sr)) < 0) break; else if (!(sr & (SR_WIP | SR_WEL))) { return 0; } udelay(500); /* REVISIT sometimes sleeping would be best */ } printf("%s: read_sr fail: %x\n", __func__, sr); return -1; } int at45_read_sr(u8 *val) { int retval = 0; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0xd7, programmerType); retval = SPI_CONTROLLER_Read_NByte(val, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { //printf("%s: ret: %x\n", __func__, retval); return retval; } return 0; } int at45_wait_ready(int sleep_ms) { int count; int sr = 0; /* one chip guarantees max 5 msec wait here after page writes, * but potentially three seconds (!) after page erase. */ for (count = 0; count < ((sleep_ms + 1) * 1000); count++) { //printf("sr= %x\n",snor_read_sr((u8 *)&sr)); if ((at45_read_sr((u8 *)&sr)) < 0) break; else if ((sr & 0x80)) { return 0; } udelay(500); /* REVISIT sometimes sleeping would be best */ } printf("%s: read_sr fail: %x\n", __func__, sr); return -1; } int at45_read_param(unsigned char *buf, unsigned long from, unsigned long len, unsigned int sector_size, unsigned char currentAlgorithm, u8 progType) { u32 physical_read_addr, remain_len, data_offset; u32 read_addr; unsigned char algorythm = (currentAlgorithm & 0xf0) >> 8; unsigned char addrLen = 9; unsigned int sector_addr = 0; int retval; programmerType = progType; if (sector_size > 511) addrLen++; /* sanity checks */ if (len == 0) return 0; /* Wait till previous write/erase is done. */ if (at45_wait_ready(1)) { /* REVISIT status return?? */ return -1; } read_addr = (u32)from; sector_addr = read_addr / sector_size; read_addr = read_addr % len; read_addr = read_addr + (sector_addr << addrLen); remain_len = (u32)len; physical_read_addr = read_addr; data_offset = (physical_read_addr % (sector_size)); SPI_CONTROLLER_Chip_Select_Low(programmerType); //SPI_CONTROLLER_Write_One_Byte(0x52); //read command SPI_CONTROLLER_Write_One_Byte(0xE8, programmerType); //read command SPI_CONTROLLER_Write_One_Byte((physical_read_addr >> 16) & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte((physical_read_addr >> 8) & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte(physical_read_addr & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte(0xff, programmerType); SPI_CONTROLLER_Write_One_Byte(0xff, programmerType); SPI_CONTROLLER_Write_One_Byte(0xff, programmerType); SPI_CONTROLLER_Write_One_Byte(0xff, programmerType); retval = SPI_CONTROLLER_Read_NByte(&buf[0],sector_size,SPI_CONTROLLER_SPEED_SINGLE, programmerType); if (retval) { return 0;//error } SPI_CONTROLLER_Chip_Select_High(programmerType); return 1; } int at45_write_param(unsigned char *buf, unsigned long from, unsigned long len, unsigned int sector_size, unsigned char currentAlgorithm, u8 progType) { u32 physical_read_addr, remain_len, data_offset; u32 read_addr; unsigned char algorythm = (currentAlgorithm & 0xf0) >> 8; unsigned char addrLen = 9; unsigned int sector_addr = 0; int retval; programmerType = progType; if (sector_size > 511) addrLen++; /* sanity checks */ if (len == 0) return 0; /* Wait till previous write/erase is done. */ if (at45_wait_ready(1)) { /* REVISIT status return?? */ return -1; } read_addr = (u32)from; sector_addr = read_addr / sector_size; read_addr = read_addr % len; read_addr = read_addr + (sector_addr << addrLen); remain_len = (u32)len; physical_read_addr = read_addr; data_offset = (physical_read_addr % (sector_size)); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x82, programmerType); //write command SPI_CONTROLLER_Write_One_Byte((physical_read_addr >> 16) & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte((physical_read_addr >> 8) & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte(physical_read_addr & 0xff, programmerType); //SPI_CONTROLLER_Write_One_Byte(0xff); retval = SPI_CONTROLLER_Write_NByte(buf, sector_size, SPI_CONTROLLER_SPEED_SINGLE, programmerType); if (retval) { return 0;//error } SPI_CONTROLLER_Chip_Select_High(programmerType); return 1; } int at45_full_erase(u8 progType) { programmerType = progType; /* Wait until finished previous write command. */ if (s95_wait_ready(3)) return -1; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0xC7, programmerType); SPI_CONTROLLER_Write_One_Byte(0x94, programmerType); SPI_CONTROLLER_Write_One_Byte(0x80, programmerType); SPI_CONTROLLER_Write_One_Byte(0x9A, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); at45_wait_ready(950); return 0; } int at45_sector_erase(unsigned int sectorNumber, unsigned int pageSize, u8 progType) { u32 send_addr = 0; unsigned char fullLen = 0x0c; programmerType = progType; if (pageSize > 511) fullLen++; send_addr = sectorNumber << fullLen; /* Wait until finished previous write command. */ if (at45_wait_ready(1)) return -1; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x50, programmerType); //block erase command SPI_CONTROLLER_Write_One_Byte((send_addr >> 16) & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte((send_addr >> 8) & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte(send_addr & 0xff, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); at45_wait_ready(1); return 0; } static int nand_read_main_sr(u8 *val) { int retval = 0; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x0f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xc0, programmerType); //main status / feature register address retval = SPI_CONTROLLER_Read_NByte(val, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { printf("%s: ret: %x\n", __func__, retval); return retval; } return 0; } int nand_wait_ready(int sleep_ms) { int count; int sr = 0; /* one chip guarantees max 5 msec wait here after page writes, * but potentially three seconds (!) after page erase. */ for (count = 0; count < ((sleep_ms + 1) * 1000); count++) { if ((nand_read_main_sr((u8 *)&sr)) < 0) break; //error reading status register if ((sr & 1) == 0) return 0; // BUSY=0 udelay(500); /* REVISIT sometimes sleeping would be best */ } printf("%s: read_sr fail: %x\n", __func__, sr); return -1; } int nand_page_read(unsigned char *buf, unsigned int page_size, uint32_t sector_number) { int retval; unsigned char cmdbuf[4]; cmdbuf[0] = 0x13;//From sector to chip buffer cmdbuf[1] = (sector_number >> 16) & 0xff; cmdbuf[2] = (sector_number >> 8) & 0xff; cmdbuf[3] = sector_number & 0xff; nand_wait_ready(100); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_NByte(cmdbuf, 4, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); nand_wait_ready(100); cmdbuf[0] = 0x03;//Reading from buffer cmdbuf[1] = 0x00; cmdbuf[2] = 0x00; cmdbuf[3] = 0x00; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_NByte(cmdbuf, 4, SPI_CONTROLLER_SPEED_SINGLE, programmerType); retval = SPI_CONTROLLER_Read_NByte(buf, page_size, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); return retval; } int nand_read_devid(u8 *rxbuf, int n_rx, uint8_t progType) { int retval = 0; programmerType = progType; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(OPCODE_RDID, programmerType); SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); retval = SPI_CONTROLLER_Read_NByte(rxbuf, n_rx, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval) { printf("%s: ret: %x\n", __func__, retval); return retval; } return 0; } void nand_write_enable(void) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(OPCODE_WREN, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } static inline void nand_write_disable(void) { SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(OPCODE_WRDI, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); } int nand_block_erase(unsigned int sector_number, unsigned int blockSize, u8 progType) { /* Wait until finished previous write command. */ if (nand_wait_ready(950)) return -1; sector_number = sector_number << 6; // PA[15:6] is the address for 128KB blocks (total 1,024 blocks), PA[5:0] is //the address for 2KB pages (total 64 pages for each block) nand_write_enable(); nand_unprotect(programmerType); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0xd8, programmerType); SPI_CONTROLLER_Write_One_Byte((sector_number >> 16) & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte((sector_number >> 8) & 0xff, programmerType); SPI_CONTROLLER_Write_One_Byte(sector_number & 0xff, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); //nand_write_disable(); return 0; } int nand_page_write(unsigned char *buf, unsigned int page_size, uint32_t sector_number) { int retval; unsigned char cmdbuf[4]; if (nand_wait_ready(950)) return -1; nand_write_enable(); cmdbuf[0] = 0x02; //From PC to buffer cmdbuf[1] = 0x00; cmdbuf[2] = 0x00; SPI_CONTROLLER_Chip_Select_Low(programmerType); retval = SPI_CONTROLLER_Write_NByte(cmdbuf, 3, SPI_CONTROLLER_SPEED_SINGLE, programmerType); if (retval == -1) return retval; retval = SPI_CONTROLLER_Write_NByte(buf, page_size, SPI_CONTROLLER_SPEED_SINGLE, programmerType); if (retval == -1) return retval; SPI_CONTROLLER_Chip_Select_High(programmerType); nand_wait_ready(200); nand_write_enable(); cmdbuf[0] = 0x10; //From buffer to chip cmdbuf[1] = (sector_number >> 16) & 0xff; cmdbuf[2] = (sector_number >> 8) & 0xff; cmdbuf[3] = sector_number & 0xff; SPI_CONTROLLER_Chip_Select_Low(programmerType); retval = SPI_CONTROLLER_Write_NByte(cmdbuf, 4, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); return retval; } int nand_block_read(unsigned char *buf, unsigned int page_size, uint32_t block_number, unsigned int pages_per_block, uint8_t progType) { int retval; unsigned int i; uint32_t secNumber; programmerType = progType; for (i = 0; i < pages_per_block; i++) { secNumber = block_number * pages_per_block + i; retval = nand_page_read(&buf[i * page_size], page_size, secNumber); if (retval == -1) return retval; } return 0; } int nand_block_write(unsigned char *buf, unsigned int page_size, uint32_t block_number, unsigned int pages_per_block, u8 progType) { int retval; unsigned int i; uint32_t secNumber; programmerType = progType; for (i = 0; i < pages_per_block; i++) { secNumber = block_number * pages_per_block + i; retval = nand_page_write(&buf[i * page_size], page_size, secNumber); if (retval == -1) return retval; } return 0; } void nand_unprotect(u8 progType) { programmerType = progType; nand_write_enable(); u8 prot_reg; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x0f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xa0, programmerType); SPI_CONTROLLER_Read_NByte(&prot_reg, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(1); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x1f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xa0, programmerType); SPI_CONTROLLER_Write_One_Byte(prot_reg & 0x83, programmerType); //set to 0 bytes 6,5,4,3,2 SPI_CONTROLLER_Chip_Select_High(programmerType); } void nand_ECCEnable(u8 progType) { u8 val; programmerType = progType; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x0f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); SPI_CONTROLLER_Read_NByte(&val, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(2); nand_write_enable(); //val = val | 0x10; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x1f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); SPI_CONTROLLER_Write_One_Byte(val | 0x10, programmerType); //set to 1 byte 4 SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(2); } void nand_ECCDisable(u8 progType) { u8 val; programmerType = progType; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x0f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); SPI_CONTROLLER_Read_NByte(&val, 1, SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(2); nand_write_enable(); //val = val | 0x10; SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x1f, programmerType); SPI_CONTROLLER_Write_One_Byte(0xb0, programmerType); SPI_CONTROLLER_Write_One_Byte(val & 0xef, programmerType); //set to 1 byte 4 SPI_CONTROLLER_Chip_Select_High(programmerType); usleep(2); } int nand_checkBadBlock(uint32_t blockNo, uint32_t sectSize, uint32_t blockPerSector, u8 progType) { int retval; // Return: -1 - error operation, 0 - good block, 1 - bad block unsigned char buf[2]; uint32_t sectNo; sectNo = blockNo * blockPerSector; programmerType = progType; nand_wait_ready(950); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x13, programmerType); SPI_CONTROLLER_Write_One_Byte((0xff0000 & sectNo) >> 16, programmerType); SPI_CONTROLLER_Write_One_Byte((0x00ff00 & sectNo) >> 8, programmerType); SPI_CONTROLLER_Write_One_Byte(0x0000ff & sectNo, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); //usleep(1000); nand_wait_ready(950); SPI_CONTROLLER_Chip_Select_Low(programmerType); SPI_CONTROLLER_Write_One_Byte(0x03, programmerType); SPI_CONTROLLER_Write_One_Byte((0x00ff00 & sectSize) >> 8, programmerType); //high address SPI_CONTROLLER_Write_One_Byte(0x0000ff & sectSize, programmerType); //low address SPI_CONTROLLER_Write_One_Byte(0x00, programmerType); //dymmy byte retval = SPI_CONTROLLER_Read_NByte(buf,2,SPI_CONTROLLER_SPEED_SINGLE, programmerType); SPI_CONTROLLER_Chip_Select_High(programmerType); if (retval == -1) return retval; if (buf[0] == 0xff) return 0; else return 1; } imsprog-1.8.5/IMSProg_programmer/timer.c000066400000000000000000000023471520775651600202300ustar00rootroot00000000000000/* * Copyright (C) 2021 McMCC * timer.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. */ #include #include #include "timer.h" static time_t start_time = 0; static time_t print_time = 0; void timer_start(void) { start_time = time(0); } void timer_end(void) { time_t end_time = 0, elapsed_seconds = 0; time(&end_time); elapsed_seconds = difftime(end_time, start_time); printf("Elapsed time: %d seconds\n", (int)elapsed_seconds); print_time = 0; } int timer_progress(void) { time_t end_time = 0; int elapsed_seconds = 0; if (!print_time) print_time = time(0); time(&end_time); elapsed_seconds = (int)difftime(end_time, print_time); if (elapsed_seconds == 1) { print_time = 0; return 1; } return 0; } /* End of [timer.c] package */ imsprog-1.8.5/IMSProg_programmer/timer.h000066400000000000000000000013401520775651600202250ustar00rootroot00000000000000/* * Copyright (C) 2021 McMCC * timer.h * * 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. */ #ifndef __TIMER_H__ #define __TIMER_H__ void timer_start(void); void timer_end(void); int timer_progress(void); #endif /* __TIMER_H__ */ /* End of [timer.h] package */ imsprog-1.8.5/IMSProg_programmer/types.h000066400000000000000000000015351520775651600202570ustar00rootroot00000000000000/* * Copyright (C) 2018-2021 McMCC * types.h * * 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. */ #ifndef __TYPES_H__ #define __TYPES_H__ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; typedef u16 __le16; typedef u16 __be16; typedef u32 __le32; typedef u32 __be32; #endif /* __TYPES_H__ */ /* End of [types.h] package */ imsprog-1.8.5/LICENSE000066400000000000000000001045151520775651600142360ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. 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 them 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 prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. 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. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey 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; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If 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 convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU 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 that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. 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. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 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. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. 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 state 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program 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, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU 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. But first, please read . imsprog-1.8.5/README.md000066400000000000000000001050471520775651600145110ustar00rootroot00000000000000## IMSProg * [System software requirements](#system-software-requirements) * [How to use](#how-to-use) * [List of supported chips](#list-of-supported-chips) * [Packages](#packages) * [Changelog](ChangeLog) * [Project structure](#project-structure) * [Chip database format](#chip-database-format) * [Licensing](#Licensing) * [Translations](#Translations) **IMSProg** - **I**2C, **M**icroWire and **S**PI EEPROM/Flash chip **Prog**rammer - is a program to read, write EEPROM chips use the `CH341A programmer` device and `CH347T programmer` device. | CH341A/B v1.2 | CH341A v1.7| CH347T v1.0| CH347T v1.1| | :---: | :---: | :---: | :---: | | ![CH341A black](img/ch341_black150.png) ![CH341A green](img/ch341_green150.png) | ![CH341A green](img/ch341v1_7.png) |![CH347T v1.0](img/ch347_150.png) |![CH347T v1.1](img/ch347_v1_1_150.png) | The IMSProg makes respect to [QHexEdit2](https://github.com/Simsys/qhexedit2) hex editor and [SNANDer programmer](https://github.com/McMCCRU/SNANDer). The format of the chip database is based on the format used in EZP2019, EZP2020, EZP2023, Minpro I, XP866+ programmers. Warning, format is not the same! IMSProg is a collection of tools: 1. IMSProg - the chip programmer (it's the main part). 2. IMSProg_editor - chip database editor. 3. IMSProg_database_update - update chip database using external web-server. ![CH341A EEPROM programmer](img/IMSProg_1.png) ![CH341A EEPROM programmer](img/IMSProg.png) ## Compiling project ``` git clone https://github.com/bigbigmdm/IMSProg.git && cd IMSProg sudo ./build_all.sh ``` ## System software requirements ### Linux For build are needed: - g++ or clang - CMake - libusb 1.0 - Qt5 or Qt6 - Qt5LinguistTools or Qt6LinguistTools - pkgconf or pkg-config - udev On Debian and derivatives: - for Qt5: `sudo apt-get install cmake g++ libusb-1.0-0-dev qtbase5-dev qttools5-dev pkgconf` - for Qt6: `sudo apt-get install cmake g++ libusb-1.0-0-dev pkgconf qt6-base-dev qt6-tools-dev linguist-qt6 qt6-l10n-tools qt6-base-dev-tools qt6-tools-dev-tools` On Debian >=13 and Ubuntu >=24.04: `sudo apt-get install systemd-dev` On older: `sudo apt-get install udev` :information_source: Debian < 11 and Ubuntu < 20.04 are not supported, you may unable to have it working on them. On Fedora and derivatives: - for Qt5: ``` sudo dnf install cmake libusb libusb1 libusb1-devel qt5-qtbase-devel sudo dnf install pkgconf-pkg-config qt5-linguist ``` - for Qt6: ``` sudo dnf install cmake gcc-c++ libusb1-devel pkgconf-pkg-config qt6-qtbase-devel sudo dnf install qt6-qttools-devel qt6-linguist ``` On OpenSUSE and derivatiles: - for Qt5: ``` sudo zypper install cmake gcc-c++ libqt5-qtbase-devel sudo zypper install libqt5-linguist-devel libusb-1_0-devel ``` - for Qt6: ``` sudo zypper install cmake gcc-c++ libqt6-qtbase-devel sudo zypper install libqt6-linguist-devel libusb-1_0-devel ``` ### macOS if using Homebrew then Xcode Command Line Tools will install by default, if not then install manually from terminal: ``` xcode-select --install ``` install the required packages using brew: ``` brew install qt@5 libusb cmake pkgconf ``` if not using the [build_all.sh](build_all.sh) script then make sure `libusb` is in your `C_INCLUDE_PATH` ``` export C_INCLUDE_PATH=/usr/local/opt/libusb/include ``` ## How to use: Note: for macOS use CMD `⌘` instead of CTRL for keyboard shortcuts. ## Chip programmer ### Launching Can be launched from Terminal by running the command ``` $ IMSProg ``` ### Connecting - Insert the chip into the appropriate slot of the CH341A programmer. The `24xxx` and `25xxx` series chips must be inserted directly, according to the markings on the PCB of the CH341A programmer. The `93xxx` series chips must be inserted into the `93xxx adapter` and the adapter into the marking `25xxx` programmer slot. The DataFlash `AT45DBxxx` series chips must be mounted in a `SOP-8 DIP-8` and this adapter shall be inserted into the `45xxx` adapter. The `45xxx` adapter must be installed in the programmer slot marked `25xxx`. The SPI NAND Flash chips must be mounted in a `WSON-8 DIP-8` adapter. This adapter must be installed in the programmer slot marked `25xxx`. > [!NOTE] > *In the current version, the MicroWire (93Cxx) protocol is not supported by the CH347 programming device.* > > *CH347T V1.1 - a device with a lower speed than the CH347T V1.0.* ![Adapter](img/93xxx_adapter.png) - If the chip supply voltage is 1.8 volt he must be inserted in `1.8 volt adapter` and the adapter into needed programmer slot. ![Adapter](img/1_8_adapter.png) - Plug the CH341A programmer into the USB socket of your computer and running the `IMSProg`. - You can plug and unplug the programmer device (CH341A) to the USB port at any time when basic operations (reading, checking, and programming) are not in progress. - Read more about adapters [here](https://github.com/bigbigmdm/Tools_for_CH341A_programmer?tab=readme-ov-file#Homemade-Chip-adapters). ### Chip type selecting Select the type of chip used from the `Type` pop-up menu: `SPI_FLASH` when using SPI NOR FLASH chips of the `25xxx` series, `SPI_NAND` when using SPI NAND FLASH chips, `24_EEPROM` when using I2C EEPROM of the `24xxx` series, `93_EEPROM` when using MicroWire EEPROM of the `93xxx` series, `45_EEPROM` when using DataFlash chips `AT45DBxxx` series. When using `25xxx` series SPI NOR FLASH chips (Menu item `type` -> `SPI_FLASH`), or SPI NAND FLASH chips (Menu item `type` -> `SPI_NAND`), or `AT45DBxx` series SPI FLASH (Menu item `type` -> `45_EEPROM`) the `Detect` button will be available. When the `Detect` button or ![Detect](img/test64.png) or `` is pressed, the JEDEC information is read from the chip and all parameters of that chip are loaded from the chip database. Any parameter (`size`, `page size`, `block size`, `VCC voltage`, `and 4-bit address length`) can be changed manually. You can manually enter the `Manufacture` and `Name` pop-up menu data - all other parameters will be automatically loaded from the chip database. When using `24xxx` or `93xxx` or `95xxx` or `25xxx` SPI EEPROM (non NOR FLASH) series chips, it is necessary to manually enter the `Manufacture` and `Name` pop-up menu data - all other parameters will be automatically loaded from the chip database. ### File operations - The ![Save](img/save64.png) or `` button is used to save the computer buffer to a file. - The ![Open](img/open64.png) or `` button is used to save the file in the computer buffer. - The ![SavePart](img/saveBlock64.png) or `` button is used to save a part of the computer buffer to a file (the start address and length of the part must be entered). This operation can be used when splitting a binary data image into parts. - The ![LoadPart](img/loadBlock64.png) or `` button is used to load a small file to a certain address in the buffer. The data fragment in the buffer will be replaced with new data from the file. - The ![Edit](img/chipEdit64.png) or `` button is used to invoke the chip database editor. - The menu item `File / Import from Intel HEX` is used to save the Intel HEX file in the computer buffer. - The menu item `File / Export to Intel HEX` is used to save the computer buffer to a file in Intel HEX format. ### Basic programmer operations - Pressing `Read` or ![Read](img/read64.png) or `` to read data from the chip into the computer buffer. - Pressing ![Write](img/write64.png) or `` to write data from the computer buffer into the chip. - Pressing ![Erase](img/erase64.png) or `` will erase all data in the chip. - By selecting `Main Menu -> Chip -> Check erase` or pressing ``, you can check whether all data has been correctly deleted from the chip. - Pressing the ![Verify](img/verify64.png) or `` button causes the data in the chip and in the computer buffer to be compared. The progress bar shows the progress of the read, erase, and verify operations. - The `Auto` button is used to perform erase, check erase, write and verify operations in sequence. If one of these operations is not needed, you can uncheck the checkbox for that operation. - The ![Stop](img/stop64.png) or `` key is used to force interruption of chip read/write/erase/verify operations. - The `i` key show the connection chip to CH341A device image form. - The `Main menu -> Chip -> Chip info` or `` item shows the Serial Flash Discoverable Parameter (SFDP) register and the status registers of the SPI NOR flash memory chips. ![SFDP](img/sfdp_unblock_en.png) If the SPI NOR FLASH chip is detected normally, but is not read (gives the message `Error reading sector 0`), then in the `Chip info` window you can change bits `BP4` and `BP3` to zero and press the `Write registers` button. Then repeat the chip reading operation. ![SFDP](img/sfdp_unblock_en2.png) If the SPI NOR FLASH chip is read unreliably (with a different checksum each time) and `Status Register 2` is available in the chip, you can change bits `DRV0` and `DRV1` to zero and press the Write Registers button. This will increase the power of the output stage of the `DO` pin of the chip. Then repeat the chip read operation. For `25xxx`, `95xxx` and `45xxx` series chips that have only one status register, the `Chip info` form is as follows: ![SFDP](img/sr0_en.png) For `SPI NAND FLASH` chips the `Chip info` form is as follows: ![SFDP](img/sr_nand_en.png) - The `Main menu -> Chip -> Security Registers` or `` item is used to work with `SPI NOR Flash` and `SPI NAND FLASH` security registers data. This form allows reading, write, erase, save and load security register data from the computer. ![Security registers](img/Security_registers_form.png) The buttons at the bottom of the form (![Read](img/read64.png), ![Erase](img/erase64.png), ![Write](img/write64.png), ![Open](img/open64.png), ![Save](img/save64.png)) perform a similar function to the top buttons on the main form. The `Security register number:` drop-down menu allows you to select one of the valid registers for the current chip for operation. The security registers can be locked for writing forever. If you want to know about this, please see `Main Menu -> Chip -> Chip Information` item or , data fields in `LB3`, `LB2` and `LB1` in `Status register 1`. Please refer to the datasheet of your chip for detailed information. For NAND FLASH chips you can scanning bad blocks, use `Main Menu -> Chip -> Bad block management` or `` key. ![Bad block scan](img/bbm_chip_scan_en.png) For these chips, you can also change the erase and write parameters in this menu. ![Bad block scan](img/bbm_settings_en.png) > [!NOTE] > *In this version of IMSProg, damaged blocks are not skipped when executing the > `Verify` and `Check erase` functions for NAND Flash chips. If your chip > contains damaged blocks, please do not use these functions.* ### Buffer (Hex editor) operations The hexadecimal chip editor (right side of the screen) is used to display and modify buffer data. It contains the following controls: ![Undo](img/undo64.png) undo, ![Redo](img/redo64.png) redo, and the ![Search](img/hexsearch64.png) search/replace. The `[Ctrl+A]` key used to update the CRC24 checksum. The `[Ctrl+G]` key used to move the cursor to the entered address. The `[Ctrl+L]` key is used to fill the hex editor buffer with a special test array. The `[Ctrl+K]` key is used to fill the hex editor buffer with a user code. The `[Ctrl+M]` key used for compares the results of the last and penultimate chip read or file open operation. ![compare](img/compare_files_en.png) ### Programmer type The `Main menu -> Programmer` item is used to change the programmer type. ### List of hotkeys: | Hotkey | Function | | :--- | :--- | | Ctrl+A | Checksum calculate | | Ctrl+B | Bad block management for NAND chips | | Ctrl+C | Copy selected bytes (Hex editor) | | Ctrl+D | Detect chip | | Ctrl+E | Erase chip | | Ctrl+F | Find/Replace (Hex editor) | | Ctrl+G | Goto address (Hex editor) | | Chrl+H | About IMSProg | | Ctrl+I | Force stop chip operation | | Ctrl+J | Check erase chip | | Ctrl+K | Fill the user code (Hex editor) | | Ctrl+L | Fill the test array (Hex editor) | | Ctrl+M | Compare files (Hex editor) | | Ctrl+N | Edit chip database | | Ctrl+O | Open file | | Ctrl+P | Chip info (SFDP + status registers) | | Ctrl+Q | Exit | | Ctrl+R | Read chip | | Ctrl+S | Save file | | Ctrl+T | Verify chip | | Ctrl+U | Security registers | | Ctrl+V | Paste selected bytes (Hex editor) | | Ctrl+W | Write chip | | Ctrl+X | Exit | | Ctrl+Y | Redo (Hex editor) | | Ctrl+Z | Undo (Hex editor) | ## Chip database editor ![Chip editor](img/chip_editor_eng.png) Chip base editor - IMSProg_editor is a stand-alone program that can be launched from the `Development` menu or from the IMSProg program by clicking on ![Edit](img/chipEdit64.png). All operations in the editor become available only after loading a chip base file with .Dat extension. Menu `File`. - `Open` or `[Ctrl+O]` or ![open](img/open.png) allows you to load the data file. - `Save` or `[Ctrl+S]` or ![save](img/save.png) saves the chip parameter table to a database file. - `Exit` or `[Ctrl+X]` or ![exit](img/exit.png) - exits the editor. - `Export to CSV format` or `[Ctrl+X]` or ![export](img/tocsv.png) allows to unload data about chips in CSV format for further processing by spreadsheet software - LibreOffice Calc, OpenOffice Calc, Google Tables, etc. - `Import from CSV file` or `[Ctrl+Shift+X]` or ![import](img/import.png) - loads a table in CSV format and adds data from it to the existing data in the table. Menu `Edit`. - `Delete Rows` or `Del` or ![delete](img/del.png) - deletes one or more rows. - `Add Row` or `Ins` or ![add](img/plus.png) - adds a row below the selected row and copies all data from the selected row to the new row. - `Move Up` or '[Ctrl+Up]` or ![up](img/undo.png) - moves the selected line up. - `Move Down' or `[Ctrl+Down]` or ![down](img/redo.png) - moves the selected row down. - `Import selected rows to CSV format` or ![import](img/import.png) - saves selected rows to CSV file. The most recent version of the chip database file can be downloaded from this page in both .Dat and .csv formats. ## Chip updater Once IMSProg_database_update app has been run, the downloaded database is copied to the ~/.local/share/imsprog folder. The script then displays the number of chips in the database before and after the update. ## List of supported chips ### I2C EEPROM 24C01, 24C02, 24C04, 24C08, 24C16, 24C32, 24C64, 24C128, 24C256, 24C512, 24C1024, 24M02 ### I2C FeRAM - RAMXEED MB85RC04, MB85RC16, MBRC64, MB85RC128, MB85RC256, MB85RC512, MB85RC1MT - RAMTRON FM24C04A, FM24C16A, FM24C32A, FM24C64A, FM24C128, FM24C256, FM24C512, FM24CL04A, FM24CL16A, FM24CL32A, FM24CL64A ### MicroWire EEPROM (only for CH341A programmer) 93C46, 93C56, 93C66, 93C76, 93C86 ### Serial SPI Bus EEPROM - ST M95010, M95020, M95040, M95080, M95160, M95320, M95640, M95128, M95256, M95512, M95M01, M95M02 - ATMEL AT25010, AT25020, AT25040, AT25080, AT25160, AT25320, AT25640, AT25128, AT25256, AT25F512, AT25F1024, AT25F2048, AT25F4096 - MICROCHIP 25AA010, 25AA020, 25AA040, 25AA080, 25AA160, 25AA320, 25AA640, 25AA128, 25AA256, 25AAF512, 25AAF1024, 25LC010, 25LC020, 25LC040, 25LC080, 25LC160, 25LC320, 25LC640, 25LC128, 25LC256, 25LC512, 25LC1024 - ONSEMI CAT25C01, CAT25C02, CAT25C04, CAT25C08, CAT25C16, CAT25C32, CAT25C64, CAT25C128, CAT25C256, CAT25C512 ### Serial SPI Bus FeRAM - RAMXEED MB85RS16N, MB85RD16LX, MB85RS64VY, MB85RS64V, MB85RS128TY, MB85RS128B, MB85RS256TY, MB85RS256LYA, MB85RS256B, MB85RS512TY, MB85RS512LY, MS85RS1MLY, MB85RS1MT, MB85RS2MTY, MB85RS2MLY, MB85RS4MTY, MB85RS4MLY ### DataFlash 45xx - ATMEL AT45DB011, AT45DB021, AT45DB041, AT45DB081, AT45DB161, AT45DB321 - ADESTO AT45DB011, AT45DB021, AT45DB041, AT45DB081, AT45DB161, AT45DB321, AT45DB641 ### SPI NOR Flash - SPANSION FL016AIF, S25FL016P, S25FL032P, FL064AIF, S25FL064P, S25FL256S, S25FL128P, S25FL129P, S25FL204K, S25FL208K, S25FL116K, S25FL132K, S25FL164K - XTX XT25F02E, XT25F04D, XT25F08B, XT25F16B, XT25F32F, XT25F64F, XT25F128F, XT25F256B, XT25W02E, XT25W04D, XT25Q08D(1.8V), XT25Q16D(1.8V), XT25Q64D(1.8V), XT25F128D(1.8V) - ACE ACE25AC512G, ACE25AC100G, ACE25AC200G, ACE25AC400G - EON EN25B10T, EN25B20T, EN25B40T, EN25B80T, EN25B16T, EN25B32T, EN25B64T, EN25P64, EN25Q40A, EN25Q80B, EN25Q16, EN25Q32C, EN25Q64, EN25Q128, EN25F10A, EN25F20A, EN25F40, EN25F80, EN25F16, EN25F32, EN25S10A(1.8V), EN25S20A(1.8V), EN25S40A(1.8V), EN25S80B(1.8V), EN25S16B(1.8V), EN25S64A(1.8V), EN25QE16A, EN25QE32A, EN25E10A, EN25E40A, EN25SE16A(1.8V), EN25SE32A(1.8V), EN25T80, EN25T16, EN25QA32B, EN25QA64A, EN25QA128A, EN25QW16A, EN25QW32A, EN25QH16, EN25QH32B, EN25QH64A, EN25QH128A, EN25Q256, EN25QX64A, EN25QX128A, EN25QX256A, EN25QY256A, EN25SX64A(1.8V), EN25SX128A(1.8V) - ATMEL AT25LS321(1.8V), AT25LS128A(1.8V), AT25LS641(1.8V), AT26DF161, AT25DF321, AT25DF641 - MICRON M25P10, M25P20, M25P40, M25P80, M25P016, M25P32, M25P64, M25P128, N25Q032A, N25Q064A, MT25QL64AB, N25Q128A, MT25QL128AB, N25Q256A, MT25QL256AB, MT25QL512AB, N25Q032A(1.8V), N25Q064A(1.8V), MT25QU64AB(1.8V), N25Q128A(1.8V), MT25QU128AB(1.8V), MT25QU256AB(1.8V), MT25QU512AB(1.8V) - XMC XM25QH10B, XM25QH20B, XM25QH40B, XM25QH80B, XM25QH16C, XM25QH32B, XM25QH64C, XM25QH128C, XM25QH256C, XM25QH512C, XM25LU64C(1.8V), XM25LU128C(1.8V), XM25QU256C(1.8V), XM25QU512C(1.8V), XM25QW16C, XM25QW32C, XM25QW64C, XM25QW128C, XM25QW256C, XM25QW512C, XM25QU41B(1.8V), XM25QU80B(1.8V), XM25QU16C(1.8V), XM25LU32C(1.8V), XM25QH32A, XM25QH64A, XM25QH128A - AMIC AT25L05P, A25L10PU, A25L20PU, A25L40PU, A25L80PU, A25L16PU, A25L10PT, A25L20PT, A25L40PT, A25L80PT, A25L16PT, A25L010, A25L020, A25L040, A25L040, A25L080, A25L016, A25L032, A25LQ080, A25LQ16, A25LQ32, A25LQ64 - EXCELSEMI ES25P10, ES25P20, ES25P40, ES25P80, ES25P16, ES25P32, ES25M40A, ES25M80A, ES25M16A - DOUQI DQ25Q64AS - Zbit ZB25LD10A(1.8V), ZB25LD20A(1.8V), ZB25LD40B(1.8V), ZB25LD80(1.8V), ZB25D10A, ZB25D20A, ZB25D40B, ZB25D80B, ZB25VQ16, ZB25VQ32, ZB25VQ64, ZB25VQ128, ZB25LQ16(1.8V), ZB25LQ32(1.8V), ZB25LQ64(1.8V), ZB25LQ128(1.8V), ZB25VQ20A, ZB25VQ40A, ZB25VQ80A, ZB25VQ16A, ZD25D20, ZD25D40, ZD25D80 - ONSemi LE25U20AMB, LE25U40CMC - Boya BY25Q05AW, BY25Q10AW, BY25Q20BL(1.8V), BY25Q40BL, BY25Q80AW(1.8V), BY25Q16BL(1.8V), BY25D05AS, BY25D10AS, BY25D20AS, BY25D40AS, BY25Q80BS, BY25Q16BS, BY25Q32BS, BY25Q64AS, BY25Q128AS, BY25Q256ES, BY25Q10AL(1.8V), BY25Q20AL(1.8V), BY25Q40AL(1.8V), BY25Q32AL(1.8V), BY25Q64AL(1.8V), BY25Q128EL(1.8V) - PFLASH Pm25LQ512B, Pm25LQ010B, Pm25LD020, Pm25LQ020B, PM25LQ016, PM25LQ032, PM25LQ064, PM25LQ128, Pm25LV010, Pm25LV020, Pm25LQ040B, Pm25LV040 - Puya P25Q06H, P25Q40H, PY25Q128HA, PY25Q256HB, PY25Q512HB, P25Q11H, P25Q21H, P25Q10H, P25Q20H, P25Q80H, P25Q16H, P25Q32H, P25Q64H, P25Q128H - ESMT F25L004A, F25L008A, F25L016, F25L032, F25L064, F25L16QA, F25L32QA, F25L64QA - ISSI IS25WQ020(1.8V), IS25WQ040(1.8V), IS25WQ080(1.8V), IS25LQ010, IS25LQ020, IS25LP040E, IS25LP080D, IS25LP016D, IS25LP032D, IS25LP064D, IS25LP128F, IS25LP256D, IS25LP512D, IS25WP512E(1.8V), IS25WP010E(1.8V), IS25WP020E(1.8V), IS25WP040D(1.8V), IS25WP080D(1.8V), IS25WP016D(1.8V), IS25WP032D(1.8V), IS25WP064D(1.8V), IS25WP128F(1.8V), IS25WP256D(1.8V), IS25WP512D(1.8V) - Fudan FM25W02, FM25W04, FM25W16, FM25W32, FM25W64, FM25W128, FM25F005, FM25F01B, FM25F02A, FM25F04A, FM25Q04, FM25Q08, FM25Q16, FS25Q32, FS25Q64, FS25Q128 - Zetta ZD25Q64B, ZD25LQ128(1.8V), ZD25LQ64(1.8V), ZD25WD20B, ZD25WD40B, ZD25Q80C, ZD25Q16B, ZD25Q32C - PCT PCT25VF016B, PCT25VF032B, PCT25VF064C, PCT25VF020B, PCT25VF040B, PCT25VF080B, PCT26VF016, PCT26VF032, PCT25VF010A - MXIC MX25L512E, MX25L1006E, MX25L2005, MX25L4005A, MX25L8005M, MX25L1605D, MX25L3205D, MX25L6405D, MX25L12805D, MX25L25635E, MX25L51245G, MX25L5121E, MX25L1021E, MX25L1633E, MX25L1635E, MX25U5121E(1.8V), MX25U1001E(1.8V), MX25U2035F(1.8V), MX25U4035F(1.8V), MX25U80356(1.8V), MX25U1632F(1.8V), MX25U3232F(1.8V), MX25U6432F(1.8V), MX25U12832F(1.8V), MX25U25643G(1.8V), MX25U51245G(1.8V), MX25L1655D, MX25L6455E, MX25L12855E, MX25L25655E, MX25R1035F, MX25R2035F, MX25R4035F, MX25R8035F, MX25R1635F, MX25R3235F, MX25R6435F, MX25L3225D, MX25L3255D - Giantec GT25D05C, GT25D10C, GT25D20C, GT25Q40C, GT25D05E, GT25D10E, GT25D20E, GT25Q80A, GT25Q16A, GT25Q32A-H, GT25Q64A-S - GigaDevice GD25F40, GD25F80, GD25D40, GD25D80, GD25D05C, GD25D10C, GD25Q20C, GD25Q40C, GD25Q80C, GD25Q16C, GD25Q32, GD25Q64CSIG, GD25Q128CSIG, GD25Q256CSIG, GD25VQ21B, GD25VQ40C, GD25VQ80C, GD25VQ16C, GD25LD05C(1.8V), GD25LD10C(1.8V), GD25LD20C(1.8V), GD25LD40C(1.8V), GD25LQ80C, GD25LQ16C, GD25LQ32E, GD25LQ64E(1.8V), GD25LQ128(1.8V), GD25LQ256D(1.8V), GD25WD05C, GD25WD10C, GD25WD20E, GD25WD40E, GD25WD80C, GD25WQ20E, GD25WQ40E, GD25WQ80E, GD25WQ16E, GD25WQ32E, GD25WQ64E, GD25WQ128E, GD25WB256E, GD25LB512ME(1.8V), YC25Q128 - Nantronix N25S80, N25S32 - PARAGON PN25F08, PN25F16, PN25F32, PN25F64, PN25F128 - DOSILICON DS25Q64A, DS25Q4AA, DS25M4CB, DS25M64E, DS25M4AE, DS25M4AB, DS25M4BA - WINBOND W25P80, W25P16, W25P32, W25P64, W25X05, W25X10, W25X20, W25X40, W25X80, W25X16, W25X32VS, W25X64, W25Q05CL, W25Q10Cl, W25Q20CL, W25Q40BV, W25Q80BL, W25Q16DV, W25Q32BV, W25Q64BV, W25Q128BV, W25Q256FV, W25Q20BW(1.8V), W25Q80, W25Q10EW(1.8V), W25Q20EW(1.8V), W25Q40EW(1.8V), W25Q80EW(1.8V), W25Q16JW(1.8V), W25Q32FW(1.8V), W25Q64DW(1.8V), W25Q128FW(1.8V), W25Q256JW(1.8V), W25M512JW(1.8V), W25Q512JV, W25M512JV, W25Q32JW(1.8V) - Fidelix FM25Q04A, FM25Q08A, FM25Q16A, FM25Q32A, FM25Q64A, FM25Q128A, FM25M04A(1.8V), FM25M08A(1.8V), FM25M16A(1.8V), FM25M32A(1.8V), FM25M64A(1.8V), FM25M4AA(1.8V) - UCUNDATA (UCUN Technology) UC25HQ05, UC25HQ10, UC25HQ20, UC25HQ40, UC25HQ80, UC25HQ16, UC25HQ32, UC25HQ64, UC25IQ128 ### SPI NAND Flash - ESMT F50L2G41XA, F50L1G41LB(2M), F50L512M41A, F50L4G41XB - MICRON MT29F4G01ABBFD12, MT29F4G01ABAFD12, MX35LF1G24AD-Z41, MX35LF2G24AD-Z41 - MXIC MX35LF4G24AD-Z41, MX35LF2G24AD-Z418, MX35LF4G24AD-Z418, MX35LF1GE4AB, MX35UF1G24AD-Z4I, MX35UF2G24AD-Z4I, MX35UF4G24AD-Z4I, MX35UF2G24AD-Z4I8, MX35UF4G24AD-Z4I8, MX35UF1G14AC, MX35UF2G14AC, MX35UF1GE4AC, MX35UF2GE4AC, MX35UF1GE4AD, MX35UF2GE4AD, MX35UF4GE4AD, MX35LF2GE4AD, MX35LF4GE4AD - WINBOND W25N512GW, W25N512GV, W25N01KW, W25N01KV, W25N01JW, W25N01GW, W25N01GV, W25N02KW, W25N02KV, W25N02JW, W25N04LW, W25N04KW, W25N04KV - XTX XT26G01C, XT26G01A, XT26G01D, XT26G11C, XT26G11D, XT26Q01D, XT26G02D, XT26G02C, XT26G12D-B, XT26Q02D, XT26Q04D XTX XT26Q14D - Dosilicon DS35Q12B, DS35M12B, DS35Q12C, DS35M12C, DS35Q1GA, DS35M1GA, DS35Q1GB, DS35M1GB, DS35Q2GA, DS35M2GA, DS35Q2GB, DS35M2GB, DS35Q2GBS, DS35M2GBS, DS35Q4GM, DS35Q4GM, DS35Q4GB, DS35M4GB - ZETTA ZD35Q1GC-IB - FORESEE F35SQA001G, F35SQB004G, F35SQA512M, F35UQA002G, F35SQA002G, GD5F1GQ5UExxG - GigaDevice GD5F1GQ5RExxG, GD5F1GM7UExxG, GD5F1GM7RExxG, GD5F1GM9UExxG, GD5F1GM9RExxG, GD5F1GQ4UFxxG, GD5F1GQ4RFxxG, GD5F1GQ4UAxxG, GD5F2GQ5UExxG, GD5F2GQ5RExxG, GD5F2GM7UExxG, GD5F2GM7RExxG, GD5F4GQ6UExxG, GD5F4GQ6RExxG, GD5F4GM8UExxG, GD5F4GM8RExxG, GD5F1GQ4UExxG, GD5F1GQ4RExxG, GD5F1GQ4UFxxS, GD5F1GQ4RFxxS, GD5F2GQ4UExxG, GD5F2GQ4RExxG The latest version of the chip database can be found [here](https://antenna-dvb-t2.ru/dl_all/IMSProg.Dat). You can download it and copy it to the ~/.local/share/imsprog folder: `cp IMSProg.Dat ~/.local/share/imsprog` ## Packages - There is a work in progress for add IMSProg to official `Debian` (and derivatives repositories) For some Ubuntu versions you can use this PPA by adding `ppa:bigmdm/imsprog` to your system's Software Sources. ``` sudo add-apt-repository ppa:bigmdm/imsprog sudo apt update sudo apt install imsprog ``` Is also possible manually build deb package using `debian/latest` branch. - For some versions of Fedora, you can use the official repositories. ``` sudo dnf install imsprog ``` Packaging status - The `RPM package` by [Red Soft](https://redos.red-soft.ru/) can be downloaded [here](http://repo.red-soft.ru/redos/7.3/x86_64/updates/) - The `RPM package` by [ALT Linux](https://packages.altlinux.org/en/sisyphus/srpms/IMSProg/) - The `RPM package` by [ROSA Linux](https://mirror.rosalinux.ru/rosa/rosa2021.1/repository/x86_64/contrib/release/) - The `ARCH AUR repository` by [kjkent](https://github.com/kjkent) is [here](https://aur.archlinux.org/packages/imsprog) - The `openSUSE` package is [here](https://software.opensuse.org/package/IMSProg?search_term=imsprog) - The `Debian` package is [here](https://tracker.debian.org/pkg/imsprog) - The Windows release by [Anime4000](https://github.com/Anime4000) is [here](https://github.com/Anime4000/IMSProg/releases/latest) ## Project structure ``` IMSProg _files_ _folder_ ================================================================================ IMSProg /usr/bin IMSProg_editor /usr/bin IMSProg_database_update /usr/bin IMSProg_programmer/database/IMSProg.Dat /usr/share/imsprog ~/.local/share/imsprog IMSProg_programmer/other/71-CH341.rules /lib/udev/rules.d IMSProg_programmer/other/index.html /usr/share//doc/imsprog/html IMSProg_programmer/language/chipProgrammer_ru_RU.qm /usr/share/imsprog IMSProg_programmer/language/chipProgrammer_es_ES.qm /usr/share/imsprog IMSProg_programmer/language/chipProgrammer_de_DE.qm /usr/share/imsprog IMSProg_programmer/language/chipProgrammer_zH_CN.qm /usr/share/imsprog IMSProg_programmer/language/chipProgrammer_uk_UA.qm /usr/share/imsprog IMSProg_programmer/language/chipProgrammer_hu_HU.qm /usr/share/imsprog IMSProg_programmer/language/chipProgrammer_pt_BR.qm /usr/share/imsprog IMSProg_editor/language/chipEditor_ru_RU.qm /usr/share/imsprog IMSProg_editor/language/chipEditor_de_DE.qm /usr/share/imsprog IMSProg_editor/language/chipEditor_es_ES.qm /usr/share/imsprog IMSProg_editor/language/chipEditor_zh_CN.qm /usr/share/imsprog IMSProg_editor/language/chipEditor_uk_UA.qm /usr/share/imsprog IMSProg_editor/language/chipEditor_hu_HU.qm /usr/share/imsprog IMSProg_editor/language/chipEditor_pt_BR.qm /usr/share/imsprog IMSProg_database_update/language/chipUpdater_ru_RU.qm /usr/share/imsprog IMSProg_database_update/language/chipUpdater_de_DE.qm /usr/share/imsprog IMSProg_database_update/language/chipUpdater_es_ES.qm /usr/share/imsprog IMSProg_database_update/language/chipUpdater_zh_CN.qm /usr/share/imsprog IMSProg_database_update/language/chipUpdater_uk_UA.qm /usr/share/imsprog IMSProg_database_update/language/chipUpdater_hu_HU.qm /usr/share/imsprog IMSProg_database_update/language/chipUpdater_pt_BR.qm /usr/share/imsprog IMSProg_programmer/other/IMSProg.desktop /usr/share/applications IMSProg_programmer/other/IMSProg_editor.desktop /usr/share/applications IMSProg_database_update/other/IMSProg_database_update.desktop /usr/share/applications IMSProg_editor/other/IMSProg_editor.1.gz /usr/share/man/man1 IMSProg_programmer/other/IMSProg.1.gz /usr/share/man/man1 IMSProg_database_update/other/IMSProg_database_update.1.gz /usr/share/man/man1 IMSProg_programmer/img/IMSProg64.png /usr/share/pixmaps IMSProg_database_update/img/IMSProg_database_update.png /usr/share/pixmaps img/chipEdit64.png /usr/share/pixmaps IMSProg_programmer/other/other/io.github.bigbigmdm.imsprog.metainfo.xml /usr/share/metainfo IMSProg_editor/other/other/io.github.bigbigmdm.imsprog_editor.metainfo.xml /usr/share/metainfo IMSProg_database_update/other/io.github.bigbigmdm.imsprog_database_update.metainfo.xml /usr/share/metainfo ``` ## Chip database format IMSProg.Dat file structure: Chip string length: 0x44 (68) bytes; ``` offset Size Value 00 - 2F ASCII Chip type, Name and Manufacture, 0x00 filling 30 1 NOR FLASH Chip Size code / 0x00 - other chips 31 1 NOR FLASH Chip ID Code / 0x00 - other chips 32 1 NOR FLASH Manufacture code / 0x00 - other chips 33 0x00 34 4 Chip Size 35 36 37 38 2 Sector size 39 3A 1 Binary chip type: - 0x00 - SPI NOR FLASH - 0x01 - 24xxx I2C - 0x02 - 93xxx MicroWire - 0x03 - 25xxx SPI EEPROM - 0x04 - 95xxx ST SPI EEPROM - 0x05 - AT45DBxxx SPI EEPROM 3B 1 Algorithm code number: - SPI NOR Flash always 0x00 - I2C (24xxx) 0x?1 - address size 1 byte - I2C (24xxx) 0x?2 - address size 2 bytes - I2C (24xxx) 0x1? - address mask 1 - I2C (24xxx) 0x3? - address mask 3 - I2C (24xxx) 0x7? - address mask 7 - MicroWire (93xxx) - 0x1? - organisation 16 bit - MicroWire (93xxx) - 0x0? - organisation 8 bit - MicroWire (93xxx) - 0x?7 - 7 bit address number - MicroWire (93xxx) - 0x?9 - 9 bit address number - MicroWire (93xxx) - 0x?A - 10 bit address number - MicroWire (93xxx) - 0x?B - 11 bit address number - 95xxx ST SPI EEPROM - 0x01 - 8 bit address - 95xxx ST SPI EEPROM - 0x02 - 16 bit address - 25xxx SPI EEPROM - 0x?0 - 8 bit address - 25xxx SPI EEPROM - 0x?1 - 16 bit address - 25xxx SPI EEPROM - 0x?2 - 24 bit address - 25xxx SPI EEPROM - 0x0? - fill erasing - 25xxx SPI EEPROM - 0x1? - The third bit of the command is used for the high bit of the address - 25xxx SPI EEPROM - 0x2? - erasing with use CHIP FULL ERASE command - 45xxx SPI EEPROM - 0x0? - ATMEL command pattern - 45xxx SPI EEPROM - 0x1? - ADESTO command pattern - 45xxx SPI EEPROM - 0x?9 - 9 bit sector address number - 45xxx SPI EEPROM - 0x?A - 10 bit sector address number - 45xxx SPI EEPROM - 0x?B - 11 bit sector address number - 45xxx SPI EEPROM - 0x?C - 12 bit sector address number - 45xxx SPI EEPROM - 0x?D - 13 bit sector address number - 45xxx SPI EEPROM - 0x?F - 15 bit sector address number - SPI NOR Flash - algorithm number for working with security registers - SPI NAND Flash - algorithm number for reading status and security registers 3C 2 Timing parameter: 3D 3000/1000/500/300/200/100 - NOR FLASH, 4000/2000 - 24xxx, 100 - 93xxx 3E 2 SPI NOR Flash 4bit address type: - 0x?0 - Not used (3 bit address data) - 0x?1 - Used (4 bit address data) - 0x01 - Default 4 bit command using - 0x11 - Winbond algorithm - 0x21 - Spansion algorithm 3F 1 0x00 40 1 SPI NOR FLASH block size in KB (64K = 0x40) 41 1 0x00 42 1 - EEPROM pages 0x01 - 0x04 - For SPI NAND Flash - ECC Size / 64 43 1 VCC 00=>3.3V 01=>1.8V 02=>5.0V 03=>2.5V The end record is 0x44 (68) zero bytes. ``` ## Licensing Copyright (C) 2023 - 2026 Mikhail Medvedev. This project use [GPL-3+ License](https://www.gnu.org/licenses/gpl-3.0.html), some parts taken from project [SNANDer](https://github.com/McMCCRU/SNANDer/commits?author=McMCCRU) are [GPL-2+](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) and from [QHexEdit2](https://github.com/Simsys/qhexedit2) is [LGPL-2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html) and [CH347](https://github.com/981213/ch347-nor-prog/tree/master) parts is [BSD-1-Clause](https://github.com/spdx/license-list-data/blob/main/text/BSD-1-Clause.txt). ## Translations - Hungarian translation by [blackPantherOS](https://github.com/blackPantherOS) - Italian translation by Marino Pasquale and [Giovanni Scafora](https://github.com/giovanni69) - Brasil translation by [Alexandre C. Leite](https://github.com/alexandrecleite) - Ukrainian translation by [Sergey Golovko](https://github.com/cappelikan) - Chinese translation by [Tian-HP](https://github.com/Tian-HP) - German translation by [wucke13](https://github.com/wucke13) - Traditional Chinese translation by [ystartgo](https://github.com/ystartgo) Anyone can add or improve a translation by making a pull request. Translations files are located in: [IMSProg_programmer/language/](https://github.com/bigbigmdm/IMSProg/tree/main/IMSProg_programmer/language) and [IMSProg_editor/language/](https://github.com/bigbigmdm/IMSProg/tree/main/IMSProg_editor/language) and [IMSProg_database_update/language/](https://github.com/bigbigmdm/IMSProg/tree/main/IMSProg_database_update/language) You can also add translation to the desktop files ([IMSProg.desktop](https://github.com/bigbigmdm/IMSProg/blob/main/IMSProg_programmer/other/IMSProg.desktop), [IMSProg_database_update.desktop](https://github.com/bigbigmdm/IMSProg/blob/main/IMSProg_programmer/other/IMSProg_database_update.desktop), [IMSProg_editor.desktop](https://github.com/bigbigmdm/IMSProg/blob/main/IMSProg_editor/other/IMSProg_editor.desktop)), and to the appstream metadata files ([io.github.bigbigmdm.imsprog_editor.metainfo.xml](https://github.com/bigbigmdm/IMSProg/blob/main/IMSProg_editor/other/io.github.bigbigmdm.imsprog_editor.metainfo.xml), [io.github.bigbigmdm.imsprog_database_update.metainfo.xml](https://github.com/bigbigmdm/IMSProg/blob/main/IMSProg_programmer/other/io.github.bigbigmdm.imsprog_database_update.metainfo.xml), [io.github.bigbigmdm.imsprog.metainfo.xml](https://github.com/bigbigmdm/IMSProg/blob/main/IMSProg_programmer/other/io.github.bigbigmdm.imsprog.metainfo.xml)). imsprog-1.8.5/build_all.sh000077500000000000000000000014471520775651600155170ustar00rootroot00000000000000#!/bin/bash if [[ "$EUID" -ne 0 ]] && [[ "$OSTYPE" != "darwin"* ]] then echo "Please run as root! (sudo ./build_all.sh)" exit fi [[ "$OSTYPE" == "darwin"* ]] && export C_INCLUDE_PATH=/usr/local/opt/libusb/include ( cd IMSProg_programmer rm -rf build/ mkdir build/ cmake -S . -B build/ cmake --build build/ --parallel cmake --install build/ rm -rf build/ ) ( cd IMSProg_editor rm -rf build/ mkdir build/ cmake -S . -B build/ cmake --build build/ --parallel cmake --install build/ rm -rf build/ ) ( cd IMSProg_database_update rm -rf build/ mkdir build/ cmake -S . -B build/ cmake --build build/ --parallel cmake --install build/ rm -rf build/ ) # Reloading the USB rules or creating the app bundles for macOS [[ "$OSTYPE" != "darwin"* ]] && udevadm control --reload-rules || ./create_macos_appbundles.sh imsprog-1.8.5/create_macos_appbundles.sh000077500000000000000000000074401520775651600204310ustar00rootroot00000000000000#!/usr/bin/env bash CONTENTSDIR1='IMSProg.app/Contents' CONTENTSDIR2='IMSProg Editor.app/Contents' CONTENTSDIR3='IMSProg Database Update.app/Contents' create_directories() { local CONTENTSDIR=$1 mkdir -p "$CONTENTSDIR/MacOS" mkdir -p "$CONTENTSDIR/Resources" } generate_iconset() { local INPUT_IMG=$1 local OUTPUT_ICONS=$2 mkdir icon.iconset sips -z 16 16 -s format png "$INPUT_IMG" --out icon.iconset/icon_16x16.png sips -z 32 32 -s format png "$INPUT_IMG" --out icon.iconset/icon_16x16@2x.png sips -z 32 32 -s format png "$INPUT_IMG" --out icon.iconset/icon_32x32.png sips -z 64 64 -s format png "$INPUT_IMG" --out icon.iconset/icon_32x32@2x.png sips -z 128 128 -s format png "$INPUT_IMG" --out icon.iconset/icon_128x128.png sips -z 256 256 -s format png "$INPUT_IMG" --out icon.iconset/icon_128x128@2x.png sips -z 256 256 -s format png "$INPUT_IMG" --out icon.iconset/icon_256x256.png sips -z 512 512 -s format png "$INPUT_IMG" --out icon.iconset/icon_256x256@2x.png iconutil -c icns icon.iconset -o "$OUTPUT_ICONS" rm -rf icon.iconset } # Update Info.plist update_plist() { local CONTENTSDIR=$1 local ICON_NAME=$2 local EXECUTABLE_NAME=$3 /usr/libexec/PlistBuddy -c 'Add :CFBundleDevelopmentRegion string English' "$CONTENTSDIR/Info.plist" 1>/dev/null /usr/libexec/PlistBuddy -c "Add :CFBundleIconFile string $ICON_NAME" "$CONTENTSDIR/Info.plist" /usr/libexec/PlistBuddy -c 'Add :CFBundleInfoDictionaryVersion string 6.0' "$CONTENTSDIR/Info.plist" /usr/libexec/PlistBuddy -c 'Add :CFBundlePackageType string APPL' "$CONTENTSDIR/Info.plist" /usr/libexec/PlistBuddy -c 'Add :CFBundleShortVersionString string 0.2' "$CONTENTSDIR/Info.plist" /usr/libexec/PlistBuddy -c 'Add :CFBundleVersion string 0.2-10' "$CONTENTSDIR/Info.plist" /usr/libexec/PlistBuddy -c 'Add :NSPrincipalClass string NSApplication' "$CONTENTSDIR/Info.plist" /usr/libexec/PlistBuddy -c "Add :CFBundleExecutable string $EXECUTABLE_NAME" "$CONTENTSDIR/Info.plist" /usr/libexec/PlistBuddy -c 'Add :LSUIElement bool true' "$CONTENTSDIR/Info.plist" } # Create app launch script create_launch_script() { local CONTENTSDIR=$1 local EXECUTABLE_NAME=$2 local COMMAND=$3 cat << ENDOFSCRIPT > "$CONTENTSDIR/MacOS/$EXECUTABLE_NAME" #!/usr/bin/env bash export PATH=$PATH:/usr/local/bin/IMSProg_editor bash -c "$COMMAND > /dev/null 2>&1 &" ENDOFSCRIPT chmod u+x "$CONTENTSDIR/MacOS/$EXECUTABLE_NAME" } move_app() { local APP_NAME=$1 mv "$APP_NAME" /Applications/"$APP_NAME" } create_imsprog_app() { create_directories "$CONTENTSDIR1" generate_iconset "img/logo_IMSProg.svg" "$CONTENTSDIR1/Resources/IMSProg.icns" update_plist "$CONTENTSDIR1" "IMSProg.icns" "IMSProg" create_launch_script "$CONTENTSDIR1" "IMSProg" "/usr/local/bin/IMSProg" move_app "IMSProg.app" } create_imsprog_editor_app() { create_directories "$CONTENTSDIR2" generate_iconset "IMSProg_editor/img/chipEdit64.png" "$CONTENTSDIR2/Resources/IMSProg_editor.icns" update_plist "$CONTENTSDIR2" "IMSProg_editor.icns" "IMSProg_Editor" create_launch_script "$CONTENTSDIR2" "IMSProg_Editor" "/usr/local/bin/IMSProg_editor" move_app "IMSProg Editor.app" } create_imsprog_database_update_app() { create_directories "$CONTENTSDIR3" generate_iconset "IMSProg_programmer/img/IMSProg_database_update.png" "$CONTENTSDIR3/Resources/IMSProg_database_update.icns" update_plist "$CONTENTSDIR3" "IMSProg_database_update.icns" "IMSProg_database_update" create_launch_script "$CONTENTSDIR3" "IMSProg_database_update" "/usr/local/bin/IMSProg_database_update" move_app "IMSProg Database Update.app" } # Run the functions to create the apps create_imsprog_app > /dev/null create_imsprog_editor_app > /dev/null create_imsprog_database_update_app > /dev/null imsprog-1.8.5/img/000077500000000000000000000000001520775651600137775ustar00rootroot00000000000000imsprog-1.8.5/img/1_8_adapter.png000066400000000000000000002601701520775651600166020ustar00rootroot00000000000000PNG  IHDR,,y}u pHYs   cHRMz%u0`:o_F_IDATxw$u:wOγ9b]dH (P"%QOL^WWl٦|mٲd__KT(Hd "/ؼcO箮\?:l, }zs>sWÐNtntD':D':V':щNtՉNt`uD':D':щ:щNtՉNt`uDXD':D':щ:щNtNt`uDXD':V':щ:щNtNtDXD':wr-h r4n}:D'c %7 Umܼ:D'ԔTrʞEVsEPt_tZjֆl?XB\ֵN)ouKw-R7ch:V'GՔڦԶ3ʼn*y1VjG-؞CRF2]J өQ 2dReD(TUjnK *+^(G[Hqw&S3Cd:}`u{LM\Y.8&55^cU7(*s=!WbfD(B QWE`:D(86KˈN"i@Mֱ=gΖ*Y]NaϱtwQ >:="M5f#3/:Q% M5mVS$fb{W7̳-ŔF'(" yFR5Kk$ҙ:+&H:ΪemcɃ3;2>:] *q7]pz2-PS]+  (Bu[ +W沭/_ Z&bۺVj%1ѡ]|PFD9V3Kd!/XٝO.MtͩRjV'KԔMԶ@?ehDQ5@z$-(+ l  = L){4YgWA_"iFw \<!X::OU)u ;woRSmjHeԈ7,GhSCk%0&o ZϰN|֘-@SM5Z6xS[&-nƂCpUqZp61$e֚C*bGKܯlijin?]8Ku`7/g/q5.@bϰY3Aj5f7\`eK $ՒeDdU&+%U^Vj1U+@ɡa̓A xVI_fPKX8 Y&ˑĉ͝bumm|p- nͩISOQJ qk\ZfZgXq`c_ϰN|)MM rj Hl,G!Us]|j.VRe ֏]ڞE g|U+YT&1>f{ AԸypnmaw;Y>IIɓN0<0C y=Gyq"FjqY2·OGǀjjØ75ֶRS)3JDVX=[ɗ[ ] щG*8e }ײgOƠp{ r<Va_c/=np?|mu29xí_$gza5hW00 ;e`u@M)mT :bFmϒӍ1݀lۢ]%(C(O:U.`56ؿVШuSЦcZOpsnIe(V <<~EKY~=?J<#p~B6z*Szrz,pG8;Q֛Y2oΦTPY>:񷤦v5TW'VҶ'ruCRU5R@HJBѷPbFErP\#}C[TR`߮;o~iIF]ص2(*N%xJS g9=}ku$~piD:^wG]=ť@$6%lQMh VvC'rNaXPSj[/ЭxƓSҙQqXK R>`&LnmtC\+P҇.rz4v2EPY핡Ii1GÌ(H54Pw\ [1YXgG`W;cqhg34ñK({ϟ}u~_z\g|xs峜]3CVta-@0DI?pHj9Y\% hF,h>U:xgiGϰNO cOGf&^Nm;gGˤZԈJCVzѷH6FKRZ\hfx~/<5!MaE$ΐw*\dCQZu[/%{R*wro~zBW^ er걧?i^\`qu<ICخ]\jeL%jT@Owd}C?` _~s*VbJtÌ(|Յm -zfϰNHc,sB_5ǁov%+YU4Y#GVTYayTsY\l!# J$=w2;/er^ruHBu"b^qZ] -qp Bv -Ջjpn.o:;Ǟx/sų>xJxY}8/S\ɳ\ {jQ[iinmLO/e(.z]a,"*Z}?Nu B?y3TptGWGI'Y\/4RD"aPA 58jު➵UF GK{ŒmƀϮ$=6g؁VXr7U͡`Xn`ʶ-jkTs7:Q NE$GDTeW ${RɌsM}w0|ts[CnP#*Ԛ )HjmCxל*+:}`}73<F_ͮ0Wj"i.1'Z\&c͢V[SJ'[5|EQ1P Nrp'O^m{g@p~eeLpSnS\<3jU;VÍd/A!Pt  ]J?/\up 򵧞'[Ss-HD{tȌ0m?=|#7kt%fD̠8D Z)՜пR/?1DBq #*eUTqP76&),No~610MMDZ<>ÿxSMHu#ZeL9wWNG/%3[Ѽ0^pZƈI)=!B,0W^CPQ^Z™]+T5 P$[ L: ,rxx;?| "$z8vS^ڵXYf&)UE]ˆ*Lv%{gTlRuP! Hu7D) Td %8KE"VYY7W_wxʷ_{4aЈu' hRcy h2"=J<&^KR ޽>CȺw]"Kģ*TĉD%!3v!Ri=Cw_}|,%ˆkh蒌(Y); ͉~pqerM] >winIO :3эͥ^PV~eK $T(j K%.;ٷvRojØk+c_~vevۊ %HjU#_YW#JT,pNs *[-rܪ ʄzOFV#jhbN2BQ*. s| \zFv翊E@U,\F 9)5A  "a$Dte/xw?-\]w[s28r'GF`J+߷;o7~GO|¯O7A9ҎD9zQ"]bze&CNJ!]?;ŻzRX&'؉)D+{c@^6)ib$?~P,3|s=~Q.}k9mOU3Gs@uU1!m$8:tyIԊ@Z`ʰGT5 DPE" m .5%<|~_"ӃkH敪/~ޏr3=x7c8ORbfj^7F2?}ynr_,czuG&o{OПsyhcw̰qJb8CfqQܶ{`M0oMVHIuGcW`$oHXN\q޶ݍ?o?y="lbc](ytctVtH 1 _|;v󎛩pj0_gfaHW>0sT*H$?P<~|F~=뾍Zp+aH$1}n=)Uo~ϰTL97?Qud  HUUVe X_-6\Z{dS'7fjj.R]BebR+Vof!@qL(yFL8oo .Pv O{n'μY֮zoc,h:\X/T@ sp.0?sӳ)- "Z\G0] Sg1Ys92_O"#0v|W&ORPU EI+Fz(膊PU1[_ r:A٬_RC y*qϻ׮sha{X cu_9a|Zn%6䅑~&P~+`]o_sx^L3[ni2BDV[^fz9Urp[}CD*݇/}gXp鳿EA I<{ߺ7_{;2䗧#=Lv;QRqvm`ybfMF4<\ۧ+ry^=lzm{F $v=%*WjZZ?} 7;MQIܸdcFĚb(Jw~@3dyW= bEbQ LJ[y~~=V0KrkzF6 p&NK4p_"??c)tM?ik־ypgӍqk}[8;b\~*_j@*C׳Ym\E xUL?_x{_=rLKNzL1Î.,6TSԸfHzL0=:5T\*⡭YX:xlXabN |f54E囧07CnSx{ox7_xӥY#KjZuv/ª]K':lD[H*C6<<]7w96KtFCccӷTeêeUu kk`/ھ ۷j'JO0C];8;sIJuʈB2ӍVů k/< ?w@DJÓr5=?\W1B`t5  C}W" 55fsNT:~ƗAN#YiEjZ,<]ˋadw"*r"^3=~47C* ⾧V&s>W8}*1JHPӋbqu %5CAϭc},喱lw%\rk6}v s!G˼ Lc ?SIKY T LsFThRдx3Νۿ~&i\g!"H"!~LF"AKyN5@ +L-,K:*1~$ʄKhS5I$#izJU˹k&tT ߵeqYq,E1ϰ|&=*NCQ @RI$+EQ6.sÁ(J""Rˀ\UhݻS{r U6 V`$0(8[\RWLqHۀ~ku;hFR>Cq~p40x>9ͿϿ~ri}-WJeMQE!oUpǡDDӗ s2b/9., iJV,yIP sg&ygXZ*Uv ]GG.9 EFZO1~=R-*6EקL+a;PKr}h-ߐm Y ?w~wwm&Fvpϐq QMe9cmb~u}1VN H[6 }B=v5Z(8+Zn$3=÷9.']Syulnĉvmo]MyJd0p5f*%94 T~^gzqsE̥i/ͫ_396u12'5Krhu_"i{a wVYk dx}/pnq;hW#D[_E>8xGٟgG̖x鑳1rY&jeF.~0`kغf-xTQx]R-SU({<4}p}?/!tfxٖrVl;ֵ*svy8AzcPZB>VF-r4X}TTz hZ\K]| Ә*am'De1Cs?їJ#rpSM}pjra~3~ [NP _{c !͐p@.0hr}R I\6o@+֕Be*K frh cIlo(]S"G>6R${RRHɩW[k._1|;؝ǯ~CIEZ:> P$:?üomrI>%>?{0&lc!g2ԟ`D/3=l㕿ȂUx6T!Z}J5%.~CK y~'ؽg/\Vhm~fp_~̫iNZM++e>Xrzq-TTzӲ̡ujTk)BJS \ ; | 4 u%QtC1ZZqTY)6{Xj5 P`=i&uS%fTjOz`])#. KT@"PwCW_B2ֻud/GYilf_~ GF_ΓBe-Х(֧&{>{VKJlSe|`-gV10XMa7MX-/-q)F_ǷoWc8Fa;lհYxϖn̡Mخ[ 6!u-XvjAw_mg^Vr7m]am5f8xn_sg&^fG 3 մ+D^ C1j TvChNbu:U|-D |@ŸZYՖM&qLaB:XK~+ňipV\bMװ]Qå/P!nxg/{psI#l[(gyaNmAIFxqv8WZg&f!j(qQހM^(Wc˓,,"5tS ]l# fWP.WLXL$Q(fWa_FYmG2e:s!gH"NzXyu4qiiKγVl? ?写VA6)Hs?}G cSm~'m&qs?xkU%7+YsPUծ6+@m>gm! \Pf>ͫ3xÛvZJjg r T]MPs] 25&tK!",lFS,~2~n$MPRN۳yԱzŻXlAP(]@Qt&?x?!NϟSȊmҭ|WNOȌ1ĕNUY |n.>icS(> VeX@ow QI_? 0BUljHd+^Xr䐣(>&gRuvz_GKqa1GWWXMPmkVvVam-G6TDt@UOQm$ԭ,H8ϭvpV&*T,O.IuSLZ+WESV Ucnf}G知VRc!2oH:.^ 2Zku<&1R_04C`%bFfPֳY F f$ĴOӟǧN"_j, }*qs+w-5TV;XzN;p5 ⢤5 Uh )v_ꭀ )שE?D XPe9bp7@sӆrCUD rTm=BDVUaXP\m OHH!&WJYDUjW + qf5=8g"žlbճ9.v)ϭ6g3#<{% gOн˗]/rϽU5~g5j${߉5-Xٺ\մ,>҃N (y7$̅==|'(U8FCE^!U$Meg9efa {~v\c˕*UK5J3X;︋|S<|cCK6"Go<#32>C UEOJ ^Vn4aҿͰj +^=tߡjVli}mOU-N?3a9kb*RS+uVUwX; yl_ +J",z9u@o?U@UxAC:FK{%ַ00O>r/ϋk~ &7WOfH.eŪ2] %H|/^|~~hIUl\X&~R Jz=<4sK@OU !.ge3 U0t#Ɠ 2-]S xop#?#*akUff/NTֵV|솓ow}ڹO~ǟ@i( zk^c&,BU L??wH(fN嫣kZ#5ލR߹LR5X+rkݱdvN"vxeP$~u7BO*/R_ì%GM'R6$U?ەV*T) UP 3{/l.˴4@ŭl˪7]Qm ?p#OZ;&.Fw<bU rJNq.['XP֬9*Ԥk)adQQUf/5PvjJKaAC4>{e!24Ub}| ˧P@6ٙ"n Q(5n߅3"VvWP g)ø|_~4?{ۍ}f>9rFP`è'O^ngxq,q,(VAv%@@Q0P#2˴~X^g&" jnAD3lV=R5VKJ"TFj\g!ZT{g72xXWQuօѴ ^e28:, YCn\A qJ8Ѓ^$Xe$v;iQ!Pda)lxxDO׋^VeezKccix C˓ %*6xSM5bhzSaThf"'d R]e$$-] GHS<1I-] ZBi 4]eSSK8H/ʅir 3_dHm3k`)K.;<Ƣe=W"K!%u|Cj-yI([;˧g~wӗ ^_S7nqo~)֙,aZ]w6~i""u7ǶcNC/w__&#Iާ45J/4#k UDqt\ #a~ bZ'/.$u0]۰So;=ݱjRPV_ k,YFԶۄfӌ#DOӀo?MPe5\ϻ뫚eW. Sg(R/JU&xf wӮMmӀU/_]r7|h[)U?G}- 7=|z3M5g ۷U=RrR0ڼZ ;Vs-22C̝·N1zQv nm8=mp/`vP Z^VSm5Wc˴/Z8+Ej{S0f^ZƸygO$WC4kP^I߂E<νh*p#1bI.?_\xI{ňVhBc<{&v3s" LPMV^ۋ5./뚰jTO?8⾏ى1֦f|Ɓ*8O(UE¶A}|  aԔ9syylZ1ƯcŬPjmNӛ -AhsL^ȡh0A՜Pj]ZeOZRviw64L_7j˟r]\JoW ej䡑WbszWz1 55˷nyzrDX2؞CR&o&=UQP.nh oʓ'm(J V$wP nZZ#;!8Y^!pEQ ʪV\{%1փsen\VY/Mvq5tU\/I`H^gX 5Xj")*fxdY~!8Ǒlf_S/*YWiƦjٲV*b ~>r3|Y~ZK G5j]OCۊIo\*kzln.Mr?3?ͯʯ",Zյ[Lwm|Fna*,,8G[Iv30>ŽTL/kjg?٨6,(-10ͨ|v#鱩 & `sRh*_6@"KEXKuOQ[czj*hm#rK`նF04 P]:wh|،[& 73 MI(ŅA)l]5AcS)fع26bH(W*d;X$cWB `xe;:!/2}=^oUW çTu(MݵAe./~a(箴4ÔM/.ɐ<,FB\QW/E|v-;S*7䳯?,وHTuu0e%j23Qd"MӘvGWkynVY| ~ u' kի'J&ٓ|rϻ>HV!_mHZoj.z+@;92lquj[Ͱ Vȁi1;%BC{Fc<l*.,To*jtsZcuKHZbkši.R**VW.Y+*\ljg_h*+ UۨTmr oj 81Ӌ*䤐_QSVJ֮"W@*:(u 4 %j;ȯ8piXW FWzըO?L*!ޗ(-. P`7]85iMc0CK0@8W<ݕp]/[0XDhk]K` q˱27ɯ?g9į}9E[$/c>+.S<·Zw(lhui| 5@r9T]=crffd49ĤFzDƲちnǚp T jT˙| ¢ 4'6z gfήZ-0 )&ݩzo3?#xpp;GƹJ RYϷQ9©wv\ޑo}}eALѝ]{wiqH_O*^٫ c a;6jxeήI3XljXFZ%iVWT.P NMo(6PYm[ۗ]M5L]fv\gyRD X\.f[=|MH0ө`e _ *(򖒼]7iReau!# \sx C5P0嗰k]G'baĽ \.0(k"4 e ^ [[_d(7HL$P"}cTf3]bVX_ZC֤M槍X,2P%<]$C+AR7;؎*UIG,[yOuQpUKk{U^tp}(Ͻ ~C|`Do䦑Cl3JZK'98ۣ|r$Dy!1ݏh Ri23zE(YΖ*1cUO @rmCxܷg."U!s@:c@o"՛1ݫJK3DŽޑ2\xe?_(y@ЗH0-;VM44cbU4F0 'g/Y˃(K[UA$MHǺ0հDu=: " >BRszExJFRTU&4wj*@iҀ DZ mJ0ԍL ace;xa(WjV~Hv50#Nh)eMOS-M CJ%䧧 s6 dbاgkk^"*&Cԧ {RewgpTbjR V!}eӬO'}}`95:L9̿?&OH)eŅp(¹ [?Ѣvh _"AZFFjU7nSoY\>q ~~y]o?O>_?, 2saRn}{o؞tRDDi|&]X ;rwM|6.lPYpJmGHfW3nYV 7v5AeʻN,ToO*o ɫcHb;6SKp}/N% ===V1#j!Dd߮ U CC&4~Xڨ.o"* li}ʼn*Sێ@_*4G'#UApl=,X.z^˛j7ћe*i:a۾wj`3k4KS5+ϱ8^.*ۻe i,Ǿ%eMbϳŘbCB 0-~Gg/fz{933ٙ$u{3 jKimpDk 3 X3kDT !Ac{Rҹa`=c-!Z<8;tB 5W3)bl؞FFJL ]g^z_~X_ncP Kv 1PBQVoe5**OL{/~gӯ}~Y_2]Μh˟]6j~i S"B&c`$32x)+9"jtK/Z+nWADz-V (jFՎ{z㲬H8b4]rsZpɑ=t*3NzKO\>8;ԍ1߮շk +P Wu3\ҢB=2Fj̈́0 7YM{zer /NCZz;MsgWͭ z.lY((of+NP1qf}Tk@64^5GFlƱw2gXBP A&|KLX[?Jmî+s-y {ƹؿ?eFP11dhxoBJqrhm$;` {"kϼx˕e_?B-#2EI:=H:IeZB *h{ǰ|Ɀ⁷}[,n+^d(W&\(AL@֣*ߨd-h56\3_7"䦚c²MP?v<ڭBs3dK@hrjq.lvsAlm^1TX[*s؜ʑTHܯz88уM݈;jeH;@%8Ju TөDgFKL N$TYj{u3 +cyIO'TYʖ]bhNR U*uE"]2Ѕ=})U&Aծ7PYB8ɛ>_8utrBAzj=Zq}J }ARq}`& Z_'V }}CDp꫇[Xt?ܥ11FZ}mxc)!]ayH5%I/Uǟem=cvzƮS7Ui˩k^DMhM2U*(Y>AB%ovh5F!+y_?yӜfc$1F2 /$:Dd?@k+-VSam1A#n9L9x+ը;nDD GZe,΅`04{֓dB"{*lT0bݻ{H܉/.f!HccvE"]jើ(7z@u-.CesWN0y?\0 }k 7j.hߑL6Vh Ӣ./,FbX>@QW&Z/ s*?A:E h(QfUP}K?*r`ɩ3\*,mXx3u%:H`Vyu8PYWjMl`H*v[ P;̯+Sun]`5jNZf%@ Dv#9|'[ F*e4Y%Tg, GRcG 0f^l[㵶JU0乴P`mq&hjj;HI$ΪrXmT;lYXVeE%H6ps_c>GS'2Ph~tsv%fz#?0ƏNǙFY__Y%>~7w4):Օ[xխWxAR4 m^)\$m<`Ν!\)x 6()"^dkBlsD 9Hqkpkerw=g-$; w% g[uA7(9(mVy>;EqnrH`o1_?; PnVՖo^2N3_XE*ۚP*VS%۪/Zp*Uj[k㻨*|xh\HM4|dcUbʐ[ۗ aXj|on"ê Z$i,%zvUxz2K5@x<@gqϾTTV:(,fzG.5YUVMi[9TI6Wo1nx7h^"+տ驨ֵZw6KGrjd*NPƤHFbɔS7ʣ] ]&+uXmFcZ=&֕tyg@mj{r׭CNp$_9ϳ:|m%t%ѡYhqjU*A Z"noq4כAZƚ[ |xϭ0v[K,; ~DdSnTe!n3aBf[Lb%ǩ߀Lb G)MummXUV%JŎ š hພ(W?OT>xV__;XXW_"FًЕ" ̶tچMf.Y P",JTWϿ'ؑgqyKi3lK$DYz[oKY\D2oxl6TjoR[zoQ˖SCW p1~f4#DSCz5až2*%J:ŸzCd]}cEI!]5(|/:KW{ٰ6֝cDF{Yp]O@@7lz(ڼW4М~ާ=oz䨲GXC+^(Y=UE2 a+D6\ID(TH}Pڬ03VVjޣ/+Ljy-Vފ8漥ǿ#'#? p)n5c/wB^ʵȭ\6 _g,$ w([aНEQJ.^z}&IE+sFY-X^Ex)a;xY&ȶzMѢfXUpǀ[`~v'OA%9S\䯟g3W&r+j`Qo'R+[IJ$paHEخEZ0\?'5A5ˊQuP ^U񚠪H,XmmR K_SQցʝ ewI^:oM P 㪴PRT0krk#LnZG6荑MhUx5AH:ʚRشQ7^T-OM{mW߲,O~/~ '~l~+˨ǎ#s?Gj1KC۾Xűl"Q\DLj[F:6/ϼBu #-cVKĈ{*& !$"z!_wk5as‰IV_G#I(""Aּ_DQh}EQ$ՑHԠ`ӬW\1y? +W]%$GU+9Z֏@?3Oȗ>9Ξ;G߭J&E:8('M MYY/JT+%J$)Wj&",`&.Sm<ʫ A Q(C%D_j/+l"W͟i$۫ ئEy (L/Áh s& uG/>H-ÇS̕֐(";]qp!)TuZ0 6(5}PU $4Q|\>nx'{`gz SJ'J((0$CdQl}mm[mAкi '!HL]%y+#k;`կr*bRT^}kT AV+;"Mwa-,uoO&Tk[@KB<ʶqRen;t#wtpETU}|?@|$B D}ɲ(tw !R۲ORQ),/|g{OϺY%}}#Įx.֗W9{{7_yg\\-85JR.QRFj @ * 3]Ր}q AK5}u4A%&Xm$%T^ _ػ:v8|gβ#ŝ7D867_|p+sܹzߺt%HӓngQzSqEbԂULbu ("!b@:~pZ0 @TTt@$Yr|B|6CHs0;v :Umu àukoYeBR fH6J%he`IB%8m/ RCE_j+TDBBB!"ؾ"($ \]՗p!` V˭M¤Z$=== /fٳg? H# -YIO"Fzq H48X5J1eYA籧s~v=MvLLpG9^ǰ':yyx칧A@Bp\R0k8.^_`M"R }A KU/ں[,7US5oV|ojW\UeBI? g"!N裘zeLL/ 7'ϗ=kc:nϟsL;9v.n T!*=#@26 b݋j߮O[#xjMFWt];0C@W$JXؾzl0@ k["#I肐k  BH臆(XowaN'/HJ a.աe9-/jh ZM%93XLCjBb^l] v+zV;6>I`G!I\RUyo!8$a5DQDE0$8eizs3߹]|K/zT\dIFTMc:#2zSV"T'‹ H'r`GEZԡ%( -`m6U;ڕV]=j3}xG8: C|lgP|x:{MO3/P,~x-:@O]<79]`?a(R5X J[ D(IPU*~s G@P ! D0 l{lN ەVX $%gզyku(ƺ\%BٯCJ6aHqUIQUޢ` jMVXN@,J lH$\Ƨuna'?K>@6jf3_ ZR\N!"bN=U$IqFxTUm UUp&Ab`+N4_ҧYȮ2v10C4񵺟(&:~pt%եu$?䘎%zx;q3FDU.j:tQb[J 7͛f (~cM-߮6X:w>Sl; sg&_=ʁ!n~/?s'x'7Wut[!$Q) b;< E9zZu}Lfaq%ʕ c$c"Qߺ`Ieص&"^\fmV4BWB cM%m R2JB'Bj莂bL.1uC-tTL/QQtw) H X[X乧aa7~{vOKSvn3 ۰׮ l:C;m(́1i wQ@i֐e yC:nX]_ _q_q=d;/7b'%Lˮo*8G 5RKE"l+y{7\^ŗE|Y˪! tGpR+}5 7[?!"6vy#^~d S$ YGr( n$yH>̜n OZ۶7N@;323_N.2jpnym]{I>Ʋtp| Yu(劄B:BuT]gyyIP!kS[pm\" t-وo˒Oդ}\3*$J9JTy8Yqևty* nm(8ڛ&B\C "FV󨡈g:vLpk.)(^)sȮy޳{>JWlWoAࡪ/v1z[:X*ţNooeRt*aXNxU Hܿ [מK'^>aknyGN/qRN-?$Z!(LK6p4y.ڵpRiАWqs>$EhSCZϻm -T9ɮҨ7! µX洴Ka`VM)ʸxEԚX$V 0M %%)Q6fբnQ2dQBl5M)B ~!lvmFOߞ}LѮҲ٩jMcҲ< tI$R!c2 :IYn&n%;:Jv|Afq&bn _1g}|??ß^;c+{YK~0 ZN8!ߙh0Qol֑DH4%ipqnO=9wjk_z7q{!N/9cY&,Jg/@#DmZ2_"*S(MACa\ӢQAmee0A G3}&p!z sÆ,3<9C/b4ԧ86wW{>J;9/σ9$9TD8A41zLԾJ[%jRNzrI본ʹGJ0 1Rtx% Je5˸ P]%>BnYّ*~\쳬?37! N}`i~-=ei2H0٫!W!1J)J^ۢSaX d9K\bxbo(w"Sp)o7kV_|'?ȯOon?T+m^ߪW2XHG6d\:Qo$*wI`7&7~#?C?J=sO=mlYkadJeF?KBڮBv=ya|n n,5bW(B`t#Dg6EXlsܒ?@^*=4/9z'y8fp玣f&XY:]pQ{a_ͩbC ZI@z7-|Vn}-O DZ'9)Z*SKgLh=dSCm‹$ !a"wKo) ư4pC6ZU74EэPqup>$ Й G&mw@Ky5b>s,'L켅4ˤh:W $$I֠ՠK=cSQhM$Μ84s=HZ CS8F`)aF 6^%hZ2ie5h!I7Xx~NM.v+_]M]' J C-ӢbH%'q@'u{VlnD!10;%hQ9 U[X_k̭հ(O\$!맗죏o7W>u ??~sϽz+ "|G),qS6Sl_^sa~W]3#/313ցY:%s˴,К[EUXpۙ~?y:ċutqgeoasVpҲ%ƌP^ݼr }aIt'Wq>ӧؿc/Nt&gډ7FpHIx#YPi<0@KҲo0eDHFK@YVq\\YaIN>$yHb S NT"qͦO Krtf"?4Ia. (M^cҥRf̫uɹ -ˑQgU>Suo˹gJޛ/)" ]^?R;sy٤۵aJ6 I:vW$c$ bMΦ (fS? _\BExr(TmAuiǪޟ|wgo'AjXI޺/٩s{Qh ~~tz{K0Л[NΞ%Dk@*B:V8wzQZRl\oSթ,-za' *;| ڽW/ZdQLij,;xa[yӱXYd[a6Wg^(`lslVqQo2mXxh<ڜhȹʾr`iȝ41T_JmZ*͵^8uՓjGHjI[(BKDϤJ=IGMnD =&&͹%g4>B(rJ f#~[rT֗ݍ+y_]9V#,-.Zq.qP,X_XݐNsȅaz;\LEd]WV^~|_'?6EqXǦ}WX* THڠp2%VQp"Upxo//y\>7+>ʳOSraCN摇"qxNVm]xSIϘObVbveG>q̅da/=GR^f!qCĝ.~[PD+v-"}d>Kijᔋqg{w_3@fA= |F{~Sdx>Dn$dSY50sh$d366L~wmy =8'>+f7}WcsmJ$V1KspR*htQ"0ێlV=8=cB>s~O<w܏s/e~ŷk]dnFl$]~vTv"$T^CA'"57-eߠ?u>sl.K |c9aMQOYBې8p,&3-'L,N%[,m!e_bbtC%izjR2P%kS繹yX3~|JCTk Dcj;f?vX=_psqxh9=+X`X!)A A3thţҲ<JN"HtjZ!FFݔrKg)LMʁPO[Pԇ+ ڭG)LQ_%Οu^T$1M %yƶQ7 Q RK J!|a mThcѬiZHi;Vbr!F) 2|ǬkTƶ.s͘PψqtrŕKi+ 'OЕ-eQ]YlHM.&5ÒRYU:͵q]#W_R+˜ BHzJN"PI&ئd E[FX9AX%+ CB$x3cٱ?{y ~coo;x~_oO}$WOZҙR@ A5B1XNvmuq=L&G[nuM';27zHzqGJ]T=-3$B![!oڙ 9sh]Ff2fcv̏ѯc1Ue׿?r/gec5sSk.ĵx2DG1>u/w}a_?>;}$<\aINKvd<2 eJCoIyT0 c,?c`,S(k4>M7ɋsPpUaE{i۾>0FX4 \#3W[S88棏ZSxE̅ND+ㄸĪP7! mUNC5V8w9.<ϤD9iZHB'1FAR_8j.#GG,m4=~7^s<1i!y8F>, ϶ Gj0$S(R,zM`[6!TOs( $46*GH֖/",mu\s^t-\8><#Φ:m#L)$ dʥ/{eee.Nt(32cIzJ ab H ɐ9AZ%i..4Xf)r28DX@۰;;gg~>{x|3E½~6\/ϾZiC(i:DQ4z^Je8JBH9lCZD`ZgqxyG{W\[}7=HǟD_Vsw P̝:cO=Jcz\S(ɱ:ϝnG88\w  :wfl|R($P *QҲ?pNtUNe߹Gz,a9g ݰӮ=sdcݨ{Mi!M0LIvKtіC8͎ Rha4Ll2F'xʾLl#q I(0uXVdG.x.a㲞)%To(@zsB ݍ n'IN:"f&65ęOcVsLɥuֻ a&'B !8j;+aXw0f>R=6&>`iK b eHzۆatt;鮞eҤmD2-{' !j`̸wܲ&_#G_?|/ o3ˊ{9KXVCD'&'QZyؖG٤|qð?늱Lmu|^Iɓ~w5&Ǚ j\oIV#,mE>o;#{X熩k8"7Q;w?Ai|]vm/䦧GcM3ֈ˼(H-RLѿAEg9~Ѹx$ѝǨG!eddm٘CC9ua/h{!")Ri2;do>Lhh!iXØ2cAbxP/)ff}$IX%]r.9~_pğ4A)mrR&DQJ>Ǥ i\Z DqD~Sm5X:{'‰gY:~"-6v-Rc3nk^~O̟dmQ,kZ@ȶ];1s .8:1u{>ÒʂiX!I-Dؘ #GFq]hu,o\ZcbreNql\ϡwihH$H$"$ߥ5I2- LCF4 ط i"_(j4;;gKΟg5q<ɖIXʑJkiPSFkglβ Z\E1qQϑ!N2"LI!["NbbCa9E˯ck9`VĄv gSܹ (t->\\M_~雿IϽ7U/}'X_?m7;eχyMW?:]&''hZt;>H0&/ÐZMڭjna?""6/z|7}7Nkko~%crtbETc- 䘼f'fNjt3'O,qaq[?~, UxrB'=D |7RnqUYoX=}>3OQYXįVe4-* 58/b*{|ǐͧr8FU?`f.%mfY5vLj'I0MT!02bMeJ $<-1 Zp0BX(r*u:V6*,VVRo6 CҨ7ɴi B9/3Fu I*{w0;QfMk.nxh1Iam/@ $~e3/jxeee?q՝q\LwYdO$H E<{&ش1\kMš)1rh'cvg(/o׾Q~'~|odY~]{~6dܔqᦔM&atlq gA"p3h]E&G'O?%W]\w85hAJwvL)2{{gT*tϱ) 8bRZˊ t='}})5&1aY]۠r Ǟw$`IC VyҾU*3};rs $GG2-Z8sKd&HQC&-×6ՍGGٵ{~FjԘ}Ą!途؞F)E~hB6%e!L slaYAPMؖSCݶs٨֨@SJ4>Ni15n^v~Zmك^iWKzfu-0GYfztnD2V̛>`rݴVq+n~9]wq`fq&` b vɃbd3tϱq F+5~!| r4Ss|?X,Xj>iH,ĨV660M᷈-kkL䃎 :RBsщTS8Y;K4qho]?`ff] àG̘Bg8NGL!R SQe|b l_:~R$(azZPb>6MDz(X6lbK&n+(Jd=mccT'Idywn^$bbɔ$ U_i?]JC\yrJj2؏/xY]ih=M+v㵛Gv_i?+g?vso Gx7 Hio[iwClc}} ocZ.ߦN3Ϸ'֗~osG) |}/L;6d6m~}'hmԈ[+v vcdwg^LzO%rL0 %M$(Danz0Qiw߲"jග;_>:! j58'# !6D'd88F>5SKt/.#I\5 oI3ADw68tM۾O~w]"?=oc_mΟ?f30RMvӻb63<ǥѨ+?J`Y澙R1~kH ??>{9u,{+&N+ N&H HljnLM' 0"" MS?S?&mPt:fWh8nW]٤2 h7ar~fvFX]4=m3^]fiQQ AӻQSgXV;GL$hG-▇`e ?RI0sP[鹬BLkdTa۔9q72;=RF7-SMƶe."7CαӯF*\XY1-_}Ӽ˾?ʧޟ;oۿxg .0H77M #\%_̒hZݴ`0$AnZપKt!O?ßy7Û>Oc>y'VPkmڡHRY1zEܲNFFG!RO[yg6Z+3RTMW9S岄n#9*j99@n[veC{wrϣ M .* : \mGouA_F {s&;K{fve,.W1Je:8CÌMMc kkƇ9Sm^oʤ\~/ՐCTO^ӟH)V= KBDH4ڗ,hX²pT:RЊBa ö(0Yrym9h `]8l>"VJ*%Z'kYYq (` uaΚ:30c#A4YD \ywre[=SR`)X]IW~Ь-)#ܰs_c~S8|Ͻnv@ryi9!-$I2aU5 àpOzA& W7uoz |9yN|~hG89ZI|ѽdeAH3}-xYԓJ&wϝgc=$π0B&m0J5Q zRxn. vP bkUB(K^gCdGGNP9w 6nL$pvIl\]g&v*@2Fʲzп721zDkLˢZ1UMRezP-W7[uXQm4OZC˲șBm:J+&V7U[ҦX4-չF7_Ufrqe5|5Gx'0IZJDzک4E ࡤZI ų#;62 8|y 3X鹼&b{ dN%Q7ނcYpɑ1j5;7OPj/~krF1Z :Em I>ϓqYZHsda0v6;XzBUo~LҚ YݨXL VU." Eư)h 4Z!Uwl,n]rnBb!8X$+5a|%UK!Zq1k |@H"KxΉ~]G>/}! 6a2êVk4-5}s%DHL//+əu> u+ġ'%" Σ{,fɞ3z`-b8ڢ,lgfxc Ch.gLcWްO]{.U-Dcl߻* VbnojV&-Z:OY2_bCIMa!˜9 g1]q_crE&C+79O_ѻZ7+( cV**FeJ A ̑VV9xˍ6{^x9(ǗIzK.eXR $DoaTK7J2{7C2N6K{y&~,䳏(S aBRifk9a`ˑ1lCө/rbCT5qyd29:e͏)H0c1:Ʊ3;v掯z 7܀ˤI :̟:əK$&bD1*k8&6Ld,ټGhb-pͶ>J /`%i]( i9F1y9\a;C(,i4V ]B0R R2imг{Zf #{q$q)Cyh}ud!0$XB5 z+0ꐱM,q,>;c[$Z*jZAFJ%W:}͵\z?ks/:=aܜ8Ea?yt%on3җX֠+la SP؞EtbdѦȻAf,#SSa8+lZm!ij>97h@!ŏB n\Ƭ6uΟkK)D'e$IR*dS5&E01`Y25$ Je$&>HkX*]Yb$s"KK64Ѧ<ő·| ?S<[M->U6wCAy4b6"0 ׾|%_"({)Y9hƽ!Rg,"oy.{3daeĹ7pr/2`xcc W[F KÜ_x mL-MeISC/1$0bB q01xlK$ĞS(ruo6lۢFDa*X>?ß}S? 'lߵҰP7淀ejsq\m392DuARå"ųv)%!c"BJ^*Ef6JHvH>F P@juճ`?Ħj,KVuD/x}$/$cT@c u iY:DaHW4:k%pLSFI419HeL~| 'y/`)71Zve>׼Xi.[AL+=G_s;wM|k)RUc&Yj3P-]6kҍ|V68S83Ov6F;+c>$^Y42ޣ7s8_%:V>VDh8a1VVd E'O0:]׼/~ FrOYٗ& fi?Ϩ$tCjeO$4];H VIJ\ICHb϶];HhJWehsx!Μ:F#Krsࣳ9LARrnQpx3\Zhͦ.kagsĶm$cuapy4BzAG?tU*r6p ¶m,2cW2ޯ,|it 궜e}!ksc=C0D.^V(D gKѡ"q"6EZ *e&\vc7~g w8̟?c?LMG grzWiFo^^71y q&Kӥ 7ItO)b5x@Kyq'nFb]mOI3'JblI^_%^YNz(F L>B/ 3Y.0n OO]e|'q=5Z鱬Ͳ uؓ8&.E@&蠗VcbJ=7HZUu X=5BQk8qn6έO ㇾm<q">Bocڣ 7$UU?$ cSַ<]f"zT#.뫩=Dc-@m:/]s6S1 aaҴ(Y=Vfx gα؎0sE\!h[dFiłReI4#9(8 *cXE*I-4 ]f`tI]aR轢e nͶLL-XZ_Cpᇨፎ2{?xl* X-$b? hNO U=>'Ea~uO>#Qs^D6ST`ju|:&v(,mӠɐ< yl`}ZB),:/AhusuYYDЬĤ7268Uo}2z4]UőT:&11fht#6+UA.Ff&Jj(Λn}Χ?̤[M9ǙpnV7^,ojrbkе)RC}ޝ+IT}#5~;TY[YdY:jwQe)2*FDܝ]D|K=bRQ;w=;S7҄Ze|7| '~-NX |tFcy0sdgX)Sexne'6~w{@I!{؎ ۘv $IbqH$Z$i""gOdg޹)&G(J0 L0%?ݖHpffq)V/̳}TcUH?q;bP ߏXXcg8w3 9DarX)F ^esq}GڸIvd#I+ّJeb&+<'0]w3zVn6 , ư,+RJQ~=7- ӐO 2Qv)uJKlZdjMxaU̷Ȼ~%;Mg99vLPtEwrn9w\sPv|ޤI&m)0irnS'rW5ɓA g̗[|kf}"sҥ%V3o?P0E$riz;p< g>듛$4ma-H>Ak=B7C[{r%ws}7{^GDIDNo4Hˆy~Q<ZҶY\{C"APY|!KLLŶ2тM tNFV$i\lU@CMŋ<補ԧ[FAftiw &*۲2)϶l 2]hM AG"C:6a2.P7O>7o^n`_RiC%\26U^;sGV:_]nϲ#Xf[pr; ~ S%ַfMw07Jm$$*;^g[G{-oo~x?=<`V7rØ#ì> we/*D߼7iǽ_6eTrY\bTAw<T_Tg|]{Y;arF E^5G( %tus;yĎ"(xbf;5+ȇUưKnGwjΟ<Y)h/^29+'¾}Ln!R:2dzL٠ T(3KLz?t(boӭ>>WX9_o~MoE,H S[|II}:6t2Zʄ \UH*#H>XE!pY 4Ig4Je/zp߇71L8q߾?ߤlVx>굈zw1q;9|4F!8H4ה\5kHC&+k,8ιe)+[.gUZ!X#Y[(;A82²h[^iJ.j81-duiQ&0R`hx38~f"3Y VK 69}zlmGɥ A'[4i<C;\6;Kyd0b:+2T*btjq,<07 I$tFIke&mdp]g6׽mEQzS8Ü~!;F:г8Jj#r=Z1,z?,7t4jreN9iiuye NHA4t$IϙU)aHA ϕ?X\gaWSK&a5-On翔\fJkM9sI;#rvDz-k;$kDi V̲HB-HQz'}dz,j&rZ׿Ǹk2`7~o|JB'DUhǠM9O|o' 6/ޕJTAbK+l; ip+~IBZ'WI ƕ.SYZftǎ!.umN0ޱOrYrK+ ҟΝ8M/$L_6h|Sp]ZiXIEX(qx3$c78DPm:$]ќ;'G':xmVf3g;q0L\fBf=sK2MD^Na ަbbޠ:|{s9UAŔ|;ϱxv{v# 4O)ximg^[zaObfF:$X|ڋ:t4Q7 [.Q cVۂ o3?); O>:qg|Vt'"e3fdl*|37aIӉLŔ0]܉㬭,xIvo%[..$XFLs5D J@sq,)$k& ? qm{K(IbBc=5$e~o>Yի=Fvcڽ-?lʲ(Fvmwz1_Rl k{)NjrXyk_1\sŦ)bt 1єR墠CѼmS'l PEX@jg?sE.ʑ7"~2hS.ؓ)PYM֦ 5::^Ldvs>vƦgȖ$dž^}G9vAdh{q6,gV/rQ^:Y( sʲZRcg6Λ bjS*2ߋl:t!158l4}.pY ;w1T*366FMcef n@ThGvAi-N<20$R^* _,4V೾{o45se҉)nۡOrJtD.Qqg9#l,\ Ͳo&v18BS*4e,FV7AJei^uL^ЈtaJ4 'M&{~R |/p'/$# I<,yB%]GPtTKKV=a o:,PA.#_.+ mS(dqh9cTRzr h;tY/U r3,7_\՗kX\u!tBi_J"m$.ʨ=st׎{'Kf i`J({benbM4'm{wqu:$J8 N/^EmIGeJ{r5o5w06>ki$]ٜGOCdXeĘh  9xRs= 4Mj\O9fG(l w=3N Q#c\ i}mT({&#ã\8 nyDJlӤsS QkfA bL߽ddn W,QLJ)(WV9y{2{w81;TưL2ϑ2n6i[aH4 ^v0@G<r0$3Y ^XRiBw}V5N1lML 0 E W}S|״Xg,-ڗ֙6Dh5ٱ]ŰkhksУE Xry ǣ9$r9MҚXJC2v7֩xh6}9 />i^zlb`ID_1F+@Q$Xu;٦4<-/9;>taaDžmzAWRDX-,kxhx/F0JzE[Lj4fr) Ko(cNsq`ٮw hlX8OP؀v#w{TQC1\fB!7ʡ7hDQ&V ˀi\4 .v04Z癩4XùHMZj1yL d:  !~Y87XlqOtʬ"iwa)$|oNe7O*:LIf*OũDzxezYc"`8se9))W}ӻh4[DQ5I,QZbhE]Y%jFi)5`_~a`?tmewa96q Qz:Api~N{"71 4˜|.CPH]r2.J 0(F`d v1, dzdfVDQ":I"h]/s[DQ #lCC#qE#^j4j38KC{s"SSoㄣf6mDa{.栗,ų,lN'FG)!uIMӂN@ FGg3-scZ 9bN/> tXU }\o]u s FX:QJۖ)g?&l#+kDc6~M.C6Q5۸n36FAH5iJ! b4JU tRkS_24R{vpi^݃p _%b:.og1%EalcprNfr EXGQG5R74$A`q͝'Neb^Wr+_TӍb$xKig>8Ν ML15:(I3O|LVH]UYŪ"$fGvp7nfz{ZlKvEYZ!2p{xDFflV1#2C*Ѷ<%$ xyd =2{Y)i,t]# #;7Yj-6w:FnkP4CCAӣP7atr"2*2'x÷XnIȂhVkzD1 pR OŋJF4IF4]BA9ԹFBIh** "*v"JPuC|?īֱ麝[YANVw;6#3=SՆzfpP l8B|~J$'I1W^t\?Cz'~_o"LBѨ5 <5T˳:Jn UݡiE=~MUz:S#=hg?"9{ BDM-V ehQMVqez-*Ͽȥ'08>HRs\ZFxd!? }wfo}D*EFFGGU$tL.H3)Ԥ@@iӈ7id]% 09W1[8d*f8UfڠrFdmacIܮu6?&c}}| Dk b6L3&w隬0^$)8!CCc2Cȩ,n9eZXO 3EUiẁ|jP5R$W! 19ORA"E5>9iYQu2(Lh,IN*$*R c$ RDO Ds\Ve{y۝Н8 MN28:JD³f8=_~@)|(BLd$#HL(L ň^IU &ALuBYQ}f׋fQHH:C$DQ"2IIq\iG?_aOov 5SMH ®W]98iAM6M4IdbMؤ^ %s93/ߖVDRNx8g?CYm%'uܜ䓣hgV[w󅀀]QH*&$*s= CVnקgd9|b&M2! 8L4-V4ZG5Q@$TY"逊”l_d[ݻeڝimXE}J EL$0 =W`jl|$o~LVMTI#A4` Dd ]UHZT{$5 QPDQ^CA!=rN 'O܀ͪɁKeo!, $+L`T$څzAn}a/!Kb;[]Fܐ0Bzu O&Vw `uvV:"<\  E"wy`|&L2t:#R}2Fq5DN$STba`(FVA腹3?V$( m‡o΃;jH7i4YHIPL*NJ$U4!* }4E#):ܩŨSNL0]Lfge>w8m}Z,n"QBxAQP f MN_f$~`pf?=͜RL`9⹫lyazyHo$;aa[eD? 0MvP QQh96Zh2jR.~kYզf3ﺔaW+XTytDUӖ Gk#f#!(0CF C8l2YAO\JzJ*y&If"C:!-]gx12T2zTFGGUQh8&V rب!*ѠJ= |?$l4eZ:~HFdwgqPj(-DAJˤFuծ +: FLoEe+.$]H!!q| , $ㄉDtRx4xڠ 3>JM@YW IBKFH}l/@RT4ս]BAxx<# *rCK$D J9FG׹,D+?Rax4]jHfT^2&zHj nH2LZrXEiE 2 FHe%OɁFS(6*ۻ,~!oޭ[`i@J^&88(w jR\P,+NN# CCBU4.L p]Vw2YZVAL1CpT s眪i8~&ǹu5 dIwuLQb׹ܳkXeꆖ*(R[*R 4Q $tjB3K!8< CdIlP}ɨL ^$;$IQ sg\ rvl!Oa_oc׹py^IRkVxo x{k|ÙL9(ћM:L&ZNÏ2( td*!+x(H}"7 MNL;smz6?wަJsgkg*sy/͵7;<$x,Y&Z =4V `|},Yש,F.̑e;wN@IIG=ꨆAq}0xo"ׯ4tCظB "A@%T]CO&Pu-*}-Pj+ :S8(b0zz{(>peayCEDBD6[lܻs ɒdxt]@UQ#" ۵(2m$nU uld*I"Q ؟ 02~~ntOA2Ł!RAy1=C9^{(f#~px/<, pPHJ}=sUu`mA!iʢ$VYRȡH {HER@èZ/A<~g[!"PY J 6d/jԠڝɵE3sYDQ 45Ep=0I:"V½%n%{{͐ *|j:-$JJh*ضkxa]Pi6?d-?vkgujI@0e@I|5+YY UDE E4-;34BXlYz&!?^F@1 l !]J$KE"Ȳa@2dmm Wͧy旾ͧ4 s TÏA=QAG ,ǩp- Z @I& \njCPr"EGGtDAUhqQh[],o,}~ѐ#x]CE"!ʄ$6V6R' ?U3h}Eui~ss0LJ'vg #)Cs yySYJZkzΒcm?ZlHAT. "r{;r|)EF0FI :)dwql*5;.p YI&T U5xFx <Ǵl|)k$ Fz/-!i[aR< WWF'3Y}JЉ+)0ia5\03:6kB@VuM%Ga8>|ܻsVE.cCfpn^M>^Fk{?:ǯ_v]ZuIU4PQLi*OeG Fjh4TX(fClf歽!WJ8.Vw1i Dv/HdS$YD#Fٽ"MQXUI@%<ŗR"O_;w=B%Tà4w˿osFFG.y*"Mۢ[:Fdd|1i!"$H@z 09$9*aDQ@74D1/u:2M?{ /1>;ڝdwc m_I( !}S$2iBE%TTDLeӌ@CPU#ʸCo0 3tzTB3!~B.j{h>z9|\E@Wt||EbZخ59~a{L=#Jet0ljIegڠ\Xcum H'42}=GɖJAqpbd F_6u{/SwL|7@RDD/DN,9j3N+dv0#OEe}! Ki+nWwz7 eBϕ.[iEb5$$0w0 TFQ 8My'3數 eFKC9ܽaW=Rfe={'LŴhEF֢|{XC L.YnHAcٴE)WhRi:QgE }^\^Quܿ}! Bo) 12̅B|.˽ S{@&?10OI_yU%`?ϴȥCGV+ }쬯q@*]>|ZJ7CO&e2蚂خڂ(g1_0 ;:++xaH(UQhL>~}o} NhyAK=8߹&nܸ~_~ `z2eHx&x]AY{{ܹsUR$Vz8ŜT^W֝{~H&dxt1ҙ,@RRQ[_#<克S?5a7?xޥٰ0R*#;z\*BPqZէ{vtI.UXB n),]LT%Ad 9Ąg1LN@(FR=|(A.8a';a6߅0k@  f@VR1}-vp!v%B1VHCQN5z1a'#PAJcx7Y$$5K$I%u\Ϗ ehh |0U30{.-*'bAϣ!((8Z[H(?xU\#CTW Y&ٱ '!Bk}:IX.`(*"P;,A9 D/]BK DÓ(&" 5M 9swAl|rYWQ*!^<6Z }<ǣ|xKK*z hRJX*پ~J 2Zˤj ZkU%-_p⻯g~j) aĠY*tXh +*eaݹlO:cVw![ͿY* ~Պm $H$T9ʠum`~ HQh(I<.A訬0;o X$).L?:$#Gþ@5p 0q4#Q,Z ⩧ Hz"(ѸaU @GIe)z># Ѵ E14%j]0s}B DVщkZigvhT =Co\&{lVM0<0Ku\FBQ9H2G,nDvm[1*FAԟI聢#.z&Oir8:Hf9>4dyATkSHHĕV[UXFxAI7Dt!(-ԤIލt?_$` &ު ֭r)$ XKHD)5EVSPORNyQa-8m@K぀J\&bL2]V Q:=qH&agi("(#JRGMuJd+ e\ hbsԬ}6ofʫ(#ץa= 0: [*5c|l.Ao`nL#ԐTt t2I P@$|Qf9\!- du޾DYѐE (iÍwLϣ% 0DDF5sE\%],`y>MNgs2${wYY~@:,hi U-qDK=ײ\Ƕ*Glܹ /<9׿,*WwelT6A)B\uYݪ ,b.H/FKyM_4c'~ePo5MQS ‡ I;OCE9@6*,]P Zgc41|\rЯ0QDBIF("$f"Q"Dxcc>DBQm*$H(ġu9:.knl߽Gm{ 4;+ųW6ar$cK2Z`?DqtTJ>A_^;#qb t@ &.]BIhXhL'e 2 e$En5 !vh.2ɞ^lAt\A8.)4 tB88" UfK:}"c}U% ZGq$37nͥDS7Μ&PO(vB{$Ka@\aeu%ck CTҪI٢OÕdx>ffuh,goi~:]a민{KlX-aPj*2z;tUNհL Zn'Oۿ^PMV1_S0Rw~K*dxdë/$; 塥mѢ #*a$:y! PE%{PJ NhA\HHb=Aڰ~5y'HA=61#ט A CAuxoyxaF{ЧY;bwpԩOn:b|D)1yb?Z،ft 7[Z4p*IEvgs_c/0]!(*xU`u4UBLʈ|g_:<ݥPlr~ JO_'Jw|?9A4q)A-߁"GwQIJxq~[ZddǶ9mL/ZR\\`4773F{X;?m1qr1>|纞OSUErhxnnhڹkC ʬ 5#}K[yl/+4m[%!gO€%mXɮaY#J0*FpN;{1c]N~'ݞzzd/j!zոi57dos۶;s+J$|i*LYl2.XAm6Q-S+U01\c E%+'W e&@yHawSBq'_}zA+nRC%(} 5~u +|Pή|U[aPS҂J"h`V&JhH!r[ u0*h 9Rd~2)xX)y]j,Eu v~7 vhۆ,U{~@jaM*[w+Uzxg$_)wt1E tD:C^1p0< +`$kS^doi\>P/tAI0$Ɠ&SCTVV;ė,~/O3y{o{\}iJ {4=:!x>@⤆,Ax[kHƊ y+* P4V9muJ'3o>lX e$eNVs=/IT-feLՁ /hF*+f+>Ha{CAKN}pCf9I22/B'֭U]R4OD6ھT;cw"[ygLhaRYɨ>nTxGKKo+x#ntS=D!^e}c1Y 72o~H:CZ.U ӨFe)Vg$3x{B xYI21z"z fŋ!r-8a-@ݯc"R*lS[[a*FQ!&!ďO6FM1|V&=KZK->_WsXw"tԕu!X) tN FO+}zwglpBiՄz3VTb{VO㺗bpJ_kL._0V>m>5%%خVY+=TJw1l7K̖ / lѫQX#h9c pھiQW~#R t#_y$cAn>-gE;4FU&ͳ&bJ`m,b"D3n*Jڟ~F9+aBX8;'Tʼ[c.%1<0•q^ϓBت&F>$j#9>X O+r?Yk+]]p$F{HB@"A)P d 4mSm ;?Cmsu c\}qCWuc6NzmߪmeK܀cjΞM {d*{TbEE4R?ՙ_T`57//|zH<.zP]ocd O̖r 'UjCaiO8m]=xgmtw苏0 D0qjUCYO<(d=Я1[8C͍|QU]Da<-+KX[<*vk^~WA,:N(sc n|VY/ !YN  ˵AUK^Է*+K]jmP'W8fߕ~psHԣ?0$;w1TRу[e=QRU%()yI&h kUx{ ? 4-ȧBi=MTv ~ŎzTϷ-|D {qɀ"I'Lri\564n߹W@c^K_'&DhY{;UCK0:ЛG)k*)G',7nnj] z8~A1"4YAYruv T6 5#]N׿yd[0E 36E @W5lƒUf&Sb]쨙n$4&DR]l#]`*ax+GXAZ~5յL\eoVYGV3AyYUEj _ƬZwKR=I+*gT_`X=f w !cC=x(*=, Ia}<ݗI(hq(h{w>7E\9b!h֣@tc嵉nٖnA}}J2vJvKJ_"Aer&MFLГBZ-Zf \)HU->˷ُ.T>K#,imnPgȕ$3i^ݭ[/'{ \eɗ rXߥl&Hıoӕ?EIx 񧎶w: =s@~9"w)Z5RII!F ]zejȪ?8Qcu2xBa|a{i5?2UMN)^NDuTXQL % IF6vvz?>ZB# "^0[$rWepl ] e sCc &5wl4("=8o:`-2>.ޠȝyv =aWuբzt:{wﲾe,Mկ5JZn44^b"AAKx'Y~`!VM!{*Rf"m0W"z 2l0z'd)vLT+]@64\ *} #Q-VP%p˫|zҨTdSG` 0uoabY{`x.5zy矠٬'"^f r v= rBQ(]j T,3$-|zvթ'[rOFyMӌ[qBVO+,$Q }[}c%_tɗ6)Dv}$?kZ+22"bx~H;D`ٌTn[/zl=X~7?Mul1Sv'g$1%rC3M@tV)Nm=6wﳹpb*dN;uxuxRbKIR4=gfB؋(A/@8A2̥˝~`:P.0O!bw=Ul-1a^j'N)Z&rEvUJ.REf~'/vیsp"5mܸ8Ǡ7[;>vTb`[|_Fp]U7T*K@l5&3%Et#24+,G`sDU&nlnr)qq`Xy4ASсz9*Sqgn(/~n띷rMհ\k4RP,KxjC] :ClmHcJBd.L'y~@WƝmi !kL]@1d#*1MĥY{%~-(hL\ s;7E]B=rNQځU'{kL\D)pVyapBEBsuIlJDiYGMhCI'nzN4 EHò8\e0FOG-D@0z qҠ?`_dsHQyF9ͫPؚY.QT_6`ATH(6~u»,\D!i$DD󤟸fC)jt\F: 37򀑁‰;osO:n@5 Pch;"Z&muB3sy.|S4sEw~𧯒V~N!eƞ|NJ.-7xcq0bV V:*ˑ"`W\[ o\NS_{eIgSG-IHu|R-ǕZbP+ vhiFR([#yŗ,_/^ybC, #KŐVU_U?+fQo>LeJw #uTT_*ӽ|ESo >!$Jv/@B$?Q-U-q2*, IkR7//.Ug픙uYn[oDLm]PSYykLu޷wPqd~&j&RwEY=,bE%IU 2b<EmoD̫e }*s37^?}=o~f xl/6˷>fcm٧B0#ȤWG.HaԱ}wN肕U /J[XLaEkº|( ΀$aFO`t=C?Ts\?$% $/zu~ZMzzڳ=9&ӋX|TжxŧAԣC_;kzQGڊٛe Ro1U R+l>5;^_!O߸*n2ht2~^I창7:9>Gjlÿ{$)TL<.lUvX{e&^8s;;uFk.xeLfxh6ay{ (XB!Q7@1L,Hˬ>mdHŏk:Ꝫ"vBjl3fjDY?Gl)j#7'=N4@冃ܘwLͶJ}BiM/ LC5`/-O3ҕKF~rSKfycJЬΓZKbW,>(W'GI3-6ƁZeߠVc`` o/?`FoғL5G6S!B7??;"' ;."kŭC+_jC|ؐeS{f.$RH^^+ʷ>2z0T>lx'|)Ogo}LfxUJpj os!Ae/pۙvv}'}+UMͽN+qp؇JF<&Um&~C>w>Qh;6r$ӝTA9~LKa(@بg27n>Wcsm-D݈n- =Zc R~@MG=B/{U5&Qa{6Y"O> j? ^מD(~ QRWDU8ؠ΃U[ߕu5h !FTG%KG?yY8#&C9~W(ߺ_ k+tI9^o[_y]r%60##|Zva7$P S8{}l{S=+!9-! 26*Lח@BY p<|YD9DDMH #.T )!'K&I'Ur}Cl>`j0υKOp SSSd2JC3\|+ݻ{(=}xgn>x_8TE!DOp[M$-*O{LDX J"NW] c%\2tƠİ{$lE-3N H]88 AdP$8 ׯ3~n>åH{hz!>a ctAqHe;D$E 5ŒM]k_[?12ũ (R >ΗXrٮo. DeneWF:iM=hD:2s:s.SU]~QMEj  p]HISuvUM'"l]Z'?>HbH,.umRe4&ҼIN`k85=إKCQ !!K,]&*U%,nٸ~xbkv}$rNn2Cԓ W?#>\\(QNǠB鹭bəw\z)Fy՗^aI @*{K;}~CT<) *+큒c S)|Eӝ{;Ldr+m"E8ӧVUmPIJ$+zäIvaW~F*KxHR’M]bPmߝ{w~k|(}+}NL>_Z`A4]5/D9 j TkA CGM$P>,m'Y_[9*+Jq|#^}퐞!;4tᦽP:u E;$H!P)14.32ܟOJnhIQq|u!yk;.R |dA±L. fizTH !E*l bIBRdBeDiњ 桟򂻁"ŰVeIiP=UbG:[^U4h5[h& ${>enL;.?eCD0ddxHUUV XU?ny 3TȜKO=_wG&ޝ~p .E垃˛%<MlaFqjq0aEr*Ŭi>/4Ca.CpI#8I$ %3I*%\ag ;j zSm6qw YUkoAizMTQTwvy>15{{?C)H Gh,mN+r22~y D)Hqwjx̉Ǩĉwv[gjn@&.<}rA._e?!k ;rAW !Eu0=pLLXuϪjJnРy"e ၑx&? 4;hRokK?ع;#%˲ 誆˸qC'yp}O$/^T 릍d6ت=zHH3$ O9&>>3EI%S,rEysoO oQh9Ȁ?#_DE=U7T{͔qlҺ91_21-VU{^9΁X7J.AxDoH&rn N(?LvT/[uqD^ŠT7$Y(bK Ro5. Y0M i8GI@WәLAdqyc>Te$AQlv) GN!MߨS3B#|Lj q M|X>g*GJ3TdEܺ!%'t| ӾfW^?Kk3>|[c3ٷ%QEF^^p~֣ŋ*+Lw[c7dUPxiVYm,\Gs=)$VOIF^S:qY“1UQfk &L(WN$ ʊLy^ ?tp)**)-Ae&k>X|hrio}PtL2Ykl)ڵ(繳;g(RUauU Uwcrޚw doh q[Q}gQe9LpťVF&}^"IlIJF K}΂M?OxsVj8lI-d3RWrtP.OS)2./o2xJtQ "A. -$IܞIP\(Y J„@Liڛmg .j%U+;9fT!aM Vj{T0EB;RY}T$r9D#Ձ{5yY;U kAd40 @-L 8Eӆd˱9*N(*bYq&@N( F'QƯ]C; ^$HtOoݍT 0t\1ÕY+ %N.# ЋTgi_ dž۠*r#]j/bs` {YՆFV_tH."/K=æ%..;9X(ExYẎ(=]C2i6*o8Wm<:aP'F彽Jt<&Ѱ}ĭ8^frWxw;5TmX=}".p`1گ= Ww˟շ}*gTИUs~l\P񻚑nKX?^*+V:ڝZ(.\8Gʾ&"A&Ku{MDwei_<K?`~ߣ蒀'-_Zw79p}8%i Dx"E4OUHS7mU]%bttu P=}Fs#7Wdޫ"߿:L'+G*m?VT[﫲/bs`lf+=+]7˯LiT_WH&-nВh{r+h6yM㐠ӓxoAu4rV *j4]pCp\ 쪙:NJp^TSTVpT*T, ٌİڹwW=UVp;k+ z2ĭQyBBdG H ^୎j/%5B +/_m͔zsأj 4 V&׻+.|we/$ǕRdFuW:*uXa[7&iZ.LխN>> %. ..b¹bb^p ZvrciN3Bʊ=<1j;;ϓǘz-^}GVw?OJV TVDvW9ᠧE251Y:.: .c fY{4V8htyB"[clQ<<==EvV=aӠꮧv҇KFŵZjpqjyaj9+m,ƠZUbsPgFe9LpdɫΨit,EqR& ?c[;\shL䅀.MO!b#"gUqڟfݡ_{+TVNgYhf}ů&8V5r*t\`a'x) .8/_m&҇a"1398?=7.We}˥|SHZ|Ue_^Gp>BSqlD qZSY}PyYDv hO"QSrmEŵlT:z4 <ǯ)u~^괁`V&ȝX@ڴ\ߤeXfW.?oq|xn:]XPT:i0ty뿷' DZIIBKVWeazcC68qGd0<ӓ<>=c4ձPŰm5QUv~d"ǟ|ʃ9SIr'!&AFj8?6401S>GƇu:x7.MJ^ CRHʲ6Xgw rN]ó:J0R$ `5[X[_ot=6vn~VTmXAWe>53qǟ|+I zRvA;UOlyT1NJj؈A<9^vn w*)MmQ>Se% R#/DSIm{lz06_7 |9 O$st}VfXP!CFdt>%mT١f{ ݽT݊{6գ<6 Uj4jAQ7oN=9^86~z|a7МK\HN,8:)@< }\]Z͏?d`l,Y NdUQw4Q8+1LdGiu)rDy3Z'>x4_ۣRUFur=fxc3 iH=*aFHkxu;H7.]oN\npXQ祟o9֗t&^xua~ wȪ"x'2U;GBUyR=S(FmJ "úֆEC \,?jh+8GAU[vг;: `CL^\% ZVSmwC0m݉K5A)/7'k}]9_~΁sLx0߳;#&%r WE@|euݥEzQ ZL"rR@Ov PuIǖlpx*hբnTݧVmPiDKA*G ڠT&<6¤ޡZ_ۛ˭N^7PUYLw}~l~qhك*ug2&|[ei>I*a(V;3}jzW{Tg~mP5O!EMzmj}2O_H/^#^ړ~Я +KAZj)~JȽ8[=6sPw//\[w5MV7B]N I ($DTn5wTCѬY*cer>мӐ}~g3NeSx^CCӼ`]em7[UTۧ,s`\Oj1_Z15g9 Yȴ\ANxMą.fby~|#0㻶=}UR{4Z晊Q: jVe_#l4yau2QQW`e3ؐysb:4<]P{ݠa/g 7S _pK(2-nhYjeE*k-R}c<$LPGcoF{뫴|!;l{T5j;;:7/]}hM֏i/ۡikW.^7z*}No.<5{nVW8_p~΁H`y*֙j*h9,:V ף`6+J[>F,lYzG%ys괉d1 N2~߰nlƽuljqdybd@apZla|atZ/LNj xd71v ġ=P\@L*ny&ڰ{뫘#|KVk]v?prZ&SxiZ՗?LPþcEyHEBZKH9/k3J 4XJv4/4~m %IBivnas]vw:V=o,a1b %#W@)rN1s}Q<_K͋4ng*i%9&j(IeˠTtoϚ׆z\fKN䗧f/;@s~΁4zrA){[/fI:{[eq]ٰ(P& dHhVF4TSmP-d(ʐh_^>VL”Q+Iq8T%|HMkڰ X996+e|S_y3*ڽO>ʗ:x!*θמjΔ. X?!ee2 / VHBK -.ؿw4a=[l+>?J8VKΘ6qwgjzT}Qf`N'ȰOhLLem7[twx`~b9~TY ~kʝũ-K $[L:z9RTԔcGoՔCڠxmZMO?7.HsUT Q!΍f_pؗ/lĊn4ꞗSX?yhLq{oawV^TaweT]#mZ9DŽۘÃl _&0tDӢm5je: WLS,m>xvgTǣj!ڵ`lhй?+U{s%Uy+~>ӀDBaasZ6۫3$syN2SQ:OxSls@mK34\z|AuWuzr£ .O(yd*5\Ts4| '}} :6;s`-h泅͙K:U"3{K \Vz5@O6=j;;/w@VT7}nP9?7\kr=suH-RT9~T#)AԷxcj;FC$U@”:f~[ cMʚ]Ih90W: |_kq?q6ffoȾ91 j^i+EUV6N)/X?#' IgC ӽ=sw rJS-(j5,S"Փ’LkRynt\zeyj SS@x?wi鐯.qfz;8;o_r=yY[> X?⸐t7Y^O5e22j+ڰӬVI+<;?je4V47 4[V UL>gyT0FwT]o\wzj&3cP-reR^_fʦujаe(Ejcq>s D-KS?lpLPU] T]ڊj//kӓ&ǦŊ|9˲4#;߳|qzڠtaA UHTY׾p22RݵkVzT>gJ&Q\eb/ FjmP]x]Hw|9X*+LwūKSw2rJ܆)(сD;I'OQCVn{ 2?OuC >س:~o~zn:]hK?|9֗Zf&S/9ZT9TCi|dwڈyN{~9̥Rd*5J;+7Мs`}UV/=yPغ?QѮ#'MªeeªIhU}!o¨5;TvdzeXQu/v8@s~΁%;>,6NHלf@6Qctd)lT d~$R:9Y?Gw:TT^ f{^921RbEu'VT9#媲RZq8tGS5, PYBB2w}^l2Q/b t/<3jKGNޏC6祟s`GBow{}u]UӖs9q̡PNu)}Cѱf)s-9^|zvXQo9?:?X*+G#ܭNԩ%!/}bxGt~@HB Ε`k4|t; Fj 4Xq:#S *󵽃x(4W+nEܜo GFo.j!UbsPs`[e9O,zwkc&71>5L8}aA iP/v8?:?MTVTX^xڟ}y||?_m VT.=ѽ*:9UYY[C5 ڡa(4FsAȮ /L݋s~΁=Pg }}Vo[9uA՞{Tc݋7Мs 0R;Rw6krS%ig5\?8~n4ps`*=ʍԢZj|8eQ5\*-~RM(|g{{I0\% .xˆgH;A5|x ՝P ?XcʳW XrXut7ـ`ul V``?:tNX+.pAV'> Xi"VAn4 V/S :J;CIENDB`imsprog-1.8.5/img/93xxx_adapter.png000066400000000000000000000103631520775651600172130ustar00rootroot00000000000000PNG  IHDR`PLTE ###iii]]]便ttt... OOO>>>+++;;;:::111```CCCTTT㕕777'''{{{GGGxxxfffΜ߆LLLnnn退XXXbbbhhh___gWvIDATx]SQ c/HAZѱ1zMR4 di F.'Mxysm]ǁEq`s~!="bq`@@`{ʸwS90ƽwSQ3 M#Uqp/if?bFid`UL3.U 80Vǁ=r`27s`80v+`OsBC$F3fX&T́q`́H5w~ȘG|T,/E'pw`tHf`J[y^_Ҁv?,8?Ҁf`  /3,<Riǁqp`?SO .BY`3 ۟ `[g~7``[Tek[Ơ50`v?اޛ^o7d~mvUrà3y[(-9oMiiǀiĀŧ1,UIǧ&jA+|К00BN0Q#‡[E/FD Њhh UAJn9zL#LN:#? )\H7q`i4KzQ װ́QƱ΁9q`́90ؕi/As`*(܁90`fs`9ɏ#8f=́]s`́]:́S]cOˀA3\N9ρ݇g80֎ӈOcaiO n'X; LN#L{!{44J`4Buߓ0{g}b3w"0{Ec{q`|`b ؓ|nLuO> ߓ s'?'*"*>Y䋴Xo0ŧ1|vD6ɟ|-0QHM>Uq߸{n LhKƼ"#cy`I>({{0y#*࠵do#A+1ꃲ'_Jƞ٢ VZW`NEeOvy{ʞeoO~kk29JʷV=:Tqn{kN0:u`L Xm190,}*80Jos~ 0+ҁ)U:0V9o`/OāwIQq v)EXZ Xczc.pf;pC_4unH,> z@`!e1:j`AK`=W]00=_V)W@`2lP.zxW瓬{VYtB|D;Mq`2L:t~| D'*O'd@`Z;L|80li }w/a`zSC/hǁi80M2WA`z>|D;Lkǁ|0=lËMD` p`z>dp`d> Lڝt:[|G|D;Lkǁ| 0=Clҭn|aw/d> v/NWS,2LP#6V~jX^M@>",?|80FhǀmBMzQ`ZLo#,l3.4s7 0`|+4=(0uFnt xOX]Z[%X37Uh*6=Mj`@9̍ݓI0`3vt؇tY Κs.=0' Val!Dfn%1fn4ꌬ_"eSRۘc H|ޝmh憂f`m@t l3]~4sAz336s{q`:! lcLn!e=w#.|IE`2&uQOA`z>Iq`Z{80ب&"K'd>Iq`Z{80د4"wŸ?$kǁi lc`E9 <>$kǁi lc`ӎ=ŀ$kǁi lc$>½ǀ$kǁi lc`ò,]y غ_}x+Vp`wEQ\1즻,^DT{E;LkmlV~%ru5|՟D+?||zE;Lkmd}S|1m̸ F?9|WGȻ.6fٓ#=Qgd]sՓKmYj`m%ӓF5ۘiO}7|3ɿ{FZÃV)lv`qm'?m`jeғ滛7<;uU7sz>}YUddnXH`"0xgF`f؝"0#0cwF`)KG${E`F`b\3#0rYF`f W夽4V LJixd|E@hr$kG l; ;0&Azq9ZXb tŠg`q+ :N4îW ~*j. @̱ \ |1󝰢 Y֠a ;̷48Q#YT:N7JpOX1,h6nS5Rk, ?l ծ`4r}2bj)8[hגipԘQj_0|Y'S-|u4رe8zwXn4\8bfx{$^Y48` |887JjcM+o<./Z?0N <ՀP]sژ&9rQ9V=G jSQ`,ޏ#OIENDB`imsprog-1.8.5/img/IMSProg.png000066400000000000000000001651671520775651600160050ustar00rootroot00000000000000PNG  IHDR$H^PLTEطxЫ%$'0.-145;9:@ @e ff*{-׷5BAF8 #^2 &jq%GJOt*FZϲ\yx| ;WX["ka#aC\ÄA${gڸт2agilKSU *)xHƾ^A-_`c1 E( 3ḃ8qrwَܾ3\xsן N4)̡TD{xM5SK">~պpݖG1|C ǪmsՓrGn< "b<¨?4&9M6Z̙],@ "Ӭ2.x>؇e*"Nq~f7(⫾"҉(zO_i!ZhtAai{}QJ)a؇z"6K#ֈ&9зό"Y䘹-_=]447`WR-jtrZ6m "!{Գ_RJ`K1W5k@VqK: V|0;L C2o,t!"Etuz6BYS"R+0ٜmf0˨Bp:EDy`"`3SSU+UNuu};ո$D\QnZ_7xz\5WI"N3L;1ЯGi[af"RWF`(l}8"XS&-:Uf, ugc)w rSPEʁz]q{ɝj4 b ~z3XYW`dKh +(Z4ֆ0sx[GYvD2UbV0x1ehm/ЙQ32:Q8j|y*#bԪFgd "ر#)*`#h۷0f{Uy*yH(epD- bTAi+cV`"|9?;Tk5%̹FER\,-CaB9I $ǖoqX:;m&>=V~%zk13ދ-^2)p T3HBM"kðXw<_*Z:v Qfd8Đ9)бc҇E]Y>zPݮ[?.Ab`o? D<'偉m|vElkR{FTB~ҥ /c h&=X50Nk@LkMZUc5Hi4#_y^m+Hn;ִ8sGVf!dq3,{cGGXza&^jlRرl-ltUw"9w({4gЇfm|ww+QIyM|(a a}\Lf:Qp @0%TgS҈r"ܩQ0@FO*!!+bv[1k~}r-gA64mŀQ*nٔ6QX^kSiJF)&LQXs &^Sdlu('rcë nYLs$Q",TUX`-H 5`b-[uХY%EH1'S^H[ل^ݺUHfPӊHkLF@.&o#SXg:7%ww#+ fse?j4oVYQR6d{N [hpt+u mYp8??,-:ݔIbKJ "JyVFŠRΆ^|6r8 cۓG0*g҈(Q?/nt_0Vڡ ]q%{+Sjrxjvy~ۍr腻χV7iSHGO^w048=Pׇ ? rw84)ćg;9׈ +W_[ψ/ceR#X'ىtYI{= ʧN:|ۜtE n)LJyM_aoߚ+5lHpBONk*%edu {CAG=emJcޫZyuzsSeffSitWnkӓ-^]lYSӖ*O@{t7 1ezn˥fvu;Љ "D$^ZG J @$""bi\>1ȢrC \7"x\f1`;f,m ;~JK VS z͆ʜmdۄ,GLQ u$ځp@ LX]wvk6.gF0xV0iSXzrӝ]#24bBD834X  wΪWl,a ŮS'NgebR`2;Q|8D$)(qȹDWzSb<^Kqvl 3̫@sIb.8Rnae22fD qruL)]JV-@I,_5ߜHNa.e`Vc2A +AG`'t]0 jIN~̈́|FIԃ@)%-ϩVG'v7npCqc&ŮbOg6ux5\FFpeۧ767bO}nQasDX老nnWմMPsCQp׈G340"Q bf&(A4w\#r?OEಊmTU 0S|T􇹯Q!wѭƅ^%rXj(al0$b9t% |gMSL6: 0^͇5)^J?#jX1|Z_MM|FJ[͹ZDz?jvp[{GVM?(L/A< IE gRƙgý Ìv6?)@$ܭ,4"G/h4A *Mx0Daf:.Y,Fd5}üo jsXü҈j.BO[o/}ޛ7lBD*:il(朝<~u*|F.1`}^{WG(jl*HM >u(A{ŧJ-w/_nhQ8 ǔ)wNTnm-}Ri>YQǿ8ӹU FĠQҷ@3b89]ހJv!4C dkGIZPzG>)K+QSΈ6' Ho"+P8V4@X3HxbmXuc DxF`y0$ޭE"i(I!!0 zǪX>/DQ bc/s)o*؉f">n4AckLo%>ݯd2fis瑔]\ι F(%h~B4.]zƤtw/9sTCɾ agfgF+]5@R'ºTf!0r \0.t~vU ŇOS$rC*0!z_GYFv/&xc첮#/`0Ҵ X™B*T8jn.vC*;+D ߄i9ޙJꥊT]9q:H䶄6 r!*w bȻ*ajzxԷomFh5_Jx9N)Z2  ѫO98Tr5J ƸzkB$hz%vP@18kS= "$3%Tkqlk)x5kC?T$VcOW$M$x1PGYH43Il[@ӫ6 D7ib^]}`TSg\:`I?Hv'Wu$0hZwN5 ɨM[k͇~QIf*.dr\6Ƨ5  @<= o7!iaPGr׷Mݴ6.+U4aV^,4=@1%;WЖ#?~Q9,Ў~d+QGe:ELKV,o&>ʕDd$tUXh\:o ;btحtPKMkoPx/JhbܘO@Mer:FܹEp=)pv-9h?ۚ6i iI` W\O_\h  $jFQ'!s0 f3T&ىh |< cp'Ԍ4n=$v*:Bԑ'zґA1z3h\ wnQkgz   *FȒd&HS1,P[1mS"I>QĢE 4 YtarBRej}_С`}L0͖6&ѕ+EܮcSa0 Cnv/?6"ZA#Gnhe${p}3y{l+14 *4uJZP^xsLyu<rvŕ ǻOos  ЈhD`2PsI@0#ҥB:ri=#^É *9).1/__%W]kt t ]"Fa10b?lh4e.\$C]e+EHaWr*\i~~y8VgsA RF͵ZiÊER\KV箦X;"v5Eq A>ni^b_"˒'EBvB bY(((}}k8赹\WZRDA,(.ISNN,p}f?G'|^^\v=㎝jйRSi&n$Z5ni8'nY0挺E\֮N52$̥-%y% |ƻ\i&a?5qYVDg_xO=Ka=cr6)G=h"l59S"`wyT!c9#!QN&iNKKkXcC/V?>muބp4 B[-wd Vv q'jo; }eDSoSw->-"D`8.GydZ:1Ѹ$CyjLRśpXJѩGΣ]Pk(z.Vr(IZ qij>YnJzh)H1\ r_WZ3*_#ǨȫZ%Wlٟu8wЛLV߸ ^1#C,J[RŭUקD9?SLCSUR&%B^Q88xЋƭc\M ~AEm~ոmכ ^R>(*$IVUԂUeSVֿ؈Do;H4+oo TX{_$Vb'"}IZK3"où!x><5%e{[5H| )]}b& u8;騨^k.–/z:ς8!7fvv+iknRH OR e/̜$W]}|k_;??{gJgD}}mt` "˺TaP"D Ax1}fean~zzB+Doq&BuPxooMUķoı_Z%NS,J#7$&0+#UDsPTҡ"FNB"A1CtiG] AR8G @$,3.+=,}-=5x^#oGAz {GY[`ץE_4Ssu:5>oDbTG~ؖ[xȌ|~d]kwWDhSE:W޸bg7$9)f##EO+h'+Ӓ5ϐ[٣@iҸ尳ұvӆXsn&"Ӌ-2w&vs#; qesn,KnID !'EBV|'ę qϝݝoNv&ėQIQod[k \Sa*TGue{O^@kGt9e$AT @qDX2Bi~KHarJ3LiPG ӑv%띒@sGFp9c3F!$V}A9b(ԕq^f"ԅ=^ &-b/2zd`S,/ ُ-ޚÌ%uxSǛt>%HGS1!~wSӧ/okʖk9~?2GT 9. uƢj DRw %kO*U,dqŹ* шfsb57G"bc ѭAlA1U?#fA;q#;0@DCBg_4EU/mrQ qǙD sao  gaJRF} o_0Z//ďMAAIhՌY+0>iف'jE:.9l@ZLcОbc K2j*{sV&\( #(S,dA!Q?mHX2AD)\eH~z{yďp@^? pGĝeSk<X8b;.1:~3%Sf1{;"n_4HDMI*d /FP*} Z13; {a=( !/rC}GT!4rEbSG~qDoKoN̮i@hƒgW^* {ᰦca2:eS)F-} +53F@[jzc bEq~ύ#2C۱ԜZeh7qD=yb2)-%ӵ;$"K+PV(KtrpX:@qVKk +؂ ی&e͑!|SԳn2pr1S-8ÌQ`6۠il*|숟ތ a̛hBX7b r5 NP !Go:Da)qze_)һ7366DƮD* ED!N9S9PKS+cGtw>˼Y#zԄEI#w"MQfbT1SƂoGtR$QW.}'ڌg!q$DQ/1 3":yƉCu4fSZX1+iO p\r.EN .rض*xjЗPu0ܜ3Ojʟ.1YM@ώCK 맀bVh,@L"sQBaARtzBa>OJ L 1ȨJ>$D!$X-ykCG6;Ddq>9SGFK:s8loυg?_͈Ƌ| _\.ܫĮݣF gȿY(2&X!QAԘ@_Ag2D!'4'xL %J47/=B?W[B $Q0pO,2E#!cf;vq=G"SO$:M\ $SD0A\yOBc0qD&y:+/񜕧ͬTOWGQa/ lo.ִ t\ (Ԑ (vr 7WJX 촢|ύSOV(xGh6t\i(Ю0=&fވAϭAyBQσ̠MIWG4{Bxk0Swq?G5M#Ġ[Kj(׌b#gד[ݢgZs>"“p:t!M|h[:"seuJ6ը>O!% G®p{5 Яv\E菄qARk_9 I#Atј84uDGϙK/㊼"0XDd5ƟN{O-8;wә=0!\\ "mp"LH[( ZJT~D<^`8E:EBDo;dn܆a0 %4"ݠ}#tҢƖ%%Mw?P:'8YY;@ ؉mV_lo6)fU@a8}R0tWM.˻i|=Mԍq&#^>\!F,j{ JrĴ42Ո%vV.[6.DW4p)%{&D*v$ "QgUׁ+ud|`tߕAGDs,M`^D:#9oqو{~k(dE6ѩF>v 1]dΐHҹVħk|$ 7\.(5# #"LA쏟7|1KΪvocGx\S\f5?ո|`(KS,M;¥%ʈ`([n#ZڂbEvDS%ƏUt7b}vOE;Pq^=8\eDi4J ,pԷoBK"hlDb'l=q΄aZ:]l{Q4lu|:UOEAT vuDSWCE.2@h &vQ,/ K@L!DÀ*waF| !aRGS4G$]f>z'Wg(c@7!i÷OU,M eit0G 4VnkT=#b[Nћ(FLZQ422IkPZ,] U nGhVJkXE*ϸyP =ٸHkO,ClHe-Ϊth>bZH/눜`1Uiq@lCS$[ V :%`#b,DWC m %ڈY{bEwBwo%7ΓCb5ʁ }pTORRɠІe⊠^{Ia=`.nq3atwO{G;Jr5p>T*z|rj9<#:3Mcѓզi#~+p~ڈ`+ bsU Vk;L@BJHb_bCwhGPDdΓ?^gC [@ń듲bU~ B!x#GQ @".s5@6"RUD+j͙K,.1Z T 5u q(-:| x؝[ E]Ϥbb/jALGG{t+9:=ZGd:ԦM99)W߉K2sDsɧvzHRLFdgDP$p@Ԑ-a_3jGԀ8plvuʚuCꬱ4RZ!T-38An\4 _:+s?d  ;=DEvkJ/K[+-v'QmD~%7G15-ymČ@R-LG$~wg2Q_ ],e0̎8op̜ |D-9Gߑk3D52̸#ݹ/~}CO"h{Me@_ns>9Y]"@ifj:m$ 4c79C>@N olKPity2ݩAHh?i6н\̬ 7ŭGx=O r_k)u 1Ig 8"RҤo@\@m:ǏeK`DLSS> ^qW6z#R]o#UXr.B?%2!ծIP4za 檍Dzsc|c"q!?( iiPޟIơ -;$;"[x{`LC:?HD,\۫d|yycC(&>]FDTqtNr1 :<@\kl}QGD"y,ݸm҂E?@Flwӵ/y`DqRz $T6u.\QB1!+ y`#)'Gt4H9\ʘ.ѐrT0Ƈ;9D,k Khd "{5@$* ODdpQ _8&OE8eGo ۈLYo#2k#vhۈxI1Yf9?6މ./-wvc;_$;VHzR@dzaI 6)c LIʤJ}/یĹ`zzM5kj"XK>ii[E^g͔X:+qD$ rحW[Z:TWY-ۮ^϶Xq pR^8q{ Z6ev)RKX gW&ܬ#rG qDb֞n˓F9RP:AqDGX+srGd}HM,4c7,5%3XjP(d<=)sl\SYQICxI|qO)c5y!ִ̚=)nN> X{Q {pDZꐐ5SƩKvY^.uS*1ifQm9!x Bc:wmaT.^9kzmDDԩXL I;H 4 W㔐R%@ HrD@A"ZT9DA"~73^͗v1'ww%yo{q\Mb*`1X|nhe| &b?Q|Đ7С5sMc0,cpɎTl6ZTAы۲''3 \0AE ,%{a[#覈Zزa [y$+z7P^JiphJƶQw[/mUAc 2 M#%/Qs[Mb2(w Zh)b fLbsDYNI$8J 9CM9EZ9=">boc]0*V"f۾dM\#jj! Bdz6a{H3G4D1$rx6OiQo[61z+;7VSOd"b{زd4pEP^/B{[6a\ɩ`Y䇌ij(mWm C6hVˏZj{!b8tW@ EEȔotFUvO F ICal0IDユ [U'k?,Ǧ lìHψv޺1鱣xzN0fvj6O* bck`}GgjXVX6Ts]o?|"[6֋>,w _"PE#b%ܴ#nWdzV)J<9b-)MqB6+bwwuD$l׊PF&p' z2"i+*Y2(h.y8z2}pĻU&'&4? "~u9}zs'b!ؖmȉG^< FQ1442U&1hFbTĘ|dK]4ٖ EhrE"~X*M͜EJڻ{J A-?Wd-΋ ڧzq9*)ě\0vRV%KE)_̾qՔҕvzpsĈx3CώCS̠w>f^ 늁`[60m 5' Z\ 7yl 7e@#q3JN)vHWN{@_ ShD}"BPl⥙#cODj&cDr-0+.%"r ")J9Alb;6ߘ`VM/E4Qˎ`bfvkZ]nEbad"֖>oDVk'Mv"۲o_rt?seu>tmj31Ssw}KW)W&+:@lH>]Oڊ`9G&"Bc4ؖ(yN .~̹r#p$Җ͔o&t2Y(xăZqk1Fh #5X%"4LD,`-?|:iMa>Vﴄ";o_>C٨F0Ī<\.[p/WODȻU۸; SV"UӍAmx.Ǟ1U<2We.#V")qJS(A:[4BB8[9X? X͑>JDG-$0 Rk#|~B3A i*4 'q Vt3+ bG18߉fGR:f_D8Ͷt `T qy4#648al4Gԭ[":%raBv0GDTZ),t;[6Tl}6RH &Ǫ=tyX AhݪieB2[6jf2U 3 ֹt<7낅TBUS_x7`t[sDc#} :a31f͆@̈XxT51x$I =ރ%& 7igM Mue K 3;h/rb`4n/GOo] J:jKȡ{߃dG im(+eY5QGvAй;=0zѫ6q fkOaJq>Q)c]S!1$hח+vf{A 0 \7'C0]\))WsiTZ?H.d|.#JG2+xTPl4G)O?VP!A_^'ktDdhVM|43޹!u+X5k~&cuwhj:ԯcQ&8 "}эN-"'x~5m,h(_/lدc'k4e3'k.ƟuV'kĖ1&W\^[>\Jg w VF'k-[ÞwŖ=ҧWjEʲI;{;ܖ87@j2x8{t Ā]xhɚ6e3ye)ϯ`qFwD"զ[GV;–(b:W࡮H*bش'k}x\0b"ʢZy'xO詈d/^6Tq~:Ob"O}ˆMtCDHftOhDkh+YsX@RDv0i :sOw†eNO<~eإLjlVA-ҦlJ/=P.,5bST`x _]:1,1>?VoM.y/0VN$s *[j(SU桡1F>2G҈M!~sEa?1jèt*++e "{7 B |Ň(LYyaOLTwo^VADྙ# D|ϵɱfزw o7m\?fW`Lt=< NvQtU7ʴAbJTUYxs뎏VGR}8AI""FS8tz[g7mLzyi}fE ZC*b29H) Cu͚cnD4bSGDio)![?ܺtiDlzd;lxYWxXp&vv&-s &"c@!!+iT"U֬ٿ+Đ'"L"R[ ⶝#^_`4dXYD^ױjO8g^9"Y4 #!#NEqe#6U,4_ "dإD׶i2|bMԇxED,y;۫YzK |ftv"߾|>$"nu"Ny(in#f7Gh}XLlC QȊ7uweS.Or"aƠw{y}Y` >uBTlTJ/&Sܴ W-˓d"sCη;@äW].fb4] ^~6GCkqfs=Sbr N։Ȧ)Υ; ?~R#E\VnP#T`gO Ζ@Z" |FuVDXS٬6Yl;18|fR!aOwA}1d6+]lkkFyk}oլi-[:25k.Fjyg:` Lqu<_ n9"%VX;{ Js[HDϖ\̲BJnFE&>Z(b ԇeܠeہD܃?oDVT*d B `qg1 ՜+(!B jrlPh9č(Ό kB%NIcwV|޼,1a1? &r"0/u^HGLvL=~q~jȲimsRA 6?Ɍs(I~K,K`pO2qB;zcۭb}1~]¹D#n <}$wM"x;ۭb n<(Y՟͢$ϽE",8{Dn1Z) b^S ܮZ$=bj="ޠ&Κ4=y÷`p6[mDBqfNC8$w7A2k*;/qf`pWoLW+9re4*i6,kο pdoGDhz CYF`]ut`DuGk^fqUg-,[:Du56~D}âj}=bSYrYEgtZlB?̮,M9Aί$]$f[Άm1cPGrZ0LcYFDm<:Q&,ܖFE: ~,eF{d&g_:kࡲ5ǥCfY҄M 8qUCשkFmǠ(& yĹ&=[,`]Ă3} oƒ /'Sh`0o&|h>s↮ 8#QlD=1N2H+-X^^b~:ΚxsqB vQe<8S˥F;ZCuXnݥbP!L.@O5Z)ZR3b/e_v|7xo-6=36;}l> cE8< M/.1ku&!TX9pي}p(,yƠJD!8R٪Q1K鬑 ̟gύ_y0ʧW΅+qBS ۧ8 ^ q:8@\y}OӐ/ M~J+ |upŤR,jF-5ix^9Н5}Ƒ9iWBlET=c[ "dky9JBpƣŒEXLȞ"drdM7j1 vg @.;]g3o<{%b+4xõh\_8B4jZ>]ϜHc܇WLʲE|.a+g2gLgkmV7DQϫMUUz@Sj&IdVS\E͚|e؂Mbp$;|~tԠ=xs= |A| 69#Mw_sgAphؒ3clW ;|ӾR\4.Guy|>S7@np(~i @:k$wq'ϵ8^tf0P"S9N3Q` cMeh*md6Λz|g ]bm o~@,% \ٹ(F  CrU>DhMjw#aIb̉K~o  ruDJ+_|[9s đIfN;۱+ς=_$R5ð<걕x:\ڜyPkA| | 9ժWuj@R=1Qd̒ݼq*JH()n. ߛ)KˇY8<u<57ĺFrkIu8$q _di:Sb7D4AsDM7k`pjw ,G7VXtȏ@'ā0tܻo@ε]d!Y#Уɽ%R5N! 5EqɟR *l,r3'ZY٘eu4ʖz@FdxLUpI)& UfK!ՉEEHp^LG18!CѡSJ,۰+Out?Nl-mM6UuCrw3-;Wp>6ͷK$!9?i, # 3,[fT iU 5 6Ċ'66;1R1H$Kɘԍbe˜QoF9QƝatt 4KaaX#('&*v0,?>TڡP}DpuKs_|g0V IVcTV?) ۘ[^׹uF{0]JCbjl785frFXЉ1}dLˮGbm`Բ:IzDbNDEBjϖYjPe60x," aTJDiMJBb|[ g]%M-_18\>+&l~xŻ) f n-1u\#j0r2\jR2*DLh(\"zX.f3P<;bq `ycRdqK~2T5ie7\٘ha>4YS">ScvUռj`\1 MK,^Lf` ֭rh) IĬVbB~0u֤]`KS:|tkkck],pȰ*䨥#.>HtufA~$xSUU/tLSL#!?M 5S|Ww >@u(j~Hyrie }#)V > :@ƥ 1gI @'Qύpp0֚tXnЌk͂*"L~ynF ĕO1>O^S=C*#UqĔ.CF"--alxXj隟f11\BbW翄_#4H Da1B -PUԋi#ҏϻԏ~`pE9u1uJPɠMTl OtX2;>5>e֧ahY ъw ;$4q< O)!!Kf g4HPQ*-*ﲳh+wyD)†6b"6=~B"{l},_3O37=L[P'2@ %AȖi)Wtwii#SfH\delh"ԵQ1XʲQVeH6jxWqX@t1z@p:_%&'0Qo)ܥ$Յ9ЊI3O6.(i{eOq?lr+BJ/jPBǢ'Y#E^7/ݦgGVj8]9<}V bl?q\M7HA,NkąMXm4*\`)/o \ Dȯ=g<7ރ^?Ii6RNvZ J6ۿ F+gMlMCt{Q`lhU0 +,g06tϓEbГKI颱of#̅We F *D&sOc@ՠ~Dh w|YxA>敠%Ii6$B>266Qး0}qjv w˲!MMخe7 7jht9;A1x=GPyFڹgYCHh7rzn6$Q"/l ̚^1K7_`T-b}CM#+A; &42`A!i7İ*hr30,˩5jfÅ8,=zB((YП?Zܯ_>DzY_qހ¾f;ބ4S!|G"67la/slV7*5(fSϹj&SM bngMAdCo`b ~-R!Lr47I!:]U-i$jc[__OVpBHLgC.VYR1G pPA}bBUo؜,^q4g##TĊI:P4C1ɾm~k8N\Bk6}HmojuT-2}?#R1=͖!YvY~/}~վ+amy+׽N,bGv( (4",=O`+Kv -qJ`xL5/˦BmuG?7#Y gzZOYSꏫ&ل 衫Ca T\oAa'ᔩEzi NΚ˲ Cg F%̲#ݡ`X4cb'C<陋̎x pk{k-ۨv4aRJ,[AX~`4uGC%5r9-MPv4Mw`z`6[U ؽ Ң^_1}6T jFZpfSSՙ1zr:ɖvis>!bR5GTV+&2z8?Tڹ b0fh#qJ<NJ97ӿBGW95$~06,@'EpXpq SIf-;k6DY(jF+~NU=7=bS1rkFlJb|<4"q }s>Nr7Nms>n.}>2 CYF4 |:Gm/C\igG01iD#,58D&O t ]gABS8-5h.EPڨU~?_<@Gw~:khH @g;I]}6;6cNSΆ'%X@i; BeS0CT_׮f! H3OazQ m¸TvPrX%Vufij,Vh S1*] _|^[!Yz;FĬ2dYb1Wݖ+ J)SF])A[=%w #\)7|IG߽2W|5 k.MGb>?-5()˶wbk3mϼ 䢷DA<n&8-pSUmWSB 5c²$Q<'RCN~'!~&l- .$"@ݨ\9?8pU)>h) X1X>|lԠT_saJ{朁37`[2Z"Tu&dIt$4g0 ݒCa'Tך5b/ei-rcvveFyyAVu>լeٺI1?|cn@}2/eG Q8PMUS=j$(2kN=א&FEv? f|1'̭XƵ>f⏪bJ'ӝ5Ȳu[gA?4 (f`y< 0R5+9|0I30)947dtTIY^ioiqʻWga͚^ۛKS=bp[IQyxI1.M|/$4byb0f-f-]veZAefӽRJ eta)V\=L" lK;mfQ7~X\詹t MXm~m_`+<>H|v|ǟg:`HA)KT|eBj?v%~v~mp ?e;3fi;t]`;͛U=SMuȣјxD0C؅mm]gONT-6JO`p_2q-4s:_Ƶws}עkg_+߀xWzZcO1,+3m[Κ˸곿] !jji$ͨGn^%+M.ъ/IhCq@0^m6CN"ӕ-z +o;3b_})wi[ԝO1'#y2o)l1=[Oqߙs=t+ n nol0ILlCf-\7 *%D뺢R$bIq ŕ7b0M,@8RPLB|p8`ūRyFL`pߝ5"6)V$>߂N+Ǒ&۶E"<lkN#2 ?$LnS^e/.en7}XtZgѩKI 2F 3&I3+A`iq:pxojKGL`p5^LzfP[\*3U{/bzx=x(}m/A|= 38#Y>k=jpn&CU\MFDFvDt^";_H~ڕ"MSR&_=A(le218 J8MNj)x^p!oO#gxĜ?rQU-_F3Me< DB 55@R /{0GѲ8521RcMmrpǍybv[w/(w9,sVg8=:ϐ/=aGr*(` 2'9052 s=H>XXF3 ㈑x79k&iUUk]O64ł&[;߱, @b601#]X]1xhuDB`j0&-ɪFvVc4JH$O (H5 X4=䳇=?\ZD?qlp(WYYLDH=~ o=",fkشj҆yh?jbӮg-(udH8nċaّcQ ZL`:Um$o[6p6dí5͛jسbp7eaط蔹Fh͈wJiODZ$ xWē3c<'x "I#l x#ţS5jP+Id'mNMbQ4h'RB(8b0.$R)j!+4yCTW6W+x%F=bݕ0\11('*s# &^{K0:,x()Ig˧qSc~Wn ҆W}_MS "^nrC> Et*8l'QGÈږQ\onf=vlC-P`cJHIXj6d>H"ItyNĈKfB0I͵ +쒽γ4 Pl;Yey'4о,;Y1xvECL2` ędKLbilaWw̡4,;Ν߬7)myEM('SQ CXސY7;iYfs5jmX2N>-՞qF,,~g6dK CӺo$DE"byB7^ݹSRRUh'ira;jar|!?VJB$H$Q8'$,40^S?YFYRwg%ꢹy%)}a)[q܄Q_l̉XJ)i/]pZpĪw{expP R 8s0slC@~9$\rplU7ɬoS$b&/ps!NK~&o";C9Z._DXӫk-WCC&l\^;Dmҡ(rqۜ#9R]T<*ۨȿox ;)]Ɯlq>q{aL[F8`06hdKJXOL y}!ۂOF.1 VBD*hP~\!de$D˟J[r0k^S Ԗb_+1$6Vg C ](@ l7 @)2)2G @1E.O1;J /O.x q`~iy3˗J"!j(DGI}a >2y&GMJ43nZw8I\;]]^^~}]Ԋ=iFa0XI&cf}psOx'`K@BPm N}r@<"sΕUntX DΡq}QqC)3RͭW '"D44hZ / l@HŚxM4R첸8MP͚o,/7VTmwψ}*ubp鍏\pe":*Q|>~+L2JȔhP .pD% i/fMKƘHǘzD7 5UBːԭDGXiiM9<,&$m+n j׍)?#o0. ߼rnx Y9/gz4 Pq|bhjZ"h=iBP jb C=`}G<:e,Q(q<\Yĕq8WANYp؜{KӤ#o0Κ{5q=s䌈DKvEwQHKWLrF\gđY\$>zKjkF(##FA UTNuBDtJI'QphQրYřBs{[?hsכ"6w<3Uo9C`>Wz\@g t]D\>{ l̚f-(%QFTť,:ulɚSa'FKNQRQ)jaԶ9KrZQ^Rmf&+W VGHO :8 DK_Fh&N [`J4կ-@J5ݛ:^Y|zSKpaj\FPУeASbYP9rk `P-WQDtJ0|?V6Jx' P5p\ e=@WKGM1&Q1x{KH'R_/sly6Bc=.DDtIY`EODQ2 sx8 gt|XnԾݵvy7 0uKLM2 }2(7pjb.F*h!KyjK5|kXᅫ<ɻt{.ݝ=ؿ`g dv~c:VrAu5Ui4' B;G+uP#nv 8z|&F}*4t!NC!lvqZhIp WG#Jpʖt=*.[aMߨL _S ֕ ¨>1y{ŒU=EQ"4i"L]|ը: 0 ht,O_~ybMޕA#0<&;$BePef_eMeۀL㝣^k-n>c-M/"45){WY(iF>V33p<#I$0\.g#wL(YZ #P`8w8L͢5QhͿ w:=\p'FHvyՠb&UŦo]$,(-n-%:jTjY 4ueSfPb Wd,[ $ȍ{l &mukWVf*돦Xr/}гbؠkOEKZ,:o-Z" %KETheB!bťN5.S7seDڕMR<,[;2}}|ҳbjP}N˃yC(ZSSOo&#QuS+֣B h rF A-Ӳ[`0~p4_^67_fp)`l_#A`~{ pq.K+痧nDX+{q[W(?<5itF$E7!qju 82* u\"f$&.(F<1v"R-Ln|KpLsʍ^_y6ýW n|ѫbu֤z BTZE=K(Pd5{EjGgJ~m0 73$R뎮-5Uj&MMmn`ͥE}a085i(ыu>D -?]Cu[/Z4a~^)GQFaٷP넮56pX]6x8TLEmG14B^<%0L[anWT8EXJ WWR_O$҈}6X|mOiNOmNZ}\+0Κ?}Z|(8Mh(bw b$p"5EgjTH "7ir\m}_]_mj1mH֟tyvi dZcbp5tA\:s8ͣRbƷ?TuDrYTX䬛4°um*k1ż>kt~}U-ܻkXM KnKb8Il Ԋng{N-^y@"=}$P|BߢA]vNѻypQ+)K#ygQ;MSfiƐy HP\Aj+ (U%P5_6i6Wj(wW0gHK˜NI57MՄ  RaeHs°V릵vs6A4e7)wLۿ'/=zGĥc7d֔aܟ8>:-)d ԮfQ|T1:ՖZ(lUTWhEQ|, vku{McHJPݤ&ݏ{ιgpd&efqj$'DtFʈrrcXj8&Ij&("=z"j&}{:)x:>-%I,ޣYmj2ZNʸ.bYcFH+j%{ؖ^hgp[{xQ}9z"q Q\DϖFX)_ЈOP??~[S9 ^"$):Y=qrV'l21M(Zgھ>YT- FЇݭ5tp "v+ѧ0=I#6i;@8d eE>dZZ:[.//#fs4ml͎6Y>{xQ1yfPf}f`+7K2A 83NqOӴ%Ffunfic $c=>օ/0e]^;9}$;7X"gpp B)N9%'i1lsJ89uIyK)㉼T[Fjɥ5Kw0dbZh<1gM3G(ia04FGCM7qJC9ܼlC)HT Cb8g~\2J^Oq3v C#(~ -φf4"ϟ,Bq >g,#9/ vG̮j<ygtI&Ek;zDإlfhbhN̂YaE1u nw;5xyq>Ǜ* nqtz1y69o@HPk$m);4$"ʍ"hGTs=L+ .{G^aSi; A4MכX]*#GҦ pȘc}zbb" `p&2]@V`Ҋ؍ j2J\W'R8$n ^Ј+ vY&Wqo&91x&?M7;oڝY:n`&JA]RS3'"()'{h8W"(DRЇK-(x`eAOqs%hi n$v.sM >V v/> B t%vK Ep8O-~-9]a2't12!vpQ1"QWls/ '΍N[kAͷw@|ƕk8obm ?fv>2sn  gg(~hȞr} R3pT''ȂQ^"K.Xe*xP#UZ LL`tDn;:)h:X's@cO، 6HSda MgSpojˑ2WFLmA>u RD5t4+0hɮkDξ: w@b_Eͳfq~!4*rx䌿::$ i:@L"m%3RhM`)K9U[EN"H%l=rTb G +IA%r1ۓ+N9QI6v}u6\{ ^̡CW^t/Z! vv<fi-#"H)]?:,ۭfzDVzij QE NrX,!&ӣ1q4mr}KQbR \Gc$ j6͜7] u{7)h 2A1[Y}D4~z$bx4=kW÷UtT6D'E1="&bD,(1 !)/BZ "KE@ "bE\0"icmѦo۝W;X,YN_:A4D;A|}MF<Ոفd@m%FH/MȀͮb7P-ȄJ8_<|مH7 ٚYa**!a)9@d"SGGY*Cy6jQ̀1dmيuc7bW%iڻ7\ Rb1914Љy=%1UNȌgm QHm0'`$6@"&FL cD+Qm) 6MČY`q+ޘ1Ȍg~0X5,Cqt 8hCfMFdtخ6W ~wex5PVN25 㡁aYV>ޟL1 uX6Vkd I9Y!o ;Cg  Bm҂*!AO5"C7Gvu21E; [Sy̚XDZ~/ϼC:$"x$yy[8~A$8"ہ0 n02O\?*TfkFXIb-ZYĩ*^r ?lhňv^rj5=zR_( $BQU*8#ʆ؎okٚI{۔Moc0Yi~\ #n0?9)D`V=0YCƞ&yTY||{'o:Eh>50O$yaZbQ iwX[j*U6t :t#t18T_8/ Fz Z{D⋇$j^"dc<Z xf'(uaUK,?Dd820Uk.4s0'"9"h'z`EdʣLߍFX.ؾ`m-- 7:ɬٯGGtXGD" 8,Ξ3 ''1ۧ &R=\[X=:_ ʑ0ߣs`'Y4 "]LqVoo2WYo_@- .ЪH uu㆑f4 2k+khֻ0O=sR[Msa!'ߚ;y;q0ح=k̞5Z;jg9:6qDB Y  l1e4bid40Pg2d2)IH_˽:9Ԗ뵇{n`' r2-9}$3k /0H-lt UA㒖Q#hX7է |"P!lM'Ak5|$A@47?$ZڝYVk(ǩrvw?M6NV)G78 sbgA9O&4̌3a u c%mT4p3!)r5C /da "zh ŚP|!.HJt p1c p[׵?n:,ǵxD iJ9ĕTTp8|zmqRLqL倮bFo?aR?ߢ{JC()$zD"_Ps9V^<@y۴@҈HAcaiB Mӄ"NM Rd\I zcZXT+ o*KIRQTv b@DʼnJb,‹r$KeB}~7(/]GJ( DSpjVh$õBc(9Cʜʂ\L" ‹!U\ :QXjD*q`b~~7(ou+ A^C՞vN̿954ɒ5IBب4N I@"<,$oOT*Q?8tD**eD[nQ"4NA$Ϭsjo ? L'RDff??u*At!K.kFPnLr[ T%CQZ#%Q$I{E(@,@l_`j.f}3uqwF@& #O) uipV Ք42RMf '9{zF{uM(ws1uӔ'|7@n6M:xe|ߗn0&Ù(e#7ϛ5Ek{ӘnQo2M̬ yCI{;/oyIqc$cX,/Uigƪ:sG ӅB1$q=Xq DĜ"EZQ 17(\(/Ŷ$}Y7~ (;t{7b3fڊnQP>Wpq< *0 "щCzTf2C=Sf 5%07[03^t{FBDU!X1@"r"9)izɾ=/?|y^S|+w곞l2L\7mk> ro q: oo]jWH{,0Yf!E9 ,=(D'Ffy$X|QbCHsePQFsA%!4To/_ uoty rLc;1~bW7о0X1;_[n0X4t"mADHJؚf2S (=b1w=C$C>2.;_"4~w/Yv 6vEY QԮ0xF B#nc?k/@ fydG(ܿPVA,I-Mk]_jo9nF~Ct ޖh(HVߦY̚}DĞqF!T?=lM0?% ОDDO} >QdlNqCل56q}apst p(]55d$ C%آ!VjZ *tjz| [Lcu4o[  v∯9)hGb+6q`G0duAw0S_pDI<(_e.81oWd;ۑrX451-1K=BQ|)Zq2(o#څ,1x4e T׈YԓK05$ι*VX'Ľ** >NHNɥ3#=8r9@ b9VV"/8C, ;[, 6[cY؄a3>wHiP'\5A,K|>{+mp8tPxקƞw/vűw>5Ag{퉘|N’o]j®g(`aj-vCNQY:?mvlE=WMPr18 b>3 [ӌY  !;X/6MbߘjqԿef؛@O'ɾnBƒ| (uϙVn<&~]. u"_IKSe. QahsaA01Nا&*d^LE+/SRܲjշ cwP9yGtHd!9ψJj*qFbM]ܴO λ_썎ζY`) duFc.WSb/ pl# : =!U q&cՀ~Z$Ycphf% 5C#?.Gxh tP$;>C 1n1!g߉7{\lƕ`( A,ZCdJWd[u"6Pmbg(IufK`}^o<^X>9{ݐVpA4K~dA,1 ~I{[U̚CSve H3IaL P"԰}Lt3wV* #T"V#οmc "1x}{<>*LJOǃgT >b0S/@Jf|o/ɟ;Y̨5 P&0Ad4[ݽpYҾiv[yf/W fkAMpf݌d!m*G=kH$o]əgPVo$L$;s |/&>WucA)"C}Kg T 6i)ٍ18A4jcn6oeNԆi6m[Gz?OuctGd7붦פ`eB>Qq^7Aו؉q:E 9^߆>fz#`y?kL054Xlz44=up-N@9YQ/ңl18@LRZ3h &igyiQ18#E>S V:Y{^! 7 NNa"m}+7 &릺Bk]^ld_1XG<ߋ_/ Bhzoڿ8v1A~KG5w戰)Lim:z)̳ȴD#qBRƕM[>/ "V0(<[GLs?bmRzU*kS;NOK ]9qӾG$ kc;ErQD=k0)שS/WbjMyh6m{DrqJs46*k$X/8 rӚ="Cтy# 笩*%g[۔#X5DU18 8xoWR~79B6CvCe}zh*Ǣmz=k2~~sW4Mm7Z+f#%%eE|(O_{d1{P).3˿84/%hJmOSiA2mJ Sɽި4 _`R j1=h oa#P ?>6@$9G=1={ImH}=ʍ_?,` Duݟ[ug89L$6 kwb{{Du%-u 1byHQT9G '<LhPbX83離G$HzDQ#w=۫h'%݄G^w#7 GnjJMBG8GT}CS^v=eִŞӊ<6X=b݅RorXt` 牧'R8Gé+.gMxyhvcp;ӭ#­{V7CBq#Y%gJ٧`rm1aɬb0>5~e@pӾ(8zz~(>~֑,G/D5iDۂ}?sKHkWRf|Q# E2֙P77g8QV?^8Xc 5-Hi#Ҕ}*|#9>/a2kAye]4nt^ TqvZ'|lGI M)<1NzDԺxh:z؅iyTp28Njf}="Cٗke/d;16^Yh#"ׇ{%ߨW>}5ֺRӼGT&\/4S5Z7]F&@"K4/ZbӴGTY`$ЕSG^Yq4986¶:O3bӲGd(5e1@jbؙnA"z֔f9G)\c I^ DgClZQ W|-%ɧK &cUԾQa=߉Y*qִNH6gMm?wW~׋a 3Aq-C5ӎb0*nyAH 3k3$0Ad}yߙF jUOZ^xd@,`Ŧ!`24%Ƿzu "ڬ79"csͣҚ#AY`Aۅ!ܥ}Ӫ}e>FP;-Ï<̶>g@d)t#r`rX1x*TPA R5|'D=kmmxk7a9]$q`9OGG+oMh Fcd޸kN+ NE%=z*=lվȀ_YqwS<9VMGXo3Mz l9I#MSA/= 14f#&+6Wbc[L?6owu Fh_ ugW8>A8+q24%G^=dTQAe1LB1X3} E8JK:d(q) 6c5^\O*; " it^jP)/4]wuMC,>!>|wTpCq0ľ0BbnmAjDM11GA\Mg- *^P|xc#oo\NbB;'fqfv62dR嗭@媗{ XWR$Qit\c=iX afh 8'94mӂֶfz?P?>tPҪ0›mG)27Ԭi CiD)fbBG Dmvi a 6]k/<|]% PYG)BM`ՠ2# 9(R\|x{q"Nv DLjmYhsN9H~nƗѡx@Ae1xGſ66, ^ ǝ %y篁]дpiTs1Abp/N#B7 :ڧBᄊ4i"G̺ӸG^c05/!i况ƾv/~,=p<@^8kXž5 Y6i`AhoMU [sDHmE[xH^GT֔é1Lՠni,_R,ߏWh@1IN#ՠdӘb0QQ+JGA~!nMw/qgلBR$Z*i\Ɣ B5.܁m}aQ w`+>R*W3D53ٙ>r'<׬amàaGT khWY@lQ9"8C뙃IK+54c0XV+}& 8?(jZP5N䯴}ѼS9,>A#:={Ǜ)\5U٠5Toc2*ATUSٛٺܼR=|yJd d\ܩ  >4g?:%cZA׶`f[B۫$ΈhjnD2$v`M>ǵz%DKΦϷya /vAR(j#~HAAldQ<7z`u֢Tu*ga]$ O~"US)zMpX'|i\,3A\ColH(c?Gܢ:OVMGtW`1>e1G8ϕÛpZGCbA^rQOީo+ 5"vII  ph{4grK.Ɏ`,#ftiP&=͌ә `r3)thݼGȃt>=7G} - lćcv;n3-D󄎨r6;kƴ a0`$# 8 '%QK0~4cp5O^ ,-zwЛ}\uLWGd#[_/Wq+#bTrg Y}fMf?[:G^wj`n:Ӟw01'Ob t=X%pKv. `#~KÒ#z#6-]I~@Ibk# Dj-b)1H@b#@P#6/S 6(ƍebH$D *D ;NVHa($Jc1<ۢhĈX؅Q4ɡ )gNx֋W\ ;"#1J7Ł_8x&X fЇ̣FH KCn/x$BOn&u}bN1CTg8#gg[ibd{-!,(bhr ~@#>$".7p|qh@>ɛVlv%1hrfY}D] _q >LbD2rfԑC?/'{I*98"|_\YTӮ$f DadQO?$ַ9oD?@VsQBE>t{-t|2R,'wˊ&Ƚ4*1(a(EG QG}:zv Kr7ۈxqsy-+}Oc#ͼP P$%žK_}oS^B1t!jF9A,70-GN^S, H)7{͜Go @d bC9* D9PJf>E= h F"Q^z}#Ɇsv&ϩt<ǧ"٫@ B$RQwLVvOx?M.OS?iK1IG1HG BơGs% g5 S+%2Z70v Wz7)6e1zH*K E"DE}"T[6Հ8܉-˒mؽmϟZ_(4dWc+BQn_o6U.q鉠WѫKo 4O;3# rg WZ,޹ ~E9q>"\ 4UTF}J!H8e?<Hh34,6Y%s3”l VT[U&nPYOӘH. ,հJuhJ7^]uXmۍx&n07BӷC;0h$fq2(37Hr@*ZDAei:⌟%ex@s,w4e˖(Fz7}-9^D / enZo0 CNS}>o'f?J ڶM@W bńEs`YAe;PcDQAʫb& pnk=VQ,z@(>uO><"u@|˯(8֊)D#v堟6I@dsB4\B7cbIL;rx$;F[('/S|p<z'E5-vׅQGb_pkb)L#hH7h23j/qq:Ű< [鋷+1e K.GwJoq,2i&hQoC^BX]61y?!XM[֪*PVz쮮-DhUQkQ.HNTU8y2pǷ!ch"Nu@JM7ß +FQ?3[{+f(T~}[oʺJD^8&OL* meaÆ #5㱌h"!=6a1p4]Q^ lHE^ 6a ??p Q3ǫADqyC҃Br/ս~| Z,^z|'O("s27@?ܷ|G F}Rt+a֨=Th;֩u_U#X ZlQyU!=@2_#D c*~ФA#?gQυ)8:`6Oeix40C(B--ΤYhN]]L9N` 1nFŅ/Q[#cw aPE_8e襪yXa"!FK,~ChBZtk`=fc@|BHm,$ܩ^M԰e|˅ bчu"}UUU ]sAlp?M?K l $zz06+ "bCX=b>p~eTg&Qt O*V͵@ܺMx2<VA@k/a e'k׋bT&lj/A$:D@iZ@6 6@6?%39x(1x'Q -WvC7rPܯu}TYKh54"ʁgAO r-RD*/\F)/d O%ϙCS38y4[]Kalt`Þ3Uv߼K8.VgAm+3C';!a%"YcSO|"M`]_x=Ũՙ" 5 b]Z2hpG^)Y<ד5 RFHr'B}@àŒ73s|#sOKЊ s:ܼWdN{FjM|bG|?Dyz5aT_=xFdF5[  Lm^ !lq}:]ygA#7 %B R>uCRy~=+4W_`]ŁZ B61S_ / 2K"1r5&m ^KvhYA<' lC[H.3n9H"yZKFVE @\my ڔ\p:m9ҫA; /Fiz} dℯǎ:]o7xg$D2=5CD "W"$k_zb8F(=ջ>tSiD?B+A,YSf.= nWi%֋X xkgzKFƝR͚ڬ ȃv7Kt(}٣ `,Lc㇊Z 1a[W6,  "\a>s?Fh5g)2$[]UD^ l XA9"H,9D#$/dʩՂ1/7a~Gsm64̬#n"z0} "JcXvOLfy*sgc+Re&Xx}u6|J\|Z7^+$ 1q-OPqtJQ=b{D /E{:ƿ$U$C?k^UU :F_bEwzU#*~KMjSMbQnԚfTI@ZcD))50,SIENDB`imsprog-1.8.5/img/IMSProg_1.png000066400000000000000000001333361520775651600162160ustar00rootroot00000000000000PNG  IHDR?N`mPLTExA р/4 ;'w @e81@@@Hm  222 a&`LG(V2t'ڥcc SIzauuuA2 4da:,| 0sRKH:z$l"d#@A %A%ܐ% 4 R T6 k(''MY l6 nA#hӟtV[^> șuo&~HV~4NxUS@R͖y*ZKbEh:" 蒳q}uې@jklTҊ [OSxFE,EH ۱yBE\k4XjCrM%eoK#rx_ /Xh;GR~;&19VьxejE1'D>1U3 A}g0K~p v~s):N[~ cdDG^4 VOʎ!I}1\GIcŗ0iZ='#hms=j1-KI:U~;gfc -=dNC>9$4NC6i8&Mڭq*ԯn\!kOްL5&tC=N*B&fm|x@(^:c0ޒfl=vLɱ=t3?MΣܧx%<|k꾤-l(X<}hP=#J/XIpYCٰj7ʦ)'tc^_"Q$=+m,qЭS[fsNBhxk?)7&Ӌ|9)Z4n,å{~ RNDŽN|f*zQ 8<U#kCU΁ 6LDX-3l9ts%@3^{u #XCues vFvSO`51WTDB "Q|֬yj0r\7O9QyU@wGSj{y@5Z: <ަ 1ĚUV}ELs>î_gUMsgpw[ZqOa\ 1iNx|pr(Ď&LffCaʀS!U"*S L["XfI wV'~9fI'| q4ћMݗ޹#^~Mpgо+K8mgLYUޯЌf[:rVPgb4\^:>' DVgop̙Eݻ7c Ξ}_O=x+;/gdCOXifjR(KWww^QOO ~{hs~ Aˣ' oM* +ð9 3矯;_;TҩslRV:2wzشwb8ÎÔRok*Gƙ3Y₠2Iݥk|St.6&-Ri &m [B  _\ȹ HCs0)@QҏQA~DZc ѦM2bX]0"$YI(N 3Jj$0+Y L|JeW޼#] )H*%"\$WyϏ 3TPVJ O E`xLP G8]:]PP26@lv 4Dsa^D <ɳ s_rĬf{@iJ M1A, )RaY*m0mLǗ*UK ' {֩8+RUzȹ^W%A HJQ˱>gє ];5{WD^ dsI0[)4A~<꡺p:8g. pJR"~3ɠ9 X|ӰI!L%qRYgN`dyUVS;֩'f F*k[ò2F{&eZbT߈Fyَ>s^ҤVl6j) lk閍@N!+!p(swR"rsyF.gu穫=܀aZ K Y1p=K8F*N#Y^]l[\+7X_ɓd:e EE%D9t>io7"jfΉ/ßW>9yZxȾhќK7A3Km!z\1'Ba#fh^Y4[)h~4߭gsé/֫!EZ\$Rd,0wHHMDa]E'mp@x-!f TJⓠT׉"rA*v^ޮ|=q jmURJP b:7YK%9wbH%?XB]-Ab3,D=|Hƚ&)7m97188Bwtt~\';/6|<̴_(=sJ˄]HKOY(9G$ Gg' &nEu>qGH빅%b5 1tK1H-ى/1q4DGz:o~c>!I=H=aȍmTRjIHH9 f.Vk$ڄkW~BRrtjɂJ1AlEH|?Kj8(׆ޑ֚Ow ?D~WVv]BCvz_?ԎfrgCkhRavlvc"\CZz󒑢w1} os$y^4zS5֫8Dyb )d 65b.q2=DD>͎w.'Plí7$}|ȇ Co~zb*-uIgӋQJ *je};v'$L[`]H?ZbDERQfۣ| 8CbbkHヵ[i7n./o&vW~h6o?h??h߰ {b$P!2w" m .=I^2/C} J3!(ξ?Df!̫`\ĭ1%> ~$ФGg9kUR>pk:2EgRQB(eoC !L}vS>6>A·:%bhk{z?'~TfmRip gk\ϻo.$OP|C<kw NOvXEng, K:8cXlƕWkC*h$p!B ̧C}EO9 JK@d`9C9N4X-ZU?Ë<.^C)[̰RvU@$c_YO<+̎0}ʓ!)jNWxۋG ATFeiR)ڤr(U2&.`J2]ͯhNf }@Њu_7! ڐllP7x=)UNSa,#ڄ|/%\ ; m9Y["Q#k F \ia:21+;u6)G,t5= /Yec0liɲxMO2ŏ|l&{%??y+4oԪ#=*huQXE+% [ *?="C,daRLej/%"T=*Eɶ=z;_5ōD@.l 6F3'aw2kxTLۦ5i’Оv8GPcd4)\R),1QDG<.\ھ N>[`] lNvN[^M[S#̒ ZgMSn气ѥ4` F^F$'qډsҴKvG~%#{ג\-dNs n dۤyl8|y?჻ v׊kdBD&@t@ ș2RKnTeًSHڜ]zc)(`8dK/{f 5y"=:2XdE gi)]΢`MopͷcOoSgڻȐ]k@ S;kS6L/]Է{扯sw}hoBbP^kѳ)?B@ˢ aاlW ởuq@C6c%>\Ov[EI>w.N;}[%й:,b`vW褐ҥЦpwdl PB b/̤ I(TAGS2 'L,$K*IUj h'3ޜ HZhH&aP•PZx\dϞ#at CP8:i@$yQLQ="X1XP T]ƹVڀE<]"HppJ)LDCm$Qx_`W0cnYHP8ԭ.^kv90Φq=wWZ!]VX|2)bE!a']|X-X,QF 6'N޽wT<|&6}I)UHފ}( aREA=6o CsOۿߑ{6@ ȇ>5Zpk@__#CK]F71 糳8ÄĘf Iۆ`)?qID(U M[JdK/9PzTyo5%ij=y{e\n qr}&>zD]5>:-IҟZXZ:؟7Gf9;ӉF㸅8Qc oNi&=[;]o?Nd~8|"bDsʺLfnLNfW bΌ(G e 3ϼ18К" IDXwo.1II  NV9sZQdkCH* 'grHG(&f5[e|fzxxL]Gv~:^*Ԫ O',IJ`QA~^[ۉv({h8Me "_Z}å-&rXwղrfrO.=09K)8XupFk9rW+++U03C"LH}3ÃN.YN?iPlT{0_h鴗ghm?v=GFds;N0 WG\Vd".ϼ\ם3Ї:l9DT]?b3>>B\ڏTp8"vѭ*Gv"3K.Cl+2ܰ[$DNؒy-O: -BDPuj,){;}'sxj(@as+BZwϊR,׍JLdm:Acl4_kb{T+s>!2mD%?B $׻9iG,҄..!abai$N1Jtccå-,x vr3Y81`D}ܞ9Օ,X_}*̈ 퇐v3Z-JS-DOXˁ}Թv`u/n{(鵘7@J&^+$*Iu;Q䔸,8l^1ښ W#< CrJ"Q^hcrN'b #.v(ʼ[eu GQ5NғKK K'e.C'@{|5ɵ>b%.2D6lD#aN.ZF "a Bm9frq_0t`p6<3sC *~ ff@WWotMGМU/:SA{gዋCC^08=~ ,73ӃC)"tH}ӋvrQ:7'!pጎB,IgE[r@pX4?%/j0P$ .%[{h5I j ]4#8&58טi^կ+:L k0W>Xl#( ^L*GXr5KjKׂd%C&egiꁳĺ!dhlKe(eH:d7$%Ju%D9bu~ BZ ׇ!G/!]ᗰAMm)ܠЍM~VbYpt68b ;j~&ZshtH/?iD}-S?V:Dl"HL Sz~zQZ#:^}d~Ya~~DIok>| MԚRGCϫ{R$/}|؞EډCX#o)ÁrVa:qV$C%6"n䇪SjPç uM!DCQL._~tx!!x޿N=R"B_o碝&ys2B4gYϗ4_Y( ?l=GVJRɏ$ ]* 9L7lus[7XsĆ 1r :DDi褕 #Ju7Ϯ>:_Ĩ$~$Ѓ Qr#OmwPgrD l ? Lj+Gi-ǯ }ŽRG?t0wCՃvE~qZJ4AB3¯sS^Jf(qiSy|~:k^*ũ# QCXVe"} Ou^>S-4;fYMYH&BV=\4tjRHIC Aa|hIVCe{O>׹9W̎~}xy0vJ|ɔ9S(*7XJBE2sIǡՂ!)B ٵM3JbC-DsaF&4W?Pa^BSjTXhK ;|j,UE|eH綿x=">[3.FϷ/{5= }B22(N~U?Qd~ w󇓛\:N,=~ؖtpsLjPE NhL/}%C-B_!V7~^=>ïoBZ#uW&8 ux 8$Ԝߝ~L֒_Ҫܳ"̗Ij(ќ/v?!?S{p.@c;Wu|x JKq\T%o56Lc/T"㻴߬Day!%qmt].J G4[ o hCC˦d|a T $^QAU*Xv?G/4pۭ9v i_  ~9e7vdN?008&"HtxX=S_iC,#4bvljFSQ2#{M*)}C|smRCXb- MxfP2ܜݝBjƭ2w[  ;0{LnixǝO|&NWJG|`vhqik!/12p'}pCȐtHfr' W/?=SZaS^&/N-xBsxm-~d}Y0D-D3Жܛte0؋؂3P0N<z/e!rdHYʛ]jJƋF/[..invvjB*F"G!' ,ET@{rxŖ.}ps󜩜KY>-\~I= &k-ӥ^OWP^>yvÝ$~ɵ%7kr뵩BN!tIdw~(CS:}|(α qoU (Q>d?̿SB!k)6 4'-A[lrsBz! G"/] sW~Yqw DZQ|=6ı"<2.FS8@艠"nfx݅ډA q󲧶2(M!H'vJmW1}t\u)).ǑH}Wmju1p 1z?[b.Nď=3!؝W_؉uUSGV}b:C/N㇤C[r\MG=Ek`u|-\|q4(7|VGSkPПCs~Ҵ0_Z0ÿv~) R] LJC?Mĉ%b"<sߟ}pvl3R)}鰇#ǖ FطeL4ytd@t!8jc5X#NG|@gtJ buS$ʉSO D4uHA }ᕇ7qw:~BR(7 +&,utӺ)`?9f?[җ-t,q~7'쇇DCa^ɘ] qr8 +4M\zZM9OCehB ꔊZzQ{Ld2x vCG`7 +쇢$n`*>}'_{XC5ݏ0](`NqRf!ր;H?X]gD &?>=bpy1{~c:̴ٯxCV ܔi$_=rO||7Z.b~"=F.L+X0oT~^W7AB%y.fn{޶7>]0?'瀲 i1V{\ ~T!9U;S#p')C'A 0 .FMo÷ONH^~{cyX`,ܺ4wetZ1cVܨ& WJaNaP@!CxY br *A2֥]g9a FSQ7/0qAHpWy2|6QUE} X<[[ʩ;vP#څUk_ȁ: ":0&Iz&K0f̯ȞgD'_y;Z RK@e{=@A .C4[|xx,C慭b{rOgлJ*GWP_=%!Qă.ytqRŏlAE`SdPN''_{~NQ3i7]"B]إIe6O!)&ZEET(1NƄ8Xʺ#0dA;]pǚU0c_VzjTD=x<+1{P.)PTZq\a-_ S'5p덉N՛|/=!R2n퐙mCfhGTeW:>8-QD@o*ÃV51X'URNg#2A5 J)TֆijRyB^ɤTyP90=+xa=)Y(F\WU(8e0'5R-VR=Zb s)H+O<^U\O9ۦVEԔH|l8o!HRYFCցXbu[dO%ܼ<a ΃M[LU<+|5/CN)Kx<x}|yz (33L6sSw>}V Mej~(?2|2~!#Ш}QWFM׮T1|b导[\oǜ]S`zVt "ԕB&BeB!'tkZk YqQ\B0Z.֯ؿ!w4Ljbn Db0-Q5Vkftj 5 j VZW(TK6AD DjgfqWVAP`:^N.'gdf>tK!ɟ;GA9 6UxL'#~#Ϸ8vvX/1=FBn9Óp->@N$%PR~DZo0F!I&djp7hƇmjÍ6 v ` !C{i$ j!C7{J~RK,f٧v4kp=9eY~7{>Vu*{mHK)~#?Ks4;%Ff~qCY;80gn&KA" io ZBNA0Dkb&4ڔ5mwvo;^~>73L>'O琘e/\::3S0]5٫=WCT~)^KKi|aE~:Xcʋ"֊K>zha :_;'O?hor,v8N1;`nҔj沍Uޝ`9q^!Oz#457j>d,TIE(fl&QtN W$s8N .h,֯L'ٕ[p!paۙ[ּ ˂W{i/Mi0, cM quSk+oILr= /1WxK&aq]Q 8įL1I7 *H?q8IþZX)cK7,aJp F$;b,4ϳؓߋ69<64wÆZh#^:>(ai`8!9@.c"CmE]׫qgwE!E FeQmQxF3r8eP3d,<*#K_>qۣf6X\ VDݲ9zb-`ՖlCko/{|)kl|RcwCk-./1zV|w9,ioe> Q(/qW8[7 ]qX #e>E!7ϛC-[|XۦTO*Ց*PC\>C04Fnű)e~c\$5oRޒ94Vu6߹?<!'s3CPp|4\@\ x-^/:ѬQ"bBl9D2.m}0XU =9CNBfj?d (|,W8yG΍*>>#p8զʉò>+8tL}|!e_gPM]m# Tֵ~ @Dm)NKF>4ϸ8*6 Ӟ}oP%>M]5ãITQxnJ<۝ΡN}|(hvFp*fzUC_9v׎O3\/X5sif8tr)9V‘ ŚC2ף5jDM=>>|ˢ&ixpυ//}u\٤ 'TR1_ y=;CR>>FڎêTt?N̥M7N@ P[/5}OՠC-0yO ('NaPaSR01><[|x‹dw(Akh|ڮRXT:lg,yV)6K\d\7|Y|(9Z 5Zυ(*y״O⽶^#-ǀ^+p?Q*g6ޟ#sT{Ksvk=~> e{%η>n>}&?4d qe|n3糍&'?"Hp'}]˿0r`qC?-Qȡ^nFj72|'${Hg,Ғ}lC_kܣPTۈ7!?m8:ω GCj?fѦ01c $s,m 7+~&## #%z,dggc@9wڱCUN3Ga83lCM>_lR3ɛ6+pxr239`䜍+Y4~):TnC(\*[v7:d:GtwX0^Ǝ8Oq8TCIv8d7T5>4z0i ~G9{\Ňb?`zr +Ψ7ϥG C5$3qvJ0[~⍎kɡ`? \/&'_ r_}.މ}l,3Q5}YQ=Dbnx/@`2 +K0Z\_іVQ>X2C0iȂ!/aZ gL-q]mpחW_P*M }gs?7T(pz d3OK=~ J+%(|GǕQll;'/qǾonFn7> &DoWU= =dpWUEp>ß0G Uqh$9 l]ˣp i'Qs5"hM(wiD5WKvC(Ӽk-r4qQ 9ϋJRkG1~l-rKE"_.JV!4P"s]p!WT[Tayi$NqH:~Qt!`zz|=HFmrXŇ v˥QDq˥]4C7~ &4֬E"m#[843M?+ຼ"RHTġjDz-;y^0Ӈ'rimʝHTP33vSkD`Î)q39=X{#{Lz-Ah{GW66h`G umI1>*OlǏǦT[y^N;umշpN{á~(؅D ]S{p_2#8H$(^_tL}09g߰氒CGph OĈ CqtKw /Ƕx>`q77C # ̾x-}o~o8y"'~9M=oXv7jѰ2?t!L("N^_.]MPVrQ=`P$Me(9. qzҦ~n2&xXɡ+~GE;H&NCCXȪ-V=,yá)?P}&\]~;z1o8̒J-&ދ]+-CCL]l&]+ aq~"4 kJk|XdܙX8VOS%;C $7ɮh\pyy4QWfk}xâwf9teڬaTYN|'%w<\5U/QJO/U8m}{J>=NFìzۯyx[}x. B&34ܐx}QtЎW2Hиj1 9|hd|L$3Yw"Wj;Ӎ0vlz y5*W/hn(@Asm=%Wl]84Ҽtw'd~A78Vs8{PS?zO}9p3߃NJN~7uKE^w-rmѧIP5pBtJ"e#t[&-aSx*Yza>̏s-MǗϷ<.sˍ0~Hban! zKV(W(`.^29X%CZCWīNw gDjܘypw g6sw) 2zck + f5}Zq!:Z'8̐BȰ188$ pM8W%qz5|W/*_,ZF'p!#|p?f4kZGׁ KC|zd' kr?֒ eq!ub$֟ssw+y!?$|DBKm=`V7jlՔuka@ohA^7&m7oc*TV%FU\=M8zׂW7D?҅> aݒP?$q9!,L}1t^/؇Q0tהa (NV\4MLr݆' T#ݵRߢ;JVyRO;8V>SB5~]SG\5χ]g0˩^Fo@)MgLNVE0V7o8̚Bv8e>vj,g45UmRU9%#έF ri懰Ȣnq/%,kE]U͙(Ov&r;h\")X*8 <έ?,yġ~ؖYPhFіEuh|XxC}~H3(M:?>8+[޼0;bvn;U:VrXCCP.ﻙqLχDZ}qhlj!wSwMm͍=km%+3?u+i8ؾ^84YgM|Zͮɮ,/G9^ׯLl|o!czP?K1+)>ůaZx?}~eHLnB1=zȡ̔-$'L<w~e@67Ge>PЬ6 +|ׄpn=-_1JfJt4E2oKSCiTݖ#WV륎鮕K cpi) fi.+Z8VrXô!6SFLI(wuBGzr/=鮕aa# /<r8W-VL]+˜7fCi>߂U*bB^k*ӈiaC>7{ٻ:b{絩IcqVio`eO.VOSxCmN'5veU$jZ_\ qxCFC|,Pv`SZ9{ġ>?͋vw5ejBӘjZ ˡ9?47 \ #7N78GxiRZK1Er~(C"R-L'N}AaLw=FZ)C j.9Tߔ$ W8{&8Rx2(E|L&wZ. 9׶2+?gM!ul2 q |\]ØZ'z]}dεϵ+ax6h78T2vcJk]u7S  -)ᧆRØss-t?CC~H,o)0)$4=ky2CT0fE`1ݵNss-t4~H! 9Dc2Qo2Y]a(cqS|94M}F~]c 륹:{~Xw3Qpڍ/ k7<}m.4d}^X8?~kkG}sן)896Ph4j:\u–K oܗ3bk~(]/-yazPd.qTVK](<0~( )+1842S%|t0 dNƮ`"pe`Za!뇂a&ɣQI3.{ke~XCǐ aZh~7u0 ?;(gF#&mqθ}#q[38bđD$BM_˫]]F۪Vߍ5%zW2m~Op>ǚQÔt/a}rw,5CɚdED}45TC-m?}O"7\M$hYtZ}8̅,P{> }YH$yw:!ˮzpθFVݳϽ0o<\C)/eߢ&@UY͇5ùץ _|3׭in!O&1! !95aaliw"0[+G)Yܠ`^-\uX!;|Glp.F8478FJŌ]sae /F͝x g/GZ"Æ-^&/&Ooi~MVs"]k<76TZ7/[a\9RWw; ĊC[z2V^k]U˚i1+Ҿ_nQyK,D|ךڌqaJ$<1K;T]kaC͂pRH*އ~Y68hXÎ̭ڒ>[/'?=CipQY}f3pg1 ߵfA'qА5凔Ý|-w\"J2n!!4%9#?Lx} Gx[2eF!)?!raȡq}[5CNé`>,ۑ=.Co=yov}q ?eH~VtxBjQ%>}i?`X0и-n 뇠 ?{\ kbomvP?C 򺐚=/#qM.{B%l6k3rؼ0L0CU~?*׺SaGK4}C-84$nMp|~ |`4ᓍ>`aCS ճu\7jqeպT_??Jzo{47CE~4Rmbk\`!22+ᤈ|<57Bp?D Oo ]sand !Sny&=68r95zNx\~FQ7bomAEOs@p_Ch'*z~dt|'Yá~ЯB11rMrsט1e.ذEjtS(qL3r>&Hds~KOV>`q:%L=!4}C6,n C*jэR~V-͞ [albQ3o>B>`pr:qbj":?Dfi軖xL}IW.lXv-P5Bx [á:?dp'hV~}Ldro*UlXܚ>`u0*C+":]-ڀ\n`?>i]!Xb;3}-^od#aetqZ"6El;˚u9LUCtY܅9\**Y0dvCOv9L!Fr.kLDiE+0ø!sXþ^p8q>4!>JH]*o=S|vYk+^p!45&;:E.Uz;]_~qGrS{IN}q/ ޕva.kʍ8(Lþkn>̡P돏~OۻE ?ρ]{ |ϧ3z]` %r0;絰s(k8lp{Ky_.fz DؙQht1Doio93(<W~(Aú? ޯu68JZa@k{~>6.m))Dg&!0CM9m#a|xgT.E5nqg8_ ax/鲶r8yyk&jߵu+شE[ 2[X[ 05a5lRr.k-zr l1h/KS?Lܶg)ذ5jC8%h[U[]!5 |A\Y`]5Q=!b-2͌~|61n CϵϏAw.k'E!5]kR~pQ3X)t}ŭPY?O'=֥rpC?>33B}җ]aqk8燼yH>k 26,n a&z a?s}0?LYX[?Ĥ b62k) &lZܢ>D)t'ԜO]sϗB֬K!CP,;LKs#k8iyzw~O95jp} G4(r\8ü!Hfo m8̉0i~#' adJoi횛s$k8C7$?L凹E뇄/F6Q!*4G[Ұ!G{g#CURqD0n3 q/^Yu3%9HˊHdEDD~ ˫=]]ݳ۶S;SOa~zo"Ӱ$44J u2US6޿n0淆C]~Hn@тEoPluϗ~D[}5a}On&1! kC{|4k.rz0|z[͟M %Q~ʥBt<<"8[ՙDb+6KxGgw. !o`l|a|}  y05X$_n~hcC*ujׯxoF?\- dQl-?î'd9=u淈Cmofc]W'Z0TvErٛ̕ocw UKqs)*cGK9=Յ0E}Z}J`MWnڃ7LU_8. !Mbd^)L'0a3zp,S\Y~k<.2ۻp:6*BJ@-Q`i'y鼶"@Ȳx}@#KND.jC\ipsep~tc) Kf~ '-$b+" eHBN9UXZ!"| sxg|񓋇4k8dy 0I'Ja%eC܃ah6'ڞ͒ԩ ; :\5Vf;)ViHJMxC zkLJA\5z\ێ5/0 buP@[ZmP~X-iM rtԗoE3YwzKpM\E&?|'J@ ߟ^rjyUQ})юkn˂/I!@=`v\ "ޤj,CN*XǗ42= .,0FVKJ|:/e:v5$=R?ZBP\QӵTG{Rݎ%MWplK\۝Mc!= ksa5 MΛ+& c-Oͯ]i~k8Tx{[DVP=C)luC-Fu6EYcPBZA*>C淆C>>͈Q,go.\zv>`pQC"Z #3} T|Ŝ&b(u}PU?2.(/U,ep1\a~8)C lB1LC2T2Rc~P>`q8qJf SR})}淦8U~z#QiR|Q;sz?pɵE/f{ E"uVA/w91kΥMI)P5HwSy2k8YzjA[41k8Lb /-Gw=%[`ӜSc>kn+-7|0f)(9[oRp0Wf!Ӌ8=)aVS1`JF~Ouy+:0f K w;[eXLxhN8 I%r(ed&lVl 랳%x [a?9-Ć QnpgVyC{s^֫;Z [aRɾު^!Cqu8zK/l凷f8]0ĿdRWESỳj7-w9=`pS?Df8|K%( kx+f 8|?]2T.X-i~[JBR!#z69lBxmr6o!Ջ^q`Xڢ:ެKKwӲ"4K$nƦjGMDCl"uBgÝ}Sv-)K!//he!(1a>~~ [aÆ=CP2qb%E| GCjpx$,z£@ 4z淦X]?Džo|}){Su}Fa}?O@!*lߚ>#85P@i+F0o##pl;=O{\y^,x-5 Ȝ1/- F~Ҟj!ܭ.b(ޗe}_J9tzO2k8)ܓY IQ@\i[t}EEn9,I]H9ASKꇎC; fsN)7fq,d]*i~OJ7凹0k8TZ8,ԲH k"\?~C4ros/` Ӥ_-J凹2k853gS_wmmݐy;=`p"<#P>ܢ8;ݵ mM/:y6o i*}!Y [a! BY\ VdDn|gp͞ 0ELP/0rtxSKᬺ淈CB#WPi$`$!o4 ,E0Cl/c2kRA`/u}bu^2,S?t}rgM$B~RW燦R` =ז\:!aRh{b%ep?7>r {7&FQ>~."ys!K"n@Z8}Ej9y2?jd\3>>Wq 6+Ew#y2k8BҺD 1?!IB3_Cӎ5fuo\rQ$-)IJ >B(b)qEC⮠ί1ggs]ne;/ٷUPy, UKxf/a'5A!?D8!k&i GfgîCX^P9wUCGfgCE~Q'k.<|e*c!rBcBc×rl*Kx+ W]j/pdv6:`~Xl8\`y7 &NL|8.YDxpy?&^wϋt4.gZˑ[@\W`/վ:~` usōn4t\lN~O}#C x5< AV^oֺ̒}}Xst tq'ߒ<CűN^ƒ<~O}6,*_2dxض=!pP3@Í<<5Y`8?ޗyN䇞m#6hS$]⓾c8t$C"~5}9{+uI燀xh170M`;Sp8"RCz_z2@O298S{G46G\ ghk*a_g[*9s}z!l=o얇v㟽z!:lxHɺLi(3F:(a<87ߢH# xhoad+ù2e}8B;#Cڑ竝a9T>޺x niHRRl_CGggCpdv6<$NܫYhЙf: Ghgb~t~(:lxH5)JKhTspCfg~iOC-plv6:`gA/GC:Lú$K{FG~'ps~ƠPkC7nQ0(#!iD%z6FkۻY8='&`9Ea9 ?ԇhQNFB]:`z:Yao>˵E <`lSsDxo{C=4xpef%SaF$xxB 'yۘsazfl!ާCPLOrrWO9P{P?K[k[c`!:`_>1 t6Tg0(0B+@l D?ɇ%C:_޶Npͯ !3bƈ8>:4 1!Al(14ESjA}7& ͯ 06b:ph'M/t8ǰ}MAߜÎX_9?ȇx 0Zdt$ J|F99P7ºhP㷈l8"4~/\C.-B:`0i7mK!1X̡Φ ^#bꑄ&?q>ӆCY\za̡ަ Z)=`,·app%'΍742ymsiaH,yȵ;}Ln޽?ooC$Ωy8Ed 0m8$69oyF3 qťjmȇ3w5ʇs!PoӈCudЙ _2;@׋huk!͇/0E+!>-ˀԷaKc{mG$ftsoWumވ%vDԧ"*]o<+FH\n8{wSÜ խ-r1>/`ξtnDItLvDЧn5so=nIY8t;6J:{]jxKsrp`6:+X8>Wׇ5J{y'Q}.~m8TY ZДg<{mw RU>rCc[mJ遇m2+ruz7냺wUqR0x6#ůz˫Mn8d/8&_{CthR~)r(->b00n?컠7aвtkziO@VDg_gׯB{Q^ |?lH/eh6NYU+9da~FӃƖt߱x0mK![EmQ"%9ߴ0>\:!K?Ê0m8 _-"5hԇq>ӆ߯P/BBB^2#nOa6*CI 7<ÌcViá:R D/nj_PlI]{G30w-F5]u QnjV&J2I&F*$$F7CФ/ϝ=qw|;3g. 3ghCA1ZTFCO'FHWaMNJyXỌyҿc4ڷ8bU|eyx))k{ PVa{!zF`Ri$tw'JljE:W]{s#GďoCL^4aK+,ۧ&qO  cu}XFQb : idtեn|Åo8xנQC,O7A8Z7T@{2'f4J-^KKt7^; GR]~ >$]0WC,Ofn-~;o̧#I=_SMiPAzZ2 u"k>>BF~L}:|oas#7!qh=sPC,O/f޻p}x{f|CL͆puoey8Pnn}(☄Q%^yIt|Cb']=5P_a|8+ezO|C>p1KĞx^-btaej*>nݺ*ޕ˓&]_0-YsJkNpا\u!xka\_a_!\ysx;yP' 94MyɲCَLÞ\,>T"% CBܨ8'߻i8y}I??5:fU|%un}gSQ|C(}ϝlXҩTq-% ȋ\qfI3F&;e~Az<n vteo0q7!&q:\w:fU|%un+<{uw }qs#ɲkao怓3l~|0όԘO`:?dF͍x[ۿԂ]{:[7S[8= -uk>0?mw}94sjC| |h[s\nfvϜˍM.uv'%!S"v~WP/B}o Mx^7NOA\$$`em{H&hZK"E%<`ٖ 8Up%jI=>TF0$Іԇ+=N2ex;|]` b$ ՇFJ:XZQ9$uGu**w/?W~$60wwP`ũdb>Tb}:t7VUU-^_o>] w~O-q `?EM=8>LY0VWxE<:'nv-/U;;XuTE\1/%:ɹcva{/v7K/'>[}4tW7JQ!C^b]oC| 1=oafg]q|%F~aVia`OPKhCaӘT QNMK#EX a.e6<ԇ/S|.1&ȝ,[SFZ OC1zL#P\&?a<I&wLiPU=9ȍ!S%/娶?LÖz5CZꧽ.EyTeRi_+-}K[ܜm#C~;i3k`B.]ϧosqpq%5K[˩d6iܞI*]0᩶ϴ:dEF_uq-nζ yN[^̍^ig,b~q}V)]gݱRn*]ut[jևѼ@Rb ilzlq(aYp~as =[7eXlq(]0U4#G!sFtq Ow3.[<`XNSST*4=y[n(!RXKo1ciGMɢa6 xwUPK(pv`M?ץ -IA5I~$D'?G xx~~UkC5ժpiAD~GT"ؾŝG ?2:˔p=tR"(?ukfN}P>嶶[%X!#[{k8y浅\RG<PФfC;!GBMZqZ44BCe#@#QRgC6H<õhmx(NNL)> ?] QόUчZ^v!(قy4D"!D"!A>_ΝidT;߼%2?{Tfܵ ?GM$4J S_J<&"CU53@+a|TVJcCgUo0f46ά?4X\_b]lkWN|C<^t%7\!IzG#PU0y 8ϫC!0`0d=5"pZC!u(=4}"fJF4WT :x975_Wb]lkWuP/aillؑZ0?`SWb]lkWGPP"}gl=miaAh|#bۆX Eɂw]syQ|R<Ԁw^!RAdo>~G~i5"7_j9rYіVuT˾i4 &'#wDU{ia~=׈Zݯs />dB4?0ݛLD K6Z3s4U^l;\_vJyo|9x^5[xL)Wa}ijQenH'pgAar"v#6Ppچ<;܅l[|?k[q!ɄH߼;G'>z<-FtJ߰D\ ׌| m[|aj2}/:B_>; Je`КC4i&4&b{!w3+^w\!lf9p䡚vXP(7di7a~//=qw>.<7AN xތV߳QT/[Zs4[T,Gӗ 6sm|'qK=' om*|6{.v0pY<9pgX! WJ\2z1^J |668f!"{۶3>l|H Csr!s y̍A#rצڙ2DYԘaЁh|W|Z":+eʨ_J-ԏ io? +T5)mEF2e:ɄNj*~2TpI%/ݳ?bƶb^z*p3[{VfR2(KŸBR'`ć j(X2&"JC3[{V& 4*% A1Qci^!D0 Am;!s߱Wݫ?d8FEѦ{Z۲A'O 6chxsqƎ35g}^P>( )>$٩@|j[t_~ؔRP+b!7yh>-b~c-pΏ> w}txh~ =,X5w4BT08H|( E jN]ˋQI |sK\'Rs|:&p'Vt?jlqC!!*o-ŗ0o#=$(n0|CnT޾{˱m2Ň4C [Qí?yi }إCsu"λ=gVov{Nh8>Cȓ[67[{Ŋ%qR]/[]dSx 8a8pmw8o.Ά.Ipz>yH_z%ڐ{o/=p\<4N-:|4.xxiگ}uBeuْW:Hǹ%>[}%Exz8ܰlGB;WS@עX?uNX)˲atʊ C 64:s!$G9mK'\$0>kKsֈ=ⅿ 8l%*׽(W,ѻ~~zwοL̔e+8 DŽ&Eۦz`uL$.@r s a (bj`M&a0v`\.t ٌ s6m> [YuO%+b~x'(cb4|bbuL<$!Lƴ~X24_5#FrR-V'B7eC[‡w d&?8ʼn `Xbv(]bQPAND8EDEA Tӿ>7]M6q{[fvdl6T%%9HK,I\a5U^Ux<5:R۟R5yeM!V~EHR8~o܅L 9dB 2v?z}]8O~Xu,k`p~iQ"ڢ[W^HҾWUeqUN}p|');&ߦ>N$jH0lD$u{RWknŞZC w.>=沩SpxiaVPiJʡ1XF#(r;}18K'>D\KWtkl~ 9])azLqG.8D$Cu=sPoP uhD[cgpEVCe?lrqhtG1+%5*÷ZlY8o vȅqSp53p!r.=p=u`$i8\yW7=Gwso(z*w_|nJ *-QSRk=38Bzu{ѕi@!G^L}ڥK`ם{>{!D b f_Z& ymH3CpNeqMH9kM<Q8%1ObՑtSVo'!e9|>4)z4VCDe[ұTNj|kN2Y'M*=9`.+Aٌ6^rȩow39=M7rN'/)kx:pxX]}V sH\FR>+'tiHsfD]OiH#.8ҵ2對9lV&9D_* '}thi63Zic ?z"_EX\O#aP8tc( ÓC47VwvWv]?1iaᰙivil cepUb wqv KVEvNr ~CS8'W_/9H7hiC$MjA~uCcve;'RD[#ŗ:~.$xIHr*gq^CRgv6j^:!>r˹Jl$TN+mN\vΧV4YȎc}o|Ւq$r{pj_ʦezpH_[(Efqw 93b/5Jmr8d.{OQU/ Mz8փ|lDsg<.}hq R'ۓ qxpӸ5 !=9A(lY9^gN!7G1lqh4y5x CNEDb^[1 NʺJr42~j etfʛ&E0~-Ro17 T`;#0J'8˲\|HT0W F)7 )mD<as|wK0%LΈےW,9AR|BˢBN5T\P?P@a&7 bOyO@X{ vRĻJ'J|CJ4ҿ˖3Q|Q*K7sUlJyߓ*;)gXcuQ6ȷ0TP8*TjS<8$Ԯjkp-|8kmC*Q Z7}+6^C<-IENDB`imsprog-1.8.5/img/Security_registers_form.png000066400000000000000000000727121520775651600214370ustar00rootroot00000000000000PNG  IHDRX'3PLTE󛛛Զױ&&%111.**ponƹvut !çz{y888e:&#6r(\/gSl2b*}ܿv@ ܨrr4ܰp2Lq'=eG3jڡܶF:At4O'6X;07G`ϕ[">t3T1Y^$=T+&jigX֬,ZW!Č&&Nd(شϠeb\2Aoip}15EX@?2g_+8T#Eqzz6N~WG֝exϘylƂUh}`3D0,ȃ?eC9Рţh6ΌQyM=!?J]n;LMM[gtSӿ%Vs??R&#߽҇rI/KfN*ɟsO! sL&RT)7rIDATxoKQ=;U ȼindlg+\$<Y,PGXP.FȺYVeH$o |VFtOϾmdt'A$wl5zO"as[u]$`0@B#"P?WD~:"n]{*XD$Bb=H,"qq1dAR$zW0N(IERX^5bQ⊥$oڳř $q͒ N{"\ %Әq-0*r10:1Ч |(ǖ)``)ÔMx,{ř#:O7J5hSz5d݀N223ݮ v@lžj͆%,|ieb/[tV=xvV~VAYW:[)KEQ 7jd82=]C.iYx/"3N|:Ip{@;u`]%C)<|KKCo+Ή\S٢.,Cm1쑃B'ןژyN ^-b~XTk*ZlemfzXu{@'WqT5ZNu({sǞf_oyDG1|~"e;pdӡĺΏوIWMd d|λ:+fLDŊ YeĞ6Ic V՛=W.ZbTq1>`•)lV5[˳ǛRŒ͓v[*ʪs:;Z_ UVV"ֶCRxD63s[o++]ؽٟҫbmQXkY5N?[S`z,٪0P4G WC4+X8󪢨8F49KG<$yt_R=0/1\ pk\f:bo\QۜBl(u zf&Xeua;T=_Xr@8,~Vdy\uŠZ˻3V?ߙwGCƗBළMI, )A>0!F90%ЧvGVOLg;)΁ ͡wHDIoo6Z`&^X?IFj҃횯H-] ˮDH,Qځ~H, E$ ? EXu""X5XD+NM+ X)&*F/"`_ EMŘXF- '_Jo+W kc4Gn&qŮ~@ E OO86X1x:qXZ|;՟bG λ#0mL7aRA4iݶž3rf BE:[gʦ3,2"r,R}ˢO`G+Q)CkV<f JT'7M)M=4Vj5VL,IR^Iܚ!(WDCn/}X7{d՞5=wg RkOfU IaLȏ5*KpRSu/bmtaafC%q)T x GoY;+KPsm/\ _.sCcsmyvUCz% .ҙaGY`[I;̳O=$;&0oBӐihK &D(F DZA 00"ZEK/jgvF_uN;N:~,݃Ѡ)~0Ovɟ=Kd1Vٳoř')~bË́{q%ٳ_wyn]_ߚT=?ޙi2uv|0Z-4cEU ig6 #7̾^s,#Z^hȿ+ RgT!&xjr})|>񧣣sVJ1T$OJ0ye ®>Pٌ%Z@*KeP Xf@P%X"XBo,%3XbbQ)&%?&ce6CA t2Cri,l+"c=d\=cQV%z8c Z^a1هbBX8,rx!X"!c-X kg,ɳX=+T NhNcY !cXMQLeئ @tMbJ2xwf}dPk{3M1Ԏk4ť|F7Κl&)&9&eLw0͸|@ A <]}<m,`~9XSh#@n=c;HMdZޟ @>Yab [1 Z@k k3Hl;ceOng.{I%tō5OnWXe)OnJcw>Gf2Gf7jPjKG4Ri$U~>@q/Z`ޥ /?a@w!> 9H b tPYt''tU%XDbYx)+>cٚcIRR5i7OOthږPcvuT5V'ōM%CHXc%e"rM$h`&$h ؁ H ؃5V0a? I* )@w<pZ!!DQ 0L q"!s#NF;7XWNT^_X̡ Hpk2VѨ?Z6b8ROq2VW?^4@b@1@BX) X}@c@ǔKg,P >'v0V33.Vp3T2V/FX ?c՜6֟sW+Xiʿ8W@k!STz_#||][S|[ ʙMT~v_n(mT8+<@kuf<C‘ޮ  ,ʤ$ }gQF8@DS@:ĵ0\beF Vp²Oo~6CW: {k&7Ulƺ%T|z$Cޡ^PXbu(PkCaաpɉDC! %cUJM`,}z5 TkPFmSpsIXKg,:WR\srUHTaLEգyGnO֏* e.D=}X2+dK%ɟ8ޒrDH$υIN Jx[kcՎ?D+;A1`0VݴA:/ʛ"gGc_afL)<tva_tWZS a X3 glhX*MU57ATy׃hWNPڔ;- 7*a$z< -tjnQvg,u,'nժ0(TF,P<3Cry0v,3/F>0h4.x`m5@}y€v+,/"V:$l8cAy)TK8}224 >OF؉B2ΌFlp>ŌP/ CZ-a{As}C?z%T7XgBuò+ `!6w.#T7`ž߄Xۺ>ȭe,tX#jx::((an5ImϓjՆz}t~h#)gzzb/0w%#y{zz?h@rrв3}}29>2S>@K?H(0 +}X'Up;#[rV|Ʋ92txoP\%8R]Ǿ>,٧Kؙ^?7.}?9ߒ] s+uPb .}ן؂9R=z^$+tN af(/@/ MU]GNV-;;}0axʶlV7+ݰ Wώt,߯Ae1ևAf^h^PPm|#H|겙Ǖ]6*X2\.嵣MWjJJcӦ6\]hc%XV 뱒z,2$6Cll&~JT_|qP6 _oR)͸wf`klre3[R\ݛ@e3\t@e3 \ye3еfzA`lՕ_6( _6$&C pe3p SI@Nl$,όZ\/b$ˡʩV׾`6$;X Λ=PR+M^JŔʫӛR*c/=X.c1] |Q 0^@x@ u;ׯ(8@+n0DF.^ %"rWA!/(HJzH9J*JXGEzN֡Ωg`ye&Yy zv|J  l%@BX1d9=XQ4 !D}_#"X pL+@XF|}xKŨ_td6zg2B4Gor %&ڷrI4Q͘V 1)WNzGT¿ɓx 3܉Ѐ< +{b C'ٵ} ֓r[Xe3|#5V5+6SƎ|ʊk>n,a,TȄÊ|[PyeRlfi|ĊұYc3c3C7Q8^c3 p2Yrfc3̇3qlfh!@w[ ڊ1/nn$u-RᮦУ]z~2PzVQPv#VוRYPX%2%@\˕6@?a9` 8"JA%I6VޙW9 (@`E%H@~[~%xaW}q"qn3}Ch v6 Hșw. ҙw^;>gGQO4YK7ឱ-q'qbIEK7A C\+ Bvؚ}"s 2Fh\TK}$ȗ1Z"n` @1- Z\ 2FPl9O`-D+ V$\P:$wD3NR[4C 36\~@@K7pkxmr3v}gq_FA`h3XB/\V*=HSy IoRn _A.˟cW#vWQ/1I_LDMbUٿ>,ҭg,4[)}VoLmԔ +dݰl J- Q@"ٿ nGA?bB,+b o{Kz>)`6@b_r @ؿ T8MPOvt=l(fʿW/M:k/VEKB?B soHΤ_p[ d[(̷/BdLۿ&Ak2M"/okdLٿUE_rq  xRT>tmB_X <+__LW ׌1_cUzmίٿ\(0%Mce2/͌5#y.5;5{8Uy=)`GAU1-cٿ4tؿ^! \ a#mzűKvB.0[l5 8ʴ}Ŗwq%(_}˱W=틐˻~y}(lMtwhc,-0{V\~u޵R?48[\y0qfrh3I7A_Y,wΊؿaysP(_@ ȝFWȔwIHۿ$# P__Puڜ_E`Z^'ٿ_fe13_m2/3e_fT(iyH^ i,bBr _ 2Wd_`ؿP3n_kؿmaej_n;c5EfzVsh_XNJtm ÝCڿKnzmٿڿ@koz_ۙ/(_ր'3/f[ZޛwOm2Ȃ~/oep`20_vfA ayS/ Roe_TN.ۿf/ (5H/tce]|q.d+)+uMn_MN]:}fr+RJ :pnmٿldE5*)]Roa_Rc},[#f x_ZՇft&'Gd-C:x:Zc9a8a5PCڿĽl%3_yA$ye0]&1X҇W HV. 0;­g,e*S4$$EZoThZo_Dޥ_P2Fkb,c38U'DNgWݚ5_>ct:ק;c4[+M4ڿ\cRgq^~/3%E/ _eQld_0!m2;B3Y(Wٿٿ H uB_n=cNRb}fƅ'`Wh(B$t}xhX8V8zW*_<.HOڇ׮ᦱ-c5X-AC! mR ~qCHA+ J0M{T-BDS_/d ijbٿ++3_ D/IdZC)VܓvA/;vn_2ۿ`v y;i@njt=_6ҀT`ه)_/-rŠ@_^l" o[ /+>ᥗ#Dٿۿ> _/wE-E(@DЀfiLٿ0`u eBf,k[s/olͲefڿfK$5'_>W?+5S+`d_ә/0_1,WS__Ann,ο/E g7ۿM-6}ٿK}d*<9+v=__i b+iۡI5]˪`_ڿƫbۿ.0_)w96/L/(Ò_ ozBۿЌ,>kMn /3fҮp t뼓Ao%gbH^ٿ^LA+ڊ~=^y(()ر`8 G8~PP%~ 5c=t?k [W)HEۿ"Ty wX"S$?X΄ 4O&@oFKWqB{cK|IK(m'6sl=^wр'm !Q}uydۏ]l۫ɛAJe}X(]˂%M4>(h,c3On%f*e_O{hUT_JTd~8;mv/s)qmf RT"%X`X y[E;l|(K, 5Yh"hgŴO"QI-EgOxYjv\r &X(o/2aYXuckѽH[gsѽ ᵿke'HA/iN@)ٿ% `B%eܽ^u9]8d0GFsK̄{vЏj!ҙɪ_JlLIfa,~FBmnkW?0Gq:,&=q=$9 _  \).FEK7ŌRr+Cڎ_k;paұrzL]4-{՚c'<~+Z%Vѡ8/#n,+#:Л %4baB&䕊3"IG:W荩?-4VףؙKXRZ>=KDѲ.> Qo)܄g,uH0Į ~ƂkHڿƫ7,GQw=;| KG|eow!SEǛp>Gv0_l}OBWܓ=7mB7"|mQ͗ Ʌ{~L\_WwXǟ<6uu玷w +}mxG5icSv%׻`rDtF?$;qq_X+w+7=MJzdj{Ii -p%%N5T>Mj';EHB(@au~hJz'v8"js`q>7+y ߡ~+|ښvT&Y]*Vz]KQc}^Z}6Y, /_fR0? #DEs!~`ۈBh!/aLx~،nCEl8A G?6\~h,>+B d>nۃm*ԀO+rDA\xPy,/2=c=t>&Q_g,efػ&(If'ښ&UDZbE7 R@U kqP8T|;|0Oxiv$kv7K3I/wa{r>/j)Rw=Hꌳ,XM5PO'E鬼`o$ Ntd&E@  ,~(' VXF6>_)Rj(Vj(Vjmȣ5H_'l_Xb'2 =l_ J!'uxd~8lTW@X|W_yK`пͥY͔e D{Ql _пxs*.[x<1XH^ ˤ4ib4AĂ}$ _,~пNw_{){,?`X²W /jiޥNNѿ},_ @_7(6Bˣ5_`_PhA_'7>_1}^WXҹe *H26J^(Sb,_ѿl;YӿP]:׿WmN,t.KnP/_Qep }b]]؟o>/݀zsF пt PBQhXd'VTG./=dL``o\6|(3`7 hտeCA Eu>U!=w?_ 5^YJW㭠̈́5^ҿfWԿ#( E1/`_a}u0 v knUYZiмU_/?_utTz6GW[:/(qwֿ?sΏ[Z2?yҿ5WóNӥ%WuD7D@1r0VpՎ=c_ X"ֿn.%6UESwXJR ^[n",TCku5Zi/5+'IR~g[b'78ӿ~T&F=t_XL}տr_׿DɎ7^>fCـXW_-< tP\p܀D@` ]"i.`_,`+_bx$'U^%Y+z59Wz_S~xt~%>OC]rL,`(d(5+qE"`'gȺ7HY@Oh X8g pt`_SRJ5_ /奻lm>/i39ƨx+*$S h߻(+kUkH>z2WDCZԿbmxm3lI@m3jp@@Am3 6ζ剁%Ar?Ԃ^3y*ֿ~t ctv./J5FNѯ7E Y@;`6uFF?h~:n_F6Bxאn~m_F?o.Q* \FC%R:ֿa3w-_~j)~,jsUg/vUR.qMTbeug%]~ пNglZEY:oW(Vfzɶ Sf[݂fEhA hcޗiB\vfA6i3PJA:/햽I%^,@\j|e˵|H @]qw2\)A .8J*oMЭɬOیn(̶XQx6FTn(eo,G\C`3 rXNAmO,O%0PXQԉ幻nE+5^"SڎH{Կkk::ZXk65蠳د  x/8 D$E@ƻan@mv*p@O,G 70pI|7yOl/S@Je(+пRKlҿX@/8/·пRHJ1 dYN+%KZWҿRY+'ž[ћBZ@XaO֌e!ArҿJ{ 9iV#_п5) Y&9&Rv_׿XH2 =K_&ҿVX&G 0H_E,Կ,eWO0|I_YYYF_п̱#Lrп,J2]Y@,(kbֿpNԿ,RHˤ$h׿BKVҿVMVpfXZeqh+{ΕE'u˄l&CZSkU"QRLbu䫈Zd0tiI{qYgd(t&\ v | ,6V/k"^Ki Kz@)jvC/vC!$kTwCy/Ihzˉ:H}yb]N,?Xd8jQޥN,CײXݴGW8»>x_:׿8/ M|lK a>l[9J3/t8/Mr/]_#`zkeb9|p]0}M_y픑w7`}п``C}_ W2ښP 5P<? ¼B4^PSxh(@ACAPP!sBP6C Bj(kʘ b #`7  uWx_du߱տR:=0ҿ` P},ZڱKxL_TwC\_AF:.R_ _ BWo䃷~n_qӿBG?!;^2 e+ $o_P$/()s_ MUԿF(:/U+TKz)KGu7~L6R'XWEEwkw&د:^B@f 1lU. n AKu,c)/mePRZzˠ +T^ DKei,*4X4R]ˀU,ib.=eu,եgb)/]Eױj@Ր`-iH/DW3 îDgh7 w,yU3XyW<`ng, LKih73 Kgh7 KkKkh7 y%6X yv<`*, LEAic3 ubc y[:\oHs $X<l,u%6X_i{k0ҦiKj;Wa>[.?GnX$`]­W!B ~ ܱƂw,^xvCVn}05 WX>sL@9;Q3A< yhO+XXxTEggTyǚ|󛽳0f}AП$QkHjfVbjPdsԠ s/A,@!1;rD,:u,3Xdq.fx{oxwcG|D܈'N͟^T4Y-R)Dx<-n@87zSJb b-ZVW=O4,,A"B3Vy#I.nU07bC㊛}0y*l;Ĵe[K&`/ @>+<Ǣ (0Ga D$#XP&eM ^JpbjOSi!;WZ 317n\eؤ֯WWZm}YUEZ0jˎOV^ˢג54?rߟP*D9-Pq qweWpy+7?=L\-v⻰NiSUoܸھ5cyqE5&k* CCѣFL\~3OHK?T8֛Ӗi—Myfƭiy=kXXV̩Hb1+Ro(݊0J`hDeI&CǃusZ:?=0dA[[o_v8H̩d},q*GrwȈai9#RK^<([J֣*w̍JE>rE`>lRGTba=)QFO6JwUS%>4u2R%XZ1Hf4}#zuX'#X>COiєOT sƵ2uu~b)up#Z@@udac"7mO>2,43-B%†l1IM72,T2%cEUlHMФAd!˘oFbxB(٤SB.:r&ϤsTJ:A 3&HX#ѡY(iCUV=ڬE*,5Mfcj;sD` U+~5i۝pr ҦI rN܈3LRÃKγ<'ʒc[?aVÓ1y9EF/Wf" t[f;B_2H\ gU9b˾qKpV>y,dv‚?J HD|GQp}⏛#)Zؒmbq ڐ+1Lqo5KlP?4~dQ}nĖGmTAc`&a>ΒѬU@)b`XAIHimm/֚ Hf j:6,W>Prww9Ia39U_f'649;wv؝M VAmJ!;g\7mnI>֧GYKSfgڌWF0 s#)\x\!:VfdX;bTr$c]*KƢ$B26o\EeM^gaPy]?VBMI<:&C^]h큏b-U,kY|7E驅.$AːI6˧٩лgnh]MUÌޕJ=u{:q6 9XdSs7ʀ*^@j( +XoEwuÀX46Y;@ ͫgF,|V\dX4K>]eT,|MW o hl.zwLhV)O=`[ko (צ;fX {T놧feiV Q;m Ykƍ3t |?TO[ǔL╠yN`T ptw9Ll^,JmPqhokCV0&BkO=bt'6Fl|-Aw5f9aowu9 V B>"[%TBIGڼuz}՞.ط }CԎŊSS1M@ ΃uE\(s}4>([ 6(?M a{5j9z0":aU LG559t-h d`1,A1\2"Ś"=NBD{ ugujr:{%p",K~r4+j3q쌓b4A@%ƴ/ɋ:4lU>Xg{r~n1;5~СK4=5mͲL,!enܢ( Xq/XOO|XVƷ{*rðY(g+|,s7v nlsx?o (Skd` C zj+"=dM@Xpz);(J[[\uzY` KHGpK RTJ3[ArWX0 j:;vf>ũ3'8p gR;/4c )XB-W9-ȹOu5dBe3X#a* ˃53, >% )Xo2.o?}CQ"XIV=0(FQ#C79VÀ XfFvkx bf'N Ǡ)NrWH`6 Xt8n?pOG7'e6JMޓôiU`dzqޫsRGKUɱ$h\ ;t^ Xms'jۗ1,0eGYiZ‚v]n'a(ŶUkJYGwE!`-+pMMB X3ˣ,/chmK< %-Q,-evlnܐή-X$ 7&U(燩K R͉`m?xg@Oɨ# %fRLc̿؟fIG;7, <^!xpP$' dQ^5``а^C(HDhÙ8ɉ_.z QmaqawATV6qHpm*:&5"l+ zפ[kv>`DL?]`"wK^ϑT.vnY{5i + t RX^ى `}Zo2j1x XIJLI0ZicX&,ĉ R.9ضv= ~g J(Kp%vutgGV "XZ `KhnLnW;Fi-T^¬b}y4Be Kd=٩΁ $'G)TS"Jr( |f<[50Ty%EQTv,芥,9jm~׃2(}swDCBım`[p` UP"'Z^2P[(kł'Ń |OPgv̠/,#dw@aq,1,i提B W`(w>ISUz'%P#J'{]c.c$9 ˀڑ%4B`M.V:^tv=6swʪ~IĜ ,j/2ꧼ?R+YMx{&B'X.ry_) F&S!khl i?p>Xm "XDx-`:.gnwr]RBɾZ,keu'XJ,f?:uj>-}(&VE@g~NJ-0y ag7wO`)`3Ţ/:wrjlp cSuNҿ+6ok,F _ P zd7!C_?1t(P3e2{ :~NsyCnm΍U&&#XS8|~e0b``iw?^`kP13F3&1 %a Հ Yج"h/#`ev "#x`x""*޷I/-f%_&fycqyiOL9sf[,b5W@-x.>kޫܓfM^Usn1WIϖNf|Z,v.t IX?9cVuiy~Z. xB}F|/Xs/eXXd¾^Du۸û3̶]F`s;uH欭C.\03#⾠+f9ڬ=?qh]\1Lq*I*uBI*z|~*&=dAzY5MTcnu&ՇQd oBklRzz-cѴ'#-pdwJ;ET2Xw˺*#Tڊ㉇nر{(e*$bTP9T Z,̭QǬnPF;1[vX=+8|(.[4N=xym?fvp): VTXEI_,  KٙOdLW+kg3$U4%g_0wS0(5q30 QǏNԊ-eBCE pI$u08*qkNMmPI+l٤d˦VB f3GځK#WX-v}  \GZ`AJ b%\PaBEmCx]FJfu֋RUbcJf\C"۠ۻdl'A"|?KR>ZhFD{Ri)g6֋&bY`Æќ{faf|SH '"Gp'FPѣG|,|=f̷LH|_;(^jdNNkD$;ÌXfblK^r&uLmkk%%:ImQ?,M%?{M2&ys>9Odm; Y@a?G`o'cR1(qi?0/_72XzT5XX !X NQWltrF x~䛿Z][LF[e2'{]uolJ>c6 zYz4X=0y Vt4W/t+łORMI?[YWaJq [w84+˼;&dP-ݐW*q?e1{SDL},$V5Ȓ] nЃ2$g VTWxŎt→,eμQ},ix(_Tam)))R1H#:ڬ%Xwo(bDQf&~Toti@n=H^@)%r;~,A!J 9pLt9e8ðQepX5"sypp*~M~Z ۻc84[CWik~xNlp0\xNiz2lyއEȈ< Du݄')| ^eճX7yB` 7/k!5< Ԧ) <X>2q&.x_[ɔ7T09g)k+׻5.+>_*'ќwSZD-ߒW=:'8+$Yjid ~VOsW~[fSaP .3?gދ!iڰ _^LKg1-7:X[p +Q0~iqܩG0]M}23bϢq*#]^^䮍*㟂0͟fŜP$_\Ɂ"7wG)+ s(*:v*g-jޚq⾺S}afbk݅7@(nQtIaJ0=,_M50mpzސTp2,}1;`Pg=q=|'-B):ӒXzݪ;Bֻ($K+|O]+Z\J`1wC{"Z^ T @w5HE4l6~*X1/KF5ulu>w R]rBY M2{wr< qOc7\Y-FI,*E+^Fmt g1^#J5PV@ tJt0w_ZB`N4hmfÕ%C',;kA1@ucG9-sl:rԆY&͗nxM"}qޟ%8 LfIn6QP}(R) Y ]Xg`1Lh16bZng[&[kUźu^X :X-.V2 @lceXPW,\C`q,F1v3XzF ,.G:X6Uc9/-oa_ݐ2;B +x" E0ɢv@2d< ,5ĠK'/ڊ+. %DܠSD,;7o{oՌBI jTz|Mln%2+QEYh-nCS74p(sյf%7QP.Vld3$c߲z,|ڙƿRns0%grUV4\{6N%>N~l9iELzT&mc{yw0UAH E6<u>n"+$4H]Zu0qcb5 yw&Q c!^_t,3eA(g#;c6,t, rI  UK5A5&DN8/:ߪ 6=KE/s!_TvFphT}Wp4݈N6E:ִM+tLSupEdx|YHp K`f<#{KWqT.E稡ynlĝ=s꟎E˩i,?"ъh=S~ rEҲE-Ȯ+[Gw=Vh |t*Vu;;P@,P}oXb~!VQ콗[腻=G~({1"L2[ju~M .yP| ,ѝՎ2ȯZ^K[ZH.Ttu8siWC1d7q"V ,jeNh;x^$t_؅]PwkWmXjJN/VPjXvO, Y@cs%? eAD,{R|-K+4!) +%{}fV2#|@EԪWeA,ws_C*XW^| Y֊?Zs@h%B*b5c'!@ЄQ*XUzB!a/ \ mV0 -s0P(EoqdR&.X-fID}7}* r_w/4?rO Z :|v)$ |EbWђؖnwU ,.\^m\_VwU ڄ_KN/*tbφu>J*5kqM5]+אh{nD;3H鿥F4 tqbyZFk3!pXRO i:/` ,K27ðRz_,},WIENDB`imsprog-1.8.5/img/arrow.png000066400000000000000000000051431520775651600156420ustar00rootroot00000000000000PNG  IHDRPLTE[jFF IDATxQRQQf8p6o21]l MkI֧CN^`/c\8N444„iiii x|2.x &L#L#L#L 2r&L#L#ƗKjnn7w0p|0׹ޞǛWw0= =%1O/ZK 󳇹rǧh\xw3M ?eфw ̅c]j\x封L̛៣ 3̷h\)\>s̍ts\x?!0hŒ`n`v0фY`{ 氇`0Cfsh3S=._S=Y)8y5| 9ުׯoէˈ0 ~'x=u 1rz~}GK6I&?{.71?\ϧK.MMg/6'Gh6+|}^ϧ-M4 ׽_{Ss5-6楔`m 3Mh Ef(0#;saV}&H0ф~`FNwф`&k4-5X״Nh`0+/ф81ߢ S4aV0w{c4a&N̗h¬90;̊{M ?1G30 ;-rz'{M`FfsY|&M`ng*sR1,g*<s`S 9frR1N̙Ja0G 00/rRqNYJa0G 0#bN] 90c3`̩Ka0GŜsLˉKa0;1'/5Ӗ`ssR}stJa0ǶssRуJf+̌d ?cf&5aNfrf| f&0K703; -ƉXNw 3yL9 `,a~91O ';;`~91C`~T *}`l`Ƃ sb,fĄ fĄ &ҭ,N0avNL`Ni9X)/`neanea0C=&0C0C?0C0C0;{Lu sL̑.ZNOr+ 3t+ 3t+ 3.c fĄZ 1asbgVvȗ?0C0C0C{Lu fwL[Y[Y[Y=&Һfgy g.e9=֭,Э,Э,кfģ~0׃y>1WY}Vvuw7[a^O@L`޳gc~9iԾi=ny9rya^ *z+Foډ_/yed1S~L?ކj_sbq&Ͻ\/0wcj_0Cc>j_0Cc'TPK2CyZ`4>@K} վ`j_0C/P f3T} վ`j_0C/P#k_>i}A%ڗdj_}If%ڗdj_}If%ڗdj_}If>s/P f3T} վ`j_0C/P f3T} վ`j_1-\IP' B/ վ$3TPK2C/ վ$3TPK2C/ վ$3TPK2C }YNj_0C/P f3T} վ`j_0C/P f3Ti9ڗOj_>i}If%ڗdj_}If%ڗdj_}If%ڗdj_}}Ĵ\pkC3T} վ`թ}|Ծ`wj_0UCswq}scC4t3O;̻RFS_~`aaa4444„iis&L#L#L#L#LFFFe&L#L#L#L#LFFFFZ`FiwNPHIENDB`imsprog-1.8.5/img/bbm_chip_scan_en.png000066400000000000000000001027661520775651600177520ustar00rootroot00000000000000PNG  IHDRRWdPLTEٓx򨨨212 @e <<=3O14@ܠ`Y_`9qxyys>31]L73ȇ('({DD06]J4Nb:Pkll!u˒U58\h;DxˌOF;DRF~f:֞L"PQM橒`Drt@0L8Tu=InmܟŬ3x`LW5tLLah}_}ՓH [lRXʥv$pVЙ!̏FI ϲTεʤjBɶ͑:ߞy@uH[ṽ ڃoyƗf뮪 5ws5gyp ЖEnxl7䘑ΪEz4~beK6ULD]M$ 7[WhЂrfdQXtRNS@f@IDATx݊0w`kХB 7EPX;F$и~ɤ9ɽrn;lUq\6]g\**NrGFi/Uu'?BB4>z蚹n:j J8`,2(@,fٸ&]LNC,[v>ٴ`dI$ ,.)_~;YC&˫Yw=VuOz3i)+;e_.><\D !ƽ`ҶgÓ77Tʭv^~E"EV1mdo\To HF݆uVWlau/rY`O4wmE%7̶irˡ ʸzݴZLvKS|5|wYr~`F픣z\~|7GùI~a X= 0Aʈӈ-1x円xm@d ¢0 )dظڰNܪL`!0d1!@!+Foգo khXnmhhxhmhx#imhsm<㋓ت墔J$PZ@<  ( UVʻ@yt0(!aKT f?ucv⤎@}s}{GG|yݻf_8]_2|yyI > gh7gW 73볎Mi;^M&"Q%GJ"+F-6/}ӈyZiUghA^iP.f^O`'asqT*#v\#׫_/`JEM\/D0486riPja._+t^䧊3"dnfdT.9rb4{ qy>+,V?Gybt5t> R9?c( o|~:yHyIq%߸uXXD<+ T3p^m)pm]H> I:icIK6f_9?6.pҁ&-UbRy?tGOy7홹HÿipYm[JBvP,"dž7x]Ŗ{2_&^¼+m[?>P gE3x^m)熨FzѽTcOE.r 0mѯW=||nO# r`Mpi]֢5t3uY,q/^@ݿ޽6yႳ^n\Ύ{֌X]Y osmZz:6n+,mOC{mUHVOEՅVEͯwK]89ԷN^CʮWm~"K\3vCҶOܪF↤-56-1Ft53f+!Kۼ쪾Cdwn*ܨ?{g lV&e0\EKySaޢ(rP.15u;_ʯҮhj`Ⱥ?[M2o}!Z%h+:,9ѫ6(i+eha;5cw .^z"PmLzrพAx圸iuNמ,.eh:y.%G!a)g>ׅf÷^nJtS2\gosnk-tikВIKB%$!x> U9r[g AB*W)~<>^tOolw uwߛ ;Wt.~윶jtC'+Nf!6xco+ p2r %r]Μ}csRR^Zot>y7LpD%֒HlKz+qh euDfa'qxr[,WWμ.q/@XqI]2E n5nO]A^"jNo;3U.\Ha`*ՑJ 皡6( Z6u=E+.k^;qFt%P5rcnA3m4 v@UbݠK νw\uTjh50 "i:'zK.$xj]KR}^>B;^YGl!KEqVa ˌbs_p+MT7[-/:4!@ubË*k]9=dy~|fѫnd`\)ݦވA@=sc(O @+{[n*+nY37]».%GGי94˓(];=4pO|Wu/jai*KW˸S *PPx]?Tu] 9S8kj@Z+\[U[QE͕ٖf5C"K<l2 Vxzrq{6/cv%$rFw`ݲK/ȅXϬz!}匒;Y.v_2ҦWTuRMH-oK$mAwϧUAj,O+”CT~_T?P(q X.>}_ /odsY\Φꥥʙ鹽BUMJbS44"rM^Cwץw).WYFO˧;3 n0 tu=3H8/wY~R9Rv; ժ.G{UӐT=vSan}N_Ek?RP*c姨̾͋k! Э;IՌ"TA`oC+ty;p!%wއr4=CŶxWCH}aYvgt73g/怸i;#Fd r.6"n٨[ϭSwn,*.6o*Jn ^]4t.WaSqoJ7;r(I '̪euؾP`>UYVR;K=T^G W ܜnlw&ȇkf5Yfa]]CY.ݬDU-:D˶R;5w^AQs VƇLnfbWT>  ܍_<̫$GѵZ/:i2;'̉ĿݺuT,3`>L-kү (UWTdϙ3c46x^zM憊k9iMŐ4%)c,fZ6a)k,CqFI틨c;mrOq٪Z2͹ Qh,|wenٽ^ U4*2bPsCL5ɒffŌ'3]PյR|ri}>_٨Bi\t|ƅ3Xv)uM晴 vjX?abz&۠nLw 3P 8bf@'kώV] Q>$mc60f*^tUEW!\Z;i{|,A1([rOJ1.ݗ\t˗vxgW~8jnf;\(jBXxV\tdؕkihavwK_rR'^tGV;Ze5.荋N 4ЇĘƫn_o(B˶$Շ}VK(J.]1]B ׭f΋_m͘ARevj%E54SX5X\8!@~LuT^?5{PTtE_+wWYdF:<5Zlt ='w,]Kٽ>%9޵-[S`2-]`;Zst٥8Kٱw'5?5fu3z+$ME2q!rɋ$Z$tEVx{{u)wzYk Yyau M43A!4|W\#бSW@ oKoOz+n)6b+J| +(Gb[W3tYLO(cхzi!Jt t-- ]Mj1N tYWg"x<;Х vVٍGA;mxC^4;[u6SSt GE;.Ʈ`NO_7~e#Zsq]WYq/px2mr'݅ PET RlːZ,ﶕFׄ1?+T T$]]@ȅF!^fR!ވ6!7J5e M&3)!k XåO\.Rŋn&o\=;6!/V(cƿas 2hv"i I[E*U]1]>}Svk%2jGY.9я<'TLEW4D7Iq%n.#* ⷧ/ \Zc5lwmrKki m/{NӸ L;G#>ɻ}ctaӏ>Hn8}YLFCWH4ˆkYX8.unv.wn㣶 wEkic&@=]>l],8Xu@*.@ YEwQ *Ḱ:u_~s+5muAnOFԢkCɓ;q<}8]Af!YX}Ahm|Su';{ڿ=wvgP|yHnsk1)f ZԱf9`ai;Ns:x! \{m?#Ž,cVϯϔ0(]ɢ/vVW593t*.EW05 t$r_G_,w7z&waֽSAAKHeXB'xOlD.Eݿzu;jo|q59ʷa ,W܀W?z+tGur9J.*+It4s9#Yj>z-7uB4z 5Z8]N½sC{[./#ƽĵɅ?u-^KoLmtMB4Z&NxSx`2t%+>)'+M36~/\vޫ GGo!wsޙuT:$ӚdnB$⊐tWL~ +dMSMw]+M5uS3e?>]iQ5Ѽ ?|TYYu.ofs ƚ!K=KMȐ`ޜe n=+;31M6Un\`YqQIW':0x\Gs;xO| rvtU&CWaE @_j]rBjȍfֻE>,뙙̜}wnxjޔ}gyu+S=7ђ&^Эv7eW XPt&Jkhlr)K^?zieq.:..~o%^oKm{Fr)ޕĻ|29Meݗn^M{r\Q4]p >jKYڻK?WO_g6㸐-{QС}47 'ܢ @7--^*$I`d<^O MwPaT^h*Ǘ!O5 tͽjP%#iT2^o@hn{>i JUt썮cmhi~M?.=p7} "jMKK.lI=h}x.e%fv\.LﱉZXu>3s vB+<5F voxڈ't-wcCW$)1Ad@b tcoʍֳ;;00;0:3Wwg;g4qd$C TTjѨU>"*( Xo@ x (ǃo#M4Gn7$_ӕdJ[uj6!E]/$úQٜ4uO=-8KjUǐUq_y򳼦U[̊k$͛ˎJexWͩ+K{nܔ5nENLYĮ؃8umLUu2RلA0V+wc:co>\AJqŜy7g펻;4 "U_*[50ȅ\(b;/$kKe_nǵ3^:0bMг*ށ'3lKɋҕwpuMr{`ΣUq=P0y;PX-wk,.';Jelʳ]vNG t)s@!Xf-Cy/L]ߡBD71ZK])/oXP䲥~_>SEWEܕ*%xQV  ܌-O;wzܸ,fÇfjjee’av;R1fvKl9].Ciw?ԝ[!)c\%q|/S eBݍDtsN\V]@,.hq@J,* Gr ,v( C/v*}=ONëW kP70Ove3UW[%ohHʛvw u K[Pȑd.MdԂ u![+.`W5-ut% "Qn٩T/#2,A]> xרꢂ,o|[{(Qf+,B٘l8his52Ru]&1+HJB]ߥ[K=tx$ qIϬKd~6 2Yu0j4bWױA!Vzx%YשTMU]_rY%j'|1>dzr]UE̫cmmC-+w `J֗bu&",WWD]*eEYqwْ ^q$ ot,?]WyiuM0VW󇡖twpuYe~ 2Y>a$jӼ¬@E2/";WV}׹g3=jWVW$5Seeedba-]e ;R,CXeY'[Ηի9a(Iܭ߫.h2" i]ukA_"b,&o SY}ƕyQuehu5kƵ_+PW;,b"r dYfߊ-"(bfv~D] |=a&୤̩+\݊S ML7r,-bdܸ]|3w}븸_lZ]UK?.2`@udւ:la|*Ңl%lj|fXTwgeUZ*>,Pu.8quq.mX i~Y@68;Z|훅B9uސ;atx:iCsl%04L3 wWWMaU8OCm䳾ÁȲY*yĸFqQa!1W.CnkYEknϪϨ{ 4D\No kk)u Uv`"X`8P_Se}A60E'߅`4PwRvN[>3 w_ݿ1dz=x _\6hSYћR'Ǝ UaϭYrs (խƓKcH ^ޏ:^5Nf563 GuD54,]=cUSWEjJ[m:ë̦k{NxI;?5m-l\執5вe߼ OD+hEoI&H.q+ZI$m2~dx4,]0Wҥ-QW]悺NU3E |̛3g-_Y3oy3:/iykBùxf:ȐMk-U c];3o=SuF3oF +Qv|.ҩ&1P;5⼛Nm22tLs27 *Ǻl hmZ]vF.-bYu!QWm.7yбi6wvh{LpWZ,Cu_aߚM=nI.cݑxZsBjG Ɠ#2U!<ꖫKPBk-X:拾XE-~n[ b 4G+_ øC<]t<"HdmECC;յ BZua2 ߂i.!e2R ].!e2R ].!e2R ].!qeҗڂwY1YEt9+.tiu,0Ĥ/t4ϞY5C/,qeҗڃnm%^A[4qLL_z mqF1tC&t_ ]&}e2 ]&Cx +9<`2o]sU40'(vԪutk4.Sw5WS2j]^Lm\W4}-{6=CV вP[<ĢaU_7#ӹ] mW򋇈)S]tAYmAC!tXh[l%|Ēdky$15CF-mkja$#ijw'?Fd蚋l?f+ٓS ŏnn7AM;!Iw1IΊD{V=F' 1&!ErJ0Eu$6eyO[la>2I=j| })i+)9hw =ۛ>bIh@S>;q~.R3g6:a:ji[ފV2~{ Vg UxpgΛƺn/ޮZVE|]UFİ^ .K:NE\>Pvvw ;M>s0Wϊ60K8⅌(S葦KtuYR^<&aE6VM0WwSn|h' ݁_Q'@NtAi䑧#LECKJ`Poue {9/p85tÕ*l*2 .N(nju:MUuRZt8-LT9ZD+4ƺu2i~n ]اE7.}.\ :ü~To܌ooʶ%Oye ɏcX]X`wpj&cb4Z< *`nEw{u% dKAڜ䲂U-9;epnO<QlȞ5@0L*gEEDg7@W졝 I(Eu3uQj n0$7JqadXB;7@).d7]׵_ ndJ,w8|y"^[@&UݮAd:ì/&n䨟RЅudK"9䳢mɉr[س ukM.46B6/aNtg4B}ņIR= un%Vj IO/pc;$jv[;Œ-2q(K+VC(驚-=i|ַ I =-t5\Z5X|s2^Cw=jϤ_]ɐ. LLwKtCdHգ2]f.CI][t?Af@[e8mjaOн't@g<;^d$ u21]{ vϴ2c쿕Pő>Z 6>uɇ q8SD@Oq`9%9 k$Iu&$giBt= |ZLg41bnkBzY K<muŞxGZ<ɪvui*$/Okż,?I8,˓}"^zS;\BfID(btsfm0w:{6P , -$IkSE7fJZ^9pTtdlPɶ]{t(ƥǏEDbn -hϾg!tgqQ"dQjUWU"x:MJ*o8~WyF#߳i.cM!.mK#Wq#$lMI5 ƨ9>AAeaYqM[(웺+߭{gĤ;c3w.ߞsd1:.->8jثRo9֝5prf"bFm젌. ^6d" Oo 6uPd:cƕy0nN}u ]9dU{yA-^ݡ .s]\\Tgm^rtj;7] l\$ُj&{[|j[Ypfw\kcK5z&tIfPW-EȽiVE"z0L;f*Υlb#{&ME2-KFMᄼ.46SVI6뮠kT_bԒ5d$t EI.[DEI.[@P%t ]2T䓡;_?5_CJ23: BW)5_y8/{_Cd6ߣzfϙm*zml7]Y@T蚼pI#tb} Q@a jۢ+'tеbᒆJcř_JntNf{ToН/5&BEWhoݿ&2+H ] x'QtځJ؀qTynˏ~ O|ytG&;7JH'UZ̀ "B{WHKdl~fMF*4%𔁊-֞r>{>gb6~3{5}nB^N-9} 0ڊ7Sc ᱵҡ=shaHj /kq["` ?ЬrRoi<3)`$;nk޸^DWz>xzS[=^+"xAtA `xf`-A jpt_t~c.1Iut󔁊-ܨ$A̝~m't0{'3v1.K %Z}=HRPv%f$7z*3y:I) s<}>2K芻Sz.؀ 4JxQHK;j^_X0㐻p[pr\ڢе4jokaɅU@LoЏN,tG$.kXVFw@є-Q>Xt?o=%lia~@Nx l ώ/$0G!TJoI(;.\qsQ%t hʖ/$Rljva8w ݾ^&O Ӻ.]R+tҙm;Sr$%tɢ69M Fe ~Rcnzkp} AGԒ ])5ɮ5{ BЭеPn*BЭ5ɮ_)Bl-μjS8#t)`%Bl.f%tu5gnkCdl[jQc46p^l6L, YV-p+W#l%iJF1 ) EY)4,Bj_@ Ff*[y#8dm( /_rj>[;8YN˗M2jz)#B4W +еRvX6. OMP{H(v:]caQHzl97QջJKzbuVLU*bBSi 5"tu+^c]gqtDi&6U(4T}SԻ8 c9РZWov]ui `A/A ,L4u>pu Y ]$7ϩ=A^X9±D7ԏp@l/$/ul3܏+N+s4/\B7o4=@7 V],yzzS 56:XN_TZn;eU Nsw(/$;/FMu ],nEXi^t &1mdX},~=X~I詋-job]9]Q^Aybos< ](`kdLP:K]Al ]:uvj"z)]V$GzP-T2ي?6,Y#Op]Uՠ%lmkN]Nj?P)3tшyȡt)l-m#J^xՏPYi~B{Mk]:YݖdA-e "t]K"K^&4u"t ]Bג"t ]B(xjྈc 4-KrfidĐ)A&dI 3s]7uٞΙsι>_-E"t ]BWK.F.]+%tzduq KQ{y.୆nn͏v+&j7.6%"U(Y ^)ũa4}7f[+Z0]ej.ؙ9Ⱥ^><=*]R < {ԦF4>28\])B ,Գ]xе_nmY|Sm:jj7ֱQq/R:W)O*̎ 0ӂ١C&uӞJF ^s9Z%5n\lT|Qka\(N9%t[Nydw 59 LyTAA~n\yQE) G[6KGb+@l6 6]cÛ {%jSKtm?ByiT3]]8ܙVQ?=_4Lus€VzM;ΦęyЕ-L+f%ȯYWmj'=^fEdpUGQ7py#3ɤ5Q˺` y׺,7Bŗ;WbU@wJYw{c5b85-UۓW7:^m+sܓ^_#kׅEIW[F}TdÃ\©rc\wpwœ:ҕ[9aƩ]3%JMM*H3t*ғrp$:;pG&&r1́8S!CoPɥD4Zlu]4%+65 5G" EKnȺg&ݥM14eeݝ/築51 Kxh͎~SY9Nu~+2jRdݒug=R8?e_- ~2 ӳny #&t}9e{+<}Շ}EzV5~H9"O-;_{/%&$Q1WOu]wFOj!Lpq)ɝbg*}M.auY2Le㤶_:e,連 }4^PYD"t} BE$-E$-7yqD|t;ҸD|t;ҸDjtcބ.Xtj^B 3u\tٿ.h-IL_0S6g]lɽ$7 l4Gww t_DG&Ph)nQ(2=BN ]/um^StO9V.L&1YMWmtV2:|H\FZ0"eoO tQt[]O=hwN.J2pey׸Q.52H>gKtcG<`3ۿQv\0 t-)Si| t!8eu" th&$yc5/]duI> fa.+b >A&&"еKD{1n9s AaMk6k|!!M:E9D2@X3еKօC>OfM#c-$,hYA xS%DޗP-Ϻ΂ww n\[HW}%;\(rvMe%D[cﯚb^Tq?Gky`si|kh>a!Qa*HtKWn4CI9? t|]2Utman7[4U0ᚍ.':r+L%E|Sa_Ҋol[^9 K]V |KByGd|#e jƫtLEFWJkѓC$=7TԵ]5QEHR%tIZ%tIZ%tIZ%tIZJoWE:OjOHZJ3VzK%Uˎ r? u:%!RGGVݠˬ葂.IUK1?KSQǹWﭐྈ[r9]kMGK unID)1@phTBswvvkr{󈀫>c]Y'WVߚa1M+ֺ&Oѝ;kr] %}4Mv ߱.W틅zAe ۏy`}uK1!u os4.Ԉ`׌h|PԄTfǘquS0I=4-mu ;|CKB,2h v+ul*J۸K>腺&RC!jԪ\_Rkf3g.uAj1+`QN̛3MwYu[7;nn _&Rِ2>O/ۣ01Uu`&6ibg[]ڴ"]3>cd5>14mݸ1܎\Ԇ\aTuá0iS]"v%=Nv⩎_UOu+TôLjD.u_ Sq)}2Qe&)MV˝%|_S5P>亦/0_mGԊd>XelG/}0噬lsݰ痦ۗݎv Tb.R^<ǭ(>cb}KKhɣTXae-KV(P &ǜ;[573Pމfh)qe GgC;05@ .QO/I]fOTk-QU@$uegASL 2B}BՙvA[3ܨ{KE[9pi[]G+h%.Ru. u@] B] %P)PH ԅ@J.Ru.L@Jj_#P80C] %P)PH ԅ@J.R"hp.-rKmre[vP W_P Apꎏ.4[]>׭f xb=rXxJ5^R8'PQn۳Cf ,h]ꆯ_~[0|/}ڛ&ײF7i+)?M_YI@\Vw-#lwKWŠ7FAѴ{Oz>uWFbMZƽI]POC GYԝ 309R7z3Z42`꺓K.7'uO2 v-Սԥ=/RgmLFf.SgvKw''KVyi`Rkk)]|ץ1&n/ >ץcynDt*z.b$¼21 P&5.ay9j9!P!yn&v`~ 3SͫBeV<ΠVJTTQLćC@V]2Enuћ \ZV Z u@] B] %P)PH C] %ju u@] wIqJU4+2,rll`1h!{hd*c[5؃\=l>AZٙ[ ]yyNq|~N)!] RBHt.H "]E %tAJH邔.)ٞBYfQ]`{'~v ]MtC6Cl̝@ { ҬjTʊeʕ [(sn ]Mti\m+ۦ B55]`rN2/B$Ծ54*s'0uA4^j* *Z٬N1u?s=68 [4܉.҅"1lrpQ9MօMoΜ:3t7w .yvKӝy!l]+; }pIM]y̷ZWJf z:Wlcbk1t }%f%_Vkޠ֌V n\3 ҅\n5ފ?`v FShl胋ҥD=ķkkn$|=u?"]{纭z^o͉oyBo.I\aNxrP?pl-I]*<׭"]Mt{y]Q\}WUwS *]Y⍐p R+FH8u"I "ѥ,dϽBlB7OqG   }qf>~RBHt.H "]E %tAJ{s= γ<]izHgyA/s= γ8]rcO83WC<%^oՆΟ@Ν;wʭ['.&C CHtH"].H "]E %tAJH邔DM7g&* γ?݇<(nElvuƲw%&* γ)]?3eߩ)1OW5ZWӉKW".[] γfoZcw i]Ly:2}WSz#vb~G6Rf&v9}F֧"whG~XMׯfh|2E+M?'CO"էLHg󽩆7lDSHvӨ}__ j6.=Z"Sb잺lD5uyttE{{'ĺ3YnϺS<0 =ލ\H|F+%u }v[>qs  Vi8Cs5S2Wط%<]ZP#k snh0/({/@K+RAxyRGanx0ʕ.|t!I%tK$JHҕ.+]"IWDt$]I%tK$JHҕ.+]"IWD*4jCWh>tYσYDt$]I%tK$JHҕ.+]"IWDK߷C.NۛtYo>.18v.!K{Fq\v-h " %a569HIBFr0 MB9ҋT]6[߬t-ML;;O6Rf݇ʗHoDAuaRy6gB3=\>M.dǕQ]o?--sQ7f)x':2uIfD})ESפkkgbz͂Gx?iB>y?8hI4מ)7.Don#{] KQA(#d]ܾ5 $q_E!u}xuDRP]}،`n XO&Qدǰ]^S!eDե}I su-4sx s2a9LEǽ/B{>A|"<vsEF&lxo" RikCU T hCGuYONɈ8Pw>jAQ]Fa/*b27o]T,c,>;lTqlk4t[hiT(Tݖv@P]>E?|&U\Yv2 .r3-g,ߔX6-ljZ`Pm\MëڳnUz돇ZuRfj<&jWR:J|+7U4=SuUh^f_-6PiJez)JY3{ņqڧ-$oiIkbW9Mkti\7D1&QL_T.*<_ xQyN,:h;v=.F{)2ޑh㖧d|;v A ѣ]l*N_ {GJMW=RtYS_\KΧuw`nB%:G^o+.AYT7΅1Ne0\ʾeMP7R.ôO6F΍Wνgp]vh0.u8s|sbL&Xzε,U%1|evkyVX T|n\}=kR:QJ9L5<}13ЍW_|j0k-a(.u8.]u@'w@m:;.1œ#H/k3QH]C]U7ʅ-b`>_L_V՗o[}+El$.aڡ.犮.]+-6nL9119$x r1oLHo^ԪK]߈D 3.ª%7x Ur#qFz8>7U]KM v.K8 k0ӗꪫŢK6VvI] IfwI]aP]TW u@P׫wuIF.K΂ErL#zeRiuE%+eRAu]RpWFuW3@eW G.\M][G]^pQ钺 ^1cGn.[O8JVtυKn]E-6x2"nQ6.irRVwQ^ď6KNp>5撺uֲVyQ_\X.UN[D&onVW7,nݲ[./p""(n;Aoj.w.ʋ"fV ȦVsIԵ:rYyOߖx7/ U/, B37gf3 ~H./1Fce[S\\R wMyqB|~_J/SRUΏqCJ^OV_2^s>~hfUW;6!H撺u555ٿyŵv]\H 3⏉]q([ɧGSZ3h ף0Lsʷ;v"qMsI4V@7'p7nҟFF|ҟϿRB P7"*임x- s9KdjA<s3~ݼ}VuK?-PwDb-zFq3x)CHtJLBd&D<0N Kv*Tufꢘ%zE-IkEi-#IqXW|Mԅ 1pd`!~z.'aD(oOeiU4<S&6Y-(V7HУrQWj?*_ZVQ :yc@QE#Ey h>8<7ΙɣK 8ASwYWuqLuϨ9t5y.*-{v&LYZATףEK!S R>ۓ,dcCjp|6]DBKi %{1݅cPxN/{uQ9LA͐RˆPޞn)jʪsmQ.\ y DVZWWhㄣN ڡ|zvu|/V?W9!Hq# PBԝw][cS'#Y~cP,|R8?LwAp%`[pn?2\NG;ņJcWf'CO&` צ-+ɯW4_ 2"nLz(p P/ȁxEISS7lkˊ> } 5v!]" BDHt.(!]P%BKwt)(!H5[/p 3YH׋t$']\5_̕ܯ]ҥKU~ ufʵ=}+%*hg|MrY $|H.8I<݇{n夡9sy$D`g@邃}ȥKgzÔ;''ͅ3> .8G<})v}MO㭳{C7Z[{S) .MÁG<+7n( ź2hjcr;K$ to#nda-tArFh\*5ylD%HOi6 *Hw5Ɲr''xPlʲHwmlI|? N!]P@tU5PN)c%"^N4=+g퍸'.(@hjkNx1v^.Jto<ۛSam; .Ȯtf~hٓ鞿q]/wEFLmwdyckSk{{@gDH~?#0C ݰ62͎Rҝ:|xXUΨh.wC%9{o$"2|[vE)Y&Pe8?`˜x4zH4gcM^ݡ3Φ:1cfu9ٜ.|//∹ySe,u]5Av¨+U22BI͟.\[YemT0DJxWt||OÜRo.y"TkߘIw2!ua6nKI6\yv|ΰDaV(>t}˸{eacm:t=#tl=>cfH60\g]<=;rm29o>bʴbX}_ %.vfmS2*l~;7~mYn6[+ KTt];qsvW3̬\ ̜nFbK\t\O>,DZ|& 3vt2_&;9Sg] sM:r6lK r.+1t%bR@9H@IH@IH@IH@IH@IH@IH@IH@IH@IH@IH@IH@It fU׶p/u -A[u4{~_".uhu68HW*ե˂l;Tt6koJktR]xv2cCs۠"]TnGknGЯn_nTZ[+ tAmPimTOǓ_EJHW*5$8s<Bsy9r5X:[#9`30Y% _~+~GHU=y =y^~<VX~O`w$2ʬt{?fo.tgι I UVhPԛĝߑϤ#0< ٍrPOCXCfXueު#t1ux2p~WvTfq?&JB+߀ .ڊ2N)Tx?@Ox2kmt=o/ns\al:FݯBa />.sB +m=6Z$ apsKY+:ѩ,kTmO |ɱA7`l˧]r$/RjܛT.OewҖN3 SWh ePO>V.?=$./na*]}VKY/wwGF~^C\8K 6znF@X],iэ1V,a\+ t՝ΫK0GlBO]_q}`.Ӗw$/Q/cFl3r,="680$T+4,:@?=s#B'RM33;tu/<ׄ^ 41jOc@s'µk4)OI ]O-jv{3M` R"o7wg;:aMB èJfǪuK=!.d4;'uu-sݸD©S%Jna0aea :}"r8eˮWfHzʬlE̸_LfBv Rw꧘;9M )ru]tk0#[[ǢmRO]ΏnW%uv&q~dJJ\w7$KIF+t;_Qn5._SnQ 4 ^S*>0[L9yy7duyCTו:*[DmUuuCTו~D]}7اGH_ wpyfHI᝛ԑoM^]mVC(IENDB`imsprog-1.8.5/img/bbm_settings_en.png000066400000000000000000001101711520775651600176500ustar00rootroot00000000000000PNG  IHDRRWsPLTEޓx󸸸325ӫ @e޴ D;92O7f;@v<32犊ҖYb[9egfR;mHԒO4較ܵq97\Vw('(38HҠE}BC|D1oNʁǥ{{{w;BVU]`٣a;CwTL`zX1-OSLcN?)3Z駽IUߩnjdrst-oU8QȈJg4,垭l=MSD;oI@LcK*E]:8{WJ;۟qBչImndx ӲXyD)/@#mQTXޙu[2#zjК!dʷ@8d^}>Y YΐߞǟxFI {ǭ9d qfꅂ"X <뱭VRɖLDzwͫDj{ ɑ\K*禞 l y )uj_aec 8IjtRNS@fIDATx]n0-JX 6zl٫`CV} g3e{,_.L3OEu]o*u>i$.\|%{ݙ@깙pRp^ať(Gtq4Uv{]pV)QYxiry]kU7T y.,e#^N=苮ݬ*{N#sBQtEvMvc^W>)/ A)EE7})ndnug[g=S~T|Bά`v[m)7s ;SZ3*ln+*ف--NN/3tݜ[[ ro[@Pݝ*薨XnSҊLb昫T5'n1vw_Ayobɹ_|fK*[ݜ+薯s]JLIahH 31ɉpjOeP_њ`)\VwP#sVFF2m6 mhP*}RHqlO4 l}z8kP*! `uu"]_PNB]AT@^aث4LH^(TVFh3w .r0֊@hDU-V눩ct iŕ`zLew?c|P Dj@"P6Cym\4#ިD<'n!vsUAd?Հi>m"B$Ľr+NRJ0.@EJ Ǖ$DƐ["j ֡.s#f椦m06",t.3zi2R0>`j eyM#./A.R`v b;!R [5aoW-M{~_2ݞVu^tNqgk(oq z7ӵ؃^u 7"j21G6iQ*9qzgM‡s/gK;<=NQп7ΛMzhgWws94~\;ª@ p\ #3X@qwe U[7#<Tdb\wJfۈ\U-/m>]yxNzڄn0̂"UaCKܭaFxjqE-ԁiGA nn|0p cF8$٨OX.-^'C}D?uӳټmzar|6;; [7ۻ,>kf5i甴MgGIv&Y9@C!vsU:tg1vSݒ۴.SJdrՓk"x}A\rj` ձѭ<<*yƿO~{'3 jxؿȴf!mr:]Q2z2fZ/]+Jp6=v# Ĥ-V.9oWav6(>`̎ r]„$Sߟ3sMZB|98W3-NݽSqr[ݲRFWǝ4"k,ﭒYԿ2S&;_Ȱ&tE ѳA[Lƈ>BSfZ@}~ٷ7Z7blρT0 {e:}}ߟ˰Jwg~dA;Eb'h]uvzd|? Z ֭v9Wם4@bNwm3G&V]ʅV[A_u%&d"x \͹(5-n#'cΡ%,=s@1݉7*81) d09"3CgQK~EfY9.Z]Mh1xȼ9#<-> ^0@aĄk!mv&< oFIIwQwo9zffCYح[NoFZT]NjZGDb3٫okn0腘k3i[j !PkxiCcmKFxp50B;cҟ$s"T,ݬ7?[h5}?(⡪Mf4 w1Y| ZMJݺi&(%~.gM\ziMzW+$ܛB7Jn1ePLdQɪ$gd9\s80J7^̿uo7NzG ꃩZnM`yhgP3~|x8Y2syl||Y?gSVLd60蘮/7 ϓO. zr3]?s۷߿o>OzzŎgQA ֺ/.;ć1xڧTJX l(tHM'u Zqd!`qˈh[a]9{eC &JsDb mAZFZq\32NRP.5W@-_axdYS2J)0Pf~{? PJZ@܅ 돿󏭓LpߨKM>seG6 /0t48='tDV}~\\7G1 dl[!3*.{'"6Dja+`?mPȈ7{;OPebSQ,nibSE(AG_%Mp"˙\-:حR |~v1EhZQ@t1 OMOZm #8J/~ P_*uE>ZKT1U0]Z Kgm&`g8ldTںK]4)5dN`J5=Zɢ넖I3/~Aq[V^ƺe"~ jpBQt!s)!/(T鿢GVTʺ*/UYR_;80ǝz{wnC 1rZ%KR U`NT F0"Zhi}EOmk@(B5Qmm/=fb5{>3}ff?_?_?) T"Ww]ֿ߫ߓas%'SN"}ѥPCdHvn½D QT\I?m]_RS34No.I,QqU ZgyB"a ss c`2ҩq?I4cQ}ƟoRjJ\m;SRcʃnt{{ Rf啿\<2lg6ܻi>?{}/I!Yhq ^M-{aÇnMhvJD&=trw8TV=?mqeYkofRN4^;bǛJ$)H$)r^VEQUvBsܺ}4+@`F@\[wu½ yPb"&Lv"v)7LMM]5wMeǭLa7mښ|'~w^p)"fiߜ`O|74v`kw }Ejn.h*mռ&Y|3БLŕKr980IꍎKCsp@W婱j^MRS~ ޱ{Ic lwu/&!z8?SSi_LM_$jZ Ȧ*.\%¼s%n@FGP/\ {iɸsXh\x̽s@WڏiOE#v)fEkzjgQ.\{溠ъ}MgG{)_oJT3=v0t >} mIcS͌Lkk.*.D.Mۦ;(ۡy=rRRFJ0Py}rt0kۻ }eLĭ2rVW+jCIQ$i)cm|Ɍ[Hy~ǶQ'n qmXY=lVOPCsEIԚraL[SZ8!JZރ/ÆP Q]_tvOGepkw=_<.j@=!I}{UR-8::ZB2U%5x> ռH;:7T\jU$c1CooL9=10_| qeXmͅ6MPrKU DnƂ2B9!.ժ/^&J7evNL.g 1O%\rnk<+ s~4:? īn/ܿ]{aqwgqw=w]p=N^*w%l>WJI&.˦ToEc `*⳶*ujo-)'G cq6m[67;vv,!̀\^u o9UwНik{]SmoG[S%ޘmNS[L456( 8.+.4]WtI,N7onVn ޏDGڃ7SM mEp^@w ;\R׏K1= W';w>(Vx=T^WҏH\謳@PݪiS]KKLsx7%4nTںwMJ́]--ȵB_`W%,T> G@wh^S;ۆF TW:XNN͈f1%XU=tx rWۻrd ^J>"i3C"撻M UdhRhO`Ww99RtrS֖p~OS+ B]l"rES4v,c1iq6`<ʴ).N~dsY%WUb<K++Am\?q]}mB6%K faRcG=`ر#Ƙr3.j> bwtt+dʪ| wdFJT\{JDs^_E Ot7J.uGPy.-|< 9Bm\3W6;#'.S榯̛ZRhrCKI ?+xzAǿY2lfϳ4 ]8CrqUBE\U{[=ެ/l%53XZќDg+k3~eV rW9p~rXӥͭBH9M`_QuI.lsjMW;Zx:EW3kv3-G zTu!lpz)55q46ftj0_tzk mޥٲ~ pAx! 4$-]yܼݹՅ充9.STq)Ivpn..rr۾5[ ciW\pZ'{*F8dW/(Byoč-Q[>k:ĭ|Zu-,fah uݿM(?U՛KlHv,ihqE+_aHUGߍ5Q\4!oO .pXg37QA_an{ƐFT{.7'ZwdQҔDkYY()c[X:i% Y]С oV;~qiЕ@:.N.=ƅ/]t;oifܾRCz=λ r!.MMo\]]!ImƱ,VEGV;CNFvwv kuGwE8wVzNv,7 =ЪsrixMrĝ;Z;|vFmĺ)6_9~eƔw'v"m 7zr9e8rqvB>Anժ+{x]o_Wt45ݚSF l+b Ű,Lɋ\uϸ!kyi0AkIpai8c)Qq Z\\ +7|Chat9]ܺ OkƀW Gu es k^iU]`ح`@/ȅTکDU]x҆i+a=r]ݔFc")P- vʫ..=VHRunWUhA^tvankZ˦e=t/n=yқw{gϹ IB]ZNjݪq Zh\=<rq E#e[F.ZY7FU]Qu=Pvw0kTĔKte4('mt9:. ];&^PYS+' f WI[cQչ.VoѨխ\]LtȈ[2oCdidSiyWc !@p `ǘ*Uyrr~YBwr;PD߸-]1Å0 %z$]uu{G#e,]T#Ke٬0SEm ;0qS6ߋiq¬8ާ[>eA.w@7ᒄ4gm̳Jٔf@$T.' {=xOHm2UtoWvIKWW]e,nPY,H/\3>S?,|rv*)j7'fLi|G6߰I CɉPmn나abyQub}ـݜ*EH֭uz.}]n+>*WXhnܧi{+m˸7ZF<1s:On)ʨ MŒfmҖ_BeUw[d-.JV]]ՉIdlJq7a^Oܾ;~6KWcTB~(|6ACOOB8qL8AN"[SO,O7*eNœ=./S tnn%`kW+ux[ġ/;^x=xTxWBɇq/mw}֎p*?^9)WרTptR+<ՄAsTC_u{>0\ 9C ZĀAK\tfܒ(,+{y2H t23z y2GͲSq T e0eC,Ͽ5u a?ߖg>577huy WxkD78Zȍ1 wzWG@fd6e0=kHBmuV{p@C=Ve\BWKrtKqcOu53|O5E3~I-Х@bS tQ1`5dc&~ϱWv!(KZexE%e*1hA]C{)&ch؆S/ 4*9֓\Vң1@M[f[\ELn=uO?wǝ:3\X<;Ė-SD+e^Lw!ض|29eC[kj4Yj[:;š+l6ovsX,E@\(/ vKiZy3Pm%E7uM !T%]Ht#.uP{\^%9#}D8bנ@7d8ta\bjf]ftΜA!Bu1q0+]Ԃl [2O>ONqp$fp#;Vز.X\^8 o35^ݔD ۙz_t-fY9P/FD5-QI~+<-w}_W/{+\v4=Aj۸MÂ܈Ϝ~+8\Q^ꡋyL# "% `MZJ/9??~TJ%fɡ_{ս& -sC t79U-x/؋Su}t8^WVIյj.@@e2nB !楧~uR{f汏>SWV?D\KkF˯Rnb1ÇfҖb+8Xևj@fTck7ý~c5vG"dx>4;N$j䡅"Ouuȅ>/\nk25 b7,"eft,3L<_4 v1ih'Br+$%\UMB]5t[M(+TgZ\x nEgb7TsDX37ή ¼Ɖĵ>[%^y\{͡]ׄO.GymPHd5 FHU쁮8*ҭOgmU>lްP-f)aKzڕhu,H0xk]j5ye;Hh`'}>ȝ`Ǫz3hrsKg!p'KU9Y;,+H5zjJuCnWvAnyn*&EZeԥ-TjX%Z?7;pu@z.'̲ba-/f:uBЀLTwa0h`0VbpRY(uxVWiN4П5аt@]$t Ybe ``Ϥ], ְFRm;I휵iN%Oպ$L8ԥdhL~eB gvw*usduܭӐrs^PhV۟y4POMk6F b\K]BH{s2ka[WE<. '{rxܤ[?B~ʽdU7!k{n]ovQL%wDeQb-j O=.آ,vY?Zan|9uv=u vo<ߐk絉 0YBE#4Dl@1uH(iDA*EBы b(xB9ߛ l]]Y7 $oo>&y>MP"2P 3ŬuC+`TSrN\ԕ~O]t.Y"vn!vF;uΎ tSNTZ)35Q :sZyg/R)еC{̤gDc׷ĭ8,aQJ;;~44PXuH]6q.XH]gw}Jz{ms뾆+M)n>^mZnAfHɢ`"fV QJ[O2Uo綸0?vкfuoiU!, ޒO1sF}fPR082 ݅u/_&Ҿԍ2_v8gFQQ\UQv'^.q8"ĨEq4_BG @5d{݅REv:U2c."~*R uݸ_K[>2S!> ψȇn1RwTV@(⹣/K_R[R[P7\\.|pM]n´N;z;h]w]) 6,S#ͺXK7> yK b}=aVu ud叺nVw;Ӧ/\][u{׮CWǍOR!dJw26ޗġ*;!q=R8q{z=.[S?>t7-u ĝ<~ BݕZY~WS3ȿ+utx"+)]ETi\LO׬kz#u_5(<N~:ZK?OR[,SŠ`t&ý͍̮JM]nL૎0*kWKD ]"_SK Ѩ^2cDQXb.{uɺ]ٹVA ] `tꦽjf\Mx uu ꆋ]kSPd.Saݲ'(,@'{p<"t˛miV*CѨ7Zg nF+Wozؘ.Ev7Kz?m=y9y<--f.n{rSi7+[LLY ]varzFYvR t[*Vuu2]4c[1]L+}\W/E{a_BF0人.t5lW1]LW#젹.u3]4k ]Wkw t人{HSC], ]@]uOI/r]uGfϖ6tXH"%J:ncO# .]j~ ]~ew|ؾܑ5iņ^mÇ_JښQ<77|C%oBT -mKC)"67f`OnWNj^뒌%}\h;` ]ڲc+] &K2tqݯ,T@e&Tt%?K+Za&Knk1@ԙTKEr]Xeɝ'f_+r]붕|"G>e;͌Oຖ+J""@bEq?ZLW{T麄.HuouIR交&Me]NSz-B/=憡kۧs]k|>\0^pFvVs]B%(׵)?5XOzuD&㗌_{qYot3)m|!߄ M[麶Fr_-}qIUgitg2u8ueg K[Gx%--wD֍E: D^2v,LL0/eKo}o7B}#&AaWYL/m)[M1#{k9]H2W(u39s#Ӳ/w  &a^嶆E˿f~+![0,2= 3!y9g;wf`2@;GBs8,T0_{MJ3H ^ֱR<G =2Ww ,Qfly|W Tm7,Vn$!8NDXK赙.ڨŠę;g^8K03]||*m_;ЅF>Lw eLt @ -}|wsok* W ٜ?t/V"^~P)~%go׃Ԉg&'BfRA ͡!vVuy.\$S]( o:pQαÌ\9W7b~RhRLXaվŒ~b(" 'f^"Fگ]@' Ww%}g tB2wIaߩDTA ,,(;cO"&UNG5]FHBD꫋е裫K"tu~`1H@%tI:Hgt'wgkYm..S]%%@`$txq%iBH+.]W? tIUE$ DVf~]1t$E~W|itnZE]k\B3(j,~gHp(~h_:+R5S?#$fej%B EW-l36F,d9罕Fzy2]kǗHScM=q ol7H YB7JQgi+!^&ˢ6H6#wANL=gsK,(#)*rNNI=."]+ u%ADMP"--w"nFHQFEےx5pUtQNͧ]; t"w_C3]:k'Zd1dP(36C])\d5]d @Q Vt+ "ڪ]. e7{}u"6Q+l({NN1?gpoGwpB_z-$ch௭ nQdXޅ]: jjfJR*GN@7Ks 5(*Z95Vid5]q󲍱}l5RE宋<.Z̭+ɻ1=7c[ΝQyHu]_ܙɨl*`cz80MS iT m0Ƥ8, nNH k IH`n,nTP"(R8\pPo{S?|;.$U|ݙY'~~oUt1}DtaRy@+oLڼ Jbwz;07nADpn|0c;20qAٙXh<}-RU[+̛yPG%%Bܑ<6F7&aߞ.Ʌi wy(`_ͣAl%E#l`O`KbìT5:V]σ'Y:**Ul ʯ.cy{e#]YtPSRjtt?Y2tj%rhҜ'g%LIЭ,@oaagb0%CfrS Z*%ᇫk si2ׅu=u= SRstː;%G7{MN`۵k@W%y5k2%%.:nBcP2F` Ga>s߁^ ]%.>fB73+6y&Gc<)t]|u7zu p˿ݕ'ܖ0+5@ G]c__߾D7e[w<'pׄGTʸ|} Bv9jܾ̠~OaVdtk.f.}S} E>”ݤfd| VuYWUJ +BW&u&TM:VFGWE]י+tJ.W;Dx֛*R|%pT&ٰ=zh%ɞH"p>ZFJU"oF6.K.Lr׮dos !Ռ'a@HGIt{EXDRetsö[*]۸\IS<G46@1#kZ Ei.Nj'G}[خau1-.{FTYZ2!kۖ\~?ly v>K4.Rb̤?wwC3jiYY@>I:EĜ' JCh26'}Og5U&z/kۖ 73@qٗS%.o=DwP@U˿YdbP|nSFJU"хQa["phxltm;b' @8ಠtⶻk"4݈BWJ:MӶD>KKltb+B)t  3 qӊb@@J2G!lE^gjDTMr]cXm\b0Sf9&(=Ō_8A\xC S`(gtؓUH5{Rmz%3|m|tm;hyTYN`,o`;,л+, c/{yDM7RQt߼Mɮ+I+1Nj>vpj`rUZK^yΓŮzͱJ1Љw/'4{whA痠"SsOsPYGNԲ4T#F*p]4G͸RjtO Uo8=~ $Wu_@|\A}ƂFd|']~Ǥ&},-g@5si b&`lo˟~.G׶5}?ߊTUdҷF"OSr_kd #)|'#*N085ď U2!6R :%ϴgMa o"\eʵPΊ׊u^^̪̤ÄoѭT_03Kn &o`q~ Pj>Ihg8|2bvGR[W8N%ښ ;s}#Pڼs=B{rm|=k6eL5RWq mFrΦ΃ PSf ]h+.>:[LM<;CUYcI:;7#KXǗIQ[Fy,`uF U2k\Uf;pz/Gu@7z^0ü PvF1L,bByln ߮ͦ ] UP!557,sFt,/&pb]3K!B5!+ڰ%EY{ uX۷_JЭ\* O{ ],iaʟ232rƶlu(^t6Kt Ǔܒ!lTdq`~]Gy0]BVqjRwސ%u5E;AVuI|eF8ơTU|$Mnt!sZ`EU5Q-Dkrߴ*t@8{e;\Ckq+ w t))0Z3 TUަۀnCY1wîk&'B0 dbF_GdƥiM xytUУvHu_iL^¤Z]ʵ9C6&{AY'HJAd?Y+Rj.L;!$ ͩDvVÌky;Е>$IOh&scе|AIJRIJ DNSɱR.~i3-&M,{Giԕ)Jb0;6(k69؍:RT 2 `-&4 d":18rJKJ(!!r^{ߙ]"xwv7:"t/-*_+'7 Xa&8m ʰteIiZTCG Õm%u˭TeM~@,tYzC"zGTn8lZTCl5+̚n8WޥjеŸ!-ls š]Bo D$?"BDlzEHѕGVuIWG@&7.гjS%[ѽ:]59x %*=,:$|Lrrڠ$^t{wn~OlD7j O_)4Uzrm2JIķt0EMfT|;`5eUDMd^_FHYॾ =C,ԉb:Q]bؠ.Az5 /~ws;7I7t`y5[k*gKみJ&qMm$#Mo18j}ˣ-xko9γEa4EӼTJ C#[uG-t&N.FfWx6_8)fno"zKηlRLrʈQW7n2bg#A"DFVxV.WgvNJ\IŠ{׫v7|ޡGG.hQe&ր ir=y-s /js>\sK0'х~oSV|rOBQrT;]*?D^ rUtQ4Տ\ҩ RTO 3!Ȼv~"!\sDdD7nŢkE\nz[2HΑaz.RH0~ԞdZQVME"]ӄ.9+DI+J"/\.^NE]ҥХKjIuX~IGD^šYUpT^ v2%]7t[斌4 Be], tC'];t[En*oE]۾9Y5faZTY tIAwc ?6]n7'3S/BA7dzB$tOy,͍6&M-i,b˵`RLtQ~fн7qɇGw@%}TRPPنnьe~<mA{QZhjQv.'5*eR ][z=_t9Vn%SVo;x&*F @'۟Y貽ATk.HG%im;7.%Wz-EQU\c\7{QÖεa'σcDG%X`7o@.Yk+rCsΥ5D@7sK%IN&Wөx($\45D]F.ޏ0 &cSEHd ÊFM^S@.B r\p\]p*f\T(כw 溿||? 1.%Mt> LP u3du]1JOWq5 tE{mkz`~h݊LcKX *{^2cm56I0#Kr Jj[F+$Z9oh6-S%D"t[6D:@d\B|K5-w߼(2u|+f5 rޱ.Sl]UN4ykYX4BȨNaNI $XH;lgTnZ}M Êu?oEuQ%PKE$GV\ڌl*u f;PZ$rwšķ5:D, )1SNB7A6Ka&-}K] a~<e({oU36a|uAitWWO(7 [AlfP3π(Jl%/]vB씎'a89HsTe%'@ޭh! bh|rZ\a:3U{#%H2̗Cdl$lqٞ;Ѱ5?E壩5_H[;"Ƨ@ {TYi{5@."®I2cՅ:"_A>7MGtѯ:*{ۊD7.{o|a: PSݾ{l vwʉ8.~RuT_vě J' 8ml?*+Ƈ8NHTTZ^=56|ٙ0G+Q)A7PVa"Tՙ"fȂL3j;^J = \]GεOh+p֮ 1LBь^k5CF檎Co!BU l>n3ɐPԢ+w !TNFݞOFݭ50$Gi :uOSKV0'4ثQ=u?u}( LVAW֥t=M.9n3/UGSero)E[ݒ^d{_}!g:qu;AQ T-K)lHѩ91=hҫ:bVG wv?MCaNNM̘H:N2:2l0 ,daBHPo! c9tg2uv=]}?*-S 'Q.Kw`]gڍns[,) o<+k .HmMa4yX;~Ty\ͪeQ-Y-A`Kx-][SdӰ CHY]g^?(3D,H ;`-1_-0k<0:jT0FfSK{+̻fGG( ^## x82%3; Ml+Vq: /^9$u~E.ȉO%F7<[5ΥQ >Sp$(@ y%-WqPׂ!݇t#nԽ-1(dH3L5i.ZRWӒԅNŻɈ KJ’1gQkWs7z iq7 +;/8H]dE9鹈b\Ajnfn,&Vnٹ_+auXr@i-r-z9wY2 /MR+k4,iC1^3O.nb A]pa40{FYZD,Srr;u Xu1Xfs٪+XjZ"8]{ɖ9PVųgeS:8s)7Q#Ru&rɹn4?@ o|+ɉKnV{銞&8 ځC֠\wu?ַͩXZѓЃ4,ǭ0SFH,Sc~m_}%LN#r&0,V;ֱ.:A]iRN>4X&ãkjVɴ'?5Tg?ץ.?tr^I*u)V\{^PK0~u=܇HV7uMG>Bf8Za&lB^sݡ|7U u!brin.uhCKZou}XiOQz޶n|vGu.3[1̺eѤ3af+rv uA3ԽLgFfF#Y6oiL؅0OBX\r3{{&xRs_xԧ.n ey0K, 4`&0yJsuo![IXgm0I29F3M7'4`&lB= |UA N@ʫHe4wDn >2ʍD-sGAz VdgK}5%s%Z Rԭ%BD!u)ԥK8jOQp$T՞.HhLQp$.E۱ DQM]] P՝8XK+_C\"]V.. HՅK%eu鲺ptY]D|K鞭j@sh VDX+CRq%4bWEq.`mvDtUr,;G_z4Ղ)xW dqr'],` )"eU0Ѡ!hn*8SHFw-])1,JAVo9o>;ΠP u.hꪄR>E`?0֪=j|3i*7]єdz9&WݪJnߡ.u炩L_R]B0^Bb[-5~b ጺ'̧Q@w"YY ŅӝJ^a6OlM.!uKEGJQ]4^_nuAQW*b)8k_L .>|ߛeFsjORC 3.IH]J]"D$!u)uHBRDWuN* BKf0A҆(?&@K-rΤn H_C@Wo X֯s%s%mu tz(48 K<@yI{, o .{Yŵ7wP\xP[1`O\%Pս_^B׹|RHvxM.wp ]v~bmmeS{4kݫ%szufK9V7ueo94jn]'7luh)uw/Mqy~=%Cd b@B1YPAa rA<Tj^0<ߣ"x HՅHB$eu!鲺tY]D.D"]V". HՅHB$eu!鲺tY]D.D Q{AX]r0 fV". HՅHB$eu!鲺tY]D.D"]V" <7{BՅyO׍qU80nQ¼K};݅buaե[=*X]w͟nK&ǜVt{_%;S2 Oguq z-GzQ{]m:e;.ޑZv8p{V97M,y[UŸ fLtgb~IiU~ɕؾr 8V~.sƶn\ÉVϓ~ȍG*X]r#}ۭJWiy^\LK4W5GUJW>+;# gÅЍ 6V~rn=88{_wlruu9}z3ںMcuFBfuqX,Wr15noX]t2QѪ$lk#ݞd"]o#˛N5鞦+ E'|/ӽjݱd"#L~뭤e./‡յJt/ꢓt-I;VLaHֽfG_>nW.z6uz+^.:3<՞'BE[2BE*X]!IՅa&]V. HՅHB$eu!鲺?;פ0wwTt&*mi,-VEdj=8+zX{ FaCџПwڵ4ݽ>9z<A;^aI\]o◠#Kϑ?arp+1:P%յtء3C}ʺ8-gQu)­;vEեKO ڷd;s^O]}Df> l> '߮AznFuÜxn2-L06WVQ{%|}̈́CJ,⏥O?IJ13P%: s˝.SƯ\ {򓀬^O0wAAGLdJf.e]0;Π{HS*W7VNY9`08 /^+RWu.% ~ՠP7bɈ;y=IU׭"+"fMEB]K4@ yUɺІs:>-{jv2qp"\o2S V]!"͠IO![Q>}d޹3{i ~ < "9To ;;*YKǀt_u:KM}u覿g]L.a2CLuIݿpR&u@sU*R+F>R0m$.KL['뒺qBrsIݿf]m+%u ѫuA K$3w'*R..K"MO%H'*W LŁjeFͺ0"dWs:ݜptsnߵN7mX ncKT\Rɴj˞S=-$L ܚ\\n>ʤel]W}!S6'znCruu)yg SqZN\\D[]]^缯EÅqu uA&u .ۛ^#?v*,y>'e<l\o6ޒK+k*c|3PQEݘvAع:s)6<ջ?+*/} 驭}d9=p8,ryܾY0ݘv~6@Qt2ez_onQquKoh۳ PbXLa7DQ+YVe㓊ӎ:U'.RmlJW{.U Vs/W}_|)Tjg*U-=P]ԺwaCt2yeG@ƴߨBVKwsW&ѫ[}z~^,C3s_'1ˮ1iw;mPOy.b?CUse$u#IQQ`E:(}E|(j>ʋԋT=e|q.ޯ0eyLڍiWBU4<5ۦ*9~ UAi24u{@MK|5;PQ8dŠ2JSw| }Ey0d4Ӯzo۶.s: M^je,=ej[L/<#ܡgqI=lx8J>Tf1$b5۲ +ķbF2XH溧kO,@-^^f_;+yqp!,U$arFMu$O.qF1c02 Q]hwɅ:'eЅ,an LE2 0fu׺;\RvYǿ[5kq$Ca,!f]v^ҩ{W zS [k׽ ^6qLx~,@ y)?Fa* iYwltww5ꎾͬ*{?.f`,WV CF dcX:D:S翆̐uJhnQ[W׋|DK3ZINݖF #6`vβQ~ OA;p uC.kLwm[u 3gd&A˺XӲ.?H]R l.Q]8s{AUWng[9(Wn$e+̣8HSQwo#OnE r@dQNQـ &-6|:^aI7(qnR .KXR%, @ u B!uH]‚.aAH]R .KXR%, @ u B?ػצ8,Nf:e6n:V((n?MAPB";  ٓ'(F3 4mY?/ M*lw?,ەVD 8_0o]V˔OcH\g]{]zrBc#u$T}Ҥ@T\fٵ{]b{Kwojҝ#;,@xVo+)5}_'qoe:OH7q};4vVvFKCw.ҕ! 吮4"](t%yn닗:UٛJE=pwq݋wG\-]#dg V'up3]g.ukӀҭEqRgN=@\. {e/g&.̙y ]"&Z7Ɩa%BarWً}Oku ]"*s]`\rADHT)ݘJP-5t&"Պ$.p5HZn$*K:NJ@Ԋ65GMH\l+>+oi^D妋Ee ])!])!])!])!])!])!])!])!])!])!])!])9 f2Cw }n#Pm5G!VH p <5Gޏ!"]Ԗn?6g(jٴz 2 t_.kw^t[ciHW(mlAzm(LEB-]#t뙮a(!pA"]7+ 3Z+kRa9vjAeDQL4rYڊLdr+,E-d[뢋1xQ n79ݎgć9}9cPhA Oa_wR"rD@g89z3~g6K(C`yӤHHzͅ|mˊ]"X@_^_(H+E*=kx}~nς@آkl#7Knnƒ7H ^OpI~|ͬ ?=t(YyqSF+.}DQV?Dwk__72PS<}kaT2Dz(؜I^m2w||?tD(M Ce;Oly96t,IS+8QyQ)- _S/etybv z~o怮@,e݌mXW'jh1SmpT? CIST)c_gZ({# ?)=TЅglYv~0gjt2DA)븃Ժqt8H0=6uNn0&̩^M,% ߫*&mP?:d&f) xti6 @UGztȐѱB"u}Yū9k@EI Cs^9n\.OqU_ˈ.8>q1+ #X©{R<'n"0qB;Zq,BWd"4Q( [zoҿޮwiX:cl@х= X|sX-C92>ޭuc1t'qv-98A<̩<*.Ҷ)#:I͒JC;Lf6篸ՃsnȤA׿\"CWm\eV$3tЩ.ܲݖc.t{8R]|Ac=0˂ Vڱel-2ȭm(U]Ξo J@OuXuQB-p,Uݶrm3ա Lh7qަ7`873]u3;ؾn' (ԺȔ.s,t;Ll}|ѕC[P, {)Z9ϻVu!YR ZЕk]J />1nh<2)CjVP;̇Ǵ-sM m?u !2nqZfs`9>u'|[U0ߧfth@37(3ҵ _M =+gE:tHo]fXY-a֡KFX[Lld,){at~]"& CR! _XJaV,\\#]Jf8Ed ^vߦT۹wa $DP/Z*}`r!-u!Eǣ R]WڪZLEZ1Hi+m^DTM iҗ!ERKӾV7D ܤ|mZP:rU@8gut7V*GIENDB`imsprog-1.8.5/img/ch341_black150.png000066400000000000000000000203071520775651600167130ustar00rootroot00000000000000PNG  IHDR ߁PLTEǽֽȼٶ½ſžϼ_]fus{ΩrqxyABHfehĬٟۉWS]GHR``lKKSAEM11455*+0FGM9:BNMS:=D>=C68@EGPGIRLMVYY^DDM538 !%&&+QPZ>AK779GEJMKO0/.BCK\\c`_fӃrrxvw~ijoffkDBEй-*)ÈnovҲ}~ÿίA>@վhee½¶ĵ Ѻ'$#{{~qnnaKCA߮UQTYOGȲwmc"Ο?95}]VU2-ťѻEG>9`ckG=#ٝRӷF=5"E630RD#8/קnYB*%Ĩֽ[Ēʲ}bi]QEţ;޺}vqbd_]OHH둈{ѻzNeP$mUrOVH8zg,|pĬOB3Ö#rte͸`Pi-oeY<# -zeLtn%=82J7tRNS j5#GI˜]}k@֞FвԇсèiBIDATxMKAI>P`բ*Vft'ɰDNˢX6ҘkZDZ0'/E"} =W=d@rPM۝ PJkM:+mog I;PF྅T6M1oRs!ϧ8"@]s㖲YӱD7PDĥ~gcܨ*br~vm^EGۀ- 3յ$,rޓ =Y E ^qxhh`41499I(л.7L'{ s?;j\iVP힞A9\M6j,93!p.`YBh`lM71TyDVBiCeg]]GF$pN %rrYn99Pʈ0HvPg֦j@Y,3PYFɴRb}&]Gop\( ,&gv\G3 Ü 65Jںm ǔBJq3MjyrH J9}9gӈ@&e!i\T^@Gtt5}Zgŕe=_L3*aB kD/5Qh ߲0Dv 94=47]+po]_^\JZIP e7\pӻ´؊] Kta@iA1a#k!:/מ_fMqW/Fz׋ջ^^{׻2]uMfŵ&F6uscellD D Yny>o5KCEEy?JZi@ue  Ö8h@(QX1U ET n:@Fm‡yxQj00`0ZX)%^IY#82oCDZH_IIֻ˵d;J YM5H\\S@a7D貽D9c0ʘ-Ghc{)ϯf:RzW)?yplA6A%gÔ,U /2$`{{ocM-O3^Z&T%MyV)Bcz M&^ZFWȶDӮaIڽ/AGh L[ò ZY=8E)3X v 4Q|}g! q\Q<֪lPaⴏbN j`9x@9)6 Mˠv/R',pRϑ[} e0唠ӛ:[2U|43{}{cպ$ax' ko<͛o(doY"U' ypc+ & *#t"l0FRv⹡z}Wn޺u`Cܺ&᠉Ƣx쪨Na8+%AZ-0/̌AQpC$D;'Nuk"|sz$MrGjLarEJ:ʡHeo/hEX*HҸnWa-=r?e? !uMQ: B_R,rd :h%>*T5I̺H?2'X]pHHv.d(ddqɊ869 jp’* 6KP"ejѳ[a[ے#K_8(/#DTa)1 4,bl1z_P89š̗G9xF^r|0VGE>CgJ-ɪm‰ %s:#4w QFQXN:C`BzҞŲPV(Dly6\8zp{OG_=zHTr8^QH4Uy~:(SDeT[YUHhS1WO@#W4Ra$TqU`9f,.We9:>wo,#0%JzY`+ǚk^GB ,Ffs- \|.I:Rk12,',Fg i+{6-t\d ?J[W:1skO?$qBQ̛u#+(5 P&;~yCwfE&Wj%ͅύ;Y(aYK$=ɫa)hгT$Wql{S9|um~T֘bnMk֮\ B-K>/]RqdĞc-U ;{sg**XolTS.l6cNSӓ&`I3r>5|k槊.'Ү*e^Ɩ^>."~F8:Ke&`X[ qxč=zNOL~:Ժ߽a?t\o+[Vtk:a-&h`BFIJ޴1?yiȞ 7jnumpFV~[h0|hnᐟTC:a `@SmuC??gHϮǯMl=aݼnܢ3)}rbyKrU }bKP\ "^MAն^y[Ѽ{ux{֘W>ݧgl}&ero& Mie2}]q oѝV-ivb H%$_V4~в^]$B,CCG'fݔbSgXOi]EÏ7 lDJ. ,ԗ(P`H`C! +2*8n9cWzeꏭGwY|/F1ދz/c6E f&!qwXdiHcnKeBB )!$6 `CQ[Pj"*R-R(qԪzq[r`|or罐 ÌH \hezF525,Tֈ@PLgj&~_g΍.rPtKT;:U*Uc!F $rO&'utTM5+n~`],8pK.VyC.|):pXP[tK/i0FrK(DB<5bYG4X Agm~uEPY&+/|z:t@@tgm*ȅpF=_-p0 lp=Kc`ٶу-e@U☵/ϯ}/ˇ|ͽ*Fp XmJrmіV(.\B6:zC'+z>>yr{_[-Wp")g(x #{eSAl-Mjv 敳OO} w}f[Bg2E7R Xr +}i**&VV+ؙ8߁_fVeAA4fszyx=g{WZYѥl 3zywqe4фIદ(x8MDb'Yef|7!Vn, ~asDeHU`_=bIl,J^w1JpԌ4D=ĩXꮛ UIDdsxk݉P(C}G<KaR`IbBr2d2c4ԋهVr`x(ot{V pg}YX#$d>xRy|z}]bod׌$èWϏ} gjZ-*Oa/XQp4׹@.MG̱U$5l(Jp(¬xÙabK\kTM\t͟,wevY}$V%(N Grrsٍ6'a.z1(`6־}gK hР疂-ibx?ݗT,I7Qw$>$bi̔ee쓘) ~2 kspk*e~F"Z XB$ :|OLcٍm;k*,cJˎF2 YO*/?|#yU;ۏd vY"m+ak&Ġ4gIQ\<+xٓR#l; Hh zR`X4[JpAÎ@(]!X$"O(n4윹<}`cVkޥ`I1c/azM|(/ͅBK+p<'Rl  =:S@52u?X$NӸc69E  SrTt4V"iE)~y[u?uwsd?y{7qjMq_ϬӡȏH%) /kC\Y \|db[k1OOwhߜg~E,gBtܬEOk>r)!8=7?=4(IWqk/~X6Ijm ch:d켟F5+VMM9~|`k%`5{'c t,KT}2N'hT?v%ϵOwy*xmWfDz%Q[#6-? D("8?|@W '着* vY]bIHe,jeW4HiyOrٙJ6G< er]{ROt(","&ԄhM`tᒊ"F5Řf8[]ghʞl̔X ŢimrE|XΧ"KZJvgOJ6{ڧUG[ϫ;n(DL1R$ $c|~|꿙`QmuOo3U਼)_[M4bbaD= Ql.$}A~W6;zÈյsnMCq2:/Ud(HJ&RL_SCU. 댶Վٖx[f22>TD,C_)~-wOrNrc) X fsc[)e0vt֚PI3%*;=UnԷRMGaF{m@A3J\!\f8K-Z}}K뽍B s~{6PiQA=CP$%W|W*T0D ӋV^d)%Պ:efOYWUX|>J'_m{"-.ׇ{n"M"MHɛHH/K\; EdD4Sѥ(sqA/v6w[O5W< AT;HJGpdA8L/]yv-ë ~\מ+(Rv̻: ī~su@,{Uq$l"pD; i]D`ʭ*'"yqE89}syԞI H)] ^͘y_QNoO_2yVj*b_*5 YTN7*ɧ="gW~SjeTc*G̚af%m-rjzeQmG_+Ϩm_έX}{⨔}%}pqzIIENDB`imsprog-1.8.5/img/ch341_green150.png000066400000000000000000000177341520775651600167510ustar00rootroot00000000000000PNG  IHDR ߁PLTE݄Tºz[ޢnĽݭȤſzhľő̘M˅þȥso:XKqd5nH¸wM_9eC\PQYd +żùļqU1l_Y6xaeX32!}x~rk Ǿh[]foMBGPAx(f?;F)"e]oR('.$)_jVW}t1syjˑrNQB 4A (3m2>^_ݹqw[Ǜ]#-F?D~qHRW3OJUB> F<ۇ"'εZzTnifP̋͟iBhfl5\QFGjĽDƦh-trj9!󨩱3tf HG׻W,îRyDl`P`[f^['/osu{ ԽC5!NZVOSKBFwfdrtBkr$mB;O.*6tRNS $D3ThtژeJވ̉`?ȭƁopK7^[IDATxmLu[X@D)Dea>?4i%&^GLN1obk j a*%Vf+0,1mT&U2p:<wfL2~5,-'g<IFD,M&<$ SrAYWڤT7{Ja_po/)~rYɱJU`Lidp-:^8CuAGX,|sIvEցJH)R>%weeS[2ZJaB!UsĵF"\Av i8xX^W+Ԟ߫ ~FnI ݾemG,ͤIya h*H9":Knwj˝Kc`Ȝy%l6"ogu9@U(Bɔڙϕ>h=4rf{vؙ;{zX]J c.1gc~1Uc gZ۾7bH>c޽{cS[ʧnˮxXΰlE&hH 0mj;.$Z9udy {w^_OcGV?n(]͙+Ex/~}u!m4a]& ,-*l:̜ZٕUkwMȠ~a>F,I K;sй//{vAp&5<0| Z?X{\VywoSʶF Zg*<}ZzOLNQDoX84Z(f=  HY\Yb#^Y;:駇 4~M[+[-``p8={⢜b1}\sl>MO_b# 5vv;u6k,=,UZlfS:TxJʓM"LZZJpk,3Ju e {LD8 x{G;a4o7(:KZzXQ=ڦ~~pk" Q6P#9(8`@MP@R";;Wgz>^"oVX'\_;j3t Nn44Dso1wpT,x?1bZJ!]/w`$uH?3q=vQZ)L2 Wؒ$N4J*#%T<җ}tcSQK#zuJP=Mzl2H=l DycX!6eQ߅ :v\o1աXu0 iţJ*E,8PJuSEhww" _-#`5B F-Zn- 2LDvꁒUЮCy]c/[0 -:`S岪Aސ%ą r~ꄥg}|va>?Lt &iN`-?cꪉx.6Uc@ BFlz=C2>>>toV@`]0T4:k*:U60Ot2e}NՓ{ '''o)_Y_k`nAv᜜]ًǸz6qn(y . 'g^oÂ+_wOЋz뤃D2pjIһI|nc:-1sVף`ժ7&MO/>ݹUU\]oE o- .13b▔\SO׃ 3w;yKn׳O朩g 5$p0f9Rim- hsJ//c|ê+ j |Z{yf~9=\m NkhUg}xX#첊CXWS0 Wd2&_R{tg6`3v޼RSTY:=wk=6##S &łiyM9Mda;*ŀCbr3LAkbޡi J[#U]N&PaXކ+jrZEj2%pe`?_Y`a(D*9w끚X,esΊp9Z#Ey XJsr] wz3=Vu(>̲pUKmйZf<PҼ1d\[ X%_P62hS*[ <ާ᛫5oM-7O'.ED"|"GF"XB,O t_p U_lY5uma4]G 'h x'S()<x5맴J\к,}VLz˾CWoK þv1Y&!Sj8 b&sbCoD쬤z25JV&]>dRݝzWhY5^#@J;#Ʉa.إ)yC=(sJ:W"u3ulgr!/JuSZ0 <gsU7444+sA.LxшnST\(a=$UUBF!>{➓Vۦ@؄{ =H(#}\(P @ި6 +UB[w+AQbץL8fxy"Yڥ#i#\6k+5{CceXn,0m ]+FV!2@5S,I4vM^٭]R\]KCʹa= DORX80*hMlhY7l/.ٸig\y`Kx;xV 9Es^:렫ܦUtKIWtwOg/O6KA@j`Qi?iHŚ,E94v]RMX8F $L TЯ%d=IBSIFx PQEE/Nh1dV$(֏fTLc?-rA$#H2J<9XEG i|A25ama%}^h F(?Մ^p!ɥΔ+׬P$EHI9/Rs9s@ "$`fe$Zf$ R`f7Ϡ I XIENDB`imsprog-1.8.5/img/ch341v1_7.png000066400000000000000000000175321520775651600160340ustar00rootroot00000000000000PNG  IHDR ߁PLTE{{xac[Ivg:qwY\QYYMb`WZ]KUaC_`KUQG`hU^KG9m||jjVdgTGR2Czz|yWx~KxB:2XOO<|{venUA5/SWdJ/$51+,Q.Srwwj_/^thaQY"HJK:,/00;/E(i;zbk)TVMTD7W."+iqZN?"<:P$!uuweT&MOk\FB[Tka+H7{9imalf,X:AXSIyxVdM`\лmyO^TO9$i~lkzjkSE^@V½Vz_\eV0LF#+`fkvAr\8L*ݯ,wy{tJkmfP8.1bHzc@R}|]C-賤?fNɺAɨҙzy|j.霹ڏ9st )K0~J$,Ae3>ng K/;GxBR$IN}}O޵9#+HB$)id<ư{-L#/HqX&w:+, \m#VCJ< ~ҹ_Feǁ20.@YqV|u_I~r8PI:D,A '*lMċ/RV}ٿc f%IM ދ?|F±qޯ%„LP .:qFbD@$G_j%wEAWeHGHV`YJ Gưj;#*KAI2@24,JT(/Swε׭7+à|ޖjPha A,Qz`@]XG'F:b#eUN ,@9 &8יnUYV}rM|r-I %(1,\&v㧷~)Q4BK",,M|J. Fu00   &ud['AtMUjÖKm$’IYN{($ʎu2F 8Uuq@Ξ+of_O0$QX,Űҩc*`/χy_Di?He6Y(Rc`ӎpaǦX?AHUf:CBs Df,G0gl\undYU군bડh"']/R qEWecc>ltB-EIU}f\烒PBd%^YJ8R/3L)C/!'2r" wE_~g(LJ+%jՠ*h i!0\v:Hd&yC`+$sX)g}Y<oʩf2RFcE.qQ}%s!i*EO:r0Bp*#|>˾f",@ivpQUTE1 Tg8u~۞uaۈJ_>uj_%\6d˼\t.K 8 xC g\TmR@T,n>Jft1(EUu|utf R`"EQ~S$ zzG,'mw!UdF?YU7٥dMJRD̀=yCDguQ! 7Xq[[uwl#Ծ$Hq敠;(˒04/WJљX3aIL==rkhߦtLWCMTz 3` ?Jd5+|%f)΅Bq,&[/.2[,ӏڦ(kGͷgA/YM<3hOe!Fa>Ogfj-n]$EQzywZe "5!(dQ 8oˋ5\x)z'}G1\oGAw: Zb5 Q/4-XbBW Te=b: AkrᩐjמYfsCtlb&1*/f˫|g#AYhRd~=j+3J:C1 FáȔ'v{/Y@wݴ\/3qݶtP:*k.$\ILKu% ~3oŠRyG|{h 3G4+V[\`w/UՌT!PZ, yz@e`X-6盏LCkEq %@: /*"sv>1Xy}nCW!fjv ۱sZbPLD08 4cxU3qZ_^Wh@C);8mhDЭ/ |PH=kp:# X@QszKR@ 9_fvY`Cq>ͮ#|̎'L@ҹ@*@mm5$HUI @#S^nVre^h:VmLONNޣO,qAͬ`0Uҥ)o,RA/Y.X 7ol}kɯ&!V8 j6W&04y=S *qkbX=4|Gӱj97ZGGz뫛&&Bck Pb9Q)?i/:x5(Fp$ y^wn`g>ӣ׽83s+O|5=7Ӏԡb^_%U\ٛ6\ 2Z|1:<~+z!d *"JlƺRm VM8z/ %&zzz"x隷F? T0ҫ)_"[6V@gY{ls}M?ڹҘV(Ÿ=. ΌL Ҙ*Դ6}MJmiMY""5x-BhxwixZ:{oȨ::mm-=+qR|\ <(\{g?{}ɚ:JJY]T 6BY:ZzvvV; ^⃱^y蹇~O]3 R YTH1,iv+g`ǟ^o|OL >' ߮is|l U@J5^y?Objh$bK깍%85wC¬u!r :0g+߮ydU.DTnu?WYZ@W V⑹|lϿ뗤z@qA/BLmYoBd6i,EmEoΗcoO 5ӧ{ⵐj)3'xzDw> NTUZKXX,Q660a>7?>mLbЂZqXi ]+-T~k6 Rӂzae39˛:a▤- Y j^B8xb)|J"7 F\,,MOB|s`*UKC257UU(Ld`v=^%P/TNܪ$Q\GWgdž#Hо!eʐ8ʼnbl!RTqGa* L>.*3t(T"'l㍅58 66:,VŦ2:MM5^P0H Q7]&VWWD0r 45llOL\;|U(хϳ' X*N>z߭;yc)J]Cf8"Z޸rE#ޔǔ<>syUɗG/PLR'W[t C[*ĭk*Ƥp?Sm [XbK"}!A-/ݟH P ڂ= ȪUxz{R7WZb+V)9fꪪzQ(U]]ų֗_ AKW\r/Pڨ5 έ D h]ɉ_U'Ow~gʁ]¹՘(.H+gNLtfDfno~lIGDբ'}[W JJ ?(`y6*[X$ mE #EX$j9qѻ !6UW 'ͰiwnU@(+O[҆JW w/ڊ)רrddlJ+kN`Uܸ\Rk.uYh3a}"0kd!g_Z+ٍq׎;6^ɇ :@:@VN>V1=|k a< ɛFZ@doFTv}}?_nt֟eUp\mwM&*ja`0h EW ү=j{p]g0FKƧ\h\r=d&&zj++W1wwrq*3`qv?;^\;ԞLjy'zn|`dUp\z3abL&F21 ҫmu1rP-XY&rJ.&f:k+3I68L nUp\k2*()@#ǢG21e6Z5 B+4. T*t<pɽr\>>E:~AXu;"S92C40Fe&BAfӊFңnI<`Pp2dr9à*J(bsȦ@K/;!ސhxyCW6gO @EhLQP*~ϞI̶C./5)ci9<=0X:7a 8P S(E)z>1[zy9G"fϩSSQW%AV:T( @(bPIAXZ>nd)]sLJ9|/j;wyVr暂:f;"%PE)L`Ii\6$! Ʊę`(r1>LeuFE pͲ~%ej .sFpcrW4[;veeu9h%Ơh910jGbɻbz-$^xsϗ񧽮cأ BL>[ΜM8'H+RuX8P{l 8N$ѓ,> EENL(dRԤLFʘ[^ \\)̱k @/e1 N|v6A 8"th2&e, djt 3kSQG7zLevOlRF3g4NK0(Ѹ5b5$1V[[sP0qZ'trl% .gSk@7ν7ooϏAλr[UDQ|?<;JNд4Pid6'JxY<~>oץbSјfh$}hDI1 05EzQO?malOzG k3Ǯ(xo)B,홸{10Q eid 'S,^ވɕh<3s!N?% cG`4Qpcj7K@^2o7w~97;m:NԷɷ; /+8Z*!Nj?>01,N5 l.1BضzSƸ2. [3_[hR@E3rRB4IQ XhM#3c4}g:aH@V $ !C~J2E|λ/Gv['Ӆ !P 8%|C8TLy?U%+iͬIo8pl9̑xjͅI@¢$"|ݰ(cYd1-hOvc{`z du( (h%EA'YeeE˲Rlr ;Gׄ!ۄJ%(lPo̥6}ZȀQաRh#*Jp!ޥaa4׬¸ 7뵙A!"JP$%9;O {qRB\%n 6YpP)\!= OYF&v_|FpqɝRE icp hjd4Է_s@^$RpU i bRF/7B^(!%`Q,M:wtrI  7K9XlK˨)H^d/1NtnWi4 W@)HGPSYK9y͞)#eRsn&9wN8蟴*H< #y#&i^tyG7N;1+M@#NZB<# Nƛ0#!\*#"_q `##?ǤBqdM\d??@+stn IENDB`imsprog-1.8.5/img/ch347_150.png000066400000000000000000000162621520775651600157310ustar00rootroot00000000000000PNG  IHDR ߁PLTE˧qþ׺czQĵ֛yH}Q•vMk7ϘxLfp;m8ѭjȶp=|nΑfQA{UycRxZ|^{[bg|ʢ~_IOvI+ЁZlJ¼W5 R NĿcVļ GEYdND6 uV2%"f;nɋeqS@:ƻ~kmpeXEB¹&O +Խ>=taĿ(vrwhb\!<`VQlZNYMI'ĶՍ~O0='#eRd`s^YK63F &p%W[\0=H=8dǰ*{w> xlj_^hJlpjvM\;5265A&T6zuwmiiQRjB_ 3vvi3J--eRo{Rx_d VSFru{jYVrL<=*}W= {qcjUIFE4}*ehx_N' 3Ni@R?t"[I#/F2' űuJȚn}{l!Lպ-b^{Lgy`x?]u;Q\CcC4{Lvu^\˶r}oV?~vSMV\5ߕU{ErcknC`f'99ŅwuGPYd{FJP2tRNS#T7iX6/ztG]븕ŻʓыBMǁ/IDATx1kAweo9R,@K= 10mIL"Dٌ܆@v 0nsXD.EK۔b䮐31'XMqOl8s̙3i؆]4:VJ=&€+CrmF)ȱ<*TEZRJWU5x͢YtE4vGi"IOW]x}G;pVo-KK+EB0Ξ"i%$#XNJo<|oُ͂݋x;JOͫl 20,& I۵UksEN9ecaѯ]ʼn eF$$bݽQOh½V*2G^]^&f2|oqP2AlR(#aLdS7F':b$`bgPccVA / GSs-x2_=N`(~MbN}ya\+ݏoz}RnC(:)*ֵ{sy4ίn2^ ^h7&< )p:>i0s_ȩ߆+ޏwnAOJI']`X Lib?^i8 QYQXJ@`S@/K®9$dwIAI{WBPtCEYtl>QZB|~~ /{i(RV8IhC?4{0bsgaTϐFc*Î\$^/X7)Jfma9A);"d _QTsM,{l:DҠ6B}l Ŗ*{6 @v9ovuYE?䤇 eStz|l#(`#<Ѷ\W hlTn|j6 ;ltٖDRьą!d8MD%B<9JiU`<`uֵi>zHv Y.+ 0V_mЂ_ "E:j߼hj0"5S_NzY. phA EiƮyA7k_Yʣ俙":ENgaB[ b3jᙀp|ۢȲ+CC_.S `ib&V+u[;R\,Jf~Y?ă7eBHϐx/t\H۩Ngqft,z`%Yqm'jâ2L+%kZ8eﴮ?`y3oHw}9fe6yZz.=X?}mŴk6B*Tb4ô­]1GFU`n '+}} d2o2+{sP qoiwӄjbTǩ,`,xϏ,EW r Ŋ dDo_[g6L& p5j2U~:smPT -K( H\Vɉ/’ކpŴ:Xd3_U}%KJû*V*RG+!8ue*E^Κ8(S!\ݡvgϮ+cX0 V㿣>#"!b܆ L2ZV1YhU DR5^W*-.63HR5+cEMFx@hE12pXהZVo4P)O ®,*/7uB抂B9CrLƘ ``Cޔ5ZYKU*}  6#e1 T``mihHU9aj;=tQ$]͌4joZ{~q[*7QK`B Q۫Vg8]}k042ڴfX$V\(?eZr[%-IKS*vO0}mjvŊ3d-!w)H*V[6}?\bh,Fj`^'fOU/Y.za$Β?Nq*)k=wӧ:8.d4DݒTcwӏYbuy{ϛ%m\Np,&d-o;+\HEh0Xdӡs`7`wZg_]hruǩEkEE+D:EMOqz"> R1_@9h -̈́Ƀ^hl1B \4ϑxmʒtjz۟kʳJR{`Zib_~1_f ATBp'Sۋ1ZY8P]{5bZÍH~W񏱺 h tܘB$"D"vVs<_=f2.XǜtVQXMYǶ|>']Ž+O*"k2{νm-< 'wrČ!n,Pkx ?mVsC)c[&t߆Ǧ,Jg*w;QJ۾!0w?`@.c d~S"d2WW+K3ّg?e3kU#J)G*~yxm12(q WG /9bMlfKmbA_d"RGp#/_Pf#m1|V3#*<}d D2VWt„u[u\U%O QǘFܾ4qp/>o5QqvI:qÙ]Y]mG{Q|]cq EkOv˅e2fEj[.ȡsѐd |N,>&aɱӽ^ھbܦ{o?f>W [\F '=@'UP 8GNAl*j;Y o*.,˕zrdޏpZ<-lqE%+3ͼ ڽb@-\*~"oGV[1-PR.^4axQQ;'dN,ٹQ5uۮuPMr8JD$nEB>p<wmìPubt0a}?4oW`KOs fЇ@_1#:(nP(Z2+sHtꌞҚ2Cuq`vyCס% `%ALp]Ư#+=2 " \Fj7hb*P"RCq[?JZz|?#@j#~A"}"D"w<\z~urbWjiMNW.0Tt. w,JԴ%t!V/M&H" cY1af:2_tU^&.4eUQƄmEg[Y RZO}4&] V9P%oqy ^^wc*sLZχ80(A$ qD^{s32ʡ_7m@u)ާ;Ec "}bzMe *y/Ò'$h8tOj9ch?94HTo?Q6d)y7"gz KP n0Il{Oh0o={3ϵ]bA7VRjw m=3C X,2`LV@3#8]>WZshɓq^rsiRipTVaLZCT v|H}ծU0*͚ZNTm_ F{*MDF=*W ƢFƭŭA FڬqP,Ae 9Sh%0q'DEgtʲedqDǏg /GA9 3+|a*[sXz>$^d~VXl6f0d.w{Kd f"onD֕F;Pw "7}dL:F'1;<ch\ lO`*Úe#\Ăҩbdi¾nf /ry ]B7gf]+3,)E!SUt& h{PL9Znjj_C O.`9 pjL@:PW^@uWaQiêXUwKEЯ<ܿ M,:BV8.m:It~ߍ闉;jik~[|GO] hi;0gA"}X`0O6PTgG?F}ÿ[u+1IxLIy\4[Fc*l@a32 R;IwWĤƾ&+IXt!FH^xM|WeXp3{Ԛ\h7+(< :V2Vhyڋp]&pxo jVP D HFv" )Ƚi-rx8n2yi@uuv\c]KukKFwnb9pcXi00);WS`N H=k}nM_g)\LӓN ST :Fkb2m^ |"-~_[^ክ^IENDB`imsprog-1.8.5/img/ch347_v1_1_150.png000066400000000000000000000153371520775651600165610ustar00rootroot00000000000000PNG  IHDR ߁PLTEesfgb]o}mdP+{yhVfFT:)q{lSj{_bt}^T?U6f};hipqJz{gdT=2fyy^PDвE\H`ZY^S\]UeeɊzil Nuq{v Ye+,. KK #%UXsȎ?Aaϕit&+t}qlGICJ}{"wlg;)`dgWK:C:JclqaUZ?se]L@tg`57{0hl3=466:qtRVJ1GE'9{P]Wԯ{LN]RRvg*b?a0&,UȋAx{tdpq:G:pFrV@JBQ%6+;*tz\F6.C+2)~S^AiRK3 ~Φ5sngqe1MDn+Ŷ|1 ?A~Y' tֿųph`ywsSl\^P2~L^:iɄǸ̶*|7^\%>>V[NݽvNӐz_aԾYU>8KtRNS JT17"lkIݜ̸g_βў}Ҿ椅ι𺶤CKCIDATxoZuRԸ6vjےƘx+%9 Px)4j$P4i6R㰖Vaj!UʶFkԙUm^t_@//@ |....h~׮]U[LjFwl1{ݹL&j iWܝd2Bjhg!l6n26RJBg9ʹwl,):ݍVm}9c-7tb\-KnOnnܯ?@ ?t직ݶ~S^}C߿ͯϽyiWϾ duA`$jU]w}uw'ûAx1 #6ڰGn=yl)=-4lwCfi7cKX1aKs;QKwݜbD^ DZ=:i\-VFp 'IBE{nlޜ*mJnBIL|U{י_?kHI7G^I/A_\s`?t 0dG'&E W|h"aZn>ڈGh,H2Yf!_℀ Жpܸ9DxAJ(E!@p y(mrm\?x#s΅d:"F,"YZ@) `wk - 8&Ű8SL頬d1&J ۠OuÒ ]m~r.c+@  `FP` LurղH KLJX%ֶH@ʫb籠̚7Si:`vrbè*JjSzXFZ %^W8C:Dy#͚S% 5y![(f"6;H:g&\fb"A2S,>\*ZjZ3n Y1+h ;EQEPzKԴΉݩs$Ӆh$lc&OY,(vJ4c\(N$E1*.z1%QʽPE}o"X)*f͸F"bnx"e`yI`dt쬪]Unw˲ SnJeYҶIy>BI'"Ҁ`HYWu#dFE{eѱ`(9)z(j2T $7hbI h'`XZog}|CY #rбzQah#|8bC)J8-;k/^?" ^ʯ# Q)˦c$ ,`ܶl+.(A,#nR޺羋%[u>"2=vgR4Sl(j}tY$LdaB 7"i )m6#Dszg$sr(\&Hz|j|n0յ |J$C_S70JI(9nb!Lؖ5z>c}]`eU}Pj˥X0!5GJ=qR@B4N(-l2X(VcdJ e*/I"`1]tmԂ=+zd̛#QB%[1P 3t0YQ4ҍN%`b'bQoM=ssMEűݹ}>WtJYpXT.C?GP[ZGD}ƒ\-|fS`,%IqXD#N3`=ś7V˝@&-Oci8WR%WI@%+Cq89{<=V#': C*;@#<8e"(Y fϞXFtbdec2!W; F+o;<}Ӷ.V+BT,Q1 |ܲE`&c8:4o~l6ZaolW߻$dh8c .f&.iZ-*xj=íUUV 0Y0pbF:XtIప#c `lj.0նGzheרj!`H4GKE 5tBAkj]uE.~ݱヽN$d-W v6.;,Ԙ=qNHK!2o8m0X^Y_25PV0fT˲^>;TWBCpbh1)!,`0=<}ʆ}{htاN''^8VqkXmΝ]>*zbqB_!EkC^K;8|o7{NHcHp#ىttuhmkFT*W+VyC-@@g$`]{ۻOZj衃+kཽ޺׿˿:e7iguZT`qI4!%,pcPuO'o^[`+j}~9㥗=9LSvߤ ! gL` No0wWxh1$8ׅz-z7EE FgZSn+vvYi4G6G9XQkszΖ EOoݛ/uۛ?pɔ:mGZGd_lI7ʵ 4fy7yZ՜ F EӗQp o& I3 @(^o F\@yp@FsqH8 =eՈ^K,lC]dTL-=Lb 0l9A^ktn'(e8'0NxS`gts!)#k)詌3ͼ-Z]{::1|\I"1ZJͫ\.dbPF"9:(E;N(ή|պ;";(sn#D'EWpc%&{ ȃp5W^~כnZ)MenH^ v!iD17I(r-U*%HZeO&~(o2]c(AU}(an1‡lnoMs"B|iVsO AHS4Aڙ؏ Q'g>W]hXAY; } W*R 2Nʫ#UNzG& 'I+(?Kv¨Ck!X-o_K{EM+c]<}fT iad-r8& VM gXX&R(k~l9@2SEғz< 3h^ULEmu]˗zRG#ks7$AXAP5?Zz:*e0zɢhIzǍ5݋yaX糹;nۻ7qj]{*J$ѽ C׏oSu+DzR07}km 8TlU!D/$'$9B.6BJhoHjBXsѵvI eƘ[7Wɼ*l>;@rd4q:O*c 4J;Zf#!ڧP[>FO=s x}Vj\a\8Nb_یƳJ̆{g3Zum*KAUܓJT}Vu,audg]1l6}̟Jid0J~tЮ>{HiH.c `h-WqpnHo7ogk޺y`OA@wht`HX$$I Y臚pML8F6y1 WVǮaI!CL ^0tc;j'gC.@1ΞfͲcW=rI& #l-^ 1B\ѩPcE0_f5|VҦ^yhZ9`B\^12@DQGh˜6w>zx,.lKa38K"PT*iY1…3V׊|Yka=cGg(,DZ  FV0 #nNŢm/GTotr6Ef0>˄B<`@\qNY\Oܣa$doBAoaJF b4ՒTq>e<]V.)l{qbyYKȂIRӣxN:О;Ćꕶu`,AD)X /& a&y2+H9Դ>_5Nu"Y/ aQF:qoW]({.|ad#"\fA?0+fQ!?_8uPhp3;+1Pk_CuX,/dd kɍphmwy~%9N(WϞ~hyqfaa9Q9?5ES@gG"Ng<Kޞwk imx&Vت Dwй cso<}ȓ9=Y}s{ ϦD# L`@&QͲ%4=2wnɕ!i# #]G`FL5k*?{fPa?yY-7/W&O"#"3j25YާjZ5UKFqeyD2l%W5AP/F"WC [2z jq/~~*a9s>}dh6܂,/ie oKaTg*jÚi!ZW*?zXO/ sӋ juEж7m?M'!L uYSNN^XJqcۨ` z G`cQ]]eke5_Yacr!YݪQu}`TrNqЛ] ŨLxVsRfLtMcB Db?-2CRpp cDM:Yv< {^'A K癍5 HN9A`;6Ds<57*EOsl.lY {<S8tM3j\RCvYh-4}2&K/dS 0`?JDO1IENDB`imsprog-1.8.5/img/chipEdit64.png000066400000000000000000000053461520775651600164200ustar00rootroot00000000000000PNG  IHDR@@PLTE𗗗򑑐㮮㧧ȱӟ񹹹Πaaa૫栠llleedsssގfffzzzwww·ژ؃qqqooo|||vvv  }mfccb:-\iiizuȉ 뵵J^]]* nK m)Ŀ:j 'lJpYYY5%xfcjU}Q3F(/)%z^ oa٫vm{ciPhK^D=:7O.4.*<*%0'e䅲*Ä8s'cV~|sjv^p[QKGHEB4  2p÷ƾuNtڸӷع`7n☈얈Sow{gi`v_`G*%rm@EtRNS!$7 DY%Ky9/޾grppmd_8 ٳeIDATXÍuPm0Ʀ2A%حw9~;v&3gmX1y|gRbs E+P$_.yi4MMtAe[zLL$45MGP[60P1!/d;Zli;Bh?qC4#m|% Ay"nUjh߆hnJ#x=S`hMbs{5ݾ=3a) .N~ߞW*$āH[ j͟BmjkXB:ƉM 5/CPx0Wѓnc3fW.en {,O>A 2lptEqx,z W/\84b݆O0{Hzvk/rgХv h ΛNuD'"׬lh˗QZi-M'{gǢtxo :zď߿9YRI>YێnHpŎ-[*>[$<%hq#{uh.lWn'jn|DikoWZl󫠽Npb앱^sj_xY9{rn|On;5VVwzyiu)#~{-$%w^T)9i'e3 +D˳ҿ[t ?U`k)$ɠ3!qQjSu ]hyi}. 2Ԃ '@xAGQGB`rGk [`qw i*],QG]{``8̍N^][춸 4΂Eh׉mXl\b"g[ܿss-V@mA;HWB~ Z3/zskf7v:S9s LH W̞~oha:+1j3Gl* ԉû'R "p $8ClM'n8QHЩ[wKخ0.]rbe0tf9I1b$Ri(aH#% *$L 8r2ι|:8:6*xz@R]2LQ.{ i+x8I ׀#ނ%ti uQ^b@S͌"]}$l,vo0PEٜI]IE[?e\3?z~ xAu<.CXMbWwwbC5^{ZeuVΓD6inrA?[m0q+Q<6)$IN2IENDB`imsprog-1.8.5/img/chip_editor_eng.png000066400000000000000000000454361520775651600176430ustar00rootroot00000000000000PNG  IHDRt֨PLTEܓ211׻y@u56=9eU>t`@RD}BKޞ]DEsWh7dɇI͍PP@9n{I@aJ=E_5;JX>di:]U9]?GrɉuhCt3@=N_bp:D`8CtN!:Ct!:{.aeDYt&e'+[f TݐF+qӺdt`@zF죓dtT]#21Ҙ<3x mkL]q<|pa0i1BCm=6_-d.|pwe&$^ӵ{݁IҤ3h\pNRJ!:jEߑk;vH3":6ԒPqtm}%?[}LnQt4>c+p:D`8jFDAt!:{=Dt_;g^mL1Yp՘PitLIfV=*EXly?=z+g_=!d'G >ۨjђ2a߿ðlTb_yxa1|~tŋ?<}"|vՌ]pw7mq#!U;rXePM`vcS%l9$ b0&"CaDwɒ5S`:]GsC'L5Gh,?ܤϐ;\G]d D'Xĵى U*V%ǫy%t󏁎 tvf} :?B͙EaiBɝz#zˋ"T:Qd.7K6sGɉ:5:"T:T+K#VoxkÊRT #I0*ZCёkA{Z[膮~]D,t[.91Us4V"LbOR#[~œ.Jiw1''%ωTǞX~t/nI癃v0!a}Y1{Dno$Nrg՚ofZ"?ܤk6֛+xOUPr,8ص{FJ&!i:MЍkфv: $wrmo=g5M/,kvjEnt t+6'Wz%dg EG>tW\+!{ GKPt4.\5_ tg4*pl+xkr*6L3Cxwal*UQtQ*lRqgJFPM>t;ss3O2Üt7#@ذ:u ܠ'3ۓfK&r<[84)TfyrAѩ.E=l*Ҳn&)%u }87W8linCGS+=Jvz AEQs]-MI  duKc]lArUɲYY:إ[A@:MeR ;mu#9o Dk@yځdDDdDs t?~jDenr$|i,9W.iuL@=RfIG 3؜-'4|CFr:\3o?${A BgX>M`MOFVM6\_oЉg16t9N6Ձv9M#\s~t$O@ޟl;((ABЭ7;>-x'>9"TLڡ^0 DW*m@dYdMy>MSnltjVk\kg:K\&sDn4)o%]txnyQs2 ]-ä;\t-`OEMhpi0ʅd(ʢ&gBW. :YtPt\e20O}?I9'Ʒvi AyO6jQ:}lJq*]ՙr(eL뒈DMwG?CVm-dyO+! 6'Wo֩(:E :_qإ;[`cfxR Cb c0e B|y0 we9( HOR.: T*@G0t t\WqC[#NcqCA ~ȍ }AسgA~8] F_ CEA,EG̅N%{A]+Wv${B=aA\(9zʀG2R1&U^9% ݗR~t/oODcwӝR^v(c-c<֚h!{t^9{1Nw4EWlt ?DrÑtAɅ//5{!ΙTJ\hpȱO^tA͓zF tU3ĵDb\S[^jd2Ĝx8]x<1rb->5~q*^l|^6*n(,optWq}vY!0ǮM!tO4qσLƚ_l6~Q܀$}p:++Y{{{øUctCHG|P}e#Y:N(Cҁ&$, =N<uz"1Fb@E]_}&q8]Bű׋ű׋űn ]_tJ!$DvtKMtL':ȉDӉrDV"ց' /1!^{^k]DDwDŽ^v槉 6B%ME)ZjK%lhX&5 X.XK&" hF=QAD r1_)awL;oyBDhAwѠۋꕮF|r^Nnj6B{4CV2ǣS=Prz^NoA{ElK~ʓ\OD@j]{y3PoGjN:AG*iFjBh*sކ?ٓ֠ӠSi?gJ..hgN$=NRkZt2HӍ+>\%vyBbirہ Z ߐ\V>Y{"c9.IPqqw`ZCPVW;x tS.DwݘEneF@;#8JW6L M0gH'i fɠˮAAB] 2frw?{.@ bl#޸ wrXВ&Ҽ?wq\Y -Dm2lm.CnUZ t#[7tWH%f ݲևQ+ç[|7t%}ϑStt- LaNv[xI@pJCZY肖fHsdžM n*pK@3>O"tAcU.8n;n6"k*K(zY䊷a32 _J6e54ʴ&yýtFW\|©Nآf 8:h@Gl$ q5|N ctYCЍ,*ؕVA*4]dmFtlL֛Opw6 r2tw IO#tX_| B5GԜS] icYn1iyrUHqQtDtU,$?jB2NCiK'Wtx=P/t(H>=Jnwzg9]4rTUc@UcU:̆!SP/Iaj1TLb.Ī}O\tuVyV Cx@]9h H ѩN jmG?%mmV|͝ee${!b3 Pّ$c f%Pl1 fxp]=U[ MkaEMrz7tژ jcڇ]DEUEK^x]#l"E,.vѽFcBq#;Me;(ut~ѷWĮdSG%yj'-N a$*}g6loe]- }WMZD c`UY"@Lb^rf.Ī}f F^-Tʏ"p;#̸ :$.t t3'0^aM%@xMS`AD:zNM,H]Ё +wzC݋a-SXyMC"'s!R3t~!R`EŖ+?Tuƨ5tw AJÝLlg=J 3Å4vcrYNIڨ@-^Q IBG"}xźr ~\,@܇-SXyMB̅P7tl,<+]v:d- _V@A<.[c<䎠-*D:eKgXW tV[:65EyU:c N㜋kMgGو9(@BŠ;i+tx~1ҥw$DE8͛vfn5μ=ӫtL9n34+-foz*?&V^9lb BVױs!R3tpOW3Aw˲Y@-X^ .ZVX6fJj!J&,cSV61֟lI&m?{;v:lus;=sΝ{?s= l` xȋ|({UA7wC\)͛ /s1[#$7Z g(5V%槗nx/Cxtx/:~?M^8r|bGms"*v?8 )ъ+Y}ʬ[AVl{/ҧSB?BM[{P2+Ε QB׌w*ysm,jB7nYsUIExɥ^+t|Ҕt[nLTAQo3͎u! X-215:7ԍ؅yuSjԗ+tP#}.cBGڟ'!kf-.}5.{`Οat_zoĆ3Ds\NDǃF/Yj3AG&(?tkS~l# &?*%l#04pQnVWAZSJٌkP?ANOm:w k YlЕ]x zlXl0 |xk[˫WCCNf h4hZ(\&g#N& hPmvB+`6 8r{) еvy9JttTH?4pFHfEKtCd2t_{(X}!vm1].X\MHa rtcWAZ1ĔY=WCCBaÈXD)YĻ~Ք?28CCU]pQ.%2Dt:tACB.ѡHᆓs \]"Nh.cU;gqG{ –TX Dm.?0ls23|NӎƟp@}5/I\ Oo5HϖgCV$2K\2L^Ecy gnWo#X[&j(!܉޼V6@BOjP2ZN8&t/Y2)X&ǎnd ‬H?[5 r0jjpA7BN?6Bʋ# H!!&B(Z4dG ꥞=0kDts;s:,oBE0tmYq}vYH9l`Մ+(V} t FhE).J2Z2B "y55=ן3`Ri,W8l(/Otٕ'\J(v@;S+vס,L, hReUH 'bt[ 8tHZ;O<8OtO%Aw7sD JǑ^uN taN^2"tfFL#f/q A"71E_Ѝ/ :-ɮ0dХM.QՋave`Nw).7:td AVlK:.Ȁ7[r\/,_U#_`d%ԊmTo)I(CGUP#3*/B(CG<\+i]Ƞ 1ղt#,:D9INu /Q-gaiqp~iH?kMN|7AP0R^;+^*?dtE2:E^;U+M8m̑Hz5KPJ t :SxiȺHk3!s݆Q0$[PG.97Q`nHJŕŐ<8⎾۲xKP*{/PotE%t:UԘ[mEOliQPMe۸x[^{caK%{i4Yr̆bfkt4pȃ_zRKu ^M$L`ސ6)&P?t]"#[$M. }^N#-Rhj91vSZlT U.A JSCY (j4CH BxWnK':СC u~{:}윽JAF , $ RH'XQ%1l4M\;5 ^&?s2tAUuNo[YeB?a+u):;,t@t;耮Bԍsz:::|t0t(NoSM*P-Oy3<)\- >ORvgRjA|bNieiȹvwDs(<|PT9Z#KKuBz~#q|E- >/>1sB >3Rm[a4D+jQy)=HL*P-/X̓nJaO7EOE߶Pm7ks߬?;qm|E- >/2; /'T Jؽ,ɹJ)Z|~ d$|f/O2o~=4)\- >?_qHgRj|skkl +R\/WCPбuc:;耮Bԍsz >BPa{:St@t@tnl[g]СC0Cuz0 7;*Sp*b8 #M#$v(r2 Rͦ$n)r'. 9}%Pnw1<﬷}Y7Yef5!ʳ뷝4FyiϳuEAA9}Y= +*q'q0gҞg|)} ໹լ [P<[~ٸԃs_e'm|I[ B}\ DsDJ/[γu̿A=>>]К(Zuٺ[]#Ň-օ &ܸ{sAA9oةcw|Ͷ<[&x?@=>T}& #OAn:oDGtDGtDRo AX|阰}#:S=AtDGtDGt],uyx :#: еAi=uN5Gd*wMK~2A̴kוFV||BXng.~{.! v||wΉ+"q%!> |F oc. 77 Od+>>G9>Ă5otL>ѩ :#:#.}Y4ײ9/v\1wdudm|Z'|Yޟt{^9 х ~t@ۿ}Ψg@~FurADM/?+ :/w[p /_#\;e:P\s]ϵ%C) ۺ(х k\)_`*_ hLg[,7峏f$::/2yj&lH^"neK򘋣$wOb|>9& MɺtĽ{J޽EɛWM_w @OXڏ wF</_3:91O>'q%!&LεރKw/!z`7R tNO/X9AtDGtDGt],uyx뜰Ǚ g:#:DGtDGtDRo #:#ލN'tI[N"5a(Gt& GU"pbE1F-{\{$*XX^LA_1Fggv,dQ]4D3;l >|%"z$\dҼr@8gƻ09K'mß@_Hz,P"e]k3*4o(̫-+*N'^tRIg?7GVUԯQF`qΥS"dm+*M9K'm04ABPlP5|T >\dbQrԖ|Cӝm#׏`.t(C]*.2R%Ԗ|9Jm|#o1(G zZ|%S"+倝|9K'Qbnzgݧ7%EOQukԳt >\dbQ8|4]Jy6OD(گ@]k+Xm+X{/{'|G ߑR >yV8"#9LABCKC?c:Sre43+88()tN:tC1t CʦٽiftuйȕM{(79#W6M3ܠCGlݛfQ]I(+ p"O m}v>ORw^}l2'X}jn}Ea5􋉠@P7@" +71'.Xąo;zm[B)E T`"|] C2еxhth4On cSjݩ*^ t-ntZ~r2lֳHkDL? {Z5p"섺 p5o҆} F=خƀ-m[B%U /{)޿9l+Vpadx9Os ^#ۄIx۝S`Nx_+6bNp}Й׈;4 2艢=CY4oXiC95k [uĖAIg&S I/BǃHgO:uA9%biM8{vU|d)t"*u4BPL3W"#~jl :yv hAϐP7?`R7PiTa+܏O#-a%ϪM*r --|] Gzx fÈ8́>cʆɪ:VGrD!# ݄1Ddmg56@*μFtލ7׆ZS7?VP_ ʤ1 nm7WGl +t|mDPfǟ& BL >U| }U } j-9st9))}:8 {}p4-6~D-xδFtށuF:4YҨzCSאZP^pdV2)@PQ;֤SN]M̽d#,Yx_U},J tuVP\J^(w>QN=M;zV;qc/SGl |mQ7Cl`#,t۷tQ|ʁc q밤JJ[8ݞ1k =[z|L Pץ5;l8{%st7Yzó//իU _N٪# J >6AE3ַ͙{ 4W}{u,:DG|23:d/ JuFw\a^#:2 pq}hAnxSN+Ui1q@vWGl |mЁ/qKu|g*;R\4;RԠ[U_ ctH1t Cǻ re43:c: W6M3ÉбVHW(ȕMsLđcHg0t C1t AlݛfC1t Cʦٽif0t CL i }w?R5y3p._lj 5f_+j j{yΛ9g).Z2f.%_g ,16dٽ^V𕿂E+.u% lLI!R.[bE`_+8LKvʋрٖCYW >|kބv9Nwޠ5Qmqq?mot}|(R ;Z h _`j|e(R'sOi)6aN8-6|Pairg;^:LׯcQRiOݿ㾰. wm^7|`qϫ{Ô|-D֫5p|9.\4Qnw`ivo+:w/U\47 c:N!ȕM{p"t< reShf8qc: C1t B+f1t C)ivo C1tع0V]c4d0=FwĒ0mKLr}K K.#\0Gq.3iDU~MgwK5\rO-#‹>g~_4 >S۝ OQOEg'v|$Y99w@3;u>?%@A5B4L||Ջrs/N@3w! |: |_N}${{QK&g>lm$>7 y_2/(xfP4h|&<ޞ7 VW.Ok>郭@3K^%/8*O /vEȔV|5I_郭@3E5 'Tԝ2/(ˌ<20w{VlM߱ x | 't"O[7ˍnv= /H^#ɜtQ"nm[tQ-sAǝ t҉tQ:J!֖yeNP:JG(qk<2'(t.[z[Fe>&t]S%5+ NT?Y| |{]PZFo?vYutm =q/ā+e_zuS\-utdH Ԓ  JϏ|^/-- ֥; &>lA%@ <&2/9YQҵ !%_.}YZe|CblMxj /vB)ZE~p)(ot-ٻNmd|AO}{2r./=>>]WS:ovކ"P{p7__onOe^(tNZMww͸-||#exMX>J'sbؗQ:^^FeoQ:JG"D2 KGw:&Q:J'zQ:JG(][[9A(t.Bĭ-x˜tQ>í |J[V>,&˼^&#||U}oZCuݻI"&}ӵ\4N!AO;7" fVId|Ω|;_ߪ3 qFd|JhM9s| |+\c KRղ=-|r '+ֻng-.]p3-o$|U >3Ao(!CiP:Bt#CJGHR?f#~(!JGHP:B=YO\#D|~*垿2kcD!?;0LƱn0"wn6GHQۑ %:ʨXɆKr7 # !Re7Jy{QK'_8xL?X| VlSڳIMn"xMva$٧_!JC^S\?֜s!H5 ?MGLeSc=GH Ы&t(x0K~^>-vΰk*!;2 x8Y,,R]gei,BLUtjAǡ[jA^DG)$P!m]ˎ/I8(}%-634kQ UN6)2vtB>YM.|$S\wGHNFZy/vA\STi,OI#e'?\ڳ8 ,9{.8G!BH.;K8μ#fſ%M>旅>Wa; WC1KPUKy`%>b N +3WADȝDmwLHhtጛؠӼo'9h_H 9KZz+]L̄a:%.{!3/cP$7PtE:-B8tIJiuQz) p^#c(?.HFkqa%rG|e:_Ei*5x+=US>{}aS8tzy:izΨRը@-sL6xĶN tMV`Fӓ0-9|8tqE`£#ۻ0LVp38t)Nf kq:ލ(pG ,`"Fp]73˞}RC'IXFt=BEYEYAqO/v]Щ۠+ewi8sAQ <qb1>udbd V>p '2Й^‚帺Q:},z"F w6NAF:,; "[W:}JqftB@}Ly|JSwB+ݦ*.a;8@ǣ:|`JgR||C/<3c}{vskk89uk`+%b~7@0nwRh ξͩ:˸2˱ѩR8ct/I p棣dӽ$ô(q /Kp~t_AS @ u=0;*u8tNײBV{SʠJ}ڵ}>vs0Kei|}:mBzc3^Qg: 턎BWx|n]FwA:Lʜٽ4]tzso"U6Z)^L@>h1I{]†]/+Cc(ZnB}RT 6WtkQ[sik0C^{Kee $oI@'$tBBtBBT:!!?'NHH(SJIENDB`imsprog-1.8.5/img/compare_files_en.png000066400000000000000000002655611520775651600200160ustar00rootroot00000000000000PNG  IHDR^.DPLTEnnnǛҵǰyxxɑ`QNNDBB૫jbf𼿁Hcmkmbyrst`^`S99;C_˽YEXbpnbw^W`eew_NF/9׶Qey\\nVU,!#Vp⿖~QӨ|˦i81N%f`dk"ưIrFGMϝojMܲ}TMָoLPcZWYY&%ʓtLɰZ-Eiqmm3-AbZ`nzhkr-M~Wzތg{E4㴸dB~VyI1[ú֛aNXu@6OkpηɅɹǖCNt7=G|ع7]͜sכ|×V7*,xm(:ppFs|σ5ϴt=a͉踑m^ß.5Sۙ@jHXdMDOzĽbRmȹO0ErA5Y<'WfF6[@}زsuwh|wkߕʽ]lf@e0ƙѤ׎yݦdq*$0]AഋtRNS/w0ghghIDATx웻@JňxH~*!*TH~wU(\h!kPrdͲler>-#O' )Ǔ w͕ wO2;%$ ¿y𐉉IDAoc2Mb )gZLLz:? ҄WքOl6fE80l1m:uUSS-F5Q_+8%' E )@ӱ&:v/׶nESk嶙bګC@ucCWgJ.ޭ*FmӟqY&hQl0ڲbn:VXso{vj;X&UTX‘;7qiқ?A#M$T&~97)ެ< E9R&4X8̖eh\Cdq7KHإMja$8 3T֙1nɣw'V,M+_Ly[V-Ĝ!&&Vi.d)fc1ˠ}Hqg:9ݨPe,N3Cf`omMŢ|?a'F:ѐ뫈(%cpĮZ7<\ѣZ؇n9F)VDj$*Ʌylf4gu.;ęCab!dc)'WAAaBH ,o&tjkѱV `&Qڰlbr}Yz縘vAv"D|3$ 8MMDhKx(av0qn&3LdŦFLe [SļGkS0'մa:;UDM¯yzhPj mAESLd-1ĸkQaa"18s&,96ܙΡ1ZgM#,_r&]`ᨆyvdqņ8Ƙ)e7zo!D2מlHo gL'i│sGRq*rfv>;NZnq9 ‰MS͢۹]2hC*B9p֢6bF0MWKh)"xr!d4^B ys_|!+j%/"/X%"GD^@X"BzD"+KDH71֡&9~l B|BěHļ G ]hIǝ:! H{^,1/,{[k{* Mk\?^}_(j:M|UR"PmOk:%Q`6 &Ȃ*%[hZmԭL[ lYwL홯_Qԝ؀?zuQK|՛DC,,OՏa1b㽾q`M @[s( \j[RֿE $`\#fg͉ZD+q9qbbNLv]59s@mĂg5$x:9X"EeˍZ׉WXo旬pa:q*\}Ϥ\׮ZW-s+RlZ%nɨLR  7qUJ`DZv)LQ)hn3VBe+&lJ?Ys3$JĬ̝UJ1'V&f?Č9i7e?7ayڐXmъsnb&ytm۰L-dj r-l-6'~n9ӝiu:]mGŕ*v*jNt~zx"=iw$Dz.-8u"/~ S"}ϰM$e06˧8q8,-J7Q>e"-QpK9ħΙ̧.s}<ʧB=]y4&im\&ҞaH2⨈69GnٶPRUTtΪ|s2'͘hZXfl45&ΠV"O_26aZoP*i%R>Kc*ާ=lHT_^G)y%4>ZGY8n#hCM fGp"8cSV"M}q>iVm^41~2znv?VdeĒ>"OZ>9 9g}% |jچs,Yc"g@uSrǽlK|&Of,yЈvԆz{{ b#؋[c#;?DM`\61ׂ 6Q;6%s}L}HC` LYZ8"8\yctO8+]whqk>)e=?R6 wTrn&+#)ӔI|y7OF<֧3>/ˢBqKJcW^a!hӛ|&:&|V9H)m53E6S*JOYٴ0V7k8z+= M=F07Vk( }]~cIK܁pb~ƒOO !sݦǍ EqW׶\W=Է-#eCԧ7m CyZ#gӌBf O38ySd-H 4O3f eO3 4#fLiR<@*'!z30*|&.)%gd.
}[9%9SO&=A)>>D6 < c]g .=Pcs]yNwω#Ğ@ X+s/ql$u ЙDsbݩc}7}8|f߼5Bzu!lz^m.ʻo۶yݩpψqZ+{mbu3s*:9s bs3D1H\`Tmc,5ErpZtPُ̙ p61gUkTN9+*ɛK+`."4l3 .ö}~ܡ6i]>}6$YHRiD8>NO+ӐzќZ%rv&}{䲧b2#1 k$b`$ )&Qzdi:CLE)wQӠ0կn¶Qf~JhcHc4 A Ippx\0nxA >9sò@,ŒȊWrpO[T3kTL$§-U TK 7"H+ rE`AKQ@m)TųjUԏJ*]vgԆ=,0/M&72)dQVS25īFeXBJߋj#TB%R 9.rJTio HǢGNSVXT&>c !#I70>q̉k"ohwVrCR"!+QCN5{5]cOm7^oj%+qj8*7_NOyT:ņ͊1y{'*VUUE);((3tX:u I]w$|آ˱g`USPE0+Ip&F==+f?y؋=Oc- U3WRj Q=p ==KcjOo7==s8AXȗ3\sr.9Gz9Jjmrm9Z̲bLMa~\D)(Wvj65Ef>M `Gd0 /2mORCEMMM!cͦByP83φyǑr( SۯipYUU[fUUm/e}8Vm߫/::zaxNlkjwUF4B]r# ֘N(qUUsfKV2|뫪٫'ս1/\TU;kʱcFTm|T"\ +76YN+g*sqtMWt%FW*~f@T?"3'T^N1K'yb$'b!CIPGS%\24; yU`%r : Bqn|.O0}nk>Uƒ\Ǫx9B@UeGE$&>ʱr0N\ѴƎ]z ݡ2"Zjw| 83ybG ׃̾MQ& 0 z}pdךwLx295߱/6΄e4.g% 96X;'5"n[6h(}-Yk]WSO~?R6c/=qpY:5Uɯ?\*wv֦ٻe+|=.vFHXy\MfΈt}ڝ %|]%#d(1͜P6|btsê)w)pX\IDFV `vO1G?h`< Mx75 *%SbQ0'~ɵӣ9{Uk ? C ^yEW'f.>?'Ĩ#¹G UW{4̐/{%?OޕwIKԝ%U+ᮁ.C3(QB||NU**'Toi&f7q}>qmy-Dsóp>8fN -aGN_N|& uNs4sF5lٗ+_{Ҹ~&a4궴M=}:QYOQnS8_w'J*`k%|9&tot?S}&$Xajs89TzVI|+Djq(No8PT e}WmQ**?LQ>cu!V.8uρN[@(k̎T ?,b-\O]^r:R<YIrrՖ4v4q^Je]wΈsEfpz%Z3;b3nX GH*arѡWl RJTgYT nDgr(Pә`.:R8)(9$J,?~s5T3J\~oe?(\x{+tYrUҙ>%(1Y`!^?$J,iJ<'(˞u]e;6wVzUiL+r J;ÚUs_ԋ+(nсM\%|aG.惕MKBx(" )Jܳ8a+f%VʉV=py)$c#/2Eb' zq\WQLJQs\*$ic "{΃QaF%z|FbU7P"BYr;KV- J,빃J 5a[^cUbSoEP"I-eBDŚdgDVzS?ltS@+QCIZJ$\vBl9 W!Q4ϯ LyL23Ndj:L`gl,N&>_m#v!PSVX+}Lбy{K+oվBz9[-=ZƤwZ8D\%bПAo&=+_k6sEv|%؛1֞uGW;Bɱ٫J+m.D53g4\=YvBhؾo:݄C|tNeJ^nOpI@bD) A^eSq gWe: bE ­JDh#V(m5p%Eΰ6(~ʔPR(ovUf:j}Npyds<}zr+T:\XT᭰" GrP)OoyWbd8NvSXXmz{ʢ:RJDT1;8lB u<, &`v?t Nٙk>%;?s6 9ˁ`]pc3t~kWQZ{5>ʜWkE 0BxZ8U;grPaQ3Ff9g55UT -*Q/2 -}s$[$/+.Ƈ:. Q">6gOק3 )>zП=/ufEF\+S){T~lh~ܘ;N#!SGTg #W"yFԋDT\rXHLϭ2So<7*PmN%kἯ%JTBrKd'7DN ;&9A1 t&79>o$m7#J|ma&IX|,8D?&* ȳZ1)PJ҆3ct$UE:Ӓje#Jk1H%G%@`3:BpD9NLs*o݃'[ea{g6)*\~6^fbg9"^i:nŲ>X< "7cCV7+hּ`6̙DϜ93Ja'5SCg(kJB5Z} 7dgkU|ԈUJP=5:H2~C6J֙tff@ -irACji*4@=$Wށ3lغUV0wE+iVBuk&9b]jI(kF(emDnϨ*Syկȳx>TO{9ρJȍA6mir5'ϐi6oy&D޶lSlUVwZi~}%cҳg_ =.Ŕ3V]E?grylݼ cgKͩ//b&n-2Ns@t04&N%`fhjn\0\c<+d;.|PZSs\YYSssA&k5\ahhaW]罣ZKآWS[֙;P X?2YZ緢r^Nʃ<Í1D$GQQsrWmBsƻ(./}2\9 qo}<Ĩ5ykK"to?>/BVb.M` c֛m8wq hN{[6 ׉>߬V[scO#Yyf!2.Tmd9YMPȰuzpMLkCܔOQansa5mfAka-jHh3[!cl٬ 烮ƟB^Ilfa_$h"Ggze@'ydY_^uU RIG+$a⼔+W+ SQQ`8}a]GrzKk KȺϦkKq=^ EysON]%X{֯m8bJa_ BNt:>јO'C'ڏ;uB#oA$)iOm֪>z}>>%UV Q"V5x>Fy^hHO `h=dқAF\J._Pv8Ņd]:3;._Pt,HQj e 9f". 9VкCGr˗te wF$^mq>WTH_xN{m<(DC[Τ81ljIA1 F$6q"F #JD+;"AkFp{xNP ص5PIq"B[DC0iخ^> /<ns;NL]B ~ԏ'i\%GIќ-aD'.%W{H?k2k[߰7<]+?B%i;w3m[ޛ5:frKeJ)%Z)zڗK1z~ޯUS*!# `7e QE]FEzm/IU΄\:(CU"R= `>-4?ZqO3jT=*OUq-@GG,MBb6%ۄ0(ڲ E{jV tI冋g4GyɢWΤzj0~}ZV4j1Rlۍ$( C*O6Ն?cWAiģ_V%ߩ,FNJT$C҇C,<_ٻҰ(,VL݃- h,ðȢ AqA"1d +BLd\"Ѹ *$~:ƐLL~͹UTjhьwyT׫Szۣ# ʹ"7G}3{}huۿkV:ϡJ2&ц򏌜[t5a"E-mrL4&j+#!w^^&r _C&|ׂS EhIf_/DtkVY* ~ξ+Ī#2L*OX X0S4\TUj317Iv~z B KQ3 L`_Drf2S=\~sU4Y8IBE&R_rÕp?$6dBa,)^( 5)d $p|yiew$9 X4AʧNj)"jfKh wz,E+<,Bdp"&u\"C|oR1+q.G#wmll6LH7MfN"JྠXobNhGV׹0Q@%")\DrP- X)6ŝ}]u849bS6GxX`ɻcTΡcŶoŠ& `rBOl8ILny72R3=\0k[jN%OfMXk%LD$Q}X{&?s1qbgj껻D$>l(7Ӭ0< GS]R&ĵ tk8fgNLӖ}d'hx74@doԇM 3&bf̧5X 3~Y}TR !/_-7c>#4,0*csdwuOQX'dn>6<*_r 1+O11 'hkm#~&2Qn MnyTw"弞 Y ,ɘ)Rx9|׊k^.hbiB#׊x*^t?" \[1OsP"$L=t,]߈w1}-!tsij:[ȋETp]S^~B޽];ywjd@1lvͅ*LC0Dh8|>KALTPF D? &:x'77p uk)p^m<rHϭ3f/,|?E& kSr?n2&}07cfУzaCGR}HO%Zkskdb01ѧ#$&:Jӑ<%L&^ni$&*D<뤥"]=Ke^;<'vV) 92ZK3.Y>&&f#<88Бcb@uNs.d)&gNsjAsˆD 'i=Mf%9(^V>"~G&Bx*av?郙D^igEBe;ԕ} U446sԄYX}b&ǎr[`"eAG^)dҿt錟%ŗOM6S'"s㣛ו HcϦGGEF>{1gwXea]' *e"&ۚU JwY&$*>:qً\'Q!e) tpz|_Kפ 7 "}9D}⌼3 wf˯o(Z|7 k3,t=ϗE*JYqŸF?JCdbs\+T, ݫU\X#1X&2. OiC9[A| Vxė̐ QNЮr{DEvv *BLϧWF=ٍt?+(}n{})gHВ&ѷ0Ayqȹ{o|;h g7#N"27ljYts[ٖ"kڜtq]Y`8'NvG#l>mh]2;M~yGd.[V3jh("]8)]X| aēݥO4:u*-zȞQ= Pmճǥmb$ 8M?Z|U߰UU3֊'T5)Z+Z+.mihʩk'RcD[! r6o+~c] ?Dr^^.bqध@V9-`Wl% uFCjwL$T AKClʆҐ A^6`FG@@ȖR~TbA9U&|֗kգu+ɪ/ɬ䭶wUDuUJMts(qg_VuT]u>o_µo_4KVʀaD>|NjP G`bS*_4AaҔ0fnk3##HLZɬh^o7BER1"GLĕedž]K% + eKֽܹ=pqf=WS*NiLtU{3|Nu(|DfzJY\e>?ɵW'!d/9L9W3vBdfELq`V+iմSf\`D 0QPEiv&^&rJ]9ūD>K(3Ŗ?"-K*ʧ1eא5 Pm Y"ײ1QΟ\꜉E1b rhQEe3!'c"N(ۆfA@l%mmfd\*: Sڨ0ɶ3a/vŦĘY[3'RƨٛllN&68 j(Tv 8Pznݜv \Pd%8I^1l*I|lN3j?,\_&*|NLQa6.!Iuц.CΚ!'脧dL(\4\ Ʉ&sȱ#lo< 9GY !.2-.?%(Ay }ilM~&Rdӑص924o#Gba2GWO;&!ȑl;cWY~@ep[V ]Z~;juvH:7bZ:!d'g{Nn+}?l^9p6աjcFRtR9Qm󑄈j,i:r6,6h"F_P澹-@z$<9&lfyS@lpI!1R>W}$L1rd :1kAPHuL8d 3<''}}g'"ydb* W I&!'^<F@2ޠcmNRs:U%Ɵ{ֹɼXrS@ޔrqgHĕ㚌U|[,x̻3ƨv_V@ xfZ;yc]b}e'E[;$fXKk;;WyM<_̺1ZaߊO6Z -2p[#_Oo-+l$s4jPgY۔x6fy bLT!tA1Wtv \JzUVirE GnjZ\fI'7'z/{4z/7MA'o7{< #_oo判AwOb#vZMގ3 ÄGSZx7@wafeS{o'ZGVMfx$s=cI-LW?nB}<,7dUSʅ!¦LC. Wx{;ua"ܾ!%p;~3O e]+bKgu1y<sk/ 8\y7ӗ\꜉qˠJc(h6-*T4![\0"AuTg>NmA^UiYo9B̰;E{ MoϘƔ_==no]uJ,ӻ%)'~ݲ,睵'd;=*eL4ϟ/y༊38"RCc'騊"T(k[ -em[qqemK!2qOw,Q! ̧Pֺ־QJ_ ~%Ấ±'c"Cׯpj 6w2X/}ȁ**xQY^i ]r\=K\M?~taYUU\Ϯ?]ecq^bb W߉Ǵr4h0AE@qrG>Q}8I~R/I6-NU쏥n & ΞȘx cWlȘX6d9<yCprvgu~Aåsgp\!g1&SNG&RkȐ Oü8]J]~cb<0 1_i&Ğ<*͸!X=81d[g(/mdLr~D Yģ:>nPԬ^ﰢ-zF.mkUy %:SUD[7d=l"hMqp PL$˗^< )C$YFc1k3:o5m2vV0&vAD >U=V_@",(i}b:N q%3B=hL m]7^%YtvҐI Ţg}Tڲy3ׯrs&BPu&NDX癈Q :| {r ) "J E*@D)Bި{}'k*( ,M<&ṓPxE\3u:a#Lw"ۣ9hbOD)Y{YLWy^& Y)#ʢPg,Fxڽavj02cD)l &^R^T5qQĦx̨9r%s&ZSYY_DA|S+6WD뜉Go$nEwD>/ȉ n1 Y %|~"A^>".vV? {9/FGCtxmx>#!ʢ?r1;g"vDϚedx8@s 9 GE+< Ru`b)2c"y]ef%VdVDEBVYqnnnJ2-fX/0NU`I'NL[_'NK!ė O~FB;rh ȡ_ȉb9 'ۆBU&ދoNV:^N E1oȴ~t8_A:2F)L"r(\ʿv|ek1zȞSYv&7uӞ-ﯺHauabOxL:rqvfD/ߴxN_r(W}gLԽjgNIVubbOxK}&jEw?uOa.WX7&v^u&L񆉯:{W[A;>(7(QT)J0c5Vg1QPϟ$+B9مr¬bՉ }6rK4 3:"TOg"9VSW`=r̪@0+/}E>?`ɯXHm슒N=( TKn0gg=qJ}$)"aVGv߇ZO0+5>Ǭv1UP5K.lJqC#/cQGL/Fh,jyM-hoGƎZ}չn|GԵV.'Ada οxrw&SE ޥ0% ;.n:tD0 ZS*c en7XqI^"OĉBOt|W"b(tCy@&D! PC ϣ;"ҭp$C5A@S5" m …t_s?*:+p{jzA.+M<ݸf78a-xBJB!-hxʛ'F࢔].joӨ5ot̟C2q2u w5wxNp522JMp`dtHYhmmY邖_[[@6ܻ1t#B%7J"N/o9> KˍX-2A.'ҹ'|^^q1ph,ttOf =(Cw)h{Uӌ%i>֔mEd+4+`Ԯfݯ1}ka {k멛Y5Lr+Eށ|WX2؆J!EosIj<&sT `e0Q98I?(v[9&J&BNx&&zp_' Ls<^Z`Կ"z g! D;+oz ǽGvx6Ndݘ# k]2!V`b~'@5AT؄kۨO4:i[';50w),02j3ݭ?r-Fх<)Yip>t]g"r6+ >,}ǧ_K<>2fkJv.٩B\d4{t{xt|O11U'?:I5Z p8 iM畠ZppʫT5,>Bx0H%2qSgS:kC^cD#A(X.7}xGbd LįLeQ\|l$'IFbdz0!OZ:4qq']҅@%p_h~ˆ ]}ҹ`xps(Գ i.T 5qQS5uLB%\F>XxOY18+ L<&9XyA _.LQm_o2R}QΒw Z㛘NҜ1η.ZA)HO;q*Ԍpx IQ=| 2 qg3}8hx2&EL$[Y>ў'ǥ * A 73m/3qCb3}hN |)#)R̘k&ӳMfVO^C)?xv(׮pY<ݑfBY<| 8'< SDt/r8.MLz6g(6CZ'-eLq{CewYD8ˊZkk_~=tf2 x}7'f9/OLC6滏dM#{&|?+^8zp3@6C$_I;Lߡ>㊉ͬ蚬 l x%@f= 'FQ+8'E[ T~QٳDLL#'~ 'xg Ǟd8&\gbx♘Mȍ9׳x2*ɞeD!X3)<͞KO?jCb45MymcDd@!frHT5/9mtGk &6q֕a蕖1['ub H#TxპoRbf Hx}SgĕL<ΦLe߈ON8:1['Jf;5fef>­^YcX։ΝYo9 fJX'ZI׉։Dz5;Eo`3&IubSiTu"J։ĹN&p.!̘yrT)Լ).dhέ&=)c)*N5d)3k)'gL OQφ489fxU' {ʺi}BG}>:fkHwjJUdȀ; :ހ=a ԏng"r]m»6Ju}8sޛ%gDj &!W>q1T`M Nȵ9w!mL<&25#rNHtu$N !#vMfZ3\\wȅN@Bsvޝz{::1E/VN ?: 8k #=OeaݗAɘO1WZĬab cL<&0J?21[Ds|db &Ү6iWʧ8րvh?Q]zd^'FOxFx}upfMٮn`vΜBPtDdãr r͖0ގ' Y'LL A}i?1]RΦ $^m| &>663xN-;Vwz#MЍ>6tDvc.~>6FL|MJ*b\VԨXyqVvo"%"Ǫnw:;%'gOėtx$xi`%(;=y~NqMnTWÔZ+y$B_ۊkZj!9=ҿ6KGjʗ ~mt܃j S&ܜREI2<4=7(8)bs1Y۠2ú)O*0GX&;nN< V}a]9_zk(;/~duPh;-%2mypI̙Z$g~E9 *'"F\Sͱg!Z&Q&(3:T#LůݓZx&7& F Ngi_9B+%9~}l| <-O[xn<5ĥnV䶰͊!pMs^p0n7ߍKqI-_2ofEQnZL>̪X[!Tpa~Ď1Hf לsY򱡈,Rm&p҇Yᚹ-v;`eQdodP3,0*&:nTbYBwTjE^-IV]hFP xb>v1K(: ,1%s]5D p]\IȻZ.Xݠ-G\i m'i)11SEm'UH Y"ܗo?J8*+ LV;sUdv8U(Qp(vg-8h+JbrU ˴_T+BQ"8 ~șmTQ^PElk\O#UT #Wf 55CM R+fTNhb!7Zo!)ü72`E3<fƫMLE&V1Ut0G9U񲭤_ "B̅>ѣi1L};"81L6_dt MQ6i)u7O<4RwϱӂCEIf{MkEWN9统hL4%vx")!Et]L#+['6V1vLĜ#L<|L^^nPmE徛{%c"(,ܶ(г8Ң􉰺cX*0QOtCUb|{hZSU!='NW> "+[NO{o'Cn3G?1n'C~>No."GZt~1u_:O*'c"\Ppھlgy`6&ͩo`'~TϺ]%+óFēI2j21=L4`h\L YzZՆxer /1sϷ2桸W |ߙMH2oVEQw&MjQ2M3<5brK뢡!9lI2QMVײA=CISBNcvx$xl\ObOS lxvG}?B\e;FV s[2YjBy,>1TPa"[9D YdڧNr2F,J$ƪ ˪h sUh Qm^r X| R/׉L‡M&ENu2\'QY e)᳏ x`KBɘIA՜.5W5߬b]Dz.^\`qYo71?6hM1cs o< xRDʳC_sx:`i]~X5\DՃs!xubv<7vgߝ!us=3<|*{e4FVq=CBnƻӶ˯ɼ3Nf3FJiFucdǷQ\xK?'u|2 ^wҁQ }w.11vvIg:&;bQo@M_oc%Hx楖GG7O)OmT%^uZ] KU;<$$JkL Y+>?aσ+Ӡlu_h@U=zU'+1 (\G!b[5O\ 1I#O®l9J[X#ocϢIxp,Qu'xvVY]6g6Z"%Κ1AF8 ͺ("g9@M F##d[9bQQ&0 TrZ[q-5T%@93<Pp|SJ7FL|3Qۂ*Z?і):^7L|v1v1TxqQh 0m/7ʖ6"vy|U|A'jf\Ұ~uF=Ŝyr\sàjFVƺz X:8vMkM6gbӣj88080kِ18c6T,1#ېmw10dnpz!(i}.vC(q?rS09(a/-Y_BĔ?.^Ӑל!mБJb&ڏiMFvn$_e4MKυa>򞂄"6ꇹFRF:ELsӴw^r#])a蝒" dfOi'Yt ~ pU*7|FPn}vulg.AipLfW#B '>Gg(gg 3N|Ϯa64WK u|fv2:W>X pQh.K x],@aH JQQ+I*_KXpOx>9QG/ݚԫ`"U=(WEɳ6 nwd%<_DN#7.:l7ml0>d>Ϙg"UQCa* Y d?vV5{;>'Y\+ p#D2̹ KsF)1U2pU𙪚OO(;)LHlwL9M>t"1ѥZ匹:Wlcc'.uEe.y y!5F͇46aYs!t~C]ϺAc e)E~ P&fItZ]1(K89#8̘],C2ߺ\Lc.-Dpj`3",EXd MWm.7%хϬjtgbZE>C {>>&WϨg|{($ThӠz^: 1P=C0\!L!f2+[ Ş|q5|5&fغEAE3(OUQw_=P3Iqf]*UȳA zSk ߬Q=C0wgCyT=WEy(ToUlshU{H4Yo4^+J+mEEr'n:oq"1*cTeqb)Weq4"=A=+EH|Ifw)KQdn˚i`sTDbH +]S$F*"+zKyEK@z_SL8C'SiOH|3m|~mv>^G"q|/s0|}(ԑ 3z1bwl~ދY21wzѾ'jcӯxҘ53kWRъD+ff'TwMmϠmΧ搪 ~aygfcɔUk+Lb+07t"s&+`nt웳|!'_(:9 ISƲC$3D2sGSLƜy|#1fh5:O#,hmc XB2CS#QQjɶƬ4ud`'2tD|SmaaXY+Ly p^0sd:6p5s |cHc&ƌ8Y 8aj!7V4G"6g\&nt-[j }eވcznp'tE]z=!1II2y;2T4Ǵ5&L \smˇ|$pN}"iOD7ƴpPf庨_>w9ƭbOX$XN"DSh4Fp4[|%WC-s4>toeb!c NMP ^l=G% у#bo}O6;*tΜ9|N78LoFw}Tl]7DoeݺK=qWom]NlS,Oq^ܘ 7,D*ֹg6=G#fҟf$,+vs{#;ussʿZ o 7h*/|=9ommx>1ݶ0T kRp\"u09d >]<ȶ]R%^ О’F\hf!ImDc!h`n$989 r\+bcSqL\Ty^3>xELOiRp5$6Fȿ߷ns_m?M_Ն{ƕ,*z?*I-sr> -,s1vpRQI\k)ὶ|S %O3 8}v~zER=TBCަԏ%uټ߾=4oZz<ً1{7KV:PAzjz6T=Ѳœv8͝ ?LF}Ե-NY避{7q-γfklx sg?.31 sY󹹳}f_Hl{a_ET"]2;HlyWߋi_;ڢ{ fLS#Eslm]?o2N,EbaݤH /` V3vmcA " [ż\xnduB9՘Cq7 Z$:\yGS#w]PP~"PPeg{Dͯ>9vK}EVdFbv|"0Z땓^ῷzu<DaJ)E"1=}{sIǟ"Qw4NZyG1O^c$Y=bka|gkf%QݛҎglX`w#^v-N:-Xm/>]Ww]q];. 2ed|rH\N\$.Aw*A,)aHA0)vйĹ00|$ਝtE"],ҡҖٱ^P`]O=WwzcX$ ޴޿1G_H{"9׎γHEls}=˙>E 4Nq=8Əu>5igñk|ľV3&iSpeGވ6 /ZOmͼJ-oMD%~fv]όћ޳cZ=ְPU$ZLO܄fA[х>ZV"\#,pᣁ7'Xs{<-s?ǧox&l'‡cauJ׽bD|X$₯s%h~^3BxKY$7gvW#E"dl!{"~8R鞨t4Pקk_v N\=''ωh*='.rZ^sω>wzNtN9I<'09qzaԈ"9l_#&sSSUQJSWX!WVsauj:uNlu:JNor9W>;ޠNߝ,wHd.IΜVq|$:}{%H#Q'F >Y$8.|r>SsDxDCdݩ3sr.x[ y?O )v2{~|?qb ^'M Fi Lj*--'.Ńo+";M\{H8h] :x?qz l6|֊^B3e~"[KOV!l?SO<~?~bxl!''OHl/1b>Y$n__ſyZ`!^ا'3"v9][.=%r14$, Nzd-@7GGOep~bN[3(K(Lsl̙&~fc€1sީdΘ3f-`sf9)4d^')yq|ީŸj`n\1ڑh5f"qt44VŸߘQ81yMgnŃ0F+PxOa#j l~Px#"J0/Ua^lYÌ^\ҴlWVwHT/ q4h|&+Ze/"q0sqɶG͜k$ӅOBb Ӆ l٦n W<ޕ .ॸ6)ԺKy--$oL0q=}6{z[!DŽwqF*[1\v t¤4~Ƶ04-`"TEȊe&"D;#;ey9>N \-8ϑ*YR317 *)Sc!7H2$3Ӻo|~yiK" B1 i,|_A| -7K 6~v~rI5C]vÁM/jk`ɗw=IS|F̎r2KQ>F#fiթ7wn\Y5c?gq&}&5z792+K)Vjت\Z\eGi4|v;ȎrWs5r-rpT3^fFVVY++K5qPyXnuj).j1?ނ.Ky pvn~&ɵQTgἔ6VD9C=|W˘;f7\Ȳrx{?&yVQcoXs{~C ?!a%r_]~{R8|mf>Ґ7o?򼛟hU~y;?1ۑƌv! :͡f]_>  5Y)G&/Q_&?j}b~~A>)'WD''If':D'[>1H{ Mť!hjaTլ!TQ}5ZsDžTQO]Pв_,0TQגUQ{!F(3"գ|:&4h$©m*jvRo[o]~q/;bggnQg9jm7׺I?4SbJ-Txc.zWsokSܜYީ^Hɵ^<8\V.x8xe1Z΀< $F'̫Q+ >CPE=uTQ}\ڲ/4}'BST3 3{, 2d$p|ȓfܞ[vN+3o#y큃pO} w%Db~R$.sUʘ$ORgnnF>?Că'Hx.|XH`]("}CH {e̡rOZҕp~{>ѧHL}j;EbTO~.{>WGxGľs-78pz_2~{ q|=~{ȇM|T8Ɯ9|D|.BZ " xљHnCCVxlah.IHbNg|riAWbnP/?<4}N&sH?YM's"1)"|gOLn|64KO)/QOV-:~Qdc-.|}<9?~O:SX>c*>2;V\hZBQ/'&M/x _"LJɸ:0)~N^SdDW||koP}skf50 },{Њ K Li5#{NԊS Z5)䛍‘E.Yw|ʣFLٿ3ʪ(~u CSWXs"s":?'S|u̧wȧ֨$/)4a4K|}g"Sهt79ƺ|g_Ļkn/icڍ++̦OF'q'K~s^[Yx98{7z6}iǤbQo.Xfkk[hvm$D[$Nm{V>\vl:al|$ښf~OLx&UQžFQ C:芉*yys'LL'E"EBi9svްb+BnW}ANurNC>#ӳ) E )3.5v |[PD+-7CBoQMZw`"S2?ᘜ"Na>1EQ~De {zTC$V"Q$rU F'OYmIͮ3W߀is|C[p ON+[[^M)iKKf&8 ^>Ɖ^?q2o-Ň>ۍXD 4cDJ Nm]y٠8m<ye}"BQ6_ft.A'37O"j3=̍d'Hja=V㑨f}$*?j`njcƆ^Րgn,-..[`/t .oл?) (bω-v[ɜv7>̋!x;EFo=N">F 7U˽AWo{9/^[d!i͐x=cW4*"(0Gʘw1\O 09.-; szܫ]>3d[)v⚰? muڂ<0vgpO lzz-Fbt/1#uR*k@ppTs/Lk sFJC!!H-b}pЩ{*Oa.ӯv1U2]l'mܐl oSDȞHiDY<8́ dD hgal.~y}J[ |.6dS!s+gJ|f3x>3x>͒V,R?zbtv iP[ U-ߐf#dGBpY븅*J8(5pD D|umZ^Q[]xGTUQUQ:m9ݨ?ٹo>*(r@[5݌yA<.rB|(^Ou*` +YP> rnVTyٞ+ p"1C1όH򥂹}VEH\>HE pb(-عIo$_hC*ܡgtف+ы T!_/iz$zj$mUCvm>Dd%7KK>QEÄ&&$p$4MBpV!8umhFJ(@vEUB]JŮmkۺuABL]JY$)phV>fO*aTQ3ux>ͯB'SNĪmIHlwL}u2MlM@j`.q/)K]8eiP ﲳ+b̑vRx);8e]ҡke_V:ݠa<%t5͏/)UȘ唥BYD)K%e#9#ei"˹s"䬁\\6]7,E * umі,DbYD{Z͔C׆NQI\$& S{>; g@>g#ǧYgT[zƉ|~QIfWK4zFLz avSTQ1k (*TQw_=#fP=/:4gټB̝oB ktv "q65 |&Q3iZ׶{\+բCFTQj+Ji\P h>qhEV֝$̯R-J[ŊRV ~+ HtS$=x\#u "qby+U,-CEJK-jI(׋Hfwn I"s=^`53O ?S|?'gCdnB9sGDRyDqr =rp"sEm$N4Rnx9IYGzTbn{c]"3h|Vw6r>oPsħuS-iaޯc<J80_ǨE/H=đ%#f$37qE/ތqԎ'8(L_VcL"XQ&p{bDgicBFLYMuˑ"˸^妾7&JSRCBBʚܳHMZx$YiGFyKw=9 `Xnk7& \3F~l2ylO h~{}000 ѥ9!\$pO|i'AT4持0H#p%! "pIE"Qd#5_؎eވ1R$!DH6L9|FG>|V'1 \M0|c&1}H[Pӧm|AHs/շ_rJ';;5){py{C3 Z{geBC3iy/R3ie t`_ Nk탦_=N^g+M`Lϖ1J N 4u)bcM!3'@s 퓁!(ɨb+'^Otm^_8!Y-F_/Ř"R$2||& H]|6ԪHg"E>`̤O,D}b'_=-0J٥'x}~ooç-.;ʘw7zky ,RC{{`/@d{jC6լN{xK3}"g7] ]>gtM/ط$6e7 m^t8m2. Db9>1[vR'+F6:%pEL< ]Iwgb6|$pf'VX➈NT'7]A'?7+ $e6" IaRPbԡ Aɂ(ceuvu6ږUԩJqŮ0؇Ϸ=iιZsmfs5s{s'.γǞ3 odiiFfNU*W$>z~0{&! t=tE=FC4?Բ{hCj3;PLL\( &FdG UN9s5RqTuTB^gę$ 'ڻg-e=1?8N)aLeg2XvދLo%-zN4Q\q Om&J=Y}hi`sKG}Rvv`} 헢S*;O6-sDIW,mRqGDrRrDrRr>Yr|W m5mRrY?ۻ9 m,勗#HTO$*K߮G[^oo W55Wgnmmv )!YNm&'ֻL^MqŶm #Źwh!A'\.'a@cL³nA8(pQI]d84Y֥UM]kFE puvͯPH#8S"/*wy!_안 K)yEnD^}u|)ELH"U3;:q-P5d,K/$- l8,'H>"̨Z=U'H~ !SE*%:T84ϣ-~ ;Ixvo#1Y"YwRN S;~)tB[)ȭ\ɶez܂[WWi˽a f'9,*0s6|'xDAoKyhI_0x^yxlC[aEϙD}{iYkqY E B5O>v+zƨ5f|\Qו]Q*v&*ku}۞i9ř0.v9Tc\Q{m1lLr 5n֭I>.% ԁb'ytލpBMR;An'n֚v1Jv&Ԁ uU,<|: 9oϢ{. j'8EOOJyvvbm}bj[cm؉3W+(Mcn}Ejh|q.+7b\-UrѠb.F\4ٗ." ErA5hP T]4XvEs`Τwѐ8$ Eql\4EpE8TࢁdP]Q$.N74)-ERڱ?~鸽-uE78<yxf&w oS-g52-^dD g&F?\7 3+j892 ,-Zӟ+G!-_uEWTE:-j*䨜psҾl?KNJiK'NY`Dk>8Q*t˕swuUst ӫNM)L y:Oଢ4G>ljhkgYW(2 ى.Q['~[<)Q-/EH$f-ɽ"}¿/>)}7-d->uH] Jo%\7SBuGl9)+G*yF'\$W:3L-^l,`Ƽi \[9kɠ !#'"1zs *f:|5'\i'O2~/:|7ȡzfç~cWb?1qxi8˨^b?K^Gua9l71eF$'by~6Ly=φogòd&MeF <BTYPe LL-$_bDQrRq/ EqJݓ9OlD"6B.X"&(y l},m݄gFe0qr'i@xNT{x ,Ǘ-K!{ۗyϽo`}x sf_*e;ԶS*wCjE |j[ Ryj@e\_W߲Qk̓ mMGr;kW@nԶB5-fj[_W0߻r+&8%ӂ7͖qwj ny̓s xWO°jwJcd;? /mV_;3F&: ]kFEڮE_5Ba\^%C :TIdǣ|V(܉ 7 +DοFV9yq< gqZߝuIqzaz8$٪wͪV0䫬KB\dq”E qQKo^%qv<9L䴜t&n4S^d,wȕí-A7y U55!IVVV LTwjcK¬Έ͂jDEYիtQC56b}(oGY93ՊuzҲa}^i{ՋOXJ䳪 E"̛TmjĬg8_JkĹ^{fK/jjT3I>=%W=U'H>NIrX2"Q#K4SFd_Y;+ yYxc؛y{O8?Aq~(R\jb?pUJtc'N/*6ts+~SpE\QS5z(u;p•\G8 -zBՍ^FbF/e z8Tx-t:Fպ*TY)ZOyJB78w -BթCg9,ԑW5K>qK/oAG([hA" I2#oa.?EQ[a9."8I|.B~"_9QI6֥!q͂8FArIŽ?QП*GW'i'._8 rYA49$Dw29O&NgvފQy/<;ey ?QOf}a<:$@~)yfС CiݲcJIi.cׄyjv~WٰiYZ.ڤWU,:W K#}v jHf5&*-435vHECiv({a>?ajSO羝1s7NU՟/{UJR۵6!A$` *H)xDJJH("* I䦂eIdR^93,p{~d9́GƝ랊{{z#u%j&ݑ੺G=tt$#P[=`N-wK4`njm&<}J\DCO`O*+QD4I[?.OGO8%zRZU"[ťrU))+8s8=n(e=8@*!ޥz8D49#PN(ƁPvttcj< 8#xf?fsXbڸuV:L/wl]`=캷B.UroS 7iM8уܾcS8S4OXcެ7y4 ^/ 0Wc,>`tyZB8_TN֚s5,\.ifC&IHfErX,y} ֑;ww%.f.g 2*]&T+Qes%-wkprȭy:\OSNf&%䰅*Ȭ]"%r|5-J!c<*+!H%" A.D8:ϭB5cى\8|K|\_>%ꦹC ӬHmTYZBH flC#H% yP=L0Wd #6DgmU]C}u>*s)4aRCŗ$rPk--vd -ϨJLJ~7xj;p)a᷎rpN?Jܾ;?eiRo&Y1%{':kS@@# nZA(%Ax-$?v~^">w@hTUŵU^APw N2C2^@cC2o1cSs37.ܔ [NhD`m[<-}Qp&xϜ]-)ϮGD*?/(z๛`E"jƞHewعam4tJ"ȵ̧8<8^wPE!X^Hg%sf/>yiI~/HiVV^蓕kP >鈼Cu+4Q%+صmWء&z+ص %xj[}Z I\f( >w.Mg^mU|PD5;h|_=qжet2ʧ-G66\)J*;mSD5%T7U_K(v@.@Nrs*qtfDi ,\\eҘ$8$$A鵇>Zݞ מk]\.[G3WaږڵyaϞS|ua b[^LS ϓ VYLK'bD9#NЃ( ɚ1zDg v2RwwzCуwXx+|AQ"%R ~fW`QͧL:;nZČ׬ `t q Cvz;*,6J\p'|Ƙ9d33ć*[ >l{gpX&s˻~=&RbuD#&L@H.0w=YU*g ؓu౩6nSb؄ vdNxOBip'.v.xNvwg98xqAKJ,5NaD07(1|LdJ<9a~5"0GSÞ+~Z>)* IJ7BwJT(L(%|R%͞p8:4$+Z%b>t~c}" O9x_};XڙP%ڃ>JsUڛ"{bmyT'~%AꀶJGx˚5_8QsljS]2]-ĮrۯvɣtBTWm{Hzc}TQ<cd?D2Đz+!sU;!vdbWՒ,Ar6<@4݂ܮ_/VEU%h ycA|vmSސyq;S؏a]ڀ̂S"|rL_w_Ȟ0&u'qz|Rbks{q,vvgr؏NТ12w #ts;8:U68:(sJ>3x>y2re=ުAw|Z>-gs!ϧvmȯ+Yo)(q Fd<ܗOX{$9,Sf5Đ,Xx; quxN(s_g3$t\SsX`ξY6TJdcE-4:߲Mk%Fԯ2sb"Rj4q-N/Oyr u]4jSAo/[v\_%17h8oy #NC~U 붢@Uzz{/i 5:zdlG!ZL戰.4n |%vyĞܩD]#՘[fDK aQ(qUM:}3ٙv_G]i;049g_NG =;) }z V\jc}4(.;AvAq aj8pV!aݳr;V#w A)qgNM\6H60.ϵn0|0# q/>]")/3{UfIf]a?;w'7%$Ǜa Ey`hbCeAW7pөlVεrTT VpTB)C>z n552-B<ձF"WΡŝV@ %π@8o;![:t$94suE-GS8 /l=1$k. ɜ_dOW@o' *`d|6 8n%bL)1j|+KUs Vph!Iħ\(Ju|Uhy9A/Ϩf6H!3ٓrEiQ(}q'h7Oc+hG6Mbl9]Qo Ԁh7Vj1n90'r1qj'wZ$TK=8Ys Մċ!{748;MTwD~+Qs4QL\"MƉgnJ0C}[zΜL#i@obYaI CgT 7iءgn#to98$~YO9EhSL {3wjD.WbI"%>oP3jWӮDbo=>ӇSKuK%.}fˣX/K%c*_4S_{BJSE Y'䯔y4TD 1dZJdq8iD_D>`e|,߭Dl:?l伕kn]t1ol)7I=O-kIX6;iGڈzc2mO iΞYwyVAئ @}-z7#@hV[1}6$/ǶIh4ͫ6nI80}q',u^ț ^ (:Z I<$,Ʀ&&%CK,9ck+X,DW,gW$R#~Sp?pfmb4E6m'9@y,1a^ pZ;V&Vu@GE5%YPiJ$ua(U==G:X ~_s2kMx ős֕d]\!gJD {2N`GAGRSg~wI5X麙ؤ)Sx)=_ BVn Oq$#B|Qx PKȱ%D8naJD9 #&CQfo Ba2a&q/ƞ|GzDE2%S|)|ɈQG`q'7rvԻ&⹌ͤq^8|Pmh 7%df4Dh&q-cIq6g_yGP[MV5x@Z+S\vG,CD%ڪAdTH"[ik8sAA~aD;!JR]|U"}a8fO\gJ"w(w !Q#X(CL0MN(XqS;W"s &¸hx|WKIqF\O|qP$1@~>Ԗi/vR ıѭۚB!P/·mJ~ISoP/ƙ[JcrSUEEA#fLU}af6MXMCD~΍ZJPt XbufNFۻb/Ɩ3Wj?1w[X7b%y9|n6j8fW ۞2bpF?D#l]s{,CcDT"lS}\'V"lHhW.8}ެƑԋO4{1(|2/{=g{ >/x3}8Y"e@5!jvm$eFcގ)k>C'O ?1AO S2scDKmǤ{]o򅅏)ĭ]̟pEYOi$;w}0ٲlU~6^~68ٰ3`lL}AJ0g3o۟X'&'+x%2?{cJg+U\41pWS,_>+t X(܅|Hp*طw! 4R +TD}Sx7lW'1 RO=qPknU]yP7QW"ӽ)S"/MQedFZ;86PbS'7WĔzQȟ/6& i2\^6ۑ+ױO/> |eBtP6ec-G)ǥ̒Dy%e!;JگMDG>JR',=ӴO!v ,{F4h6D }ۈڡr+&K%'vTOl>10uyH?a8W>q?yb8wTDLOQڧO4)s0+&cI8X%Puoy'yǹ>w>q"JҏZH,?_O'c.I.&LO)(}kRdOD#|F+|?"ugI6[  nOLҠ-Yang=81D8{~( Fr^D8l(S,^2=^; l!CFu[}7a󝓉M1e.DDzǟ,v䕨KMp8]a%4 .D8_Vqk_pHғ Vͣ(X4`8²hzJ?cd/[p9儏ǟڃ@}`O`_'"Ջ*IOTJW1RD8_m{E d¯s^$TއO9Jn3XɃXRR@ڦxO:N |o@82Շz%89ONԭ rŸDfbHs'~HE,$| 36AH=#3{HR-g]9yKE`B.! ۟z>Dd**i93lZMuISZ+Ÿ=z:o#;87'S֯s:]FT/簢>66'.FIlz1mk&d|[JPV$ZoUPZQ~K6iv[RΨU=3Y# a,4pGN2sc|sj8UkMex+yv.#bxpwzΖo X֯n@&1^E?+j3&5a>C3NU .Y ;47Yy!byӂE%7ܩ3111H%8@vyzEe[b{ e)?<*&یmF!o#89n'>EF2&@-F$b5Cg0wfi@$йS?wlNϜIy12Nj%R/;E%ohph7&MUFW{(}ŐH5D sZS2}©jo%r0Ź{E˵| R0)VBJH$D4^A&:__ 43m`5ʙH)8?ŊKBS $ C9zoB9`'!["0зd MLY3GLđW[1I"dN`3>TO Sdb0#){Z8 r0ptAu QoAQ< !J-^~[NB;6DWFWJl5ZFT<'BY6wy#MbAІ;7k$TbThh-ZAHҝQcejn씵 Њ׃aJjMʢ4} OrMpԉ 7j䖡[;Z pWz~:9EwIhmkKY9] 0w?.h4RVR;T3F-hFF4:mkQlA]@[9Hg'$2V)01oD }u<˔^n|6OL ;1QV%}nWܦLhנE7j"đÔ@G*GdJCU&SE4|]c6=|I;]_}K\hK1|Ʋ>J>:EP7بY97 &^Snr[C?[Vcڦr4֣7SY $Lǚ=Y9ףiپA$n_Ci$`Fd&N?lL?ۢ L Y$MGZD-:P7dydViWyE+s Pigt+6s% ݡ@W-7PVM0 LԢnd*+omܦG 7Loکڜ? 3ivm˹LbbG>5O2SZz=ͧ}&1'4j~`&"UDqAOGTx[R(sCm*D_@9ir>!{11$Vϝ֛TX䅟ray';нY-3q;>vz \~&F(eL|_Oђe]SVhxDXGجbVw==@a|aXg5.k`l#j=<@⋫t\1pp(a}p<5ŠY[=kTQX^2r= ,H=*]b9ڬ*7ou(|^^ _Qў\p~4(pp>S5*Y4lO@WlatntԚkN{OvmCxsD'%\h.|VPk96s>7j9>;5Jj^'V&R~ݘωIUXг&Ba+B߁W[kak[ YqBKB~W\F0hnU4u>\ aQ|0 T4U.c_0`55YV ֋J:DhRE&^ 0ATd"wzM䷷2Ka5CW6L\U6 ;X2RtRfeg>h|&\(HOS8W"1zDR e4כZc"?h!a57kb"Gk9O JrOL4L|ȐDwX.)3&|@>gi{=?[O$VNx|HrbĘ1`"2wkBtY0l>H D&v,*ΟbL2սqKMoi^v?q/8R=mD͈K_pw*3D2jqB; *7 !AaNݝ.ޝBFwгS/@GOpmė_zNs/ :ƹMYЬd"Eboڞ$H2al݉6y YS(R>WP>hV۷(M#P1Ug/ R>,4N;$+uߪr5k)zjU*MŻ9'qw lŽ(~w )ݝ!xwԘU)fs"D9Q%ޝb&='/zxy}CR|뉜ge}]w\s?ՖD,jdN{DZ0h[s7b N _ #eՉ|QqJXxcK>j|zO~۸mx4k |aVWlp,ٖ7.O0 1h`F* .]EA' E''6!|*zm; õ0iFʂރ{(ժ!Ꜧ)s?={LafgoʲO@Ɗ KaEOs]wiWw5Lжam a?)=?LSW(MߋGkgD{68cOۻu4x[ZۃeF`"bFD UV&6ӆeocZ 7w@KêfxˈNu}":q=ukԻ3֩#'F:ZvcW҆ePkHZơG(]0r5;W-\o1 Foc-|$ַ-Ld,l8-e)Tz}5qGD+9\xMSz/.-X/M%6PWG D))s?!s>_ ohFb  NF?`9f-A sOap3:zznE›' 4/ُ?s '14l o|zv lf- g7wNҰ>j rT;pj7wj~,~}1VƳ̜"uPfvC.n2|5SQE}}6w6q_XH$>; Ey^wjul\wj&1qplWk&oW4I6DabHdb8xMOI;4F;HKt`u)N4-aSVҴl #yn%'MccDp>Q~ vȐK..6mGzw'Sђ|Iu_qEK_hԍ?dj2O/6-ܴdZiذeb ;nĠ. l4wgebhٿÕ0`J a`/+NҒaXE:OIxeVNSCfi'ja=ps:"*5=}N.$p[++nq&ds&RDkoT%R톬BV$)>^a!4N퐹)ş"Α'JbtS,(K)JGȣ`"E]4SCATXFQ&莍qnu"T.|XܩEW`3O%+DE?*DU28:[,2ހD%8Rc\9E¡ІT"]A'7hY0ܗ_>l&׶=ǵ*faf26;@c bB[=, 7jzZQSer֝GT W0S+\TFGkhq ]7|yfMn4dusB-՛юM;+.;qBa,)rQpon\pmP54jd}b-[P ~0(K9xJ&RAd"ZbFd"RbbxRZb""1%&bHSxs&Kd"`"E%0qv)ʙD%2dw ")S)u׶%f6?I8yږy7-T~* Ҡ{7Eq$;‹ȵWڶ#Hrm+ *jbI^6ɊO],|=/ smko+a˻G L|,`tr}Ɉʪ]$}b(Dݤ98_DeUT_tF_GA42pݦ(n&hG(ѵk[a$ +L$&rU**rV[hvm %e4c C}w40Z ;Y)8?f c"뵽FTp&"½1nbCC2?YNDQ?M!:4" 6@1vNhx";i.a>?%ݝҔ(.@sp21&J93YEk"Ȃ*ɐundDL\`NG9;zxNPE5'_6dDO@bBћ>ȢE'S\ګ Ɯ/}.LL+կqXVAL_{q 3(/қ}|vLD4:#6~M ptM\Iduf"Ѧ 4DG |W++%rLΖkf/T! ‚oƼoJ䗍gME1((EQ=?31m_ E4 'L, ](Z~o"MgX#;(cm^jՋ5 Qݴ=m6!o4p2J 0#2{Ep;epdopΚ?ޑ.7<͙ܜ>woOm8ejmnPix+ [(Z{" n"K? zM\K]Rr41Eٕ쉐zP'çd<O'qgOF'yѺ*J'/E1>cKZ蠚 )YkhOʳ %vN(=%^G1 1>mlʇ(Ld4L 4jcd#݌c2RLy/{+5ޫz|s~}QO!QO$ :hD-ۋ@4x%MT<:JSCƨIc uXG9ϡ?ԩ먙45`գ?Q]əɍT| JO\H=4Kd b#EϹeO>CaG|P;=sГC .y|@Ds GTcZHbʞҔZǟ2bE0VC1Erԟ=OL"IPIlt*=UǢ"AlzrvrK e^mJMaJh,ZXL/mI9JCE-ۢ=çn CJn.SCzrrTF81Im{vݵC M5'{'>(7Ώ 9E/%+l:D↹k~\bUmNj20i@d(cJ;w|Rw*ЮFB$Iܥ'hCRiYNC"Dq,'Pt)g' M72B&B3'wP{P; r:&P@V獝u%;4k;aLwZ~~hŏ¶3i~NtCH/N!q&Sם43"̀Rw SG*,PgdH#ɐnuVN4+h{r) (ҝaU@ST 4\Tie37)ԶSSHVtP^")\ӝhvҝwm(tgt~s/$$nP;@CݴAA[TݰNBff(vSz[ (݀rBF(םHIGJSd.A~a~X'r/Ԭ('jdYQ{Z~`Xx1^ەO o^H爹{3C۸#sQ y1"Bc@b N.^Ÿ>ɋq6b +xKwqp:y1 {pb4ɑÛcT(b̦x,;'G^$HmYQbyMzpՋ!vm!8v]b/ 49x1_Ub^mYlv(,uX eטZ# DZ7k-E#(t4@a&UTs팆JD=] E%o ʨD=9Aɡ EƟ''&I}ED8‹JD *&is:bM'F?\'\+?1Οt+j~JVB?1AO> b1P Q*kJ_?O%|Q(m'J"ȉxY'nwCixs'o@j'K {^tM?1.HV"-j"#YY('[fDxvG\N 4.ОOhS'o$"sbʯ4caTryt eAK2'i֓;LTcO偔tM s*v(mɱ'D[>]Oxe{ nkjKVSȟkq[9 ,}afB3lv{6ٟQQSlٟb+W2-]e\k6kOD._ޣkb-`)y3m'֛cThHPxӥg"6ĂGxgZL6|('P'[}led#^rpطG|eEٜGW0NzdX ǡG -W/C(⓲v:kQc/=h{ L;zg"PQbJWĮlG$\ә$JmÝpڹle؞7u ]QfcW?eػnD7#~(烒6iux9܊n/ ^;D_DaD|jVK7doD=g}%~ʬ\sη)_ʺUDa "ѶMY߲"Y2,B|Q-̎jɺEvM vʎo$Dg i ?YE)䚴-`C9,crepXǷY". !aڽSeW<$v.xG7Nn[xkL;(*OOܯT~CbޟRTfoXj%nUbTRkO9H"U~Bj[~޻ {nѼ;냳gضrb9NCc/՜-s~r<1264tzZw:Ot}5 ԣ-:ǖ+b͏"-NDNCci4]CM"FC4ȁ keLA.Pt$9,%9IٍظTݕS-s FZj9vnعC-iHE ΀h+ue9T oQ"ԩNrEQ,Wik QL L%Q o9FCrNreܧWbƆ J33lz݌Ztȹ4ڹ vNU JC&zzd5b _dӣK1eȍNc\wG'>5:Ư_O&㡩 8x+q8xh*q8x+q/1L<4L̶{y)Sɏ}v*:h} voDi0S\GN΃{4r!qiWh;& 휲f'9YA. Qujq4 2Fz>BK<45FU6jL{B+Ơs<چm4Yi4H' OT5!XOD ┛XjQQ-''Цt|)?qyćO}Y^,E[ST!?2GϏ~5 $8 θ@Y i-Mt&dg:i{_3?{9v FMx:-(5eo *~hz4][T")'Ÿ`rO$0 r)7R%CQ) E%H"*;GxjKVs^S6b^(Q[D]Ϫ>Bk-yHwDFRY-vQw|"{^*(k B2->hWӽQ@/t`*$g2f'pԀQ>rҟR3r.B9l\'9+ҽ1??N~_Os^_>>5w5ZpY _-:ݝ&>f);KQi `'*j6t!-|01Z=ۢtq:tތ~鴫~w+T-?ntz͖?^U?'RdDO Ph2G>i׹"[taNm7k:qQSH|y5+%tt:.=;5\4R锧 S?.ͨ{+Bj0 S=0df2$')6mDwлLcf9~o{锕f4jqF&/F&<_,MM즆zh47pvկAǦGܱ)=oMؐjwlFwlz$9P@??M*FY;6;6ikpot}~ +<'n-F5+ͨ[bOtJvC&8 S!;^Ł3zv/Ě՚"pKV;/?p]H -} q8.}L :j-~[{L)X)]o&4SzW(M}VQ,:స[b81@ 3Nc rN<+lFSٸCZSiHvv;>jսȌ붮S"e?/SDC?0?q~~]'iql:u' P%SNrS&58'ԃN =96 3| wcr6O`08Q:acH>P<1IY5:ƮSF;JORNG`%/8Z{% 6Rgmf?6, xj~n^{0@qn#zz7z_ۉicoӔDV,JC /p" EfHqr*Zv) <|]\I*IgmQv[xyvK<|@EXj {д.Jnw<+WAkY,%̨dynAgRugBWHE?U~|'E5T8/PCէFuۑT:Wͨ(lSfgLmJ e%T]f f{fꬸ*g.,5I)t;hZ;q³jҠU"ĩ*NN')(' &LD "'7&OoV6덵_>ypEn'N(_CSg(mWP2"a=kMoz(Ҽt 7u'{lM|KwGj7~Ӎps FJ]xK MoQeT,LD@ enWsJ!T׍sSx7~Y :x(+@n6op+tK~}ͿP׍Y ]Q;ELLe&0WP٬f+L( _Gj7& Wٕ+ (\Q uSȩ('vEqt=9B \Q 9P6Ijۆ{|46s'b{"3 \ ^]BMϭ{ v'4ܻ9tN˽ڥM2f&jВ3i5jxB@_%j]AZQB.PsO84db{!<[[N_½{ %2v b)HXG4xۭzݣ")ܢnN(ߥ{ y7.Wj^ƮAj۴? f͞^O\K j WOϟhJşMj[&ş+djmg+jE>-Ÿ,B@jˢfw3Wٖ<0Gv0Pku?\^lVQmT_,E_+Զ(?H}'\+~W(MWbO(39rE%6"ߪeNNV4FWTk'.xr֋jVԒW`k+JB|)gtt# 6fy::SۀԶY@) hG| P]j[GHmwh(6QR+ hKmÔR06Bshg$e*QP(چE%W4\5w sE rܘ<*q m_3|Vo>ѕ=?,jbTk2iQAFᔇ5u[L 9F^ArNq7#ʮuYTw6ΧC1Y ?j{@'µZ'n7`.FѺԶ@mMzZA+ެr 8CWsz+{t5w ITQ)5%JLmt͈$rvE8 (WUN5+XJc.pT8iTO LccVnYa`&.z5(yZ3ijC՟΂;)Qoil p4JX ɬCMfu0nQ'Fǒ+uiN'Nu;^ W㡮 DTk㡮k㡩k㡪 <8a{hXC6a;pk\wjգQQcGj6 F1eM?] 9~TOL; uj8GT QPușƊŘܧ<11 KE gy&kf~8 '&{x+'z|EAin<-J䨿uEe|<1('Ľ('cQ (M&l<1'ySyb)E(Siv牓JDXd0Dkfb\uytEj[5Pvк9`DP/iԶ~,Bj[e< q)- (Km˯閔4X4M{r Diw ,@Y3UDyjJ& kfy@OmT/H8<}pHc6o&M0b"EcS'?9,ilZ|q:ilrtEc<`&4^\dŝ kl"MӝsӤ&Nqs+LcE\0"BU46ͫv>xkU\T rB@46OL' Q /pQc]!VEck~j7ڹ>nuhl<M&ͤ)dEY]mR)P'~>KyO 2MsaI9Ŧ]i`)&G6 5rprb?y L%r}Mr޲0-:I3I@LӈK G+~4a;ӝ0gUHםTiNwN\w &QS^wPttEwtyMvddHGLS(t+P#Hs-E$əݩC;5An )ݘVѝr)aS+JiHrҝB1Nq{j$Mt.äb P:- DEwjb s1Dbu!$nD0݀rR8$ם8 A0Cs1c/JVԖ}'jYQυ.uk:/FcJ'h^۔FqJ<+jfx1.q/FbD6q/Ƣn5x^xwpbvÉ؅P]V`Ȋ*ͽË.b4D5_zr݃kdVTc_!D(J>DQ:rb$곢@n>+ ,ȝk\DuWOlB^m5/suZ'n?x[m\6vMEHmyv9.v _舫JE#ϗhq#*Q,BX nB#&]it j@r5QPvD\(z9PZ&bko '\xޟXi2DLD}`,ߖ,?1'& 𓫸?qx8on]~HJm شssHO99OD~"'OpݟTKO,_*}q҇(Ǯ5m?g_?ϾZ^RU4&:> W̋Ns$sJNjvZ6XKh_Gzn:Ƿ h'OA5QA/$geN.UCr\}PP#E1cz*YSǦrQS&/9qM+)}l f_Z,^XSd'PE>6)}l&/dž6IC}lfچ{+~}lr>0%[Hp{~u-]!l7XomV[LB|~tݰ('lQLQ6Ҹ?9(pܟćb U1 C::sTzQUldGy *l͞g$3rESVk [v? ;SCi4bQӜ_ReuԥyHCFDڇД=5a5p-!MLJ,bi!G.kŚh*a3%kS*h:it]VA_'yu>F; HPv}mZ )<$DNR&rsrݤkҍdeQsv(ct0^V.)iW?]w"_mڅ?)UwlVfӧJ +ajMMmRlJj[SlFmDj[MW6АDByjFW@ڦKד+TyJt* ;%>]⿑(E/5D0 [Ң1Muc3-&fe/Ymʦͺf\f%a3"! VdR[)Դ<7sL9wyg{.\Q"슢F,CӆF-)S8ԁ T*]Q\Q+*:a1JE]Q߹]ׅ6kGCppE\Q׸+YWx*}+j5OdѧxGnp%RŞZXϺݢCEL>ntxMq[4qaM9ơE؀+\QzU@5Y)ك=쳷VKx+*AwuWc<?4 ڝEw%\hUAC 9q+Fp]xn d\i6䶹'Ռ; `}01T1[vą=qJgʇ8e~g1(e3DgZ5~\0`3zb4a&օ2&~ NL;AŸv|]0UzX01P&JW3&;'LDpu;O CFpYp;㪮mc޺`" 3C&j*Ռ+ ;]A5ǻxbD{t@ bM&Vb;gwS&`"` ޕ'ƀxE01O0(`"ZčDxD9ziBxwor68k?7a\wBMlmsNO闶s:iңSJw^܀_C*Ll-Ϥ W":y:[:lƔ:3j u)"rY-B\?괽$ Bsd]Us,W\-ҷ\ڽT"8N#D!HNm^NOތS: u̗Q&NSFo OtҳużcͷPh13(3,fNϰ >=RWT}_Oթ\!COϰ9=Ò3 cB8Ds3w5fe%82iLdlr&VndJHƦ6^uƦpۏ26>v"^]<(mƦgl|:8(dlnFf90bb&BL^el cbɿ?Q9(rtѩȅ#5.W1z" V1}WvuFMMEH{'GPh %U!j29_l\pW1W10aIrW*FeT1_ğXOL)M-Lתf'^O'fCޗ"ȖOKӎKha#OlEC-(/ԠͼĐ%Dy(/gJjT"ʾXl+7B=3( %CA P1ΪPfF(5% *]0؅"c|j0B(hQө5x`̯( t@1o/P񪉐ӂѲq~bOF^a^A$IlD`6 vI,kmQ}KLjKtܤܬ pD3 c8/tؖ8滳%ޡ%p2 4g(: !:M*g80ݬ$ĊDb8l觱dp D3񌯓;X0AsJM0&:"ҟ폵7X5'e:>%LD˼i;Ī D8` غ:ӴLsbf0*jq D3D%3-ho"Bm"HV'1{'nbuN{w' NDB4q򡉗6s ua%e:\EX,-"E&# hHVQ Zk:mVB .QM܆آq 0*b;iϹ]GvIIy>mN[a?M"B yO,bk+g P˞H?P94{KNĬvtK{bPT,zݿc?ᤓlDrr'>%=w!ɇV- F{$$٪^Dn׌>!4ݜY#c$nJ.z(\`7o:]`C,  v#_l3v\x]Rw#'K8LgITo ,nTF}cIUXJuԸKۤgRuҪS➧dASGN ZiH^2!mךk.meHL>O"dFq cЊ4Qn6O! ?Oq18hobcIl۹86$$dц57TjW)vq@B | <.`mf9XnQ?:?Ĝq@k[V[6|$[LJ|9RsTOq92tK1i/ٸ~I/ؑ qܻq<4 f+='>'fgO,}Ծh0^`@^}15܉sɼs~T~dRVע̾tBM>^wwV)e۱֎5S*zn,$]^r>8O^ހ4zݙyrz둉Թ;}{bTZϓߡX չdi$J?h8(y@";#Bܢxҕ:v~'L] 5%]%bدqE~Gx-biT1ݵWla*~|^^{cX3+Ѿ?y0X $ՙ}sřGޚ/wCGr$v4C\HձIZ )jnGv81PwQٱ-Rcb )a[E.z xw1б$m,zlV^lVu5s۸>!ZOe@8Q6,] GSe6Gb:FHx03ډrH[RIu맄ROQh[^7~S췕Y8`9yꐳtH_߫J2GXG+pD DCLW:nkjmIg$ACFL*b$ߔalb Ox+ ¼ O?3ƪH@6T׺KdvȦm;&܍qqWa!\ tZUޙLJCu+ ޅȉb9!X(0Zqp.LLi_g4^ UaSrQ4FJwCp}m';r0ɞgݩ+B<=r, wt?Ț9fȈPFмX"`M)xɢ{T}Do  r/%\lu㽛لD<}ɊzP(s.]=!V{rԄUt"Ѫ[DYӳ]y'pR숷xW/XEkwSZP !⃱Dk'1ۦ Ov>iPC+~6iJDB9m NE%(Oh8 J,6 JH̕u/N1h;cK2اHz&[M DCPQ8*G^.ޙ"΍rW::] CJTE?D@08WKlyqq5OgLN  wm@:|q3QDDbH_ ī5| s^RY8YH,~'GZMgD t8f͔:DY@Te{1r@E`BXELJ^TSL높^ǂEE7׈lơZr;%x`u}/{$~67 )iL[M 1TZ2dԪx}#-&eɝTӦ }g[$yD[.c2S<&HfzblL'XPV q U=qN8!$^D,1B" |wrn&7ֽ_o{vTM"yBPUS<ˡC<їB 0h ,G9 RF5G2dP ̠y"EBE$)v3$IdH>㉓ Q8=bk>. !NI'2E ?R:/ix OXj`5ѣ:~O 2$΁DсZI?Cbj%|g@"]?ebe6yq'VXf n*nI쟻HHyF'sCA?De0CVSa@VF~KfBH~&lMA -+%ekýN-X: K[8&vkG$;"qWLbt>Qm짐{*K\WsON Q8|d"$ 2}bRO xq3*ٱ;HU3$Xż$yIÄnƷZ/9XV]xO=q AH}"T"LMh<_PzmhJMߪ:V6|)kyM]o]dJnͣ*ĔucԕJ#S(zE:'Z͐(T]}ԭI+FΩ\'AMVf:¦Pį1KI}"‡nT"\qܭ2 j4$҆Nח$jX};H,P0 EVk7/+ݴ6%w^M;@W\*iR(1$JaPҔ=Tv!]$dC!XlEҿj̔g8E .Ǚj}I+ "1p{M[H,mII5SƮ.Y@biM#ZgAG !$]ᝊA* )Lﵟr(\r_qS_,'^XsTSYC?08ewał'Ag:lj4r ^07G0d93:UkyVj;,\X` !ꪺ [ŜW=ƙ 71>T5< Ӧp/fqb゚g^bY?oU9imJr'tD頻+glxD:Y}H$fs@mmֲbqUfMVC 4mije'q_\! nPazan&3kROx$~*1UAo@Csٌ{YnEW4A|64O1"6lxF8fb'cC?y=ǯܠHzu>RS>2!!G&9ݕZ{gC6_O\./^:<ڎede~moY.#TsZm7 cA;_Z!@,#Z*IzH@'yTFɱ޺jx~4tv?/krYC@==G35\d6LߤsZHYn*LoR9L{/H6P4H9~KY#>i <-$LHYv)%Fɡx++sϳHSgPjӌěVϵ]3&@ov bp5It@sCzXUZ9 -4pupߗWQ3 ̍.2i 갵ļoȵhYAYʆUf b-k4<Pxr칳/ȏ!P #$XB(_N>븹 zeL,J2([$~q#Oׁ9Nk3&_D$T`,"H4پS )ra% JDԘ5SBe3m=6AUkN> }_A)B͉%Cj{s=Qt@f5I&b^,dkcq̶7]oF^dQLAu=xc5^-2$z꓄.}o"QM*) H+C{N@6qfH0qKڑ;QY 0g1vSQ-o3MtqL|**g#}U|*j#N E!Q=O%zXL.81# D9KmЉsb{b7D'g"2R'}'\ޥ HO7+ʼtHb=wkѾW/DZ'oAԯj8>xr{c=}$.d%rȉ1(9QSv[AHKmuV==(4 j]TfFuOR63))F GiFVDc/D+nqrCg.M1OO?1:8QP7FNkR&{IƖInZϨ[> IK%DN91E '܆ŋ뇺F Du vL;|tsq`m,~s-m$Z^õu9=iyF48O91PN+zjϔNiW(AdE|Ĥz6K:X6?1+$Z ?x&co9CyZDcOq"ľpai s¾O%q4۽'҇<q8|zx j|8]USgH9Q B9b^/'H?VRrʇXTljo%f-Ҵi\m$$&Hl!Cv[5JK9?2(rb Ɯ|%ȤRBRT.Q_;)iM~!G^sz9ҕF 4-"ؐ (cb1|㱯JHهT=$i9.7K{?I+&~=1BW]){1sÈ\,*6vP<,AQ`|<Ε>}uΧ`FyȳȩL]ҭ"&GܠKNbLA&^ݹ ;G^S̍$E1"=K3T@&2`qְ38axvfFiY8 (5E1ӗdiqKƗ3U /j72? ,c˒D*d:Y- #^(gEt #9L-N^{pQv{`GKa"s-MHᦵK8C@OeV-/6_vw ( B_Dy^FH'^oo[ru7Wov1( 0ʓ)yS98ԓNzjO^l|}p~yK!!H^$~vviw%Q$!ٳ jwDoKZM^җMּ IԼ9^c:ޜ<TQ!NN;)wb/'x5yO{Fq:qNVx0lk= Vk.G&1IBRwҚĂ'R/fen %ܝe5$T mlٵEoP n@05f}(8L@RVXyJ޳F_1dzLB ~>R&[uəܬn*kd񧐑 tLOvsHt6!yI[ wE$ ͨ=Ppșb2' goNp p"n3 yF?[*fO<:Vu-1Ei{:t|(|Dv 6]KH0jp>2fO)U.ܢ?6&fA1%6}yh$pie7F4tvGE"Yqyڢ[ QP8Ew$x.fDiR\sW0)u|yq ,QΜ9ڞ)>_"hWNx:A{T/Z2_|Vn$^CFfc8[>l؟.J5[O v Hd SXo${9j墛nf{4ioM@<y!Z"E=-aif$$M4Dv,M,[V`"|$x֤Ux4`$VeYA5zv>v<7CǓóS/]̒؊Tļ|Q677S*UM9?2:cH6N &.F&PhO`%?<ҀGboT'$r|AD,%opn,o๼"B#rs+BD8D ߫qKibPXƑXRx _X7-q_fl}{&;7Ւl$o21L@䌣Œ8jBKZzuGW+N-!@W+"gI̼E~nnjaQX4xjbD ,YP:@2ͅ(K".fMDC"Q#&KTq+(zzC(r0 Zbj.Nm#68&D4amy̾hm(k$GQ60}Za_1# ̴D4ND+K"'ϣ,*] Lx%HWkxWCW| >; "uts}26O>~YM{?iyF$eB1Kt7qn&i.FlqHXAK78Ks x˸dh鬊U;DWdM,lYyAٸR 8YXFŘ.L~# 9:*Z*c˺xzӓ_}vTiO{HShzW5 $WeOam#sA2&jNe%wNm. mͦ<?٩)όf^❬ N9tg$L,Ƞ2=0bΙ6c' l"ܝY9M"(]tSA.]mZ`++ȡH|J@el}{ X0|0W^q}$˽$nG5ow ܼ37՜-7JҲoٛɩhd2;  #5x;s!lOۍ|^=6C>W&|w0ތ.vC`hx!;d+v*Ҝڡo0b>H8'3 ."1%@1J=cWYKVJZM]N]N^QɳTH~tynZNٺ7@!): -#= 931*'G$B!S)P(0%!  U*M'K&< uI@O5D,M&C#F!> 49!SHyND}?2D)?)6%H$7#C"6x+@.)'%%"%1'&!& * %    #     y }c\ya\}^UtUN~UMSIoD9wB7J3K0F0}=0q9.A,<%5"1!1!2.42/++-{%4,8"6'!21$t+ '    yŴZtRNSf 阇[V;2!ƬxvolhKJD>86ʿf_^SI>1&hGIDAT8bT<}y4pnWCx<|ZhU lRЉ.ϫW2?|g|\KPyF)qr7_=o^zG9s͍NqA%{lg|qlRlllUݓDy9O %QQQII]eQm@_D pSR@ 6)**1:+rб8=nTrr'؜خhyշRj@@\Bm(,LI**'%mXWWҹZC .KMMkLy;&--&&h*=n]SO}4!hSn|^æmI+d7\^ or|Yuoou3&M*J[2Q B̦o-3\ٝP T $)yb `iTdD_-YYY5uewtSOuu HZvdeggMLS%a999$?] x4fmiiN΄dbffdffȉ5ܾnB_+*I r* J&yFRt UIENDB`imsprog-1.8.5/img/erase64.png000066400000000000000000000153051520775651600157620ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_FKIDATxڴyt\G?U^%Z%"y8dbN+g7c,SJdgOONF XnQg-i;Xr 0>>Nkk+-"?*4c,_v1Ơ:Gw…o}ܓ[IDmv"bډ̧㽛fʕ 8p8c*|Zk={\.GWWBӓ3B(xf Ƶ-MʣXvJr Ik t\q8qO=s+БHv)ϧ3LLuO*m׮]b1֮]=ubnv~1G!(Gca*c'$jH)dsGkYډ|>ώ;H$Y&orR3*g}6$ꫯ2:>mIIN )F`A)CլS5KuF8-+P_4 W}1w~?_R][[K*BJq"y^4RVV6c;ȓJ [$΃UœU eX.kUȢʪc4/3ŕhÖoiGZRJK**<ϳ(LyJ4#Z.c?~ #&%'S^% Y6Fh3%u1D]MK zVF 2X5͟%m|8C>G),laݟgϷ}xsi0е.`@iWUi[DZDQxio rr?wIO (,Is6 ӼW壏`qz2>C٠}UPk(JWRe`golgK 5Yz;%*}cʹC9B|wLP2_V]jLJΗ m>8rlITm]"C v2? ~| 75(mD%9XCN› 9k}7bQTWN `cny 1kgs$?яظq# sFi{D~MulA:_psNo3::J,cu԰jhICZ@C@K$(e2 0|P 9 GVo9sޯޱȷW}Ynf/f,]zuB`h۬SIXZ{ TiJ]uQg0̙3L&Cձ6deZ!xQk! r9HNxy%6 ʘW1 Y ٲOqbK{\:*p1u;۶k&ܓ4dE0aQǶHT YnK)/u.ˇ092tu06XB*^{A뵽|~BYu%ܠπ'O288yAab4oJgQxSضm*+B>]6Fs9~Eq4dw2Uq@xgH M1LF p^)Vt|f },+++BpWj*ɤ'~@/mx!,WW[ \L] 46/Tw~5ϟcq҈`bҥ%R b /p[JyQCٶm֭qy+P?(cE!$ (V B\rl]5ͭ"V32";4r*62+e4Qx_yW}x67?0AJ+e1.o'ΑOp3yPXYYǍ)D5`G2RĕYCj|xy9lݺǏ 7p͜}v1Ut:ͶmAJ8ӧHI>G]2 #m qOi?rQ~`YUUU$3 lz5j8}x=jɘe8Fb 1l~[,qB)iN8AKK Abɜ3Be||>OEE,[lapp۶-KzFN}o+2.H~_T8a2KJE"prdْ@K&S=pxOee%DQٳgDH$¾}<l?Su`c-7oR3>U/}K|ߠ,8GBPG>˲fǎc6Zs,d2| yd2??/6c)ҏK-B_!qP&''3gXz]tuB$P(-ض}fll,N ť6x6lʕ+I$q1.ZkjjjX|9xJ>xL&9.-}naJl,}Х 966VPHhDmCаRh+!Dnll 3`6 XECChǬ[!RT0L&s=ݟt8Geڵ .z<z KNN9;ҹ}`pVo8;̙{n{|8f͚5Ap}vz{{qR+?)w}7D{'+vAaXkww_ub1.\ȼy󨨨, ,Tg1~yN>Moo/Xիퟱm;y򸌔L&SQ\}#TPHis}WqBٻ$ 4 *)\13PJS|RjPKKӤR)ömΝKGGǙϯX?ǣJ)[)YeY&0ꓓ"iO?t'SCCCMO<@hht(I <X3X&U[qjkky(L~/?R ؘ,˲ MXHJi!Jd\׽h>qTyLi]pLa”aMdjA_ ۝ "P( *iX,#N)%eYM[5;IENDB`imsprog-1.8.5/img/excel.png000066400000000000000000000144151520775651600156120ustar00rootroot00000000000000PNG  IHDR{PLTEr3f!t6]̸(IDATxK{:d)늓V*̺ IB?`[Gas Dft 6  w0a&L 0a&L 0a&L4W0;l&`L 0&`L 0&`L 3@LNL 0&`L 0&`L 0 &&a&LL 0&`&L 0&`&Lab20&`L 0&`L 0&`Li 070a&5r2\-$`\_HaI2HaYM$ceb ok݅͢)ڻ*͙-|&0O] L"rj+`ѧOaGWIvkr|:0SJ `vfDrKD ݁yWE ]9)U̮?"7LasCAr^$` S n˩n0f C18hG7$ Fsl5fga$Y&`~f\k5'?o\azt$}e;Z+0P";EYPfW`FQhY݇WA5Dz]41>!)6L9?$ɰ蝊 9g.|”R 0=gy20Yp0kO?`rt`%` L62OӁ?0C@J59 ji*. 0}:ءL`v420000ӛr~D019 gSfL((0`"f&`&`5 h&,`/m$-dߞeg{On<f?y>+/ ޞ^V s `7jZxm g_]Hft3l#ayw![N?s '`\E906rF0A']N0SUYL',JUN2d2w\ZF;8^OR{9U`:r Ru] 3t9M6u [f364 C[bW&nȴDUlxv o`:Aӕߨvlsؐf/u#2[\y200鴀#Znp-MQ^+{ 99?Ԣ4jAg|d (oBTěV2EK0+/BGUfUެ(Ё,dQmpY7h%je{Q[sɊ[@! eʞl ;~F a8;E- gal52Eknv\Pr e^Z@jY6@lQ03*}z8lB&"̫|}ySk9KeKe9IQi.fP4\&}?|ɛ5 L$9xe%[D+Uf|swN|G0dFO]ͪ، IIhԆ\,p{/¸ېVL]1@0 $n'}nH˚ɃAڐVLۊw韢z5.vkML#uDj5_'7je!}..5YSLJ{;e5*`ݙSObfAFOeZ9mX֝U\x*~,HSVNEeK:.%t76_cWN6h|IxL-ZT\zboʧul/vLt&4|p|Fs"09]rS|*Z&s]?hҏ2'_܎2]D̠G2r,㼼Iv̓&6#uoKALN$ im 5e , w͇gFHц2Ș4ul#LQ'<7KV'ZD9a3Ih<<Lq=e?W҅?ߪ`~x{_fW*2'+c92ߍ{Qu5=6+sκњQ1iFӝR&_¬LgOkgl=h޹tCìzӲ9d mɖ`^ݏ,>Cfrz{>Ny7̬` 4;3PLۮzZgnID0x6L´Z= J!Փ`q#U`&$7bivfֳjh풚n6mLNЅ l8{}t#7a@X0{EV[T5327GųEW}]iMQNSځZ6t*cuC59@<8:DUZL/];LefJNk EҧAgAPAC/im4̢DG/ChaM1iLgsNy>(k%}?<9XTZUD LE@ʄb e|iyjgya|SOkf8dkӝ97"_:|4h6TTٚ)D4~5`^$i2\JN{Q}cY|uCT\!y ,: ˥a:[صnbmF 6f6ޝìwYYڽt_Eb _Գ_~i2,>Sa6+G9wxTRvS*eD DM9LWyLg"]ioI?܅6?<^ cWQD3f-iFp˕h+k<0? {(1GalQ>#n$v6uT\楪J'ȩs3Tb(mgXF_}՞x\i=sgn䏗vVqբ*Y{#-D=-)=&:v67ב"ᔟ8>*iL3NOwfɉqI Pl`eq^LxhH2Y|p 6=r`t3\cv۳f}bكҠ .Nq߷(xd6٬ElSϹt0tiOAn?G+;71@>wݞjeg=вz،ϓ6>f-L􋉬Ni]t$[j>mt<،̀YQSv͟aS}~cOkuyFLٴgg;BDŢ=YJUxxf-LQxp"',^esѫEpicπW5ԝvyxymo\?Lz_49昦:ntxδ9xi9`{^zm*+M0rD8_*Zd)gE\ֹ}XDvHr9@7WTTfv_M{_ۭ͑kl.&g/W/:hOߏ 1f睙ǣQ8Y杚@ b uξr*?+MX&{"Wݝvh8L p8hfCuvڊQ95ycuX'FWc6+F\jp\n}yU17aj wt6{]Q7y V3 N|& L4| WCU^=ހy*˨t_D`9@y6s4W̢T3 L,Y43 Lfh& L`3[ӟxfE*hhQz~] = L4L`dyq˓m/RS'u0)&0I ̎W#Up&0ye}ɛE31U`L`d6 Lfu`&8}t4 ӟHI0o71W'd0{sJ0S/0U LNgqʧ[C]| LfvzۈH ӣxftO `48.+f,<%0{solAp1I3LLoWhCt3J<^mW3t 3 O`:<$HpD&0LD`"D&"0I"iD`"|0D&"0 LD`"&0 F&"0 LD`"&"0LD`RHp& 0LD`D&"0'"Y H)}IENDB`imsprog-1.8.5/img/exit.png000066400000000000000000000025301520775651600154560ustar00rootroot00000000000000PNG  IHDR DjPLTESA6Q;3~T2f>%_8#W2"mD&V?8?T1Q-{N+hA8L8.P?4jq% O#6EoK s ;r$1020oO3\3*LB8J@;**i3u-`-Y(E7 $l''] k0/j#$+-[#10/.`9^;O(X'32|Y:)'`AqG(yO-T4';1kJ-S@3ND9m5p8{AzAu=m6t;s;r:o7|Bq9~Cy@x?w>©l4n6̧j3ɴv=I~GEvĆMKz@s;**Ş{ÜzÙwѓ^Y%U#Ơ}ŌZEo5l-i-e+b)^'f$X$9ѵбyuЗbÊUCz=34_3o1k.T$##""N!>u( ûdzʲǨ{ۦx՝iaŒ_͉TˆR`OGHɀG|@<=f<34i3m212m0-.a-]'K&&&e%[%Z!`;IU IIy&(E$JHtRNSa]]]]ifd3#![RQ; ŷ~vsqoc]ZJF<( |UIDAT8˕ewP)0i4m(ަ2 qwwwNo&)pM^<{ras*úTD"E"цb_D"]Wn mpwmN͎@ m!vTMc# wUMZxK: N'y(Lx'Qa@^r`L^&\x/S8Vsrp"e4'G!_> 0Ol PSU}gsqOlzBM^47_jٌ:'R!1`qo4ڷf#MVh5LP0+;~ßqfջ!.po Z}x$LZc^B,屟&{%GCOh쑷(+!֦y<^+ǼAuAw]liUiY!`(Y'?ԆYP׏J=ޢ)ʢP) #@F~F F3O,m0yAɼ[g^Ff.g?0s2&edP2q̩YY0>2Le5RA_Lz2IENDB`imsprog-1.8.5/img/ezp_editor.png000066400000000000000000000547561520775651600166720ustar00rootroot00000000000000PNG  IHDRyPLTEַ̓vYEDEN')`! """ P֭JII>uZ&@@@Dsa# !o @eN4& ~ ;;;F:pQ.R(((v.e/?^7)̽+M...Pgfb6:DYt;}2 I -v0v_&554ۯp8qzi$QaaŶ8#?<>~1uk#̾+uWMNR:ё2W1Аr'θJuACa2 L I<gjυ8P 08 r2V sK{8'ݖGĖgǠh!مyQ¾7%,uk\&>Y|M:زw,K^`Ƃ?"Ν|3fD[4}ȉW'TҞjX\_ЬKj}ҽOyoҭĪ8Š(|rlrs+M{fIǪ!IB[tkMAgt1i&VIDATx͋@m܊R,=S豧 ^ʞ7.ՒzP_ 9ۃx)RhCI|g1iڴ5.LfbT雙lO2IP?I>Bi?$3f2,`v$EV3ckF>d!ĉdfNh@ ṕSP8f^Pr#( T)QU*s$3? n#sS̅If҄l;4x12ռeħ kĩxˠ7XG!\=s/cGp93|nK"@;x'BGJ$T6/!"# PU!<@$`Ӂy `y_?t׻0Ȓv, "{(¼,'>Dkex&y] ԕ.rӖ]5ń=v - l$?ubKw =HYm`+mH@?&yX%?pvļq |IrJ׽r㛮gҮJNfGU27U?ϦT zy~6K=*V7fQOAА njҠ2dFҖ7Z4vSݑ&:=ZL|W7:5MмuGYL1OBT1՝=U7u 岺Wi\6ڤVxKiS#`,yR\xA&]Zm {=UT^vȩ|xj4fd1 ODTzUL]>bޮӫIx'X׿^{.!qfÒ[=ҮIcQRcML]Yэ6ga *r0, ȢojN5^}gi*z7hRn{Oi((4 tyDX50%!~b Ǽ"!0r⎹X<ڱ@R 2&}+?8uuR*5vV4i5O((03iaٛcyܼʻT*uy敏e\XC!!?gTsvR|9=TNW=.е7/=]AC <:f2|Wsqv|[X(q=^9Á<CfyBRLmx9X,[l9( 2y![D 0} RZR2(((%Z,9O>祢,&X41#2URw7'j`3˺NY2Ӱ?w矐(Px&)h^p(GƐtN wM26xצ˗_?tG(O Q~s>-NQw2@,ϒO'oP=Rlx(j*H)Xme#ږIUq:76,ͯof\W4,i^ncTjXlNj}9P:uCQJP4e٦%S &2Dfyg%6og6'0DZK^kڎK)(N&Șhgrf 6 c* S|˼m~g׳A#ՃXIE->bي=۪y <  =9ykáWBT;<8L@%Nae{)̣"/K_T{]}`'64.\Jdr nA -J&8.iC9 U5O&eܼpXmА9X@a!6lR|2Ra^(\,V/DgH=ՋjYpȉdS'ӕO(n _罋yRtͣ\7Jtk DzaAh ܼF<8gu0/2/'Du5JgSiE3`ދyxyׅ r et2yЬh43d4F0=VMdT;NA<ɰ[ax@Zh@c2e̖AR y'\t<MyXvҼًtMɠ.tZPS"mrФ}(wN? R̤ҼWXOGּ˝,^ *Hy:n4~α]S'kO&CvhHT#mhɨyA0,`&yO\V]TU;YҼ耬yi~9@ȼܻ.M7]# (^.??G"e^J`y [+ &dr diw9˂aʺiCٝQvJgyبl/,X%&Eoo#HDϘ@*>qڔΥy0;lL= HygK'a1^09[^)`PҰ*|wC<UTin~hdO؆,̯*GPy b<@+R)F<# ⷁ ⷁ1BH6 *~Ky(U5O U/]k#GʃMBDYH"R.E Ti ’,6H.}XC2#ac0"!Mi{3+K+rtZ{3ooY̛=țżhb=gf4#/4mΞ_xf1oF3H?OS,f}ِwx++Qz<ߙF6M~Tng;2\OO3yq7'2šY׵OIxgjz25%I9{Ǽɓ1[1n|x/[ (1A y[wW}olR!m,#rXӒ/"o@#zIۉ"|va[# ҳv~jhljyco4oLG֎q/q`n < N0'Kṉ=ynw"fpaA V81KQ d Fy70'`(niӤK BvNjkb c_#u̷zghMiM stlJrF^' nxjۥR'o[xS6|nЛżi>zK22ż&ȽܲvfNG%9"/!S@w/oEs'ZEM^ԗӿ Yf$;6}'c=vc$n߯Oyo9`9Opv)ŷYErOe֌y٢H\?Fm*}i=X`҅XZyCD4f{[} ?ƣ "_/Jk<_S@OghF~a[76ظ3 ՘xiz3&a&yb^(_UraXpż[,]yĸ|IEOh&&dø!O=Fc"}~9!J|chDrZsLB^DN|dP2t" O삐L|;N͟ 6Niwvz*9&M|VGm?q.6<6H^bY XοD2<&`95 ojXyjNyL<jńĖ?vG߈QBD#y@J7:8~Q6dn3/-r 2|Im:vx?R;esrR!1 OZ r&xE0(z\B&Nt UQ$0n}km+؅csOzG=s:}`ΕǢjh8#]\׊L"eUG̮P,j#^ҙ1w<*ˀ.S1ɘ'Y:I#w$wYcW{- {a^&FʖV5[^]xy-g8r0| }ŐcKH"jn_i'%.ݺN4&UZdŎ~bļBߘdž"D:FYLV'[blt.~/T첗+*@7˪ j2+c@Y]<fQNȴ_bl9"p E <:S*x yaYu .7KǤlniQ`[sKAd-Ąy¢bʆ췰 ZvY-o9BQ`sdAvL,ACuDtJ!26Pq .tQWAe*#tWUqaوGUCz=s*;˼,P3Tre@(H_q6$cGWI,ic\ckR|X7UI7rhc[Uܮ%T@d{!5v */:=8w/DrlvpG bԮo0MNLpaV""mEH\܋+Ně|zD|!"oO@(\2ynceR5$lCcJ^ĸeȔ]ʫj~e*@b#/syy)rYnpAa΄_뺣3YWqh=BR@^0*GLCUiƣR:G^C(p;AbTuDr{#v&e ګ[<- FArӘw #ASTbO "۰D.Lgkx h@gyN(>q^t'(1/wF&xaJ {ދ+q`þJi:ȣA^;~r;AE9˗Xd4%myz.&,!](C5f~:eǏytv!CnSNěy zL21WlaO&HHȃu%sU9B~@X*0YLmHJ_#gqN(8C!')sah nr_&H6jO[y;9YIzY<Yb(+i{+\ {'P(BKBz VZ[JCXMT$ V 6Z!j%TJiL/1mbO5~r󐰷oٙ*,5UǼ6M~i ;2)8>z{/(Id'xǒ[@rS[ۍt1%;Rnj|t|yVז,͌3[Cϗw [h-ļx+kMF#O]*"<]9`z<1/Ѕ1yVync#.ooCQINDsık3j Qzؔ({aӉa(KWX gؔqƨKKr\c/6qB9.a}$WZe>8YnbKLN=T$7פԌi[.ȆoFZ/d _`Oޖ|i>4oswͽqc8;;KGb-?GB PooVJzW׏J-:_Kw#2"?͇jyn=@f@^oNl"eQFEĦ%U-XwRq! ]gsB)yƴ:.diQX-O^nԄɳF.t egHQr>;3G^bۥKv_Eb4as61,:5Jy%j届\׵ ~M{vi=cJ˜Wt)ykN $ߢ9 M~W3ah,Q^&1,Dku}Il%.@%74rړƫx>El{W^D5J ZdPnUZ_Zo 5לQGwYb+m /5y7*N.2&Y;F?k.>y$[{aڨņV@3mV܆E9NW2jB$o`PGp|?yۍy|;cJIuNtэK+*."Q_8n2&MOHHܶY0=%/&>VWjّ֓5 ʢA^2Hj#/юF50]e6ՒJٰ"k H%Y[ek.Hs:?PtR9!Wӭ~_Gey0'[֘=W!o/wB̋iiļn!m&׬֌87hJ:d }E9XNvytf"yU#By㗺2}]~m#m*jJGN_7i;cJۜW׏b TgxyMț !T V'S0exך V( }JM[JWpdj'>T4SDv7fj+] ]̓AL~؎ïX BW޴UبH5eZ <?{ AX-7T7R5 ej+^ bޘJAժV@(,5h15. ;Jj:(0zRXc.L bAy25UojVh,:%iSDgCّL bAb^yr5!UG4SsS'ĊWż0â2oa915FʼUD1/,iS`[EјDdL .ow[ s 1sc@wsCXSbPcc1"nySȣ1Gc^ c1"܎aa1"{'H <ܳoHށ1saPk}k3)PV/.5Ad-FPHȭ1kp؈AClc-y*jSs3fnlbރXTҘǓ3"10T"d1Ig[Ek1y*VybL Ǫ[ MTNPE[9zVh25%yr5yV!jpTieV _4ƥ(%єJ1Zbc,#jj߉uV %D, D! >X>B| }^6)39'1^}޿w߻n'\A:8= *?L(4 B\KP,K>:6] c(0BnG42C45N]{*޾ zEHByöD~+oo:ydKm$R;&rٝ+ yG>l+쭛9d+=#cmظQ=W5Y`7aupoI5h,c4O*WM^fIgq9[\ 4paǁ#hyZq7YuO[MvJ(Qsĥ6Bmi9 *B/HC cC6#Rm5*[ RD+1 DP%p&hP~cYr(`^0^g/ZE=-([ ) fi8;Îs- $F 0 b?vLD>ͱ6Xs ʃvzk= %AOv ){;ZX ez'-A84d1Sްs۫!ASFɨѐr`ٸk8 gg3\}Q`!1"AiX y7W082'yLZy'* y"rXy~=I?+Bi[]bh9Zy5Z7* (3?0 0CpkJb4@ _PH^fz-?$2)([  ) gA Z=KAΞtD˃&u4a4*KkXx +aW FypS +;NyKy?{8/B4>|rr 4i<1!ҝp]%UKD0 d*4~I8wڸtDT)CD05ؓ+KO) A6MĮo?nO'R.iO.;jRAvIL= y BŜ7 r D_9A([ ?+IyAxO`׏{AP1}힘tDNyggAKg(I; y^?i_{ipzP EZpG T g$ < Apy& D .ͲF? AU44aRkXB< +9 i[YޠCAxOLD/KADvT=OMsHhŨ݀@/ z4>1q|m4zz/ tOyL\ |A6MM9u@s# |A6 DިM*P.CAr].ANy& b oNUӔ]2sBU;/4i63ijsApmӔS3DcgeD:4iyha-]ahPlAʳzhPlAc ʓ-HyM K -ڴCO:'7[ž(On yIg R<<(-Hy6A6t8%Q^Չ 44hfomN(Q29+Jn] HYYj7 ANyA_{P8 +,PL Ƨ<4[ݦA^p?ۇV:AtkY4ڦIu6&A䊖N YƔ4{AvCe V\< ,o]F4{ AhGE r2+Dfrn3a(4i63hZ141gvЋci{h l<i^4*PlC ®< A@@ l5, yA@y²)/yW4(OV YyA@y)6 sy{zҡ<ق<قg尠'ʓ-Hy4t`M[y-T kҗh OOJd]ˊ;4QRKvܶe9Cj@?uhi-"TPhRAXM43+ͿtdIC)>LՕK>D+. B7ONq,)#짚\}ᨿQ5 4h95‹ cN_96J(4QYoi8Qcy2aXG}(v(Z:%҇K@AʋY4zfcuBi:`պ|$;WdDiI2[4Y~>0{'@atjh> w!2EqkA !BJh=g3,F5fZZyWI^]H$%?;e\s6왟;9~ 1hRp+ k5{6y _4Nŕ4ʾ,R> XC4h=D_>4nbߵ? o4<a^, _ 37I'Fu$#F<glD#)vEڦyep)Ͼو'pĢ[o.^hTub3[dN#|)2/fMghAX$Ļ7n+\;h:%wu Iy컪ɫ"mA,=uhΥAd<$ j7 @?zŭ 3bͦjYb̌h`Y ¹4˞' gԢATs]) yJ~獬gI>>{ ¹4k" bC~N-h} z@hq% g14 gI޽k5 KyI4]SCByMJ 9Uӽq``W9Nxf ࢷG4 ,m& ʁrN׵F-~GϴM 99?ONߩ㡢,߁h [4 | Q[4/˅4oY)b J֭\̪L|A(Bho" ?xǞcA$#WiZ`e e; B  >ڈNu&ylM46s4m'8'=]uDP!԰ ps<9 "r%P:q\& AhLw\x.yڦa(= B'A,E͞7fn}f ԠA=OUi A:=Gʓ :AW Xw "4I8," += .6kOdA@i 4$߁h vozx.s, jXfۼǤ4s. 4z g:ACm{ kyD ʶ4~^AA!9y{zIyxmTq5ܻӷGC(ڏ$<6&<8)Q՘ҢF.](-֌8ZsFnx9wʵn݀L> ZF2v]D4h.LM%u>D!t{M$ҎѷT$. qlEZ-hŗRGlU&f,ֽAT Ǎr/'[FD(ɛtwY anҦkyG[5J>ڢxT<<˩skDO⎇ߡuָ[6U Tr@q+(I+xM"$TBԉ}bQKs&3tLls^ga&"J + Z>@A,E8P~;0",_l¾`ɛ,pO0alҁq0% N9i&[vmR0"m89$Y2o6+Zd~P$y"=l3!f@`] g"eU.,$wf1,IW>¶7QP+;֚>ӊĐɳl0n: dmyaZ$~9ffm1t2{ֽ;>I$17  6]$`DbeUbKmNzĶ+Ӗ7KL<*>:*g<Om": HmJx y (r lLܴ I$y";4{>Z+7 5:d0y>*ͩui50]kG>DnR¤2&fWyE W3RG:|<Ž]3Nz̀NS ׃u..c%*:^|΁]L|WAͷu]/( tY>W誂y 8Plb'rGutC>#y7mo_IqgvYL^JzN=E?퍱B f&W].Ƙh$.D{7|Qg5٦ d]}gixC܊b 7bXOYIF4tUdc-E ȓuU87*'jĵ!NW O*O9CRDERԪ]T# ,w9LR>z:^dT~\zتaP#+:Glϻ yc3yƪJq\\7=O/D+@_$OKK>ȳp릔%޲KК#x lEl:N RuW%ʚ+Ojb2qA=qo_C:ϫ{I?x:NQ7 .E }Et~ITPz|9@'fTHd^-E |~U\n wOP,3WIENDB`imsprog-1.8.5/img/hexsearch64.png000066400000000000000000000066701520775651600166420ustar00rootroot00000000000000PNG  IHDR@@PLTE𗗗勋񐐐磣ᮮﮮў엗羾ιΠ~Gࡡ'*Νرސ𳳳ffeeedH󸸸ǛĽyz}ӪnmoePII׽ʭhhhǢ~~’Kɱ]yDlCɵĿwwx{jaYͧha`bRqA콿qqsvi[qX|fN6?Ba=ӧÚgps}tkiOX[Wk_TtcQCLOfYM*36sT3fTBrQ/&)3:tRNS!7 #Y&JC$įyqi9ҷ0d_ 0IDATXÍ\SWR鲶{'#$H d4$@{qmA@TTQujVZUv==/D m^^Ϲ{yKsn{t;w 7\JϞ-A젙Ŧ^lGϾ& C.-d9|4H^_ݧaDHD ybqה̝e\ƫ=|d}` N_7*ϝ쯩(:*_^( !ճcshGwXX(6E0a?Ƀ:sBY,lA b[{ܫO! 8 WiA4"Fp ZdZKC v& 4 XtBpd#ڥK֬=Ytƪ=j; [2ꁽ[?d~/:*,YTnu{ւ%YE6q~Dجwc67]gO9 3ؼS6ZCB&5wDHŒ%KFgp]δYj%4RȡHx%`З3B vqg|S!߬<i]ҹ45 `" p-56q5Gڞ>*&}fe%li8 ۿE_nh8En@d<pGdB3ϮĀ0`ial%, /ZWхQSX&8uAJ_pVT?*Q-5ᭊ+` cw@&- 7* Hk 9_V]>!T*SMh Gʓb*·!*uEɸZUe$r9\P;}$D nY3ؠ]:ܰ` nMеQ߆ Rᐐod O'{ڦ:W(&ypa(E*o ST t#o% j@M&{DCj*?iz0D=RuX5 Joub4|5nwANC -1UHc1&ejE.لVs";Zj]j2xe=pv/pi0AB.QƸ\v.\'yTnqR*Q- Tr ΒCb>\Dky*%x|)WQ^^vtQR`}m 3`mMJ `pנ'/TBۯenΟ${}D7Iө@Wr[AH[ f?;Z Tq[]xV/4,$-T8" vB!glpwDwH`?]fl7uJ$Sb{sۂ1uʡX\uV:={ [_P''f́.ٝ,âM[0̕wGX< r}|}n 17fHs$7F(%--IkQ .E0#݈'ږ `EcL"ƌ/S imwhI8S"nH+xf$4 A_dd"hPA^x=\8*;TF]8ɔ Ғhg>ss)qa8D(W|=$\6萩7_JnsKolc]=bQuS%m4Wp=5ƾZ, ;O. |UG1_yvu&tS?~ox6||PAVz_IENDB`imsprog-1.8.5/img/import.png000066400000000000000000000023531520775651600160220ustar00rootroot00000000000000PNG  IHDR D PLTEƣ};fȨή!{!fҾ%6tRNSn+nnlDxgUípol`MA+# Ѭ{z\T74] (ZIDAT8˭wSA/bCG@iֻǙJzi !!=(7{w{Fٛ{y7KwuȤ͵:e5GleimQWEmu!ь$IDD"GKҕjxfQgJ,BK,+Â'7BXB q г ;ʯBAR!)/.O7 䥆%oBħ2@R&`4 4PσGS̬y5ZHDH:0ف(э ΂B9jlP6ɰcd@ /)>k߲ڟBC`:!E#PuF\A~~ jb`Q(c}zý珯>yv9"8LU|~P^jri#-&O!7C^$"$O?2 8/ *{:.Mhh d`2:}hw %ygh@ȇS5"xm蝝+J+JP'r:l^MjtmU OZ0lYDhJ Μ:tpwVv/uڿ ^p~IENDB`imsprog-1.8.5/img/loadBlock64.png000066400000000000000000000056221520775651600165560ustar00rootroot00000000000000PNG  IHDR@@PLTE旗ߛ֋񦦦ꫫﴴؿιȓeeeпX^TZGE7-/4(OV=5JJ&ž[91b8Aޛ֒AIB?B=@:1$lSWHO=+3 ̰LMҍr𿻶+4۔q便hhhPVOR# Ήz ڙ\嗏vcX938Dž⇇wwwrsvqcT"ߏnnnibr\XI?=.35 - -~Ѻ涬ɩըख़ܔԎ}|mӶiehLOֱ7lj4C0t&*" ՔA& R!ϼěːԈɲxuæmaaaVSR[B:9O1(ÎЈJ  ܫ g[\CA]@k<Ԝ76v,bnޟ կյ• vr/*1tRNS 7$ [D%rKڽqi9.OUIDATXÅuTSQ vwcLPN&9JAABJ@얰w{k΁]v9wF:4ogٻi=UѴeF ѷiLF=h-w޴o}\.Omi\Klb&sL:M+ IW 6wQJ^Rʰ#xlrHHbCe˕i}.vL*f`D!! D*fcHYjrյYA$y2f*,_k#ɍ3dPY4nM, D)ˁGRJ;6!ʜK#}k "}0(~Zf ,b|"Лd!_NM!rje+d !@3W a-YNCT}\`뼔 =G^\ZJEiGTrT5ly.X`؆ =0 =X9|<2e fn`|ܒS_x@r:$?07ĵQȖH$ȑHN?Lܚ?{v ;"Jj!=55 6C_($=.l z7 % $„M1N.x'|yuQNO,>}*bSBft4_$5.mҙO:v((s<<<& |YڄLlafBuR%3bf~6 ^=+# `$ડfΥ$xPO`#*8 L7/!/33/a'bު/~zGWzy99C?ٴ8!|؀bsЍ 4i [W9xy~%AmX De&\"@sU<NFD-^|aoOHvuwzo` 'Hrv'gpp⇓tva y.@#ceoAwvvr.2 Шޅ _ ܸ&ϋO<0vGz`iUGo/h.~v+B;yy;:RM`qpȏ\ƺ۝a `Gv2Un8Hnڷvak&4 lR b=!O(A 6 6փňf  .ϝ{F(@3 qt7DAAt1npƲUh]`4jnd6 #zxzGl&עNi\.M q}67=-]f  fpҗnpM/{m TsbMٝ)FfMT&ɂ??ϡl;e(F=6mQ9KXG-}(0g^iJ, , :֞my(B1^c98A@:~T0s\2ptX[(pWlsL (&nHl! _ Ƒ9-vL{؆cj`kGO8q~ ia&LlQHc!<84#; p1 .NEE嘌6,L̈.VTn2TZ iDW)FC =L t(JfiCNVNIENDB`imsprog-1.8.5/img/logo_IMSProg.svg000066400000000000000000000065301520775651600170240ustar00rootroot00000000000000 IMSProg imsprog-1.8.5/img/mini_logo_IMSProg.svg000066400000000000000000000064361520775651600200450ustar00rootroot00000000000000 IMSProg imsprog-1.8.5/img/open.png000066400000000000000000000040311520775651600154440ustar00rootroot00000000000000PNG  IHDR szzgAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATXíW[Pgb/nٛκ;{z:vTpuֶT mQB!@Hs$!grB GTx~0X}g/>ߗ]v uH W*e`[ '3">vH~Y2ϭB9DQ臆={XSR,::NI1>I,`]YSMM4 1y`Ż?ū)LOϮ׼tCO3@{=.4W S2^5C`\&K|H$8As''H׻ "U77N,V>V:q,k,'6?F}oY1~ Z{?0L(CF&e-,!4{Z;~m$~CF=5iu?PZlY]/sq 1% cbjC'ݼ-Ӱ;3&SXO!,CPF BBsZ*tȼE lϛ'Ào%Q(/bM$"R-BySt < ] /yƪԳs LŔbK˫#7G<<b~/=/-:C(QNܿ}3i 3Th58 X\3>GelAC'b ER$nPD΋J~ m['Ѡe")(Ȑx5 >c f]KcNzI1N[;|%jJ0("3 t.| J*qQF@7 jH7'@L{RE qAAͷ]lC(N#KQWHoXQG `4QɫgA@?noiқ*/ru)S)+vQŕky8n3cjs@"mDžPt +4X$ |J8aVU;:!z/]&o8=cn*F׃H:381 ^QO`+] 9g=JUmCeS@%`+njǩD9|6ZZ8/95j'zLIdnFڍv9,9=NrG ;Fc9=pOJnX,P(@!F.[! o<<5iEX?7Ǎ: !p5U!4[7*4nI:rsm$Jesp)>|c.2*\"]~M 6tvw䈶"I m2JxLKIõ.|me6Y\Q{ %&6ǝՂ^NEXx]\UPuTA/ rjQCO-H/5z-Wxܯ\u˯Ev2g`§ҩ;P 9 /"mak^2/f_=IENDB`imsprog-1.8.5/img/open64.png000066400000000000000000000127101520775651600156210ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_FNIDATxԛ{]U}?9sL2$`KbU >j"ЊE,oTyQWE, _# !0Id2guǹd<9g}u-z{{k OqR)Vi_s[UP(aB2h8PV)9s0{lbO>@)Lt:^4662gZZZD"(*>ڵk !ؙ &ٙ~:!^^6vwZz7 ݸq#tax(X ԇ˚5k*TG/$fj".Di w踊zo㻯!k* B$aŊϕgG/m,xCJlb{z3ǃ^(4r0œwW= )Ee5#h4Ypܨ6`ycLjF$I0<υ_g; ֺf# v13nF؟ +h8̧_~(6\Ƕ}0fϞJ6559sLIa'WOiQsy\CiO0 gX,80"FIu%$VXTe=“oؾYs')/.VJ)miPb1<ϛ` @<=? #OJ:0{X9}\HV<#`JPN,fb5+r `H!8PhH| %ٗһXZy 1s-dh8@YT$$RAn|#C+}|~=oQѣ[LWVS~:7v,(y'b(|*MG|8]E cC\@P%("1J>O\좒{|qK3hOa#srk92pv| [8pHdCƝ?)@gٳX-m WDbJEsd?}5})~R¡g}f]ϋ#;cͬ jVx UJslVZJ6b(vt8ݍ9ʵ](Q>5ij`pee=:ue|&=w3*FM(ŋ:R\/^l\u) ?bfL"yq:iJo\8e~'nGl35)b{e_YuS@- MF8Gg? Ɉ4Nz1ή/ӻn'YKpO.EbY^F \V;Y 6(\nxN(vi yJ=00aKUJSX''J5 3Iӎ=qB A^~m߂u.+=3 "Ɗ,!9)1Mizu.f0T3@ ; #+F&5C͎G ܯ ҙj8 #[E}7rN1 d)4LVr`z g3y Mq|bQzFz?l84-3 P\k=99l@fSSd֒h4$P t0 k̀:ͫcA)2Xk J>BztxxL&32rŮ0y|]Ejs.mBZg|?aahZ c ,@o`:1EWill$GI)sRk=LOOOϨa&O0N|;Fgg'B#yc̲eX|9TjJX]xop&zpXk9~8۷oe˖q饗n }?mW(%D I!gϞڵݻwYd /&LV<?ZA@>gpp}ՅR+W|;/zXk=!vI6m08c眳9t5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z'fw^?}@ 3^yqrz?^^yޚWZP҂r9=GsM^?}3FO%='W'sNY>5=}oy8;Z)Ez)Qzץ''GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn4=|zօ'#w>5|#^ @r1͗_{C< iX8P_5 W#u:ozۥzO*;ZS`Px5\se4=|zօ'#w>5|#^ @r1͗_{C< iX8P_5 W#u:ozۥzO*;ZS`Px5\se<|WKb@i$+K~?z_*”[X'1NOgpWft^߉3Jk1у|ֲ F߽^цV|zֿߊ_^=շmU-u_zu$pn'm&"P )_)x }z0Ӿ!>;WAԯ ,B^d'$g0p_kNl^ibgMovל1>>|CB# Fq>'Q0$p^Pi?DUu߭!~^%s&CHfmh&|4뀞ґW?ªc5 m5v>!]݅oڹ3s2ǝ?ŷWgܚג?+ҥ)~֧='x5m'_zSKc`rx=OcI#_Õ+ѵǕc[˼EլsZm⍢_;*F_VӤ,#H֫ƞXzBޤy>2x*+'m5F9ouDԁ8?৿6S>)5ǘT߰Ai;#+ϯoچ|s:눗PGPQ?eT)vaRY>Q5XTj2F:ȃ?hluh|G~ g{ι|5JxR5-Kĺo;ΉIߖ&2z1÷lF{osּFim~"M/en IIm{= E1 @Ȯ/yI(<^:u*,.wM|y0\НL8g6Pa[JS[旼p,O}i0}k'xv~{Kj~2)?=n2E ࣿ>:GjHV#nDsqG!84mNDK;|w g<eIWSՓva-NգJ(]UQ8^.u|8PyVŬ- _0(ﻟVx5\se4NG'}h`rx=OcI#_C@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}_<9<Iϭ} @<`עx5\se4NG'}h`rx=OcI#_C@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}G:+NG'}h۩I^z|z2Tz}I QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?}^x<TyKGQ@^yޚWZQ QȔxw?~yl_//{@ע?*]@Oǐ:+@$e8Ȕz?4%=}oyz77_w?÷T>@Oǐ@$e8Ȕu=}o KǍ}30iW^!tA VtkI"uY[3O+M?Jҭ^Y`iDH 7Sn.%gWf$diggb 8ъ֖F/K-sh5Oѯ0 X|Zu JK )QXsΕlDgjNtp ǁ>_uMJo Ӭa#KUwHs8P7sjL MVd[>"g#SbO({~_5W:$ZD,Yum6љP/H v? 5_Y_j%zgz顈>t5^ JT2[[?: ~Ydρ9+)xsY2Zh_zT>yjvi&ӵov7i3 _H=gK|S[a=oϧH3_Guk>vߧ|t[O#n^{ csOüRX|6}]5=73"m*f?ɜk|Ra;g6OX$/zOc ؞?Za3+p@xu6d>LH<Շ5W Z%jEv=eA뷱axe Ϫ: U%32Ϧf+3 TO6z[[Gc:O'pS7ק[٬d*2<5z2?=3ٟ~?xS\V+4{1B!ϙy@O*zvy_ěˠgK}&gvKt\)¹{\b0z*R?W<}\99ԝ(ʙv&ma*J򖑼cMw_A1izAǑ>ߧMz_|s/kLʭvZR8ٶѮw~!kZp #To,&AOհu -t֍.V/Χu|M)$Ҝ[Vqs]^zCoGV{2+љQH% p|e9뷁wũM{46ӦLEiB,NJK'\`<r~>4| о"Yjz\Pi.' XJ)e+g ¾UyUpu0*־ɻI4잉)^gท R]L=zW"B,9$w ީAIS\W -!+%ߌ|{,v1׼'oV(g@Dɬi佴T<mnI-E2,RȌUՃ) _SPf𮺓Y#_=ͽva T*LAFCa>oSOx[)3ͭ,/v/:[vA eo엿O&INEVIOXEY9Uh0ug/z*E?NM3^)CN>Y|OrX:8dQecKkMB|EQJ%8zy0:Xbmר_CמA=x?G"WDzyzi_[iG'GG"RqL?}|/;yU>ע?*]@Oǐ:+@$e8Ȕz?4%=}oyz77_w?÷T>@Oǐ@$e8Ȕu=}o KǍ}30iW^!tA=x?G"Q QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?}^x<TyKGQ@^yޚWZQ QȔxw?~yl_//{@>4lzy瀁U6] ẟu=|zր^.]םעx5\se袊ẟt'>>4lzy瀁U6] ẟu=|zր^.]םעx5\se袊ẟt'>>4lzy瀁U6] ẟu=|zր^.]םעx5\se袊ẟt'>>4lzy瀁U6] ẟu=|zր^.]םעx5\se袊.I3q2-u}—0h^~&XuJy"O(f¯5 NVi5/.kXشM,+6v1$-&ѿgx*_X^5)\==*骵'k^գ+ݎf?g %kfYgV*pXNv횔| |[ 558NQ'ɔuN*joǖ?xzyF֞5U_FBxW­l*7Ãx_Uބ̃ArU6/>.>' 7L"{۶f}WrY|9=> ߷mdk(? O~ݻԾ'/q3)+Q[Fh5ӂ0~<2={7c\~W|3^_COoֹY mzMؿ.QŚ5m$ѹ;~?ң̻-qk65ux-8|uiyyoiC/u8fTwi_e_?ʫA#noߋuXOJ۷o!%at)z}8zP]#8E15.&ֵda^w}\")сaq_?R A,+L'3xvev/Imc4si8$?m_*7[[k W:MÎayQ|ՕŻ9ΚH#>1丈br;rnQr\EJ?0nEk'Udӱ'`k~(ZF%ƯxOĶ63ZVѠE}&_#Z6O^Ӽ1 ϩϥVizf5-v,6SZ@]0_Ğ$/ 6֥~栱eͧ3I$i,o9t` :e`A2 C,2#eP̝yթN uiNIʏ$N^ޖ;Ecïp\׏qg.g]W%o%gi uK+,]NG߶uosH[U| ѯJUAneO)ªuS?*irV`cM[­ \a8?WBtG44sL۸N讬5X-.#=h&E=Յxku?Sd?/,">kMߊ8W,^> ~_i7Vk&n?ִ%Li|O}2n<7>n8YSt>+ ~hpoѿ˛AX}+bo}cϠZ>_fMվɛ}O5)cMeѾ_=2_/~<ɾ7Fk.s+[?F{_O'Eg 5׎̶9eдiIB>wֿA?'پ͌}HϿzc>v+&AGU?c˟tC o]-c 9Ҿ5zJ~)fqpk2Lٱc3ױ G>Xcu0 fWA=0~ky|Y\INwh xp}8_˧|뻹Ӧ븷^ jVJI%=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn x^ w✶|>@zdg?kwcMO>r$'4>jeXo>L; 爇g2~!gW5y78E')wSj) T1`Q2zOriH[5xO>o&ֵ'B[EW+V˰kAb,fZvr۶~v7/BΚ96,JOzrFrk}_~DžZϧ,ggq~F1z5Ǘ5? QYu_mJW3kfX۱FlYjϠOZ>f6&l-JʗZReLpr~_a/ʗYsOMixb}XVTwga~m3.:~ѫ"~߇KAk*c?\_?}m3&?1l7YK}y}5S=4ok_ӑ/~Ҳ8_?jJ~}qeMϨYO#ínʛ'#YS?iM?+2c?\s_G(B/. Ʊi_ܮy? ?JS/WO\xZ]ULԷ=7㿊uy:wSH)M=ѴG/S,O C J8maqX8=y|fFG-<#//mK}:~H KǍ}30k|U+#T j9!utPH>5Cu?S(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ)_ZY"mdpB|de#[Ǚl]Y3چUOv)Ǹ lj "TgnX- my_2rֿV\xõ)4fk:Rj]yR.z {oJlj}IXg}ƼBlWa ^_ }(0\Yҽ{5ckSOs {vxO4{~tNykM -[yMSڙIO3IzIKh/s?ΔH=g+"clV}q"S}z?~$ogJG˘SZ3OYW8EsI7~ ɏ}OeFWa㳵>ÙVTg?hy?\>uSO{ ?f_O??]jLx8$~F%8 }¹fEo=7l>?YW?*gWU`ۿf?//_QW>I"lf`-&fq[}{??#,6 Eao/_w%x<'j?]QO?=/]\+՘|3j_R×UIx-ո>?O"Z=> x>k'>s~'C>m_-?Ld?+队'O\>x?D j˯סמx4s{+Cx?Rr9=Gs@{ZLClzyIJ7?Ҽ'f>XSФrz־0}k<F9ouu=$ +J:+猟SU'#w>09<?< j˯סמx4s{+}Ohz= NG'}kjF@c.^^y@ҰqOtCx?Rr9=Gs@{ZLClzyIJ7?Ҽ'f>XSФrz־0}k<F9ouu=$ +J:+猟SU'#w>09<?< j˯סמx4s{+}Oh>_<r9=GsE}O:JѓJOOGDǽ4:F㾙g~_ݿv @vG:xA?=ǽ4@)xf__oy*Q???. ?ڧ]zǠ?J?= ??ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWH9m8ہ_?օuUeLy_'&OG)կ93zdqִlz+"clq rIݞ[[K3?7Ì?{ZzT휟\z%=4Z36S<˔ǯ?8B%n 9ʲ<yݿ_mu?{?ƴQɜ<,ޭZ;k?hϘD?19bf?1ҹ'{ / ʔ\~_є}Z~'V~(`߳OñZb|gL+;!pg>*_٫ȝLŘai#oN<(x5? <~g_Q>Yǚ a{qXFjݭ[R/` q3I >џozHxg!&q^q=2==k?]eHP~{SHJW/;&o?,f6xDj?nu7Q|Ϲ{l2[ +XGQ_#$Cb!e}S<{J+J?= ??ga; eovsJG:O@OKx@Ey?OGDǽ4:F㾙g~_ݿv @vG:xA?=ǽ4@)xf__oy*Q???. ?ڧ]zǠ?J?= ??ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWHƿVAQ?w< K)GofjФ^`3u~(f}sOCOɿZ=~oJb{ $_'#~^7 O~uNٵ_*4I{~'WfYq(͖=}˕'Wenu3`{¾Rn }?V┭>dJxӯZ?ϯVT\{/Ky~l1OpȫzO?eN8sMnǽK#>sUfLyzN?ƯLcex,#E;tlΜ9ֲnIOWnXv?˕'8?I/{hmo/Nݗϕc&Sδgl.9?`:ə^?׏*_֧Vo~(Ϙ?k.:hNyp8\z۷GOK}~~Mn`˓Rn뮕(g/ (ꚿ:&׊<ԷŨ*ӈߚbeSk k8yg5#/Vf)O |,nB"Ozt9|Wc?R>v-j?IsqM[N_q} (?c6ƪͱvGZ!xK~E?ሴz|@}ӭ O}kwW1?¯/O6]5_;?D j˯EP O09<?DMWe<F9outW O'>_t~_F@c.@EP O09<?DMWe<F9outW O'>_t~_F@c.@EP O09<?DMWe<F9outW O'>_t~_F@c.@EP O09<?DMWe<F9out}G>@u?S)[I@y@ҰqOt;?DM+{+ΨNG'}kjzu==$ +J:ҾҀ<'fIϭ6zt=Q@y@ҰqOt;?DM+{+ΨNG'}kjzu==$ +J:ҾҀ<'fIϭ6zt=Q@y@ҰqOt;?DM+{+ΨNG'}kjzu==$ +J:ҾҀ<'fIϭ6zt=Q@y@ҰqOt;?DM+{+ΨNG'}kjzu==$ +J:ҾҀ<'fIϭ6ztul~7o_Z k? "/cG)p_KxH|¿8HWo|c 6<:QǪ)G5UK;uK1Ys^?޿l}C. }gÊ8/xټ~!~/>8n6[–]9ґWmr_xٷ;a?yGp<|F?*V'c|پ"7cA?N_3I;kVϭLUnm]9?ҳ&lƭOϟk2W'z!_37~?rk^2퓏sWVd͒O\=~\Os~\i~pۿO|r??5+rO?sүu3`{¹dݛ~GӯעlR'βl̟;t+*ẏîu7]vn }x>o^q?[}?sM{hmo/Nݗϸnβ98r*3dA_Ok.VğoOɮYCE|O~(+rOzAY37zp ?3pO}dJ1C%Gu'=4vOooo7yS9?Iusuo7.sx_7_p}8n|Pj?:Oxmk^o7qqS9 GW 8S? }?7?˛g۵Ilvo㳟+T_Fbʞӊ~X?^;P}OL Y^$zs<̱I5c?#?'Gj̯/#cߌڿskW1?/O=$ +J:ҾҾpSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:r9=GsE"QE>=?*=O_(hJ~PqqL?}|/;yO@OK]5_C<x<%|z#(~DC@ QȔxw?~yl_//{|]5_!ASCx<%ס@x|z#(~D@+۩I@Ǎ}30???.t~_'ؼ'9foO!1OL~~3nx`Wcjx/?S jv w|FnGZgo#_0?|yI__wf]}} u]e_cO>PwV? [69^N?ֿfJv`gqq*n#ΒÖ&zf^msOE_>ρ9ҾCЭOjRyzW'ӏ,A;v?Z5k-?#UʭN}ӹ˕I~WI7?`ioܩ3vOɛ'OOV~>}}MfJ~u7=<6o)N8𬹛$ Vn ?r}}MfJ<~U7pwL+}lY2$^UY36<iv|w w7~9[d}NOqUٛ1U_*唕{xmUV(tYs6=[5vfx2V>'8kNɾ[Ϸϲnz{O+&cA'îk2VOzA\{/]~t;:n \UwjI`it^)_w&cI~;?AW8'R@]{mdi4KVQ/&;{޸ƫ~z-Fq?zWwh~>:6? 鱐r>_ w([ɑf N3P_F-{n%KY?[?#C?] ڳx\SVOǴ6O#Qt;'>>}ahN_Ǡ?J-ɐ?P@<rx=OcI#_D7S?Β<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQ4Bfohb?pO|H>?¿}??"ο4xM_Moq7+p:p3qp |^-fD>w}$ 8sc?k?jSnjrϏӃJ*bʝJ Ǵ}qd_\3V>i~.>-]@a3YL]tG־Y&>1x}X9?M`8[gkޯ̱r(I7xRe2R js-UOaY>;SI'f[>^<ߒ?HKzvVp??ʲ~p>zs5nW$^?5+9^+Rod{xz{KeY<Vl͓9?2/+6g9y 攷vRV\ϒ}MZ'׏f|p+n}_sOnefTcBel}2}>^1?n?ə=?7iܩ+}l3A[\_W&o>~ʹfmsm-ߧo?)[z˙*d͓9?I=[Smv?KtݟNS7Rg_t?s qFO|DX d3؃޾ߑOvuOx{ӊsH5WejW_swMSM\c%A`: |y~}omN,j_~"k;jx:|wu4ڇ}۟p4}g:\u}y>| ˹y q_J^Mv?"Z=> x>k'>s~'C>m_?Ld?+队W)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JS!ztWOQ@CS?ΒdĨ?=ғ@(M+{+ΫѸf__o C%Qξ<x<%|z#(~DC18?|}oO^'e>F? ;;+N#w>lRk\NMA&)E?ίp򇈼QB1nSuPngKSn[!"mN^0cɜ?OۊԯV̗7O#g#;}yo|w)_=OA?M~;RN*N{H 088w amB:izZz$C3>?͕p:On1Sls׿׷7enKB_ֽ5+O&x0=SY7aVy VlOs~?Z_C߫+>}+.w#8zթzn+$?zS\wv3KmzidVq~_$>2?lρy?9⹤ߩaYRg!YI~sVe|}aY>??sJWmsOn}~*Oϧ[}?A533sW$}ǹvYRW>}?+2Vݹ*_?:̝<7[[G/z?5 pIt? ܂='NO|gOx;~k:2{ W#YJ~MV:Ho`͢J3ܩn8x"ɾdoƭsjQA"MTR pVڶ,$a9A.'L:k8X|y$c*vB\T} /sqqq+if%Wgf>?S_2OG g|?:ŋ~׫n1O8UuͯAS˳YG!"I$$VMC"?ɛ=K-64;sOrd^+XGQ_#$Cb0H_>>+sT:ҾҏOGD㾙g~_ݿvG㇜үQν!ASCx<%^x|z#(~D@(M+{+ΫѸf__o C%Qξ<x<%|z#(~DC_t~_F@c.@EP O09<?DMWe<F9outW O'>_t~_F@c.@EP O09<?DMWe<F9outW O'>_t~_F@c.@EP O09<?DMWe<F9outW O'>_t~_F@c.@EP136w; x|o /~s3Fw# sv1~AW"'PM o?تIĜ{y"J"f9 ֞p ly#\灜 +1ۿB #8}I_F4&dͪϤpmJx=+}haބJ [kRK#xK.Pn9uVX>YO7' ӗd,n,{d&$x?zY;?qYɞ?2^HGm=篒"IfM&I}9}k6WGs男lhROv!Oyf$8J͚L ?kRտj=ۮd럧cAYItʧ ³|3nJ本O-DI>ϰ:t$ӟY1}÷&|簮i+wdWOYrIRj_'²|s>'{#o~5hGſ>yV8|aV3j[cƝ{K$uS1]>[e:E׋Ci,N᳃Qda-mW7|5~o -wc3-qms Mkum,1eK4C >:o5]5^aP[ Xm--b(;r~q3 Tgr^89N8)gNR~2Xڵ٘^noS)ЫNtriӜ*{GUc(J}~5?M{\7a?:Sħ?MM9eGkp ~gau~4۷c ^34ݾqھn|x$nb2ⷎ% o.D}U4zֿ8b*7>ZrQݻη,NļE*jG3 48mz/j[/w^w#^ @r1͗_{t:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{C^?/QΊIJO:JozۥyOz'zi_[i^u@Rr9=Gs_CW }G< iX8WמxVy>4NG'}i}G袊ozۥyOz'zi_[i^u@Rr9=Gs_CW }G< iX8W_z7G^z&i5ז~Y[!{۩"5/$H $Wsl5W>tn(g}9)ͽƧ->mc,Ysg|C9.WkuJs-8!xŜ Fi:._j52szT3Q'iS [VuM?GumFL"i l-A{#(rR+@?c$^!ۨXJ *A]j8$qq$"6HɃwI㞡-į>+G;MIvlm=5FN#u qX~ s~1Hu_MCui#6N5?,MjE{O.UkT^WOm=ֽG?fKf>+x%axz -Pi'*k:V&5Ӵ;p꿮tbJiv|XA!n4 h66?xE {bŘ:Wp?쏄_5 i{췺_|^kEm~ڪ^pXlmRW|f#*$'> v~ߩ,} _o%7];mR)Au~&_Ǟ GO|1P3>(\5~H_xX`iЮVqgcĿ_~ x?wVZ|}}j{[ċF^R?O8h^ |#-WWടMcY/oO?2ω?'KOӿᄆ$ 俋?q#Q?|!/D|Q&fO_˟ S~ğ"?/u_^?DOW՜Ho]v/G|K4 N?r?X>$k)U 'sj#T|DJ`0kz_~C787'g c]# D l|)fw:hf:Օ8RT*Pi68Z>*ȼ+¬ρ<<鼹SrXV?eŵʭzUqZBܶ5/ aI9Y1|z{~I2ڎ΀LK;r>LMF>85Pwog[k]Z;mBwmaE.y4-*0_]-CD,mt=6Q-Bdt&9Unf'Fd("ucHӧ':Uc(Ùs{*YO~[SI+ Âqx8{>QxNc_^;,V_GmȫcpXq)]~hRV+WI+98zz W?q̞N>O^p;WSYI=Gs~ ?a׿Yҿ{߿sJ[vG[_+O V\}'anɟoYMg[>͑ 5bg}~5<s 曲|[eY_$5+O?'קf݇ד\}>EY_ϰw>SYRI>5nw>:V\́?sMnǹ_ϧ駫eY_?ZϤ|aֵKm{+.eWۤovȥAd`Al翈t6$Ksx"Xb 98wIpQm۸qI~%'{[];}eWJG#RHF4d,[hßV˺-ǃW%E5)_-<AhͻqNǖ:<l8xyr(t?lm' #5enj_)} ]Y+BM_.s;yk\?(c#ordŌQ3VE_Ź3 Y+V k9|I|N{ś9W3|:)̿%n|<*v7?b-Js GI?௄PxׇS]WHwIfpz|cP[*Ƕk'WEz?Ob}\ng/(fG\C/˭-8#سX? y|0r%1qMp uƅ'|{uuad9l&)i1Xʼn>񳌺bnR5{L'{|GSZJ~^gpHH/]zs٥x9so|{Cf濎S\\v6 2 ,RMw˨>^W=}:&kjmnj3Zixoѧ`_ |K}+yPVwIӵ!o~w̟r"ozG[?eϮڎ=7 ig}} vUFO:>#jWS~:eC+i%s>3~xg:Xk<ĩ=J+.?菍RmfC1M [H:ѳ+“_r#NO#_P8U^KxOii>ʒ$I7 vfmٳlo9v-'-R#~ k4[CT|#N99ҕ쑭Y7Q#Jý07|랄ZoOۈquD$o`=uPGEt_/*mSu̷/6ENu| kse\_X8T0Yfѓߣ 8 n=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKK (#Y(QY/#8gwf¢,Ĝ 'ߴ$f h:2{/4-1^xf%Y\FmJw! ͳ*F[̱НW]I/v(Z}9}Ƽ59?< ³C Bru1R OԝFoƛ7]_Q a$4bOɕ3q-zQ/>XU/0X?v5NO?@o]ޱl~R/ҾySq /bRYa2[z|'쓥7 -@[?Z'Za`:]"JYN&*mU[m՝g*vvlU.́zi>&@ IᬃuF:)V-yxOp:y=?^ό _xT%vypQ/kҾ#C_R*ʲw{[00onڿC>)q&}3|g3z%LZǃ5h؟q&=sW5_)J۹b!Qmkܯ/e[v~X|{QZk6>ܶ`}  wye sjU7'`@ ;@+> Ƶ 鎙W֟Xq3(\UO)KXMU}NSHѧdGos7EǸ*-j?5O4.-, /SSrX9t'98YxT%]$FGFJ0<`A_:M[FJ$@}/P.G$+؁|o=@Ѿ*] /x;I4 ?{i}Ju fyNO9Q)թr[E΄i$Sx]`jԧLU\.m\dbUu$}>;Ldz{JՏI_sp4[=3_#)_E^_h !ɻ#?_@z|g tqztvABY;>y- ;_vo,?~٥>$=+6I:yzӞrngB_erɀGs}g&zI:y穬$I眯ۯP mm< ̕}}yK,$uW#?_$}Rݿ{Xz[ine~ =OǠ̕I?StjyힿVl#yyKvj=./ĂWs?_'qsgׯ{du{攷okKm;^vy~IVlվڬL?ϯƳf|g +RZW'~j˕sfwɛzpkn/==='V!Cm3&oI4"[kͰn+xTT^k-:xo [O/7]&mRU",WOhX6X I4^7׌E~)x \p-lGfbEJ]K /zR UIyT黾E4 qepxw tcȱY#R`1NL jԱ(x)ar{ )8+}f` =G5>}^â1e},4?xn7 kźf?4@3`_lqE'XUԂB$<jy.vJޛ6w#lKwn1T4MCCGVGɚw9(Zʀ`rjt{#f~-eٳO? >p{>vϾZM@NI5ɲI*YV[M%eɁFݤx.>R;w'Y:7y]:h ؑM5nF= Zbc|>W!:y~Mcڱ{Sk8<$U-hRKQGS3Ly=\fXڭۻy7o  xz-/Fӓm㚙t jRutEP> 1s~' z*RJ.ѧN6z%ό;Vfن[hA{M?N¾|I=~V!8Tta77(bQi6\$?K;<k›~S$NyH'?SPOg,._JJyPK+Z0ӵrVV<ˬیi҈5˟E?j \< .}Iߢ7^P>W=L.)7З=bGqgPkUғO}91Q~ɗViV s~v j[?x=~c=vgj6~jA8S2SᩑdeU?Ǘ'Qg`XOx6ոLjh[k[f1#ZWÚLq.xDaėGձpMxWIx߅91i-RB{<:.nG`5>s~2 >%gFYhTz3יīVܡ]oKG .aJW[5%x4-<fy%Q+crr? l)f먧]M|K$tnGvrq_ğ#h߉Qor<X 3xrYe+K |Vn񷄴{"-6><~8Sg$WMHUC{6BO.O <IO3ˀkFVO)M7Wjbi%(Eo/-EJP »e/0&:rV|_69|I% Oχ~-!ORFZ[I/- hH)!W< t {mͶQG"捶͏Aٿi R3EJosPx_5"\?Z-ׇIkK֬M\o=2_KZ97$budwVKٷ.A| eJ?Ե [v/­c=%Y3ek>0d-Uܲ9yT.X$a'ڕj0=oĪ|gØ%7x=88R&uTR)jѧHE.l~]bq4GQG'GG"WS?Βb?Ѹf__o C%.]סA=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@z<2?jzrEzQ9<?I@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}_ƿ;k>iZ|8qaȷWyw]32xxJIϭW`߶ra<.: < 1GA7?Y$>,C(JZѧ4tQb? i?[߳#x"|PG=)&Sk6 *oOE4HI7S.h}Ms24m:+;r|zkiqc\s~.;g->T)ռWM@.cL x98Ӷg@faNC,* CA,0 &30 )^jc'e8SG>WǕF< ødOC ZԊVR[~mt 7O~W~~-iK^~Kc>6u"|fp?_G~kfB[i7G ӏ R.veOm[*}7W>Կk_[}ZY$۞y{}k:I3OR~oZlu$ dIg.}iɟ}+>I3pJR~yz(wlgç͚M|sޟ4?x+>Y19'=q+hz(~#N_ooAd}jIds=k:Y6z\[=u۲)?l篾O嚒I1O?ǿ?|u$&g.ߟPn|p:Vt`oK#$}_l}A\[/hRO˽[vC+'?ɬ_zL֦NztMgJ$gx+-{8z[|ߢ׻!<}?޲~?SsɫIOqZ͕O`?׿'ڹ+%6{Xz[iӶ̂W$?;rsY[W4k˯O^w{t)lۦ?m_H+fk:x[ߡ4Tb$>BBuCAA^=;=k2gxqtqX]^?mEV6gdX*=V2#6O?li9 JՋ,@~5e韵3s$&LOR$VK3eCLk洼R!Mܿ^ݿ+O)O-K6>>/rPlN|adO?V&g:tRZxdoz-Ͽn?cDzn~'o_G\ݓ9bT>:{NWs>ϯTO:p?+|YҿdYݗl4E='m87{1QurɵoO)G6C|qW=| x&#.?mm|V&A<"2: p\q+?Qw>SY=?gpTn"nYr5]>TlxK'/ CkmbNHo 9u8=XLt>~__cXxUǦ<zWR }~lǓJ૟^sɿqozt}^ O h[xk4k{>vw\r+l_>g#s0hbjofYnh_J o0aD9=}Mx=,5ř7/Ϋ=^ { <ᬖpJ#o2|]wj|Qn񟈮}|FL5^֤ _S|ugtҹϾsֲZ^ORsҤ e8+˰Ih$/cJ$3Jz!k;Rh,$w(}W%Үm&yy׏PM<4}z0wiԍגw+,&UFPTQi%i{8?U)E6&O3O$䪔?*?Ц <>ٱeЪ7&7_Q~)8&mRw'J(l!u2Vk[kim&Gd>* a(KK gOk7<1 neмkg4:崳4heP[q,em–/0a>F+W3(>AxF{H|} &s?̰?/^+>v ǂ9|MsjRe%_ ҥl<(c-B'%>$TʹsL㣷6/pV1WS `rx=OcI#_C_'y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}G:+NG'}h۩I^z|z2Tz}I QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?TIߵ/&s,u>{/e' m_f]W5XwI=B*~6mOqFX͎?gqzS=5eEoŠp62x#Zn-kyˋ?gřpjf9l*%)f}OVas&?ϽXm|/CiQݏ> YeR~T0?Z;4m;~36?Oj?DeVs&vfy^~.Qݿ.?ZaTZeJ=+m</W|)=N?SWi*LO櫴u9=_b:ӯq'/='ڪ~YO[^e<>Z?Zy8UO)=?0ǁJɿ%nwS?}VXysU9'_ӭWy8׷_UG ?_ Rý4ۻbi$I?*1Q<3'TR{V2}~zm7?"Y%}:5JIBvG$}>"I&rIc)7J ?[}II8}ITdON6II9랕JI{/XWmiD:I1FI6{Zl?Ssֳ<ɬ%>/N >ݽI3O$8__I?U$?O[_ѣ_/Y3:ӧgM.8{v4 +6I1O?甭}ztZ_ d'</a5$O?tc$g&2Ig鄥o6֣Gm?lc$?~fe$?Z|n'#OZϖLϯaֹ+i}_(QNj2Y2O<?o$9<z|g t}}{4ۧ?yJ-/ ХSIoS8_9egK&=+rw#ءKnr~QG~5<`}]YIՏ?sVu=ZJzz3YҾ8O~< K#$3y_=OA?Ms]]/SڡKm?rHi00?;eTI=NzsYr}3W4?'~ȆW#<Z͚L }su}y_Ϯ?V\yuivm[A+zǧ9ٟįOaOçOSYS>F~8sM/?N&?_x_*į}|{~:z瓻n-oOm>kEi_t83>N3S^be|?_ǩYKvoOo4v+L}+2grMZ'qYS>IW4{{xz{|Oȭ+Sx&l ?ZI}ӧfJN}q{}+n}_sOm?_բ=?߷eLcujW'N+9^+oKw===m}?]=*8YSr3o_}O+?\S7wnao~߫]J6N~ʨOl߁?ΠY;=QQH(+ǬϾv`uW!#@O#r|U?%752,RNxj/S_5sxuopݙO+g_FbA+<..{_O_Tctr>q~&M>BqNbh7h 4n4Yݚ=jhCdt1H0zr9?ڀ>)|7ԌG'W>_ho<1L{Wt3Dzf*ө~=y}3rq>PS7|+Ԗ9ŭt]O<| !'*z?4%xVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?C#&!_tP7S?ΒA=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{CwiW|bY]>6WI3W~Wi?iOJ#P~|d\?͌;3gT2jmO?G?a~\~➇"|><xKqMc۫ds_=6?gAo1_\g  ql?y;Sv'eC=u2?xfۮO>_T~/j(jN,v u~TԸ}x{3,zz<<9 ?ƚf^GyV^kHU33c/''V۷7޿n&r}5 J{?˟TV$ZiGv>T9EuNEJRO:?`:֢iX P*]N/'Dp^_G/.~]x?1P4÷?~4u$P=3˿j}:aM^Ɣg^ßҩ4뚬ҁ\~Vnk_m_ȶj~~uY'(?_ʳrowe/Oo>p?_玵Q:z?JSǟW_AT >sRoKk|Xy{^* ώM@?_9RKwwB|39=?sSLg~y@zT䗩c RoVGJ_;mII9랕FY?:Y/_^*y_Oe6Z/Ş*io;kc䓻jg$??$RHNy?ְ/oR [O{Rs?͌~K7a5$'{)[E^~;i/?Iy_Y$??$c$QLz?\%+y];i_(^$??~KߩK,=ju{_>9[;i_9=^d>dNLp9'?PL?{sVo=jv~~vHl:[?gI'V?S9'{c$ORQOϷ܆I'V?V|ucg>Y2O<?o٥$;/o~}+RQOҲݑ&I4A\W4e3١Km?}!N?f&~ï?ҦO>k:W'?ӓ本=mݐO&z˕r׷zՉ_~Y<+.W$Oι}_D?z ͙1O?ȩ|gǠ_}q?קs===?;`{ǭew?įI?k6WIg֟&W?_j̝ǧ2Sa}}|{Lֹ۾cOZgw53vON Zs+O?'-}iVw?ڲoՙ_9>+6GOs湦L0t"cE]((6oTv;Z+׿ EeJsW|;d 1[_똮Ç"^?ҷ |/ gZVGP(X~n,mFĞ?ݞ9]O(sӽ}!EQԆ?qY~+֧gfpvg}&tSq_X,m5;p`(-G>D<Q?ZFxĴ~=]5_C< j˯סW O'>_t~_F@c.@EP O09<?DMWe<F9out}G>@u?S)[I@y@ҰqOt;?DM+{+ΨNG'}kjzu==$ +J:ҾҀ<'fIϭ6zt=Q@y@ҰqOt;?DM+{+ΨwSm+|m/3|gsD<ϡ+ jkByjˌuݚ_i[-c޶:_ +n?٧G  Q~qPѿ؊oO q޿ O q3rx0ҿ/ؚmǂWo_' o q-$-Ͽ/x9.$O龚4 3Kxz>WWd>0jh:ϱ/W4P~ضzdz}'e1tzU?9IsX˽;a3~s,{ gWOw԰_֞K֩*3)IUgl:a??.xk ^o'e/3~fzߐ}sj]E?k5y迯E:1c~}Zf=Q4{zEKo 6tOK]iGvsfi?5I_\G? LON?O5I=^{:aO=eƔ?ÜsSiGs~pOӯsθazSBt?ǭSyIjqr?OwbO|(?_ʫ8}UZaڲsom??u<>~ZXy:>*OU9$rrO׽DCT'?e)~,iPYI'v>QbxR:IKg=s~%>=:46>I1rOZ$䜟4%|?aRHI<kI+N EݱIԓg?ϖRI4e,O?S]P^??J~VAI$oɀ{>$rO2Is\գGm?_c<A|nϠ8$y*g_}km;i_(^d9ɞ=)d9;뚡,=kRݿ ;i[uoQKӥgK&?8I&2I>%'q\;i[uoWd#??`8&2O_Oש6Y7{OXJW}^rIgҳ䓫|S Y7g=+:Y3?\Җ [;_޽~8,'wR.N휚Ε??男l(RO{)_$y٤$?sSM&dd}O_=Rݿ^gB/]dS>xlGaSJy?`wEZ =O=xeJ[=n_o^۲#9>ÁjF}O 擻ob9bɅQH((+OL8;]p$q__ToC(Lz9ݏs5p|'?^;ҷ=:8G> ypnj<9F:ȼyLzb)~'iVe7['~q&E2 ]ֽgRԄW/U#ZmZUߵ*zˇwv@=!~H52!(4OlVY=$ +JSOҾҼꘇ)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:r9=GsE"QE>=?*=O_(hJ~PqqL?}|/;yO@OK]5_C<x<%|z#(~DC@ QȔxw?~yl_//{|]5_!ASCx<%ס@x|z#(~D@+۩I@Ǎ}30???.t~_#~G|7Md#'~h?qxm$T@`wM~7>魇mgocԡ%ak7'VYzvl/n?1_ߵb;O'B~3־dSIZת?3Pד =D<{7SL8P7o_Z,]gy}_e'M08 v?g'R_EMwkCD̿_3L3zfU>ߒ4m;~]߯SE<NQ4' 37 T-/t'7˯o_.ӁNO&`:sMBғC9L0^_oկԸ%/o5LO:ҁ!=Gҡͽc}ӯߩm=6:ǧ(NU~>Ǿ>^~u׵m?.sN:_=֪<8nVy?=So[cm?+OS׷7e?Wy=O?|{UW?ڲsKm_C˷bw'O^?Udsǯy@NI19sZRB 뢲'`8˯TLw~C<U9$3I%*i6DJNpp?OS^s{_\TO)=?O$+OiPO۷ЖIB'~C%ݞp?$II.{{a)=:4_6]v/P:ީI(z~L^q{=:zJI?SO[o7ojzh-4yLg{=ϒLp?ҒI3?5FII8?+ Jھ{=:4vQZEL8/QN?ڒIzǩle@?%.nlzh|z z|c$IOsrOFI3p/hOBK'V?U $I8Y$I:{>泥@?Ma)_/Qi~,3_+>Y99&e$?rxyJW=;l#L$XaRK&I+>Y2Ov=O\ߒ{)mieE#$3yd>=~4H? ͕??甮{4)mȊW9?ӷ95+㚖W?Ƴg>˷5)^}dz~Ȇi2q?N1YN;?M+#?gJu?Ͽ5)nu==-忡 }=Me&NïsެM&çsڲ|<~^e|یVl}><{@{l`u}'9o_CNצ^ey#aǭfL8@T==?=Mgv` 2kWTm}?w~~M#keqbjtsھ:>?GXX,?'~![b~ù!ʆIb}U;Gy댿W|W}HA-{S'_C;"nO;5gŦߧx6}wjG9i"Rf\ob:_̸׈3c"3 5'd{5҅1u.RwK65{}*}-y_}FKE9HGH|*ʓ,yr_?Ek*X䟳9o]%-Vz߯zWcu׍Xb!$d hŽ:30S/?1_?؛,~]J=Gxqھ˕|}7PiE|/ꦭS<\| [͞0e'$|OfyM3/~Y#a%[3(X/)e?3t9?OT2m4?Tffǧ3z Tf_s9ƱyJݮ7̽~o}sNPi'u\cOҡ=m7O_3ӏO*o~?MPi^9 =?.}tC _bN??Wi??Qi_PMf~T0Zȸ׏SjM?,jJSp*?!8ǸVnko#}o/Sv }jJSUy*%'}3 vEw9_5RIUW8Vy/};v/u*Nq?nP9'>zsU^R{&磊O}= w&y@NTy1Osy$TR{~E)POmՓ6x<3qT xzO/P>&w SoEYҡo&rI3AT=g>NYwte;hҥB-w$P8xT$'O_lLrO??T'O\z RK}[=*T|%|_2I$ݞ?͎^X[y#ԣCk/ ~&'$ yYJI3p/(OI&rO=}$I<?~'ؒL=}<=qXJWK=Z4vQZBis?oS߷${O:I1rOZϒLgp?ְ/^I&3ܞ>Z,s==d$a|dx~ׯA\[u=z4vrz&rOA5$=OsӤ9SA\[u}סGm?^64ïsg'>Y1$>=g&$ް/У_?>!#YJ v={zjIdQɀOs泥o~$ucgg'V?W<|f-R)d<>8ducxR&IB|_ǩ~_?fLw}ҹe-==-/oDe|{3ZNI>lV =jqQH(((7#ۡһ*FOF|0o칥iz>_`גu~IT9c?@?!/-]gnOI|?Y|%GK-/Կ6:qq";7Ѕc3(ht/.{@|i, ŻvA>ŀޞ1 l|_L^%txtwsxAITl5uQfzߴ_q,E/zg4__\V{ݣ `rx=OcI#_C_'y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}G:+NG'}h۩I^z|z2Tz}I QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK6e?ώVO8,Gwk5? I#˓'c.)>5y 6^7Ŧ&{GBŗQrTǴ?JKƘW㧄a~W.V{MuQϳdI]xRK#Џ3.KgJDH_[Yj8W{jwdB ?ok @/ 3^ou=ӢmcNA_],v#U gJ ՟ӟK\|*O͠M;Z^Jlezz{{75~~7oX+{{Nzyx_ϏAo>0|N|wC:1ꈧp1[)|FIoc$aN+\?BВ[TphGVQv)ׯ9{,5Zz_}L7~??fot3zבk ۧ}37?o?Fe'?+899gTǿ#ߚ责z~QoyvL37=/hἺBLǾ;rC-(E-2Թ0i~^i? J{~T?Rz?nߦk75wY ?/ú̼([9?TP: '?*M<uC>-rP?.櫴?cUP:/*LOOY%vSnKO(,sӁ*'zǶOfhjvZZki_@*NqI3:w>ϖL?!\[_סGm?/K&I=gΚ\briK>d}O+R{(z#Nÿ{V|# }}*Id{qz³\[_ءGm?/?ol̖Lz=ATI}q=B|S 眭߯ХחmJOYI^=K#$3yd>=~9t]7f-m;lH|dϧ>ϑ3ךW>=9U$\ݖgF??](:B((((G?OE?Vn dأ'+|,1eMR|gPQRZ4TW^nT^]G,o5g'>{Yet!?qYH_O0ǷNx?L;i#пh!sc}Ԧa:7\yw'?~)um޿ͯ|?)eǠ?J?= ??>ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWH_t~_F@c.@EP O09<?DMWe<F9outA1:Ih?[N۱#Nm|g}ylAq++ ~_uS״]l c#Y<9/g9=kh xڴW^IwؿEfc/q._)Ybg$ʨ9ۿ1'JWo~~>&:ǿ [\!ִؐoPϙ"~fW?엨 h z3ג`8lW؞TSp̑^<Б$x]I# ~3#⹬ԕ gaKr2%*pt#KեxW*vI=zJlpO@B/&1pFr .ps޵Iڍ*MYeI,ڂ̄{o"7BOpE3]Hy2dv,I$޿JU<Җ21$;?tL+ѣExU*N|xxs-֦M37\OZP(ԼmK\;JL'j~>"ȓlϽѺGb?~X#SO_?d[:X eUզ]WsĎX~yekp~ Z?}3]m4\+Qۦ_hu}S݇ L{rgWտO5_ԏʔ~ۧ *^3 ?&̣1_˴?WgFbzqE@{?&vgOfмB{t4Ʀ_OĘ8Ni'tIX/W cÙm|1[oo=@Ҟ~Wsp~Q4Sd~?7ҏx?ҡ⨿JSӿ߳6E+'Gn4gW[j,ܳaq?G&v?Xai<-ZW^O"n=dyӻE/\÷~5Y'O+#LSV魎 R"qZ1fcsQϿsoEoqs v?{ Z=Qy@s^?:8ֹ?^:FꛆAԬ2=4 y_ᵻ~e 8>YP}c(oŧ ߏSy8U]I?⪼=_SYInvRMv'y@9?5QOឞ?  r_UG$?_ׯ&;aOuٓ<皥$g ~]?$g''=>5=Tک(>}{U $SϧkKez*|x_劥$OaL\~R^~~'c)_/K.'$r}{RJI</6I@<g&rI>JWmvI7g;J$p_ZI%'88=Oj,sXJ}_;iuHYe??YIOI%'p*$+ J-#գGm?I$I9'$??~g$)$a甭?ZA&'ۿS޳䓰>NrOgڨI&8Ұvz(ndnBi{z:YyTv xt=j4v_u$?|u$?)22fbw{a5?4E$dqˈn;wksY6ߓ){ۚ8_zq_}5d'3%$:V4*MF޽6vYCzEpzb#_c(Myv^k]QQ`nl^?:?Fܲg>v$o/C z._*&nW::)UmP(kKA'[3Zi3=95+~'5"Ҏqt =s8_S}sMlsS} Qk]TKס2(:o뮣u^yhieK4h-_2/_$?<3JIMzMgwG9vVS*IOM?imGs]LMϋy.]N?l03n%9=&sz'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{C^?/QΊIJO:JozۥyOz'zi_[i^u@Rr9=Gs_CW }G< iX8WמxVy>4NG'}i}G袊ozۥyOz'zi_[i^u@Rr9=Gs_MށXxhhB2.Y7 -oHү\n3?>XQ;[|DxLڷ{U񅭺k>-7Oא Wc|Ajf1F|$SJj2TܤR? a|=φ& ,8b5alU*NoJt0Y\jՓ(ѕJ.20; Ȋ,u݁15lnk11qӟ~Gx=o^*>#cwZuS"7孮*N%JD~|UAisqk3̭w]c Ik#k[@'d,Q)7U7RnkqM-]_X\G>qBBNZ9T9$ҝ;|S#6]ź|Ay%:ΙZhZxe: x\A

ugҊrΤ﬜wguk ~Y[qUJ>G+)'YM_)`?0}h?HXqs?M,ORh?FyD5!(Ǣ]+)s1UtRM'k4N=ElAo]5ng)s혞>$"\J ~$_~+Э|MǗyhm8Wx))Sծ&o'I*5^Ԫ?HK7/E,MzZ:X?֚HM}k/Oǟg]jlsVgnKO'A_י>aqjSͣ gyE=w8ǹ:a$md876a-tTY%ԧϳ:=+fc+Ck$jZøM!$N1aVuz>#߭jKA>Jk> UI/VMNQ_?(]6[8}{cIuM:Qմ E4{d-a{]$g˸maRw4 xWÈC40۾)I~|d麶R{~uQ:rRu%tӴvwZ.;2qWd>i\'}UyIzzWy<ǞzU7zsۯ]R^oLiޖ_"̓Q_V2ҡ֟$9$$~cr};ojgxOXuc)uoJ ?[}IspqTn@NOv?QLrNOac)7ѡ˾&rI?8)9>$I8,}a)E~zh_ޯA:~Mg&2I>$9'_OQ\rNOSR~oR ݓY$I9'$??~g$>YI${[_QvzHI$oI1FI1rOZRѣ_/I1rOZΒM֫:u6F$(;<֑m7%H>}T~뎻qSRQ~?ԟWNҡZ=:|Wݻ?RJcpzrkaH ;$dhĢF.}UE;ku#9DsV?ҋ $eATsN}#m9DI yz/ahV~(O=-.?ӏ?Zzztg/*]jKz׬f0X_n\=WC׳(QZFO$CJq}s*9*'KS.o?,|cEw1KuÒcf+PU/RgL8k<]YTyǿnÑӟbUn:z}'o`ȠȊ8U/HKnOۚ*_RvrnHqSE5l<%V6`I)?NkMNOa@UحS Q(oű&iҔʢuz^ ̣8N>7,;RJ F7YYoxwvHI]Tљ]y#쬣1[!+ y* 99Wd# KŲH#]^H 犍*RU%ʣVItQNWoDoeT2:ζ.u)K ET]ޫ5z'-9ZQ)oKx>n#2Z3&x$Z{}o]-ܸڗ/χ HwB4NG'}i}G袊ozۥyOz'zi_[i^u@rz֊E>@|z2Tz}I QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??.3qoq\C-ҼSC*r$mhȌ)*A"xn4iM4ӳMjkT5J|G|[?kK't+4STFݎ*e_:\_~xºmok$!i A00]I fWmm紼) 'U),3C"r"1GՕԕ`A"$h#7ï>%=~Gx$~m%ýJqpζb7Լ'ʻ:Vz=|bjx~d7Vytg5(ToSԓ%%y=)s.JpU~O*.bQ,+QsL,-NptcS U*|sB" Ǭ=E_j|WX3&3JX,B82]X|֌r-7`!\-}Gxþ&[z~n}399QO /U%ϠY4n<&`R. 2E&z-R#//]"]i7zχcmMa{*4MPӮ#d鎀ߋp9[UtjF*L.!-7S,ҷe}dYif=kakq<'j2jakZsTtQ[!O|HC{sv}O=N* p @Λ7<|C)A^<LVbXJT5/ |.>C}|Ts(>2}mGh7g?{ucoӛxI~JӧoNhe.Go{{vr}>ܰym~4=y:yZuOb$YCuG.7=q2"n}b[F'iDvc(Tp⛉Kx%1kgԂ}CK?A&||uc;~x^凯)ۏ^vs?)gwBMU5._s˥nl 1\,vN-9=?T )ߗ^?Q,q֒8(J1L5͟+_۽[qbX酨jP]knrUt_3߃>ig5Y  9_GpOQ<>{r7? MϋnI& sƽR]~Sk.[>JVϝ{i|c?zǛ~4gSV3 ~@Cq1nIɃmn:y9k' wL'VQ G kqӗ'~?s^ۯ#R<c,/w}/6PLڿ?HL? [XPr]Dg .9vCm1,R_gvMf?:}}=?AmƮ<m%f{9=:{Ÿ^5]KG D-Aװ :!f1ʓ "(aʭ7V9ߑɦһIvgv2 Bƭ(͸R8&Sǚ~Zy7:o)wkv0gu#MvEځg;k4ˏjZ}pmmgʙ$;nMyUdw+ꤿ[1~1iS:2mun3wgl_9Sy:>O=* c#۞;Ugv9y?J_|rgQ5 OSOΩ8}kM-= T6k99?Qbs?td<ïOCZRJ vMY#}=jcr};oj9&8<'*x>e&o=*46v2I%,N?*@~ڙ$p;RQ{OV[wGF[w.?U)$Ir$nrr}}? $V2[gFEՎR>U %^t=QQ'OҰOVAK{^BIv_I6{ZϒL=}տ(Zi/$޴z1j"#*,= y5'9hgeF-咲Z'4K]U"}~~A#ʷgEkn:X(&j^զ}G$=}?T&@?MQ^erO=?thԸ!=2 >w?纚$؄4[̕$eEg 1^R^NwmS8.[xKq*r\u(B0&Wgm$'{ђN{{{ kFxpTh¯U ݣ2Tdqwħ|kn8>nG$ҏ=W.޾Ɲ%Zk>]4GPÎnWkq.~wIEhI&2O==?ldN+[ϊۯlOG"+<G˜g9=ڹ g-Ї 뿫OO k;`q_[Q+8˧Sc{1s3SC?-;-os!~Gu?|2_𭉿mYwl+G%(t' *?]Oϊ632'Wo(z&10n:Ls?O Gϊ63؟7)_L6#ֶ+OC?Zw [Tο?\د7?_TW$K8QF<)S:x_ޗ?Wb蟮7_f&bSgQ^؟ |ggn0FQdwn|gY` N~y. HԸG78RUa+m.~s}"9Ӕج~:MT8|JX*jZj| u$6hx z qk_fx?7RY"LyY;{RV[Lv]f/)?dHtO 5\<]~1쌅~moW4:/9mCQ<I*w'[UYxz ϐ_b5>#-Z466dᦴQnb)UNzr ttܔ^&J~+'/'k4QԸG+QIFኍ UIzt}*kyo x;O4i>1U4nc1NHeuX]dK =lx^p-adY. ˨(JkY$b+/i^Z9ͤ)݊?O3̸ˉrd]/x4()u*4Uyx|z#(~D@+۩I^xw?~yl_//{S!ASCMWe j9!tHXSФrz־0}k<F9ouu=$ +JUu*ꮤ`GGW?cwdsq+^K$ w75o'fIϭa_ Cp14*uԌSgY%c2,4qYNa˱+ZUhO!c=y:ge!lxVx;WQ^!\,i'`ԛºLoW>Q^n j2<ï*ImeIOrF_ckhq-6jXϚNn9~|>M>>`6x?H%DcWJCzgQZJ iX8W'&۶'g?HkxӾKH_՟>+f<[;.Gco=07ĩNma\<9߭~ܩ9\#ZUrұ~ʯ YZ~&fYo} s#͉|E>1 Ϯ<]c=k|FۼG6<^-g7n7|qrkxKckdY^̈́>}* tf?jvp)a |"qjO'5>9?j pvrut{CΩwoljq$c2Q̟1a YFGyqͻ;;޽6&5oǃ<fL9zHV9ny>52(9.R2"ڏ8x_x OKJ_Ϲ:bh9|:8̺}ԙ?Z`?F;gO>/ogt;Z&',/:G7E!7 JIo> k%i s jGSOft`Ut'USA מx4s{*%է2]a%۽:hxJx|@5S1LgOh-"Ytg欄UN7|u1 ƿ~4QH'KxUp^)q]i+{6'˷5cJ^w[ſJŚ hswo5۴F(-6=K{)/͟m?yt[k:w\__g_"E;\[c'$MyI=97f>(TeAdq\Y~~e'yImMƕ(4_qct3-y 1'Iךs| W=]4 N~G>ý]yz.veSȆ=:Oi'bz~'<L0>QO??oBӁ*$w?~sKm/'},;Om?i3ԓ8T?yP)9<*ˌ_ϧJRKVOB ^rY$$8gtP2I=$?S!XM#ҥCodI$_z)&8L\7[ME/1k.dIGagri<_8nGep&e?P?k$R=#I'>hx|_OZ[#jQֽ'ێyF1&We?=s~~ ?i#ޕ?Övx'Kko(t}6$V;X1Vsj_g^qȳ\W^p߰ SЏ>4zڿb83E|bL]z*ӕLM u䒔!9F0U&~5C^>ɲ9'-+2IQ䙦'-RJ4c1b\Mj՜):1N_z|Q¶%X!*$l =}q9Z< iX8W'#Oyr/c=,e9G91?}OiTOQ' ⿗#?dL|Qmz"O?V=_Q'!xGW[3_ERiM0g7ŮYiWIJ7?Ҽ'f?E<| &7o:gz_䏁?ȿx6~ș?a~)9S_Ywxysg=>([av^,~zLGm񆞿>Ѹt-~מx4s{(S_YwxGW[~`Ñcc -??ȿ}3Jrz֏?E<|Loux'"dS3m3ԟz|Q¶墏?E<|&;o:gzE)ڠ-mi`Ois}+{FS8'>\0``/~x4s{+}Oi/ ˥[Lq6zkToqlχ,O|BU-n$póZ vƿc~_Q&tǍNDŚ`sj OQCx{ %:&W g,<g^T7ŝP3?8jq|OQՌZ41TUH.>e=#}v"tm: IZE $ƫN9W j˯סמx4s{+IE(($I$$ItH¥JNZV:*JSRrms&۔mCx?Rr9=GsL`rx=OcI#_C@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}G:+NG'}h۩I^z|z2Tz}I QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?}^x<TyKGQ@^yޚWZQ QȔxw?~yl_//{@ע?*]@Oǐ:+@$e8Ȕz?4%=}oyz77_w?÷T>@Oǐ@$e8Ȕu=}o KǍ}30iW^!tA'<ŴLxk'E/\_1Aα`HrNO_.zR[z_7bw?Qbs?t^\=!TRzp=_V2z=T6+CJ$y3~ˎ^orII=ߙe;_Rۻ&y'_AU)f?OX?AT9'}/ZS_>ztmu/k$Ny^_o)$I&2I^o)$$XJVo=:46$&rs{~&K7acSe?ԎI(?;V2V=J4/m?ny/d~ t¸rI?zWYFݭ7#'rU֕7cKyz'dŝ̌Ag7¹ Dw;4w]Wõ2|_v3qq\Ğ3Wwó^3k,le[ 3tIjmm?^$Ն3D)5-Π[9:f6xDj?nu7Q|Ϲ{l2[ +XGQ_o ˆrX%E~ >7h5Ozi7I3<{J+J?= ??ga; eovПsJG:O@OKx@Ey?OGDǽ4:F㾙g~_ݿv @vG:xA?=ǽ4@)xf__oy*Q???. ?ڧ]zǠ?J?= ??ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWHynL3d]URs=y ˎXj.V2VF֟ɤ >&y'ӹ~fP3O$?S!YJm_=T<G=:w*^oQ.zp~L]j>>ڱϷ*iZvZI$dO>J[ ?S_?D_Əõgx5_`? SfLy=ϭv}hxK7o3QScttGKec͏ h+yqܚ\䓏lNMk%'zW4СxAx꼗}~ /7e?~uQ?OçUbzp?[U^P2sq8VNm<>oy~ZnXyII&_C*NǏW_AUP;[j'Jt-۲MY;OSOΪ<A\8yuQ@]:RV$zmMY3|_8U$'obP3O<x%-ߏSg_ҡM$S< $֣yqNI19>[5}z4hmuDI$xN?=ꔒp={gLLO?2~?~WDGH늡$'O$$~I'8;V2տSӣCm?{8_6I2 u>Eba}CIG[KgOᾷ_HmJ_7?i'}n7ō.]S?(q[LfvG>O~3O__G3}ǿe~?Ld?+队5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVTNG'}h^?ǣ'%G^ ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??.p~'?g?N~nݦ|tcOS__Ş5~uz^]\7hxaƝcc_6WP0g8)x Ng*w8('zs򨋓ӏQK͟Wx>BQ??j͞?OO*S~N=&v_rOJ_w,<8UQ'=:UOSN}qs-47eŇO៦2.S~']'zv{=qe)%z)a֚imk3ԓ9UR{T/ O?>x)<?c)v= T<z"gsl7 ?ϯ5 ?q&&y'_AV2z-z4m|ȚIҩs^.] C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@z<2?jzrEzQ9<?I@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}_<9<Iϭ} @<`עx5\se4NG'}h`rx=OcI#_C@y @r1͗_{C< iX8W{ZOQz'U6]Ǥ`ޟ@E|3Jrzր'>>5= W#u:ozۥyO}_<9<Iϭ} @<`עx5\se4NG'}h{ !?3x߷C @6gf׿{oK "/cG*nj_5ʜ#{vQwp83?e}y {f~Eg00b?ZJV~en99z]\GT_Wr4;XsӪOR{VS?\!3 oRp:dh<{#^4iI-]ޯ?DFG,0=Lg9=#3U^Q2Y?S̲j')>WVNoo;XyIxO/k~1Sr~?F\~j  x>k'>]vc(/mc]s]+~#.1دQOGi}!㗊ɫ7SԔ_-?z'U6]Ǥ`ޟ_F~6zO*;ZS`Px5\se4=|zօ'#w>5|#^ @r1͗_{C< iX8P_5 W#u:ozۥzO*;ZS`Px5\se4=|zօ'#w>5|#^ @r1͗_{C< iX8P_@Oǐ@$e8Ȕu=}o KǍ}30iW^!tA=x?G"Q QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?}^x<TyKGQ@^yޚWZQ QȔxw?~yl_//{@ע?*]@Oǐ0ȋ:6xv=_5T qx#|O<foO&~~<8nUy?ϵ`_^ZZyIp;zTysZx?*'VNMziջYyR{ׯ0ҠyI}:˯5rzp?_d/'}<=?o瓓?<%v: (((3?'*~)1_Ovݟ/ "^>j,uqzŁ?ޞC"?M| 3|q ӏ_Z-GNz|mN|9*b:o8Cg?QlFswa{k!^5gŅ}4(7[~|z#(~D?fpG%|ԩM'n' 47O3ŧUӿS<{J+J?= ??ga; eovԟsJG:O@OKx@Ey?OGDǽ4:F㾙g~_ݿv @vG:xA?=ǽ4@)xf__oy*Q???. ?ڧ]zǠ?J?= ??ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWH?q89g%礚#۬ŕ1mu5cc֕?ӰaxpQ}c\}}(Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U>QEyIJ7?Ҽ'fǽ4:)9>Wx4s{+<{J+JSU'#w>U> ;pJ~pO ^?-K.OCӗm(Y1+ߏ^gW3lmDj?t?r P?NҸ2v닃:R/QΊSѓJOOGD;n%z77_w?÷T<U+: ?ڧ]Ǡ?J:ẟt KǍ}30k|U+???. ?ڧ]zǠ?J?= ??txw?~yl_//{S!ASCMWe j9!tH?]uoFaմ}|+GzJjõ]6_־ $w}6?78IkSI%_aI(6@+K eNqfGk>_=zn7\Y o6թ 6}P#// XדmxWV&}GV֦c 4ۂNI+T>=x?G"WoA?hl| 1 M-@} R@~'K2Su__ /՟GK8` S]el5VGz?4%/7_w?÷9EMWeT j9!utPH>5Cu?S(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ|Q/㦍kޗሼa,|Xx"E86H_vqmtW5 pQW"Of׭:󤎎!zU4#m~U Oo_7]aS=/עGg/ܹuS|SUAzr+BpQ_iE#ҥ^uF*J*/ hS ѽ!kIO3P_?˟º/D^d>TO*O~>@^K>Xl㑑P*??u~Gy ux^ ӡ{Wl 싮=_IXFiƥ ū8֝5RZ9,jZ\a׈GLˋs`j5r6. .߼Mtv>x?D j˯סמx4s{+?0='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?'>)9COlzyIJ7?Ҁ='fIϭ O}i0}kz(<F9ouu=$ +JSy`rx=OcB;Z>x?D j˯סמx4s{(诞2}OiTOQz֓F<@c.^^y@ҰqOt;?E| ϭ;u?S+OFOJS/)?= ??ҾҼga; eov?*]yQz ?ڧ]Ǡ?J:ҾҏOGD㾙g~_ݿv4}GDT j9!ttWH02)v*ت3BRsT­*M}ڎZy'[m_HGQQQ"FKµX3s9%g,۴'/%3"Կ"cj#]';d|їFkB:VfeϹqt}c?y?[LG;+SR??aJw&tg)#I9dC[qi?gԃ×qoX#U`iס>ϔq4䶗4iW8OBzơU6#w=ZP۫8ہ?%Jp+>gG߹EO^jU&4b)X- {9֌UN/ ^NJjHZ_Q\*he}6*6MO9$ÁgâXLI#)y "89՟wr~m6L";o,6B`8QWTTp^ޤfpӟdrIc]cĒ0bi) )ԋsWO]Ɣ&xu;5ZK"(i UrŘb1ҿ^~8|4dg:x;{ׇeèE{ p̩}*s_|,4VM#,"Q<:|"*d\ VMDc,`ߏmIZ]KVV<-H.KNZ:Ʒo)OT^%\nq;+̯QBNU1R]N4iQ+B~ sra<1u#Jtft"4y ̫beB>9n>YЫ[5aT* }^x<TyKGQ_Gɞ^yޚWZQ QȔxw?~yl_//{@ע?*]@Oǐ:+@$e8Ȕz?4%=}oyz77_w?÷T>@Oǐ@$e8Ȕu=}o KǍ}30iW^!tA=x?G"Q QȔxVUxw?~yl_//{S!ASCר_CמA=x?G"PמxVz?4%/7_w?÷9^?z' C%<TyKCGQG'GG"PޚWZWWqqL?}|/;yO@OK;^?C#&!_tP7S?ΒA=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&z'j[/w^^y @r1͗_{Cxn}_<9<ע Wux>5 W#u:(>xn%9=&|R ?l j/2O⟇졃,IJďWEƁ,三/4dOf<k&SJn/'=CxOe{Q5âiҶĄK}ep[|F9oux^vyxAKj/m{Mմ[Eua p2qҿ=^,RRf k5:U_YʹUjsU)`?L~1!R*aqTe79cc E*xwRNn^iPZZ_:s$ѼAnLOu+q(=߹n<'F+qd8ch_.kV8*N{q_-|Q5w\Ux|1b$ 붺EF_K6?>9xcXhCRk9nz~?i_;_g/]BIZ$C2x_Ĩ:M=r7 |Yw?<ҿ_r@_]Y5!+x>e՛s:{e|UӯOhsqF|?mPX=1%)p4bE/\!&?|^a0em?gKb'ϟSgM%}Y^ q2瀨~|J*[__ۭ?ǥuДTP=.\!Aoï|>3Ki9 բ@zLktg'cvI°\Qr˛WCgOeF\lR͈=.ͅ)ng5HRiwÏgkh\k^y7|;#cx,JOo-_.oEIVl?iGV_ )>IRgu YU^(w? "?i?|vz|0lx{`gm7xt ͸fPD|tyfyn*]] G|[Irc~R_rZٴDlqHH;;9bO`s` m6^bXU?<qڿ8?_OEy |BpD2VF ljhSWor k>10V߇Mh ufiQIq<ܢe9guyT-ջ+;ḃx{N 9_Ck%on*BQtO< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVT'#w>5|G: ozۥzyzi_[i@w3Jrz֛JG:(< iX8WעxVTNG'}h^?ǣ'%G^ ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@x<TyKGQ^_<7S?΀=@)xf__oz/j[/w@ C%<TyKC<GQG'GG"WS?Β=ga; eov?*]lzyS??. G?%z|O:OOGD㾙g~_ݿv5l @S??. G?% ^vO:Jn=x?G"W OD(hJ^s^.]!tA=x?G"Q QȕmOF㾙g~_ݿv Gj[/w^@z<2?jzrEzQI}“aQEz/Uuoj=~El> $9'(aW 5Q[^k=~F?_$9')6QP 5Q[^kC}GQ@?_ I}Š(6Qz/Uuoj(C}Gl> ( I}“aQEz/Uuoj=~El> $9'(aW 5Q[^k=~F?_$9')6QP 5Q[^kC}GQ@?_ I}Š(6Qz/Uuoj(C}Gl> ( I}“aQEz/Uuoj=~El> $9'(aW 5Q[^k=~F?_$9')6QP 5Q[^kC}GQ@?_ I}Š(6Qz/Uuoj(C}Gl> ( I}“aQEz/Uuoj=~El> $9'(aW 5Q[^k=~F?_$9')6QP 5Q[^kC}GQ@?_ I}Š(6Qz/Uuoj(C}Gl> ( I}“aQEz/Uuoj=~El> $9'(aW 5Q[^k=~F?_$9')6QP 5Q[^kC}GQ@?_ I}Š(6Qz/Uuoj(C}Gl> ( I}“aQEz/Uuoj=~E EPimsprog-1.8.5/img/plus.png000066400000000000000000000024061520775651600154720ustar00rootroot00000000000000PNG  IHDR DPLTE:5ٿ5={]ÒCt]j뽄,P}g}꽊upS1:sU" x11dbnyUOcEG`^yrl|xure]Iw!ÅojP(CϝƊXT@6/ ܷد3߼‚gb`=tɏȍňs[,ƍ^zv|s!N:&$ʑtaW7Ðhu~ ;̗˗ʓԨ~S>~uĒL %$z9CGtRNS  ?L?;0 75( oϕ-gIDAT8uwSQoa)J{,R,    H{z2o!r?8%׈ HpACmmIz!ms oݲXc e1\wT1(33){r̰ uUgNɣywZ~ߜ45F7+'P348o <㖖G/Uuvtt>w[aվ (Uybى;ރ:|{k46i ]0<`"%9Sz8]#CjT*,G+t?T#߀C)W ;'ofGJ%N݂J׫ >*4Tx|y%D8Wt*`e=Y_ ?_?r\AV q@8A\6SWd7o1`т8 [*b8姑Mj!zmCQrjyrO@!Rfugd1HE%>y3}#A$$E@؍[LǮIENDB`imsprog-1.8.5/img/read64.png000066400000000000000000000153741520775651600156040ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_FIDATxڼ{|Uk;\L2_ m ~ZV#~sؠЃ"-n{8[[@DJk[(i!I[ILuI2iY̚y~e=YM)H)q])R.PJŤnJ)\BL BJ HS@@Rv5No^Wt:3oR*BlvmqB-ϴGQii0|>_/J)R=&}>hfڶ}d2yeww7!u(g,m2j7K&qQ[[K C9i"!pi(uuub1LD4o\cekXRlRضM&^FGGijjP([)5k6gR7kHGGGF,X@ii)J)\םB;َ$}ks_%S駦̙3300ŋinn5 k͘>*$+W$8Gl!4_5`#<\^(ȫnOO;wd,]7|W}_Ȁ3gL[ю;,_~RJ< fԉhΥk:buGl=B.qdYmF$aٲe)4?dBl6KAJ)pkk+~+WzP4syF2d2s {S xv1IXC*6/ۛ%9q-&˕sUDd9{9m"!Mu5qsmeezu>|ٳg)Ftqp]wM__@H$mJ W5k^ E 8dc̉s8:--\> V0bß熑;({z<]=zx"ǡ{244)//_ <++/&(~i K.ԩdW2;I;)\\P8.RhRU MH\K,Ez~#s׼x|S|k7zHI=OBﱱ C h)) E2_E>.a< 19d,I+E,:W歴$#t?aR$/s'6X. :8rF2e Mch_OH)ߪ ?2ht2qs̩b Jq퍧>%fl`9Y )MG(3_8dU])F2nj>Gknc4Wwfe$Sjk׮ettRt]=yֆ@ENgqpqƵU FeP=Evs5d}ށV %Z$igr’$GObxtwzϭn9WgqSe){~?pu_#LCOOvBJc…E^,9 jƍ x-7phٳg{B4#(3-K oM{~{>澍2]Yp=vLGb̝;h4: T>|>H9y$cccR[[; U2Bȶqe99უMؔKϳ'vy7Ƒ0%" p Ahii4Mb9 b  m@.h4Jgg'<1::ա&$h5I׾ih1}9N2`0K/ěoʕ+ua>OigO8A}}\23TڐRRSSiTUUb nV֮]˪U8ueMAQ2laJ: 9ȰFOߜgcijj1z)6ns=wN/{9I'I6o̙3gR0Mӳ---FJ֭[.s?SƠ1LZJT`l 5'p[0 ȺuH$ڵ={iP˲H<Ԕd:Ć FJiD"Ǐw^,²,Xn\pGГatdD']YwrP(Dee%SQQAEEMMMrWr%xu֭[QJy ]twjp14M0 /^L,cxxd2I2ĉ444xHxƠًa|:.>8Tn&? |CB)d]ש0 G|%%%8p&.r0MMMJ)͛G,DQbMp2.? P ҊR9/f|>p`0zL&ikköm***TWW3k,~9S~ztM_ J2+Ɛ15|$.Or:x[fiE 7 ضM:&xFTWW{9Eqf (HlڴSN7q>pQ$eee$I.]J07 h5FI:Kru=LJi,cth)ez~4|~&!N{F':'~4͢(P^^ Νaܹ3r+?eYtww{1jJ퉓S)) 2z""c("{NRL&=R)l_2?<Ӫtg5k*6,Cq饗RYYɅ^Hii)\œ9s|lذT*E2ĶmuHW%O`_Xat>q ~ߋ,4tz‘}k׮o& 87#0B@FYz5a+2QJ144D6555[V"~}}گTb8OSr>e #dnY'|Y˚5k[\01-&<Ŀo~lٲ!皪w^QQmۨFuMiOshKRdYp۶IR,_{wϷ🜻](RU0 >Ϸ۶ͦM8v>˲<(j8lذ~?PJi&ϟyqXvqH&\|}ݼ] dl2 ٶXA!C^~e/RJ`fϞ!&{z[__ς (++# 166(dY ͣGGREo[VXA__eH$y=N [uMkShjjB:4 c{]]ݧv=Li,[ rlBgg'a8eeeD"&W!x'XnH;||ٝbϻ` @}}}BJ 逿dWUUU8G .@t'B6oLss3i2k,.=3a?_BR.Ta]9p`m_]z 87ϟ?={L|m˲:o޼L&ë Tly&"~DQ4M#QQQ1aiϯpkΝ;1{'Ǔn>4G-Zt׋/Huu5^RTJia+B tI:mG1d͚5TVV~C1dr(jhhx<~yOO5< k֬jL+Ph$;VvWDyl˙;w<B)QJ&HڷootiV^Ms j])ܿضkƎ;Xp!^{s ,RJ<8q$hR&_=v-bѢED")RE⽍{3P9W#yWdѢE\}/\xᅟ2 #ol8M?yV Y`s!{w らO.z|~1>288Hgg'hƒ%KXhc۶Ŕ{NT*<.}H|N2w= te+d4MsMhH&S$N̙3qRTeYm]׽ʶJ۶Rqx>0:ׅr[UR +B\Ra~\.0dNFQ***B^U d"NSy!x<Xrܶmm۪0ιM& arɷRʲm{l&9}ͩV"Lt|>_4M' yi`0#q),47J&(LrpIENDB`imsprog-1.8.5/img/redo.png000066400000000000000000000017311520775651600154400ustar00rootroot00000000000000PNG  IHDR szz pHYs  ~tIME 3-T>6bKGDfIDATXmLaJHN:5̲YkYhˑLikaژՇPPDCY#FZ,Eb%EOO[//}뾞#d\O6 CHUϣ k l ~DK2]pu(݆f U8^/vΩ,i"~6}ҿLԵv9EBGcMW NIH;w#ftضPƜjK? = R+_!pBk]({\Ê~!J&'RN t'A$kB\l!FfQo"y=ĺ%?ZOl000u%ğ,$DXmUI[_qJaFtΧxk/Eawu_[I\X&A4d:q#dwTŦBr?nl[>gY Ds|Zx 9ZP.YڰRf!96 h6wY'Z5u1h0 "D\{g/gʜjhgKZVo+;6&XB^9,XWPG4<68J^@`ȑBּpB0{5|@xN1Ϊj7kETS%iQ Ec%l 0ld+.<L.o,""*Y s8 EHIr(Ll0=F8&`,"P7Dp6Kf"8/&ETꔵ !_n&-0_IENDB`imsprog-1.8.5/img/redo64.png000066400000000000000000000137001520775651600156110ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_FFIDATx̛yp}?=3px --:HA莔uyIJrYQjomevRެd[^'vul$IE2EJ/EA@\?@hT3}GwF P۬8c RʵvZ;GJ@) Yk-BXuo!&}F4ci8e9BRʓoYp=B 0N !T Ѧ (<]Js)i8v5ֲEa8"Q*R~>ϯ̙3!p.u&ZaS?k1R!c޼yRcM&R c MMMX,477+eLRx4u:t3gikk#HLr6PhΰdG&)'hbZL0 )J 2008-L&Jx|M:uH$u]ie||^)z{{3ǎc…ZFc&ibZ){9 GQR"K?UܲyVZܹstwwdɒuSJ`q#@6UABZ^yQ(ذaluEjg?Kdw[zy|Kp{!fDؾ};K.媫2d^!.pܹA0 }vR^{mRʊгZ#t^mX}lyr?ͦ_^6wVTZkZ#}nJSS===D"d0 +H{czWH$\wu+*0Zp{snCH-PEM}z\Wjǩ7n8r gϞe޽0 }q5C'>v옗ذaAzW3d ! B %/<LJI]nk |l ?ſ;Jߪ6@{뭷r1N<9_k$T R#GS -SzgLuR`-߲c[}7вg17NZPR`*H2 INOW첹ɫlww_IZP322r8Blt:MCCƘJ~1m/,Vs\lJ$"~1CB?!:4>F>AÝq8(iI< 7\y >a sdy/q]#7fUk]kacYRֺ) C'J;6ZF :.fOTWkFabB 5)%V"AHHx@ponyK:,_ҕ<ՓL">1u}BqH@Ŷ >M&AKB\gl_ PX<%Hϑ(%PJ"U9a'(G~H Nec8{7!SKw5w?\!Ok6!L˘&9j*i )96.$%HGh$AQ8J⨲R D˩A7. 1(@xiZ^xj/۟>@~4`N>W˛Â:7,kCL80nd\HO աH"ck1I G)U M*ܴN0,n/?7 LBK[UM|RIH(p$H%4XeGFYBǚUKHqFWTI+I6&9389k}>R,3%/vf<|G{2ҴWF@AEZcM[$dQ$兟΋?Me7,Y< >{u$x J+@fl] "@H@ HMz˓m,n8: ?>bp>< \8TB.P}J W B l 2M$ Ξ74 -o_Ozz.O+I*p(qARTyoj4ZcCnVNS1TS U]nC"1ο3B+@KYD^>֎`\N@ Y Xe5\W,{y^<7WqӴ3*)FBDڏXV@ďJDnw↧5@Yp-FCX \wZm5n{g6,h=n3RwY',J#,r*ډ[lR-SROLh(JdB /)[V-}Ad>,(UÒ4VbŇ:";7`_}W^|ܸaQ|ptg:'Z1D Oڊ-[LLYk*Zq*6ĉX5 Ly,cb?Bhpe~9N9ciJsޚzNCCCcPK o$XdemmZS%|{=8s[଍׶0J45&ëY W?R נbR)k+WP5J D2`uu]֑m&)ig64u. ΟɗzpFp`X;+S塍5h%qPn(1Ԝϕ(I2C.|F"lRV_[{m\byq'hkN3EuvAh*፱ƢM7r#q)ZŀoKT0xl6͵7bAg3A=s{/ܻ{4 U@ΠT h\Ipd2֒AMœ֖!rq=x C9]\a9-.gr8f|{:@5(Ɗ YX{榨h]( XВ+$e4)L:3"lYx1XKU\=ѽxѝ\c3ѽh-ϔ8,IhN#"Oo-`}m"e(97XY౨IPzZ?m\b BECK!W)VбRzr_2+MM[=Ch@[,ۀ)qS~h,928}s7{hSNGQ@R -FkR@犹r1&s9~9z.m3-Ztc&Da1B#%KnsX630zAh=ɺNpd {[Ȥ anD9Y"k{k A>3'3 ᵭG|/_NȒhFz9 [Xth)jP䱛E @9Zŭ44=O00o\ k49b!!aa:mIGZԂEӥ9-qbq]Aenp9w_X?Wp 3 1XSmNZ % 9KOGXZK(]D+еt! yOII.{}{_>㤢{lݢ|XO\~֔ܐϣ?~?t::.[y=RF,^ߌzRJ_Rz"B DItr*=)- o(B߂4?rZ") _o=.*޷0RC?4>7jrЦ{,Z"@L&|raX[73252iHg~&ch :yRQpgtxx|>_!'ŕ\>ʪ\^=9Y.?է1xI {wFkp .9sBc 4DE6̳ x?zlS _G*ȸٳ'E8θ8?ZcB ^:Ȅm?|Bw] @Yx1Bt]W ,A0ixUY@Jຈd,;g'^z1#/ ߭ NX`ANJI644KּX0 ZmM00ZVY|b3's1^KZO>yСCiOܼkS+&&2m5*=#NGGx[[cL毛sJ)W) "OʲbMy9w### ~/ czPa NM T M>]vN5ػ」;v<:̗7XSڠkg|p?0x.ory #ӟd}k@E@xp,#˲m00aP|#%"+Օs΃* ,I Iw:琷Ղv+m(r8 㯼IkFؽ{k놮ZVmQg5 ,# /#&|#!Я'aa%% 4M:ólc V_)Fara-р: TIO4/!g iXvj#wPE x:Tx3x$wh6h߱R^DM_ 8ňKvRPZ0}@Ű&WU.2p}Ʉ-Jsf+7QW?תd~')Ü wl 55Y1{X0+WVU!ѐS,-޸Wj'WڣU<_o|w__sl}5ځ?MKFIENDB`imsprog-1.8.5/img/save64.png000066400000000000000000000146401520775651600156220ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_F&IDATxڼy\e?{Ω^tvJ$l. 8`eDd@awA`uQp@AdKLIH;k9NWW:IssΩs~4k-"2:K)WXkLZѽjǍBhsa}Ƙ>!]J!>)VN_±4$IDMuxYx1k֬1Dr)Pi?a)7mD2dݺu9)eڢde6己G3͸xՅ;+C BO@)21 yWxHFJIlذT*ڵkKx}=ZOF 8x|1!gy&J)8sP $Ur/M &ppA Pb4JG _(,(E a>˹̽͹jnÃ>Ȃ 8uB[;N_{v矏1q" PO Z>ߎOĪEu MAD>(Qgܒg E@ Z w\~Oz$Xk xN; ?XcL$4558Χ|?a۶m[.r-mTb,w.#NµqD/ꌣ`Z( |?9& aX)?s?UG\._Z.A@*g[n۶nR:hf!ߒ$n D4|,hVhcȋ4m7W?+93t0c4Rj<9J)QJdرCc>_={pG[^<o,hI:`eSBY6 _q;ռvwz} S& &I3i[kͱ믿Rl|5RkGFFH$RHff30b9if2,TJc U(mPVAi&g'8Q_s\?Z\c5$wrUc#ɐNSZӵHcN޳gCCMeWQk0jZ*M9 Mt&&Uwsa3g|d!yEl2mXN݋a"\L&C{{;Ƙ7ڐg,rPHb@]w6eB M`X@!,JA3p@ȗJ(kH$+?eV uUPFhBpw}y#f[. ?}oЗBk9SxG,ۦSk-/2˖-l6BDL:|{7*Sn"f9|ԉ&P-{(i?Õ}ײi_z+>Lh)tttJxW⭵3/Ko߾`!˂y|&q+_z&4-?G'0!JnVAڧK8y_w}"H6嬳{yKPliii˘dǎddd$ ֪2%?`om;;. 4%U&.7%Ufai|-Cly_P qGNgX|9oRi8`& RJwqF֯_QtM˯%+f(4tIbn#s_掮)fCTVwdRXkYjO?> _לs9nnA )y pܴ쫴6~*Q ˔Tu }eŧ]wp>u-7Дm%B@Fk]ab"I'=sD_㵲~0B0::Jkk+LLLP. À0  Q\,Lpқ)rPVƋ^eG}_&\A(1FTL)YRDWWW%9;# yzs=(m^Y85=b3n(|gދ(*~@ɖB&qòrϟ Oq!(K]o!ҡ*~дrt*W7 s/=#{7p/i9b&WVI7?unAAM@1ֆ\.DZZQ^b``)%b1"H)LZKhe|o2ڱw0-&ᚥ͉]k_/zT!SYʤVmm-hmPJXK_>9FFF&bֆxk?ǚwn\y/0GVN(bU!OՉyմvy\uӟ۬`rr1pI.}ikkqjQI\v W \Ν#;ӭG NTwIkk+}H)ٿ *| EC%6<guB ӊ'| hobdr\Gy'$z_ٲU)'q1K/4( 7R Tvxֈ5+]_/˔J%<#HL&&de.{֌f&' U+Yc!^gjaVÀv.]O<mdų>˂ 6yTz[PtWF\.TSݜƘ:Ō oߏO9HRtttA&ຮT|>O:dB+a׊ixr[Tf]Zj< ѱemU8FNt3ypt("$DOTĿS`]Wv~2LJ)e|ߏz4W;sc 9s^̙KKKkt`t3Ssa"P(DqMJA6exx311A&arrB!W,hiiEkMssKuߊ1 @VVXkq/!%usL&b<#hDUZyԼq^&C,BX,_kM:&booj3ƿbVOߙt^]-c]Rʲt]wu-]]]ٳ'"@Mg MWW͑Lōip]%riGFX`B ͻ'  IGG;RV1 )*F#x$QES ӣȌ\4ɦ&͛WR> 8.hiimooz;XlYtFQUfM,x *JM33PTDJzM>]}k-ApJU[L&Od2+V|駟f``5lݺ֖(&Fr ԟ2鞞h@kMkk3b1xJ9Z<óg&lWG|زeKs= 'yя~!A L'vKq:;;XRj /088%\BOON-Z5}A lrc=~׮]\|Fgzs;>V_M=]epp￟O?{ѢE7 !ZkSu oܸq} Xx4콁_pAUE_dƍwq}\򿻮XkH֩ q tz?ߓO>9sNV^իioo?oo q.ZkFGGygd՜y晿>裯EcLl HU)'#l6O_|3_~e$+WdҥRƩ G? nh}gbbAq5kְzYd_bZW_)%T*iZccz׮]rhhL&sj5v#BLVS(3DeW,fi2 dVX;ꨣ>B&!DqQNEB RK)ٹs'CCCca\.}͟X,a5ګmHqt R#f `r%mhnnsNvuuζ9IqrsGv8ܶÛ[* hhh& ̉µ魺ڛ{|aj&e# Ԕv⾰wwwmN^F3C^4o/)Ą꺷ڶɤԏnnnreVc[_WI44&#"\K УҤ~nkND7*7Ya۬ / ͜ϼӳӎɲ|ujsӶmiaaa\M3ֱ1)ǐyHFh]SMٵJC;$pϰ}Գ  Ƚյ<ɵ% x4 ' ~ڨj3tRNS!#7 GɟY;,ݺyެqngd_XIDATXÅXRQ(2{'pjjZYZRQZ P)TJsTZVf{{~9W^}8?^N JUذ +дmX|)RBX?$,Q-ͫ( ,?1-wJXPPnVZ J~d%QL$&RZ ?.*\mWbш*D$].oibYZўoLq-XQ^2M?tz(-l5%d"+; = WWbQVCbt)J%qVGτ=O l䦜tV5EyvD3W?u:(J dv1(znG'Dy PDfM%[Œ" 5mIt|zppp>}WO׭pP_$2v>6#`δiv=4G>cW4GsMbB/d/ۭ`޽z0ju9P\C[%x Y1#F Գg/R&_" \1paZmp0cG-^4/D"(]RHAo h%`1lqu帰ya1` P }&Z<~eʼh=n aO~xL @}u|V~F вt+ypm45: @XL۰TfIVYqᐷ pN4oB*5>.&U`,#lwݍ[wȓxB( ٓ0É`6vleȤbF**Jcƌ#GNZh6fDzE=.e"Sf@ U sܜ9(77C0;bC,U<o0GrK:ȕ] Haag<9!?)U?kC##@qh [ MG{mI Ay$Kv $h4eBؼ$}nԃ[s?5 [P QDϼ7{!5x8͖[ aGn]`[BB|$ |qǻu{#UA %q<0hr+PM؇R*B !"s )J u\A@åLp-!E &a)'٠@\3=^y\ɭ́4Rwf z\e>ΐSb79\|||{Np8?D8j46:q707i@557438>P117;OZ?v3SJ6;Bivvɥn8D2/ܤٝ_>B\ʍ꼔rbŇLG<6הV6՛AMbh/5cEFGI\r5D~-0FO7pe9QJ~G7?sq^?TD9霬ģܴ|dOA԰T8X V51hf:@qbMzBCcOppD5)#&߼RPeFipG<ܼE5Glnnyx?̣cʦxɫhYmF9LF}stʹc+!׀`ruqT?vwpuV6CōUۃ?/ɝhrmRjgsN:lzZsXHB]ҠiIĮQKQTJlהnUdg=l[FZ|~zÚ>4tIYa(6see>Ш|tG\eǚO=ˇwa33і5YRt\mnLrfXZڴXshsPElpIJ=ex)J|zr[v9f;cX#tRNS@fIDATxOn@[QZ/|%| Q Tko[ܡ^xyq-`-HI*nڒ* :~Щ9Vm%}6G9f6QuH]yv5+sVBN5s ̱o=y!U6WAݑq+diP-HCvIBr&ZLjJ,''*jޓK0N8&zCI3:\kPp[6;޶R9KK6M'[2~xʬ-˨EuX-2 ]zrv _yAt*B*[W/™eԬ8֒xY>(mz%5Hxn sVսx^ڐsҍ~?Izo\_VW܅fSPq ,Sg]/,ĆdK qHpiH*J$FzюM\Ecck(✸~jkK?.(s'g*(iM 7iEr^F]pCnU Ǐrh>e4|_u͆ GLgcu.Zč& lmdPēY0 f!suɓ(ZV"VOUUmo^]1W2h~"#^2nRu KG.W u=#*/Ή%quȠ 7ԵYm*á_VWE.a.;\F5JZR:\ȶ{E*t8)ea:ϛv@u$l<5[r9l6esvt.Ή%quȠ<"C[?n}.y)!Rs7rqNf+SIow#gk)F]4'K#[sA]i& fxqNhbS׌ Dl<|$<.ɒed ӼΜ/OB⃐Jf>-HLӼΜoH|_`}_U{.J.{Dqd$N,IA"#ڊ(> bGъR]],PBZZ"A! ]X~.g9sѴI:MNҙs3yLeu濄e 4%Lz5X]),I2LsPōQXi>d>V"1 `@,iuz у=\x]m%lei E#=i*d?u7 g!>.KdìA9;Sf]b^L_fs!Wnl0{eC:sOfYw+nlcӬ.ìxqo%u.ì tקu7?Re%wJեK$VaO~<<\/0nJO׍` 1.4%"umwt]j.au]=F]l~&̖c`.o0SB¬5ưã.]]77ՍyVLw+ҕjoc[39?Ρ_!Z eJu> [꒹ VwER:Ws$Z都nQ[9$|rMgRc 8 uT]iES`.[MP+=d\ k)Zfa;T&; O oE^)bgMu)A>V6㦴ʴƗP4w)u#Q%-|ք:;GTu*LNkB [U/ (3\9EæVP xwGHa"=@c+wn?mPӆ4Lu{h"s<%wCP'%FTq4TF22 ?ҭtFi.nW?*%]_QXQfgGz(i'J(TbghNX(; y\} .PEY&nr8P9)+S4yV%0U;IɉL]8 Q2 DnlsPX's>lu)ٌ)_d[[k4J7Su&R]6U[U]{NRpa{w)Uu++pHR++ߩdrԅo-DpH|TjT ='LvWS4w',\--QwK@@^VasR뒾RO+Tת5 c)K@DZw%NjSZ/(7`+k+PnVXr">>Zg+#\qMvRwՍŬR] R ZQjH ivzBݍ{FDoK]ܛ' ;''R0e`~,APTq f-Em|8dX̏r]px V={Gq[d޻0Եj w  =,^hMU%2uR~kD_Tg@aû!i":[wm6k)vJF3cfuf3;(_a h%J$ !R&_Sܡo#xЉ.(yw_0.BMnuI:nvIPIx/ݺ^ ?u'݅t'nHhӚ]n3m:.N3 PҲ/$=sf@1)GkI81ݐN9XkїKt 'n..=ݰ KCkٶt6.*$j] 2~.p@uttDuL]@:]. Q.SN HH@t m-H@t/N:{;&?_ Ὦtgodl0F5[ޮX~;6(k/OTe@ fT奬: )n*nai1#8 2ath>i]RK.{n{Rr*yx=Pf ,P4tCˮЀ$[嵥*DtU[qCX+mɫ4G;9NU O5^րL ݕ6:d-{w_nt^d|s{O8URlI%1tAnLdh(AGH]XKߚ3:fSM߀ ]8nNe2mee_jV>W}O*]Nq(ńp`9^qF*-ñ_y̠?څ Go\1Ԫ±m<]! +&xJm3[9v)ع梻wx{}6TjK%F;X3m4>~ <ڃʍF -^Qplqj4W>u_`. aPXd.htĒR62\IA:0DG\E)&uj5T_kљJ]JU݃V8pamǕO$~-N?tKD  Qi-BsOOsLKnjt2Mhqf2V`)IuK9*?RI⩤<ڧk ~QLJ8p$yUVè5twmW'VW"O;Vptϋ~Ր3 W ſtryNE84<:$|^J.ݏ.DTW~$*D7P1 ;C疲uA4_zB&uA!Q.N[T[X]cD-9r(uyp=i._0!ߜ"d]I{KҐRtUI OGYf^[|ޟ]SӼe2^[1oaTR"+d[t53ǿ-~{ݳmH0Y>3Duo$7q%y!̱יbbi%CUB> oǖ#fjWO5׺1⺒%㝼]gbrםlݵV鈱ዩ"ɮ&mqd+$C1dz ľ{ VX Z&1OE~:-u]늠 &(e>.QiQn RhF7>Ӈj]푑VEY]Ё!:tP"uu3)-"].6A!͆q^q7HVB QXL04UVӖ!;WA+7LݎczCtI$hϴCIB̠dW=KÕ:< Bt-8&݈GV0 | Ip_Խ~5O% h>tߏM5K堭~1R ϓ|##m RXXl꘡td.>ԑDDX CsfAOMI6,HV٦u)A BtWV<Ҩ}\1tʌ^ f?tּ4ؕr A7KqU%ǤOq q5ם]⁁ 4d2t }= cT#Cu뇮@C:/=I;jJz0 Beѕ?EF}DCWCwJ( 9vk@.pp@WqL enUOY8ZN!fJ] S7fYph fW&ơ&OWvR 증z[S\{K8[CPT%N$AJUp.)Ѝf.DBnN3Rr aHںl;8TdyťVo%w/k6<ȡfv750'xڼ&)(4CyeRo!=G{z* 9aPKIh7fANO'jfnAW)2SQ#j`$hhs($8Sl9 ROS8G\0~؞({Nѹ &`tWEf.ЅeFם[Z}?qf4;ѱ3o΀A $}#'n&8GŹ*_htla?d)r:tͼݺg'_"z* ݿnyg;Z\}ӷmsPfKgjo 'QnC,qwT >m @˥o"4_SӣE3 ]q%-wFҾʢbyf>sWfķJ{~<OIDS\Eo *K9Н7rHpғ0`B?Xd\"^}By|ԥ 3.,#'н`k.+T;]EtV(nCu)mn١ˁCmNu].ӢNS=p")0nU$`L+I.|#KR@x>qqA `fbb2tVLLK1tŊC~q|ZOW,qS*)ӭi /`+^'~b0MD5mAح* ,b7x2|Tg8Ω8:`@[2b@I|OFQ{{wo+ak{dqy8=]ٹܯjЛjGo@oDx†czzKưWRak%!tM^RawlN6!O?>Pb vf^:_NM!2cԡ?n2% ]6'ͺTiu@Wb:݅}bC˦MÆT;z3gݿ<(uE itG.ws .}Wk]}¬M+ﺔ Nb}}L1KoZQ.xvq"P01 9LOls6[BCu]nL)g0V;>u]X@/x:T,/=y=wVQvw%w!-N_[1[+M%ϻ~"tՋv~W./'J7s S3flow{7^=w\nfJ+ :yLE6 k~Kҩ2IJsަSuZZV. VZXTޅ(8  Tמj?qTSjTWɝSשKWכ)Fk]ã[S]Km8Wv+ ?lLK>pd NPמ}}ͺRť?9v#׼޲^_&S+ktMAw], YXu7JJXIȡr# Iȍb菷gLo< g%EiBa_Z{^ιO>J8ku}kCXKȡr# Iȍb菷gLo.mGh Gj]SR(ֶv.wW/~D׺ko3f/{ʹ+]%toaޔmw0}\lw -a4dْq ЭZ]9ܱZE75܊6 =8d'-ڹZt$ku3b:7+?F .!G] CPr.LJRC%F -oϘПFw0wCF>LJRC$F -oϘПFwZ W f}¬ J{i#,ӷ4ݱE^#g ;]Mm(t\G~e ituQDvj itN]-nZJ%/-O*OIAѝ^QnZ(f]6S^q-{h=8 b A6#CYCEޠl#mH/~[u8e O˓:^K/8I]ð7".W7y>ȇͷK4qE=5[odv[$40]!yG4h-b N_)1 Fʗ VjzP cD ou]V;F34VD*:5Zߞf.tm$BY>v$YXw*`R4;hT;l c şqEAaڋ+o![JڴC 4aitqU' ]<ņ:' `x|hW9<6ÂBWcеP+G{{sM x񓲷[wZ&Nݬ;{`!&S?Bt:shpL=8]OfK؉&:^hb b( hTt}-a U냝@m;|+MŃ:C@[أidB׀< A8Rv;96GqHLgQnd0??$[3g%W ߠYve a97&Bl6fx}BE7. |gn0@|+j[}ʐ<觱D UWSB!M3l itFH(YU{u6fk׺PM5%W:WʖT.;lԛmSB{nioylϼDva>+}솢x.%E;(F̃a& Bhf/rE㭲h' [P+ެ7azަ"z4VߞCp?6Z]hA8 ]=;n>UJ*)u9!QZW:K{CS_xwy1.t;ulC aeBTmHtabGoVt1v&ǎvk1zEoto/]еT7,s\[Rn;S_@Besbumu9ipRbm?w}_<ZI&ԁvT;z+3FŎ^!dƨ}C0VCCck ?;aҤ #EWj_[Ģ\s.5C%6.CK%Tm~4ku[*nrrwh!&ŗ 5۩v[ l"BȌQ!= zEoV J%2N4aU ]ia`tOѰo.iiL9V~UmO>_Q{ow{Wg}UMvՃCc9-u r\몳4=7'̓FZ՞j׻*Ϟ*qx09os9n]\/Xwr[]u_YEU}qxqVG菾Z鏿NvuqhăvҚh1؊DoGs;zKbMl2c찡=1jtup M/SLKiYT>?PO]l ̝)7.G.yF73߲k)C&Ri|Z:l5mțF,ƨuT%]p˚hi45/;(8̓vٚ`<=F TNz6Jfj*pjb.uQ͖PeEYL `o> @۽|?%˛hu;\wΊlaxr10!ab=Q\=Jtdܘj`7F &0&4tˣҩFɭ9=Bcpf01ab=# y]uUt?.yٸiMuo3Kt&jߚv wlu8 +YňaItg]X̀s_7[mF?#[Θ?)0DW.S#8!OSLnؒ+BLhy%5$L]nI$ѕ膜$L]n艐;Z(av(hGP(E)=˽=}5E}_V ¨68tG(ݍˮz;GSo>]:jDCItD;U2bsz 5#tz{b[0GmMmGC>YY zE;f?`bM9]=h?GDlzG"aC-֣J!ÉAXz.C}]B1ZZh§?NɘLHMHC7(,+*/6nNsu@xrsj&˃`j?n8z:_ŀ]IfpC72FXWgﰗkD}7*ХN}g0]F1.;ytޘzF1=0Dw _Bz Z՟Þ$ ɛ\CC1KLFQBGyzmCr4svSyF:i( d0 6< 4,ף0uCwpӬt =k# ZE]tԡ8¦?(xt I)km-?냛܎5Du&KWy%e{얠}wgRs~(+'KGY2vЋ<%t 2Um]36QR6@wI('H{PL:=#Dp.E>et^tϘ{-m ][E Ip4o"5.u39}EV-wֹsskh,/>RƭtY^셷R?:gB҅Ut2ӑk4LEW4?ss]# V ".Ӈ@f:78`4SA_)t7}|>Xt+_@a_QZbCleLͲ%O[a/ziɘ~0qVH]KFL}ׄpy`jW%A@꧴G (%$g.VHGR.֕9_䕏$F޿xmmH6F*uWo_ӁGԥ8X.†r4]GLݱu{؎t}0ڴj? "!nʡ4^l2Ds.}mV?hJIۑYLE7~UCrHsIp8Mtzt9uɲxziuYb)yި+A%?5l[jZO]Kk=W8}%Q;52|@63t؊MJ_ ɧqt+Zb{J~Z-ٯ竽nlS3.NMn{_TL=?f󑦖D74Y<ԔiqV.Z*#&SjoV<#̒膛nоFoTl%t]bLIn{9uIf|o3VBP[ӒOi=O =O o+I;"|Љ$B1b-&;UB/ m5J6hA©qlnOtǑ<9?f*5xWRGN]%aasi}銿`NԬg2`C1t3 H \\/:AmP.  ]B+P6?S YaSBL"6=NEBvh E416QacaW?$ѕN;S`%Nc®l͈OONBrZa+7~bgguѮ,}?` o C7P;M0wdHU/Zg| .^Ԝ!ѕNLe:GcoYg] *hPkA0ao CW" ߑ_ۛb|J]L>۽3 +h %M]1"dNCv=vψIq*t[)Jv”d;iP=15& n^u(4yѭFPJk]DݺC 3;oO'Ѹ!" 1dã(r} ģyH]=A1gd,>in/Hqmfl"M XHrmDtV>xZ9);Irꬺ'vؚF[]ЈM[R ݼ6u{}|NFo!bmU&_>] !e!*k$q4V6ÞBVnE㴠 BnAƒ>toO Z!:#!ۦtXWm?p ٸB ϸ;$N㺻N}AZo89q߹U_P)K6i>hzPOϪSY,=IOCӟ?ü{uvp 芁󛗯%[-(zp0G [{%ʄZn#ʪVC̨+PtYݖɎruKFݼs:+\eV>h~NCӟ⦿#?5KOt@V[(w9F,0խn1-܎QF0"駖Ot-cyau}N:kYQyV2f~ԍiosINÖ [2F #Zw-8޵,7kݴ7Ԅ&ege{ӛͳg ZJ Y.-g!WTKaO.2vs [ @wc[۵\leғd Y&md|]x٨m*f#=-1!@Wٖ1+si=)L{y5Ptq`0Cۜt BXvx@ʾ6O9R -{5Yi&ob Qb[)x# as`R.,<:Z$csUOo2';MTry79i{NBP9ėg'@^JxBbҟL [3xĶi{Ҡ/ ^(.DtcM%×{ˇOs?e˶K)qЗ<饥a Nv7_Zԗ?ɝ;mm >s-QtIbk,~PsEL^KV WYP3=ݩ'ख़٧6ٚl ˿]tqL|8͔=gu=AwsXvysJ=A!hЅd榬EhZ3}x"N0>t{>ko.$ Ud(eS='kNФ?xpҟB]ND[i14鏤jҟڌ*RU\I$嬏+)1bg%*Qtvr8b?e 17T&ׯ䈘GgM1OyTh3]*`/Q7|ETzh &%!M\ݞ-`nh,+uiMAäd%QPݿPGF.)ll`Z=ϰ{pDutțp/'uiҟ a:mpwPB>4/r^84h,u<6.*ZR+})7HUޞmd?1 "VѹgZCXB^&G{iqΊU!NA~Tw|* uٸC{{y⒕  ,o*MF٠ ~jDdzMD]O’>⯊c-4[ڸW"CTgJ空IKV$LS]Yi:egQXiPi> %w>"RPWD0/,K(+JNVwXN <+u}+>8;Eޞm.yҟڪd.Jlj`xLulL1LJQ]=;{ H/&&uEӵU)PS躩t׭˲,c;! \L%TDuW߻.h~qh8>%Jotug/[8o=H+i]>͒*+^r&W "KgH03T NSiQ4]&[җG:u^- ;7z3̦k4m~;)+^T39sRuuOvq(Qu!lGuULnt (W{~?ndd$]ݒ!TI]uc-?".ʤ?DѨF]5#JF57PҧJ+GOK>VsERAs_]3%sgKG#Qqˁ_N*{w)큾Uhn..ARA݋+1`]w:_%Qn.vkHJ![wTf2EsCBPvքO4t"Js^ꨯ؈5NEr/MH܀C3?$!CU2MIHTy%-@IaT.ї({azɌ3j8 SNq.}fp™: N8n}cmiX~ZټRPc4 \8ch>{ne 0מ9W}6 q[8y{Ngn=4*~h]OQ! S7cf^^| [wo t:㞞aԃ<ۉquqǡ##^M =c,SIW?nPmj5G'.o8U!*Da}\(>5nغçq2q}@a53qg5Q2f3=Rq >.[mq7$ c>9“˪Ʃ[8D(L]sm˝}A}*sI[3}ky=]fӺ43+0<ŏs\uS&B]sT He&X o۵#՛€hnt<.D(L]崠ϱ C NTˌoaN`KEƂfPV"^9cz{22͗6x%Ģ8\F]]:Lsڹ__ͪCfD(L]{|=+L8n*i?wI{ݘqslG[zqܸ: . u4gH=τ9lU= SwyC]nYzF!dƎo~\bN,PXjF-Yל]"w,K/&C0|͍'CQP]%.TAd $Vw 2BTwdTAo Q3PFeXZR]֮U/]jkZʖ(JnuTJ"B4$Ax QxO):2a3{6Oϙٝ )I %@XJdB0`,n`H'0R7鵩Q u)P u)P; u.0 qu> IrQgD:sƎQPꂞ꾭l̾ PۼؼifoռRsD^XSwӬ歜s_\wzumpwISw=oNgܩ#_?- |""0[]08|uuq ۥtx)[*n$u6-K[V͉+(,'B}|uS[L9q]QWmrfJ7RlKP׌wuq[Wp(^8;0mKz3NWvfeԈuKwFѱ:IE]ɮvo"ÜB[]_ﮪgx^7/!k*`.u\@PK]<~uԅj@] L ԅXJ]$sR":PK}uG3؇~Qwp _bA] CUO{H 6[0ȑ!C.|.huPu0%SE>R2Qp=/\O($[ါ)z߱2C׉N9OGm; })XB|4O;jwR9N;^XER媐,y~x{SʠeUN?Sw‡XXߡ* ]=m78&?}Y%pOwPg!(eR:k[]mu{vZs<1FI9_yY`͕tS{Wm)ŷbJ.kG,+UuC!n[^^dO:-S3M6zw=\u]9RjRWsx2֦6 ߙ9u:scbD;ug"^r|u2R׷3s$fֺ:8׷u`j/IGA.1ѯ,l٬{Ks쳮Ӫ"9]Bk]ZX0U#^Gκt;OUWsx z̺ʟ͞N9x@]b9uLn($7w,ɋ \5yez[\f\uY6f X#"1OOze&Q8Uó@]g} I VU-rј s膢Ml\;/ꪘīKt&Aǂ`bBRȫVۍq'D(ljpꪒī xtшeʨ7%gT]!ufTW  )oM.VbC 2 ƒW]Ruiڸ9ꪔAi_v1kurcS-~ԅ:iRu=Ʀ]35]Aꖣ$ lw5vұ,M+0~ٿؠů0w]aRㄠ.۪jW:O?&5B-Bm旳*3̨."3u[ƵQXueYrTWrVQ)и8^Um(J?\c|IP\8^B]uju= C\:zOW0#z@uD"KP]%.TAd Dvjo=?zn$ 36^rRRLXdZy3ٓ]/(ė@-gvמ][ڝ}VLnx{Ӵlu{0 7#U@uYwgٙ~L4.mz* .v> [*Oėk2|K~2/VS é,yuZVGǏ/"T-˄|!=5[.4b7l)"X oM|)q@J«Kg@A:&Rk)k g 4(bӷ烚F6Kr?!~ U+ TDЪ:A݁Ξ=\L\}.39d/:+LЯWټT?eu@u ^LZTNM 76ߞPu;{ q,&{ &vX+Mu( n̉?̀Qu sqpݘ0Ǎ Q0K4_𳿺=`is?3"ucYbhZ@dGյZR;#V:<#'m%0qC]5O5#=Q!:>-G݁{sCޢ^Mg–{ ҋ Cq'2.Yd!߲c̊T]H5=Mu{S6ԍ+UD7[g$SiuOtV+ 6|"0D\L^s {LY$  EY",AuD"Kؤ#dtX9%ETMMI $P@SRDU(Jݑäf"EuYꢺ,AuQ]D(T{X"x=ꪒa. 17.2ٙz}I©z q31\4C-x JusO+:]p`ub,[ް'u{%S[puOEPN-_[wzƹ ލl 1\4%! s2kn5+'mgȲyS%E۬Ҩ xP3?Gu!Twl,ߞGtll68zm@qi7kIe~2̶҉RbAF3]`ŸKnGEfA=ȗCsJc٢&?ņ_%Kg .E략u8ÜHRe݃v:TvPvyǞrI,kpyޣ{;I07]V4Tʹdipgsmɴ(/y{H݉f1'w_ ͇%Rw.=Aю P&F]ԅ܋~<6< \ݨQ~UQ8Zu.Fݴ1)i#rצߒ²Rkk UWZu瓢Ȑ\{,\pW]\ݒl u%Uw܎;֖CuW7>,Yav fгwτ-纩ti,\*0Kx7gEuWE9Buv~_7o_wcۺgZzKW=t_7Eaҩ+.UwO0 yͥM)۲eMKZ6umK$Lf;!Adn!>Hd|!92SkUs9]w9y{/2wSፐx7e.ꢺ,AuQ]D."JQ{T%z^SI+#XAuD"JP]%.TAD EQ"$XIDl"25AĆ5C>y!K:N-|̨Izo{ta3ETg@2sݵxؔ7|pAxuEgߝ=+d!_?Ysg fMuLjCGq;Sw*U+SFsKȡ^MxWaK[ * giy^7_xI׍y^}mmsWJ %bWԿ-2"BR懵W5gyjйOn vV ̣G~ F@]i\ =u. U@2靶BG(Suˉfq"Gmy,€9큺`LP?VMIյ4./S7Z[b6W8L9f ?$d08y0|= hPݿ.-`/&ɕKD"rqۨ_yoV .TAD EQ"(AuDHJ]<%CRE RWbN")uǏ/X[nHQ{TzE%+78@uQ]$gխ>_ r.5jNQ-Cu_U+t.Pd #yP,0y8z]Cu2Ra&gZy.VfaB ;@]d !P]+.1/T1Uع:9— u!J+jPݯY QsǠZcim}iRRjMm =DPE,$5N-RB[0)XK'ߝ9e,RcrDsms~ssm} B27ֈ#9s*U6B%=/|Fvk>7}PYZC.P56d-/ VzKj2'tBԝ]*tcNR ]hNm'9zhk>T`ˁפ?Z`=֏nn*T.لg[݀F" K$m{{*NeSuUtb6:}+6b:Tk(c2)H.CO"tf]!s*0en]{] 7m:ݎMJ]F]ڭ;u҂u6dQ]\{^ZK\T)꺭tU]0w۔i]|' ْ=Jul;xWoBx BQn fHK]Wvl}ﺭ[a yeTE9^()f1{܋zQ)kuGCڐ v]kT+0B !>t/X 1tu`.u=,{ѭ^JdP:3Q~Jҁig۫ߊ ٧x%ylF׌O,I$ȗU"6AgN]ҥ W2J ~nPҥW@3f5cҾ}TnxT tsJq\+7e)SV;꒬GKN;S#brʷ_B +eϣRjB$DcU)_$G=D{ =Ot,6X]fbISSobA4>+11P_B^NNfh}WmW|XtUi?K::@nGRFAXQ=pz3xw}gDNVzpa7\,hjH+Ѕqfх%=ʾ 9VBIF1,, tM>|l\$%qԩ !4M$_'Kan tЀ==O}}l^ =78bbkZWt-B{;W j>ǂޑ>yEGlz1Cv:$SI~@JƤdЕecERQݲЁ;x˲:YjYkfjVgB'N7Vlt ٺh*U&5嫝k5֍|@ht?=.w>c!2H\@(*z娋X*+2FtNȸG1.M|Ycqt@Sp> wp "nOc2z~b{z".|AAr o2 l;xQG݄.2]dPH?dbL1н!c]RBB) _{llV]|6G[dtс~{UO+BgjҽnԱH٧+\"G|3-|B .=S#{~AqNQjR8ѥ|@h]>tEn}nLO1]7Q0ooO ss'Pl}#5H)o` F+?VVjp?D*V%C,OES%#LԦ*T!BwZ0Ƣr薐OWֵsNJ1)9.ܹ˵nr㽵v[3FJ@UUam:^i%I]%+U̵\=]Dve.MWE J16ZF؆p؅]W2]ၖR#rA7Q J%0ǣlpC*]^x-^U o[\vpC ɉ./0/^Fιn]^)g;{7." bxQ!~D;>^k#o-\.YM wݟcߥC.J 6ivsv+w&j]y{a~4@xK792V }uw0jAtzMTsd,>Y~gwOڴ6{7.ٴL5GƮ^GZg=YLYmd9fSeR氎&YzIMXmfm3jYϐ&Yz u{xՒv-8ӈ$$ ՚;[NM7TT9iA0,}ٕF^,/`Jz=!zC?;GE1o?.NݩO_߬6'r,W U%{}zȩ*yg*f)Cw*'~ i&3v X`]EQr;UgRlʬetZ+އ 7yE(EsT:S W?; BWy0N.^bsF5Rt_zFN^O1xc)%Tuт0I[,Y ݨeyg͠dO[L 82/S>/ o| 𹾌f(K984EK.|,n^:4RtmVvoe6#e~=t; m*=߯͟Z͋C׊kr]Xguzdu\tzV`aK05uKqtu A8lB{f5M-(Tuj6l{oXI`̍Hy7&q 8I4l;aTɁ59_vqBny V L6؜@7Q%ꌜp[cnD(|^QV;I|v9N]Bwx ψY1&i~Sr?<690G&:Jt $-nUkr?; L5B <?S` N9$S_AԤքMmVgH"}sе!&Q7Fɕ~ad^ea4˜Re}&ҝ/qE8墄4u4[>u{YJOR $;,lI+bF bIm8K^.dI/ dC s|2B|_ Bd0ɴ;0"W몔M]8*W3RV[nuqncU4ld4Mt O>AW%4 p}KkF](݃6H]u"u1Ѝ.!!V:YZ/[4T΋.F4MYt9M쑫u_˧ Qԭxh.g s {Vuyt7VyBx[t[+(A 3'م[>u˚m.jaoOު79:Gg҈fݼ [ˣ[SUF]Dp+D])HCLq j͜ylkɱ֥~#ԺZ{ceDЕ|v^Al1[N) M~X" {\jG{Ry_ ݨTg;̏yYf.}t_Jj 4 {L{`zyü/w3kƿ=:L|WfYt!Y03.FH+c@jz'A+u6VZtU}|ouAB{{[l鱨±$\OQΠ{+]'[Y34BSr|+Y.qv$I>R /atp=½.̽叆{v^`}aHk]Q^W@7tW@u1W+/W"mr}[v0 CaD*R,<r.׈@ #*7r}ÿeB]ǤH"]w.5:LwͲCi;tվFt键Plj;D麣O7=c.rH;E9LƘ_{w`Ov5-u'ȹ1REGNy  '|XIENDB`imsprog-1.8.5/img/sfdp_unblock_en2.png000066400000000000000000000776151520775651600177420ustar00rootroot00000000000000PNG  IHDR PLTE32wwϓxؾ000ә @e>>>b7ΐSN8]o8>D8j{wu734ww127D21r627jvv35<|||>65H9\aL]AnTC8F5F!taʋOqC5OQfEd vulXW⻁frg1)iPA֮vwgari@=EK^sR?߳wFXrsuT=DPrux叿ߤϷ{FQ>sǵt:p\po=S|@*w`MZD`YleNzY̦weV.*E_}$"$\iI>4Tj~I7jsnow;52;rݼĩ®cqwl_dTXLVRIěihl]LAIilh=kzͰNv9&!sQauլӲؖiqЗˇuZΨzZUzcY}vfr%F}ʩ!sqy}Tw'WYigFIEGptRNSa5|9IDATxK@E#E%"aL{MoD=HY`cKl{ e1y>) i·nCQG!+2Y>!L^wo !*BȤ\B&Ky2EP]B%dP]B& %'\q!%dBDIlI"KTمCK4 .~3/+an Ð$6Z{slj.IԾq[yK繖RU"Pp5>3.0QvwzM[ԷU/Qwځ3Eu^=C$"M۲Ȓ2o~`]$HtqXCj W4]#lf0;WW4jLJL8W`"~7d} 4FԍPFxuDy@ջ܎;DIu3DFmQa x L}h6&p>FU.]tXadNmXU.uS,- uaLs|$E 6\VY֒j#$ DDv-4;U[lLך\" s>"nV7XfeFIzc\T33}K N p-t)> 9ŀ ϗ qDn0r6NPT^<^* ŵ7 Oυ9_S}|P-ܭ?F]0.jl%{2d* afB *eQ/:ͮl-H3۬<=!ȾoOx|8yMt}Q6FunfT1 f`̰xl ";PfG녽 f?CLs<ȹׅ+2. b7&`>7u1^4;=Ш|PijZ~1?yuBY'4,-F2IIe̕olE lK܍'u{<29ZA1{.>βRE.>;>uo\W醺vfTA/rTuI ynj*!X X5#C GvYw"RalɈb^ݕi[0׭45}I]733$ٲl7AUw0wvwbg6cB!x_ B(kQMf!" U{B.!2I.! vp0 a$ 4؋EDw*ޫn;[v3|Q*&%5dJBitX֘KVanW|Q䯨hkǪTtcEvU"E7趮/SM9oZytoo06t.tW(Ynҍa v]UW]o3\ q誹'i4N4tlw>5DWe&Kto]K2jD, @]mDB\n7i#خX?0&,uQ8KXS WIraeUtUѭnx>|hAwbv8J́[36d^Ĩ F̗(9>AAfޛ$\Ga+&2S?NPfffc4}gU-J\>,,C*|{Z.]$ɍ*-e,~(Ѫ\a>g_Ox!oK9l(3N ' ] ӕӝC]w썌8\\(0t/TYEp8w8}\{ &,]o0~3 vZtXvE<B ;E"Ϯ&#kCzN8Z3VsO p;9}ƒpTzv^w;.]޽Q"x +ZUŝP eW.7H2B ;ެ ȶ? ]յ(b\OyMѕ4IE;= N1Ҹ{^ZtQy 4?]JE"sKAg-%!E;]ב.0M^a9[=u 8MIp3HkE*.J atN']`tO LnOtO7Nwjt`[|:w4xHWI7j勽 fa [d6f٥%uhy30f' 12iU24$f(^HD  mjsϽmE˳9s>yyD]+rKirפdeޗ,& áCweݤ-%/݂G / 22Mը7@;S1s݄bU1Kĭ 'sѥL *[Ӗ]rﺉ&@7jo(2"Stݫ!KCi0Std讨ܣk8> `/td($/UDpԤ~0rXnz RpOyk}VkD{p`PMՅƚPH<<sUc:m5Z-z›(ye~z#r)0ȿ^L]_'y2w -$=]ˬ٠-F-r1ٹ]{m!5>gv'rVH1'~1'8u^aݺ> Gi^i*O۪i/(o%L˂?l,2tW\Eg(볒Iiuڑ!6. g !! c@/ /O  }nLHHHC7#\ ίJ#vэJD Ѕ  W|؏3e[0n\)tw3tg6Ur,j !d$ސ "ÙVPK.l#S՛*K2{/@4mVPd*W@W}a`:GQa9]Ψ;?4 FHi އd̳]K݄TVCSU^UoKZ[rn;1F1<2[E]@Zox]Z9Js: f!dJ.0\, ftqD=Es̢hYtmWKU}~~~fzRƴeF+^qx-@W#DAΩ+6ѥe*i{Uov˭lv$2 sgr\w[PkeNftq6u<VMw2ղnC{ nȡ[?fw^ Y|&Skؒ+>GKɤs !VWzzXt(T+K;6RJ߱4;5 kgyˈx]_ևoq.-GuQ4[}|=.K@({|kF(ViG@@tWV=;\TrqY>_aw~ݕ3ݖ> ϵU*o\KݕNԸGT*g3l?mLa21t]<:ȎЅ1uf]n_MSq 􄎭q&Ra0sByхe4یWB~tpptCq`BCtMCOB]?׆ff71R-W&/>:'d; S7_CF:=(&mC (8Ԇcni;`E3S h"[5ZOx 2Ou(Q%yA׏=]qɣΨU ݏŠv$+C|D{-f {)x2}8át]?/ZtHNR]{Rx;aܙ(gk4:Ukg ˛[_U˛_myfxyG`\$#L.?MS^Y[ʠ[NGL]MX0?YO-AIU;cTKTcnA0H79"i#L@7lM6ԉI-ZMIxKTCN=FuIu>FuI<놫Hڤ*uz+?\0覂2?1Śp 0XC.u#?ZPt~IP wjՁ'- KM>HLs4u tUD5GVБthbE/Zxޙ&*$fSh}se&'tKB|(_1쮥V.4 ;m-5Y h(dy> ttgMر][[5[t𮊻e]ق.Gw<T =K\{ tݮ䠛a䨑Y7oϱ担Gٹnî%R* ~"9eF|[T@J&l. ҼmK DhR2K˼ fpD Oӟ1۵1kJh$(;]=EwIxm9 ]lNQݮ/mK-4nT;w%(cU<w k]'!?tvmdLؠ֌%]::vu<ޣۛnDw-8׋;NM 95yY!QݮlMy`s>Fu6?;Y f1U>.MAFM0]zn*I+tq+i.P#Ep i.G@R@Wc\`i#1Gy}L@7Mk[w?liϿeb?mhh ]<R=};?L#gK3xcΈC j Jt%Ca0f]lTuӟf 鯻޾;a ]M5kl3覱lL\7)(&t5u&nӀ+K@B)T8R{Cw.ҸN?tەtj/["ߏ:x8DZWOG_RU͔m[z:lǩb˩{<$rZXӮ<6^`Ttթ{fOmKmDC_͘A[=:vin,)huh+Ѝ}t^k~?lP8޴,6-f,][am@us!nSY>o:tU&NxjD 6]z-]zɗ@+W1.еmҟ]CH~~Q[@דq:~:qҕ>6b-ʦ_VWMU4] &5NgtaFN1$#tթBBċ&{]ڲ3k%<}'@Uekumz\ӟ.3LgS__ZK7q/ţK,|=h 9Eт;L$qascFȔs]B? tSQM6]Mt&t5u&nV0W= ]np()]B%?Ž3t3]r#$k`mK*W^lL3dmSspL;0_tFTH).ję $ um,T0tzJ7#TMA6T$BJдK% yvPR@^ll<~/FQ2a4 dCX03=MwyL(ѝh.mK6_&Ftt$ďPK!Id? #B]D"˛]$"tyDj7B5Z%D%դ꺥dfKֳw=?$ G2 tMFv]okP,Fz2 oOgAgJ&Tڪւ3d ]qaD =C7RƈC#tb/Qڥ% t#QT-^L|t*`.嚪 {'ClJU%@x\ θܼ;ití~cVjV^Yߩ"U=#dqtꂀL*Im9L\4D36v8~\.{1-kQdՕx-s~4g`]4,-VlRu]鏯Y3H,S#dt_OYQdeC0j(j9)|lփ Iblj_N f2Iκ'p˦9{v!UؾDQs'aϺB[\t P?/ȳ܀dEǮھ.4(N?2}ekc.wɆ2XmЍTsU^w`Θ]6fM[ qt ER3NV{F~f-4FM_ C9ɴK>{CK {vV|}C› əXaֹj}6]ޔY ߍn 6{b| eaYjV5+YwpMvTׅ=2d+U.oJbsBt%.:"tyD*CmbrF?L1"ͼldG un2a臺5▋SocI0H%BW0/߈}طUn/KJyU\[+7swz3 ӏOM!N4qvǏ0)a7=)S_~l$o=~]$UDWFS_*\dWgRzn14h<ˈhԾ-$M7*#LP*t߼W%ė]qE"JdDDt$R09a&Y;鋯 y+F卵:4!^ pY 47¸\!B1ϛ^|61?e˄g<\WN"3&z'?$2CQFWO./FSS Bg<|mZ-u~1\Ea ӏ^W+M }6U0MƅE1]=Gt9<[0\*=lN4aR8<`p%E~hivRi=pKz.hk8LG?& )j%ZoqӋФ溝v_<+;vVC "t݀;5ay|0>w=N_rk |NnɄ.oO0+] p}vpsϮBjOs]: F?ͼS[Z-0vӆ6_՞V]W=>u_l`m9u ׷3V/-myF60=1W\a^5wjѴmtqn)Wj%{?len*z`;RmQg.uD D6Z"cib[,*Q~h⊕Q]/Sgo/!NAwn_D8K s .Ň`RG0[lR7џVW>E3\G "JzBɢ?p*!rƢNG2O_ $BFd#J&eqa+(XB]:M,ΈS*tLWCwT/E,驕 yYi}||GBC@dۡUWF-{^W?0 .J9tw(-sSjTJCr? ~>.uD 7r7_"" L:u(=TX4RGpClRM^WN]:Jj0{Buk'K7:M@.>Yr\ߣ^搗7sQ]E/Xy}V?t . 3DDQ9t!&rXaYw6nN]:իRG"Jz uBMw}لkn=P5t|_E6Z} ~0SC"1?ɶ`5e"踔B#ѠXdNi錊i`"6ΘM_/*L]˹:{󺆟%/1g~RM%%b\ .,&!ucB]P7&!ucB]P7&1Х;$4_'A"6Y艗!fĆ LO '^ |#|{N/%\wQO'%39 JM< j0' ? >8da"I1#w$V47VԽAuwk:.lXei7/肺KXsfU|7-l_M>TV.}n'֎#MP YGuɧ~-|h @K¥;b7w_\-)J2 !_YpeԘ3o@Ȑk:PZL P,pJ_I=/T w?*OkEj3I!Vi+KHKospu5AIny ;=a 9EPN V)K]%:h6)rgye1j+;^AE[?7'zHvݤå/܊6q?L89M9f\?P:,n gqoi7(4A!sus_ pbBSx>ы/Sqr9R.<0 L^0ǥOhCOQG/#Oqpu!fqmU7vA+:ȿIԗB;M i(bq1_tAT||BQ'\R8j>mlPl_pYԍ9> ԍRЛ5S2?m/Q~+u3Ϻ>ɛì NnPɯ.h Jel+YX]AiS*]i3|3ͺ ?Ąo ACM%U2x+f{>M5Z_y՜ϼ+%; 3zzGv&7 p.X/^oYjN ?b2Y=ԝ\}lLzM d2uaPcVxg1uyw9wEn&c:[ 6՗_WU\mB=_<0vNZ7촛>jJ\sQgݳeSf Mscb#L o͓f&*SwN SwQ]׻Ե& fKW[HG{jB.xۥ衞*<=-,{N5E۩7ޭBpƥ<3SI1V[NtƴjFh+OO}9fDd"|uGQaF-S7e ڳcܩ|/x#Üx1E]OnV7c2?56wUзYKͼ{֥=qoSE˒/= XMWer?=^mUj4|_3!DqjPI+'Oez7g7B].{qLlV!LDJuݲ%*kڏ]a*kj-#Af/uOU8PTۚuݗx}kzaA_4#k/nQGD]֙,Yw䀟uQi#o8X[!-Ă{Üix)(!9;/٭s] u]מG9o\f:ݻ> +ۛݘL7qQpYY`k.wL,7Ͼt5P +(IM5$ 9vCk"S0 y>\ ҇j垵WE fmdWj6n?tnno a"T1C] `Ak/k .g>TUesn&vmk+ޏ2@fyPnvpjAM!4QM5{B' 8Y0uџ|qK"m*FY* u$q`P7N l B8Pw!V u)g4&Ot37k\tFWSM-6ȯa}Oe%?йc$`bZL:k!|=:WD'~ |QE+;̢"=4en?2 ;y0?[#ߜ`_ܕdDWj^,PwJb'X}%!j]~E+^ɛ=$N~dع B]89uY64ADqGJ5dWf=c+49ϢfY0 N&u.Ajfݚ|4WVt?5B[f]ť/ZR{fj_Ϻ2]kͺ[YWv#+[0#9ٞ^M Ofu)>7g1&ƹyֵvE'G^2M]CF#1zJC`c٤n ba?y] uSMBJ5@;8 l@PW t޹q!$RA4bGf-ڵ{vW ae)K.K.%˺Km)ey5ֵ(% /<{f3yBY + Pj@]IVCW7A]|5^r6ˎ?PPOUKP'aYR qI! '+BW,#:IB9& e+9sO¢ֺ/.9N2m~ؒpNrNf7+z?t,UJFu.ɧnK;my!IVrcX AYJnsk!^$as2:}8g9ԅ@] L ԕX]}q/EF.M$]?VP@ #Twp+"m?z!G۠} ;=79J2Nk-N.iݻ4ze\\GJP?fj?wY<0i)JFn}-uduO̟*Dx_wQ3\|\?R 1GWQ.[Y7t|==;NId@-?~X]:6OF_i_G{d'va+4YݻS ܝ2kڟjf<.0g}ѡˬuu^"xk|~suGGnibWwTScJl-HO$;v^קV<cjf\.$tPݬu860]Î*;?nNLvW+uul=4quЧ>9suHM}~Qoǭk N.b.y5o0]][eu-yWld=aUWd%wu1y(9WŽ4y!'.gC PcMݕk=Q.V4i~[(hR^-.di.Qض/_捪 ϭG6JPNk]+;\3va<3+1gn.ql״ZK[JImyd3nrΣgQLݢE>R?Q69zKty{(`$Z,e rE!ɟUTʒE!UM݋+ ̍)KD΢ "jLp|lw~ ,׺.ػ;xF94o+e]O>cA†%Uڱ!\26C~+ؽ)KOuw].uyޭ~`ESWQD\[OFwf2> 9WӴ<&匪Qq3Q* T]c'E0*R'Hs][n~g^Tc'kGݔ:Юv9% vOjIgdmZ}uX9ۙys$7ov_J4.$.ԅta~ДRRcuUꂺ*uA]@.JDu>?ꂺj?rͧgLE-' (NDuA] *5vKΣcRafTۼMd˱[)6: NJJ]לZ)_݋8V?uu +ߡOcRv;sы1CV7`u-ْr[<9: +_1{iSԨ^ulZN˺:u9ږc(YP .oVx^=T,PxzhZڽ*~u6D?vRRc+oul/OE5gUu8LeˁԨ Gڪ撽/ %ںv_me<RJy靆^z]<P'Euꃺ?<y;TG$+ˢC_:YBH<ϛ6MZś󂩛 2c$7Lrfdtiܴm߽HwQ]~I"n+}[.뛩i+V-}vf[6`u) Vwn,۩;D]E:ĺ+ CO|xfUE,_ToR>t'_(Յ{]cխTܰhsWxuΞΌ))"ĮEz4_! e1Ipdqϴ3nRW#̼0 t}k޲5ײ/ތQ{cv֡Zq+,E#̶"DσyuMjmsyQjn\s{`z7B¯u : 3 L]x@]P. PTԅ\)ua u@?u RDc.n>.$PTV^?Yaգ!Kf i.t@PP Dc_Z@`o]tQSJvF>?P3^WeZbsߌ&8j-A0 KeO_oZSGDaNQ^s񗇎m egVCc;&Vn -6jr+3ȼouf J?^%F U7頓JX,J]T`w] KeO|^;xߑ D-x^a<|Uu==} n+wm P!/צXh'T; r2JK_Ptr'wƪ+f!u '.#Si>]h]AD7UXpQtr6'; ',']Ϭ8߽Zԕ?==..<1[ bKNl]InǕ|h%MUb1k͉ˑwq#DuN7V<.mot4zEsꢖ}^1ǴQ$CȋXyNJt=Qg/XBZ]t-X]ӣchGTWAF (gA]1uAtsNk]a6l+\ވ).bzS̫FK$P B'qCD@ ]?SK#DGQs%YjY)$ 7 O =!վ@U+ty >jR7bD&u@yuGVaxc87 ](MM1!o H ( k6D$ m/ (}kLz frє=ښkXϙA-H\( M+OB M. ԕb6!7|ߕN@N@IhJ]Ł=!T;7Rc B?͍]# (ݨ t|CFHIrЍa!veݐ A7vqC2uubЕsC>b@]'{g`iS(u\u#ipD$UQb4Y3vn86mt Eg׮vl(jN[]m~ܫ]c>޼9o'9?NH+2LCOuC\!.oHj/G݉ySQn,coqe" uΧn^;{ҟ$㞽Pbs_Q]#qݩzU^įU*7VwKkiG*iuԕJ/6uU0[a>j3)lMVɱnSAB]c5*ߓ+XWVuc>Ͽ &ս+K3`y ӯ|{vutXWե]0莏&\Cu߫زbp]Yuݩ3ho}^]3r0]V bu]9ՅOH3SeVWF:ʏa*J\ D$a2w5pMޣG?!P]"nuKfREkE+~$݉ǝ D+TD|x."~uOxŐŲ =G.qI @ 䴙D.MHt\ fZ, Y|$ wĽn -}n[`GuFjn0/Θ3Cu>7wEuq+vo!QGsc>?`mcO:+Su֌t/r9v4)N|T{_ߧny?:͐6)_"F[ݼT: "(DuQP̌sFGWxu/+e_o>u! Wx6x.}jR4QF7[!}t$Hcbu|40 Qjvx+uԅsUg&.oPx}TBu7 a=\WaY*-S:>sP&0Фvtj'RuqPB֮\R;Y[gV_TJ_\WՑ/P8u F?` Zig҈QWEŔΥFgݼP&bWWoFY-;9d\|?UFk{÷z3k1[8M,4GE~l%o;sD@7zDDDt;1uEܯsݳ[ P*M\Wp[S̈́0 ׳P 3k*&l{f¬-K?249s,Puf[ i֥h>9`4]e?c̳"RXS]hz`Ei;|ˀS=t1nIxs-6rJL3NX hqdhjg%6jLx Wl{8:x]Rp,OOH%Ns fm\Tv}\35Ķ+ʹt^'K=}+&ÃT]v?RuUxbLC uʪnp[k՛gKl+LLƩ5;Њjǰ&`m}:\cSk`S1[NPlO]-jvuU9qbRkQŭ ?rQwg1_ἕn' \Z)w͘X6:|k`ti ߊKrqkxui8%xx\j S7j{3HMz-|TCՠjd٭NN2UFե话;%*Kyv$hDW8{AM/JUWjYQ^LVԕu{>4lD^9wy*LU_a+̻+7V?fek  tyOnΆ*mU> s<ֳ-tM>a6\ 켧tKo䐧(1dQT\ vb[eB r5/,1v%ln 8 vȩ1ɤ~y݅1y!gi˨NjnnC,.;JUoQaI׸8XÍʓvH!'kuՑa:\7╡fHeL>1r"nD^]_qTR1jl\W3c/SVE])wuU]nꊄg\a򽻨tԟ~lol 7]+xWxJqP`wujL#GhE{E놲G+̵' /֘Ǜ&`xsc:TWͯϽS׿0S͏^;Gu +^>x7>/{Dᇍec k QckXA7b b**7Q!jEyGgl\5d5?ܹsnrsͷX#UwV{-@VsS:-b7|iCc{ͻ>2.30wjXӸLB$M\4sy{XD%{Gz!v/W*{k$;ѭ\nfkyn?aʻ[nnõ7A%]J>u*}F/1D+5$uG7wC%jܢߋu6m=4xH$uG]AI l܂*58t $!Qt_x;x)وnZг-!D螯.d 4_K)3yGF + IRFէ c5hqНU$uPٝ15Ay܄n,wnR>M۪Ab.-n?eEt%!GeC[x?jժ\&)QSs ]տA5tğU  5e_J:u<BJ-EY] FЖO)5d@Ǧ/֒>e9@:m3PYB.֏|-t~bI@\lх{Xhn/:L x ".yBU ѷvb-GW}˻i #XQ?7a@FTӣrxmRQQu~[z 1ck#6a06Kƾ#أtK66T. n1Az~&jTс0~9ST3@705g#b/M ǹ_޿s-X돏fCgy ( |oS#e*cFӘ< ?tvÅq_+ņh/@TXvc \=kt ;GUʋQ 3: !!}0Qw'h7.s>xRpU>6q] v&9Q]Y>{+<ʪo1 ?dYLƄwi;OrxyБGzI;Ӎjy݃rըQ'q=Jާgwg捴Z$ֺuɱ&R^0E#NѨ&g }*tq ?'#S3Z&nԘ-o#2X*SGnD=nmVEO /=f >@A]hL*Dd)0I-gL5U)!m5Z뚎㦻]* z &iXT]ܙ=Q'&##]9j"AB7N/pn*c(V,f,e#G]~nd5INywVn*pt1-~FOɱ磛TPaN qnŒj-V$L {Y]*gD]zoQd*=Rf''3lE~y)rGRk*G׬Gxb`$`JKpNĦdBG=CZi"(%frtjF?J LagɭQ^V+Vuի *)SB+HqJN!Z8%# "8kgS t^8Э"!v"@_!K9BB.@WHȓ yR]!!O@?[R+$-o]"t_b-BBr+tsa g.-s\/3vcgx2 Nr^hgz&*Nd|ʏnFw#JʥyeWtBW.,ݣ*`^슮Rq"]u*%0ԗY^=$JEɥMTm_u{-.t)ڱ+Jʼnt5ΩkǗ'f]U*J`r7GtQɟ؝<({Uw taw4QJE _ ^ .QGW.vlOUfp+㼙L ݅/]{lR*H9j\9[8cױ AR*PemԵt]ěf(p]~t Kk*%\]>/[p:v-^=J A :r9t=rҮK H-r辷KhJm[½":µKk.J@n+׏nhxUJnF-ze%箋͔Ra[]g/Rw{|stE#񮉗|nc(}po=u#?]- zY{}DƧG^?}0>f&kKJe if?znTYU?-ۻ=lcMN$4]mJ-V~Tw]?}QV[~/[M.j/窞eӎUa_NVu6GSO=:`I.z]:w7c^{O6{jttXx]_v3YtkIVjEwp}nr=|Պ_v/(F\RؖW.O۴?V4g ,22J!B6RK c!YdS!}==D޳yf-/깿W8NݯOCm Nd[6gL{aZb;[ ~| SIv6t&nwp4H<sz3󆽚oL`R<72h* ɾZ Mxf2涱DY5,[!VWv ۏNӈKWM7@3\a-4ѭitf5@GGGHs2G5%*q/ ^aJK*[B#+XY']ns { 'lݥƲڶ7d6ZY֤vJb~Mv-͉y.ovzg["0G釷0yHO$e]6].X̽9 tt!E=In!`A\nb,Xk1"vpDAN,n\xHO7ޠC*E]'><~3d Z+pEp|hvbr.-\&{ kG}B9Ѝ.-dwAHԽԘyIsV.Ty( Jt?q 2d`htOP‘0?BpG.a>hnlЅceB`5\8,U,lmہn<A,cK(;\AW6l/_Ѧdtia.7 8EQ/R1ntI/?OcZT(շ:u3u2R|=&9QZ*n hfY\*0Nt-׊bȦ@ݧ]0UV0uNB3(\RtQGn7kDw697[|Fkݬ{=,-o ݨB'@ߝ05esZT`ֺ*t8;DQRk~\<|xüTyrSys?9zU]* 3;B;!tPTn$U⌐}LZeF l:shٛmhYz>scmE[o ѽXoT1*tMۻ;gFiY.qc;Mu?8Gj^TX%08ׅ,;s}um-8UwyTX\+Dì^y}%`RŒφ)|)s]䢍i|gQ !o80 kp*a@`C&runcS1xt_?(P PtY=ӝdwúҴL7{,rn>fWv@cO7=E|u= v@sTř?z>min8dyoC)ti.^%"8KD@DVkIENDB`imsprog-1.8.5/img/sr0_en.png000066400000000000000000001370031520775651600156770ustar00rootroot00000000000000PNG  IHDRRWgPLTEx騨0009@~ @e6e򠠢rR8[a7PJ;6=65L9r΍N\9uE@c:j ޒƅH꾀؊9@Q;WG8447kz{zO5p =LdؗT֬]vA֝֔R35EfM߮`OBcN`Ny~Npnnn9_ƍ{o>7__]BCBᡀF9iJZn׾?-˗`3,/6bǦzܠ`ОXHLLOnլʩm 3PZaﺋ]UL}{מB#RA㵓ղz#xɶNSE5Z7nH6&`{q(u]Oh6r\ aIK Qӧe^Ity6U뭩Ǚ ƖnE6qdp VQ|lsm鉅#g ]M;sr6' ^ 8XbbM$MWIDATxO0S0rȎUB%3uHݡ]%]s&x<N?T%EMlI|mƢk˲8hВZC8-ڱBt<_I=.?/.R7木R 8CԘY8ru_ .?/hwc3W}Y܅j SELqX{d }zno)EIߖ|Nx7oB?S{.K.KwƮq?bG8i^1`%56 jk(xB!AnJ+2g/gl%Du#7n$FՍDH ZD" եeeҸRhF#]v$㫒> t4v$fX-1$FߏFB Tj]#BKYo Qi|)hoL*$|HL]҈&5j*cQP#&F^:`Shu/>$"ڗka(Tp Q`=6Y|RcMպ,rW7FCH1T׆[ b꨾An 53 Ru$W(eYmRy֥ei[ܫa*;n@%~d-oqRDLTi u 굲~pb$hl&D@k$*}4F]}'̪csqtx¹ ?ӈq%ܤƾl`pLHy"[O]/UrVRNrH_5 sk"! +aUF:g_頰 &UW# WI$1mt4m|)NQYyO[UE9#F{>eE *dĮC@u@3?m#yJ# @&K?mvh4z1v&RPu(MtȚ﵃DGC3E $eVeb5H בm⵶_O d*B@u~~hg\m\FEB2bQ׫kPiEwf/ۣx\@)ʭY-\g3*k7kݑY뢯p[(@{m(/K]Z_IʛbOtOL㲹%ddb,gD0^W)c˃l$pVݏ  u!blҌ ZIh^zو,m hPݦ=J.}{ØS'ƇbF;̈l:KEX3֩B&jn5WG8A;6i۶MIށiJeY'mI!7;a#v/g`"\;}R'&ݟ\]I3N؅JƋl2yr0<-fdy;msTE;mzwr'/viLyL!aidk\eӬaӌ~A_&J'̑dsK({yTše޲AV0 ZwjIYa]$6}]NKy; ɄX%tt4 򺯻7) iRXylrQ"NK8n/\u&OPuB {sWy3\k͹OQcƄGl.K??$Wt&eؽDxP0u|ҝ}-pB2͸əЏ W݃L@ BoFa~HwÓ,́2^ZcT7xl]6+.JYt(9h꺴$SNP(P7L4Ab{6٠B)#&};Yq&AީԋU[_IRS*"wוy6bh>CnBtuA{wjR4׷/ΝļQE=w.!0<&9DAPU+_]3(P۾ ]lWֿ0ck 3e h}@$~X@c+=U4hw+ 7R"" OyGW(2t?RJKRvUV}"D![ثk{ݮcFpҙI^|T)V<"ku_lfm6@1=F71O:g7?qD}̴n$DS2$2W !b&@E<8""G~T& BƇ $ Huԥ?ɿW0~\C Fu#!Ix,^1$a8:y X kn@H}Ub$ H–/6G"DW VЍY@H@Q.«#sm->cx y Q7aDu#7n$;W4Eg_uA- w E]u#8*;A E݈.Tu-ahE)SlA-O$mQTLikN}36I?'.=ıPDN Zگo׷K{aKO/޺I8Qœ/⒅ͮ#*,RӌvFԃiۡ܍Q~md@բ0]hKC`<,T7e\+DRa(9X&uvџmTmRVhVV<6zA%)Z"LܮlkHڐ~ k0 x)i\Zm%>>rqi}+`PZ>\NrK~qҲ@Ͱbbummm՚Y8IxߔR<ە$Zӻ2`QJO_-7p9+6gD>.Oܮ,kaM{þY*\aoxs5.*0Dɓd4j.˸iu$ ]v]LD=s=$t˗Uϻrn D&RJ^{8(ƴRBJNAfQ9Z6u{+U+J{VpU K܅Zװ[ֆÑWHٚ8`2]ϔoIj\%NPCruDIoȣ.{I}_zeؼ?Mky?sU͐[lB-O޽i9&j] Mz6UVVZmX=SqR]owۭFY0eqק-= ']uרsPG:=gأnfVQj.scKzW͌\iKqr['If\cՇ1+:АWMOR(9=Q@]}vZdoɦGϹo5-ΕZ@O/ESS@$,u No%MmZMN%ʭ[I\cwܧϩ6 -)"k$(Y{#&Qm9^Lȅ(`[^nqu}W  (]^݇5k\;sk𮌫.48'B0ҽ6CGu™b\`%u!(JyubkBKJl:GCĸ-D:.Mkօ 1Ǔ(UEFX 6ׯ6\UQ °kwv pc~BK %`Tܟ \F Cz- KJ990/Dj7w`XnoW\K'!>x,Xpy *  JoDOu2tMs]qZr$F qrgE+Es:{9Gɶ^آ1G:q%7Lz Q-(H 2%ŒWtQUq TFֳk:N@&KL@!yJ(sRlz ݒ?&pGE{΅u93tN++u6fwٸΔJEƕf^n14( \ܬm}C..ֺE--޽,tix n%Y;u;һgeKt2W奖xmPԧoT(nn|0N?a ft ^Q RJ%Ercufxqwt)[d^Zr\ Qs#MxWtN++1Jօ ++po.- i:Ww ܷʸԴ޴\ ;R)ZYIr5u.ƫW+_Y.zc] S﮻C]مze&C5,4_1ݷ/u¹wך:@XG`,úw<`ܫE½|[tʽ6F "]MKph#Gv*`+.}zb,ͺ>[~Cd~RrqoO.Y4Cr`֝6\ν]a%u,;AWWZ 9-y޵XWځayhɮ  UTF0.ZQپQqnge͋ 4BS}ah#ŇAŚZ8rzzM(ZiJxjRy,mRIGٻMr ~7s77{]],EcrG!mF/x^j_;tC 4 n7oJx='!.n6!p'焦մAwiddDtZ#P\O<.KEX{S#A@.-!v[̀ͫ۹"mNX}6.6_qP!B;tf '%2g݆d"7fX=y*vC ٽv|ypC.+f 3m C[ZT?m>8q) 'fYHхB Bp1 1h~%p+>gAC@( <+C 6⺷E+R͜3s]ۖT-gMUR@{;캆al5b\mw4t?攮)t^ ac$ C ]][229N&|bd>`9;Q7n9|P)k2.p60gDt"w].cCl-V_Hr}_\I}6!mKg΋}oڿ;MnЕۨt &h"8 ȅ~]v o#3$uU}7"QIȽ.v뚮e)nANvR@tg@KG|6m7ήD/-bU]ڡJn'a.(g[0+m"HXL,|zkv/)Wrߑڮ=&΅m^ !ge£T9A%f5x?r+t$54'Ǟ 7m rѨHmWȽELu]E.,I>mYtyvt%u/*UXJȅ@}<QҡGluu!trUVN|=]Ї'5>1_ᖛ~~Bvvg̥=6±HMD6]GkמMC3!mHtY1;PKuM n5-B\ [xn|*pU; aFIR`#99tdݴ__$iѪBWy`˰ّF&eZ!z\% osKÑ|Wkuw!4uK]C/ϫ.G>v{\R\ؙ ݶ-dIb Q^#X=$gNΥd dm tSk]O;Tk]`)3v?9w][{~n[mD7w*LaƃzpZ+T_*UZۣ "QWC͊Bӟ@T uCxnhU_ع,\Cd$7;eEa sr%5Y6x¼ܒ C?Am$GJ}N&[xgaA3񷀥{{.2]@sR,|EQs]J]Ɉ.|6 ֭e4zXwdNj}ftG9E !2a2>f5 7[tMac=2Cyv,/UEUy|iv~𮞹FXmBK ZuI ݸT~4Z퐆p] *0n\mJw]"Zo¡ߓS?]CțoX]\xgMj6m6HEwPgtښuS0\5Mk@rt,nZ)%1"zk(R$˯UCtbQ:V] BtwRtte77<"@HhD2tΙ{B.Gk͌Y-ȅI)xg UOe,OX(D7 b)s] GvtӝM-ʨ")fͫO.=T]'.<^X6HD&.L +yѽq=߬5zFkS˥'|_MT>֥?n5[kk[>99pO՝C5TJ"<7S ZD32 /$ ̦݊E 4$Yšy E[>b9$+@)Ŧgvޯf}l(Ezti.*GVL#B]TXs,wΞ}"(C. _AHAڑJ*{]J=Z|yjʪ e[1l*tV ŸQDkIt sDZx9Eզ_w2Vrg}lus˂\ " DlsB}yș 1[K s%|޽~PW! 1ֱ -c_;tG#mմYv3~jV_5]*6Li]Bguq dEWH;cp#/;AWS^䀮Dswoo9݆` @kgɓ=MM3n~{ƹ5]& t=k^Bȭ1],MЋh=i snn&u'ص]c\DVɥlR0NT&vOwnGX4M_ ]X-cCt-<1\.3lc ]4٬uqU/.(_U9's]Ṍ#^9 z_8nj|~m0qԂ4@rC'Bp%8D"o'UCcr;Sq(4talnn>SkYk)v#Y?(8q[׺PtP;K8rRT袆bZƺW0,]/M] 7Sݫt0!c "ԣkqx,"` mn0ӣ+;."o緍"㓝ΌFAp@qR%p DBB $*8@*EH68G]ۻkZ%cvͼ}Y \ڙg,2ivBeJ@tqߣY\IB]$F6nP9.G:W^2Ο⋯{?1/0 qT!:/.HnE׺2βl0}c>S->?U57K[\^;.着> r#kGEѼDo^@H$7zUbex]ZpVAV5vE".ݹߐH?.nUE'e$B$­+d7~Vwn]i o6U.ƴ[%!/KE3*8BIǎ&^Jk,m~=]WyZws؍x{ƅ`]{%{Ww}.0~>$}iN_w~roW0&6+1/_^˖gЬ/ #lT8@W۬~ Si܊=,:yN ny# ¸Vfl4 DnWE^Sə,幚ӾeFL꓌^A޳V濧㞎{i劢Xя.1Vi zjЅG"*wn p)"^,_=oRW)p[^2.饓Ckp;uGY9)0JP k8o _Jt*& DM(CX!/uLEV.[XxnΣ膣brN4Kioe>{e. '!tQc;ur2޴"]!Yj~(l7VޣWb.2xלƍU":o`tF܁zr7cCeF)L%{\aYl+Z{홖.|ճX6Z&[KkΩցL,&}da6edh,Ie77mnn[L*U{.X 5Mtd]|q-*3}>+h\n: 1U ]Q70$ˍ`V:[[dӧY2_z3'k'‡gET^8^آH$ yNT{mkE=sTDN2Vӛ1A}^D:yOvXD1W$.awŘkmAO ~p Bd}Zxn25iyH[mo~nVl&/{̿z&U78sh#ݜZ𓝒-D@^h#i+(e[19/̶ͫ qJԡY)-![OL:ď:49e2Ž0k0 3c5ō< =^tm0>t[TY漾ar\RptkrK^~v۽iTSiWe֯,yo7_Xd9,?ft0antyMw~\b\ˡo^{ko$fݬ%HH&劋cc! XUIq֊'\Ze͵ˆ|J$!cq JE߿`-Vgfn}HG19HBS&al0zЫb^m, :Y+> . . . )k H$ H$ HM"89S$>,JtPʾrdG F a [Boq?wftZz=>ıqsaPBtB % JH .@(!]P:\^2R#]l -n!28(iE.Z溛.YNfJᒱ#o#2B sʲX%#iɧm:0 'UqÎ˾yn:HG*S0,>ͯH \ٛul~|n!y50tc溗V."PWp7b>*]_ soXRbI024Rjeo8tfimo{7b^w*~+ܱ&t0iip_Wrt eJtk{yѬ*q_knueƀ`jֽDwXx&.[Ĭ 3Jw0c1eT#Lu=ͼ0_Kۺ]vxeuty0\eK2嶺eiAYV6*5Cn6ss!]8jpH8j0{ hHQn47ģHtiߐ#]OӍhDm҅1=]=i-C[ꏍ47žG)w؈yfFSd݄igFcνOx"]_ksf})\_t.M9;K?iNkpxIEM\] IMP5^og#mjtg]EB0٧?Odb֒Sjض] {5ok ^!Z,)ږWTL/ϼ}BS^ۿ^a>sink%tԖbl. RhåH1PK@X\TUxUҗJ'zͮMxS/e ]eGhIo;=*+C@5_.l#7GIHu6OU@3%rvע\kDw%r;k$r!NɨLޜ^IE,u9-?nFI#vm9plC@w!lΡ'0' JY9iaiNj `s01zѫ&*d]ӹ>%%t/]"tF*ڥInOC]LXEF+k:8j00nGٰWxKo$i]+V S,js+5UޱRuc[^|rh*1dgg}q<)fr/1#DN]_r\\iuӅԉ)/nQ^.np 秲k>xЭ~}_޿ iY#h(|ֈn4¼~r˻>ƭh 0-mߨ@F%LYIuttEE*&DuIZh0+\i,atܻm۳څz}]fm<3"g0IOcm[L<@DZufo[$&T~JSJ%򴊧,3@uat.vƫs!VSu|#q% +ζIQf*F7{ɡ0 4M6Bh UW_]:{oJ}p&f?bc *+#$l#ָ~J'`8Z\{7o|Z{P#n9DbU24&ojgn])o{@5m=;8CJ٘e$[7TZ۷!ۗ[UwJu1L:I(ᨮ-mzHjx>=)MBQW>+ pnx!璾C,ɡ_Fj#~QE╣o<2>{!C4;_T86;RտڏhӞb |:*d lMCe2Q+5n!bM^R"3t11&EJu&ːf]5k\ThLG(5fܱ%U]}J)%6AݒTWb7ʚdz20eW) wf,<*nP]l/9ĕK7PJuGN,]ɊBVS?Ywjo_R1O~? p)}-|Tsi]nJVtw,-x-~bq6z(SU=S=F2JVbmBus =GmC᫟S9 /X(|"d@ Uj.4_ԓohƓU )Oelj,4^x~.I,'l츏3gT‹X9veXuyr/t)DXI2S >`7:[Nl}YƎ@ǵY: ?PNS=!]tOK/8 5"d@om|P=y}E:k#s r*/ aŷבcY0C7I7"HԳxPvH6\x(5Jt?K9C:)6]ٟj@qrdmWSut5`\G5Ti=kw)viypLRy<7BstkՓoh"rPhP]\؆XYV]*oPœ 'f;!ãK5y`ZG,#53kET讚N\B$6ړꊐw |: =W DLSB)XG(7ԓohCեPu=4^ZݏVO|B7Mp@;JrA.@~D=~tGi.eԥw۾{9t۟\i̾L.[_SG[B߼';q93uU3+*м. f]j?a]d(mgBRn]K/|I O{DDRx@,TO|B9qwti<9y'5rˤ$_}k[%He9~Mk#=$.WSUyMҩ.Bƫw&TzyZF0G!!vStPi{_9TFz]_\Q !56/\s'uql$RhjfTu٠V[)avNjEQf̞(͇Kn-\g9(gĐ>0&jvh5!e CjsY-=3TOiy||(7=b[UzʛChJXQƖd0X~tm<7Pc{;AiGtOx}OV)si>Ġ7n+gQRO[˚?qouE"i6Rz0Uz/-nH.{qe_Y,$`uai/.q3X0=`x;(L6A2#tD/?3:f IAEC7Dt[cKzhQF%\}]&-LD#, pKvR^-]X a̠a?Xڀagr<tkNmGOu| ju'GX+rTBzL qeƒ=d?=d?q^)mIIj[btANf~-qݸA&;l&zos خq@2=֝Ӯ3zPWDB'ExD]%xU-B}+tGWt)m ,'@(3gfW@9̜DF a>#zsB< ">*fuvu./zlKӑe3^/‚MҖsblj!~ii/q_$1Z$}vR@^ʤ5#KsCZR^;Ǫ(qI">VY9?qX1Z]1<$Ӳ0d!:x%A cAfun.o>S:r՟˾+L}j|B_H(Y}oGG$_<٩.P<|k;U{8\9]M\?z] ݝґY2K"aD5ʳ,/;.@+ >;uY褷+ǚYֶga'ͷndJ|t%;=6gRÛ˟BPtㆰ}RXŨ+⦰.jV‘*N L2曣sCczs?LO.y$^]HඑQW髩, !TҞ떣|݉]NuXQ\[W47^scE<BbKn)a^ i\g$ܯ2UTmg8;Lv7WV}vɐw>tो?qh nD%Ut`KDK)wAMmLczYoQdm:G +X6s;ACU7U:aEw"Ӗ:@Ew(}`uąTN.lty=Y$rr;"'[栗/5aJj_}6)хUTzd.O5 0GNwg׵5񺭎0_Ρk2)<+BZ.+ f.g~g G0c9QJ[7ִ{P-p` &;F+/-)х*.HhX/`t2z6c06RP<-IׅaVؾ'W`B3 'KbV 뻬l +NA;",% E]l $?QjOc>Š,Inp>L t{_6\U.3KEx)[[`v\̤6k6$V ]ۢ,|SAZ)vg)u L~SGy1R G.]]$pe0V%Ou[ VgSP|l\hr6U>,, 2솫kQ׉]w,2my/k>\݆QWCbmC͢u]M|tNw]1ή]9t|mDw̡{u0Ac~Tuj*T_rP۝jD[4ɍߗbQn"U D ѝ1bKU S9-ksY=qo][Y8}Sf&@H*z~цBk"ZZ%w}o6V8:ش%ѥ3&<˾YH?H, ʁJD%qᯌn2)1#hD00R[u];F]Y$K2$Պ.kr8v`k_7 aXR`Ԓ nЭTk_l !A O6SBcAzuʊ.(ʗ⋉QWTyt@HU`E^+,L|zΜ5 ci3â.a%UrZ0*WLԅ[%Q#ćURԾѵꞤh)<ϲ$(ͷoZm'8vU'q!~(+W^a*H~R{OSKSEFƪl 8NoRx5fRoWϙTU>vk{v_TH+1R jo¯7ߣɾb>{j4uϾiJ7DČcI.Q?lu^4tmv)<ϲO|2)ͷ;wu8|.Jt:WdZ?DKTr"*\;54].1:v]I>wRK:%/x#] G78NoRxj$5(ͷmQ7u#;N{[+&DyXe bv.foAbHxfs=q@< ?l7q zr\D%gOjK3 ~NoS5v\Mׇ]Cw>)/;}q#e5D ]h%ol0D޸n*6`0׃1qIS}]Dw^#}]9 zS41.1Ɩ7|:jXu*_|_&х;/5]uƺD7$j⼯A_ڔKj\ GsEK 2 >k[Ϲoۗ_P?w9<ָ.#Z&t@]H ֺOǏ=!;]2x0J\󇩄yEJ6L&Drf(}xI6|ZtfݦFs.T_{2wjѝ8A9K|F b+1ې[NU4žWݼz*@VTw/ǻ]h.gu;O9j,_Oa>wbTMl{ۈСFm~a{[c@rf@Wj#}nMx Ғ Ѐ^DNDJ~m uD}tЭFџ %˟=_x_~`o۔FYŽҤfh8Y z䓻jusv`* TD $t+".?uBjz]&y{˨(""h(P#u0i)%S|%a|[ŧkVPXxƯOnn]eKfӖ\rKFo"LٚGD]Iݓ4]o2Q{SUVk?HoPϊ{/ϥ'iSj$<4aəـs{Y~wJAg?ؗ\>: KiZ7Jὗ'i>jϤ ] ?~L` ɄM2|޲l;n'L?P)">w?mUaUY*VR~PTpn% "VKBcpJ3 _^l /E}D_W?>=sn+sNo6>}ίV q)$a[k C Ϊ &t™\{N&,KrG.] o^KNgi>D'n 4%$xjuB`vLS_׻޼>c9FUBP :sǨ)J_fy݀9G]{j0{{O|oQGը;?0CiȰi|RnTCUњBYz?]2hRx/I/Tu*%䨡zO f!-+n%DnrxO0ԈJɡ)$o^rRdjcu @*{G󺲫[uw!qUr佩K+uS}D7}01i>CI|K ]Y]o.kKrq+Q^[0lYMuTL-eQ7#\_te#mWBG%.Bx^*u $:j?}dj*ʌWհKw}rx3.qoKeG~u& Ş,;5H'ܸ~a .i>RjeQWE] VXBG_ٞ7_%݊ˏ%T@&˥|;N賶7eq?= ?^Ϗ Xbxc?$C;0rDo\:*DR@rգv) JTiVr+ؓ3,0F1B7[~%.EN:[7}MB/OlK #uI۽rgtnaPRtPfۘز\[x}cG=߳xQ8+brw"Ϣ@c]Q5A_--K$~U扎eܸWbEAKej]hrҒ ^ԐŜ[PF^\}_^.i:oc,<@72ik݈@7"_-+kWs-+$=pi3-9aqOm| 3 j\ 9D柫,RtP Z)R}^'!]ǥfB8LT[/u .a¿:םR_eW{#E]Uc%‰[,].pAӺSU"1fWRYHAQF0ȍbm-㱵/%tk]VN+|D S}.K'tž oB}!} yP@tIӸQ 6/,ttu}w2j sus}h_NooN6}{w۔bro~Ӻp.)_a%_MEa*^f"'tzv00Iّ yt?V]JTUٛG1VSȄHVx V6;B>p ٍK|t]K4Rzg٬ |t| !kTR\|)9˫ ő߸Kv}t,[xt^p[#j('?6venB\obcΠWrM'n\,*Q>\iUf"nU<-]L$7!WIףqno\85Cܔީ]lGvaǨSKLΰg}(qrJ3# mH.GQg׷fIRM]Nc|Luysw57J[j@57 7uwKL`ued,R9HL@nu 1aL#Uޛ"{+6A׷uԾ.%4XEՍ﯉эSg>]<{Tl<SyI]?b2{wahP0iKk~M]5wt1 鐵xu=c)xi)xj>R{./^ $)>ٮe9-~! b.WakZS$g`aԥ .;zDOh]JOj^$'t\P.﯍5X*UtYS[­龆QyFPC. !t_i]wz`&rEB]ޟvF)lj\]J9{?+rW'wZg@j_h}d+;Bp.$`k R/I].< \ ]d+aBFjK%1G$R;et ?6j*B.EmrZM NƦ &Њ%?H(6̬Hs¸2]Q!Cҡk~BcAHt0ހ]<сKw G]Ձܜr:Wlh 6rFle/n"t:#zt߸HtM,GV[v@˴r'sA(L:tzqLNKtnCD]BŞ+xtGQ\ a놏nCF]eI/шټ\Yqno*)k4NXeg:v+uOQtsڶD;P@*U;9]?xW.h/6V_ K0R}J3`.ugaVjy-%{;#مdoBXg4n0Ceх0=0ZZ]||L`6=gE{[0QW%ĈcHdsQߤL>YBcXԥV{w^`c.tKKWZ-]FZTC^ѵ$Qndutc-t&.͟Q>3tن47sCccKt;ilPi}oқ9\&] ċ<6cy4}ݙY+UhEi6 Lg^X|}է]>u@#HDV$FAm&? v cB )h,.uMGRJBiš6ooew޹4_HvP(-9+g&vTWM ]T-yX_G=x&÷75 /B7U8jDIؐ(I3a&sLc6]ée?l@ٵw^Lbm;t]d3?7޻cmc])p]"4baz*?']Rx|YyxEʰR\!Gi<1T(#TWb}˥ tf3^ !ԇFI.YorG߆D']oʴ^J哩AU|BAJbu뿅:ڳDYΕsxa-7Im^,ZO ~YZjm%{-.lV'rewkokg4RBwO uޥT,S*"4͞uÉ4M0}V_>k&gJxbUR}/lBtJ|ėԭ %*l>iTfw19Y}*KRt5̵f="ڔ^a d􆽳YR~_46,ft҃ۀ !ZEą_V+v{72`8h%Lqj>_a5u ƙa ,nqtyJ!8UwpKAW)e6.-P**PΉ^:3Va?G&C2}/N 8-No=kBtg 񌠍3d$}}nJN#)rrA.WpQ:p8^mp[9;Ъ1fP:h52ؾ%_' P̞e1G֩&d9G?*-Qƴ9+aG[W)dsŠCRebo1F/%K Ij}E<> MzO?nO-{}=L]SR5asե]]{ͪyLu1I25ۇBsEU{[ޯhz| 3/ĢE6%'ae ?.ɨpUڣ~ߘpz| ck$PUzO_I|Ic-]uQ /ڃIrS]fcꮟ<@tD'Sk݀u1^՞[gIuk`)ҳd}@ uTn",ړ~$6;+6Ũ5fXx?Iu]'ut{N9եvU{nhw5. *=A0~eLWepnkU FMn+Pq*JqK0/t)AWSflU)sԽ UjϪ+͘[}/^3VZMU{B7ڻxRUګxJUJghfЪV}uˆT]X1W[)ޭ0[aV¡,SiӫUǛfpdD[VGnnT*%'7W]ԭ0f>J :եtMڷe*pd#QJ j{S܄`dpw;e ?^tYP:fNu3t 6^0,^ŞT~~{Luv[9:h u޾J=?8+fOvbUѻ cY{F/z'D GΜln,Ţ# XDXE"W&CY9TeS%yiEgc>5 ˛2}ܒ+}ӹ.ۀQ/BT.'2wzZv[*BՁo\|o"z^+T^[3Js݆T],Yr^*iauԾg޾Jr[LxPu?ΞH>O]6>+%5U]\`n6\7ȵU]ݟ4O-B~YoRaV˪{٥';g/ltTsPXbr㯧+,BṮ*Hnq D]V{*/|[uyUzbtw'n|oWh7^k|ʺр!POﵽn еej׳joo'k>ڭUWGϓ1tYr!ƅ>ꗪKl]2k߀O%jݳjo_TY ;`JO\/lBޛn4؀C m?S8v̶oxyz}zvRſ6f.U5vs} ]n)ppY@(bZzOǖh.t{>GWSiҳG|~psxC.]KT׋ jkNoޣ^{-ٞw]VJgW[W~l4mHCPR^kɧ{nZi%ͶEZFK=WsXɵ9'J%7@ `i,G7{/^/uzw2Гh3׵ZJe :{'yvg/ݶ3jAU2/+1Gټ_{#nCW=1`m<d9׵j dOxwǡЕf`}3!alD.;M覃o/aW8gp^]Q,V ]0ܳ5Nt ƜUu L5f.vqx=oV]N%[舩GiHt*\̣|4K63)6S]\w^̴G~㻻9xz4ۢ6Mk:yPXP|B^=ˉw<eJ 6e 7W]>3C!Pף bX}qxd^MﴊWSem=ےܑ+޽]M{"t)ߡ>X \ b]'dY-x' ڷ5!Ŷ]̯aMxЍZX᭭`NvCJU6:~\;Nx/TBWٽJ61TuNu+9s( oo=hkUw|歀bWɥ&)g9s|=xRumq~]TXYk̚oR՞ r54R1',@oTs!U_.l (7 "6Vx{k>c((Rz#ilו5_>쩮_)P;vTݒjߐs MB{S{Smά[ajl.Uwh4Yjw]w(.Td7FpZ;BnnG7h#JhZZ2-;( =Y1yi+S;[R]07Ub>ru3k0ՕVx{k~ݴ}L◦o(x`\{*+|S]!󺋿*U oo͏|Wu3ǹ557b@ـfv5*t1U}^KsB(x?ـms_/,oP\n=u*v~ ʧͧ ExAUWTl*ȮCWAnUan6>Gl>`x~Ps( u%h~{/&HQ7еQݎ]pNuKF w-lsYsd9⾎f9 9tߠ%T}[WERkр^b#f.} [磌:l BR>7&P9j1U]\`]2:BKM8b9t'|QǑՆTW+́]dWW ?n>F-|yLʢT/La#wOS'U6Wvy]8\QJLv;Pv48 K ?moLV\U{s 7 KYm>Jr)eܚW z/ q /q!cg:+<LF|[7YUf@w笊=ExUtݸ@fdw۱Ǐ'SKg }DsO3ZnNTG}9Ktcy~o BskXV}||,4J83;{sYgIuka][bhJtJϡrXbTUG]C]IKSpL=:btEr*yePԩ}977ٟv|TD?ѝG _XOom\zo[Gbi.Z+k>rՅ(.UJ{`6ߵPbE̅5 zzItJuw t$3D?,6"3V[}[vk2re~GdB[1. qZ4;MʴGu*B.XTWV|%W%Q\d"8MJڜYu+>/`@ ēH$E>T AcYخm/w?%xdf%>s-kdvDLF \u1qcAB'UM*еeW.2#/mjm~nMt/K|kO3|!?athVQ^6y۟lv|KH)LJ;5?. .D5VxPorF̵[Uktft(y)>xMss]r%8Ex;Sc8_Fk(i뼹V` [zLTaP{hK|iPx[U0ƭGGw`XyݱEƚO2 }b㱪?̄&WJCB4t kẏb,G~:ex6{޳(߼=:յ]B GB>*nvh7_7 rqz R]bW14ZanGC ޒR/{VoEQKbѲ"0FuN섺.EDDf,&%3,?_S}ۣ_=ګ}=|ioWEbաi.K'3mgM2/pPxOa6=Yq̑7]$^^ -DNíC<̀+QzA./p,H5Tg*JGmw.{ooHƄtAR4n#}LB?O󱎮ƫoHD[DZ4*_VoṞ.MCXwQN?/2F?$\dK|+)x`[loKhԴz)UuBx0KL&Frn'g8[N_Sȅ\>f@Yh;5[.^}=!<-.,!҂ PR- >w_a~/u6>tZ'{Hs%vNterYE`KY 12kSžzb{4AgπқvJOAw9֡V~:;"[?甠} P׻za-UiiXP"ΫݫT ߋ=nO%yy-E޾5ݑo}/4+:\eL@b?7I K{pɔ# %)YJWWo|ƥ~窖[/3>j~Í{ s2)=>leOxAh/.,)Z]ty:- ۷kR,x`m%!,RտfT tp$&^(K˻͏ }-Po܂wKQf.=Tznӷy[/K#3AV$YWK+t)ZTz~~S4j*פSNY+܅ȴKЕGsbݚJ\ K`՗9t5)ד[š /N ޯua̺Tn  tz5 u!+%p(%*-1Wk]wǵnhs 9t5)=SQYb-%%Z7U!&`Aב]ѷO pYfֻgDJ*GurF.j;|^hV034Bs(ޕ#tGx#B3>kn+.Z}GdbGkrV !uj.=߃n,5ЌGk*t#Ay@⫸\.Xp"jnTMe^ҳx~|T)]] ]tU/aIӺWJ7]X * ]tkj0}j]sҳX! ć s"^ ]zp,ȈuzN})_{ƺpIoYWZw<-HA͛==׀uBW]ɪ`ѲnHXY_<ݣ)Om0]+e0u.;ąwm@%՟ RmY74.!g[z.I - 3d(iX/dSHϱpTz~6/K&B50ҥH:i0լ Jցo,kh.+W] !?+BBHϥ{g,=? Ssϗ'"ga(o'hE/A̛: k#v,`AYr@GK+0/WЌ7_0u]\95+r7hyމXb 79aF Rj?FR8B,G+=GM[oPzL|ЌNTf]<_\Tg]udQlxj*+?@ \jߟHjWzg*=?ٹX s>.Kjy"Jo+g.6g" ^jX8JuJa2tKud9.sf$r)^7u6,p@-?@=89^#ΚXWC.[*5IngZ{5Tkk7nVX^j%#JW3K;Txu=G.IkĽ˥K cn"rZR9bY+6lr~>ZT`]qE)qkqYmIF>֪Y oqhgRڎf]avu 񕡋e7n/A71@=Юt: 4ڎOiV`gTJ+^ ޿UMao)-444D5 sw)=6JSXBLǣK޹0ƺ{!}ˤiZE&۫pk9bdzuR\#{@󷺁h9,Rx[\_.B>1 Օ4W07a 1W ݗ's%ru0$`F1\/ͱTucĺll$gGצjmT ݉$"noHulmJ۲;M!w]="ث=lW0{9|5M~XD$2=^7t|Rk7?/ˌH1^f;5J3RhxN UuDr0a=R)ȡo?zuO*s,W8kS*6Mu09=[&@7 нtBbd~ÉclP93XU>K2jn:!OdVu qj_k'^24F[nrs"fR=m!$s77_;8cϺ|mKK% yV7\GPLAn֍qD߮sM9ѕMM3ѼG&Y㙁z]=-}*p'1zZj.=wuX4?X?Me*Jϻ[+[ mn3f]Tom[]!,yE+=J[O f5[j?ZWz zt[Xzx-p\9+G V~ y`;5u#Gs)<@h]s%i|%Tq[zOt0ŮQ ^BYPR2tZ>HuG9qO~]ѝWfϡѽx>zFeצb ߌݶoXW{-<]x_%)=gABq~k.gXĻ.YR{bݸ,ba]Qb.诹>X?.cQ̺OnuRk9dYWZ׺eZ놨K=uk>uhХx>cFCfmٻ0<!qKVkեUj%"v#HB"_$|(Lys}۷S4gn< WYN,< Vrޖ]zWx~PVRrf:|TG-T1^fGuE S]TjpPjJ[^zmyV4nl=QB0[~rC[~Xu@*럹RR{SO_Nyy ՛a~u+EӕSꊨ=0<.S ;0tKbW{\NǪ+kOtlu}T¬vvC)u/__9(ȩ)zuǩX98t䁺5c :x13tqU˙5#FC2_j4 WD}]EFo96yLL7> /N3q|ѥ"TOdby־|Po D[2 On]?LM^^K鳘ͪ ٰ:\Nc\c䠍U{\j߂9`Vm6A'dwyH+1@QWj#+3u^ۖғh[PAMqyrnpN) lDu V~Qjћ܂} Kc\]XTsX}VC[ftH6gr"n 3gaXAYhڻyf_HΣYh?];}@>׌޸˩+k 7W\+[sjR{>>\OL]ۯUGZ^W]Sg.vu?iq_WphoP9LOU{ͨ=ץs=վ[̺2ro-Yc@] JkG+̀( W.TCWOS D]'վKug2txW]ZaF0j/nKu tH ..0#uK!cAXܪyD] *R-%bͬidDiYRlrzbW 6j6v&]DIrZ޻ꊠtUez) KT1R] [0B{ƪq_7F`>w=9,@izue_T=KOfJjR]݉.׿:޻TQW{aF0_joE.'W彨.(F4zG+J̖ }ZO+0uhtҥT\ѵ4 X~^8I*PTQW{Yz6?[7gyFjeaxjg"w{TRߘ=ڜ/]}ݠݮ~#SQ#ލ>=w}COWz<ȣrwu*j߶hW{ 2`buL:+eE݆6VaBw}x3uڰZzLr׿'63ű8\*vp?g,osu8վNSdxh.gVZ\Votgϵ0: `1^]}9̏v6վN+D\@$Iعsmƶq~%x/7ӆl}U ꩮ+Ya~d<_=_^gz N]_N[]C]ro4j3?W]I^s`sl&{Uԅm\uxtuվm]W%Mw=`2bwbW{`ڇK!  (^Ymj=|O\a,ݛ(`in|"Sebś JݩR{ kWPw.p/"_.y h?Ws]1-LldOuMGkM8i50 +3-ǯYj=JӟtWC(/;m~ht>(ij=ЩVMVr)wM5_WTxTݼkAOtlT0*Ub-ҪPA(/jTQ/ -tW">g6Փę힯MNre<;sɉێIXR^jj?3 .cQ/WgoҺ20u{vPO8DTewXQJeGڛ.#"}'I~cux>^u%.Ò;0ޞ.8PuٚW)}h]>UUJ3su>*t6O}R2Zh~?0ו4ze]~K n"~)KT{]uU>ӯ@Rڇר9DjªGb槞O~aOUǕjO㢙KF]Hw8 DlMՖJNW վ<˟M((>tMZRa۠<85u>ɫx?AY{[ٺDnWSdT{*#WTPeއ5^dGjOnfի[(uQeS=RtFH%r@A瑬tu)% ['Z.wQ2{0q-';q2o+獬;/Iwf .rIףÛz#]2(zֹVWr#uTVsBD \!o7țgblMϏ+=*j|UZeUhl"Tj^.;yr=?tE5Ql7}K:R^_5DN!^E oԚaW*T{2fTms } wղjo7j?7Szjo3mFe]863"5_oQoj񗡕^߭yj]]cV{ X{m\ v_"rO̴uoyf+=WEm[{Ƶڛku_ĶrE6Y|^YnԁWQ5=_v{Sqc}W+Oe o֚?0R+{ṒMs]"T #j7|ywz~\iS}]z|!_ PE|3W`S\⧺ړq%-fo[S__aV h^{ӽqCZN> N\喯T{ȒK'L2)**V^g+Kn|(;Bz"]2@Qh]~]e^K(L֕ͧ'%~jOH zrߺFT{%^>Ȋj?ļ@_ 9ڃ<. FwIAZWV \ykm.Vu;281=_!|\@i=8qj};B+oD,ۺPΗ;R>tbi)j^z}|Ϗ+՞*}h}lWCc)rnd]4&:>0?u婜]~03VT@Q46Qzצn\Q:10OLuuՅ&9SVѹOJV{՞o76h2 f&_4#* U}X7۩^T'WFT{c9ק_TMhm4N0έXrfp NZG%3j^z}fbƼUl{_A& ݎs fbKIV΄BoiQ|RБiP҆'̱V{՞{~\iQAEEoPQ[퉜RT1՞{~\iQ텊M}j5CDNTܯL,sSu=5՞maNjajڷzȚcuqhv 3=&{%[D=RGpl]2a\'W]2m:r/Siץ \u}:7%RE W "u3-+s*d!*9nd0{$K=qt鈷v?¬ƺ˙غ(G-R+غeePl].+buY[ʠغl]V`2(.[Auغ eePl].+buY[ʠغl]V`2?MkAL״)VZJF#TzP'ŃzԂz*O$x O9HDZn%`mv>yYta!ta!ta!ta!ta!ta¥ڭjZmEtlTcQ!]tҶ֝o?Y!]t03w݉ٺ{5$*]w*ϫ}ꖓj;ϫ}$pjȾܧ[:Vj>%]Xt%Yx뤋#]S҅EHqtau5ދ%9!]d:Zd04HGSw`8mGOn6jҝ]\ HFt~ې~OAtR"GetS^l>L^?7>l> ڽHM슐ڌSJ];Lw~UkE)g+n ]ZުVwm^L7~EIc3m AVܟo/?\QƂs]\|Η񷬚F;1u=¬SwA>3ߏs9UWS馅3G. 9 `Ѣ?F5HT0WT>sx ҂ DCЁVg7݉TeB Ҥ)3HH̄K0V.*!]J Xt+.`%DHV"]J Xt+.`%MC #_pv-fMN7ݱjNOyK!%2퀛iw19U}wSqkaFȱ`ޒnO5Ψ8=ȱ1ش9mSPqt?l[͜[3]ו)%I5/tkƯIEQ7OfkL5[ӑ\z$mZVfnFk ڢcbD ~k0S{wA"~A=dzq߽sM36M'\y1`~0ƍgP9nq7 _C@k5N 7X)fXL)9Y֗,0f& <vx1x;TDQ? Ԕܪ/4 %T/Wdn-u<2.~[N{j/O ͷ%""!?_)k[ |]ֿj_]IENDB`imsprog-1.8.5/img/sr_nand_en.png000066400000000000000000001056371520775651600166270ustar00rootroot00000000000000PNG  IHDRRWyPLTExؓɧ @e11297{o:Uڰ}bɵW9ˇf4.?42LjMN3Nm✚HAsʍRTzɟyyxr8BuŎЬE¾j}cLAjE]:H̭˦zj;j׻!"L9Xez^Ӱ06aNs}`NYϙ ͼĕeQ+n^rWab<y# tB0đpgТ|ꠙℊ }blwWQXa|BC7ov@=l9!heѯ8ʠ+tRNS@fIDATx_n@[[8 ,TB$ސ|~;۵4/Ϯ~BOdzdz-"dz*\)2tMgG dv<v-L(A&驔.i;9Q-M9p,27`\utgN3"*9o9D|:}-M F|j[9q;܁usv"X?/%n)ti`o&ߙүۈnh.?4rO&"OQ_E2QT/%{ˈE:zW}_,~|Bv#MUuUm.~9BT6f8<%ja<8q{>LG3=\f~A/;`UE~<ʃqW<_ n7Y znWTX ]ʽGFm!:1ӡ8׀s! ʙFwpK-s}t0Ny+b""`p!:uTNa&]؋)n|4VBֶ]4yO2r9_,eTR4.4̲\8MJaN=ŸeWk*!/СP jr*ŧf:M-"n|x4s.p߹/3' (c8vP3Y|暇F7&R $%vA5P]\:慨[e;GX $t[t=lz= Q49u>\{`!WU)T]uؤtףQL}/[j]b(ocUdr&t<H 8#`wrX<5 zbﱪ]\GG,dWQ]^V\yOl}9"/Ǚnۢ#ZkZ0CjY˹hGs"(R>v"he-^m;0͖Dqqآ}+6,[qE<կyQr\?lvuUJO]B|-[^ t]{`pqf5G:F눜PTɞ$y9@Z"CDZPnk/27z{&{lGэ3>%F~C-NIQV)߾rܿ#7in7_٨)it#|`"m}3nOwՀ(viLjbC>k.M&S[ĨoW8_Z0~E7ѫDjTj[d4 wi4,yDc5n;A..t&5& S tCi"޿_%Cr/-a1dJ-5ܚ?Eɵ!l=Ώ^JdppneDK )\( "rOg{Xp<3;vg>LYxkV+Tzd{+vͱ- ?ag6,dl*F.Ve;i_o_sOHPwSAZw|aIRHWbTQw3/kx^Y۰jͮlI0242ZÐWec%@$2rF3?GˬafzMfԪ|sM%6_g0BB47_UzB /| WyGb&`cdX>A]u<պ#@. "z_5 񤁴c.MI(nZKi(u X3HHu9-D MF*tZ`a!ތBbzұ반%czǰF9` 749hQR\_uc@b䈝2kM4qhнb>#T͛ P,5 JdVgPj+ 3լ..tq]>AUϺPJ>? ͟RWeJIApMBx'8p`PTjX INs׺xx =oڴ)*0NQCjH2wN(|U©t<ZA+ (`k]Q@okP 5kMKӯ*:I *bP:u؉׵V^6LDa ]XT,1Mqf^>kYg};dl3s.f{C:.47uy0ୟoRV%I r.4-uyACBk2U?9!Ir՗mF4EpE&. }/Q)spj "D0#HRS_թZF3R/ 9W (3J^P]iN%C>>jh׀䮻Y-2<,u+"HSRC\12^"5fn"H3R$GQ P"dL ݗEQTA$@M(Z sޒݐ}\uRW * I]A"L\M6TO\wk:4>,[p7 Ҍ"IʀnVR5Su%?GpH&S297y'kGك#u@4b沍&.[TBӗ4jk%~9F4~xيÜ kl7qcp2|-"}*^2!co&g>Dz5gj[#Ak5tTePTwBHJvnz],~O髂u6PQTד#uwE=)2u6^*84#3m۩G")kV3swqGu'Iu .uF$޷kgvGtõs"yGr`]uP;oD[_w[;i]mYIQHܕ g-bm AOκMΛ8/.wVtn(U+uT։!]O4icN$m3u{Jul-Q#]ewvN v-;9u!a/QQvlg}od]7pxuגp0|z;YH:S8v/Kg9.2*t4te0jFiN(uG e>fl >9+y92 Z8=F$5i2dʌsapY:azzϺ]Ɋ8dRQW/B>5ȿV/l+.np`.M@qdS"Sؚ):ȰyJ] Yn(iG/R:on"iVLݒFƬxg eY+% oDksʲӇɺ,ԅ6}K$fKv}U Pݟ]%[[vܜR MQ=Ǻ9̞ 㜺`;um yn8RPrkuo{ ܎qsA]AzTNv<[Ɠ/;Q'HOB['Q_SNQ71Z]{M?elAxtV vލ'gfEϵnݞ/WhHy儀nĭU%wIJ+/ep,* m';_n޲٪d”7qf0٦vwDY'Q_Pva sG$a_fZcҏbIV;㘺jF&;ࡖ1Gzon(jTL,rTߤK2PS8d׺w}&v<`*öPo[5\X?#qؼBƟx F=u? mFF}xg~07TJt3 oDu?.tb.5#ЦeR7e@45f+f>w'P]irZ?|0jH}a D\Q ^#ْ'Euk]>TޱDwAqj5еmOÌ MN]fRtz Tܰ*YNdⶔQ]iZ: >q CYj:.G< Enc5pmns(M 1yB./Q]iNHԝnX ݐH-.&ԽVw"/O?XF>w?.DQ#3}fMU[ozJ- Mx%_&/)޹혎vߐw9n칯63"jmtH xiyG_baPPR蔹W aGX7Z&[!kJRv5Q&bJ]M.d(ʣkܑ'OX7j-u8tu]v*i[DTUbө}KgG/Y/MNd]A!tvFקBD4@W 9uytnª?ZP;88(ЕBNdEn8З4Z"Wzk+V^r2Knȥ]X t]f]P  ,4d}TerFwg çH1Qؙskt$t}oX[@*Hf#|Qϕ65`=l0YW},|*jAU4lUQQ{7̉ AA(bo~2;31|u<*CgL:}\Jo];ar۽dٙ-sc6$|i3Xc?nɺR <r*Ũ=fLlݵWfifҴ)Pak#;SX3ۮJ }>#4OJLJI|8Dw҃ILAr?Y'MM{Gl03YP#]@neK򮾿lnͯ1M} qk|Oѝ1БCSݹtԇل&< `= 8uAb ndMNU1}e U}*T=}H\99+R]}ٻ\hJV >Q_B5@f.|jƒ}\` WZVWzp}p )R7x Q:.uu2v#ݨ{GdN29rs2הg#"KpX%4J ϖz$:ރ8Ue,H~]!X4U;W4Fz8R m I̵אV\q\UjAsҖUÑSvƆWCrC%PWF@S&/߷BX,\tx6'ݐ:A N@(U%DE*Ã4{wN@^^ &_ 1 /91mU7`>s˅hPuCkom0/2(ENUӟvR,MR?<,0&dxA=errbk 7EզY77pnj#Η~~ /{Jؚ ~};VxYo]Xɳb-γJX  p'd; 6 SEdeWNMcD0~ U[14JqVu */Wu2z;VuF]:d|Id7|: u5A͗My}Уg!݃Q: 3fu)3u^7K,-ق"TK&P(pT 79Lws$9QGgŽi.Б>^-&о겷d( B$5O(UO0\g(#ߊ%=Aw D1g~1(@a4M@˰wRG ^usrjd .@]4/M@˰OER pκbbi'6^Q̝]օD= >( YVuNB5aݕ+| .a*Q}J(@a4OWO%U Άh}vIC7ǠJ]%AƤ3n((oW Ύ X`)z;НR&y72*$*6L a % }IkP&Pޮ4S7RiruSdMڰv8o)tmb=#?>L [1S7 0&' pC@yL]XTԵaݍ8ln{l)DɩWIUl@&x)Kt& }Ҟ$$XL^7P@zIНR[\WIUl@&x)Ks$ pC@yJ@0ʉeo&^?tuMb2NY'Ǥ3n((o^)kzR{.{7Ut`8;t3NY'& euի)o7GX^U+TlH]6y4T]3dd{f2 O]Ǣͨi|W<X^u3 O]Q7âu35wь:Ꚅ@w4nFB`>w9r_Js;kG=5329vr#Y}ԝS85=;:9`v{{釺fZ@Op !S?C},4?ܯ.mm%& /B|@ ѩSoU5{]]IE? ~C]ʪ{1l~w /хy #]tJRwt5>qL!SYëcu!/5\O?ԥ7cE7cUDtyG2RDyhu؟?u56J[CwrH2{TS-[`1iKo4b*vi4=QB{H =E+/YR xKoϺQh @hd`t^ iUvaDS5{7M!D8OKzT#e@uRWUF fg/y%H=Ѽt7~9y;l{8%ѯk,m<qlsIqE\??}/>U>wRaQ4<>tVt1U<u 93jE/9uGBu>hktmKF7߇a*mC,zLclZ4^wu&#RX88,Qw(8jVZM^pDW pPgNRM?N-WK7ok0Wxkr?Z5ź. %Z^ےW=$i7qE"cP{-mIK.\f.Cj8BtmW?ϭzE{ ,BW .v_ö%y2x#yɯk`e4t9dj5ѥ~Ej D~ ᩷5aLy=7+LY[[ 0f[]e~̠!:Ԓ=Wmx\15&euϟYvm`o>(-wׇS Ocqg9Ɔ3 GUt?p=TLʼ0L_m' C 0&;:eMwqpl;d_΢?).*_O x`Q! ` *r:l88cLTuM\W7aLM8yoq)1-$;8cLkkU\km) ӺabW15A}_YuMJt ` v צE88cL宺3N_cO(6VW,GK3*0[CQƔ _uWu1̣z4-\W~tUĭLl8H)[U_1e4aՍk sEmN:Nu\,._]2T-ke)^[.&טM=1 Ne*=&u)cʿ{[}_at3y{uuݍrOO׈n"9揿n>6h?vt|?uaZO[AmvSTG7#ޣ9L֚|63&{147o~987z8f$BW?j뺉q_+:ټgd!'Y?]T`zNEUGWdMFG׀%Gds EsjS÷]8"t ]cH87dV>Z]:Pumkݬ>G1{~l2PHNtV݇5:.x_D?:=GzGo1D3ЍLx]x$-IN آ=̉Y?XРNZNou9냇WҠq5l#N2n'S~a\!qSߒ {s sʠS?spZk=[:g޶_a.N&3ev;湃5Tu͡cF}g:L^ )u!@kk)u3\w;}Miya0Jn8O)t@VfgnSq^k=̆%ѿMTƾ,*aTubcy8-]t;l f]CG=n}#4Ys:84Wp4<8DHd")ogH"BY5kхUQ4Y2朵 %&2%8 Stžx>d]HhOuB,sSJ֍n]ȿsMl>XMj],,fCw2]vɵ}Zi(q.5G,Ǭ8fc’rK'~Jh U^l2ĆK #s?kպ*]Z4ۆFM;gi_ =/Zmg}&vSI'©_!u+DWCt1W~b5]Ŭk\!Y׸R]SF7~7=b5'Us$O›n$7'eIBhxkɟ'gy3#�$QSmrKOɦS#@3Zm$GKH;ώK9,Dwko eYx }F )]Si-KM>_tRtFT$solʵf.P1$/ue\m$|02;4 ?qҟ!R?#AvHb eVsJ`̡+v1)jа W'铩:gMx0{Og1߿ucy *z{Gk6lߩagYwb. ,׌VwQ4Bq\ $z%ںݹVFM29UtNXE휃 /j]Nv;ˣ/ľPVSm/tfLߩ.!8@/*:%=YM2sNU] y o[ znd&[Vϟ6D rz8"㻡N%DO?u;B}&CѼe,r<γ* !BHpIEzϚn=vSNM+2W7UKniPn* /ӡ -Ih.0]~](^\ \ r Vƒ)6xu DẄnvCκM禪^x־4r~= *K׏Cl*3/@ѥJD\CJl{̩$p̺&_C7~<芥@ʆZ|Zj9mŋX@2c>/Bӟ6ZWtm?fxuE 8fHAwm4Y'ƮF Wj֝e*ig.[tk]3.4@ӟ!.`}9zL?%Ї1A ]eMh}]hTѷYMh!XCi ~Eӟj݅κ3qc ڦc%(+hojΉx t5äp}]4Yk_wA-11S4;"kK2tN'E@C"MeXݖnbZ3-\ez2=, LvOORtOMm=1*3^Of'ۏLy"qe|t[0?}}%4n) \!2a|^dtinL͈#aD5־nʸ/] [WhDU!q͹BEt ,㣫˶ni{t1`Iѥi9L6nJa=*M^v / zQ1e|t[ֺO۫Ή~4kt\W|: +'/[onxeQtih/ ]f]D2>-FnjnnK7,򱐘)@tdEG`YmJ49wetdQ4Ђ0gO]4Yg@WOrN5?4sTbґ ?ĥ5>/ڀ`[F]fttՆY4b⤿ORaMj:@]`)8^R3AH [`9mEjl̲jn\ <绕߭gyoOj] EWStz=V[{ɋf!"i:ѵ X*E3xTTUtMtD32{CmXlj}TTHN0uu]`ADFP֋^}n`t^&S tak]ewSUJGWpFZڝÆ,,=W)\]F܉ԵE!xE\7˚ʌTΆ]Aq7PyHuDODnnL]Tntaɝ`"聞 ֺX$eMȵTBȔ ˘eBeGW v$om"ߏ6EprYw9=Pv ݺfpqȤ6jL/g6 2RWJnF_zf1w˯ o(?-]q+FH@TEm'.{SZewt_IS"AfmUO5 K=C;Ǚ\_?JхX~t1uYsE|?Ǚ"O9Yf;;w5C}Q@Lˮf]mx~'Glt#\]wH&J$퉑wONՊm~tr%:&v7MXdXp@)ܛyB~Ahઓn 5O<нdGntէpDl7Žuݎ?kyɡJ mzatX /"KA t]^L]jԿzbFUfiњF KS_ռy~ݦeZkNǧj_>>]v={n'_B'fpnk A(7-ܱnӫHcͳ)emyyu7 Lw[;U!݄sOO'>`N벑(X'yڢpq1̱vtҷG};r~Zߛu3NhgiICѽz2Зa^KB3ffW9 M*fgaH?(yڝDT\ϻ |YB^۠& Z/0,x>ơAѥa lU4uMu]Xmuݕ^$}uKRBb|4 dxv%a^¸@B,{养*7ì_/k> k54Uty֍i_ͪ.΀ʭFG0`pf/forZAGS.o jݦs)˰ DTeX62,U(Ŧn˂I2vv*"S7ԛ5F;Btn;=;J2v9vBxz~1{:va6.T("ۅaPDSR$("E.. Ht1u]8!LjnP Lj/짉(ÙHVą`muKwE\Jqkը(-"FЪP`$4)/F޹tg33\>]ԃ?H~n5b AWKDWGRq u1nJ &qHvZ %Nx РJFNHR&1nWv]0ԉ(}.0z1yAFt `;:@K<+\puSo.9*7Cop u a}j_3>د'˴=du`{{X}}mcrҲ/L\Be.85-ԱuR‹ f Y=@> tZ|_޶p[Y[_ fDk=^1$E.]# 6iNХR1v!î9mu^G8ӡ600уCIkV\֚n!wKoS"<6/yyfuDx*ֶ/L\Be.8kIt,]@)^w~ϠyT)'tYd4ǎ8ceߧ{WHpU?pYFjϓ s_OpMtiP76z1 '.9Ae.:PfZKludf25|lOz|t/߁pTq]',ttL+|b]Ep]'j9BF `[% 椫>ȭu1dÀ"1 ՛+UD?}GrVAHսniGnz $49ZZ=mNݯۈORn[#vjK,Ut&S]OMsCWjWwi+Q]Hd E|1GO_q{V1C7v_f6+e!Ptt+}I[hď]A\IڏW4ԭE\e.CwiQnM|QG覻ZCq `9] {geNv9 nta.}?c2'manp'VN[x^+r_E]}z*n~i4]Хǡ~v+E[?Mo_:t| t~2>|o 4AU`ܶ8}/N7NK%R7CT7p!7 Cmye=/*8чMWAt naD.DXD3u.`x1H]- E?9TAt .~^ԃ/sMn_ݾBT\]1. !Mu9ATcjQt3늜I-՚1nMuΤNjոK1NtnhJ5Vc5Nt.' (xs)Cꌂd;HF]yO׃Ѽpa&M:!0~m7ٳSuB 2覰ZZK (n+8(8h/ C$ݘ~J/Bt}. f0Wg ݿ~{_:\cݟ`x*I fP(e!]TD7y4`ؾOޞIDZv]0]N46kcǙ/ktɞkLxeyݲy.GtDߡ4i0 5Tk=(AK !oJY˂;=륷Wd|c% hʆN']00&y@J辮V "bBGĜΝ)-.=2K\a"0tɞuM/Ussν_ĐbECU͡Jm5"x$H5:=Ykƪep"oЫzU]GB9 _xPJ !K.],[vNjgk=C>RpVNu;H)8|kPugz-8)a@u ln!9 =qTgTM)p$8IOA2D){:BW 0 β G;p| vrPr7x+7^H Wqg*T ήFZR^-p Nq <:_"Ԡ{&jcJTi*ۜi#)QcL[zj}Tw}9aj6YQOSEst{I6R Kuwdږ{5 QŪ_X٬nu ruXR;5ZS6fUsK[LAݐfnTnY^tBDh_~3 3];#W`7S+̵YiUd@|fT9u&Q] 3wxUbꂃTNߩRAh"$WP]}3:n8D1L M=9+:Ԡ]aēQJ~]ck$k):{ 4udGϹMTZ.i l qӣoRVxb֖ D];&xqXi/_+Htߘ`zT=G.F|Vnԭ' IRB YA[w``VDOc=Enȟ%-yխ6PJ[l*G7=qe,+S.l 5+.U;i{KJv= sՁVJݺ8IELV]Dj_NE7UXLBu TR֗e=Anɲ+ i.stzPhൿWխCu Tb";t` 'FWœJɾ ʒ #$V&UDFu | 3D6ׄ"K 3F]bLuTA .NĐA .V]1V;90C-i0ȑ n.1A-e`Eyn>՝e`zWwr"p<.YInn͙%vL=+򝕨xI3'uTw՝<T^ݯrfExfvΎaEP] ps+Ӽvpx?4f#:uZ0.RF1B].7(Ϫe)fʭ1 Ū[ F@uqs0'@ey^ᾮq)+\]L׉[>iuMn0oɴy-|C]1`cؘ矫zQW<Ԅ þ]TfP{]c'TI~E{v'9534s$=So,ؑꆬ.{8z<UW0u#Y/dn1zeP#[ stl0 ` hu!xœ1uagM:_۟{8\wOܑ}jT?VW`_`$7fgoO{gM#-#;!3Rr@oN5j1lNt [OT4 uM31 A5pDBy*hLN pg{4uqxޭbP]gU91uώMnmL)U4#1A^)vԍܭQ]lO)AkPugI }n(|b50A{]o{4c/ˏʂpx)u bG$Ne:HQ]vhN൳X\zG[aN߼L K j3̑]֕#Au$*>[oO[Uێ@LS50-hMNQǏ U~0IuqlCٜ@`$,œs2"Y+RlG>^`rz899sҞTk"RAd&tIDHDHDRIDn6RusMsQHƞ } 4?@=3K]n<˖PgD6(mu_!%Z&mZJ t3@5ibDu{Ej+uѝguhڵ[vJu'ϿW [vJ;D8߲;(FV(ҁ.'t)Uхs!O3*WwLupL~Fw6|Zx>}k ][tKE8?3њ/k?Jt$]j@\-GNw@YH"%"Pھ3+(|o0}]P|](о]7.(&uONZ-j< u=3pEtw|)WKm찄z[,eVMna)5YLJKfv] eS{gTSܵZ'$iV|ҨAvȃmb`QxY&\|oJ\_ h(62$z>ta9W^{@,X]!x;Pz%ࡍljGFφO@ VÒk G mu2?}#Gr%y}U~ ﵐ7u PwQm7ߘBtܚ.ɵ7uky`|ۯ (ouzԉ֏3v:nhc/iXQYhXNdmE|%\6Pǒ]=c#Fkэ0+/U瞕4 Vtܛb~̀8?2&2@ꄁJxkGK ݄x ta{6\D7V ɓg~489.dBywCDtYaC˻ʰK'b>d#Qadt,_ LB Dph@7CCwa|19z|JFJC+ώk⊇nS5n"!Wrͣh16yy+ܨ>jq45=v8VR{H.jx#%%T\t?<֫}<%MATw$W@Wk}ݬ;!@7F`Qh]l.p]I'˕aM fLc{%$o0%:}/M%`n@1NN1w꫔^y|]E[989< dvEP7Ic~WYQ#f䁶!^+8R,C N]Fc}`iy /̵#V7>>EF7JR+SEJ{٬JBNY G`,.|kWNH.yN>=Ŭ=`vTPuconfs6, <Kiu=fs DJXGQd6:q]FcnB#LQ_LռY ;莡+NV, / TvJdu~_UE.ǂ834*?̎B WnML=떰cMu5,0ta}0/!l]nodja ^f854怞iWkGO6ZRL^UZ`uFck̫ܸū#0GN-MҺ45g[{/뻛¬F6[a+;DהiF 3JmvA}1.z/ݰ+-Ls㾮VP mW jV]j\tUAWs_7ePkT]aN 9dT]aN}}QeHt)9i>VDDi%CKVХ\5dԪduKGǗaPu]ن1_V&BU['Arr6ycNC]6ΛRwrHwBe ..I%VמbA} `/EŔꓖH+[ Pn/1"EEF{D7tJ?QĠ kPR\>_2KPQXF+PM?+ѕ\<.v4DY5<&$a(f"wII覰 _vyQt=b֖yWٚww]~L[C?Ijt׏@xcXL;LDΞABw0׽ǕNEH5aU}1|]6 E^_Sr 翬}]rf }ٱI,K@ aշ ͓^gu1P]"rל6Z]׌}6rf I*&"goYn 0j8COSh_Wsԧ@_e:u/#]uIkϢmu/#KSV]L】\aFtOZ4rN$!WwB&ߌEœ?+q,0'"gOW` KC)9¾)@][a}][tlUBkˏOs]ׅB.c"o}]rŽVMDΞ@B2R4$KjȨÜ\%]J?ВAK&M;:jmt9."t*m\B7E&ݵ sVc7@Vw'Yjtd(Ummݵ* 85yR%{Cuj=kus^wkVV]J=)ЭBuUۊ|_ev,~LVҮj/W7iK8%Ỵi͐Aފi\^*э,x{jb,fR5YO5^LU{vU{W˅U(o\62_PE%]4Xݵn[+kYv3qLPr_&klj*KLCMN,4A-%uU{]oB SmRkW.gW+Wn0Pх7歿L]n3] k^~8R ]KgBKDX]o 'W낔V7R2#[ݲfF_u ]S^{jv>$$SSURk. /XID 蒯kliV?3th'LAv}-Ӧ\™abww.jstI6NO^NaW'kliWvuKm\{EHd42_UJ<?s__KRG:<@,o;l~\8-_aG^teHrNoTqɉ.dBJ ).TtU<˲>_TC.8S]JrU#.B^Tx ֪.1Xk,=~鞠X\ʘo50 8:*KF\s/}}oQFM:*~X. b0bA3/L{RNCÝu;+sͰCOxm(55~5ixWT -~:ԅ2*0א梁_ t-S\R^a(,qygS%1ɼyKԑxZLϾni u&8A׻pBŶXwIгf{5;%?Ѫyk.\ʣ|zR賧jo%х{[ZZV0@LktzqmS¹rOi-u)}5w;|\B gvN¢mʲXJ5U~^{n:4y D/d\w%s`x.GEק%sQKݔ^yN,̧JAƍcQjqfkcUt}s9r ΋vf]y IZ\P:00% $B*Хrn"w  ҲV!dnǺ1o>{:oeOƷuٟ"DU+R\.|};d ^͡ bǽ.Ť2 ^Idk.( 1hc_F|ܡ6PKNSyZ7`tWP賧j-7u,u%`sZ3^oST@Rђ@~&e'x QQ!sd-8OZ>?2ÝB=Vkmq㮵6 o=2ʀn?20,Cе 3cj;uqnӁx%DْV]ז2:v(Sk&l^sxeX* 膯 :=%2\eakdA0G )W \uZ=;p80>Ez'c&](QA=VG0PNjDdsxPR p,_}cAB, rQA]#V ]gN(o}_np0}tZB-kcU7Bj3M2 L^Q r5sB]o EV cFJV󃶡orI뒹n l@cz #XIœ8 L]ܧ֦@FuT4Li8̙(U.APMMkeZ.8f(zWT]E{kH;cݶa(BbҢ%#Y+Y{Aѥ;SO}'0D˕Hɺ`!K&cjwulC{ʛCu]lC۩+~>}P68kzh¾4{cuM%WorsnG"%&Q77EH\ %w$J5Y0F]2hu_gr bǡ;BZ i.nu1*I'$#J(+`Xݔtu>].wX(|P1ꅤn. uV//#u&s.C:v..u VDA]Ncs;`\pE/vwA5RcOIG5eF\>W%]0V\6=O.v[w-ƚ&S.` }uժl:ҿDGS{ڒɈ|{~>Pۦu{}Jެ{Tm}{TUU8v͈HMc6u!U?{>eo©+.M=J /왏C:IiaJD {QVU:|"YfJiv5Ezd')Q=,Z):"mȳ$h%dT*go䪹z-#~%EXxelzdG$2,UAa1Ւ̾onUWeLEf>nu5uU! @Ҫ%k-/Vr eL0mWCt% ب x4z!-֢ Mm-ZohG- (&cBI]]M!<2Kߙ_fp?d+R뾯à &Hs]6SfiQk,-H JB,7U"-[ ڞe}J+"a4 j''7my4nnb{}?3ZA';+SuVI~\~q|7?*sWbSUe)i!Ec~Ҟ/Lq#՛OXqCw8 rCSr2Um/vW5Os8嶾矢7 t+Gz' ͟(ah.$`fa4MN(i0 G`K=M'z+ V[ɐ(#M{{$"vMutL ߑBFo0e^y^#~k { \Ysl~[q"{h , x2aa *||bfAv(XYŊڃ),Q[9tV7X**~%jK)0my&]c_ml@|hіȅ:e9V[A䁳@6 ,!c3uu<ݯ`6k'K(G3$(.ǵu--H#Tq: )Nq#'J5W;>͘|ފRnSˡk/v|n}o @k"=ŶK݆^KHGu s]yB%#a>߻{mH fA@.9"=}Jܜ`2G[:jn>c. Hz nOƞoT[*z^>'"2.mF9#XmUE4)_/ JWKGoK{w0 aZpӹt$ d͒N6T|4S#PtvNtP1׎2E]2\=nȴ醢K}mZqҊV7dZtCѥK`spo_;O<"wlo7[waVgu<]y Ϟ.޼HhOGIENDB`imsprog-1.8.5/img/stop64.png000066400000000000000000000151161520775651600156500ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_FIDATx̛y]}?Uw{K/7}@H`B#23fN g2v$&`'g|Ğ}lpb02f9}i!d$u[Uǽ}O%g:{߫Wocm)%Zk{c̀r1[JвN@ǿ5 7+=@[O>?jc( Et4nzW,'p]w^bEɓ<,_K/TR(gx?s=G&aӦMuD'ZN@)}V@c\GB_wɫ1RJ*>,\q%~q%.\![l!XuVKBJ4QAC,}F>+/o=6Zkz),Y%\rMBpĉ>oȑ#\{h,$H?3;}hK222ɟxwHy޳e]5_?֬YӔ_)U'|+K~ߎ#BPV.gꪫfo@ӌ2p%ˁ;8v}tف<x?ٿg/e~"\DݻB$@k\޹cǎJM6A1333ߏӒe+9c,=Lo3j ʄgT2'ugq{w&Nvڦ\}l'dpp۶}1;Uryٲe |揉';Xz zɭ_΀A@t >WB'făLH6nֱ{Nvź|xg)%J)֮]믿ΪUǥR oJhoo9%͔]ziaKߋmULc *q`Txƨy{U+5ͅ]DXdϞ==]ץ'N`Y>\.)OMMZ73be3ܾbh[G+k#szDtƀֆLCkC78\RĮ]nR^8R~:r;gf9u4= zCwprX~VyYD|P '$ޘ1#69%+P >>ԧר:k^@Ra޽MQkkkC)zҒJ t:8u2+PwwwcӼsp'K!w]6#]/$^7wLnzLCFY>yQu\xAMO*EqV( !% bѬ+v1Y|@WlFN= @53d?ћ~hLFVOxlY ^ ͸@;H2#cdbctww#S)Ňv[5@וW!k^눏At1s~@Տ} J{D7: RTطo9-d$Zrctuuݜntm+INhmyCaLh L}>\Ia.c?gcmWRp!hgg=|?("_]p=L#VSjI`}4WjU b]K`*G3EC=Iá*!>bK\M\fdddhsPԱmqlAF͒7[-jynza#X8TJSbJh(Fx1 tJBd>^> S)5|њؔb_eh[Oזk_# ' `*Ut)ѕJ'Zpd6) LΦt7F==Sy7/h`fz{ϡ㽗cӨrc\z~DdJ)1zf=;.EńZ6" iVR }*]ǔ(Hg: 3}=}}=?rl V&֎+`%Ry//A@k)J/3/a|!Rh - 3v '1"֪A߸l%²ѧG#A!u7!T*eP; qbc0*c沾F^)vzMC gʞxs~8Rb9J}ax݅q&/ ?QL,"C ̯\@jgZaNTfg''-Fb7} +et53Σe4*ԧ?$jtita{pͯc%t*qfX8߀{C1 DΗUV,99$-t@:b5C6mhiHH:CthA+Het?1=;P*! #Z@)}lL-'}-8 tHq0^P8|}z- PB`iRTz q~_|z1X1_ _qг^}BOoh#B6 L:F'8A7t"7mF hB@"Z8͢C{^` "sJS޽33-~ 39GPj>A;o߯ޡ1#Dx Z' %F03Sˊ W_J{vr^Byyl_&mX9]L#6mAگh2sQ]-P:N(?@=Әn: !Y 0t HV "C(֭P.#Ej$2N.,9 g>mpR 4vkPanMg漆,K0]>x@- 9谦:|TՏ8'W\Yw gQ1%ScJdD=poMɬA@·` R T&9 ff&,$A.R]dTh}\g۾J5҆NaUiAxF L88AH ex, ͟1F œ @4_!e4Z!B`ˁ154K_Mh,zt'pRZh׍6h&%4y! x{1X <31Qł < *PK\cN W\B݃|+pR?02R*B:El.9u }ͅ/48!1S.7/K1ؔpPikQvA#X6tt`l Q,!xи2'KG7t7BG'FJ,al̟R'̖3AƻI~K|@McU !%Fafm3-02ʣ) r)#82 5pr85)!KM!@X Z45BU8T GId3y.V: *YHE.dl'T:%{U8#LїʂS,]uy>mz|GɪM¨R=tKI%Й뤽}ސx^R,YAݽCFsO~2M[(Ⱦ2K,Ql%#{?² 줧  tteZ94 "0gɪ*eW(6ő`wtSGO]p@v.~WTH)ɤ3,_4|wV*^C/w| M~FnԽa 袯> OPe?J TjP 5wLU˖0>ɗ< dD^`yeKtᅮcQw}}1KZb !JmOOMMuE<ϫL&êw@Ũp[$,p2>ŪޙQsSSShqS$m.{Z)dBøkf|ݹz>~'.[ؔO~ 02_B7%&`g;kYܽg 9сzǤeim8~x A1d2_\; qzԴݪF/ۦ(1\+C,ƹ}xd%K ( Hq]p!Gŏb$э d3V/_Iw{;KrzT$x9C1Llo!;X~-z믛R*4}&''ɤ,\ |$jiiIooR#G =ڽ1l6ꕫjpz+%1Hyw]XTa* 8ن],\wl$<ɽg˲ؿ?L^H tvӷ`ncڵ!n&zzz>c,zVUo߾'~_}1nFz#6kV5ޘe-8*#Tffy: r.西H3g'ömx'ؼy3W_}_-[>!DIcY]v=m۶\wu,Nh$$T*OLP ||q1i z֣2qRwf۶m_ke۶ej'ՔReYw/ѣlذ 686_;=7vN5;V8NW^ahh 6e˖YCnU9Rxt[K&app+W^;3(\Oxv 6~'+  144eY\zlذ+V뺾1MQ*ڔRF)cʶmu1y>yСz ۶rr5 1+YTgE333UJuA $FS `c8$+jz'"Dx\{,tttdm)ղ,0"`IM+{IENDB`imsprog-1.8.5/img/test64.png000066400000000000000000000156341520775651600156470ustar00rootroot00000000000000PNG  IHDR@@iq pHYs+ cHRMz%u0`:o_F"IDATxěit]Օo{O<#`Kx£)*C-B*NV*(V*ɗ":+StˡRS *!)b lc3,cIe˖d֛߻cC%zýܳ}}3($I8$IVIuRIeY.|[uB !#E>g).0800($I?kr~5Mu Ȯ6 !1߲m>!W̡(G嬪5Mrg$I$I:zMZeY,%Iz0Ncxx!̪Yz2578C.ömTUUQYY}]YoB[*ZrID"TUUQZZȲ\k?\Ų,r H$c…$IneY?}4,X`08sd(Yq]Q:::aɒ%444 E]|dw:$4mmmB!l.;UOZٔGDtٷoXx}ZK&[4 T!_l>N3U3y$9}4/^,O*dYj.[v)֮][XZ檳 d&rv׫JuKof?faHAu?uB+l~c\ʛm2$I²,$3gqGrf٦/~zLӜfs OOOCÌbaRĔ0WL-ImxbinnnjdDu ^P(eYWuvccc>ts(B8BYY)`YL.uZh BlۦGrPqqqseppPE,21~ E71<$###$Ih)52wƲ,>u(+/DPTAQ#Zs%VHTǩq+ݻvukBpD~$ n\m8z-Nt|+ %aTE\eb"5RM q˖26>[_j'< qdY%۶,R^/N#˲WVYIqI =?y;q zjnJ.D뺨aض]#(Uf'[ola,[FPvp I(Ͷm^yv؁CGg'uhɆ67)ض뺺$I>%py/sV$I_;dͪ[&c ?! ۶͞={x饗p]Wstdޡa+I$,nY/%gпZQf..]"zs+۷Ȓ5XrΤI™)p'luٻw/>,4S]ݴkbhdh)\gR^Qi3C ڵso;0]m(TYuיþ}ؾ};m)8,) silPQZZ[xG`arJ֯_?(; "ͼ?@8q[os-xu uv>tvgEӴ ?1`]=z4$E&Hm066ٳg ^{߾}l۶;v(3##dtvvPm;0yݴm>~3,^HD? x,΂yghoox<Ή'8|0x˗e҅#I9w巠%w'$z4.I$qbm;zoQ0H4-gdIEHYY4"f׮]755Q]]='QyGmJKK|Z~ .L~7N}xxX,0}XtB:;"pۆ lܸ]yhvUc&ъJ}#  _*@rؾgq"PK6B GQbz뭔x$ ^|E9eR)hjjTUݚ M3˖ԓO>§s 0+ۻw/xTٖEu}=wn MQlx yұr-!8s4# m[:z9v6NezPU^{5xR7De~?ifQڡp~$I~^'Ore&L×%~?/͛۶e%˖Ӷbd6I<6MSOS]S#5yˬ YN$'Q쳸5Z$S):Ώq+ᥫ0M:ǡ_~6*y7eܹSx2t9FI8HMU%hnn&Nsjjj5 qWfrjYF H .Kkk+rz~/c+p\ Y .!kz@ ӊXYa ×ccۿNyyy/)B4EUiU'G3 @WvzF$ BЇ/;o#KL:Moo/K`,lC$dl6CiIp8/~,{^ۃS_˱bUc۸8BȊ(~>."kʖ֮95ԩSȲLKk 7tY.s ^Љgstt-Բh<^222F"ulEAnhj$OsϡMgKCtvmj&1)D pHIQt'p5EMyc_~_8! ><<\922}IҥKQEQȟLnY#z!zjB;C(pWl]xu'?yb+w/jb9s31T݇\8i.u]dI4 EQ%>>>I> %+Ɇ Xd POeee!PZZJKK ~p8̹s +K&!LN{N*~M6Mmz^7yv^}᧔ghOٶ\ e'pm3FIQimŦ hvNt+WRZZB:@6(BEE,SQQ駟AbXQL4yٵkwqGq33@,Y7#4l;L#I*B IEM222B$A$e%EQt_|m .,}yQ]]u]Ξ=ˏ~# QXa [AL$Jq{n kkj`a(P䳼!2Wv:֮]ŋ}qpϞĈ *ޒZ_*>$IY<@`4rn >NlΝ444:477O$LE"WpB{1>3wks19QRQQ=4櫢( 9ڳ-ųM.D:FMu >w"8ylٲh4$̽bm;v&N+&-gvj7k2(BWW*WnH䕼uݐ@Bdt_ܻwo06m~gZK 3_|'ؿ?---_~?(캮\m!#P]$DÇz{{immYg7Qg}6ZksmfddznZ[[ikk۳p/+286-/0h Yxĉ?;sNDc#G5-4M twwݍ,,[?dYa|Dd2"It@B؀+E Ðx㍿ӧPp8LQQPhZ\$I.숙l?"Dħ[P4XX,8yhѢf2eYaYe-8T*%|> ̙o u,`tBp 9S<:M1fF$ TUF)++KF_DG-Z;r-YeeYt#?CtK.1::J,#LeYw9ڲeu)^-(@IN??p&ⳚN*%>p"JZ*rZUu]._D" 1Lԁ_UUD6eWΧ,abo$0MoveY˲ܙ҇iSVӲGIzW1Ȳ,t]5Mn~D"|B<2lۖ$I ʲ(BIENDB`imsprog-1.8.5/img/tocsv.png000066400000000000000000000051411520775651600156440ustar00rootroot00000000000000PNG  IHDR szz pHYs   cHRMz%u0`:o_F IDATxWk={fzvwx/`yB*BCP 4EJXDM)bQ  h  ID JD䑅]޾1.ɭ?vsO{!_x# C}0`6ѫW/yh0R4Be :zS[KS^v(amǑ$Ii@޽faY!p]555\8$I1a&#.CRU㙦aOy(2iGf,^ؔ;qd !}!eA PByBOY?6N=~:7ۿv&f xT$LE+˚ 9V\.qHYPȪ *DكԳיּ}C r-#Գȳ@HʀVf&Z鹮JipptC1[sGښ?g ɀTP GS^~끝JTc @D." }<1 *JLT$P@Wtak^|pڂ P;k,f= bh:i59Xn9Hq륳0E,W=(vhڎ[ {瞁W@ڋ4 oTaI@(=_"u (*GP3i`~G l hKC){DO18( $I0 {OFQk0nd*ڊ96t5a?|o~8)!Y'%, Œ 2"/L@T:grasĮ%k1yX㑩K`:Dt,|랞yK\ǜ>}ݾ}639x),b TPA8 aᆆN4*̟v F7N1[x*YV}=m*$b sY{w}Puln܁NM*/WdÁ/޴_57dT.+{Iu]P9>E!T@LIj盨e3ƙb^ڹD3B bCWEsEҴ0E°ز,*ʞd2% ļg:^x 0UB{G `3Ǜ7۝/^9k+xcѪ7}'|I a:[^ƈup1|*VS{X]?W.PIB03ߥ0q`p=s /`҈~C@f°{&ܲ|̻-)UQGqbm E)! d?`d"@NcE"˄15`PLW9hνX0 T.޴g>uG-}xiAHUr;-DX Ω8WL&oAǓW qPh*f_ LۇvEs[Ӑc iʏ;#fd\^؇Tx˲ ǛwLFhd?1dB@`gTXZ&MOLkɵ:Y$4+xfc UQJӱQpu$Wi3+:Xօg57h'-JHHRH)fg8*FƐ(?m~r/=fVꁡ+fX{B#]IB[MWS(gOP PZ0\X@VP4N؎(ĐT'4SJ,*K^H4&'QΞ1ብ7`$p ?403fuɾQ]7>z2qidER|@"纓{r9pC.w"N@"_;;=2L8vB7mB km7l !T"JiזPĄ"&0n#9DGˮ@Ĩ6ִfu*  Y8D)b!@XTV2dryb^Ή=͟]vpH{W3h0y IE|{ |jZ?L] *sS^L (Pw 2j{GPH.{oj߼rC _Y-v;v#x7ۏXDcKB, @"pY0=!ò,8۶ɸԙ~i'8=W*\X_.C:\ץRNTWW#4MyHӤB`hF((A6m" CaHlFGG2 "$I-̮I{{L&9G\F&A[[jjjP*e!͒ 7$G `IENDB`imsprog-1.8.5/img/undo.png000066400000000000000000000017021520775651600154520ustar00rootroot00000000000000PNG  IHDR szz pHYs  ~tIME 6*-WbKGDOIDATX[HTQ4^2InCt"5pP&O:ZVjIʒ¬({DDBHj)"Vf&""%_g63:7eֿ{FKOO P)\/zW6aPD'ڈu*=|7E8|Kj`>Qv2HTx,rBJ{X7@6  `b_.>Xs1|`c!Q:9'Wc |m]]= "YDx!iB!DLUUR)1d2y{]]]nϟϲe˨9u^<0J)s! ,Z󼻅/cl,3ge@*Cc_رCR)֯_O}}=ƘTɬŋ|`ђ<ϭm<'P`DxuV.B֬YcZ'MAH$*NL&a>uVb֭+6R/=S|oEla9q;1{l6˖-[cڵH$ry(NfY,ZkjǎD"6lPR @R iZk6oof, Ǭ KAZ5j^wwL&Y~=AT}@5KRg"m}|plvJJ;OKL"$ * `JUZJp mj9~0 [Yh4J,Z{o&u]t@JUb|~2>w|qK/E*nv<h1@)FLcnb D"VZݻIӷ ι?줹):_i}k!n:6_̍w]Acsl{ǎ $"O $#o(UT.$ CڐR-hk-A|8N/aƍAR꜅MNnw=KVbBx~~ y=%VTh0qbX ߥcKbɒ%ǵ1c̍'N R__O Z>vdVfls4+[=j}chmme׮] 755mZ\yq̙3%Ue1ЏX+|A1odb,CMm)(-QJsH!1kV-QƑR!gyd_tʹwf"r3bAMMMظ2 't:nRֆBɡ7ݷC#:.M}w{ D$'H%2W$'Ҍ}5@0:T0  VCDX_RFGGR^yZQA,SSSߟ>m,\;4͎3:a篻xфO4  zHPFDb4x$u݆_7[d:FFF^RSbh*upv#]VpA^yS"x*\JӀA &%N Rh_yD"-hN(QJ[]CQylc|`l`Ge#>Ņ+Z 3xma'V !2'pHQ!Y% f (OKIs "SқdHs~8Hy҈ů>wS27*as?'a xٳ~q9\s3~ v~X?So!r7 r(UT8 ٦@ < >N;\-A}恐Dj3ʚڙ/jklX?{_&Wlr-s*a.i&%.R:eqJ9Jܤ(J%x:p- sXT߻v{x5l\f.M;&Z)[Y!9ua%Y鸐 He h!@uansT8:HYlތlt%-n?9ô̯cYMǕB2clQlsWk-~̣!N6J&F4EG}RXYc #,飔Y:pڝU]z> TCn:>w+<ϸM\2]19&4α m.K.ƲK硵-r#48jcy?p,ȄӕSC@'bh~MïqN[.c%hje׶C j SX:F=<_3>bx8ED>@w<097-BXl~ 310 y3gZyB~擤9Ɠ"=4+G?kɆdan&CKXq()8}#5kG9؛b`<$krTA((c%β,Efeak=_Ǘ&?||Yk/;#GQp_[dBdž(cq »!ێ 8:jhQ4ZH'rKSd^33YYyZWq~.e'sfzzFc>NH|p:<+fiV{y[CB"7"sgQ<7rɏb44GvVG&2 rud*x_lM:Ʋ6AAgAdl6ZeX?XSlg+GRb|>rR r b\=OhYxN`lNx! .^u9P8PR})HiFFF,k\@L̿Dͮ~:灵TɗWS.c?]Ohxx iՒ5J n_͹sqsC}en7'?00@cc#?rTJZ fzzzK;DD=1;#oDQڪc/Ծ~.\mH@zyqȑ ] j0ZǁCCt|Fj A2CP=a022B<c޼yI)k-l5kV1weɒ%e0$d)eJwa, n$vٳv{6b>$x>u8y5%wG~Ν;fI ðκkDK@+ȧτ.;_ec-s yc?Bd[# ?Xtg_seaqK-iH$\svB݁ 7ܿ'}9+Ȧ8/CS@)Zk^~ei[ܶBzF! fKK#Vb֭.RT+a/\>Ԭf<_!,'GS4McWOai)J)z-Xn---ZObDse^^d >,}}}EwXj\ ;['!1D$anYn^e%J):;;y+Xx466TKRRŋ811§z㴵*7tɭ$(v":^ڢ@H6ĥ0i{a˖-\/s~M-{S[B(km2J-}7~}=JGG444WR_N.h䦫fu8gdV&A6H@8'''8p۷o㴷xb T0fHٌh!d2 EWWJ)֬YCGGǏ/^%uJ)SvI*38 *\&H'Oʃ?<<ծǏ"ek)R䟝1 ,'Mr)qtIFGGadd5mmm-X+]tѣL&;@V)夔BɤURJ9Boo/ 866v' 199IU+`DYӧQfҔO"։O$߮;XTJyJ)sE(SbLMNN R n zk04-aJ5 ?we9U  S=)%P1RJY iJ&RIENDB`imsprog-1.8.5/img/verify64.png000066400000000000000000000056131520775651600161700ustar00rootroot00000000000000PNG  IHDR@@PLTE𖖖߰񐐐᧧便Ι螞ߢۛ𻻻333ա۾iii٭O///FFFC***BBBL=SHE=@555K:999xKJI'''ѷKC111~ÖRF:|zLJlllggg@5)$>?><<<;ɟzzzppp;7/-~RaaaXXYW21/.- LzӦVRRQMML4 `YKv׹ߠfh_ZXG>7'#uڛيuly~khhdWQKII82 h Gq须̌oeydrxc^_^]SWJGC;;;6n1s ɹǟꋰukoa_akM@?\m=tRNS!7# Z%JC9ԾǛqj/$߾hÚ~{h^[IDATXÍXa7c:ֽ1<'S6M]MA0hTn}vlJ?a~w;h>RQbGd6Xŏ_kUH.;rEk*V-/ڿb}y#a ,0DFFR?|TFL"K}ÇX,P6bC8vKr zo$Bsm!ͫp^!YЦ'd. uዥ8 6߬;lӯZr {T,9j!׿+U,@|Hm!9|X&d:L"&yVcMZt<2D `HQӑ/r+ K*op*tB-`Y+_Y@"RUGgC(XOP0ojsf A,PKXH"MȎ_/3LH s(DbӚF$[ 7 YY^ATXM$Ɛk?:~nBVOn/h*_@:;!6+{G7h\Ah6'ϵw"'M>J+-N-xkdc;2=Xfg4:.ZS 1zcѺjجn NRbuӝqq_ 0e~v&P0nO~q7&Dl>Fg4^EA840(zz~&0nj(C?ChKI_>;0p`PЫp AH֪B@7,%(,=e;uzi >}5 ^'2O!! 7ubd@7>lvJA" ro$_=qb; roH+ Do/O B  F _IᡀkCj !rOF>1 :)D}^}wFB0jЊɶAHgxgCGr% ޵dWc' ~3p\丠R0Ŵk؍`K>SŹwgJD 8ǫ@7ȼ\mIz9> 8/z  ʅa"|fM A0thB r-X$YQ:\LU*dr!mλA`.ܲ@ \p:52cu׎Yrd ׎OD(\ߏdcGpn)zpOQ6"° c-1uA"EJY!M !$ȰoǶ! ߹) s 0\gY}1sL)//]:Kk־s/(bl )0oVT\LMq, c tttŋ={vo [q6Lhu۶m"J|rbJ)_ROUx108kG8L6ƀCfs͢3+u2D!hfӦMtR R8uoPJ=qF"˖-R>%3O8R()0O14?\OӺu\[sJ#=C̲):[xǜ9sR ?/ d2̜Cqi.<-?( s1^><hO,ڶ@9|>G(VIYm=^'=v6r% Sh ɽ(^8y+83ywڵrJf۶kl@h?04hix^1%F2t1` _<2Jkd}݇9Ě['IQ$H2bmctO% : Ce3X Z)J{(N(Oc.LK!NO+#r7Hm 8=qn75Q !i a(PCa?-hl&Cf0[%PQyJ9JsS_܏su_22gsB@ 2 ϣRb|((pw`S\,J1t\鏭CS6M{p {o%6~V  #AWH:ƲW>I&& d8vsaƨ/Z=BuIў.1~r;)_|/;vGX#AP^Z+Jp?yPc y ˡ)tQ Π_`-*~ n6#oڭD/r0 <$G)VhUDtL"`0OiνdGx??C:t0Y(pf~t{iD<+VJץTQf fL9?Ғ|c [lʕ_`fZn7ͥ?]Nx,Auu5;vɐMPlVF窿C`e;ELdFi͛eci4K.KSST&CSvc8z(DbTzoW/%Xi8Rb9²BYXB92C~ *:wykh;0o<~s'"k'B첲L&sҐ!`ҥ o>x饗#Ns1l#DT|͛7#ddd;wpIw}2>#O'xdH&|3᳟,)Jx*sUx{v]XT/u3x ^6͒xj8YmgWA+ ~z~ ln ,_x<~JPOft>,ˢ;s9y166FooPz6l"o Un/ss^H/g_<xJ0/2> D"Yx1555L c@'Þa!s9DWW<e1::JOOVo>4ZA*9%q >3olbsaiub$W^ꫯ2sLѨc8_dժU$I6o۱,h4d2ԔT޽{ٸq#@)%@?08p:P!MMMZnvIkk߰_xq0IO3t+ݝ~Ȼ#<>%#$ ꢣ˗.---h7oh~08Y0 ~j~,"gxxT*E*477CU$}[A}9NL( | ,`|ӟd۶%L꣎S@񕕕kqW`,*6L&1FMM I<'Ouu !į9Aw^̫뙖`p8yd2,;vPQQvl߾8/p]"3dD"fϞ+l2N_N6Jͳtm8(oMD"'Y@Ʋ,m&uq]_M7D<Dz,jjjDMwR:זei&khӺB1XSQQE}_(ZRVw-鴸+EUm]vŊ+mc@D*mnnA"8=SX3fiQSuB0"1۶dݺu,[s$+ 2&fKs5/RѣG˘={8<]dylܸ r?~mۖ1#R*V@)e2Hرw۶m~-ZĢEbM#N\RcǎoŢE ןvi uprmۣ-o/ Μ9s3X ,8U13E~.,bɒ%,ZWmmm7۶q** :D&a¬$ uݨRy&I2RRJYnYw$*aIENDB`imsprog-1.8.5/rpm/000077500000000000000000000000001520775651600140215ustar00rootroot00000000000000imsprog-1.8.5/rpm/imsprog.spec000066400000000000000000000306711520775651600163640ustar00rootroot00000000000000Name: imsprog Version: 1.8.4 Release: 1%dist Summary: I2C, SPI and MicroWire EEPROM/Flash chip programmer for CH341a/CH347t devices Summary(ru_RU.UTF-8): I2C, SPI and MicroWire EEPROM/Flash программатор для CH341a/CH347t устройств Summary(de_DE.UTF-8): I2C, SPI und MicroWire EEPROM/Flash Chip-Programmierer für CH341a/CH347t Geräte Summary(es_ES.UTF-8): Programador de chips EEPROM/Flash I2C, SPI y MicroWire para dispositivos CH341a/CH347t Summary(hu_HU.UTF-8): I2C, SPI és MicroWire EEPROM/Flash chipprogramozó CH341a/CH347t eszközökhöz Summary(it_IT.UTF-8): Programmatore di chip EEPROM/Flash I2C, SPI e MicroWire per dispositivi CH341a/CH347t Summary(pt_BR.UTF-8): Programador de chip EEPROM/Flash I2C, SPI e MicroWire para dispositivos CH341a/CH347t Summary(uk_UA.UTF-8): I2C, SPI і MicroWire EEPROM/програматор мікросхем для пристроїв CH341a/CH347t Summary(zh_CN.UTF-8): 用于 CH341a/CH347t 设备的 I2C、SPI 和 MicroWire EEPROM/闪存芯片编程器 SourceLicense: GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-2.1-only and BSD-1-Clause License: GPL-3.0-or-later AND LGPL-2.1-only ExcludeArch: s390x Group: Applications/Engineering Url: https://github.com/bigbigmdm/IMSProg Source: https://github.com/bigbigmdm/IMSProg/archive/refs/tags/v%{version}.tar.gz BuildRequires: gcc-c++ BuildRequires: pkgconfig(Qt6Core) BuildRequires: pkgconfig(Qt6Widgets) BuildRequires: cmake(Qt6LinguistTools) BuildRequires: pkgconfig(libusb-1.0) BuildRequires: cmake BuildRequires: desktop-file-utils BuildRequires: libappstream-glib %description IMSProg is a free software for CH341A/CH347T based chip programmers with graphical interface. With IMSProg you can read, verify, program, erase i2C, SPI, SPI NOR, MicroWire, Dataflash EEPROM chips using the CH341A/CH347T programmer device. IMSProg is a collection of tools: IMSProg - the chip programmer (it's the main part). IMSProg_editor - chip database editor. IMSProg_database_update - script to update chip database using external web-server. %description -l ru_RU.UTF-8 IMSProg - это бесплатное программное обеспечение для программаторов микросхем на базе CH341A/CH347T с графическим интерфейсом. С помощью IMSProg вы можете читать, проверять, программировать, стирать микросхемы i2C, SPI, SPI NOR, MicroWire EEPROM, DataFlash используя устройство-программатор CH341A/CH347T. IMSProg - это набор инструментов: IMSProg - программатор микросхем (это основная часть). IMSProg_editor - редактор базы данных микросхем. IMSProg_database_update - скрипт для обновления базы данных микросхем с помощью внешнего веб-сервера. %description -l de_DE.UTF-8 IMSProg ist eine kostenlose Software für CH341A/CH347T-basierte Chip-Programmiergeräte mit grafischer Oberfläche. Mit IMSProg können Sie i2C, SPI, SPI NOR, MicroWire, DataFlash EEPROM Chips mit dem CH341A/CH347T Programmiergerät lesen, verifizieren, programmieren, löschen. IMSProg ist eine Sammlung von Werkzeugen: IMSProg - der Chip-Programmierer (das ist der Hauptteil). IMSProg_editor - Chipdatenbank-Editor. IMSProg_database_update - Skript zur Aktualisierung der Chipdatenbank mit Hilfe eines externen Web-Servers. %description -l es_ES.UTF-8 IMSProg es un software gratuito para programadores de chips basados en CH341A/CH347T con interfaz gráfica. Con IMSProg puede leer, verificar, programar, borrar chips i2C, SPI, SPI NOR, MicroWire, DataFlash EEPROM utilizando el dispositivo programador CH341A/CH347T. IMSProg es una colección de herramientas: IMSProg - el programador de chips (es la parte principal). IMSProg_editor - editor de bases de datos de chips. IMSProg_database_update - script para actualizar la base de datos de chips utilizando un servidor web externo. %description -l hu_HU.UTF-8 Az IMSProg egy ingyenes szoftver CH341A/CH347T alapú chipprogramozók számára grafikus felülettel. Az IMSProg segítségével a CH341A/CH347T programozó eszközzel i2C, SPI, SPI NOR, MicroWire, DataFlash EEPROM chipeket olvashat, ellenőrizhet, programozhat, törölhet. Az IMSProg egy eszközgyűjtemény: IMSProg - a chip programozó (ez a fő rész). IMSProg_editor - chip adatbázis szerkesztő. IMSProg_database_update - szkript a chip adatbázis frissítéséhez külső webszerver használatával. %description -l it_IT.UTF-8 IMSProg è un software gratuito per programmatori di chip basati su CH341A/CH347T con interfaccia grafica. Con IMSProg è possibile leggere, verificare, programmare, cancellare chip i2C, SPI, SPI NOR, MicroWire, DataFlash EEPROM, utilizzando il programmatore CH341A/CH347T. IMSProg è una raccolta di strumenti: IMSProg - il programmatore di chip (è la parte principale). IMSProg_editor - editor del database dei chip. IMSProg_database_update - script per aggiornare il database dei chip utilizzando un server web esterno. %description -l pt_BR.UTF-8 O IMSProg é um software gratuito para programadores de chips baseados no CH341A/CH347T com interface gráfica. Com o IMSProg, você pode ler, verificar, programar e apagar chips i2C, SPI, SPI NOR e MicroWire, DataFlash EEPROM usando o dispositivo programador CH341A/CH347T. O IMSProg é uma coleção de ferramentas: IMSProg - o programador de chips (é a parte principal). IMSProg_editor - editor de banco de dados de chips. IMSProg_database_update - script para atualizar o banco de dados de chips usando um servidor da Web externo. %description -l uk_UA.UTF-8 IMSProg - вільне програмне забезпечення для програматорів мікросхем на базі CH341A/CH347T з графічним інтерфейсом. За допомогою IMSProg ви можете читати, перевіряти, програмувати, стирати мікросхеми i2C, SPI, SPI NOR, MicroWire, DataFlash EEPROM за допомогою програматора CH341A/CH347T. IMSProg - це набір інструментів: IMSProg - програматор мікросхеми (це основна частина). IMSProg_editor - редактор бази даних мікросхем. IMSProg_database_update - скрипт для оновлення бази даних чіпів за допомогою зовнішнього веб-сервера. %description -l zh_CN.UTF-8 MSProg 是一套 I2C、SPI、MicroWire EEPROM/Flash 芯片 CH341A/CH347T 编程器免费软件。 借助 IMSProg,您可以使用 CH341A/CH347T 编程器读取、编程、校验、擦除 I2C、DataFlash、 SPI、SPI NOR 和 MicroWire 芯片。 IMSProg 是一套工具集合 IMSProg - 芯片编程器(主要部分) IMSProg_editor - 芯片数据库编辑器。 IMSProg_database_update - 使用外部Web服务器更新芯片数据库的脚本。 %prep %autosetup -p1 -n IMSProg-%{version} %build # update translations lrelease-qt6 IMSProg_editor/language/*.ts lrelease-qt6 IMSProg_programmer/language/*.ts lrelease-qt6 IMSProg_database_update/language/*.ts pushd IMSProg_editor %cmake -DCMAKE_INSTALL_SYSCONFDIR=%_sysconfdir %cmake_build popd pushd IMSProg_programmer %cmake -DCMAKE_INSTALL_SYSCONFDIR=%_sysconfdir %cmake_build popd pushd IMSProg_database_update %cmake -DCMAKE_INSTALL_SYSCONFDIR=%_sysconfdir %cmake_build popd %install pushd IMSProg_editor %cmake_install popd pushd IMSProg_programmer %cmake_install popd pushd IMSProg_database_update %cmake_install popd # rename README cp IMSProg_editor/README.md IMSProg_editor.md cp IMSProg_programmer/README.md IMSProg_programmer.md %check desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/*.xml %files %doc README.md IMSProg_editor.md IMSProg_programmer.md ChangeLog %_docdir/imsprog/ %_bindir/IMSProg %_bindir/IMSProg_editor %_bindir/IMSProg_database_update %_datadir/imsprog %_datadir/applications/IMSProg.desktop %_datadir/applications/IMSProg_editor.desktop %_datadir/applications/IMSProg_database_update.desktop %_datadir/metainfo/*.xml /usr/lib/udev/rules.d/*.rules %_datadir/pixmaps/chipEdit64.png %_datadir/pixmaps/IMSProg64.png %_datadir/pixmaps/IMSProg_database_update.png %_datadir/man/man1/*.1.* %license LICENSE %changelog * Wed May 20 2026 Mikhail Medvedev 1.8.4-1 - Fixed: segmentation fault in Qt6 - Fixed: incorrect interface display on macOS - Fixed: write error to sector 0 in Windows - Fixed: incorrect saving of the database file in the chip editor - Fixed: Unable to erase the 93C66, 93C76 and 93C86 chips - Fixed: the font is too large in Qt6 - Added: migration to Qt6 - Added: specification file for Fedora - Added: universal Qt5/Qt6 CmakeLists.txt - Added: support for the spare area for NAND flash memory. * Tue Apr 21 2026 Mikhail Medvedev 1.8.3-1 - Fixed: If no chip is selected, the programmer was not detected - Fixed: MACOS library compatibility - Fixed: MACOS invalid pathes - Fixed: libusb detection - Fixed: udev rules install - Added: 2.5v VCC item - SPI NOR FLASH writing speed increased - Changed chip database update bash script to Qt app - The Zenity package is no longer used * Wed Mar 18 2026 Mikhail Medvedev 1.8.2-1 - Fix: error reading/writing data from I2C chips on the CH347T version 5.44 - Fix: bit error during NOR/NAND operations in the CH347V1.1 programmer - Added: showing the programmer revision function - Added: erase check function - Added: filling code function * Fri Mar 13 2026 Mikhail Medvedev 1.8.1-1 - Fix: increased interface speed - Fix: increased SPI NOR Flash operations speed - Fix: incorrect chip page sizes values removed - Fix: unused files removed - Added: support for the CH347T programmer * Fri Feb 06 2026 Mikhail Medvedev 1.7.3-1 - Fix: Incorrect HexEdit size when starting the program - Added: saving program settings to an ini file * Tue Nov 25 2025 Mikhail Medvedev 1.7.2-1 - Fix: NAND Flash information form freeze - Added new images for CH341A v1.7 - Added programmer type menu - Added support for the AT24CM02 chip * Thu Nov 06 2025 Mikhail Medvedev 1.7.1-1 - Fix: pressing the Stop key did not stop auto operations - Added support for SPI NAND flash - Added traditional chinese translation - New chips added to database * Thu Jul 24 2025 Fedora Release Engineering - 1.6.2-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild * Tue Jul 01 2025 Mikhail Medvedev 1.6.2-1 - Fix: program crashed if security registers was less than 256 bytes - Fix: Information in the status bar disappears when hovering over a menu - Added comparison of INTEL HEX and ASUS CAP with other files - Added close and minimise buttons for subordinate forms - New chips added to database - Chip information form code optimized * Mon May 19 2025 Mikhail Medvedev 1.6.1-1 - Add new feature: compare files - Add new feature: fill test array - Fix: when the page size is changed, the buffer is cleared - Fix: the code is executed twice and the code slows down the display of the interface * Tue Apr 29 2025 Mikhail Medvedev 1.5.3-1 - Last version of QHexEdit used - Hex-functions optimised - Added support GIANTEC, DOSILICON NOR FLASH chips - Fix: incorrect uninstall script - Fix: i2C 128K size is repeated twice - Fix: error calculating file size * Wed Mar 05 2025 Mikhail Medvedev 1.5.2-1 - Fix: Memory leaks - Fix: Gigadevice status registers write error - Added new SPI chip sizes - Added Fidelix, Zetta, MXIC OTP algorithm - Added support for new Boya, Winbond chips * Wed Feb 19 2025 Mikhail Medvedev 1.5.1-1 - Fix: Incorrect install dir for udev while cross compiling - Added form for working with security registers for SPI NOR flash memory chips * Mon Jan 20 2025 Mikhail Medvedev 1.4.5-1 - Fix: Incorrect block/page size after first read procedure - Fix: Incorrect reading/writing I2C low speed chips - Added support for MXIC MX25V8035F - Added I2C bus speed combobox to the main form * Tue Sep 24 2024 Mikhail Medvedev 1.4.4-1 - Fix: incorrect reading of the DataFlash chips status register - Fix: In the Save menu, the cancel button causes an error message - Fix: Incorrect names of DataFlash chips - Fedora repository added - MacOS build support added - Uninstall script added * Sat Sep 07 2024 Mikhail Medvedev 1.4.3-3 - added license file to the spec file * Tue Sep 03 2024 Mikhail Medvedev 1.4.3-2 - added translations to the spec file * Wed Aug 21 2024 Mikhail Medvedev 1.4.3-1 - initial release imsprog-1.8.5/uninstall.sh000077500000000000000000000037271520775651600156040ustar00rootroot00000000000000#!/usr/bin/env bash bold=$(tput bold) normal=$(tput sgr0) files=() if [[ "$OSTYPE" == "darwin"* ]]; then CMAKE_INSTALL_PREFIX='/usr/local' files+=( "/Applications/IMSProg.app" "/Applications/IMSProg Database Update.app" "/Applications/IMSProg Editor.app") else CMAKE_INSTALL_PREFIX='/usr' fi files+=( "${CMAKE_INSTALL_PREFIX}/bin/IMSProg" "${CMAKE_INSTALL_PREFIX}/share/pixmaps/chipEdit64.png" "${CMAKE_INSTALL_PREFIX}/share/pixmaps/IMSProg64.png" "${CMAKE_INSTALL_PREFIX}/share/pixmaps/IMSProg_database_update.png" "${CMAKE_INSTALL_PREFIX}/share/imsprog" "${CMAKE_INSTALL_PREFIX}/share/doc/imsprog" "${CMAKE_INSTALL_PREFIX}/bin/IMSProg_database_update" "${CMAKE_INSTALL_PREFIX}/share/applications/IMSProg_editor.desktop" "${CMAKE_INSTALL_PREFIX}/share/applications/IMSProg.desktop" "${CMAKE_INSTALL_PREFIX}/share/applications/IMSProg_database_update.desktop" "${CMAKE_INSTALL_PREFIX}/share/man/man1/IMSProg.1.gz" "${CMAKE_INSTALL_PREFIX}/share/man/man1/IMSProg_database_update.1.gz" "${CMAKE_INSTALL_PREFIX}/share/metainfo/io.github.bigbigmdm.imsprog.metainfo.xml" "${CMAKE_INSTALL_PREFIX}/share/metainfo/io.github.bigbigmdm.imsprog_database_update.metainfo.xml" "${CMAKE_INSTALL_PREFIX}/bin/IMSProg_editor" "${CMAKE_INSTALL_PREFIX}/share/man/man1/IMSProg_editor.1.gz" "${CMAKE_INSTALL_PREFIX}/share/metainfo/io.github.bigbigmdm.imsprog_editor.metainfo.xml" "${HOME}/.local/share/imsprog") echo "${bold}Warning: This script will permanently delete the following files and directories:${normal}" for file in "${files[@]}"; do echo "${bold}\"$file\"${normal}" done read -rp "Are you sure you want to proceed? (Y/n): " confirm confirm=${confirm:-y} if [[ $confirm != "y" && $confirm != "Y" ]]; then echo "Operation Canceled." exit 1 fi for file in "${files[@]}"; do if [ ! -e "$file" ]; then continue else sudo rm -rf "$file" fi done && echo Uninstall Complete imsprog-1.8.5/update.sh000066400000000000000000000002271520775651600150420ustar00rootroot00000000000000#!/bin/bash # wget https://github.com/bigbigmdm/IMSProg/archive/refs/heads/main.zip unzip main.zip rm -rf main.zip cd IMSProg-main sudo ./build_all.sh