diff --git a/.reviewboardrc b/.reviewboardrc new file mode 100644 index 000000000..867c1a7ac --- /dev/null +++ b/.reviewboardrc @@ -0,0 +1,3 @@ +REPOSITORY = "git://anongit.kde.org/gcompris" +REVIEWBOARD_URL = "https://git.reviewboard.kde.org" +TARGET_GROUPS = "kdeedu" diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f1b582c5..2cce3b880 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,242 +1,247 @@ if(SAILFISHOS) cmake_minimum_required(VERSION 2.8.11) else(SAILfISHOS) cmake_minimum_required(VERSION 2.8.12) endif() project(gcompris C CXX) # Set c++11 support include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) if(COMPILER_SUPPORTS_CXX11) set(my_cxx_flags "-std=c++11") elseif(COMPILER_SUPPORTS_CXX0X) set(my_cxx_flags "-std=c++0x") else() message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${my_cxx_flags}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${my_cxx_flags}") set(GCOMPRIS_MAJOR_VERSION 0) set(GCOMPRIS_MINOR_VERSION 40) set(GCOMPRIS_PATCH_VERSION 0) -set(GCOMPRIS_VERSION ${GCOMPRIS_MAJOR_VERSION}.${GCOMPRIS_MINOR_VERSION}) - -# An integer value that represents the version of the application -# Increase it at each release -set(GCOMPRIS_VERSION_CODE ${GCOMPRIS_MINOR_VERSION}) - # Set executable filename if(ANDROID) set(GCOMPRIS_EXECUTABLE_NAME GCompris) + if("${ANDROID_ABI}" STREQUAL "x86") + # We always want x86 to be a release above to arm one because the play + # store want x86 to be pushed after arm. + MATH(EXPR GCOMPRIS_MINOR_VERSION "${GCOMPRIS_MINOR_VERSION}+1") + endif("${ANDROID_ABI}" STREQUAL "x86") elseif(SAILFISHOS) set(GCOMPRIS_EXECUTABLE_NAME harbour-gcompris-qt) else() set(GCOMPRIS_EXECUTABLE_NAME gcompris-qt) endif() +set(GCOMPRIS_VERSION ${GCOMPRIS_MAJOR_VERSION}.${GCOMPRIS_MINOR_VERSION}) + +# An integer value that represents the version of the application +# Increase it at each release +set(GCOMPRIS_VERSION_CODE ${GCOMPRIS_MINOR_VERSION}) + # cmake modules setup find_package(ECM 1.4.0 QUIET NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_SOURCE_DIR}/cmake/) set(CMAKE_PREFIX_PATH "${Qt5_DIR}/lib/cmake/Qt5") # KDE po to qm tools if(ECM_FOUND) include(ECMPoQmTools) if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") ecm_install_po_files_as_qm(po) endif() endif(ECM_FOUND) # prevent build in source directory if("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") message(SEND_ERROR "Building in the source directory is not supported.") message(FATAL_ERROR "Please remove the created \"CMakeCache.txt\" file, the \"CMakeFiles\" directory and create a build directory and call \"${CMAKE_COMMAND} \".") endif("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") # Sailfish does not provide a recent Qt version if(SAILFISHOS) set(QT_REQUIRED_VERSION 5.2.2) else() set(QT_REQUIRED_VERSION 5.3.0) endif() find_package(Qt5 ${QT_REQUIRED_VERSION} REQUIRED Qml Quick Gui Multimedia Core Svg Xml XmlPatterns LinguistTools) find_package (KF5 QUIET COMPONENTS DocTools ) if(KF5_FOUND) include(KDEInstallDirs) endif(KF5_FOUND) #get_cmake_property(_variableNames VARIABLES) #foreach (_variableName ${_variableNames}) # message("${_variableName}=${${_variableName}}") #endforeach() option(WITH_ACTIVATION_CODE "Include the activation system" OFF) option(WITH_DEMO_ONLY "Include only demo activities" OFF) option(WITH_DOWNLOAD "Internal download" ON) if(WITH_DOWNLOAD) set(ANDROID_INTERNET_PERMISSION "") set(ANDROID_ACCESS_NETWORK_STATE_PERMISSION "") endif(WITH_DOWNLOAD) # Set output directory if(CMAKE_HOST_APPLE) set(_bundle_bin gcompris-qt.app/Contents/MacOS) set(_data_dest_dir bin/${_bundle_bin}) elseif(ANDROID) set(_data_dest_dir android/assets) else() set(_data_dest_dir share/${GCOMPRIS_EXECUTABLE_NAME}) endif() if(ANDROID) # Android .so output set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/android/libs/${ARM_TARGET}/) set(GCOMPRIS_TRANSLATIONS_DIR ${CMAKE_BINARY_DIR}/${_data_dest_dir} CACHE INTERNAL "" FORCE) set(GCOMPRIS_RCC_DIR ${CMAKE_BINARY_DIR}/${_data_dest_dir} CACHE INTERNAL "" FORCE) if(WITH_ACTIVATION_CODE) set(ANDROID_BILLING_PERMISSION "") set(ANDROID_PACKAGE "net.gcompris") else(WITH_ACTIVATION_CODE) set(ANDROID_PACKAGE "net.gcompris.full") endif() add_subdirectory(android) else(ANDROID) # Desktop build set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(GCOMPRIS_TRANSLATIONS_DIR ${CMAKE_BINARY_DIR}/${_data_dest_dir}/translations CACHE INTERNAL "" FORCE) set(GCOMPRIS_RCC_DIR ${CMAKE_BINARY_DIR}/${_data_dest_dir}/rcc CACHE INTERNAL "" FORCE) endif(ANDROID) # Always create these folders add_custom_command( OUTPUT shareFolders COMMAND cmake -E make_directory ${GCOMPRIS_TRANSLATIONS_DIR} COMMAND cmake -E make_directory ${GCOMPRIS_RCC_DIR} ) add_custom_target( createShareFolders ALL DEPENDS shareFolders ) include(cmake/rcc.cmake) # Translations handling # Simple command calling the python script add_custom_command( OUTPUT retrievePoFilesFromSvn COMMAND python2 tools/l10n-fetch-po-files.py WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) # Install translations add_custom_target(getSvnTranslations DEPENDS retrievePoFilesFromSvn COMMENT "Re-run cmake after this to be able to run BuildTranslations with the latest files" ) # Get all po files in po/. You can get them doing : python2 tools/l10n-fetch-po-files.py file(GLOB TRANSLATIONS_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "po/*.po") # Set the output dir for the translation files to /bin foreach(PoSource ${TRANSLATIONS_FILES}) # Changes the .po extension to .ts string(REPLACE ".po" ".ts" TsSource ${PoSource}) # Removes the po/ folder string(REPLACE "po/" "" TsSource ${TsSource}) # qm filename string(REPLACE ".ts" ".qm" QmOutput ${TsSource}) set(OutTsFile ${CMAKE_BINARY_DIR}/tmp/${TsSource}) add_custom_command( OUTPUT ${QmOutput} COMMAND cmake -E make_directory ${GCOMPRIS_TRANSLATIONS_DIR} COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/tmp # Remove the obsolete translations and set po in the ts output file COMMAND msgattrib --no-obsolete ${CMAKE_CURRENT_SOURCE_DIR}/${PoSource} -o ${OutTsFile} # Convert the po into ts - COMMAND lconvert -if po -of ts -i ${OutTsFile} -o ${OutTsFile} + COMMAND ${Qt5_DIR}/../../../bin/lconvert -if po -of ts -i ${OutTsFile} -o ${OutTsFile} # Convert the ts in qm removing non finished translations - COMMAND lrelease -compress -nounfinished ${OutTsFile} -qm ${GCOMPRIS_TRANSLATIONS_DIR}/${QmOutput} + COMMAND ${Qt5_DIR}/../../../bin/lrelease -compress -nounfinished ${OutTsFile} -qm ${GCOMPRIS_TRANSLATIONS_DIR}/${QmOutput} ) list(APPEND QM_FILES ${QmOutput}) endforeach() # Install translations add_custom_target(BuildTranslations DEPENDS ${QM_FILES} COMMENT "If you don't have the .po, you need to run make getSvnTranslations first then re-run cmake" ) if(CMAKE_HOST_APPLE) install(DIRECTORY ${GCOMPRIS_TRANSLATIONS_DIR} DESTINATION ${_bundle_bin}) else() install(DIRECTORY ${GCOMPRIS_TRANSLATIONS_DIR} DESTINATION ${_data_dest_dir}) endif() # Build standalone package option -> if ON, we will copy the required Qt files in the build package. # If OFF, "make install" will not copy Qt files so only GCompris files will be packaged. # By default, it is true on Windows (as we deliver NSIS package), macOS (bundled), android (apk) and false on linux (to do make install) # If you want to create a STGZ package for linux (auto-extractible), override this variable by typing : cmake -DBUILD_STANDALONE=ON if(UNIX AND NOT ANDROID AND NOT APPLE) option(BUILD_STANDALONE "Build a standalone package when typing 'make package'" OFF) else() option(BUILD_STANDALONE "Build a standalone package when typing 'make package'" ON) endif() option(WITH_KIOSK_MODE "Set the kiosk mode by default" OFF) if(WIN32) set(COMPRESSED_AUDIO "ac3" CACHE STRING "Compressed Audio format [ogg|aac|ac3]") elseif(APPLE) set(COMPRESSED_AUDIO "aac" CACHE STRING "Compressed Audio format [ogg|aac|ac3]") else() set(COMPRESSED_AUDIO "ogg" CACHE STRING "Compressed Audio format [ogg|aac|ac3]") endif() file(GLOB_RECURSE OGG_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/ "*.ogg") foreach(OGG_FILE ${OGG_FILES}) # This should only replace the extension string(REGEX REPLACE "ogg$" "aac" AAC_FILE ${OGG_FILE}) add_custom_command( OUTPUT ${AAC_FILE} # Put the good line depending on your installation COMMAND avconv -v warning -i ${OGG_FILE} -acodec libvo_aacenc ${AAC_FILE} #COMMAND ffmpeg -v warning -i ${OGG_FILE} -acodec aac -strict -2 ${AAC_FILE} ) list(APPEND AAC_FILES ${AAC_FILE}) endforeach() add_custom_target( createAacFromOgg DEPENDS ${AAC_FILES} ) set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${GCOMPRIS_VERSION}) add_custom_target(dist COMMAND git archive --prefix=${ARCHIVE_NAME}/ HEAD | bzip2 > ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.bz2 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) add_subdirectory(src) if(KF5_FOUND) add_subdirectory(docs/docbook) endif(KF5_FOUND) if(SAILFISHOS) # Need to be done at the end, after src add_subdirectory(platforms/sailfishOS) endif() diff --git a/README.rst b/README.rst index 8b3f9ce00..bbb812be5 100644 --- a/README.rst +++ b/README.rst @@ -1,54 +1,62 @@ ********************************* `GCompris `_ ********************************* .. image:: src/core/resource/gcompris.png Presentation ============ `GCompris `_ is a high quality educational software suite comprising of numerous activities for children aged 2 to 10. Some of the activities are game orientated, but nonetheless still educational. Currently GCompris offers in excess of 100 activities and more are being developed. GCompris is free software, that means that you can use it as you wish, adapt it to your own needs, improve it, and, most importantly, share it with everyone. This version is a full rewrite of GCompris using the QtQuick technology. It is developed within the `KDE community `_ and is part of the `GNU Project `_. Goal ==== There are many simple activities dedicated to children on any platforms, desktops, web and tablets. When they exist, they are hard to find and request the teacher or parent to manage a lot of independant small tools. -GCompris is an educational suite of activities all accessible from a single -user interface. It provides a unique user interface for all its activities. +GCompris is an educational suite of activities all accessible from a +single unified user interface. How === GCompris is designed in a way that it is easy to add new activities to it. The activity is free to implement the game scheme it wants. The status bar is a common facility provided to the activities. GCompris provides some tools to let teacher/educator to easily add activities to GCompris. About You ========= - + You can help by: -* Creating new activities. +* `Creating new activities _`. * Providing fancy graphics to incorporate as icons or backgrounds. -* Translating GCompris. -* Just giving your ideas. +* `Translating GCompris + `_. +* `Recording voices `_. +* `Just giving your ideas + `_. Get more information on our `developer's wiki `_. +Licence +======= + +GCompris is free software released under the `GPL V3+ +`_. diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt index e840b87b5..370e201a8 100644 --- a/android/CMakeLists.txt +++ b/android/CMakeLists.txt @@ -1,113 +1,131 @@ #android build # copied/inspired from stellarium project (http://www.stellarium.org/wiki/index.php/Building_for_Android) LIST(APPEND JAVA_SRCS "src/com/android/vending/billing/IInAppBillingService.aidl" "src/net/gcompris/GComprisActivity.java") FOREACH(JavaSource ${JAVA_SRCS}) ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${JavaSource} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${JavaSource} ${CMAKE_CURRENT_BINARY_DIR}/${JavaSource} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${JavaSource} ) LIST(APPEND TARGET_JAVA_FILES ${CMAKE_CURRENT_BINARY_DIR}/${JavaSource}) ENDFOREACH() ADD_CUSTOM_TARGET (java_src DEPENDS ${TARGET_JAVA_FILES}) find_program(ANDROID_DEPLOY_QT NAMES androiddeployqt PATHS ${_qt5Core_install_prefix}/bin/ ) # Look for androiddeployqt program if (NOT ANDROID_DEPLOY_QT) message(FATAL_ERROR "Could not find androiddeployqt. Make sure you set all the Qt5_* paths to the Qt for android compiled version.") endif(NOT ANDROID_DEPLOY_QT) # Set version set(ANDROID_VERSION_NAME ${GCOMPRIS_VERSION}) +# Set a name representing the build type +set(APK_SUFFIX "-") +if(WITH_ACTIVATION_CODE) + set(APK_SUFFIX "-inapp${APK_SUFFIX}") +endif(WITH_ACTIVATION_CODE) + +if(WITH_DEMO_ONLY) + set(APK_SUFFIX "-demo${APK_SUFFIX}") +endif(WITH_DEMO_ONLY) + +if(WITH_DOWNLOAD) + set(APK_SUFFIX "-dl${APK_SUFFIX}") +endif(WITH_DOWNLOAD) + +if(WITH_KIOSK_MODE) + set(APK_SUFFIX "-kiosk${APK_SUFFIX}") +endif(WITH_KIOSK_MODE) + # set android package source for androiddeployqt json file set(PACKAGE_SOURCE_ANDROID ${CMAKE_BINARY_DIR}/tmpAndroid) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.cmake ${PACKAGE_SOURCE_ANDROID}/AndroidManifest.xml @ONLY) # create json file parsed by the androiddeployqt set(ANDROID_SDK $ENV{ANDROID_SDK}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configAndroid.json.cmake ${PACKAGE_SOURCE_ANDROID}/configAndroid.json @ONLY) # Get all po files in po/ to create the values-{locale} in order to have the locales available in android file(GLOB TRANSLATIONS_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../po/*.po") foreach(PoSource ${TRANSLATIONS_FILES}) # Remove suffix ".po" string(REPLACE ".po" "" PoSource ${PoSource}) # Remove prefix "../po/gcompris_" string(REPLACE "../po/gcompris_" "" locale ${PoSource}) # replace _ par -r for locales with country string(REPLACE "_" "-r" locale ${locale}) - + add_custom_command( OUTPUT ${locale} COMMAND cmake -E make_directory ${GCOMPRIS_TRANSLATIONS_DIR} COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/android/res/values-${locale} COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/android/strings.xml ${CMAKE_BINARY_DIR}/android/res/values-${locale}/strings.xml ) list(APPEND ALL_LOCALES ${locale}) endforeach() add_custom_command ( OUTPUT createApkFromAndroidDeployQtDebug DEPENDS ${PACKAGE_SOURCE_ANDROID}/AndroidManifest.xml COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${PACKAGE_SOURCE_ANDROID} COMMAND ${ANDROID_DEPLOY_QT} --output ${CMAKE_CURRENT_BINARY_DIR}/ --input ${PACKAGE_SOURCE_ANDROID}/configAndroid.json --debug - COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/bin/QtApp-debug.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-debug-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk + COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/bin/QtApp-debug.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-debug-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk ) add_custom_command ( OUTPUT createApkFromAndroidDeployQtRelease DEPENDS ${PACKAGE_SOURCE_ANDROID}/AndroidManifest.xml COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${PACKAGE_SOURCE_ANDROID} COMMAND ${ANDROID_DEPLOY_QT} --output ${CMAKE_CURRENT_BINARY_DIR}/ --input ${PACKAGE_SOURCE_ANDROID}/configAndroid.json --release - COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/bin/QtApp-release-unsigned.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk + COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/bin/QtApp-release-unsigned.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk ) add_custom_command ( OUTPUT createApkSignedFromAndroidDeployQtRelease - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk - COMMAND jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore $ENV{ANDROID_KEYSTORE} -storepass $ENV{ANDROID_KEYSTORE_PASSWD} ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk gcompris + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk + COMMAND jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore $ENV{ANDROID_KEYSTORE} -storepass $ENV{ANDROID_KEYSTORE_PASSWD} ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk gcompris ) add_custom_command ( OUTPUT createApkSignedAlignedFromAndroidDeployQtRelease - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk - COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk - COMMAND ${ANDROID_SDK}/build-tools/20.0.0/zipalign -v 4 ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk + COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk + COMMAND ${ANDROID_SDK}/build-tools/22.0.1/zipalign -v 4 ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk ) add_custom_command ( OUTPUT apkInstall - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk - COMMAND ${ANDROID_SDK}/platform-tools/adb install -r ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}-${GCOMPRIS_VERSION}.apk + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk + COMMAND ${ANDROID_SDK}/platform-tools/adb install -r ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk ) # Command to create apk from Makefile add_custom_target (apk_debug DEPENDS ${ALL_LOCALES} createApkFromAndroidDeployQtDebug java_src ) # Command to create apk from Makefile add_custom_target (apk_release DEPENDS ${ALL_LOCALES} createApkFromAndroidDeployQtRelease java_src ) # Command to create signed apk from Makefile add_custom_target (apk_signed DEPENDS ${ALL_LOCALES} createApkSignedFromAndroidDeployQtRelease java_src ) # Command to create signed aligned apk from Makefile add_custom_target (apk_signed_aligned DEPENDS ${ALL_LOCALES} createApkSignedAlignedFromAndroidDeployQtRelease java_src ) # Command to install the signed aligned apk through adb from Makefile add_custom_target (apk_install DEPENDS apkInstall ) diff --git a/cmake/rcc.cmake b/cmake/rcc.cmake index aa64f1c1d..7df90511d 100644 --- a/cmake/rcc.cmake +++ b/cmake/rcc.cmake @@ -1,51 +1,63 @@ # # GCOMPRIS_ADD_RCC(resource_path ) # function(GCOMPRIS_ADD_RCC resource_path) set(options) set(oneValueArgs) set(multiValueArgs) cmake_parse_arguments(_RCC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) set(rcc_files ${_RCC_UNPARSED_ARGUMENTS}) get_filename_component(activity "${resource_path}" NAME) - # Create this QRC file - # (cannot create it in the build dir because rcc expect local files) - set(CREATED_QRC "${CMAKE_CURRENT_SOURCE_DIR}/${activity}.qrc") + if(Qt5Widgets_VERSION_STRING VERSION_LESS 5.4.2 OR WIN32) + # (cannot create it in the build dir because rcc expect local files) + # Create this QRC file + set(CREATED_QRC "${CMAKE_CURRENT_SOURCE_DIR}/${activity}.qrc") + else() + set(CREATED_QRC "${CMAKE_CURRENT_BINARY_DIR}/${activity}.qrc") + endif() set(ACTIVITY_PATH "/gcompris/src/${resource_path}") file(GLOB QRC_CONTENTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${rcc_files}) file(GLOB QRC_CONTENTS_ABS ${CMAKE_CURRENT_SOURCE_DIR} ${rcc_files}) file(WRITE ${CREATED_QRC} "\n\t") foreach(FILE ${QRC_CONTENTS}) file(APPEND ${CREATED_QRC} "\n\t\t${FILE}") endforeach() file(APPEND ${CREATED_QRC} "\n\t\n\n") list(APPEND QRC_FILES ${CREATED_QRC}) set(CREATED_RCC ${GCOMPRIS_RCC_DIR}/${activity}.rcc) + if(Qt5Widgets_VERSION_STRING VERSION_LESS 5.4.2 OR WIN32) + set(_RCC_COMMAND ${Qt5Core_RCC_EXECUTABLE} "-binary" -o ${CREATED_RCC} ${CREATED_QRC}) + else() + set(_RCC_COMMAND ${Qt5Core_RCC_EXECUTABLE} "-binary" -o ${CREATED_RCC} - < ${CREATED_QRC}) + endif() + add_custom_command(OUTPUT ${CREATED_RCC} - COMMAND ${Qt5Core_RCC_EXECUTABLE} "-binary" -o ${CREATED_RCC} ${CREATED_QRC} - DEPENDS ${QRC_CONTENTS} "${out_depends}" VERBATIM) + COMMAND ${_RCC_COMMAND} + DEPENDS ${QRC_CONTENTS} "${out_depends}" VERBATIM + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + if(CMAKE_HOST_APPLE) install(FILES ${CREATED_RCC} DESTINATION gcompris-qt.app/Contents/MacOS/rcc) elseif(SAILFISHOS) install(FILES ${CREATED_RCC} DESTINATION share/harbour-gcompris-qt/rcc) else() install(FILES ${CREATED_RCC} DESTINATION share/gcompris-qt/rcc) endif() add_custom_target( rcc_${activity} ALL DEPENDS createShareFolders ${CREATED_RCC} ${CREATED_QRC} COMMENT "Generate ${activity} RCC" SOURCES ${QRC_CONTENTS} VERBATIM ) endfunction() diff --git a/gcompris.appdata.xml b/gcompris.appdata.xml index 9a3da22b1..ab608ac68 100644 --- a/gcompris.appdata.xml +++ b/gcompris.appdata.xml @@ -1,671 +1,682 @@ gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop gcompris.desktop xxgcompris.desktopxx gcompris.desktop gcompris.desktop CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 xxCC0-1.0xx CC0-1.0 CC0-1.0 GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ xxGPL-3.0+xx GPL-3.0+ GPL-3.0+ GCompris Educational Game Joc educatiu GCompris GCompris-Lernspiel GCompris Educational Game Juego educativo GCompris GCompris, opettavainen peli Jeu éducatif GCompris Xogo educativo GCompris Gioco didattico GCompris GCompris 교육용 게임 Educatief spel GCompris GCompris leik-og-lær-spel Gra edukacyjna GCompris Jogo Educativo GCompris Jogo educacional GCompris Výuková hra GCompris Izobraževalna igra GCompris GCompris pedagogiskt spel Освітня гра GCompris xxGCompris Educational Gamexx GCompris 教育游戏 GCompris 教育遊戲 Multi-Activity Educational game for children 2 to 10 Joc educatiu amb múltiples activitats per a nens dels 2 a 10 anys Lernspiel mit vielen Aktivitäten für Kinder von 2 bis 10 Jahren Multi-Activity Educational game for children 2 to 10 Juego educativo multiactividad para niños de 2 a 10 años Useampitoimintoinen opettavainen peli 2–10-vuotiaille lapsille Jeu éducatif multi-activités pour les enfants de 2 à 10 ans Xogo educativo con varias actividades para nenos de entre 2 e 10 anos. Gioco didattico multi-attività per bambini da 2 a 10 anni 2-10세 어린이를 위한 다양한 활동이 있는 교육용 게임 Educatief spel met meerdere activiteiten voor kinderen van 2 tot 10 Leik-og-lærspel med mange aktivitetar – for barn frå 2 til 10 år Gra edukacyjna z wieloma aktywnościami dla dzieci w wieku od 2 do 10 lat Jogo Educativo Multi-Actividades para crianças dos 2 aos 10 anos Jogo educacional com várias atividades para crianças de 2 a 10 anos Viac-aktivitová výuková hra pre deti od 2 do 10 rokov Izobraževalna igra z več dejavnostmi za otroke med drugim in desetim letom starosti Pedagogiskt multiaktivitetsspel för barn från 2 till 10 år Набір освітніх ігор для дітей від 2 до 10 років xxMulti-Activity Educational game for children 2 to 10xx 为 2 到 10 岁儿童准备的多功能教育游戏 為 2-10 歲孩子設計的教育遊戲

GCompris is an educational software suite comprising of numerous activities for children aged 2 to 10.

El GCompris és una suite de programari educatiu que consisteix de nombroses activitats per a nens i nenes entre els 2 i els 10 anys.

GCompris ist eine Lernsoftware, die verschiedene Aktivitäten für Kinder im Alter von 2 bis 10 Jahren anbietet.

GCompris is an educational software suite comprising of numerous activities for children aged 2 to 10.

GCompris es una suite de software educativo que consta de numerosas actividades para niños de 2 a 10 años.

GCompris on useista toiminnoista koostuva opetusohjelmisto 2–10-vuotiaille lapsille.

GCompris est une suite éducative comprenant de nombreuses activités pour les enfants de 2 à 10 ans.

GCompris é unha colección de programas educativos composta por numerosas actividades para nenos de entre 2 e 10 anos.

GCompris è una raccolta di programmi didattici che comprende numerose attività per bambini da 2 a 10 anni.

GCompris는 2-10세 어린이를 위한 활동을 모아 놓은 교육용 소프트웨어 모음입니다.

GCompris is suite met educatieve software die bestaat uit vele activiteiten voor kinderen vanaf twee tot tien jaar.

GCompris er eit leik-og-lær spel med mange ulike aktivitetar, laga for ungar frå 2 til 10 år.

GCompris to pakiet oprogramowania edukacyjnego z licznymi aktywnościami dla dzieci w wieku od 2 do 10 lat.

O GCompris é um pacote de aplicações educativas que é composto por diversas actividades para as crianças dos 2 aos 10 anos de idade.

GCompris é uma suíte de software educacional que apresenta uma série de atividades para crianças com idade entre 2 e 10 anos.

+

GCompris je balík výukového softvéru zložený z rôznych aktivít pre deti od 2 do 10 rokov.

Program GCompris je visokokakovostna zbirka izobraževalnih dejavnosti, namenjenih otrokom med drugim in desetim letom starosti.

GCompris är en pedagogisk programsvit som består av en mängd olika aktiviteter för barn från 2 till 10 år gamla.

GCompris — комплекс навчального програмного забезпечення, що складається з багатьох вправ для дітей від 2 до 10 років.

xxGCompris is an educational software suite comprising of numerous activities for children aged 2 to 10.xx

GCompris 是一款教育套件,由针对 2 到 10 岁孩子的许多活动组成。

GCompris 是一套教育軟體的集合,它提供適合兩歲到十歲兒童各種不同的活動。

Some of the activities are game orientated, but nonetheless still educational.

Algunes de les activitats estan orientades a joc, però sempre són educatives.

Některé aktivity jsou v podobě her, ale přesto jsou poučné.

Einige Aktivitäten sind eher spielerisch, aber immer lehrreich.

Some of the activities are game orientated, but nonetheless still educational.

Algunas de las actividades son juegos, aunque siguen siendo educativas.

Jotkin tehtävistä ovat pelimäisiä mutta silti opettavaisia.

Certaines activités sont ludiques mais ont toujours un intérêt pédagogique.

Algunhas das actividades están orientadas ao xogo, pero son aínda así educativas.

Alcune delle attività sono orientate al gioco, ma comunque didattiche.

일부 활동은 기능성 게임을 지향합니다.

Sommige activiteiten zijn spelletjes, maar toch leerzaam.

Nokre av aktivitetane er mest som spel, men er likevel lærerike.

Niektóre z aktywności są bardziej grą, lecz nadal bardzo pouczającą.

Algumas das actividades são apresentadas como jogos, mas são educativas à mesma.

Algumas das atividades são de orientação lúdica, mas mesmo assim ainda educacional.

+

Niektoré z aktivít sú herne orientované, ale stále výukové.

Nekatere dejavnosti so bolj podobne igram, vendar še vedno poučne.

Vissa av aktiviteterna är spelorienterade, men trots det ändå pedagogiska.

Деякі із вправ є суто ігровими, але містять і елементи навчання.

xxSome of the activities are game orientated, but nonetheless still educational.xx

一些活动是游戏导向的,不过尽管如此仍是教育性的。

有些活動是遊戲性質,但還是有很棒的教育意義。

Below you can find a list of categories with some of the activities available in that category.

A continuació trobareu una llista de les categories amb algunes de les activitats disponibles en cadascuna.

Sie können Aktivitäten aus folgenden Bereichen in GCompris finden:

Below you can find a list of categories with some of the activities available in that category.

A continuación puede encontrar una lista de categorías con algunas de las actividades disponibles en cada una de ellas.

Alta löydät luettelot luokista sekä maininnan joistakin kuhunkin luokkaan kuuluvista toiminnoista.

Vous pouvez trouver ci-dessous une liste des catégories avec certaines de leurs activités.

A continuación atopará unha lista de categorías e mailas actividades dispoñíbeis en cada unha desas categorías.

Di seguito puoi trovare un elenco di categorie con alcune delle attività disponibili per categoria.

아래에서 분류 목록과 해당 분류의 활동을 찾을 수 있습니다.

Hieronder vindt u een lijst met categorieën met enige van de activiteiten beschikbaar in die categorie.

Nedanfor finn du ei oversikt over kategoriar, saman med nokre av aktivitetane i kvar kategori.

Poniżej znajdziesz wykaz kategorii z niektórymi aktywnościami dostępnymi w tej kategorii.

Em baixo, poderá encontrar uma lista de categorias, com algumas das actividades disponíveis para essa categoria.

Abaixo está relacionada uma lista de categorias com algumas das atividades disponíveis em cada uma delas.

+

Tu môžete nájsť zoznam kategórií s niektorými aktivitami dostupnými v kategórii.

Spodaj lahko najdete seznam kategorij in nekaj dejavnosti, ki so na voljo v tisti kategoriji.

Nedan finns en lista över kategorier med några av aktiviteterna tillgängliga i varje kategori.

Нижче наведено список категорій із деякими вправами у цих категоріях.

xxBelow you can find a list of categories with some of the activities available in that category.xx

下方您可以看到該類別的活動清單。

  • computer discovery: keyboard, mouse, different mouse gestures, ...
  • descobrir l'ordinador: teclat, ratolí, diferents gestos del ratolí...
  • Entdeckung des Computers: Tastatur, Maus, verschiedene Mausgesten ...
  • computer discovery: keyboard, mouse, different mouse gestures, ...
  • descubrimiento del ordenador: teclado, ratón, distintos gestos con el ratón...
  • tietokoneen oppiminen: näppäimistö, hiiri, eri hiirieleet…
  • découverte de l'ordinateur : clavier, souris, mouvements de la souris…
  • Descubrimento do computador: teclado, rato, xestos do rato, etc.
  • scoperta del computer: tastiera, mouse, vari gesti con il mouse, ...
  • 컴퓨터와 친해지기: 키보드, 마우스, 마우스 제스처, ...
  • ontdekken van de computer: toetsenbord, muis, verschillende muisbewegingen, ...
  • datamaskin: tastatur, mus, ulike muserørsler, …
  • odkrywanie komputera: klawiatura, mysz, różne ruchy myszą, ...
  • descoberta do computador: teclado, rato, os diferentes gestos com o rato, ...
  • conhecendo o computador: teclado, mouse, diferentes movimentações com o mouse, ...
  • +
  • objavovanie počítača: klávesnica, myš, rôzne gestá myši...
  • delo z računalnikom: tipkovnica, miška, kretnje miške, ...
  • upptäcka datorn: tangentbord, mus, olika musgester, ...
  • Знайомство з комп’ютером: клавіатура, миша, керування мишею…
  • xxcomputer discovery: keyboard, mouse, different mouse gestures, ...xx
  • 電腦探索:鍵盤、滑鼠、不同的滑鼠手勢等
  • arithmetic: table memory, enumeration, mirror image, balance the scale, change giving, ...
  • aritmètica: memoritzar la taula, enumeració, imatge al mirall, equilibrar la balança, donar el canvi...
  • Arithmetik: Kombitabellen, Aufzählungen, Bilder spiegeln, Gewichte ausgleichen, Wechselgeld geben...
  • arithmetic: table memory, enumeration, mirror image, balance the scale, change giving, ...
  • aritmética: memorización de tablas, enumeración, imagen especular, equilibrar la balanza, devolver cambios...
  • +
  • aritmetiikka: kertotaulujen opettelu, laskutehtävät, peilikuvan piirtäminen, vaa’an tasapainottaminen, vaihtorahan antaminen, …
  • arithmétique : apprentissage des tables d'opérations mathématiques, l'énumération, de symétrie d'image, équilibrage de la balance, rendre la monnaie…
  • Aritmética: táboas de memoria, enumeración, imaxes espello, equilibrio de balanzas, cálculo do cambio, etc.
  • aritmetica: tabelline, enumerazione, immagine speculare, allineare la bilancia, dare il resto, ...
  • 산술 연산: 표 기억하기, 배열하기, 그림 뒤집기, 저울 맞추기, 거스름돈 계산하기, ...
  • rekenen: tafels oefenen, reeksen, afbeelding spiegelen, de schaal in evenwicht brengen, wijziging gegeven, ...
  • rekning: gongetabellen¸teljing, spegelbilete, måling av vekt, vekslepengar, …
  • arytmetyka: tablice pamięciowe, wyliczanie, obraz lustrzany, wyrównoważanie wagi, wydawanie reszty, ...
  • aritmética: memória da tabuada, enumeração, imagem-espelho, equilíbrio de balanças, trocos, ...
  • matemática: memória matemática, enumeração, imagens espelhadas, balanceamento de escalas, moedas e troco, ...
  • +
  • aritmetické: tabuľková pamäť, výpočet, zrkalový obrázok, vyváženie mierky, zmena dávky...
  • računstvo: spomin z računi, štetje, uravnoteži tehtnico, vračanje drobiža, ...
  • aritmetik: tabellminne, uppräkning, spegelbild, balansera vågen, ge växel, ...
  • Арифметика: запам’ятовування таблиць, нумерація, віддзеркалення, балансування масштабу, обчислення решти…
  • xxarithmetic: table memory, enumeration, mirror image, balance the scale, change giving, ...xx
  • 數學運算:表格記憶、列舉、影像映射、平衡、找零計算等
  • science: the canal lock, color mixing, gravity concept, ...
  • ciència: blocar el canal, barreja de colors, el concepte de la gravetat...
  • Wissenschaft: Kanalschleuse, Farbmischung, Gravitation,...
  • science: the canal lock, colour mixing, gravity concept, ...
  • ciencia: la esclusa de un canal, mezcla de colores, concepto de gravedad...
  • tiede: kanavasulku, värien sekoitus, painovoiman käsite…
  • science : fonctionnement d'une écluse, mélange des couleurs, concept de la gravité…
  • Ciencia: o bloqueo da canle, mestura de cores, o concepto de gravidade, etc.
  • scienza: la chiusa del canale, miscelazione dei colori, il concetto di gravità, ...
  • 과학: 운하 갑문, 색 섞기, 중력, ...
  • natuurkunde: de sluis, mengen van kleuren, concept van zwaartekracht, ...
  • vitskap: kanalsluse, blanding av fargar, tyngdekraft, …
  • nauka: śluza na kanale, mieszanie barw, poczucie grawitacji, ...
  • ciência: bloqueio de canais, misturas de cores, conceito de gravidade, ...
  • ciência: comporta de canal, mistura de cores, conceito de gravidade, ...
  • +
  • veda: zamknutý kanál, miešanie farieb, koncept grvitácie...
  • znanost: zapornica kanala, mešanje barv, koncept težnosti ...
  • vetenskap: kanalslussen, färgblandning, gravitationskonceptet, ...
  • Наука: шлюзування, змішування кольорів, поняття тяжіння…
  • xxscience: the canal lock, color mixing, gravity concept, ...xx
  • 科學:顏色混合、重力觀念、運河鎖等等
  • games: memory, connect 4, tic tac toe, sudoku, hanoi tower, ...
  • jocs: memòria, connectar 4, tres en ratlla, sudoku, torre de Hanoi...
  • Spiele: Memory, Vier gewinnt, Tic-Tac-Toe, Sudoku, Türme von Hanoi,...
  • games: memory, connect 4, tic tac toe, sudoku, hanoi tower, ...
  • juegos: memoria, conectar 4, tres en raya, sudoku, torres de hanoi...
  • pelit: muisti, neljän suora, ristinolla, sudoku, Hanoin tornit…
  • jeux: trouve les paires, puissance 4, morpion, sudoku, la tour d'hanoï…
  • Xogos: memoria, conectar 4, pai nai fillo, sudoku, torre de Hanoi, etc.
  • giochi: memory, forza 4, filetto, sudoku, torre di hanoi, ...
  • 게임: 메모리 게임, 4개 연결하기, 삼목, 수도쿠, 하노이 탑, ...
  • spellen: geheugenspel, vier verbinden, tic-tac-toe, sudoku, torens van hanoi, ...
  • spel: hugsespel, fire på rad, bondesjakk, sudoku, tårnet i Hanoi, …
  • gry: na pamięć, łączenie czwórek, tic tac toe, sudoku, wieża hanoi, ...
  • jogos: memória, 4 em linha, jogo do galo, sudoku, torres de Hanói, ...
  • jogos: memória, ligue 4, jogo da velha, sudoku, torre de Hanoi, ...
  • +
  • hry: pamäť, spojenie 4, tic tac toe, sudoku, hanojská veža...
  • igre: spomin, štiri v vrsto, križci in krožci, sudoku, Hanojski stolpi, ...
  • spel: memory, koppla 4, tre-i-rad, sudoku, tornen i Hanoi, ...
  • Ігри: запам’ятовування, чотири-у-рядок, хрестики-нулики, судоку, ханойські вежі…
  • xxgames: memory, connect 4, tic tac toe, sudoku, hanoi tower, ...xx
  • 遊戲:記憶遊戲、四子棋、井字遊戲、數獨、河內塔等等
  • reading: reading practice, ...
  • lectura: practicar la lectura...
  • Lesen: Leseübungen ...
  • reading: reading practice, ...
  • lectura: prácticas de lectura...
  • lukeminen: lukemisen harjoittelu…
  • lecture : entraînement à la lecture…
  • Lectura: práctica de lectura, etc.
  • lettura: esercitare la lettura, ...
  • 읽기: 읽기 연습, ...
  • lezen: lezen oefenen, ...
  • lesing: leseøvingar, …
  • czytanie: nauka czytania, ...
  • leitura: exercícios de leitura, ...
  • leitura: prática de leitura, ...
  • +
  • čítanie: precvičovanie čítania...
  • branje: bralna vaja, ...
  • läsning: läsningsövning, ...
  • Читання: вправи із читання…
  • xxreading: reading practice, ...xx
  • 閱讀:閱讀練習等等
  • other: learn to tell time, the braille system, maze, music instruments, ...
  • altres: aprendre a dir l'hora, el sistema braille, laberint, instruments musicals...
  • Sonstiges: Uhrzeit, Braille-System, Labyrinthe, Musikinstrumente ...
  • other: learn to tell time, the braille system, maze, music instruments, ...
  • otras: aprender a decir la hora, el sistema braille, laberintos, instrumentos musicales...
  • muuta: kellonajan kertominen, Braille-järjestelmä, sokkelo, soittimet…
  • autre : apprendre à dire l'heure, le système braille, le labyrinthe, les instruments de musique…
  • Outros: aprender a dicir as horas, o sistema braille, labirinto, instrumentos musicais, etc.
  • altro: impara a leggere l'ora, il sistema braille, labirinto, strumenti musicali, ...
  • 기타: 시간 읽기, 점자, 미로, 악기, ...
  • overig: leren klokkijken, het braille-systeem, doolhof, muziekinstrumenten, ...
  • anna: lær klokka, lær blindeskrift, labyrint, musikkinstrument, …
  • inne: naucz się godzin na zegarze, systemu brajla, labiryntów, instrumentów muzycznych, ...
  • outros: aprender a dizer as horas, o sistema Braille, labirintos, instrumentos musicais, ...
  • outros: aprendendo a ver as horas, o sistema Braille, labirintos, instrumentos musicais, ...
  • +
  • iné: ako povedať čas, braillov systém, bludisko, hudobná nástroje...
  • ostalo: prepoznavanje časa, brajica, blodnjak, glasbila, ...
  • annat: lära sig klockan, punktskrift, labyrint, musikinstrument, ...
  • Інше: навчання позначенням часу, система Брайля, лабіринти, музичні інструменти…
  • xxother: learn to tell time, the braille system, maze, music instruments, ...xx
  • 其他:看時間、點字系統、迷宮、認識樂器等等

Currently GCompris offers in excess of 100 activities and more are being developed. GCompris is free software, that means that you can adapt it to your own needs, improve it and, most importantly, share it with children everywhere.

Actualment el GCompris ofereix més de 100 activitats i encara se'n desenvolupen més. El GCompris és programari lliure, el qual vol dir que podeu adaptar-lo a les vostres pròpies necessitats, millorar-lo i, el més important, compartir-lo amb nens de tot arreu.

Insgesamt beinhaltet GCompris mehr als 100 Aktivitäten und wird ständig weiterentwickelt. GCompris ist freie Software. Sie haben also die Möglichkeit, sie ihren Bedürfnissen anzupassen und zu verbessern, und gerne auch alle Kinder der Welt von Ihrer Arbeit profitieren zu lassen.

Currently GCompris offers in excess of 100 activities and more are being developed. GCompris is free software, that means that you can adapt it to your own needs, improve it and, most importantly, share it with children everywhere.

En la actualidad, GCompris ofrece más de 100 actividades y hay muchas más en desarrollo. GCompris es software libre, lo que significa que puede adaptarlo a sus necesidades, mejorarlo y, lo que es más importante, compartirlo con los niños de todo el mundo.

GComprisissa on nykyisellään yli sata toimintoa, ja lisää kehitetään. GCompris on vapaata ohjelmistoa, mikä tarkoittaa, että voit muokata sitä tarpeisiisi, parannella sitä ja mikä tärkeintä jakaa sitä lapsille kaikkialla.

Actuellement, GCompris contient plus de 100 activités et d'autres sont en cours de développement. GCompris est un logiciel libre, ce qui veut dire que vous pouvez l'adapter à vos propres besoins, le modifier et, le plus important, le partager avec des enfants où que ce soit.

Actualmente GCompris ofrece máis de 100 actividades e hai máis en progreso. GCompris é software libre, o que significa que pode adaptalo para axustalo ás súas necesidades, melloralo e, o máis importante, compartilo con nenos de todo o mundo.

Attualmente GCompris offre più di 100 attività e altre sono in fase di sviluppo. GCompris è software libero, che significa che puoi adattarlo alle tue necessità, migliorarlo e, cosa più importante, condividerlo con tutti i bambini.

GCompris는 100개 이상의 활동을 포함하고 있으며 더 많은 활동을 개발하고 있습니다. GCompris는 자유 소프트웨어이며, 필요에 따라서 활동을 개선할 수 있으며 전 세계의 사람들과 공유할 수 있습니다.

Op dit moment biedt GCompris meer dan 100 activiteiten en meer zijn er in ontwikkeling. GCompris is vrije software, dat betekent dat u het kunt aanpassen aan uw eigen behoeften, het verbeteren en, meest belangrijk, het met kinderen overal kun delen.

GCompris har over 100 aktivitetar, og fleire vert utvikla. GCompris er fri programvare. Det vil seia at du kan tilpassa spelet slik du ønskjer, forbetra det og dela det med andre ungar i heile verda.

Obecnie GCompris zapewnia ponad 100 aktywności, a jeszcze więcej jest opracowywanych. GCompris jest darmowym oprogramowaniem, co oznacza, że możesz je dopasować do własnych potrzeb, ulepszać je i co najważniejsze udostępniać je dzieciom.

De momento, o GCompris oferece mais de 100 actividades, estando ainda mais em desenvolvimento. O GCompris é uma aplicação de 'software' livre, o que significa que o poderá adaptar às suas próprias necessidades, melhorá-lo e, o mais importante, partilhá-lo com as crianças em todo o lado.

Atualmente o GCompris oferece mais de 100 atividades e outras mais estão sendo desenvolvidas. O GCompris é um software livre, o que significa que você pode adaptá-lo para as suas próprias necessidades, melhorá-lo e, mais importante, compartilhar com as crianças de todo o mundo.

+

Aktuálne GCompris ponúka vyše 100 aktivít a ďalšie sa vyvíjajú. GCompris je slobodný softvér, čo znamená, že si ho môžete prispôsobiť na vlastné potreby, zlepšiť, a hlavne zdieľať s deťmi všade.

GCompris trenutno ponuja več kot 100 dejavnosti, še več pa jih je v razvoju. GCompris je prosta programska oprema, kar pomeni, da jo lahko prilagodite po svoje, še pomembneje pa je, da jo lahko delite z otroki širom sveta.

För närvarande erbjuder GCompris över 100 aktiviteter och ännu fler håller på att utvecklas. GCompris är fri programvara, vilket betyder att man kan anpassa det till sina egna behov, och viktigast av allt, dela det med barn överallt.

У поточній версії GCompris понад 100 вправ. Розробники постійно працюють над новими вправами. GCompris є вільним програмним забезпеченням, це означає, що ви можете адаптувати програму до власних потреб, покращувати її і, що найважливіше, ділитися вашими творіннями із усіма дітьми.

xxCurrently GCompris offers in excess of 100 activities and more are being developed. GCompris is free software, that means that you can adapt it to your own needs, improve it and, most importantly, share it with children everywhere.xx

目前 GCompris 提供超過 100 個活動,還有更多正在開發中。GCompris 是一套自由軟體,表示您可以根據您自己的需求來改進,並分享給所有的孩子們。

http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png xxhttp://gcompris.net/screenshots-qt/middle/canal_lock.pngxx http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ xxhttp://gcompris.net/screenshots-qt/middle/xx http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png xxhttp://gcompris.net/screenshots-qt/middle/click_on_letter_up.pngxx http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png xxhttp://gcompris.net/screenshots-qt/middle/clockgame.pngxx http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png xxhttp://gcompris.net/screenshots-qt/middle/color_mix.pngxx http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png xxhttp://gcompris.net/screenshots-qt/middle/colors.pngxx http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png xxhttp://gcompris.net/screenshots-qt/middle/enumerate.pngxx http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png xxhttp://gcompris.net/screenshots-qt/middle/fifteen.pngxx http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png xxhttp://gcompris.net/screenshots-qt/middle/hexagon.pngxx http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png xxhttp://gcompris.net/screenshots-qt/middle/redraw_symmetrical.pngxx http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png xxhttp://gcompris.net/screenshots-qt/middle/scalesboard.pngxx http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png xxhttp://gcompris.net/screenshots-qt/middle/traffic.pngxx http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ xxhttp://gcompris.net/xx http://gcompris.net/ http://gcompris.net/ https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris xxhttps://bugs.kde.org/enter_bug.cgi?format=guided&product=gcomprisxx https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net xxbruno.coudoin@gcompris.netxx bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net
diff --git a/platforms/ios/config.h b/platforms/ios/config.h index 5b08df880..1c5280955 100644 --- a/platforms/ios/config.h +++ b/platforms/ios/config.h @@ -1,14 +1,39 @@ +/* GCompris - config.h + * + * Copyright (C) 2015 Bruno Coudoin + * + * Authors: + * Bruno Coudoin + * + * 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 GCOMPRIS_CONFIG_H +#define GCOMPRIS_CONFIG_H + /* Version number of package */ #define VERSION "0.35" /* Folder where rccs and translations are installed */ #ifdef Q_OS_MAC #define GCOMPRIS_DATA_FOLDER "." #else #define GCOMPRIS_DATA_FOLDER "../bin/gcompris-qt.app/Contents/MacOS" #endif /* GCompris for android, gcompris-qt for others */ #define GCOMPRIS_APPLICATION_NAME "gcompris-qt" /* Compressed audio format */ #define COMPRESSED_AUDIO "aac" /* Download Allowed */ #define DOWNLOAD_ALLOWED "ON" + +#endif // GCOMPRIS_CONFIG_H diff --git a/src/activities/activities.txt b/src/activities/activities.txt index 6718182b1..0cbd97026 100644 --- a/src/activities/activities.txt +++ b/src/activities/activities.txt @@ -1,106 +1,108 @@ # The list of activities that will be loaded at GCompris start. # Keep it sorted advanced_colors algebra_by algebra_div algebra_minus algebra_plus algorithm align4 align4-2players alphabet-sequence babymatch babyshapes ballcatch braille_alphabets braille_fun canal_lock chronos -clickanddraw -clickgame click_on_letter click_on_letter_up +clickanddraw +clickgame clockgame color_mix color_mix_light colors details drawnumber electric enumerate erase erase_2clic erase_clic fifteen followline football geo-country geography gletters gnumch-equality gnumch-factors gnumch-inequality gnumch-multiples gnumch-primes guessnumber hanoi hanoi_real hexagon imageid imagename instruments intro_gravity leftright lightsoff louis-braille magic-hat-minus magic-hat-plus maze mazeinvisible mazerelative memory memory-enumerate memory-math-add memory-math-add-minus memory-math-add-minus-mult-div memory-math-add-minus-mult-div-tux memory-math-add-minus-tux memory-math-add-tux memory-math-div memory-math-div-tux memory-math-minus memory-math-minus-tux memory-math-mult memory-math-mult-div memory-math-mult-div-tux memory-math-mult-tux memory-sound memory-sound-tux memory-tux memory-wordnumber mining missing-letter money money_back money_back_cents money_cents mosaic numbers-odd-even penalty planegame +readingh +readingv redraw redraw_symmetrical reversecount scalesboard scalesboard_weight scalesboard_weight_avoirdupois simplepaint smallnumbers smallnumbers2 sudoku superbrain target tic_tac_toe tic_tac_toe_2players traffic wordsgame diff --git a/src/activities/algorithm/algorithm.svg b/src/activities/algorithm/algorithm.svg index 3d3f9515b..d4d07e0c1 100644 --- a/src/activities/algorithm/algorithm.svg +++ b/src/activities/algorithm/algorithm.svg @@ -1,307 +1,307 @@ + inkscape:window-maximized="1" /> image/svg+xml + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#d08832;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" /> + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#e7dcd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" /> diff --git a/src/activities/babymatch/ActivityInfo.qml b/src/activities/babymatch/ActivityInfo.qml index 5dbba02f3..d57395c54 100644 --- a/src/activities/babymatch/ActivityInfo.qml +++ b/src/activities/babymatch/ActivityInfo.qml @@ -1,36 +1,37 @@ /* GCompris - ActivityInfo.qml * * Copyright (C) 2015 Pulkit Gupta * * Authors: * Pulkit Gupta * * 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 . */ import GCompris 1.0 ActivityInfo { name: "babymatch/Babymatch.qml" difficulty: 1 icon: "babymatch/babymatch.svg" author: "Pulkit Gupta <pulkitgenius@gmail.com>" demo: false title: qsTr("Matching Items") description: qsTr("Drag and Drop the items to make them match") +// intro: "Slide the images on their respective targets" goal: qsTr("Motor coordination. Conceptual matching.") prerequisite: qsTr("Cultural references.") manual: qsTr("In the main board area, a set of objects is displayed. In the vertical box (at the left of the main board) another set of objects is shown, each object in the group on the left matching exactly one object in the main board area. This game challenges you to find the logical link between these objects. How do they fit together? Drag each object to the correct red space in the main area.") credit: "" section: "discovery" } diff --git a/src/activities/babymatch/babymatch.svg b/src/activities/babymatch/babymatch.svg index 661946e50..6f6c45ca0 100644 --- a/src/activities/babymatch/babymatch.svg +++ b/src/activities/babymatch/babymatch.svg @@ -1,117 +1,106 @@ + + inkscape:window-width="3200" + inkscape:window-height="1741" + inkscape:window-x="-4" + inkscape:window-y="0" + showgrid="false" + inkscape:window-maximized="1" /> image/svg+xml - + sodipodi:nodetypes="ccscscsscccc" + inkscape:connector-curvature="0" /> + sodipodi:nodetypes="cccccsssccccccccc" + inkscape:connector-curvature="0" /> + sodipodi:nodetypes="cccssssscccccccc" + inkscape:connector-curvature="0" /> - - - + sodipodi:nodetypes="ccccccccccccc" + inkscape:connector-curvature="0" /> diff --git a/src/activities/babyshapes/ActivityInfo.qml b/src/activities/babyshapes/ActivityInfo.qml index 2bfe76b93..0bfe73041 100644 --- a/src/activities/babyshapes/ActivityInfo.qml +++ b/src/activities/babyshapes/ActivityInfo.qml @@ -1,37 +1,38 @@ /* GCompris - ActivityInfo.qml * * Copyright (C) 2015 Pulkit Gupta * * Authors: * Pulkit Gupta * * 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 . */ import GCompris 1.0 ActivityInfo { name: "babyshapes/Babyshapes.qml" difficulty: 1 icon: "babyshapes/babyshapes.svg" author: "Pulkit Gupta <pulkitgenius@gmail.com>" demo: false title: qsTr("Complete the puzzle") description: qsTr("Drag and Drop the shapes on their respective targets") +// intro: "Slide the images on their respective targets" goal: "" prerequisite: "" manual: qsTr("Complete the puzzle by dragging each piece from the set of pieces on the left, to the matching space in the puzzle.") credit: qsTr("The dog is provided by Andre Connes and released under the GPL") section: "discovery" } diff --git a/src/activities/babyshapes/babyshapes.svg b/src/activities/babyshapes/babyshapes.svg index d40929f98..c980a5385 100644 --- a/src/activities/babyshapes/babyshapes.svg +++ b/src/activities/babyshapes/babyshapes.svg @@ -1,155 +1,157 @@ + + inkscape:window-width="3200" + inkscape:window-height="1741" + inkscape:window-x="-4" + inkscape:window-y="0" + showgrid="false" + inkscape:window-maximized="1" /> image/svg+xml + style="fill:#f4a932;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="fill:#f4a932;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="fill:#f4a932;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> diff --git a/src/activities/chronos/ActivityInfo.qml b/src/activities/chronos/ActivityInfo.qml index 380da930f..22e24f99e 100644 --- a/src/activities/chronos/ActivityInfo.qml +++ b/src/activities/chronos/ActivityInfo.qml @@ -1,37 +1,38 @@ /* GCompris - ActivityInfo.qml * * Copyright (C) 2015 Pulkit Gupta * * Authors: * Pulkit Gupta * * 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 . */ import GCompris 1.0 ActivityInfo { name: "chronos/Chronos.qml" difficulty: 1 icon: "chronos/chronos.svg" author: "Pulkit Gupta <pulkitgenius@gmail.com>" demo: true title: qsTr("Chronos") description: qsTr("Drag and Drop the items to organize the story") +// intro: "Slide the pictures into the order that tells the story" goal: qsTr("Sort the pictures into the order that tells the story") prerequisite: qsTr("Tell a short story") manual: qsTr("Pick from the pictures on the left and put them on the red dots") credit: qsTr("Moon photo is copyright NASA. The space sounds come from Tuxpaint and Vegastrike which are released under the GPL license. The transportation images are copyright Franck Doucet. Dates of Transportation are based on those found in <http://www.wikipedia.org>.") section: "discovery" } diff --git a/src/activities/chronos/chronos.svg b/src/activities/chronos/chronos.svg index 3844b6810..b4ed58f82 100644 --- a/src/activities/chronos/chronos.svg +++ b/src/activities/chronos/chronos.svg @@ -1,387 +1,384 @@ + + inkscape:window-width="3200" + inkscape:window-height="1741" + inkscape:window-x="-4" + inkscape:window-y="0" + showgrid="false" + inkscape:window-maximized="1" /> image/svg+xml + style="fill:#85c751;fill-opacity:1;fill-rule:evenodd;stroke:#577e1c;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:#e3432f;fill-opacity:1;fill-rule:evenodd;stroke:#577e1c;stroke-width:1.28704023;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:#85c751;fill-opacity:1;fill-rule:evenodd;stroke:#577e1c;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - - + sodipodi:nodetypes="cssz" + inkscape:connector-curvature="0" /> + sodipodi:nodetypes="cccc" + inkscape:connector-curvature="0" /> + style="fill:#85c751;fill-opacity:1;fill-rule:evenodd;stroke:#577e1c;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + transform="matrix(0.445577,0.539159,-0.59803,0.414677,128.94033,11.11452)"> + d="m 38.47611,137.77546 c 2.94022,-2.93297 4.502312,-11.38828 2.136544,-12.0748 -5.921216,-1.7183 -14.911974,5.55915 -15.024061,8.64384 -0.184713,5.08342 9.9473,6.36393 12.887517,3.43096 z" + style="fill:#85c751;fill-opacity:1;fill-rule:evenodd;stroke:#577e1c;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + inkscape:connector-curvature="0" /> + d="m 40.861769,129.29131 c 0,0 -2.173415,-0.92205 -4.280968,-2.83202 -2.798955,0.73499 -6.06339,2.94741 -6.931875,3.8364 3.391844,-2.35453 12.069037,1.2349 11.212843,-1.00438 z" + style="fill:#ffffff;fill-opacity:0.54545456;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + inkscape:connector-curvature="0" /> + d="m 26.550977,134.47056 c 0,0 0.935937,5.35128 10.941795,3.58456 0.662753,-0.81089 3.069517,-3.25664 2.423198,-3.61875 -1.335606,0.5287 -9.034387,5.90666 -12.633711,-2.53041 0.115258,0.48366 -1.159379,1.44496 -0.731282,2.5646 z" + style="fill:#000000;fill-opacity:0.29912026;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + inkscape:connector-curvature="0" /> + style="fill:#85c751;fill-opacity:1;fill-rule:evenodd;stroke:#577e1c;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/src/activities/colors/ColorItem.qml b/src/activities/colors/ColorItem.qml index b10e8e200..798091e77 100644 --- a/src/activities/colors/ColorItem.qml +++ b/src/activities/colors/ColorItem.qml @@ -1,123 +1,136 @@ /* GCompris - ColorItem.qml * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Pascal Georges (GTK+ version) * Bruno Coudoin (Qt Quick port) * * 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 . */ import QtQuick 2.1 import "findit.js" as Activity import "../../core" import GCompris 1.0 Image { id: item property GCAudio audioVoices property Item bar property string audioSrc property string question property bool playAudioOnError: false function select() { + mouseArea.enabled = false if(question === Activity.getCurrentTextQuestion()) { particles.burst(40) animWin.start() Activity.nextQuestion() } else { if(audioSrc && item.playAudioOnError) { item.audioVoices.play(audioSrc) } crossAnim.start() } } MouseArea { + id: mouseArea anchors.fill: parent onClicked: select() } SequentialAnimation { id: anim running: true loops: Animation.Infinite NumberAnimation { target: item property: "rotation" from: -10; to: 10 duration: 400 + Math.floor(Math.random() * 400) easing.type: Easing.InOutQuad } NumberAnimation { target: item property: "rotation" from: 10; to: -10 duration: 400 + Math.floor(Math.random() * 400) - easing.type: Easing.InOutQuad } + easing.type: Easing.InOutQuad + } } SequentialAnimation { id: animWin running: false loops: 1 NumberAnimation { target: item property: "rotation" from: 0; to: 360 duration: 600 easing.type: Easing.InOutQuad } + onRunningChanged: { + if (running == false) { + mouseArea.enabled = true + } + } } ParticleSystemStarLoader { id: particles clip: false } Image { id: cross source: Activity.url + "checkError.svg" sourceSize.width: 128 * ApplicationInfo.ratio anchors.centerIn: parent width: 0 height: width opacity: 1 property int size: Math.min(parent.width, parent.height) } SequentialAnimation { id: crossAnim PropertyAnimation { target: cross property: "width" duration: 300 from: 0 to: cross.size easing.type: Easing.InOutQuad } PauseAnimation { duration: 800 } PropertyAnimation { target: cross property: "width" duration: 300 from: cross.size to: 0 easing.type: Easing.InOutQuad } + onRunningChanged: { + if (running == false) { + mouseArea.enabled = true + } + } } } diff --git a/src/activities/colors/FindIt.qml b/src/activities/colors/FindIt.qml index e71d87936..22ef6dd55 100644 --- a/src/activities/colors/FindIt.qml +++ b/src/activities/colors/FindIt.qml @@ -1,217 +1,239 @@ /* GCompris - FindIt.qml * * Copyright (C) 2015 Bruno Coudoin * * Original activity in the Gtk+ version of GCompris by * Pascal Georges (pascal.georges1@free.fr) * * 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 . */ import QtQuick 2.1 import QtGraphicalEffects 1.0 import GCompris 1.0 import "../../core" import "findit.js" as Activity ActivityBase { id: activity focus: true property var dataset property string backgroundImg property int itemWidth property int itemHeight property string mode: "" onStart: { focus = true; } pageComponent: Image { id: background focus: true fillMode: Image.PreserveAspectCrop sourceSize.width: parent.width source: backgroundImg property bool keyboardMode: false signal start signal stop Component.onCompleted: { activity.start.connect(start) activity.stop.connect(stop) } QtObject { id: items property alias background: background property alias bar: bar - property alias bonus: bonus + property alias bonusTimer: bonusTimer property alias containerModel: containerModel property alias questionItem: questionItem // On startup we want to queue the first sound but not after property bool firstQuestion: true property bool audioOk: false property alias score: score } onStart: Activity.start(items, dataset, mode) onStop: Activity.stop() Keys.onPressed: { if(event.key === Qt.Key_Space) { container.currentItem.select() } } Keys.onReleased: { keyboardMode = true event.accepted = false } Keys.onEnterPressed: container.currentItem.select(); Keys.onReturnPressed: container.currentItem.select(); Keys.onRightPressed: container.moveCurrentIndexRight(); Keys.onLeftPressed: container.moveCurrentIndexLeft(); Keys.onDownPressed: container.moveCurrentIndexDown(); Keys.onUpPressed: container.moveCurrentIndexUp(); ListModel { id: containerModel } GridView { id: container model: containerModel x: background.width * 0.2 y: background.height * 0.2 width: background.width * 0.7 height: background.height * 0.6 interactive: false cellWidth: itemHeight + 10 cellHeight: itemWidth + 10 keyNavigationWraps: true delegate: ColorItem { audioVoices: activity.audioVoices source: model.image audioSrc: model.audio ? model.audio : "" question: model.text sourceSize.height: itemHeight sourceSize.width: itemWidth } add: Transition { PathAnimation { path: Path { PathCurve { x: background.width / 3} PathCurve { y: background.height / 3} PathCurve {} } easing.type: Easing.InOutQuad duration: 2000 } } highlight: Rectangle { width: container.cellWidth - container.spacing height: container.cellHeight - container.spacing color: "#AAFFFFFF" border.width: 3 border.color: "black" visible: background.keyboardMode Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } } Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } } } } GCText { id: questionItem anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top anchors.topMargin: 10 fontSize: largeSize font.weight: Font.DemiBold style: Text.Outline styleColor: "black" color: "white" function initQuestion() { text = Activity.getCurrentTextQuestion() if(Activity.getCurrentAudioQuestion()) { if(items.firstQuestion) items.audioOk = activity.audioVoices.append(Activity.getCurrentAudioQuestion()) else items.audioOk = activity.audioVoices.play(Activity.getCurrentAudioQuestion()) items.firstQuestion = false } opacity = 1.0 } onOpacityChanged: opacity == 0 ? initQuestion() : "" Behavior on opacity { PropertyAnimation { duration: 500 } } } DropShadow { anchors.fill: questionItem cached: false horizontalOffset: 3 verticalOffset: 3 radius: 8.0 samples: 16 color: "#80000000" source: questionItem } DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar content: BarEnumContent { value: help | home | level } onHelpClicked: { displayDialog(dialogHelp) } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() } BarButton { id: repeatItem source: "qrc:/gcompris/src/core/resource/bar_repeat.svg"; - sourceSize.width: 80 * ApplicationInfo.ratio + sourceSize.height: visible ? 80 * ApplicationInfo.ratio : 1 z: bar.z + 1 visible: items.audioOk anchors { bottom: parent.bottom right: parent.right margins: 10 * ApplicationInfo.ratio } onClicked: if (ApplicationSettings.isAudioVoicesEnabled) questionItem.initQuestion() } + Score { + id: score + anchors.bottom: repeatItem.top + anchors.right: repeatItem.right + anchors.bottomMargin: 30 + anchors.margins: 0 + } + + Timer { + id: bonusTimer + interval: 2000 + property bool win + + function good() { + win = true + start() + } + + function bad() { + win = false + start() + } + + onTriggered: win ? bonus.good("flower") : bonus.bad("flower") + } + Bonus { id: bonus Component.onCompleted: win.connect(Activity.nextLevel) } - - Score { - id: score - } } } diff --git a/src/activities/colors/colors.js b/src/activities/colors/colors.js index 7ed055cc5..52954988a 100644 --- a/src/activities/colors/colors.js +++ b/src/activities/colors/colors.js @@ -1,138 +1,138 @@ /* GCompris - colors.js * * Copyright (C) 2015 Bruno Coudoin * * 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 . */ function get() { return [ [ // Level 1 { "image": "qrc:/gcompris/src/activities/colors/resource/yellow_duck.svg", "text": qsTr("Find the yellow duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/yellow.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/black_duck.svg", "text": qsTr("Find the black duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/black.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/green_duck.svg", "text": qsTr("Find the green duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/green.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/red_duck.svg", "text": qsTr("Find the red duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/red.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/white_duck.svg", "text": qsTr("Find the white duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/white.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/blue_duck.svg", "text": qsTr("Find the blue duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/blue.$CA") } ], [ // Level 2 { "image": "qrc:/gcompris/src/activities/colors/resource/yellow_duck.svg", "text": qsTr("Find the yellow duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/yellow.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/black_duck.svg", "text": qsTr("Find the black duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/black.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/brown_duck.svg", "text": qsTr("Find the brown duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/brown.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/green_duck.svg", "text": qsTr("Find the green duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/green.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/grey_duck.svg", "text": qsTr("Find the grey duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/grey.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/orange_duck.svg", "text": qsTr("Find the orange duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/orange.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/purple_duck.svg", "text": qsTr("Find the purple duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/purple.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/white_duck.svg", "text": qsTr("Find the white duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/white.$CA") } ], [ // Level 3 { "image": "qrc:/gcompris/src/activities/colors/resource/yellow_duck.svg", "text": qsTr("Find the yellow duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/yellow.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/brown_duck.svg", "text": qsTr("Find the brown duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/brown.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/green_duck.svg", "text": qsTr("Find the green duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/green.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/grey_duck.svg", "text": qsTr("Find the grey duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/grey.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/orange_duck.svg", "text": qsTr("Find the orange duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/orange.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/purple_duck.svg", "text": qsTr("Find the purple duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/purple.$CA") }, { - "image": "qrc:/gcompris/src/activities/colors/resource/red_duck.svg", - "text": qsTr("Find the red duck"), - "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/red.$CA") + "image": "qrc:/gcompris/src/activities/colors/resource/pink_duck.svg", + "text": qsTr("Find the pink duck"), + "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/pink.$CA") }, { "image": "qrc:/gcompris/src/activities/colors/resource/blue_duck.svg", "text": qsTr("Find the blue duck"), "audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/blue.$CA") } ] ]; } diff --git a/src/activities/colors/findit.js b/src/activities/colors/findit.js index 1e0862111..845979c60 100644 --- a/src/activities/colors/findit.js +++ b/src/activities/colors/findit.js @@ -1,105 +1,105 @@ /* GCompris - findit.js * * Copyright (C) 2015 Bruno Coudoin * * 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 . */ .pragma library .import QtQuick 2.0 as Quick .import "qrc:/gcompris/src/core/core.js" as Core var url = "qrc:/gcompris/src/activities/colors/resource/" var currentLevel var numberOfLevel var items var dataset var currentQuestion function start(items_, dataset_, mode_) { if (mode_ == "Colors") Core.checkForVoices(items_.background); items = items_ dataset = dataset_.get() currentLevel = 0 numberOfLevel = dataset.length items.firstQuestion = true items.audioOk = false items.score.currentSubLevel = 1 initLevel() } function stop() { } function initLevel() { items.bar.level = currentLevel + 1 items.containerModel.clear() currentQuestion = 0 dataset[currentLevel] = Core.shuffle(dataset[currentLevel]) for(var i = 0; i < dataset[currentLevel].length; ++i) { items.containerModel.append(dataset[currentLevel][i]) } items.score.numberOfSubLevels = dataset[currentLevel].length // Shuffle again not to ask the question in the model order dataset[currentLevel] = Core.shuffle(dataset[currentLevel]) initQuestion() } function initQuestion() { // We just set the opacity to 0, the questionItem will then grab // the new question by itself // Need to set opacity to 0.1 before in order to be sure it's changed and trigger the questionItem onOpacityChanged items.questionItem.opacity = 0.1 items.questionItem.opacity = 0 } function nextQuestion() { if(dataset[currentLevel].length <= currentQuestion + 1) { - items.bonus.good("flower") + items.bonusTimer.good() } else { currentQuestion++ items.score.currentSubLevel++ initQuestion() } } function nextLevel() { items.score.currentSubLevel = 1 if(numberOfLevel <= ++currentLevel) { currentLevel = 0 } initLevel(); } function previousLevel() { items.score.currentSubLevel = 1 if(--currentLevel < 0) { currentLevel = numberOfLevel - 1 } initLevel(); } function getCurrentTextQuestion() { return dataset[currentLevel][currentQuestion].text } function getCurrentAudioQuestion() { return dataset[currentLevel][currentQuestion].audio } diff --git a/src/activities/colors/resource/pink_duck.svg b/src/activities/colors/resource/pink_duck.svg new file mode 100644 index 000000000..631f362ed --- /dev/null +++ b/src/activities/colors/resource/pink_duck.svg @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/activities/details/ActivityInfo.qml b/src/activities/details/ActivityInfo.qml index fbe730434..faa8fcd61 100644 --- a/src/activities/details/ActivityInfo.qml +++ b/src/activities/details/ActivityInfo.qml @@ -1,36 +1,37 @@ /* GCompris - ActivityInfo.qml * * Copyright (C) 2015 Pulkit Gupta * * Authors: * Pulkit Gupta * * 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 . */ import GCompris 1.0 ActivityInfo { name: "details/Details.qml" difficulty: 1 icon: "details/details.svg" author: "Pulkit Gupta <pulkitgenius@gmail.com>" demo: false title: qsTr("Find the details") description: qsTr("Drag and Drop the shapes on their respective targets") +// intro: "Slide the images on their respective targets" goal: "" prerequisite: "" manual: qsTr("Complete the puzzle by dragging each piece from the set of pieces on the left, to the matching space in the puzzle.") credit: qsTr("The images are from Wikimedia Commons.") section: "discovery" } diff --git a/src/activities/details/details.svg b/src/activities/details/details.svg index 5d1d0b3b2..a4b6d1749 100644 --- a/src/activities/details/details.svg +++ b/src/activities/details/details.svg @@ -1,525 +1,330 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + inkscape:window-maximized="1" + borderlayer="true"> image/svg+xml document search find Lapo Calamandrei Jakub Steiner 2006-04-21 - - - + cx="21" + cy="20" + rx="16.265623" + ry="16.18751" /> + sodipodi:nodetypes="cczzzcc" + id="path17267" + d="m 33.628394,32.341095 0.195544,4.173043 8.378714,8.73507 c 0.412068,0.429596 1.543317,-0.216601 2.586631,-1.297203 1.043319,-1.080602 1.624818,-1.965259 1.106795,-2.504958 l -8.378713,-8.7293 z" + style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#f4a932;fill-opacity:1;stroke:none;stroke-width:0.99999934;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none" + inkscape:connector-curvature="0" /> + style="fill:none;fill-opacity:1;stroke:#9f6710;stroke-opacity:1"> - - - - - + diff --git a/src/activities/erase_clic/ActivityInfo.qml b/src/activities/erase_clic/ActivityInfo.qml index c431e5641..ddc95e9dd 100644 --- a/src/activities/erase_clic/ActivityInfo.qml +++ b/src/activities/erase_clic/ActivityInfo.qml @@ -1,34 +1,34 @@ /* GCompris - ActivityInfo.qml * * Copyright (C) 2015 Bruno Coudoin * * 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 . */ import GCompris 1.0 ActivityInfo { name: "erase_clic/EraseClic.qml" difficulty: 1 icon: "erase_clic/erase_clic.svg" author: "Bruno Coudoin <bruno.coudoin@gcompris.net>" demo: false title: qsTr("Click or tap") description: qsTr("Click or tap to erase the area and discover the background") -// intro: " Click or tap on the transparent bricks and discover the hidden picture." +// intro: "Click or tap on the transparent bricks and discover the hidden picture." goal: qsTr("Motor-coordination") prerequisite: qsTr("Mouse-manipulation") manual: qsTr("Click or tap on the blocks all of them disappear.") credit: "" section: "computer mouse" } diff --git a/src/activities/geo-country/ActivityInfo.qml b/src/activities/geo-country/ActivityInfo.qml index 622e65c5b..196817a1b 100644 --- a/src/activities/geo-country/ActivityInfo.qml +++ b/src/activities/geo-country/ActivityInfo.qml @@ -1,37 +1,38 @@ /* GCompris - ActivityInfo.qml * * Copyright (C) 2015 Pulkit Gupta * * Authors: * Pulkit Gupta * * 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 . */ import GCompris 1.0 ActivityInfo { name: "geo-country/GeoCountry.qml" difficulty: 2 icon: "geo-country/france_region.svg" author: "Pulkit Gupta <pulkitgenius@gmail.com>" demo: true title: qsTr("Locate the region") description: qsTr("Drag and Drop the regions to redraw the whole country") +// intro: "Slide the regions to redraw the whole country" goal: "" prerequisite: "" manual: "" credit: qsTr("The map of Germany comes from Wikipedia and is released under the GNU Free Documentation License. Olaf Ronneberger and his children Lina and Julia Ronneberger created the German level.") section: "discovery" } diff --git a/src/activities/geo-country/france_region.svg b/src/activities/geo-country/france_region.svg index 3579e8311..d7470b348 100644 --- a/src/activities/geo-country/france_region.svg +++ b/src/activities/geo-country/france_region.svg @@ -1,169 +1,85 @@ + + inkscape:window-width="3200" + inkscape:window-height="1741" + inkscape:window-x="-4" + inkscape:window-y="0" + showgrid="false" + inkscape:window-maximized="1" /> image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - + style="fill:#f4a932;fill-opacity:1;stroke:none;stroke-width:8.96682072;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m 131.7445,61.001757 c 13.27957,-10.277934 29.80388,-21.565163 30.99677,-39.974307 7.30783,-16.6704932 28.05466,-8.191076 38.03704,1.060193 23.54629,24.396504 56.84897,35.910202 89.22117,43.130751 23.42733,-5.388266 30.14721,26.372094 19.67509,41.439276 -1.93207,21.11322 -18.67591,35.9891 -28.90909,53.14119 -3.23313,19.15426 27.45448,8.71104 24.20295,28.8912 0.67674,20.03463 -7.55531,45.62584 13.52892,58.47259 16.7753,12.49057 -0.66198,30.40332 -13.4089,37.36387 -15.63121,11.08047 -34.80859,5.4749 -51.31353,0.15955 -21.53844,-9.32222 -41.56059,5.72548 -44.4609,27.62231 -8.77101,24.01009 -34.77226,8.55008 -50.87347,2.94534 -19.61624,-2.8232 -40.95019,1.16221 -59.276716,-8.58012 C 81.069212,300.26026 80.370074,278.39348 88.491611,263.71397 99.49471,249.01446 81.070968,225.48145 97.737937,214.44859 100.24604,202.79577 87.799287,191.60157 85.168331,178.90956 74.652002,162.1388 68.043529,140.56951 48.690304,131.73717 31.410916,128.80175 8.0183588,118.003 16.455209,96.136826 24.925551,84.058437 41.448418,90.011403 53.188575,92.835005 65.407254,97.356327 92.258786,86.952798 90.30065,68.39262" + id="path11548-2" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccccccccccccccccc" /> + + + diff --git a/src/activities/geo-country/resource/board/board1_0.qml b/src/activities/geo-country/resource/board/board1_0.qml index 768570473..dbaba4be0 100644 --- a/src/activities/geo-country/resource/board/board1_0.qml +++ b/src/activities/geo-country/resource/board/board1_0.qml @@ -1,164 +1,186 @@ /* GCompris * * Copyright (C) 2015 Bruno Coudoin * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * * 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 . */ import QtQuick 2.0 QtObject { property string instruction: qsTr("Districts of France") property variant levels: [ { "pixmapfile" : "france/france-regions.png", "type" : "SHAPE_BACKGROUND_IMAGE" }, { "pixmapfile" : "france/rhone-alpes.png", + "sound": "voices-$CA/$LOCALE/france/rhone-alpes.$CA", "toolTipText" : "Rhône Alpes", "x" : "0.639", "y" : "0.6" }, { "pixmapfile" : "france/paca.png", + "sound": "voices-$CA/$LOCALE/france/provence-alpes-cote_d_azur.$CA", "toolTipText" : "Provence Alpes Côte d'Azur", "x" : "0.671", "y" : "0.73" }, { "pixmapfile" : "france/poitou-charentes.png", + "sound": "voices-$CA/$LOCALE/france/poitou-charentes.$CA", "toolTipText" : "Poitou Charentes", "x" : "0.363", "y" : "0.517" }, { "pixmapfile" : "france/picardie.png", + "sound": "voices-$CA/$LOCALE/france/picardie.$CA", "toolTipText" : "Picardie", "x" : "0.506", "y" : "0.158" }, { "pixmapfile" : "france/pays-de-la-loire.png", + "sound": "voices-$CA/$LOCALE/france/pays-de-la-loire.$CA", "toolTipText" : "Pays de la Loire", "x" : "0.333", "y" : "0.382" }, { "pixmapfile" : "france/nord-pas-de-calais.png", + "sound": "voices-$CA/$LOCALE/france/nord-pas-de-calais.$CA", "toolTipText" : "Nord Pas de Calais", "x" : "0.51", "y" : "0.062" }, { "pixmapfile" : "france/midi-pyrenees.png", + "sound": "voices-$CA/$LOCALE/france/midi-pyrenees.$CA", "toolTipText" : "Midi Pyrénées", "x" : "0.444", "y" : "0.763" }, { "pixmapfile" : "france/lorraine.png", + "sound": "voices-$CA/$LOCALE/france/lorraine.$CA", "toolTipText" : "Lorraine", "x" : "0.667", "y" : "0.243" }, { "pixmapfile" : "france/limousin.png", + "sound": "voices-$CA/$LOCALE/france/limousin.$CA", "toolTipText" : "Limousin", "x" : "0.45", "y" : "0.566" }, { "pixmapfile" : "france/languedoc-roussillon.png", + "sound": "voices-$CA/$LOCALE/france/languedoc-roussillon.$CA", "toolTipText" : "Languedoc Roussillon", "x" : "0.532", "y" : "0.778" }, { "pixmapfile" : "france/ile-de-france.png", + "sound": "voices-$CA/$LOCALE/france/ile-de-france.$CA", "toolTipText" : "Ile de France", "x" : "0.493", "y" : "0.253" }, { "pixmapfile" : "france/haute-normandie.png", + "sound": "voices-$CA/$LOCALE/france/haute-normandie.$CA", "toolTipText" : "Normandie", "x" : "0.421", "y" : "0.181" }, { "pixmapfile" : "france/franche-conte.png", + "sound": "voices-$CA/$LOCALE/france/franche-conte.$CA", "toolTipText" : "Franche Comté", "x" : "0.669", "y" : "0.407" }, { "pixmapfile" : "france/corse.png", + "sound": "voices-$CA/$LOCALE/france/corse.$CA", "toolTipText" : "Corse", "x" : "0.836", "y" : "0.909" }, { "pixmapfile" : "france/champagne-ardenne.png", + "sound": "voices-$CA/$LOCALE/france/champagne-ardenne.$CA", "toolTipText" : "Champagne Ardenne", "x" : "0.593", "y" : "0.23" }, { "pixmapfile" : "france/centre.png", + "sound": "voices-$CA/$LOCALE/france/centre.$CA", "toolTipText" : "Centre", "x" : "0.449", "y" : "0.361" }, { "pixmapfile" : "france/bretagne.png", + "sound": "voices-$CA/$LOCALE/france/bretagne.$CA", "toolTipText" : "Bretagne", "x" : "0.231", "y" : "0.303" }, { "pixmapfile" : "france/bourgogne.png", + "sound": "voices-$CA/$LOCALE/france/bourgogne.$CA", "toolTipText" : "Bourgogne", "x" : "0.574", "y" : "0.398" }, { "pixmapfile" : "france/basse-normandie.png", + "sound": "voices-$CA/$LOCALE/france/basse-normandie.$CA", "toolTipText" : "Basse Normandie", "x" : "0.354", "y" : "0.22" }, { "pixmapfile" : "france/auvergne.png", + "sound": "voices-$CA/$LOCALE/france/auvergne.$CA", "toolTipText" : "Auvergne", "x" : "0.532", "y" : "0.564" }, { "pixmapfile" : "france/aquitaine.png", + "sound": "voices-$CA/$LOCALE/france/aquitaine.$CA", "toolTipText" : "Aquitaine", "x" : "0.357", "y" : "0.714" }, { "pixmapfile" : "france/alsace.png", + "sound": "voices-$CA/$LOCALE/france/alsace.$CA", "toolTipText" : "Alsace", "x" : "0.729", "y" : "0.286" } ] } diff --git a/src/activities/geography/ActivityInfo.qml b/src/activities/geography/ActivityInfo.qml index cb96e62e8..d49e135e2 100644 --- a/src/activities/geography/ActivityInfo.qml +++ b/src/activities/geography/ActivityInfo.qml @@ -1,37 +1,38 @@ /* GCompris - ActivityInfo.qml * * Copyright (C) 2015 Pulkit Gupta * * Authors: * Pulkit Gupta * * 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 . */ import GCompris 1.0 ActivityInfo { name: "geography/Geography.qml" difficulty: 2 icon: "geography/globe.svg" author: "Pulkit Gupta <pulkitgenius@gmail.com>" demo: true title: qsTr("Locate the countries") description: qsTr("Drag and Drop the items to redraw the whole map") +// intro: "Slide the countries to redraw the whole map" goal: "" prerequisite: "" manual: "" credit: "" section: "discovery" } diff --git a/src/activities/geography/globe.svg b/src/activities/geography/globe.svg index 016b54b6d..95ada954b 100644 --- a/src/activities/geography/globe.svg +++ b/src/activities/geography/globe.svg @@ -1,122 +1,124 @@ + + inkscape:window-width="3200" + inkscape:window-height="1741" + inkscape:window-x="-4" + inkscape:window-y="0" + showgrid="false" + inkscape:window-maximized="1" /> image/svg+xml diff --git a/src/activities/geography/resource/board/board9_0.qml b/src/activities/geography/resource/board/board9_0.qml index aec39d221..097da7256 100644 --- a/src/activities/geography/resource/board/board9_0.qml +++ b/src/activities/geography/resource/board/board9_0.qml @@ -1,305 +1,305 @@ /* GCompris * * Copyright (C) 2015 Bruno Coudoin * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * * 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 . */ import QtQuick 2.0 QtObject { property string instruction: qsTr("Africa") property variant levels: [ { "pixmapfile": "africa/africa.png", "type": "SHAPE_BACKGROUND_IMAGE" }, { "pixmapfile": "africa/zimbabwe.png", "sound": "voices-$CA/$LOCALE/geography/zimbabwe.$CA", "toolTipText": qsTr("Zimbabwe"), "x": "0.676", "y": "0.783" }, { "pixmapfile": "africa/zambia.png", "sound": "voices-$CA/$LOCALE/geography/zambia.$CA", "toolTipText": qsTr("Zambia"), "x": "0.662", "y": "0.704" }, { "pixmapfile": "africa/tunisia.png", "sound": "voices-$CA/$LOCALE/geography/tunisia.$CA", "toolTipText": qsTr("Tunisia"), "x": "0.39", "y": "0.051" }, { "pixmapfile": "africa/togo.png", "sound": "voices-$CA/$LOCALE/geography/togo.$CA", "toolTipText": qsTr("Togo"), "x": "0.268", "y": "0.403" }, { "pixmapfile": "africa/chad.png", "sound": "voices-$CA/$LOCALE/geography/chad.$CA", "toolTipText": qsTr("Chad"), "x": "0.528", "y": "0.306" }, { "pixmapfile": "africa/tanzania.png", "sound": "voices-$CA/$LOCALE/geography/tanzania.$CA", "toolTipText": qsTr("Tanzania"), "x": "0.763", "y": "0.609" }, { "pixmapfile": "africa/soudan.png", "sound": "voices-$CA/$LOCALE/geography/soudan.$CA", "toolTipText": qsTr("Sudan"), "x": "0.69", "y": "0.34" }, { "pixmapfile": "africa/somalia.png", "sound": "voices-$CA/$LOCALE/geography/somalia.$CA", "toolTipText": qsTr("Somalia"), "x": "0.925", "y": "0.449" }, { "pixmapfile": "africa/senegal.png", "sound": "voices-$CA/$LOCALE/geography/senegal.$CA", "toolTipText": qsTr("Senegal"), "x": "0.049", "y": "0.32" }, { "pixmapfile": "africa/rep_congo.png", - "sound": "voices-$CA/$LOCALE/geography/rep_congo.$CA", + "sound": "voices-$CA/$LOCALE/geography/democratic_republic_of_congo.$CA", "toolTipText": qsTr("Democratic Republic of Congo"), "x": "0.57", "y": "0.577" }, { "pixmapfile": "africa/rep_centrafrique.png", "sound": "voices-$CA/$LOCALE/geography/rep_centrafrique.$CA", "toolTipText": qsTr("Central African Republic"), "x": "0.563", "y": "0.425" }, { "pixmapfile": "africa/uganda.png", "sound": "voices-$CA/$LOCALE/geography/uganda.$CA", "toolTipText": qsTr("Uganda"), "x": "0.725", "y": "0.5" }, { "pixmapfile": "africa/nigeria.png", "sound": "voices-$CA/$LOCALE/geography/nigeria.$CA", "toolTipText": qsTr("Nigeria"), "x": "0.385", "y": "0.395" }, { "pixmapfile": "africa/niger.png", "sound": "voices-$CA/$LOCALE/geography/niger.$CA", "toolTipText": qsTr("Niger"), "x": "0.373", "y": "0.277" }, { "pixmapfile": "africa/namibia.png", "sound": "voices-$CA/$LOCALE/geography/namibia.$CA", "toolTipText": qsTr("Namibia"), "x": "0.516", "y": "0.84" }, { "pixmapfile": "africa/mozambique.png", "sound": "voices-$CA/$LOCALE/geography/mozambique.$CA", "toolTipText": qsTr("Mozambique"), "x": "0.768", "y": "0.783" }, { "pixmapfile": "africa/mauritania.png", "sound": "voices-$CA/$LOCALE/geography/mauritania.$CA", "toolTipText": qsTr("Mauritania"), "x": "0.099", "y": "0.231" }, { "pixmapfile": "africa/moroco.png", "sound": "voices-$CA/$LOCALE/geography/moroco.$CA", "toolTipText": qsTr("Morocco"), "x": "0.127", "y": "0.123" }, { "pixmapfile": "africa/mali.png", "sound": "voices-$CA/$LOCALE/geography/mali.$CA", "toolTipText": qsTr("Mali"), "x": "0.2", "y": "0.273" }, { "pixmapfile": "africa/malawi.png", "sound": "voices-$CA/$LOCALE/geography/malawi.$CA", "toolTipText": qsTr("Malawi"), "x": "0.751", "y": "0.702" }, { "pixmapfile": "africa/madagascar.png", "sound": "voices-$CA/$LOCALE/geography/madagascar.$CA", "toolTipText": qsTr("Madagascar"), "x": "0.927", "y": "0.781" }, { "pixmapfile": "africa/libya.png", "sound": "voices-$CA/$LOCALE/geography/libya.$CA", "toolTipText": qsTr("Libya"), "x": "0.502", "y": "0.154" }, { "pixmapfile": "africa/liberia.png", "sound": "voices-$CA/$LOCALE/geography/liberia.$CA", "toolTipText": qsTr("Liberia"), "x": "0.117", "y": "0.433" }, { "pixmapfile": "africa/kenya.png", "sound": "voices-$CA/$LOCALE/geography/kenya.$CA", "toolTipText": qsTr("Kenya"), "x": "0.81", "y": "0.52" }, { "pixmapfile": "africa/guinea.png", "sound": "voices-$CA/$LOCALE/geography/guinea.$CA", "toolTipText": qsTr("Guinea"), "x": "0.094", "y": "0.381" }, { "pixmapfile": "africa/ghana.png", "sound": "voices-$CA/$LOCALE/geography/ghana.$CA", "toolTipText": qsTr("Ghana"), "x": "0.237", "y": "0.411" }, { "pixmapfile": "africa/gabon.png", "sound": "voices-$CA/$LOCALE/geography/gabon.$CA", "toolTipText": qsTr("Gabon"), "x": "0.427", "y": "0.538" }, { "pixmapfile": "africa/ethiopia.png", "sound": "voices-$CA/$LOCALE/geography/ethiopia.$CA", "toolTipText": qsTr("Ethiopia"), "x": "0.845", "y": "0.395" }, { "pixmapfile": "africa/eritrea.png", "sound": "voices-$CA/$LOCALE/geography/eritrea.$CA", "toolTipText": qsTr("Eritrea"), "x": "0.831", "y": "0.31" }, { "pixmapfile": "africa/egypt.png", "sound": "voices-$CA/$LOCALE/geography/egypt.$CA", "toolTipText": qsTr("Egypt"), "x": "0.683", "y": "0.152" }, { "pixmapfile": "africa/ivory_coast.png", "sound": "voices-$CA/$LOCALE/geography/ivory_coast.$CA", "toolTipText": qsTr("Ivory Coast"), "x": "0.178", "y": "0.417" }, { "pixmapfile": "africa/congo.png", "sound": "voices-$CA/$LOCALE/geography/congo.$CA", "toolTipText": qsTr("Republic of Congo"), "x": "0.477", "y": "0.528" }, { "pixmapfile": "africa/cameroon.png", "sound": "voices-$CA/$LOCALE/geography/cameroon.$CA", "toolTipText": qsTr("Cameroon"), "x": "0.441", "y": "0.427" }, { "pixmapfile": "africa/burkina_faso.png", "sound": "voices-$CA/$LOCALE/geography/burkina_faso.$CA", "toolTipText": qsTr("Burkina Faso"), "x": "0.232", "y": "0.35" }, { "pixmapfile": "africa/botswana.png", "sound": "voices-$CA/$LOCALE/geography/botswana.$CA", "toolTipText": qsTr("Botswana"), "x": "0.608", "y": "0.832" }, { "pixmapfile": "africa/benin.png", "sound": "voices-$CA/$LOCALE/geography/benin.$CA", "toolTipText": qsTr("Benin"), "x": "0.291", "y": "0.393" }, { "pixmapfile": "africa/angola.png", "sound": "voices-$CA/$LOCALE/geography/angola.$CA", "toolTipText": qsTr("Angola"), "x": "0.514", "y": "0.686" }, { "pixmapfile": "africa/algeria.png", "sound": "voices-$CA/$LOCALE/geography/algeria.$CA", "toolTipText": qsTr("Algeria"), "x": "0.279", "y": "0.128" }, { "pixmapfile": "africa/south_africa.png", "sound": "voices-$CA/$LOCALE/geography/south_africa.$CA", "toolTipText": qsTr("South Africa"), "x": "0.606", "y": "0.913" } ] } diff --git a/src/activities/gletters/FallingWord.qml b/src/activities/gletters/FallingWord.qml index 44320e960..0d7c27e84 100644 --- a/src/activities/gletters/FallingWord.qml +++ b/src/activities/gletters/FallingWord.qml @@ -1,162 +1,168 @@ /* GCompris - Word.qml * * Copyright (C) 2014 Holger Kaelberer * * Authors: * Bruno Coudoin (GTK+ version) * Holger Kaelberer (Qt Quick port) * * * 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 . */ import QtQuick 2.0 import QtGraphicalEffects 1.0 import GCompris 1.0 import "../../core" import "gletters.js" as Activity Item { id: word width: wordText.width height: wordText.height /// index into text.split("") where next typed match should occur property int unmatchedIndex: 0; property alias text: wordText.text; property bool wonState: false + property string mode signal won onWon: { wonState = true particle.burst(30) dropShadow.opacity = 0 fadeout.restart(); } Component.onCompleted: { // make sure our word is completely visible if (x + width > parent.width) x = parent.width - width; } onUnmatchedIndexChanged: { if (unmatchedIndex <= 0) highlightedWordText.text = ""; else if (wordText.text.length > 0 && wordText.text.length >= unmatchedIndex) { highlightedWordText.text = wordText.text.substring(0, unmatchedIndex); /* Need to add the ZERO WIDTH JOINER to force joined char in Arabic and * Hangul: http://en.wikipedia.org/wiki/Zero-width_joiner * * FIXME: this works only on desktop systems, on android this * shifts the typed word a few pixels down. */ if (!ApplicationInfo.isMobile) highlightedWordText.text += "\u200C"; } } PropertyAnimation { id: fadeout target: word; property: "opacity" to: 0 duration: 1000 onStopped: Activity.deleteWord(word); } function checkMatch(c) { // We are in the ending animation if (wonState) return - var chars = text.split(""); - if (chars[unmatchedIndex] == c) { - unmatchedIndex++; - return true; + if(word.mode === 'letter') { + unmatchedIndex = c.length + return (text === c) } else { - unmatchedIndex = 0; - return false; + var chars = text.split(""); + if (chars[unmatchedIndex] == c) { + unmatchedIndex++; + return true; + } else { + unmatchedIndex = 0; + return false; + } } } function startMoving(dur) { down.duration = dur; down.restart(); } function isCompleted() { return (unmatchedIndex === text.length); } GCText { id: wordText text: "" fontSize: 35 font.bold: true color: "navy" style: Text.Outline styleColor: "white" ParticleSystemStarLoader { id: particle clip: false } GCText { id: highlightedWordText anchors.fill: parent text: "" fontSize: parent.fontSize font.bold: parent.font.bold color: "red" style: Text.Outline styleColor: "white" } } DropShadow { id: dropShadow anchors.fill: wordText cached: false horizontalOffset: 1 verticalOffset: 1 radius: 3.0 samples: 16 color: "#422a2a2a" source: wordText } NumberAnimation { id: down target: word property: "y" to: parent.height duration: 10000 onStopped: { Activity.audioCrashPlay(); Activity.appendRandomWord(word.text) Activity.deleteWord(word); } } } diff --git a/src/activities/gletters/gletters.js b/src/activities/gletters/gletters.js index ff40171f1..4afc844b1 100644 --- a/src/activities/gletters/gletters.js +++ b/src/activities/gletters/gletters.js @@ -1,403 +1,417 @@ /* GCompris - gletters.js * * Copyright (C) 2014 Holger Kaelberer * * Authors: * Bruno Coudoin (GTK+ version) * Holger Kaelberer (Qt Quick port) * * 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 . */ /* ToDo / open issues: * - adjust wordlist filenames once we have an ApplicationInfo.dataPath() or so * - make uppercaseOnly be taken from (activity-) settings */ .pragma library .import QtQuick 2.0 as Quick .import GCompris 1.0 as GCompris //for ApplicationInfo .import "qrc:/gcompris/src/core/core.js" as Core var currentLevel = 0; var currentSubLevel = 0; var level = null; var maxLevel = 0; var maxSubLevel = 0; var items; var uppercaseOnly; var mode; //speed calculations, common: var speed = 0; // how fast letters fall var fallSpeed = 0; // how often new letters are dropped var incFallSpeed = 1000; // how much drop rate increases per sublevel var incSpeed = 10; // how much speed increases per sublevel // gletters: var fallRateBase = 40; // default for how fast letters fall (smaller is faster) var fallRateMult = 80; // default for how much falling speed increases per level (smaller is faster) var dropRateBase = 5000; // default for how often new letters are dropped var dropRateMult = 100; // default for how much drop rate increases per level // wordsgame: var wgMaxFallSpeed = 7000; var wgMaxSpeed = 150; var wgMinFallSpeed = 3000; var wgMinSpeed = 50; var wgDefaultFallSpeed = 8000; var wgDefaultSpeed = 170; var wgAddSpeed = 20; var wgAddFallSpeed = 1000; var wgMaxFallingItems; var droppedWords; var currentWord = null; // reference to the word currently typing, null if n/a var wordComponent = null; var successRate // Falling speed depends on it function start(items_, uppercaseOnly_, _mode) { items = items_; uppercaseOnly = uppercaseOnly_; mode = _mode; currentLevel = 0; currentSubLevel = 0; var locale = items.locale == "system" ? "$LOCALE" : items.locale // register the voices for the locale GCompris.DownloadManager.updateResource(GCompris.DownloadManager.getVoicesResourceForLocale(GCompris.ApplicationInfo.getVoicesLocale(items.locale))); items.wordlist.loadFromFile(GCompris.ApplicationInfo.getLocaleFilePath( items.ourActivity.dataSetUrl + "default-"+locale+".json")); // If wordlist is empty, we try to load from short locale and if not present again, we switch to default one var localeUnderscoreIndex = locale.indexOf('_') // probably exist a better way to see if the list is empty if(items.wordlist.maxLevel == 0) { var localeShort; // We will first look again for locale xx (without _XX if exist) if(localeUnderscoreIndex > 0) { localeShort = locale.substring(0, localeUnderscoreIndex) } else { localeShort = locale; } // If not found, we will use the default file items.wordlist.useDefault = true items.wordlist.loadFromFile(GCompris.ApplicationInfo.getLocaleFilePath( items.ourActivity.dataSetUrl + "default-"+localeShort+".json")); // We remove the using of default file for next time we enter this function items.wordlist.useDefault = false } maxLevel = items.wordlist.maxLevel; droppedWords = new Array(); initLevel(); } function stop() { deleteWords(); wordComponent = null items.wordDropTimer.stop(); } function initLevel() { items.audioVoices.clearQueue() items.bar.level = currentLevel + 1; wgMaxFallingItems = 3 successRate = 1.0 // initialize level deleteWords(); level = items.wordlist.getLevelWordList(currentLevel + 1); maxSubLevel = items.wordlist.getMaxSubLevel(currentLevel + 1); if (maxSubLevel == 0) { // If "sublevels" length is not set in wordlist, use the words length maxSubLevel = level.words.length } items.score.numberOfSubLevels = maxSubLevel; setSpeed(); /*console.log("Gletters: initializing level " + (currentLevel + 1) + " maxSubLvl=" + maxSubLevel + " wordCount=" + level.words.length + " speed=" + speed + " fallspeed=" + fallSpeed);*/ { /* populate VirtualKeyboard for mobile: * 1. for < 10 letters print them all in the same row * 2. for > 10 letters create 3 rows with equal amount of keys per row * if possible, otherwise more keys in the upper rows * 3. if we have both upper- and lowercase letters activate the shift * key*/ // first generate a map of needed letters var letters = new Array(); items.keyboard.shiftKey = false; for (var i = 0; i < level.words.length; i++) { - for (var j = 0; j < level.words[i].length; j++) { - var letter = level.words[i].charAt(j); + if(mode ==='letter') { + // The word is a letter, even if it has several chars (digraph) + var letter = level.words[i]; var isUpper = (letter == letter.toLocaleUpperCase()); if (isUpper && letters.indexOf(letter.toLocaleLowerCase()) !== -1) items.keyboard.shiftKey = true; else if (!isUpper && letters.indexOf(letter.toLocaleUpperCase()) !== -1) items.keyboard.shiftKey = true; else if (letters.indexOf(letter) === -1) - letters.push(level.words[i].charAt(j)); + letters.push(level.words[i]); + } else { + // We split each word in char to create the keyboard + for (var j = 0; j < level.words[i].length; j++) { + var letter = level.words[i].charAt(j); + var isUpper = (letter == letter.toLocaleUpperCase()); + if (isUpper && letters.indexOf(letter.toLocaleLowerCase()) !== -1) + items.keyboard.shiftKey = true; + else if (!isUpper && letters.indexOf(letter.toLocaleUpperCase()) !== -1) + items.keyboard.shiftKey = true; + else if (letters.indexOf(letter) === -1) + letters.push(level.words[i].charAt(j)); + } } } letters.sort(); // generate layout from letter map var layout = new Array(); var row = 0; var offset = 0; while (offset < letters.length-1) { var cols = letters.length <= 10 ? letters.length : (Math.ceil((letters.length-offset) / (3 - row))); layout[row] = new Array(); for (var j = 0; j < cols; j++) layout[row][j] = { label: letters[j+offset] }; offset += j; row++; } items.keyboard.layout = layout; } items.wordlist.initRandomWord(currentLevel + 1) initSubLevel() } function initSubLevel() { currentWord = null; if (currentSubLevel != 0) { // increase speed speed = Math.max(speed - incSpeed, wgMinSpeed); items.wordDropTimer.interval = fallSpeed = Math.max(fallSpeed - incFallSpeed, wgMinFallSpeed); } items.score.currentSubLevel = currentSubLevel + 1; if (currentSubLevel == 0 || droppedWords.length <= 1) // note, last word is still fading out dropWord(); //console.log("Gletters: initializing subLevel " + (currentSubLevel + 1) + " words=" + JSON.stringify(level.words)); } function processKeyPress(text) { var typedText = uppercaseOnly ? text.toLocaleUpperCase() : text; if (currentWord !== null) { // check against a currently typed word if (!currentWord.checkMatch(typedText)) { currentWord = null; audioCrashPlay() } else { playLetter(text) } } else { // no current word, check against all available words var found = false for (var i = 0; i< droppedWords.length; i++) { if (droppedWords[i].checkMatch(typedText)) { // typed correctly currentWord = droppedWords[i]; playLetter(text) found = true break; } } if(!found) { audioCrashPlay() } } if (currentWord !== null && currentWord.isCompleted()) { // win! currentWord.won(); // note: deleteWord() is triggered after fadeout successRate += 0.1 currentWord = null nextSubLevel(); } } function setSpeed() { if (mode == "letter") { speed = (level.speed !== undefined) ? level.speed : (fallRateBase + Math.floor(fallRateMult / (currentLevel + 1))); fallSpeed = (level.fallspeed !== undefined) ? level.fallspeed : Math.floor((dropRateBase + (dropRateMult * (currentLevel + 1)))); } else { // wordsgame speed = (level.speed !== undefined) ? level.speed : wgDefaultSpeed - (currentLevel+1)*wgAddSpeed; fallSpeed = (level.fallspeed !== undefined) ? level.fallspeed : wgDefaultFallSpeed - (currentLevel+1)*wgAddFallSpeed if(speed < wgMinSpeed ) speed = wgMinSpeed; if(speed > wgMaxSpeed ) speed = wgMaxSpeed; if(fallSpeed < wgMinFallSpeed ) fallSpeed = wgMinFallSpeed; if(fallSpeed > wgMaxFallSpeed ) fallSpeed = wgMaxFallSpeed; } items.wordDropTimer.interval = fallSpeed; } function deleteWords() { if (droppedWords === undefined || droppedWords.length < 1) return; for (var i = 0; i< droppedWords.length; i++) droppedWords[i].destroy(); droppedWords.length = 0; } function deleteWord(w) { if (droppedWords === undefined || droppedWords.length < 1) return; if (w == currentWord) currentWord = null; for (var i = 0; i< droppedWords.length; i++) if (droppedWords[i] == w) { droppedWords[i].destroy(); droppedWords.splice(i, 1); break; } } function createWord() { if (wordComponent.status == 1 /* Component.Ready */) { var text = items.wordlist.getRandomWord(); if(!text) { items.wordDropTimer.restart(); return } // if uppercaseOnly case does not matter otherwise it does if (uppercaseOnly) text = text.toLocaleUpperCase(); var word if(items.ourActivity.getImage(text)) { word = wordComponent.createObject( items.background, { "text": text, "image": items.ourActivity.getImage(text), // assume x=width-25px for now, Word auto-adjusts onCompleted(): "x": Math.random() * (items.main.width - 25), "y": -25, }); - } else if(items.ourActivity.getDominoValues(text)) { + } else if(items.ourActivity.getDominoValues(text).length) { word = wordComponent.createObject( items.background, { "text": text, "dominoValues": items.ourActivity.getDominoValues(text), // assume x=width-25px for now, Word auto-adjusts onCompleted(): "x": Math.random() * (items.main.width - 25), "y": -25, }); } else { word = wordComponent.createObject( items.background, { "text": text, // assume x=width-25px for now, Word auto-adjusts onCompleted(): "x": Math.random() * (items.main.width - 25), "y": -25, + "mode": mode, }); } if (word === null) console.log("Gletters: Error creating word object"); else { droppedWords[droppedWords.length] = word; // speed to duration: var duration = (items.main.height / 2) * speed / successRate; /* console.debug("Gletters: dropping new word " + word.text + " duration=" + duration + " (speed=" + speed + ")" + " num=" + droppedWords.length);*/ word.startMoving(duration); } items.wordDropTimer.restart(); } else if (wordComponent.status == 3 /* Component.Error */) { console.log("Gletters: error creating word component: " + wordComponent.errorString()); } } function dropWord() { // Do not create too many falling items if(droppedWords.length > wgMaxFallingItems) { items.wordDropTimer.restart(); return } if (wordComponent !== null) createWord(); else { var text = items.wordlist.getRandomWord(); items.wordlist.appendRandomWord(text) var fallingItem if(items.ourActivity.getImage(text)) fallingItem = "FallingImage.qml" else if(items.ourActivity.getDominoValues(text).length) fallingItem = "FallingDomino.qml" else fallingItem = "FallingWord.qml" wordComponent = Qt.createComponent("qrc:/gcompris/src/activities/gletters/" + fallingItem); if (wordComponent.status == 1 /* Component.Ready */) createWord(); else if (wordComponent.status == 3 /* Component.Error */) { console.log("Gletters: error creating word component: " + wordComponent.errorString()); } else wordComponent.statusChanged.connect(createWord); } } function appendRandomWord(word) { items.wordlist.appendRandomWord(word) } function audioCrashPlay() { if(successRate > 0.5) successRate -= 0.1 items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav") } function nextLevel() { if(maxLevel <= ++currentLevel ) { currentLevel = 0 } currentSubLevel = 0; initLevel(); } function previousLevel() { if(--currentLevel < 0) { currentLevel = maxLevel - 1 } currentSubLevel = 0; initLevel(); } function nextSubLevel() { if( ++currentSubLevel >= maxSubLevel) { currentSubLevel = 0 items.bonusTimer.start(); } else initSubLevel(); } function playLetter(letter) { var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale) items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/"+locale+"/alphabet/" + Core.getSoundFilenamForChar(letter))) } function focusTextInput() { if (!GCompris.ApplicationInfo.isMobile && items) items.textinput.forceActiveFocus(); } diff --git a/src/activities/gletters/resource/default-en.json b/src/activities/gletters/resource/default-en.json index dd89890cb..ffc16287c 100644 --- a/src/activities/gletters/resource/default-en.json +++ b/src/activities/gletters/resource/default-en.json @@ -1,179 +1,220 @@ { "levels" : [ { "level" : "1", "words" : [ "a", "e", "i", "o", - "u" + "u", + "y" ] }, { "level" : "2", "words" : [ "b", "c", "d", "f", "g", + "h", + "j", + "k", "l", "m", "n", - "p", - "r", - "s", - "t" + "p" ] }, { "level" : "3", "words" : [ - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0" + "m", + "n", + "p", + "q", + "r", + "s", + "t", + "v", + "w", + "x", + "z" ] }, { "level" : "4", "words" : [ "a", "b", "c", "d", "e", "f", "g", + "h", "i", + "j", + "k", "l", "m", "n", "o", "p", + "q", "r", "s", "t", "u", + "v", + "w", + "x", + "y", + "z" + ] + }, + { + "level" : "5", + "words" : [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" ] }, { - "level" : "5", + "level" : "6", "words" : [ "A", "E", "I", "O", - "U" + "U", + "Y" ] }, { - "level" : "6", + "level" : "7", "words" : [ "B", "C", "D", "F", "G", - "L", + "H", + "J", + "K", + "L" + ] + }, + { + "level" : "8", + "words" : [ "M", "N", "P", + "Q", "R", "S", - "T" + "T", + "V", + "W", + "X", + "Z" ] }, { - "level" : "7", + "level" : "9", "words" : [ - "A", "B", "C", "D", - "E", "F", "G", - "I", + "H", + "J", + "K", "L", "M", "N", - "O", "P", + "Q", "R", "S", "T", - "U", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0" + "V", + "W", + "X", + "Z" ] }, { - "level" : "8", + "level" : "10", "words" : [ "a", "b", "c", "d", "e", "f", "g", + "h", "i", + "j", + "k", "l", "m", "n", "o", "p", + "q", "r", "s", "t", "u", + "v", + "w", + "x", + "y", + "z", "A", "B", "C", "D", "E", "F", "G", + "H", "I", + "J", + "K", "L", "M", "N", "O", "P", + "Q", "R", "S", "T", - "U" + "U", + "V", + "W", + "X", + "Y", + "Z" ] } ], "name" : "default-en", "locale" : "en", "description" : "English" } diff --git a/src/activities/gletters/resource/default-en.json b/src/activities/gletters/resource/default-nl.json similarity index 100% copy from src/activities/gletters/resource/default-en.json copy to src/activities/gletters/resource/default-nl.json diff --git a/src/activities/gletters/resource/default-en.json b/src/activities/gletters/resource/default-ro.json similarity index 60% copy from src/activities/gletters/resource/default-en.json copy to src/activities/gletters/resource/default-ro.json index dd89890cb..2f07e0972 100644 --- a/src/activities/gletters/resource/default-en.json +++ b/src/activities/gletters/resource/default-ro.json @@ -1,179 +1,240 @@ { "levels" : [ { "level" : "1", "words" : [ "a", "e", "i", "o", - "u" + "u", + "y" ] }, { "level" : "2", "words" : [ "b", "c", "d", "f", "g", + "h", + "j", + "k", "l", "m", "n", - "p", - "r", - "s", - "t" + "p" ] }, { "level" : "3", "words" : [ - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0" + "m", + "n", + "p", + "q", + "r", + "s", + "t", + "v", + "w", + "x", + "z" ] }, { "level" : "4", "words" : [ "a", "b", "c", "d", "e", "f", "g", + "h", "i", + "j", + "k", "l", "m", "n", "o", "p", + "q", "r", "s", "t", "u", + "v", + "w", + "x", + "y", + "z" + ] + }, + { + "level" : "5", + "words" : [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" ] }, { - "level" : "5", + "level" : "6", "words" : [ "A", "E", "I", "O", - "U" + "U", + "Y" ] }, { - "level" : "6", + "level" : "7", "words" : [ "B", "C", "D", "F", "G", - "L", + "H", + "J", + "K", + "L" + ] + }, + { + "level" : "8", + "words" : [ "M", "N", "P", + "Q", "R", "S", - "T" + "T", + "V", + "W", + "X", + "Z" ] }, { - "level" : "7", + "level" : "9", "words" : [ - "A", "B", "C", "D", - "E", "F", "G", - "I", + "H", + "J", + "K", "L", "M", "N", - "O", "P", + "Q", "R", "S", "T", - "U", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0" + "V", + "W", + "X", + "Z" ] }, { - "level" : "8", + "level" : "10", "words" : [ "a", "b", "c", "d", "e", "f", "g", + "h", "i", + "j", + "k", "l", "m", "n", "o", "p", + "q", "r", "s", "t", "u", + "v", + "w", + "x", + "y", + "z", "A", "B", "C", "D", "E", "F", "G", + "H", "I", + "J", + "K", "L", "M", "N", "O", "P", + "Q", "R", "S", "T", - "U" + "U", + "V", + "W", + "X", + "Y", + "Z" + ] + }, + { + "level" : "11", + "words" : [ + "ă", + "â", + "î", + "ș", + "ț" + ] + }, + { + "level" : "12", + "words" : [ + "Ă", + "â", + "Î", + "Ș", + "Ț" ] } ], - "name" : "default-en", - "locale" : "en", - "description" : "English" + "name" : "default-ro", + "locale" : "ro", + "description" : "Romanian" } diff --git a/src/activities/imageid/lang_api.js b/src/activities/imageid/lang_api.js index 84aac3444..0d693a981 100644 --- a/src/activities/imageid/lang_api.js +++ b/src/activities/imageid/lang_api.js @@ -1,112 +1,109 @@ /* GCompris - lang_api.js * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin (bruno.coudoin@gcompris.net) * * 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 . */ .pragma library .import GCompris 1.0 as GCompris .import "qrc:/gcompris/src/core/core.js" as Core var contentText function validateDataset(levels) { return true; } function load(parser, baseUrl, datasetFilename, translationFilename) { var datasetUrl = baseUrl + "/" + datasetFilename; var dataset = parser.parseFromUrl(datasetUrl, validateDataset); if (dataset === null) { console.error("Lang: Invalid dataset, can't continue: " + datasetUrl); return; } dataset['contentText'] = loadContent(parser, GCompris.ApplicationInfo.getLocaleFilePath(baseUrl + "/" + translationFilename)) if(!dataset['contentText']) { return null } return dataset } function loadContent(parser, datasetUrl) { var dataset = parser.parseFromUrl(datasetUrl, validateDataset); if (dataset === null) { console.error("Lang: Invalid dataset, can't continue: " + datasetUrl); return; } return dataset } function getChapter(dataset, chapter) { return dataset[chapter] } // Return a datamodel for the chapter suitable for creating a chapter selector function getChapterModel(dataset) { var chapters = [] for (var c = 0; c < dataset.length; c++) { chapters.push( {'name': dataset[c].name, 'image': dataset[c].content[0].content[0].image, 'index': c }) } return chapters } function getLesson(dataset, chapter, lesson) { return chapter.content[lesson] } function getAllLessons(dataset) { var lessons = [] for (var c in dataset) { for (var l in dataset[c].content) { var lesson = getLesson(dataset, dataset[c], l) lessons.push(lesson) } } return lessons } function getLessonWords(dataset, lesson) { var wordList = lesson.content // Fill up the lesson with the translated text var allWords = [] for (var k in wordList) { var word = wordList[k] - word['translatedTxt'] = getTextByAudio(dataset.contentText, - word.description) + + word['translatedTxt'] = dataset.contentText[word.voice.substr(word.voice.lastIndexOf("/")+1).replace("$CA", "ogg")]; + if(word['translatedTxt']) allWords.push(word) } - return allWords -} -function getTextByAudio(contentText, audio) { - audio += ".ogg" - return contentText[audio] + return allWords } diff --git a/src/activities/imageid/resource/content-ca.json b/src/activities/imageid/resource/content-ca.json new file mode 100644 index 000000000..d91e3feca --- /dev/null +++ b/src/activities/imageid/resource/content-ca.json @@ -0,0 +1,582 @@ +{ + "ate.ogg": "menjar", + "bake.ogg": "cuinar", + "bark.ogg": "bordar", + "beg.ogg": "demanar", + "bite.ogg": "mossegar", + "blink.ogg": "picada d'ullet", + "boil.ogg": "bullir", + "break.ogg": "trencar", + "call.ogg": "trucada", + "catch.ogg": "pescar", + "centipede.ogg": "centpeus", + "chat.ogg": "parlar", + "chop.ogg": "tallar", + "clap.ogg": "picar de mans", + "clean.ogg": "rentar", + "crawl.ogg": "gatejar", + "croak.ogg": "raucar", + "cry.ogg": "plorar", + "cut.ogg": "tallar", + "dig.ogg": "cavar", + "drank.ogg": "beure", + "draw.ogg": "dibuix", + "dream.ogg": "somiar", + "drive.ogg": "conduir", + "drool.ogg": "bavejar", + "dry.ogg": "assecar", + "eat.ogg": "menjar", + "fell.ogg": "caure", + "fetch.ogg": "informar", + "find.ogg": "trobar", + "float.ogg": "flotador", + "fly.ogg": "volar", + "freeze.ogg": "congelar", + "growl.ogg": "grunyir", + "hatch.ogg": "sortir de l'ou", + "hear.ogg": "sentir", + "howl.ogg": "udolar", + "hug.ogg": "abraçar", + "jump.ogg": "saltar", + "kneel.ogg": "agenollar", + "knit.ogg": "punt de mitja", + "lick.ogg": "llepar", + "look.ogg": "mirar-se", + "meet.ogg": "trobar-se", + "nap.ogg": "migdiada", + "peck.ogg": "picotejar", + "play.ogg": "jugar", + "plow.ogg": "llaurar", + "pounce.ogg": "saltar", + "quarrel.ogg": "baralla", + "read.ogg": "llegir", + "rip.ogg": "estripar", + "run.ogg": "córrer", + "sat.ogg": "seure", + "scared.ogg": "espantat", + "scratch.ogg": "esgarrapar", + "scream.ogg": "cridar", + "scribble.ogg": "gargot", + "see.ogg": "mirar", + "shake.ogg": "sacsejar", + "sing.ogg": "cantar", + "sip.ogg": "xarrupar", + "sit.ogg": "seure", + "sleep.ogg": "dormir", + "smell.ogg": "olorar", + "smooch.ogg": "bessar", + "sniff.ogg": "ensumar", + "spill.ogg": "vessar", + "splash.ogg": "doll d'aigua", + "spray.ogg": "ruixar", + "spread.ogg": "untar", + "spring.ogg": "botar", + "squat.ogg": "ajupir", + "sting.ogg": "fibló", + "stop.ogg": "aturar", + "stretch.ogg": "estiraments", + "study.ogg": "estudiar", + "teach.ogg": "ensenyar", + "tear.ogg": "estripar", + "think.ogg": "pensar", + "touch.ogg": "tocar", + "wag.ogg": "moure la cua", + "walk.ogg": "caminar", + "wash.ogg": "banyar", + "whisper.ogg": "xiuxiuejar", + "win.ogg": "guanyar", + "back.ogg": "esquena", + "braid.ogg": "trena", + "brain.ogg": "cervell", + "bump.ogg": "bony", + "chin.ogg": "barbeta", + "ear.ogg": "orella", + "face.ogg": "cara", + "feet.ogg": "peu", + "fist.ogg": "puny", + "foot.ogg": "peu", + "grin.ogg": "somriure", + "hair.ogg": "cabell", + "hand.ogg": "mà", + "head.ogg": "cap", + "hip.ogg": "maluc", + "knee.ogg": "genoll", + "lap.ogg": "a la falda", + "lip.ogg": "llavis", + "mouth.ogg": "boca", + "neck.ogg": "coll", + "nose.ogg": "nas", + "scar.ogg": "cicatriu", + "skin.ogg": "pell", + "stare.ogg": "mirar fixament", + "sweat.ogg": "suor", + "teeth.ogg": "dents", + "thigh.ogg": "cuixa", + "throat.ogg": "gola", + "wrist.ogg": "canell", + "bib.ogg": "pitet", + "cap.ogg": "gorra", + "cape.ogg": "capa", + "coat.ogg": "abric", + "dress.ogg": "vestit", + "glove.ogg": "guants", + "hat.ogg": "barret", + "patch.ogg": "pedaç", + "scarf.ogg": "bufanda", + "shirt.ogg": "camisa", + "shoe.ogg": "sabata", + "short.ogg": "pantalons curts", + "skirt.ogg": "faldilla", + "sleeve.ogg": "màniga", + "smock.ogg": "brusa", + "sneaker.ogg": "sabatilla deportiva", + "sock.ogg": "mitjó", + "suit.ogg": "vestit", + "zoo.ogg": "zoològic", + "danger.ogg": "perill", + "frown.ogg": "envejar", + "fun.ogg": "divertit", + "mad.ogg": "ira", + "rage.ogg": "ràbia", + "sad.ogg": "trist", + "smile.ogg": "somriure", + "whisk.ogg": "batedora", + "chief.ogg": "indi", + "clown.ogg": "pallasso", + "coach.ogg": "entrenador", + "cowboy.ogg": "vaquer", + "hunter.ogg": "caçador", + "judge.ogg": "jutge", + "knight.ogg": "cavaller", + "lad.ogg": "mosso", + "pope.ogg": "papa", + "prince.ogg": "príncep", + "princess.ogg": "princesa", + "queen.ogg": "reina", + "teacher.ogg": "professora", + "vet.ogg": "veterinari", + "boy.ogg": "noi", + "bride.ogg": "núvia", + "brother.ogg": "germà", + "child.ogg": "nen", + "dad.ogg": "pare", + "friend.ogg": "amics", + "girl.ogg": "dona", + "gnome.ogg": "gnom", + "mate.ogg": "amics", + "men.ogg": "multitud", + "pal.ogg": "col·legues", + "athlete.ogg": "atleta", + "ballet.ogg": "ballet", + "camp.ogg": "acampar", + "cheer.ogg": "animar", + "climb.ogg": "escalada", + "dance.ogg": "ballar", + "dive.ogg": "immersió", + "explore.ogg": "exploradors", + "hike.ogg": "caminada", + "hit.ogg": "pegar", + "hop.ogg": "saltar", + "jog.ogg": "fúting", + "lift.ogg": "aixecar", + "ran.ogg": "córrer", + "ride.ogg": "anar amb bicicleta", + "skate.ogg": "patinar", + "ski.ogg": "esquiar", + "sport.ogg": "esport", + "swim.ogg": "nedar", + "write.ogg": "escriure", + "alligator.ogg": "caiman", + "animal.ogg": "animals", + "bait.ogg": "esquer", + "bat.ogg": "ratpenat", + "bee.ogg": "abella", + "beetle.ogg": "escarabat", + "bird.ogg": "ocell", + "bug.ogg": "insecte", + "camel.ogg": "camell", + "cat.ogg": "gat", + "chick.ogg": "pollet", + "chicken.ogg": "pollastre", + "chimp.ogg": "ximpanzé", + "clam.ogg": "cloïssa", + "claw.ogg": "urpa", + "cow.ogg": "vaca", + "crab.ogg": "cranc", + "crocodile.ogg": "cocodril", + "crow.ogg": "corb", + "den.ogg": "cau", + "dog.ogg": "gos", + "dragon.ogg": "drac", + "duck.ogg": "ànec", + "fin.ogg": "aleta", + "fish.ogg": "peix", + "flies.ogg": "mosca", + "fox.ogg": "guineu", + "frog.ogg": "granota", + "fur.ogg": "pell", + "giraffe.ogg": "girafa", + "goat.ogg": "cabra", + "hen.ogg": "gallina", + "herd.ogg": "ramat", + "hound.ogg": "empaita", + "lamb.ogg": "xai", + "mane.ogg": "cabellera", + "mice.ogg": "ratolins", + "mole.ogg": "talp", + "mosquito.ogg": "mosquit", + "mule.ogg": "mula", + "owl.ogg": "òliba", + "ox.ogg": "bou", + "paw.ogg": "pota", + "pet.ogg": "mascota", + "pig.ogg": "porc", + "pug.ogg": "carlí", + "puppy.ogg": "cadell", + "rat.ogg": "rata", + "shark.ogg": "tauró", + "shell.ogg": "closca", + "shrimp.ogg": "gamba", + "skunk.ogg": "mofeta", + "slime.ogg": "bava", + "snail.ogg": "cargol", + "snake.ogg": "serp", + "spider.ogg": "aranya", + "spike.ogg": "eriçó", + "squid.ogg": "calamar", + "squirrel.ogg": "esquirol", + "starfish.ogg": "estrella de mar", + "swan.ogg": "cigne", + "tick.ogg": "paparra", + "wing.ogg": "ala", + "yum.ogg": "saborós", + "bone.ogg": "os", + "bread.ogg": "pans", + "bun.ogg": "brioix", + "cake.ogg": "pastís", + "candy.ogg": "caramel", + "cheese.ogg": "formatge", + "chocolate.ogg": "xocolata", + "cookie.ogg": "galetes", + "crumb.ogg": "engrunes", + "crust.ogg": "crosta", + "drink.ogg": "tassa", + "feast.ogg": "banquet", + "flour.ogg": "farina", + "food.ogg": "hamburguesa", + "fudge.ogg": "dolços de xocolata", + "gum.ogg": "xiclet", + "ice.ogg": "glaçó", + "juice.ogg": "suc", + "lunch.ogg": "aperitiu", + "pop.ogg": "crispetes", + "rice.ogg": "arròs", + "sandwich.ogg": "sandvitx", + "sauce.ogg": "salsa", + "snack.ogg": "mos", + "spaghetti.ogg": "espagueti", + "sprinkle.ogg": "espurnes", + "stew.ogg": "guisat", + "treat.ogg": "dolços", + "cherry.ogg": "cireres", + "fruit.ogg": "fruita", + "lime.ogg": "llima", + "orange.ogg": "taronja", + "peach.ogg": "préssecs", + "plum.ogg": "prunes", + "bay.ogg": "badia", + "beach.ogg": "platja", + "cave.ogg": "cova", + "cliff.ogg": "penya-segat", + "cloud.ogg": "núvol", + "cold.ogg": "fred", + "dirt.ogg": "sòl", + "dune.ogg": "duna", + "earth.ogg": "la Terra", + "fire.ogg": "foc", + "flame.ogg": "flama", + "garden.ogg": "jardí", + "gem.ogg": "joia", + "ground.ogg": "el terra", + "heat.ogg": "calor", + "hole.ogg": "forat", + "lake.ogg": "llac", + "land.ogg": "terreny", + "ledge.ogg": "sortint", + "mud.ogg": "fang", + "night.ogg": "nit", + "ocean.ogg": "oceà", + "path.ogg": "camí", + "rock.ogg": "roques", + "sand.ogg": "sorra", + "shore.ogg": "riba", + "sky.ogg": "cel", + "slope.ogg": "pendent", + "smoke.ogg": "fum", + "snow.ogg": "neu", + "star.ogg": "estel", + "stone.ogg": "pedres", + "stream.ogg": "riu", + "summer.ogg": "estiu", + "sun.ogg": "sol", + "time.ogg": "temps", + "top.ogg": "al cim", + "trail.ogg": "sender", + "water.ogg": "aigua", + "wind.ogg": "vent", + "yarn.ogg": "fil", + "angel.ogg": "àngel", + "bit.ogg": "mica", + "class.ogg": "classe", + "price.ogg": "preu", + "question.ogg": "pregunta", + "quiz.ogg": "examen", + "science.ogg": "ciència", + "splatter.ogg": "esquitxada", + "tune.ogg": "melodia", + "branch.ogg": "branca", + "bud.ogg": "brot", + "bush.ogg": "arbust", + "flower.ogg": "flor", + "grass.ogg": "herba", + "hay.ogg": "farratge", + "hedge.ogg": "tanca", + "lawn.ogg": "gespa", + "pine.ogg": "pi", + "plant.ogg": "plantes", + "rose.ogg": "rosa", + "seed.ogg": "llavors", + "shrub.ogg": "arbust", + "stem.ogg": "tija", + "stick.ogg": "branca", + "stump.ogg": "tronc", + "tree.ogg": "arbre", + "carrot.ogg": "pastanaga", + "corn.ogg": "blat de moro", + "cucumber.ogg": "cogombre", + "mushroom.ogg": "bolet", + "nut.ogg": "cacauet", + "squash.ogg": "carbassó", + "bank.ogg": "banc", + "barn.ogg": "graner", + "bridge.ogg": "pont", + "cabin.ogg": "cabana", + "cage.ogg": "gàbia", + "castle.ogg": "castell", + "door.ogg": "porta", + "fair.ogg": "atracció", + "fountain.ogg": "font", + "grave.ogg": "tomba", + "home.ogg": "casa", + "hut.ogg": "cabana", + "lane.ogg": "carrils", + "pool.ogg": "piscina", + "ramp.ogg": "rampa", + "roof.ogg": "sostre", + "school.ogg": "col·legi", + "shed.ogg": "cobert", + "shop.ogg": "botiga", + "stage.ogg": "escenari", + "store.ogg": "botiga", + "street.ogg": "carrer", + "strawberry.ogg": "maduixa", + "bath.ogg": "banyera", + "bed.ogg": "llit", + "bench.ogg": "banc", + "chair.ogg": "cadira", + "chest.ogg": "bagul", + "couch.ogg": "sofà", + "crib.ogg": "bressols", + "desk.ogg": "escriptori", + "fan.ogg": "ventilador", + "lamp.ogg": "el llum", + "light.ogg": "la llum", + "mat.ogg": "estora", + "quilt.ogg": "edredó", + "rug.ogg": "catifa", + "seat.ogg": "seient", + "shelf.ogg": "prestatge", + "shower.ogg": "dutxa", + "sink.ogg": "pica", + "stove.ogg": "cuina", + "toilet.ogg": "vàter", + "balance.ogg": "balança", + "can.ogg": "llaunes", + "clock.ogg": "despertador", + "dish.ogg": "font", + "fork.ogg": "forquilla", + "glass.ogg": "got", + "knife.ogg": "ganivet", + "lid.ogg": "tapa", + "mop.ogg": "fregona", + "mug.ogg": "tassa", + "pan.ogg": "paella", + "plate.ogg": "plat", + "pot.ogg": "olla", + "scale.ogg": "balança", + "sponge.ogg": "esponja", + "spoon.ogg": "cullera", + "trash.ogg": "escombraries", + "tray.ogg": "safata", + "farm.ogg": "granja", + "anchor.ogg": "àncora", + "badge.ogg": "insígnia", + "bag.ogg": "bossa", + "ball.ogg": "bola", + "bead.ogg": "bombolla", + "block.ogg": "bloc", + "board.ogg": "tauló", + "bomb.ogg": "bomba", + "book.ogg": "llibre", + "box.ogg": "caixa", + "candle.ogg": "espelma", + "cane.ogg": "bastó", + "card.ogg": "tarjeta", + "cart.ogg": "carro", + "cash.ogg": "diners", + "chalk.ogg": "guix", + "clay.ogg": "argila", + "cloth.ogg": "drap", + "coin.ogg": "monedes", + "comb.ogg": "pinta", + "cone.ogg": "con", + "crown.ogg": "corona", + "cube.ogg": "cub", + "drum.ogg": "tambor", + "flag.ogg": "bandera", + "flute.ogg": "flauta", + "game.ogg": "joc", + "gift.ogg": "regal", + "glue.ogg": "cola", + "hook.ogg": "ham", + "hose.ogg": "mànega", + "ink.ogg": "tinta", + "jewel.ogg": "joia", + "kite.ogg": "estel", + "knot.ogg": "nus", + "log.ogg": "troncs", + "map.ogg": "mapa", + "mask.ogg": "màscara", + "match.ogg": "llumins", + "nest.ogg": "niu", + "net.ogg": "xarxa", + "oar.ogg": "rems", + "page.ogg": "pàgina", + "pair.ogg": "parell", + "pen.ogg": "bolígraf", + "pencil.ogg": "llapis", + "picture.ogg": "pintura", + "pole.ogg": "pal", + "prize.ogg": "trofeu", + "rag.ogg": "drap", + "rope.ogg": "corda", + "sign.ogg": "el senyal", + "sleigh.ogg": "trineu", + "slide.ogg": "tobogan", + "squirt.ogg": "pulveritzador", + "stack.ogg": "apilar", + "stamp.ogg": "segell", + "straw.ogg": "palles", + "string.ogg": "cordill", + "tag.ogg": "etiqueta", + "thread.ogg": "bobina", + "torch.ogg": "torxa", + "towel.ogg": "tovallola", + "toy.ogg": "joguina", + "trap.ogg": "parany", + "tube.ogg": "llapis de llavis", + "watch.ogg": "rellotge", + "wheel.ogg": "roda", + "wig.ogg": "perruca", + "wood.ogg": "fusta", + "link.ogg": "enllaç", + "dirty.ogg": "brut", + "throw.ogg": "llançar", + "brick.ogg": "maons", + "brush.ogg": "brotxa", + "flash.ogg": "llanterna", + "rake.ogg": "rasclet", + "screw.ogg": "vis", + "spear.ogg": "la llança", + "tool.ogg": "eines", + "wedge.ogg": "falca", + "wrench.ogg": "clau anglesa", + "bike.ogg": "bicicleta", + "boat.ogg": "barca", + "canoe.ogg": "canoa", + "car.ogg": "cotxe", + "plane.ogg": "avió", + "sail.ogg": "veler", + "ship.ogg": "vaixell", + "sled.ogg": "trineu", + "train.ogg": "tren", + "truck.ogg": "camió", + "black.ogg": "negre", + "blue.ogg": "blau", + "brown.ogg": "marró", + "color.ogg": "colors", + "gray.ogg": "gris", + "green.ogg": "verd", + "orange-color.ogg": "taronja", + "pink.ogg": "rosa", + "red.ogg": "vermell", + "white.ogg": "blanc", + "five.ogg": "cinc", + "one.ogg": "un", + "ten.ogg": "deu", + "three.ogg": "tres", + "two.ogg": "dos", + "van.ogg": "furgoneta", + "big.ogg": "gran", + "blind.ogg": "cec", + "blond.ogg": "rossa", + "bright.ogg": "brillant", + "crazy.ogg": "ximple", + "cute.ogg": "bufona", + "dot.ogg": "punt", + "empty.ogg": "buida", + "fat.ogg": "gras", + "flat.ogg": "pisos", + "front.ogg": "davant", + "full.ogg": "ple", + "giant.ogg": "gegant", + "happy.ogg": "feliç", + "high.ogg": "a gran altura", + "hot.ogg": "calent", + "huge.ogg": "enorme", + "left.ogg": "esquerra", + "line.ogg": "codi de barres", + "liquid.ogg": "líquid", + "magic.ogg": "mag", + "on.ogg": "sobre", + "pretty.ogg": "bella", + "right.ogg": "dreta", + "round.ogg": "circular", + "royal.ogg": "reial", + "shut.ogg": "tancat", + "sick.ogg": "malalt", + "small.ogg": "petit", + "spot.ogg": "taca", + "square.ogg": "quadrat", + "stand.ogg": "dret", + "straight.ogg": "recte", + "stripe.ogg": "ratlles", + "strong.ogg": "fortalesa", + "tall.ogg": "alt", + "thick.ogg": "gruixut", + "tired.ogg": "cansat", + "under.ogg": "sota", + "wet.ogg": "mullat", + "wheat.ogg": "blat", + "U0030.ogg": "zero", + "U0031.ogg": "un", + "U0032.ogg": "dos", + "U0033.ogg": "tres", + "U0034.ogg": "quatre", + "U0035.ogg": "cinc", + "U0036.ogg": "sis", + "U0037.ogg": "set", + "U0038.ogg": "vuit", + "U0039.ogg": "nou", + "10.ogg": "deu" +} diff --git a/src/activities/imageid/resource/content-de.json b/src/activities/imageid/resource/content-de.json index 4f8b91f11..e19ed5fb0 100644 --- a/src/activities/imageid/resource/content-de.json +++ b/src/activities/imageid/resource/content-de.json @@ -1,1105 +1,1096 @@ { "accountant.ogg": "der Buchhalter", "ache.ogg": "der Schmerz", "acorn.ogg": "die Eichel", "actor.ogg": "der Schauspieler", "air_horn.ogg": "die Hupe", "alarmclock.ogg": "der Wecker", "alligator.ogg": "der Alligator", "alphabet.ogg": "das Alphabet", "anchor.ogg": "der Anker", "angel.ogg": "der Engle", "angry.ogg": "wütend", "animal.ogg": "die Tiere", "ankle.ogg": "der Knöchel", "ant.ogg": "die Ameise", "anteater.ogg": "der Ameisenbär", "antelope.ogg": "die Antilope", "apple.ogg": "der Apfel", "apple_tree.ogg": "der Apfelbaum", "appliance.ogg": "das Gerät", "apricot.ogg": "die Aprikose", "arm.ogg": "der Arm", "armchair.ogg": "der Sessel", "artichoke.ogg": "die Artischocke", "artist.ogg": "der Künstler", "asparagus.ogg": "der Spargel", "astronaut.ogg": "der Astronaut", "athlete.ogg": "der Athlet", "avocado.ogg": "die Avocado", "ax.ogg": "die Axt", "baby_bottle.ogg": "die Babyflasche", "back.ogg": "der Rücken", "badge.ogg": "das Abzeichen", "bag.ogg": "der Rucksack", "bait.ogg": "der Köder", "bake.ogg": "kochen", "balance.ogg": "die Waage", "bald.ogg": "glatzköpfig", "ball.ogg": "der Ball", "ball_of_yarn.ogg": "der Wollknäuel", "ball_soccer.ogg": "der Fußball", "ballet.ogg": "das Ballet", "bank.ogg": "die Bank", "banker_female.ogg": "die Bankangestellte", "bark.ogg": "bellen", "barn.ogg": "die Scheune", "bat.ogg": "die Fledermaus", "bath.ogg": "das Bad", "bathing_suit.ogg": "der Badeanzug", "bay.ogg": "die Bucht", "beach.ogg": "der Strand", "bead.ogg": "die Blase", "bean.ogg": "die Bohne", "bear.ogg": "der Bär", "beard.ogg": "der Bart", "beat.ogg": "schlagen", "beaver.ogg": "der Biber", "bed.ogg": "das Bett", "bedroom.ogg": "das Schlafzimmer", "bee.ogg": "die Biene", "beef.ogg": "das Rindfleisch", "beetle.ogg": "der Käfer", "beg.ogg": "betteln", "behind.ogg": "dahinter", "bell.ogg": "die Glocke", "belly.ogg": "der Bauch", "bench.ogg": "die Bank", "bib.ogg": "der Latz", "big.ogg": "groß", "big_top.ogg": "das Zirkuszelt", "bike.ogg": "das Fahrrad", "bird.ogg": "der Vogel", "bit.ogg": "der Bissen", "bite.ogg": "abbeißen", "black.ogg": "schwarz", "blackberry.ogg": "die Brombeere", "blackbird.ogg": "die Amsel", "blade.ogg": "die Klinge", "blind.ogg": "blind", "blink.ogg": "blinzeln", "block.ogg": "der Block", "blond.ogg": "blond", "blue.ogg": "blau", "blueberry.ogg": "die Heidelbeere", "blush.ogg": "erröten", "board.ogg": "das Brett", "boat.ogg": "das Boot", "boil.ogg": "kochen", "bolt.ogg": "die Mutter", "bomb.ogg": "die Bombe", "bone.ogg": "der Knochen", "book.ogg": "das Buch", "bookcase.ogg": "das Bücherregal", "bottom.ogg": "das Gesäß", "box.ogg": "die Schachtel", "boxer.ogg": "der Boxer", "boy.ogg": "der Junge", "braid.ogg": "der Zopf", "brain.ogg": "das Gehirn", "branch.ogg": "der Ast", "bread.ogg": "das Brot", "break.ogg": "brechen", "breast.ogg": "die Brust", "brick.ogg": "der Ziegelstein", "bricklayer.ogg": "der Maurer", "bride.ogg": "die Braut", "bridge.ogg": "die Brücke", "bright.ogg": "leuchtend", "broccoli.ogg": "der Brokkoli", "brother.ogg": "der Bruder", "brown.ogg": "braun", "brush.ogg": "der Pinsel", "bubble.ogg": "die Blase", "bucket.ogg": "der Eimer", "bud.ogg": "die Knospe", "buffalo.ogg": "der Büffel", "bug.ogg": "das Insekt", "bulb.ogg": "die Glühbirne", "bull.ogg": "der Stier", "bump.ogg": "die Beule", "bun.ogg": "das Brötchen", "bus.ogg": "der Bus", "bush.ogg": "der Busch", "butcher.ogg": "der Metzger", "butter.ogg": "die Butter", "butterfly.ogg": "der Schmetterling", "button.ogg": "der Knopf", "cabbage.ogg": "der Kohl", "cabin.ogg": "die Hütte", "cacao.ogg": "der Kakao", "cactus.ogg": "der Kaktus", "cage.ogg": "der Käfig", "cake.ogg": "die Torte", "call.ogg": "anrufen", "camel.ogg": "das Kamel", "camera.ogg": "der Fotoapparat", "camp.ogg": "zelten", "can.ogg": "die Dose", "canary.ogg": "der Kanarienvogel", "candle.ogg": "die Kerze", "candy.ogg": "das Bonbon", "cane.ogg": "der Stock", "canoe.ogg": "das Kanu", "canon.ogg": "die Kanone", "canyon.ogg": "der Canyon", "cap.ogg": "die Mütze", "cape.ogg": "der Umhang", "car.ogg": "das Auto", "carafe.ogg": "die Karaffe", "card.ogg": "die Karte", "carnival.ogg": "der Karneval", "carpenter.ogg": "der Zimmermann", "carpet.ogg": "der Teppich", "carrot.ogg": "die Karotte", "cart.ogg": "der Einkaufswagen", "cash.ogg": "das Geld", "castle.ogg": "das Schloß", "cat.ogg": "der Kater", "cat_female.ogg": "die Katze", "catch.ogg": "fangen", "caterpillar.ogg": "die Raupe", "cauldron.ogg": "der Kessel", "cauliflower.ogg": "der Blumenkohl", "cavern.ogg": "die Höhle", "celery.ogg": "der Sellerie", "centipede.ogg": "der Tausendfüßler", "cereal.ogg": "das Getreide", "chain.ogg": "die Kette", "chair.ogg": "der Stuhl", "chalk.ogg": "die Kreide", "chameleon.ogg": "das Chamäleon", "chandelier.ogg": "der Kronleuchter", "chat.ogg": "paludern", "cheek.ogg": "die Wange", "cheer.ogg": "jubeln", "cheese.ogg": "der Käse", "chef.ogg": "die Köchin", "cherry.ogg": "die Kirsche", "chest.ogg": "die Truhe", "chick.ogg": "das Küken", "chicken.ogg": "das Huhn", "chief.ogg": "der Indianer", "child.ogg": "das Kind", "chimney.ogg": "der Schornstein", "chimp.ogg": "der Schimpanse", "chin.ogg": "das Kinn", "chocolate.ogg": "die Schokolade", "chop.ogg": "zerschneiden", "chores.ogg": "die Hausarbeit", "christmas.ogg": "das Weihnachten", "cigar.ogg": "die Zigarre", "circus.ogg": "der Zirkus", "city.ogg": "die Stadt", "clam.ogg": "die Muschel", "clap.ogg": "klatschen", "class.ogg": "die Klasse", "claw.ogg": "die Tatze", "clay.ogg": "der Ton", "clean.ogg": "sich waschen", "cleaning_lady.ogg": "die Putzfrau", "cliff.ogg": "das Kliff", "climb.ogg": "klettern", "clock.ogg": "der Wecker", "cloth.ogg": "der Stoff", "clothes_hanger.ogg": "der Kleiderbügel", "cloud.ogg": "die Wolke", "cloudy.ogg": "wolkig", "clover.ogg": "der Klee", "cowboy.ogg": "der Cowboy", "clown.ogg": "der Clown", "coach.ogg": "die Trainerin", "coast.ogg": "die Küste", "coat.ogg": "der Mantel", "cobra.ogg": "die Kobra", "coconut.ogg": "die Kokosnuss", "cod.ogg": "der Dorsch", "coffee.ogg": "der Kaffee", "coin.ogg": "das Geldstück", "cold.ogg": "die Kälte", "color.ogg": "bunt", "colt.ogg": "das Fohlen", "comb.ogg": "der Kamm", "cone.ogg": "der Kegel", "cookie.ogg": "der Keks", "cork.ogg": "der Korken", "corn.ogg": "der Mais", "couch.ogg": "das Sofa", "cough.ogg": "husten", "couple.ogg": "das Paar", "cow.ogg": "die Kuh", "crab.ogg": "der Krebs", "cradle.ogg": "die Wiege", "craft.ogg": "das Handwerk", "crawl.ogg": "krabbeln", "crazy.ogg": "verrückt", "creek.ogg": "der Bach", "crepe.ogg": "der Pfannkuchen", "crib.ogg": "das Kinderbett", "criminal.ogg": "der Verbrecher", "croak.ogg": "quaken", "crocodile.ogg": "das Krokodil", "cross.ogg": "das Kreuz", "crow.ogg": "die Krähe", "crown.ogg": "die Krone", "crumb.ogg": "der Krümel", "crust.ogg": "die Kruste", "cry.ogg": "weinen", "crystal.ogg": "der Kristall", "cube.ogg": "der Würfel", "cucumber.ogg": "die Gurke", "curtain.ogg": "der Vorhang", "cut.ogg": "schneiden", "cute.ogg": "reizend", "dad.ogg": "der Vater", "daffodil.ogg": "die Osterglocke", "daisy.ogg": "die Margerite", "dam.ogg": "der Staudamm ", "dance.ogg": "tanzen", "dandelion.ogg": "der Löwenzahn", "danger.ogg": "die Gefahr", "dart_board.ogg": "die Zielscheibe", "date_fruit.ogg": "die Dattel", "deer.ogg": "der Hirsch", "den.ogg": "der Bau", "desert.ogg": "die Wüste", "desk.ogg": "der Schreibtisch", "dessert.ogg": "der Nachtisch", "diamond.ogg": "der Diamant", "dig.ogg": "graben", "dirt.ogg": "der Schmutz", "dirty.ogg": "schmutzig", "dish.ogg": "das Gericht", "dishcloth.ogg": "der Spüllappen", "dive.ogg": "tauchen", "doctor.ogg": "die Ärztin", "doe.ogg": "die Hirschkuh", "dog.ogg": "der Hund", "doll.ogg": "die Puppe", "dolphin.ogg": "der Delphin", "domino.ogg": "der Domino", "door.ogg": "die Tür", "doormat.ogg": "die Fußmatte", "dot.ogg": "der Punkt", "doughnut.ogg": "der Donut", "dove.ogg": "die Taube", "dragon.ogg": "der Drache", "dragonfly.ogg": "die Libelle", "drank.ogg": "trinken", "draw.ogg": "die Zeichnung", "drawer.ogg": "die Schublade", "dream.ogg": "träumen", "dress.ogg": "das Kleid", "drink.ogg": "das Getränk", "drinking.ogg": "trinken", "drip.ogg": "der Tropfen", "drive.ogg": "fahren", "drool.ogg": "sabbern", "drum.ogg": "die Trommel", "dry.ogg": "trocknen", "duck.ogg": "der Erpel", "duck_mother.ogg": "die Ente", "dune.ogg": "die Düne", "dwarf.ogg": "der Zwerg", "eagle.ogg": "der Adler", "ear.ogg": "das Ohr", "earth.ogg": "die Erde", "eat.ogg": "essen", "egg.ogg": "das Ei", "eggplant.ogg": "die Aubergine", "elbow.ogg": "der Ellbogen", "electrician.ogg": "der Elektriker", - "eleven.ogg": "elf", "elk.ogg": "der Elch", "empty.ogg": "leer", "engine.ogg": "der Motor", "engineer.ogg": "der Ingenieur", "eraser.ogg": "der Radiergummi", "explore.ogg": "die Erforscher", "eyelash.ogg": "die Wimper", "eyes.ogg": "die Augen", "face.ogg": "das Gesicht", "fair.ogg": "die Kirmes", "fairy.ogg": "die Fee", "fall_down.ogg": "fallen", "fall_season.ogg": "der Herbst", "family.ogg": "die Familie", "fan.ogg": "der Ventilator", "farm.ogg": "der Bauernhof", "farmer.ogg": "der Bauer", "fat.ogg": "dick", "faucet.ogg": "der Wasserhahn", "fawn.ogg": "das Rehkitz", "feast.ogg": "das Hähnchen", "feather.ogg": "die Feder", "feed.ogg": "füttern", "feet.ogg": "Füße", "fell.ogg": "fallen", "femur.ogg": "der Oberschenkelknochen", "fetch.ogg": "bringen", "fig.ogg": "die Feige", "fin.ogg": "die Flosse", "find.ogg": "finden", "finger.ogg": "der Finger", "fire.ogg": "das Feuer", "fire_extinguisher.ogg": "der Feuerlöscher", "fireman.ogg": "der Feuerwehrmann", "fish.ogg": "der Fisch", "fisherman.ogg": "der Fischer", "fist.ogg": "die Faust", "flacon.ogg": "der Flakon", "flag.ogg": "die Flagge", "flame.ogg": "die Flamme", "flamingo.ogg": "der Flamingo", "flash.ogg": "die Taschenlampe", "flat.ogg": "die Wohnungen", "flies.ogg": "die Fliege", "flight.ogg": "der Flug", "float.ogg": "treiben", "flour.ogg": "das Mehl", "flower.ogg": "die Blume", "fluff.ogg": "die Fluse", "flute.ogg": "die Flöte", "fly.ogg": "fliegen", "foam.ogg": "der Schaum", "food.ogg": "der Hamburger", "foot.ogg": "der Fuß", "forest.ogg": "der Wald", "fork.ogg": "die Gabel", "fountain.ogg": "der Brunnen", "fox.ogg": "der Fuchs", "freeze.ogg": "friehren", "friend.ogg": "der Freund", "fries.ogg": "die Pommes Frites", "frog.ogg": "der Frosch", "front.ogg": "davor", "frown.ogg": "murren", "fruit.ogg": "die Früchte", "fudge.ogg": "das Sahnebonbon", "full.ogg": "voll", "fun.ogg": "der Spaß", "fur.ogg": "der Pelz", "game.ogg": "die Freude", "garage.ogg": "die Garage", "garden.ogg": "der Garten", "garlic.ogg": "der Knoblauch", "gem.ogg": "der Edelstein", "giant.ogg": "riesig", "gift.ogg": "das Geschenk", "giraffe.ogg": "die Giraffe", "girl.ogg": "das Mädchen", "glass.ogg": "das Glas", "glasses.ogg": "die Brille", "glove.ogg": "die Handschuhe", "glue.ogg": "der Kleber", "gnome.ogg": "der Gnom", "goat.ogg": "die Ziege", "golden.ogg": "golden", "golf.ogg": "das Golf", "goose.ogg": "die Gans", "gorilla.ogg": "der Gorilla", "grain.ogg": "das Getreide", "grandmother.ogg": "die Großmutter", "grape.ogg": "die Traube", "grapefruit.ogg": "die Pampelmuse", "grass.ogg": "das Gras", "grave.ogg": "das Grab", "gray.ogg": "grau", "green.ogg": "grün", "grill.ogg": "der Grill", "grin.ogg": "lächeln", "ground.ogg": "die Erde", "growl.ogg": "knurren", "guignol.ogg": "der Kasper", "guinea_pig.ogg": "das Meerschweinchen", "gum.ogg": "der Kaugummi", "hair.ogg": "die Haare", "hair_dryer.ogg": "der Föhn", "half.ogg": "halb", "ham.ogg": "der Schinken", "hammer.ogg": "der Hammer", "hand.ogg": "die Hand", "handlebar.ogg": "der Lenker", "happy.ogg": "glücklich", "harp.ogg": "die Harfe", "hat.ogg": "der Hut", "hatch.ogg": "ausschlüpfen", "hay.ogg": "das Heu", "head.ogg": "der Kopf", "hear.ogg": "hören", "heat.ogg": "die Hitze ", "hedge.ogg": "die Hecke", "hedgehog.ogg": "der Igel", "heel.ogg": "der Absatz", "helmet.ogg": "der Helm", "hen.ogg": "die Henne", "herd.ogg": "die Herde", "high.ogg": "hoch", "hike.ogg": "wandern", "hill.ogg": "der Hügel", "hip.ogg": "die Hüfte", "hippopotamus.ogg": "das Nilpferd", "hit.ogg": "schlagen", "hive.ogg": "der Bienenstock", "hockey.ogg": "das Eishockey", "hole.ogg": "das Loch", "home.ogg": "das Zuhause", "hook.ogg": "der Angelhaken", "horse.ogg": "das Pferd", "hose.ogg": "der Schlauch", "hospital.ogg": "das Krankenhaus", "hot.ogg": "heiß", "hot_dog.ogg": "der Hotdog", "hound.ogg": "der Jagdhund", "house.ogg": "das Haus", "howl.ogg": "heulen", "huge.ogg": "riesig", "hummingbird.ogg": "der Kolibri", "hunchback.ogg": "der Buckel", "hunter.ogg": "der Jäger", "husband.ogg": "der Ehemann", "hut.ogg": "die Hütte", "hyena.ogg": "die Hyäne", "ice.ogg": "der Eiswürfel", "iceberg.ogg": "der Eisberg", "iguana.ogg": "der Leguan", "ill.ogg": "krank", "ink.ogg": "die Tinte", "island.ogg": "die Insel", "jacket.ogg": "das Jackett", "jaguar.ogg": "der Jaguar", "jam.ogg": "die Marmelade", "jay.ogg": "der Eichelhäher", "jelly.ogg": "das Gelee", "jellyfish.ogg": "die Qualle", "jewel.ogg": "das Juwel", "job.ogg": "die Arbeit", "jockey.ogg": "der Jockey", "jog.ogg": "das Jogging", "judge.ogg": "der Richter", "judo.ogg": "das Judo", "juggler.ogg": "Jongleur", "juice.ogg": "der Saft", "jump.ogg": "springen", "kangaroo.ogg": "das Känguru", "keel.ogg": "der Kegel", "kernel.ogg": "der Kern", "keyboard.ogg": "die Tastatur", "kimono.ogg": "der Kimono", "king.ogg": "der König", "kiss.ogg": "küssen", "kitchen.ogg": "die Küche", "kite.ogg": "der Drachen", "kitten.ogg": "das Kätzchen", "kiwi.ogg": "die Kiwi", "knee.ogg": "das Knie", "kneel.ogg": "sich hinknien", "knife.ogg": "das Messer", "knight.ogg": "der Ritter", "knit.ogg": "stricken", "knot.ogg": "der Knoten", "koala.ogg": "der Koala", "lady.ogg": "die Dame", "ladybug.ogg": "der Marienkäfer", "lake.ogg": "der See", "lama.ogg": "das Lama", "lamb.ogg": "das Lamm", "lamp.ogg": "die Lampe", "lane.ogg": "die Fahrbahn", "lap.ogg": "der Schoß", "land.ogg": "das Gelände", "lasso.ogg": "das Lasso", "laugh.ogg": "lachen", "lava.ogg": "die Lava", "lawn.ogg": "der Rasen", "lawyer.ogg": "der Rechtsanwalt", "leaf.ogg": "das Blatt", "ledge.ogg": "der Felsvorsprung", "leek.ogg": "der Lauch", "left.ogg": "links", "leg.ogg": "das Bein", "leg_animal.ogg": "das Käferbein", "lemon.ogg": "die Zitrone", "lemonade.ogg": "die Limonade", "lemur.ogg": "der Lemur", "leopard.ogg": "der Leopard", "lettuce.ogg": "der Blattsalat", "librarian.ogg": "die Bibliothekarin", "lick.ogg": "ablecken", "lid.ogg": "der Deckel", "lift.ogg": "hochheben", "light.ogg": "das Licht", "lighthouse.ogg": "der Leuchtturm", "lightning.ogg": "der Blitz", "lilac.ogg": "der Flieder", "lime.ogg": "die Limone", "line.ogg": "der Strich", "link.ogg": "das Kettenglied", "lion.ogg": "der Löwe", "lion_cub.ogg": "das Löwenjunge", "lip.ogg": "die Lippe", "liquid.ogg": "flüssig", "lizard.ogg": "die Eidechse", "lobster.ogg": "der Hummer", "log.ogg": "das Holzscheit", "look.ogg": "das Aussehen", "lunch.ogg": "der Imbiß", "mad.ogg": "der Zorn", "magic.ogg": "magisch", "magnet.ogg": "der Magnet", "magnifying_glass.ogg": "die Lupe", "magpie.ogg": "die Elster", "mail.ogg": "der Briefumschlag", "man.ogg": "der Mann", "mane.ogg": "die Mähne", "mango.ogg": "die Mango", "map.ogg": "die Landkarte", "maple.ogg": "der Ahorn", "marble.ogg": "die Murmel", "mashed_potatoes.ogg": "der Kartoffelbrei", "mask.ogg": "die Taucherbrille", "mast.ogg": "der Mast", "mat.ogg": "die Matte", "match.ogg": "die Streichhölzer", "mate_male.ogg": "der Freund", "mate_female.ogg": "die Freundin", "mattress.ogg": "die Matratze", "mauve.ogg": "lila", "meal.ogg": "die Mahlzeit", "meat.ogg": "das Fleisch", "mechanic.ogg": "der Mechaniker", "medal.ogg": "die Medaille", "meet.ogg": "treffen", "melon.ogg": "die Melone", "men.ogg": "die Menschenmenge", "merry-go-round.ogg": "das Karussell", "mice.ogg": "die Mäuse", "microphone.ogg": "das Mikrophon", "milk.ogg": "die Milch", "mill.ogg": "die Windmühle", "mimosa.ogg": "die Mimose", "mirror.ogg": "der Spiegel", "mixer.ogg": "der Mixer", "mole.ogg": "der Maulwurf", "mom.ogg": "die Mama", "moon.ogg": "der Mond", "moose.ogg": "der Elch", "mop.ogg": "der Mopp", "mosque.ogg": "die Moschee", "mosquito.ogg": "die Mücke", "mother.ogg": "die Mutter", "motorcycle.ogg": "das Motorrad", "mountain.ogg": "der Berg", "mouse.ogg": "die Maus", "mouth.ogg": "der Mund", "movie.ogg": "der Film", "mower.ogg": "der Rasenmäher", "mud.ogg": "der Schlamm", "mug.ogg": "die Tasse", "mule.ogg": "der Esel", "muscle.ogg": "der Muskel", "mushroom.ogg": "der Fliegenpilz", "music.ogg": "die Musik", "musician.ogg": "der Musiker", "naked.ogg": "nackt", "nap.ogg": "schlummern", "navel.ogg": "der Bauchnabel", "neck.ogg": "der Nacken", "necklace.ogg": "die Halskette", "needle.ogg": "die Nadel", "nest.ogg": "das Nest", "net.ogg": "der Kescher", "newspaper.ogg": "die Zeitung", "night.ogg": "die Nacht", "nightgown.ogg": "das Nachthemd", "nose.ogg": "die Nase", "nostril.ogg": "das Nasenloch", "notebook.ogg": "das Notizbuch", "number.ogg": "die Zahl", "nun.ogg": "die Nonne", "nurse.ogg": "die Krankenschwester", "nurse_male.ogg": "der Krankenpfleger", "nut.ogg": "die Erdnuß", "oar.ogg": "das Ruder", "ocean.ogg": "der Ozean", "office.ogg": "das Büro", "olive.ogg": "die Olive", "on.ogg": "darauf", "onion.ogg": "die Zwiebel", "open.ogg": "offen", "opossum.ogg": "das Opossum", "orange-color.ogg": "orange", "orange.ogg": "die Orange", "orchid.ogg": "die Orchidee", "ostrich.ogg": "der Strauß", "otter.ogg": "der Otter", "owl.ogg": "die Eule", "ox.ogg": "der Ochse", "oyster.ogg": "die Auster", "pacifier.ogg": "der Schnuller", "page.ogg": "die Seite", "pair.ogg": "das Paar", "pajamas.ogg": "der Pyjama", "palm_tree.ogg": "die Palme", "pan.ogg": "die Pfanne", "panda.ogg": "der Panda", "panther.ogg": "der Panther", "panties.ogg": "die Unterhose", "pants.ogg": "die Hose", "papaya.ogg": "die Papaya", "paper.ogg": "das Papier", "parachute.ogg": "der Fallschirm", "parakeet.ogg": "der Sittich", "parrot.ogg": "der Papagei", "patch.ogg": "der Flicken", "path.ogg": "der Weg", "paw.ogg": "die Pfote", "pea.ogg": "die Erbse", "peach.ogg": "der Pfirsich", "peacock.ogg": "der Pfau", "peak.ogg": "der Gipfel", "pear.ogg": "die Birne", "pearl.ogg": "die Perle", "peck.ogg": "picken", "pedal.ogg": "das Pedal", "pelican.ogg": "der Pelikan", "pen.ogg": "der Füller", "pencil.ogg": "der Bleistift", "peony.ogg": "die Päonie", "people.ogg": "die Leute", "pepper.ogg": "der Pfeffer", "peppers.ogg": "die Peperoni", "petal.ogg": "das Blütenblatt", "petite.ogg": "klein", "phone.ogg": "das Telefon", "piano.ogg": "das Klavier", "picture.ogg": "das Bild", "pie.ogg": "der Kuchen", "pig.ogg": "das Schwein", "pigeon.ogg": "die Taube", "pill.ogg": "die Tablette", "pillow.ogg": "das Kissen", "pilot.ogg": "der Pilot", "pine.ogg": "die Pinie", "pine_cone.ogg": "der Tannenzapfen", "pink.ogg": "rosa", "pip.ogg": "der Kern", "pipe.ogg": "die Pfeife", "piranha.ogg": "der Piranha", "pirate.ogg": "der Pirat", "pizza.ogg": "die Pizza", "plane.ogg": "das Flugzeug", "planet.ogg": "der Planet", "plant.ogg": "die Pflanze", "plate.ogg": "der Teller", "play.ogg": "spielen", "pliers.ogg": "die Zange", "plum.ogg": "die Pflaume", "plow.ogg": "pflügen", "plumber.ogg": "der Klempner", "pocket.ogg": "die Hosentasche", "pod.ogg": "die Schote", "pole.ogg": "der Pfosten", "police.ogg": "der Polizist", "pompon.ogg": "der Pompon", "pond.ogg": "der Teich", "pony.ogg": "das Ponny", "pool.ogg": "das Schwimmbad", "pop.ogg": "das Popcorn", "pope.ogg": "der Papst", "porthole.ogg": "das Bullauge", "post.ogg": "der Briefkasten", "pot.ogg": "der Topf", "potato.ogg": "die Kartoffel", "pounce.ogg": "anspringen", "president.ogg": "der Präsident", "pretty.ogg": "schön", "price.ogg": "der Preis", "priest.ogg": "der Pfarrer", "prince.ogg": "der Prinz", "princess.ogg": "die Prinzession", "prison.ogg": "das Gefängnis", "prisoner.ogg": "der Häftling", "prize.ogg": "der Pokal", "pug.ogg": "der Mops", "pull.ogg": "ziehen", "pullover.ogg": "der Pullover", "pumpkin.ogg": "der Kürbis", "puppy.ogg": "der Welpe", "pyramid.ogg": "die Pyramide", "quarrel.ogg": "sich streiten", "queen.ogg": "die Königin", "question.ogg": "die Frage", "quilt.ogg": "die Steppdecke", "quiz.ogg": "das Quiz", "rabbit.ogg": "das Kaninchen", "rabbit_baby.ogg": "das Kaninchenjunge", "race.ogg": "das Wettrennen", "radio.ogg": "das Radio", "radish.ogg": "der Rettich", "raft.ogg": "das Floß", "rag.ogg": "der Lappen", "rage.ogg": "die Wut", "rain.ogg": "der Regen", "raincoat.ogg": "der Regenmantel", "rake.ogg": "die Harke", "ramp.ogg": "die Rampe", "raspberry.ogg": "die Himbeere", "rat.ogg": "die Ratte", "razor.ogg": "der Rasierer", "read.ogg": "lesen", "red.ogg": "rot", "reptile.ogg": "das Reptil", "rhinoceros.ogg": "das Nashorn", "rice.ogg": "der Reis", "ride.ogg": "Fahrrad fahren", "rifle.ogg": "das Gewehr", "right.ogg": "rechts", "rip.ogg": "das Grab", "rise.ogg": "ansteigen", "river.ogg": "der Fluß", "road.ogg": "die Straße", "roast.ogg": "der Braten", "robe.ogg": "die Robe", "robot.ogg": "der Roboter", "rock.ogg": "der Stein", "rocket.ogg": "die Rakete", "rolling_pin.ogg": "das Nudelholz", "roof.ogg": "das Dach", "room.ogg": "das Zimmer", "root.ogg": "die Wurzel", "rope.ogg": "das Seil", "rose.ogg": "die Rose", "round.ogg": "rund", "rowing.ogg": "das Rudern", "royal.ogg": "königlich", "rug.ogg": "der Vorleger", "run.ogg": "rennen", "sad.ogg": "traurig", "saddle.ogg": "der Sattel", "sail.ogg": "das Segelboot", "sailor.ogg": "der Matrose", "salamander.ogg": "der Salamander", "salmon.ogg": "der Lachs", "sand.ogg": "der Sand", "sandals.ogg": "die Sandalen", "sandwich.ogg": "das Sandwich", "sash.ogg": "die Schärpe", "sat.ogg": "sich hinsetzen", "sauce.ogg": "die Sauce", "sausage.ogg": "die Wurst", "scale.ogg": "die Waage", "scar.ogg": "die Narbe", "scared.ogg": "erschrecken", "scarf.ogg": "der Schal", "school.ogg": "die Schule", "school_bag.ogg": "die Schultasche", "science.ogg": "die Wissenschaft", "scissors.ogg": "die Schere", "scorpion.ogg": "der Skorpion", "scratch.ogg": "kratzen", "scream.ogg": "schreien", "screw.ogg": "die Schraube", "screwdriver.ogg": "der Schraubenzieher", "scribble.ogg": "kritzeln", "sea.ogg": "das Meer", "seat.ogg": "der Stuhl", "see.ogg": "sehen", "seed.ogg": "der Samen", "shadow.ogg": "der Schatten", "shake.ogg": "schütteln", "shark.ogg": "der Hai", "shave.ogg": "scheren", "shed.ogg": "der Schuppen", "sheep.ogg": "das Schaf", "shelf.ogg": "das Regal", "shell.ogg": "die Muschel", "ship.ogg": "das Schiff", "shirt.ogg": "das Hemd", "shoe.ogg": "der Schuh", "shoelace.ogg": "der Schnürsenkel", "shop.ogg": "der Laden", "shore.ogg": "das Ufer", "short.ogg": "die Shorts", "shovel.ogg": "die Schippe", "shower.ogg": "die Dusche", "shrimp.ogg": "die Garnele", "shrub.ogg": "der Strauch", "shut.ogg": "geschlossen", "shutter.ogg": "der Fensterladen", "sick.ogg": "krank", "sidewalk.ogg": "der Gehweg", "sign.ogg": "das Schild", "sing.ogg": "singen", "sink.ogg": "die Spüle", "sip.ogg": "nippen", "sister.ogg": "die Schwester", "sit.ogg": "sich hinsetzen", - "sixteen.ogg": "sechzehn", "skate.ogg": "das Skateboardfahren", "skeleton.ogg": "das Skelett", "ski.ogg": "das Skifahren", "skimmer.ogg": "der Schaumlöffel", "skin.ogg": "die Haut", "skirt.ogg": "der Rock", "skunk.ogg": "das Stinktier", "sky.ogg": "der Himmel", "sled.ogg": "der Schlitten", "sleep.ogg": "schlafen", "sleeve.ogg": "der Ärmel", "sleigh.ogg": "der Pferdeschlitten", "slide.ogg": "die Rutsche", "slim.ogg": "schlank", "slime.ogg": "der Schleim", "slippers.ogg": "der Hausschuh", "slope.ogg": "der Abhang", "sloppy.ogg": "durchnäßt", "slot.ogg": "der Schlitz", "sloth.ogg": "das Faultier", "slug.ogg": "die Nacktschnecke", "small.ogg": "klein", "smell.ogg": "riechen", "smile.ogg": "lächeln", "smock.ogg": "der Kittel", "smoke.ogg": "der Rauch", "smooch.ogg": "küssen", "snack.ogg": "der Imbiss", "snail.ogg": "die Schnecke", "snake.ogg": "die Schlange", "sneaker.ogg": "der Turnschuh", "sniff.ogg": "schnüffeln", "snow.ogg": "der Schnee", "soap.ogg": "die Seife", "sob.ogg": "schluchzen", "sock.ogg": "die Socke", "soldier.ogg": "die Soldatin", "sole.ogg": "die Seezunge", "sole_shoe.ogg": "die Schuhsohle", "son.ogg": "der Sohn", "soup.ogg": "die Suppe", "spade.ogg": "der Spaten", "spaghetti.ogg": "die Spaghetti", "spark.ogg": "der Funke", "sparrow.ogg": "der Spatz", "spatula.ogg": "der Pfannenwender", "speak.ogg": "sprechen", "spear.ogg": "der Speer", "spice.ogg": "das Gewürz", "spider.ogg": "die Spinne", "spider_web.ogg": "das Spinnennetz", "spike.ogg": "der Stachel", "spill.ogg": "ausschütten", "spinach.ogg": "der Spinat", "spine.ogg": "die Wirbelsäule", "spinning_top.ogg": "der Kreisel", "splash.ogg": "spritzen", "splatter.ogg": "der Spritzer", "sponge.ogg": "der Schwamm", "spool.ogg": "die Spule", "spoon.ogg": "der Löffel", "sport.ogg": "der Sport", "spot.ogg": "fleckig", "spray.ogg": "sprühen", "spread.ogg": "verteilen", "spring.ogg": "federn", "spring_season.ogg": "der Frühling", "sprinkle.ogg": "der Streusel", "square.ogg": "das Quadrat", "squash.ogg": "der Kürbis", "squat.ogg": "die Hocke", "squid.ogg": "der Tintenfisch", "squirrel.ogg": "das Eichhörnchen", "stack.ogg": "der Stapel", "stage.ogg": "die Bühne", "staircase.ogg": "die Treppe", "stamp.ogg": "die Briefmarke", "stand.ogg": "stehend", "star.ogg": "der Stern", "stare.ogg": "der Blick", "starfish.ogg": "der Seestern", "steak.ogg": "das Steak", "steam.ogg": "der Dampf", "steep.ogg": "steil", "steeple.ogg": "der Kirchturm", "stem.ogg": "der Stiel", "step.ogg": "die Stufe", "stew.ogg": "der Eintopf", "stick.ogg": "der Ast", "sting.ogg": "stechen", "stinky.ogg": "stinkend", "stitch.ogg": "nähen", "stomach.ogg": "der Magen", "stone.ogg": "der Stein", "stop.ogg": "anhalten", "store.ogg": "das Geschäft", "stove.ogg": "der Herd", "straight.ogg": "gerade", "strainer.ogg": "das Sieb", "straw.ogg": "der Strohhalm", "strawberry.ogg": "die Erdbeere", "stream.ogg": "der Strom", "street.ogg": "die Straße", "stretch.ogg": "sich strecken", "string.ogg": "die Schnur", "stripe.ogg": "gestreift", "strong.ogg": "stark", "student.ogg": "der Student", "study.ogg": "lernen", "stump.ogg": "der Baumstumpf", "sugar.ogg": "der Zucker", "suit.ogg": "der Anzug", "suitcase.ogg": "der Koffer", "summer.ogg": "der Sommer", "summit.ogg": "der Gipfel", "sun.ogg": "die Sonne", "swan.ogg": "der Schwan", "sweat.ogg": "schwitzen", "sweatshirt.ogg": "das Sweatshirt", "swim.ogg": "schwimmen", "table.ogg": "der Tisch", "tablecloth.ogg": "die Tischdecke", "tadpole.ogg": "die Kaulquappe", "tag.ogg": "das Etikett", "tail.ogg": "der Schwanz", "tall.ogg": "groß", "tape_measure.ogg": "das Metermaß", "taxi.ogg": "das Taxi", "teach.ogg": "unterrichten", "teacher.ogg": "die Lehrerin", "tear.ogg": "zerreißen", "teddy.ogg": "der Teddybär", "teeth.ogg": "die Zähne", "television.ogg": "das Fernsehen", "temple.ogg": "der Tempel", "tennis.ogg": "das Tennis", "tent.ogg": "das Zelt", "text.ogg": "der Text", "thick.ogg": "dick", "thief.ogg": "der Dieb", "thigh.ogg": "der Oberschenkel", "think.ogg": "denken", "thread.ogg": "die Spule", "throat.ogg": "der Rachen", "throw.ogg": "werfen", "thumb.ogg": "der Daumen", "ticket.ogg": "die Eintrittskarte", "tiger.ogg": "der Tiger", "time.ogg": "die Zeit", "tin.ogg": "die Dose", "tire.ogg": "der Reifen", "tired.ogg": "müde", "tissue.ogg": "das Papiertaschentuch", "toad.ogg": "die Kröte", "toaster.ogg": "der Toaster", "toe.ogg": "der Zeh", "toilet.ogg": "die Toilette", "tomatoe.ogg": "die Tomate", "tongs.ogg": "die Zange", "tongue.ogg": "die Zunge", "tool.ogg": "das Werkzeug", "top.ogg": "darauf", "torch.ogg": "die Fackel", "touch.ogg": "berühren", "towel.ogg": "das Handtuch", "toy.ogg": "das Spielzeug", "trail.ogg": "der Pfad", "train.ogg": "der Zug", "train_station.ogg": "der Bahnhof", "trap.ogg": "die Falle", "trash.ogg": "der Schmutz", "tray.ogg": "das Tablett", "treat.ogg": "die Süßigkeit", "tree.ogg": "der Baum", "triangle.ogg": "dreieckig", "tribe.ogg": "der Stamm", "trip.ogg": "die Reise", "truck.ogg": "der Lastwagen", "tube.ogg": "der Lippenstift", "tulip.ogg": "die Tulpe", "tune.ogg": "die Melodie", "turkey.ogg": "der Truthahn", "turnip.ogg": "die Rübe", "turtle.ogg": "die Schildkröte", "tusk.ogg": "der Stoßzahn", - "twelve.ogg": "zwölf", "twin_boys.ogg": "der Zwillingsbruder", "twin_girls.ogg": "die Zwillingsschwester", "umbrella.ogg": "der Regenschirm", "under.ogg": "darunter", "uniform.ogg": "die Uniform", "van.ogg": "der Kleinbus", "vase.ogg": "die Vase", "vegetable.ogg": "das Gemüse", "vein.ogg": "die Ader", "verdure.ogg": "das Grün", "vest.ogg": "die Veste", "vet.ogg": "der Tierarzt", "viper.ogg": "die Viper", "vowel.ogg": "der Vokal", "vulture.ogg": "der Geier", "wag.ogg": "schwänzeln", "walk.ogg": "gehen", "wall.ogg": "die Mauer", "walnut.ogg": "die Walnuß", "wart.ogg": "die Warze", "wash.ogg": "baden", "wasp.ogg": "die Wespe", "watch.ogg": "die Armbanduhr", "water.ogg": "das Wasser", "wave.ogg": "die Welle", "wedding.ogg": "die Hochzeit", "wedge.ogg": "der Keil", "weight.ogg": "das Gewicht", "wet.ogg": "naß", "whale.ogg": "der Wal", "wheat.ogg": "der Weizen", "wheel.ogg": "das Rad", "whisk.ogg": "der Schneebesen", "whisper.ogg": "flüstern", "white.ogg": "weiß", "wide.ogg": "breit", "wife.ogg": "die Ehefrau", "wig.ogg": "die Perücke", "win.ogg": "gewinnen", "wind.ogg": "der Wind", "window.ogg": "das Fenster", "window_glass.ogg": "die Fensterscheibe", "wing.ogg": "der Flügel", "winter.ogg": "der Winter", "wolf.ogg": "der Wolf", "woman.ogg": "die Frau", "wood.ogg": "das Holz", "word.ogg": "das Wort", "worker.ogg": "der Arbeiter", "world.ogg": "die Welt", "wreath.ogg": "der Kranz", "wrench.ogg": "der Schraubenschlüssel", "wrist.ogg": "das Handgelenk", "write.ogg": "schreiben", "yellow.ogg": "gelb", "yogurt.ogg": "der Joghurt", "yum.ogg": "lecker", "zebra.ogg": "das Zebra", "zipper.ogg": "der Reißverschluß", "zoo.ogg": "der Zoo", - "one.ogg": "eins", - "two.ogg": "zwei", - "three.ogg": "drei", - "four.ogg": "vier", - "five.ogg": "fünf", - "six.ogg": "sechs", - "seven.ogg": "sieben", - "eight.ogg": "acht", - "nine.ogg": "neun", - "ten.ogg": "zehn", "U0030.ogg": "null", "U0031.ogg": "eins", "U0032.ogg": "zwei", "U0033.ogg": "drei", "U0034.ogg": "vier", "U0035.ogg": "fünf", "U0036.ogg": "sechs", "U0037.ogg": "sieben", "U0038.ogg": "acht", - "U0039.ogg": "neun" + "U0039.ogg": "neun", + "10.ogg": "zehn", + "11.ogg": "elf", + "12.ogg": "zwölf", + "16.ogg": "sechzehn" } diff --git a/src/activities/imageid/resource/content-en.json b/src/activities/imageid/resource/content-en.json index c0074c86c..69177d707 100644 --- a/src/activities/imageid/resource/content-en.json +++ b/src/activities/imageid/resource/content-en.json @@ -1,582 +1,580 @@ { "ate.ogg": "ate", "bake.ogg": "bake", "bark.ogg": "bark", "beg.ogg": "beg", "bite.ogg": "bite", "blink.ogg": "blink", "boil.ogg": "boil", "break.ogg": "break", "call.ogg": "call", "catch.ogg": "catch", "centipede.ogg": "centipede", "chat.ogg": "chat", "chop.ogg": "chop", "clap.ogg": "clap", "clean.ogg": "clean", "crawl.ogg": "crawl", "croak.ogg": "croak", "cry.ogg": "cry", "cut.ogg": "cut", "dig.ogg": "dig", "drank.ogg": "drank", "draw.ogg": "draw", "dream.ogg": "dream", "drive.ogg": "drive", "drool.ogg": "drool", "dry.ogg": "dry", "eat.ogg": "eat", "fell.ogg": "fell", "fetch.ogg": "fetch", "find.ogg": "find", "float.ogg": "float", "fly.ogg": "fly", "freeze.ogg": "freeze", "growl.ogg": "growl", "hatch.ogg": "hatch", "hear.ogg": "hear", "howl.ogg": "howl", "hug.ogg": "hug", "jump.ogg": "jump", "kneel.ogg": "kneel", "knit.ogg": "knit", "lick.ogg": "lick", "look.ogg": "look", "meet.ogg": "meet", "nap.ogg": "nap", "peck.ogg": "peck", "play.ogg": "play", "plow.ogg": "plow", "pounce.ogg": "pounce", "quarrel.ogg": "quarrel", "read.ogg": "read", "rip.ogg": "rip", "run.ogg": "run", "sat.ogg": "sat", "scared.ogg": "scared", "scratch.ogg": "scratch", "scream.ogg": "scream", "scribble.ogg": "scribble", "see.ogg": "see", "shake.ogg": "shake", "sing.ogg": "sing", "sip.ogg": "sip", "sit.ogg": "sit", "sleep.ogg": "sleep", "smell.ogg": "smell", "smooch.ogg": "smooch", "sniff.ogg": "sniff", "spill.ogg": "spill", "splash.ogg": "splash", "spray.ogg": "spray", "spread.ogg": "spread", "spring.ogg": "spring", "squat.ogg": "squat", "sting.ogg": "sting", "stop.ogg": "stop", "stretch.ogg": "stretch", "study.ogg": "study", "teach.ogg": "teach", "tear.ogg": "tear", "think.ogg": "think", "touch.ogg": "touch", "wag.ogg": "wag", "walk.ogg": "walk", "wash.ogg": "wash", "whisper.ogg": "whisper", "win.ogg": "win", "back.ogg": "back", "braid.ogg": "braid", "brain.ogg": "brain", "bump.ogg": "bump", "chin.ogg": "chin", "ear.ogg": "ear", "face.ogg": "face", "feet.ogg": "feet", "fist.ogg": "fist", "foot.ogg": "foot", "grin.ogg": "grin", "hair.ogg": "hair", "hand.ogg": "hand", "head.ogg": "head", "hip.ogg": "hip", "knee.ogg": "knee", "lap.ogg": "lap", "lip.ogg": "lip", "mouth.ogg": "mouth", "neck.ogg": "neck", "nose.ogg": "nose", "scar.ogg": "scar", "skin.ogg": "skin", "stare.ogg": "stare", "sweat.ogg": "sweat", "teeth.ogg": "teeth", "thigh.ogg": "thigh", "throat.ogg": "throat", "wrist.ogg": "wrist", "bib.ogg": "bib", "cap.ogg": "cap", "cape.ogg": "cape", "coat.ogg": "coat", "dress.ogg": "dress", "glove.ogg": "glove", "hat.ogg": "hat", "patch.ogg": "patch", "scarf.ogg": "scarf", "shirt.ogg": "shirt", "shoe.ogg": "shoe", "short.ogg": "short", "skirt.ogg": "skirt", "sleeve.ogg": "sleeve", "smock.ogg": "smock", "sneaker.ogg": "sneaker", "sock.ogg": "sock", "suit.ogg": "suit", "zoo.ogg": "zoo", "danger.ogg": "danger", "frown.ogg": "frown", "fun.ogg": "fun", "mad.ogg": "mad", "rage.ogg": "rage", "sad.ogg": "sad", "smile.ogg": "smile", "whisk.ogg": "whisk", "chief.ogg": "chief", "clown.ogg": "clown", "coach.ogg": "coach", "cowboy.ogg": "cowboy", "hunter.ogg": "hunter", "judge.ogg": "judge", "knight.ogg": "knight", "lad.ogg": "lad", "pope.ogg": "pope", "prince.ogg": "prince", "princess.ogg": "princess", "queen.ogg": "queen", "teacher.ogg": "teacher", "vet.ogg": "vet", "boy.ogg": "boy", "bride.ogg": "bride", "brother.ogg": "brother", "child.ogg": "child", "dad.ogg": "dad", "friend.ogg": "friend", "girl.ogg": "girl", "gnome.ogg": "gnome", "mate.ogg": "mate", "men.ogg": "men", "pal.ogg": "pal", "athlete.ogg": "athlete", "ballet.ogg": "ballet", "camp.ogg": "camp", "cheer.ogg": "cheer", "climb.ogg": "climb", "dance.ogg": "dance", "dive.ogg": "dive", "explore.ogg": "explore", "hike.ogg": "hike", "hit.ogg": "hit", "hop.ogg": "hop", "jog.ogg": "jog", "lift.ogg": "lift", "ran.ogg": "ran", "ride.ogg": "ride", "skate.ogg": "skate", "ski.ogg": "ski", "sport.ogg": "sport", "swim.ogg": "swim", "write.ogg": "write", "alligator.ogg": "alligator", "animal.ogg": "animal", "bait.ogg": "bait", "bat.ogg": "bat", "bee.ogg": "bee", "beetle.ogg": "beetle", "bird.ogg": "bird", "bug.ogg": "bug", "camel.ogg": "camel", "cat.ogg": "cat", "chick.ogg": "chick", "chicken.ogg": "chicken", "chimp.ogg": "chimp", "clam.ogg": "clam", "claw.ogg": "claw", "cow.ogg": "cow", "crab.ogg": "crab", "crocodile.ogg": "crocodile", "crow.ogg": "crow", "den.ogg": "den", "dog.ogg": "dog", "dragon.ogg": "dragon", "duck.ogg": "duck", "fin.ogg": "fin", "fish.ogg": "fish", "flies.ogg": "flies", "fox.ogg": "fox", "frog.ogg": "frog", "fur.ogg": "fur", "giraffe.ogg": "giraffe", "goat.ogg": "goat", "hen.ogg": "hen", "herd.ogg": "herd", "hound.ogg": "hound", "lamb.ogg": "lamb", "mane.ogg": "mane", "mice.ogg": "mice", "mole.ogg": "mole", "mosquito.ogg": "mosquito", "mule.ogg": "mule", "owl.ogg": "owl", "ox.ogg": "ox", "paw.ogg": "paw", "pet.ogg": "pet", "pig.ogg": "pig", "pug.ogg": "pug", "puppy.ogg": "puppy", "rat.ogg": "rat", "shark.ogg": "shark", "shell.ogg": "shell", "shrimp.ogg": "shrimp", "skunk.ogg": "skunk", "slime.ogg": "slime", "snail.ogg": "snail", "snake.ogg": "snake", "spider.ogg": "spider", "spike.ogg": "spike", "squid.ogg": "squid", "squirrel.ogg": "squirrel", "starfish.ogg": "starfish", "swan.ogg": "swan", "tick.ogg": "tick", "wing.ogg": "wing", "yum.ogg": "yum", "bone.ogg": "bone", "bread.ogg": "bread", "bun.ogg": "bun", "cake.ogg": "cake", "candy.ogg": "candy", "cheese.ogg": "cheese", "chocolate.ogg": "chocolate", "cookie.ogg": "cookie", "crumb.ogg": "crumb", "crust.ogg": "crust", "drink.ogg": "drink", "feast.ogg": "feast", "flour.ogg": "flour", "food.ogg": "food", "fudge.ogg": "fudge", "gum.ogg": "gum", "ice.ogg": "ice", "juice.ogg": "juice", "lunch.ogg": "lunch", "pop.ogg": "pop", "rice.ogg": "rice", "sandwich.ogg": "sandwich", "sauce.ogg": "sauce", "snack.ogg": "snack", "spaghetti.ogg": "spaghetti", "sprinkle.ogg": "sprinkle", "stew.ogg": "stew", "treat.ogg": "treat", "cherry.ogg": "cherry", "fruit.ogg": "fruit", "lime.ogg": "lime", "orange.ogg": "orange", "peach.ogg": "peach", "plum.ogg": "plum", "bay.ogg": "bay", "beach.ogg": "beach", "cave.ogg": "cave", "cliff.ogg": "cliff", "cloud.ogg": "cloud", "cold.ogg": "cold", "dirt.ogg": "dirt", "dune.ogg": "dune", "earth.ogg": "earth", "fire.ogg": "fire", "flame.ogg": "flame", "garden.ogg": "garden", "gem.ogg": "gem", "ground.ogg": "ground", "heat.ogg": "heat", "hole.ogg": "hole", "lake.ogg": "lake", "land.ogg": "land", "ledge.ogg": "ledge", "mud.ogg": "mud", "night.ogg": "night", "ocean.ogg": "ocean", "path.ogg": "path", "rock.ogg": "rock", "sand.ogg": "sand", "shore.ogg": "shore", "sky.ogg": "sky", "slope.ogg": "slope", "smoke.ogg": "smoke", "snow.ogg": "snow", "star.ogg": "star", "stone.ogg": "stone", "stream.ogg": "stream", "summer.ogg": "summer", "sun.ogg": "sun", "time.ogg": "time", "top.ogg": "top", "trail.ogg": "trail", "water.ogg": "water", "wind.ogg": "wind", "yarn.ogg": "yarn", "angel.ogg": "angel", "bit.ogg": "bit", "class.ogg": "class", "price.ogg": "price", "question.ogg": "question", "quiz.ogg": "quiz", "science.ogg": "science", "splatter.ogg": "splatter", "tune.ogg": "tune", "branch.ogg": "branch", "bud.ogg": "bud", "bush.ogg": "bush", "flower.ogg": "flower", "grass.ogg": "grass", "hay.ogg": "hay", "hedge.ogg": "hedge", "lawn.ogg": "lawn", "pine.ogg": "pine", "plant.ogg": "plant", "rose.ogg": "rose", "seed.ogg": "seed", "shrub.ogg": "shrub", "stem.ogg": "stem", "stick.ogg": "stick", "stump.ogg": "stump", "tree.ogg": "tree", "carrot.ogg": "carrot", "corn.ogg": "corn", "cucumber.ogg": "cucumber", "mushroom.ogg": "mushroom", "nut.ogg": "nut", "squash.ogg": "squash", "bank.ogg": "bank", "barn.ogg": "barn", "bridge.ogg": "bridge", "cabin.ogg": "cabin", "cage.ogg": "cage", "castle.ogg": "castle", "door.ogg": "door", "fair.ogg": "fair", "fountain.ogg": "fountain", "grave.ogg": "grave", "home.ogg": "home", "hut.ogg": "hut", "lane.ogg": "lane", "pool.ogg": "pool", "ramp.ogg": "ramp", "roof.ogg": "roof", "school.ogg": "school", "shed.ogg": "shed", "shop.ogg": "shop", "stage.ogg": "stage", "store.ogg": "store", "street.ogg": "street", "strawberry.ogg": "strawberry", "bath.ogg": "bath", "bed.ogg": "bed", "bench.ogg": "bench", "chair.ogg": "chair", "chest.ogg": "chest", "couch.ogg": "couch", "crib.ogg": "crib", "desk.ogg": "desk", "fan.ogg": "fan", "lamp.ogg": "lamp", "light.ogg": "light", "mat.ogg": "mat", "quilt.ogg": "quilt", "rug.ogg": "rug", "seat.ogg": "seat", "shelf.ogg": "shelf", "shower.ogg": "shower", "sink.ogg": "sink", "stove.ogg": "stove", "toilet.ogg": "toilet", "balance.ogg": "balance", "can.ogg": "can", "clock.ogg": "clock", "dish.ogg": "dish", "fork.ogg": "fork", "glass.ogg": "glass", "knife.ogg": "knife", "lid.ogg": "lid", "mop.ogg": "mop", "mug.ogg": "mug", "pan.ogg": "pan", "plate.ogg": "plate", "pot.ogg": "pot", "scale.ogg": "scale", "sponge.ogg": "sponge", "spoon.ogg": "spoon", "trash.ogg": "trash", "tray.ogg": "tray", "farm.ogg": "farm", "anchor.ogg": "anchor", "badge.ogg": "badge", "bag.ogg": "bag", "ball.ogg": "ball", "bead.ogg": "bead", "block.ogg": "block", "board.ogg": "board", "bomb.ogg": "bomb", "book.ogg": "book", "box.ogg": "box", "candle.ogg": "candle", "cane.ogg": "cane", "card.ogg": "card", "cart.ogg": "cart", "cash.ogg": "cash", "chalk.ogg": "chalk", "clay.ogg": "clay", "cloth.ogg": "cloth", "coin.ogg": "coin", "comb.ogg": "comb", "cone.ogg": "cone", "crown.ogg": "crown", "cube.ogg": "cube", "drum.ogg": "drum", "flag.ogg": "flag", "flute.ogg": "flute", "game.ogg": "game", "gift.ogg": "gift", "glue.ogg": "glue", "hook.ogg": "hook", "hose.ogg": "hose", "ink.ogg": "ink", "jewel.ogg": "jewel", "kite.ogg": "kite", "knot.ogg": "knot", "log.ogg": "log", "map.ogg": "map", "mask.ogg": "mask", "match.ogg": "match", "nest.ogg": "nest", "net.ogg": "net", "oar.ogg": "oar", "page.ogg": "page", "pair.ogg": "pair", "pen.ogg": "pen", "pencil.ogg": "pencil", "picture.ogg": "picture", "pole.ogg": "pole", "prize.ogg": "prize", "rag.ogg": "rag", "rope.ogg": "rope", "sign.ogg": "sign", "sleigh.ogg": "sleigh", "slide.ogg": "slide", "squirt.ogg": "squirt", "stack.ogg": "stack", "stamp.ogg": "stamp", "straw.ogg": "straw", "string.ogg": "string", "tag.ogg": "tag", "thread.ogg": "thread", "torch.ogg": "torch", "towel.ogg": "towel", "toy.ogg": "toy", "trap.ogg": "trap", "tube.ogg": "tube", "watch.ogg": "watch", "wheel.ogg": "wheel", "wig.ogg": "wig", "wood.ogg": "wood", "link.ogg": "link", "dirty.ogg": "dirty", "throw.ogg": "throw", "brick.ogg": "brick", "brush.ogg": "brush", "flash.ogg": "flash", "rake.ogg": "rake", "screw.ogg": "screw", "spear.ogg": "spear", "tool.ogg": "tool", "wedge.ogg": "wedge", "wrench.ogg": "wrench", "bike.ogg": "bike", "boat.ogg": "boat", "canoe.ogg": "canoe", "car.ogg": "car", "plane.ogg": "plane", "sail.ogg": "sail", "ship.ogg": "ship", "sled.ogg": "sled", "train.ogg": "train", "truck.ogg": "truck", "black.ogg": "black", "blue.ogg": "blue", "brown.ogg": "brown", "color.ogg": "color", "gray.ogg": "gray", "green.ogg": "green", "orange-color.ogg": "orange", "pink.ogg": "pink", "red.ogg": "red", "white.ogg": "white", - "five.ogg": "five", - "one.ogg": "one", - "ten.ogg": "ten", - "three.ogg": "three", - "two.ogg": "two", "van.ogg": "van", "big.ogg": "big", "blind.ogg": "blind", "blond.ogg": "blond", "bright.ogg": "bright", "crazy.ogg": "crazy", "cute.ogg": "cute", "dot.ogg": "dot", "empty.ogg": "empty", "fat.ogg": "fat", "flat.ogg": "flat", "front.ogg": "front", "full.ogg": "full", "giant.ogg": "giant", "happy.ogg": "happy", "high.ogg": "high", "hot.ogg": "hot", "huge.ogg": "huge", "left.ogg": "left", "line.ogg": "line", "liquid.ogg": "liquid", "magic.ogg": "magic", "on.ogg": "on", "pretty.ogg": "pretty", "right.ogg": "right", "round.ogg": "round", "royal.ogg": "royal", "shut.ogg": "shut", "sick.ogg": "sick", "small.ogg": "small", "spot.ogg": "spot", "square.ogg": "square", "stand.ogg": "stand", "straight.ogg": "straight", "stripe.ogg": "stripe", "strong.ogg": "strong", "tall.ogg": "tall", "thick.ogg": "thick", "tired.ogg": "tired", "under.ogg": "under", "wet.ogg": "wet", "wheat.ogg": "wheat", "U0030.ogg": "zero", "U0031.ogg": "one", "U0032.ogg": "two", "U0033.ogg": "three", "U0034.ogg": "four", "U0035.ogg": "five", "U0036.ogg": "six", "U0037.ogg": "seven", "U0038.ogg": "eight", "U0039.ogg": "nine", - "10.ogg": "ten" + "10.ogg": "ten", + "11.ogg": "eleven", + "12.ogg": "twelve", + "16.ogg": "sixteen" } diff --git a/src/activities/imageid/resource/content-es.json b/src/activities/imageid/resource/content-es.json index 2f353ad42..e5cc5aef1 100644 --- a/src/activities/imageid/resource/content-es.json +++ b/src/activities/imageid/resource/content-es.json @@ -1,724 +1,714 @@ { "acorn.ogg": "bellota", "actor.ogg": "actor", "add.ogg": "anadir", "admire.ogg": "admirar", "age.ogg": "edad", "air.ogg": "aire", "alligator.ogg": "caimán", "alone.ogg": "solo", "alphabet.ogg": "alfabeto", "always.ogg": "siempre", "anchor.ogg": "ancla", "angel.ogg": "angel", "animal.ogg": "animal", "ankle.ogg": "tobillo", "answer.ogg": "responder", "ant.ogg": "hormiga", "antelope.ogg": "antilope", "apple.ogg": "manzana", "apricot.ogg": "albaricoque", "april.ogg": "abril", "arm.ogg": "brazo", "armchair.ogg": "sillón", "artichoke.ogg": "alcachofa", "artist.ogg": "artista", "ask.ogg": "pedir", "asparagus.ogg": "espárragos", "astronaut.ogg": "astronauta", "athlete.ogg": "atleta", "august.ogg": "agosto", "avocado.ogg": "aguacate", "baby.ogg": "bebe", "back.ogg": "espalda", "bad.ogg": "malo", "bag.ogg": "bolsa", "bald.ogg": "calvo", "ballet.ogg": "ballet", "bank.ogg": "banco", "bark.ogg": "ladrido", "barn.ogg": "granero", "basket.ogg": "canasta", "bath.ogg": "baño", "be.ogg": "ser", "beach.ogg": "playa", "bean.ogg": "frejol", "beard.ogg": "barba", "beat.ogg": "batir", "bed.ogg": "cama", "bedroom.ogg": "dormitorio", "bee.ogg": "abeja", "beef.ogg": "carne de res", "bell.ogg": "campana", "belly.ogg": "vientre", "bet.ogg": "apostar", "bib.ogg": "babero", "big.ogg": "grande", "bike.ogg": "bicicleta", "bird.ogg": "pájaro", "birth.ogg": "nacimiento", "black.ogg": "negro", "blind.ogg": "ciego", "blond.ogg": "rubio", "blue.ogg": "azul", "boat.ogg": "barco", "boil.ogg": "hervir", "bomb.ogg": "bomba", "bone.ogg": "hueso", "book.ogg": "libro", "bowl.ogg": "cuenco", "box.ogg": "caja", "boy.ogg": "niño", "brain.ogg": "cerebro", "branch.ogg": "rama", "bread.ogg": "pan", "break.ogg": "romper", "bridge.ogg": "puente", "bright.ogg": "brillante", "bring.ogg": "llevar", "broccoli.ogg": "brócoli", "brown.ogg": "marrón", "bubble.ogg": "burbuja", "bucket.ogg": "cubo", "bug.ogg": "escarabajo", "build.ogg": "construir", "bus.ogg": "autobús", "butcher.ogg": "carnicero", "butter.ogg": "mantequilla", "butterfly.ogg": "mariposa", "button.ogg": "botón", "buy.ogg": "comprar", "cab.ogg": "cabina", "cabbage.ogg": "repollo", "cactus.ogg": "cactus", "cage.ogg": "jaula", "cake.ogg": "pastel", "call.ogg": "llamar", "camel.ogg": "camello", "camera.ogg": "cámara", "camp.ogg": "campamento", "candle.ogg": "vela", "candy.ogg": "caramelo", - "cane.ogg": "caña", + "cane.ogg": "bastón", "canoe.ogg": "canoa", "cape.ogg": "capa", "car.ogg": "coche", "carpet.ogg": "alfombra", "carrot.ogg": "zanahoria", "castle.ogg": "castillo", "cat.ogg": "gato", "caterpillar.ogg": "oruga", "cauliflower.ogg": "coliflor", "cave.ogg": "cueva", "cereal.ogg": "cereal", "chain.ogg": "cadena", "chair.ogg": "silla", "chalk.ogg": "tiza", "chat.ogg": "charlar", "cheese.ogg": "queso", "cherry.ogg": "cereza", "chick.ogg": "pollito", "chicken.ogg": "pollo", "chimney.ogg": "chimenea", "chin.ogg": "mentón", "chocolate.ogg": "chocolate", "christmas.ogg": "Navidad", "church.ogg": "iglesia", "cigar.ogg": "cigarro", "circle.ogg": "círculo", "circus.ogg": "circo", "city.ogg": "ciudad", "class.ogg": "clase", "claw.ogg": "garra", "clean.ogg": "limpiar", "clock.ogg": "reloj", "close.ogg": "cerrar", "cloth.ogg": "ropa", "cloud.ogg": "nube", "clown.ogg": "payaso", "coast.ogg": "costa", "coat.ogg": "abrigo", "cobra.ogg": "cobra", "coffee.ogg": "cafe", "coin.ogg": "moneda", "cold.ogg": "frio", "color.ogg": "color", "comb.ogg": "peine", "cone.ogg": "cono", "cookie.ogg": "galleta", "corn.ogg": "maíz", "couple.ogg": "pareja", "cow.ogg": "vaca", "crab.ogg": "cangrejo", "crazy.ogg": "loco", "cream.ogg": "crema", "crocodile.ogg": "cocodrilo", "cry.ogg": "llorar", "cucumber.ogg": "pepino", "curtain.ogg": "cortina", "cut.ogg": "cortar", "dad.ogg": "papá", "daisy.ogg": "margarita", "dance.ogg": "bailar", "danger.ogg": "peligro", "day.ogg": "dia", "dead.ogg": "muerto", "december.ogg": "Diciembre", "deer.ogg": "ciervo", "desert.ogg": "desierto", "desk.ogg": "escritorio", "dessert.ogg": "postre", "diamond.ogg": "diamante", "die.ogg": "morir", "dig.ogg": "cavar", "dirty.ogg": "sucio", "dive.ogg": "inmersión", "do.ogg": "hacer", "doctor.ogg": "médico", "dog.ogg": "perro", "doll.ogg": "muñeca", "donkey.ogg": "burro", "door.ogg": "puerta", "dot.ogg": "punto", "dragon.ogg": "dragón", "draw.ogg": "dibujar", "dream.ogg": "sueño", "dress.ogg": "vestir", "drink.ogg": "beber", "drive.ogg": "conducir", "drum.ogg": "tambor", "dry.ogg": "secar", "duck.ogg": "pato", "dune.ogg": "duna", "dwarf.ogg": "enano", "eagle.ogg": "águila", "earth.ogg": "tierra", "eat.ogg": "comer", "egg.ogg": "huevo", - "eight.ogg": "ocho", "elbow.ogg": "codo", "electrician.ogg": "electricista", "elephant.ogg": "elefante", - "eleven.ogg": "once", "empty.ogg": "vacío", "engine.ogg": "motor", "engineer.ogg": "ingeniero", "english.ogg": "Ingles", "eraser.ogg": "borrador", "eyebrow.ogg": "ceja", "eyelash.ogg": "de pestañas", "eyes.ogg": "ojos", "face.ogg": "cara", "fairy.ogg": "hada", "fall.ogg": "caer", "family.ogg": "familia", "fan.ogg": "ventilador", "far.ogg": "lejos", "farm.ogg": "granja", "farmer.ogg": "agricultor", "fat.ogg": "grasa", "feather.ogg": "pluma", "february.ogg": "Febrero", "feet.ogg": "pies", "female.ogg": "femenino", "fill.ogg": "llenar", "fin.ogg": "aleta", "find.ogg": "encontrar", "finger.ogg": "dedo", "fire.ogg": "fuego", "fireman.ogg": "bombero", "first.ogg": "primero", "fisherman.ogg": "pescador", "fist.ogg": "puño", - "five.ogg": "cinco", "flag.ogg": "bandera", "flame.ogg": "llama", "flour.ogg": "harina", "flower.ogg": "flor", "flute.ogg": "flauta", "fly.ogg": "volar", "food.ogg": "alimento", "foot.ogg": "pie", "forest.ogg": "bosque", "fork.ogg": "tenedor", - "four.ogg": "cuatro", "fox.ogg": "zorro", "frame.ogg": "marco", "france.ogg": "Francia", "friday.ogg": "Viernes", "friend.ogg": "amigo", "frog.ogg": "rana", "front.ogg": "enfrente", "front.ogg": "frente", "fruit.ogg": "fruta", "fun.ogg": "diversión", "fur.ogg": "piel", "game.ogg": "juego", "gap.ogg": "brecha", "garage.ogg": "garaje", "garden.ogg": "jardín", "garlic.ogg": "ajo", "germany.ogg": "Alemania", "get.ogg": "obtener", "giant.ogg": "gigante", "gift.ogg": "regalo", "giraffe.ogg": "jirafa", "girl.ogg": "chica", "glasses.ogg": "gafas", "glove.ogg": "guante", "glue.ogg": "pegamento", "goat.ogg": "cabra", "gold.ogg": "oro", "good.ogg": "bueno", "grain.ogg": "grano", "grandfather.ogg": "abuelo", "grandmother.ogg": "abuela", "grape.ogg": "uva", "grapefruit.ogg": "pomelo", "grass.ogg": "hierba", "gray.ogg": "gris", "great_britain.ogg": "Gran bretaña", "green.ogg": "verde", "grill.ogg": "grilla", "grow.ogg": "crecer", "hair.ogg": "cabello", "hairdresser.ogg": "peluquero", "half.ogg": "mitad", "ham.ogg": "jamón", "hamburger.ogg": "hamburguesa", "hammer.ogg": "martillo", "hamster.ogg": "hámster", "hand.ogg": "mano", "happy.ogg": "feliz", "hard.ogg": "duro", "hat.ogg": "sombrero", "hatch.ogg": "escotilla", "hay.ogg": "heno", "head.ogg": "cabeza", "hear.ogg": "escuchar", "heart.ogg": "corazón", "heat.ogg": "calor", "helmet.ogg": "casco", "help.ogg": "ayudar", "hen.ogg": "gallina", "high.ogg": "alto", "hike.ogg": "caminata", "hill.ogg": "colina", "hippopotamus.ogg": "hipopótamo", "hit.ogg": "golpear", "hive.ogg": "colmena", "hole.ogg": "agujero", "home.ogg": "hogar", "hop.ogg": "salto", "horse.ogg": "caballo", "hospital.ogg": "hospital", "hot.ogg": "caliente", "house.ogg": "casa", "huge.ogg": "enorme", "hunter.ogg": "cazador", "hurt.ogg": "daño", "husband.ogg": "marido", "ice.ogg": "hielo", "ill.ogg": "enfermo", "ink.ogg": "tinta", "island.ogg": "isla", "italy.ogg": "Italia", "jacket.ogg": "chaqueta", "jam.ogg": "mermelada", "january.ogg": "Enero", "jelly.ogg": "jalea", "jewel.ogg": "joya", "judge.ogg": "juez", "july.ogg": "Julio", "jump.ogg": "saltar", "june.ogg": "Junio", "kangaroo.ogg": "canguro", "king.ogg": "rey", "kiss.ogg": "beso", "kitchen.ogg": "cocina", "kite.ogg": "cometa", "kiwi.ogg": "kiwi", "knee.ogg": "rodilla", "knife.ogg": "cuchillo", "knot.ogg": "nudo", "know.ogg": "saber", "koala.ogg": "coala", "ladder.ogg": "escalera", "ladybug.ogg": "mariquita", "lake.ogg": "lago", "lamb.ogg": "cordero", "lamp.ogg": "lámpara", "lane.ogg": "carril", "laugh.ogg": "reír", "lava.ogg": "lava", "lawn.ogg": "cesped", "lazy.ogg": "perezoso", "leaf.ogg": "hoja", "leek.ogg": "puerro", "left.ogg": "izquierda", "leg.ogg": "pierna", "lemon.ogg": "limón", "leopard.ogg": "leopardo", "lettuce.ogg": "lechuga", "librarian.ogg": "librera", "librarian.ogg": "librero", "lick.ogg": "lamer", "lid.ogg": "tapa", "life.ogg": "vida", "light.ogg": "luz", "lighthouse.ogg": "faro", "line.ogg": "linea", "link.ogg": "enlace", "lion.ogg": "león", "lip.ogg": "labio", "liquid.ogg": "líquido", "lizard.ogg": "lagartija", "lobster.ogg": "langosta", "love.ogg": "amor", "luck.ogg": "suerte", "lunch.ogg": "almuerzo", "mail.ogg": "correo", "male.ogg": "masculino", "man.ogg": "hombre", "map.ogg": "mapa", "mask.ogg": "máscara", "may.ogg": "Mayo", "meal.ogg": "comida", "meat.ogg": "carne", "melon.ogg": "melón", "milk.ogg": "leche", "mill.ogg": "molino", "mirror.ogg": "espejo", "mole.ogg": "topo", "monday.ogg": "Lunes", "monkey.ogg": "mono", "moon.ogg": "luna", "mosquito.ogg": "mosquito", "mother.ogg": "madre", "motorcycle.ogg": "motocicleta", "mountain.ogg": "montaña", "mouse.ogg": "ratón", "mouth.ogg": "boca", "movie.ogg": "película", "mud.ogg": "barro", "mug.ogg": "jarra", "muscle.ogg": "músculo", "mushroom.ogg": "hongo", "music.ogg": "música", "musician.ogg": "músico", "nail.ogg": "clavo", "neck.ogg": "cuello", "necklace.ogg": "collar", "needle.ogg": "aguja", "nest.ogg": "nido", "newspaper.ogg": "periódico", "night.ogg": "noche", - "nine.ogg": "nueve", "noise.ogg": "ruido", "north.ogg": "norte", "nose.ogg": "nariz", "nostril.ogg": "ventana de la nariz", "note.ogg": "nota", "notebook.ogg": "cuaderno", "november.ogg": "Noviembre", "now.ogg": "ahora", "number.ogg": "número", "nurse.ogg": "enfermera", "nut.ogg": "nuez", "oar.ogg": "remo", "ocean.ogg": "océano", "october.ogg": "Octubre", "oil.ogg": "aceite", "olive.ogg": "oliva", - "one.ogg": "uno", "onion.ogg": "cebolla", "open.ogg": "abrir", "orange.ogg": "naranja", "owl.ogg": "búho", "page.ogg": "página", "paint.ogg": "pintar", "pair.ogg": "par", "panda.ogg": "panda", "panther.ogg": "pantera", "pants.ogg": "pantalones", "paper.ogg": "papel", "park.ogg": "parque", "parrot.ogg": "loro", "patch.ogg": "parche", "path.ogg": "camino", "pay.ogg": "pagar", "pea.ogg": "guisante", "peach.ogg": "melocotón", "pear.ogg": "pera", "pearl.ogg": "perla", "pen.ogg": "pluma", "pencil.ogg": "lápiz", "pepper.ogg": "pimienta", "petal.ogg": "pétalo", "phone.ogg": "teléfono", "piano.ogg": "piano", "picture.ogg": "imagen", "pig.ogg": "cerdo", "pigeon.ogg": "paloma", "pill.ogg": "píldora", "pillow.ogg": "almohada", "pilot.ogg": "piloto", "pine_tree.ogg": "árbol de pino", "pineapple.ogg": "piña", "pink.ogg": "rosa", "pirate.ogg": "pirata", "pizza.ogg": "pizza", "planet.ogg": "planeta", "play.ogg": "jugar", "please.ogg": "complacer", "plum.ogg": "ciruela", "plumber.ogg": "fontanero", "pocket.ogg": "bolsillo", "police.ogg": "policía", "pond.ogg": "estanque", "pool.ogg": "piscina", "pot.ogg": "olla", "potato.ogg": "patata", "pray.ogg": "orar", "present.ogg": "presentar", "pretty.ogg": "bonita", "price.ogg": "precio", "priest.ogg": "sacerdote", "prince.ogg": "príncipe", "princess.ogg": "princesa", "print.ogg": "imprimir", "prison.ogg": "prisión", "pullover.ogg": "jersey", "pumpkin.ogg": "calabaza", "purple.ogg": "púrpura", "pyramid.ogg": "pirámide", "queen.ogg": "reina", "question.ogg": "cuestión", "quick.ogg": "rápido", "quiet.ogg": "tranquilo", "rabbit.ogg": "conejo", "radio.ogg": "radio", "rain.ogg": "lluvia", "rake.ogg": "rastrillo", "raspberry.ogg": "frambuesa", "rat.ogg": "rata", "read.ogg": "leer", "red.ogg": "rojo", "reptile.ogg": "reptil", "rhinoceros.ogg": "rinoceronte", "rice.ogg": "arroz", "ring.ogg": "anillo", "risk.ogg": "riesgo", "river.ogg": "río", "road.ogg": "carretera", "robot.ogg": "robot", "rocket.ogg": "cohete", "roof.ogg": "techo", "rooster.ogg": "gallo", "root.ogg": "raíz", "rope.ogg": "cuerda", "sad.ogg": "triste", "sail.ogg": "navegar", "sailor.ogg": "marinero", "salmon.ogg": "salmón", "sand.ogg": "arena", "sandals.ogg": "sandalias", "saturday.ogg": "sábado", "sauce.ogg": "salsa", "sausage.ogg": "salchicha", "scar.ogg": "cicatriz", "school.ogg": "escuela", "scissors.ogg": "tijeras", "scorpion.ogg": "escorpión", "scream.ogg": "gritar", "screen.ogg": "pantalla", "sea.ogg": "mar", "see.ogg": "ver", "seed.ogg": "semilla", "sell.ogg": "vender", "september.ogg": "Septiembre", - "seven.ogg": "siete", "shadow.ogg": "sombra", "shake.ogg": "sacudir", "shark.ogg": "tiburón", "sheep.ogg": "oveja", "shell.ogg": "concha", "shirt.ogg": "camisa", "shoe.ogg": "zapato", "short.ogg": "corto", "shovel.ogg": "pala", "shower.ogg": "ducha", "shrimp.ogg": "camarón", "silence.ogg": "silencio", "silver.ogg": "plata", "sing.ogg": "cantar", "singer.ogg": "cantante", "sister.ogg": "hermana", "sit.ogg": "sentarse", - "six.ogg": "seis", - "sixteen.ogg": "dieciséis", "ski.ogg": "esquiar", "skirt.ogg": "falda", "sky.ogg": "cielo", "sleep.ogg": "dormir", "sleeve.ogg": "manga", "slow.ogg": "lento", "small.ogg": "pequeño", "smart.ogg": "inteligente", "smell.ogg": "olor", "smile.ogg": "sonreír", "snack.ogg": "bocadillo", "snail.ogg": "caracol", "snake.ogg": "serpiente", "snow.ogg": "nieve", "soap.ogg": "jabón", "sock.ogg": "calcetín", "soft.ogg": "suave", "soldier.ogg": "soldado", "son.ogg": "hijo", "sorry.ogg": "arrepentido", "soup.ogg": "sopa", "space.ogg": "espacio", "speak.ogg": "hablar", "spice.ogg": "especia", "spider.ogg": "araña", "spill.ogg": "derramar", "spinach.ogg": "espinacas", "split.ogg": "dividido", "sponge.ogg": "esponja", "spoon.ogg": "cuchara", "sport.ogg": "deporte", "spouse.ogg": "cónyuge", "squirrel.ogg": "ardilla", "stain.ogg": "mancha", "stamp.ogg": "sello", "star.ogg": "estrella", "start.ogg": "iniciar", "steak.ogg": "filete", "stem.ogg": "vástago", "stick.ogg": "palo", "stone.ogg": "piedra", "stop.ogg": "parar", "store.ogg": "almacenar", "straight.ogg": "recto", "straw.ogg": "paja", "strawberry.ogg": "fresa", "street.ogg": "calle", "strong.ogg": "fuerte", "student.ogg": "estudiante", "study.ogg": "estudiar", "sugar.ogg": "azúcar", "suitcase.ogg": "maleta", "summer.ogg": "verano", "summit.ogg": "cumbre", "sun.ogg": "sol", "sunday.ogg": "Domingo", "super.ogg": "súper", "sweat.ogg": "sudar", "sweatshirt.ogg": "Sudadera", "sweet.ogg": "dulce", "swim.ogg": "nadar", "swiss.ogg": "suizo", "table.ogg": "mesa", "tag.ogg": "etiqueta", "tail.ogg": "cola", "take.ogg": "tomar", "task.ogg": "tarea", "teach.ogg": "enseñar", "teacher.ogg": "maestro", "team.ogg": "equipo", "television.ogg": "televisión", "tell.ogg": "contar", "temple.ogg": "templo", - "ten.ogg": "diez", "tennis.ogg": "tenis", "text.ogg": "texto", "thank.ogg": "agradecer", "thief.ogg": "ladrón", "think.ogg": "pensar", - "three.ogg": "tres", "thumb.ogg": "pulgar", "thursday.ogg": "Jueves", "ticket.ogg": "billete", "tiger.ogg": "tigre", "time.ogg": "tiempo", "tired.ogg": "cansado", "tissue.ogg": "tejido", "today.ogg": "hoy", "tomato.ogg": "tomate", "tomorrow.ogg": "mañana", "tongue.ogg": "lengua", "tool.ogg": "herramienta", "towel.ogg": "toalla", "tower.ogg": "torre", "toy.ogg": "juguete", "train.ogg": "tren", "train_station.ogg": "estación de tren", "tree.ogg": "árbol", "triangle.ogg": "triángulo", "trip.ogg": "viaje", "truck.ogg": "camión", "tube.ogg": "tubo", "tuesday.ogg": "Martes", "tulip.ogg": "tulipán", "tunnel.ogg": "túnel", "turkey.ogg": "pavo", "turtle.ogg": "tortuga marina", - "twelve.ogg": "doce", - "two.ogg": "dos", "umbrella.ogg": "paraguas", "uniform.ogg": "uniforme", "valley.ogg": "valle", "vase.ogg": "florero", "vet.ogg": "veterinario", "viper.ogg": "víbora", "voice.ogg": "voz", "vowel.ogg": "vocal", "wait.ogg": "esperar", "walk.ogg": "caminar", "wall.ogg": "pared", "want.ogg": "querer", "wash.ogg": "lavar", "wasp.ogg": "avispa", "water.ogg": "agua", "wave.ogg": "ola", "wedding.ogg": "boda", "wednesday.ogg": "miércoles", "weight.ogg": "peso", "well.ogg": "bien", "wet.ogg": "humedo", "wheat.ogg": "trigo", "wheel.ogg": "rueda", "white.ogg": "blanco", "wide.ogg": "ancho", "wife.ogg": "esposa", "wig.ogg": "peluca", "win.ogg": "ganar", "wind.ogg": "viento", "window.ogg": "ventana", "winter.ogg": "invierno", "wolf.ogg": "lobo", "woman.ogg": "mujer", "wood.ogg": "madera", "word.ogg": "palabra", "worker.ogg": "obrero", "world.ogg": "mundo", "write.ogg": "escribir", "wrong.ogg": "erroneo", "yard.ogg": "patio", "yellow.ogg": "amarillo", "yesterday.ogg": "ayer", "yogurt.ogg": "yogur", "zebra.ogg": "cebra", "U0030.ogg": "cero", "U0031.ogg": "uno", "U0032.ogg": "dos", "U0033.ogg": "tres", "U0034.ogg": "cuatro", "U0035.ogg": "cinco", "U0036.ogg": "seis", "U0037.ogg": "siete", "U0038.ogg": "ocho", "U0039.ogg": "nueve", - "10.ogg": "diez" + "10.ogg": "diez", + "11.ogg": "once", + "12.ogg": "doce", + "16.ogg": "dieciséis" } diff --git a/src/activities/imageid/resource/content-fr.json b/src/activities/imageid/resource/content-fr.json index e90cfb4f1..f8350c18d 100644 --- a/src/activities/imageid/resource/content-fr.json +++ b/src/activities/imageid/resource/content-fr.json @@ -1,1082 +1,1081 @@ { "accountant.ogg": "un comptable", "ache.ogg": "la douleur", "acorn.ogg": "un gland", "actor.ogg": "un acteur", "air_horn.ogg": "un klaxon", "alarmclock.ogg": "un réveil", "alligator.ogg": "un alligator", "alphabet.ogg": "un alphabet", "anchor.ogg": "une ancre", "angel.ogg": "un ange", "angry.ogg": "la colère", "animal.ogg": "les animaux", "ankle.ogg": "la cheville", "ant.ogg": "une fourmi", "anteater.ogg": "un fourmilier", "antelope.ogg": "une antilope", "apple.ogg": "une pomme", "apple_tree.ogg": "un pommier", "appliance.ogg": "un appareil", "apricot.ogg": "un abricot", "arm.ogg": "un bras", "armchair.ogg": "un fauteuil", "artichoke.ogg": "un artichaut", "artist.ogg": "un artiste", "asparagus.ogg": "une asperge", "astronaut.ogg": "un astronaute", "athlete.ogg": "un athlète", "avocado.ogg": "un avocat", "ax.ogg": "une hache", "baby_bottle.ogg": "un biberon", "back.ogg": "le dos", "badge.ogg": "une décoration", "bag.ogg": "un sac", "bait.ogg": "un appât", "bake.ogg": "cuisiner", "balance.ogg": "une balance", "bald.ogg": "chauve", "ball.ogg": "une balle", "ball_of_yarn.ogg": "une pelote", "ball_soccer.ogg": "un ballon de foot", "ballet.ogg": "un ballet", "bank.ogg": "une banque", "banker_female.ogg": "une employée de banque", "bark.ogg": "aboyer", "barn.ogg": "une grange", "bat.ogg": "une chauve-souris", "bath.ogg": "un bain", "bathing_suit.ogg": "un maillot", "bay.ogg": "une baie", "beach.ogg": "une plage", "bead.ogg": "une bulle", "bean.ogg": "un haricot", "bear.ogg": "un ours", "beard.ogg": "une barbe", "beat.ogg": "se battre", "beaver.ogg": "un castor", "bed.ogg": "un lit", "bedroom.ogg": "une chambre", "bee.ogg": "une abeille", "beef.ogg": "du boeuf", "beetle.ogg": "un scarabée", "beg.ogg": "supplier", "behind.ogg": "derrière", "bell.ogg": "une cloche", "belly.ogg": "le ventre", "bench.ogg": "un banc", "bib.ogg": "un bavoir", "big.ogg": "grand", "big_top.ogg": "un chapiteau", "bike.ogg": "un vélo", "bird.ogg": "un oiseau", "bit.ogg": "un morceau", "bite.ogg": "croquer", "black.ogg": "noir", - "blackberry.ogg": "un mûre", + "blackberry.ogg": "une mûre", "blackbird.ogg": "un merle", "blade.ogg": "une lame", "blind.ogg": "un aveugle", "blink.ogg": "cligner", "block.ogg": "un bloc", "blond.ogg": "blond", "blue.ogg": "bleu", "blueberry.ogg": "une myrtille", "blush.ogg": "rougir", "board.ogg": "une planche", "boat.ogg": "une barque", "boil.ogg": "bouillir", "bolt.ogg": "un boulon", "bomb.ogg": "une bombe", "bone.ogg": "un os", "book.ogg": "un livre", "bookcase.ogg": "une bibliothèque", "bottom.ogg": "le derrière", "box.ogg": "une boîte", "boxer.ogg": "boxer", "boy.ogg": "un garçon", "braid.ogg": "une tresse", "brain.ogg": "un cerveau", "branch.ogg": "une branche", "bread.ogg": "du pain", "break.ogg": "casser", "breast.ogg": "la poitrine", "brick.ogg": "une brique", "bricklayer.ogg": "un maçon", "bride.ogg": "la mariée", "bridge.ogg": "un pont", "bright.ogg": "brillant", "broccoli.ogg": "un brocoli", "brother.ogg": "un frère", "brown.ogg": "brun", "brush.ogg": "un pinceau", "bubble.ogg": "une bulle", "bucket.ogg": "un seau", "bud.ogg": "un bourgeon", "buffalo.ogg": "un buffle", "bug.ogg": "un insecte", "bulb.ogg": "une ampoule", "bull.ogg": "un taureau", "bump.ogg": "une bosse", "bun.ogg": "une brioche", "bus.ogg": "un bus", "bush.ogg": "un buisson", "butcher.ogg": "un boucher", "butter.ogg": "du beurre", "butterfly.ogg": "un papillon", "button.ogg": "un bouton", "cabbage.ogg": "un chou", "cabin.ogg": "une cabane", "cacao.ogg": "du cacao", "cactus.ogg": "un cactus", "cage.ogg": "une cage", "cake.ogg": "un gâteau", "call.ogg": "appeler", "camel.ogg": "un chameau", "camera.ogg": "un appareil photo", "camp.ogg": "un camping", "canary.ogg": "un canari", "candle.ogg": "une bougie", "candy.ogg": "un bonbon", "cane.ogg": "une cane", "canoe.ogg": "un canoë", "canon.ogg": "un canon", "canyon.ogg": "un canyon", "cap.ogg": "une casquette", "cape.ogg": "une cape", "car.ogg": "une voiture", "carafe.ogg": "une carafe", "card.ogg": "une carte", "carnival.ogg": "le carnaval", "carpenter.ogg": "un charpentier", "carpet.ogg": "un tapis", "carrot.ogg": "une carotte", - "cart.ogg": "un cady", + "cart.ogg": "un chariot de supermarché", "cash.ogg": "de l'argent", "castle.ogg": "un château", "cat.ogg": "un chat", "cat_female.ogg": "une chatte", "catch.ogg": "attraper", "caterpillar.ogg": "une chenille", "cauldron.ogg": "un chaudron", "cauliflower.ogg": "un chou-fleur", "cavern.ogg": "une caverne", "celery.ogg": "un céleri", "centipede.ogg": "un mille-pattes", "cereal.ogg": "une céréale", "chain.ogg": "une chaîne", "chair.ogg": "une chaise", "chalk.ogg": "une craie", "chameleon.ogg": "un caméléon", "chandelier.ogg": "un lustre", "chat.ogg": "discuter", "cheek.ogg": "la joue", "cheer.ogg": "encourager", "cheese.ogg": "du fromage", "chef.ogg": "une cuisinière", "cherry.ogg": "une cerise", "chest.ogg": "un coffre", "chick.ogg": "un poussin", "chicken.ogg": "un poulet", "chief.ogg": "un indien", "child.ogg": "un enfant", "chimney.ogg": "une cheminée", "chimp.ogg": "un chimpanzé", "chin.ogg": "le menton", "chocolate.ogg": "du chocolat", "chop.ogg": "découper", "chores.ogg": "des tâches ménagères", "christmas.ogg": "noël", "cigar.ogg": "un cigare", "circus.ogg": "un cirque", "city.ogg": "une ville", "clam.ogg": "une palourde", "clap.ogg": "une tape", "class.ogg": "une classe", "claw.ogg": "une griffe", "clay.ogg": "de l'argile", "clean.ogg": "se laver", "cleaning_lady.ogg": "une femme de ménage", "cliff.ogg": "une falaise", "climb.ogg": "escalader", "clock.ogg": "un réveil", - "cloth.ogg": "du tissus", + "cloth.ogg": "du tissu", "clothes_hanger.ogg": "un cintre", "cloud.ogg": "un nuage", "cloudy.ogg": "nuageux", "clover.ogg": "un trèfle", "cowboy.ogg": "un cow-boy", "clown.ogg": "un clown", "coach.ogg": "une entraîneuse", "coast.ogg": "une côte", "coat.ogg": "un manteau", "cobra.ogg": "un cobra", "coconut.ogg": "une noix de coco", "cod.ogg": "une morue", "coffee.ogg": "un café", "coin.ogg": "une pièce", "cold.ogg": "le froid", "color.ogg": "la couleur", "colt.ogg": "un poulain", "comb.ogg": "un peigne", "cone.ogg": "un cône", "cookie.ogg": "un biscuit", "cork.ogg": "un bouchon", "corn.ogg": "du maïs", "couch.ogg": "un canapé", "cough.ogg": "tousser", "couple.ogg": "un couple", "cow.ogg": "une vache", "crab.ogg": "un crabe", "cradle.ogg": "un berceau", "craft.ogg": "des travaux manuels", "crawl.ogg": "ramper", "crazy.ogg": "un fou", "creek.ogg": "un ruisseau", "crepe.ogg": "une crêpe", "crib.ogg": "des berceaux", "criminal.ogg": "un criminel", "croak.ogg": "coasser", "crocodile.ogg": "un crocodile", "cross.ogg": "une croix", "crow.ogg": "un corbeau", "crown.ogg": "une couronne", "crumb.ogg": "une miette", "crust.ogg": "une croûte", "cry.ogg": "pleurer", "crystal.ogg": "un cristal", "cube.ogg": "un cube", "cucumber.ogg": "un concombre", "curtain.ogg": "un rideau", "cut.ogg": "couper", "cute.ogg": "adorable", "dad.ogg": "un papa", "daffodil.ogg": "une jonquille", "daisy.ogg": "une marguerite", "dam.ogg": "un barrage", - "dance.ogg": "dancer", + "dance.ogg": "danser", "dandelion.ogg": "un pissenlit", "danger.ogg": "un danger", "dart_board.ogg": "une cible", "date_fruit.ogg": "une datte", "deer.ogg": "un cerf", "den.ogg": "une tanière", "desert.ogg": "un désert", "desk.ogg": "un bureau", "dessert.ogg": "un dessert", "diamond.ogg": "un diamant", "dig.ogg": "creuser", "dirt.ogg": "le sol", "dirty.ogg": "sale", "dish.ogg": "un plat", "dishcloth.ogg": "un torchon", "dive.ogg": "plonger", "doctor.ogg": "une docteure", "doe.ogg": "une biche", "dog.ogg": "un chien", "doll.ogg": "une poupée", "dolphin.ogg": "un dauphin", "domino.ogg": "un domino", "door.ogg": "une porte", "doormat.ogg": "un paillasson", "dot.ogg": "un point", "doughnut.ogg": "un beignet", "dove.ogg": "une colombe", "dragon.ogg": "un dragon", "dragonfly.ogg": "une libellule", "draw.ogg": "un dessin", "drawer.ogg": "un tiroir", "dream.ogg": "un rêve", "dress.ogg": "une robe", "drink.ogg": "une boisson", "drinking.ogg": "boire", "drip.ogg": "une goutte", "drive.ogg": "conduire", "drool.ogg": "baver", "drum.ogg": "un tambour", "dry.ogg": "sécher", "duck.ogg": "un canard", "duck_mother.ogg": "une canne", "dune.ogg": "une dune", "dwarf.ogg": "un nain", "eagle.ogg": "un aigle", "ear.ogg": "une oreille", "earth.ogg": "la Terre", "eat.ogg": "manger", "egg.ogg": "un oeuf", "eggplant.ogg": "une aubergine", "elbow.ogg": "le coude", "electrician.ogg": "un électricien", - "eleven.ogg": "onze", "elk.ogg": "un wapiti", "empty.ogg": "vide", "engine.ogg": "un moteur", "engineer.ogg": "un ingénieur", "eraser.ogg": "une gomme", "explore.ogg": "des explorateurs", "eyelash.ogg": "un cil", "eyes.ogg": "les yeux", "face.ogg": "un visage", "fair.ogg": "un manège", "fairy.ogg": "une fée", "fall_down.ogg": "tomber", "fall_season.ogg": "l'automne", "family.ogg": "une famille", "fan.ogg": "un ventilateur", "farm.ogg": "une ferme", "farmer.ogg": "un fermier", "fat.ogg": "gras", "faucet.ogg": "un robinet", "fawn.ogg": "un faon", "feast.ogg": "un poulet", "feather.ogg": "une plume", "feed.ogg": "nourrir", "femur.ogg": "un fémur", "fetch.ogg": "rapporter", "fig.ogg": "une figue", "fin.ogg": "une nageoire", "find.ogg": "trouver", "finger.ogg": "un doigt", "fire.ogg": "un feu", "fire_extinguisher.ogg": "un extincteur", "fireman.ogg": "un pompier", "fish.ogg": "un poisson", "fisherman.ogg": "un pêcheur", "fist.ogg": "un poing", "flacon.ogg": "un flacon", "flag.ogg": "un drapeau", "flame.ogg": "une flamme", "flamingo.ogg": "un flamant rose", "flash.ogg": "une lampe torche", "flat.ogg": "un appartement", "flies.ogg": "une mouche", "flight.ogg": "un vol", "float.ogg": "flotter", "flour.ogg": "la farine", "flower.ogg": "une fleur", "fluff.ogg": "une peluche", "flute.ogg": "une flûte", "fly.ogg": "voler", "foam.ogg": "la mousse", "food.ogg": "un hamburger", "foot.ogg": "un pied", "forest.ogg": "une forêt", "fork.ogg": "une fourchette", "fountain.ogg": "une fontaine", "fox.ogg": "un renard", "freeze.ogg": "geler", "friend.ogg": "des amis", "fries.ogg": "une frite", "frog.ogg": "une grenouille", "front.ogg": "devant", "frown.ogg": "rechigner", "fruit.ogg": "un fruit", "fudge.ogg": "un caramel", "full.ogg": "plein", "fun.ogg": "un jeu", "fur.ogg": "la fourrure", "game.ogg": "un jeu", "garage.ogg": "un garage", "garden.ogg": "un jardin", "garlic.ogg": "de l'ail", "giant.ogg": "un géant", "gift.ogg": "un cadeau", "giraffe.ogg": "une girafe", "girl.ogg": "une fille", "glass.ogg": "un verre", "glasses.ogg": "des lunettes", "glove.ogg": "un gant", "glue.ogg": "la colle", "gnome.ogg": "un gnome", "goat.ogg": "une chèvre", "golden.ogg": "doré", "golf.ogg": "le golf", "goose.ogg": "une oie", "gorilla.ogg": "un gorille", "grain.ogg": "un épi", "grandmother.ogg": "une grand-mère", "grape.ogg": "une grappe de raisin", "grapefruit.ogg": "un pamplemousse", "grass.ogg": "une herbe", "grave.ogg": "une tombe", "gray.ogg": "gris", "green.ogg": "vert", "grill.ogg": "un barbecue", "grin.ogg": "un sourire", "ground.ogg": "la terre", "growl.ogg": "grogner", "guignol.ogg": "guignol", "guinea_pig.ogg": "un cochon d'inde", "gum.ogg": "du chewing-gum", "hair.ogg": "les cheveux", "hair_dryer.ogg": "un sèche-cheveux", "half.ogg": "la moitié", "ham.ogg": "un jambon", "hammer.ogg": "un marteau", "hand.ogg": "une main", "handlebar.ogg": "un guidon", "happy.ogg": "heureux", "harp.ogg": "une harpe", "hat.ogg": "un chapeau", "hatch.ogg": "éclore", "hay.ogg": "le foin", "head.ogg": "la tête", "hear.ogg": "entendre", "heat.ogg": "la chaleur", "hedge.ogg": "une bordure", "hedgehog.ogg": "un hérisson", "heel.ogg": "le talon", "helmet.ogg": "un casque", "hen.ogg": "une poule", "herd.ogg": "un troupeau", "high.ogg": "haut", "hike.ogg": "une promenade", "hill.ogg": "une colline", "hip.ogg": "une hanche", "hippopotamus.ogg": "un hippopotame", "hit.ogg": "une bagarre", "hive.ogg": "une ruche", "hockey.ogg": "le hockey", "hole.ogg": "un trou", "hook.ogg": "un hameçon", "hop.ogg": "rebondir", "horse.ogg": "un cheval", "hose.ogg": "un tuyau", "hospital.ogg": "un hôpital", "hot.ogg": "chaud", "hot_dog.ogg": "un hot-dog", "house.ogg": "une maison", "howl.ogg": "un hurlement", "huge.ogg": "énorme", "hummingbird.ogg": "un colibri", "hunchback.ogg": "un bossu", "hunter.ogg": "un chasseur", "husband.ogg": "un mari", "hut.ogg": "une hutte", "hyena.ogg": "une hyène", "ice.ogg": "un glaçon", "iceberg.ogg": "un iceberg", "iguana.ogg": "un iguane", "ill.ogg": "malade", - "ink.ogg": "une encre", + "ink.ogg": "de l'encre", "island.ogg": "une île", "jacket.ogg": "une veste", "jaguar.ogg": "un jaguar", "jam.ogg": "une confiture", "jay.ogg": "un geai", "jelly.ogg": "une gelée", "jellyfish.ogg": "une méduse", "jewel.ogg": "un bijou", "job.ogg": "un travail", "jockey.ogg": "un jockey", "jog.ogg": "un joggeur", "judge.ogg": "un juge", "judo.ogg": "une judokate", "juggler.ogg": "une jongleuse", "juice.ogg": "un jus", "jump.ogg": "sauter", "kangaroo.ogg": "un kangourou", "keel.ogg": "une quille", "kernel.ogg": "un noyau", "keyboard.ogg": "un clavier", "kimono.ogg": "un kimono", "king.ogg": "un roi", "kiss.ogg": "un baiser", "kitchen.ogg": "une cuisine", "kite.ogg": "un cerf-volant", "kitten.ogg": "un chaton", "kiwi.ogg": "un kiwi", "knee.ogg": "un genou", "kneel.ogg": "s'agenouiller", "knife.ogg": "un couteau", "knight.ogg": "un chevalier", "knit.ogg": "tricoter", "knot.ogg": "un noeud", "koala.ogg": "un koala", "lady.ogg": "une dame", "ladybug.ogg": "une coccinelle", "lake.ogg": "un lac", "lama.ogg": "un lama", "lamb.ogg": "un agneau", "lamp.ogg": "une lampe", "land.ogg": "un terrain", "lasso.ogg": "un lasso", "laugh.ogg": "rire", "lava.ogg": "la lave", "lawn.ogg": "la pelouse", "lawyer.ogg": "un avocat", "leaf.ogg": "une feuille", "ledge.ogg": "un rebord", "leek.ogg": "un poireau", "left.ogg": "la gauche", "leg.ogg": "la jambe", "leg_animal.ogg": "la patte", "lemon.ogg": "un citron", "lemonade.ogg": "une limonade", "lemur.ogg": "un lémur", "leopard.ogg": "un léopard", "lettuce.ogg": "une laitue", "librarian.ogg": "une bibliothécaire", "lick.ogg": "lécher", "lid.ogg": "un couvercle", "lift.ogg": "soulever", "light.ogg": "la lumière", - "lilac.ogg": "un lilas", "lighthouse.ogg": "un phare", "lightning.ogg": "la foudre", "lilac.ogg": "un lilas", "lime.ogg": "un citron vert", "line.ogg": "un code-barres", "link.ogg": "un chaînon", "lion.ogg": "un lion", "lion_cub.ogg": "un lionceau", "lip.ogg": "une lèvre", "liquid.ogg": "un liquide", "lizard.ogg": "un lézard", "lobster.ogg": "un homard", "log.ogg": "une bûche", "look.ogg": "regarder", "lunch.ogg": "un casse-croûte", "mad.ogg": "la colère", "magic.ogg": "un magicien", "magnet.ogg": "un aimant", "magnifying_glass.ogg": "une loupe", "magpie.ogg": "une pie", "mail.ogg": "une enveloppe", "man.ogg": "un homme", "mane.ogg": "une crinière", "mango.ogg": "une mangue", "map.ogg": "une carte", "maple.ogg": "un érable", "marble.ogg": "une bille", "mashed_potatoes.ogg": "une purée", "mask.ogg": "un masque", "mast.ogg": "un mât", "mat.ogg": "une natte", "match.ogg": "une allumette", "mate_male.ogg": "un copain", "mate_female.ogg": "une camarade", "mattress.ogg": "un matelas", "mauve.ogg": "violet", "meal.ogg": "un repas", "meat.ogg": "de la viande", "mechanic.ogg": "un mécanicien", "medal.ogg": "une médaille", "meet.ogg": "rencontrer", "melon.ogg": "un melon", "men.ogg": "une foule", "merry-go-round.ogg": "un tourniquet", "microphone.ogg": "un micro", "milk.ogg": "du lait", "mill.ogg": "un moulin", "mimosa.ogg": "un mimosa", "mirror.ogg": "un miroir", "mixer.ogg": "un mixer", "mole.ogg": "une taupe", "mom.ogg": "une maman", "moon.ogg": "une lune", "moose.ogg": "un élan", "mop.ogg": "un balai", "mosque.ogg": "une mosquée", "mosquito.ogg": "un moustique", "mother.ogg": "une mère", "motorcycle.ogg": "une moto", "mountain.ogg": "une montagne", "mouse.ogg": "une souris", "mouth.ogg": "une bouche", "movie.ogg": "un film", "mower.ogg": "une tondeuse", "mud.ogg": "la boue", "mug.ogg": "une tasse", "mule.ogg": "une mule", "muscle.ogg": "un muscle", "mushroom.ogg": "un champignon", "music.ogg": "la musique", "musician.ogg": "un musicien", "naked.ogg": "nu", "nap.ogg": "une sieste", "navel.ogg": "le nombril", "neck.ogg": "le cou", "necklace.ogg": "un collier", "needle.ogg": "une aiguille", "nest.ogg": "un nid", "net.ogg": "un filet", "newspaper.ogg": "un journal", "night.ogg": "la nuit", "nightgown.ogg": "une chemise de nuit", "nose.ogg": "le nez", "nostril.ogg": "la narine", "notebook.ogg": "un cahier", "number.ogg": "un nombre", "nun.ogg": "une religieuse", "nurse.ogg": "une infirmière", "nurse_male.ogg": "un infirmier", "nut.ogg": "une cacahuète", "oar.ogg": "une rame", "ocean.ogg": "un océan", "office.ogg": "un bureau", "olive.ogg": "une olive", "on.ogg": "sur", "onion.ogg": "un oignon", "open.ogg": "ouvert", "opossum.ogg": "un opossum", "orange-color.ogg": "orange", "orange.ogg": "une orange", "orchid.ogg": "une orchidée", "ostrich.ogg": "une autruche", "otter.ogg": "une loutre", "owl.ogg": "un hibou", "ox.ogg": "un boeuf", "oyster.ogg": "une huître", "pacifier.ogg": "une tétine", "page.ogg": "une page", "pair.ogg": "une paire", "pajamas.ogg": "un pyjama", "palm_tree.ogg": "un palmier", "pan.ogg": "une poêle", "panda.ogg": "un panda", "panther.ogg": "une panthère", "panties.ogg": "une culotte", "pants.ogg": "un pantalon", "papaya.ogg": "une papaye", "paper.ogg": "un papier", "parachute.ogg": "un parachute", "parakeet.ogg": "une perruche", "parrot.ogg": "un perroquet", "patch.ogg": "une pièce", "path.ogg": "un chemin", "paw.ogg": "une patte", "pea.ogg": "un petit pois", "peach.ogg": "une pêche", "peacock.ogg": "un paon", "peak.ogg": "un pic", "pear.ogg": "une poire", "pearl.ogg": "une perle", "peck.ogg": "picorer", "pedal.ogg": "une pédale", "pelican.ogg": "un pélican", "pen.ogg": "un stylo", "pencil.ogg": "un crayon", "peony.ogg": "une pivoine", "people.ogg": "les gens", "pepper.ogg": "le poivre", "peppers.ogg": "un poivron", "petal.ogg": "un pétale", "petite.ogg": "la petite", "phone.ogg": "un téléphone", "piano.ogg": "un piano", "picture.ogg": "une photo", "pie.ogg": "une tarte", "pig.ogg": "un cochon", "pigeon.ogg": "un pigeon", "pill.ogg": "une pilule", "pillow.ogg": "un oreiller", "pilot.ogg": "un pilote", "pine.ogg": "un pin", "pine_cone.ogg": "une pomme de pin", "pink.ogg": "rose", "pip.ogg": "un pépin", "pipe.ogg": "une pipe", "piranha.ogg": "un piranha", "pirate.ogg": "un pirate", "pizza.ogg": "une pizza", "plane.ogg": "un avion", "planet.ogg": "une planète", "plant.ogg": "une plante", "plate.ogg": "une assiette", "play.ogg": "jouer", "pliers.ogg": "une pince", "plum.ogg": "une prune", "plow.ogg": "labourer", "plumber.ogg": "un plombier", "pocket.ogg": "une poche", "pod.ogg": "une cosse", "pole.ogg": "un poteau", "police.ogg": "un policier", "pompon.ogg": "un pompon", "pond.ogg": "un étang", "pony.ogg": "un poney", "pool.ogg": "une piscine", "pop.ogg": "du pop-corn", "pope.ogg": "le pape", "porthole.ogg": "un hublot", "post.ogg": "une boîte aux lettres", "pot.ogg": "un pot", "potato.ogg": "une pomme de terre", "pounce.ogg": "bondir", "president.ogg": "le président", "pretty.ogg": "jolie", "price.ogg": "le prix", "priest.ogg": "un prêtre", "prince.ogg": "un prince", "princess.ogg": "une princesse", "prison.ogg": "une prison", "prisoner.ogg": "un prisonnier", "prize.ogg": "un trophée", "pug.ogg": "un bouledogue", "pull.ogg": "tirer", "pullover.ogg": "un pull-over", "pumpkin.ogg": "une citrouille", "puppy.ogg": "un chiot", "pyramid.ogg": "une pyramide", "quarrel.ogg": "se quereller", "queen.ogg": "une reine", "question.ogg": "une question", "quilt.ogg": "une couette", "quiz.ogg": "un quiz", "rabbit.ogg": "un lapin", "rabbit_baby.ogg": "un lapereau", "race.ogg": "une course", "radio.ogg": "une radio", "radish.ogg": "un radis", "raft.ogg": "un radeau", "rag.ogg": "un chiffon", "rage.ogg": "la rage", "rain.ogg": "la pluie", "raincoat.ogg": "un imperméable", "rake.ogg": "un râteau", "ramp.ogg": "une rampe", "raspberry.ogg": "une framboise", "rat.ogg": "un rat", "razor.ogg": "un rasoir", "read.ogg": "lire", "red.ogg": "rouge", "reptile.ogg": "un reptile", "rhinoceros.ogg": "un rhinocéros", "rice.ogg": "le riz", "rifle.ogg": "un fusil", "right.ogg": "la droite", "rise.ogg": "augmenter", "river.ogg": "une rivière", "road.ogg": "une route", "roast.ogg": "un rôti", "robot.ogg": "un robot", "rock.ogg": "un caillou", "rocket.ogg": "une fusée", "rolling_pin.ogg": "un rouleau", "roof.ogg": "un toit", "room.ogg": "une pièce", "root.ogg": "une racine", "rope.ogg": "une corde", "rose.ogg": "une rose", "round.ogg": "un rond", "rowing.ogg": "un aviron", "royal.ogg": "royal", "rug.ogg": "un tapis", "run.ogg": "courir", "sad.ogg": "triste", "saddle.ogg": "une selle", "sail.ogg": "un voilier", "sailor.ogg": "un marin", "salamander.ogg": "une salamandre", "salmon.ogg": "un saumon", "sand.ogg": "le sable", "sandals.ogg": "une sandale", "sandwich.ogg": "un sandwich", "sash.ogg": "une ceinture", "sat.ogg": "s'asseoir", "sauce.ogg": "une sauce", "sausage.ogg": "une saucisse", "scale.ogg": "une balance", "scar.ogg": "une cicatrice", "scared.ogg": "effrayé", "scarf.ogg": "une écharpe", "school.ogg": "une école", "school_bag.ogg": "un sac", "science.ogg": "la science", "scissors.ogg": "un ciseau", "scorpion.ogg": "un scorpion", "scratch.ogg": "griffer", "scream.ogg": "crier", "screw.ogg": "une vis", "screwdriver.ogg": "un tournevis", "scribble.ogg": "gribouiller", "sea.ogg": "la mer", "seat.ogg": "un siège", "see.ogg": "voir", "seed.ogg": "une graine", "shadow.ogg": "une ombre", "shake.ogg": "secouer", "shark.ogg": "un requin", "shave.ogg": "se raser", "shed.ogg": "un hangar", "sheep.ogg": "un mouton", "shelf.ogg": "une étagère", "shell.ogg": "un coquillage", "ship.ogg": "un bateau", "shirt.ogg": "une chemise", "shoe.ogg": "une chaussure", "shoelace.ogg": "un lacet", "shop.ogg": "un magasin", "shore.ogg": "un rivage", "short.ogg": "un short", "shovel.ogg": "une pelle", "shower.ogg": "une douche", "shrimp.ogg": "une crevette", "shrub.ogg": "un arbuste", "shut.ogg": "fermé", "shutter.ogg": "un volet", "sick.ogg": "malade", "sidewalk.ogg": "un trottoir", "sign.ogg": "un panneau", "sing.ogg": "chanter", "sink.ogg": "un évier", "sip.ogg": "siroter", "sister.ogg": "une soeur", "sit.ogg": "s'asseoir", - "sixteen.ogg": "seize", "skate.ogg": "un skate", "skeleton.ogg": "un squelette", "ski.ogg": "le ski", "skimmer.ogg": "une écumoire", "skin.ogg": "la peau", "skirt.ogg": "une jupe", "skunk.ogg": "une mouffette", "sky.ogg": "le ciel", "slam.ogg": "smasher", "sled.ogg": "une luge", "sleep.ogg": "dormir", "sleeve.ogg": "une manche", "sleigh.ogg": "un traîneau", "slide.ogg": "un toboggan", "slim.ogg": "mince", "slime.ogg": "la bave", "slippers.ogg": "un chausson", "slope.ogg": "une pente", "sloppy.ogg": "trempé", "slot.ogg": "une fente", "sloth.ogg": "un paresseux", "slug.ogg": "une limace", "small.ogg": "le petit", "smell.ogg": "sentir", "smile.ogg": "un sourire", "smock.ogg": "une blouse", "smoke.ogg": "la fumée", "smooch.ogg": "s'embrasser", "snail.ogg": "un escargot", "snake.ogg": "un serpent", "sneaker.ogg": "une basket", "sniff.ogg": "renifler", "snow.ogg": "la neige", "soap.ogg": "le savon", "sob.ogg": "sangloter", "sock.ogg": "une chaussette", "soldier.ogg": "un soldat", "sole.ogg": "une sole", "sole_shoe.ogg": "une semelle", "son.ogg": "un fils", "soup.ogg": "une soupe", "spade.ogg": "une bêche", "spaghetti.ogg": "un spaghetti", "spark.ogg": "une étincelle", "sparrow.ogg": "un moineau", "spatula.ogg": "une spatule", "speak.ogg": "parler", "spear.ogg": "une lance", "spice.ogg": "un épice", "spider.ogg": "une araignée", "spider_web.ogg": "une toile d'araignée", "spike.ogg": "un hérisson", "spill.ogg": "répandre", "spinach.ogg": "un épinard", "spine.ogg": "une colonne vertébrale", "spinning_top.ogg": "une toupie", "splash.ogg": "un jet", "splatter.ogg": "une éclaboussure", "sponge.ogg": "une éponge", "spool.ogg": "une bobine", "spoon.ogg": "une cuillère", "sport.ogg": "le sport", "spot.ogg": "une tâche", "spray.ogg": "pulvériser", "spread.ogg": "étaler", "spring.ogg": "bondir", "spring_season.ogg": "le printemps", "square.ogg": "un carré", "squash.ogg": "une courge", "squat.ogg": "s'accroupir", "squid.ogg": "un calmar", "squirrel.ogg": "un écureuil", "stack.ogg": "une pile", "stage.ogg": "une scène", "staircase.ogg": "un escalier", "stamp.ogg": "un timbre", "stand.ogg": "debout", "star.ogg": "une étoile", "stare.ogg": "un regard", "starfish.ogg": "une étoile de mer", "steak.ogg": "un steak", "steam.ogg": "la vapeur", "steep.ogg": "raide", "steeple.ogg": "un clocher", "stem.ogg": "une tige", "step.ogg": "une marche", "stew.ogg": "un ragoût", "stick.ogg": "une branche", "sting.ogg": "piquer", "stinky.ogg": "puant", "stitch.ogg": "coudre", "stomach.ogg": "un estomac", "stone.ogg": "une pierre", "stop.ogg": "arrêter", "store.ogg": "un magasin", "stove.ogg": "une cuisinière", "straight.ogg": "droit", "strainer.ogg": "une passoire", "straw.ogg": "une paille", "strawberry.ogg": "une fraise", "stream.ogg": "une rivière", "street.ogg": "une rue", "stretch.ogg": "s'étirer", "string.ogg": "une ficelle", "stripe.ogg": "une bande", "strong.ogg": "fort", "student.ogg": "un étudiant", "study.ogg": "étudier", "stump.ogg": "une souche", "sugar.ogg": "un sucre", "suit.ogg": "un costume", "suitcase.ogg": "une valise", "summer.ogg": "un été", "summit.ogg": "un sommet", "sun.ogg": "le soleil", "swan.ogg": "un cygne", "sweat.ogg": "transpirer", "sweatshirt.ogg": "un sweat-shirt", "swim.ogg": "nager", "table.ogg": "une table", "tablecloth.ogg": "une nappe", "tadpole.ogg": "un têtard", "tag.ogg": "une étiquette", "tail.ogg": "une queue", "tall.ogg": "grand", "tape_measure.ogg": "un mètre", "taxi.ogg": "un taxi", "teach.ogg": "enseigner", "teacher.ogg": "un professeur", "tear.ogg": "déchirer", "teddy.ogg": "une peluche", "teeth.ogg": "les dents", "television.ogg": "une télévision", "temple.ogg": "un temple", "tennis.ogg": "le tennis", "tent.ogg": "une tente", "text.ogg": "un texte", "thick.ogg": "épais", "thief.ogg": "un voleur", "thigh.ogg": "une cuisse", "think.ogg": "penser", "thread.ogg": "une bobine", "throat.ogg": "la gorge", "throw.ogg": "envoyer", "thumb.ogg": "un pouce", "ticket.ogg": "un billet", "tiger.ogg": "un tigre", "time.ogg": "le temps", "tin.ogg": "une conserve", "tire.ogg": "un pneu", "tired.ogg": "fatigué", "tissue.ogg": "un mouchoir", "toad.ogg": "un crapaud", "toaster.ogg": "un grille-pain", "toe.ogg": "un orteil", "toilet.ogg": "les toilettes", "tomatoe.ogg": "une tomate", "tongs.ogg": "une pince", "tongue.ogg": "une langue", "tool.ogg": "un outil", "top.ogg": "dessus", "torch.ogg": "une torche", "touch.ogg": "toucher", "towel.ogg": "une serviette", "toy.ogg": "un jouet", "trail.ogg": "une piste", "train.ogg": "un train", "train_station.ogg": "une gare", "trap.ogg": "un piège", "trash.ogg": "la saleté", "tray.ogg": "un plateau", "treat.ogg": "un bonbon", "tree.ogg": "un arbre", "triangle.ogg": "un triangle", "tribe.ogg": "une tribu", "trip.ogg": "un voyage", "truck.ogg": "un camion", "tube.ogg": "un rouge à lèvres", "tulip.ogg": "une tulipe", "tune.ogg": "un air de musique", "turkey.ogg": "une dinde", "turnip.ogg": "un navet", "turtle.ogg": "une tortue", "tusk.ogg": "une défense", - "twelve.ogg": "douze", "twin_boys.ogg": "un jumeau", "twin_girls.ogg": "une jumelle", "umbrella.ogg": "un parapluie", "under.ogg": "sous", "uniform.ogg": "un uniforme", "van.ogg": "un fourgon", "vase.ogg": "un vase", "vegetable.ogg": "un légume", "vein.ogg": "une veine", "verdure.ogg": "la verdure", "vest.ogg": "un gilet", "vet.ogg": "un vétérinaire", "viper.ogg": "une vipère", "vowel.ogg": "une voyelle", "vulture.ogg": "un vautour", "wag.ogg": "remuer la queue", "walk.ogg": "marcher", "wall.ogg": "un mur", "walnut.ogg": "une noix", "wart.ogg": "une verrue", "wasp.ogg": "une guêpe", "watch.ogg": "une montre", "water.ogg": "de l'eau", "wave.ogg": "une vague", "wedding.ogg": "un mariage", "wedge.ogg": "une cale", "weight.ogg": "un poids", "wet.ogg": "humide", "whale.ogg": "une baleine", "wheat.ogg": "le blé", "wheel.ogg": "une roue", "whisk.ogg": "un fouet", "whisper.ogg": "chuchoter", "white.ogg": "blanc", "wide.ogg": "large", "wig.ogg": "une perruque", "win.ogg": "gagner", "wind.ogg": "le vent", "window.ogg": "une fenêtre", "window_glass.ogg": "une vitre", "wing.ogg": "une aile", "winter.ogg": "un hiver", "wolf.ogg": "un loup", "woman.ogg": "une femme", "wood.ogg": "le bois", "word.ogg": "un mot", "worker.ogg": "un travailleur", "world.ogg": "le monde", "wreath.ogg": "une couronne", "wrench.ogg": "une clé", "wrist.ogg": "un poignet", "write.ogg": "écrire", "yellow.ogg": "jaune", "yogurt.ogg": "un yaourt", "yum.ogg": "miam-miam", "zebra.ogg": "un zèbre", "zipper.ogg": "une fermeture éclair", "zoo.ogg": "un zoo", "U0030.ogg": "zéro", "U0031.ogg": "un", "U0032.ogg": "deux", "U0033.ogg": "trois", "U0034.ogg": "quatre", "U0035.ogg": "cinq", "U0036.ogg": "six", "U0037.ogg": "sept", "U0038.ogg": "huit", "U0039.ogg": "neuf", - "10.ogg": "dix" + "10.ogg": "dix", + "11.ogg": "onze", + "12.ogg": "douze", + "16.ogg": "seize" } diff --git a/src/activities/imageid/resource/content-it.json b/src/activities/imageid/resource/content-it.json new file mode 100644 index 000000000..247cea85d --- /dev/null +++ b/src/activities/imageid/resource/content-it.json @@ -0,0 +1,582 @@ +{ + "ate.ogg": "", + "bake.ogg": "cucinare", + "bark.ogg": "abbaiare", + "beg.ogg": "pregare", + "bite.ogg": "mordere", + "blink.ogg": "", + "boil.ogg": "bollire", + "break.ogg": "", + "call.ogg": "chiamare", + "catch.ogg": "pescare", + "centipede.ogg": "il centipede", + "chat.ogg": "bisbigliare", + "chop.ogg": "affettare", + "clap.ogg": "", + "clean.ogg": "", + "crawl.ogg": "gattonare", + "croak.ogg": "gracidare", + "cry.ogg": "piangere", + "cut.ogg": "tagliare", + "dig.ogg": "scavare", + "drank.ogg": "bere", + "draw.ogg": "disegnare", + "dream.ogg": "sognare", + "drive.ogg": "guida", + "drool.ogg": "sbava", + "dry.ogg": "", + "eat.ogg": "mangiare", + "fell.ogg": "", + "fetch.ogg": "riportare", + "find.ogg": "trovare", + "float.ogg": "galleggiare", + "fly.ogg": "volare", + "freeze.ogg": "congelare", + "growl.ogg": "ringhiare", + "hatch.ogg": "schiudere", + "hear.ogg": "ascoltare", + "howl.ogg": "ululare", + "hug.ogg": "abbracciare", + "jump.ogg": "saltare", + "kneel.ogg": "", + "knit.ogg": "lavorare ai ferri", + "lick.ogg": "leccare", + "look.ogg": "guardare", + "meet.ogg": "incontrare", + "nap.ogg": "pisolare", + "peck.ogg": "beccare", + "play.ogg": "giocare", + "plow.ogg": "dissodare", + "pounce.ogg": "", + "quarrel.ogg": "litigare", + "read.ogg": "leggere", + "rip.ogg": "strappato", + "run.ogg": "corre", + "sat.ogg": "", + "scared.ogg": "", + "scratch.ogg": "", + "scream.ogg": "urlare", + "scribble.ogg": "lo scarabocchio", + "see.ogg": "vedere", + "shake.ogg": "", + "sing.ogg": "cantare", + "sip.ogg": "succhiare", + "sit.ogg": "sedere", + "sleep.ogg": "dormire", + "smell.ogg": "", + "smooch.ogg": "", + "sniff.ogg": "annusare", + "spill.ogg": "", + "splash.ogg": "", + "spray.ogg": "spruzzare", + "spread.ogg": "spalmare", + "spring.ogg": "", + "squat.ogg": "", + "sting.ogg": "pungere", + "stop.ogg": "", + "stretch.ogg": "", + "study.ogg": "studiare", + "teach.ogg": "insegnare", + "tear.ogg": "strappare", + "think.ogg": "pensare", + "touch.ogg": "toccare", + "wag.ogg": "", + "walk.ogg": "camminare", + "wash.ogg": "", + "whisper.ogg": "sussurrare", + "win.ogg": "", + "back.ogg": "la schiena", + "braid.ogg": "la treccia", + "brain.ogg": "il cervello", + "bump.ogg": "il bernoccolo", + "chin.ogg": "il mento", + "ear.ogg": "l'orecchio", + "face.ogg": "la faccia", + "feet.ogg": "i piedi", + "fist.ogg": "il pugno", + "foot.ogg": "il piede", + "grin.ogg": "il ghigno", + "hair.ogg": "i capelli", + "hand.ogg": "la mano", + "head.ogg": "la testa", + "hip.ogg": "i fianchi", + "knee.ogg": "il ginocchio", + "lap.ogg": "il grembo", + "lip.ogg": "le labbra", + "mouth.ogg": "la bocca", + "neck.ogg": "il collo", + "nose.ogg": "il naso", + "scar.ogg": "la cicatrice", + "skin.ogg": "la pelle", + "stare.ogg": "lo sguardo", + "sweat.ogg": "il sudore", + "teeth.ogg": "i denti", + "thigh.ogg": "la coscia", + "throat.ogg": "la gola", + "wrist.ogg": "il polso", + "bib.ogg": "il bavaglino", + "cap.ogg": "il cappellino", + "cape.ogg": "il mantello", + "coat.ogg": "il cappotto", + "dress.ogg": "il vestito", + "glove.ogg": "i guanti", + "hat.ogg": "il cappello", + "patch.ogg": "la toppa", + "scarf.ogg": "la sciarpa", + "shirt.ogg": "la camicia", + "shoe.ogg": "la scarpa", + "short.ogg": "i pantaloni corti", + "skirt.ogg": "la gonna", + "sleeve.ogg": "la manica", + "smock.ogg": "", + "sneaker.ogg": "la scarpa da tennis", + "sock.ogg": "il calzino", + "suit.ogg": "l'abito", + "zoo.ogg": "lo zoo", + "danger.ogg": "", + "frown.ogg": "", + "fun.ogg": "il divertimento", + "mad.ogg": "la follia", + "rage.ogg": "la rabbia", + "sad.ogg": "la tristezza", + "smile.ogg": "il sorriso", + "whisk.ogg": "", + "chief.ogg": "", + "clown.ogg": "il pagliaccio", + "coach.ogg": "l'allenatrice", + "cowboy.ogg": "il cowboy", + "hunter.ogg": "il cacciatore", + "judge.ogg": "il giudice", + "knight.ogg": "il cavaliere", + "lad.ogg": "", + "pope.ogg": "il papa", + "prince.ogg": "il principe", + "princess.ogg": "la principessa", + "queen.ogg": "la regina", + "teacher.ogg": "la maestra", + "vet.ogg": "il veterinario", + "boy.ogg": "il ragazzo", + "bride.ogg": "la sposa", + "brother.ogg": "il fratello", + "child.ogg": "il bambino", + "dad.ogg": "il papà", + "friend.ogg": "gli amici", + "girl.ogg": "la ragazza", + "gnome.ogg": "lo gnomo", + "mate.ogg": "", + "men.ogg": "gli uomini", + "pal.ogg": "", + "athlete.ogg": "l'atleta", + "ballet.ogg": "il balletto", + "camp.ogg": "", + "cheer.ogg": "", + "climb.ogg": "", + "dance.ogg": "", + "dive.ogg": "", + "explore.ogg": "", + "hike.ogg": "", + "hit.ogg": "", + "hop.ogg": "", + "jog.ogg": "correre", + "lift.ogg": "sollevare i pesi", + "ran.ogg": "", + "ride.ogg": "andare in bicicletta", + "skate.ogg": "pattinare", + "ski.ogg": "sciare", + "sport.ogg": "sport", + "swim.ogg": "nuotare", + "write.ogg": "", + "alligator.ogg": "l'alligatore", + "animal.ogg": "gli animali", + "bait.ogg": "", + "bat.ogg": "il pipistrello", + "bee.ogg": "l'ape", + "beetle.ogg": "lo scarabeo", + "bird.ogg": "l'uccello", + "bug.ogg": "l'insetto", + "camel.ogg": "il cammello", + "cat.ogg": "il gatto", + "chick.ogg": "il pulcino", + "chicken.ogg": "la gallina", + "chimp.ogg": "la scimmia", + "clam.ogg": "la conchiglia", + "claw.ogg": "gli artigli", + "cow.ogg": "la mucca", + "crab.ogg": "il granchio", + "crocodile.ogg": "il coccodrillo", + "crow.ogg": "il corvo", + "den.ogg": "la tana", + "dog.ogg": "il cane", + "dragon.ogg": "il drago", + "duck.ogg": "l'anatra", + "fin.ogg": "la pinna", + "fish.ogg": "il pesce", + "flies.ogg": "la mosca", + "fox.ogg": "la volpe", + "frog.ogg": "la rana", + "fur.ogg": "la pelliccia", + "giraffe.ogg": "la giraffa", + "goat.ogg": "la capra", + "hen.ogg": "la gallina", + "herd.ogg": "il gregge", + "hound.ogg": "il segugio", + "lamb.ogg": "l'agnello", + "mane.ogg": "la criniera", + "mice.ogg": "i topi", + "mole.ogg": "la talpa", + "mosquito.ogg": "la zanzara", + "mule.ogg": "il mulo", + "owl.ogg": "il gufo", + "ox.ogg": "il bue", + "paw.ogg": "", + "pet.ogg": "", + "pig.ogg": "il maiale", + "pug.ogg": "", + "puppy.ogg": "il cucciolo", + "rat.ogg": "il ratto", + "shark.ogg": "il pescecane", + "shell.ogg": "la conchiglia", + "shrimp.ogg": "il gambero", + "skunk.ogg": "la puzzola", + "slime.ogg": "la bava", + "snail.ogg": "la lumaca", + "snake.ogg": "il serpente", + "spider.ogg": "il ragno", + "spike.ogg": "gli aculei", + "squid.ogg": "il calamaro", + "squirrel.ogg": "lo scoiattolo", + "starfish.ogg": "la stella di mare", + "swan.ogg": "il cigno", + "tick.ogg": "la zecca", + "wing.ogg": "l'ala", + "yum.ogg": "", + "bone.ogg": "l'osso", + "bread.ogg": "il pane", + "bun.ogg": "il panino", + "cake.ogg": "il dolce", + "candy.ogg": "la caramella", + "cheese.ogg": "il formaggio", + "chocolate.ogg": "il cioccolato", + "cookie.ogg": "i biscotti", + "crumb.ogg": "la briciola", + "crust.ogg": "la crosta", + "drink.ogg": "il caffè", + "feast.ogg": "", + "flour.ogg": "la farina", + "food.ogg": "", + "fudge.ogg": "", + "gum.ogg": "la gomma da masticare", + "ice.ogg": "il ghiaccio", + "juice.ogg": "il succo d'arancia", + "lunch.ogg": "la merenda", + "pop.ogg": "", + "rice.ogg": "il riso", + "sandwich.ogg": "il panino", + "sauce.ogg": "la salsa", + "snack.ogg": "", + "spaghetti.ogg": "gli spaghetti", + "sprinkle.ogg": "", + "stew.ogg": "lo stufato", + "treat.ogg": "", + "cherry.ogg": "le ciliegie", + "fruit.ogg": "la frutta", + "lime.ogg": "il lime", + "orange.ogg": "l'arancio", + "peach.ogg": "la pesca", + "plum.ogg": "la prugna", + "bay.ogg": "la baia", + "beach.ogg": "la spiaggia", + "cave.ogg": "la grotta", + "cliff.ogg": "il burrone", + "cloud.ogg": "la nuvola", + "cold.ogg": "", + "dirt.ogg": "", + "dune.ogg": "la duna", + "earth.ogg": "la terra", + "fire.ogg": "il fuoco", + "flame.ogg": "la fiamma", + "garden.ogg": "il giardino", + "gem.ogg": "", + "ground.ogg": "la terra", + "heat.ogg": "il caldo", + "hole.ogg": "il buco", + "lake.ogg": "il lago", + "land.ogg": "la terra", + "ledge.ogg": "", + "mud.ogg": "il fango", + "night.ogg": "la notte", + "ocean.ogg": "l'oceano", + "path.ogg": "il sentiero", + "rock.ogg": "la roccia", + "sand.ogg": "la sabbia", + "shore.ogg": "il bagnasciuga", + "sky.ogg": "il cielo", + "slope.ogg": "", + "smoke.ogg": "il fumo", + "snow.ogg": "la neve", + "star.ogg": "la stella", + "stone.ogg": "la pietra", + "stream.ogg": "il vapore", + "summer.ogg": "l'estate", + "sun.ogg": "il sole", + "time.ogg": "il tempo", + "top.ogg": "la cima", + "trail.ogg": "", + "water.ogg": "l'acqua", + "wind.ogg": "il vento", + "yarn.ogg": "", + "angel.ogg": "", + "bit.ogg": "il bocconcino", + "class.ogg": "i compiti", + "price.ogg": "il prezzo", + "question.ogg": "la domanda", + "quiz.ogg": "quiz", + "science.ogg": "la scienza", + "splatter.ogg": "", + "tune.ogg": "le note", + "branch.ogg": "il ramo", + "bud.ogg": "la gemma", + "bush.ogg": "il cespuglio", + "flower.ogg": "il fiore", + "grass.ogg": "l'erba", + "hay.ogg": "la paglia", + "hedge.ogg": "la siepe", + "lawn.ogg": "il prato", + "pine.ogg": "il pino", + "plant.ogg": "la pianta", + "rose.ogg": "la rosa", + "seed.ogg": "il seme", + "shrub.ogg": "", + "stem.ogg": "lo stelo", + "stick.ogg": "", + "stump.ogg": "il ceppo", + "tree.ogg": "l'albero", + "carrot.ogg": "la carota", + "corn.ogg": "la pannocchia", + "cucumber.ogg": "il cetriolo", + "mushroom.ogg": "il fungo", + "nut.ogg": "l'arachide", + "squash.ogg": "la zucca", + "bank.ogg": "la banca", + "barn.ogg": "il fienile", + "bridge.ogg": "il ponte", + "cabin.ogg": "", + "cage.ogg": "la gabbia", + "castle.ogg": "il castello", + "door.ogg": "la porta", + "fair.ogg": "", + "fountain.ogg": "la fontana", + "grave.ogg": "la tomba", + "home.ogg": "la casa", + "hut.ogg": "la capanna", + "lane.ogg": "la strada", + "pool.ogg": "la piscina", + "ramp.ogg": "la rampa", + "roof.ogg": "il tetto", + "school.ogg": "la scuola", + "shed.ogg": "", + "shop.ogg": "il negozio", + "stage.ogg": "il palco", + "store.ogg": "il negozio", + "street.ogg": "la via", + "strawberry.ogg": "la fragola", + "bath.ogg": "la vasca da bagno", + "bed.ogg": "il letto", + "bench.ogg": "la panchina", + "chair.ogg": "la sedia", + "chest.ogg": "il forziere", + "couch.ogg": "il divano", + "crib.ogg": "la culla", + "desk.ogg": "la scrivania", + "fan.ogg": "il ventilatore", + "lamp.ogg": "la lampada", + "light.ogg": "la luce", + "mat.ogg": "il tappetino", + "quilt.ogg": "la trapunta", + "rug.ogg": "il tappeto", + "seat.ogg": "la sedia a dondolo", + "shelf.ogg": "lo scaffale", + "shower.ogg": "la doccia", + "sink.ogg": "il lavandino", + "stove.ogg": "la cucina", + "toilet.ogg": "il gabinetto", + "balance.ogg": "la bilancia", + "can.ogg": "i barattoli", + "clock.ogg": "la sveglia", + "dish.ogg": "la zuppiera", + "fork.ogg": "la forchetta", + "glass.ogg": "il bicchiere", + "knife.ogg": "il coltello", + "lid.ogg": "il coperchio", + "mop.ogg": "", + "mug.ogg": "la tazza", + "pan.ogg": "la padella", + "plate.ogg": "il piatto", + "pot.ogg": "la pentola", + "scale.ogg": "la bilancia", + "sponge.ogg": "la spugna", + "spoon.ogg": "il cucchiaio", + "trash.ogg": "la spazzatura", + "tray.ogg": "il vassoio", + "farm.ogg": "la fattoria", + "anchor.ogg": "l'ancora", + "badge.ogg": "la medaglia", + "bag.ogg": "lo zaino", + "ball.ogg": "la palla", + "bead.ogg": "la perlina", + "block.ogg": "il cubo", + "board.ogg": "il cartello", + "bomb.ogg": "la bomba", + "book.ogg": "il libro", + "box.ogg": "la scatola", + "candle.ogg": "la candela", + "cane.ogg": "il bastone", + "card.ogg": "la cartolina", + "cart.ogg": "il carrello", + "cash.ogg": "i soldi", + "chalk.ogg": "il gesso", + "clay.ogg": "l'argilla", + "cloth.ogg": "il tessuto", + "coin.ogg": "le monete", + "comb.ogg": "il pettine", + "cone.ogg": "", + "crown.ogg": "la corona", + "cube.ogg": "il cubo", + "drum.ogg": "il tamburo", + "flag.ogg": "la bandiera", + "flute.ogg": "il flauto", + "game.ogg": "il giocattolo", + "gift.ogg": "il regalo", + "glue.ogg": "la colla", + "hook.ogg": "l'amo", + "hose.ogg": "", + "ink.ogg": "l'inchiostro", + "jewel.ogg": "il gioiello", + "kite.ogg": "l'aquilone", + "knot.ogg": "il nodo", + "log.ogg": "i ceppi", + "map.ogg": "la mappa", + "mask.ogg": "la maschera da sub", + "match.ogg": "i fiammiferi", + "nest.ogg": "il nido", + "net.ogg": "la rete", + "oar.ogg": "i remi", + "page.ogg": "la pagina", + "pair.ogg": "un paio", + "pen.ogg": "la penna", + "pencil.ogg": "la matita", + "picture.ogg": "il quadro", + "pole.ogg": "il palo", + "prize.ogg": "il premio", + "rag.ogg": "lo strofinaccio", + "rope.ogg": "la corda", + "sign.ogg": "il cartello", + "sleigh.ogg": "la slitta", + "slide.ogg": "lo scivolo", + "squirt.ogg": "", + "stack.ogg": "una pila", + "stamp.ogg": "il francobollo", + "straw.ogg": "la cannuccia", + "string.ogg": "lo spago", + "tag.ogg": "il cartellino", + "thread.ogg": "il filo", + "torch.ogg": "la torcia", + "towel.ogg": "l'asciugamano", + "toy.ogg": "il giocattolo", + "trap.ogg": "la trappola", + "tube.ogg": "il rossetto", + "watch.ogg": "l'orologio da polso", + "wheel.ogg": "la ruota", + "wig.ogg": "la parrucca", + "wood.ogg": "il legno", + "link.ogg": "l'anello", + "dirty.ogg": "sporco", + "throw.ogg": "lanciare", + "brick.ogg": "i mattoni", + "brush.ogg": "il pennello", + "flash.ogg": "la torcia elettrica", + "rake.ogg": "il rastrello", + "screw.ogg": "la vite", + "spear.ogg": "la lancia", + "tool.ogg": "gli attrezzi", + "wedge.ogg": "il cuneo", + "wrench.ogg": "la chiave inglese", + "bike.ogg": "la bicicletta", + "boat.ogg": "la barca", + "canoe.ogg": "la canoa", + "car.ogg": "l'automobile", + "plane.ogg": "l'aeroplano", + "sail.ogg": "la vela", + "ship.ogg": "la nave", + "sled.ogg": "la slitta", + "train.ogg": "il treno", + "truck.ogg": "il camion", + "black.ogg": "nero", + "blue.ogg": "blu", + "brown.ogg": "marrone", + "color.ogg": "", + "gray.ogg": "grigio", + "green.ogg": "verde", + "orange-color.ogg": "arancione", + "pink.ogg": "rosa", + "red.ogg": "rosso", + "white.ogg": "bianco", + "five.ogg": "cinque", + "one.ogg": "uno", + "ten.ogg": "dieci", + "three.ogg": "tre", + "two.ogg": "due", + "van.ogg": "", + "big.ogg": "", + "blind.ogg": "", + "blond.ogg": "", + "bright.ogg": "", + "crazy.ogg": "", + "cute.ogg": "", + "dot.ogg": "", + "empty.ogg": "", + "fat.ogg": "", + "flat.ogg": "", + "front.ogg": "", + "full.ogg": "", + "giant.ogg": "", + "happy.ogg": "", + "high.ogg": "", + "hot.ogg": "", + "huge.ogg": "", + "left.ogg": "", + "line.ogg": "", + "liquid.ogg": "", + "magic.ogg": "", + "on.ogg": "", + "pretty.ogg": "", + "right.ogg": "", + "round.ogg": "", + "royal.ogg": "", + "shut.ogg": "", + "sick.ogg": "", + "small.ogg": "", + "spot.ogg": "", + "square.ogg": "", + "stand.ogg": "", + "straight.ogg": "", + "stripe.ogg": "", + "strong.ogg": "", + "tall.ogg": "", + "thick.ogg": "", + "tired.ogg": "", + "under.ogg": "", + "wet.ogg": "", + "wheat.ogg": "", + "U0030.ogg": "zero", + "U0031.ogg": "uno", + "U0032.ogg": "due", + "U0033.ogg": "tre", + "U0034.ogg": "quattro", + "U0035.ogg": "cinque", + "U0036.ogg": "sei", + "U0037.ogg": "sette", + "U0038.ogg": "otto", + "U0039.ogg": "nove", + "10.ogg": "dieci" +} diff --git a/src/activities/imageid/resource/words.json b/src/activities/imageid/resource/words.json index 1925a13c9..a8d06527b 100644 --- a/src/activities/imageid/resource/words.json +++ b/src/activities/imageid/resource/words.json @@ -1,5700 +1,5700 @@ [ { "type": "chapter", "name": "other", "content": [ { "type": "lesson", "name": "other", "content": [ { "description": "alphabet", "image": "words/alphabet.png", "voice": "voices-$CA/$LOCALE/words/alphabet.$CA" }, { "description": "bit", "image": "words/bit.png", "voice": "voices-$CA/$LOCALE/words/bit.$CA" }, { "description": "bubble", "image": "words/bubble.png", "voice": "voices-$CA/$LOCALE/words/bubble.$CA" }, { "description": "carnival", "image": "words/carnival.png", "voice": "voices-$CA/$LOCALE/words/carnival.$CA" }, { "description": "craft", "image": "words/craft.png", "voice": "voices-$CA/$LOCALE/words/craft.$CA" }, { "description": "link", "image": "words/link.png", "voice": "voices-$CA/$LOCALE/words/link.$CA" }, { "description": "number", "image": "words/number.png", "voice": "voices-$CA/$LOCALE/words/number.$CA" }, { "description": "question", "image": "words/question.png", "voice": "voices-$CA/$LOCALE/words/question.$CA" }, { "description": "quiz", "image": "words/quiz.png", "voice": "voices-$CA/$LOCALE/words/quiz.$CA" }, { "description": "science", "image": "words/science.png", "voice": "voices-$CA/$LOCALE/words/science.$CA" }, { "description": "splatter", "image": "words/splatter.png", "voice": "voices-$CA/$LOCALE/words/splatter.$CA" }, { "description": "text", "image": "words/text.png", "voice": "voices-$CA/$LOCALE/words/text.$CA" }, { "description": "tune", "image": "words/tune.png", "voice": "voices-$CA/$LOCALE/words/tune.$CA" }, { "description": "vowel", "image": "words/vowel.png", "voice": "voices-$CA/$LOCALE/words/vowel.$CA" }, { "description": "weight", "image": "words/weight.png", "voice": "voices-$CA/$LOCALE/words/weight.$CA" }, { "description": "word", "image": "words/word.png", "voice": "voices-$CA/$LOCALE/words/word.$CA" } ] }, { "type": "lesson", "name": "action", "content": [ { "description": "ate", "image": "words/ate.png", "voice": "voices-$CA/$LOCALE/words/ate.$CA" }, { "description": "bake", "image": "words/bake.png", "voice": "voices-$CA/$LOCALE/words/bake.$CA" }, { "description": "bark", "image": "words/bark.png", "voice": "voices-$CA/$LOCALE/words/bark.$CA" }, { "description": "beat", "image": "words/beat.png", "voice": "voices-$CA/$LOCALE/words/beat.$CA" }, { "description": "beg", "image": "words/beg.png", "voice": "voices-$CA/$LOCALE/words/beg.$CA" }, { "description": "bite", "image": "words/bite.png", "voice": "voices-$CA/$LOCALE/words/bite.$CA" }, { "description": "blink", "image": "words/blink.png", "voice": "voices-$CA/$LOCALE/words/blink.$CA" }, { "description": "boil", "image": "words/boil.png", "voice": "voices-$CA/$LOCALE/words/boil.$CA" }, { "description": "break", "image": "words/break.png", "voice": "voices-$CA/$LOCALE/words/break.$CA" }, { "description": "call", "image": "words/call.png", "voice": "voices-$CA/$LOCALE/words/call.$CA" }, { "description": "catch", "image": "words/catch.png", "voice": "voices-$CA/$LOCALE/words/catch.$CA" }, { "description": "chat", "image": "words/chat.png", "voice": "voices-$CA/$LOCALE/words/chat.$CA" }, { "description": "chop", "image": "words/chop.png", "voice": "voices-$CA/$LOCALE/words/chop.$CA" }, { "description": "chores", "image": "words/chores.png", "voice": "voices-$CA/$LOCALE/words/chores.$CA" }, { "description": "clap", "image": "words/clap.png", "voice": "voices-$CA/$LOCALE/words/clap.$CA" }, { "description": "clean", "image": "words/clean.png", "voice": "voices-$CA/$LOCALE/words/clean.$CA" }, { "description": "cough", "image": "words/cough.png", "voice": "voices-$CA/$LOCALE/words/cough.$CA" }, { "description": "crawl", "image": "words/crawl.png", "voice": "voices-$CA/$LOCALE/words/crawl.$CA" }, { "description": "croak", "image": "words/croak.png", "voice": "voices-$CA/$LOCALE/words/croak.$CA" }, { "description": "cry", "image": "words/cry.png", "voice": "voices-$CA/$LOCALE/words/cry.$CA" }, { "description": "cut", "image": "words/cut.png", "voice": "voices-$CA/$LOCALE/words/cut.$CA" }, { "description": "dig", "image": "words/dig.png", "voice": "voices-$CA/$LOCALE/words/dig.$CA" }, { "description": "drank", "image": "words/drank.png", "voice": "voices-$CA/$LOCALE/words/drank.$CA" }, { "description": "draw", "image": "words/draw.png", "voice": "voices-$CA/$LOCALE/words/draw.$CA" }, { "description": "dream", "image": "words/dream.png", "voice": "voices-$CA/$LOCALE/words/dream.$CA" }, { "description": "drinking", "image": "words/drinking.png", "voice": "voices-$CA/$LOCALE/words/drinking.$CA" }, { "description": "drive", "image": "words/drive.png", "voice": "voices-$CA/$LOCALE/words/drive.$CA" }, { "description": "drool", "image": "words/drool.png", "voice": "voices-$CA/$LOCALE/words/drool.$CA" }, { "description": "dry", "image": "words/dry.png", "voice": "voices-$CA/$LOCALE/words/dry.$CA" }, { "description": "eat", "image": "words/eat.png", "voice": "voices-$CA/$LOCALE/words/eat.$CA" }, { "description": "fall down", "image": "words/fall_down.png", "voice": "voices-$CA/$LOCALE/words/fall_down.$CA" }, { "description": "feed", "image": "words/feed.png", "voice": "voices-$CA/$LOCALE/words/feed.$CA" }, { "description": "fell", "image": "words/fell.png", "voice": "voices-$CA/$LOCALE/words/fell.$CA" }, { "description": "fetch", "image": "words/fetch.png", "voice": "voices-$CA/$LOCALE/words/fetch.$CA" }, { "description": "find", "image": "words/find.png", "voice": "voices-$CA/$LOCALE/words/find.$CA" }, { "description": "flight", "image": "words/flight.png", "voice": "voices-$CA/$LOCALE/words/flight.$CA" }, { "description": "float", "image": "words/float.png", "voice": "voices-$CA/$LOCALE/words/float.$CA" }, { "description": "fly", "image": "words/fly.png", "voice": "voices-$CA/$LOCALE/words/fly.$CA" }, { "description": "freeze", "image": "words/freeze.png", "voice": "voices-$CA/$LOCALE/words/freeze.$CA" }, { "description": "growl", "image": "words/growl.png", "voice": "voices-$CA/$LOCALE/words/growl.$CA" }, { "description": "hatch", "image": "words/hatch.png", "voice": "voices-$CA/$LOCALE/words/hatch.$CA" }, { "description": "hear", "image": "words/hear.png", "voice": "voices-$CA/$LOCALE/words/hear.$CA" }, { "description": "howl", "image": "words/howl.png", "voice": "voices-$CA/$LOCALE/words/howl.$CA" }, { "description": "hug", "image": "words/hug.png", "voice": "voices-$CA/$LOCALE/words/hug.$CA" }, { "description": "jump", "image": "words/jump.png", "voice": "voices-$CA/$LOCALE/words/jump.$CA" }, { "description": "kiss", "image": "words/kiss.png", "voice": "voices-$CA/$LOCALE/words/kiss.$CA" }, { "description": "kneel", "image": "words/kneel.png", "voice": "voices-$CA/$LOCALE/words/kneel.$CA" }, { "description": "knit", "image": "words/knit.png", "voice": "voices-$CA/$LOCALE/words/knit.$CA" }, { "description": "lick", "image": "words/lick.png", "voice": "voices-$CA/$LOCALE/words/lick.$CA" }, { "description": "look", "image": "words/look.png", "voice": "voices-$CA/$LOCALE/words/look.$CA" }, { "description": "meet", "image": "words/meet.png", "voice": "voices-$CA/$LOCALE/words/meet.$CA" }, { "description": "nap", "image": "words/nap.png", "voice": "voices-$CA/$LOCALE/words/nap.$CA" }, { "description": "peck", "image": "words/peck.png", "voice": "voices-$CA/$LOCALE/words/peck.$CA" }, { "description": "play", "image": "words/play.png", "voice": "voices-$CA/$LOCALE/words/play.$CA" }, { "description": "plow", "image": "words/plow.png", "voice": "voices-$CA/$LOCALE/words/plow.$CA" }, { "description": "pounce", "image": "words/pounce.png", "voice": "voices-$CA/$LOCALE/words/pounce.$CA" }, { "description": "pull", "image": "words/pull.png", "voice": "voices-$CA/$LOCALE/words/pull.$CA" }, { "description": "quarrel", "image": "words/quarrel.png", "voice": "voices-$CA/$LOCALE/words/quarrel.$CA" }, { "description": "read", "image": "words/read.png", "voice": "voices-$CA/$LOCALE/words/read.$CA" }, { "description": "rip", "image": "words/rip.png", "voice": "voices-$CA/$LOCALE/words/rip.$CA" }, { "description": "rise", "image": "words/rise.png", "voice": "voices-$CA/$LOCALE/words/rise.$CA" }, { "description": "run", "image": "words/run.png", "voice": "voices-$CA/$LOCALE/words/run.$CA" }, { "description": "sat", "image": "words/sat.png", "voice": "voices-$CA/$LOCALE/words/sat.$CA" }, { "description": "scared", "image": "words/scared.png", "voice": "voices-$CA/$LOCALE/words/scared.$CA" }, { "description": "scratch", "image": "words/scratch.png", "voice": "voices-$CA/$LOCALE/words/scratch.$CA" }, { "description": "scream", "image": "words/scream.png", "voice": "voices-$CA/$LOCALE/words/scream.$CA" }, { "description": "scribble", "image": "words/scribble.png", "voice": "voices-$CA/$LOCALE/words/scribble.$CA" }, { "description": "see", "image": "words/see.png", "voice": "voices-$CA/$LOCALE/words/see.$CA" }, { "description": "shake", "image": "words/shake.png", "voice": "voices-$CA/$LOCALE/words/shake.$CA" }, { "description": "shave", "image": "words/shave.png", "voice": "voices-$CA/$LOCALE/words/shave.$CA" }, { "description": "sing", "image": "words/sing.png", "voice": "voices-$CA/$LOCALE/words/sing.$CA" }, { "description": "sip", "image": "words/sip.png", "voice": "voices-$CA/$LOCALE/words/sip.$CA" }, { "description": "sit", "image": "words/sit.png", "voice": "voices-$CA/$LOCALE/words/sit.$CA" }, { "description": "slam", "image": "words/slam.png", "voice": "voices-$CA/$LOCALE/words/slam.$CA" }, { "description": "sleep", "image": "words/sleep.png", "voice": "voices-$CA/$LOCALE/words/sleep.$CA" }, { "description": "smell", "image": "words/smell.png", "voice": "voices-$CA/$LOCALE/words/smell.$CA" }, { "description": "smooch", "image": "words/smooch.png", "voice": "voices-$CA/$LOCALE/words/smooch.$CA" }, { "description": "sniff", "image": "words/sniff.png", "voice": "voices-$CA/$LOCALE/words/sniff.$CA" }, { "description": "speak", "image": "words/speak.png", "voice": "voices-$CA/$LOCALE/words/speak.$CA" }, { "description": "spill", "image": "words/spill.png", "voice": "voices-$CA/$LOCALE/words/spill.$CA" }, { "description": "splash", "image": "words/splash.png", "voice": "voices-$CA/$LOCALE/words/splash.$CA" }, { "description": "spray", "image": "words/spray.png", "voice": "voices-$CA/$LOCALE/words/spray.$CA" }, { "description": "spread", "image": "words/spread.png", "voice": "voices-$CA/$LOCALE/words/spread.$CA" }, { "description": "spring", "image": "words/spring.png", "voice": "voices-$CA/$LOCALE/words/spring.$CA" }, { "description": "squat", "image": "words/squat.png", "voice": "voices-$CA/$LOCALE/words/squat.$CA" }, { "description": "sting", "image": "words/sting.png", "voice": "voices-$CA/$LOCALE/words/sting.$CA" }, { "description": "stitch", "image": "words/stitch.png", "voice": "voices-$CA/$LOCALE/words/stitch.$CA" }, { "description": "stop", "image": "words/stop.png", "voice": "voices-$CA/$LOCALE/words/stop.$CA" }, { "description": "stretch", "image": "words/stretch.png", "voice": "voices-$CA/$LOCALE/words/stretch.$CA" }, { "description": "study", "image": "words/study.png", "voice": "voices-$CA/$LOCALE/words/study.$CA" }, { "description": "teach", "image": "words/teach.png", "voice": "voices-$CA/$LOCALE/words/teach.$CA" }, { "description": "tear", "image": "words/tear.png", "voice": "voices-$CA/$LOCALE/words/tear.$CA" }, { "description": "think", "image": "words/think.png", "voice": "voices-$CA/$LOCALE/words/think.$CA" }, { "description": "touch", "image": "words/touch.png", "voice": "voices-$CA/$LOCALE/words/touch.$CA" }, { "description": "wag", "image": "words/wag.png", "voice": "voices-$CA/$LOCALE/words/wag.$CA" }, { "description": "walk", "image": "words/walk.png", "voice": "voices-$CA/$LOCALE/words/walk.$CA" }, { "description": "wash", "image": "words/wash.png", "voice": "voices-$CA/$LOCALE/words/wash.$CA" }, { "description": "whisper", "image": "words/whisper.png", "voice": "voices-$CA/$LOCALE/words/whisper.$CA" }, { "description": "win", "image": "words/win.png", "voice": "voices-$CA/$LOCALE/words/win.$CA" }, { "description": "write", "image": "words/write.png", "voice": "voices-$CA/$LOCALE/words/write.$CA" } ] }, { "type": "lesson", "name": "adjective", "content": [ { "description": "behind", "image": "words/behind.png", "voice": "voices-$CA/$LOCALE/words/behind.$CA" }, { "description": "big", "image": "words/big.png", "voice": "voices-$CA/$LOCALE/words/big.$CA" }, { "description": "blind", "image": "words/blind.png", "voice": "voices-$CA/$LOCALE/words/blind.$CA" }, { "description": "blond", "image": "words/blond.png", "voice": "voices-$CA/$LOCALE/words/blond.$CA" }, { "description": "bright", "image": "words/bright.png", "voice": "voices-$CA/$LOCALE/words/bright.$CA" }, { "description": "crazy", "image": "words/crazy.png", "voice": "voices-$CA/$LOCALE/words/crazy.$CA" }, { "description": "cute", "image": "words/cute.png", "voice": "voices-$CA/$LOCALE/words/cute.$CA" }, { "description": "dirty", "image": "words/dirty.png", "voice": "voices-$CA/$LOCALE/words/dirty.$CA" }, { "description": "empty", "image": "words/empty.png", "voice": "voices-$CA/$LOCALE/words/empty.$CA" }, { "description": "fat", "image": "words/fat.png", "voice": "voices-$CA/$LOCALE/words/fat.$CA" }, { "description": "flat", "image": "words/flat.png", "voice": "voices-$CA/$LOCALE/words/flat.$CA" }, { "description": "front", "image": "words/front.png", "voice": "voices-$CA/$LOCALE/words/front.$CA" }, { "description": "full", "image": "words/full.png", "voice": "voices-$CA/$LOCALE/words/full.$CA" }, { "description": "giant", "image": "words/giant.png", "voice": "voices-$CA/$LOCALE/words/giant.$CA" }, { "description": "golden", "image": "words/golden.png", "voice": "voices-$CA/$LOCALE/words/golden.$CA" }, { "description": "half", "image": "words/half.png", "voice": "voices-$CA/$LOCALE/words/half.$CA" }, { "description": "happy", "image": "words/happy.png", "voice": "voices-$CA/$LOCALE/words/happy.$CA" }, { "description": "high", "image": "words/high.png", "voice": "voices-$CA/$LOCALE/words/high.$CA" }, { "description": "hot", "image": "words/hot.png", "voice": "voices-$CA/$LOCALE/words/hot.$CA" }, { "description": "huge", "image": "words/huge.png", "voice": "voices-$CA/$LOCALE/words/huge.$CA" }, { "description": "hunchback", "image": "words/hunchback.png", "voice": "voices-$CA/$LOCALE/words/hunchback.$CA" }, { "description": "ill", "image": "words/ill.png", "voice": "voices-$CA/$LOCALE/words/ill.$CA" }, { "description": "left", "image": "words/left.png", "voice": "voices-$CA/$LOCALE/words/left.$CA" }, { "description": "line", "image": "words/line.png", "voice": "voices-$CA/$LOCALE/words/line.$CA" }, { "description": "liquid", "image": "words/liquid.png", "voice": "voices-$CA/$LOCALE/words/liquid.$CA" }, { "description": "magic", "image": "words/magic.png", "voice": "voices-$CA/$LOCALE/words/magic.$CA" }, { "description": "naked", "image": "words/naked.png", "voice": "voices-$CA/$LOCALE/words/naked.$CA" }, { "description": "on", "image": "words/on.png", "voice": "voices-$CA/$LOCALE/words/on.$CA" }, { "description": "open", "image": "words/open.png", "voice": "voices-$CA/$LOCALE/words/open.$CA" }, { "description": "petite", "image": "words/petite.png", "voice": "voices-$CA/$LOCALE/words/petite.$CA" }, { "description": "pretty", "image": "words/pretty.png", "voice": "voices-$CA/$LOCALE/words/pretty.$CA" }, { "description": "right", "image": "words/right.png", "voice": "voices-$CA/$LOCALE/words/right.$CA" }, { "description": "round", "image": "words/round.png", "voice": "voices-$CA/$LOCALE/words/round.$CA" }, { "description": "royal", "image": "words/royal.png", "voice": "voices-$CA/$LOCALE/words/royal.$CA" }, { "description": "shut", "image": "words/shut.png", "voice": "voices-$CA/$LOCALE/words/shut.$CA" }, { "description": "sick", "image": "words/sick.png", "voice": "voices-$CA/$LOCALE/words/sick.$CA" }, { "description": "slim", "image": "words/slim.png", "voice": "voices-$CA/$LOCALE/words/slim.$CA" }, { "description": "sloppy", "image": "words/sloppy.png", "voice": "voices-$CA/$LOCALE/words/sloppy.$CA" }, { "description": "small", "image": "words/small.png", "voice": "voices-$CA/$LOCALE/words/small.$CA" }, { "description": "spot", "image": "words/spot.png", "voice": "voices-$CA/$LOCALE/words/spot.$CA" }, { "description": "square", "image": "words/square.png", "voice": "voices-$CA/$LOCALE/words/square.$CA" }, { "description": "stand", "image": "words/stand.png", "voice": "voices-$CA/$LOCALE/words/stand.$CA" }, { "description": "steep", "image": "words/steep.png", "voice": "voices-$CA/$LOCALE/words/steep.$CA" }, { "description": "stinky", "image": "words/stinky.png", "voice": "voices-$CA/$LOCALE/words/stinky.$CA" }, { "description": "straight", "image": "words/straight.png", "voice": "voices-$CA/$LOCALE/words/straight.$CA" }, { "description": "stripe", "image": "words/stripe.png", "voice": "voices-$CA/$LOCALE/words/stripe.$CA" }, { "description": "strong", "image": "words/strong.png", "voice": "voices-$CA/$LOCALE/words/strong.$CA" }, { "description": "tall", "image": "words/tall.png", "voice": "voices-$CA/$LOCALE/words/tall.$CA" }, { "description": "thick", "image": "words/thick.png", "voice": "voices-$CA/$LOCALE/words/thick.$CA" }, { "description": "tired", "image": "words/tired.png", "voice": "voices-$CA/$LOCALE/words/tired.$CA" }, { "description": "triangle", "image": "words/triangle.png", "voice": "voices-$CA/$LOCALE/words/triangle.$CA" }, { "description": "under", "image": "words/under.png", "voice": "voices-$CA/$LOCALE/words/under.$CA" }, { "description": "wet", "image": "words/wet.png", "voice": "voices-$CA/$LOCALE/words/wet.$CA" }, { "description": "wide", "image": "words/wide.png", "voice": "voices-$CA/$LOCALE/words/wide.$CA" } ] }, { "type": "lesson", "name": "color", "content": [ { "description": "color", "image": "words/color.png", "voice": "voices-$CA/$LOCALE/words/color.$CA" }, { "description": "blue", "image": "words/blue.png", "voice": "voices-$CA/$LOCALE/words/blue.$CA" }, { "description": "brown", "image": "words/brown.png", "voice": "voices-$CA/$LOCALE/words/brown.$CA" }, { "description": "black", "image": "words/black.png", "voice": "voices-$CA/$LOCALE/words/black.$CA" }, { "description": "gray", "image": "words/gray.png", "voice": "voices-$CA/$LOCALE/words/gray.$CA" }, { "description": "green", "image": "words/green.png", "voice": "voices-$CA/$LOCALE/words/green.$CA" }, { "description": "mauve", "image": "words/mauve.png", "voice": "voices-$CA/$LOCALE/words/mauve.$CA" }, { "description": "orange color", "image": "words/orange-color.png", "voice": "voices-$CA/$LOCALE/words/orange-color.$CA" }, { "description": "pink", "image": "words/pink.png", "voice": "voices-$CA/$LOCALE/words/pink.$CA" }, { "description": "red", "image": "words/red.png", "voice": "voices-$CA/$LOCALE/words/red.$CA" }, { "description": "white", "image": "words/white.png", "voice": "voices-$CA/$LOCALE/words/white.$CA" }, { "description": "yellow", "image": "words/yellow.png", "voice": "voices-$CA/$LOCALE/words/yellow.$CA" } ] }, { "type": "lesson", "name": "number", "content": [ { "description": "zero", "image": "words/zero.png", "voice": "voices-$CA/$LOCALE/alphabet/U0030.$CA" }, { "description": "one", "image": "words/one.png", "voice": "voices-$CA/$LOCALE/alphabet/U0031.$CA" }, { "description": "two", "image": "words/two.png", "voice": "voices-$CA/$LOCALE/alphabet/U0032.$CA" }, { "description": "three", "image": "words/three.png", "voice": "voices-$CA/$LOCALE/alphabet/U0033.$CA" }, { "description": "four", "image": "words/four.png", "voice": "voices-$CA/$LOCALE/alphabet/U0034.$CA" }, { "description": "five", "image": "words/five.png", "voice": "voices-$CA/$LOCALE/alphabet/U0035.$CA" }, { "description": "six", "image": "words/six.png", "voice": "voices-$CA/$LOCALE/alphabet/U0036.$CA" }, { "description": "seven", "image": "words/seven.png", "voice": "voices-$CA/$LOCALE/alphabet/U0037.$CA" }, { "description": "eight", "image": "words/eight.png", "voice": "voices-$CA/$LOCALE/alphabet/U0038.$CA" }, { "description": "nine", "image": "words/nine.png", "voice": "voices-$CA/$LOCALE/alphabet/U0039.$CA" }, { "description": "ten", "image": "words/ten.png", "voice": "voices-$CA/$LOCALE/alphabet/10.$CA" }, { "description": "eleven", "image": "words/eleven.png", - "voice": "voices-$CA/$LOCALE/words/eleven.$CA" + "voice": "voices-$CA/$LOCALE/alphabet/11.$CA" }, { "description": "twelve", "image": "words/twelve.png", - "voice": "voices-$CA/$LOCALE/words/twelve.$CA" + "voice": "voices-$CA/$LOCALE/alphabet/12.$CA" }, { "description": "sixteen", "image": "words/sixteen.png", - "voice": "voices-$CA/$LOCALE/words/sixteen.$CA" + "voice": "voices-$CA/$LOCALE/alphabet/16.$CA" } ] } ] }, { "type": "chapter", "name": "people", "content": [ { "type": "lesson", "name": "bodyparts", "content": [ { "description": "ankle", "image": "words/ankle.png", "voice": "voices-$CA/$LOCALE/words/ankle.$CA" }, { "description": "arm", "image": "words/arm.png", "voice": "voices-$CA/$LOCALE/words/arm.$CA" }, { "description": "back", "image": "words/back.png", "voice": "voices-$CA/$LOCALE/words/back.$CA" }, { "description": "bald", "image": "words/bald.png", "voice": "voices-$CA/$LOCALE/words/bald.$CA" }, { "description": "beard", "image": "words/beard.png", "voice": "voices-$CA/$LOCALE/words/beard.$CA" }, { "description": "belly", "image": "words/belly.png", "voice": "voices-$CA/$LOCALE/words/belly.$CA" }, { "description": "bottom", "image": "words/bottom.png", "voice": "voices-$CA/$LOCALE/words/bottom.$CA" }, { "description": "braid", "image": "words/braid.png", "voice": "voices-$CA/$LOCALE/words/braid.$CA" }, { "description": "brain", "image": "words/brain.png", "voice": "voices-$CA/$LOCALE/words/brain.$CA" }, { "description": "breast", "image": "words/breast.png", "voice": "voices-$CA/$LOCALE/words/breast.$CA" }, { "description": "bump", "image": "words/bump.png", "voice": "voices-$CA/$LOCALE/words/bump.$CA" }, { "description": "cheek", "image": "words/cheek.png", "voice": "voices-$CA/$LOCALE/words/cheek.$CA" }, { "description": "chin", "image": "words/chin.png", "voice": "voices-$CA/$LOCALE/words/chin.$CA" }, { "description": "ear", "image": "words/ear.png", "voice": "voices-$CA/$LOCALE/words/ear.$CA" }, { "description": "elbow", "image": "words/elbow.png", "voice": "voices-$CA/$LOCALE/words/elbow.$CA" }, { "description": "eyelash", "image": "words/eyelash.png", "voice": "voices-$CA/$LOCALE/words/eyelash.$CA" }, { "description": "eyes", "image": "words/eyes.png", "voice": "voices-$CA/$LOCALE/words/eyes.$CA" }, { "description": "face", "image": "words/face.png", "voice": "voices-$CA/$LOCALE/words/face.$CA" }, { "description": "feet", "image": "words/feet.png", "voice": "voices-$CA/$LOCALE/words/feet.$CA" }, { "description": "femur", "image": "words/femur.png", "voice": "voices-$CA/$LOCALE/words/femur.$CA" }, { "description": "finger", "image": "words/finger.png", "voice": "voices-$CA/$LOCALE/words/finger.$CA" }, { "description": "fist", "image": "words/fist.png", "voice": "voices-$CA/$LOCALE/words/fist.$CA" }, { "description": "foot", "image": "words/foot.png", "voice": "voices-$CA/$LOCALE/words/foot.$CA" }, { "description": "grin", "image": "words/grin.png", "voice": "voices-$CA/$LOCALE/words/grin.$CA" }, { "description": "hair", "image": "words/hair.png", "voice": "voices-$CA/$LOCALE/words/hair.$CA" }, { "description": "hand", "image": "words/hand.png", "voice": "voices-$CA/$LOCALE/words/hand.$CA" }, { "description": "head", "image": "words/head.png", "voice": "voices-$CA/$LOCALE/words/head.$CA" }, { "description": "hip", "image": "words/hip.png", "voice": "voices-$CA/$LOCALE/words/hip.$CA" }, { "description": "knee", "image": "words/knee.png", "voice": "voices-$CA/$LOCALE/words/knee.$CA" }, { "description": "lap", "image": "words/lap.png", "voice": "voices-$CA/$LOCALE/words/lap.$CA" }, { "description": "leg", "image": "words/leg.png", "voice": "voices-$CA/$LOCALE/words/leg.$CA" }, { "description": "lip", "image": "words/lip.png", "voice": "voices-$CA/$LOCALE/words/lip.$CA" }, { "description": "mouth", "image": "words/mouth.png", "voice": "voices-$CA/$LOCALE/words/mouth.$CA" }, { "description": "muscle", "image": "words/muscle.png", "voice": "voices-$CA/$LOCALE/words/muscle.$CA" }, { "description": "navel", "image": "words/navel.png", "voice": "voices-$CA/$LOCALE/words/navel.$CA" }, { "description": "neck", "image": "words/neck.png", "voice": "voices-$CA/$LOCALE/words/neck.$CA" }, { "description": "nose", "image": "words/nose.png", "voice": "voices-$CA/$LOCALE/words/nose.$CA" }, { "description": "nostril", "image": "words/nostril.png", "voice": "voices-$CA/$LOCALE/words/nostril.$CA" }, { "description": "scar", "image": "words/scar.png", "voice": "voices-$CA/$LOCALE/words/scar.$CA" }, { "description": "skeleton", "image": "words/skeleton.png", "voice": "voices-$CA/$LOCALE/words/skeleton.$CA" }, { "description": "skin", "image": "words/skin.png", "voice": "voices-$CA/$LOCALE/words/skin.$CA" }, { "description": "spine", "image": "words/spine.png", "voice": "voices-$CA/$LOCALE/words/spine.$CA" }, { "description": "stare", "image": "words/stare.png", "voice": "voices-$CA/$LOCALE/words/stare.$CA" }, { "description": "stomach", "image": "words/stomach.png", "voice": "voices-$CA/$LOCALE/words/stomach.$CA" }, { "description": "sweat", "image": "words/sweat.png", "voice": "voices-$CA/$LOCALE/words/sweat.$CA" }, { "description": "teeth", "image": "words/teeth.png", "voice": "voices-$CA/$LOCALE/words/teeth.$CA" }, { "description": "thigh", "image": "words/thigh.png", "voice": "voices-$CA/$LOCALE/words/thigh.$CA" }, { "description": "throat", "image": "words/throat.png", "voice": "voices-$CA/$LOCALE/words/throat.$CA" }, { "description": "thumb", "image": "words/thumb.png", "voice": "voices-$CA/$LOCALE/words/thumb.$CA" }, { "description": "toe", "image": "words/toe.png", "voice": "voices-$CA/$LOCALE/words/toe.$CA" }, { "description": "tongue", "image": "words/tongue.png", "voice": "voices-$CA/$LOCALE/words/tongue.$CA" }, { "description": "vein", "image": "words/vein.png", "voice": "voices-$CA/$LOCALE/words/vein.$CA" }, { "description": "wart", "image": "words/wart.png", "voice": "voices-$CA/$LOCALE/words/wart.$CA" }, { "description": "wrist", "image": "words/wrist.png", "voice": "voices-$CA/$LOCALE/words/wrist.$CA" } ] }, { "type": "lesson", "name": "clothes", "content": [ { "description": "bathing suit", "image": "words/bathing_suit.png", "voice": "voices-$CA/$LOCALE/words/bathing_suit.$CA" }, { "description": "bib", "image": "words/bib.png", "voice": "voices-$CA/$LOCALE/words/bib.$CA" }, { "description": "button", "image": "words/button.png", "voice": "voices-$CA/$LOCALE/words/button.$CA" }, { "description": "cap", "image": "words/cap.png", "voice": "voices-$CA/$LOCALE/words/cap.$CA" }, { "description": "cape", "image": "words/cape.png", "voice": "voices-$CA/$LOCALE/words/cape.$CA" }, { "description": "coat", "image": "words/coat.png", "voice": "voices-$CA/$LOCALE/words/coat.$CA" }, { "description": "dress", "image": "words/dress.png", "voice": "voices-$CA/$LOCALE/words/dress.$CA" }, { "description": "glove", "image": "words/glove.png", "voice": "voices-$CA/$LOCALE/words/glove.$CA" }, { "description": "hat", "image": "words/hat.png", "voice": "voices-$CA/$LOCALE/words/hat.$CA" }, { "description": "heel", "image": "words/heel.png", "voice": "voices-$CA/$LOCALE/words/heel.$CA" }, { "description": "helmet", "image": "words/helmet.png", "voice": "voices-$CA/$LOCALE/words/helmet.$CA" }, { "description": "jacket", "image": "words/jacket.png", "voice": "voices-$CA/$LOCALE/words/jacket.$CA" }, { "description": "kimono", "image": "words/kimono.png", "voice": "voices-$CA/$LOCALE/words/kimono.$CA" }, { "description": "nightgown", "image": "words/nightgown.png", "voice": "voices-$CA/$LOCALE/words/nightgown.$CA" }, { "description": "pajamas", "image": "words/pajamas.png", "voice": "voices-$CA/$LOCALE/words/pajamas.$CA" }, { "description": "panties", "image": "words/panties.png", "voice": "voices-$CA/$LOCALE/words/panties.$CA" }, { "description": "pants", "image": "words/pants.png", "voice": "voices-$CA/$LOCALE/words/pants.$CA" }, { "description": "patch", "image": "words/patch.png", "voice": "voices-$CA/$LOCALE/words/patch.$CA" }, { "description": "pocket", "image": "words/pocket.png", "voice": "voices-$CA/$LOCALE/words/pocket.$CA" }, { "description": "pompon", "image": "words/pompon.png", "voice": "voices-$CA/$LOCALE/words/pompon.$CA" }, { "description": "pullover", "image": "words/pullover.png", "voice": "voices-$CA/$LOCALE/words/pullover.$CA" }, { "description": "raincoat", "image": "words/raincoat.png", "voice": "voices-$CA/$LOCALE/words/raincoat.$CA" }, { "description": "robe", "image": "words/robe.png", "voice": "voices-$CA/$LOCALE/words/robe.$CA" }, { "description": "sandals", "image": "words/sandals.png", "voice": "voices-$CA/$LOCALE/words/sandals.$CA" }, { "description": "sash", "image": "words/sash.png", "voice": "voices-$CA/$LOCALE/words/sash.$CA" }, { "description": "scarf", "image": "words/scarf.png", "voice": "voices-$CA/$LOCALE/words/scarf.$CA" }, { "description": "shirt", "image": "words/shirt.png", "voice": "voices-$CA/$LOCALE/words/shirt.$CA" }, { "description": "shoe", "image": "words/shoe.png", "voice": "voices-$CA/$LOCALE/words/shoe.$CA" }, { "description": "shoelace", "image": "words/shoelace.png", "voice": "voices-$CA/$LOCALE/words/shoelace.$CA" }, { "description": "short", "image": "words/short.png", "voice": "voices-$CA/$LOCALE/words/short.$CA" }, { "description": "skirt", "image": "words/skirt.png", "voice": "voices-$CA/$LOCALE/words/skirt.$CA" }, { "description": "sleeve", "image": "words/sleeve.png", "voice": "voices-$CA/$LOCALE/words/sleeve.$CA" }, { "description": "slippers", "image": "words/slippers.png", "voice": "voices-$CA/$LOCALE/words/slippers.$CA" }, { "description": "smock", "image": "words/smock.png", "voice": "voices-$CA/$LOCALE/words/smock.$CA" }, { "description": "sneaker", "image": "words/sneaker.png", "voice": "voices-$CA/$LOCALE/words/sneaker.$CA" }, { "description": "sock", "image": "words/sock.png", "voice": "voices-$CA/$LOCALE/words/sock.$CA" }, { "description": "sole shoe", "image": "words/sole_shoe.png", "voice": "voices-$CA/$LOCALE/words/sole_shoe.$CA" }, { "description": "suit", "image": "words/suit.png", "voice": "voices-$CA/$LOCALE/words/suit.$CA" }, { "description": "sweatshirt", "image": "words/sweatshirt.png", "voice": "voices-$CA/$LOCALE/words/sweatshirt.$CA" }, { "description": "uniform", "image": "words/uniform.png", "voice": "voices-$CA/$LOCALE/words/uniform.$CA" }, { "description": "vest", "image": "words/vest.png", "voice": "voices-$CA/$LOCALE/words/vest.$CA" }, { "description": "zipper", "image": "words/zipper.png", "voice": "voices-$CA/$LOCALE/words/zipper.$CA" } ] }, { "type": "lesson", "name": "emotion", "content": [ { "description": "ache", "image": "words/ache.png", "voice": "voices-$CA/$LOCALE/words/ache.$CA" }, { "description": "angry", "image": "words/angry.png", "voice": "voices-$CA/$LOCALE/words/angry.$CA" }, { "description": "blush", "image": "words/blush.png", "voice": "voices-$CA/$LOCALE/words/blush.$CA" }, { "description": "danger", "image": "words/danger.png", "voice": "voices-$CA/$LOCALE/words/danger.$CA" }, { "description": "frown", "image": "words/frown.png", "voice": "voices-$CA/$LOCALE/words/frown.$CA" }, { "description": "fun", "image": "words/fun.png", "voice": "voices-$CA/$LOCALE/words/fun.$CA" }, { "description": "laugh", "image": "words/laugh.png", "voice": "voices-$CA/$LOCALE/words/laugh.$CA" }, { "description": "mad", "image": "words/mad.png", "voice": "voices-$CA/$LOCALE/words/mad.$CA" }, { "description": "rage", "image": "words/rage.png", "voice": "voices-$CA/$LOCALE/words/rage.$CA" }, { "description": "sad", "image": "words/sad.png", "voice": "voices-$CA/$LOCALE/words/sad.$CA" }, { "description": "smile", "image": "words/smile.png", "voice": "voices-$CA/$LOCALE/words/smile.$CA" }, { "description": "sob", "image": "words/sob.png", "voice": "voices-$CA/$LOCALE/words/sob.$CA" }, { "description": "yum", "image": "words/yum.png", "voice": "voices-$CA/$LOCALE/words/yum.$CA" } ] }, { "type": "lesson", "name": "job", "content": [ { "description": "accountant", "image": "words/accountant.png", "voice": "voices-$CA/$LOCALE/words/accountant.$CA" }, { "description": "actor", "image": "words/actor.png", "voice": "voices-$CA/$LOCALE/words/actor.$CA" }, { "description": "artist", "image": "words/artist.png", "voice": "voices-$CA/$LOCALE/words/artist.$CA" }, { "description": "astronaut", "image": "words/astronaut.png", "voice": "voices-$CA/$LOCALE/words/astronaut.$CA" }, { "description": "boxer", "image": "words/boxer.png", "voice": "voices-$CA/$LOCALE/words/boxer.$CA" }, { "description": "banker female", "image": "words/banker_female.png", "voice": "voices-$CA/$LOCALE/words/banker_female.$CA" }, { "description": "bricklayer", "image": "words/bricklayer.png", "voice": "voices-$CA/$LOCALE/words/bricklayer.$CA" }, { "description": "butcher", "image": "words/butcher.png", "voice": "voices-$CA/$LOCALE/words/butcher.$CA" }, { "description": "carpenter", "image": "words/carpenter.png", "voice": "voices-$CA/$LOCALE/words/carpenter.$CA" }, { "description": "chef", "image": "words/chef.png", "voice": "voices-$CA/$LOCALE/words/chef.$CA" }, { "description": "chief", "image": "words/chief.png", "voice": "voices-$CA/$LOCALE/words/chief.$CA" }, { "description": "cleaning lady", "image": "words/cleaning_lady.png", "voice": "voices-$CA/$LOCALE/words/cleaning_lady.$CA" }, { "description": "clown", "image": "words/clown.png", "voice": "voices-$CA/$LOCALE/words/clown.$CA" }, { "description": "coach", "image": "words/coach.png", "voice": "voices-$CA/$LOCALE/words/coach.$CA" }, { "description": "cowboy", "image": "words/cowboy.png", "voice": "voices-$CA/$LOCALE/words/cowboy.$CA" }, { "description": "criminal", "image": "words/criminal.png", "voice": "voices-$CA/$LOCALE/words/criminal.$CA" }, { "description": "doctor", "image": "words/doctor.png", "voice": "voices-$CA/$LOCALE/words/doctor.$CA" }, { "description": "electrician", "image": "words/electrician.png", "voice": "voices-$CA/$LOCALE/words/electrician.$CA" }, { "description": "engineer", "image": "words/engineer.png", "voice": "voices-$CA/$LOCALE/words/engineer.$CA" }, { "description": "farmer", "image": "words/farmer.png", "voice": "voices-$CA/$LOCALE/words/farmer.$CA" }, { "description": "fireman", "image": "words/fireman.png", "voice": "voices-$CA/$LOCALE/words/fireman.$CA" }, { "description": "fisherman", "image": "words/fisherman.png", "voice": "voices-$CA/$LOCALE/words/fisherman.$CA" }, { "description": "hunter", "image": "words/hunter.png", "voice": "voices-$CA/$LOCALE/words/hunter.$CA" }, { "description": "job", "image": "words/job.png", "voice": "voices-$CA/$LOCALE/words/job.$CA" }, { "description": "jockey", "image": "words/jockey.png", "voice": "voices-$CA/$LOCALE/words/jockey.$CA" }, { "description": "judge", "image": "words/judge.png", "voice": "voices-$CA/$LOCALE/words/judge.$CA" }, { "description": "juggler", "image": "words/juggler.png", "voice": "voices-$CA/$LOCALE/words/juggler.$CA" }, { "description": "king", "image": "words/king.png", "voice": "voices-$CA/$LOCALE/words/king.$CA" }, { "description": "knight", "image": "words/knight.png", "voice": "voices-$CA/$LOCALE/words/knight.$CA" }, { "description": "lad", "image": "words/lad.png", "voice": "voices-$CA/$LOCALE/words/lad.$CA" }, { "description": "lawyer", "image": "words/lawyer.png", "voice": "voices-$CA/$LOCALE/words/lawyer.$CA" }, { "description": "librarian", "image": "words/librarian.png", "voice": "voices-$CA/$LOCALE/words/librarian.$CA" }, { "description": "mechanic", "image": "words/mechanic.png", "voice": "voices-$CA/$LOCALE/words/mechanic.$CA" }, { "description": "musician", "image": "words/musician.png", "voice": "voices-$CA/$LOCALE/words/musician.$CA" }, { "description": "nun", "image": "words/nun.png", "voice": "voices-$CA/$LOCALE/words/nun.$CA" }, { "description": "nurse", "image": "words/nurse.png", "voice": "voices-$CA/$LOCALE/words/nurse.$CA" }, { "description": "nurse male", "image": "words/nurse_male.png", "voice": "voices-$CA/$LOCALE/words/nurse_male.$CA" }, { "description": "pilot", "image": "words/pilot.png", "voice": "voices-$CA/$LOCALE/words/pilot.$CA" }, { "description": "pirate", "image": "words/pirate.png", "voice": "voices-$CA/$LOCALE/words/pirate.$CA" }, { "description": "plumber", "image": "words/plumber.png", "voice": "voices-$CA/$LOCALE/words/plumber.$CA" }, { "description": "police", "image": "words/police.png", "voice": "voices-$CA/$LOCALE/words/police.$CA" }, { "description": "pope", "image": "words/pope.png", "voice": "voices-$CA/$LOCALE/words/pope.$CA" }, { "description": "president", "image": "words/president.png", "voice": "voices-$CA/$LOCALE/words/president.$CA" }, { "description": "priest", "image": "words/priest.png", "voice": "voices-$CA/$LOCALE/words/priest.$CA" }, { "description": "prince", "image": "words/prince.png", "voice": "voices-$CA/$LOCALE/words/prince.$CA" }, { "description": "princess", "image": "words/princess.png", "voice": "voices-$CA/$LOCALE/words/princess.$CA" }, { "description": "prisoner", "image": "words/prisoner.png", "voice": "voices-$CA/$LOCALE/words/prisoner.$CA" }, { "description": "queen", "image": "words/queen.png", "voice": "voices-$CA/$LOCALE/words/queen.$CA" }, { "description": "sailor", "image": "words/sailor.png", "voice": "voices-$CA/$LOCALE/words/sailor.$CA" }, { "description": "soldier", "image": "words/soldier.png", "voice": "voices-$CA/$LOCALE/words/soldier.$CA" }, { "description": "female soldier", "image": "words/soldier_female.png", "voice": "voices-$CA/$LOCALE/words/soldier_female.$CA" }, { "description": "student", "image": "words/student.png", "voice": "voices-$CA/$LOCALE/words/student.$CA" }, { "description": "teacher", "image": "words/teacher.png", "voice": "voices-$CA/$LOCALE/words/teacher.$CA" }, { "description": "thief", "image": "words/thief.png", "voice": "voices-$CA/$LOCALE/words/thief.$CA" }, { "description": "vet", "image": "words/vet.png", "voice": "voices-$CA/$LOCALE/words/vet.$CA" }, { "description": "worker", "image": "words/worker.png", "voice": "voices-$CA/$LOCALE/words/worker.$CA" } ] }, { "type": "lesson", "name": "people", "content": [ { "description": "angel", "image": "words/angel.png", "voice": "voices-$CA/$LOCALE/words/angel.$CA" }, { "description": "fairy", "image": "words/fairy.png", "voice": "voices-$CA/$LOCALE/words/fairy.$CA" }, { "description": "wedding", "image": "words/wedding.png", "voice": "voices-$CA/$LOCALE/words/wedding.$CA" }, { "description": "boy", "image": "words/boy.png", "voice": "voices-$CA/$LOCALE/words/boy.$CA" }, { "description": "bride", "image": "words/bride.png", "voice": "voices-$CA/$LOCALE/words/bride.$CA" }, { "description": "brother", "image": "words/brother.png", "voice": "voices-$CA/$LOCALE/words/brother.$CA" }, { "description": "child", "image": "words/child.png", "voice": "voices-$CA/$LOCALE/words/child.$CA" }, { "description": "couple", "image": "words/couple.png", "voice": "voices-$CA/$LOCALE/words/couple.$CA" }, { "description": "dad", "image": "words/dad.png", "voice": "voices-$CA/$LOCALE/words/dad.$CA" }, { "description": "dwarf", "image": "words/dwarf.png", "voice": "voices-$CA/$LOCALE/words/dwarf.$CA" }, { "description": "family", "image": "words/family.png", "voice": "voices-$CA/$LOCALE/words/family.$CA" }, { "description": "friend", "image": "words/friend.png", "voice": "voices-$CA/$LOCALE/words/friend.$CA" }, { "description": "girl", "image": "words/girl.png", "voice": "voices-$CA/$LOCALE/words/girl.$CA" }, { "description": "gnome", "image": "words/gnome.png", "voice": "voices-$CA/$LOCALE/words/gnome.$CA" }, { "description": "grandmother", "image": "words/grandmother.png", "voice": "voices-$CA/$LOCALE/words/grandmother.$CA" }, { "description": "husband", "image": "words/husband.png", "voice": "voices-$CA/$LOCALE/words/husband.$CA" }, { "description": "lady", "image": "words/lady.png", "voice": "voices-$CA/$LOCALE/words/lady.$CA" }, { "description": "man", "image": "words/man.png", "voice": "voices-$CA/$LOCALE/words/man.$CA" }, { "description": "mate", "image": "words/mate.png", "voice": "voices-$CA/$LOCALE/words/mate.$CA" }, { "description": "mate female", "image": "words/mate_female.png", "voice": "voices-$CA/$LOCALE/words/mate_female.$CA" }, { "description": "mate male", "image": "words/mate_male.png", "voice": "voices-$CA/$LOCALE/words/mate_male.$CA" }, { "description": "men", "image": "words/men.png", "voice": "voices-$CA/$LOCALE/words/men.$CA" }, { "description": "mom", "image": "words/mom.png", "voice": "voices-$CA/$LOCALE/words/mom.$CA" }, { "description": "mother", "image": "words/mother.png", "voice": "voices-$CA/$LOCALE/words/mother.$CA" }, { "description": "pal", "image": "words/pal.png", "voice": "voices-$CA/$LOCALE/words/pal.$CA" }, { "description": "people", "image": "words/people.png", "voice": "voices-$CA/$LOCALE/words/people.$CA" }, { "description": "sister", "image": "words/sister.png", "voice": "voices-$CA/$LOCALE/words/sister.$CA" }, { "description": "son", "image": "words/son.png", "voice": "voices-$CA/$LOCALE/words/son.$CA" }, { "description": "tribe", "image": "words/tribe.png", "voice": "voices-$CA/$LOCALE/words/tribe.$CA" }, { "description": "twin boys", "image": "words/twin_boys.png", "voice": "voices-$CA/$LOCALE/words/twin_boys.$CA" }, { "description": "twin girls", "image": "words/twin_girls.png", "voice": "voices-$CA/$LOCALE/words/twin_girls.$CA" }, { "description": "wife", "image": "words/wife.png", "voice": "voices-$CA/$LOCALE/words/wife.$CA" }, { "description": "woman", "image": "words/woman.png", "voice": "voices-$CA/$LOCALE/words/woman.$CA" } ] }, { "type": "lesson", "name": "sport", "content": [ { "description": "athlete", "image": "words/athlete.png", "voice": "voices-$CA/$LOCALE/words/athlete.$CA" }, { "description": "ballet", "image": "words/ballet.png", "voice": "voices-$CA/$LOCALE/words/ballet.$CA" }, { "description": "camp", "image": "words/camp.png", "voice": "voices-$CA/$LOCALE/words/camp.$CA" }, { "description": "cheer", "image": "words/cheer.png", "voice": "voices-$CA/$LOCALE/words/cheer.$CA" }, { "description": "climb", "image": "words/climb.png", "voice": "voices-$CA/$LOCALE/words/climb.$CA" }, { "description": "dance", "image": "words/dance.png", "voice": "voices-$CA/$LOCALE/words/dance.$CA" }, { "description": "dive", "image": "words/dive.png", "voice": "voices-$CA/$LOCALE/words/dive.$CA" }, { "description": "explore", "image": "words/explore.png", "voice": "voices-$CA/$LOCALE/words/explore.$CA" }, { "description": "golf", "image": "words/golf.png", "voice": "voices-$CA/$LOCALE/words/golf.$CA" }, { "description": "hike", "image": "words/hike.png", "voice": "voices-$CA/$LOCALE/words/hike.$CA" }, { "description": "hit", "image": "words/hit.png", "voice": "voices-$CA/$LOCALE/words/hit.$CA" }, { "description": "hockey", "image": "words/hockey.png", "voice": "voices-$CA/$LOCALE/words/hockey.$CA" }, { "description": "hop", "image": "words/hop.png", "voice": "voices-$CA/$LOCALE/words/hop.$CA" }, { "description": "jog", "image": "words/jog.png", "voice": "voices-$CA/$LOCALE/words/jog.$CA" }, { "description": "judo", "image": "words/judo.png", "voice": "voices-$CA/$LOCALE/words/judo.$CA" }, { "description": "lift", "image": "words/lift.png", "voice": "voices-$CA/$LOCALE/words/lift.$CA" }, { "description": "race", "image": "words/race.png", "voice": "voices-$CA/$LOCALE/words/race.$CA" }, { "description": "ran", "image": "words/ran.png", "voice": "voices-$CA/$LOCALE/words/ran.$CA" }, { "description": "ride", "image": "words/ride.png", "voice": "voices-$CA/$LOCALE/words/ride.$CA" }, { "description": "rowing", "image": "words/rowing.png", "voice": "voices-$CA/$LOCALE/words/rowing.$CA" }, { "description": "skate", "image": "words/skate.png", "voice": "voices-$CA/$LOCALE/words/skate.$CA" }, { "description": "ski", "image": "words/ski.png", "voice": "voices-$CA/$LOCALE/words/ski.$CA" }, { "description": "sport", "image": "words/sport.png", "voice": "voices-$CA/$LOCALE/words/sport.$CA" }, { "description": "swim", "image": "words/swim.png", "voice": "voices-$CA/$LOCALE/words/swim.$CA" }, { "description": "tennis", "image": "words/tennis.png", "voice": "voices-$CA/$LOCALE/words/tennis.$CA" }, { "description": "throw", "image": "words/throw.png", "voice": "voices-$CA/$LOCALE/words/throw.$CA" } ] }, { "type": "lesson", "name": "food", "content": [ { "description": "beef", "image": "words/beef.png", "voice": "voices-$CA/$LOCALE/words/beef.$CA" }, { "description": "bone", "image": "words/bone.png", "voice": "voices-$CA/$LOCALE/words/bone.$CA" }, { "description": "bread", "image": "words/bread.png", "voice": "voices-$CA/$LOCALE/words/bread.$CA" }, { "description": "bun", "image": "words/bun.png", "voice": "voices-$CA/$LOCALE/words/bun.$CA" }, { "description": "butter", "image": "words/butter.png", "voice": "voices-$CA/$LOCALE/words/butter.$CA" }, { "description": "cake", "image": "words/cake.png", "voice": "voices-$CA/$LOCALE/words/cake.$CA" }, { "description": "candy", "image": "words/candy.png", "voice": "voices-$CA/$LOCALE/words/candy.$CA" }, { "description": "cereal", "image": "words/cereal.png", "voice": "voices-$CA/$LOCALE/words/cereal.$CA" }, { "description": "cheese", "image": "words/cheese.png", "voice": "voices-$CA/$LOCALE/words/cheese.$CA" }, { "description": "chocolate", "image": "words/chocolate.png", "voice": "voices-$CA/$LOCALE/words/chocolate.$CA" }, { "description": "coffee", "image": "words/coffee.png", "voice": "voices-$CA/$LOCALE/words/coffee.$CA" }, { "description": "cookie", "image": "words/cookie.png", "voice": "voices-$CA/$LOCALE/words/cookie.$CA" }, { "description": "crepe", "image": "words/crepe.png", "voice": "voices-$CA/$LOCALE/words/crepe.$CA" }, { "description": "crumb", "image": "words/crumb.png", "voice": "voices-$CA/$LOCALE/words/crumb.$CA" }, { "description": "crust", "image": "words/crust.png", "voice": "voices-$CA/$LOCALE/words/crust.$CA" }, { "description": "dessert", "image": "words/dessert.png", "voice": "voices-$CA/$LOCALE/words/dessert.$CA" }, { "description": "doughnut", "image": "words/doughnut.png", "voice": "voices-$CA/$LOCALE/words/doughnut.$CA" }, { "description": "drink", "image": "words/drink.png", "voice": "voices-$CA/$LOCALE/words/drink.$CA" }, { "description": "egg", "image": "words/egg.png", "voice": "voices-$CA/$LOCALE/words/egg.$CA" }, { "description": "feast", "image": "words/feast.png", "voice": "voices-$CA/$LOCALE/words/feast.$CA" }, { "description": "flour", "image": "words/flour.png", "voice": "voices-$CA/$LOCALE/words/flour.$CA" }, { "description": "food", "image": "words/food.png", "voice": "voices-$CA/$LOCALE/words/food.$CA" }, { "description": "fries", "image": "words/fries.png", "voice": "voices-$CA/$LOCALE/words/fries.$CA" }, { "description": "fudge", "image": "words/fudge.png", "voice": "voices-$CA/$LOCALE/words/fudge.$CA" }, { "description": "gum", "image": "words/gum.png", "voice": "voices-$CA/$LOCALE/words/gum.$CA" }, { "description": "ham", "image": "words/ham.png", "voice": "voices-$CA/$LOCALE/words/ham.$CA" }, { "description": "hot dog", "image": "words/hot_dog.png", "voice": "voices-$CA/$LOCALE/words/hot_dog.$CA" }, { "description": "ice", "image": "words/ice.png", "voice": "voices-$CA/$LOCALE/words/ice.$CA" }, { "description": "jam", "image": "words/jam.png", "voice": "voices-$CA/$LOCALE/words/jam.$CA" }, { "description": "jelly", "image": "words/jelly.png", "voice": "voices-$CA/$LOCALE/words/jelly.$CA" }, { "description": "juice", "image": "words/juice.png", "voice": "voices-$CA/$LOCALE/words/juice.$CA" }, { "description": "lemonade", "image": "words/lemonade.png", "voice": "voices-$CA/$LOCALE/words/lemonade.$CA" }, { "description": "lunch", "image": "words/lunch.png", "voice": "voices-$CA/$LOCALE/words/lunch.$CA" }, { "description": "mashed potatoes", "image": "words/mashed_potatoes.png", "voice": "voices-$CA/$LOCALE/words/mashed_potatoes.$CA" }, { "description": "meal", "image": "words/meal.png", "voice": "voices-$CA/$LOCALE/words/meal.$CA" }, { "description": "meat", "image": "words/meat.png", "voice": "voices-$CA/$LOCALE/words/meat.$CA" }, { "description": "milk", "image": "words/milk.png", "voice": "voices-$CA/$LOCALE/words/milk.$CA" }, { "description": "pepper", "image": "words/pepper.png", "voice": "voices-$CA/$LOCALE/words/pepper.$CA" }, { "description": "pie", "image": "words/pie.png", "voice": "voices-$CA/$LOCALE/words/pie.$CA" }, { "description": "pizza", "image": "words/pizza.png", "voice": "voices-$CA/$LOCALE/words/pizza.$CA" }, { "description": "pop", "image": "words/pop.png", "voice": "voices-$CA/$LOCALE/words/pop.$CA" }, { "description": "rice", "image": "words/rice.png", "voice": "voices-$CA/$LOCALE/words/rice.$CA" }, { "description": "roast", "image": "words/roast.png", "voice": "voices-$CA/$LOCALE/words/roast.$CA" }, { "description": "sandwich", "image": "words/sandwich.png", "voice": "voices-$CA/$LOCALE/words/sandwich.$CA" }, { "description": "sauce", "image": "words/sauce.png", "voice": "voices-$CA/$LOCALE/words/sauce.$CA" }, { "description": "sausage", "image": "words/sausage.png", "voice": "voices-$CA/$LOCALE/words/sausage.$CA" }, { "description": "snack", "image": "words/snack.png", "voice": "voices-$CA/$LOCALE/words/snack.$CA" }, { "description": "soup", "image": "words/soup.png", "voice": "voices-$CA/$LOCALE/words/soup.$CA" }, { "description": "spaghetti", "image": "words/spaghetti.png", "voice": "voices-$CA/$LOCALE/words/spaghetti.$CA" }, { "description": "spice", "image": "words/spice.png", "voice": "voices-$CA/$LOCALE/words/spice.$CA" }, { "description": "sprinkle", "image": "words/sprinkle.png", "voice": "voices-$CA/$LOCALE/words/sprinkle.$CA" }, { "description": "steak", "image": "words/steak.png", "voice": "voices-$CA/$LOCALE/words/steak.$CA" }, { "description": "stew", "image": "words/stew.png", "voice": "voices-$CA/$LOCALE/words/stew.$CA" }, { "description": "sugar", "image": "words/sugar.png", "voice": "voices-$CA/$LOCALE/words/sugar.$CA" }, { "description": "treat", "image": "words/treat.png", "voice": "voices-$CA/$LOCALE/words/treat.$CA" }, { "description": "yogurt", "image": "words/yogurt.png", "voice": "voices-$CA/$LOCALE/words/yogurt.$CA" } ] } ] }, { "type": "chapter", "name": "nature", "content": [ { "type": "lesson", "name": "animal", "content": [ { "description": "alligator", "image": "words/alligator.png", "voice": "voices-$CA/$LOCALE/words/alligator.$CA" }, { "description": "animal", "image": "words/animal.png", "voice": "voices-$CA/$LOCALE/words/animal.$CA" }, { "description": "ant", "image": "words/ant.png", "voice": "voices-$CA/$LOCALE/words/ant.$CA" }, { "description": "anteater", "image": "words/anteater.png", "voice": "voices-$CA/$LOCALE/words/anteater.$CA" }, { "description": "antelope", "image": "words/antelope.png", "voice": "voices-$CA/$LOCALE/words/antelope.$CA" }, { "description": "bait", "image": "words/bait.png", "voice": "voices-$CA/$LOCALE/words/bait.$CA" }, { "description": "bat", "image": "words/bat.png", "voice": "voices-$CA/$LOCALE/words/bat.$CA" }, { "description": "bear", "image": "words/bear.png", "voice": "voices-$CA/$LOCALE/words/bear.$CA" }, { "description": "beaver", "image": "words/beaver.png", "voice": "voices-$CA/$LOCALE/words/beaver.$CA" }, { "description": "bee", "image": "words/bee.png", "voice": "voices-$CA/$LOCALE/words/bee.$CA" }, { "description": "beetle", "image": "words/beetle.png", "voice": "voices-$CA/$LOCALE/words/beetle.$CA" }, { "description": "bird", "image": "words/bird.png", "voice": "voices-$CA/$LOCALE/words/bird.$CA" }, { "description": "blackbird", "image": "words/blackbird.png", "voice": "voices-$CA/$LOCALE/words/blackbird.$CA" }, { "description": "buffalo", "image": "words/buffalo.png", "voice": "voices-$CA/$LOCALE/words/buffalo.$CA" }, { "description": "bug", "image": "words/bug.png", "voice": "voices-$CA/$LOCALE/words/bug.$CA" }, { "description": "bull", "image": "words/bull.png", "voice": "voices-$CA/$LOCALE/words/bull.$CA" }, { "description": "butterfly", "image": "words/butterfly.png", "voice": "voices-$CA/$LOCALE/words/butterfly.$CA" }, { "description": "camel", "image": "words/camel.png", "voice": "voices-$CA/$LOCALE/words/camel.$CA" }, { "description": "canary", "image": "words/canary.png", "voice": "voices-$CA/$LOCALE/words/canary.$CA" }, { "description": "cat", "image": "words/cat.png", "voice": "voices-$CA/$LOCALE/words/cat.$CA" }, { "description": "caterpillar", "image": "words/caterpillar.png", "voice": "voices-$CA/$LOCALE/words/caterpillar.$CA" }, { "description": "female cat", "image": "words/cat_female.png", "voice": "voices-$CA/$LOCALE/words/cat_female.$CA" }, { "description": "centipede", "image": "words/centipede.png", "voice": "voices-$CA/$LOCALE/words/centipede.$CA" }, { "description": "chameleon", "image": "words/chameleon.png", "voice": "voices-$CA/$LOCALE/words/chameleon.$CA" }, { "description": "chick", "image": "words/chick.png", "voice": "voices-$CA/$LOCALE/words/chick.$CA" }, { "description": "chicken", "image": "words/chicken.png", "voice": "voices-$CA/$LOCALE/words/chicken.$CA" }, { "description": "chimp", "image": "words/chimp.png", "voice": "voices-$CA/$LOCALE/words/chimp.$CA" }, { "description": "clam", "image": "words/clam.png", "voice": "voices-$CA/$LOCALE/words/clam.$CA" }, { "description": "claw", "image": "words/claw.png", "voice": "voices-$CA/$LOCALE/words/claw.$CA" }, { "description": "cobra", "image": "words/cobra.png", "voice": "voices-$CA/$LOCALE/words/cobra.$CA" }, { "description": "cod", "image": "words/cod.png", "voice": "voices-$CA/$LOCALE/words/cod.$CA" }, { "description": "colt", "image": "words/colt.png", "voice": "voices-$CA/$LOCALE/words/colt.$CA" }, { "description": "cow", "image": "words/cow.png", "voice": "voices-$CA/$LOCALE/words/cow.$CA" }, { "description": "crab", "image": "words/crab.png", "voice": "voices-$CA/$LOCALE/words/crab.$CA" }, { "description": "crocodile", "image": "words/crocodile.png", "voice": "voices-$CA/$LOCALE/words/crocodile.$CA" }, { "description": "crow", "image": "words/crow.png", "voice": "voices-$CA/$LOCALE/words/crow.$CA" }, { "description": "deer", "image": "words/deer.png", "voice": "voices-$CA/$LOCALE/words/deer.$CA" }, { "description": "den", "image": "words/den.png", "voice": "voices-$CA/$LOCALE/words/den.$CA" }, { "description": "doe", "image": "words/doe.png", "voice": "voices-$CA/$LOCALE/words/doe.$CA" }, { "description": "dog", "image": "words/dog.png", "voice": "voices-$CA/$LOCALE/words/dog.$CA" }, { "description": "dolphin", "image": "words/dolphin.png", "voice": "voices-$CA/$LOCALE/words/dolphin.$CA" }, { "description": "dove", "image": "words/dove.png", "voice": "voices-$CA/$LOCALE/words/dove.$CA" }, { "description": "dragon", "image": "words/dragon.png", "voice": "voices-$CA/$LOCALE/words/dragon.$CA" }, { "description": "dragonfly", "image": "words/dragonfly.png", "voice": "voices-$CA/$LOCALE/words/dragonfly.$CA" }, { "description": "duck", "image": "words/duck.png", "voice": "voices-$CA/$LOCALE/words/duck.$CA" }, { "description": "duck mother", "image": "words/duck_mother.png", "voice": "voices-$CA/$LOCALE/words/duck_mother.$CA" }, { "description": "eagle", "image": "words/eagle.png", "voice": "voices-$CA/$LOCALE/words/eagle.$CA" }, { "description": "elk", "image": "words/elk.png", "voice": "voices-$CA/$LOCALE/words/elk.$CA" }, { "description": "fawn", "image": "words/fawn.png", "voice": "voices-$CA/$LOCALE/words/fawn.$CA" }, { "description": "feather", "image": "words/feather.png", "voice": "voices-$CA/$LOCALE/words/feather.$CA" }, { "description": "fin", "image": "words/fin.png", "voice": "voices-$CA/$LOCALE/words/fin.$CA" }, { "description": "fish", "image": "words/fish.png", "voice": "voices-$CA/$LOCALE/words/fish.$CA" }, { "description": "flamingo", "image": "words/flamingo.png", "voice": "voices-$CA/$LOCALE/words/flamingo.$CA" }, { "description": "flies", "image": "words/flies.png", "voice": "voices-$CA/$LOCALE/words/flies.$CA" }, { "description": "fox", "image": "words/fox.png", "voice": "voices-$CA/$LOCALE/words/fox.$CA" }, { "description": "frog", "image": "words/frog.png", "voice": "voices-$CA/$LOCALE/words/frog.$CA" }, { "description": "fur", "image": "words/fur.png", "voice": "voices-$CA/$LOCALE/words/fur.$CA" }, { "description": "giraffe", "image": "words/giraffe.png", "voice": "voices-$CA/$LOCALE/words/giraffe.$CA" }, { "description": "goat", "image": "words/goat.png", "voice": "voices-$CA/$LOCALE/words/goat.$CA" }, { "description": "goose", "image": "words/goose.png", "voice": "voices-$CA/$LOCALE/words/goose.$CA" }, { "description": "gorilla", "image": "words/gorilla.png", "voice": "voices-$CA/$LOCALE/words/gorilla.$CA" }, { "description": "guinea pig", "image": "words/guinea_pig.png", "voice": "voices-$CA/$LOCALE/words/guinea_pig.$CA" }, { "description": "hedgehog", "image": "words/hedgehog.png", "voice": "voices-$CA/$LOCALE/words/hedgehog.$CA" }, { "description": "hen", "image": "words/hen.png", "voice": "voices-$CA/$LOCALE/words/hen.$CA" }, { "description": "herd", "image": "words/herd.png", "voice": "voices-$CA/$LOCALE/words/herd.$CA" }, { "description": "hippopotamus", "image": "words/hippopotamus.png", "voice": "voices-$CA/$LOCALE/words/hippopotamus.$CA" }, { "description": "hive", "image": "words/hive.png", "voice": "voices-$CA/$LOCALE/words/hive.$CA" }, { "description": "horse", "image": "words/horse.png", "voice": "voices-$CA/$LOCALE/words/horse.$CA" }, { "description": "hound", "image": "words/hound.png", "voice": "voices-$CA/$LOCALE/words/hound.$CA" }, { "description": "hummingbird", "image": "words/hummingbird.png", "voice": "voices-$CA/$LOCALE/words/hummingbird.$CA" }, { "description": "hyena", "image": "words/hyena.png", "voice": "voices-$CA/$LOCALE/words/hyena.$CA" }, { "description": "iguana", "image": "words/iguana.png", "voice": "voices-$CA/$LOCALE/words/iguana.$CA" }, { "description": "jaguar", "image": "words/jaguar.png", "voice": "voices-$CA/$LOCALE/words/jaguar.$CA" }, { "description": "jay", "image": "words/jay.png", "voice": "voices-$CA/$LOCALE/words/jay.$CA" }, { "description": "jellyfish", "image": "words/jellyfish.png", "voice": "voices-$CA/$LOCALE/words/jellyfish.$CA" }, { "description": "kangaroo", "image": "words/kangaroo.png", "voice": "voices-$CA/$LOCALE/words/kangaroo.$CA" }, { "description": "kitten", "image": "words/kitten.png", "voice": "voices-$CA/$LOCALE/words/kitten.$CA" }, { "description": "koala", "image": "words/koala.png", "voice": "voices-$CA/$LOCALE/words/koala.$CA" }, { "description": "ladybug", "image": "words/ladybug.png", "voice": "voices-$CA/$LOCALE/words/ladybug.$CA" }, { "description": "lama", "image": "words/lama.png", "voice": "voices-$CA/$LOCALE/words/lama.$CA" }, { "description": "lamb", "image": "words/lamb.png", "voice": "voices-$CA/$LOCALE/words/lamb.$CA" }, { "description": "leg animal", "image": "words/leg_animal.png", "voice": "voices-$CA/$LOCALE/words/leg_animal.$CA" }, { "description": "lemur", "image": "words/lemur.png", "voice": "voices-$CA/$LOCALE/words/lemur.$CA" }, { "description": "leopard", "image": "words/leopard.png", "voice": "voices-$CA/$LOCALE/words/leopard.$CA" }, { "description": "lion", "image": "words/lion.png", "voice": "voices-$CA/$LOCALE/words/lion.$CA" }, { "description": "lion cub", "image": "words/lion_cub.png", "voice": "voices-$CA/$LOCALE/words/lion_cub.$CA" }, { "description": "lizard", "image": "words/lizard.png", "voice": "voices-$CA/$LOCALE/words/lizard.$CA" }, { "description": "lobster", "image": "words/lobster.png", "voice": "voices-$CA/$LOCALE/words/lobster.$CA" }, { "description": "magpie", "image": "words/magpie.png", "voice": "voices-$CA/$LOCALE/words/magpie.$CA" }, { "description": "mane", "image": "words/mane.png", "voice": "voices-$CA/$LOCALE/words/mane.$CA" }, { "description": "mice", "image": "words/mice.png", "voice": "voices-$CA/$LOCALE/words/mice.$CA" }, { "description": "mole", "image": "words/mole.png", "voice": "voices-$CA/$LOCALE/words/mole.$CA" }, { "description": "moose", "image": "words/moose.png", "voice": "voices-$CA/$LOCALE/words/moose.$CA" }, { "description": "mosquito", "image": "words/mosquito.png", "voice": "voices-$CA/$LOCALE/words/mosquito.$CA" }, { "description": "mouse", "image": "words/mouse.png", "voice": "voices-$CA/$LOCALE/words/mouse.$CA" }, { "description": "mule", "image": "words/mule.png", "voice": "voices-$CA/$LOCALE/words/mule.$CA" }, { "description": "opossum", "image": "words/opossum.png", "voice": "voices-$CA/$LOCALE/words/opossum.$CA" }, { "description": "ostrich", "image": "words/ostrich.png", "voice": "voices-$CA/$LOCALE/words/ostrich.$CA" }, { "description": "otter", "image": "words/otter.png", "voice": "voices-$CA/$LOCALE/words/otter.$CA" }, { "description": "owl", "image": "words/owl.png", "voice": "voices-$CA/$LOCALE/words/owl.$CA" }, { "description": "ox", "image": "words/ox.png", "voice": "voices-$CA/$LOCALE/words/ox.$CA" }, { "description": "oyster", "image": "words/oyster.png", "voice": "voices-$CA/$LOCALE/words/oyster.$CA" }, { "description": "panda", "image": "words/panda.png", "voice": "voices-$CA/$LOCALE/words/panda.$CA" }, { "description": "panther", "image": "words/panther.png", "voice": "voices-$CA/$LOCALE/words/panther.$CA" }, { "description": "parakeet", "image": "words/parakeet.png", "voice": "voices-$CA/$LOCALE/words/parakeet.$CA" }, { "description": "parrot", "image": "words/parrot.png", "voice": "voices-$CA/$LOCALE/words/parrot.$CA" }, { "description": "paw", "image": "words/paw.png", "voice": "voices-$CA/$LOCALE/words/paw.$CA" }, { "description": "peacock", "image": "words/peacock.png", "voice": "voices-$CA/$LOCALE/words/peacock.$CA" }, { "description": "pelican", "image": "words/pelican.png", "voice": "voices-$CA/$LOCALE/words/pelican.$CA" }, { "description": "pet", "image": "words/pet.png", "voice": "voices-$CA/$LOCALE/words/pet.$CA" }, { "description": "pig", "image": "words/pig.png", "voice": "voices-$CA/$LOCALE/words/pig.$CA" }, { "description": "pigeon", "image": "words/pigeon.png", "voice": "voices-$CA/$LOCALE/words/pigeon.$CA" }, { "description": "piranha", "image": "words/piranha.png", "voice": "voices-$CA/$LOCALE/words/piranha.$CA" }, { "description": "pony", "image": "words/pony.png", "voice": "voices-$CA/$LOCALE/words/pony.$CA" }, { "description": "pug", "image": "words/pug.png", "voice": "voices-$CA/$LOCALE/words/pug.$CA" }, { "description": "puppy", "image": "words/puppy.png", "voice": "voices-$CA/$LOCALE/words/puppy.$CA" }, { "description": "rabbit", "image": "words/rabbit.png", "voice": "voices-$CA/$LOCALE/words/rabbit.$CA" }, { "description": "baby rabbit", "image": "words/rabbit_baby.png", "voice": "voices-$CA/$LOCALE/words/rabbit_baby.$CA" }, { "description": "rat", "image": "words/rat.png", "voice": "voices-$CA/$LOCALE/words/rat.$CA" }, { "description": "reptile", "image": "words/reptile.png", "voice": "voices-$CA/$LOCALE/words/reptile.$CA" }, { "description": "rhinoceros", "image": "words/rhinoceros.png", "voice": "voices-$CA/$LOCALE/words/rhinoceros.$CA" }, { "description": "salamander", "image": "words/salamander.png", "voice": "voices-$CA/$LOCALE/words/salamander.$CA" }, { "description": "salmon", "image": "words/salmon.png", "voice": "voices-$CA/$LOCALE/words/salmon.$CA" }, { "description": "scorpion", "image": "words/scorpion.png", "voice": "voices-$CA/$LOCALE/words/scorpion.$CA" }, { "description": "shark", "image": "words/shark.png", "voice": "voices-$CA/$LOCALE/words/shark.$CA" }, { "description": "sheep", "image": "words/sheep.png", "voice": "voices-$CA/$LOCALE/words/sheep.$CA" }, { "description": "shell", "image": "words/shell.png", "voice": "voices-$CA/$LOCALE/words/shell.$CA" }, { "description": "shrimp", "image": "words/shrimp.png", "voice": "voices-$CA/$LOCALE/words/shrimp.$CA" }, { "description": "skunk", "image": "words/skunk.png", "voice": "voices-$CA/$LOCALE/words/skunk.$CA" }, { "description": "slime", "image": "words/slime.png", "voice": "voices-$CA/$LOCALE/words/slime.$CA" }, { "description": "sloth", "image": "words/sloth.png", "voice": "voices-$CA/$LOCALE/words/sloth.$CA" }, { "description": "slug", "image": "words/slug.png", "voice": "voices-$CA/$LOCALE/words/slug.$CA" }, { "description": "snail", "image": "words/snail.png", "voice": "voices-$CA/$LOCALE/words/snail.$CA" }, { "description": "snake", "image": "words/snake.png", "voice": "voices-$CA/$LOCALE/words/snake.$CA" }, { "description": "sole", "image": "words/sole.png", "voice": "voices-$CA/$LOCALE/words/sole.$CA" }, { "description": "sparrow", "image": "words/sparrow.png", "voice": "voices-$CA/$LOCALE/words/sparrow.$CA" }, { "description": "spider", "image": "words/spider.png", "voice": "voices-$CA/$LOCALE/words/spider.$CA" }, { "description": "spike", "image": "words/spike.png", "voice": "voices-$CA/$LOCALE/words/spike.$CA" }, { "description": "squid", "image": "words/squid.png", "voice": "voices-$CA/$LOCALE/words/squid.$CA" }, { "description": "squirrel", "image": "words/squirrel.png", "voice": "voices-$CA/$LOCALE/words/squirrel.$CA" }, { "description": "starfish", "image": "words/starfish.png", "voice": "voices-$CA/$LOCALE/words/starfish.$CA" }, { "description": "swan", "image": "words/swan.png", "voice": "voices-$CA/$LOCALE/words/swan.$CA" }, { "description": "tadpole", "image": "words/tadpole.png", "voice": "voices-$CA/$LOCALE/words/tadpole.$CA" }, { "description": "tail", "image": "words/tail.png", "voice": "voices-$CA/$LOCALE/words/tail.$CA" }, { "description": "tick", "image": "words/tick.png", "voice": "voices-$CA/$LOCALE/words/tick.$CA" }, { "description": "tiger", "image": "words/tiger.png", "voice": "voices-$CA/$LOCALE/words/tiger.$CA" }, { "description": "toad", "image": "words/toad.png", "voice": "voices-$CA/$LOCALE/words/toad.$CA" }, { "description": "turkey", "image": "words/turkey.png", "voice": "voices-$CA/$LOCALE/words/turkey.$CA" }, { "description": "turtle", "image": "words/turtle.png", "voice": "voices-$CA/$LOCALE/words/turtle.$CA" }, { "description": "tusk", "image": "words/tusk.png", "voice": "voices-$CA/$LOCALE/words/tusk.$CA" }, { "description": "viper", "image": "words/viper.png", "voice": "voices-$CA/$LOCALE/words/viper.$CA" }, { "description": "vulture", "image": "words/vulture.png", "voice": "voices-$CA/$LOCALE/words/vulture.$CA" }, { "description": "wasp", "image": "words/wasp.png", "voice": "voices-$CA/$LOCALE/words/wasp.$CA" }, { "description": "whale", "image": "words/whale.png", "voice": "voices-$CA/$LOCALE/words/whale.$CA" }, { "description": "wing", "image": "words/wing.png", "voice": "voices-$CA/$LOCALE/words/wing.$CA" }, { "description": "wolf", "image": "words/wolf.png", "voice": "voices-$CA/$LOCALE/words/wolf.$CA" }, { "description": "zebra", "image": "words/zebra.png", "voice": "voices-$CA/$LOCALE/words/zebra.$CA" } ] }, { "type": "lesson", "name": "fruit", "content": [ { "description": "apple", "image": "words/apple.png", "voice": "voices-$CA/$LOCALE/words/apple.$CA" }, { "description": "apricot", "image": "words/apricot.png", "voice": "voices-$CA/$LOCALE/words/apricot.$CA" }, { "description": "blackberry", "image": "words/blackberry.png", "voice": "voices-$CA/$LOCALE/words/blackberry.$CA" }, { "description": "blueberry", "image": "words/blueberry.png", "voice": "voices-$CA/$LOCALE/words/blueberry.$CA" }, { "description": "cacao", "image": "words/cacao.png", "voice": "voices-$CA/$LOCALE/words/cacao.$CA" }, { "description": "cherry", "image": "words/cherry.png", "voice": "voices-$CA/$LOCALE/words/cherry.$CA" }, { "description": "coconut", "image": "words/coconut.png", "voice": "voices-$CA/$LOCALE/words/coconut.$CA" }, { "description": "date fruit", "image": "words/date_fruit.png", "voice": "voices-$CA/$LOCALE/words/date_fruit.$CA" }, { "description": "fig", "image": "words/fig.png", "voice": "voices-$CA/$LOCALE/words/fig.$CA" }, { "description": "fruit", "image": "words/fruit.png", "voice": "voices-$CA/$LOCALE/words/fruit.$CA" }, { "description": "grape", "image": "words/grape.png", "voice": "voices-$CA/$LOCALE/words/grape.$CA" }, { "description": "grapefruit", "image": "words/grapefruit.png", "voice": "voices-$CA/$LOCALE/words/grapefruit.$CA" }, { "description": "kernel", "image": "words/kernel.png", "voice": "voices-$CA/$LOCALE/words/kernel.$CA" }, { "description": "kiwi", "image": "words/kiwi.png", "voice": "voices-$CA/$LOCALE/words/kiwi.$CA" }, { "description": "lemon", "image": "words/lemon.png", "voice": "voices-$CA/$LOCALE/words/lemon.$CA" }, { "description": "lime", "image": "words/lime.png", "voice": "voices-$CA/$LOCALE/words/lime.$CA" }, { "description": "mango", "image": "words/mango.png", "voice": "voices-$CA/$LOCALE/words/mango.$CA" }, { "description": "melon", "image": "words/melon.png", "voice": "voices-$CA/$LOCALE/words/melon.$CA" }, { "description": "orange", "image": "words/orange.png", "voice": "voices-$CA/$LOCALE/words/orange.$CA" }, { "description": "papaya", "image": "words/papaya.png", "voice": "voices-$CA/$LOCALE/words/papaya.$CA" }, { "description": "peach", "image": "words/peach.png", "voice": "voices-$CA/$LOCALE/words/peach.$CA" }, { "description": "pear", "image": "words/pear.png", "voice": "voices-$CA/$LOCALE/words/pear.$CA" }, { "description": "plum", "image": "words/plum.png", "voice": "voices-$CA/$LOCALE/words/plum.$CA" }, { "description": "raspberry", "image": "words/raspberry.png", "voice": "voices-$CA/$LOCALE/words/raspberry.$CA" }, { "description": "strawberry", "image": "words/strawberry.png", "voice": "voices-$CA/$LOCALE/words/strawberry.$CA" } ] }, { "type": "lesson", "name": "nature", "content": [ { "description": "bay", "image": "words/bay.png", "voice": "voices-$CA/$LOCALE/words/bay.$CA" }, { "description": "beach", "image": "words/beach.png", "voice": "voices-$CA/$LOCALE/words/beach.$CA" }, { "description": "canyon", "image": "words/canyon.png", "voice": "voices-$CA/$LOCALE/words/canyon.$CA" }, { "description": "cave", "image": "words/cave.png", "voice": "voices-$CA/$LOCALE/words/cave.$CA" }, { "description": "cavern", "image": "words/cavern.png", "voice": "voices-$CA/$LOCALE/words/cavern.$CA" }, { "description": "cliff", "image": "words/cliff.png", "voice": "voices-$CA/$LOCALE/words/cliff.$CA" }, { "description": "cloud", "image": "words/cloud.png", "voice": "voices-$CA/$LOCALE/words/cloud.$CA" }, { "description": "cloudy", "image": "words/cloudy.png", "voice": "voices-$CA/$LOCALE/words/cloudy.$CA" }, { "description": "coast", "image": "words/coast.png", "voice": "voices-$CA/$LOCALE/words/coast.$CA" }, { "description": "cold", "image": "words/cold.png", "voice": "voices-$CA/$LOCALE/words/cold.$CA" }, { "description": "creek", "image": "words/creek.png", "voice": "voices-$CA/$LOCALE/words/creek.$CA" }, { "description": "crystal", "image": "words/crystal.png", "voice": "voices-$CA/$LOCALE/words/crystal.$CA" }, { "description": "desert", "image": "words/desert.png", "voice": "voices-$CA/$LOCALE/words/desert.$CA" }, { "description": "diamond", "image": "words/diamond.png", "voice": "voices-$CA/$LOCALE/words/diamond.$CA" }, { "description": "dirt", "image": "words/dirt.png", "voice": "voices-$CA/$LOCALE/words/dirt.$CA" }, { "description": "drip", "image": "words/drip.png", "voice": "voices-$CA/$LOCALE/words/drip.$CA" }, { "description": "dune", "image": "words/dune.png", "voice": "voices-$CA/$LOCALE/words/dune.$CA" }, { "description": "earth", "image": "words/earth.png", "voice": "voices-$CA/$LOCALE/words/earth.$CA" }, { "description": "fall season", "image": "words/fall_season.png", "voice": "voices-$CA/$LOCALE/words/fall_season.$CA" }, { "description": "fire", "image": "words/fire.png", "voice": "voices-$CA/$LOCALE/words/fire.$CA" }, { "description": "flame", "image": "words/flame.png", "voice": "voices-$CA/$LOCALE/words/flame.$CA" }, { "description": "forest", "image": "words/forest.png", "voice": "voices-$CA/$LOCALE/words/forest.$CA" }, { "description": "garden", "image": "words/garden.png", "voice": "voices-$CA/$LOCALE/words/garden.$CA" }, { "description": "gem", "image": "words/gem.png", "voice": "voices-$CA/$LOCALE/words/gem.$CA" }, { "description": "ground", "image": "words/ground.png", "voice": "voices-$CA/$LOCALE/words/ground.$CA" }, { "description": "heat", "image": "words/heat.png", "voice": "voices-$CA/$LOCALE/words/heat.$CA" }, { "description": "hill", "image": "words/hill.png", "voice": "voices-$CA/$LOCALE/words/hill.$CA" }, { "description": "hole", "image": "words/hole.png", "voice": "voices-$CA/$LOCALE/words/hole.$CA" }, { "description": "iceberg", "image": "words/iceberg.png", "voice": "voices-$CA/$LOCALE/words/iceberg.$CA" }, { "description": "island", "image": "words/island.png", "voice": "voices-$CA/$LOCALE/words/island.$CA" }, { "description": "lake", "image": "words/lake.png", "voice": "voices-$CA/$LOCALE/words/lake.$CA" }, { "description": "land", "image": "words/land.png", "voice": "voices-$CA/$LOCALE/words/land.$CA" }, { "description": "lava", "image": "words/lava.png", "voice": "voices-$CA/$LOCALE/words/lava.$CA" }, { "description": "ledge", "image": "words/ledge.png", "voice": "voices-$CA/$LOCALE/words/ledge.$CA" }, { "description": "lightning", "image": "words/lightning.png", "voice": "voices-$CA/$LOCALE/words/lightning.$CA" }, { "description": "moon", "image": "words/moon.png", "voice": "voices-$CA/$LOCALE/words/moon.$CA" }, { "description": "mountain", "image": "words/mountain.png", "voice": "voices-$CA/$LOCALE/words/mountain.$CA" }, { "description": "mud", "image": "words/mud.png", "voice": "voices-$CA/$LOCALE/words/mud.$CA" }, { "description": "night", "image": "words/night.png", "voice": "voices-$CA/$LOCALE/words/night.$CA" }, { "description": "ocean", "image": "words/ocean.png", "voice": "voices-$CA/$LOCALE/words/ocean.$CA" }, { "description": "path", "image": "words/path.png", "voice": "voices-$CA/$LOCALE/words/path.$CA" }, { "description": "peak", "image": "words/peak.png", "voice": "voices-$CA/$LOCALE/words/peak.$CA" }, { "description": "planet", "image": "words/planet.png", "voice": "voices-$CA/$LOCALE/words/planet.$CA" }, { "description": "pond", "image": "words/pond.png", "voice": "voices-$CA/$LOCALE/words/pond.$CA" }, { "description": "rain", "image": "words/rain.png", "voice": "voices-$CA/$LOCALE/words/rain.$CA" }, { "description": "river", "image": "words/river.png", "voice": "voices-$CA/$LOCALE/words/river.$CA" }, { "description": "rock", "image": "words/rock.png", "voice": "voices-$CA/$LOCALE/words/rock.$CA" }, { "description": "sand", "image": "words/sand.png", "voice": "voices-$CA/$LOCALE/words/sand.$CA" }, { "description": "sea", "image": "words/sea.png", "voice": "voices-$CA/$LOCALE/words/sea.$CA" }, { "description": "shadow", "image": "words/shadow.png", "voice": "voices-$CA/$LOCALE/words/shadow.$CA" }, { "description": "shore", "image": "words/shore.png", "voice": "voices-$CA/$LOCALE/words/shore.$CA" }, { "description": "sky", "image": "words/sky.png", "voice": "voices-$CA/$LOCALE/words/sky.$CA" }, { "description": "slope", "image": "words/slope.png", "voice": "voices-$CA/$LOCALE/words/slope.$CA" }, { "description": "smoke", "image": "words/smoke.png", "voice": "voices-$CA/$LOCALE/words/smoke.$CA" }, { "description": "snow", "image": "words/snow.png", "voice": "voices-$CA/$LOCALE/words/snow.$CA" }, { "description": "spider web", "image": "words/spider_web.png", "voice": "voices-$CA/$LOCALE/words/spider_web.$CA" }, { "description": "spring season", "image": "words/spring_season.png", "voice": "voices-$CA/$LOCALE/words/spring_season.$CA" }, { "description": "star", "image": "words/star.png", "voice": "voices-$CA/$LOCALE/words/star.$CA" }, { "description": "steam", "image": "words/steam.png", "voice": "voices-$CA/$LOCALE/words/steam.$CA" }, { "description": "stone", "image": "words/stone.png", "voice": "voices-$CA/$LOCALE/words/stone.$CA" }, { "description": "stream", "image": "words/stream.png", "voice": "voices-$CA/$LOCALE/words/stream.$CA" }, { "description": "summer", "image": "words/summer.png", "voice": "voices-$CA/$LOCALE/words/summer.$CA" }, { "description": "summit", "image": "words/summit.png", "voice": "voices-$CA/$LOCALE/words/summit.$CA" }, { "description": "sun", "image": "words/sun.png", "voice": "voices-$CA/$LOCALE/words/sun.$CA" }, { "description": "time", "image": "words/time.png", "voice": "voices-$CA/$LOCALE/words/time.$CA" }, { "description": "top", "image": "words/top.png", "voice": "voices-$CA/$LOCALE/words/top.$CA" }, { "description": "trail", "image": "words/trail.png", "voice": "voices-$CA/$LOCALE/words/trail.$CA" }, { "description": "water", "image": "words/water.png", "voice": "voices-$CA/$LOCALE/words/water.$CA" }, { "description": "wave", "image": "words/wave.png", "voice": "voices-$CA/$LOCALE/words/wave.$CA" }, { "description": "wind", "image": "words/wind.png", "voice": "voices-$CA/$LOCALE/words/wind.$CA" }, { "description": "winter", "image": "words/winter.png", "voice": "voices-$CA/$LOCALE/words/winter.$CA" }, { "description": "world", "image": "words/world.png", "voice": "voices-$CA/$LOCALE/words/world.$CA" }, { "description": "vapor", "image": "words/vapor.png", "voice": "voices-$CA/$LOCALE/words/vapor.$CA" } ] }, { "type": "lesson", "name": "plant", "content": [ { "description": "acorn", "image": "words/acorn.png", "voice": "voices-$CA/$LOCALE/words/acorn.$CA" }, { "description": "apple tree", "image": "words/apple_tree.png", "voice": "voices-$CA/$LOCALE/words/apple_tree.$CA" }, { "description": "branch", "image": "words/branch.png", "voice": "voices-$CA/$LOCALE/words/branch.$CA" }, { "description": "bud", "image": "words/bud.png", "voice": "voices-$CA/$LOCALE/words/bud.$CA" }, { "description": "bush", "image": "words/bush.png", "voice": "voices-$CA/$LOCALE/words/bush.$CA" }, { "description": "cactus", "image": "words/cactus.png", "voice": "voices-$CA/$LOCALE/words/cactus.$CA" }, { "description": "clover", "image": "words/clover.png", "voice": "voices-$CA/$LOCALE/words/clover.$CA" }, { "description": "daffodil", "image": "words/daffodil.png", "voice": "voices-$CA/$LOCALE/words/daffodil.$CA" }, { "description": "daisy", "image": "words/daisy.png", "voice": "voices-$CA/$LOCALE/words/daisy.$CA" }, { "description": "dandelion", "image": "words/dandelion.png", "voice": "voices-$CA/$LOCALE/words/dandelion.$CA" }, { "description": "flower", "image": "words/flower.png", "voice": "voices-$CA/$LOCALE/words/flower.$CA" }, { "description": "grain", "image": "words/grain.png", "voice": "voices-$CA/$LOCALE/words/grain.$CA" }, { "description": "grass", "image": "words/grass.png", "voice": "voices-$CA/$LOCALE/words/grass.$CA" }, { "description": "hay", "image": "words/hay.png", "voice": "voices-$CA/$LOCALE/words/hay.$CA" }, { "description": "hedge", "image": "words/hedge.png", "voice": "voices-$CA/$LOCALE/words/hedge.$CA" }, { "description": "lawn", "image": "words/lawn.png", "voice": "voices-$CA/$LOCALE/words/lawn.$CA" }, { "description": "leaf", "image": "words/leaf.png", "voice": "voices-$CA/$LOCALE/words/leaf.$CA" }, { "description": "lilac", "image": "words/lilac.png", "voice": "voices-$CA/$LOCALE/words/lilac.$CA" }, { "description": "maple", "image": "words/maple.png", "voice": "voices-$CA/$LOCALE/words/maple.$CA" }, { "description": "mimosa", "image": "words/mimosa.png", "voice": "voices-$CA/$LOCALE/words/mimosa.$CA" }, { "description": "orchid", "image": "words/orchid.png", "voice": "voices-$CA/$LOCALE/words/orchid.$CA" }, { "description": "palm tree", "image": "words/palm_tree.png", "voice": "voices-$CA/$LOCALE/words/palm_tree.$CA" }, { "description": "peony", "image": "words/peony.png", "voice": "voices-$CA/$LOCALE/words/peony.$CA" }, { "description": "petal", "image": "words/petal.png", "voice": "voices-$CA/$LOCALE/words/petal.$CA" }, { "description": "pine", "image": "words/pine.png", "voice": "voices-$CA/$LOCALE/words/pine.$CA" }, { "description": "pine cone", "image": "words/pine_cone.png", "voice": "voices-$CA/$LOCALE/words/pine_cone.$CA" }, { "description": "pip", "image": "words/pip.png", "voice": "voices-$CA/$LOCALE/words/pip.$CA" }, { "description": "plant", "image": "words/plant.png", "voice": "voices-$CA/$LOCALE/words/plant.$CA" }, { "description": "root", "image": "words/root.png", "voice": "voices-$CA/$LOCALE/words/root.$CA" }, { "description": "rose", "image": "words/rose.png", "voice": "voices-$CA/$LOCALE/words/rose.$CA" }, { "description": "seed", "image": "words/seed.png", "voice": "voices-$CA/$LOCALE/words/seed.$CA" }, { "description": "shrub", "image": "words/shrub.png", "voice": "voices-$CA/$LOCALE/words/shrub.$CA" }, { "description": "stem", "image": "words/stem.png", "voice": "voices-$CA/$LOCALE/words/stem.$CA" }, { "description": "stick", "image": "words/stick.png", "voice": "voices-$CA/$LOCALE/words/stick.$CA" }, { "description": "stump", "image": "words/stump.png", "voice": "voices-$CA/$LOCALE/words/stump.$CA" }, { "description": "tree", "image": "words/tree.png", "voice": "voices-$CA/$LOCALE/words/tree.$CA" }, { "description": "tulip", "image": "words/tulip.png", "voice": "voices-$CA/$LOCALE/words/tulip.$CA" }, { "description": "verdure", "image": "words/verdure.png", "voice": "voices-$CA/$LOCALE/words/verdure.$CA" } ] }, { "type": "lesson", "name": "vegetables", "content": [ { "description": "artichoke", "image": "words/artichoke.png", "voice": "voices-$CA/$LOCALE/words/artichoke.$CA" }, { "description": "asparagus", "image": "words/asparagus.png", "voice": "voices-$CA/$LOCALE/words/asparagus.$CA" }, { "description": "avocado", "image": "words/avocado.png", "voice": "voices-$CA/$LOCALE/words/avocado.$CA" }, { "description": "bean", "image": "words/bean.png", "voice": "voices-$CA/$LOCALE/words/bean.$CA" }, { "description": "broccoli", "image": "words/broccoli.png", "voice": "voices-$CA/$LOCALE/words/broccoli.$CA" }, { "description": "cabbage", "image": "words/cabbage.png", "voice": "voices-$CA/$LOCALE/words/cabbage.$CA" }, { "description": "carrot", "image": "words/carrot.png", "voice": "voices-$CA/$LOCALE/words/carrot.$CA" }, { "description": "cauliflower", "image": "words/cauliflower.png", "voice": "voices-$CA/$LOCALE/words/cauliflower.$CA" }, { "description": "celery", "image": "words/celery.png", "voice": "voices-$CA/$LOCALE/words/celery.$CA" }, { "description": "corn", "image": "words/corn.png", "voice": "voices-$CA/$LOCALE/words/corn.$CA" }, { "description": "cucumber", "image": "words/cucumber.png", "voice": "voices-$CA/$LOCALE/words/cucumber.$CA" }, { "description": "eggplant", "image": "words/eggplant.png", "voice": "voices-$CA/$LOCALE/words/eggplant.$CA" }, { "description": "garlic", "image": "words/garlic.png", "voice": "voices-$CA/$LOCALE/words/garlic.$CA" }, { "description": "leek", "image": "words/leek.png", "voice": "voices-$CA/$LOCALE/words/leek.$CA" }, { "description": "lettuce", "image": "words/lettuce.png", "voice": "voices-$CA/$LOCALE/words/lettuce.$CA" }, { "description": "mushroom", "image": "words/mushroom.png", "voice": "voices-$CA/$LOCALE/words/mushroom.$CA" }, { "description": "nut", "image": "words/nut.png", "voice": "voices-$CA/$LOCALE/words/nut.$CA" }, { "description": "olive", "image": "words/olive.png", "voice": "voices-$CA/$LOCALE/words/olive.$CA" }, { "description": "onion", "image": "words/onion.png", "voice": "voices-$CA/$LOCALE/words/onion.$CA" }, { "description": "pea", "image": "words/pea.png", "voice": "voices-$CA/$LOCALE/words/pea.$CA" }, { "description": "peppers", "image": "words/peppers.png", "voice": "voices-$CA/$LOCALE/words/peppers.$CA" }, { "description": "pod", "image": "words/pod.png", "voice": "voices-$CA/$LOCALE/words/pod.$CA" }, { "description": "potato", "image": "words/potato.png", "voice": "voices-$CA/$LOCALE/words/potato.$CA" }, { "description": "pumpkin", "image": "words/pumpkin.png", "voice": "voices-$CA/$LOCALE/words/pumpkin.$CA" }, { "description": "radish", "image": "words/radish.png", "voice": "voices-$CA/$LOCALE/words/radish.$CA" }, { "description": "spinach", "image": "words/spinach.png", "voice": "voices-$CA/$LOCALE/words/spinach.$CA" }, { "description": "squash", "image": "words/squash.png", "voice": "voices-$CA/$LOCALE/words/squash.$CA" }, { "description": "tomatoe", "image": "words/tomatoe.png", "voice": "voices-$CA/$LOCALE/words/tomatoe.$CA" }, { "description": "turnip", "image": "words/turnip.png", "voice": "voices-$CA/$LOCALE/words/turnip.$CA" }, { "description": "vegetable", "image": "words/vegetable.png", "voice": "voices-$CA/$LOCALE/words/vegetable.$CA" }, { "description": "walnut", "image": "words/walnut.png", "voice": "voices-$CA/$LOCALE/words/walnut.$CA" }, { "description": "wheat", "image": "words/wheat.png", "voice": "voices-$CA/$LOCALE/words/wheat.$CA" } ] } ] }, { "type": "chapter", "name": "object", "content": [ { "type": "lesson", "name": "construction", "content": [ { "description": "bank", "image": "words/bank.png", "voice": "voices-$CA/$LOCALE/words/bank.$CA" }, { "description": "barn", "image": "words/barn.png", "voice": "voices-$CA/$LOCALE/words/barn.$CA" }, { "description": "bedroom", "image": "words/bedroom.png", "voice": "voices-$CA/$LOCALE/words/bedroom.$CA" }, { "description": "big top", "image": "words/big_top.png", "voice": "voices-$CA/$LOCALE/words/big_top.$CA" }, { "description": "bridge", "image": "words/bridge.png", "voice": "voices-$CA/$LOCALE/words/bridge.$CA" }, { "description": "cabin", "image": "words/cabin.png", "voice": "voices-$CA/$LOCALE/words/cabin.$CA" }, { "description": "cage", "image": "words/cage.png", "voice": "voices-$CA/$LOCALE/words/cage.$CA" }, { "description": "castle", "image": "words/castle.png", "voice": "voices-$CA/$LOCALE/words/castle.$CA" }, { "description": "chimney", "image": "words/chimney.png", "voice": "voices-$CA/$LOCALE/words/chimney.$CA" }, { "description": "circus", "image": "words/circus.png", "voice": "voices-$CA/$LOCALE/words/circus.$CA" }, { "description": "city", "image": "words/city.png", "voice": "voices-$CA/$LOCALE/words/city.$CA" }, { "description": "dam", "image": "words/dam.png", "voice": "voices-$CA/$LOCALE/words/dam.$CA" }, { "description": "door", "image": "words/door.png", "voice": "voices-$CA/$LOCALE/words/door.$CA" }, { "description": "fair", "image": "words/fair.png", "voice": "voices-$CA/$LOCALE/words/fair.$CA" }, { "description": "farm", "image": "words/farm.png", "voice": "voices-$CA/$LOCALE/words/farm.$CA" }, { "description": "fountain", "image": "words/fountain.png", "voice": "voices-$CA/$LOCALE/words/fountain.$CA" }, { "description": "garage", "image": "words/garage.png", "voice": "voices-$CA/$LOCALE/words/garage.$CA" }, { "description": "grave", "image": "words/grave.png", "voice": "voices-$CA/$LOCALE/words/grave.$CA" }, { "description": "home", "image": "words/home.png", "voice": "voices-$CA/$LOCALE/words/home.$CA" }, { "description": "hospital", "image": "words/hospital.png", "voice": "voices-$CA/$LOCALE/words/hospital.$CA" }, { "description": "house", "image": "words/house.png", "voice": "voices-$CA/$LOCALE/words/house.$CA" }, { "description": "hut", "image": "words/hut.png", "voice": "voices-$CA/$LOCALE/words/hut.$CA" }, { "description": "kitchen", "image": "words/kitchen.png", "voice": "voices-$CA/$LOCALE/words/kitchen.$CA" }, { "description": "lane", "image": "words/lane.png", "voice": "voices-$CA/$LOCALE/words/lane.$CA" }, { "description": "lighthouse", "image": "words/lighthouse.png", "voice": "voices-$CA/$LOCALE/words/lighthouse.$CA" }, { "description": "merry-go-round", "image": "words/merry-go-round.png", "voice": "voices-$CA/$LOCALE/words/merry-go-round.$CA" }, { "description": "mill", "image": "words/mill.png", "voice": "voices-$CA/$LOCALE/words/mill.$CA" }, { "description": "mosque", "image": "words/mosque.png", "voice": "voices-$CA/$LOCALE/words/mosque.$CA" }, { "description": "office", "image": "words/office.png", "voice": "voices-$CA/$LOCALE/words/office.$CA" }, { "description": "pool", "image": "words/pool.png", "voice": "voices-$CA/$LOCALE/words/pool.$CA" }, { "description": "post", "image": "words/post.png", "voice": "voices-$CA/$LOCALE/words/post.$CA" }, { "description": "prison", "image": "words/prison.png", "voice": "voices-$CA/$LOCALE/words/prison.$CA" }, { "description": "pyramid", "image": "words/pyramid.png", "voice": "voices-$CA/$LOCALE/words/pyramid.$CA" }, { "description": "ramp", "image": "words/ramp.png", "voice": "voices-$CA/$LOCALE/words/ramp.$CA" }, { "description": "road", "image": "words/road.png", "voice": "voices-$CA/$LOCALE/words/road.$CA" }, { "description": "roof", "image": "words/roof.png", "voice": "voices-$CA/$LOCALE/words/roof.$CA" }, { "description": "room", "image": "words/room.png", "voice": "voices-$CA/$LOCALE/words/room.$CA" }, { "description": "school", "image": "words/school.png", "voice": "voices-$CA/$LOCALE/words/school.$CA" }, { "description": "shed", "image": "words/shed.png", "voice": "voices-$CA/$LOCALE/words/shed.$CA" }, { "description": "shop", "image": "words/shop.png", "voice": "voices-$CA/$LOCALE/words/shop.$CA" }, { "description": "shutter", "image": "words/shutter.png", "voice": "voices-$CA/$LOCALE/words/shutter.$CA" }, { "description": "sidewalk", "image": "words/sidewalk.png", "voice": "voices-$CA/$LOCALE/words/sidewalk.$CA" }, { "description": "stage", "image": "words/stage.png", "voice": "voices-$CA/$LOCALE/words/stage.$CA" }, { "description": "staircase", "image": "words/staircase.png", "voice": "voices-$CA/$LOCALE/words/staircase.$CA" }, { "description": "steeple", "image": "words/steeple.png", "voice": "voices-$CA/$LOCALE/words/steeple.$CA" }, { "description": "step", "image": "words/step.png", "voice": "voices-$CA/$LOCALE/words/step.$CA" }, { "description": "store", "image": "words/store.png", "voice": "voices-$CA/$LOCALE/words/store.$CA" }, { "description": "street", "image": "words/street.png", "voice": "voices-$CA/$LOCALE/words/street.$CA" }, { "description": "temple", "image": "words/temple.png", "voice": "voices-$CA/$LOCALE/words/temple.$CA" }, { "description": "tent", "image": "words/tent.png", "voice": "voices-$CA/$LOCALE/words/tent.$CA" }, { "description": "train station", "image": "words/train_station.png", "voice": "voices-$CA/$LOCALE/words/train_station.$CA" }, { "description": "wall", "image": "words/wall.png", "voice": "voices-$CA/$LOCALE/words/wall.$CA" }, { "description": "window", "image": "words/window.png", "voice": "voices-$CA/$LOCALE/words/window.$CA" }, { "description": "window glass", "image": "words/window_glass.png", "voice": "voices-$CA/$LOCALE/words/window_glass.$CA" }, { "description": "zoo", "image": "words/zoo.png", "voice": "voices-$CA/$LOCALE/words/zoo.$CA" }, { "description": "class", "image": "words/class.png", "voice": "voices-$CA/$LOCALE/words/class.$CA" } ] }, { "type": "lesson", "name": "furniture", "content": [ { "description": "armchair", "image": "words/armchair.png", "voice": "voices-$CA/$LOCALE/words/armchair.$CA" }, { "description": "bath", "image": "words/bath.png", "voice": "voices-$CA/$LOCALE/words/bath.$CA" }, { "description": "bed", "image": "words/bed.png", "voice": "voices-$CA/$LOCALE/words/bed.$CA" }, { "description": "bench", "image": "words/bench.png", "voice": "voices-$CA/$LOCALE/words/bench.$CA" }, { "description": "bookcase", "image": "words/bookcase.png", "voice": "voices-$CA/$LOCALE/words/bookcase.$CA" }, { "description": "carpet", "image": "words/carpet.png", "voice": "voices-$CA/$LOCALE/words/carpet.$CA" }, { "description": "chair", "image": "words/chair.png", "voice": "voices-$CA/$LOCALE/words/chair.$CA" }, { "description": "chest", "image": "words/chest.png", "voice": "voices-$CA/$LOCALE/words/chest.$CA" }, { "description": "couch", "image": "words/couch.png", "voice": "voices-$CA/$LOCALE/words/couch.$CA" }, { "description": "cradle", "image": "words/cradle.png", "voice": "voices-$CA/$LOCALE/words/cradle.$CA" }, { "description": "crib", "image": "words/crib.png", "voice": "voices-$CA/$LOCALE/words/crib.$CA" }, { "description": "desk", "image": "words/desk.png", "voice": "voices-$CA/$LOCALE/words/desk.$CA" }, { "description": "doormat", "image": "words/doormat.png", "voice": "voices-$CA/$LOCALE/words/doormat.$CA" }, { "description": "drawer", "image": "words/drawer.png", "voice": "voices-$CA/$LOCALE/words/drawer.$CA" }, { "description": "fan", "image": "words/fan.png", "voice": "voices-$CA/$LOCALE/words/fan.$CA" }, { "description": "lamp", "image": "words/lamp.png", "voice": "voices-$CA/$LOCALE/words/lamp.$CA" }, { "description": "light", "image": "words/light.png", "voice": "voices-$CA/$LOCALE/words/light.$CA" }, { "description": "mat", "image": "words/mat.png", "voice": "voices-$CA/$LOCALE/words/mat.$CA" }, { "description": "mattress", "image": "words/mattress.png", "voice": "voices-$CA/$LOCALE/words/mattress.$CA" }, { "description": "quilt", "image": "words/quilt.png", "voice": "voices-$CA/$LOCALE/words/quilt.$CA" }, { "description": "rug", "image": "words/rug.png", "voice": "voices-$CA/$LOCALE/words/rug.$CA" }, { "description": "seat", "image": "words/seat.png", "voice": "voices-$CA/$LOCALE/words/seat.$CA" }, { "description": "shelf", "image": "words/shelf.png", "voice": "voices-$CA/$LOCALE/words/shelf.$CA" }, { "description": "shower", "image": "words/shower.png", "voice": "voices-$CA/$LOCALE/words/shower.$CA" }, { "description": "sink", "image": "words/sink.png", "voice": "voices-$CA/$LOCALE/words/sink.$CA" }, { "description": "stove", "image": "words/stove.png", "voice": "voices-$CA/$LOCALE/words/stove.$CA" }, { "description": "table", "image": "words/table.png", "voice": "voices-$CA/$LOCALE/words/table.$CA" }, { "description": "television", "image": "words/television.png", "voice": "voices-$CA/$LOCALE/words/television.$CA" }, { "description": "toilet", "image": "words/toilet.png", "voice": "voices-$CA/$LOCALE/words/toilet.$CA" } ] }, { "type": "lesson", "name": "houseware", "content": [ { "description": "appliance", "image": "words/appliance.png", "voice": "voices-$CA/$LOCALE/words/appliance.$CA" }, { "description": "baby bottle", "image": "words/baby_bottle.png", "voice": "voices-$CA/$LOCALE/words/baby_bottle.$CA" }, { "description": "balance", "image": "words/balance.png", "voice": "voices-$CA/$LOCALE/words/balance.$CA" }, { "description": "blade", "image": "words/blade.png", "voice": "voices-$CA/$LOCALE/words/blade.$CA" }, { "description": "can", "image": "words/can.png", "voice": "voices-$CA/$LOCALE/words/can.$CA" }, { "description": "carafe", "image": "words/carafe.png", "voice": "voices-$CA/$LOCALE/words/carafe.$CA" }, { "description": "cauldron", "image": "words/cauldron.png", "voice": "voices-$CA/$LOCALE/words/cauldron.$CA" }, { "description": "chandelier", "image": "words/chandelier.png", "voice": "voices-$CA/$LOCALE/words/chandelier.$CA" }, { "description": "clock", "image": "words/clock.png", "voice": "voices-$CA/$LOCALE/words/clock.$CA" }, { "description": "curtain", "image": "words/curtain.png", "voice": "voices-$CA/$LOCALE/words/curtain.$CA" }, { "description": "dish", "image": "words/dish.png", "voice": "voices-$CA/$LOCALE/words/dish.$CA" }, { "description": "fork", "image": "words/fork.png", "voice": "voices-$CA/$LOCALE/words/fork.$CA" }, { "description": "glass", "image": "words/glass.png", "voice": "voices-$CA/$LOCALE/words/glass.$CA" }, { "description": "knife", "image": "words/knife.png", "voice": "voices-$CA/$LOCALE/words/knife.$CA" }, { "description": "lid", "image": "words/lid.png", "voice": "voices-$CA/$LOCALE/words/lid.$CA" }, { "description": "mop", "image": "words/mop.png", "voice": "voices-$CA/$LOCALE/words/mop.$CA" }, { "description": "mug", "image": "words/mug.png", "voice": "voices-$CA/$LOCALE/words/mug.$CA" }, { "description": "pan", "image": "words/pan.png", "voice": "voices-$CA/$LOCALE/words/pan.$CA" }, { "description": "plate", "image": "words/plate.png", "voice": "voices-$CA/$LOCALE/words/plate.$CA" }, { "description": "pot", "image": "words/pot.png", "voice": "voices-$CA/$LOCALE/words/pot.$CA" }, { "description": "scale", "image": "words/scale.png", "voice": "voices-$CA/$LOCALE/words/scale.$CA" }, { "description": "skimmer", "image": "words/skimmer.png", "voice": "voices-$CA/$LOCALE/words/skimmer.$CA" }, { "description": "spatula", "image": "words/spatula.png", "voice": "voices-$CA/$LOCALE/words/spatula.$CA" }, { "description": "sponge", "image": "words/sponge.png", "voice": "voices-$CA/$LOCALE/words/sponge.$CA" }, { "description": "spoon", "image": "words/spoon.png", "voice": "voices-$CA/$LOCALE/words/spoon.$CA" }, { "description": "strainer", "image": "words/strainer.png", "voice": "voices-$CA/$LOCALE/words/strainer.$CA" }, { "description": "tablecloth", "image": "words/tablecloth.png", "voice": "voices-$CA/$LOCALE/words/tablecloth.$CA" }, { "description": "tin", "image": "words/tin.png", "voice": "voices-$CA/$LOCALE/words/tin.$CA" }, { "description": "toaster", "image": "words/toaster.png", "voice": "voices-$CA/$LOCALE/words/toaster.$CA" }, { "description": "tongs", "image": "words/tongs.png", "voice": "voices-$CA/$LOCALE/words/tongs.$CA" }, { "description": "trash", "image": "words/trash.png", "voice": "voices-$CA/$LOCALE/words/trash.$CA" }, { "description": "tray", "image": "words/tray.png", "voice": "voices-$CA/$LOCALE/words/tray.$CA" }, { "description": "vase", "image": "words/vase.png", "voice": "voices-$CA/$LOCALE/words/vase.$CA" }, { "description": "whisk", "image": "words/whisk.png", "voice": "voices-$CA/$LOCALE/words/whisk.$CA" }, { "description": "alarmclock", "image": "words/alarmclock.png", "voice": "voices-$CA/$LOCALE/words/alarmclock.$CA" } ] }, { "type": "lesson", "name": "object", "content": [ { "description": "faucet", "image": "words/faucet.png", "voice": "voices-$CA/$LOCALE/words/faucet.$CA" }, { "description": "air horn", "image": "words/air_horn.png", "voice": "voices-$CA/$LOCALE/words/air_horn.$CA" }, { "description": "anchor", "image": "words/anchor.png", "voice": "voices-$CA/$LOCALE/words/anchor.$CA" }, { "description": "badge", "image": "words/badge.png", "voice": "voices-$CA/$LOCALE/words/badge.$CA" }, { "description": "bag", "image": "words/bag.png", "voice": "voices-$CA/$LOCALE/words/bag.$CA" }, { "description": "ball", "image": "words/ball.png", "voice": "voices-$CA/$LOCALE/words/ball.$CA" }, { "description": "soccer ball", "image": "words/ball_soccer.png", "voice": "voices-$CA/$LOCALE/words/ball_soccer.$CA" }, { "description": "bead", "image": "words/bead.png", "voice": "voices-$CA/$LOCALE/words/bead.$CA" }, { "description": "bell", "image": "words/bell.png", "voice": "voices-$CA/$LOCALE/words/bell.$CA" }, { "description": "block", "image": "words/block.png", "voice": "voices-$CA/$LOCALE/words/block.$CA" }, { "description": "board", "image": "words/board.png", "voice": "voices-$CA/$LOCALE/words/board.$CA" }, { "description": "bomb", "image": "words/bomb.png", "voice": "voices-$CA/$LOCALE/words/bomb.$CA" }, { "description": "book", "image": "words/book.png", "voice": "voices-$CA/$LOCALE/words/book.$CA" }, { "description": "box", "image": "words/box.png", "voice": "voices-$CA/$LOCALE/words/box.$CA" }, { "description": "bucket", "image": "words/bucket.png", "voice": "voices-$CA/$LOCALE/words/bucket.$CA" }, { "description": "bulb", "image": "words/bulb.png", "voice": "voices-$CA/$LOCALE/words/bulb.$CA" }, { "description": "camera", "image": "words/camera.png", "voice": "voices-$CA/$LOCALE/words/camera.$CA" }, { "description": "candle", "image": "words/candle.png", "voice": "voices-$CA/$LOCALE/words/candle.$CA" }, { "description": "cane", "image": "words/cane.png", "voice": "voices-$CA/$LOCALE/words/cane.$CA" }, { "description": "canon", "image": "words/canon.png", "voice": "voices-$CA/$LOCALE/words/canon.$CA" }, { "description": "card", "image": "words/card.png", "voice": "voices-$CA/$LOCALE/words/card.$CA" }, { "description": "cart", "image": "words/cart.png", "voice": "voices-$CA/$LOCALE/words/cart.$CA" }, { "description": "cash", "image": "words/cash.png", "voice": "voices-$CA/$LOCALE/words/cash.$CA" }, { "description": "chain", "image": "words/chain.png", "voice": "voices-$CA/$LOCALE/words/chain.$CA" }, { "description": "chalk", "image": "words/chalk.png", "voice": "voices-$CA/$LOCALE/words/chalk.$CA" }, { "description": "cigar", "image": "words/cigar.png", "voice": "voices-$CA/$LOCALE/words/cigar.$CA" }, { "description": "clay", "image": "words/clay.png", "voice": "voices-$CA/$LOCALE/words/clay.$CA" }, { "description": "cloth", "image": "words/cloth.png", "voice": "voices-$CA/$LOCALE/words/cloth.$CA" }, { "description": "clothes hanger", "image": "words/clothes_hanger.png", "voice": "voices-$CA/$LOCALE/words/clothes_hanger.$CA" }, { "description": "coin", "image": "words/coin.png", "voice": "voices-$CA/$LOCALE/words/coin.$CA" }, { "description": "comb", "image": "words/comb.png", "voice": "voices-$CA/$LOCALE/words/comb.$CA" }, { "description": "cone", "image": "words/cone.png", "voice": "voices-$CA/$LOCALE/words/cone.$CA" }, { "description": "cork", "image": "words/cork.png", "voice": "voices-$CA/$LOCALE/words/cork.$CA" }, { "description": "cross", "image": "words/cross.png", "voice": "voices-$CA/$LOCALE/words/cross.$CA" }, { "description": "crown", "image": "words/crown.png", "voice": "voices-$CA/$LOCALE/words/crown.$CA" }, { "description": "cube", "image": "words/cube.png", "voice": "voices-$CA/$LOCALE/words/cube.$CA" }, { "description": "tire", "image": "words/tire.png", "voice": "voices-$CA/$LOCALE/words/tire.$CA" }, { "description": "dart board", "image": "words/dart_board.png", "voice": "voices-$CA/$LOCALE/words/dart_board.$CA" }, { "description": "dishcloth", "image": "words/dishcloth.png", "voice": "voices-$CA/$LOCALE/words/dishcloth.$CA" }, { "description": "doll", "image": "words/doll.png", "voice": "voices-$CA/$LOCALE/words/doll.$CA" }, { "description": "domino", "image": "words/domino.png", "voice": "voices-$CA/$LOCALE/words/domino.$CA" }, { "description": "drum", "image": "words/drum.png", "voice": "voices-$CA/$LOCALE/words/drum.$CA" }, { "description": "eraser", "image": "words/eraser.png", "voice": "voices-$CA/$LOCALE/words/eraser.$CA" }, { "description": "fire extinguisher", "image": "words/fire_extinguisher.png", "voice": "voices-$CA/$LOCALE/words/fire_extinguisher.$CA" }, { "description": "flacon", "image": "words/flacon.png", "voice": "voices-$CA/$LOCALE/words/flacon.$CA" }, { "description": "flag", "image": "words/flag.png", "voice": "voices-$CA/$LOCALE/words/flag.$CA" }, { "description": "fluff", "image": "words/fluff.png", "voice": "voices-$CA/$LOCALE/words/fluff.$CA" }, { "description": "flute", "image": "words/flute.png", "voice": "voices-$CA/$LOCALE/words/flute.$CA" }, { "description": "game", "image": "words/game.png", "voice": "voices-$CA/$LOCALE/words/game.$CA" }, { "description": "gift", "image": "words/gift.png", "voice": "voices-$CA/$LOCALE/words/gift.$CA" }, { "description": "glasses", "image": "words/glasses.png", "voice": "voices-$CA/$LOCALE/words/glasses.$CA" }, { "description": "glue", "image": "words/glue.png", "voice": "voices-$CA/$LOCALE/words/glue.$CA" }, { "description": "grill", "image": "words/grill.png", "voice": "voices-$CA/$LOCALE/words/grill.$CA" }, { "description": "hair-dryer", "image": "words/hair_dryer.png", "voice": "voices-$CA/$LOCALE/words/hair_dryer.$CA" }, { "description": "handlebar", "image": "words/handlebar.png", "voice": "voices-$CA/$LOCALE/words/handlebar.$CA" }, { "description": "harp", "image": "words/harp.png", "voice": "voices-$CA/$LOCALE/words/harp.$CA" }, { "description": "hook", "image": "words/hook.png", "voice": "voices-$CA/$LOCALE/words/hook.$CA" }, { "description": "hose", "image": "words/hose.png", "voice": "voices-$CA/$LOCALE/words/hose.$CA" }, { "description": "ink", "image": "words/ink.png", "voice": "voices-$CA/$LOCALE/words/ink.$CA" }, { "description": "jewel", "image": "words/jewel.png", "voice": "voices-$CA/$LOCALE/words/jewel.$CA" }, { "description": "keel", "image": "words/keel.png", "voice": "voices-$CA/$LOCALE/words/keel.$CA" }, { "description": "keyboard", "image": "words/keyboard.png", "voice": "voices-$CA/$LOCALE/words/keyboard.$CA" }, { "description": "kite", "image": "words/kite.png", "voice": "voices-$CA/$LOCALE/words/kite.$CA" }, { "description": "knot", "image": "words/knot.png", "voice": "voices-$CA/$LOCALE/words/knot.$CA" }, { "description": "lasso", "image": "words/lasso.png", "voice": "voices-$CA/$LOCALE/words/lasso.$CA" }, { "description": "log", "image": "words/log.png", "voice": "voices-$CA/$LOCALE/words/log.$CA" }, { "description": "magnet", "image": "words/magnet.png", "voice": "voices-$CA/$LOCALE/words/magnet.$CA" }, { "description": "magnifying glass", "image": "words/magnifying_glass.png", "voice": "voices-$CA/$LOCALE/words/magnifying_glass.$CA" }, { "description": "mail", "image": "words/mail.png", "voice": "voices-$CA/$LOCALE/words/mail.$CA" }, { "description": "map", "image": "words/map.png", "voice": "voices-$CA/$LOCALE/words/map.$CA" }, { "description": "marble", "image": "words/marble.png", "voice": "voices-$CA/$LOCALE/words/marble.$CA" }, { "description": "mask", "image": "words/mask.png", "voice": "voices-$CA/$LOCALE/words/mask.$CA" }, { "description": "mast", "image": "words/mast.png", "voice": "voices-$CA/$LOCALE/words/mast.$CA" }, { "description": "match", "image": "words/match.png", "voice": "voices-$CA/$LOCALE/words/match.$CA" }, { "description": "medal", "image": "words/medal.png", "voice": "voices-$CA/$LOCALE/words/medal.$CA" }, { "description": "microphone", "image": "words/microphone.png", "voice": "voices-$CA/$LOCALE/words/microphone.$CA" }, { "description": "mirror", "image": "words/mirror.png", "voice": "voices-$CA/$LOCALE/words/mirror.$CA" }, { "description": "mixer", "image": "words/mixer.png", "voice": "voices-$CA/$LOCALE/words/mixer.$CA" }, { "description": "necklace", "image": "words/necklace.png", "voice": "voices-$CA/$LOCALE/words/necklace.$CA" }, { "description": "nest", "image": "words/nest.png", "voice": "voices-$CA/$LOCALE/words/nest.$CA" }, { "description": "net", "image": "words/net.png", "voice": "voices-$CA/$LOCALE/words/net.$CA" }, { "description": "newspaper", "image": "words/newspaper.png", "voice": "voices-$CA/$LOCALE/words/newspaper.$CA" }, { "description": "notebook", "image": "words/notebook.png", "voice": "voices-$CA/$LOCALE/words/notebook.$CA" }, { "description": "oar", "image": "words/oar.png", "voice": "voices-$CA/$LOCALE/words/oar.$CA" }, { "description": "pacifier", "image": "words/pacifier.png", "voice": "voices-$CA/$LOCALE/words/pacifier.$CA" }, { "description": "page", "image": "words/page.png", "voice": "voices-$CA/$LOCALE/words/page.$CA" }, { "description": "pair", "image": "words/pair.png", "voice": "voices-$CA/$LOCALE/words/pair.$CA" }, { "description": "paper", "image": "words/paper.png", "voice": "voices-$CA/$LOCALE/words/paper.$CA" }, { "description": "pearl", "image": "words/pearl.png", "voice": "voices-$CA/$LOCALE/words/pearl.$CA" }, { "description": "pen", "image": "words/pen.png", "voice": "voices-$CA/$LOCALE/words/pen.$CA" }, { "description": "pencil", "image": "words/pencil.png", "voice": "voices-$CA/$LOCALE/words/pencil.$CA" }, { "description": "phone", "image": "words/phone.png", "voice": "voices-$CA/$LOCALE/words/phone.$CA" }, { "description": "piano", "image": "words/piano.png", "voice": "voices-$CA/$LOCALE/words/piano.$CA" }, { "description": "picture", "image": "words/picture.png", "voice": "voices-$CA/$LOCALE/words/picture.$CA" }, { "description": "pill", "image": "words/pill.png", "voice": "voices-$CA/$LOCALE/words/pill.$CA" }, { "description": "pillow", "image": "words/pillow.png", "voice": "voices-$CA/$LOCALE/words/pillow.$CA" }, { "description": "pipe", "image": "words/pipe.png", "voice": "voices-$CA/$LOCALE/words/pipe.$CA" }, { "description": "pole", "image": "words/pole.png", "voice": "voices-$CA/$LOCALE/words/pole.$CA" }, { "description": "prize", "image": "words/prize.png", "voice": "voices-$CA/$LOCALE/words/prize.$CA" }, { "description": "radio", "image": "words/radio.png", "voice": "voices-$CA/$LOCALE/words/radio.$CA" }, { "description": "rag", "image": "words/rag.png", "voice": "voices-$CA/$LOCALE/words/rag.$CA" }, { "description": "razor", "image": "words/razor.png", "voice": "voices-$CA/$LOCALE/words/razor.$CA" }, { "description": "rifle", "image": "words/rifle.png", "voice": "voices-$CA/$LOCALE/words/rifle.$CA" }, { "description": "robot", "image": "words/robot.png", "voice": "voices-$CA/$LOCALE/words/robot.$CA" }, { "description": "rolling pin", "image": "words/rolling_pin.png", "voice": "voices-$CA/$LOCALE/words/rolling_pin.$CA" }, { "description": "rope", "image": "words/rope.png", "voice": "voices-$CA/$LOCALE/words/rope.$CA" }, { "description": "saddle", "image": "words/saddle.png", "voice": "voices-$CA/$LOCALE/words/saddle.$CA" }, { "description": "school bag", "image": "words/school_bag.png", "voice": "voices-$CA/$LOCALE/words/school_bag.$CA" }, { "description": "sign", "image": "words/sign.png", "voice": "voices-$CA/$LOCALE/words/sign.$CA" }, { "description": "sleigh", "image": "words/sleigh.png", "voice": "voices-$CA/$LOCALE/words/sleigh.$CA" }, { "description": "slide", "image": "words/slide.png", "voice": "voices-$CA/$LOCALE/words/slide.$CA" }, { "description": "slot", "image": "words/slot.png", "voice": "voices-$CA/$LOCALE/words/slot.$CA" }, { "description": "soap", "image": "words/soap.png", "voice": "voices-$CA/$LOCALE/words/soap.$CA" }, { "description": "spark", "image": "words/spark.png", "voice": "voices-$CA/$LOCALE/words/spark.$CA" }, { "description": "spinning top", "image": "words/spinning_top.png", "voice": "voices-$CA/$LOCALE/words/spinning_top.$CA" }, { "description": "spool", "image": "words/spool.png", "voice": "voices-$CA/$LOCALE/words/spool.$CA" }, { "description": "squirt", "image": "words/squirt.png", "voice": "voices-$CA/$LOCALE/words/squirt.$CA" }, { "description": "stack", "image": "words/stack.png", "voice": "voices-$CA/$LOCALE/words/stack.$CA" }, { "description": "stamp", "image": "words/stamp.png", "voice": "voices-$CA/$LOCALE/words/stamp.$CA" }, { "description": "straw", "image": "words/straw.png", "voice": "voices-$CA/$LOCALE/words/straw.$CA" }, { "description": "string", "image": "words/string.png", "voice": "voices-$CA/$LOCALE/words/string.$CA" }, { "description": "suitcase", "image": "words/suitcase.png", "voice": "voices-$CA/$LOCALE/words/suitcase.$CA" }, { "description": "tag", "image": "words/tag.png", "voice": "voices-$CA/$LOCALE/words/tag.$CA" }, { "description": "teddy", "image": "words/teddy.png", "voice": "voices-$CA/$LOCALE/words/teddy.$CA" }, { "description": "thread", "image": "words/thread.png", "voice": "voices-$CA/$LOCALE/words/thread.$CA" }, { "description": "ticket", "image": "words/ticket.png", "voice": "voices-$CA/$LOCALE/words/ticket.$CA" }, { "description": "tissue", "image": "words/tissue.png", "voice": "voices-$CA/$LOCALE/words/tissue.$CA" }, { "description": "torch", "image": "words/torch.png", "voice": "voices-$CA/$LOCALE/words/torch.$CA" }, { "description": "towel", "image": "words/towel.png", "voice": "voices-$CA/$LOCALE/words/towel.$CA" }, { "description": "toy", "image": "words/toy.png", "voice": "voices-$CA/$LOCALE/words/toy.$CA" }, { "description": "trap", "image": "words/trap.png", "voice": "voices-$CA/$LOCALE/words/trap.$CA" }, { "description": "tube", "image": "words/tube.png", "voice": "voices-$CA/$LOCALE/words/tube.$CA" }, { "description": "umbrella", "image": "words/umbrella.png", "voice": "voices-$CA/$LOCALE/words/umbrella.$CA" }, { "description": "watch", "image": "words/watch.png", "voice": "voices-$CA/$LOCALE/words/watch.$CA" }, { "description": "wheel", "image": "words/wheel.png", "voice": "voices-$CA/$LOCALE/words/wheel.$CA" }, { "description": "wig", "image": "words/wig.png", "voice": "voices-$CA/$LOCALE/words/wig.$CA" }, { "description": "wood", "image": "words/wood.png", "voice": "voices-$CA/$LOCALE/words/wood.$CA" }, { "description": "wreath", "image": "words/wreath.png", "voice": "voices-$CA/$LOCALE/words/wreath.$CA" }, { "description": "ball of yarn", "image": "words/ball_of_yarn.png", "voice": "voices-$CA/$LOCALE/words/ball_of_yarn.$CA" }, { "description": "christmas", "image": "words/christmas.png", "voice": "voices-$CA/$LOCALE/words/christmas.$CA" }, { "description": "foam", "image": "words/foam.png", "voice": "voices-$CA/$LOCALE/words/foam.$CA" }, { "description": "guignol", "image": "words/guignol.png", "voice": "voices-$CA/$LOCALE/words/guignol.$CA" }, { "description": "movie", "image": "words/movie.png", "voice": "voices-$CA/$LOCALE/words/movie.$CA" }, { "description": "music", "image": "words/music.png", "voice": "voices-$CA/$LOCALE/words/music.$CA" }, { "description": "price", "image": "words/price.png", "voice": "voices-$CA/$LOCALE/words/price.$CA" }, { "description": "dot", "image": "words/dot.png", "voice": "voices-$CA/$LOCALE/words/dot.$CA" } ] }, { "type": "lesson", "name": "tool", "content": [ { "description": "ax", "image": "words/ax.png", "voice": "voices-$CA/$LOCALE/words/ax.$CA" }, { "description": "bolt", "image": "words/bolt.png", "voice": "voices-$CA/$LOCALE/words/bolt.$CA" }, { "description": "brick", "image": "words/brick.png", "voice": "voices-$CA/$LOCALE/words/brick.$CA" }, { "description": "brush", "image": "words/brush.png", "voice": "voices-$CA/$LOCALE/words/brush.$CA" }, { "description": "flash", "image": "words/flash.png", "voice": "voices-$CA/$LOCALE/words/flash.$CA" }, { "description": "hammer", "image": "words/hammer.png", "voice": "voices-$CA/$LOCALE/words/hammer.$CA" }, { "description": "mower", "image": "words/mower.png", "voice": "voices-$CA/$LOCALE/words/mower.$CA" }, { "description": "needle", "image": "words/needle.png", "voice": "voices-$CA/$LOCALE/words/needle.$CA" }, { "description": "pliers", "image": "words/pliers.png", "voice": "voices-$CA/$LOCALE/words/pliers.$CA" }, { "description": "rake", "image": "words/rake.png", "voice": "voices-$CA/$LOCALE/words/rake.$CA" }, { "description": "scissors", "image": "words/scissors.png", "voice": "voices-$CA/$LOCALE/words/scissors.$CA" }, { "description": "screw", "image": "words/screw.png", "voice": "voices-$CA/$LOCALE/words/screw.$CA" }, { "description": "screwdriver", "image": "words/screwdriver.png", "voice": "voices-$CA/$LOCALE/words/screwdriver.$CA" }, { "description": "shovel", "image": "words/shovel.png", "voice": "voices-$CA/$LOCALE/words/shovel.$CA" }, { "description": "spade", "image": "words/spade.png", "voice": "voices-$CA/$LOCALE/words/spade.$CA" }, { "description": "spear", "image": "words/spear.png", "voice": "voices-$CA/$LOCALE/words/spear.$CA" }, { "description": "tape measure", "image": "words/tape_measure.png", "voice": "voices-$CA/$LOCALE/words/tape_measure.$CA" }, { "description": "tool", "image": "words/tool.png", "voice": "voices-$CA/$LOCALE/words/tool.$CA" }, { "description": "wedge", "image": "words/wedge.png", "voice": "voices-$CA/$LOCALE/words/wedge.$CA" }, { "description": "wrench", "image": "words/wrench.png", "voice": "voices-$CA/$LOCALE/words/wrench.$CA" }, { "description": "trip", "image": "words/trip.png", "voice": "voices-$CA/$LOCALE/words/trip.$CA" }, { "description": "bike", "image": "words/bike.png", "voice": "voices-$CA/$LOCALE/words/bike.$CA" }, { "description": "boat", "image": "words/boat.png", "voice": "voices-$CA/$LOCALE/words/boat.$CA" }, { "description": "bus", "image": "words/bus.png", "voice": "voices-$CA/$LOCALE/words/bus.$CA" }, { "description": "canoe", "image": "words/canoe.png", "voice": "voices-$CA/$LOCALE/words/canoe.$CA" }, { "description": "car", "image": "words/car.png", "voice": "voices-$CA/$LOCALE/words/car.$CA" }, { "description": "engine", "image": "words/engine.png", "voice": "voices-$CA/$LOCALE/words/engine.$CA" }, { "description": "motorcycle", "image": "words/motorcycle.png", "voice": "voices-$CA/$LOCALE/words/motorcycle.$CA" }, { "description": "parachute", "image": "words/parachute.png", "voice": "voices-$CA/$LOCALE/words/parachute.$CA" }, { "description": "pedal", "image": "words/pedal.png", "voice": "voices-$CA/$LOCALE/words/pedal.$CA" }, { "description": "plane", "image": "words/plane.png", "voice": "voices-$CA/$LOCALE/words/plane.$CA" }, { "description": "porthole", "image": "words/porthole.png", "voice": "voices-$CA/$LOCALE/words/porthole.$CA" }, { "description": "raft", "image": "words/raft.png", "voice": "voices-$CA/$LOCALE/words/raft.$CA" }, { "description": "rocket", "image": "words/rocket.png", "voice": "voices-$CA/$LOCALE/words/rocket.$CA" }, { "description": "sail", "image": "words/sail.png", "voice": "voices-$CA/$LOCALE/words/sail.$CA" }, { "description": "ship", "image": "words/ship.png", "voice": "voices-$CA/$LOCALE/words/ship.$CA" }, { "description": "sled", "image": "words/sled.png", "voice": "voices-$CA/$LOCALE/words/sled.$CA" }, { "description": "taxi", "image": "words/taxi.png", "voice": "voices-$CA/$LOCALE/words/taxi.$CA" }, { "description": "train", "image": "words/train.png", "voice": "voices-$CA/$LOCALE/words/train.$CA" }, { "description": "truck", "image": "words/truck.png", "voice": "voices-$CA/$LOCALE/words/truck.$CA" }, { "description": "van", "image": "words/van.png", "voice": "voices-$CA/$LOCALE/words/van.$CA" } ] } ] } ] diff --git a/src/activities/imagename/ActivityInfo.qml b/src/activities/imagename/ActivityInfo.qml index 60fb5d18d..e0a3d6e1d 100644 --- a/src/activities/imagename/ActivityInfo.qml +++ b/src/activities/imagename/ActivityInfo.qml @@ -1,35 +1,36 @@ /* GCompris - ActivityInfo.qml * * Copyright (C) 2015 Pulkit Gupta * * Authors: * Pulkit Gupta * * 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 . */ import GCompris 1.0 ActivityInfo { name: "imagename/Imagename.qml" difficulty: 1 icon: "imagename/imagename.svg" author: "Pulkit Gupta <pulkitgenius@gmail.com>" demo: false title: qsTr("Image Name") description: qsTr("Drag and Drop each item above its name") +// intro: "Slide the images on their respective targets" goal: qsTr("Vocabulary and reading") prerequisite: qsTr("Reading") manual: qsTr("Drag each image from the (vertical) box on the left to its (corresponding) name on the right. Click the OK button to check your answer.") section: "reading" } diff --git a/src/activities/imagename/imagename.svg b/src/activities/imagename/imagename.svg index b16836dc8..223af8307 100644 --- a/src/activities/imagename/imagename.svg +++ b/src/activities/imagename/imagename.svg @@ -1,183 +1,232 @@ + + inkscape:window-width="3200" + inkscape:window-height="1741" + inkscape:window-x="-4" + inkscape:window-y="0" + showgrid="false" + inkscape:window-maximized="1" /> image/svg+xml - - - + d="m -5.9132601,-12.757095 -19.0624999,10.2500005 5.53125,21.8124995 6.9375,3.3125 4.4142181,-8.889631 8.08578177,2.577131 c 1.44552003,0.389801 2.52187003,0.787166 3.37500003,1.1875 L 10.77424,4.3054055 C 6.1669699,3.2326085 -2.4045031,1.1112145 -2.7882601,-0.03834454 -3.3127391,-1.6094464 0.30548887,-10.382095 0.30548987,-10.382095 Z" + style="fill:#c58101;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccccscc" /> + style="fill:#ffc06e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + d="m -5.9132601,-12.757095 -19.0624999,10.2500005 5.53125,21.8124995 6.9375,3.3125 4.8888509,-9.004249 7.17712898,3.156433 C 1.0044899,17.15989 2.5148599,17.092571 3.3679899,17.492905 L 10.77424,4.3054055 C 6.1669699,3.2326085 -2.4045031,1.1112145 -2.7882601,-0.03834454 -3.3127391,-1.6094464 0.30548887,-10.382095 0.30548987,-10.382095 Z" + style="fill:#c58101;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccccscc" /> + style="fill:#ffc06e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + + + + + + + + + + + + + + diff --git a/src/activities/memory/MemoryCommon.qml b/src/activities/memory/MemoryCommon.qml index f107f0d7b..be11a359a 100644 --- a/src/activities/memory/MemoryCommon.qml +++ b/src/activities/memory/MemoryCommon.qml @@ -1,194 +1,212 @@ /* GCompris - MemoryCommon.qml * * Copyright (C) 2014 JB BUTET * * Authors: * Bruno Coudoin (GTK+ version) * JB BUTET (Qt Quick port) * * 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 . */ import QtQuick 2.1 import GCompris 1.0 import "." import "../../core" import "memory.js" as Activity ActivityBase { id: activity focus: true property string backgroundImg property var dataset property bool withTux: false property string additionnalPath onStart: focus = true onStop: {} pageComponent: Image { id: background source: activity.backgroundImg sourceSize.width: parent.width fillMode: Image.PreserveAspectCrop focus: true signal start signal stop property alias items: items Component.onCompleted: { activity.start.connect(start) activity.stop.connect(stop) } QtObject { id: items property alias bar: bar - property alias bonus: bonus + property alias bonusTimer: bonusTimer property GCAudio audioEffects: activity.audioEffects property bool withTux: activity.withTux property bool tuxTurn: false property var playQueue property int selectionCount property int tuxScore: tuxScore.text property int playerScore: playerScore.text property variant dataset: activity.dataset property alias containerModel: containerModel property alias cardRepeater: cardRepeater property alias grid: grid property int columns property int rows } onStart: Activity.start(items) onStop: Activity.stop() ListModel { id: containerModel } Grid { id: grid spacing: 5 * ApplicationInfo.ratio columns: items.columns rows: items.rows anchors { left: background.left right: background.rigth top: background.top margins: 10 * ApplicationInfo.ratio } Repeater { id: cardRepeater model: containerModel delegate: CardItem { pairData: pairData_ tuxTurn: background.items.tuxTurn width: (background.width - (grid.columns + 1) * grid.spacing) / grid.columns height: (background.height - (grid.rows + 1) * grid.spacing) / (grid.rows + 0.5) audioVoices: activity.audioVoices audioEffects: activity.audioEffects } } add: Transition { PathAnimation { path: Path { PathCurve { x: background.width / 3} PathCurve { y: background.height / 3} PathCurve {} } easing.type: Easing.InOutQuad duration: 2000 } } } DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar content: BarEnumContent { value: help | home | level } onHelpClicked: { displayDialog(dialogHelp) } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: home() } Image { id: player source: 'qrc:/gcompris/src/activities/memory/resource/children.svg' anchors { bottom: bar.bottom right: parent.right rightMargin: 2 * ApplicationInfo.ratio } width: height * 0.83 height: bar.height * 1.2 GCText { id: playerScore anchors.centerIn: parent anchors.verticalCenterOffset: parent.height / 6 color: "black" font.bold: true fontSize: largeSize style: Text.Outline styleColor: "white" text: items.playerScore } } Image { id: tux visible: activity.withTux source: 'qrc:/gcompris/src/activities/memory/resource/tux-teacher.svg' anchors { bottom: bar.bottom right: player.left rightMargin: 2 * ApplicationInfo.ratio } width: height * 0.83 height: bar.height * 1.2 GCText { id: tuxScore anchors.centerIn: parent anchors.verticalCenterOffset: parent.height / 6 color: "black" font.bold: true fontSize: largeSize style: Text.Outline styleColor: "white" text: items.tuxScore } } + Timer { + id: bonusTimer + interval: 2000 + property bool win + + function good() { + win = true + start() + } + + function bad() { + win = false + start() + } + + onTriggered: win ? bonus.good("flower") : bonus.bad("flower") + } + Bonus { id: bonus Component.onCompleted: win.connect(Activity.nextLevel) } } } diff --git a/src/activities/memory/memory.js b/src/activities/memory/memory.js index 55b7c81d3..841714883 100644 --- a/src/activities/memory/memory.js +++ b/src/activities/memory/memory.js @@ -1,262 +1,262 @@ /* gcompris - memory.js * * Copyright (C) 2014 JB BUTET * * Authors: * Bruno Coudoin (GTK+ version) * JB BUTET (Qt Quick port) * * 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 . */ .pragma library .import QtQuick 2.0 as Quick .import "qrc:/gcompris/src/core/core.js" as Core var url = "qrc:/gcompris/src/activities/memory/resource/" var items var currentLevel var numberOfLevel var nbOfPair var cardLeft var cardList function start(items_) { items = items_ currentLevel = 0 numberOfLevel = items.dataset.length initLevel() } function stop() { } function initLevel() { items.bar.level = currentLevel + 1 items.containerModel.clear() items.playQueue = [] items.tuxTurn = false items.selectionCount = 0 // compute the number of cards var columns = items.dataset[currentLevel].columns var rows = items.dataset[currentLevel].rows var images = items.dataset[currentLevel].images var sounds = items.dataset[currentLevel].sounds var texts = items.dataset[currentLevel].texts items.columns = columns items.rows = rows nbOfPair = rows * columns / 2 cardLeft = nbOfPair * 2 // Check the provided dataset has enough data var maxData = Math.max( images ? images.length : 0, sounds ? sounds.length : 0, texts ? texts.length : 0) if(rows * columns > maxData) { console.log("ERROR: Memory dataset does not have enough data pairs at level ", currentLevel + 1) return } // Create a list of indexes for the shuffling // This way we can keep the 3 lists in sync var shuffleIds = [] for(var i = 0; i < maxData; ++i) { shuffleIds.push(i) } Core.shuffle(shuffleIds) // place randomly a level-defined number of pairs cardList = [] for(var ix = 0; ix < nbOfPair; ++ix) { // select a random item for(var j = 0; j < 2; ++j) { cardList.push( { image: images ? images[shuffleIds[ix]][j] : "", sound: sounds ? sounds[shuffleIds[ix]][j] : "", text: texts ? texts[shuffleIds[ix]][j] : "", matchCode: ix, back: url + "backcard.png", emptyCard: url + "emptycard.png" } ) } } cardList = Core.shuffle(cardList) // fill the model for(i = 0; i < cardList.length; ++i) { items.containerModel.append( { pairData_: cardList[i] } ) } items.tuxScore = 0 items.playerScore = 0 } // Return a pair of cards that have already been shown function getShownPair() { for(var i = 0; i < nbOfPair * 2; ++i) { var cardItem1 = items.cardRepeater.itemAt(i) for(var j = 0; j < nbOfPair * 2; ++j) { var cardItem2 = items.cardRepeater.itemAt(j) if(i != j && !cardItem1.isFound && cardItem1.isShown && !cardItem2.isFound && cardItem2.isShown && (cardItem1.pairData.matchCode === cardItem2.pairData.matchCode) ) { return [cardItem1, cardItem2] } } } return } // Calc randomly is Tux is a good player // Return true if Tux should play correctly function getRandomTuxIsGood() { return Math.random() * numberOfLevel < currentLevel } function chooseCard() { // Tux looks in the shown card to make his choice if(getRandomTuxIsGood()) { var shownPair = getShownPair() if(shownPair) { if(shownPair[0].isBack) { return shownPair[0] } else { return shownPair[1] } } } // If no pairs shown select a random card var listCardNonReturned = [] for(var i = 0; i < cardList.length; ++i) { if (items.cardRepeater.itemAt(i).isFound == false && items.cardRepeater.itemAt(i).isBack) listCardNonReturned.push(items.cardRepeater.itemAt(i)) } //select randomly a card in it return listCardNonReturned[Math.floor(Math.random() * listCardNonReturned.length)] } function reverseCardsIfNeeded() { if(items.playQueue.length >= 2) { items.selectionCount = 0 var item1 = items.playQueue.shift() var item2 = items.playQueue.shift() var tuxTurn = item1.tuxTurn if (item1.card.pairData.matchCode === item2.card.pairData.matchCode) { // the 2 cards are the same item1.card.isBack = false // stay faced item1.card.isFound = true // signal for hidden state item2.card.isBack = false item2.card.isFound = true cardLeft = cardLeft - 2 if (tuxTurn) items.tuxScore++ else items.playerScore++ if(cardLeft === 0) { // no more cards in the level if(items.withTux) { if (items.tuxScore < items.playerScore) { youWon() } else { youLoose() } } else { youWon() } } else { if(items.withTux && items.tuxTurn) { tuxPlay() } else { items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/win.wav') } } } else { // pictures clicked are not the same item1.card.isBack = true item2.card.isBack = true if(items.withTux) items.tuxTurn = !items.tuxTurn // The user lost, it's Tux turn if (items.withTux && items.tuxTurn) { tuxPlay() } } } } function tuxPlay() { // choose a card chooseCard().selected() } function youWon() { - items.bonus.good("flower") + items.bonusTimer.good() } function youLoose(){ - items.bonus.bad("flower") + items.bonusTimer.bad() if (items.withTux){ initLevel() } } function nextLevel() { if(numberOfLevel <= ++currentLevel ) { currentLevel = 0 } initLevel(); } function previousLevel() { if(--currentLevel < 0) { currentLevel = numberOfLevel - 1 } initLevel(); } function dumpPlayQueue() { for(var i in items.playQueue) console.log(items.playQueue[i].card, items.playQueue[i].tuxTurn) } // Return true is we have enough to make a pair function addPlayQueue(card) { items.playQueue.push({'card': card, 'tuxTurn': items.tuxTurn}) return items.playQueue.length >= 2 } diff --git a/src/activities/menu/ConfigurationItem.qml b/src/activities/menu/ConfigurationItem.qml index bc188c3ae..f6dc98fec 100644 --- a/src/activities/menu/ConfigurationItem.qml +++ b/src/activities/menu/ConfigurationItem.qml @@ -1,567 +1,567 @@ /* GCompris - ConfigurationItem.qml * * Copyright (C) 2014 Johnny Jazeix * * Authors: * Johnny Jazeix * * 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 . */ import QtQuick 2.2 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.0 import GCompris 1.0 import "../../core" import "qrc:/gcompris/src/core/core.js" as Core Item { property var languages: allLangs.languages id: dialogConfig height: column.height LanguageList { id: allLangs } Column { id: column spacing: 10 width: parent.width // Put configuration here Row { id: demoModeBox width: parent.width spacing: 10 property bool checked: !ApplicationSettings.isDemoMode Image { sourceSize.height: 50 * ApplicationInfo.ratio source: demoModeBox.checked ? "qrc:/gcompris/src/core/resource/apply.svg" : "qrc:/gcompris/src/core/resource/cancel.svg" MouseArea { anchors.fill: parent onClicked: { if(ApplicationSettings.isDemoMode) ApplicationSettings.isDemoMode = false } } } Button { width: parent.parent.width - 50 * ApplicationInfo.ratio - 10 * 2 height: parent.height enabled: ApplicationSettings.isDemoMode anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter text: demoModeBox.checked ? qsTr("You have the full version") : qsTr("Buy the full version").toUpperCase() style: ButtonStyle { background: Rectangle { implicitWidth: 100 implicitHeight: 25 border.width: control.activeFocus ? 4 : 2 border.color: "black" radius: 10 gradient: Gradient { GradientStop { position: 0 ; color: control.pressed ? "#87ff5c" : ApplicationSettings.isDemoMode ? "#ffe85c" : "#EEEEEE"} GradientStop { position: 1 ; color: control.pressed ? "#44ff00" : ApplicationSettings.isDemoMode ? "#f8d600" : "#AAAAAA"} } } label: GCText { text: control.text horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter wrapMode: Text.WordWrap } } onClicked: { if(ApplicationSettings.isDemoMode) ApplicationSettings.isDemoMode = false } } } GCDialogCheckBox { id: displayLockedActivitiesBox text: qsTr("Show locked activities") visible: ApplicationSettings.isDemoMode checked: showLockedActivities onCheckedChanged: { showLockedActivities = checked; } } GCDialogCheckBox { id: enableAudioVoicesBox text: qsTr("Enable audio voices") checked: isAudioVoicesEnabled onCheckedChanged: { isAudioVoicesEnabled = checked; } } GCDialogCheckBox { id: enableAudioEffectsBox text: qsTr("Enable audio effects") checked: isAudioEffectsEnabled onCheckedChanged: { isAudioEffectsEnabled = checked; } } GCDialogCheckBox { id: enableFullscreenBox text: qsTr("Fullscreen") checked: isFullscreen onCheckedChanged: { isFullscreen = checked; } } GCDialogCheckBox { id: enableVirtualKeyboardBox text: qsTr("Virtual Keyboard") checked: isVirtualKeyboard onCheckedChanged: { isVirtualKeyboard = checked; } } GCDialogCheckBox { id: enableAutomaticDownloadsBox checked: isAutomaticDownloadsEnabled text: qsTr("Enable automatic downloads/updates of sound files") onCheckedChanged: { isAutomaticDownloadsEnabled = checked; } } GCDialogCheckBox { id: sectionVisibleBox checked: sectionVisible text: qsTr("The activity section menu is visible") onCheckedChanged: { sectionVisible = checked; } } Flow { spacing: 5 width: parent.width GCComboBox { id: fontBox model: fonts background: dialogActivityConfig label: qsTr("Font selector") } } Flow { spacing: 5 width: parent.width Slider { id: baseFontSizeSlider width: 250 * ApplicationInfo.ratio style: GCSliderStyle {} maximumValue: ApplicationSettings.baseFontSizeMax minimumValue: ApplicationSettings.baseFontSizeMin stepSize: 1.0 tickmarksEnabled: true updateValueWhileDragging: true value: baseFontSize onValueChanged: ApplicationSettings.baseFontSize = value; } GCText { id: baseFontSizeText text: qsTr("Font size") fontSize: mediumSize wrapMode: Text.WordWrap } Button { height: 30 * ApplicationInfo.ratio text: qsTr("Default"); style: GCButtonStyle {} onClicked: baseFontSizeSlider.value = 0.0 } } Flow { spacing: 5 width: parent.width GCComboBox { id: fontCapitalizationBox model: fontCapitalizationModel background: dialogActivityConfig label: qsTr("Font Capitalization") } } Flow { spacing: 5 width: parent.width GCComboBox { id: languageBox model: dialogConfig.languages background: dialogActivityConfig onCurrentIndexChanged: voicesRow.localeChanged(); label: qsTr("Language selector") } } Flow { id: voicesRow width: parent.width spacing: 5 * ApplicationInfo.ratio property bool haveLocalResource: false function localeChanged() { var language = dialogConfig.languages[languageBox.currentIndex].text; voicesRow.haveLocalResource = DownloadManager.isDataRegistered( "voices-" + ApplicationInfo.CompressedAudio + "/" + ApplicationInfo.getVoicesLocale(dialogConfig.languages[languageBox.currentIndex].locale) ) } Connections { target: DownloadManager onDownloadFinished: voicesRow.localeChanged() } GCText { id: voicesText text: qsTr("Localized voices") } Image { id: voicesImage sourceSize.height: 30 * ApplicationInfo.ratio source: voicesRow.haveLocalResource ? "qrc:/gcompris/src/core/resource/apply.svg" : "qrc:/gcompris/src/core/resource/cancel.svg" } Button { id: voicesButton height: 30 * ApplicationInfo.ratio visible: ApplicationInfo.isDownloadAllowed text: voicesRow.haveLocalResource ? qsTr("Check for updates") : qsTr("Download") style: GCButtonStyle {} onClicked: { if (DownloadManager.downloadResource( DownloadManager.getVoicesResourceForLocale(dialogConfig.languages[languageBox.currentIndex].locale))) { var downloadDialog = Core.showDownloadDialog(dialogConfig.parent.rootItem, {}); } } } } Flow { width: parent.width spacing: 5 * ApplicationInfo.ratio GCText { text: qsTr("Difficulty filter:") fontSize: mediumSize height: 50 * ApplicationInfo.ratio } // Padding Item { height: 1 width: 10 * ApplicationInfo.ratio } Image { source: "qrc:/gcompris/src/core/resource/bar_next.svg" sourceSize.height: Math.min(50 * ApplicationInfo.ratio, parent.width / 8) MouseArea { anchors.fill: parent onClicked: { filterRepeater.setMin(filterRepeater.min + 1) } } } // Padding Item { height: 1 width: 5 * ApplicationInfo.ratio } // Level filtering Repeater { id: filterRepeater model: 6 property int min: ApplicationSettings.filterLevelMin property int max: ApplicationSettings.filterLevelMax function setMin(value) { var newMin if(min < 1) newMin = 1 else if(min > 6) newMin = 6 else if(max >= value) newMin = value if(newMin) ApplicationSettings.filterLevelMin = newMin } function setMax(value) { var newMax if(max < 1) newMax = 1 else if(max > 6) newMax = 6 else if(min <= value) newMax = value if(newMax) ApplicationSettings.filterLevelMax = newMax } Image { source: "qrc:/gcompris/src/core/resource/difficulty" + (modelData + 1) + ".svg"; sourceSize.width: Math.min(50 * ApplicationInfo.ratio, parent.width / 8) opacity: modelData + 1 >= filterRepeater.min && modelData + 1 <= filterRepeater.max ? 1 : 0.4 property int value: modelData + 1 MouseArea { anchors.fill: parent onClicked: { if(parent.value < filterRepeater.max) { if(parent.opacity == 1) filterRepeater.setMin(parent.value + 1) else filterRepeater.setMin(parent.value) } else if(parent.value > filterRepeater.min) { if(parent.opacity == 1) filterRepeater.setMax(parent.value - 1) else filterRepeater.setMax(parent.value) } } } } } // Padding Item { height: 1 width: 5 * ApplicationInfo.ratio } Image { source: "qrc:/gcompris/src/core/resource/bar_previous.svg" sourceSize.height: Math.min(50 * ApplicationInfo.ratio, parent.width / 8) MouseArea { anchors.fill: parent onClicked: { filterRepeater.setMax(filterRepeater.max - 1) } } } } } property bool showLockedActivities: ApplicationSettings.showLockedActivities property bool isAudioVoicesEnabled: ApplicationSettings.isAudioVoicesEnabled property bool isAudioEffectsEnabled: ApplicationSettings.isAudioEffectsEnabled property bool isFullscreen: ApplicationSettings.isFullscreen property bool isVirtualKeyboard: ApplicationSettings.isVirtualKeyboard property bool isAutomaticDownloadsEnabled: ApplicationSettings.isAutomaticDownloadsEnabled property bool sectionVisible: ApplicationSettings.sectionVisible property int baseFontSize // don't bind to ApplicationSettings.baseFontSize // or we get a binding loop warning function loadFromConfig() { // Synchronize settings with data showLockedActivities = ApplicationSettings.showLockedActivities isAudioVoicesEnabled = ApplicationSettings.isAudioVoicesEnabled enableAudioVoicesBox.checked = isAudioVoicesEnabled isAudioEffectsEnabled = ApplicationSettings.isAudioEffectsEnabled enableAudioEffectsBox.checked = isAudioEffectsEnabled isFullscreen = ApplicationSettings.isFullscreen enableFullscreenBox.checked = isFullscreen isVirtualKeyboard = ApplicationSettings.isVirtualKeyboard enableVirtualKeyboardBox.checked = isVirtualKeyboard isAutomaticDownloadsEnabled = ApplicationSettings.isAutomaticDownloadsEnabled enableAutomaticDownloadsBox.checked = isAutomaticDownloadsEnabled sectionVisible = ApplicationSettings.sectionVisible sectionVisibleBox.checked = sectionVisible baseFontSize = ApplicationSettings.baseFontSize; // Set locale for(var i = 0 ; i < dialogConfig.languages.length ; i ++) { if(dialogConfig.languages[i].locale === ApplicationSettings.locale) { languageBox.currentIndex = i; break; } } // Set font for(var i = 0 ; i < fonts.count ; i ++) { if(fonts.get(i).text == ApplicationSettings.font) { fontBox.currentIndex = i; break; } } // Set font capitalization for(var i = 0 ; i < fontCapitalizationModel.length ; i ++) { if(fontCapitalizationModel[i].value == ApplicationSettings.fontCapitalization) { fontCapitalizationBox.currentIndex = i; break; } } } function save() { ApplicationSettings.showLockedActivities = showLockedActivities ApplicationSettings.isAudioVoicesEnabled = isAudioVoicesEnabled ApplicationSettings.isAudioEffectsEnabled = isAudioEffectsEnabled ApplicationSettings.isFullscreen = isFullscreen ApplicationSettings.isVirtualKeyboard = isVirtualKeyboard ApplicationSettings.isAutomaticDownloadsEnabled = isAutomaticDownloadsEnabled ApplicationSettings.sectionVisible = sectionVisible ApplicationSettings.isEmbeddedFont = fonts.get(fontBox.currentIndex).isLocalResource; ApplicationSettings.font = fonts.get(fontBox.currentIndex).text ApplicationSettings.fontCapitalization = fontCapitalizationModel[fontCapitalizationBox.currentIndex].value ApplicationSettings.saveBaseFontSize(); if (ApplicationSettings.locale != dialogConfig.languages[languageBox.currentIndex].locale) { ApplicationSettings.locale = dialogConfig.languages[languageBox.currentIndex].locale if(!DownloadManager.isDataRegistered( "voices-" + ApplicationInfo.CompressedAudio + "/" + ApplicationInfo.getVoicesLocale(dialogConfig.languages[languageBox.currentIndex].locale) )) { // ask for downloading new voices Core.showMessageDialog(main, qsTr("You selected a new locale. You need to restart GCompris to play in your new locale.
Do you want to download the corresponding sound files now?"), qsTr("Yes"), function() { // yes -> start download if (DownloadManager.downloadResource( - DownloadManager.getVoicesResourceForLocale(ApplicationInfo.localeShort))) + DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale))) var downloadDialog = Core.showDownloadDialog(main, {}); }, qsTr("No"), null, null ); } else // check for updates or/and register new voices DownloadManager.updateResource( DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale)) } } function reset() { ApplicationSettings.baseFontSize = baseFontSize; } ListModel { id: fonts Component.onCompleted: { var systemFonts = Qt.fontFamilies(); var rccFonts = ApplicationInfo.getFontsFromRcc(); // Remove explicitly all *symbol* and *ding* fonts var excludedFonts = ApplicationInfo.getSystemExcludedFonts(); excludedFonts.push("ding"); excludedFonts.push("symbol"); for(var i = 0 ; i < systemFonts.length ; ++ i) { var isExcluded = false; // Remove symbol fonts for(var j = 0 ; j < excludedFonts.length ; ++ j) { if(systemFonts[i].toLowerCase().indexOf(excludedFonts[j].toLowerCase()) != -1) { isExcluded = true; break; } } // Remove fonts from rcc (if you have a default font from rcc, Qt will add it to systemFonts) for(var j = 0 ; j < rccFonts.length ; ++ j) { if(rccFonts[j].toLowerCase().indexOf(systemFonts[i].toLowerCase()) != -1) { isExcluded = true; break; } } // Finally, we know if we add this font or not if(!isExcluded) { fonts.append({ "text": systemFonts[i], "isLocalResource": false }); } } for(var i = 0 ; i < rccFonts.length ; ++ i) { // Append fonts from resources fonts.append({ "text": rccFonts[i], "isLocalResource": true }); } } } property variant fontCapitalizationModel: [ { text: qsTr("Mixed case (default)"), value: Font.MixedCase }, { text: qsTr("All uppercase"), value: Font.AllUppercase }, { text: qsTr("All lowercase"), value: Font.AllLowercase } ] function hasConfigChanged() { return (ApplicationSettings.locale !== dialogConfig.languages[languageBox.currentIndex].locale || (ApplicationSettings.sectionVisible != sectionVisible) || (ApplicationSettings.font != fonts.get(fontBox.currentIndex).text) || (ApplicationSettings.isEmbeddedFont != fonts.get(fontBox.currentIndex).isLocalResource) || (ApplicationSettings.isEmbeddedFont != fonts.get(fontBox.currentIndex).isLocalResource) || (ApplicationSettings.fontCapitalization != fontCapitalizationModel[(fontcapitalizationBox.currentIndex)].value) || (ApplicationSettings.isAudioVoicesEnabled != isAudioVoicesEnabled) || (ApplicationSettings.isAudioEffectsEnabled != isAudioEffectsEnabled) || (ApplicationSettings.isFullscreen != isFullscreen) || (ApplicationSettings.isVirtualKeyboard != isVirtualKeyboard) || (ApplicationSettings.isAutomaticDownloadsEnabled != isAutomaticDownloadsEnabled) || (ApplicationSettings.baseFontSize != baseFontSize) || (ApplicationSettings.showLockedActivities != showLockedActivities) ); } } diff --git a/src/activities/missing-letter/missing-letter.js b/src/activities/missing-letter/missing-letter.js index d34b8a33d..5ed0bba1d 100644 --- a/src/activities/missing-letter/missing-letter.js +++ b/src/activities/missing-letter/missing-letter.js @@ -1,258 +1,260 @@ /* GCompris - missing-letter.js * * Copyright (C) 2014 "Amit Tomar" * * Authors: * "Pascal Georges" (GTK+ version) * "Amit Tomar" (Qt Quick port) * * 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 . */ .pragma library .import QtQuick 2.0 as Quick .import "qrc:/gcompris/src/core/core.js" as Core .import GCompris 1.0 as GCompris //for ApplicationInfo var url = "qrc:/gcompris/src/activities/missing-letter/resource/" var questionsStatic = [ [ // Level 1 { questionString: "c_r", answerString : "car", choiceString : "atr", pictureSource : url + "car.png", }, { questionString: "_og", answerString : "dog", choiceString : "dws", pictureSource : url + "dog.png", }, { questionString: "_pple", answerString : "apple", choiceString : "back", pictureSource : url + "apple.png", }, { questionString: "bal_", answerString : "ball", choiceString : "hlt", pictureSource : url + "ball.png", } ], [ // Level 2 { questionString: "be_", answerString : "bed", choiceString : "dfg", pictureSource : url + "bed.png", }, { questionString: "_ake", answerString : "cake", choiceString : "lxc", pictureSource : url + "cake.png", }, { questionString: "ba_", answerString : "bag", choiceString : "qlg", pictureSource : url + "bag.png", }, { questionString: "f_sh", answerString : "fish", choiceString : "epi", pictureSource : url + "fish.png", } ], [ // Level 3 { questionString: "bana_a", answerString : "banana", choiceString : "bakn", pictureSource : url + "banana.png", }, { questionString: "bottl_", answerString : "bottle", choiceString : "degw", pictureSource : url + "bottle.png", }, { questionString: "_ouse", answerString : "house", choiceString : "khpz", pictureSource : url + "house.png", }, { questionString: "_lane", answerString : "plane", choiceString : "lmpo", pictureSource : url + "plane.png", } ] ] var items var currentLevel var numberOfLevel var currentQuestionNumber var questions var dataset function start(items_) { items = items_ currentLevel = 0 questions = questionsStatic createLastLevel() numberOfLevel = questions.length initLevel() } function stop() { } function initLevel() { items.bar.level = currentLevel + 1 dataset = Core.shuffle(questions[currentLevel]) currentQuestionNumber = 0 nextQuestion() items.currentQuestionNumberText.text = "1/" + dataset.length } function nextLevel() { if(numberOfLevel <= ++currentLevel ) { currentLevel = 0 } initLevel(); } function previousLevel() { if(--currentLevel < 0) { currentLevel = numberOfLevel - 1 } initLevel(); } function correctOptionPressed() { nextQuestion() if( currentQuestionNumber > dataset.length ) currentQuestionNumber = 0 items.currentQuestionNumberText.text = currentQuestionNumber + "/" + dataset.length } function wrongOptionPressed() { items.bar.opacity = 1 } function getCorrectAnswer() { var question = dataset[currentQuestionNumber] var currentQuestion = question.questionString var i = 0 for( ; i < currentQuestion.length ; ++i ) { if( "_" == currentQuestion.charAt(i) ) { break; } } return question.answerString.charAt(i) } // Take appropriate action based on the character being pressed function answerPressed(character) { if( character === getCorrectAnswer() ) { items.bonus.good("flower") return true } else { items.bonus.bad("flower") } return false } function showAnswer() { var question = dataset[currentQuestionNumber] items.questionText.text = question.answerString items.questionText.state = "answer" } // Reset the screen values for next question function nextQuestion() { items.questionText.state = "question" items.answers.model = [] if(++currentQuestionNumber >= dataset.length) { nextLevel() return } var question = dataset[currentQuestionNumber] var choice = question.choiceString var answersModel = new Array() for(var i = 0 ; i < choice.length ; ++i) answersModel.push(choice.charAt(i)) items.answers.model = answersModel items.questionText.text = question.questionString items.questionImage.source = question.pictureSource } // Add a new level which contains all the questions given in the // questions list, combined together. function createLastLevel() { var lastData = [] for(var level = 0 ; level < questions.length ; ++level) for(var i = 0 ; i < questions.length ; ++i) lastData.push(questions[level][i]) questions.push(lastData) } function playLetter(letter) { - items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + // WARNING This activity is english only for now + // replace en by $LOCALE once i18n support + items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/en/alphabet/" + Core.getSoundFilenamForChar(letter))) } diff --git a/tools/menus/readingh.qml b/src/activities/readingh/ActivityInfo.qml similarity index 83% rename from tools/menus/readingh.qml rename to src/activities/readingh/ActivityInfo.qml index 4f7c595fd..cf9a0481d 100644 --- a/tools/menus/readingh.qml +++ b/src/activities/readingh/ActivityInfo.qml @@ -1,33 +1,35 @@ /* GCompris - ActivityInfo.qml * - * Copyright (C) 2015 Your Name + * Copyright (C) 2015 Johnny Jazeix * * 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 . */ import GCompris 1.0 ActivityInfo { name: "readingh/Readingh.qml" difficulty: 2 icon: "readingh/readingh.svg" - author: "Bruno Coudoin " - demo: false + author: "Johnny Jazeix <jazeix@gmail.com>" + demo: true title: qsTr("Horizontal reading practice") - description: qsTr("Read a list of words and work out if a given word is in it") + description: qsTr("Read a list of words and work out if a given word is in it.") +// intro: "Read a list of words and work out if a given word is in it." goal: qsTr("Reading training in a limited time") prerequisite: qsTr("Reading") manual: qsTr("A word is shown at the top right of the board. A list of words will appear and disappear on the left. Does the given word belong to the list?") credit: "" - section: "/reading" + section: "reading" } + diff --git a/src/activities/readingh/CMakeLists.txt b/src/activities/readingh/CMakeLists.txt new file mode 100644 index 000000000..7f5f7d3a9 --- /dev/null +++ b/src/activities/readingh/CMakeLists.txt @@ -0,0 +1 @@ +GCOMPRIS_ADD_RCC(activities/readingh *.qml *.svg *.js resource/*) diff --git a/src/activities/readingh/Readingh.qml b/src/activities/readingh/Readingh.qml new file mode 100644 index 000000000..a12ff5dec --- /dev/null +++ b/src/activities/readingh/Readingh.qml @@ -0,0 +1,321 @@ +/* GCompris - readingh.qml + * + * Copyright (C) 2015 Johnny Jazeix + * + * Authors: + * Bruno Coudoin (GTK+ version) + * Johnny Jazeix (Qt Quick port) + * + * 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 . + */ +import QtQuick 2.1 +import GCompris 1.0 + +import "../../core" +import "readingh.js" as Activity + +ActivityBase { + id: activity + + onStart: focus = true + onStop: {} + + /* mode of the activity, "readingh" (horizontal) or "readingv" (vertical):*/ + property string mode: "readingh" + + pageComponent: Image { + id: background + anchors.fill: parent + source: Activity.url + "reading-bg.svg" + signal start + signal stop + sourceSize.width: parent.width + fillMode: Image.Stretch + + Component.onCompleted: { + dialogActivityConfig.getInitialConfiguration() + activity.start.connect(start) + activity.stop.connect(stop) + } + + // system locale by default + property string locale: "system" + + // Add here the QML items you need to access in javascript + QtObject { + id: items + property Item main: activity.main + property alias background: background + property alias bar: bar + property alias bonus: bonus + property alias wordlist: wordlist + property alias wordDropTimer: wordDropTimer + property alias locale: background.locale + property alias iAmReady: iAmReady + property alias answerButtonFound: answerButtonFound + property alias answerButtonNotFound: answerButtonNotFound + property alias answerButtonsFlow: answerButtonsFlow + property alias wordDisplayRepeater: wordDisplayRepeater + property string textToFind + property int currentIndex + } + + onStart: { Activity.start(items, mode) } + onStop: { Activity.stop() } + + DialogActivityConfig { + id: dialogActivityConfig + currentActivity: activity + content: Component { + Item { + property alias localeBox: localeBox + property alias leftToRightBox: leftToRightBox + height: column.height + + property alias availableLangs: langs.languages + LanguageList { + id: langs + } + + Column { + id: column + spacing: 10 + width: parent.width + + Flow { + spacing: 5 + width: dialogActivityConfig.width + GCComboBox { + id: localeBox + model: langs.languages + background: dialogActivityConfig + width: dialogActivityConfig.width + label: qsTr("Select your locale") + } + } + GCDialogCheckBox { + id: leftToRightBox + width: 300 * ApplicationInfo.ratio + text: qsTr("Left to right mode") + checked: wordDisplayList.layoutDirection == Qt.LeftToRight + } + } + } + } + + onClose: home() + onLoadData: { + if(dataToSave) { + if(dataToSave["locale"]) { + background.locale = dataToSave["locale"]; + } + if(dataToSave["leftToRight"] == false) { + wordDisplayList.layoutDirection = Qt.RightToLeft; + } + else { // true or undefined (default value) + wordDisplayList.layoutDirection = Qt.LeftToRight; + } + } + } + onSaveData: { + var oldLocale = background.locale; + var newLocale = dialogActivityConfig.configItem.availableLangs[dialogActivityConfig.loader.item.localeBox.currentIndex].locale; + var leftToRightMode = dialogActivityConfig.loader.item.leftToRightBox.checked; + // Remove .UTF-8 + if(newLocale.indexOf('.') != -1) { + newLocale = newLocale.substring(0, newLocale.indexOf('.')) + } + dataToSave = { + "locale": newLocale, + "leftToRight": leftToRightMode + } + + background.locale = newLocale; + wordDisplayList.layoutDirection = leftToRightMode ? Qt.LeftToRight : Qt.RightToLeft; + + // Restart the activity with new information + if(oldLocale !== newLocale) { + background.stop(); + background.start(); + } + } + + function setDefaultValues() { + var localeUtf8 = background.locale; + if(background.locale != "system") { + localeUtf8 += ".UTF-8"; + } + + for(var i = 0 ; i < dialogActivityConfig.configItem.availableLangs.length ; i ++) { + if(dialogActivityConfig.configItem.availableLangs[i].locale === localeUtf8) { + dialogActivityConfig.loader.item.localeBox.currentIndex = i; + break; + } + } + } + } + + DialogHelp { + id: dialogHelp + onClose: home() + } + + Bar { + id: bar + content: BarEnumContent { value: help | home | level | config } + onHelpClicked: { + displayDialog(dialogHelp) + } + onPreviousLevelClicked: Activity.previousLevel() + onNextLevelClicked: Activity.nextLevel() + onHomeClicked: activity.home() + onConfigClicked: { + dialogActivityConfig.active = true + dialogActivityConfig.setDefaultValues() + displayDialog(dialogActivityConfig) + } + } + + Bonus { + id: bonus + // Do not pass automatically at next level, allowing the child to do more than one try, or add sublevels? + Component.onCompleted: { + win.connect(resetClickInProgress) + loose.connect(resetClickInProgress) + } + } + // used to know if we already click on "Yes" or "No" + property bool isClickInProgress: false + // used to avoid multiple clicks between the begin and end of bonus play + property bool isClickInProgress2: false + function resetClickInProgress() { + isClickInProgress = false; + isClickInProgress2 = false; + Activity.initLevel() + } + + Flow { + id: wordDisplayList + spacing: 20 + x: 70/800*parent.width + y: 100/600*parent.height + width: 350/800*parent.width-x + height: 520/600*parent.height-y + flow: mode == "readingh" ? Flow.LeftToRight : Flow.TopToBottom + layoutDirection: Qt.LeftToRight + + Repeater { + id: wordDisplayRepeater + model: Activity.words + property int idToHideBecauseOverflow: 0 + delegate: GCText { + text: modelData + opacity: iAmReady.visible ? false : (index == items.currentIndex ? 1 : 0) + + onOpacityChanged: { + /* Handle case where we go over the image + On these cases, we hide all above items to restart to 0 + As we don't replay the same level and always replace the model, + we do not care about restoring visible to true */ + if((x+width > wordDisplayList.width) || + (y+height > wordDisplayList.height)) { + var i = wordDisplayRepeater.idToHideBecauseOverflow; + for(; i < index; ++i) { + wordDisplayRepeater.itemAt(i).visible=false + } + wordDisplayRepeater.idToHideBecauseOverflow = i + } + } + } + } + } + + GCText { + id: wordToFindBox + x: 430/800*parent.width + y: 90/600*parent.height + text: qsTr("Check if the word
%1
is displayed").arg(items.textToFind) + color: "black" + horizontalAlignment: Text.AlignHCenter + width: background.width/3 + height: background.height/5 + fontSizeMode: Text.Fit + } + + ReadyButton { + id: iAmReady + onClicked: Activity.run() + x: background.width / 2 + y: background.height / 2 + anchors.verticalCenter: undefined + anchors.horizontalCenter: undefined + } + Flow { + id: answerButtonsFlow + x: iAmReady.x + y: iAmReady.y + width: wordToFindBox.width + AnswerButton { + id : answerButtonFound + width: Math.min(250 * ApplicationInfo.ratio, background.width/2-10) + height: 80 * ApplicationInfo.ratio + textLabel: qsTr("Yes, I saw it!") + isCorrectAnswer: Activity.words ? Activity.words.indexOf(items.textToFind) != -1 : false + onCorrectlyPressed: if(isClickInProgress && !isClickInProgress2) { bonus.good("flower"); isClickInProgress2 = true } + onIncorrectlyPressed: if(isClickInProgress && !isClickInProgress2) { bonus.bad("flower"); isClickInProgress2 = true } + onPressed: { + if(!isClickInProgress) { + isClickInProgress = true + } + } + } + + AnswerButton { + id : answerButtonNotFound + width: Math.min(250 * ApplicationInfo.ratio, background.width/2-10) + height: 80 * ApplicationInfo.ratio + textLabel: qsTr("No, it was not there!") + isCorrectAnswer: !answerButtonFound.isCorrectAnswer + onCorrectlyPressed: if(isClickInProgress && !isClickInProgress2) { bonus.good("flower"); isClickInProgress2 = true } + onIncorrectlyPressed: if(isClickInProgress && !isClickInProgress2) { bonus.bad("flower"); isClickInProgress2 = true } + + onPressed: { + if(!isClickInProgress) { + isClickInProgress = true + } + } + } + } + + Wordlist { + id: wordlist + defaultFilename: Activity.dataSetUrl + "default-en.json" + // To switch between locales: xx_XX stored in configuration and + // possibly correct xx if available (ie fr_FR for french but dataset is fr.) + useDefault: false + filename: "" + + onError: console.log("Reading: Wordlist error: " + msg); + } + + Timer { + id: wordDropTimer + repeat: true + interval: 1000 + onTriggered: Activity.dropWord(); + } + + } + +} diff --git a/src/activities/readingh/readingh.js b/src/activities/readingh/readingh.js new file mode 100644 index 000000000..d3735dbe1 --- /dev/null +++ b/src/activities/readingh/readingh.js @@ -0,0 +1,118 @@ +/* GCompris - readingh.js + * + * Copyright (C) 2015 Johnny Jazeix + * + * Authors: + * Bruno Coudoin (GTK+ version) + * Johnny Jazeix (Qt Quick port) + * + * 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 . + */ +.pragma library +.import QtQuick 2.0 as Quick +.import GCompris 1.0 as GCompris //for ApplicationInfo +.import "qrc:/gcompris/src/core/core.js" as Core + +var currentLevel = 0 +var items +var maxLevel + +var url = "qrc:/gcompris/src/activities/readingh/resource/" +var dataSetUrl= "qrc:/gcompris/src/activities/wordsgame/resource/" + +// +var level +// words to display +var words + +function start(items_) { + items = items_ + currentLevel = 0 + var locale = items.locale == "system" ? "$LOCALE" : items.locale + + items.wordlist.loadFromFile(GCompris.ApplicationInfo.getLocaleFilePath( + dataSetUrl + "default-"+locale+".json")); + // If wordlist is empty, we try to load from short locale and if not present again, we switch to default one + var localeUnderscoreIndex = locale.indexOf('_') + // probably exist a better way to see if the list is empty + if(items.wordlist.maxLevel == 0) { + var localeShort; + // We will first look again for locale xx (without _XX if exist) + if(localeUnderscoreIndex > 0) { + localeShort = locale.substring(0, localeUnderscoreIndex) + } + else { + localeShort = locale; + } + // If not found, we will use the default file + items.wordlist.useDefault = true + items.wordlist.loadFromFile(GCompris.ApplicationInfo.getLocaleFilePath( + dataSetUrl + "default-"+localeShort+".json")); + // We remove the using of default file for next time we enter this function + items.wordlist.useDefault = false + } + maxLevel = items.wordlist.maxLevel; + initLevel(); +} + +function stop() { + items.wordDropTimer.stop(); +} + +function initLevel() { + items.bar.level = currentLevel + 1; + items.wordDropTimer.stop(); + items.answerButtonsFlow.visible = false; + + // initialize level + level = items.wordlist.getLevelWordList(currentLevel + 1); + items.wordlist.initRandomWord(currentLevel + 1) + items.textToFind = items.wordlist.getRandomWord() + Core.shuffle(level.words) + words = level.words.slice(0, 15) + items.currentIndex = -1 + + items.wordDisplayRepeater.model = words + items.wordDisplayRepeater.idToHideBecauseOverflow = 0 + items.answerButtonFound.isCorrectAnswer = words.indexOf(items.textToFind) != -1 + items.iAmReady.visible = true +} + +function nextLevel() { + if(maxLevel <= ++currentLevel) { + currentLevel = 0 + } + initLevel(); +} + +function previousLevel() { + if(--currentLevel < 0) { + currentLevel = maxLevel - 1 + } + initLevel(); +} + +function run() { + items.wordDropTimer.start(); +} + +function dropWord() { + if(++items.currentIndex < words.length) { + // Display next word + } + else { + items.wordDropTimer.stop(); + items.answerButtonsFlow.visible = true + } +} diff --git a/tools/menus/resource/readingh.svg b/src/activities/readingh/readingh.svg similarity index 71% rename from tools/menus/resource/readingh.svg rename to src/activities/readingh/readingh.svg index b6850a048..530f694dc 100644 --- a/tools/menus/resource/readingh.svg +++ b/src/activities/readingh/readingh.svg @@ -1,186 +1,112 @@ + inkscape:window-width="3200" + inkscape:window-height="1741" + inkscape:window-x="-4" + inkscape:window-y="0" + showgrid="false" + inkscape:window-maximized="1" /> image/svg+xml - - - A - - - - B - - - - C - + style="fill:#327cf4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="fill:#f4ef32;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + d="m 46.844192,15.88938 -3.330316,1.627712 -1.724122,3.516278 0.41104,4.667076 1.703898,5.245872 3.53568,2.849828 4.466351,0.4402 3.594799,-1.996596 1.890591,-2.954463 -1.467495,-5.013753 -8.189892,2.444512 -0.13691,-2.985027 1.126389,0.01698 6.543014,-2.138587 -0.342585,-3.174563 -2.242822,-2.271033 -2.869803,-0.602567 z" + style="fill:#83e137;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.42767739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccccccccccccccc" /> - - - - + style="fill:#f4a932;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> diff --git a/src/activities/readingh/resource/reading-bg.svg b/src/activities/readingh/resource/reading-bg.svg new file mode 100644 index 000000000..b0cc9c1a9 --- /dev/null +++ b/src/activities/readingh/resource/reading-bg.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/tools/menus/readingv.qml b/src/activities/readingv/ActivityInfo.qml similarity index 82% rename from tools/menus/readingv.qml rename to src/activities/readingv/ActivityInfo.qml index 1923ed7a6..8c36c8f8d 100644 --- a/tools/menus/readingv.qml +++ b/src/activities/readingv/ActivityInfo.qml @@ -1,33 +1,35 @@ /* GCompris - ActivityInfo.qml * - * Copyright (C) 2015 Your Name + * Copyright (C) 2015 Johnny Jazeix * * 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 . */ import GCompris 1.0 ActivityInfo { name: "readingv/Readingv.qml" difficulty: 2 icon: "readingv/reading.svg" - author: "Bruno Coudoin " - demo: false + author: "Johnny Jazeix <jazeix@gmail.com>" + demo: true title: qsTr("Vertical-reading practice") - description: qsTr("Read a vertical list of words and work out if a given word is in it") + description: qsTr("Read a vertical list of words and work out if a given word is in it.") +// intro: "Read a list of words and work out if a given word is in it." goal: qsTr("Read training in a limited time") prerequisite: qsTr("Reading") manual: qsTr("A word is shown at the top right of the board. A list of words will appear and disappear on the left. Does the given word belong to the list?") credit: "" - section: "/reading" + section: "reading" } + diff --git a/src/activities/readingv/CMakeLists.txt b/src/activities/readingv/CMakeLists.txt new file mode 100644 index 000000000..c8a37b49a --- /dev/null +++ b/src/activities/readingv/CMakeLists.txt @@ -0,0 +1 @@ +GCOMPRIS_ADD_RCC(activities/readingv *.qml *.svg) diff --git a/src/activities/geography/ActivityInfo.qml b/src/activities/readingv/Readingv.qml similarity index 57% copy from src/activities/geography/ActivityInfo.qml copy to src/activities/readingv/Readingv.qml index cb96e62e8..f4eb03b00 100644 --- a/src/activities/geography/ActivityInfo.qml +++ b/src/activities/readingv/Readingv.qml @@ -1,37 +1,28 @@ -/* GCompris - ActivityInfo.qml +/* GCompris - readingv.qml * - * Copyright (C) 2015 Pulkit Gupta + * Copyright (C) 2015 Johnny Jazeix * * Authors: - * Pulkit Gupta + * Bruno Coudoin (GTK+ version) + * Johnny Jazeix (Qt Quick port) * * 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 . */ +import QtQuick 2.1 -import GCompris 1.0 +import "../readingh" -ActivityInfo { - name: "geography/Geography.qml" - difficulty: 2 - icon: "geography/globe.svg" - author: "Pulkit Gupta <pulkitgenius@gmail.com>" - demo: true - title: qsTr("Locate the countries") - description: qsTr("Drag and Drop the items to redraw the whole map") - goal: "" - prerequisite: "" - manual: "" - credit: "" - section: "discovery" +Readingh { + mode: "readingv" } diff --git a/src/activities/readingv/reading.svg b/src/activities/readingv/reading.svg new file mode 100644 index 000000000..af105318e --- /dev/null +++ b/src/activities/readingv/reading.svg @@ -0,0 +1,114 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/src/activities/superbrain/ActivityInfo.qml b/src/activities/superbrain/ActivityInfo.qml index bc4ddbc39..34a113550 100644 --- a/src/activities/superbrain/ActivityInfo.qml +++ b/src/activities/superbrain/ActivityInfo.qml @@ -1,34 +1,34 @@ /* GCompris - ActivityInfo.qml * * Copyright (C) 2015 Holger Kaelberer * * 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 . */ import GCompris 1.0 ActivityInfo { name: "superbrain/Superbrain.qml" difficulty: 2 icon: "superbrain/superbrain.svg" author: "Holger Kaelberer <holger.k@elberer.de>" demo: true title: qsTr("Super Brain") description: qsTr("Tux has hidden several items. Find them again in the correct order") //intro: "Find out the right combination of colors. A black pin means you found the correct colour in the correct position, a white pin means it's the correct colour but in the wrong position." goal: qsTr("Tux has hidden several items. Find them again in the correct order") prerequisite: "" - manual: qsTr("Click on the items until you find what you think is the correct answer. Then, click on the OK button. In the lower levels, Tux gives you an indication if you found a hiding place by marking the item with a black box. You can use the right mouse button to flip the colors in the opposite order or the color chooser to directly pick a color. Press and hold a mouse button or on the touch screen to automatically choose the last color selected on a column.") + manual: qsTr("Click on the items until you find what you think is the correct answer. Then, click on the OK button. In the lower levels, Tux gives you an indication if you found a hiding place by marking the item with a black box. In the levels 4 and 8 an item may be hidden several times.
You can use the right mouse button to flip the items in the opposite order or the item chooser to directly pick an item. Press and hold a mouse button or on the touch screen to automatically choose the last item selected on a column. Double click or tap on a previously selected item in your guess history to mark it as 'correct'. Such marked items are automatically selected in your current and future guesses until you un-mark them, again by double clicking or tapping.") credit: "" section: "puzzle" } diff --git a/src/activities/superbrain/SearchItem.qml b/src/activities/superbrain/SearchItem.qml new file mode 100644 index 000000000..7aefb107b --- /dev/null +++ b/src/activities/superbrain/SearchItem.qml @@ -0,0 +1,65 @@ +/* GCompris - SearchItem.qml + * + * Copyright (C) 2015 Holger Kaelberer + * + * Authors: + * Holger Kaelberer + * + * 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 . + */ + +import QtQuick 2.1 +import GCompris 1.0 +//import QtGraphicalEffects 1.0 +import "superbrain.js" as Activity + +Item { + id: root + property int searchItemIndex: 0 + property alias border: color.border + property alias radius: color.radius + property bool highlightSymbol: false + + Image { + id: symbol + visible: Activity.mode === "symbol" + fillMode: Image.PreserveAspectFit + source: Activity.symbols[root.searchItemIndex] + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: 3 + width: parent.width - 6 + height: parent.height - 6 + } + Rectangle { + id: symbolHighlighter + visible: (Activity.mode === "symbol") && root.highlightSymbol + anchors.fill: parent + width: parent.width + height: parent.height + border.width: 3 + border.color: "white" + color: "transparent" + } + + Rectangle { + id: color + visible: Activity.mode === "color" + color: Activity.colors[root.searchItemIndex] + anchors.fill: parent + width: parent.width + height: parent.height + radius: width / 2 + } +} diff --git a/src/activities/superbrain/Superbrain.qml b/src/activities/superbrain/Superbrain.qml index 9de2b4201..ab35486e8 100644 --- a/src/activities/superbrain/Superbrain.qml +++ b/src/activities/superbrain/Superbrain.qml @@ -1,651 +1,707 @@ /* GCompris - Superbrain.qml * * Copyright (C) 2015 Holger Kaelberer * * Authors: * Bruno Coudoin (GTK+ version) * Holger Kaelberer (Qt Quick port) * * 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 . */ import QtQuick 2.1 import "../../core" import "superbrain.js" as Activity import GCompris 1.0 ActivityBase { id: activity onStart: focus = true onStop: {} pageComponent: Image { id: background source: Activity.baseUrl + "background.svg" sourceSize.width: parent.width fillMode: Image.PreserveAspectCrop focus: true - readonly property double scaleFactor: Math.max(1, - Math.min(background.width / 800, - background.height / 520)) + readonly property double scaleFactor: 1 readonly property bool isPortrait: (height > width) signal start signal stop MouseArea { anchors.fill: parent onClicked: showChooser(false); } Component.onCompleted: { + dialogActivityConfig.getInitialConfiguration() activity.start.connect(start) activity.stop.connect(stop) } QtObject { id: items property Item main: activity.main property alias background: background property alias bar: bar property alias bonus: bonus property alias score: score property alias colorsRepeater: colorsRepeater property alias chooserGrid: chooserGrid property alias guessModel: guessModel property alias guessColumn: guessColumn property alias currentRepeater: currentRepeater } onStart: { Activity.start(items) } onStop: { Activity.stop() } Column { id: colorsColumn anchors.left: parent.left - anchors.leftMargin: 5 * background.scaleFactor * ApplicationInfo.ratio + anchors.leftMargin: 5 * ApplicationInfo.ratio anchors.top: parent.top - anchors.topMargin: 5 * background.scaleFactor * ApplicationInfo.ratio + anchors.topMargin: 5 * ApplicationInfo.ratio - spacing: 3 * background.scaleFactor * ApplicationInfo.ratio + spacing: 3 * ApplicationInfo.ratio width: guessColumn.guessSize height: guessColumn.guessSize add: Transition { NumberAnimation { properties: "y"; duration: 1000; easing.type: Easing.OutBounce } } Repeater { id: colorsRepeater model: ListModel {} - delegate: Rectangle { - width: 40 * background.scaleFactor * ApplicationInfo.ratio - height: 40 * background.scaleFactor * ApplicationInfo.ratio - radius: width * 0.5 + delegate: SearchItem { + width: 40 * ApplicationInfo.ratio + height: 40 * ApplicationInfo.ratio border.width: 2 border.color: "white" - color: col + searchItemIndex: itemIndex } } } Rectangle { id: tooltipRect width: 100 * ApplicationInfo.ratio height: tooltipText.height + 10 * ApplicationInfo.ratio radius: 4 x: 0 y: 0 color: "lightgray" opacity: 0 z: 10 property alias text: tooltipText.text GCText { id: tooltipText anchors.centerIn: parent fontSize: 13 text: "" color: "black" onTextChanged: parent.width = width + 10 } Behavior on opacity { NumberAnimation { duration: 100 } } } function showTooltip(visible, status, mouseArea) { if (!visible || status === Activity.STATUS_UNKNOWN) { tooltipRect.opacity = 0; return; } showChooser(false); var obj = background.mapFromItem(mouseArea, mouseArea.mouseX, mouseArea.mouseY); if (status === Activity.STATUS_CORRECT) tooltipRect.text = qsTr("This item is well placed"); if (status === Activity.STATUS_MISPLACED) tooltipRect.text = qsTr("This item is misplaced"); tooltipRect.x = obj.x - 5 - tooltipRect.width; tooltipRect.y = obj.y - 5 - tooltipRect.height; tooltipRect.opacity = 0.9; } function showChooser(visible, guessIndex, item) { if (!visible) { chooserTimer.stop(); chooser.scale = 0; return; } var modelObj = guessModel.get(0).guess.get(guessIndex); var absolute = currentRow.mapToItem(background, item.x, item.y); chooserGrid.colIndex = modelObj.colIndex; chooserGrid.guessIndex = guessIndex; var chooserOffset = 0.5*chooser.width - item.width/2; var arrowOffset = 0; var targetX = item.x - chooserOffset; // beyond left screen border: if (absolute.x - chooserOffset < 0) { arrowOffset = absolute.x - chooserOffset; targetX -= arrowOffset; } // beyond right screen border: if (absolute.x + chooserOffset + item.width > background.width) { arrowOffset = absolute.x + chooserOffset + item.width - background.width; targetX -= arrowOffset; } chooser.x = targetX; chooser.arrowOffset = arrowOffset; var targetY = item.y - chooser.height - 15; var targetAbove = true; /* //only on top-level, at window border: if (targetY < 0) { targetY = item.y + guessColumn.guessSize + 10; targetAbove = false; }*/ chooser.y = targetY; chooser.above = targetAbove; chooser.scale = 1; chooser.visible = true; chooserTimer.restart(); //console.log("XXX chooser at item.x=" + item.x + " absolute.x=" + absolute.x + " chooser.x/w=" + chooser.x + "/" + chooser.width + " background.width=" + background.width + " currentRow.x/y/w/h=" + currentRow.x + "/" + currentRow.y + "/" + currentRow.width + "/" + currentRow.height + " guessIdx=" + guessIndex + " arrowOff=" + arrowOffset); } Item { id: currentWrapper width: currentRow.width height: currentRow.height z: 8 anchors.horizontalCenter: parent.horizontalCenter anchors.bottomMargin: 20 * ApplicationInfo.ratio state: ApplicationSettings.isBarHidden ? "hidden" : "shown" states: [ State { name: "hidden" when: ApplicationSettings.isBarHidden AnchorChanges { target: currentWrapper; anchors.bottom: parent.bottom } }, State { name: "shown" when: !ApplicationSettings.isBarHidden AnchorChanges { target: currentWrapper; anchors.bottom: bar.top } } ] transitions: Transition { AnchorAnimation { duration: 800; easing.type: Easing.OutBounce } } Rectangle { id: chooser width: chooserGrid.width + 15 height: chooserGrid.height + 15 color: "darkgray" border.width: 0 border.color: "white" opacity: 1 scale: 0 visible: false z: 10 property bool above: true property real arrowOffset: 0 Rectangle { id: chooserArrow width: 10 height: 10 x: chooser.width / 2 - 5 + chooser.arrowOffset y: chooser.above ? (chooser.height - 5) : (-5) color: chooser.color z: chooser.z transform: Rotation { origin.x: 5; origin.y: 5; angle: 45} } GridView { id: chooserGrid cellWidth: guessColumn.guessSize * 2 cellHeight: guessColumn.guessSize * 2 - width: Math.ceil(count / 2) * cellWidth// * 1.2 - height: 2 * cellHeight// * 1.2 + width: Math.ceil(count / 2) * cellWidth + height: 2 * cellHeight anchors.centerIn: parent z: 11 clip: false interactive: false verticalLayoutDirection: GridView.TopToBottom layoutDirection: Qt.LeftToRight flow: GridView.FlowLeftToRight property int colIndex: 0 property int guessIndex: 0 Timer { id: chooserTimer interval: 5000 onTriggered: showChooser(false); } model: new Array() - delegate: Rectangle { + delegate: SearchItem { + id: chooserItem width: chooserGrid.cellWidth height: chooserGrid.cellWidth - radius: 5 * background.scaleFactor border.width: index == chooserGrid.colIndex ? 3 : 1 border.color: index == chooserGrid.colIndex ? "white" : "darkgray" - color: modelData + highlightSymbol: index == chooserGrid.colIndex + searchItemIndex: modelData + radius: 5 MouseArea { id: chooserMouseArea anchors.fill: parent acceptedButtons: Qt.LeftButton z: 11 hoverEnabled: ApplicationInfo.isMobile ? false : true onClicked: { - chooserGrid.colIndex = index; + chooserGrid.colIndex = chooserItem.searchItemIndex; var obj = items.guessModel.get(0); obj.guess.setProperty(chooserGrid.guessIndex, "colIndex", chooserGrid.colIndex); showChooser(false); } } } } Behavior on scale { NumberAnimation { duration: 100 } } } Row { id: currentRow visible: true property double factor: 1.9 anchors.left: parent.left anchors.top: parent.top spacing: guessColumn.horizSpacing * factor height: guessColumn.guessSize * factor scale: 1 z: 9 Repeater { id: currentRepeater - delegate: Rectangle { + delegate: SearchItem { id: currentGuess width: guessColumn.guessSize * currentRow.factor height: guessColumn.guessSize * currentRow.factor - radius: width * 0.5 border.width: 2 * currentRow.factor border.color: "lightgray" - color: Activity.colors[colIndex] + searchItemIndex: colIndex opacity: 1.0 z: 2 MouseArea { id: mouseArea anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton enabled: true z: 3 hoverEnabled: ApplicationInfo.isMobile ? false : true onPressAndHold: { if (guessColumn.count > 1) guessModel.get(0).guess.get(index).colIndex = guessModel.get(1).guess.get(index).colIndex; } onClicked: { var obj = items.guessModel.get(0).guess.get(index); if(chooserTimer.running && chooserGrid.guessIndex === index) { if (mouse.button == Qt.LeftButton) obj.colIndex = (obj.colIndex == - Activity.currentColors.length - 1) ? 0 : obj.colIndex + 1; + Activity.currentIndeces.length - 1) ? 0 : obj.colIndex + 1; else obj.colIndex = (obj.colIndex == 0) ? - Activity.currentColors.length - 1 : obj.colIndex - 1; + Activity.currentIndeces.length - 1 : obj.colIndex - 1; } showChooser(true, index, parent); } } states: State { name: "scaled"; when: mouseArea.containsMouse PropertyChanges { target: currentGuess scale: 1.1 } } transitions: Transition { NumberAnimation { properties: "scale"; easing.type: Easing.OutCubic } } } } BarButton { id: okButton source: "qrc:/gcompris/src/core/resource/bar_ok.svg" sourceSize.width: 66 * bar.barZoom width: guessColumn.guessSize * currentRow.factor height: guessColumn.guessSize * currentRow.factor visible: true z: 8 onClicked: { showChooser(false); Activity.checkGuess(); } } } } ListModel { id: guessModel dynamicRoles: true } ListView { id: guessColumn anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: currentWrapper.top anchors.bottomMargin: 10 * ApplicationInfo.ratio boundsBehavior: Flickable.DragOverBounds verticalLayoutDirection: ListView.BottomToTop - readonly property int guessSize: 30 * background.scaleFactor * ApplicationInfo.ratio - readonly property int vertSpacing: 15 * background.scaleFactor * ApplicationInfo.ratio - readonly property int horizSpacing: 15 * background.scaleFactor * ApplicationInfo.ratio - readonly property int statusMargin: 5 * background.scaleFactor * ApplicationInfo.ratio - readonly property int resultSize: 10 * background.scaleFactor * ApplicationInfo.ratio + readonly property int guessSize: 30 * ApplicationInfo.ratio + readonly property int vertSpacing: 15 * ApplicationInfo.ratio + readonly property int horizSpacing: 15 * ApplicationInfo.ratio + readonly property int statusMargin: 5 * ApplicationInfo.ratio + readonly property int resultSize: 10 * ApplicationInfo.ratio readonly property int guessColWidth: Activity.maxPieces * (guessSize + (2 * guessColumn.statusMargin)) + (Activity.maxPieces-1) * horizSpacing; readonly property int resultColWidth: Activity.maxPieces * resultSize + (Activity.maxPieces-1) * 2; spacing: vertSpacing width: guessColWidth + 10 + (2 * horizSpacing) + resultColWidth height: count * (guessSize + vertSpacing) displaced: Transition { NumberAnimation { easing.type: Easing.OutCubic; properties: "y"; duration: 300 } } model: guessModel delegate: Row { id: guessRow width: guessColumn.width height: guessColumn.guessSize spacing: guessColumn.horizSpacing property int rowIndex: index visible: index != 0 Item { id: guessRowSpacer width: guessColumn.guessColWidth - (guessRepeater.count * (guessColumn.guessSize + (2 * guessColumn.statusMargin) + guessColumn.horizSpacing)) height: parent.height } Repeater { id: guessRepeater anchors.left: parent.left anchors.top: parent.top model: guess delegate: Item { // wrapper needed for singleGuessStatusRect's opacity id: singleGuessWrapper width: guessColumn.guessSize + (2 * guessColumn.statusMargin); height: guessColumn.guessSize + (2 * guessColumn.statusMargin); Rectangle { id: singleGuessStatusRect border.width: 2 border.color: (status == Activity.STATUS_CORRECT) ? "white" : "black"; anchors.fill: parent radius: 3 color: (status == Activity.STATUS_CORRECT) ? "black" : "white"; opacity: (status == Activity.STATUS_UNKNOWN) ? 0 : 0.9 z: 1 MouseArea { id: mouseAreaRect anchors.fill: parent acceptedButtons: Qt.LeftButton enabled: guessRow.rowIndex > 0 z: 4 hoverEnabled: ApplicationInfo.isMobile ? false : true Timer { id: tooltipTimer repeat: false interval: 500 onTriggered: showTooltip(true, status, mouseAreaRect) } onEntered: tooltipTimer.restart() onExited: { tooltipTimer.stop() showTooltip(false) } onClicked: showTooltip(true, status, mouseAreaRect); onDoubleClicked: Activity.ackColor(index, colIndex); } } - Rectangle { + SearchItem { id: singleGuess width: guessColumn.guessSize height: guessColumn.guessSize anchors.left: parent.left anchors.top: parent.top anchors.leftMargin: guessColumn.statusMargin anchors.topMargin: guessColumn.statusMargin - radius: width * 0.5 border.width: 2 border.color: "lightgray" - color: Activity.colors[colIndex] + searchItemIndex: colIndex opacity: 1.0 z: 2 Image { id: okImage visible: isAcked width: parent.width / 2 height: parent.height / 2 anchors.centerIn: parent source: Activity.baseUrl + "apply.svg" } MouseArea { id: ackMouseArea anchors.fill: parent acceptedButtons: Qt.LeftButton enabled: status == Activity.STATUS_UNKNOWN visible: status == Activity.STATUS_UNKNOWN z: 3 hoverEnabled: ApplicationInfo.isMobile ? false : true onDoubleClicked: Activity.ackColor(index, colIndex); } } } } Item { id: guessRowSpacer2 width: 10 height: guessColumn.guessSize } Column { id: guessResultColumn width: guessColumn.resultColWidth height: guessColumn.guessSize spacing: 2 Item { id: guessResultColSpacer width: guessResultColumn.width height: (guessResultColumn.height - 2 * (guessColumn.resultSize)) } Row { id: guessResultCorrectRow width: guessResultColumn.width height: guessColumn.resultSize spacing: 2 Repeater { id: guessResultCorrectRepeater model: result.correct delegate: Rectangle { id: singleCorrectResult width: guessColumn.resultSize height: guessColumn.resultSize radius: width * 0.5 border.width: 1 border.color: "white" color: "black" } } } Row { id: guessResultMisplacedRow width: guessResultColumn.width height: guessColumn.resultSize spacing: 2 Repeater { id: guessResultMisplacedRepeater model: result.misplaced delegate: Rectangle { id: singleMisplacedResult width: guessColumn.resultSize height: guessColumn.resultSize radius: width * 0.5 border.width: 1 border.color: "black" color: "white" } } } } } } DialogHelp { id: dialogHelp onClose: home() } + DialogActivityConfig { + id: dialogActivityConfig + currentActivity: activity + content: Component { + Item { + property alias modeBox: modeBox + + property var availableModes: [ + { "text": qsTr("Colors"), "value": "color" }, + { "text": qsTr("Shapes"), "value": "symbol" } + ] + + Flow { + id: flow + spacing: 5 + width: dialogActivityConfig.width + GCComboBox { + id: modeBox + model: availableModes + background: dialogActivityConfig + label: qsTr("Select your mode") + } + } + } + } + onClose: home() + onLoadData: { + if(dataToSave && dataToSave["mode"]) { + Activity.mode = dataToSave["mode"]; + } + } + + onSaveData: { + var newMode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.modeBox.currentIndex].value; + if (newMode !== Activity.mode) { + chooserGrid.model = new Array(); + Activity.mode = newMode; + dataToSave = {"mode": Activity.mode}; + Activity.initLevel(); + } + } + + function setDefaultValues() { + for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length ; i ++) { + if(dialogActivityConfig.configItem.availableModes[i].value === Activity.mode) { + dialogActivityConfig.configItem.modeBox.currentIndex = i; + break; + } + } + } + } + Bar { id: bar - content: BarEnumContent { value: help | home | level } + content: BarEnumContent { value: help | home | level | config } onHelpClicked: { displayDialog(dialogHelp) } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() + onConfigClicked: { + dialogActivityConfig.active = true + // Set default values + dialogActivityConfig.setDefaultValues(); + displayDialog(dialogActivityConfig) + } } Bonus { id: bonus Component.onCompleted: win.connect(Activity.nextSubLevel) } Score { id: score anchors.bottom: undefined anchors.rightMargin: 10 * ApplicationInfo.ratio anchors.topMargin: 10 * ApplicationInfo.ratio anchors.left: undefined anchors.top: parent.top anchors.right: parent.right } } } diff --git a/src/activities/superbrain/resource/brown_cross.svg b/src/activities/superbrain/resource/brown_cross.svg new file mode 100644 index 000000000..0d3df7328 --- /dev/null +++ b/src/activities/superbrain/resource/brown_cross.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/activities/superbrain/resource/darkblue_star.svg b/src/activities/superbrain/resource/darkblue_star.svg new file mode 100644 index 000000000..b92acc607 --- /dev/null +++ b/src/activities/superbrain/resource/darkblue_star.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/activities/superbrain/resource/darkgreen_ring.svg b/src/activities/superbrain/resource/darkgreen_ring.svg new file mode 100644 index 000000000..bbda237ee --- /dev/null +++ b/src/activities/superbrain/resource/darkgreen_ring.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/activities/superbrain/resource/lightblue_cloud.svg b/src/activities/superbrain/resource/lightblue_cloud.svg new file mode 100644 index 000000000..3f069ebf4 --- /dev/null +++ b/src/activities/superbrain/resource/lightblue_cloud.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/activities/superbrain/resource/lightgreen_triangle.svg b/src/activities/superbrain/resource/lightgreen_triangle.svg new file mode 100644 index 000000000..dd1c841ee --- /dev/null +++ b/src/activities/superbrain/resource/lightgreen_triangle.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/activities/superbrain/resource/magenta_diamond.svg b/src/activities/superbrain/resource/magenta_diamond.svg new file mode 100644 index 000000000..1d75a1eb7 --- /dev/null +++ b/src/activities/superbrain/resource/magenta_diamond.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/activities/superbrain/resource/red_circle.svg b/src/activities/superbrain/resource/red_circle.svg new file mode 100644 index 000000000..88348d47f --- /dev/null +++ b/src/activities/superbrain/resource/red_circle.svg @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/activities/superbrain/resource/red_heart.svg b/src/activities/superbrain/resource/red_heart.svg new file mode 100644 index 000000000..968c68da6 --- /dev/null +++ b/src/activities/superbrain/resource/red_heart.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/activities/superbrain/resource/yellow_star.svg b/src/activities/superbrain/resource/yellow_star.svg new file mode 100644 index 000000000..f97e04294 --- /dev/null +++ b/src/activities/superbrain/resource/yellow_star.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/activities/superbrain/superbrain.js b/src/activities/superbrain/superbrain.js index ee53c6350..0d5fdafed 100644 --- a/src/activities/superbrain/superbrain.js +++ b/src/activities/superbrain/superbrain.js @@ -1,218 +1,221 @@ /* GCompris - superbrain.js * * Copyright (C) 2015 Holger Kaelberer * * Authors: * Bruno Coudoin (GTK+ version) * Holger Kaelberer (Qt Quick port) * * 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 . */ .pragma library .import QtQuick 2.0 as Quick .import GCompris 1.0 as GCompris -/* Todo/possible improvements: - * - * - select colors to guess instead of cycling through - * - (> 6 levels with duplicate colors) - * - improve layout for smartphones (too small, stretch horizontally/vertically - * in landscape/portrait orientation) - */ - var currentLevel = 0; -var maxLevel = 6; +var maxLevel = 8; var currentSubLevel = 0; var maxSubLevel = 6; var items; var baseUrl = "qrc:/gcompris/src/activities/superbrain/resource/"; -var maxLevelForHelp = 4; // after this level, we provide less feedback to the user -var numberOfPieces = 0; -var numberOfColors = 0; +var levels = [ + { numberOfPieces: 3, numberOfColors: 5, help: true, uniqueColors: true }, + { numberOfPieces: 4, numberOfColors: 6, help: true, uniqueColors: true }, + { numberOfPieces: 5, numberOfColors: 7, help: true, uniqueColors: true }, + { numberOfPieces: 5, numberOfColors: 7, help: true, uniqueColors: false }, + { numberOfPieces: 3, numberOfColors: 5, help: false, uniqueColors: true }, + { numberOfPieces: 4, numberOfColors: 6, help: false, uniqueColors: true }, + { numberOfPieces: 5, numberOfColors: 7, help: false, uniqueColors: true }, + { numberOfPieces: 5, numberOfColors: 7, help: false, uniqueColors: false } + ]; var maxPieces = 5; var solution = new Array(maxPieces); var colors = [ - "#FF0000FF", - "#FF00FF00", - "#FFFF0000", - "#FF00FFFF", - "#FFFF00FF", - "#FFFFFF00", - "#FF8e7016", - "#FF04611a", - "#FFa0174b", - "#FF7F007F" + "#FF0000FF", // dark blue + "#FF00FF00", // light green + "#FFFF0000", // red + "#FF00FFFF", // light blue + "#FFFF00FF", // magenta + "#FFFFFF00", // yellow + "#FF8e7016", // brown + "#FF04611a", // dark green + "#FFa0174b", // dark magenta ]; +var mode = "color"; +var symbols = [ + baseUrl + "darkblue_star.svg", + baseUrl + "lightgreen_triangle.svg", + baseUrl + "red_heart.svg", + baseUrl + "lightblue_cloud.svg", + baseUrl + "magenta_diamond.svg", + baseUrl + "yellow_star.svg", + baseUrl + "brown_cross.svg", + baseUrl + "darkgreen_ring.svg", + baseUrl + "red_circle.svg", + ]; + var ackColors = new Array(); -var currentColors = new Array(); +var currentIndeces = new Array(); var maxColors = colors.length; var STATUS_UNKNOWN = 0; var STATUS_MISPLACED = 1; var STATUS_CORRECT = 2; function start(items_) { items = items_; currentLevel = 0; currentSubLevel = 0; initLevel(); } function stop() { } function initLevel() { if (currentSubLevel == 0) { // init level items.bar.level = currentLevel + 1; - - if(currentLevel + 1 < maxLevelForHelp) { - numberOfPieces = currentLevel + 3; - numberOfColors = currentLevel + 5; - } else { - numberOfPieces = currentLevel - maxLevelForHelp + 4; - numberOfColors = currentLevel - maxLevelForHelp + 6; - } } // init sublevel - ackColors = new Array(numberOfPieces); + ackColors = new Array(levels[currentLevel].numberOfPieces); items.score.numberOfSubLevels = maxSubLevel; items.score.currentSubLevel = currentSubLevel + 1; var selectedColors = new Array(maxColors); - solution = new Array(numberOfPieces); + solution = new Array(levels[currentLevel].numberOfPieces); for (var i = 0; i < maxColors; ++i) selectedColors[i] = false; // generate solution: - for(var i = 0; i < numberOfPieces; ++i) { + for(var i = 0; i < levels[currentLevel].numberOfPieces; ++i) { var j; do - j = Math.floor(Math.random() * numberOfColors); - while (selectedColors[j]); + j = Math.floor(Math.random() * levels[currentLevel].numberOfColors); + while (levels[currentLevel].uniqueColors && selectedColors[j]); solution[i] = j; selectedColors[j] = true; } //console.log("XXX solution: " + JSON.stringify(solution)); - // populate currentColors: + // populate currentIndeces: items.colorsRepeater.model.clear(); items.currentRepeater.model = new Array(); - currentColors = new Array(); - for (var i = 0; i < numberOfColors; ++i) { - currentColors[i] = colors[i]; - items.colorsRepeater.model.append({"col": colors[i]}); + currentIndeces = new Array(); + for (var i = 0; i < levels[currentLevel].numberOfColors; ++i) { + currentIndeces[i] = i; + items.colorsRepeater.model.append({"itemIndex": i}); } - items.chooserGrid.model = currentColors; + items.chooserGrid.model = currentIndeces; // add first guess row: items.guessModel.clear(); appendGuessRow(); } function appendGuessRow() { var guessRow = new Array(); - for (var i = 0; i < numberOfPieces; ++i) { + for (var i = 0; i < levels[currentLevel].numberOfPieces; ++i) { var col = guessRow.push({ index: i, colIndex: (ackColors[i] === undefined) ? 0 : ackColors[i], status: STATUS_UNKNOWN, isAcked: (ackColors[i] !== undefined) }); } items.guessModel.insert(0, { guess: guessRow, result: {correct: 0, misplaced: 0} }); var obj = items.guessModel.get(0); items.currentRepeater.model = obj.guess; } function ackColor(column, colIndex) { ackColors[column] = (ackColors[column] == colIndex) ? undefined : colIndex; for (var i = 0; i < items.guessModel.count; i++) { var obj = items.guessModel.get(i).guess.get(column); obj.isAcked = (ackColors[column] == obj.colIndex); } items.currentRepeater.model.get(column).colIndex = colIndex; items.currentRepeater.model.get(column).isAcked = (ackColors[column] !== undefined); } function checkGuess() { var remainingIndeces = solution.slice(); var obj = items.guessModel.get(0); var correctCount = 0; var misplacedCount = 0; // check for exact matches first: - for (var i = 0; i < numberOfPieces; i++) { + for (var i = 0; i < levels[currentLevel].numberOfPieces; i++) { var guessIndex = obj.guess.get(i).colIndex; var newStatus; if (solution[i] == guessIndex) { // correct remainingIndeces.splice(remainingIndeces.indexOf(guessIndex), 1); - if (currentLevel + 1 < maxLevelForHelp) + if (levels[currentLevel].help) obj.guess.setProperty(i, "status", STATUS_CORRECT); correctCount++; } } obj.result = ({ correct: correctCount }); if (remainingIndeces.length == 0) { items.bonus.good("smiley"); } - for (var i = 0; i < numberOfPieces; i++) { + for (var i = 0; i < levels[currentLevel].numberOfPieces; i++) { if (obj.guess.get(i).status == STATUS_CORRECT) continue; var guessIndex = obj.guess.get(i).colIndex; var newStatus = STATUS_UNKNOWN; if (solution.indexOf(guessIndex) != -1 && remainingIndeces.indexOf(guessIndex) != -1) { // misplaced remainingIndeces.splice(remainingIndeces.indexOf(guessIndex), 1); - if (currentLevel + 1 < maxLevelForHelp) + if (levels[currentLevel].help) obj.guess.setProperty(i, "status", STATUS_MISPLACED); misplacedCount++; } } obj.result = ({ misplaced: misplacedCount, correct: correctCount }); appendGuessRow(); } function nextLevel() { if(maxLevel <= ++currentLevel ) { currentLevel = 0; } currentSubLevel = 0; initLevel(); } function previousLevel() { if(--currentLevel < 0) { currentLevel = maxLevel - 1 } currentSubLevel = 0; initLevel(); } function nextSubLevel() { if( ++currentSubLevel >= maxSubLevel) { currentSubLevel = 0 nextLevel() } initLevel(); } diff --git a/src/activities/traffic/Car.qml b/src/activities/traffic/Car.qml index 73d37a2ae..e0e71b6e7 100644 --- a/src/activities/traffic/Car.qml +++ b/src/activities/traffic/Car.qml @@ -1,167 +1,184 @@ /* GCompris - Car.qml * * Copyright (C) 2014 Holger Kaelberer * * Authors: * Bruno Coudoin (GTK+ Mostly full rewrite) * Holger Kaelberer (Qt Quick port) * * 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 . */ import QtQuick 2.1 import GCompris 1.0 import QtGraphicalEffects 1.0 import "../../core" import "traffic.js" as Activity Item { id: car property int xPos property int yPos property int size property bool goal: false property bool isHorizontal: false property alias color: carRect.color property alias source: carImage.source property real blockSize: ((parent.width-3) / 6) property var xBounds: undefined property var yBounds: undefined property string mode + property bool isMoving: false Component.onCompleted: { mode = parent.mode connection.target = parent } // Connect the jamGrid.mode to car.mode to automatically change the wrapped object Connections { id: connection onModeChanged: { car.mode = parent.mode; } } x: (mode == "COLOR" || car.isHorizontal) ? (xPos * blockSize) : ((xPos+1) * blockSize) y: (mode == "COLOR" || car.isHorizontal) ? (yPos * blockSize) : ((yPos) * blockSize) // track effective coordinates (needed for transformed image): property real effX: car.xPos * car.blockSize property real effY: car.yPos * car.blockSize property real effWidth: (mode == "COLOR" || car.isHorizontal) ? car.width : car.height property real effHeight: (mode == "COLOR" || car.isHorizontal) ? car.height : car.width property GCAudio audioEffects width: (mode == "IMAGE" || isHorizontal) ? (size * blockSize) : blockSize height: (mode == "IMAGE" || isHorizontal) ? blockSize : (size * blockSize) Item { id: carWrapper anchors.fill: parent width: parent.width height: parent.height Rectangle { id: carRect visible: (mode == "COLOR") z: 11 anchors.fill: parent width: parent.width height: parent.height border.width: 1 border.color: "white" MultiPointTouchArea { id: rectTouch anchors.fill: parent touchPoints: [ TouchPoint { id: point1 } ] property real startX; property real startY; onPressed: { - car.audioEffects.play(Activity.baseUrl + "car.wav") - rectTouch.startX = point1.x; - rectTouch.startY = point1.y; + if (!Activity.isMoving) { + Activity.isMoving = true; + car.isMoving = true; + car.audioEffects.play(Activity.baseUrl + "car.wav") + rectTouch.startX = point1.x; + rectTouch.startY = point1.y; + } } onUpdated: { - if (!Activity.haveWon) { + if (car.isMoving && !Activity.haveWon) { var deltaX = point1.x - startX; var deltaY = point1.y - startY; Activity.updateCarPosition(car, car.x + deltaX, car.y + deltaY); } } onReleased: { - if (!Activity.haveWon) - Activity.snapCarToGrid(car); + if (car.isMoving) { + car.isMoving = false; + Activity.isMoving = false; + if (!Activity.haveWon) + Activity.snapCarToGrid(car); + } } } } Image { id: carImage visible: (mode == "IMAGE") fillMode: Image.PreserveAspectFit anchors.fill: parent sourceSize.width: parent.width sourceSize.height: parent.height rotation: car.isHorizontal ? 0 : 90 transformOrigin: Item.TopLeft MultiPointTouchArea { id: imageTouch anchors.fill: parent touchPoints: [ TouchPoint { id: imagePoint } ] property real startX; property real startY; onPressed: { - car.audioEffects.play(Activity.baseUrl + "car.wav") - imageTouch.startX = imagePoint.x; - imageTouch.startY = imagePoint.y; + if (!Activity.isMoving) { + Activity.isMoving = true; + car.isMoving = true; + car.audioEffects.play(Activity.baseUrl + "car.wav") + imageTouch.startX = imagePoint.x; + imageTouch.startY = imagePoint.y; + } } onUpdated: { - if (!Activity.haveWon) { + if (car.isMoving && !Activity.haveWon) { var deltaX = imagePoint.x - startX; var deltaY = imagePoint.y - startY; if (!car.isHorizontal) { var w = deltaX; deltaX = deltaY; deltaY = w; } Activity.updateCarPosition(car, car.effX + deltaX, car.effY + deltaY); } } onReleased: { - if (!Activity.haveWon) - Activity.snapCarToGrid(car); + if (car.isMoving) { + Activity.isMoving = false; + car.isMoving = false; + if (!Activity.haveWon) + Activity.snapCarToGrid(car); + } } } } } // note: the following leads to delayed dragging, therefore deactivated: //Behavior on x { PropertyAnimation { duration: 50 } } //Behavior on y { PropertyAnimation { duration: 50 } } } diff --git a/src/activities/traffic/Traffic.qml b/src/activities/traffic/Traffic.qml index 8459c06d7..d26fd4d4d 100644 --- a/src/activities/traffic/Traffic.qml +++ b/src/activities/traffic/Traffic.qml @@ -1,193 +1,192 @@ /* GCompris - Traffic.qml * * Copyright (C) 2014 Holger Kaelberer * * Authors: * Bruno Coudoin (GTK+ version) * Holger Kaelberer (Qt Quick port) * * 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 . */ import QtQuick 2.1 import GCompris 1.0 import "../../core" import "traffic.js" as Activity ActivityBase { id: activity onStart: focus = true onStop: {} pageComponent: Image { id: background source: "qrc:/gcompris/src/activities/traffic/resource/traffic_bg.svg" sourceSize.width: parent.width fillMode: Image.PreserveAspectCrop signal start signal stop property string mode: "IMAGE" // allow to choose between "COLOR" and "IMAGE" // mode, candidate for a config dialog Component.onCompleted: { dialogActivityConfig.getInitialConfiguration() activity.start.connect(start) activity.stop.connect(stop) } QtObject { id: items property Item main: activity.main property GCAudio audioEffects: activity.audioEffects property alias background: background property alias bar: bar property alias bonus: bonus property alias score: score property alias jamBox: jamBox property alias jamGrid: jamGrid } onStart: { Activity.start(items, mode) } onStop: { Activity.stop() } Image { id: jamBox source: "qrc:/gcompris/src/activities/traffic/resource/traffic_box.svg" anchors.centerIn: parent - sourceSize.width: Math.max(400, background.width * 0.4175 * ApplicationInfo.ratio) //334 - sourceSize.height: Math.max(400, background.height * 0.636538462 * ApplicationInfo.ratio) //331 + sourceSize.width: Math.min(background.width * 0.85, + background.height * 0.85) fillMode: Image.PreserveAspectFit - property double scaleFactor: Math.min(background.width / background.sourceSize.width, - background.height / background.sourceSize.height) - + property double scaleFactor: background.width / background.sourceSize.width + Grid { id: jamGrid anchors.centerIn: parent width: parent.width - 86 * jamBox.scaleFactor * ApplicationInfo.ratio height: parent.height - 86 * jamBox.scaleFactor * ApplicationInfo.ratio columns: 6 rows: 6 spacing: 0 // Add an alias to mode so it can be used on Car items property alias mode: background.mode Repeater { id: gridRepeater model: jamGrid.columns * jamGrid.rows delegate: Rectangle { id: gridDelegate height: jamGrid.height/ jamGrid.rows width: height border.width: 1 border.color: "white" color: "#444444" } } } } DialogHelp { id: dialogHelp onClose: home() } DialogActivityConfig { id: dialogActivityConfig currentActivity: activity content: Component { Item { property alias modeBox: modeBox property var availableModes: [ { "text": qsTr("Colors"), "value": "COLOR" }, { "text": qsTr("Images"), "value": "IMAGE" } ] Flow { id: flow spacing: 5 width: dialogActivityConfig.width GCComboBox { id: modeBox model: availableModes background: dialogActivityConfig label: qsTr("Select your mode") } } } } onClose: home() onLoadData: { if(dataToSave && dataToSave["mode"]) { mode = dataToSave["mode"]; Activity.mode = dataToSave["mode"]; } } onSaveData: { mode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.modeBox.currentIndex].value; dataToSave = {"mode": mode} Activity.mode = mode; } function setDefaultValues() { for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length ; i ++) { if(dialogActivityConfig.configItem.availableModes[i].value === mode) { dialogActivityConfig.configItem.modeBox.currentIndex = i; break; } } } } Bar { id: bar content: BarEnumContent { value: help | home | level | reload | config } onHelpClicked: { displayDialog(dialogHelp) } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() onReloadClicked: Activity.initLevel() onConfigClicked: { dialogActivityConfig.active = true // Set default values dialogActivityConfig.setDefaultValues(); displayDialog(dialogActivityConfig) } } Bonus { id: bonus Component.onCompleted: win.connect(Activity.nextSubLevel) } Score { id: score anchors.top: parent.top anchors.topMargin: 10 * ApplicationInfo.ratio anchors.right: parent.right anchors.rightMargin: 10 * ApplicationInfo.ratio anchors.bottom: undefined } } } diff --git a/src/activities/traffic/traffic.js b/src/activities/traffic/traffic.js index 73ee05404..ddba6d760 100644 --- a/src/activities/traffic/traffic.js +++ b/src/activities/traffic/traffic.js @@ -1,416 +1,418 @@ /* GCompris - traffic.js * * Copyright (C) 2014 Holger Kaelberer * * Authors: * Bruno Coudoin (GTK+ version) * Holger Kaelberer (Qt Quick port) * * 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 . */ .pragma library .import QtQuick 2.0 as Quick .import GCompris 1.0 as GCompris .import QtQml 2.2 as Qml /* The format and the dataset for the traffic game in gcompris * is taken from from * http://www.javascript-games.org/puzzle/rushhour/ * * [LevelX] * CardY=string describing card 1 * CardY=string describing card 2 * ... * Where X is the Gcompris Level (in the control bar) * Where Y is the sublevel. * * This is followed by a comma separated list defining the cars on the * grid. So the string looks as follows: * * 'ID''X''Y' * * - 'ID' is one char in the range A-R and X * A-N Specify a different car color of size 2 * O-R Specify a different car color of size 3 * X Always Red, the goal car of size 2 * * - 'X' xpos numbers between * 1 to 6 for Vertical car * A to F for Horizontal car * * - 'Y' ypos numbers between * 1 to 6 for Horizontal car * A to F for Vertical car * */ var dataList = [ /* [Level1] */ "XD3,O2F", "XD3,A4C,O2F,PD5", "XC3,A2E,BE5,O2F,P4B", "XB3,AB1,B2E,C2F,D4C,OD1,PD4", "XC3,A3F,BE6,O2E,PD5,Q2B", /* [Level2] */ "XB3,AE5,O2F,P4D", "XB3,A2F,B4C,OD4,PB6,QA1,RD1", "XC3,AC2,B3B,C4C,O2F,PD5", "XD3,AB2,B4D,CE5,O2F", "XC3,A1F,B2E,CD4,DE6,E5D,O3F", /* [Level3] */ "XC3,A2E,BB4,C5B,OA1,PD1,QC5", "XC3,AB2,B3B,C4D,DE5,O1E", "XD3,AE2,BE6,C5B,O3F,P4D", "XD3,AD2,BE5,C4D,OA1,PD1,Q2F", "XC3,AB4,CE6,D5B,OC5,P1E", /* [Level4] */ "XC3,AA1,BC2,CE5,D2B,E4C,O1E", "XA3,AB1,B2C,CD4,E3F,OD1,F4C,QD5", "XA3,AE4,BC6,CE6,D2C,E2F,F4C,G4D,OD1,P4A", "XC3,AB2,BD2,CC4,D5B,E3E,FC6,GE6,O2F,PD5", "XD3,A2C,BD2,C2F,DE4,E4D,F5B,OA1,PD1,QC6", /* [Level5] */ "XC3,A1C,B2F,C4C,D4D,EE4,FC6,GE6,OD1,P4B", "XD3,A2B,B4C,CE6,O2F,P4D,Q1A,R4A", "XD3,A1D,BC5,CC6,DE6,E4E,F5B,GE1,O2F,PB4", "XB3,AD2,BB4,C3E,DE5,EE6,O2F,P3D", "XB3,AD2,B3E,CB4,DE5,EE6,OA1,PD1,Q2F,R3D", /* [Level6] */ "XC3,AC2,BE2,C3E,D3F,EB4,FE5,GE6,HA6,O4D,P3A,QD1", "XB3,AA1,B5A,CE5,O1F,P2A,Q2D,RC6", "XA3,A1A,B2D,C3E,D5C,EE5,FA6,GD6,OD1,P2F,QA4", "XB3,AB4,B5B,CC6,O3D,P4F", "XB3,A4C,B5F,O1A,P1D,QD4,RC6", /* [Level7] */ "XB3,AA1,B1D,CA2,DA4,E4C,F5A,O2E,P2F,Q3D,RD6", "XB3,A1B,BC1,C1E,D1F,E2D,F3F,IC4,H5D", "XA3,AD1,BC2,C2E,D3C,E3D,FA4,GE4,HA5,I5C,KA6,O1F,PD5,QD6", "XA3,A1B,BC1,CE1,D2D,EE2,F3F,G5C,H5F,O3E,P4A,QB4", "XB3,AA1,B1C,CE1,DA2,E5D,FE5,GA6,HE6,O2F,P3A,QB4", /* [Level8] */ "XB3,AB1,B4C,E5F,O1A,P1D,QD4,RC6", "XA3,A1A,BB1,C5E,O1F,P2C,QD4,RA6", "XD3,AA1,BC1,C1E,D2C,E3B,FD4,G5D,HE5,IB6,KE6,O2F,P4A", "XC3,AA1,B1C,CE2,D3A,E3B,F3E,G3F,HC4,I5C,JE5,KA6", "XC3,AB1,BD1,CA2,DC2,E4C,F4D,GE5,HB6,ID6,O2E,P2F,Q3A,R3B", /* [Level9] */ "XD3,AA1,BC1,C1E,D2A,EC2,F3B,GA6,O1F,P3C,QD4", "XA3,A1A,BC2,CE2,D3C,EA4,F5E,G5F,OB1,P4D,QA5,RA6", "XB3,AA1,B1C,CA2,DB5,O1D,P3A,QB4,RA6", "XC3,A1C,BD1,D3B,EC4,F4E,J2E,OB5", "XA3,A1A,BB2,C2D,D3C,E5C,FD5,OD1,P3F,QD6", /* [Level10] */ "XB3,AA1,B1C,O1D,P2A,QB4,RD6", "XB3,A1C,B2A,CE2,D4B,EE4,F5A,GC5,H5F,OD1,P2D,QB6", "XD3,A2C,BD2,C4C,D4D,EE4,FE5,OC1,P1F,QC6", "XC3,A1C,BD1,C2B,D3A,E3E,FB4,G5E,HA6,OA5", "XB3,AA1,B1C,CE1,DA2,E3E,F5B,G5D,HE5,IE6,O2F,P3A,QB4", /* [Level11] */ "XB3,A1B,B2A,C2D,D3F,E4A,F5C,G5F,HD6,OD1,P2E,RB4", "XA3,A1A,BB1,CB2,D3C,ED4,F5C,O1D,P3F,RD6", "XA3,A1D,BE2,C4A,D4B,ED4,FA6,GC6,OA1,P2C,Q4F,RC5", "XA3,A2C,B3F,C4A,DB4,ED4,FB5,G5D,H5F,OA1,P1E,RA6", "XB3,A1C,B2D,CA4,DC4,EA6,FC6,O1A,PD1,Q4F", /* [Level12] */ "XB3,AA1,B2D,CE2,D3A,ED4,FA5,OD1,P3F,Q4C,RD6", "XA3,AA1,B1D,CE1,D4A,EB4,FD4,HA6,K5D,O1C,P4F", "XA3,A1B,BE1,DB4,ED4,FB5,G5D,H5E,I4A,P4F,QA6,R1C", "XA3,A1A,B2D,C3E,D4D,E5C,FE5,HD6,IA6,P2F,QA4,RD1", "XA3,AD1,B2D,DB5,E5D,F5E,GA6,K4A,O1C,P1F,QB4", /* [Level13] */ "XC3,AE1,B2B,CC2,D4D,E5C,FE5,GA6,O1A,PB1,Q2F,RA4", "XB3,AA1,B1C,CE1,DA2,E5D,FE5,GA6,HE6,O2E,P2F,Q3A,RB4", "XA3,A1A,BB2,C2D,D3C,ED4,F5C,GD5,OD1,QD6,R3F", "XA3,A1C,B2D,C3C,DA4,ED4,F5A,G5B,HC5,IC6,OD1,R3F", "XD3,AB1,B1E,C2B,D2C,E4D,F5C,GE5,HA6,ID6,O1A,P2F,QA4" ]; var colorMap = { 'X': "#FF0000", 'A': "#80FF80", 'B': "#C0C000", 'C': "#8080FF", 'D': "#FF80FF", 'E': "#C00000", 'F': "#008000", 'G': "#C0C0C0", 'H': "#6000ef", 'I': "#FFFF00", 'J': "#FFA801", 'K': "#00FF00", 'O': "#FFFF00", 'P': "#FF80FF", 'Q': "#0000FF", 'R': "#00FFFF" }; var baseUrl="qrc:/gcompris/src/activities/traffic/resource/"; var carList = [ baseUrl + "car1.svg", baseUrl + "car2.svg", baseUrl + "car3.svg", baseUrl + "car4.svg", baseUrl + "car5.svg", baseUrl + "car6.svg", baseUrl + "car7.svg", baseUrl + "car8.svg", baseUrl + "car9.svg", baseUrl + "car10.svg", baseUrl + "car11.svg", baseUrl + "car12.svg", baseUrl + "car13.svg", baseUrl + "car14.svg", baseUrl + "car15.svg" ]; var truckList = [ baseUrl + "truck1.svg", baseUrl + "truck2.svg", baseUrl + "truck3.svg", baseUrl + "truck4.svg" ]; var currentLevel = 0; var currentSubLevel = 0; var level = null; var maxLevel = 13; var maxSubLevel = 5; var items; var cars; var numCars; var carComponent = null; var activeCars = new Array(); var haveWon = false; var mode = null; var truckIndex = 0; var carIndex = 0; +var isMoving = false; function start(items_, mode_) { items = items_; mode = mode_; currentLevel = 0; currentSubLevel = 0; initLevel(); } function stop() { cleanupActiveCars(); } function findYBounds(car) { if (car.yBounds !== undefined) return; var bounds = { "lower": 0, "upper": items.jamGrid.height }; for (var i = 0; i < activeCars.length; i++) { if (activeCars[i] != car && ((activeCars[i].xPos == car.xPos) || (activeCars[i].isHorizontal && activeCars[i].xPos < car.xPos && activeCars[i].xPos+activeCars[i].size > car.xPos))) { // y intersects if (activeCars[i].effY < car.effY && activeCars[i].effY + activeCars[i].effHeight > bounds.lower) { bounds.lower = activeCars[i].effY + activeCars[i].effHeight; } else if (activeCars[i].effY > car.effY && activeCars[i].effY < bounds.upper) bounds.upper = activeCars[i].effY; } } car.yBounds = bounds; } function findXBounds(car) { if (car.xBounds !== undefined) return; var bounds = { "lower": 0, "upper": items.jamGrid.width + (car.goal ? car.blockSize : 0)}; for (var i = 0; i < activeCars.length; i++) { if (activeCars[i] != car && ((activeCars[i].yPos == car.yPos) || (!activeCars[i].isHorizontal && activeCars[i].yPos < car.yPos && activeCars[i].yPos+activeCars[i].size > car.yPos))) { // y intersects if (activeCars[i].effX < car.effX && activeCars[i].effX + activeCars[i].effWidth > bounds.lower) { bounds.lower = activeCars[i].effX + activeCars[i].effWidth; } else if (activeCars[i].effX > car.effX && activeCars[i].effX < bounds.upper) bounds.upper = activeCars[i].effX; } } car.xBounds = bounds; } function updateCarPosition(car, newX, newY) { if (car.isHorizontal) { findXBounds(car); var deltaX = Math.min(car.xBounds.upper - car.effWidth, Math.max(car.xBounds.lower, newX)) - car.effX; car.x += deltaX; car.effX += deltaX; // check for reached goal: if (car.goal && car.effX + car.width >= items.jamGrid.width) { haveWon = true; items.bonus.good("smiley"); return; } } else { findYBounds(car) var deltaY = Math.min(car.yBounds.upper - car.effHeight, Math.max(car.yBounds.lower, newY)) - car.effY; car.y += deltaY; car.effY += deltaY; } } function snapCarToGrid(car) { if (car.isHorizontal) { car.xPos = Math.min(5, Math.max(0, Math.round(car.x / car.blockSize))); car.x = car.effX = Qt.binding(function() { return car.xPos * car.blockSize; }); } else { car.yPos = Math.min(5, Math.max(0, Math.round(car.y / car.blockSize))); car.y = car.effY = Qt.binding(function() { return car.yPos * car.blockSize; }); } car.xBounds = car.yBounds = undefined; } function drawCar(car) { if (!carComponent) { carComponent = Qt.createComponent("qrc:/gcompris/src/activities/traffic/Car.qml"); if (carComponent.status != Qml.Component.Ready) { console.error("Error creating Rectangle component (" + carComponent.status + "): " + carComponent.errorString()); carComponent = null; return; } } var id = car[0]; var x = car[1]; var y = car[2]; var xPos; var yPos; xPos = 0; yPos = y.charCodeAt(0) - '1'.charCodeAt(0); var isHorizontal = true; var size = 0; var source; if (id == 'O' || id == 'P' || id == 'Q' || id == 'R') { size = 3; source = truckList[Math.floor(truckIndex++ % truckList.length)]; } else { size = 2; source = carList[Math.floor(carIndex++ % (carList.length-1)) + 1]; } if (x == 'A') xPos = 0; else if (x == 'B') xPos = 1; else if (x == 'C') xPos = 2; else if (x == 'D') xPos = 3; else if (x == 'E') xPos = 4; else if (x == 'F') xPos = 5; else { // vertical yPos = x.charCodeAt(0) - '1'.charCodeAt(0); //vertical isHorizontal = false; if (y == 'A') xPos = 0; else if (y == 'B') xPos = 1; else if (y == 'C') xPos = 2; else if (y == 'D') xPos = 3; else if (y == 'E') xPos = 4; else if (y == 'F') xPos = 5; } var color = colorMap[id]; var goal; if (id == 'X') { goal = 1; source = carList[0]; } var carObject = carComponent.createObject( items.jamGrid, { "xPos": xPos, "yPos": yPos, "size": size, "goal": goal, "color": color, "source": source, "isHorizontal": isHorizontal, "audioEffects": items.audioEffects }); if (carObject == null) console.error("traffic: Error creating Car object!"); else activeCars.push(carObject); } function drawJam() { for (var i = 0; i < cars.length; i++) drawCar(cars[i]); } function cleanupActiveCars() { while (activeCars.length > 0) activeCars.pop().destroy(); } function initLevel() { // destroy old cars + isMoving = false; cleanupActiveCars(); truckIndex = 0; carIndex = 0; items.bar.level = currentLevel + 1; if (currentSubLevel == 0) { // initialize level items.score.numberOfSubLevels = maxSubLevel; } // initialize sublevel haveWon = false; items.score.currentSubLevel = currentSubLevel + 1; cars = dataList[(currentLevel * maxSubLevel) + currentSubLevel].split(","); drawJam(); } function nextLevel() { if(maxLevel <= ++currentLevel ) { currentLevel = 0 } currentSubLevel = 0; initLevel(); } function previousLevel() { if(--currentLevel < 0) { currentLevel = maxLevel - 1 } currentSubLevel = 0; initLevel(); } function nextSubLevel() { if( ++currentSubLevel >= maxSubLevel) { currentSubLevel = 0; nextLevel(); } else initLevel(); } diff --git a/src/core/ActivityInfoTree.cpp b/src/core/ActivityInfoTree.cpp index 371b0fc65..81217fd5b 100644 --- a/src/core/ActivityInfoTree.cpp +++ b/src/core/ActivityInfoTree.cpp @@ -1,284 +1,284 @@ /* GCompris - ActivityInfoTree.cpp * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin * * 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 "ActivityInfoTree.h" #include "ApplicationInfo.h" #include #include #include #include #include #include #include ActivityInfoTree::ActivityInfoTree(QObject *parent) : QObject(parent), m_currentActivity(NULL) {} void ActivityInfoTree::setRootMenu(ActivityInfo *rootMenu) { m_rootMenu = rootMenu; } ActivityInfo *ActivityInfoTree::getRootMenu() const { return m_rootMenu; } QQmlListProperty ActivityInfoTree::menuTree() { return QQmlListProperty(this, NULL, &menuTreeCount, &menuTreeAt); } int ActivityInfoTree::menuTreeCount(QQmlListProperty *property) { ActivityInfoTree *obj = qobject_cast(property->object); if(obj) return obj->m_menuTree.count(); else return 0; } ActivityInfo *ActivityInfoTree::menuTreeAt(QQmlListProperty *property, int index) { ActivityInfoTree *obj = qobject_cast(property->object); if(obj) return obj->m_menuTree.at(index); else return 0; } ActivityInfo *ActivityInfoTree::menuTree(int index) const { return m_menuTree.at(index); } void ActivityInfoTree::setCurrentActivity(ActivityInfo *currentActivity) { m_currentActivity = currentActivity; emit currentActivityChanged(); } ActivityInfo *ActivityInfoTree::getCurrentActivity() const { return m_currentActivity; } ActivityInfo *ActivityInfoTree::getParentActivity(ActivityInfo *root, ActivityInfo *menu) { qDebug() << "Parent Path= " << menu->getSectionPath(); Q_FOREACH( QObject *object, root->children() ) { ActivityInfo *activityInfo = qobject_cast(object); if(activityInfo->section() == menu->section()) { return activityInfo; } } return m_menuTree.at(0); } void ActivityInfoTree::menuTreeAppend(ActivityInfo *menu) { m_menuTreeFull.append(menu); } void ActivityInfoTree::menuTreeAppend(QQmlEngine *engine, const QDir &menuDir, const QString &menuFile) { QQmlComponent component(engine, QUrl::fromLocalFile(menuDir.absolutePath() + '/' + menuFile)); QObject *object = component.create(); if(component.isReady()) { if(QQmlProperty::read(object, "section").toString() == "/") { menuTreeAppend(qobject_cast(object)); } } else { qDebug() << menuFile << ": Failed to load"; } } void ActivityInfoTree::sortByDifficulty() { qSort(m_menuTree.begin(), m_menuTree.end(), SortByDifficulty()); emit menuTreeChanged(); } void ActivityInfoTree::sortByName() { qSort(m_menuTree.begin(), m_menuTree.end(), SortByName()); emit menuTreeChanged(); } // Filter the current activity list by the given tag // the tag 'all' means no filter // the tag 'favorite' means only marked as favorite // The level is also filtered based on the global property void ActivityInfoTree::filterByTag(const QString &tag) { m_menuTree.clear(); for(auto activity: m_menuTreeFull) { if((activity->section().indexOf(tag) != -1 || tag == "all" || (tag == "favorite" && activity->favorite())) && (activity->difficulty() >= ApplicationSettings::getInstance()->filterLevelMin() && activity->difficulty() <= ApplicationSettings::getInstance()->filterLevelMax())) { m_menuTree.push_back(activity); } } sortByDifficulty(); emit menuTreeChanged(); } void ActivityInfoTree::filterLockedActivities() { // If we have the full version or if we show all the activities, we don't need to do anything if(!ApplicationSettings::getInstance()->isDemoMode() || ApplicationSettings::getInstance()->showLockedActivities()) return; for(auto activity: m_menuTree) { // Remove non free activities if needed. We need to already have a menuTree filled! if(!activity->demo()) { m_menuTree.removeOne(activity); } } emit menuTreeChanged(); } void ActivityInfoTree::filterEnabledActivities() { for(auto activity: m_menuTree) { if(!activity->enabled()) { m_menuTree.removeOne(activity); } } emit menuTreeChanged(); } void ActivityInfoTree::exportAsSQL() { QTextStream cout(stdout); ApplicationSettings::getInstance()->setFilterLevelMin(1); ApplicationSettings::getInstance()->setFilterLevelMax(6); filterByTag("all"); cout << "CREATE TABLE activities (" << "id INT UNIQUE, " << "name TEXT," << "section TEXT," << "author TEXT," << "difficulty INT," << "icon TEXT," << "title TEXT," << "description TEXT," << "prerequisite TEXT," << "goal TEXT," << "manual TEXT," << "credit TEXT," << "demo INT);" << endl; cout << "DELETE FROM activities" << endl; int i(0); for(auto activity: m_menuTree) { cout << "INSERT INTO activities VALUES(" << i++ << ", " << "'" << activity->name() << "', " << "'" << activity->section() << "', " << "'" << activity->author() << "', " << activity->difficulty() << ", " << "'" << activity->icon() << "', " << "\"" << activity->title() << "\", " << "\"" << activity->description() << "\", " << "\"" << activity->prerequisite() << "\", " << "\"" << activity->goal().toHtmlEscaped() << "\", " << "\"" << activity->manual().toHtmlEscaped() << "\", " << "\"" << activity->credit() << "\", " << activity->demo() << ");" << endl; } } QObject *ActivityInfoTree::menuTreeProvider(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(scriptEngine) ActivityInfoTree *menuTree = new ActivityInfoTree(NULL); QQmlComponent componentRoot(engine, QUrl("qrc:/gcompris/src/activities/menu/ActivityInfo.qml")); QObject *objectRoot = componentRoot.create(); menuTree->setRootMenu(qobject_cast(objectRoot)); QFile file(":/gcompris/src/activities/activities_out.txt"); if(!file.open(QFile::ReadOnly)) { qDebug() << "Failed to load the activity list"; } QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine(); if(!line.startsWith(QLatin1String("#"))) { QString url = QString("qrc:/gcompris/src/activities/%1/ActivityInfo.qml").arg(line); if(!QResource::registerResource( ApplicationInfo::getFilePath(line + ".rcc"))) qDebug() << "Failed to load the resource file " << line + ".rcc"; QQmlComponent componentRoot(engine, QUrl(url)); QObject *objectRoot = componentRoot.create(); if(objectRoot) { menuTree->menuTreeAppend(qobject_cast(objectRoot)); } else { qDebug() << "ERROR: failed to load " << line << " " << componentRoot.errors(); } } } file.close(); menuTree->filterByTag("favorite"); menuTree->filterLockedActivities(); menuTree->filterEnabledActivities(); return menuTree; } void ActivityInfoTree::init() { if(!QResource::registerResource(ApplicationInfo::getFilePath("core.rcc"))) qDebug() << "Failed to load the resource file " << ApplicationInfo::getFilePath("core.rcc"); if(!QResource::registerResource(ApplicationInfo::getFilePath("menu.rcc"))) qDebug() << "Failed to load the resource file menu.rcc"; if(!QResource::registerResource(ApplicationInfo::getFilePath("activities.rcc"))) qDebug() << "Failed to load the resource file activities.rcc"; if(QResource::registerResource(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/data2/" + QString("full-%1.rcc").arg(COMPRESSED_AUDIO))) - qDebug() << "Registered the pre-download " << QString("full-%1.rcc").arg(COMPRESSED_AUDIO);; + qDebug() << "Registered the pre-download " << QString("full-%1.rcc").arg(COMPRESSED_AUDIO); qmlRegisterSingletonType("GCompris", 1, 0, "ActivityInfoTree", menuTreeProvider); qmlRegisterType("GCompris", 1, 0, "ActivityInfo"); } diff --git a/src/core/AnswerButton.qml b/src/core/AnswerButton.qml index ef8402730..4a656e772 100644 --- a/src/core/AnswerButton.qml +++ b/src/core/AnswerButton.qml @@ -1,189 +1,189 @@ /* Copyed in GCompris from Touch'n'learn Touch'n'learn - Fun and easy mobile lessons for kids Copyright (C) 2010, 2011 by Alessandro Portale http://touchandlearn.sourceforge.net This file is part of Touch'n'learn Touch'n'learn 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. Touch'n'learn 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 Touch'n'learn; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import QtQuick 2.1 import GCompris 1.0 Item { id: button property string textLabel property bool isCorrectAnswer: false property color normalStateColor: "#fff" property color correctStateColor: "#ffa" property color wrongStateColor: "#f66" property bool blockClicks: false property int wrongAnswerShakeAmplitudeCalc: width * 0.2 property int wrongAnswerShakeAmplitudeMin: 45 property int wrongAnswerShakeAmplitude: wrongAnswerShakeAmplitudeCalc < wrongAnswerShakeAmplitudeMin ? wrongAnswerShakeAmplitudeMin : wrongAnswerShakeAmplitudeCalc // If you want the sound effects just pass the audioEffects property GCAudio audioEffects signal correctlyPressed signal incorrectlyPressed signal pressed onPressed: { if (!blockClicks) { if (isCorrectAnswer) { if(audioEffects) audioEffects.play("qrc:/gcompris/src/core/resource/sounds/win.wav") correctAnswerAnimation.start(); } else { if(audioEffects) audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav") wrongAnswerAnimation.start(); } } } Rectangle { id: rect anchors.fill: parent color: normalStateColor opacity: 0.5 } ParticleSystemStarLoader { id: particles } Image { source: "qrc:/gcompris/src/core/resource/button.svg" sourceSize { height: parent.height; width: parent.width } width: sourceSize.width height: sourceSize.height smooth: false } GCText { id: label anchors.verticalCenter: parent.verticalCenter // We need to manually horizonally center the text, because in wrongAnswerAnimation, // the x of the text is changed, which would not work if we use an anchor layout. property int horizontallyCenteredX: (button.width - width) >> 1; x: horizontallyCenteredX; - fontSize: 18 + fontSizeMode: Text.Fit font.bold: true text: textLabel } MouseArea { id: mouseArea anchors.fill: parent onPressed: button.pressed() } SequentialAnimation { id: correctAnswerAnimation ScriptAction { script: { if (typeof(feedback) === "object") feedback.playCorrectSound(); blockClicks = true; if (typeof(particles) === "object") particles.burst(40); } } PropertyAction { target: rect property: "color" value: correctStateColor } PropertyAnimation { target: rect property: "color" to: normalStateColor duration: 700 } PauseAnimation { duration: 300 // Wait for particles to finish } ScriptAction { script: { blockClicks = false; correctlyPressed(); } } } SequentialAnimation { id: wrongAnswerAnimation ParallelAnimation { SequentialAnimation { PropertyAction { target: rect property: "color" value: wrongStateColor } ScriptAction { script: { if (typeof(feedback) === "object") feedback.playIncorrectSound(); } } PropertyAnimation { target: rect property: "color" to: normalStateColor duration: 600 } } SequentialAnimation { PropertyAnimation { target: label property: "x" to: label.horizontallyCenteredX - wrongAnswerShakeAmplitude easing.type: Easing.InCubic duration: 120 } PropertyAnimation { target: label property: "x" to: label.horizontallyCenteredX + wrongAnswerShakeAmplitude easing.type: Easing.InOutCubic duration: 220 } PropertyAnimation { target: label property: "x" to: label.horizontallyCenteredX easing { type: Easing.OutBack; overshoot: 3 } duration: 180 } } } PropertyAnimation { target: rect property: "color" to: normalStateColor duration: 450 } ScriptAction { script: { incorrectlyPressed(); } } } } diff --git a/src/core/ApplicationInfo.cpp b/src/core/ApplicationInfo.cpp index 38d969776..eedeeb2fb 100644 --- a/src/core/ApplicationInfo.cpp +++ b/src/core/ApplicationInfo.cpp @@ -1,228 +1,228 @@ /* GCompris - ApplicationSettingsDefault.cpp * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin * * This file was originally created from Digia example code under BSD license * and heavily modified since then. * * 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 "ApplicationInfo.h" #include #include #include #include #include #include #include #include #include #include #include QQuickWindow *ApplicationInfo::m_window = NULL; ApplicationInfo *ApplicationInfo::m_instance = NULL; ApplicationInfo::ApplicationInfo(QObject *parent): QObject(parent) { m_isMobile = false; #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_BLACKBERRY) || defined(SAILFISHOS) m_isMobile = true; #endif #if defined(Q_OS_ANDROID) // Put android before checking linux/unix as it is also a linux m_platform = Android; #elif (defined(Q_OS_LINUX) || defined(Q_OS_UNIX)) m_platform = Linux; #elif defined(Q_OS_WIN) m_platform = Windows; #elif defined(Q_OS_MAC) m_platform = MacOSX; #elif defined(Q_OS_IOS) m_platform = Ios; #elif defined(Q_OS_BLACKBERRY) m_platform = Blackberry; #elif defined(SAILFISHOS) m_platform = SailfishOS; #endif QRect rect = qApp->primaryScreen()->geometry(); -// m_ratio = 2; -// m_ratio = 2.56; - m_ratio = m_isMobile ? qMin(qMax(rect.width(), rect.height())/800. , qMin(rect.width(), rect.height())/520.) : 1; + m_ratio = qMin(qMax(rect.width(), rect.height())/800. , qMin(rect.width(), rect.height())/520.); // calculate a factor for font-scaling, cf. // http://doc.qt.io/qt-5/scalability.html#calculating-scaling-ratio qreal refDpi = 216.; qreal refHeight = 1776.; qreal refWidth = 1080.; qreal height = qMax(rect.width(), rect.height()); qreal width = qMin(rect.width(), rect.height()); qreal dpi = qApp->primaryScreen()->logicalDotsPerInch(); - m_fontRatio = m_isMobile ? qMax(qreal(1.0), qMin(height*refDpi/(dpi*refHeight), width*refDpi/(dpi*refWidth))) : 1; + m_fontRatio = qMax(qreal(1.0), qMin(height*refDpi/(dpi*refHeight), width*refDpi/(dpi*refWidth))); m_isPortraitMode = m_isMobile ? rect.height() > rect.width() : false; m_applicationWidth = m_isMobile ? rect.width() : 1120; if (m_isMobile) connect(qApp->primaryScreen(), SIGNAL(physicalSizeChanged(QSizeF)), this, SLOT(notifyPortraitMode())); // Get all symbol fonts to remove them QFontDatabase database; m_excludedFonts = database.families(QFontDatabase::Symbol); // Get fonts from rcc const QStringList fontFilters = {"*.otf", "*.ttf"}; m_fontsFromRcc = QDir(":/gcompris/src/core/resource/fonts").entryList(fontFilters); } ApplicationInfo::~ApplicationInfo() { m_instance = NULL; } void ApplicationInfo::setApplicationWidth(const int newWidth) { if (newWidth != m_applicationWidth) { m_applicationWidth = newWidth; emit applicationWidthChanged(); } } QString ApplicationInfo::getResourceDataPath() { return QString("qrc:/gcompris/data"); } QString ApplicationInfo::getFilePath(const QString &file) { #if defined(Q_OS_ANDROID) return QString("assets:/%1").arg(file); #elif defined(Q_OS_MAC) return QString("%1/rcc/%2").arg(QCoreApplication::applicationDirPath(), file); #else return QString("%1/%2/rcc/%3").arg(QCoreApplication::applicationDirPath(), GCOMPRIS_DATA_FOLDER, file); #endif } QString ApplicationInfo::getAudioFilePath(const QString &file) { QString localeName = getVoicesLocale(ApplicationSettings::getInstance()->locale()); QString filename = file; filename.replace("$LOCALE", localeName); filename.replace("$CA", COMPRESSED_AUDIO); if(file.startsWith('/') || file.startsWith(QLatin1String("qrc:")) || file.startsWith(':')) return filename; else return getResourceDataPath() + '/' + filename; } QString ApplicationInfo::getLocaleFilePath(const QString &file) { QString localeShortName = localeShort(); QString filename = file; filename.replace("$LOCALE", localeShortName); return filename; } QStringList ApplicationInfo::getSystemExcludedFonts() { return m_excludedFonts; } QStringList ApplicationInfo::getFontsFromRcc() { return m_fontsFromRcc; } void ApplicationInfo::notifyPortraitMode() { int width = qApp->primaryScreen()->geometry().width(); int height = qApp->primaryScreen()->geometry().height(); setIsPortraitMode(height > width); } void ApplicationInfo::setIsPortraitMode(const bool newMode) { if (m_isPortraitMode != newMode) { m_isPortraitMode = newMode; emit portraitModeChanged(); } } void ApplicationInfo::setWindow(QQuickWindow *window) { m_window = window; } void ApplicationInfo::screenshot(QString const &path) { QImage img = m_window->grabWindow(); img.save(path); } void ApplicationInfo::notifyFullscreenChanged() { if(ApplicationSettings::getInstance()->isFullscreen()) m_window->showFullScreen(); else m_window->showNormal(); } // return the shortest possible locale name for the given locale, describing // a unique voices dataset QString ApplicationInfo::getVoicesLocale(const QString &locale) { QString _locale = locale; if(_locale == GC_DEFAULT_LOCALE) { _locale = QLocale::system().name(); } // locales we have country-specific voices for: - if (_locale.startsWith(QLatin1String("pt_BR")) || _locale.startsWith(QLatin1String("zh_CN"))) + if (_locale.startsWith(QLatin1String("pt_BR")) || + _locale.startsWith(QLatin1String("zh_CN")) || + _locale.startsWith(QLatin1String("zh_TW"))) return QLocale(_locale).name(); // short locale for all the rest: return localeShort(_locale); } QObject *ApplicationInfo::systeminfoProvider(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) Q_UNUSED(scriptEngine) /* * Connect the fullscreen change signal to applicationInfo in order to change * the QQuickWindow value */ ApplicationInfo* appInfo = getInstance(); connect(ApplicationSettings::getInstance(), SIGNAL(fullscreenChanged()), appInfo, SLOT(notifyFullscreenChanged())); return appInfo; } void ApplicationInfo::init() { qmlRegisterSingletonType("GCompris", 1, 0, "ApplicationInfo", systeminfoProvider); } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a61e353bf..b02b44acc 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,257 +1,255 @@ include(qt_helper) configure_file(config.h.in "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) if(WITH_ACTIVATION_CODE) add_definitions(-DWITH_ACTIVATION_CODE) endif() if(WITH_KIOSK_MODE) add_definitions(-DWITH_KIOSK_MODE) endif() if(SAILFISHOS) add_definitions(-DSAILFISHOS) endif() # Note: put .cpp files before .h files in the following or cmake messes up # moc generation -- WTF! set(gcompris_SRCS ActivityInfo.cpp ActivityInfo.h ActivityInfoTree.cpp ActivityInfoTree.h ApplicationInfo.cpp ApplicationInfo.h ApplicationSettings.cpp ApplicationSettings.h File.cpp File.h DownloadManager.cpp DownloadManager.h ) qt5_wrap_cpp(gcompris_MOC ${gcompris_SRCS}) # Add files that do no need to pass through the moc processor set(gcompris_SRCS ${gcompris_SRCS} main.cpp config.h.in ) if(ANDROID) list(APPEND gcompris_SRCS ApplicationAndroid.cpp) else() list(APPEND gcompris_SRCS ApplicationSettingsDefault.cpp ApplicationInfoDefault.cpp) endif() include_directories( "${CMAKE_CURRENT_BINARY_DIR}" # to find config.h ) # Resources set(GCOMPRIS_RESOURCES "${PROJECT_SOURCE_DIR}/installer") if(CMAKE_HOST_WIN32) set(gcompris_icon GCompris.ico) set(gcompris_RES ${GCOMPRIS_RESOURCES}/${gcompris_icon} GCompris.rc ) elseif(CMAKE_HOST_APPLE) set(gcompris_icon GCompris.icns) set(gcompris_RES ${GCOMPRIS_RESOURCES}/${gcompris_icon}) set_source_files_properties(${gcompris_RES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") endif() if(ANDROID) add_library(${GCOMPRIS_EXECUTABLE_NAME} SHARED ${gcompris_SRCS} ${gcompris_MOC}) qt5_use_modules(${GCOMPRIS_EXECUTABLE_NAME} Qml Quick Gui Multimedia Core Svg Xml XmlPatterns AndroidExtras) else() add_executable(${GCOMPRIS_EXECUTABLE_NAME} MACOSX_BUNDLE ${gcompris_SRCS} ${gcompris_MOC} ${gcompris_RES}) qt5_use_modules(${GCOMPRIS_EXECUTABLE_NAME} Qml Quick Gui Multimedia Network XmlPatterns Svg Xml Core) endif() -target_link_libraries(${GCOMPRIS_EXECUTABLE_NAME} ${QT_LIBRARIES}) - if(CMAKE_HOST_WIN32) # Remove the console for windows set_target_properties(${GCOMPRIS_EXECUTABLE_NAME} PROPERTIES LINK_FLAGS -Wl,-subsystem,windows) endif() GCOMPRIS_ADD_RCC(core *.qml *.js resource/*.${COMPRESSED_AUDIO} resource/*.gif resource/*.png resource/*.svg resource/bonus/* resource/sounds/* resource/fonts/* qmldir) # Installation # ============ install(TARGETS ${GCOMPRIS_EXECUTABLE_NAME} ARCHIVE DESTINATION bin RUNTIME DESTINATION bin LIBRARY DESTINATION lib BUNDLE DESTINATION .) if(BUILD_STANDALONE) # Qt plugins to install set(_qt_plugins "") if(NOT SAILFISHOS) list(APPEND _qt_plugins Qt5::QJpegPlugin) endif() if(APPLE) list(APPEND _qt_plugins Qt5::QTgaPlugin Qt5::QTiffPlugin) elseif(WIN32) list(APPEND _qt_plugins Qt5::QWindowsIntegrationPlugin Qt5::QWindowsAudioPlugin Qt5::AudioCaptureServicePlugin Qt5::DSServicePlugin) elseif(UNIX AND NOT ANDROID AND NOT SAILFISHOS) list(APPEND _qt_plugins Qt5::QXcbIntegrationPlugin) endif() # Qml plugins to install if(WIN32) set(_lib_prefix "") else() set(_lib_prefix "lib") endif() set(_qt_plugins2 imageformats/${_lib_prefix}qsvg) if(UNIX AND NOT ANDROID AND NOT APPLE AND NOT SAILFISHOS) list(APPEND _qt_plugins2 mediaservice/${_lib_prefix}gstaudiodecoder mediaservice/${_lib_prefix}gstcamerabin mediaservice/${_lib_prefix}gstmediacapture mediaservice/${_lib_prefix}gstmediaplayer) elseif(APPLE) list(APPEND _qt_plugins2 mediaservice/${_lib_prefix}qavfmediaplayer mediaservice/${_lib_prefix}qtmedia_audioengine mediaservice/${_lib_prefix}qavfcamera) endif() set(_qml_plugins QtQuick/Window.2/${_lib_prefix}windowplugin QtQuick/Particles.2/${_lib_prefix}particlesplugin QtQuick.2/${_lib_prefix}qtquick2plugin QtMultimedia/${_lib_prefix}declarative_multimedia) if(NOT SAILFISHOS) list(APPEND _qml_plugins QtQuick/Controls/${_lib_prefix}qtquickcontrolsplugin QtQuick/Layouts/${_lib_prefix}qquicklayoutsplugin) endif() if(NOT WIN32 AND NOT SAILFISHOS) list(APPEND QtAudioEngine/${_lib_prefix}declarative_audioengine) endif() set(GCOMPRIS_OTHER_LIBS) if(APPLE) set(_app gcompris-qt.app) set(_qtconf_destdir ${_app}/Contents/Resources) set(_qt_plugins_destdir ${_app}/Contents/plugins) set(_qt_qml_destdir ${_app}/Contents/qml) set(GCOMPRIS_BUNDLE "\${CMAKE_INSTALL_PREFIX}/${_app}") set_target_properties(gcompris-qt PROPERTIES MACOSX_BUNDLE_INFO_STRING "GCompris, Educational game for children 2 to 10" MACOSX_BUNDLE_ICON_FILE "${gcompris_icon}" MACOSX_BUNDLE_GUI_IDENTIFIER "net.gcompris" MACOSX_BUNDLE_LONG_VERSION_STRING "${GCOMPRIS_MAJOR_VERSION}.${GCOMPRIS_MINOR_VERSION}.${GCOMPRIS_PATCH_VERSION}" MACOSX_BUNDLE_BUNDLE_NAME "gcompris-qt" MACOSX_BUNDLE_SHORT_VERSION_STRING "${GCOMPRIS_VERSION}" MACOSX_BUNDLE_BUNDLE_VERSION "${GCOMPRIS_VERSION}" MACOSX_BUNDLE_COPYRIGHT "GPL License, Copyright 2000-2015 Bruno Coudoin and Others.") set_source_files_properties(${GCOMPRIS_RESOURCES}/${gcompris_icon} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") else() set(_qtconf_destdir bin) set(_qt_plugins_destdir bin/plugins) set(_qt_qml_destdir bin/qml) if(CMAKE_HOST_WIN32) set(GCOMPRIS_BUNDLE "\${CMAKE_INSTALL_PREFIX}/bin/${GCOMPRIS_EXECUTABLE_NAME}.exe") else() set(GCOMPRIS_BUNDLE "\${CMAKE_INSTALL_PREFIX}/bin/${GCOMPRIS_EXECUTABLE_NAME}") endif() endif() # install qt.conf file install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/qt.conf DESTINATION ${_qtconf_destdir}) # install qt plugins foreach(_plugin ${_qt_plugins}) installQtPlugin(${_plugin} ${_qt_plugins_destdir} _lib) list(APPEND GCOMPRIS_OTHER_LIBS ${_lib}) endforeach() foreach(_plugin ${_qt_plugins2}) installQtPlugin2(${_plugin} ${_qt_plugins_destdir} _lib) list(APPEND GCOMPRIS_OTHER_LIBS ${_lib}) endforeach() # install qml plugins foreach(_plugin ${_qml_plugins}) installQmlPlugin(${_plugin} ${_qt_qml_destdir} _lib) list(APPEND GCOMPRIS_OTHER_LIBS ${_lib}) endforeach() # install QtGraphicalEffects (which is not a lib but only qml files) set(_qml_subdir QtGraphicalEffects) getQtQmlPath(_qt_qml_path) install(DIRECTORY ${_qt_qml_path}/QtGraphicalEffects DESTINATION ${_qt_qml_destdir}) endif(BUILD_STANDALONE) # Hack: do not fixup Qt and Qml plugins on Windows because fixup_bundle takes ages (cmake bug ?) -> Johnny : we need this even if it takes time because some required dependencies are pulled here #if(WIN32) set(GCOMPRIS_OTHER_LIBS "") endif() # install fixup_bundle script to resolve and fixup runtime dependencies if(BUILD_STANDALONE) configure_file(${CMAKE_SOURCE_DIR}/cmake/FixBundle.cmake.in FixBundle.cmake) install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake) # install a startup script for linux bundle if(UNIX AND NOT APPLE AND NOT SAILFISHOS) install(PROGRAMS ../../tools/gcompris-qt.sh DESTINATION bin) endif() endif() # Packaging # ========= set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "GCompris is a high quality educational software suite comprising of numerous activities for children aged 2 to 10.") set(CPACK_PACKAGE_VERSION_MAJOR ${GCOMPRIS_MAJOR_VERSION}) set(CPACK_PACKAGE_VERSION_MINOR ${GCOMPRIS_MINOR_VERSION}) set(CPACK_PACKAGE_VERSION_PATCH ${GCOMPRIS_PATCH_VERSION}) set(CPACK_PACKAGE_VERSION ${GCOMPRIS_VERSION}) set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING") set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README") if(WIN32) set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/installer\\\\gcompris-header.bmp") set(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/installer\\\\GCompris-install.ico") set(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/installer\\\\GCompris-uninstall.ico") set(CPACK_NSIS_EXECUTABLES_DIRECTORY "bin") set(CPACK_PACKAGE_EXECUTABLES "${GCOMPRIS_EXECUTABLE_NAME}" "${GCOMPRIS_EXECUTABLE_NAME}") else(WIN32) set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/GCompris64.png") endif() if(APPLE) set(CPACK_GENERATOR "DragNDrop") set(CPACK_DMG_DS_STORE "${GCOMPRIS_RESOURCES}/dmg_DS_Store") set(CPACK_DMG_BACKGROUND_IMAGE "${GCOMPRIS_RESOURCES}/dmg_background.png") elseif(WIN32) set(CPACK_GENERATOR "NSIS") elseif(SAILFISHOS) configure_file(${PROJECT_SOURCE_DIR}/platforms/sailfishOS/harbour-gcompris-qt.spec.cmake ${CMAKE_BINARY_DIR}/harbour-gcompris-qt.spec @ONLY) install(FILES ${PROJECT_SOURCE_DIR}/platforms/sailfishOS/harbour-gcompris-qt.desktop DESTINATION share/applications) install(FILES ${PROJECT_SOURCE_DIR}/platforms/sailfishOS/harbour-gcompris-qt.png DESTINATION share/icons/hicolor/86x86/apps) set(CPACK_RPM_PACKAGE_SUMMARY "gcompris-qt") # BUILD_ARCH is either armv7hl or i486 set(CPACK_RPM_PACKAGE_ARCHITECTURE "${BUILD_ARCH}") set(CPACK_RPM_PACKAGE_NAME "${GCOMPRIS_EXECUTABLE_NAME}") set(CPACK_RPM_PACKAGE_VERSION "${GCOMPRIS_VERSION}") set(CPACK_RPM_PACKAGE_LICENSED "GPLv3") set(CPACK_RPM_PACKAGE_URL "https://www.gcompris.org") set(CPACK_RPM_PACKAGE_DESCRIPTION "GCompris is a high quality educational software suite comprising of numerous activities for children aged 2 to 10.") set(CPACK_RPM_USER_BINARY_SPECFILE "${CMAKE_BINARY_DIR}/harbour-gcompris-qt.spec") set(CMAKE_INSTALL_PREFIX "/usr") set(CPACK_PACKAGING_INSTALL_PREFIX "/usr") set(CPACK_GENERATOR "RPM") else() set(CPACK_GENERATOR "STGZ") endif() include(CPack) diff --git a/src/core/GCButtonCancel.qml b/src/core/GCButtonCancel.qml index 93c9157c6..45bb9e81d 100644 --- a/src/core/GCButtonCancel.qml +++ b/src/core/GCButtonCancel.qml @@ -1,64 +1,63 @@ /* GCompris - GCButtonCancel.qml * * Copyright (C) 2015 Bruno Coudoin * * Authors: * Bruno Coudoin * * 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 . */ import QtQuick 2.2 -import QtQuick.Controls 1.0 import GCompris 1.0 /** * A QML component representing GCompris' cancel button. * @ingroup components * * @inherit QtQuick.Image */ Image { id: cancel source: "qrc:/gcompris/src/core/resource/cancel.svg"; anchors.right: parent.right anchors.top: parent.top smooth: true sourceSize.width: 60 * ApplicationInfo.ratio anchors.margins: 10 signal close SequentialAnimation { id: anim running: true loops: Animation.Infinite NumberAnimation { target: cancel property: "rotation" from: -10; to: 10 duration: 500 easing.type: Easing.InOutQuad } NumberAnimation { target: cancel property: "rotation" from: 10; to: -10 duration: 500 easing.type: Easing.InOutQuad } } MouseArea { anchors.fill: parent onClicked: close() } } diff --git a/src/core/GCDialogCheckBox.qml b/src/core/GCDialogCheckBox.qml index d1c94341d..9df596311 100644 --- a/src/core/GCDialogCheckBox.qml +++ b/src/core/GCDialogCheckBox.qml @@ -1,53 +1,52 @@ /* GCompris - GCDialogCheckBox.qml * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin * * 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 . */ import QtQuick 2.2 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.0 import GCompris 1.0 -import QtQuick.Layouts 1.1 /** * GCompris' CheckBox component. * @ingroup components * * @inherit QtQuick.Controls.CheckBox */ CheckBox { id: checkBox width: parent.width style: CheckBoxStyle { spacing: 10 indicator: Image { sourceSize.height: 50 * ApplicationInfo.ratio source: control.checked ? "qrc:/gcompris/src/core/resource/apply.svg" : "qrc:/gcompris/src/core/resource/cancel.svg" } label: GCText { fontSize: mediumSize text: control.text wrapMode: Text.WordWrap width: parent.parent.width - 50 * ApplicationInfo.ratio - 10 * 2 } } } diff --git a/src/core/config.h.in b/src/core/config.h.in index cd7b2209e..7cc48ddf5 100644 --- a/src/core/config.h.in +++ b/src/core/config.h.in @@ -1,14 +1,39 @@ +/* GCompris - config.h + * + * Copyright (C) 2015 Bruno Coudoin + * + * Authors: + * Bruno Coudoin + * + * 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 GCOMPRIS_CONFIG_H +#define GCOMPRIS_CONFIG_H + /* Version number of package */ #define VERSION "@GCOMPRIS_VERSION@" /* Folder where rccs and translations are installed */ #ifdef Q_OS_MAC #define GCOMPRIS_DATA_FOLDER "." #else #define GCOMPRIS_DATA_FOLDER "../@_data_dest_dir@" #endif /* GCompris for android, gcompris-qt for others */ #define GCOMPRIS_APPLICATION_NAME "@GCOMPRIS_EXECUTABLE_NAME@" /* Compressed audio format */ #define COMPRESSED_AUDIO "@COMPRESSED_AUDIO@" /* Download Allowed */ #define DOWNLOAD_ALLOWED "@WITH_DOWNLOAD@" + +#endif // GCOMPRIS_CONFIG_H diff --git a/src/core/core.js b/src/core/core.js index b6a4486e2..c106e1db7 100644 --- a/src/core/core.js +++ b/src/core/core.js @@ -1,232 +1,239 @@ /* GCompris - core.js * * Copyright (C) 2014 * Authors: * Bruno Coudoin * Holger Kaelberer * Johnny Jazeix * * 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 . */ /** * @file * Contains commonly used javascript methods. * @ingroup components * * FIXME: how to include this file in kgenapidox's output? */ .pragma library .import QtQml 2.2 as Qml .import GCompris 1.0 as GCompris /** * Shuffle the array @p o and returns it. * * @param o Array to shuffle. * @returns A shuffled array. */ function shuffle(o) { for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); return o; } /** - * Return the filename of the audio voices file for the passed letter + * Return the filename of the audio voices file for the passed letters * (or a number) @p c * + * A letter maybe a digraph or more characters (a pair of characters used + * to write one phoneme). In this case the result have the form U0066U0068.ogg + * * The returned audio file. has the suffix .ogg * * @param c Letter or number character. * @return A filename for the audio file for the passed letter @p c of the * form U0033.ogg */ function getSoundFilenamForChar(c) { - var result = "U"; - var codeHex = c.toLowerCase().charCodeAt(0).toString(16).toUpperCase(); - while (codeHex.length < 4) { - codeHex = "0" + codeHex; + var results = '' + for(var i = 0; i < c.length; ++i) { + var result = "U"; + var codeHex = c.toLowerCase().charCodeAt(i).toString(16).toUpperCase(); + while (codeHex.length < 4) { + codeHex = "0" + codeHex; + } + results += "U" + codeHex } - result += codeHex + ".$CA"; - return result; + results += ".$CA"; + return results; } /** * Create and present a GCDialog with the given parameters * * Instantiates a GCDialog object dynamically as child of the passed * parent object. After one of the buttons passed in the buttonHandler parameter * has been pressed, the dialog will be closed and destroyed automatically. * * @param parent QML parent object * @param informativeText Informative text * @param button1Text the Label of the first button * @param button1Callback Callback handler for the first button * @param button2Text Label of the second button * @param button2Callback Callback handler for the second button * @param closeCallback Callback handler for the close button * @returns The GCDialog object upon success, null otherwise * * @sa GCDialog */ function showMessageDialog(parent, informativeText, button1Text, button1Callback, button2Text, button2Callback, closeCallback) { var qmlStr = 'import QtQuick 2.0\n' + 'GCDialog {\n' + ' message: "' + informativeText + '"\n' + ' button1Text: "' + button1Text + '"\n' + ' button2Text: "' + button2Text + '"\n' + ' }\n'; var dialog = null; try { dialog = Qt.createQmlObject(qmlStr, parent); if(button1Callback) dialog.button1Hit.connect(button1Callback); if(button2Callback) dialog.button2Hit.connect(button2Callback); if(closeCallback) dialog.close.connect(closeCallback); dialog.start(); } catch (e) { console.error("core.js: Error creating a MessageDialog: " + e); if (dialog) dialog.destroy(); return null; } return dialog; } /** * Destroy dialog @p dialog * * @param dialog A dynamically created GCDialog or DownloadDialog */ function destroyDialog(dialog) { if (dialog) { dialog.stop(); dialog.destroy(); } } var downloadDialogComponent = null; /** * Create and present a DownloadDialog with the given parameters. * * Instantiates a DownloadDialog object dynamically as child of the passed * parent object. The DownloadDialog.dynamic property will be set, and the * dialog will be destroyed dynamically after closing. * * @param parent QML parent object * @param properties Object with property-value pairs used to parametrize the new * object. Used directly as properties parameter of * Component.createObject() * @returns A newly created DownloadDialog object upon success, null * otherwise. */ function showDownloadDialog(parent, properties) { var dialog = null; try { if (!downloadDialogComponent) { downloadDialogComponent = Qt.createComponent("qrc:/gcompris/src/core/DownloadDialog.qml"); if (downloadDialogComponent.status != Qml.Component.Ready) { throw new Error("Error creating DownloadDialog component: " + downloadDialogComponent.errorString()); downloadDialogComponent = null; } } properties.dynamic = true; dialog = downloadDialogComponent.createObject( parent, properties); dialog.main = parent dialog.start(); } catch (e) { console.error("core.js: Error creating a DownloadDialog: " + e); if (dialog) dialog.destroy(); return null; } //console.log("created DownloadDialog " + dialog); return dialog; } /** * Helper checking for availability of audio voices for the current locale and * informing the user in case they're missing. * * Can be used by acitivities that depend on audio voices to inform the user * of missing resources during startup. * * @param parent Parent QML object. */ function checkForVoices(parent) { if (!GCompris.DownloadManager.areVoicesRegistered()) { showMessageDialog(parent, qsTr("Missing sound files!") + '\n' + qsTr("This activity uses language sound files, that are not yet installed on your system.") + '\n' + qsTr("For downloading the needed sound files go to the preferences dialog."), "", null, "", null, null); } } var aboutToQuit = false; /** * Central function for quitting GCompris. * * Should be used everywhere instead of Qt.quit(), warning in case of running * downloadloads and showing a confirmation dialog on mobile devices. * Call Qt.quit() itself upon confirmation. * * @param parent QML parent object used for the dynamic dialog. */ function quit(parent) { if (aboutToQuit) // don't execute concurrently return; aboutToQuit = true; GCompris.ApplicationInfo.abandonAudioFocus() if (GCompris.DownloadManager.downloadIsRunning()) { var dialog = showDownloadDialog(parent, { text: qsTr("Download in progress") + '\n' + qsTr("Download in progress.
'Abort' it to quit immediately."), autohide: true, reportError: false, reportSuccess: false, backgroundButtonVisible: false }); dialog.finished.connect(function() {Qt.quit();}); } else if (GCompris.ApplicationInfo.isMobile) { // prevent the user from quitting accidentially by clicking back too often: showMessageDialog(parent, qsTr("Quit?") + '\n' + qsTr("Do you really want to quit GCompris?"), qsTr("Yes"), function() { Qt.quit(); }, qsTr("No"), function() { aboutToQuit = false; }, function() { aboutToQuit = false; } ); } else Qt.quit(); } diff --git a/src/core/main.qml b/src/core/main.qml index cf80a8a7c..ad857b3c7 100644 --- a/src/core/main.qml +++ b/src/core/main.qml @@ -1,272 +1,273 @@ /* GCompris - main.qml * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin * * 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 . */ import QtQuick 2.2 import QtQuick.Controls 1.0 import QtQuick.Window 2.1 import QtQml 2.2 import GCompris 1.0 import "qrc:/gcompris/src/core/core.js" as Core /** * GCompris' main QML file defining the top level window. * @ingroup infrastructure * * Handles application start (Component.onCompleted) and shutdown (onClosing) * on the QML layer. * * Contains the central GCAudio objects audio effects and audio voices. * * Contains the top level StackView presenting and animating GCompris' * full screen views. * * @sa BarButton, BarEnumContent * @inherit QtQuick.Window */ Window { id: main - width: 800 - height: 520 - minimumWidth: 400 - minimumHeight: 400 + // Start in window mode at full screen size + width: Screen.width + height: Screen.height + minimumWidth: 400 * ApplicationInfo.ratio + minimumHeight: 400 * ApplicationInfo.ratio title: "GCompris" /// @cond INTERNAL_DOCS property var applicationState: Qt.application.state onApplicationStateChanged: { if (ApplicationInfo.isMobile && applicationState != Qt.ApplicationActive) { audioVoices.stop(); audioEffects.stop(); } } onClosing: Core.quit() GCAudio { id: audioVoices muted: !ApplicationSettings.isAudioVoicesEnabled Timer { id: delayedWelcomeTimer interval: 10000 /* Make sure, that playing welcome.ogg if delayed * because of not yet registered voices, will only * happen max 10sec after startup */ repeat: false onTriggered: { DownloadManager.voicesRegistered.disconnect(playWelcome); } function playWelcome() { audioVoices.append(ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/misc/welcome.$CA")); } } Component.onCompleted: { if(ApplicationSettings.isAudioEffectsEnabled) append(ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/core/resource/intro.$CA")) if (DownloadManager.areVoicesRegistered()) delayedWelcomeTimer.playWelcome(); else { DownloadManager.voicesRegistered.connect( delayedWelcomeTimer.playWelcome); delayedWelcomeTimer.start(); } } } GCAudio { id: audioEffects muted: !ApplicationSettings.isAudioEffectsEnabled } function playIntroVoice(name) { name = name.split("/")[0] audioVoices.append(ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/intro/" + name + ".$CA")) } Component.onCompleted: { console.log("enter main.qml (run #" + ApplicationSettings.exeCount + ", ratio=" + ApplicationInfo.ratio + ", fontRatio=" + ApplicationInfo.fontRatio + ", dpi=" + Math.round(Screen.pixelDensity*25.4) + ")"); if (ApplicationSettings.exeCount == 1 && !ApplicationSettings.isKioskMode) { // first run var dialog; dialog = Core.showMessageDialog( main, qsTr("Welcome to GCompris!") + '\n' + qsTr("You are running GCompris for the first time.") + '\n' + qsTr("You should verify that your application settings especially your language is set correctly, and that all language specific sound files are installed. You can do this in the Preferences Dialog.") + "\n" + qsTr("Have Fun!") + "\n" + qsTr("Your current language is %1 (%2).") - .arg(Qt.locale(ApplicationInfo.localeShort).nativeLanguageName) - .arg(ApplicationInfo.localeShort) + .arg(Qt.locale(ApplicationInfo.getVoicesLocale(ApplicationSettings.locale)).nativeLanguageName) + .arg(ApplicationInfo.getVoicesLocale(ApplicationSettings.locale)) + "\n" + qsTr("Do you want to download the corresponding sound files now?"), qsTr("Yes"), function() { if (DownloadManager.downloadResource( - DownloadManager.getVoicesResourceForLocale(ApplicationInfo.localeShort))) + DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale))) var downloadDialog = Core.showDownloadDialog(pageView.currentItem, {}); }, qsTr("No"), null, function() { pageView.currentItem.focus = true } ); } } StackView { id: pageView anchors.fill: parent initialItem: { "item": "qrc:/gcompris/src/activities/" + ActivityInfoTree.rootMenu.name, "properties": { 'audioVoices': audioVoices, 'audioEffects': audioEffects } } focus: ApplicationInfo.QTVersion >= "5.4.0" delegate: StackViewDelegate { id: root function getTransition(properties) { audioVoices.clearQueue() if(!properties.exitItem.isDialog) { if(!properties.enterItem.isDialog) { playIntroVoice(properties.enterItem.activityInfo.name) } properties.enterItem.start() } if(properties.name === "pushTransition") { if(properties.enterItem.isDialog) { return pushVTransition } else { return pushHTransition } } else { if(properties.exitItem.isDialog) { return popVTransition } else { return popHTransition } } } function transitionFinished(properties) { properties.exitItem.opacity = 1 if(!properties.enterItem.isDialog) { properties.exitItem.stop() } } property Component pushHTransition: StackViewTransition { PropertyAnimation { target: enterItem property: "x" from: target.width to: 0 duration: 500 easing.type: Easing.OutSine } PropertyAnimation { target: exitItem property: "x" from: 0 to: -target.width duration: 500 easing.type: Easing.OutSine } } property Component popHTransition: StackViewTransition { PropertyAnimation { target: enterItem property: "x" from: -target.width to: 0 duration: 500 easing.type: Easing.OutSine } PropertyAnimation { target: exitItem property: "x" from: 0 to: target.width duration: 500 easing.type: Easing.OutSine } } property Component pushVTransition: StackViewTransition { PropertyAnimation { target: enterItem property: "y" from: -target.height to: 0 duration: 500 easing.type: Easing.OutSine } PropertyAnimation { target: exitItem property: "y" from: 0 to: target.height duration: 500 easing.type: Easing.OutSine } } property Component popVTransition: StackViewTransition { PropertyAnimation { target: enterItem property: "y" from: target.height to: 0 duration: 500 easing.type: Easing.OutSine } PropertyAnimation { target: exitItem property: "y" from: 0 to: -target.height duration: 500 easing.type: Easing.OutSine } } property Component replaceTransition: pushHTransition } } /// @endcond } diff --git a/tools/menus/resource/reading.svg b/tools/menus/resource/reading.svg deleted file mode 100644 index c6ff55f30..000000000 --- a/tools/menus/resource/reading.svg +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - A - - - - B - - - - C - - - - - - - - - - - - - - - - - - - diff --git a/tools/menus/resource/searace.svg b/tools/menus/resource/searace.svg deleted file mode 100644 index 4c7d3854d..000000000 --- a/tools/menus/resource/searace.svg +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/menus/resource/searace1player.svg b/tools/menus/resource/searace1player.svg deleted file mode 100644 index 71641ecd1..000000000 --- a/tools/menus/resource/searace1player.svg +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/menus/resource/tuxpaint.svg b/tools/menus/resource/tuxpaint.svg deleted file mode 100644 index 7d9472c20..000000000 --- a/tools/menus/resource/tuxpaint.svg +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/menus/searace.qml b/tools/menus/searace.qml deleted file mode 100644 index 5005c2085..000000000 --- a/tools/menus/searace.qml +++ /dev/null @@ -1,38 +0,0 @@ -/* GCompris - ActivityInfo.qml - * - * Copyright (C) 2015 Your Name - * - * 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 . - */ -import GCompris 1.0 - -ActivityInfo { - name: "searace/Searace.qml" - difficulty: 6 - icon: "searace/searace.svg" - author: "Bruno Coudoin <bruno.coudoin@gcompris.net>" - demo: false - title: qsTr("Sea race (2 Players)") - description: qsTr("Direct your boat accurately to win the race.") - goal: qsTr("In this activity, you will learn how to enter commands into a computer. Even if the language is extremely basic, you learn here how to think ahead and construct a program. This activity can be used to introduce the programming concept to children.") - prerequisite: "" - manual: qsTr("In the text entry, enter one command per line, to control your boat. -Commands supported are displayed between the two entry areas. The 'left' and 'right' commands must be followed by an angle in degrees. The angle value is also called a 'parameter' to the left or right command. By default 45 degrees is used. The 'forward' command accepts a distance parameter. By default 1 is used. -For example: -- left 90: Make a perpendicular left turn -- forward 10: Go forward for 10 units (as displayed on the ruler). -The goal is to reach the right of the screen (the red line). When done, you can try to improve your program and start a new race with the same weather conditions by using the retry button. You can click and drag your mouse anywhere on the map to get a measurement in distance and angle. Going to the next level will give you more complex weather conditions.") - credit: "" - section: "/experience" -} diff --git a/tools/menus/searace1player.qml b/tools/menus/searace1player.qml deleted file mode 100644 index 75a6d6772..000000000 --- a/tools/menus/searace1player.qml +++ /dev/null @@ -1,37 +0,0 @@ -/* GCompris - ActivityInfo.qml - * - * Copyright (C) 2015 Your Name - * - * 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 . - */ -import GCompris 1.0 - -ActivityInfo { - name: "searace1player/Searace1player.qml" - difficulty: 6 - icon: "searace1player/searace1player.svg" - author: "Bruno Coudoin <bruno.coudoin@gcompris.net>" - demo: false - title: qsTr("Sea race (Single Player)") - description: qsTr("Give good instructions to your ship in order to be first in the race.") - goal: qsTr("In this activity, you will learn how to enter commands into a computer. Even if the language is extremely basic, you learn here how to think ahead and construct a program. This activity can be used to introduce the programming concept to children.") - prerequisite: "" - manual: qsTr("In the text entry, enter one command per line, to control your boat. Commands supported are displayed between the two entry areas. The 'left' and 'right' commands must be followed by an angle in degrees. The angle value is also called a 'parameter' to the left or right command. By default 45 degrees is used. The 'forward' command accepts a distance parameter. By default 1 is used. -For example: -- left 90: Make a perpendicular left turn -- forward 10: Go forward for 10 units (as displayed on the ruler). -The goal is to reach the right of the screen (the red line). When done, you can try to improve your program and start a new race with the same weather conditions by using the retry button. You can click and drag your mouse anywhere on the map to get a measurement in distance and angle. Going to the next level will give you more complex weather conditions.") - credit: "" - section: "/experience" -} diff --git a/tools/menus/tuxpaint.qml b/tools/menus/tuxpaint.qml deleted file mode 100644 index aef8973c5..000000000 --- a/tools/menus/tuxpaint.qml +++ /dev/null @@ -1,33 +0,0 @@ -/* GCompris - ActivityInfo.qml - * - * Copyright (C) 2015 Your Name - * - * 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 . - */ -import GCompris 1.0 - -ActivityInfo { - name: "tuxpaint/Tuxpaint.qml" - difficulty: 1 - icon: "tuxpaint/tuxpaint.svg" - author: "Bill Kendrick <Tuxpaint>" - demo: true - title: qsTr("Tuxpaint") - description: qsTr("Launch Tuxpaint") - goal: qsTr("Drawing activity (pixmap)") - prerequisite: qsTr("mouse and keyboard manipulation") - manual: qsTr("Use Tuxpaint to draw. When Tuxpaint is finished this board will end.") - credit: "" - section: "/fun" -}