diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..ffd0a85 --- /dev/null +++ b/.clang-format @@ -0,0 +1,55 @@ +--- +BasedOnStyle: Microsoft +AlignArrayOfStructures: Left +AllowShortBlocksOnASingleLine: Always +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakArrays: false +BreakBeforeTernaryOperators: false +BreakInheritanceList: AfterComma +BreakStringLiterals: false +ColumnLimit: 0 +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 2 +IncludeBlocks: Regroup +IndentRequiresClause: false +IndentWidth: 2 +KeepEmptyLinesAtTheStartOfBlocks: false +PenaltyBreakTemplateDeclaration: 1000000 +PointerAlignment: Left +SpaceAfterTemplateKeyword: false +SpaceBeforeParens: Custom +SpaceBeforeParensOptions: + AfterControlStatements: false + AfterForeachMacros: false + AfterIfMacros: false +SpacesInContainerLiterals: false +TabWidth: 2 +BracedInitializerIndentWidth: 2 +NamespaceIndentation: All +IncludeCategories: + - Regex: '^\<.*\>' + Priority: 1 + CaseSensitive: false + - Regex: '^".*"' + Priority: 2 + CaseSensitive: false \ No newline at end of file diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..b4ca4a0 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,100 @@ +Checks: > + -*, + bugprone-*, + -bugprone-easily-swappable-parameters, + -bugprone-branch-clone, + -bugprone-unchecked-optional-access, + cppcoreguidelines-avoid-goto, + cppcoreguidelines-init-variables, + cppcoreguidelines-no-malloc, + cppcoreguidelines-prefer-member-initializer, + cppcoreguidelines-virtual-class-destructor, + misc-const-correctness, + misc-header-include-cycle, + misc-include-cleaner, + misc-misleading-identifier, + misc-misplaced-const, + misc-new-delete-overloads, + misc-non-copyable-objects, + misc-redundant-expression, + misc-static-assert, + misc-throw-by-value-catch-by-reference, + misc-unconventional-assign-operator, + misc-uniqueptr-reset-release, + misc-unused-*, + modernize-avoid-*, + -modernize-avoid-bind, + modernize-concat-nested-namespaces, + modernize-deprecated-*, + modernize-loop-convert, + modernize-make-*, + modernize-min-max-use-initializer-list, + modernize-raw-string-literal, + modernize-redundant-void-arg, + modernize-replace-*, + modernize-unary-static-assert, + modernize-use-bool-literals, + modernize-use-emplace, + modernize-use-equals-*, + modernize-use-noexcept, + modernize-use-nullptr, + modernize-use-override, + modernize-use-starts-ends-with, + modernize-use-using, + boost-use-to-string, + performance-faster-string-find, + performance-for-range-copy, + performance-implicit-conversion-in-loop, + performance-inefficient-*, + -performance-inefficient-string-concatenation, + performance-move-const-arg, + performance-no-automatic-move, + performance-noexcept-destructor, + performance-noexcept-swap, + performance-trivially-destructible, + performance-type-promotion-in-math-fn, + performance-unnecessary-*, + readability-avoid-*, + readability-const-return-type, + readability-container-*, + readability-static-accessed-through-instance, + readability-delete-null-pointer, + readability-duplicate-include, + readability-identifier-naming, + readability-implicit-bool-conversion, + readability-inconsistent-declaration-parameter-name, + readability-make-member-function-const, + readability-math-missing-parentheses, + readability-misleading-indentation, + readability-misplaced-array-index, + readability-named-parameter, + readability-non-const-parameter, + readability-operators-representation, + readability-qualified-auto, + readability-redundant-*, + readability-reference-to-constructed-temporary, + readability-simplify-subscript-expr, + readability-string-compare, + readability-use-std-min-max +HeaderFilterRegex: 'mementar/include/mementar/*' +CheckOptions: + - { key: readability-identifier-naming.NamespaceCase, value: lower_case } + - { key: readability-identifier-naming.ClassCase, value: CamelCase } + - { key: readability-identifier-naming.StructCase, value: CamelCase } + - { key: readability-identifier-naming.StructSuffix, value: _t } + - { key: readability-identifier-naming.FunctionCase, value: camelBack } + - { key: readability-identifier-naming.VariableCase, value: lower_case } + - { key: readability-identifier-naming.PrivateMemberCase, value: lower_case } + - { key: readability-identifier-naming.PrivateMemberSuffix, value: _ } + - { key: readability-identifier-naming.EnumCase, value: CamelCase } + - { key: readability-identifier-naming.EnumSuffix, value: _e } + - { key: readability-identifier-naming.EnumConstantCase, value: lower_case } + - { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE } + - { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE } + - { key: readability-identifier-naming.StaticVariableCase, value: lower_case } + - { key: readability-identifier-naming.StaticVariableSuffix, value: _ } + - { key: readability-operators-representation.BinaryOperators, value: '&&;&=;&;|;~;!;!=;||;|=;^;^=' } + - { key: misc-const-correctness.AnalyzeValues, value: false } + - { key: misc-include-cleaner.DeduplicateFindings, value: false } +ExtraArgsBefore: + - '-frelaxed-template-template-args' \ No newline at end of file diff --git a/.github/run_clang_tidy.py b/.github/run_clang_tidy.py new file mode 100644 index 0000000..e7870a0 --- /dev/null +++ b/.github/run_clang_tidy.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python + +# Run clang-tidy recursively and parallel on directory +# Usage: run-clang-tidy sourcedir builddir excludedirs extensions +# extensions and excludedirs are specified as comma-separated +# string without dot, e.g. 'c,cpp' +# e.g. run-clang-tidy . build test,other c,cpp file + +import os, sys, subprocess, multiprocessing +import json + +manager = multiprocessing.Manager() +failedfiles = manager.list() + +# Get absolute paths from arguments +print("Arguments: " + str(sys.argv)) +sourcedir = os.path.abspath(sys.argv[1]) +print("Source directory: " + sourcedir) +builddir = os.path.abspath(sys.argv[2]) +print("Build directory: " + builddir) +# If exclude dirs is not empty, split it into a tuple +excludedirs = () +if len(sys.argv) > 3 and sys.argv[3]: + excludedirs = tuple([os.path.join(sourcedir, s) for s in sys.argv[3].split(',')]) +# If the build directory is not the same as the source directory, exclude it +if not sourcedir == builddir: + excludedirs = excludedirs + (builddir,) + +print("Exclude directories: " + str(excludedirs)) +# Split extensions into a tuple +extensions = () +if(len(sys.argv) >= 4): + extensions = tuple([("." + s) for s in sys.argv[4].split(',')]) +print("Extensions: " + str(extensions)) + +def runclangtidy(filepath): + print("Checking: " + filepath) + proc = subprocess.Popen(f'clang-tidy -warnings-as-errors=* -p {builddir} {filepath}', shell=True) + if proc.wait() != 0: + failedfiles.append(filepath) + +def collectfiles(dir, exclude, exts): + collectedfiles = [] + for root, dirs, files in os.walk(dir): + root = os.path.abspath(root) + for file in files: + filepath = os.path.join(root, file) + if (len(exclude) == 0 or not filepath.startswith(exclude)) and filepath.endswith(exts): + collectedfiles.append(filepath) + return collectedfiles + +def collectcompiledfiles(dir, builddir): + collectedfiles = [] + if(builddir): + compile_file = open(builddir + '/compile_commands.json') + if compile_file is not None: + compile_data = json.load(compile_file) + for line in compile_data: + filepath = line["file"] + if dir in filepath and not builddir in filepath: + collectedfiles.append(filepath) + + return collectedfiles + +# Define the pool AFTER the global variables and subprocess function because WTF python +# See: https://stackoverflow.com/questions/41385708/multiprocessing-example-giving-attributeerror +pool = multiprocessing.Pool() +files = collectcompiledfiles(sourcedir, builddir) +if len(files) == 0: + files = collectfiles(sourcedir, excludedirs, extensions) +pool.map(runclangtidy, files) +pool.close() +pool.join() +if len(failedfiles) > 0: + print("Errors in " + str(len(failedfiles)) + " files") + sys.exit(1) +print("No errors found") +sys.exit(0) \ No newline at end of file diff --git a/.github/workflows/ROS1.yml b/.github/workflows/ROS1.yml new file mode 100644 index 0000000..bab4cbc --- /dev/null +++ b/.github/workflows/ROS1.yml @@ -0,0 +1,68 @@ +name: ROS1 CI + +on: + push: + paths-ignore: + - 'docs/**' + - 'launch/ros2/**' + - 'resources/*' + pull_request: + paths-ignore: + - 'docs/**' + - 'launch/ros2/**' + - 'resources/*' + +jobs: + build: + + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + include: + #- operating-system: ubuntu-18.04 + # ros_distro: melodic + # distro: bionic + - operating-system: ubuntu-20.04 + ros_distro: noetic + distro: focal + env: + ROS_CI_DESKTOP: ${{ matrix.distro }} + CI_SOURCE_PATH: $(pwd) + # Set the python path manually to include /usr/-/python2.7/dist-packages + # as this is where apt-get installs python packages. + PYTHONPATH: $PYTHONPATH:/usr/lib/python2.7/dist-packages:/usr/local/lib/python2.7/dist-packages:/usr/lib/python3.8/dist-packages:/usr/local/lib/python3.8/dist-packages + ROS_DISTRO: ${{ matrix.ros_distro }} + steps: + - uses: actions/checkout@v1 + - name: Install ROS1 + run: | + sudo sh -c "echo \"deb http://packages.ros.org/ros/ubuntu $ROS_CI_DESKTOP main\" > /etc/apt/sources.list.d/ros-latest.list" + sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 + sudo apt update -qq + sudo apt install dpkg + sudo apt install -y ros-$ROS_DISTRO-desktop qtbase5-dev qtdeclarative5-dev + sudo apt install -y libcppunit-dev libcurl4-openssl-dev + sudo apt-get install python3-rosdep + + source /opt/ros/$ROS_DISTRO/setup.bash + sudo rosdep init + rosdep update --include-eol-distros # Support EOL distros. + + - name: build + run: | + source /opt/ros/$ROS_DISTRO/setup.bash + cmake --version + mkdir -p ~/catkin_ws/src + cd ~/catkin_ws + catkin_make + source devel/setup.bash + cd ~/catkin_ws/src + ln -s ~/work # $CI_SOURCE_PATH + git clone https://github.com/sarthou/ontologenius.git + cd .. + catkin_make + - name: rostest + run: | + cd ~/catkin_ws + source devel/setup.bash + catkin_make run_tests_mementar_rostest -j1 && catkin_make test -j1 -DCATKIN_WHITELIST_PACKAGES="mementar" diff --git a/.github/workflows/ROS2.yml b/.github/workflows/ROS2.yml new file mode 100644 index 0000000..cd1de5a --- /dev/null +++ b/.github/workflows/ROS2.yml @@ -0,0 +1,66 @@ +name: ROS2 CI + +on: + push: + paths-ignore: + - 'docs/**' + - 'resources/*' + pull_request: + paths-ignore: + - 'docs/**' + - 'resources/*' + +jobs: + build: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + include: + - operating-system: ubuntu-22.04 + ros_distro: humble + distro: jammy + - operating-system: ubuntu-22.04 + ros_distro: iron + distro: jammy + env: + ROS_CI_DESKTOP: ${{ matrix.distro }} + CI_SOURCE_PATH: $(pwd) + ROS_DISTRO: ${{ matrix.ros_distro }} + steps: + - name: Setup ROS + uses: ros-tooling/setup-ros@v0.7 + with: + required-ros-distributions: ${{ matrix.ros_distro }} + + - name: Install deps + run: | + sudo apt install dpkg + sudo apt install -y qtbase5-dev qtdeclarative5-dev + sudo apt install -y libcppunit-dev libcurl4-openssl-dev + sudo apt-get install python3-rosdep + sudo apt install ros-cmake-modules + sudo apt install ros-$ROS_DISTRO-std-msgs ros-$ROS_DISTRO-pluginlib + source /opt/ros/$ROS_DISTRO/setup.bash + + - name: Setup Workspace + run: | + source /opt/ros/$ROS_DISTRO/setup.bash + cmake --version + cd $GITHUB_WORKSPACE + mkdir -p ros2_ws/src/mementar + cd $GITHUB_WORKSPACE/ros2_ws/src + git clone https://github.com/sarthou/ontologenius.git + cd $GITHUB_WORKSPACE/ros2_ws + colcon build --symlink-install + + - name: Checkout + uses: actions/checkout@v4 + with: + path: ros2_ws/src/mementar + + - name: Build + run: | + cd $GITHUB_WORKSPACE/ros2_ws + source install/setup.bash + export ROS_LOCALHOST_ONLY=1 + colcon build --symlink-install \ No newline at end of file diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml new file mode 100644 index 0000000..9bf7a74 --- /dev/null +++ b/.github/workflows/linter.yml @@ -0,0 +1,86 @@ +name: Clang linter + +on: + push: + branches: + - master + - dev + paths-ignore: + - 'docs/**' + - 'resources/*' + - 'ui/*' + - 'files/*' + - 'configuration/*' + pull_request: + branches: + - master + - dev + paths-ignore: + - 'docs/**' + - 'resources/*' + - 'ui/*' + - 'files/*' + - 'configuration/*' + +jobs: + build: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + include: + - operating-system: ubuntu-22.04 + ros_distro: humble + distro: jammy + env: + ROS_CI_DESKTOP: ${{ matrix.distro }} + CI_SOURCE_PATH: $(pwd) + ROS_DISTRO: ${{ matrix.ros_distro }} + steps: + - name: Setup ROS + uses: ros-tooling/setup-ros@v0.7 + with: + required-ros-distributions: ${{ matrix.ros_distro }} + + - name: Install deps + run: | + sudo apt install dpkg + sudo apt install -y qtbase5-dev qtdeclarative5-dev + sudo apt install -y libcppunit-dev libcurl4-openssl-dev + sudo apt-get install python3-rosdep + sudo apt install ros-cmake-modules + sudo apt install ros-$ROS_DISTRO-std-msgs ros-$ROS_DISTRO-pluginlib + sudo apt install g++-12 + source /opt/ros/$ROS_DISTRO/setup.bash + + - name: Setup Workspace + run: | + source /opt/ros/$ROS_DISTRO/setup.bash + export CXX=clang++ + export CC=clang + cmake --version + cd $GITHUB_WORKSPACE + mkdir -p ros2_ws/src/mementar + cd $GITHUB_WORKSPACE/ros2_ws/src + git clone https://github.com/sarthou/ontologenius.git + cd $GITHUB_WORKSPACE/ros2_ws + colcon build --symlink-install + + - name: Checkout + uses: actions/checkout@v4 + with: + path: ros2_ws/src/mementar + + - name: Build + run: | + cd $GITHUB_WORKSPACE/ros2_ws + source install/setup.bash + export ROS_LOCALHOST_ONLY= + export CXX=clang++ + export CC=clang + colcon build --symlink-install + + - name: Lint + run: | + cd $GITHUB_WORKSPACE/ros2_ws/src/mementar + ls + python3 .github/run_clang_tidy.py . ../../build/ diff --git a/.gitignore b/.gitignore index 01e8206..c67f57e 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ tests_files/* # mementar intern files /file_intern/* +settings.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..1ce31d8 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Limux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/clang", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "clang-x64", + "compileCommands": "${workspaceFolder}/../../build/compile_commands.json" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index b254b74..539a039 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,320 +1,20 @@ -cmake_minimum_required(VERSION 2.8.3) +cmake_minimum_required(VERSION 3.8) +set(CMAKE_EXPORT_COMPILE_COMMANDS 1) project(mementar) -add_compile_options(-std=c++1z -Wall) -link_libraries(stdc++fs) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED on) -## Find catkin macros and libraries -## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) -## is used, also find other catkin packages -find_package(catkin REQUIRED COMPONENTS - roscpp - rospy - std_msgs - genmsg - message_generation - pluginlib - ontologenius -) +# link_libraries(stdc++fs) -## System dependencies are found with CMake's conventions +# Do we really need boost?? find_package(Boost REQUIRED COMPONENTS system) -find_package(cmake_modules REQUIRED) -find_package(pluginlib REQUIRED) find_package(Qt5 COMPONENTS Core Gui Widgets PrintSupport) +find_package(PkgConfig REQUIRED) find_package(OpenCV REQUIRED) - -################################################ -## Declare ROS messages, services and actions ## -################################################ - -## Generate messages in the 'msg' folder - add_message_files( - FILES - MementarAction.msg - MementarExplanation.msg - MementarOccasion.msg - StampedString.msg - ) - -## Generate services in the 'srv' folder - add_service_files( - FILES - MementarService.srv - MementarOccasionSubscription.srv - MementarOcassionUnsubscription.srv - ) - -## Generate added messages and services with any dependencies listed here - generate_messages( - DEPENDENCIES - std_msgs - ) - -################################### -## catkin specific configuration ## -################################### -## The catkin_package macro generates cmake config files for your package -## Declare things to be passed to dependent projects -## INCLUDE_DIRS: uncomment this if you package contains header files -## LIBRARIES: libraries you create in this project that dependent projects also need -## CATKIN_DEPENDS: catkin_packages dependent projects also need -## DEPENDS: system dependencies of this project that dependent projects also need -catkin_package( - INCLUDE_DIRS include - LIBRARIES mementar_lib - CATKIN_DEPENDS roscpp rospy std_msgs ontologenius - DEPENDS OpenCV -) - -########### -## Build ## -########### - -## Specify additional locations of header files -## Your package locations should be listed before other locations -include_directories( - include include/mementar/API - ${catkin_INCLUDE_DIRS} -) - -############################## -## Declare a C++ library -############################## -############################## -## ARCHIVING & COMPRESSION -############################## - -############################## -## EVENTS -############################## - -add_library(mementar_events_lib - src/core/Occasions/Subscription.cpp - src/core/Occasions/OccasionsManager.cpp -) -target_link_libraries(mementar_events_lib ${catkin_LIBRARIES}) -add_dependencies(mementar_events_lib ${catkin_EXPORTED_TARGETS} mementar_gencpp) - -############################## -## CORE -############################## -add_library(mementar_compression_lib - src/core/LtManagement/archiving_compressing/binaryManagement/BitFileGenerator.cpp - src/core/LtManagement/archiving_compressing/binaryManagement/BitFileGetter.cpp - src/core/LtManagement/archiving_compressing/compressing/LzCompress.cpp - src/core/LtManagement/archiving_compressing/compressing/LzUncompress.cpp - src/core/LtManagement/archiving_compressing/compressing/Huffman.cpp - src/core/LtManagement/archiving_compressing/archiving/Header.cpp - src/core/LtManagement/archiving_compressing/archiving/Archive.cpp -) - -add_library(mementar_memGraphs_lib - src/core/memGraphs/Branchs/ValuedNode.cpp - src/core/memGraphs/Branchs/types/Action.cpp - src/core/memGraphs/Branchs/types/Fact.cpp - src/core/memGraphs/Branchs/types/SoftPoint.cpp - src/core/memGraphs/Branchs/types/Triplet.cpp - src/core/memGraphs/Graphs/ActionGraph.cpp - src/core/memGraphs/Graphs/FactGraph.cpp -) - -add_library(mementar_lt_lib - src/core/LtManagement/EpisodicTree/CompressedLeaf.cpp - src/core/LtManagement/EpisodicTree/CompressedLeafNode.cpp - src/core/LtManagement/EpisodicTree/Context.cpp - src/core/LtManagement/EpisodicTree/CompressedLeafSession.cpp - src/core/LtManagement/EpisodicTree/CompressedLeafNodeSession.cpp - src/core/LtManagement/EpisodicTree/ArchivedLeaf.cpp - src/core/LtManagement/EpisodicTree/ArchivedLeafNode.cpp -) -target_link_libraries(mementar_lt_lib - mementar_compression_lib - mementar_memGraphs_lib - pthread -) - -add_library(mementar_core_lib - src/core/feeder/FeedStorage.cpp - src/core/feeder/Feeder.cpp - src/core/Parametrization/Configuration.cpp -) -target_link_libraries(mementar_core_lib mementar_lt_lib) -target_link_libraries(mementar_core_lib ${catkin_LIBRARIES}) -add_dependencies(mementar_core_lib ${catkin_EXPORTED_TARGETS}) - -############################## -## DRAWER -############################## - -add_library(mementar_drawer_lib - src/graphical/timeline/ActionReader.cpp - src/graphical/timeline/FactReader.cpp - src/graphical/timeline/TimelineDrawer.cpp -) -target_include_directories(mementar_drawer_lib -PUBLIC - ${OpenCV_INCLUDE_DIRS} -) -target_link_libraries(mementar_drawer_lib - mementar_memGraphs_lib - ${OpenCV_LIBS} -) - -############################## -## API -############################## - -add_library(mementar_lib - src/API/ActionsPublisher.cpp - src/API/ActionsSubscriber.cpp - src/API/TimelineManipulator.cpp - src/API/TimelinesManipulator.cpp - src/API/clients/ManagerClient.cpp - src/API/clients/ClientBase.cpp - src/API/OccasionsPublisher.cpp - src/API/OccasionsSubscriber.cpp -) -target_link_libraries(mementar_lib ${catkin_LIBRARIES}) -add_dependencies(mementar_lib ${catkin_EXPORTED_TARGETS} mementar_gencpp) - -############################## -## INTERFACE -############################## - -add_library(mementar_interface - src/RosInterface.cpp -) -target_link_libraries(mementar_interface mementar_core_lib mementar_events_lib mementar_drawer_lib) -target_link_libraries(mementar_interface ${catkin_LIBRARIES}) -add_dependencies(mementar_interface ${catkin_EXPORTED_TARGETS} mementar_gencpp) - -############################## -## Declare a C++ executable -## With catkin_make all packages are built within a single CMake context -## The recommended prefix ensures that target names across packages don't collide -############################## - -add_executable(mementar src/nodes/mementar.cpp) -target_link_libraries(mementar mementar_interface) -target_link_libraries(mementar ${catkin_LIBRARIES}) -add_dependencies(mementar ${catkin_EXPORTED_TARGETS}) - -add_executable(mementar_multi src/nodes/mementar_multi.cpp) -target_link_libraries(mementar_multi mementar_interface) -target_link_libraries(mementar_multi ${catkin_LIBRARIES}) -add_dependencies(mementar_multi ${catkin_EXPORTED_TARGETS}) - -add_executable(mementar_timeline src/graphical/timeline/main.cpp) -target_link_libraries(mementar_timeline mementar_core_lib mementar_drawer_lib) -target_link_libraries(mementar_timeline ${catkin_LIBRARIES}) -add_dependencies(mementar_timeline ${catkin_EXPORTED_TARGETS}) - -############################## -## Test executables -############################## - -add_executable(config src/test/config.cpp) -target_link_libraries(config ${catkin_LIBRARIES}) -target_link_libraries(config mementar_interface) - -add_executable(event_sub_pub src/test/occasions_sub_pub.cpp) -target_link_libraries(event_sub_pub ${catkin_LIBRARIES}) -target_link_libraries(event_sub_pub mementar_lib) - -add_executable(graphs src/test/graphs.cpp) -target_link_libraries(graphs ${catkin_LIBRARIES}) -target_link_libraries(graphs mementar_memGraphs_lib) - - -#add_executable(eventLink src/test/EventLink.cpp) -#target_link_libraries(eventLink mementar_lt_lib) - -############################################################################## -# Qt Environment -############################################################################## - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(CMAKE_AUTOMOC ON) - -############################################################################## -# Sections -############################################################################## - -file(GLOB QT_FORMS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ui/*.ui) -file(GLOB QT_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} resources/*.qrc) - -QT5_ADD_RESOURCES(QT_RESOURCES_CPP ${QT_RESOURCES}) -QT5_WRAP_UI(QT_FORMS_HPP ${QT_FORMS}) - -add_definitions( -std=c++11 -fPIC) - -############################################################################## -# Sources -############################################################################## - -set( QT_SOURCES - src/graphical/mementarGUI/main.cpp - src/graphical/mementarGUI/mementargui.cpp - src/graphical/mementarGUI/DarkStyle.cpp - src/graphical/mementarGUI/QPushButtonExtended.cpp - src/graphical/mementarGUI/QCheckBoxExtended.cpp - src/graphical/mementarGUI/QLineEditExtended.cpp - - include/mementar/graphical/mementarGUI/mementargui.h - include/mementar/graphical/mementarGUI/DarkStyle.h - include/mementar/graphical/mementarGUI/QPushButtonExtended.h - include/mementar/graphical/mementarGUI/QCheckBoxExtended.h - include/mementar/graphical/mementarGUI/QLineEditExtended.h -) -############################################################################## -# Binaries -############################################################################## - -add_executable(mementarGUI ${QT_SOURCES} ${QT_RESOURCES_CPP} ${QT_FORMS_HPP} ${QT_MOC_HPP}) -target_include_directories(mementarGUI - PRIVATE - ${catkin_INCLUDE_DIRS} -) -add_dependencies(mementarGUI mementar_gencpp) -target_link_libraries(mementarGUI - ${catkin_LIBRARIES} - Qt5::Core - Qt5::Widgets - Qt5::PrintSupport -) -install(TARGETS mementarGUI RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) - -############################## -## Install -############################## - -install(TARGETS - mementar_lib - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} -) - -install(DIRECTORY include/${PROJECT_NAME}/ - DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} - FILES_MATCHING PATTERN "*.h" - PATTERN ".svn" EXCLUDE -) - -############################## -## Tests -############################## - -if(CATKIN_ENABLE_TESTING) - find_package(rostest REQUIRED) - - add_rostest_gtest(mementar_fact_pub_sub_tester test/fact_pub_sub.test src/test/CI/fact_pub_sub.cpp) - target_link_libraries(mementar_fact_pub_sub_tester mementar_lib ontologenius_lib) - - add_rostest_gtest(mementar_action_pub_sub_tester test/action_pub_sub.test src/test/CI/action_pub_sub.cpp) - target_link_libraries(mementar_action_pub_sub_tester mementar_lib ontologenius_lib) - +if($ENV{ROS_VERSION} STREQUAL "1") + include(cmake/BuildROS1.cmake) +elseif($ENV{ROS_VERSION} STREQUAL "2") + include(cmake/BuildROS2.cmake) endif() diff --git a/README.md b/README.md index 01593c2..9c43a38 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ ``` G. Sarthou, mementar,” https://github.com/sarthou/mementar, -LAAS-CNRS, Toulouse, 2018 – 2020. +LAAS-CNRS, Toulouse, 2018 – 2024. ``` [Release-Url]: https://github.com/sarthou/mementar/releases -[Release-image]: http://img.shields.io/badge/release-v0.0.3-1eb0fc.svg +[Release-image]: http://img.shields.io/badge/release-v0.0.4-1eb0fc.svg diff --git a/cmake/BuildCommon.cmake b/cmake/BuildCommon.cmake new file mode 100644 index 0000000..a93c5b3 --- /dev/null +++ b/cmake/BuildCommon.cmake @@ -0,0 +1,186 @@ +# This file should only be included by ROS1.cmake or ROS2.cmake which define the following functions: +# - meme_add_library +# - meme_add_ros_library (target linked with ROS-related deps) +# - meme_add_ros_executable (target linked with ROS-related deps) + +include(cmake/Sanitizers.cmake) + +# ############################################### +# # Declare ROS messages, services and actions ## +# ############################################### +meme_queue_messages_generation( + MementarAction.msg + MementarExplanation.msg + MementarOccasion.msg + MementarTimestamp.msg + StampedFact.msg + StampedString.msg) + +meme_queue_services_generation( + MementarOccasionSubscription.srv + MementarOccasionUnsubscription.srv + MementarService.srv) + +meme_generate_interfaces() + +# ################################## +# # Compatibility layer ## +# ################################## +meme_add_ros_library(mementar_compat + src/compat/ros.cpp) + +# ################################## +meme_add_ros_library(mementar_events_lib + src/core/Occasions/Subscription.cpp + src/core/Occasions/OccasionsManager.cpp) + +# ################################## +meme_add_ros_library(mementar_compression_lib + src/core/LtManagement/archiving_compressing/binaryManagement/BitFileGenerator.cpp + src/core/LtManagement/archiving_compressing/binaryManagement/BitFileGetter.cpp + src/core/LtManagement/archiving_compressing/compressing/LzCompress.cpp + src/core/LtManagement/archiving_compressing/compressing/LzUncompress.cpp + src/core/LtManagement/archiving_compressing/compressing/Huffman.cpp + src/core/LtManagement/archiving_compressing/archiving/Header.cpp + src/core/LtManagement/archiving_compressing/archiving/Archive.cpp) + +meme_add_ros_library(mementar_memGraphs_lib + src/core/memGraphs/Branchs/ValuedNode.cpp + src/core/memGraphs/Branchs/types/Action.cpp + src/core/memGraphs/Branchs/types/Fact.cpp + src/core/memGraphs/Branchs/types/SoftPoint.cpp + src/core/memGraphs/Branchs/types/Triplet.cpp + src/core/memGraphs/Graphs/ActionGraph.cpp + src/core/memGraphs/Graphs/FactGraph.cpp) + +meme_add_ros_library(mementar_lt_lib + src/core/LtManagement/EpisodicTree/CompressedLeaf.cpp + src/core/LtManagement/EpisodicTree/CompressedLeafNode.cpp + src/core/LtManagement/EpisodicTree/Context.cpp + src/core/LtManagement/EpisodicTree/CompressedLeafSession.cpp + src/core/LtManagement/EpisodicTree/CompressedLeafNodeSession.cpp + src/core/LtManagement/EpisodicTree/ArchivedLeaf.cpp + src/core/LtManagement/EpisodicTree/ArchivedLeafNode.cpp) + +target_link_libraries(mementar_lt_lib + PUBLIC + mementar_compression_lib + mementar_memGraphs_lib + pthread) + +meme_add_ros_library(mementar_core_lib + src/core/feeder/FeedStorage.cpp + src/core/feeder/Feeder.cpp + src/core/Parametrization/Configuration.cpp) + +target_link_libraries(mementar_core_lib + PUBLIC + mementar_lt_lib) + +# ################################## +meme_add_ros_library(mementar_drawer_lib + src/graphical/timeline/ActionReader.cpp + src/graphical/timeline/FactReader.cpp + src/graphical/timeline/TimelineDrawer.cpp) + +target_include_directories(mementar_drawer_lib + PUBLIC + ${OpenCV_INCLUDE_DIRS}) + +target_link_libraries(mementar_drawer_lib + PUBLIC + ${OpenCV_LIBS} + mementar_memGraphs_lib) + +# ################################## +meme_add_ros_library(mementar_lib + src/API/mementar/ActionsPublisher.cpp + src/API/mementar/ActionsSubscriber.cpp + src/API/mementar/TimelineManipulator.cpp + src/API/mementar/TimelinesManipulator.cpp + src/API/mementar/clients/ActionClient.cpp + src/API/mementar/clients/ClientBase.cpp + src/API/mementar/clients/FactClient.cpp + src/API/mementar/clients/ManagerClient.cpp + src/API/mementar/clients/InstanceManagerClient.cpp + src/API/mementar/OccasionsPublisher.cpp + src/API/mementar/OccasionsSubscriber.cpp) +target_include_directories(mementar_lib PUBLIC $ + $) +target_link_libraries(mementar_lib PUBLIC mementar_compat +) + +# ################################## +meme_add_ros_library(mementar_interface + src/RosInterface.cpp + src/graphical/timeline/CsvSaver.cpp) + +target_link_libraries(mementar_interface + PUBLIC + mementar_core_lib + mementar_events_lib + mementar_drawer_lib) + +# ################################## +meme_add_ros_executable(mementar_single src/nodes/mementar_single.cpp) +target_link_libraries(mementar_single PUBLIC mementar_interface mementar_compat) + +meme_add_ros_executable(mementar_multi src/nodes/mementar_multi.cpp) +target_link_libraries(mementar_multi PUBLIC mementar_interface mementar_compat) + +meme_add_ros_executable(mementar_timeline src/graphical/timeline/main.cpp) +target_link_libraries(mementar_timeline PUBLIC mementar_core_lib mementar_drawer_lib) + +# ################################## + +# ############################################################################# +# Qt Environment +# ############################################################################# +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) + +# ############################################################################# +# Sections +# ############################################################################# +file(GLOB QT_FORMS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ui/*.ui) +file(GLOB QT_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} resources/*.qrc) + +QT5_ADD_RESOURCES(QT_RESOURCES_CPP ${QT_RESOURCES}) +QT5_WRAP_UI(QT_FORMS_HPP ${QT_FORMS}) + +# ############################################################################# +# Sources +# ############################################################################# +set(QT_SOURCES + src/graphical/mementarGUI/main.cpp + src/graphical/mementarGUI/mementargui.cpp + src/graphical/mementarGUI/DarkStyle.cpp + src/graphical/mementarGUI/QPushButtonExtended.cpp + src/graphical/mementarGUI/QCheckBoxExtended.cpp + src/graphical/mementarGUI/QLineEditExtended.cpp + include/mementar/graphical/mementarGUI/mementargui.h + include/mementar/graphical/mementarGUI/DarkStyle.h + include/mementar/graphical/mementarGUI/QPushButtonExtended.h + include/mementar/graphical/mementarGUI/QCheckBoxExtended.h + include/mementar/graphical/mementarGUI/QLineEditExtended.h) + +# ############################################################################# +# Binaries +# ############################################################################# +add_executable(mementarGUI ${QT_SOURCES} ${QT_RESOURCES_CPP} ${QT_FORMS_HPP} ${QT_MOC_HPP}) +set_target_properties(mementarGUI PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON) +target_compile_options(mementarGUI PUBLIC -DMEME_ROS_VERSION=$ENV{ROS_VERSION}) +target_link_libraries(mementarGUI + mementar_lib + Qt5::Core + Qt5::Widgets + Qt5::PrintSupport) +target_include_directories(mementarGUI PUBLIC include) + +meme_install_executables( + mementar_single + mementar_multi + mementar_timeline + mementarGUI) + +# ################################## \ No newline at end of file diff --git a/cmake/BuildROS1.cmake b/cmake/BuildROS1.cmake new file mode 100644 index 0000000..b1fa0c0 --- /dev/null +++ b/cmake/BuildROS1.cmake @@ -0,0 +1,173 @@ +# ############################################### +# # Find macros and libraries ## +# ############################################### + +find_package(catkin REQUIRED COMPONENTS + roscpp + + # rospy + std_msgs + genmsg + message_generation + pluginlib + ontologenius +) + +find_package(cmake_modules REQUIRED) +find_package(pluginlib REQUIRED) + +# ################################## +# # ROS specific configuration ## +# ################################## +macro(meme_queue_messages_generation) + add_message_files(FILES ${ARGN}) +endmacro(meme_queue_messages_generation) + +macro(meme_queue_services_generation) + add_service_files(FILES ${ARGN}) +endmacro(meme_queue_services_generation) + +macro(meme_generate_interfaces) + generate_messages( + DEPENDENCIES + std_msgs + ontologenius + ) +endmacro(meme_generate_interfaces) + +# ################################## +# # Build ## +# ################################## +function(meme_add_generic TARGET) + set_target_properties(${TARGET} + PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON) + + target_compile_options(${TARGET} + PRIVATE + -Wall -Wextra) + + target_enable_sanitizers(${TARGET}) +endfunction(meme_add_generic) + +function(meme_add_ros_generic TARGET) + target_link_libraries(${TARGET} PUBLIC ${catkin_LIBRARIES}) + target_include_directories(${TARGET} PUBLIC ${catkin_INCLUDE_DIRS}) + add_dependencies(${TARGET} ${catkin_EXPORTED_TARGETS} mementar_gencpp) + + target_compile_definitions(${TARGET} PUBLIC MEME_ROS_VERSION=$ENV{ROS_VERSION}) + target_compile_definitions(${TARGET} PUBLIC ONTO_ROS_VERSION=$ENV{ROS_VERSION}) + meme_add_generic(${TARGET}) +endfunction(meme_add_ros_generic) + +function(meme_add_library TARGET) + if(NOT TARGET) + message(FATAL_ERROR "Expected the target name as first argument") + endif() + + if(NOT ARGN) + message(FATAL_ERROR "Expected source file list after target name") + endif() + + add_library(${TARGET} ${ARGN}) + + target_include_directories(${TARGET} + PUBLIC + $ + $) + + meme_add_generic(${TARGET}) +endfunction(meme_add_library) + +function(meme_add_ros_library TARGET) + if(NOT TARGET) + message(FATAL_ERROR "Expected the target name as first argument") + endif() + + if(NOT ARGN) + message(FATAL_ERROR "Expected source file list after target name") + endif() + + add_library(${TARGET} ${ARGN}) + + target_include_directories(${TARGET} + PUBLIC + $ + $) + + # ament_export_libraries(${TARGET}) + meme_add_ros_generic(${TARGET}) +endfunction(meme_add_ros_library) + +function(meme_add_ros_executable TARGET) + if(NOT TARGET) + message(FATAL_ERROR "Expected the target name as first argument") + endif() + + if(NOT ARGN) + message(FATAL_ERROR "Expected source file list after target name") + endif() + + add_executable(${TARGET} ${ARGN}) + target_include_directories(${TARGET} PUBLIC include) + meme_add_ros_generic(${TARGET}) +endfunction(meme_add_ros_executable) + +function(meme_install_libs) + install(TARGETS ${ARGN} + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +endfunction(meme_install_libs) + +function(meme_install_executables) + install(TARGETS ${ARGN} + RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) +endfunction(meme_install_executables) + +include(cmake/BuildCommon.cmake) + +catkin_package( + INCLUDE_DIRS include + LIBRARIES mementar_lib + CATKIN_DEPENDS roscpp std_msgs ontologenius + DEPENDS OpenCV +) + +# ############################# +# # Test executables +# ############################# +add_executable(config src/test/config.cpp) +target_link_libraries(config ${catkin_LIBRARIES}) +target_link_libraries(config mementar_interface) + +add_executable(event_sub_pub src/test/occasions_sub_pub.cpp) +target_link_libraries(event_sub_pub ${catkin_LIBRARIES}) +target_link_libraries(event_sub_pub mementar_lib) + +add_executable(graphs src/test/graphs.cpp) +target_link_libraries(graphs ${catkin_LIBRARIES}) +target_link_libraries(graphs mementar_memGraphs_lib) + +# ############################# +# # Install +# ############################# +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} + FILES_MATCHING PATTERN "*.h" + PATTERN ".svn" EXCLUDE) + +# ############################# +# # Tests +# ############################# +if(CATKIN_ENABLE_TESTING) + find_package(rostest REQUIRED) + + add_rostest_gtest(mementar_fact_pub_sub_tester test/fact_pub_sub.test src/test/CI/fact_pub_sub.cpp) + target_link_libraries(mementar_fact_pub_sub_tester mementar_lib ontologenius_lib) + + add_rostest_gtest(mementar_action_pub_sub_tester test/action_pub_sub.test src/test/CI/action_pub_sub.cpp) + target_link_libraries(mementar_action_pub_sub_tester mementar_lib ontologenius_lib) +endif() \ No newline at end of file diff --git a/cmake/BuildROS2.cmake b/cmake/BuildROS2.cmake new file mode 100644 index 0000000..66f5443 --- /dev/null +++ b/cmake/BuildROS2.cmake @@ -0,0 +1,156 @@ +################################################ +## Find macros and libraries ## +################################################ + +find_package(ament_cmake REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(rclcpp REQUIRED) +find_package(pluginlib REQUIRED) +find_package(TinyXML2 REQUIRED) +find_package(ontologenius REQUIRED) +find_package(ament_cmake_python REQUIRED) + +################################### +## ROS specific configuration ## +################################### + +set(TMP_INTERFACES "mementar") + +macro(meme_queue_messages_generation) + foreach (MSG ${ARGN}) + list(APPEND TMP_INTERFACES "msg/${MSG}") + endforeach () +endmacro(meme_queue_messages_generation) + +macro(meme_queue_services_generation) + foreach (SRV ${ARGN}) + list(APPEND TMP_INTERFACES "srv/${SRV}") + endforeach() +endmacro(meme_queue_services_generation) + +macro(meme_generate_interfaces) + list(APPEND TMP_INTERFACES DEPENDENCIES builtin_interfaces std_msgs ontologenius) + + rosidl_generate_interfaces(${TMP_INTERFACES}) + + ament_export_dependencies(rosidl_default_runtime pluginlib) + rosidl_get_typesupport_target(cpp_typesupport_target ${PROJECT_NAME} rosidl_typesupport_cpp) +endmacro(meme_generate_interfaces) + +################################### +## Build ## +################################### + +function(meme_add_generic TARGET) + set_target_properties(${TARGET} + PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON) + + target_compile_options(${TARGET} + PRIVATE + -Wall -Wextra) + + target_enable_sanitizers(${TARGET}) +endfunction(meme_add_generic) + +function(meme_add_ros_generic TARGET) + ament_target_dependencies(${TARGET} + PUBLIC + rclcpp + pluginlib + builtin_interfaces + std_msgs + ontologenius) + + target_link_libraries(${TARGET} PUBLIC + ontologenius::ontologenius_lib + # todo: I feel like I shouldn't be doing this ^ + ${cpp_typesupport_target}) + + target_compile_definitions(${TARGET} PUBLIC MEME_ROS_VERSION=$ENV{ROS_VERSION}) + target_compile_definitions(${TARGET} PUBLIC ONTO_ROS_VERSION=$ENV{ROS_VERSION}) + meme_add_generic(${TARGET}) +endfunction(meme_add_ros_generic) + +function(meme_add_library TARGET) + if(NOT TARGET) + message(FATAL_ERROR "Expected the target name as first argument") + endif() + + if(NOT ARGN) + message(FATAL_ERROR "Expected source file list after target name") + endif() + + add_library(${TARGET} ${ARGN}) + + target_include_directories(${TARGET} + PUBLIC + $ + $) + + meme_add_generic(${TARGET}) +endfunction(meme_add_library) + +function(meme_add_ros_library TARGET) + if(NOT TARGET) + message(FATAL_ERROR "Expected the target name as first argument") + endif() + + if(NOT ARGN) + message(FATAL_ERROR "Expected source file list after target name") + endif() + + add_library(${TARGET} ${ARGN}) + + target_include_directories(${TARGET} + PUBLIC + $ + $) + + ament_export_libraries(${TARGET}) + meme_add_ros_generic(${TARGET}) +endfunction(meme_add_ros_library) + +function(meme_add_ros_executable TARGET) + if(NOT TARGET) + message(FATAL_ERROR "Expected the target name as first argument") + endif() + + if(NOT ARGN) + message(FATAL_ERROR "Expected source file list after target name") + endif() + + add_executable(${TARGET} ${ARGN}) + target_include_directories(${TARGET} PUBLIC include) + meme_add_ros_generic(${TARGET}) +endfunction(meme_add_ros_executable) + +function(meme_install_libs) + install( + TARGETS ${ARGN} + EXPORT mementar + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + # INCLUDES DESTINATION include + DESTINATION lib/${PROJECT_NAME}) +endfunction(meme_install_libs) + +function(meme_install_executables) + install( + TARGETS ${ARGN} + DESTINATION lib/${PROJECT_NAME}) +endfunction(meme_install_executables) + +include(cmake/BuildCommon.cmake) + +install(DIRECTORY launch/ros2/launch DESTINATION share/${PROJECT_NAME}/) +install(DIRECTORY include/ DESTINATION include) + +install(DIRECTORY files DESTINATION share/${PROJECT_NAME}/) +install(DIRECTORY docs DESTINATION share/${PROJECT_NAME}/) +# install(DIRECTORY configuration DESTINATION share/${PROJECT_NAME}/) + +# ament_export_targets(mementar) +ament_package() \ No newline at end of file diff --git a/cmake/Sanitizers.cmake b/cmake/Sanitizers.cmake new file mode 100644 index 0000000..3ac831a --- /dev/null +++ b/cmake/Sanitizers.cmake @@ -0,0 +1,38 @@ +function(join VALUES GLUE OUTPUT) + string (REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}") + string (REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping + set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE) +endfunction() + +function(target_enable_sanitizers TARGET_NAME) + + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(SUPPORTED_SANITIZERS "address" "memory" "undefined" "thread") + else() + set(SUPPORTED_SANITIZERS "") + message(VERBOSE "Sanitizers not supported for compiler of type ${CMAKE_CXX_COMPILER_ID}") + endif() + + if (NOT TARGET ${TARGET_NAME}) + message(FATAL_ERROR "${TARGET_NAME} is not a valid target") + endif() + + set(SANITIZERS "") + + foreach(sanitizer IN LISTS SUPPORTED_SANITIZERS) + option(${TARGET_NAME}_SANITIZE_${sanitizer} "Enable sanitizer '${sanitizer}' for target ${TARGET_NAME}" OFF) + if (${TARGET_NAME}_SANITIZE_${sanitizer}) + list(APPEND SANITIZERS "${sanitizer}") + endif() + endforeach() + + join("${SANITIZERS}" "," LIST_OF_SANITIZERS) + + if(LIST_OF_SANITIZERS) + if(NOT "${LIST_OF_SANITIZERS}" STREQUAL "") + target_compile_options(${TARGET_NAME} PUBLIC -fsanitize=${LIST_OF_SANITIZERS}) + target_link_libraries(${TARGET_NAME} PUBLIC -fsanitize=${LIST_OF_SANITIZERS}) + endif() + endif() + +endfunction() \ No newline at end of file diff --git a/docs/Download.html b/docs/Download.html index 4ea6a16..47633ab 100644 --- a/docs/Download.html +++ b/docs/Download.html @@ -1,29 +1,34 @@ - Download | Mementar 0.0.3 + Download | Mementar 0.0.4 - + - + \ No newline at end of file diff --git a/docs/InstallMementar.html b/docs/InstallMementarROS1.html similarity index 61% rename from docs/InstallMementar.html rename to docs/InstallMementarROS1.html index 4edaa12..fe06eaa 100644 --- a/docs/InstallMementar.html +++ b/docs/InstallMementarROS1.html @@ -1,29 +1,34 @@ - Install | Mementar 0.0.3 + Install ROS1 | Mementar 0.0.4 - +
-

Install Mementar

-

Since Mementar is a ROS package, make sure that ROS is installed on your platform. Mementar is fully supported and maintained by ROS Kinetic Kame and ROS Melodic Morenia. Desktop ROS configuration is not required for use of mementar.

+

Install Mementar ROS1

+

Since Mementar is a ROS package, make sure that ROS is installed on your platform. Mementar is fully + supported and maintained on ROS Noetic + Ninjemys. + Desktop ROS configuration is not required for use of mementar.

-

Mementar is strongly linked to the Ontologenius software to provide a semantic abstraction of the knowledge it stores.

+

Mementar is strongly linked to the Ontologenius software to provide a semantic abstraction of the knowledge + it stores.

Clone the package on your catkin workspace:

-

cd ~/catkin_ws/src/
git clone https://github.com/sarthou/mementar.git
git clone https://github.com/sarthou/ontologenius.git
cd ..
catkin_make

+

cd ~/catkin_ws/src/

git clone https://github.com/sarthou/ontologenius.git +
git clone https://github.com/sarthou/mementar.git

cd ..

catkin_make +

Troubles

If you have the following error :

-

Could not find a package configuration file provided by "qt_build" with any of the following names:

qt_buildConfig.cmake
qt_build-config.cmake

+

Could not find a package configuration file provided by "qt_build" with any of the following names:
+
qt_buildConfig.cmake +
qt_build-config.cmake +

You just have to install qt-build:

@@ -117,10 +137,10 @@

Test Mementar installation

Brought to you by:

- + \ No newline at end of file diff --git a/docs/InstallMementarROS2.html b/docs/InstallMementarROS2.html new file mode 100644 index 0000000..d624e02 --- /dev/null +++ b/docs/InstallMementarROS2.html @@ -0,0 +1,141 @@ + + + + Install ROS2 | Mementar 0.0.4 + + + + + + + + + + + +
+ + + +
+ + +
+

Install Mementar ROS2

+

Since Mementar is a ROS package, make sure that ROS is installed on your platform. Mementar is fully + supported and maintained on ROS + Humble. + Desktop ROS configuration is not required for use of mementar.

+ +

Mementar is strongly linked to the Ontologenius software to provide a semantic abstraction of the knowledge + it stores.

+ +

First you have to install dependency:

+
+

sudo apt install ros-cmake-modules

+
+ +

Clone the package on your ros2 workspace:

+
+

cd ~/ros2_ws/src/
+
git clone https://github.com/sarthou/ontologenius.git
+
git clone https://github.com/sarthou/mementar.git
+
cd ..
+
colcon build --symlink-install

+
+ +

Test Mementar installation

+

Just run colcon test to check if all the features work well on your platform:

+
+

colcon test --packages-select mementar

+
+

Some asynchronous mechanisms are used. A computer with little computing power can therefore + affect some tests due to a slow response time.

+ + + +
+
+ +
+ + +
+
+

+ Brought to you by: + +

+
+
+ + \ No newline at end of file diff --git a/docs/SetUp.html b/docs/SetUp.html index ce4825e..52b22a0 100644 --- a/docs/SetUp.html +++ b/docs/SetUp.html @@ -1,29 +1,36 @@ - Set up | Mementar 0.0.3 + Set up | Mementar 0.0.4 + - + +
@@ -49,7 +55,9 @@

Mementar 0.0.3

Getting Start

@@ -59,8 +67,13 @@

Getting Start

All C++ Classes

    +
  • ActionClient
  • +
  • ActionsPublisher
  • +
  • ActionsSubscriber
  • ClientBase
  • Fact
  • +
  • FactClient
  • +
  • InstanceManagerClient
  • ManagerClient
  • OccasionsPublisher
  • OccasionsSubscriber
  • @@ -74,79 +87,255 @@

    All C++ Classes

    Set Up Your Environnement

    To set up your environment, we will first create a new package that represents your application.

    -
    -
    cd ~/catkin_ws/src
    -

    -
    catkin_create_pkg my_pkg roscpp mementar
    + +
    +
    + + + +
    + +
    +
    +
    +
    cd ~/catkin_ws/src
    +

    +
    catkin_create_pkg <my_pkg> roscpp mementar
    +
    +
    +
    + + + + +

    For the moment, the API only exist for the C ++ language.

    -

    The package.xml in format 2 should look like this:

    -
    -
    <package>
    -
    ...
    -
    <buildtool_depend>catkin</buildtool_depend>
    -
    <build_depend>mementar</build_depend>
    -
    <build_depend>roscpp</build_depend>
    -
    <build_export_depend>mementar</build_export_depend>
    -
    <build_export_depend>roscpp</build_export_depend>
    -
    <exec_depend>mementar</exec_depend>
    -
    <exec_depend>roscpp</exec_depend>
    -
    ...
    -
    </package>
    -
    +

    The package.xml in format 3 should look like as follow and does not need to be modified:

    -

    The CMakeLists.txt should look like this:

    -
    -
    ...
    -
    find_package(catkin REQUIRED COMPONENTS
    -
    mementar
    -
    roscpp
    -
    )
    -
    ...
    -
    catkin_package(
    -
    # INCLUDE_DIRS include
    -
    # LIBRARIES my_pkg
    -
    # CATKIN_DEPENDS mementar roscpp
    -
    # DEPENDS system_lib
    -
    )
    -
    ...
    -
    # include
    -
    ${catkin_INCLUDE_DIRS}
    -
    )
    -
    ...
    +
    +
    + + + +
    + +
    +
    +
    +
    <package format="3">
    +
    <name>my_pkg</name>
    +
    ...
    +
    <buildtool_depend>catkin</buildtool_depend>
    +
    <depend>mementar</depend>
    +
    <depend>rospy</depend>
    +
    <depend>roscpp</depend>
    +
    ...
    +
    </package>
    +
    +
    +
    + + + + +
    -

    The package.xml do not need to be modified. For the CMakeLists.txt, we will required a minimal version (optional) and include ontologenius API.

    -
    -
    find_package(mementar 0.0.3 REQUIRED)
    -
    ...
    -
    catkin_package(
    -
    # INCLUDE_DIRS include
    -
    # LIBRARIES my_pkg
    -
    CATKIN_DEPENDS mementar
    -
    # DEPENDS system_lib
    -
    )
    -
    ...
    -
    # include
    -
    ${catkin_INCLUDE_DIRS}
    -
    ${mementar_INCLUDE_DIRS}
    -
    )
    -
    ...
    + +
    +
    + + + +
    + +
    +
    +

    The CMakeLists.txt should look like this:

    +
    +
    ...
    +
    find_package(catkin REQUIRED COMPONENTS
    +
    mementar
    +
    roscpp
    +
    )
    +
    ...
    +
    catkin_package(
    +
    # INCLUDE_DIRS include
    +
    # LIBRARIES my_pkg
    +
    # CATKIN_DEPENDS mementar roscpp
    +
    # DEPENDS system_lib
    +
    )
    +
    ...
    +
    # include
    +
    ${catkin_INCLUDE_DIRS}
    +
    )
    +
    ...
    +
    + +

    We will require a minimal version of Mementar (optional) and include the mementar API.

    + +
    +
    find_package(mementar 0.0.4 REQUIRED)
    +
    ...
    +
    catkin_package(
    +
    # INCLUDE_DIRS include
    +
    # LIBRARIES my_pkg
    +
    CATKIN_DEPENDS mementar
    +
    # DEPENDS system_lib
    +
    )
    +
    ...
    +
    # include
    +
    ${catkin_INCLUDE_DIRS}
    +
    ${mementar_INCLUDE_DIRS}
    +
    )
    +
    ...
    +
    +
    +
    + + + + +

    Create your executable

    -

    Now we can create our executable that will use mementar. Create your main file that we call main.cpp.

    -

    In this part, we will not write our program but we will only configure the CMakeLists.txt file to compile our file by linking it to ontologenius. - To do this, simply add the following two lines:

    -
    -
    add_executable(my_exe src/main.cpp)
    -
    target_link_libraries(my_exe ${catkin_LIBRARIES})
    -
    target_link_libraries(my_exe ${mementar_LIBRARIES})
    -
    +

    Now we can create our executable that will use mementar.

    + +
    +
    + + + +
    + +
    +
    +

    In this part, we will not write our program but we will only configure the CMakeLists.txt file to compile our file by linking it to mementar. + To do this, create your main file that we call main.cpp and simply add the following lines:

    +
    +
    add_executable(my_exe src/main.cpp)
    +
    target_link_libraries(my_exe ${catkin_LIBRARIES})
    +
    target_link_libraries(my_exe ${mementar_LIBRARIES})
    +
    +
    +
    + + + + + +

    You are now ready to write your program!

    -

    To see how to use mementar with its C ++ API, continue with the tutorial.

    +

    To see how to use mementar with its C++ API, continue with the tutorial.

    - + \ No newline at end of file diff --git a/docs/Tutorials.html b/docs/Tutorials.html index 56babfb..8403d55 100644 --- a/docs/Tutorials.html +++ b/docs/Tutorials.html @@ -1,14 +1,15 @@ - Under Construction | Mementar 0.0.3 + Under Construction | Mementar 0.0.4 - - + + @@ -16,16 +17,20 @@

Mementar Documentation

-

Mementar 0.0.3

@@ -51,7 +55,9 @@

Mementar 0.0.3

Getting Start

@@ -61,8 +67,13 @@

Getting Start

All C++ Classes

@@ -90,10 +101,10 @@

Sorry, we're doing some work on the site

Brought to you by:

- + \ No newline at end of file diff --git a/docs/construction.html b/docs/construction.html index 56babfb..8403d55 100644 --- a/docs/construction.html +++ b/docs/construction.html @@ -1,14 +1,15 @@ - Under Construction | Mementar 0.0.3 + Under Construction | Mementar 0.0.4 - - + + @@ -16,16 +17,20 @@
@@ -51,7 +55,9 @@

Mementar 0.0.3

Getting Start

@@ -61,8 +67,13 @@

Getting Start

All C++ Classes

@@ -90,10 +101,10 @@

Sorry, we're doing some work on the site

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/ActionClient.html b/docs/cpp_API/ActionClient.html new file mode 100644 index 0000000..8f813b4 --- /dev/null +++ b/docs/cpp_API/ActionClient.html @@ -0,0 +1,280 @@ + + + + ActionClient Class | Mementar 0.0.4 + + + + + + + + + + +
+ + + +
+ + +
+

ActionClient Class

+

The ActionClient class provides a ROS service abstraction for actions exploration. More...

+
+ + + + + + + + + + + + + + + +
Header: #include + "mementar/clients/ActionClient.h"
Inherits: ClientBase
Namespace: mementar
+
+ + +

Public Functions

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ActionClient(const std::string& name) +
bool exist(const + std::string& action_name)
std::vector<std::string> getPending()
bool isPending(const + std::string& action_name) +
compat::mem_ros::Time getStartStamp(const + std::string& action_name) +
compat::mem_ros::Time getEndStamp(const std::string& action_name) +
compat::mem_ros::Time getDuration(const std::string& action_name) +
std::string getStartFact(const std::string& action_name) +
std::string getEndFact(const + std::string& action_name)
std::vector<std::string> getFactsDuring(const std::string& + action_name) +
+
+ +
+ +
+

Detailed Description

+

The ActionClient class provides an abstraction of mementar actions ROS service.

+

The mementar actions service allows the exploration of actions contained by mementar core.

+

This class is based on ClientBase and so ensure a persistent connection + with mementar/actions service. The persistent connection ensures a minimal response time. A reconnection + logic is implemented in the event that the persistent connection fails.

+
+ +
+

Public Functions Documentation

+ +

ActionClient::ActionClient(const std::string& name = + "")

+

Constructs an action client.

+

Can be used in a multi-timeline mode by specifying the name of the timeline name. For classic use, + name should be defined as "". +

+ +

bool ActionClient::exist(const std::string& action_name) +

+

Returns true if the action action_name exists.

+ +

std::vector<string> + ActionClient::getPending()

+

Returns the list of pending actions.

+ +

bool + ActionClient::isPending(const std::string& + action_name) +

+

Returns true if the action action_name is pending.

+ +

compat::mem_ros::Time ActionClient::getStartStamp(const + std::string& action_name) +

+

Returns the starting time stamp of the action action_name.

+

If the action does not exist the time stamp will be 0.

+ +

compat::mem_ros::Time + ActionClient::getEndStamp(const std::string& + action_name) +

+

Returns the ending time stamp of the action action_name.

+

If the action does not exist or is not yet finished, the time stamp will be 0.

+ +

compat::mem_ros::Time + ActionClient::getDuration(const std::string& + action_name) +

+

Returns the duration of the action action_name.

+

If the action does not exist or is not yet finished, the time stamp will be 0.

+ +

std::string + ActionClient::getStartFact(const std::string& + action_name) +

+

Returns the fact representing the beginning of the action action_name.

+

If the action does not exist the returned string will be empty.

+ +

std::string + ActionClient::getEndFact(const std::string& + action_name) +

+

Returns the fact representing the ending of the action action_name.

+

If the action does not exist or is not yet finished, the returned string will be empty.

+ +

std::vector<std::string> + ActionClient::getFactsDuring(const std::string& + action_name) +

+

Returns the list of fact having took place during the action action_name.

+

Even if the action is pending, all facts having took place since its beginning will be considered.

+ +
+
+
+ +
+
+ + +
+
+

+ Brought to you by: + +

+
+
+ + \ No newline at end of file diff --git a/docs/cpp_API/ActionsPublisher.html b/docs/cpp_API/ActionsPublisher.html new file mode 100644 index 0000000..d870380 --- /dev/null +++ b/docs/cpp_API/ActionsPublisher.html @@ -0,0 +1,251 @@ + + + + ActionsPublisher Class | Mementar 0.0.4 + + + + + + + + + + +
+ + + +
+ + +
+

ActionsPublisher Class

+

The ActionsPublisher class provides an abstraction for mementar action insertion topic. More...

+
+ + + + + + + + + + +
Header: #include + "mementar/ActionsPublisher.h" +
Namespace: mementar +
+
+ + +

Public Functions

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
ActionsPublisher(const + std::string& name = "") +
void insert(const + std::string& name, const + compat::mem_ros::Time& start_stamp = compat::mem_ros::Node::get().currentTime(), const + compat::mem_ros::Time& end_stamp = compat::mem_ros::Time(0)) +
void insert(const + std::string& name, time_t start_stamp, time_t end_stamp = 0) +
void insertEnd(const + std::string& name, const + compat::mem_ros::Time& end_stamp = compat::mem_ros::Node::get().currentTime()) +
void insertEnd(const + std::string& name, time_t end_stamp) +
void registerFeederNotificationCallback(const + std::function<void(const std::string&)>& callback) +
+
+ + +
+

Detailed Description

+

The ActionsPublisher class provides an abstraction for mementar action insertion ROS topic.

+

The insertion process is asynchronous and therefore does not guarantee any response time.

+

In mementar, a fact is a datum that is not linked to a temporal stamp. When a fact occurs at a moment t, it + is called an occasion. An occasion is a particular time or instance of an event. An event occurs on a time + interval. It is thus composed of two occasions, one being the beginning of the event and the other the end. + An event is therefore a change of state of a fact, so that two facts have the same subject and the same + predicate, but the object changes.

+
+ +
+

Public Functions Documentation

+ +

ActionsPublisher::ActionsPublisher(const std::string& name = "") +

+

Constructs an ActionsPublisher.

+

Can be used in a multi-process mode by specifying the name of the mementar instance name. For + classic use, name should be defined as "".

+ +

void + ActionsPublisher::insert(const std::string& + name, + const compat::mem_ros::Time& start_stamp = + mem_ros::Node::get().currentTime(), + const compat::mem_ros::Time& end_stamp = + compat::mem_ros::Time(0)) +

+

Inserts the action defined in its name name starting at the time stamp start_stamp + and ending at end_stamp.

+

If the start_stamp parameter is not set, it will be set at the current time.

+

If the end_stamp parameter is not set, it will be set at the 0 representing an unfinished action.

+ +

void + ActionsPublisher::insert(const std::string& + name, + time_t start_stamp, + time_t end_stamp = 0) +

+

Inserts the action defined in its name name starting at the time stamp start_stamp + and ending at end_stamp.

+

If the end_stamp parameter is not set, it will be set at the 0 representing an unfinished action.

+ +

void + ActionsPublisher::insertEnd(const std::string& + name, + const compat::mem_ros::Time& end_stamp = + mem_ros::Node::get().currentTime()) +

+

Inserts the ending of the action defined in its name name at end_stamp.

+

If the end_stamp parameter is not set, it will be set at the current time.

+ +

void + ActionsPublisher::insertEnd(const std::string& + name, + time_t end_stamp) +

+

Inserts the ending of the action defined in its name name at end_stamp.

+ +

void FeederPublisher::registerFeederNotificationCallback(const std::function<void(const std::string&)>& callback)

+

Registers a callback function to get notifications from the publisher.

+

The parameter callback is the callback function taking a string.

+ +
+
+
+ +
+ + +
+
+

+ Brought to you by: + +

+
+
+ + \ No newline at end of file diff --git a/docs/cpp_API/ActionsSubscriber.html b/docs/cpp_API/ActionsSubscriber.html new file mode 100644 index 0000000..a7f36c6 --- /dev/null +++ b/docs/cpp_API/ActionsSubscriber.html @@ -0,0 +1,229 @@ + + + + ActionsSubscriber Class | Mementar 0.0.4 + + + + + + + + + + +
+ + + +
+ + +
+

ActionsSubscriber Class

+

The ActionsSubscriber class can be seen as an action server to subscribe to occasions about actions. More...

+
+ + + + + + + + + + + + + + + +
Header: #include + "mementar/ActionsSubscriber.h" +
Inherits: OccasionsSubscriber +
Namespace: mementar +
+
+ + +

Public Functions

+
+ + + + + + + + + + + + + + + + + + + + + + + +
ActionsSubscriberconst + (std::function<void(const std::string&)>& callback, const + std::string& name = "") +
bool subscribeToStart(const std::string& + name, size_t count = -1) +
bool subscribeToEnd(const std::string& + name, size_t count = -1) +
bool cancel()
bool end()
+
+ + +
+

Detailed Description

+

The ActionsSubscriber class can be seen as an action server to subscribe to occasions about actions.

+

It allows you to subscribe to multiple actions at the same time and specify a number of occasions + that you expect.

+

In mementar, a fact is a datum that is not linked to a temporal stamp. When a fact occurs at a moment t, it + is called an occasion. An occasion is a particular time or instance of an event. An event occurs on a time + interval. It is thus composed of two occasions, one being the beginning of the event and the other the end. + An event is therefore a change of state of a fact, so that two facts have the same subject and the same + predicate, but the object changes.

+
+ +
+

Public Functions Documentation

+ +

ActionsSubscriber::ActionsSubscriber(const std::function<void(std::string + &)>& callback, const std::string& name = "") +

+

Constructs an ActionsSubscriber with a callback function callback.

+

Can be used in a multi-process mode by specifying the name of the mementar instance name. For + classic use, name should be defined as "".

+ +

bool + ActionsSubscriber::subscribeToStart(const + std::string& name, size_t& count + = -1)

+

Subscribe to the fact representing the begining of the action name.

+

The count parameter defines the number of occasions corresponding to the model you want to know. By + using the default value -1, the number of occasions is unlimited.

+

Returns false if the subscription failed.

+ +

bool + ActionsSubscriber::subscribeToEnd(const + std::string& name, size_t& count + = -1)

+

Subscribe to the fact representing the ending of the action name.

+

The count parameter defines the number of occasions corresponding to the model you want to know. By + using the default value -1, the number of occasions is unlimited.

+

Returns false if the subscription failed.

+ +

bool + ActionsSubscriber::cancel()

+

Cancel all subscriptions.

+

Returns false if the unsubscription fails.

+ +

bool ActionsSubscriber::end()

+

Returns true if no more occasions are expected.

+

If at least one subscription has been made with an account set to -1, the end function will always return + false until the next cancellation.

+ +
+
+
+ +
+ + +
+
+

+ Brought to you by: + +

+
+
+ + \ No newline at end of file diff --git a/docs/cpp_API/ClientBase.html b/docs/cpp_API/ClientBase.html index 76eea49..7bc3cd5 100644 --- a/docs/cpp_API/ClientBase.html +++ b/docs/cpp_API/ClientBase.html @@ -1,7 +1,7 @@ - ClientBase Class | Mementar 0.0.3 + ClientBase Class | Mementar 0.0.4 @@ -13,16 +13,20 @@ @@ -58,7 +59,9 @@

Contents

Getting Start

@@ -68,8 +71,13 @@

Getting Start

All C++ Classes

    +
  • ActionClient
  • +
  • ActionsPublisher
  • +
  • ActionsSubscriber
  • ClientBase
  • Fact
  • +
  • FactClient
  • +
  • InstanceManagerClient
  • ManagerClient
  • OccasionsPublisher
  • OccasionsSubscriber
  • @@ -86,8 +94,19 @@

    ClientBase Class

    - - + + + + + + + + + + + +
    Header: #include "mementar/API/clients/ClientBase.h"
    Inherited By: ManagerClient
    Header: #include + "mementar/clients/ClientBase.h"
    Inherited By: ManagerClient
    Namespace: mementar
    @@ -97,61 +116,146 @@

    Public Functions

    - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ClientBase(ros::NodeHandle* n, std::string name)
    size_t nb()
    void resetNb()
    ClientBase(std::string name) +
    size_t nb()
    void resetNb()
    int getErrorCode() +
    std::pair<std::vector<std::string>, + compat::mem_ros::Time> call(const + std::string& action, const std::string& param) +
    std::vector<std::string> callStrs(const + std::string& action, const std::string& param)
    compat::mem_ros::Time callStamp(const + std::string& action, const std::string& param)
    std::string callStr(const + std::string& action, const std::string& param)
    bool callNR(const + std::string& action, const std::string& param)
    bool callBool(const + std::string& action, const std::string& param)
    - -

    Protected Functions

    - - - - - - -
    std::vector<std::string> call(mementar::MementarService& srv)
    std::string callStr(mementar::MementarService& srv)
    bool callNR(mementar::MementarService& srv)
    +
    +

    Detailed Description

    +

    The ClientBase class provides an abstraction for any ROS services.

    +

    This class ensure a persistent connection with the service based on. The persistent connection ensure a + minimal response time. A reconnection logic is implemented in the event that the persistent connection + fails.

    +
    - -
    -

    Detailed Description

    -

    The ClientBase class provides an abstraction for any ROS services.

    -

    This class ensure a persistent connection with the service based on. The persistent connection ensure a minimal response time. A reconnection logic is implemented in the event that the persistent connection fails.

    -
    +
    +

    Public Functions Documentation

    -
    -

    Public Functions Documentation

    +

    ClientBase::ClientBase(const std::string& name)

    +

    Constructs a ROS client linked to the service name.

    -

    mementar::ClientBase::ClientBase(ros::NodeHandle* n, const std::string& name)

    -

    Constructs a ROS client linked to the service name with a pointer to a NodeHandle n.

    +

    size_t ClientBase::nb()

    +

    Gives the total number of service calls from all ClientBase instances since the last reset.

    -

    size_t mementar::ClientBase::nb()

    -

    Gives the total number of service calls from all ClientBase instances since the last reset.

    +

    void ClientBase::resetNb()

    +

    Reset Call Counter for all instances of ClientBase.

    -

    void mementar::ClientBase::resetNb()

    -

    Reset Call Counter for all instances of ClientBase.

    +

    int + ClientBase::getErrorCode()

    +

    Gives the error code of the last service call. Code 0 corresponds to no error. Code -1 corresponds to + service call error. Code 1 corresponds to an internal error. Code 2 corresponds to unknown query. Code 3 + corresponds to unclosed ontology.

    -

    Protected Function Documentation

    +

    std::pair<std::vector<std::string>, + compat::mem_ros::Time> + ClientBase::call(const std::string& + action, const std::string& param) +

    +

    Calls the service set up in the constructor of ClientBase with the request composed of an action action + and parameters param.

    +

    getErrorCode should be used to test if the call fail.

    -

    inline std::vector<std::string> mementar::ClientBase::call(mementar::MementarService& srv)

    -

    Call the service setup in the constructor of ClientBase with the request srv

    -

    If the service call fails, the first element of the returned vector is "ERR:SERVICE_FAIL".

    +

    std::vector<std::string> + ClientBase::callStrs(const std::string& + action, const std::string& param) +

    +

    Calls the service set up in the constructor of ClientBase with the request composed of an action action + and parameters param.

    +

    getErrorCode should be used to test if the call fail.

    -

    inline std::string mementar::ClientBase::callStr(mementar::MementarService& srv)

    -

    Call the service setup in the constructor of ClientBase with the request srv

    -

    If the service call fails, the returned value is "ERR:SERVICE_FAIL".

    +

    std::string + ClientBase::callStr(const std::string& + action, const std::string& param) +

    +

    Calls the service set up in the constructor of ClientBase with the request composed of an action action + and parameters param.

    +

    getErrorCode should be used to test if the call fail.

    -

    inline bool mementar::ClientBase::callNR(mementar::MementarService& srv)

    -

    Call the service setup in the constructor of ClientBase with the request srv

    -

    Return false if the service call fails.

    +

    compat::mem_ros::Time + ClientBase::callStamp(const std::string& + action, const std::string& param) +

    +

    Calls the service set up in the constructor of ClientBase with the request composed of an action action + and parameters param.

    +

    getErrorCode should be used to test if the call fail.

    +

    bool + ClientBase::callNR(const std::string& + action, const std::string& param) +

    +

    Calls the service set up in the constructor of ClientBase with the request composed of an action action + and parameters param.

    +

    Returns false if the service call fails.

    + +

    bool + ClientBase::callBool(const std::string& + action, const std::string& param) +

    +

    Calls the service set up in the constructor of ClientBase with the request composed of an action action + and parameters param.

    +

    getErrorCode should be used to test if the call fail.

    + +
    - + @@ -160,10 +264,10 @@

    inline bool Brought to you by:

    - + \ No newline at end of file diff --git a/docs/cpp_API/CppAPI.html b/docs/cpp_API/CppAPI.html index 73707f5..b53eb09 100644 --- a/docs/cpp_API/CppAPI.html +++ b/docs/cpp_API/CppAPI.html @@ -1,29 +1,34 @@ - C++ API | Mementar 0.0.3 + C++ API | Mementar 0.0.4 - +

Mementar API Documentation

-

Mementar 0.0.3

@@ -49,7 +53,9 @@

Mementar 0.0.3

Getting Start

@@ -59,8 +65,13 @@

Getting Start

All C++ Classes

@@ -99,10 +112,10 @@

TimelinesManipulator

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/Fact.html b/docs/cpp_API/Fact.html index 9e3db7b..6f2efb1 100644 --- a/docs/cpp_API/Fact.html +++ b/docs/cpp_API/Fact.html @@ -1,7 +1,7 @@ - Fact Class | Mementar 0.0.3 + Fact Class | Mementar 0.0.4 @@ -13,16 +13,20 @@
@@ -56,7 +59,9 @@

Contents

Getting Start

@@ -66,8 +71,13 @@

Getting Start

All C++ Classes

    +
  • ActionClient
  • +
  • ActionsPublisher
  • +
  • ActionsSubscriber
  • ClientBase
  • Fact
  • +
  • FactClient
  • +
  • InstanceManagerClient
  • ManagerClient
  • OccasionsPublisher
  • OccasionsSubscriber
  • @@ -84,7 +94,16 @@

    Fact Class

    - + + + + + + +
    Header: #include "mementar/API/Fact.h" +
    Header: #include + "mementar/Fact.h" +
    Namespace:mementar
    @@ -94,16 +113,68 @@

    Public Functions

    - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Fact(const std::string& fact)
    Fact(const std::string& subject, const std::string& predicat, const std::string& object)
    std::string subject()
    std::string predicat()
    std::string object()
    std::string operator()()
    void subject(const std::string& subject)
    void predicat(const std::string& predicat)
    void object(const std::string& object)
    void operator()(const std::string& fact)
    Fact(const std::string& + fact, bool add = true) +
    Fact(const std::string& + subject, const std::string& predicat, const std::string& object, bool + add = true) +
    std::string getSubject()
    std::string getPredicat()
    std::string getObject()
    bool getAdd()
    std::string operator()()
    std::string toString()
    void setSubject(const + std::string& subject)
    void setPredicat(const + std::string& predicat)
    void setObject(const + std::string& object)
    void setAdd(bool add)
    void operator()(const + std::string& fact, bool add = true) +
    @@ -112,49 +183,88 @@

    Public Functions

    Detailed Description

    The Fact class provides a way to represent facts in mementar.

    -

    Mementar formats the data representing an fact to be able to communicate them at the level of ROS messages. The Fact class makes it possible to make the link between this formatted representation and the representation in the form of a triplet.

    -

    In mementar, a fact is a datum that is not linked to a temporal stamp. When a fact occurs at a moment t, it is - called an occasion. An occasion is a particular time or instance of an event. An event occurs on a time interval. - It is thus composed of two occasions, one being the beginning of the event and the other the end. An event is - therefore a change of state of a fact, so that two facts have the same subject and the same predicate, but the - object changes.

    +

    Mementar formats the data representing a fact to be able to communicate them at the level of ROS messages. + The Fact class makes it possible to make the link between this formatted representation and the + representation in the form of a triplet.

    +

    In mementar, a fact is a datum that is not linked to a temporal stamp. When a fact occurs at a moment t, it + is called an occasion. An occasion is a particular time or instance of an event. An event occurs on a time + interval. It is thus composed of two occasions, one being the beginning of the event and the other the end. + An event is therefore a change of state of a fact, so that two facts have the same subject and the same + predicate, but the object changes.

    Public Functions Documentation

    -

    mementar::Fact::Fact(const std::string& fact)

    -

    Constructs a new fact from the formatted parameter fact.

    +

    Fact::Fact(const std::string& fact, bool add = true)

    +

    Constructs a new fact from the formatted parameter fact and the optional boolean add + representing the addition or deletion of the fact.

    In its formatted form, an fact is written as follows: subject|predicat|object

    +

    The add parameter can be transmitted in the formatted form with the syntax: + [add/del]subject|predicat|object

    -

    mementar::Fact::Fact(const std::string& subject, const std::string& predicat, const std::string& object)

    -

    Constructs a new fact from the triplet defined by the parameters subject, predicat and object.

    +

    Fact::Fact(const std::string& subject, const std::string& + predicat, const std::string& object, bool add = true) +

    +

    Constructs a new fact from the triplet defined by the parameters subject, predicat and + object and the optional boolean add + representing the addition or deletion of the fact. +

    -

    std::string mementar::Fact::subject()

    -

    Return the subject of the fact.

    +

    std::string + Fact::getSubject()

    +

    Returns the subject of the fact.

    -

    std::string mementar::Fact::predicat()

    -

    Return the predicat of the fact.

    +

    std::string + Fact::getPredicat()

    +

    Returns the predicat of the fact.

    -

    std::string mementar::Fact::object()

    -

    Return the object of the fact.

    +

    std::string + Fact::getObject()

    +

    Returns the object of the fact.

    -

    std::string mementar::Fact::operator()()

    -

    Return the fact in its formatted form.

    -

    In its formatted form, an fact is written as follows: subject|predicat|object

    +

    bool + Fact::getAdd()

    +

    Returns true if the fact is an insertion and false if it is a deletion.

    -

    void mementar::Fact::subject(const std::string& subject)

    -

    Set the subject of the fact.

    +

    std::string + Fact::operator()()

    +

    Returns the fact in its formatted form.

    +

    In its formatted form, an fact is written as follows: [add/del]subject|predicat|object

    -

    void mementar::Fact::predicat(const std::string& predicat)

    -

    Set the predicat of the fact.

    +

    std::string + Fact::toString()

    +

    Returns the fact in its formatted form.

    +

    In its formatted form, an fact is written as follows: [add/del]subject|predicat|object

    -

    void mementar::Fact::object(const std::string& object)

    -

    Set the object of the fact.

    +

    void Fact::setSubject(const std::string& subject)

    +

    Sets the subject of the fact.

    -

    void mementar::Fact::operator()(const std::string& fact)

    -

    Set the fact using its formatted form.

    -

    In its formatted form, an fact is written as follows: subject|predicat|object

    +

    void + Fact::setPredicat(const std::string& + predicat) +

    +

    Sets the predicat of the fact.

    + +

    void Fact::setObject(const std::string& object)

    +

    Sets the object of the fact.

    + +

    void Fact::setAdd(const bool& add)

    +

    Sets the addition or deletion of the fact.

    + +

    void + Fact::operator()(const std::string& + fact, bool add = true) +

    +

    Set the fact using its formatted form and the optional add parameter.

    +

    In its formatted form, an fact is written as follows: subject|predicat|object or + [add/del]subject|predicat|object

@@ -168,10 +278,10 @@

v

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/FactClient.html b/docs/cpp_API/FactClient.html new file mode 100644 index 0000000..db2676b --- /dev/null +++ b/docs/cpp_API/FactClient.html @@ -0,0 +1,232 @@ + + + + FactClient Class | Mementar 0.0.4 + + + + + + + + + + +
+ + + +
+ + +
+

FactClient Class

+

The FactClient class provides a ROS service abstraction for facts exploration. More... +

+
+ + + + + + + + + + + + + + + +
Header: #include + "mementar/clients/FactClient.h"
Inherits: ClientBase
Namespace: mementar
+
+ + +

Public Functions

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FactClient(const + std::string& name) +
bool exist(const + std::string& fact_id)
bool isActionPart + (const std::string& fact_id) +
std::string getActionPart(const std::string& fact_id) +
std::string getData(const + std::string& fact_id) +
compat::mem_ros::Time getStamp(const + std::string& fact_id) +
+
+ +
+ +
+

Detailed Description

+

The FactClient class provides an abstraction of mementar facts ROS service.

+

The mementar facts service allows the exploration of facts contained by mementar core.

+

This class is based on ClientBase and so ensure a persistent connection + with mementar/facts service. The persistent connection ensures a minimal response time. A reconnection + logic is implemented in the event that the persistent connection fails.

+
+ +
+

Public Functions Documentation

+ +

FactClient::FactClient(const std::string& name = + "")

+

Constructs an fact client.

+

Can be used in a multi-timeline mode by specifying the name of the timeline name. For classic use, + name should be defined as "". +

+ +

bool FactClient::exist(const std::string& fact_id) +

+

Returns true if the fact represented by its id fact_id exists.

+ +

bool + FactClient::isActionPart(const std::string& + fact_id) +

+

Returns true if the fact represented by its id fact_id is part of an action.

+ +

std::string + FactClient::getActionPart(const std::string& + fact_id) +

+

Returns the action the fact represented by its id fact_id is part of.

+

If the fact is not part of any action, the returned string will be empty.

+ +

std::string + FactClient::getData(const std::string& + fact_id) +

+

Returns the formatted representation of the fact represented by its id fact_id.

+

If the fact does not exist, the returned string will be empty.

+ +

compat::mem_ros::Time + FactClient::getStamp(const + std::string& fact_id) +

+

Returns the time stamp of the fact represented by its id fact_id.

+

If the fact does not exist the time stamp will be 0.

+ +
+
+
+ +
+
+ + +
+
+

+ Brought to you by: + +

+
+
+ + \ No newline at end of file diff --git a/docs/cpp_API/InstanceManagerClient.html b/docs/cpp_API/InstanceManagerClient.html new file mode 100644 index 0000000..bb7f148 --- /dev/null +++ b/docs/cpp_API/InstanceManagerClient.html @@ -0,0 +1,203 @@ + + + + InstanceManagerClient Class | Mementar 0.0.4 + + + + + + + + + + +
+ + + +
+ + +
+

InstanceManagerClient Class

+

The InstanceManagerClient class provides a ROS service abstraction for facts exploration. More... +

+
+ + + + + + + + + + + + + + + +
Header: #include + "mementar/clients/InstanceManagerClient.h"
Inherits: ClientBase
Namespace: mementar
+
+ + +

Public Functions

+
+ + + + + + + + + + + + + + + + + + + +
InstanceManagerClient(const + std::string& name) +
bool reset()
bool save(const + std::string& path)
bool draw + (const std::string& path) +
+
+ +
+ +
+

Detailed Description

+

The InstanceManagerClient class provides an abstraction of mementar instance management ROS service.

+

The mementar instance management service allows the management of one specific mementar instance.

+

This class is based on ClientBase and so ensure a persistent connection + with mementar service. The persistent connection ensures a minimal response time. A reconnection + logic is implemented in the event that the persistent connection fails.

+
+ +
+

Public Functions Documentation

+ +

InstanceManagerClient::InstanceManagerClient(const std::string& name = + "")

+

Constructs an instance manager client.

+

Can be used in a multi-timeline mode by specifying the name of the timeline name. For classic use, + name should be defined as "". +

+ +

bool InstanceManagerClient::reset() +

+

Resets completly the timeline.

+ +

bool InstanceManagerClient::save(const std::string& path) +

+

Saves the timeline as a CSV file and store it at path.

+ +

bool InstanceManagerClient::draw(const std::string& path) +

+

Generates a graphical representation of the timeline and store it at path.

+ +
+
+
+ +
+
+ + +
+
+

+ Brought to you by: + +

+
+
+ + \ No newline at end of file diff --git a/docs/cpp_API/ManagerClient.html b/docs/cpp_API/ManagerClient.html index c81406c..03141a4 100644 --- a/docs/cpp_API/ManagerClient.html +++ b/docs/cpp_API/ManagerClient.html @@ -1,7 +1,7 @@ - ManagerClient Class | Mementar 0.0.3 + ManagerClient Class | Mementar 0.0.4 @@ -13,16 +13,20 @@
@@ -57,7 +60,9 @@

Contents

Getting Start

@@ -67,8 +72,13 @@

Getting Start

All C++ Classes

    +
  • ActionClient
  • +
  • ActionsPublisher
  • +
  • ActionsSubscriber
  • ClientBase
  • Fact
  • +
  • FactClient
  • +
  • InstanceManagerClient
  • ManagerClient
  • OccasionsPublisher
  • OccasionsSubscriber
  • @@ -81,12 +91,24 @@

    All C++ Classes

    ManagerClient Class

    -

    The ManagerClient class provides an abstraction for mementar manage service. More...

    +

    The ManagerClient class provides an abstraction for mementar manage service. More... +

    - - + + + + + + + + + + + +
    Header: #include "mementar/API/clients/ManagerClient.h"
    Inherits: ClientBase
    Header: #include + "mementar/clients/ManagerClient.h"
    Inherits: ClientBase
    Namespace:mementar
    @@ -96,10 +118,26 @@

    Public Functions

    - - - - + + + + + + + + + + + + + + + +
    ManagerClient(ros::NodeHandle* n)
    std::vector<std::string> list()
    bool add(const std::string& name)
    bool del(const std::string& name)
    ManagerClient() +
    std::vector<std::string> list()
    bool add(const + std::string& name)
    bool del(const + std::string& name)
    @@ -107,33 +145,42 @@

    Public Functions

    Reimplemented Public Functions

    Detailed Description

    The ManagerClient class provides an abstraction mementar manage ROS services.

    -

    The manager client is used to manage ontology instances in multi-ontology usage. This makes it possible to start new ontologies or to stop old ones, but also to study the differences of knowledge between several instances. With the manager client, it is easy to develop software using theory of mind.

    -

    This class is based on ClientBase and so ensure a persistent connection with the service based on. The persistent connection ensure a minimal response time. A reconnection logic is implemented in the event that the persistent connection fails.

    +

    The manager client is used to manage ontology instances in multi-ontology usage. This makes it possible to + start new ontologies or to stop old ones, but also to study the differences of knowledge between several + instances. With the manager client, it is easy to develop software using theory of mind.

    +

    This class is based on ClientBase and so ensure a persistent connection with + the service based on. The persistent connection ensure a minimal response time. A reconnection logic is + implemented in the event that the persistent connection fails.

    Public Functions Documentation

    -

    mementar::ManagerClient::ManagerClient(ros::NodeHandle* n)

    -

    Constructs an manager client with a pointer to a NodeHandle n.

    +

    ManagerClient::ManagerClient()

    +

    Constructs an manager client.

    Can only be used in a multi-process mode.

    -

    std::vector<std::string> mementar::ManagerClient::list()

    +

    std::vector<std::string> + ManagerClient::list()

    Returns the name of the intanced mementar process.

    -

    bool mementar::ManagerClient::add(const std::string& name)

    +

    bool ManagerClient::add(const std::string& name)

    Create an mementar instance named name.

    Returns false if the service call fails.

    -

    bool mementar::ManagerClient::del(const std::string& name)

    -

    Delete the mementar instance named name

    +

    bool ManagerClient::del(const std::string& name)

    +

    Delete the mementar instance named name

    Returns false if the service call fails.

    @@ -148,10 +195,10 @@

    bool mementa

    Brought to you by:

    - + \ No newline at end of file diff --git a/docs/cpp_API/OccasionsPublisher.html b/docs/cpp_API/OccasionsPublisher.html index 15bff9a..e6c7a17 100644 --- a/docs/cpp_API/OccasionsPublisher.html +++ b/docs/cpp_API/OccasionsPublisher.html @@ -1,7 +1,7 @@ - OccasionsPublisher Class | Mementar 0.0.3 + OccasionsPublisher Class | Mementar 0.0.4 @@ -13,16 +13,20 @@

Mementar API Documentation

-

Mementar 0.0.3

@@ -56,7 +59,9 @@

Contents

Getting Start

@@ -66,8 +71,13 @@

Getting Start

All C++ Classes

    +
  • ActionClient
  • +
  • ActionsPublisher
  • +
  • ActionsSubscriber
  • ClientBase
  • Fact
  • +
  • FactClient
  • +
  • InstanceManagerClient
  • ManagerClient
  • OccasionsPublisher
  • OccasionsSubscriber
  • @@ -80,12 +90,21 @@

    All C++ Classes

    OccasionsPublisher Class

    -

    The OccasionsPublisher class provides an abstraction for mementar insertion topic. More...

    +

    The OccasionsPublisher class provides an abstraction for mementar insertion topic. More...

    - + + + + + + +
    Header: #include "mementar/API/OccasionsPublisher.h" -
    Inherited By: OntologiesManipulator
    Header: #include + "mementar/OccasionsPublisher.h" +
    Namespace: mementar +
    @@ -95,8 +114,33 @@

    Public Functions

    - - + + + + + + + + + + + + + + + +
    OccasionsPublisher(ros::NodeHandle* n, const std::string& name = "")
    void insert(const Fact& fact, time_t stamp = 0)
    OccasionsPublisher(const + std::string& name = "") +
    void insert(const + Fact& fact, const + compat::mem_ros::Time& stamp = compat::mem_ros::Node::get().currentTime()) +
    void insert(const + Fact& fact, time_t stamp ) +
    void registerFeederNotificationCallback(const + std::function<void(const std::string&)>& callback) +
    @@ -106,23 +150,45 @@

    Public Functions

    Detailed Description

    The OccasionsPublisher class provides an abstraction for mementar insertion ROS topic.

    The insertion process is asynchronous and therefore does not guarantee any response time.

    -

    In mementar, a fact is a datum that is not linked to a temporal stamp. When a fact occurs at a moment t, it is - called an occasion. An occasion is a particular time or instance of an event. An event occurs on a time interval. - It is thus composed of two occasions, one being the beginning of the event and the other the end. An event is - therefore a change of state of a fact, so that two facts have the same subject and the same predicate, but the - object changes.

    +

    In mementar, a fact is a datum that is not linked to a temporal stamp. When a fact occurs at a moment t, it + is called an occasion. An occasion is a particular time or instance of an event. An event occurs on a time + interval. It is thus composed of two occasions, one being the beginning of the event and the other the end. + An event is therefore a change of state of a fact, so that two facts have the same subject and the same + predicate, but the object changes.

    Public Functions Documentation

    -

    mementar::OccasionsPublisher::OccasionsPublisher(ros::NodeHandle* n, const std::string& name = "")

    -

    Constructs an OccasionsPublisher with a pointer to a NodeHandle n.

    -

    Can be used in a multi-process mode by specifying the name of the mementar instance name. For classic use, name should be defined as "".

    - -

    void mementar::OccasionsPublisher::insert(const Fact& fact, time_t stamp = 0)

    -

    Inserts the fact defined in the fact object.

    -

    The fact can be stamped using the stamp parameter. If the stamp parameter is not set (set to default 0), it will be set at the current time.

    +

    OccasionsPublisher::OccasionsPublisher(const std::string& name = "") +

    +

    Constructs an OccasionsPublisher.

    +

    Can be used in a multi-process mode by specifying the name of the mementar instance name. For + classic use, name should be defined as "".

    + +

    void + OccasionsPublisher::insert(const Fact& fact, const compat::mem_ros::Time& stamp = + mem_ros::Node::get().currentTime()) +

    +

    Inserts the fact defined in the fact object at the time stamp stamp.

    +

    If the stamp parameter is not set, it will be set at the current time.

    + +

    void + OccasionsPublisher::insert(const Fact& fact, time_t stamp) +

    +

    Inserts the fact defined in the fact object at the time stamp stamp.

    + +

    void FeederPublisher::registerFeederNotificationCallback(const std::function<void(const std::string&)>& callback)

    +

    Registers a callback function to get notifications from the publisher.

    +

    The parameter callback is the callback function taking a string.

@@ -136,10 +202,10 @@

void

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/OccasionsSubscriber.html b/docs/cpp_API/OccasionsSubscriber.html index 9156504..0114d86 100644 --- a/docs/cpp_API/OccasionsSubscriber.html +++ b/docs/cpp_API/OccasionsSubscriber.html @@ -1,7 +1,7 @@ - OccasionsSubscriber Class | Mementar 0.0.3 + OccasionsSubscriber Class | Mementar 0.0.4 @@ -13,16 +13,20 @@
-

OccasionsPublisher Class

-

The OccasionsSubscriber class can be seen as an action server to subscribe to occasions. More...

+

OccasionsSubscriber Class

+

The OccasionsSubscriber class can be seen as an action server to subscribe to occasions. More...

- + + + + + + +
Header: #include "mementar/API/OccasionsSubscriber.h" +
Header: #include + "mementar/OccasionsSubscriber.h" +
Namespace: mementar +
@@ -94,12 +115,33 @@

Public Functions

- - - - - - + + + + + + + + + + + + + + + + + + + +
OccasionsSubscriber(std::function<void(const Fact&)> callback, const std::string& name = "", bool spin_thread = true)
OccasionsSubscriber(std::function<void(const Fact&)> callback, bool spin_thread)
~OccasionsSubscriber()
bool subscribe(const Fact& pattern, size_t count = -1)
bool cancel()
bool end()
OccasionsSubscriberconst + (std::function<void(const Fact&)>& callback, const + std::string& name = "") +
~OccasionsSubscriber()
bool subscribe(const Fact& pattern, size_t count = -1)
bool cancel()
bool end()
@@ -108,42 +150,55 @@

Public Functions

Detailed Description

The OccasionsSubscriber class can be seen as an action server to subscribe to occasions.

-

It allows you to subscribe to multiple fact patterns at the same time and specify a number of occasions that you expect.

-

In mementar, a fact is a datum that is not linked to a temporal stamp. When a fact occurs at a moment t, it is - called an occasion. An occasion is a particular time or instance of an event. An event occurs on a time interval. - It is thus composed of two occasions, one being the beginning of the event and the other the end. An event is - therefore a change of state of a fact, so that two facts have the same subject and the same predicate, but the +

It allows you to subscribe to multiple fact patterns at the same time and specify a number of occasions + that you expect.

+

In mementar, a fact is a datum that is not linked to a temporal stamp. When a fact occurs at a moment t, it + is + called an occasion. An occasion is a particular time or instance of an event. An event occurs on a time + interval. + It is thus composed of two occasions, one being the beginning of the event and the other the end. An event + is + therefore a change of state of a fact, so that two facts have the same subject and the same predicate, but + the object changes.

Public Functions Documentation

-

mementar::OccasionsSubscriber::OccasionsSubscriber(const std::function<void(Fact&)> callback, const std::string& name = "", bool spin_thread = true)

+

OccasionsSubscriber::OccasionsSubscriber(const std::function<void(Fact&)>& callback, const std::string& name = "")

Constructs an OccasionsSubscriber with a callback function callback.

-

The OccasionsSubscriber constructor also takes a boolean option to automatically spin a thread. If you prefer not to use threads (and you want the OccasionsSubscriber to do the 'thread magic' behind the scenes), this is a good option for you.

-

Can be used in a multi-process mode by specifying the name of the mementar instance name. For classic use, name should be defined as "".

+

Can be used in a multi-process mode by specifying the name of the mementar instance name. For + classic use, name should be defined as "".

-

mementar::OccasionsSubscriber::OccasionsSubscriber(const std::function<void(Fact&)> callback, bool spin_thread)

-

Constructs an OccasionsSubscriber with a callback function callback.

-

The OccasionsSubscriber constructor also takes a boolean option to automatically spin a thread. If you prefer not to use threads (and you want the OccasionsSubscriber to do the 'thread magic' behind the scenes), this is a good option for you.

- -

mementar::OccasionsSubscriber::~OccasionsSubscriber()

+

OccasionsSubscriber::~OccasionsSubscriber()

The OccasionsSubscriber destructor cancel all the subscriptions previous done.

-

bool mementar::OccasionsSubscriber::subscribe(const Fact& pattern, size_t& count = -1)

+

bool + OccasionsSubscriber::subscribe(const Fact& pattern, size_t& count + = -1)

Subscribe to the fact pattern pattern defined as an Fact object.

-

A pattern can be constructed as a classic fact, but each component of the triplet can also be set to the value "?" to represent anything.

-

The count parameter defines the number of occasions corresponding to the model you want to know. By using the default value -1, the number of occasions is unlimited.

-

Returns false if the subscription failed.

- -

bool mementar::OccasionsSubscriber::cancel()

+

A pattern can be constructed as a classic fact, but each component of the triplet can also be set to the + value "?" to represent anything.

+

The count parameter defines the number of occasions corresponding to the model you want to know. By + using the default value -1, the number of occasions is unlimited.

+

Returns false if the subscription failed.

+ +

bool + OccasionsSubscriber::cancel()

Cancel all subscriptions.

-

Returns false if at least one subscription fails.

+

Returns false if the unsubscription fails.

-

bool mementar::OccasionsSubscriber::end()

+

bool OccasionsSubscriber::end()

Returns true if no more occasions are expected.

-

If at least one subscription has been made with an account set to -1, the end function will always return false until the next cancellation.

+

If at least one subscription has been made with an account set to -1, the end function will always return + false until the next cancellation.

@@ -157,10 +212,10 @@

bool mementa

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/TimelineManipulator.html b/docs/cpp_API/TimelineManipulator.html index 4f0c2af..b869f6b 100644 --- a/docs/cpp_API/TimelineManipulator.html +++ b/docs/cpp_API/TimelineManipulator.html @@ -1,7 +1,7 @@ - TimelineManipulator Class | Mementar 0.0.3 + TimelineManipulator Class | Mementar 0.0.4 @@ -13,16 +13,20 @@
@@ -57,7 +60,9 @@

Contents

Getting Start

@@ -67,8 +72,13 @@

Getting Start

All C++ Classes

    +
  • ActionClient
  • +
  • ActionsPublisher
  • +
  • ActionsSubscriber
  • ClientBase
  • Fact
  • +
  • FactClient
  • +
  • InstanceManagerClient
  • ManagerClient
  • OccasionsPublisher
  • OccasionsSubscriber
  • @@ -80,34 +90,70 @@

    All C++ Classes

    TimelineManipulator Class

    -

    The TimelineManipulator class is an object with instances of all classes needed to manipulate a mementar instance.More...

    +

    The TimelineManipulator class is an object with instances of all classes needed to manipulate a mementar + instance.More...

    - + + + + + + +
    Header: #include "mementar/API/TimelineManipulator.h" -
    Inherits: OccasionsPublisher
    Header: #include + "mementar/TimelineManipulator.h"
    Namespace: mementar +

    Public Attributes

    - +

    Public Functions

    - - - - - + + + + + + + + + + + + + + + + + + + +
    TimelineManipulator(ros::NodeHandle* n, const std::string& name = "")
    bool waitInit(int32_t timeout = -1)
    size_t nb()
    void resetNb()
    void verbose(bool verbose)
    TimelineManipulator(const + std::string& name = "") +
    bool waitInit(int32_t timeout = -1)
    size_t nb()
    void resetNb() +
    void verbose(bool + verbose)
    @@ -115,7 +161,8 @@

    Public Functions

    Detailed Description

    -

    The TimelineManipulator class is just an object to access all API ROS abstraction classes so that you can query and manage mementar.

    +

    The TimelineManipulator class is just an object to access all API ROS abstraction classes so that you can + query and manage mementar.

    See also TimelinesManipulator.

    @@ -123,7 +170,24 @@

    Detailed Description

    Public Attribute Documentation

    -

    actions : ActionClient

    +

    fact_feeder : OccasionsPublisher

    +

    ROS publisher to insert facts in the timeline.

    + +

    action_feeder : ActionsPublisher

    +

    ROS publisher to insert actions in the timeline.

    + +

    actions : ActionClient

    +

    ROS service client to query the timeline about actions.

    + +

    facts : FactClient

    +

    ROS service client to query the timeline about facts.

    + +

    inst_manager : InstanceManagerClient

    ROS service client to manage the mementar instance.

    @@ -131,22 +195,33 @@

    actions

    Public Functions Documentation

    -

    mementar::TimelineManipulator::TimelineManipulator(ros::NodeHandle* n, const std::string& name = "")

    -

    Constructs a manipulator for a mementar instance with a pointer to a NodeHandle n.

    -

    Can be used in a multi-instances mode by specifying the name of the mementar instance name. For classic use, do not specify any name name.

    +

    TimelineManipulator::TimelineManipulator(const std::string& name = + "")

    +

    Constructs a manipulator for a mementar instance.

    +

    Can be used in a multi-instances mode by specifying the name of the mementar instance name. For + classic use, do not specify any name name.

    -

    bool mementar::TimelineManipulator::waitInit(int32_t timeout = -1)

    +

    bool + TimelineManipulator::waitInit(int32_t + timeout = -1)

    Wait for mementar services to be advertised and available for. Blocks until it is.

    -

    timeout is the amount of time to wait for before timing out. If timeout is -1 (default), waits until the node is shutdown.

    +

    timeout is the amount of time to wait for before timing out. If timeout is -1 (default), waits until + the node is shutdown.

    -

    size_t mementar::TimelineManipulator::nb()

    +

    size_t TimelineManipulator::nb()

    Gives the total number of service calls from all ROS clients instances since the last reset.

    -

    void mementar::TimelineManipulator::resetNb()

    +

    void + TimelineManipulator::resetNb()

    Reset Call Counter for all instances of ROS clients.

    -

    void mementar::TimelineManipulator::verbose(bool verbose)

    -

    If verbose is set to true, the clients will post messages about the failure to call the services and about their restoration.

    +

    void + TimelineManipulator::verbose(bool verbose) +

    +

    If verbose is set to true, the clients will post messages about the failure to call the services and about + their restoration.

@@ -160,10 +235,10 @@

void

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/TimelinesManipulator.html b/docs/cpp_API/TimelinesManipulator.html index df60e45..80db0bb 100644 --- a/docs/cpp_API/TimelinesManipulator.html +++ b/docs/cpp_API/TimelinesManipulator.html @@ -1,7 +1,7 @@ - TimelinesManipulator Class | Mementar 0.0.3 + TimelinesManipulator Class | Mementar 0.0.4 @@ -13,16 +13,20 @@
@@ -57,7 +60,9 @@

Contents

Getting Start

@@ -67,8 +72,13 @@

Getting Start

All C++ Classes

    +
  • ActionClient
  • +
  • ActionsPublisher
  • +
  • ActionsSubscriber
  • ClientBase
  • Fact
  • +
  • FactClient
  • +
  • InstanceManagerClient
  • ManagerClient
  • OccasionsPublisher
  • OccasionsSubscriber
  • @@ -80,14 +90,30 @@

    All C++ Classes

    TimelinesManipulator Class

    -

    The TimelinesManipulator class is an interface to manage several instance of TimelineManipulator in a multi-instances usage. More...

    +

    The TimelinesManipulator class is an interface to manage several instance of TimelineManipulator in a multi-instances usage. More...

    -
    Header: #include "mementar/API/TimelinesManipulator.h" -
    Inherits: ManagerClient
    + + Header: + #include + "mementar/TimelinesManipulator.h" + + + + Inherits: + ManagerClient + + + Namespace: + mementar + + +
    @@ -95,11 +121,33 @@

    Public Functions

    - - - - - + + + + + + + + + + + + + + + + + + + +
    TimelinesManipulator(ros::NodeHandle* n)
    bool waitInit(int32_t timeout = -1)
    TimelineManipulator* operator[](const std::string& name)
    TimelineManipulator* get(const std::string& name)
    void verbose(bool verbose)
    TimelinesManipulator() +
    bool waitInit(int32_t timeout = -1)
    TimelineManipulator* operator[](const std::string& name) +
    TimelineManipulator* get(const + std::string& name)
    void verbose(bool + verbose)
    @@ -109,50 +157,73 @@

    Reimplemented Public Functions

    - - + + + + + + + +
    bool add(const std::string& name)
    bool del(const std::string& name)
    bool add(const + std::string& name)
    bool del(const + std::string& name)

    Detailed Description

    -

    The TimelinesManipulator class allows to create and delete mementar instances dynamically. It's usage is strongly recommanded for multi-instances usage and ensure a good thread management.

    +

    The TimelinesManipulator class allows to create and delete mementar instances dynamically. It's usage is + strongly recommanded for multi-instances usage and ensure a good thread management.

    This class allows you to set up the theory of mind quickly in a software application.

    Public Functions Documentation

    -

    mementar::TimelinesManipulator::TimelinesManipulator(ros::NodeHandle* n)

    -

    Constructs a manipulator for several instance of mementar with a pointer to a NodeHandle n.

    +

    TimelinesManipulator::TimelinesManipulator()

    +

    Constructs a manipulator for several instance of mementar.

    -

    bool mementar::TimelinesManipulator::waitInit(int32_t timeout = -1)

    +

    bool + TimelinesManipulator::waitInit(int32_t + timeout = -1)

    Wait for mementar services to be advertised and available for. Blocks until it is.

    -

    timeout is the amount of time to wait for before timing out. If timeout is -1 (default), waits until the node is shutdown.

    +

    timeout is the amount of time to wait for before timing out. If timeout is -1 (default), waits until + the node is shutdown.

    -

    TimelineManipulator* mementar::TimelinesManipulator::operator[](const std::string& name)

    +

    TimelineManipulator* TimelinesManipulator::operator[](const std::string& name)

    Return a pointer on the TimelineManipulator instance named name.

    Return nullptr if no TimelineManipulator instance is named name.

    -

    TimelineManipulator* mementar::TimelinesManipulator::get(const std::string& name)

    +

    TimelineManipulator* TimelinesManipulator::get(const std::string& name)

    Return a pointer on the TimelineManipulator instance named name.

    Return nullptr if no TimelineManipulator instance is named name.

    -

    void mementar::TimelinesManipulator::verbose(bool verbose)

    -

    If verbose is set to true, the clients will post messages about the failure to call the services and about their restoration.

    +

    void + TimelinesManipulator::verbose(bool verbose) +

    +

    If verbose is set to true, the clients will post messages about the failure to call the services and about + their restoration.

    Reimplemented Public Functions Documentation

    -

    bool mementar::TimelinesManipulator::add(const std::string& name)

    +

    bool TimelinesManipulator::add(const std::string& name)

    Creates a new instance of TimelineManipulator identified by the name name.

    Returns false creating fails. Returns true even if the instance already exists.

    -

    bool mementar::TimelinesManipulator::del(const std::string& name)

    +

    bool TimelinesManipulator::del(const std::string& name)

    Deletes the instance of TimelineManipulator identified by the name name.

    Returns false deletation fails. Returns true even if the instance do not exists.

    @@ -167,10 +238,10 @@

    bool mementa

    Brought to you by:

    - + \ No newline at end of file diff --git a/docs/img/LogoLAAS-2016_BW.png b/docs/img/LogoLAAS-2016_BW.png index 3bf0842..9da974f 100644 Binary files a/docs/img/LogoLAAS-2016_BW.png and b/docs/img/LogoLAAS-2016_BW.png differ diff --git a/docs/img/logo/favicon-16x16.png b/docs/img/logo/favicon-16x16.png index f0b2a2f..957c7f0 100644 Binary files a/docs/img/logo/favicon-16x16.png and b/docs/img/logo/favicon-16x16.png differ diff --git a/docs/img/logo/favicon-32x32.png b/docs/img/logo/favicon-32x32.png index cd8b6ab..186bb66 100644 Binary files a/docs/img/logo/favicon-32x32.png and b/docs/img/logo/favicon-32x32.png differ diff --git a/docs/img/logo/favicon.ico b/docs/img/logo/favicon.ico index ef82075..1043116 100644 Binary files a/docs/img/logo/favicon.ico and b/docs/img/logo/favicon.ico differ diff --git a/docs/img/logo/mementar.ico b/docs/img/logo/mementar.ico index 81c897a..1043116 100644 Binary files a/docs/img/logo/mementar.ico and b/docs/img/logo/mementar.ico differ diff --git a/docs/img/logo/mementar.png b/docs/img/logo/mementar.png index 3f7efc1..e54f985 100644 Binary files a/docs/img/logo/mementar.png and b/docs/img/logo/mementar.png differ diff --git a/docs/img/logo/mementar.svg b/docs/img/logo/mementar.svg index 2144c99..ba2ca3c 100644 --- a/docs/img/logo/mementar.svg +++ b/docs/img/logo/mementar.svg @@ -14,7 +14,7 @@ viewBox="0 0 210 297" version="1.1" id="svg8" - inkscape:version="0.92.3 (2405546, 2018-03-11)" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)" sodipodi:docname="mementar.svg"> @@ -26,15 +26,15 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.35" - inkscape:cx="594.84477" - inkscape:cy="560" + inkscape:cx="1808.2039" + inkscape:cy="707.71393" inkscape:document-units="mm" - inkscape:current-layer="g1064" + inkscape:current-layer="layer1-3" showgrid="false" - inkscape:window-width="1853" - inkscape:window-height="1025" - inkscape:window-x="67" - inkscape:window-y="27" + inkscape:window-width="1848" + inkscape:window-height="1129" + inkscape:window-x="72" + inkscape:window-y="994" inkscape:window-maximized="1" /> @@ -44,7 +44,7 @@ image/svg+xml - + @@ -82,61 +82,165 @@ height="58.336311" width="286.88333" id="rect4878" />ONTOLoojcin dsc sc s + id="flowPara4880">ONTOLoojcin dsc sc s + MEMENTAR + + + + + + + + + + + + + + + MEMENTAR + id="tspan4882-7" + x="278.07236" + y="199.60683" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:58.31838989px;font-family:Dooodleista;-inkscape-font-specification:'Dooodleista Bold';fill:#ffffff;fill-opacity:1;stroke-width:0.68341857">MEMENTAR + id="g1047-5" + transform="matrix(-1,0,0,1,454.27937,-0.37798891)"> + id="path3778-62" /> + id="path3778-3-9" /> + id="path3778-6-5-6-2" /> + id="g3872-7"> + id="path3778-6-5-2-93" + cx="117.63202" + cy="122.32267" + rx="4.7025542" + ry="4.6512537" + style="fill:#d43617;fill-opacity:1;stroke-width:0.289435" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id="path3778-6-5-60-9" /> + id="path3778-6-6-4" /> diff --git a/docs/img/logo/mementar_light.png b/docs/img/logo/mementar_light.png new file mode 100644 index 0000000..95db6ce Binary files /dev/null and b/docs/img/logo/mementar_light.png differ diff --git a/docs/img/logo/mementar_simple.png b/docs/img/logo/mementar_simple.png index 4cc8ca7..01d6fea 100644 Binary files a/docs/img/logo/mementar_simple.png and b/docs/img/logo/mementar_simple.png differ diff --git a/docs/img/ros1-and-ros2.jpg b/docs/img/ros1-and-ros2.jpg new file mode 100644 index 0000000..07cf2c9 Binary files /dev/null and b/docs/img/ros1-and-ros2.jpg differ diff --git a/docs/index.html b/docs/index.html index 492cd26..0b8e900 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,24 +1,26 @@ - Mementar 0.0.3 + Mementar 0.0.4 - - Exemple avec navbar-default - - + + Exemple avec navbar-default + + - + - +
    @@ -26,8 +28,8 @@
    @@ -40,7 +42,7 @@

    A long-term episodic memory for robotic agents

    @@ -52,28 +54,38 @@

    A long-term episodic memory for robotic agents

+
+ @@ -90,14 +102,19 @@

A long-term episodic memory for robotic agents

-
+

A powerful way to store your robot experience.


A smart way to organize the knowledge of your agent.

@@ -140,8 +157,8 @@

About mementar

Based on the principle of compression and archiving, Mementar aims to store a large amount of past events.

- -
Mementar uses ROS for maximum compatibility with all robotics projects. + +
Mementar uses ROS1 and ROS2 for maximum compatibility with all robotics projects.
@@ -166,39 +183,44 @@

C++ API is already available

- + -
-
-

See also

-
-
-
-
-
-

Ontologenius

-
-
-
- -
- - +
+
+

See also

+
+
+
+
+
+

Ontologenius

+
+
+
+
+ +
+
-
+
@@ -208,10 +230,10 @@

Ontologenius

Brought to you by:

- + \ No newline at end of file diff --git a/docs/scripts/jquery-3.3.1.min.js b/docs/scripts/jquery-3.3.1.min.js deleted file mode 100644 index 4d9b3a2..0000000 --- a/docs/scripts/jquery-3.3.1.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w("