Merge branch 'master' into curl

Conflicts:
	CMakeLists.txt
	src/CMakeLists.txt
	src/zm_camera.h
	src/zm_monitor.cpp
	web/skins/classic/views/console.php
	web/skins/classic/views/monitor.php
This commit is contained in:
Kfir Itzhak 2013-12-27 14:21:12 +02:00
commit bf708a8373
95 changed files with 1680 additions and 1208 deletions

View File

@ -10,7 +10,7 @@
# #
cmake_minimum_required (VERSION 2.6) cmake_minimum_required (VERSION 2.6)
project (zoneminder) project (zoneminder)
set(zoneminder_VERSION "1.26.4") set(zoneminder_VERSION "1.26.5")
# CMake does not allow out-of-source build if CMakeCache.exists in the source folder. Abort and notify the user to save him from headache why it doesn't work. # CMake does not allow out-of-source build if CMakeCache.exists in the source folder. Abort and notify the user to save him from headache why it doesn't work.
if((NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)) AND (EXISTS "${CMAKE_SOURCE_DIR}/CMakeCache.txt")) if((NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)) AND (EXISTS "${CMAKE_SOURCE_DIR}/CMakeCache.txt"))
@ -62,12 +62,11 @@ set(ZM_EXTRA_LIBS "" CACHE STRING "A list of optional libraries, separated by se
set(ZM_MYSQL_ENGINE "InnoDB" CACHE STRING "MySQL engine to use with database, default: InnoDB") set(ZM_MYSQL_ENGINE "InnoDB" CACHE STRING "MySQL engine to use with database, default: InnoDB")
set(ZM_NO_MMAP "OFF" CACHE BOOL "Set to ON to not use mmap shared memory. Shouldn't be enabled unless you experience problems with the shared memory. default: OFF") set(ZM_NO_MMAP "OFF" CACHE BOOL "Set to ON to not use mmap shared memory. Shouldn't be enabled unless you experience problems with the shared memory. default: OFF")
set(ZM_NO_FFMPEG "OFF" CACHE BOOL "Set to ON to skip ffmpeg checks and force building ZM without ffmpeg. default: OFF") set(ZM_NO_FFMPEG "OFF" CACHE BOOL "Set to ON to skip ffmpeg checks and force building ZM without ffmpeg. default: OFF")
set(ZM_NO_LIBVLC "OFF" CACHE BOOL "Set to ON to skip libvlc checks and force building ZM without libvlc. default: OFF")
set(ZM_NO_X10 "OFF" CACHE BOOL "Set to ON to build ZoneMinder without X10 support. default: OFF") set(ZM_NO_X10 "OFF" CACHE BOOL "Set to ON to build ZoneMinder without X10 support. default: OFF")
set(ZM_PERL_SUBPREFIX "${CMAKE_INSTALL_LIBDIR}/perl5" CACHE PATH "Use a different directory for the zm perl modules. NOTE: This is a subprefix, e.g. lib will be turned into <prefix>/lib, default: ${CMAKE_INSTALL_LIBDIR}/perl5") set(ZM_PERL_SUBPREFIX "${CMAKE_INSTALL_LIBDIR}/perl5" CACHE PATH "Use a different directory for the zm perl modules. NOTE: This is a subprefix, e.g. lib will be turned into <prefix>/lib, default: <libdir>/perl5")
set(ZM_PERL_USE_PATH "${CMAKE_INSTALL_PREFIX}/${ZM_PERL_SUBPREFIX}" CACHE PATH "Override the include path for zm perl modules. Useful if you are moving the perl modules without using the ZM_PERL_SUBPREFIX option. default: <prefix>/<zmperlsubprefix>") set(ZM_PERL_USE_PATH "${CMAKE_INSTALL_PREFIX}/${ZM_PERL_SUBPREFIX}" CACHE PATH "Override the include path for zm perl modules. Useful if you are moving the perl modules without using the ZM_PERL_SUBPREFIX option. default: <prefix>/<zmperlsubprefix>")
set(ZM_TARGET_DISTRO "" CACHE STRING "Build ZoneMinder for a specific distribution. Currently, valid names are: f19, el6") set(ZM_TARGET_DISTRO "" CACHE STRING "Build ZoneMinder for a specific distribution. Currently, valid names are: f19, el6")
# Only required for cmakecacheimport:
set(CMAKE_INSTALL_FULL_BINDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}" CACHE PATH "Override default binary directory")
# Required for certain checks to work # Required for certain checks to work
set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} stdio.h stdlib.h math.h signal.h) set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} stdio.h stdlib.h math.h signal.h)
@ -88,7 +87,6 @@ check_function_exists("sendfile" HAVE_SENDFILE)
check_function_exists("backtrace" HAVE_DECL_BACKTRACE) check_function_exists("backtrace" HAVE_DECL_BACKTRACE)
check_function_exists("backtrace_symbols" HAVE_DECL_BACKTRACE_SYMBOLS) check_function_exists("backtrace_symbols" HAVE_DECL_BACKTRACE_SYMBOLS)
check_function_exists("posix_memalign" HAVE_POSIX_MEMALIGN) check_function_exists("posix_memalign" HAVE_POSIX_MEMALIGN)
check_prototype_definition("round" "double round (double x)" "0.0" "math.h" HAVE_DECL_ROUND)
check_type_size("siginfo_t" HAVE_SIGINFO_T) check_type_size("siginfo_t" HAVE_SIGINFO_T)
check_type_size("ucontext_t" HAVE_UCONTEXT_T) check_type_size("ucontext_t" HAVE_UCONTEXT_T)
@ -98,9 +96,9 @@ check_type_size("ucontext_t" HAVE_UCONTEXT_T)
find_package(ZLIB) find_package(ZLIB)
if(ZLIB_FOUND) if(ZLIB_FOUND)
set(HAVE_LIBZLIB 1) set(HAVE_LIBZLIB 1)
list(APPEND ZM_BIN_LIBS ${ZLIB_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${ZLIB_LIBRARIES}")
include_directories(${ZLIB_INCLUDE_DIRS}) include_directories("${ZLIB_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS}) set(CMAKE_REQUIRED_INCLUDES "${ZLIB_INCLUDE_DIR}")
check_include_file("zlib.h" HAVE_ZLIB_H) check_include_file("zlib.h" HAVE_ZLIB_H)
set(optlibsfound "${optlibsfound} zlib") set(optlibsfound "${optlibsfound} zlib")
else(ZLIB_FOUND) else(ZLIB_FOUND)
@ -124,10 +122,10 @@ endif(CURL_FOUND)
find_package(JPEG) find_package(JPEG)
if(JPEG_FOUND) if(JPEG_FOUND)
set(HAVE_LIBJPEG 1) set(HAVE_LIBJPEG 1)
list(APPEND ZM_BIN_LIBS ${JPEG_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${JPEG_LIBRARIES}")
#link_directories(${JPEG_LIBRARY}) #link_directories(${JPEG_LIBRARY})
include_directories(${JPEG_INCLUDE_DIR}) include_directories("${JPEG_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${JPEG_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${JPEG_INCLUDE_DIR}")
check_include_files("stdio.h;jpeglib.h" HAVE_JPEGLIB_H) check_include_files("stdio.h;jpeglib.h" HAVE_JPEGLIB_H)
if(NOT HAVE_JPEGLIB_H) if(NOT HAVE_JPEGLIB_H)
message(FATAL_ERROR " zm requires libjpeg headers - check that libjpeg development packages are installed") message(FATAL_ERROR " zm requires libjpeg headers - check that libjpeg development packages are installed")
@ -141,9 +139,9 @@ find_package(OpenSSL)
if(OPENSSL_FOUND) if(OPENSSL_FOUND)
set(HAVE_LIBOPENSSL 1) set(HAVE_LIBOPENSSL 1)
set(HAVE_LIBCRYPTO 1) set(HAVE_LIBCRYPTO 1)
list(APPEND ZM_BIN_LIBS ${OPENSSL_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${OPENSSL_LIBRARIES}")
include_directories(${OPENSSL_INCLUDE_DIR}) include_directories("${OPENSSL_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}")
check_include_file("openssl/md5.h" HAVE_OPENSSL_MD5_H) check_include_file("openssl/md5.h" HAVE_OPENSSL_MD5_H)
set(optlibsfound "${optlibsfound} OpenSSL") set(optlibsfound "${optlibsfound} OpenSSL")
else(OPENSSL_FOUND) else(OPENSSL_FOUND)
@ -154,11 +152,11 @@ endif(OPENSSL_FOUND)
find_library(PTHREAD_LIBRARIES pthread) find_library(PTHREAD_LIBRARIES pthread)
if(PTHREAD_LIBRARIES) if(PTHREAD_LIBRARIES)
set(HAVE_LIBPTHREAD 1) set(HAVE_LIBPTHREAD 1)
list(APPEND ZM_BIN_LIBS ${PTHREAD_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${PTHREAD_LIBRARIES}")
find_path(PTHREAD_INCLUDE_DIR pthread.h) find_path(PTHREAD_INCLUDE_DIR pthread.h)
if(PTHREAD_INCLUDE_DIR) if(PTHREAD_INCLUDE_DIR)
include_directories(${PTHREAD_INCLUDE_DIR}) include_directories("${PTHREAD_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${PTHREAD_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${PTHREAD_INCLUDE_DIR}")
endif(PTHREAD_INCLUDE_DIR) endif(PTHREAD_INCLUDE_DIR)
mark_as_advanced(FORCE PTHREAD_LIBRARIES PTHREAD_INCLUDE_DIR) mark_as_advanced(FORCE PTHREAD_LIBRARIES PTHREAD_INCLUDE_DIR)
check_include_file("pthread.h" HAVE_PTHREAD_H) check_include_file("pthread.h" HAVE_PTHREAD_H)
@ -173,11 +171,11 @@ endif(PTHREAD_LIBRARIES)
find_library(PCRE_LIBRARIES pcre) find_library(PCRE_LIBRARIES pcre)
if(PCRE_LIBRARIES) if(PCRE_LIBRARIES)
set(HAVE_LIBPCRE 1) set(HAVE_LIBPCRE 1)
list(APPEND ZM_BIN_LIBS ${PCRE_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${PCRE_LIBRARIES}")
find_path(PCRE_INCLUDE_DIR pcre.h) find_path(PCRE_INCLUDE_DIR pcre.h)
if(PCRE_INCLUDE_DIR) if(PCRE_INCLUDE_DIR)
include_directories(${PCRE_INCLUDE_DIR}) include_directories("${PCRE_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${PCRE_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE_DIR}")
endif(PCRE_INCLUDE_DIR) endif(PCRE_INCLUDE_DIR)
mark_as_advanced(FORCE PCRE_LIBRARIES PCRE_INCLUDE_DIR) mark_as_advanced(FORCE PCRE_LIBRARIES PCRE_INCLUDE_DIR)
check_include_file("pcre.h" HAVE_PCRE_H) check_include_file("pcre.h" HAVE_PCRE_H)
@ -190,11 +188,11 @@ endif(PCRE_LIBRARIES)
find_library(GCRYPT_LIBRARIES gcrypt) find_library(GCRYPT_LIBRARIES gcrypt)
if(GCRYPT_LIBRARIES) if(GCRYPT_LIBRARIES)
set(HAVE_LIBGCRYPT 1) set(HAVE_LIBGCRYPT 1)
list(APPEND ZM_BIN_LIBS ${GCRYPT_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${GCRYPT_LIBRARIES}")
find_path(GCRYPT_INCLUDE_DIR gcrypt.h) find_path(GCRYPT_INCLUDE_DIR gcrypt.h)
if(GCRYPT_INCLUDE_DIR) if(GCRYPT_INCLUDE_DIR)
include_directories(${GCRYPT_INCLUDE_DIR}) include_directories("${GCRYPT_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${GCRYPT_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${GCRYPT_INCLUDE_DIR}")
endif(GCRYPT_INCLUDE_DIR) endif(GCRYPT_INCLUDE_DIR)
mark_as_advanced(FORCE GCRYPT_LIBRARIES GCRYPT_INCLUDE_DIR) mark_as_advanced(FORCE GCRYPT_LIBRARIES GCRYPT_INCLUDE_DIR)
check_include_file("gcrypt.h" HAVE_GCRYPT_H) check_include_file("gcrypt.h" HAVE_GCRYPT_H)
@ -207,11 +205,11 @@ endif(GCRYPT_LIBRARIES)
find_library(GNUTLS_LIBRARIES gnutls) find_library(GNUTLS_LIBRARIES gnutls)
if(GNUTLS_LIBRARIES) if(GNUTLS_LIBRARIES)
set(HAVE_LIBGNUTLS 1) set(HAVE_LIBGNUTLS 1)
list(APPEND ZM_BIN_LIBS ${GNUTLS_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${GNUTLS_LIBRARIES}")
find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h) find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h)
if(GNUTLS_INCLUDE_DIR) if(GNUTLS_INCLUDE_DIR)
include_directories(${GNUTLS_INCLUDE_DIR}) include_directories("${GNUTLS_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${GNUTLS_INCLUDE_DIR}")
endif(GNUTLS_INCLUDE_DIR) endif(GNUTLS_INCLUDE_DIR)
mark_as_advanced(FORCE GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIR) mark_as_advanced(FORCE GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIR)
check_include_file("gnutls/openssl.h" HAVE_GNUTLS_OPENSSL_H) check_include_file("gnutls/openssl.h" HAVE_GNUTLS_OPENSSL_H)
@ -225,11 +223,11 @@ endif(GNUTLS_LIBRARIES)
find_library(MYSQLCLIENT_LIBRARIES mysqlclient PATH_SUFFIXES mysql) find_library(MYSQLCLIENT_LIBRARIES mysqlclient PATH_SUFFIXES mysql)
if(MYSQLCLIENT_LIBRARIES) if(MYSQLCLIENT_LIBRARIES)
set(HAVE_LIBMYSQLCLIENT 1) set(HAVE_LIBMYSQLCLIENT 1)
list(APPEND ZM_BIN_LIBS ${MYSQLCLIENT_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${MYSQLCLIENT_LIBRARIES}")
find_path(MYSQLCLIENT_INCLUDE_DIR mysql/mysql.h) find_path(MYSQLCLIENT_INCLUDE_DIR mysql/mysql.h)
if(MYSQLCLIENT_INCLUDE_DIR) if(MYSQLCLIENT_INCLUDE_DIR)
include_directories(${MYSQLCLIENT_INCLUDE_DIR}) include_directories("${MYSQLCLIENT_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${MYSQLCLIENT_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${MYSQLCLIENT_INCLUDE_DIR}")
endif(MYSQLCLIENT_INCLUDE_DIR) endif(MYSQLCLIENT_INCLUDE_DIR)
mark_as_advanced(FORCE MYSQLCLIENT_LIBRARIES MYSQLCLIENT_INCLUDE_DIR) mark_as_advanced(FORCE MYSQLCLIENT_LIBRARIES MYSQLCLIENT_INCLUDE_DIR)
check_include_file("mysql/mysql.h" HAVE_MYSQL_H) check_include_file("mysql/mysql.h" HAVE_MYSQL_H)
@ -240,17 +238,19 @@ else(MYSQLCLIENT_LIBRARIES)
message(FATAL_ERROR "zm requires mysqlclient but it was not found on your system") message(FATAL_ERROR "zm requires mysqlclient but it was not found on your system")
endif(MYSQLCLIENT_LIBRARIES) endif(MYSQLCLIENT_LIBRARIES)
set(PATH_FFMPEG "")
set(OPT_FFMPEG "no")
# Do not check for ffmpeg if ZM_NO_FFMPEG is on # Do not check for ffmpeg if ZM_NO_FFMPEG is on
if(NOT ZM_NO_FFMPEG) if(NOT ZM_NO_FFMPEG)
# avformat (using find_library and find_path) # avformat (using find_library and find_path)
find_library(AVFORMAT_LIBRARIES avformat) find_library(AVFORMAT_LIBRARIES avformat)
if(AVFORMAT_LIBRARIES) if(AVFORMAT_LIBRARIES)
set(HAVE_LIBAVFORMAT 1) set(HAVE_LIBAVFORMAT 1)
list(APPEND ZM_BIN_LIBS ${AVFORMAT_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${AVFORMAT_LIBRARIES}")
find_path(AVFORMAT_INCLUDE_DIR "libavformat/avformat.h") find_path(AVFORMAT_INCLUDE_DIR "libavformat/avformat.h")
if(AVFORMAT_INCLUDE_DIR) if(AVFORMAT_INCLUDE_DIR)
include_directories(${AVFORMAT_INCLUDE_DIR}) include_directories("${AVFORMAT_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${AVFORMAT_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${AVFORMAT_INCLUDE_DIR}")
endif(AVFORMAT_INCLUDE_DIR) endif(AVFORMAT_INCLUDE_DIR)
mark_as_advanced(FORCE AVFORMAT_LIBRARIES AVFORMAT_INCLUDE_DIR) mark_as_advanced(FORCE AVFORMAT_LIBRARIES AVFORMAT_INCLUDE_DIR)
check_include_file("libavformat/avformat.h" HAVE_LIBAVFORMAT_AVFORMAT_H) check_include_file("libavformat/avformat.h" HAVE_LIBAVFORMAT_AVFORMAT_H)
@ -263,11 +263,11 @@ if(NOT ZM_NO_FFMPEG)
find_library(AVCODEC_LIBRARIES avcodec) find_library(AVCODEC_LIBRARIES avcodec)
if(AVCODEC_LIBRARIES) if(AVCODEC_LIBRARIES)
set(HAVE_LIBAVCODEC 1) set(HAVE_LIBAVCODEC 1)
list(APPEND ZM_BIN_LIBS ${AVCODEC_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${AVCODEC_LIBRARIES}")
find_path(AVCODEC_INCLUDE_DIR "libavcodec/avcodec.h") find_path(AVCODEC_INCLUDE_DIR "libavcodec/avcodec.h")
if(AVCODEC_INCLUDE_DIR) if(AVCODEC_INCLUDE_DIR)
include_directories(${AVCODEC_INCLUDE_DIR}) include_directories("${AVCODEC_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${AVCODEC_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${AVCODEC_INCLUDE_DIR}")
endif(AVCODEC_INCLUDE_DIR) endif(AVCODEC_INCLUDE_DIR)
mark_as_advanced(FORCE AVCODEC_LIBRARIES AVCODEC_INCLUDE_DIR) mark_as_advanced(FORCE AVCODEC_LIBRARIES AVCODEC_INCLUDE_DIR)
check_include_file("libavcodec/avcodec.h" HAVE_LIBAVCODEC_AVCODEC_H) check_include_file("libavcodec/avcodec.h" HAVE_LIBAVCODEC_AVCODEC_H)
@ -280,11 +280,11 @@ if(NOT ZM_NO_FFMPEG)
find_library(AVDEVICE_LIBRARIES avdevice) find_library(AVDEVICE_LIBRARIES avdevice)
if(AVDEVICE_LIBRARIES) if(AVDEVICE_LIBRARIES)
set(HAVE_LIBAVDEVICE 1) set(HAVE_LIBAVDEVICE 1)
list(APPEND ZM_BIN_LIBS ${AVDEVICE_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${AVDEVICE_LIBRARIES}")
find_path(AVDEVICE_INCLUDE_DIR "libavdevice/avdevice.h") find_path(AVDEVICE_INCLUDE_DIR "libavdevice/avdevice.h")
if(AVDEVICE_INCLUDE_DIR) if(AVDEVICE_INCLUDE_DIR)
include_directories(${AVDEVICE_INCLUDE_DIR}) include_directories("${AVDEVICE_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${AVDEVICE_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${AVDEVICE_INCLUDE_DIR}")
endif(AVDEVICE_INCLUDE_DIR) endif(AVDEVICE_INCLUDE_DIR)
mark_as_advanced(FORCE AVDEVICE_LIBRARIES AVDEVICE_INCLUDE_DIR) mark_as_advanced(FORCE AVDEVICE_LIBRARIES AVDEVICE_INCLUDE_DIR)
check_include_file("libavdevice/avdevice.h" HAVE_LIBAVDEVICE_AVDEVICE_H) check_include_file("libavdevice/avdevice.h" HAVE_LIBAVDEVICE_AVDEVICE_H)
@ -297,11 +297,11 @@ if(NOT ZM_NO_FFMPEG)
find_library(AVUTIL_LIBRARIES avutil) find_library(AVUTIL_LIBRARIES avutil)
if(AVUTIL_LIBRARIES) if(AVUTIL_LIBRARIES)
set(HAVE_LIBAVUTIL 1) set(HAVE_LIBAVUTIL 1)
list(APPEND ZM_BIN_LIBS ${AVUTIL_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${AVUTIL_LIBRARIES}")
find_path(AVUTIL_INCLUDE_DIR "libavutil/avutil.h") find_path(AVUTIL_INCLUDE_DIR "libavutil/avutil.h")
if(AVUTIL_INCLUDE_DIR) if(AVUTIL_INCLUDE_DIR)
include_directories(${AVUTIL_INCLUDE_DIR}) include_directories("${AVUTIL_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${AVUTIL_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${AVUTIL_INCLUDE_DIR}")
endif(AVUTIL_INCLUDE_DIR) endif(AVUTIL_INCLUDE_DIR)
mark_as_advanced(FORCE AVUTIL_LIBRARIES AVUTIL_INCLUDE_DIR) mark_as_advanced(FORCE AVUTIL_LIBRARIES AVUTIL_INCLUDE_DIR)
check_include_file("libavutil/avutil.h" HAVE_LIBAVUTIL_AVUTIL_H) check_include_file("libavutil/avutil.h" HAVE_LIBAVUTIL_AVUTIL_H)
@ -315,11 +315,11 @@ if(NOT ZM_NO_FFMPEG)
find_library(SWSCALE_LIBRARIES swscale) find_library(SWSCALE_LIBRARIES swscale)
if(SWSCALE_LIBRARIES) if(SWSCALE_LIBRARIES)
set(HAVE_LIBSWSCALE 1) set(HAVE_LIBSWSCALE 1)
list(APPEND ZM_BIN_LIBS ${SWSCALE_LIBRARIES}) list(APPEND ZM_BIN_LIBS "${SWSCALE_LIBRARIES}")
find_path(SWSCALE_INCLUDE_DIR "libswscale/swscale.h") find_path(SWSCALE_INCLUDE_DIR "libswscale/swscale.h")
if(SWSCALE_INCLUDE_DIR) if(SWSCALE_INCLUDE_DIR)
include_directories(${SWSCALE_INCLUDE_DIR}) include_directories("${SWSCALE_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES ${SWSCALE_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${SWSCALE_INCLUDE_DIR}")
endif(SWSCALE_INCLUDE_DIR) endif(SWSCALE_INCLUDE_DIR)
mark_as_advanced(FORCE SWSCALE_LIBRARIES SWSCALE_INCLUDE_DIR) mark_as_advanced(FORCE SWSCALE_LIBRARIES SWSCALE_INCLUDE_DIR)
check_include_file("libswscale/swscale.h" HAVE_LIBSWSCALE_SWSCALE_H) check_include_file("libswscale/swscale.h" HAVE_LIBSWSCALE_SWSCALE_H)
@ -327,8 +327,37 @@ if(NOT ZM_NO_FFMPEG)
else(SWSCALE_LIBRARIES) else(SWSCALE_LIBRARIES)
set(optlibsnotfound "${optlibsnotfound} SWScale") set(optlibsnotfound "${optlibsnotfound} SWScale")
endif(SWSCALE_LIBRARIES) endif(SWSCALE_LIBRARIES)
# Find the path to the ffmpeg executable
find_program(FFMPEG_EXECUTABLE ffmpeg PATH_SUFFIXES ffmpeg)
if(FFMPEG_EXECUTABLE)
set(PATH_FFMPEG "${FFMPEG_EXECUTABLE}")
set(OPT_FFMPEG "yes")
mark_as_advanced(FFMPEG_EXECUTABLE)
endif(FFMPEG_EXECUTABLE)
endif(NOT ZM_NO_FFMPEG) endif(NOT ZM_NO_FFMPEG)
# Do not check for libvlc if ZM_NO_LIBVLC is on
if(NOT ZM_NO_LIBVLC)
# libvlc (using find_library and find_path)
find_library(LIBVLC_LIBRARIES vlc)
if(LIBVLC_LIBRARIES)
set(HAVE_LIBVLC 1)
list(APPEND ZM_BIN_LIBS "${LIBVLC_LIBRARIES}")
find_path(LIBVLC_INCLUDE_DIR "vlc/vlc.h")
if(LIBVLC_INCLUDE_DIR)
include_directories("${LIBVLC_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES "${LIBVLC_INCLUDE_DIR}")
endif(LIBVLC_INCLUDE_DIR)
mark_as_advanced(FORCE LIBVLC_LIBRARIES LIBVLC_INCLUDE_DIR)
check_include_file("vlc/vlc.h" HAVE_VLC_VLC_H)
set(optlibsfound "${optlibsfound} libVLC")
else(LIBVLC_LIBRARIES)
set(optlibsnotfound "${optlibsnotfound} libVLC")
endif(LIBVLC_LIBRARIES)
endif(NOT ZM_NO_LIBVLC)
# *** END OF LIBRARY CHECKS *** # *** END OF LIBRARY CHECKS ***
# Check for gnutls or crypto # Check for gnutls or crypto
@ -368,18 +397,18 @@ endif(NOT ZM_NO_MMAP)
# Check for authenication functions # Check for authenication functions
if(HAVE_OPENSSL_MD5_H) if(HAVE_OPENSSL_MD5_H)
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) set(CMAKE_REQUIRED_LIBRARIES "${OPENSSL_LIBRARIES}")
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}")
check_prototype_definition(MD5 "unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)" "NULL" "openssl/md5.h" HAVE_MD5_OPENSSL) check_prototype_definition(MD5 "unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)" "NULL" "openssl/md5.h" HAVE_MD5_OPENSSL)
endif(HAVE_OPENSSL_MD5_H) endif(HAVE_OPENSSL_MD5_H)
if(HAVE_GNUTLS_OPENSSL_H) if(HAVE_GNUTLS_OPENSSL_H)
set(CMAKE_REQUIRED_LIBRARIES ${GNUTLS_LIBRARIES}) set(CMAKE_REQUIRED_LIBRARIES "${GNUTLS_LIBRARIES}")
set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${GNUTLS_INCLUDE_DIR}")
check_prototype_definition(MD5 "unsigned char *MD5 (const unsigned char *buf, unsigned long len, unsigned char *md)" "NULL" "gnutls/openssl.h" HAVE_MD5_GNUTLS) check_prototype_definition(MD5 "unsigned char *MD5 (const unsigned char *buf, unsigned long len, unsigned char *md)" "NULL" "gnutls/openssl.h" HAVE_MD5_GNUTLS)
endif(HAVE_GNUTLS_OPENSSL_H) endif(HAVE_GNUTLS_OPENSSL_H)
if(HAVE_GNUTLS_GNUTLS_H) if(HAVE_GNUTLS_GNUTLS_H)
set(CMAKE_REQUIRED_LIBRARIES ${GNUTLS_LIBRARIES}) set(CMAKE_REQUIRED_LIBRARIES "${GNUTLS_LIBRARIES}")
set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES "${GNUTLS_INCLUDE_DIR}")
check_prototype_definition(gnutls_fingerprint "int gnutls_fingerprint (gnutls_digest_algorithm_t algo, const gnutls_datum_t * data, void *result, size_t * result_size)" "0" "stdlib.h;gnutls/gnutls.h" HAVE_DECL_GNUTLS_FINGERPRINT) check_prototype_definition(gnutls_fingerprint "int gnutls_fingerprint (gnutls_digest_algorithm_t algo, const gnutls_datum_t * data, void *result, size_t * result_size)" "0" "stdlib.h;gnutls/gnutls.h" HAVE_DECL_GNUTLS_FINGERPRINT)
endif(HAVE_GNUTLS_GNUTLS_H) endif(HAVE_GNUTLS_GNUTLS_H)
if(HAVE_MD5_OPENSSL OR HAVE_MD5_GNUTLS) if(HAVE_MD5_OPENSSL OR HAVE_MD5_GNUTLS)
@ -431,9 +460,7 @@ message(STATUS "Using web group: ${ZM_WEB_GROUP}")
set(ZM_PID "${ZM_RUNDIR}/zm.pid") set(ZM_PID "${ZM_RUNDIR}/zm.pid")
set(ZM_CONFIG "/${CMAKE_INSTALL_SYSCONFDIR}/zm.conf") set(ZM_CONFIG "/${CMAKE_INSTALL_SYSCONFDIR}/zm.conf")
set(VERSION "${zoneminder_VERSION}") set(VERSION "${zoneminder_VERSION}")
set(PATH_BUILD "${PROJECT_SOURCE_DIR}")
set(PKGDATADIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/zoneminder") set(PKGDATADIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/zoneminder")
set(TIME_BUILD "1000000") # Don't have a solution for this one yet
set(BINDIR "${CMAKE_INSTALL_FULL_BINDIR}") set(BINDIR "${CMAKE_INSTALL_FULL_BINDIR}")
set(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}") set(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}")
set(SYSCONFDIR "/${CMAKE_INSTALL_SYSCONFDIR}") set(SYSCONFDIR "/${CMAKE_INSTALL_SYSCONFDIR}")
@ -441,6 +468,7 @@ set(WEB_PREFIX "${ZM_WEBDIR}")
set(CGI_PREFIX "${ZM_CGIDIR}") set(CGI_PREFIX "${ZM_CGIDIR}")
set(WEB_USER "${ZM_WEB_USER}") set(WEB_USER "${ZM_WEB_USER}")
set(WEB_GROUP "${ZM_WEB_GROUP}") set(WEB_GROUP "${ZM_WEB_GROUP}")
set(ZM_DB_TYPE "mysql")
set(EXTRA_PERL_LIB "use lib '${ZM_PERL_USE_PATH}';") set(EXTRA_PERL_LIB "use lib '${ZM_PERL_USE_PATH}';")
# Reassign some variables if a target distro has been specified # Reassign some variables if a target distro has been specified

View File

@ -26,7 +26,7 @@ root@host:~# aptitude install -y apache2 mysql-server php5 php5-mysql build-esse
root@host:~# git clone https://github.com/ZoneMinder/ZoneMinder.git zoneminder; root@host:~# git clone https://github.com/ZoneMinder/ZoneMinder.git zoneminder;
root@host:~# cd zoneminder; root@host:~# cd zoneminder;
root@host:~# ln -s distros/ubuntu1204; root@host:~# ln -s distros/ubuntu1204 debian;
root@host:~# dpkg-checkbuilddeps; root@host:~# dpkg-checkbuilddeps;
root@host:~# dpkg-buildpackage; root@host:~# dpkg-buildpackage;
``` ```

View File

@ -44,7 +44,7 @@ if [ "$?" != "0" ]; then
fi fi
# Print some information # Print some information
echo "Executables directory : $ZM_PATH_BIN" #echo "Executables directory : $ZM_PATH_BIN"
#echo "Libraries directory : $ZM_PATH_LIB" #echo "Libraries directory : $ZM_PATH_LIB"
#echo "System config directory : $ZM_PATH_CONF" #echo "System config directory : $ZM_PATH_CONF"
echo "Web directory : $ZM_PATH_WEB" echo "Web directory : $ZM_PATH_WEB"
@ -60,8 +60,8 @@ echo "Database password : Not shown"
CMPATH="CACHE PATH \"Imported by cmakecacheimport.sh\" FORCE" CMPATH="CACHE PATH \"Imported by cmakecacheimport.sh\" FORCE"
CMSTRING="CACHE STRING \"Imported by cmakecacheimport.sh\" FORCE" CMSTRING="CACHE STRING \"Imported by cmakecacheimport.sh\" FORCE"
# Write # Write
echo "# Generated by cmakecacheimport.sh">zm_conf.cmake echo "# This file was generated by cmakecacheimport.sh">zm_conf.cmake
echo "set(CMAKE_INSTALL_FULL_BINDIR \"$ZM_PATH_BIN\" $CMPATH)">>zm_conf.cmake #echo "set(CMAKE_INSTALL_FULL_BINDIR \"$ZM_PATH_BIN\" $CMPATH)">>zm_conf.cmake
#echo "set(CMAKE_INSTALL_FULL_LIBDIR \"$ZM_PATH_LIB\" $CMPATH)">>zm_conf.cmake #echo "set(CMAKE_INSTALL_FULL_LIBDIR \"$ZM_PATH_LIB\" $CMPATH)">>zm_conf.cmake
#echo "set(CMAKE_INSTALL_FULL_SYSCONFDIR \"$ZM_PATH_CONF\" $CMPATH)">>zm_conf.cmake #echo "set(CMAKE_INSTALL_FULL_SYSCONFDIR \"$ZM_PATH_CONF\" $CMPATH)">>zm_conf.cmake
echo "set(ZM_WEBDIR \"$ZM_PATH_WEB\" $CMPATH)">>zm_conf.cmake echo "set(ZM_WEBDIR \"$ZM_PATH_WEB\" $CMPATH)">>zm_conf.cmake

View File

@ -1,15 +1,12 @@
AC_PREREQ(2.59) AC_PREREQ(2.59)
AC_INIT(zm,1.26.4,[http://www.zoneminder.com/forums/ - Please check FAQ first],zoneminder,http://www.zoneminder.com/downloads.html) AC_INIT(zm,1.26.5,[http://www.zoneminder.com/forums/ - Please check FAQ first],zoneminder,http://www.zoneminder.com/downloads.html)
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR(src/zm.h) AC_CONFIG_SRCDIR(src/zm.h)
AC_CONFIG_HEADERS(config.h) AC_CONFIG_HEADERS(config.h)
AC_SUBST([AM_CXXFLAGS], [-D__STDC_CONSTANT_MACROS]) AC_SUBST([AM_CXXFLAGS], [-D__STDC_CONSTANT_MACROS])
PATH_BUILD=`pwd` AC_SUBST(VERSION)
AC_SUBST(PATH_BUILD)
TIME_BUILD=`date +'%s'`
AC_SUBST(TIME_BUILD)
AC_ARG_VAR(ZM_DB_HOST,[Hostname where ZoneMinder database located, default localhost]) AC_ARG_VAR(ZM_DB_HOST,[Hostname where ZoneMinder database located, default localhost])
AC_ARG_VAR(ZM_DB_NAME,[Name of ZoneMinder database, default zm]) AC_ARG_VAR(ZM_DB_NAME,[Name of ZoneMinder database, default zm])
@ -21,6 +18,9 @@ AC_ARG_VAR(ZM_RUNDIR,[Location of transient process files, default /var/run/zm])
AC_ARG_VAR(ZM_TMPDIR,[Location of temporary files, default /tmp/zm]) AC_ARG_VAR(ZM_TMPDIR,[Location of temporary files, default /tmp/zm])
AC_ARG_VAR(ZM_LOGDIR,[Location of generated log files, default /var/log/zm]) AC_ARG_VAR(ZM_LOGDIR,[Location of generated log files, default /var/log/zm])
if test "$ZM_DB_TYPE" == ""; then
AC_SUBST(ZM_DB_TYPE,[mysql])
fi
if test "$ZM_DB_HOST" == ""; then if test "$ZM_DB_HOST" == ""; then
AC_SUBST(ZM_DB_HOST,[localhost]) AC_SUBST(ZM_DB_HOST,[localhost])
fi fi
@ -177,22 +177,6 @@ if test "$ENABLE_DEBUG" != "yes"; then
AC_DEFINE(ZM_DBG_OFF,1,"Whether debug is switched off and compiled out") AC_DEFINE(ZM_DBG_OFF,1,"Whether debug is switched off and compiled out")
fi fi
ENABLE_CRASHTRACE=yes
AC_ARG_ENABLE(crashtrace,
[ --enable-crashtrace=<yes|no> enable or disabled crash tracing, default enabled],
[ENABLE_CRASHTRACE=$enable_crashtrace],
AC_MSG_WARN([You can call configure with the --enable-crashtrace=<yes|no> or --disable-crashtrace option.
This tells configure whether to compile ZoneMinder with crash tracing included. This allows a
dump of the stack trace when a ZoneMinder binary crashes or is killed by an unexpected signal.
Although this should work on most systems it does rely on un(or loosely) documented features and
so should be regarded as experimental. If you experience problems compiling zm_signal.cpp or
ZoneMinder binaries fail to shut down correctly then you should probably disable this feature.
e.g. --enable-crashtrace=yes or --disable-crashtrace])
)
if test "$ENABLE_CRASHTRACE" != "yes"; then
AC_DEFINE(ZM_NO_CRASHTRACE,1,"Whether crash tracing is switched off and compiled out")
fi
ENABLE_MMAP=yes ENABLE_MMAP=yes
AC_ARG_ENABLE(mmap, AC_ARG_ENABLE(mmap,
[ --enable-mmap=<yes|no> enable or disabled mapped memory versus shared memory, default mapped], [ --enable-mmap=<yes|no> enable or disabled mapped memory versus shared memory, default mapped],
@ -291,6 +275,7 @@ AC_CHECK_LIB(avformat,avformat_version,,AC_MSG_WARN(libavformat.a is required fo
#AC_CHECK_LIB(avformat,av_new_stream,,AC_MSG_WARN(libavformat.a is required for MPEG streaming)) #AC_CHECK_LIB(avformat,av_new_stream,,AC_MSG_WARN(libavformat.a is required for MPEG streaming))
AC_CHECK_LIB(avdevice,avdevice_register_all,,AC_MSG_WARN(libavdevice.a may be required for MPEG streaming)) AC_CHECK_LIB(avdevice,avdevice_register_all,,AC_MSG_WARN(libavdevice.a may be required for MPEG streaming))
AC_CHECK_LIB(swscale,sws_scale,,,-lswscale) AC_CHECK_LIB(swscale,sws_scale,,,-lswscale)
AC_CHECK_LIB(vlc,libvlc_new,,AC_MSG_WARN(libvlc.a may be required for streaming))
AC_CHECK_LIB(bz2,BZ2_bzCompress,,AC_MSG_WARN(zm requires libbz2.a for recent versions of ffmpeg)) AC_CHECK_LIB(bz2,BZ2_bzCompress,,AC_MSG_WARN(zm requires libbz2.a for recent versions of ffmpeg))
AC_CHECK_LIB(z,compress,,) AC_CHECK_LIB(z,compress,,)
@ -329,8 +314,8 @@ AC_CHECK_HEADERS(sys/ipc.h,,,)
AC_CHECK_HEADERS(sys/shm.h,,,) AC_CHECK_HEADERS(sys/shm.h,,,)
fi fi
AC_CHECK_HEADERS(zlib.h,,,) AC_CHECK_HEADERS(zlib.h,,,)
AC_CHECK_HEADERS(vlc/vlc.h,,,)
AC_CHECK_DECLS(round,,,[#include <math.h>])
if test "$ZM_SSL_LIB" == "openssl"; then if test "$ZM_SSL_LIB" == "openssl"; then
AC_CHECK_DECLS(MD5,,AC_MSG_ERROR([zm requires openssl/md5.h - use ZM_SSL_LIB option to select gnutls instead]),[#include <stdlib.h> AC_CHECK_DECLS(MD5,,AC_MSG_ERROR([zm requires openssl/md5.h - use ZM_SSL_LIB option to select gnutls instead]),[#include <stdlib.h>
#include <openssl/md5.h>]) #include <openssl/md5.h>])

View File

@ -1,4 +1,4 @@
AUTOMAKE_OPTIONS = gnu AUTOMAKE_OPTIONS = foreign
zmdbdatadir = $(pkgdatadir)/db zmdbdatadir = $(pkgdatadir)/db
@ -10,48 +10,5 @@ dist_zmdbdata_DATA = \
zm_create.sql \ zm_create.sql \
$(dbupgrade_scripts) $(dbupgrade_scripts)
dbupgrade_scripts = \ dbupgrade_scripts = $(wildcard zm_update-*.sql)
zm_update-0.0.1.sql \
zm_update-0.9.7.sql \
zm_update-0.9.8.sql \
zm_update-0.9.9.sql \
zm_update-0.9.10.sql \
zm_update-0.9.11.sql \
zm_update-0.9.12.sql \
zm_update-0.9.13.sql \
zm_update-0.9.15.sql \
zm_update-0.9.16.sql \
zm_update-1.17.1.sql \
zm_update-1.17.2.sql \
zm_update-1.18.0.sql \
zm_update-1.18.1.sql \
zm_update-1.19.0.sql \
zm_update-1.19.1.sql \
zm_update-1.19.2.sql \
zm_update-1.19.3.sql \
zm_update-1.19.4.sql \
zm_update-1.19.5.sql \
zm_update-1.20.0.sql \
zm_update-1.20.1.sql \
zm_update-1.21.0.sql \
zm_update-1.21.1.sql \
zm_update-1.21.2.sql \
zm_update-1.21.3.sql \
zm_update-1.21.4.sql \
zm_update-1.22.0.sql \
zm_update-1.22.1.sql \
zm_update-1.22.2.sql \
zm_update-1.22.3.sql \
zm_update-1.23.0.sql \
zm_update-1.23.1.sql \
zm_update-1.23.2.sql \
zm_update-1.23.3.sql \
zm_update-1.24.0.sql \
zm_update-1.24.1.sql \
zm_update-1.24.2.sql \
zm_update-1.24.3.sql \
zm_update-1.24.4.sql \
zm_update-1.26.0.sql \
zm_update-1.26.1.sql \
zm_update-1.26.2.sql \
zm_update-1.26.3.sql

View File

@ -63,7 +63,7 @@ DROP TABLE IF EXISTS `Controls`;
CREATE TABLE `Controls` ( CREATE TABLE `Controls` (
`Id` int(10) unsigned NOT NULL auto_increment, `Id` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(64) NOT NULL default '', `Name` varchar(64) NOT NULL default '',
`Type` enum('Local','Remote','Ffmpeg') NOT NULL default 'Local', `Type` enum('Local','Remote','Ffmpeg','Libvlc') NOT NULL default 'Local',
`Protocol` varchar(64) default NULL, `Protocol` varchar(64) default NULL,
`CanWake` tinyint(3) unsigned NOT NULL default '0', `CanWake` tinyint(3) unsigned NOT NULL default '0',
`CanSleep` tinyint(3) unsigned NOT NULL default '0', `CanSleep` tinyint(3) unsigned NOT NULL default '0',
@ -282,7 +282,7 @@ DROP TABLE IF EXISTS `MonitorPresets`;
CREATE TABLE `MonitorPresets` ( CREATE TABLE `MonitorPresets` (
`Id` int(10) unsigned NOT NULL auto_increment, `Id` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(64) NOT NULL default '', `Name` varchar(64) NOT NULL default '',
`Type` enum('Local','Remote','File','Ffmpeg') NOT NULL default 'Local', `Type` enum('Local','Remote','File','Ffmpeg','Libvlc') NOT NULL default 'Local',
`Device` tinytext, `Device` tinytext,
`Channel` tinytext, `Channel` tinytext,
`Format` int(10) unsigned default NULL, `Format` int(10) unsigned default NULL,
@ -313,7 +313,7 @@ DROP TABLE IF EXISTS `Monitors`;
CREATE TABLE `Monitors` ( CREATE TABLE `Monitors` (
`Id` int(10) unsigned NOT NULL auto_increment, `Id` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(64) NOT NULL default '', `Name` varchar(64) NOT NULL default '',
`Type` enum('Local','Remote','File','Ffmpeg') NOT NULL default 'Local', `Type` enum('Local','Remote','File','Ffmpeg','Libvlc') NOT NULL default 'Local',
`Function` enum('None','Monitor','Modect','Record','Mocord','Nodect') NOT NULL default 'Monitor', `Function` enum('None','Monitor','Modect','Record','Mocord','Nodect') NOT NULL default 'Monitor',
`Enabled` tinyint(3) unsigned NOT NULL default '1', `Enabled` tinyint(3) unsigned NOT NULL default '1',
`LinkedMonitors` varchar(255) NOT NULL default '', `LinkedMonitors` varchar(255) NOT NULL default '',
@ -354,7 +354,8 @@ CREATE TABLE `Monitors` (
`MaxFPS` decimal(5,2) default NULL, `MaxFPS` decimal(5,2) default NULL,
`AlarmMaxFPS` decimal(5,2) default NULL, `AlarmMaxFPS` decimal(5,2) default NULL,
`FPSReportInterval` smallint(5) unsigned NOT NULL default '250', `FPSReportInterval` smallint(5) unsigned NOT NULL default '250',
`RefBlendPerc` tinyint(3) unsigned NOT NULL default '10', `RefBlendPerc` tinyint(3) unsigned NOT NULL default '6',
`AlarmRefBlendPerc` tinyint(3) unsigned NOT NULL default '3',
`Controllable` tinyint(3) unsigned NOT NULL default '0', `Controllable` tinyint(3) unsigned NOT NULL default '0',
`ControlId` int(10) unsigned NOT NULL default '0', `ControlId` int(10) unsigned NOT NULL default '0',
`ControlDevice` varchar(255) default NULL, `ControlDevice` varchar(255) default NULL,

9
db/zm_update-1.26.5.sql Normal file
View File

@ -0,0 +1,9 @@
--
-- This updates a 1.26.4 database to 1.26.5
--
--
-- Add AlarmRefBlendPerc field for controlling the reference image blend percent during alarm (see pull request #241)
--
ALTER TABLE `Monitors` ADD `AlarmRefBlendPerc` TINYINT(3) UNSIGNED NOT NULL DEFAULT '3' AFTER `RefBlendPerc`;

11
db/zm_update-1.26.6.sql Normal file
View File

@ -0,0 +1,11 @@
--
-- This updates a 1.26.5 database to 1.26.6
--
--
-- Add Libvlc monitor type
--
ALTER TABLE Controls modify column Type enum('Local','Remote','Ffmpeg','Libvlc') NOT NULL default 'Local';
ALTER TABLE MonitorPresets modify column Type enum('Local','Remote','File','Ffmpeg','Libvlc') NOT NULL default 'Local';
ALTER TABLE Monitors modify column Type enum('Local','Remote','File','Ffmpeg','Libvlc') NOT NULL default 'Local';

View File

@ -1,4 +1,4 @@
zoneminder (1.26.4-1) unstable; urgency=low zoneminder (1.26.5-1) unstable; urgency=low
* improvements to zmupdate.pl, cleanups * improvements to zmupdate.pl, cleanups

View File

@ -2,13 +2,32 @@ Source: zoneminder
Section: net Section: net
Priority: optional Priority: optional
Maintainer: Isaac Connor <iconnor@connortechnology.com> Maintainer: Isaac Connor <iconnor@connortechnology.com>
Build-Depends: debhelper (>= 5), autoconf, automake, dpatch, libphp-serialization-perl, libgnutls-dev, libmysqlclient-dev, libdbd-mysql-perl, libdate-manip-perl, libwww-perl, libjpeg8-dev, libpcre3-dev, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libv4l-dev (>= 0.8.3), libbz2-dev, libtool, libsys-mmap-perl, ffmpeg, libnetpbm10-dev, libavdevice-dev, libdevice-serialport-perl, libpcre3, libarchive-zip-perl, libmime-lite-perl, libjpeg8, dh-autoreconf Build-Depends: debhelper (>= 7.0.50), autoconf, automake, dpatch, libphp-serialization-perl, libgnutls-dev, libmysqlclient-dev, libdbd-mysql-perl, libdate-manip-perl, libwww-perl, libjpeg8-dev, libpcre3-dev, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libv4l-dev (>= 0.8.3), libbz2-dev, libtool, libsys-mmap-perl, ffmpeg, libnetpbm10-dev, libavdevice-dev, libdevice-serialport-perl, libpcre3, libarchive-zip-perl, libmime-lite-perl, libjpeg8, dh-autoreconf
Standards-Version: 3.9.2 Standards-Version: 3.9.2
Package: zoneminder Package: zoneminder
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, apache2, libapache2-mod-php5, php5, php5-mysql, libphp-serialization-perl, libdate-manip-perl, libmime-lite-perl, libmime-lite-perl, mysql-client, libwww-perl, libarchive-tar-perl, libarchive-zip-perl, libdevice-serialport-perl, libpcre3, ffmpeg, rsyslog | system-log-daemon, libmodule-load-perl, libsys-mmap-perl, libjson-any-perl, netpbm, libavdevice53, libjpeg8, zip, libnet-sftp-foreign-perl Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, apache2, libapache2-mod-php5, php5, php5-mysql, libphp-serialization-perl, libdate-manip-perl, libmime-lite-perl, libmime-lite-perl, mysql-client, libwww-perl, libarchive-tar-perl, libarchive-zip-perl, libdevice-serialport-perl, libpcre3, ffmpeg, rsyslog | system-log-daemon, libmodule-load-perl, libsys-mmap-perl, libjson-any-perl, netpbm, libavdevice53, libjpeg8, zip, libnet-sftp-foreign-perl
Description: Linux video camera security and surveillance solution Recommends: mysql-server
Description: A video camera security and surveillance solution
ZoneMinder is intended for use in single or multi-camera video security
applications, including commercial or home CCTV, theft prevention and child
or family member or home monitoring and other care scenarios. It
supports capture, analysis, recording, and monitoring of video data coming
from one or more video or network cameras attached to a Linux system.
ZoneMinder also support web and semi-automatic control of Pan/Tilt/Zoom
cameras using a variety of protocols. It is suitable for use as a home
video security system and for commercial or professional video security
and surveillance. It can also be integrated into a home automation system
via X.10 or other protocols.
Package: zoneminder-dbg
Architecture: any
Depends:
zoneminder (= ${binary:Version}),
${misc:Depends}
Description: debugging syumbols for zoneminder.
ZoneMinder is a video camera security and surveillance solution.
ZoneMinder is intended for use in single or multi-camera video security ZoneMinder is intended for use in single or multi-camera video security
applications, including commercial or home CCTV, theft prevention and child applications, including commercial or home CCTV, theft prevention and child
or family member or home monitoring and other care scenarios. It or family member or home monitoring and other care scenarios. It

View File

@ -25,7 +25,6 @@ start() {
echo -n "Starting $prog: " echo -n "Starting $prog: "
mkdir -p $RUNDIR && chown www-data:www-data $RUNDIR mkdir -p $RUNDIR && chown www-data:www-data $RUNDIR
mkdir -p $TMPDIR && chown www-data:www-data $TMPDIR mkdir -p $TMPDIR && chown www-data:www-data $TMPDIR
zmfix -a
$command start $command start
RETVAL=$? RETVAL=$?
[ $RETVAL = 0 ] && echo success [ $RETVAL = 0 ] && echo success

View File

@ -71,3 +71,7 @@ override_dh_fixperms:
override_dh_auto_test: override_dh_auto_test:
# do not run tests... # do not run tests...
.PHONY: override_dh_strip
override_dh_strip:
dh_strip --dbg-package=zoneminder-dbg

View File

@ -25,7 +25,7 @@ New installs
introduce an obvious security issue. The following should set this up: introduce an obvious security issue. The following should set this up:
mysql -u root -p mysql -u root -p
grant select,insert,update,delete,alter on zm.* to grant select,insert,update,delete,lock tables,alter on zm.* to
'zmuser'@localhost identified by 'zmpass'; 'zmuser'@localhost identified by 'zmpass';
Obviously, change at least zmpass to an actual, secure password or Obviously, change at least zmpass to an actual, secure password or

View File

@ -4,7 +4,7 @@
%define zmgid_final apache %define zmgid_final apache
Name: zoneminder Name: zoneminder
Version: 1.26.4 Version: 1.26.5
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons
@ -126,7 +126,6 @@ fi
%{_bindir}/zmdc.pl %{_bindir}/zmdc.pl
%{_bindir}/zmf %{_bindir}/zmf
%{_bindir}/zmfilter.pl %{_bindir}/zmfilter.pl
%attr(4755,root,root) %{_bindir}/zmfix
%{_bindir}/zmpkg.pl %{_bindir}/zmpkg.pl
%{_bindir}/zmstreamer %{_bindir}/zmstreamer
%{_bindir}/zmtrack.pl %{_bindir}/zmtrack.pl
@ -139,7 +138,7 @@ fi
#%{_bindir}/zmx10.pl #%{_bindir}/zmx10.pl
%{perl_vendorlib}/ZoneMinder* %{perl_vendorlib}/ZoneMinder*
%{perl_vendorlib}/x86_64-linux-thread-multi/auto/ZoneMinder* %{perl_vendorlib}/%{_arch}-linux-thread-multi/auto/ZoneMinder*
#%{perl_archlib}/ZoneMinder* #%{perl_archlib}/ZoneMinder*
%{_mandir}/man*/* %{_mandir}/man*/*
%dir %{_libexecdir}/zoneminder %dir %{_libexecdir}/zoneminder
@ -160,6 +159,10 @@ fi
%changelog %changelog
* Mon Dec 16 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.5
- This is a bug fixe release
- RTSP fixes, cmake enhancements, couple other misc fixes
* Mon Oct 07 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4 * Mon Oct 07 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
- Initial cmake build. - Initial cmake build.

View File

@ -8,7 +8,7 @@
%define zmgid_final apache %define zmgid_final apache
Name: zoneminder Name: zoneminder
Version: 1.26.4 Version: 1.26.5
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons
@ -228,7 +228,6 @@ fi
%{_bindir}/zmdc.pl %{_bindir}/zmdc.pl
%{_bindir}/zmf %{_bindir}/zmf
%{_bindir}/zmfilter.pl %{_bindir}/zmfilter.pl
%attr(4755,root,root) %{_bindir}/zmfix
%{_bindir}/zmpkg.pl %{_bindir}/zmpkg.pl
%{_bindir}/zmstreamer %{_bindir}/zmstreamer
%{_bindir}/zmtrack.pl %{_bindir}/zmtrack.pl
@ -259,6 +258,10 @@ fi
%changelog %changelog
* Mon Dec 16 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.5
- This is a bug fixe release
- RTSP fixes, cmake enhancements, couple other misc fixes
* Sat Oct 05 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4 * Sat Oct 05 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
- Fedora specific path changes have been moved to zoneminder-1.26.0-defaults.patch - Fedora specific path changes have been moved to zoneminder-1.26.0-defaults.patch
- All files are now part of the zoneminder source tree. Update specfile accordingly. - All files are now part of the zoneminder source tree. Update specfile accordingly.

View File

@ -1,5 +1,6 @@
[Unit] [Unit]
Description=Video security and surveillance system Description=Video security and surveillance system
After=mysqld.service
[Service] [Service]
Type=forking Type=forking

View File

@ -15,7 +15,7 @@
mysql -uroot -p mysql -uroot -p
mysql> create database zm; mysql> create database zm;
mysql> grant select,insert,update,delete,alter on zm.* to mysql> grant select,insert,update,delete,lock tables,alter on zm.* to
'zmuser'@localhost identified by 'zmpass'; 'zmuser'@localhost identified by 'zmpass';
mysql> exit; mysql> exit;
mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql

View File

@ -4,7 +4,7 @@
%define zmgid_final apache %define zmgid_final apache
Name: zoneminder Name: zoneminder
Version: 1.26.4 Version: 1.26.5
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons
@ -124,7 +124,6 @@ rm -rf %{_docdir}/%{name}-%{version}
%{_bindir}/zmdc.pl %{_bindir}/zmdc.pl
%{_bindir}/zmf %{_bindir}/zmf
%{_bindir}/zmfilter.pl %{_bindir}/zmfilter.pl
%attr(4755,root,root) %{_bindir}/zmfix
%{_bindir}/zmpkg.pl %{_bindir}/zmpkg.pl
%{_bindir}/zmstreamer %{_bindir}/zmstreamer
%{_bindir}/zmtrack.pl %{_bindir}/zmtrack.pl
@ -136,7 +135,7 @@ rm -rf %{_docdir}/%{name}-%{version}
%{_bindir}/zmx10.pl %{_bindir}/zmx10.pl
%{perl_vendorlib}/ZoneMinder* %{perl_vendorlib}/ZoneMinder*
%{perl_vendorlib}/x86_64-linux-thread-multi/auto/ZoneMinder* %{perl_vendorlib}/%{_arch}-linux-thread-multi/auto/ZoneMinder*
%{_mandir}/man*/* %{_mandir}/man*/*
%dir %{_libexecdir}/%{name} %dir %{_libexecdir}/%{name}
%{_libexecdir}/%{name}/cgi-bin %{_libexecdir}/%{name}/cgi-bin
@ -155,6 +154,10 @@ rm -rf %{_docdir}/%{name}-%{version}
%changelog %changelog
* Mon Dec 16 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.5
- This is a bug fixe release
- RTSP fixes, cmake enhancements, couple other misc fixes
* Sat Oct 19 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4 * Sat Oct 19 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
- Streamline the cmake build. Move much code into cmakelist.txt file. - Streamline the cmake build. Move much code into cmakelist.txt file.

View File

@ -8,7 +8,7 @@
%define zmgid_final apache %define zmgid_final apache
Name: zoneminder Name: zoneminder
Version: 1.26.4 Version: 1.26.5
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons
@ -233,7 +233,6 @@ fi
%{_bindir}/zmdc.pl %{_bindir}/zmdc.pl
%{_bindir}/zmf %{_bindir}/zmf
%{_bindir}/zmfilter.pl %{_bindir}/zmfilter.pl
%attr(4755,root,root) %{_bindir}/zmfix
%{_bindir}/zmpkg.pl %{_bindir}/zmpkg.pl
%{_bindir}/zmstreamer %{_bindir}/zmstreamer
%{_bindir}/zmtrack.pl %{_bindir}/zmtrack.pl
@ -263,6 +262,10 @@ fi
%changelog %changelog
* Mon Dec 16 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.5
- This is a bug fixe release
- RTSP fixes, cmake enhancements, couple other misc fixes
* Sun Oct 06 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4 * Sun Oct 06 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
- All files are now part of the zoneminder source tree. Update specfile accordingly. - All files are now part of the zoneminder source tree. Update specfile accordingly.

View File

@ -26,7 +26,8 @@ command="$ZM_PATH_BIN/zmpkg.pl"
start() start()
{ {
zmupdate || return $? # Commenting out as it is not needed. Leaving as a placeholder for future use.
# zmupdate || return $?
loadconf || return $? loadconf || return $?
#Make sure the directory for our PID folder exists or create one. #Make sure the directory for our PID folder exists or create one.
[ ! -d $pidfile ] \ [ ! -d $pidfile ] \

View File

@ -1,4 +1,4 @@
zoneminder (1.26.4-2) precise; urgency=high zoneminder (1.26.5-1) precise; urgency=high
* improvements to zmupdate.pl, cleanups * improvements to zmupdate.pl, cleanups

View File

@ -2,13 +2,32 @@ Source: zoneminder
Section: net Section: net
Priority: optional Priority: optional
Maintainer: Isaac Connor <iconnor@connortechnology.com> Maintainer: Isaac Connor <iconnor@connortechnology.com>
Build-Depends: debhelper (>= 5), autoconf, automake, dpatch, libphp-serialization-perl, libgnutls-dev, libmysqlclient-dev, libdbd-mysql-perl, libdate-manip-perl, libwww-perl, libjpeg8-dev, libpcre3-dev, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libv4l-dev (>= 0.8.3), libbz2-dev, libtool, libsys-mmap-perl, ffmpeg, libnetpbm10-dev, libavdevice-dev, libdevice-serialport-perl, libpcre3, libarchive-zip-perl, libmime-lite-perl, libjpeg8, dh-autoreconf Build-Depends: debhelper (>= 7.0.50), autoconf, automake, dpatch, libphp-serialization-perl, libgnutls-dev, libmysqlclient-dev, libdbd-mysql-perl, libdate-manip-perl, libwww-perl, libjpeg8-dev, libpcre3-dev, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libv4l-dev (>= 0.8.3), libbz2-dev, libtool, libsys-mmap-perl, ffmpeg, libnetpbm10-dev, libavdevice-dev, libdevice-serialport-perl, libpcre3, libarchive-zip-perl, libmime-lite-perl, libjpeg8, dh-autoreconf
Standards-Version: 3.9.2 Standards-Version: 3.9.2
Package: zoneminder Package: zoneminder
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, apache2, libapache2-mod-php5, php5, php5-mysql, libphp-serialization-perl, libdate-manip-perl, libmime-lite-perl, libmime-lite-perl, mysql-client, libwww-perl, libarchive-tar-perl, libarchive-zip-perl, libdevice-serialport-perl, libpcre3, ffmpeg, rsyslog | system-log-daemon, libmodule-load-perl, libsys-mmap-perl, libjson-any-perl, netpbm, libavdevice53, libjpeg8, zip, libnet-sftp-foreign-perl Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, apache2, libapache2-mod-php5, php5, php5-mysql, libphp-serialization-perl, libdate-manip-perl, libmime-lite-perl, libmime-lite-perl, mysql-client, libwww-perl, libarchive-tar-perl, libarchive-zip-perl, libdevice-serialport-perl, libpcre3, ffmpeg, rsyslog | system-log-daemon, libmodule-load-perl, libsys-mmap-perl, libjson-any-perl, netpbm, libavdevice53, libjpeg8, zip, libnet-sftp-foreign-perl
Description: Linux video camera security and surveillance solution SUggests: mysql-server
Description: A video camera security and surveillance solution
ZoneMinder is intended for use in single or multi-camera video security
applications, including commercial or home CCTV, theft prevention and child
or family member or home monitoring and other care scenarios. It
supports capture, analysis, recording, and monitoring of video data coming
from one or more video or network cameras attached to a Linux system.
ZoneMinder also support web and semi-automatic control of Pan/Tilt/Zoom
cameras using a variety of protocols. It is suitable for use as a home
video security system and for commercial or professional video security
and surveillance. It can also be integrated into a home automation system
via X.10 or other protocols.
Package: zoneminder-dbg
Architecture: any
Depends:
zoneminder (= ${binary:Version}),
${misc:Depends}
Description: debugging syumbols for zoneminder.
ZoneMinder is a video camera security and surveillance solution.
ZoneMinder is intended for use in single or multi-camera video security ZoneMinder is intended for use in single or multi-camera video security
applications, including commercial or home CCTV, theft prevention and child applications, including commercial or home CCTV, theft prevention and child
or family member or home monitoring and other care scenarios. It or family member or home monitoring and other care scenarios. It

View File

@ -25,7 +25,6 @@ start() {
echo -n "Starting $prog: " echo -n "Starting $prog: "
mkdir -p $RUNDIR && chown www-data:www-data $RUNDIR mkdir -p $RUNDIR && chown www-data:www-data $RUNDIR
mkdir -p $TMPDIR && chown www-data:www-data $TMPDIR mkdir -p $TMPDIR && chown www-data:www-data $TMPDIR
zmfix -a
$command start $command start
RETVAL=$? RETVAL=$?
[ $RETVAL = 0 ] && echo success [ $RETVAL = 0 ] && echo success

View File

@ -2,9 +2,8 @@
set -e set -e
VERSION=1.26.4
if [ "$1" = "configure" ]; then if [ "$1" = "configure" ]; then
if [ -e "/etc/init.d/mysql" ]; then
# #
# Get mysql started if it isn't # Get mysql started if it isn't
# #
@ -19,22 +18,15 @@ if [ "$1" = "configure" ]; then
echo 'grant lock tables, alter,select,insert,update,delete on zm.* to 'zmuser'@localhost identified by "zmpass";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql echo 'grant lock tables, alter,select,insert,update,delete on zm.* to 'zmuser'@localhost identified by "zmpass";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql
fi fi
# get old version from upgrade...
OLD_ZM_VERSION=${2%-*}
if [ -z "$OLD_ZM_VERSION" ]; then
# fall back to getting version from database itself, which may not necessarily be accurate?
OLD_ZM_VERSION=$(echo 'select Value from Config where Name = "ZM_DYN_CURR_VERSION";' | mysql --defaults-file=/etc/mysql/debian.cnf --skip-column-names zm )
fi
if [ -n "$OLD_ZM_VERSION" ] && [ "$OLD_ZM_VERSION" != "$VERSION" ] ; then
echo 'grant lock tables, create, alter on zm.* to 'zmuser'@localhost identified by "zmpass";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql
# stop zoneminder before performing database upgrade.
invoke-rc.d zoneminder stop || true invoke-rc.d zoneminder stop || true
zmupdate.pl --nointeractive --version $OLD_ZM_VERSION zmupdate.pl --nointeractive
fi
else else
echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.' echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.'
fi fi
else
echo 'mysql not found, assuming remote server.'
fi
chown www-data:www-data /var/log/zm chown www-data:www-data /var/log/zm
chown www-data:www-data /var/lib/zm/ chown www-data:www-data /var/lib/zm/
if [ -z "$2" ]; then if [ -z "$2" ]; then
@ -55,10 +47,7 @@ if [ "$1" = "configure" ]; then
chown www-data:www-data -R /var/cache/zoneminder chown www-data:www-data -R /var/cache/zoneminder
else else
chown www-data:www-data /var/log/zm chown www-data:www-data /var/log/zm
OLD_ZM_VERSION=${2%-*} zmupdate.pl
if [ "$OLD_ZM_VERSION" != "$VERSION" ] ; then
zmupdate.pl --version $OLD_ZM_VERSION
fi
fi fi
fi fi
#DEBHELPER# #DEBHELPER#

View File

@ -9,9 +9,6 @@
# Uncomment this to turn on verbose mode. # Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1 #export DH_VERBOSE=1
UPSTREAM_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ' | cut -d - -f 1)
POSTINST_VERSION := $(shell egrep ^VERSION= debian/postinst | cut -d = -f 2)
# These are used for cross-compiling and for saving the configure script # These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already) # from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
@ -34,9 +31,6 @@ override_dh_auto_configure:
CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --sysconfdir=/etc/zm --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --with-mysql=/usr --with-webdir=/usr/share/zoneminder --with-ffmpeg=/usr --with-cgidir=/usr/lib/cgi-bin --with-webuser=www-data --with-webgroup=www-data --enable-crashtrace=no --enable-mmap=yes CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --sysconfdir=/etc/zm --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --with-mysql=/usr --with-webdir=/usr/share/zoneminder --with-ffmpeg=/usr --with-cgidir=/usr/lib/cgi-bin --with-webuser=www-data --with-webgroup=www-data --enable-crashtrace=no --enable-mmap=yes
override_dh_clean: override_dh_clean:
# check to make sure that postinst contains the correct upstream version
[ $(UPSTREAM_VERSION) = $(POSTINST_VERSION) ]
# Add here commands to clean up after the build process. # Add here commands to clean up after the build process.
[ ! -f Makefile ] || $(MAKE) distclean [ ! -f Makefile ] || $(MAKE) distclean
dh_clean dh_clean
@ -71,3 +65,7 @@ override_dh_fixperms:
override_dh_auto_test: override_dh_auto_test:
# do not run tests... # do not run tests...
.PHONY: override_dh_strip
override_dh_strip:
dh_strip --dbg-package=zoneminder-dbg

View File

@ -32,6 +32,8 @@ require Exporter;
our @ISA = qw(Exporter); our @ISA = qw(Exporter);
use constant ZM_VERSION => "@VERSION@";
# Items to export into callers namespace by default. Note: do not export # Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead. # names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants. # Do not simply export all your public functions/methods/constants.
@ -39,7 +41,7 @@ our @ISA = qw(Exporter);
# This allows declaration use ZoneMinder ':all'; # This allows declaration use ZoneMinder ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory. # will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw() ] ); our %EXPORT_TAGS = ( 'all' => [ qw(ZM_VERSION) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

View File

@ -33,6 +33,7 @@ require ZoneMinder::Base;
our @ISA = qw(Exporter ZoneMinder::Base); our @ISA = qw(Exporter ZoneMinder::Base);
use vars qw( %Config );
# Items to export into callers namespace by default. Note: do not export # Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead. # names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants. # Do not simply export all your public functions/methods/constants.
@ -40,7 +41,7 @@ our @ISA = qw(Exporter ZoneMinder::Base);
# This allows declaration use ZoneMinder ':all'; # This allows declaration use ZoneMinder ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory. # will save memory.
our @EXPORT_CONFIG; # Get populated by BEGIN our @EXPORT_CONFIG = qw( %Config ); # Get populated by BEGIN
our %EXPORT_TAGS = ( our %EXPORT_TAGS = (
'constants' => [ qw( 'constants' => [ qw(
@ -64,11 +65,9 @@ use Carp;
# Load the config from the database into the symbol table # Load the config from the database into the symbol table
BEGIN BEGIN
{ {
no strict 'refs';
my $config_file = ZM_CONFIG; my $config_file = ZM_CONFIG;
( my $local_config_file = $config_file ) =~ s|^.*/|./|; ( my $local_config_file = $config_file ) =~ s|^.*/|./|;
if ( -s $local_config_file && -r $local_config_file ) if ( -s $local_config_file and -r $local_config_file )
{ {
print( STDERR "Warning, overriding installed $local_config_file file with local copy\n" ); print( STDERR "Warning, overriding installed $local_config_file file with local copy\n" );
$config_file = $local_config_file; $config_file = $local_config_file;
@ -78,25 +77,26 @@ BEGIN
{ {
next if ( $str =~ /^\s*$/ ); next if ( $str =~ /^\s*$/ );
next if ( $str =~ /^\s*#/ ); next if ( $str =~ /^\s*#/ );
my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*(.+?)\s*$/; my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*(.*?)\s*$/;
if ( ! $name ) {
print( STDERR "Warning, bad line in $config_file: $str\n" );
next;
} # end if
$name =~ tr/a-z/A-Z/; $name =~ tr/a-z/A-Z/;
*{$name} = sub { $value }; $Config{$name} = $value;
push( @EXPORT_CONFIG, $name );
} }
close( CONFIG ); close( CONFIG );
use DBI; use DBI;
my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_HOST, &ZM_DB_USER, &ZM_DB_PASS ); my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} ) or croak( "Can't connect to db" );
my $sql = "select * from Config"; my $sql = 'select * from Config';
my $sth = $dbh->prepare_cached( $sql ) or croak( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or croak( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or croak( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute() or croak( "Can't execute: ".$sth->errstr() );
while( my $config = $sth->fetchrow_hashref() ) while( my $config = $sth->fetchrow_hashref() ) {
{ $Config{$config->{Name}} = $config->{Value};
*{$config->{Name}} = sub { $config->{Value} };
push( @EXPORT_CONFIG, $config->{Name} );
} }
$sth->finish(); $sth->finish();
$dbh->disconnect(); #$dbh->disconnect();
} }
1; 1;
@ -116,7 +116,7 @@ The ZoneMinder::Config module is used to import the ZoneMinder configuration fro
Once the configuration has been imported then configuration variables are defined as constants and can be accessed directory by name, e.g. Once the configuration has been imported then configuration variables are defined as constants and can be accessed directory by name, e.g.
$lang = ZM_LANG_DEFAULT; $lang = $Config{ZM_LANG_DEFAULT};
=head2 EXPORT =head2 EXPORT

View File

@ -68,7 +68,7 @@ use Carp;
sub loadConfigFromDB sub loadConfigFromDB
{ {
print( "Loading config from DB\n" ); print( "Loading config from DB\n" );
my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} );
if ( !$dbh ) if ( !$dbh )
{ {
@ -111,13 +111,19 @@ sub loadConfigFromDB
sub saveConfigToDB sub saveConfigToDB
{ {
print( "Saving config to DB\n" ); print( "Saving config to DB\n" );
my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} );
if ( !$dbh ) if ( !$dbh )
{ {
print( "Error: unable to save options to database: $DBI::errstr\n" ); print( "Error: unable to save options to database: $DBI::errstr\n" );
return( 0 ); return( 0 );
} }
my $ac = $dbh->{AutoCommit};
$dbh->{AutoCommit} = 0;
$dbh->do('LOCK TABLE Config WRITE') or croak( "Can't lock Config table: " . $dbh->errstr() );
my $sql = "delete from Config"; my $sql = "delete from Config";
my $res = $dbh->do( $sql ) or croak( "Can't do '$sql': ".$dbh->errstr() ); my $res = $dbh->do( $sql ) or croak( "Can't do '$sql': ".$dbh->errstr() );
@ -149,6 +155,10 @@ sub saveConfigToDB
my $res = $sth->execute( $option->{id}, $option->{name}, $option->{db_value}, $option->{db_type}, $option->{default}, $option->{db_hint}, $option->{db_pattern}, $option->{db_format}, $option->{description}, $option->{help}, $option->{category}, $option->{readonly}?1:0, $option->{db_requires} ) or croak( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $option->{id}, $option->{name}, $option->{db_value}, $option->{db_type}, $option->{default}, $option->{db_hint}, $option->{db_pattern}, $option->{db_format}, $option->{description}, $option->{help}, $option->{category}, $option->{readonly}?1:0, $option->{db_requires} ) or croak( "Can't execute: ".$sth->errstr() );
} }
$sth->finish(); $sth->finish();
$dbh->do('UNLOCK TABLES');
$dbh->{AutoCommit} = $ac;
$dbh->disconnect(); $dbh->disconnect();
} }

View File

@ -331,14 +331,6 @@ our @options =
type => $types{boolean}, type => $types{boolean},
category => "config", category => "config",
}, },
{
name => "ZM_BLEND_ALARMED_IMAGES",
default => "yes",
description => "Blend alarmed images to update the reference image",
help => "To detect alarms ZoneMinder compares an image with a reference image which is formed from a composite of the previous images. This option determines whether images that cause events are included in this process. Doing so may increase the precision of the alarmed region but can cause problems if wholescale lighting changes cause alarms as this would not get fed back into the image and an alarm may persist indefinately. A better way to achive the same effect in most cases is to lower substantially the reference blend percentage in specific monitors.",
type => $types{boolean},
category => "config",
},
{ {
name => "ZM_MAX_SUSPEND_TIME", name => "ZM_MAX_SUSPEND_TIME",
default => "30", default => "30",
@ -370,7 +362,7 @@ our @options =
name => "ZM_HTTP_VERSION", name => "ZM_HTTP_VERSION",
default => "1.0", default => "1.0",
description => "The version of HTTP that ZoneMinder will use to connect", description => "The version of HTTP that ZoneMinder will use to connect",
help => "ZoneMinder can communicate with network cameras using either of the HTTP/1.1 or HTTP/1.0 standard. A server will normally fall back to the version it supports iwht no problem so this should usually by left at the default. However it can be changed to HTTP/1.0 if necessary to resolve particular issues.", help => "ZoneMinder can communicate with network cameras using either of the HTTP/1.1 or HTTP/1.0 standard. A server will normally fall back to the version it supports with no problem so this should usually by left at the default. However it can be changed to HTTP/1.0 if necessary to resolve particular issues.",
type => { db_type=>"string", hint=>"1.1|1.0", pattern=>qr|^(1\.[01])$|, format=>q( $1?$1:"" ) }, type => { db_type=>"string", hint=>"1.1|1.0", pattern=>qr|^(1\.[01])$|, format=>q( $1?$1:"" ) },
category => "network", category => "network",
}, },

View File

@ -37,7 +37,6 @@ require ZoneMinder::Base;
require ZoneMinder::Control; require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# =================================================================================================================================== # ===================================================================================================================================
# #
# FI8608W FOSCAM PT H264 Control Protocol # FI8608W FOSCAM PT H264 Control Protocol
@ -111,7 +110,7 @@ sub open
$self->loadMonitor(); $self->loadMonitor();
use LWP::UserAgent; use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new; $self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open'; $self->{state} = 'open';
} }

View File

@ -41,7 +41,6 @@ require ZoneMinder::Base;
require ZoneMinder::Control; require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# =================================================================================================================================== # ===================================================================================================================================
# #
# FI8620 FOSCAM Dome PTZ H264 Control Protocol # FI8620 FOSCAM Dome PTZ H264 Control Protocol
@ -117,7 +116,7 @@ sub open
$self->loadMonitor(); $self->loadMonitor();
use LWP::UserAgent; use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new; $self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open'; $self->{state} = 'open';
} }

View File

@ -36,7 +36,6 @@ require ZoneMinder::Base;
require ZoneMinder::Control; require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# =================================================================================================================================== # ===================================================================================================================================
# #
# FI9821 FOSCAM PT H264 Control Protocol # FI9821 FOSCAM PT H264 Control Protocol
@ -91,7 +90,7 @@ sub open
$self->loadMonitor(); $self->loadMonitor();
use LWP::UserAgent; use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new; $self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open'; $self->{state} = 'open';
} }

View File

@ -36,8 +36,6 @@ require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
our %CamParams = (); our %CamParams = ();
# ========================================================================== # ==========================================================================
@ -91,7 +89,7 @@ sub open
use LWP::UserAgent; use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new; $self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open'; $self->{state} = 'open';
} }

View File

@ -33,8 +33,6 @@ require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
# #
# Ncs370 IP Control Protocol # Ncs370 IP Control Protocol
@ -79,7 +77,7 @@ sub open
use LWP::UserAgent; use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new; $self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open'; $self->{state} = 'open';
} }

View File

@ -33,8 +33,6 @@ require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
# #
# Panasonic IP Control Protocol # Panasonic IP Control Protocol
@ -79,7 +77,7 @@ sub open
use LWP::UserAgent; use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new; $self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open'; $self->{state} = 'open';
} }

View File

@ -33,8 +33,6 @@ require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
# #
# Pelco-D Control Protocol # Pelco-D Control Protocol

View File

@ -33,8 +33,6 @@ require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
# #
# Pelco-P Control Protocol # Pelco-P Control Protocol

View File

@ -34,8 +34,6 @@ require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
# #
# Airlink SkyIPCam AICN747/AICN747W Control Protocol # Airlink SkyIPCam AICN747/AICN747W Control Protocol
@ -80,7 +78,7 @@ sub open
use LWP::UserAgent; use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new; $self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open'; $self->{state} = 'open';
} }

View File

@ -33,8 +33,6 @@ require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
# #
# Visca Control Protocol # Visca Control Protocol

View File

@ -33,8 +33,6 @@ require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
# #
# mjpgSTreamer Control Protocol # mjpgSTreamer Control Protocol
@ -81,7 +79,7 @@ sub open
Debug( "Camera open" ); Debug( "Camera open" );
use LWP::UserAgent; use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new; $self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION ); $self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open'; $self->{state} = 'open';
} }

View File

@ -79,15 +79,15 @@ sub zmDbConnect( ;$ )
} }
if ( !defined( $dbh ) ) if ( !defined( $dbh ) )
{ {
my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ ); my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
if ( defined($port) ) if ( defined($port) )
{ {
$dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".$host.";port=".$port, ZM_DB_USER, ZM_DB_PASS ); $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$host.";port=".$port, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} );
} }
else else
{ {
$dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} );
} }
$dbh->trace( 0 ); $dbh->trace( 0 );
} }

View File

@ -95,7 +95,7 @@ sub getCmdFormat()
Debug( "Testing valid shell syntax\n" ); Debug( "Testing valid shell syntax\n" );
my ( $name ) = getpwuid( $> ); my ( $name ) = getpwuid( $> );
if ( $name eq ZM_WEB_USER ) if ( $name eq $Config{ZM_WEB_USER} )
{ {
Debug( "Running as '$name', su commands not needed\n" ); Debug( "Running as '$name', su commands not needed\n" );
return( "" ); return( "" );
@ -103,7 +103,7 @@ sub getCmdFormat()
my $null_command = "true"; my $null_command = "true";
my $prefix = "sudo -u ".ZM_WEB_USER." "; my $prefix = "sudo -u ".$Config{ZM_WEB_USER}." ";
my $suffix = ""; my $suffix = "";
my $command = $prefix.$null_command.$suffix; my $command = $prefix.$null_command.$suffix;
Debug( "Testing \"$command\"\n" ); Debug( "Testing \"$command\"\n" );
@ -120,7 +120,7 @@ sub getCmdFormat()
chomp( $output ); chomp( $output );
Debug( "Test failed, '$output'\n" ); Debug( "Test failed, '$output'\n" );
$prefix = "su ".ZM_WEB_USER." --shell=/bin/sh --command='"; $prefix = "su ".$Config{ZM_WEB_USER}." --shell=/bin/sh --command='";
$suffix = "'"; $suffix = "'";
$command = $prefix.$null_command.$suffix; $command = $prefix.$null_command.$suffix;
Debug( "Testing \"$command\"\n" ); Debug( "Testing \"$command\"\n" );
@ -136,7 +136,7 @@ sub getCmdFormat()
chomp( $output ); chomp( $output );
Debug( "Test failed, '$output'\n" ); Debug( "Test failed, '$output'\n" );
$prefix = "su ".ZM_WEB_USER." -c '"; $prefix = "su ".$Config{ZM_WEB_USER}." -c '";
$suffix = "'"; $suffix = "'";
$command = $prefix.$null_command.$suffix; $command = $prefix.$null_command.$suffix;
Debug( "Testing \"$command\"\n" ); Debug( "Testing \"$command\"\n" );
@ -172,7 +172,7 @@ sub runCommand( $ )
} }
my $command = shift; my $command = shift;
$command = ZM_PATH_BIN."/".$command; $command = $Config{ZM_PATH_BIN}."/".$command;
if ( $cmdPrefix ) if ( $cmdPrefix )
{ {
$command = $cmdPrefix.$command.$cmdSuffix; $command = $cmdPrefix.$command.$cmdSuffix;
@ -201,15 +201,15 @@ sub getEventPath( $ )
my $event = shift; my $event = shift;
my $event_path = ""; my $event_path = "";
if ( ZM_USE_DEEP_STORAGE ) if ( $Config{ZM_USE_DEEP_STORAGE} )
{ {
$event_path = ZM_DIR_EVENTS.'/'.$event->{MonitorId}.'/'.strftime( "%y/%m/%d/%H/%M/%S", localtime($event->{Time}) ); $event_path = $Config{ZM_DIR_EVENTS}.'/'.$event->{MonitorId}.'/'.strftime( "%y/%m/%d/%H/%M/%S", localtime($event->{Time}) );
} }
else else
{ {
$event_path = ZM_DIR_EVENTS.'/'.$event->{MonitorId}.'/'.$event->{Id}; $event_path = $Config{ZM_DIR_EVENTS}.'/'.$event->{MonitorId}.'/'.$event->{Id};
} }
$event_path = ZM_PATH_WEB.'/'.$event_path if ( index(ZM_DIR_EVENTS,'/') != 0 ); $event_path = $Config{ZM_PATH_WEB}.'/'.$event_path if ( index($Config{ZM_DIR_EVENTS},'/') != 0 );
return( $event_path ); return( $event_path );
} }
@ -219,10 +219,10 @@ sub createEventPath( $ )
# WARNING assumes running from events directory # WARNING assumes running from events directory
# #
my $event = shift; my $event = shift;
my $eventRootPath = (ZM_DIR_EVENTS=~m|/|)?ZM_DIR_EVENTS:(ZM_PATH_WEB.'/'.ZM_DIR_EVENTS); my $eventRootPath = ($Config{ZM_DIR_EVENTS}=~m|/|)?$Config{ZM_DIR_EVENTS}:($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS});
my $eventPath = $eventRootPath.'/'.$event->{MonitorId}; my $eventPath = $eventRootPath.'/'.$event->{MonitorId};
if ( ZM_USE_DEEP_STORAGE ) if ( $Config{ZM_USE_DEEP_STORAGE} )
{ {
my @startTime = localtime( $event->{StartTime} ); my @startTime = localtime( $event->{StartTime} );
@ -277,10 +277,10 @@ sub _checkProcessOwner()
if ( !defined($_setFileOwner) ) if ( !defined($_setFileOwner) )
{ {
my ( $processOwner ) = getpwuid( $> ); my ( $processOwner ) = getpwuid( $> );
if ( $processOwner ne ZM_WEB_USER ) if ( $processOwner ne $Config{ZM_WEB_USER} )
{ {
# Not running as web user, so should be root in whch case chown the temporary directory # Not running as web user, so should be root in whch case chown the temporary directory
( my $ownerName, my $ownerPass, $_ownerUid, $_ownerGid ) = getpwnam( ZM_WEB_USER ) or Fatal( "Can't get user details for web user '".ZM_WEB_USER."': $!" ); ( my $ownerName, my $ownerPass, $_ownerUid, $_ownerGid ) = getpwnam( $Config{ZM_WEB_USER} ) or Fatal( "Can't get user details for web user '".$Config{ZM_WEB_USER}."': $!" );
$_setFileOwner = 1; $_setFileOwner = 1;
} }
else else
@ -297,7 +297,7 @@ sub setFileOwner( $ )
if ( _checkProcessOwner() ) if ( _checkProcessOwner() )
{ {
chown( $_ownerUid, $_ownerGid, $file ) or Fatal( "Can't change ownership of file '$file' to '".ZM_WEB_USER.":".ZM_WEB_GROUP."': $!" ); chown( $_ownerUid, $_ownerGid, $file ) or Fatal( "Can't change ownership of file '$file' to '".$Config{ZM_WEB_USER}.":".$Config{ZM_WEB_GROUP}."': $!" );
} }
} }
@ -434,12 +434,12 @@ sub createEvent( $;$ )
#$frame->{FrameId} = $dbh->{mysql_insertid}; #$frame->{FrameId} = $dbh->{mysql_insertid};
if ( $frame->{imagePath} ) if ( $frame->{imagePath} )
{ {
$frame->{capturePath} = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg", $eventPath, $frame->{FrameId} ); $frame->{capturePath} = sprintf( "%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg", $eventPath, $frame->{FrameId} );
rename( $frame->{imagePath}, $frame->{capturePath} ) or Fatal( "Can't copy ".$frame->{imagePath}." to ".$frame->{capturePath}.": $!" ); rename( $frame->{imagePath}, $frame->{capturePath} ) or Fatal( "Can't copy ".$frame->{imagePath}." to ".$frame->{capturePath}.": $!" );
setFileOwner( $frame->{capturePath} ); setFileOwner( $frame->{capturePath} );
if ( 0 && ZM_CREATE_ANALYSIS_IMAGES ) if ( 0 && $Config{ZM_CREATE_ANALYSIS_IMAGES} )
{ {
$frame->{analysePath} = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-analyse.jpg", $eventPath, $frame->{FrameId} ); $frame->{analysePath} = sprintf( "%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-analyse.jpg", $eventPath, $frame->{FrameId} );
link( $frame->{capturePath}, $frame->{analysePath} ) or Fatal( "Can't link ".$frame->{capturePath}." to ".$frame->{analysePath}.": $!" ); link( $frame->{capturePath}, $frame->{analysePath} ) or Fatal( "Can't link ".$frame->{capturePath}." to ".$frame->{analysePath}.": $!" );
setFileOwner( $frame->{analysePath} ); setFileOwner( $frame->{analysePath} );
} }
@ -497,7 +497,7 @@ sub deleteEventFiles( $;$ )
my $monitor_id = shift; my $monitor_id = shift;
$monitor_id = '*' if ( !defined($monitor_id) ); $monitor_id = '*' if ( !defined($monitor_id) );
if ( ZM_USE_DEEP_STORAGE ) if ( $Config{ZM_USE_DEEP_STORAGE} )
{ {
my $link_path = $monitor_id."/*/*/*/.".$event_id; my $link_path = $monitor_id."/*/*/*/.".$event_id;
#Debug( "LP1:$link_path" ); #Debug( "LP1:$link_path" );

View File

@ -150,7 +150,7 @@ sub new
$this->{hasTerm} = -t STDERR; $this->{hasTerm} = -t STDERR;
( $this->{fileName} = $0 ) =~ s|^.*/||; ( $this->{fileName} = $0 ) =~ s|^.*/||;
$this->{logPath} = ZM_PATH_LOGS; $this->{logPath} = $Config{ZM_PATH_LOGS};
$this->{logFile} = $this->{logPath}."/".$this->{id}.".log"; $this->{logFile} = $this->{logPath}."/".$this->{id}.".log";
$this->{trace} = 0; $this->{trace} = 0;
@ -163,7 +163,7 @@ sub BEGIN
{ {
# Fake the config variables that are used in case they are not defined yet # Fake the config variables that are used in case they are not defined yet
# Only really necessary to support upgrade from previous version # Only really necessary to support upgrade from previous version
if ( !eval('defined(ZM_LOG_DEBUG)') ) if ( !eval('defined($Config{ZM_LOG_DEBUG})') )
{ {
no strict 'subs'; no strict 'subs';
no strict 'refs'; no strict 'refs';
@ -221,7 +221,7 @@ sub initialise( @ )
} }
else else
{ {
$tempDatabaseLevel = ZM_LOG_LEVEL_DATABASE; $tempDatabaseLevel = $Config{ZM_LOG_LEVEL_DATABASE};
} }
if ( defined($options{fileLevel}) ) if ( defined($options{fileLevel}) )
{ {
@ -229,7 +229,7 @@ sub initialise( @ )
} }
else else
{ {
$tempFileLevel = ZM_LOG_LEVEL_FILE; $tempFileLevel = $Config{ZM_LOG_LEVEL_FILE};
} }
if ( defined($options{syslogLevel}) ) if ( defined($options{syslogLevel}) )
{ {
@ -237,7 +237,7 @@ sub initialise( @ )
} }
else else
{ {
$tempSyslogLevel = ZM_LOG_LEVEL_SYSLOG; $tempSyslogLevel = $Config{ZM_LOG_LEVEL_SYSLOG};
} }
if ( defined($ENV{'LOG_PRINT'}) ) if ( defined($ENV{'LOG_PRINT'}) )
@ -253,18 +253,18 @@ sub initialise( @ )
$tempFileLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_FILE')) ); $tempFileLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_FILE')) );
$tempSyslogLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_SYSLOG')) ); $tempSyslogLevel = $level if ( defined($level = $this->getTargettedEnv('LOG_LEVEL_SYSLOG')) );
if ( ZM_LOG_DEBUG ) if ( $Config{ZM_LOG_DEBUG} )
{ {
foreach my $target ( split( /\|/, ZM_LOG_DEBUG_TARGET ) ) foreach my $target ( split( /\|/, $Config{ZM_LOG_DEBUG_TARGET} ) )
{ {
if ( $target eq $this->{id} || $target eq "_".$this->{id} || $target eq $this->{idRoot} || $target eq "_".$this->{idRoot} || $target eq "" ) if ( $target eq $this->{id} || $target eq "_".$this->{id} || $target eq $this->{idRoot} || $target eq "_".$this->{idRoot} || $target eq "" )
{ {
if ( ZM_LOG_DEBUG_LEVEL > NOLOG ) if ( $Config{ZM_LOG_DEBUG_LEVEL} > NOLOG )
{ {
$tempLevel = $this->limit( ZM_LOG_DEBUG_LEVEL ); $tempLevel = $this->limit( $Config{ZM_LOG_DEBUG_LEVEL} );
if ( ZM_LOG_DEBUG_FILE ne "" ) if ( $Config{ZM_LOG_DEBUG_FILE} ne "" )
{ {
$tempLogFile = ZM_LOG_DEBUG_FILE; $tempLogFile = $Config{ZM_LOG_DEBUG_FILE};
$tempFileLevel = $tempLevel; $tempFileLevel = $tempLevel;
} }
} }
@ -447,20 +447,20 @@ sub databaseLevel( ;$ )
{ {
if ( !$this->{dbh} ) if ( !$this->{dbh} )
{ {
my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ ); my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
if ( defined($port) ) if ( defined($port) )
{ {
$this->{dbh} = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".$host.";port=".$port, ZM_DB_USER, ZM_DB_PASS ); $this->{dbh} = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$host.";port=".$port, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} );
} }
else else
{ {
$this->{dbh} = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); $this->{dbh} = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} );
} }
if ( !$this->{dbh} ) if ( !$this->{dbh} )
{ {
$databaseLevel = NOLOG; $databaseLevel = NOLOG;
Error( "Unable to write log entries to DB, can't connect to database '".ZM_DB_NAME."' on host '".ZM_DB_HOST."'" ); Error( "Unable to write log entries to DB, can't connect to database '".$Config{ZM_DB_NAME}."' on host '".$Config{ZM_DB_HOST}."'" );
} }
else else
{ {
@ -553,8 +553,8 @@ sub openFile()
{ {
LOGFILE->autoflush() if ( $this->{autoFlush} ); LOGFILE->autoflush() if ( $this->{autoFlush} );
my $webUid = (getpwnam( ZM_WEB_USER ))[2]; my $webUid = (getpwnam( $Config{ZM_WEB_USER} ))[2];
my $webGid = (getgrnam( ZM_WEB_GROUP ))[2]; my $webGid = (getgrnam( $Config{ZM_WEB_GROUP} ))[2];
if ( $> == 0 ) if ( $> == 0 )
{ {
chown( $webUid, $webGid, $this->{logFile} ) or Fatal( "Can't change permissions on log file '".$this->{logFile}."': $!" ) chown( $webUid, $webGid, $this->{logFile} ) or Fatal( "Can't change permissions on log file '".$this->{logFile}."': $!" )

View File

@ -80,7 +80,7 @@ sub zmMemAttach( $$ )
my $size = shift; my $size = shift;
if ( !defined($monitor->{MMapAddr}) ) if ( !defined($monitor->{MMapAddr}) )
{ {
my $mmap_file = ZM_PATH_MAP."/zm.mmap.".$monitor->{Id}; my $mmap_file = $Config{ZM_PATH_MAP}."/zm.mmap.".$monitor->{Id};
if ( -s $mmap_file < $size ) { if ( -s $mmap_file < $size ) {
Error( sprintf( "Memory map file '%s' should have been %d but was instead %d", $mmap_file, $size, -s $mmap_file ) ); Error( sprintf( "Memory map file '%s' should have been %d but was instead %d", $mmap_file, $size, -s $mmap_file ) );
return ( undef ); return ( undef );
@ -160,7 +160,7 @@ sub zmMemPut( $$$$ )
sub zmMemClean sub zmMemClean
{ {
Debug( "Removing memory map files\n" ); Debug( "Removing memory map files\n" );
my $mapPath = ZM_PATH_MAP."/zm.mmap.*"; my $mapPath = $Config{ZM_PATH_MAP}."/zm.mmap.*";
foreach my $mapFile( glob( $mapPath ) ) foreach my $mapFile( glob( $mapPath ) )
{ {
( $mapFile ) = $mapFile =~ /^(.+)$/; ( $mapFile ) = $mapFile =~ /^(.+)$/;

View File

@ -33,6 +33,8 @@ require ZoneMinder::Base;
our @ISA = qw(Exporter ZoneMinder::Base); our @ISA = qw(Exporter ZoneMinder::Base);
eval 'sub IPC_CREAT {0001000}' unless defined &IPC_CREAT;
# Items to export into callers namespace by default. Note: do not export # Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead. # names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants. # Do not simply export all your public functions/methods/constants.
@ -79,8 +81,8 @@ sub zmMemAttach( $$ )
my $size = shift; my $size = shift;
if ( !defined($monitor->{ShmId}) ) if ( !defined($monitor->{ShmId}) )
{ {
my $shm_key = (hex(ZM_SHM_KEY)&0xffff0000)|$monitor->{Id}; my $shm_key = (hex($Config{ZM_SHM_KEY})&0xffff0000)|$monitor->{Id};
my $shm_id = shmget( $shm_key, $size, 0 ); my $shm_id = shmget( $shm_key, $size, &IPC_CREAT | 0777 );
if ( !defined($shm_id) ) if ( !defined($shm_id) )
{ {
Error( sprintf( "Can't get shared memory id '%x', %d: $!\n", $shm_key, $monitor->{Id} ) ); Error( sprintf( "Can't get shared memory id '%x', %d: $!\n", $shm_key, $monitor->{Id} ) );
@ -139,7 +141,7 @@ sub zmMemClean
{ {
Debug( "Removing shared memory\n" ); Debug( "Removing shared memory\n" );
# Find ZoneMinder shared memory # Find ZoneMinder shared memory
my $command = "ipcs -m | grep '^".substr( sprintf( "0x%x", hex(ZM_SHM_KEY) ), 0, -2 )."'"; my $command = "ipcs -m | grep '^".substr( sprintf( "0x%x", hex($Config{ZM_SHM_KEY}) ), 0, -2 )."'";
Debug( "Checking for shared memory with '$command'\n" ); Debug( "Checking for shared memory with '$command'\n" );
open( CMD, "$command |" ) or Fatal( "Can't execute '$command': $!" ); open( CMD, "$command |" ) or Fatal( "Can't execute '$command': $!" );
while( <CMD> ) while( <CMD> )

View File

@ -26,7 +26,8 @@ command="$ZM_PATH_BIN/zmpkg.pl"
start() start()
{ {
zmupdate || return $? # Commenting out as it is not needed. Leaving as a placeholder for future use.
# zmupdate || return $?
loadconf || return $? loadconf || return $?
#Make sure the directory for our PID folder exists or create one. #Make sure the directory for our PID folder exists or create one.
[ ! -d $pidfile ] \ [ ! -d $pidfile ] \

View File

@ -57,8 +57,8 @@ use File::Find;
use Time::HiRes qw/gettimeofday/; use Time::HiRes qw/gettimeofday/;
use Getopt::Long; use Getopt::Long;
use constant IMAGE_PATH => ZM_PATH_WEB.'/'.ZM_DIR_IMAGES; use constant IMAGE_PATH => $Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_IMAGES};
use constant EVENT_PATH => (ZM_DIR_EVENTS=~m|/|)?ZM_DIR_EVENTS:(ZM_PATH_WEB.'/'.ZM_DIR_EVENTS); use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)?$Config{ZM_DIR_EVENTS}:($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS});
$| = 1; $| = 1;
@ -107,7 +107,7 @@ chdir( EVENT_PATH );
my $max_image_age = 6/24; # 6 hours my $max_image_age = 6/24; # 6 hours
my $max_swap_age = 24/24; # 24 hours my $max_swap_age = 24/24; # 24 hours
my $image_path = IMAGE_PATH; my $image_path = IMAGE_PATH;
my $swap_image_path = ZM_PATH_SWAP; my $swap_image_path = $Config{ZM_PATH_SWAP};
my $loop = 1; my $loop = 1;
my $cleaned = 0; my $cleaned = 0;
@ -142,7 +142,7 @@ MAIN: while( $loop )
my $fs_events = $fs_monitors->{$monitor} = {}; my $fs_events = $fs_monitors->{$monitor} = {};
( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ ); # De-taint ( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ ); # De-taint
if ( ZM_USE_DEEP_STORAGE ) if ( $Config{ZM_USE_DEEP_STORAGE} )
{ {
foreach my $day_dir ( <$monitor_dir/*/*/*> ) foreach my $day_dir ( <$monitor_dir/*/*/*> )
{ {
@ -399,9 +399,9 @@ MAIN: while( $loop )
File::Find::find( { wanted=>\&deleteSwapImage, untaint=>1 }, $swap_image_root ); File::Find::find( { wanted=>\&deleteSwapImage, untaint=>1 }, $swap_image_root );
# Prune the Logs table if required # Prune the Logs table if required
if ( ZM_LOG_DATABASE_LIMIT ) if ( $Config{ZM_LOG_DATABASE_LIMIT} )
{ {
if ( ZM_LOG_DATABASE_LIMIT =~ /^\d+$/ ) if ( $Config{ZM_LOG_DATABASE_LIMIT} =~ /^\d+$/ )
{ {
# Number of rows # Number of rows
my $selectLogRowCountSql = "select count(*) as Rows from Logs"; my $selectLogRowCountSql = "select count(*) as Rows from Logs";
@ -410,18 +410,18 @@ MAIN: while( $loop )
my $row = $selectLogRowCountSth->fetchrow_hashref(); my $row = $selectLogRowCountSth->fetchrow_hashref();
my $logRows = $row->{Rows}; my $logRows = $row->{Rows};
$selectLogRowCountSth->finish(); $selectLogRowCountSth->finish();
if ( $logRows > ZM_LOG_DATABASE_LIMIT ) if ( $logRows > $Config{ZM_LOG_DATABASE_LIMIT} )
{ {
my $deleteLogByRowsSql = "delete low_priority from Logs order by TimeKey asc limit ?"; my $deleteLogByRowsSql = "delete low_priority from Logs order by TimeKey asc limit ?";
my $deleteLogByRowsSth = $dbh->prepare_cached( $deleteLogByRowsSql ) or Fatal( "Can't prepare '$deleteLogByRowsSql': ".$dbh->errstr() ); my $deleteLogByRowsSth = $dbh->prepare_cached( $deleteLogByRowsSql ) or Fatal( "Can't prepare '$deleteLogByRowsSql': ".$dbh->errstr() );
$res = $deleteLogByRowsSth->execute( $logRows - ZM_LOG_DATABASE_LIMIT ) or Fatal( "Can't execute: ".$deleteLogByRowsSth->errstr() ); $res = $deleteLogByRowsSth->execute( $logRows - $Config{ZM_LOG_DATABASE_LIMIT} ) or Fatal( "Can't execute: ".$deleteLogByRowsSth->errstr() );
aud_print( "Deleted ".$deleteLogByRowsSth->rows()." log table entries by count\n" ) if ( $deleteLogByRowsSth->rows() ); aud_print( "Deleted ".$deleteLogByRowsSth->rows()." log table entries by count\n" ) if ( $deleteLogByRowsSth->rows() );
} }
} }
else else
{ {
# Time of record # Time of record
my $deleteLogByTimeSql = "delete low_priority from Logs where TimeKey < unix_timestamp(now() - interval ".ZM_LOG_DATABASE_LIMIT.")"; my $deleteLogByTimeSql = "delete low_priority from Logs where TimeKey < unix_timestamp(now() - interval ".$Config{ZM_LOG_DATABASE_LIMIT}.")";
my $deleteLogByTimeSth = $dbh->prepare_cached( $deleteLogByTimeSql ) or Fatal( "Can't prepare '$deleteLogByTimeSql': ".$dbh->errstr() ); my $deleteLogByTimeSth = $dbh->prepare_cached( $deleteLogByTimeSql ) or Fatal( "Can't prepare '$deleteLogByTimeSql': ".$dbh->errstr() );
$res = $deleteLogByTimeSth->execute() or Fatal( "Can't execute: ".$deleteLogByTimeSth->errstr() ); $res = $deleteLogByTimeSth->execute() or Fatal( "Can't execute: ".$deleteLogByTimeSth->errstr() );
aud_print( "Deleted ".$deleteLogByTimeSth->rows()." log table entries by time\n" ) if ( $deleteLogByTimeSth->rows() ); aud_print( "Deleted ".$deleteLogByTimeSth->rows()." log table entries by time\n" ) if ( $deleteLogByTimeSth->rows() );
@ -429,7 +429,7 @@ MAIN: while( $loop )
} }
$loop = $continuous; $loop = $continuous;
sleep( ZM_AUDIT_CHECK_INTERVAL ) if ( $continuous ); sleep( $Config{ZM_AUDIT_CHECK_INTERVAL} ) if $continuous;
}; };
exit( 0 ); exit( 0 );

View File

@ -88,7 +88,7 @@ if ( !$id || !$options{command} )
Debug( $arg_string ); Debug( $arg_string );
my $sock_file = ZM_PATH_SOCKS.'/zmcontrol-'.$id.'.sock'; my $sock_file = $Config{ZM_PATH_SOCKS}.'/zmcontrol-'.$id.'.sock';
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" ); socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );

View File

@ -20,6 +20,8 @@
# Edit these to suit your configuration # Edit these to suit your configuration
ZM_CONFIG=@ZM_CONFIG@ ZM_CONFIG=@ZM_CONFIG@
source $ZM_CONFIG source $ZM_CONFIG
# ZM_VERSION in the config is now deprecated but will likely still exist in people's config files. This will override it.
ZM_VERSION=@VERSION@
MYSQLDUMP=/usr/bin/mysqldump MYSQLDUMP=/usr/bin/mysqldump
BACKUP_PATH=/var/lib/zm BACKUP_PATH=/var/lib/zm

View File

@ -51,7 +51,7 @@ use Socket;
use IO::Handle; use IO::Handle;
use Data::Dumper; use Data::Dumper;
use constant SOCK_FILE => ZM_PATH_SOCKS.'/zmdc.sock'; use constant SOCK_FILE => $Config{ZM_PATH_SOCKS}.'/zmdc.sock';
$| = 1; $| = 1;
@ -437,7 +437,7 @@ sub start
if ( $daemon =~ /^${daemon_patt}$/ ) if ( $daemon =~ /^${daemon_patt}$/ )
{ {
$daemon = ZM_PATH_BIN.'/'.$1; $daemon = $Config{ZM_PATH_BIN}.'/'.$1;
} }
else else
{ {
@ -645,7 +645,7 @@ sub reaper
if ( $process->{keepalive} ) if ( $process->{keepalive} )
{ {
if ( !$process->{delay} || ($process->{runtime} > ZM_MAX_RESTART_DELAY) ) if ( !$process->{delay} || ($process->{runtime} > $Config{ZM_MAX_RESTART_DELAY} ) )
{ {
#start( $process->{daemon}, @{$process->{args}} ); #start( $process->{daemon}, @{$process->{args}} );
# Schedule for immediate restart # Schedule for immediate restart
@ -659,9 +659,9 @@ sub reaper
$process->{pending} = $process->{stopped}+$process->{delay}; $process->{pending} = $process->{stopped}+$process->{delay};
$process->{delay} *= 2; $process->{delay} *= 2;
# Limit the start delay to 15 minutes max # Limit the start delay to 15 minutes max
if ( $process->{delay} > ZM_MAX_RESTART_DELAY ) if ( $process->{delay} > $Config{ZM_MAX_RESTART_DELAY} )
{ {
$process->{delay} = ZM_MAX_RESTART_DELAY; $process->{delay} = $Config{ZM_MAX_RESTART_DELAY};
} }
} }
} }

View File

@ -23,6 +23,8 @@
# Edit these to suit your configuration # Edit these to suit your configuration
ZM_CONFIG=@ZM_CONFIG@ ZM_CONFIG=@ZM_CONFIG@
# ZM_VERSION in the config is now deprecated but will likely still exist in people's config files. This will override it.
ZM_VERSION=@VERSION@
MYSQLDUMP=/usr/bin/mysqldump MYSQLDUMP=/usr/bin/mysqldump
# The rest should not need editing # The rest should not need editing

View File

@ -51,16 +51,16 @@ use Date::Manip;
use Getopt::Long; use Getopt::Long;
use Data::Dumper; use Data::Dumper;
use constant EVENT_PATH => (ZM_DIR_EVENTS=~m|/|)?ZM_DIR_EVENTS:(ZM_PATH_WEB.'/'.ZM_DIR_EVENTS); use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)?$Config{ZM_DIR_EVENTS}:($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS});
logInit(); logInit();
logSetSignal(); logSetSignal();
if ( ZM_OPT_UPLOAD ) if ( $Config{ZM_OPT_UPLOAD} )
{ {
# Comment these out if you don't have them and don't want to upload # Comment these out if you don't have them and don't want to upload
# or don't want to use that format # or don't want to use that format
if ( ZM_UPLOAD_ARCH_FORMAT eq "zip" ) if ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq "zip" )
{ {
require Archive::Zip; require Archive::Zip;
import Archive::Zip qw( :ERROR_CODES :CONSTANTS ); import Archive::Zip qw( :ERROR_CODES :CONSTANTS );
@ -69,7 +69,7 @@ if ( ZM_OPT_UPLOAD )
{ {
require Archive::Tar; require Archive::Tar;
} }
if ( ZM_UPLOAD_PROTOCOL eq "ftp" ) if ( $Config{ZM_UPLOAD_PROTOCOL} eq "ftp" )
{ {
require Net::FTP; require Net::FTP;
} }
@ -79,9 +79,9 @@ if ( ZM_OPT_UPLOAD )
} }
} }
if ( ZM_OPT_EMAIL ) if ( $Config{ZM_OPT_EMAIL} )
{ {
if ( ZM_NEW_MAIL_MODULES ) if ( $Config{ZM_NEW_MAIL_MODULES} )
{ {
require MIME::Lite; require MIME::Lite;
require Net::SMTP; require Net::SMTP;
@ -92,9 +92,9 @@ if ( ZM_OPT_EMAIL )
} }
} }
if ( ZM_OPT_MESSAGE ) if ( $Config{ZM_OPT_MESSAGE} )
{ {
if ( ZM_NEW_MAIL_MODULES ) if ( $Config{ZM_NEW_MAIL_MODULES} )
{ {
require MIME::Lite; require MIME::Lite;
require Net::SMTP; require Net::SMTP;
@ -112,7 +112,7 @@ $ENV{PATH} = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
my $delay = ZM_FILTER_EXECUTE_INTERVAL; my $delay = $Config{ZM_FILTER_EXECUTE_INTERVAL};
my $event_id = 0; my $event_id = 0;
my $filter_parm = ""; my $filter_parm = "";
@ -163,6 +163,11 @@ if ( !GetOptions( 'filter=s'=>\$filter_parm ) )
Usage(); Usage();
} }
if ( ! EVENT_PATH ) {
Error( "No event path defined. Config was $Config{ZM_DIR_EVENTS}\n" );
die;
}
chdir( EVENT_PATH ); chdir( EVENT_PATH );
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
@ -186,7 +191,7 @@ my $last_action = 0;
while( 1 ) while( 1 )
{ {
if ( (time() - $last_action) > ZM_FILTER_RELOAD_DELAY ) if ( (time() - $last_action) > $Config{ZM_FILTER_RELOAD_DELAY} )
{ {
Debug( "Reloading filters\n" ); Debug( "Reloading filters\n" );
$last_action = time(); $last_action = time();
@ -573,28 +578,28 @@ sub checkFilter
my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $event->{Id} ) or Fatal( "Can't execute '$sql': ".$sth->errstr() ); my $res = $sth->execute( $event->{Id} ) or Fatal( "Can't execute '$sql': ".$sth->errstr() );
} }
if ( ZM_OPT_FFMPEG && $filter->{AutoVideo} ) if ( $Config{ZM_OPT_FFMPEG} && $filter->{AutoVideo} )
{ {
if ( !$event->{Videoed} ) if ( !$event->{Videoed} )
{ {
$delete_ok = undef if ( !generateVideo( $filter, $event ) ); $delete_ok = undef if ( !generateVideo( $filter, $event ) );
} }
} }
if ( ZM_OPT_EMAIL && $filter->{AutoEmail} ) if ( $Config{ZM_OPT_EMAIL} && $filter->{AutoEmail} )
{ {
if ( !$event->{Emailed} ) if ( !$event->{Emailed} )
{ {
$delete_ok = undef if ( !sendEmail( $filter, $event ) ); $delete_ok = undef if ( !sendEmail( $filter, $event ) );
} }
} }
if ( ZM_OPT_MESSAGE && $filter->{AutoMessage} ) if ( $Config{ZM_OPT_MESSAGE} && $filter->{AutoMessage} )
{ {
if ( !$event->{Messaged} ) if ( !$event->{Messaged} )
{ {
$delete_ok = undef if ( !sendMessage( $filter, $event ) ); $delete_ok = undef if ( !sendMessage( $filter, $event ) );
} }
} }
if ( ZM_OPT_UPLOAD && $filter->{AutoUpload} ) if ( $Config{ZM_OPT_UPLOAD} && $filter->{AutoUpload} )
{ {
if ( !$event->{Uploaded} ) if ( !$event->{Uploaded} )
{ {
@ -618,7 +623,7 @@ sub checkFilter
my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $event->{Id} ) or Fatal( "Can't execute '$sql': ".$sth->errstr() ); my $res = $sth->execute( $event->{Id} ) or Fatal( "Can't execute '$sql': ".$sth->errstr() );
if ( !ZM_OPT_FAST_DELETE ) if ( ! $Config{ZM_OPT_FAST_DELETE} )
{ {
my $sql = "delete from Frames where EventId = ?"; my $sql = "delete from Frames where EventId = ?";
my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
@ -650,7 +655,7 @@ sub generateVideo
my $scale = $event->{DefaultScale}/100; my $scale = $event->{DefaultScale}/100;
my $format; my $format;
my @ffmpeg_formats = split( /\s+/, ZM_FFMPEG_FORMATS ); my @ffmpeg_formats = split( /\s+/, $Config{ZM_FFMPEG_FORMATS} );
my $default_video_format; my $default_video_format;
my $default_phone_format; my $default_phone_format;
foreach my $ffmpeg_format( @ffmpeg_formats ) foreach my $ffmpeg_format( @ffmpeg_formats )
@ -678,7 +683,7 @@ sub generateVideo
$format = $ffmpeg_formats[0]; $format = $ffmpeg_formats[0];
} }
my $command = ZM_PATH_BIN."/zmvideo.pl -e ".$event->{Id}." -r ".$rate." -s ".$scale." -f ".$format; my $command = $Config{ZM_PATH_BIN}."/zmvideo.pl -e ".$event->{Id}." -r ".$rate." -s ".$scale." -f ".$format;
my $output = qx($command); my $output = qx($command);
chomp( $output ); chomp( $output );
my $status = $? >> 8; my $status = $? >> 8;
@ -713,22 +718,22 @@ sub uploadArchFile
my $filter = shift; my $filter = shift;
my $event = shift; my $event = shift;
if ( !ZM_UPLOAD_HOST ) if ( ! $Config{ZM_UPLOAD_HOST} )
{ {
Error( "Cannot upload archive as no upload host defined" ); Error( "Cannot upload archive as no upload host defined" );
return( 0 ); return( 0 );
} }
my $archFile = $event->{MonitorName}.'-'.$event->{Id}; my $archFile = $event->{MonitorName}.'-'.$event->{Id};
my $archImagePath = getEventPath( $event )."/".((ZM_UPLOAD_ARCH_ANALYSE)?'{*analyse,*capture}':'*capture').".jpg"; my $archImagePath = getEventPath( $event )."/".(( $Config{ZM_UPLOAD_ARCH_ANALYSE} )?'{*analyse,*capture}':'*capture').".jpg";
my @archImageFiles = glob($archImagePath); my @archImageFiles = glob($archImagePath);
my $archLocPath; my $archLocPath;
my $archError = 0; my $archError = 0;
if ( ZM_UPLOAD_ARCH_FORMAT eq "zip" ) if ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq "zip" )
{ {
$archFile .= '.zip'; $archFile .= '.zip';
$archLocPath = ZM_UPLOAD_LOC_DIR.'/'.$archFile; $archLocPath = $Config{ZM_UPLOAD_LOC_DIR}.'/'.$archFile;
my $zip = Archive::Zip->new(); my $zip = Archive::Zip->new();
Info( "Creating upload file '$archLocPath', ".int(@archImageFiles)." files\n" ); Info( "Creating upload file '$archLocPath', ".int(@archImageFiles)." files\n" );
@ -743,7 +748,7 @@ sub uploadArchFile
$archError = 1; $archError = 1;
last; last;
} }
$member->desiredCompressionMethod( (ZM_UPLOAD_ARCH_COMPRESS)?&COMPRESSION_DEFLATED:&COMPRESSION_STORED ); $member->desiredCompressionMethod( $Config{ZM_UPLOAD_ARCH_COMPRESS} ? &COMPRESSION_DEFLATED : &COMPRESSION_STORED );
} }
if ( !$archError ) if ( !$archError )
{ {
@ -759,9 +764,9 @@ sub uploadArchFile
Error( "Error adding images to zip archive $archLocPath, not writing" ); Error( "Error adding images to zip archive $archLocPath, not writing" );
} }
} }
elsif ( ZM_UPLOAD_ARCH_FORMAT eq "tar" ) elsif ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq "tar" )
{ {
if ( ZM_UPLOAD_ARCH_COMPRESS ) if ( $Config{ZM_UPLOAD_ARCH_COMPRESS} )
{ {
$archFile .= '.tar.gz'; $archFile .= '.tar.gz';
} }
@ -769,10 +774,10 @@ sub uploadArchFile
{ {
$archFile .= '.tar'; $archFile .= '.tar';
} }
$archLocPath = ZM_UPLOAD_LOC_DIR.'/'.$archFile; $archLocPath = $Config{ZM_UPLOAD_LOC_DIR}.'/'.$archFile;
Info( "Creating upload file '$archLocPath', ".int(@archImageFiles)." files\n" ); Info( "Creating upload file '$archLocPath', ".int(@archImageFiles)." files\n" );
if ( $archError = !Archive::Tar->create_archive( $archLocPath, ZM_UPLOAD_ARCH_COMPRESS, @archImageFiles ) ) if ( $archError = !Archive::Tar->create_archive( $archLocPath, $Config{ZM_UPLOAD_ARCH_COMPRESS}, @archImageFiles ) )
{ {
Error( "Tar error: ".Archive::Tar->error()."\n " ); Error( "Tar error: ".Archive::Tar->error()."\n " );
} }
@ -784,39 +789,39 @@ sub uploadArchFile
} }
else else
{ {
if ( ZM_UPLOAD_PROTOCOL eq "ftp" ) if ( $Config{ZM_UPLOAD_PROTOCOL} eq "ftp" )
{ {
Info( "Uploading to ".ZM_UPLOAD_HOST." using FTP\n" ); Info( "Uploading to ".$Config{ZM_UPLOAD_HOST}." using FTP\n" );
my $ftp = Net::FTP->new( ZM_UPLOAD_HOST, Timeout=>ZM_UPLOAD_TIMEOUT, Passive=>ZM_UPLOAD_FTP_PASSIVE, Debug=>ZM_UPLOAD_DEBUG ); my $ftp = Net::FTP->new( $Config{ZM_UPLOAD_HOST}, Timeout=>$Config{ZM_UPLOAD_TIMEOUT}, Passive=>$Config{ZM_UPLOAD_FTP_PASSIVE}, Debug=>$Config{ZM_UPLOAD_DEBUG} );
if ( !$ftp ) if ( !$ftp )
{ {
Error( "Can't create FTP connection: $@" ); Error( "Can't create FTP connection: $@" );
return( 0 ); return( 0 );
} }
$ftp->login( ZM_UPLOAD_USER, ZM_UPLOAD_PASS ) or Error( "FTP - Can't login" ); $ftp->login( $Config{ZM_UPLOAD_USER}, $Config{ZM_UPLOAD_PASS} ) or Error( "FTP - Can't login" );
$ftp->binary() or Error( "FTP - Can't go binary" ); $ftp->binary() or Error( "FTP - Can't go binary" );
$ftp->cwd( ZM_UPLOAD_REM_DIR ) or Error( "FTP - Can't cwd" ) if ( ZM_UPLOAD_REM_DIR ); $ftp->cwd( $Config{ZM_UPLOAD_REM_DIR} ) or Error( "FTP - Can't cwd" ) if ( $Config{ZM_UPLOAD_REM_DIR} );
$ftp->put( $archLocPath ) or Error( "FTP - Can't upload '$archLocPath'" ); $ftp->put( $archLocPath ) or Error( "FTP - Can't upload '$archLocPath'" );
$ftp->quit() or Error( "FTP - Can't quit" ); $ftp->quit() or Error( "FTP - Can't quit" );
} }
else else
{ {
my $host = ZM_UPLOAD_HOST; my $host = $Config{ZM_UPLOAD_HOST};
$host .= ":".ZM_UPLOAD_PORT if ( ZM_UPLOAD_PORT ); $host .= ":".$Config{ZM_UPLOAD_PORT} if $Config{ZM_UPLOAD_PORT};
Info( "Uploading to ".$host." using SFTP\n" ); Info( "Uploading to ".$host." using SFTP\n" );
my %sftpOptions = ( host=>ZM_UPLOAD_HOST, user=>ZM_UPLOAD_USER ); my %sftpOptions = ( host=>$Config{ZM_UPLOAD_HOST}, user=>$Config{ZM_UPLOAD_USER} );
$sftpOptions{password} = ZM_UPLOAD_PASS if ( ZM_UPLOAD_PASS ); $sftpOptions{password} = $Config{ZM_UPLOAD_PASS} if $Config{ZM_UPLOAD_PASS};
$sftpOptions{port} = ZM_UPLOAD_PORT if ( ZM_UPLOAD_PORT ); $sftpOptions{port} = $Config{ZM_UPLOAD_PORT} if $Config{ZM_UPLOAD_PORT};
$sftpOptions{timeout} = ZM_UPLOAD_TIMEOUT if ( ZM_UPLOAD_TIMEOUT ); $sftpOptions{timeout} = $Config{ZM_UPLOAD_TIMEOUT} if $Config{ZM_UPLOAD_TIMEOUT};
$sftpOptions{more} = [ '-o'=>'StrictHostKeyChecking=no' ]; $sftpOptions{more} = [ '-o'=>'StrictHostKeyChecking=no' ];
$Net::SFTP::Foreign::debug = -1 if ( ZM_UPLOAD_DEBUG ); $Net::SFTP::Foreign::debug = -1 if $Config{ZM_UPLOAD_DEBUG};
my $sftp = Net::SFTP::Foreign->new( ZM_UPLOAD_HOST, %sftpOptions ); my $sftp = Net::SFTP::Foreign->new( $Config{ZM_UPLOAD_HOST}, %sftpOptions );
if ( $sftp->error ) if ( $sftp->error )
{ {
Error( "Can't create SFTP connection: ".$sftp->error ); Error( "Can't create SFTP connection: ".$sftp->error );
return( 0 ); return( 0 );
} }
$sftp->setcwd( ZM_UPLOAD_REM_DIR ) or Error( "SFTP - Can't setcwd: ".$sftp->error ) if ( ZM_UPLOAD_REM_DIR ); $sftp->setcwd( $Config{ZM_UPLOAD_REM_DIR} ) or Error( "SFTP - Can't setcwd: ".$sftp->error ) if $Config{ZM_UPLOAD_REM_DIR};
$sftp->put( $archLocPath, $archFile ) or Error( "SFTP - Can't upload '$archLocPath': ".$sftp->error ); $sftp->put( $archLocPath, $archFile ) or Error( "SFTP - Can't upload '$archLocPath': ".$sftp->error );
} }
unlink( $archLocPath ); unlink( $archLocPath );
@ -876,7 +881,7 @@ sub substituteTags
$sth->finish(); $sth->finish();
} }
my $url = ZM_URL; my $url = $Config{ZM_URL};
$text =~ s/%ZP%/$url/g; $text =~ s/%ZP%/$url/g;
$text =~ s/%MN%/$event->{MonitorName}/g; $text =~ s/%MN%/$event->{MonitorName}/g;
$text =~ s/%MET%/$monitor->{EventCount}/g; $text =~ s/%MET%/$monitor->{EventCount}/g;
@ -908,18 +913,18 @@ sub substituteTags
$text =~ s/%EPIM%/$url?view=frame&mid=$event->{MonitorId}&eid=$event->{Id}&fid=$max_alarm_frame->{FrameId}/g; $text =~ s/%EPIM%/$url?view=frame&mid=$event->{MonitorId}&eid=$event->{Id}&fid=$max_alarm_frame->{FrameId}/g;
if ( $attachments_ref && $text =~ s/%EI1%//g ) if ( $attachments_ref && $text =~ s/%EI1%//g )
{ {
push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg", getEventPath( $event ), $first_alarm_frame->{FrameId} ) } ); push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg", getEventPath( $event ), $first_alarm_frame->{FrameId} ) } );
} }
if ( $attachments_ref && $text =~ s/%EIM%//g ) if ( $attachments_ref && $text =~ s/%EIM%//g )
{ {
# Don't attach the same image twice # Don't attach the same image twice
if ( !@$attachments_ref || ($first_alarm_frame->{FrameId} != $max_alarm_frame->{FrameId} ) ) if ( !@$attachments_ref || ($first_alarm_frame->{FrameId} != $max_alarm_frame->{FrameId} ) )
{ {
push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg", getEventPath( $event ), $max_alarm_frame->{FrameId} ) } ); push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg", getEventPath( $event ), $max_alarm_frame->{FrameId} ) } );
} }
} }
} }
if ( $attachments_ref && ZM_OPT_FFMPEG ) if ( $attachments_ref && $Config{ZM_OPT_FFMPEG} )
{ {
if ( $text =~ s/%EV%//g ) if ( $text =~ s/%EV%//g )
{ {
@ -952,12 +957,12 @@ sub sendEmail
my $filter = shift; my $filter = shift;
my $event = shift; my $event = shift;
if ( !ZM_FROM_EMAIL ) if ( ! $Config{ZM_FROM_EMAIL} )
{ {
Error( "No 'from' email address defined, not sending email" ); Error( "No 'from' email address defined, not sending email" );
return( 0 ); return( 0 );
} }
if ( !ZM_EMAIL_ADDRESS ) if ( ! $Config{ZM_EMAIL_ADDRESS} )
{ {
Error( "No email address defined, not sending email" ); Error( "No email address defined, not sending email" );
return( 0 ); return( 0 );
@ -965,22 +970,22 @@ sub sendEmail
Info( "Creating notification email\n" ); Info( "Creating notification email\n" );
my $subject = substituteTags( ZM_EMAIL_SUBJECT, $filter, $event ); my $subject = substituteTags( $Config{ZM_EMAIL_SUBJECT}, $filter, $event );
return( 0 ) if ( !$subject ); return( 0 ) if ( !$subject );
my @attachments; my @attachments;
my $body = substituteTags( ZM_EMAIL_BODY, $filter, $event, \@attachments ); my $body = substituteTags( $Config{ZM_EMAIL_BODY}, $filter, $event, \@attachments );
return( 0 ) if ( !$body ); return( 0 ) if ( !$body );
Info( "Sending notification email '$subject'\n" ); Info( "Sending notification email '$subject'\n" );
eval eval
{ {
if ( ZM_NEW_MAIL_MODULES ) if ( $Config{ZM_NEW_MAIL_MODULES} )
{ {
### Create the multipart container ### Create the multipart container
my $mail = MIME::Lite->new ( my $mail = MIME::Lite->new (
From => ZM_FROM_EMAIL, From => $Config{ZM_FROM_EMAIL},
To => ZM_EMAIL_ADDRESS, To => $Config{ZM_EMAIL_ADDRESS},
Subject => $subject, Subject => $subject,
Type => "multipart/mixed" Type => "multipart/mixed"
); );
@ -1000,14 +1005,14 @@ sub sendEmail
); );
} }
### Send the Message ### Send the Message
MIME::Lite->send( "smtp", ZM_EMAIL_HOST, Timeout=>60 ); MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 );
$mail->send(); $mail->send();
} }
else else
{ {
my $mail = MIME::Entity->build( my $mail = MIME::Entity->build(
From => ZM_FROM_EMAIL, From => $Config{ZM_FROM_EMAIL},
To => ZM_EMAIL_ADDRESS, To => $Config{ZM_EMAIL_ADDRESS},
Subject => $subject, Subject => $subject,
Type => (($body=~/<html>/)?'text/html':'text/plain'), Type => (($body=~/<html>/)?'text/html':'text/plain'),
Data => $body Data => $body
@ -1022,7 +1027,7 @@ sub sendEmail
Encoding => "base64" Encoding => "base64"
); );
} }
$mail->smtpsend( Host => ZM_EMAIL_HOST, MailFrom => ZM_FROM_EMAIL ); $mail->smtpsend( Host => $Config{ZM_EMAIL_HOST}, MailFrom => $Config{ZM_FROM_EMAIL} );
} }
}; };
if ( $@ ) if ( $@ )
@ -1046,12 +1051,12 @@ sub sendMessage
my $filter = shift; my $filter = shift;
my $event = shift; my $event = shift;
if ( !ZM_FROM_EMAIL ) if ( ! $Config{ZM_FROM_EMAIL} )
{ {
Error( "No 'from' email address defined, not sending message" ); Error( "No 'from' email address defined, not sending message" );
return( 0 ); return( 0 );
} }
if ( !ZM_MESSAGE_ADDRESS ) if ( ! $Config{ZM_MESSAGE_ADDRESS} )
{ {
Error( "No message address defined, not sending message" ); Error( "No message address defined, not sending message" );
return( 0 ); return( 0 );
@ -1059,22 +1064,22 @@ sub sendMessage
Info( "Creating notification message\n" ); Info( "Creating notification message\n" );
my $subject = substituteTags( ZM_MESSAGE_SUBJECT, $filter, $event ); my $subject = substituteTags( $Config{ZM_MESSAGE_SUBJECT}, $filter, $event );
return( 0 ) if ( !$subject ); return( 0 ) if ( !$subject );
my @attachments; my @attachments;
my $body = substituteTags( ZM_MESSAGE_BODY, $filter, $event, \@attachments ); my $body = substituteTags( $Config{ZM_MESSAGE_BODY}, $filter, $event, \@attachments );
return( 0 ) if ( !$body ); return( 0 ) if ( !$body );
Info( "Sending notification message '$subject'\n" ); Info( "Sending notification message '$subject'\n" );
eval eval
{ {
if ( ZM_NEW_MAIL_MODULES ) if ( $Config{ZM_NEW_MAIL_MODULES} )
{ {
### Create the multipart container ### Create the multipart container
my $mail = MIME::Lite->new ( my $mail = MIME::Lite->new (
From => ZM_FROM_EMAIL, From => $Config{ZM_FROM_EMAIL},
To => ZM_MESSAGE_ADDRESS, To => $Config{ZM_MESSAGE_ADDRESS},
Subject => $subject, Subject => $subject,
Type => "multipart/mixed" Type => "multipart/mixed"
); );
@ -1094,14 +1099,14 @@ sub sendMessage
); );
} }
### Send the Message ### Send the Message
MIME::Lite->send( "smtp", ZM_EMAIL_HOST, Timeout=>60 ); MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 );
$mail->send(); $mail->send();
} }
else else
{ {
my $mail = MIME::Entity->build( my $mail = MIME::Entity->build(
From => ZM_FROM_EMAIL, From => $Config{ZM_FROM_EMAIL},
To => ZM_MESSAGE_ADDRESS, To => $Config{ZM_MESSAGE_ADDRESS},
Subject => $subject, Subject => $subject,
Type => (($body=~/<html>/)?'text/html':'text/plain'), Type => (($body=~/<html>/)?'text/html':'text/plain'),
Data => $body Data => $body
@ -1116,7 +1121,7 @@ sub sendMessage
Encoding => "base64" Encoding => "base64"
); );
} }
$mail->smtpsend( Host => ZM_EMAIL_HOST, MailFrom => ZM_FROM_EMAIL ); $mail->smtpsend( Host => $Config{ZM_EMAIL_HOST}, MailFrom => $Config{ZM_FROM_EMAIL} );
} }
}; };
if ( $@ ) if ( $@ )

View File

@ -57,9 +57,9 @@ if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot)$/ )
if ( $command ) if ( $command )
{ {
# Check to see if it's a valid run state # Check to see if it's a valid run state
my $sql = "select * from States where Name = '$command'"; my $sql = 'select * from States where Name = ?';
my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or Fatal( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $command ) or Fatal( "Can't execute: ".$sth->errstr() );
if ( $state = $sth->fetchrow_hashref() ) if ( $state = $sth->fetchrow_hashref() )
{ {
$state->{Name} = $command; $state->{Name} = $command;
@ -84,7 +84,7 @@ if ( !$command || $command !~ /^(?:start|stop|restart|status|logrot)$/ )
} }
# Move to the right place # Move to the right place
chdir( ZM_PATH_WEB ) or Fatal( "Can't chdir to '".ZM_PATH_WEB."': $!" ); chdir( $Config{ZM_PATH_WEB} ) or Fatal( "Can't chdir to '".$Config{ZM_PATH_WEB}."': $!" );
my $dbg_id = ""; my $dbg_id = "";
@ -138,7 +138,7 @@ if ( $command =~ /^(?:stop|restart)$/ )
} }
} }
runCommand( "zmupdate.pl -f" ); #runCommand( "zmupdate.pl -f" );
if ( $command =~ /^(?:start|restart)$/ ) if ( $command =~ /^(?:start|restart)$/ )
{ {
@ -146,9 +146,9 @@ if ( $command =~ /^(?:start|restart)$/ )
if ( $status eq "stopped" ) if ( $status eq "stopped" )
{ {
if ( ZM_DYN_DB_VERSION && ZM_DYN_DB_VERSION ne ZM_VERSION ) if ( $Config{ZM_DYN_DB_VERSION} and ( $Config{ZM_DYN_DB_VERSION} ne ZM_VERSION ) )
{ {
Fatal( "Version mismatch, system is version ".ZM_VERSION.", database is ".ZM_DYN_DB_VERSION.", please run zmupdate.pl to update." ); Fatal( "Version mismatch, system is version ".ZM_VERSION.", database is ".$Config{ZM_DYN_DB_VERSION}.", please run zmupdate.pl to update." );
exit( -1 ); exit( -1 );
} }
@ -158,15 +158,14 @@ if ( $command =~ /^(?:start|restart)$/ )
Debug( "Recreating temporary directory '@ZM_TMPDIR@'" ); Debug( "Recreating temporary directory '@ZM_TMPDIR@'" );
mkdir( "@ZM_TMPDIR@", 0700 ) or Fatal( "Can't create missing temporary directory '@ZM_TMPDIR@': $!" ); mkdir( "@ZM_TMPDIR@", 0700 ) or Fatal( "Can't create missing temporary directory '@ZM_TMPDIR@': $!" );
my ( $runName ) = getpwuid( $> ); my ( $runName ) = getpwuid( $> );
if ( $runName ne ZM_WEB_USER ) if ( $runName ne $Config{ZM_WEB_USER} )
{ {
# Not running as web user, so should be root in whch case chown the temporary directory # Not running as web user, so should be root in whch case chown the temporary directory
my ( $webName, $webPass, $webUid, $webGid ) = getpwnam( ZM_WEB_USER ) or Fatal( "Can't get user details for web user '".ZM_WEB_USER."': $!" ); my ( $webName, $webPass, $webUid, $webGid ) = getpwnam( $Config{ZM_WEB_USER} ) or Fatal( "Can't get user details for web user '".$Config{ZM_WEB_USER}."': $!" );
chown( $webUid, $webGid, "@ZM_TMPDIR@" ) or Fatal( "Can't change ownership of temporary directory '@ZM_TMPDIR@' to '".ZM_WEB_USER.":".ZM_WEB_GROUP."': $!" ); chown( $webUid, $webGid, "@ZM_TMPDIR@" ) or Fatal( "Can't change ownership of temporary directory '@ZM_TMPDIR@' to '".$Config{ZM_WEB_USER}.":".$Config{ZM_WEB_GROUP}."': $!" );
} }
} }
zmMemTidy(); zmMemTidy();
runCommand( "zmfix" );
runCommand( "zmdc.pl startup" ); runCommand( "zmdc.pl startup" );
my $sql = "select * from Monitors"; my $sql = "select * from Monitors";
@ -186,13 +185,13 @@ if ( $command =~ /^(?:start|restart)$/ )
} }
if ( $monitor->{Function} ne 'Monitor' ) if ( $monitor->{Function} ne 'Monitor' )
{ {
if ( ZM_OPT_FRAME_SERVER ) if ( $Config{ZM_OPT_FRAME_SERVER} )
{ {
runCommand( "zmdc.pl start zmf -m $monitor->{Id}" ); runCommand( "zmdc.pl start zmf -m $monitor->{Id}" );
} }
runCommand( "zmdc.pl start zma -m $monitor->{Id}" ); runCommand( "zmdc.pl start zma -m $monitor->{Id}" );
} }
if ( ZM_OPT_CONTROL ) if ( $Config{ZM_OPT_CONTROL} )
{ {
if ( $monitor->{Function} eq 'Modect' || $monitor->{Function} eq 'Mocord' ) if ( $monitor->{Function} eq 'Modect' || $monitor->{Function} eq 'Mocord' )
{ {
@ -208,20 +207,20 @@ if ( $command =~ /^(?:start|restart)$/ )
# This is now started unconditionally # This is now started unconditionally
runCommand( "zmdc.pl start zmfilter.pl" ); runCommand( "zmdc.pl start zmfilter.pl" );
if ( ZM_RUN_AUDIT ) if ( $Config{ZM_RUN_AUDIT} )
{ {
runCommand( "zmdc.pl start zmaudit.pl -c" ); runCommand( "zmdc.pl start zmaudit.pl -c" );
} }
if ( ZM_OPT_TRIGGERS ) if ( $Config{ZM_OPT_TRIGGERS} )
{ {
runCommand( "zmdc.pl start zmtrigger.pl" ); runCommand( "zmdc.pl start zmtrigger.pl" );
} }
if ( ZM_OPT_X10 ) if ( $Config{ZM_OPT_X10} )
{ {
runCommand( "zmdc.pl start zmx10.pl -c start" ); runCommand( "zmdc.pl start zmx10.pl -c start" );
} }
runCommand( "zmdc.pl start zmwatch.pl" ); runCommand( "zmdc.pl start zmwatch.pl" );
if ( ZM_CHECK_FOR_UPDATES ) if ( $Config{ZM_CHECK_FOR_UPDATES} )
{ {
runCommand( "zmdc.pl start zmupdate.pl -c" ); runCommand( "zmdc.pl start zmupdate.pl -c" );
} }
@ -245,3 +244,5 @@ if ( $command eq "logrot" )
} }
exit( $retval ); exit( $retval );
__END__

View File

@ -54,7 +54,7 @@ use DBI;
use Getopt::Long; use Getopt::Long;
use Data::Dumper; use Data::Dumper;
use constant EVENT_PATH => (ZM_DIR_EVENTS=~m|/|)?ZM_DIR_EVENTS:(ZM_PATH_WEB.'/'.ZM_DIR_EVENTS); use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)?$Config{ZM_DIR_EVENTS}:($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS});
$| = 1; $| = 1;
@ -62,7 +62,7 @@ $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
my $web_uid = (getpwnam( ZM_WEB_USER ))[2]; my $web_uid = (getpwnam( $Config{ZM_WEB_USER} ))[2];
my $use_log = (($> == 0) || ($> == $web_uid)); my $use_log = (($> == 0) || ($> == $web_uid));
logInit( toFile=>$use_log?DEBUG:NOLOG ); logInit( toFile=>$use_log?DEBUG:NOLOG );
@ -75,8 +75,8 @@ my $rename = 0;
my $zoneFix = 0; my $zoneFix = 0;
my $migrateEvents = 0; my $migrateEvents = 0;
my $version = ''; my $version = '';
my $dbUser = ZM_DB_USER; my $dbUser = $Config{ZM_DB_USER};
my $dbPass = ZM_DB_PASS; my $dbPass = $Config{ZM_DB_PASS};
my $updateDir = ''; my $updateDir = '';
sub Usage sub Usage
{ {
@ -99,15 +99,14 @@ if ( !GetOptions( 'check'=>\$check, 'freshen'=>\$freshen, 'rename'=>\$rename, 'z
} }
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
*ZoneMinder::Database::ZM_DB_USER = sub { $dbUser } if ZoneMinder::Database::ZM_DB_USER ne $dbUser; $Config{ZM_DB_USER} = $dbUser;
*ZoneMinder::Database::ZM_DB_PASS = sub { $dbPass } if ZoneMinder::Database::ZM_DB_PASS ne $dbPass; $Config{ZM_DB_PASS} = $dbPass;
zmDbDisconnect();
if ( ! ($check || $freshen || $rename || $zoneFix || $migrateEvents || $version) ) if ( ! ($check || $freshen || $rename || $zoneFix || $migrateEvents || $version) )
{ {
if ( ZM_DYN_DB_VERSION ) if ( $Config{ZM_DYN_DB_VERSION} )
{ {
$version = ZM_DYN_DB_VERSION; $version = $Config{ZM_DYN_DB_VERSION};
} }
else else
{ {
@ -122,46 +121,35 @@ if ( ($check + $freshen + $rename + $zoneFix + $migrateEvents + ($version?1:0))
Usage(); Usage();
} }
if ( $check && ZM_CHECK_FOR_UPDATES ) if ( $check && $Config{ZM_CHECK_FOR_UPDATES} )
{ {
print( "Update agent starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" ); print( "Update agent starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
my $dbh = zmDbConnect(); my $currVersion = $Config{ZM_DYN_CURR_VERSION};
my $lastVersion = $Config{ZM_DYN_LAST_VERSION};
my $currVersion = ZM_DYN_CURR_VERSION; my $lastCheck = $Config{ZM_DYN_LAST_CHECK};
my $lastVersion = ZM_DYN_LAST_VERSION;
my $lastCheck = ZM_DYN_LAST_CHECK;
if ( !$currVersion ) if ( !$currVersion )
{ {
$currVersion = ZM_VERSION; $currVersion = $Config{ZM_VERSION};
my $sql = "update Config set Value = ? where Name = 'ZM_DYN_CURR_VERSION'"; my $sql = "update Config set Value = ? where Name = 'ZM_DYN_CURR_VERSION'";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( "$currVersion" ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( "$currVersion" ) or die( "Can't execute: ".$sth->errstr() );
} }
zmDbDisconnect();
while( 1 ) while( 1 )
{ {
my $now = time(); my $now = time();
if ( !$lastVersion || !$lastCheck || (($now-$lastCheck) > CHECK_INTERVAL) ) if ( !$lastVersion || !$lastCheck || (($now-$lastCheck) > CHECK_INTERVAL) )
{ {
$dbh = zmDbConnect();
Info( "Checking for updates\n" ); Info( "Checking for updates\n" );
use LWP::UserAgent; use LWP::UserAgent;
my $ua = LWP::UserAgent->new; my $ua = LWP::UserAgent->new;
$ua->agent( "ZoneMinder Update Agent/".ZM_VERSION ); $ua->agent( "ZoneMinder Update Agent/".ZM_VERSION );
if ( eval('defined(ZM_UPDATE_CHECK_PROXY)') ) if ( $Config{ZM_UPDATE_CHECK_PROXY} ) {
{ $ua->proxy( "http", $Config{ZM_UPDATE_CHECK_PROXY} );
no strict 'subs';
if ( ZM_UPDATE_CHECK_PROXY )
{
$ua->proxy( "http", ZM_UPDATE_CHECK_PROXY );
}
use strict 'subs';
} }
my $req = HTTP::Request->new( GET=>'http://zoneminder.github.io/ZoneMinder/version.txt' ); my $req = HTTP::Request->new( GET=>'http://zoneminder.github.io/ZoneMinder/version.txt' );
my $res = $ua->request($req); my $res = $ua->request($req);
@ -186,7 +174,6 @@ if ( $check && ZM_CHECK_FOR_UPDATES )
{ {
Error( "Error check failed: '".$res->status_line()."'\n" ); Error( "Error check failed: '".$res->status_line()."'\n" );
} }
zmDbDisconnect();
} }
sleep( 3600 ); sleep( 3600 );
} }
@ -222,9 +209,6 @@ if ( $rename )
} }
if ( $zoneFix ) if ( $zoneFix )
{ {
require DBI;
my $dbh = zmDbConnect();
my $sql = "select Z.*, M.Width as MonitorWidth, M.Height as MonitorHeight from Zones as Z inner join Monitors as M on Z.MonitorId = M.Id where Z.Units = 'Percent'"; my $sql = "select Z.*, M.Width as MonitorWidth, M.Height as MonitorHeight from Zones as Z inner join Monitors as M on Z.MonitorId = M.Id where Z.Units = 'Percent'";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
@ -257,12 +241,12 @@ if ( $zoneFix )
} }
if ( $migrateEvents ) if ( $migrateEvents )
{ {
my $webUid = (getpwnam( ZM_WEB_USER ))[2]; my $webUid = (getpwnam( $Config{ZM_WEB_USER} ))[2];
my $webGid = (getgrnam( ZM_WEB_USER ))[2]; my $webGid = (getgrnam( $Config{ZM_WEB_USER} ))[2];
if ( !(($> == 0) || ($> == $webUid)) ) if ( !(($> == 0) || ($> == $webUid)) )
{ {
print( "Error, migrating events can only be done as user root or ".ZM_WEB_USER.".\n" ); print( "Error, migrating events can only be done as user root or ".$Config{ZM_WEB_USER}.".\n" );
exit( -1 ); exit( -1 );
} }
@ -286,8 +270,7 @@ if ( $migrateEvents )
{ {
print( "Converting all events to deep storage.\n" ); print( "Converting all events to deep storage.\n" );
chdir( ZM_PATH_WEB ); chdir( $Config{ZM_PATH_WEB} );
my $dbh = zmDbConnect();
my $sql = "select *, unix_timestamp(StartTime) as UnixStartTime from Events"; my $sql = "select *, unix_timestamp(StartTime) as UnixStartTime from Events";
my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute(); my $res = $sth->execute();
@ -298,7 +281,7 @@ if ( $migrateEvents )
while( my $event = $sth->fetchrow_hashref() ) while( my $event = $sth->fetchrow_hashref() )
{ {
my $oldEventPath = ZM_DIR_EVENTS.'/'.$event->{MonitorId}.'/'.$event->{Id}; my $oldEventPath = $Config{ZM_DIR_EVENTS}.'/'.$event->{MonitorId}.'/'.$event->{Id};
if ( !-d $oldEventPath ) if ( !-d $oldEventPath )
{ {
@ -307,11 +290,11 @@ if ( $migrateEvents )
} }
print( "Converting event ".$event->{Id}."\n" ); print( "Converting event ".$event->{Id}."\n" );
my $newDatePath = ZM_DIR_EVENTS.'/'.$event->{MonitorId}.'/'.strftime( "%y/%m/%d", localtime($event->{UnixStartTime}) ); my $newDatePath = $Config{ZM_DIR_EVENTS}.'/'.$event->{MonitorId}.'/'.strftime( "%y/%m/%d", localtime($event->{UnixStartTime}) );
my $newTimePath = strftime( "%H/%M/%S", localtime($event->{UnixStartTime}) ); my $newTimePath = strftime( "%H/%M/%S", localtime($event->{UnixStartTime}) );
my $newEventPath = $newDatePath.'/'.$newTimePath; my $newEventPath = $newDatePath.'/'.$newTimePath;
( my $truncEventPath = $newEventPath ) =~ s|/\d+$||; ( my $truncEventPath = $newEventPath ) =~ s|/\d+$||;
makePath( $truncEventPath, ZM_PATH_WEB ); makePath( $truncEventPath, $Config{ZM_PATH_WEB} );
my $idLink = $newDatePath.'/.'.$event->{Id}; my $idLink = $newDatePath.'/.'.$event->{Id};
symlink( $newTimePath, $idLink ) or die( "Can't symlink $newTimePath -> $idLink: $!" ); symlink( $newTimePath, $idLink ) or die( "Can't symlink $newTimePath -> $idLink: $!" );
rename( $oldEventPath, $newEventPath ) or die( "Can't move $oldEventPath -> $newEventPath: $!" ); rename( $oldEventPath, $newEventPath ) or die( "Can't move $oldEventPath -> $newEventPath: $!" );
@ -335,6 +318,34 @@ if ( $freshen )
loadConfigFromDB(); loadConfigFromDB();
saveConfigToDB(); saveConfigToDB();
} }
# Now check for MyISAM Tables
my @MyISAM_Tables;
my $sql = "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='zm' AND engine = 'MyISAM'";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
while( my $dbTable = $sth->fetchrow() ) {
push @MyISAM_Tables, $dbTable;
}
$sth->finish();
if ( @MyISAM_Tables ) {
print( "\nPrevious versions of ZoneMinder used the MyISAM database engine.\nHowever, the recommended database engine is InnoDB.\n");
print( "\nHint: InnoDB tables are much less likely to be corrupted during an unclean shutdown.\n\nPress 'y' to convert your tables to InnoDB or 'n' to skip : ");
my $response = <STDIN>;
chomp( $response );
if ( $response =~ /^[yY]$/ ) {
print "\nConverting MyISAM tables to InnoDB. Please wait.\n";
foreach (@MyISAM_Tables) {
my $sql = "ALTER TABLE $_ ENGINE = InnoDB";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
}
}
}
if ( $version ) if ( $version )
{ {
my ( $detaint_version ) = $version =~ /^([\w.]+)$/; my ( $detaint_version ) = $version =~ /^([\w.]+)$/;
@ -343,15 +354,15 @@ if ( $version )
if ( ZM_VERSION eq $version ) if ( ZM_VERSION eq $version )
{ {
print( "\nDatabase already at version $version, update aborted.\n\n" ); print( "\nDatabase already at version $version, update aborted.\n\n" );
exit( -1 ); exit( 0 );
} }
print( "\nInitiating database upgrade to version ".ZM_VERSION." from version $version\n" ); print( "\nInitiating database upgrade to version ".ZM_VERSION." from version $version\n" );
if ( $interactive ) if ( $interactive )
{ {
if ( ZM_DYN_DB_VERSION && ZM_DYN_DB_VERSION ne $version ) if ( $Config{ZM_DYN_DB_VERSION} && $Config{ZM_DYN_DB_VERSION} ne $version )
{ {
print( "\nWARNING - You have specified an upgrade from version $version but the database version found is ".ZM_DYN_DB_VERSION.". Is this correct?\nPress enter to continue or ctrl-C to abort : " ); print( "\nWARNING - You have specified an upgrade from version $version but the database version found is ".$Config{ZM_DYN_DB_VERSION}.". Is this correct?\nPress enter to continue or ctrl-C to abort : " );
my $response = <STDIN>; my $response = <STDIN>;
} }
@ -370,7 +381,7 @@ if ( $version )
if ( $response =~ /^[yY]$/ ) if ( $response =~ /^[yY]$/ )
{ {
my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ ); my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
my $command = "mysqldump -h".$host; my $command = "mysqldump -h".$host;
$command .= " -P".$port if defined($port); $command .= " -P".$port if defined($port);
if ( $dbUser ) if ( $dbUser )
@ -381,8 +392,8 @@ if ( $version )
$command .= " -p".$dbPass; $command .= " -p".$dbPass;
} }
} }
my $backup = "@ZM_TMPDIR@/".ZM_DB_NAME."-".$version.".dump"; my $backup = "@ZM_TMPDIR@/".$Config{ZM_DB_NAME}."-".$version.".dump";
$command .= " --add-drop-table --databases ".ZM_DB_NAME." > ".$backup; $command .= " --add-drop-table --databases ".$Config{ZM_DB_NAME}." > ".$backup;
print( "Creating backup to $backup. This may take several minutes.\n" ); print( "Creating backup to $backup. This may take several minutes.\n" );
print( "Executing '$command'\n" ) if ( logDebugging() ); print( "Executing '$command'\n" ) if ( logDebugging() );
my $output = qx($command); my $output = qx($command);
@ -411,7 +422,7 @@ if ( $version )
my $dbh = shift; my $dbh = shift;
my $version = shift; my $version = shift;
my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ ); my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
my $command = "mysql -h".$host; my $command = "mysql -h".$host;
$command .= " -P".$port if defined($port); $command .= " -P".$port if defined($port);
if ( $dbUser ) if ( $dbUser )
@ -422,14 +433,14 @@ if ( $version )
$command .= " -p".$dbPass; $command .= " -p".$dbPass;
} }
} }
$command .= " ".ZM_DB_NAME." < "; $command .= " ".$Config{ZM_DB_NAME}." < ";
if ( $updateDir ) if ( $updateDir )
{ {
$command .= $updateDir; $command .= $updateDir;
} }
else else
{ {
$command .= ZM_PATH_DATA."/db"; $command .= $Config{ZM_PATH_DATA}."/db";
} }
$command .= "/zm_update-".$version.".sql"; $command .= "/zm_update-".$version.".sql";
@ -454,34 +465,6 @@ if ( $version )
} }
} }
sub toInnoDB
{
my $dbh = shift;
my $sql = "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='zm' AND engine = 'MyISAM'";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
my @dbTables;
while( my $dbTable = $sth->fetchrow() )
{
push( @dbTables, $dbTable );
}
$sth->finish();
if (@dbTables)
{
print "\nConverting MyISAM tables to InnoDB. Please wait.\n";
foreach (@dbTables)
{
my $sql = "ALTER TABLE $_ ENGINE = InnoDB";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
}
$sth->finish();
} else {
print "\nNo MyISAM tables found. Skipping...\n";
}
}
print( "\nUpgrading database to version ".ZM_VERSION."\n" ); print( "\nUpgrading database to version ".ZM_VERSION."\n" );
@ -489,8 +472,6 @@ if ( $version )
loadConfigFromDB(); loadConfigFromDB();
saveConfigToDB(); saveConfigToDB();
my $dbh = zmDbConnect();
my $cascade = undef; my $cascade = undef;
if ( $cascade || $version eq "1.19.0" ) if ( $cascade || $version eq "1.19.0" )
{ {
@ -518,8 +499,6 @@ if ( $version )
} }
if ( $cascade || $version eq "1.19.4" ) if ( $cascade || $version eq "1.19.4" )
{ {
require DBI;
# Rename the event directories and create a new symlink for the names # Rename the event directories and create a new symlink for the names
chdir( EVENT_PATH ); chdir( EVENT_PATH );
@ -742,7 +721,7 @@ if ( $version )
my ( $sql, $sth, $res ); my ( $sql, $sth, $res );
if ( defined(&ZM_EMAIL_TEXT) && &ZM_EMAIL_TEXT ) if ( defined(&ZM_EMAIL_TEXT) && &ZM_EMAIL_TEXT )
{ {
my ( $email_subject, $email_body ) = ZM_EMAIL_TEXT =~ /subject\s*=\s*"([^\n]*)".*body\s*=\s*"(.*)"?$/ms; my ( $email_subject, $email_body ) = $Config{ZM_EMAIL_TEXT} =~ /subject\s*=\s*"([^\n]*)".*body\s*=\s*"(.*)"?$/ms;
$sql = "replace into Config set Id = 0, Name = 'ZM_EMAIL_SUBJECT', Value = '".$email_subject."', Type = 'string', DefaultValue = 'ZoneMinder: Alarm - %MN%-%EI% (%ESM% - %ESA% %EFA%)', Hint = 'string', Pattern = '(?-xism:^(.+)\$)', Format = ' \$1 ', Prompt = 'The subject of the email used to send matching event details', Help = 'This option is used to define the subject of the email that is sent for any events that match the appropriate filters.', Category = 'mail', Readonly = '0', Requires = 'ZM_OPT_EMAIL=1'"; $sql = "replace into Config set Id = 0, Name = 'ZM_EMAIL_SUBJECT', Value = '".$email_subject."', Type = 'string', DefaultValue = 'ZoneMinder: Alarm - %MN%-%EI% (%ESM% - %ESA% %EFA%)', Hint = 'string', Pattern = '(?-xism:^(.+)\$)', Format = ' \$1 ', Prompt = 'The subject of the email used to send matching event details', Help = 'This option is used to define the subject of the email that is sent for any events that match the appropriate filters.', Category = 'mail', Readonly = '0', Requires = 'ZM_OPT_EMAIL=1'";
$sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
$res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
@ -752,7 +731,7 @@ if ( $version )
} }
if ( defined(&ZM_MESSAGE_TEXT) && &ZM_MESSAGE_TEXT ) if ( defined(&ZM_MESSAGE_TEXT) && &ZM_MESSAGE_TEXT )
{ {
my ( $message_subject, $message_body ) = ZM_MESSAGE_TEXT =~ /subject\s*=\s*"([^\n]*)".*body\s*=\s*"(.*)"?$/ms; my ( $message_subject, $message_body ) = $Config{ZM_MESSAGE_TEXT} =~ /subject\s*=\s*"([^\n]*)".*body\s*=\s*"(.*)"?$/ms;
$sql = "replace into Config set Id = 0, Name = 'ZM_MESSAGE_SUBJECT', Value = '".$message_subject."', Type = 'string', DefaultValue = 'ZoneMinder: Alarm - %MN%-%EI%', Hint = 'string', Pattern = '(?-xism:^(.+)\$)', Format = ' \$1 ', Prompt = 'The subject of the message used to send matching event details', Help = 'This option is used to define the subject of the message that is sent for any events that match the appropriate filters.', Category = 'mail', Readonly = '0', Requires = 'ZM_OPT_MESSAGE=1'"; $sql = "replace into Config set Id = 0, Name = 'ZM_MESSAGE_SUBJECT', Value = '".$message_subject."', Type = 'string', DefaultValue = 'ZoneMinder: Alarm - %MN%-%EI%', Hint = 'string', Pattern = '(?-xism:^(.+)\$)', Format = ' \$1 ', Prompt = 'The subject of the message used to send matching event details', Help = 'This option is used to define the subject of the message that is sent for any events that match the appropriate filters.', Category = 'mail', Readonly = '0', Requires = 'ZM_OPT_MESSAGE=1'";
$sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
$res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
@ -886,7 +865,7 @@ if ( $version )
my $sql = "update Config set Value = ? where Name = 'ZM_JPEG_STREAM_QUALITY'"; my $sql = "update Config set Value = ? where Name = 'ZM_JPEG_STREAM_QUALITY'";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( ZM_JPEG_IMAGE_QUALITY ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $Config{ZM_JPEG_IMAGE_QUALITY} ) or die( "Can't execute: ".$sth->errstr() );
} }
$cascade = !undef; $cascade = !undef;
} }
@ -1014,14 +993,6 @@ if ( $version )
} # end if } # end if
$sth->finish(); $sth->finish();
print( "\nPrevious versions of ZoneMinder used the MyISAM database engine.\nHowever, the recommended database engine is InnoDB.\n");
print( "\nHint: InnoDB tables are much less likely to be corrupted during an unclean shutdown.\n\nPress 'y' to convert your tables to InnoDB or 'n' to skip : ");
my $response = <STDIN>;
chomp( $response );
if ( $response =~ /^[yY]$/ )
{
toInnoDB($dbh);
}
$cascade = !undef; $cascade = !undef;
$version = '1.26.0'; $version = '1.26.0';
@ -1030,7 +1001,7 @@ if ( $version )
if ( $version ge '1.26.0' ) { if ( $version ge '1.26.0' ) {
my @files; my @files;
$updateDir = ZM_PATH_DATA."/db" if ! $updateDir; $updateDir = $Config{ZM_PATH_DATA}."/db" if ! $updateDir;
opendir( my $dh, $updateDir ) || die "Can't open updateDir $!"; opendir( my $dh, $updateDir ) || die "Can't open updateDir $!";
@files = sort grep { (!/^\./) && /^zm_update\-[\d\.]+\.sql$/ && -f "$updateDir/$_" } readdir($dh); @files = sort grep { (!/^\./) && /^zm_update\-[\d\.]+\.sql$/ && -f "$updateDir/$_" } readdir($dh);
closedir $dh; closedir $dh;
@ -1061,13 +1032,13 @@ if ( $version )
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( "$installed_version", "ZM_DYN_DB_VERSION" ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( "$installed_version", "ZM_DYN_DB_VERSION" ) or die( "Can't execute: ".$sth->errstr() );
$res = $sth->execute( "$installed_version", "ZM_DYN_CURR_VERSION" ) or die( "Can't execute: ".$sth->errstr() ); $res = $sth->execute( "$installed_version", "ZM_DYN_CURR_VERSION" ) or die( "Can't execute: ".$sth->errstr() );
$dbh->disconnect();
} }
else else
{ {
$dbh->disconnect(); zmDbDisconnect();
die( "Can't find upgrade from version '$version'" ); die( "Can't find upgrade from version '$version'" );
} }
print( "\nDatabase upgrade to version ".ZM_VERSION." successful.\n\n" ); print( "\nDatabase upgrade to version ".ZM_VERSION." successful.\n\n" );
} }
zmDbDisconnect();
exit( 0 ); exit( 0 );

View File

@ -56,7 +56,7 @@ my $fps = '';
my $size = ''; my $size = '';
my $overwrite = 0; my $overwrite = 0;
my @formats = split( /\s+/, ZM_FFMPEG_FORMATS ); my @formats = split( /\s+/, $Config{ZM_FFMPEG_FORMATS} );
for ( my $i = 0; $i < @formats; $i++ ) for ( my $i = 0; $i < @formats; $i++ )
{ {
if ( $i =~ /^(.+)\*$/ ) if ( $i =~ /^(.+)\*$/ )
@ -92,7 +92,7 @@ if ( !$event_id || $event_id < 0 )
Usage(); Usage();
} }
if ( !ZM_OPT_FFMPEG ) if ( ! $Config{ZM_OPT_FFMPEG} )
{ {
print( STDERR "Mpeg encoding is not currently enabled\n" ); print( STDERR "Mpeg encoding is not currently enabled\n" );
exit(-1); exit(-1);
@ -221,7 +221,7 @@ if ( $overwrite || !-s $video_file )
$video_size = $size; $video_size = $size;
} }
my $command = ZM_PATH_FFMPEG." -y -r $frame_rate ".ZM_FFMPEG_INPUT_OPTIONS." -i %0".ZM_EVENT_IMAGE_DIGITS."d-capture.jpg -s $video_size ".ZM_FFMPEG_OUTPUT_OPTIONS." '$video_file' > ffmpeg.log 2>&1"; my $command = $Config{ZM_PATH_FFMPEG}." -y -r $frame_rate ".$Config{ZM_FFMPEG_INPUT_OPTIONS}." -i %0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg -s $video_size ".$Config{ZM_FFMPEG_OUTPUT_OPTIONS}." '$video_file' > ffmpeg.log 2>&1";
Debug( $command."\n" ); Debug( $command."\n" );
my $output = qx($command); my $output = qx($command);

View File

@ -90,7 +90,7 @@ while( 1 )
next if ( !defined($image_time) ); # Can't read from shared data next if ( !defined($image_time) ); # Can't read from shared data
next if ( !$image_time ); # We can't get the last capture time so can't be sure it's died. next if ( !$image_time ); # We can't get the last capture time so can't be sure it's died.
my $max_image_delay = ($monitor->{MaxFPS}&&($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):ZM_WATCH_MAX_DELAY; my $max_image_delay = ($monitor->{MaxFPS}&&($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):$Config{ZM_WATCH_MAX_DELAY};
my $image_delay = $now-$image_time; my $image_delay = $now-$image_time;
Debug( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" ); Debug( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" );
if ( $image_delay > $max_image_delay ) if ( $image_delay > $max_image_delay )
@ -127,7 +127,7 @@ while( 1 )
next if ( !defined($image_time) ); # Can't read from shared data next if ( !defined($image_time) ); # Can't read from shared data
next if ( !$image_time ); # We can't get the last capture time so can't be sure it's died. next if ( !$image_time ); # We can't get the last capture time so can't be sure it's died.
my $max_image_delay = ($monitor->{MaxFPS}&&($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):ZM_WATCH_MAX_DELAY; my $max_image_delay = ($monitor->{MaxFPS}&&($monitor->{MaxFPS}>0)&&($monitor->{MaxFPS}<1))?(3/$monitor->{MaxFPS}):$Config{ZM_WATCH_MAX_DELAY};
my $image_delay = $now-$image_time; my $image_delay = $now-$image_time;
Debug( "Monitor $monitor->{Id} last analysed $image_delay seconds ago, max is $max_image_delay\n" ); Debug( "Monitor $monitor->{Id} last analysed $image_delay seconds ago, max is $max_image_delay\n" );
if ( $image_delay > $max_image_delay ) if ( $image_delay > $max_image_delay )
@ -142,7 +142,7 @@ while( 1 )
# Prevent open handles building up if we have connect to shared memory # Prevent open handles building up if we have connect to shared memory
zmMemInvalidate( $monitor ); zmMemInvalidate( $monitor );
} }
sleep( ZM_WATCH_CHECK_INTERVAL ); sleep( $Config{ZM_WATCH_CHECK_INTERVAL} );
} }
Info( "Watchdog exiting\n" ); Info( "Watchdog exiting\n" );
exit(); exit();

View File

@ -4,7 +4,7 @@
configure_file(zm_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config.h" @ONLY) configure_file(zm_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config.h" @ONLY)
# Group together all the source files that are used by all the binaries (zmc, zma, zmu, zms etc) # Group together all the source files that are used by all the binaries (zmc, zma, zmu, zms etc)
set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_camera.cpp zm_image.cpp zm_jpeg.cpp zm_local_camera.cpp zm_monitor.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_zone.cpp) set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_camera.cpp zm_image.cpp zm_jpeg.cpp zm_libvlc_camera.cpp zm_local_camera.cpp zm_monitor.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_zone.cpp)
# A fix for cmake recompiling the source files for every target. # A fix for cmake recompiling the source files for every target.
add_library(zm STATIC ${ZM_BIN_SRC_FILES}) add_library(zm STATIC ${ZM_BIN_SRC_FILES})
@ -16,7 +16,6 @@ add_executable(zmf zmf.cpp)
add_executable(zms zms.cpp) add_executable(zms zms.cpp)
add_executable(nph-zms zms.cpp) add_executable(nph-zms zms.cpp)
add_executable(zmstreamer zmstreamer.cpp) add_executable(zmstreamer zmstreamer.cpp)
add_executable(zmfix zmfix.cpp zm_config.cpp zm_regexp.cpp zm_logger.cpp zm_utils.cpp zm_db.cpp zm.cpp)
target_link_libraries(zmc zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) target_link_libraries(zmc zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS})
target_link_libraries(zma zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) target_link_libraries(zma zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS})
@ -25,9 +24,8 @@ target_link_libraries(zmf zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS})
target_link_libraries(zms zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) target_link_libraries(zms zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS})
target_link_libraries(nph-zms zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) target_link_libraries(nph-zms zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS})
target_link_libraries(zmstreamer zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) target_link_libraries(zmstreamer zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS})
target_link_libraries(zmfix ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS})
install(TARGETS zmc zma zmu zmf zmstreamer zmfix RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(TARGETS zmc zma zmu zmf zmstreamer RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(TARGETS zms nph-zms RUNTIME DESTINATION "${ZM_CGIDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(TARGETS zms nph-zms RUNTIME DESTINATION "${ZM_CGIDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)

View File

@ -17,8 +17,7 @@ bin_PROGRAMS = \
zmu \ zmu \
zms \ zms \
zmf \ zmf \
zmstreamer \ zmstreamer
zmfix
zm_SOURCES = \ zm_SOURCES = \
zm_box.cpp \ zm_box.cpp \
@ -36,6 +35,7 @@ zm_SOURCES = \
zm_ffmpeg_camera.cpp \ zm_ffmpeg_camera.cpp \
zm_image.cpp \ zm_image.cpp \
zm_jpeg.cpp \ zm_jpeg.cpp \
zm_libvlc_camera.cpp \
zm_local_camera.cpp \ zm_local_camera.cpp \
zm_monitor.cpp \ zm_monitor.cpp \
zm_ffmpeg.cpp \ zm_ffmpeg.cpp \
@ -66,7 +66,6 @@ zms_SOURCES = zms.cpp $(zm_SOURCES)
zmu_SOURCES = zmu.cpp $(zm_SOURCES) zmu_SOURCES = zmu.cpp $(zm_SOURCES)
zmf_SOURCES = zmf.cpp $(zm_SOURCES) zmf_SOURCES = zmf.cpp $(zm_SOURCES)
zmstreamer_SOURCES = zmstreamer.cpp $(zm_SOURCES) zmstreamer_SOURCES = zmstreamer.cpp $(zm_SOURCES)
zmfix_SOURCES = zmfix.cpp zm_config.cpp zm_regexp.cpp zm_logger.cpp zm_utils.cpp zm_db.cpp zm.cpp
noinst_HEADERS = \ noinst_HEADERS = \
jinclude.h \ jinclude.h \
@ -89,6 +88,7 @@ noinst_HEADERS = \
zm.h \ zm.h \
zm_image.h \ zm_image.h \
zm_jpeg.h \ zm_jpeg.h \
zm_libvlc_camera.h \
zm_local_camera.h \ zm_local_camera.h \
zm_mem_utils.h \ zm_mem_utils.h \
zm_monitor.h \ zm_monitor.h \
@ -126,7 +126,6 @@ dist-hook:
install-exec-hook: install-exec-hook:
( cd $(DESTDIR)@bindir@; mkdir -p $(DESTDIR)$(cgidir); mv zms $(DESTDIR)$(cgidir) ) ( cd $(DESTDIR)@bindir@; mkdir -p $(DESTDIR)$(cgidir); mv zms $(DESTDIR)$(cgidir) )
( cd $(DESTDIR)$(cgidir); chown $(webuser):$(webgroup) zms; ln -f zms nph-zms ) ( cd $(DESTDIR)$(cgidir); chown $(webuser):$(webgroup) zms; ln -f zms nph-zms )
( cd $(DESTDIR)@bindir@; chmod u+s zmfix )
uninstall-hook: uninstall-hook:
( cd $(DESTDIR)$(cgidir); rm -f zms nph-zms ) ( cd $(DESTDIR)$(cgidir); rm -f zms nph-zms )

View File

@ -23,13 +23,6 @@
#include "zm_config.h" #include "zm_config.h"
#include "zm_logger.h" #include "zm_logger.h"
extern "C"
{
#if !HAVE_DECL_ROUND
double round(double);
#endif
}
#include <stdint.h> #include <stdint.h>
extern const char* self; extern const char* self;

View File

@ -32,7 +32,7 @@
class Camera class Camera
{ {
protected: protected:
typedef enum { LOCAL_SRC, REMOTE_SRC, FILE_SRC, FFMPEG_SRC, CURL_SRC } SourceType; typedef enum { LOCAL_SRC, REMOTE_SRC, FILE_SRC, FFMPEG_SRC, LIBVLC_SRC, CURL_SRC } SourceType;
int id; int id;
SourceType type; SourceType type;
@ -58,6 +58,7 @@ public:
bool IsRemote() const { return( type == REMOTE_SRC ); } bool IsRemote() const { return( type == REMOTE_SRC ); }
bool IsFile() const { return( type == FILE_SRC ); } bool IsFile() const { return( type == FILE_SRC ); }
bool IsFfmpeg() const { return( type == FFMPEG_SRC ); } bool IsFfmpeg() const { return( type == FFMPEG_SRC ); }
bool IsLibvlc() const { return( type == LIBVLC_SRC ); }
unsigned int Width() const { return( width ); } unsigned int Width() const { return( width ); }
unsigned int Height() const { return( height ); } unsigned int Height() const { return( height ); }
unsigned int Colours() const { return( colours ); } unsigned int Colours() const { return( colours ); }

View File

@ -30,196 +30,195 @@
#define ZM_CPU_EXTENSIONS 26 #define ZM_CPU_EXTENSIONS 26
#define ZM_FAST_IMAGE_BLENDS 27 #define ZM_FAST_IMAGE_BLENDS 27
#define ZM_OPT_ADAPTIVE_SKIP 28 #define ZM_OPT_ADAPTIVE_SKIP 28
#define ZM_BLEND_ALARMED_IMAGES 29 #define ZM_MAX_SUSPEND_TIME 29
#define ZM_MAX_SUSPEND_TIME 30 #define ZM_OPT_REMOTE_CAMERAS 30
#define ZM_OPT_REMOTE_CAMERAS 31 #define ZM_NETCAM_REGEXPS 31
#define ZM_NETCAM_REGEXPS 32 #define ZM_HTTP_VERSION 32
#define ZM_HTTP_VERSION 33 #define ZM_HTTP_UA 33
#define ZM_HTTP_UA 34 #define ZM_HTTP_TIMEOUT 34
#define ZM_HTTP_TIMEOUT 35 #define ZM_MIN_RTP_PORT 35
#define ZM_MIN_RTP_PORT 36 #define ZM_MAX_RTP_PORT 36
#define ZM_MAX_RTP_PORT 37 #define ZM_OPT_FFMPEG 37
#define ZM_OPT_FFMPEG 38 #define ZM_PATH_FFMPEG 38
#define ZM_PATH_FFMPEG 39 #define ZM_FFMPEG_INPUT_OPTIONS 39
#define ZM_FFMPEG_INPUT_OPTIONS 40 #define ZM_FFMPEG_OUTPUT_OPTIONS 40
#define ZM_FFMPEG_OUTPUT_OPTIONS 41 #define ZM_FFMPEG_FORMATS 41
#define ZM_FFMPEG_FORMATS 42 #define ZM_LOG_LEVEL_SYSLOG 42
#define ZM_LOG_LEVEL_SYSLOG 43 #define ZM_LOG_LEVEL_FILE 43
#define ZM_LOG_LEVEL_FILE 44 #define ZM_LOG_LEVEL_WEBLOG 44
#define ZM_LOG_LEVEL_WEBLOG 45 #define ZM_LOG_LEVEL_DATABASE 45
#define ZM_LOG_LEVEL_DATABASE 46 #define ZM_LOG_DATABASE_LIMIT 46
#define ZM_LOG_DATABASE_LIMIT 47 #define ZM_LOG_DEBUG 47
#define ZM_LOG_DEBUG 48 #define ZM_LOG_DEBUG_TARGET 48
#define ZM_LOG_DEBUG_TARGET 49 #define ZM_LOG_DEBUG_LEVEL 49
#define ZM_LOG_DEBUG_LEVEL 50 #define ZM_LOG_DEBUG_FILE 50
#define ZM_LOG_DEBUG_FILE 51 #define ZM_LOG_CHECK_PERIOD 51
#define ZM_LOG_CHECK_PERIOD 52 #define ZM_LOG_ALERT_WAR_COUNT 52
#define ZM_LOG_ALERT_WAR_COUNT 53 #define ZM_LOG_ALERT_ERR_COUNT 53
#define ZM_LOG_ALERT_ERR_COUNT 54 #define ZM_LOG_ALERT_FAT_COUNT 54
#define ZM_LOG_ALERT_FAT_COUNT 55 #define ZM_LOG_ALARM_WAR_COUNT 55
#define ZM_LOG_ALARM_WAR_COUNT 56 #define ZM_LOG_ALARM_ERR_COUNT 56
#define ZM_LOG_ALARM_ERR_COUNT 57 #define ZM_LOG_ALARM_FAT_COUNT 57
#define ZM_LOG_ALARM_FAT_COUNT 58 #define ZM_RECORD_EVENT_STATS 58
#define ZM_RECORD_EVENT_STATS 59 #define ZM_RECORD_DIAG_IMAGES 59
#define ZM_RECORD_DIAG_IMAGES 60 #define ZM_DUMP_CORES 60
#define ZM_DUMP_CORES 61 #define ZM_PATH_MAP 61
#define ZM_PATH_MAP 62 #define ZM_PATH_SOCKS 62
#define ZM_PATH_SOCKS 63 #define ZM_PATH_LOGS 63
#define ZM_PATH_LOGS 64 #define ZM_PATH_SWAP 64
#define ZM_PATH_SWAP 65 #define ZM_WEB_TITLE_PREFIX 65
#define ZM_WEB_TITLE_PREFIX 66 #define ZM_WEB_RESIZE_CONSOLE 66
#define ZM_WEB_RESIZE_CONSOLE 67 #define ZM_WEB_POPUP_ON_ALARM 67
#define ZM_WEB_POPUP_ON_ALARM 68 #define ZM_OPT_X10 68
#define ZM_OPT_X10 69 #define ZM_X10_DEVICE 69
#define ZM_X10_DEVICE 70 #define ZM_X10_HOUSE_CODE 70
#define ZM_X10_HOUSE_CODE 71 #define ZM_X10_DB_RELOAD_INTERVAL 71
#define ZM_X10_DB_RELOAD_INTERVAL 72 #define ZM_WEB_SOUND_ON_ALARM 72
#define ZM_WEB_SOUND_ON_ALARM 73 #define ZM_WEB_ALARM_SOUND 73
#define ZM_WEB_ALARM_SOUND 74 #define ZM_WEB_COMPACT_MONTAGE 74
#define ZM_WEB_COMPACT_MONTAGE 75 #define ZM_OPT_FAST_DELETE 75
#define ZM_OPT_FAST_DELETE 76 #define ZM_STRICT_VIDEO_CONFIG 76
#define ZM_STRICT_VIDEO_CONFIG 77 #define ZM_SIGNAL_CHECK_POINTS 77
#define ZM_SIGNAL_CHECK_POINTS 78 #define ZM_V4L_MULTI_BUFFER 78
#define ZM_V4L_MULTI_BUFFER 79 #define ZM_CAPTURES_PER_FRAME 79
#define ZM_CAPTURES_PER_FRAME 80 #define ZM_FILTER_RELOAD_DELAY 80
#define ZM_FILTER_RELOAD_DELAY 81 #define ZM_FILTER_EXECUTE_INTERVAL 81
#define ZM_FILTER_EXECUTE_INTERVAL 82 #define ZM_OPT_UPLOAD 82
#define ZM_OPT_UPLOAD 83 #define ZM_UPLOAD_ARCH_FORMAT 83
#define ZM_UPLOAD_ARCH_FORMAT 84 #define ZM_UPLOAD_ARCH_COMPRESS 84
#define ZM_UPLOAD_ARCH_COMPRESS 85 #define ZM_UPLOAD_ARCH_ANALYSE 85
#define ZM_UPLOAD_ARCH_ANALYSE 86 #define ZM_UPLOAD_PROTOCOL 86
#define ZM_UPLOAD_PROTOCOL 87 #define ZM_UPLOAD_FTP_HOST 87
#define ZM_UPLOAD_FTP_HOST 88 #define ZM_UPLOAD_HOST 88
#define ZM_UPLOAD_HOST 89 #define ZM_UPLOAD_PORT 89
#define ZM_UPLOAD_PORT 90 #define ZM_UPLOAD_FTP_USER 90
#define ZM_UPLOAD_FTP_USER 91 #define ZM_UPLOAD_USER 91
#define ZM_UPLOAD_USER 92 #define ZM_UPLOAD_FTP_PASS 92
#define ZM_UPLOAD_FTP_PASS 93 #define ZM_UPLOAD_PASS 93
#define ZM_UPLOAD_PASS 94 #define ZM_UPLOAD_FTP_LOC_DIR 94
#define ZM_UPLOAD_FTP_LOC_DIR 95 #define ZM_UPLOAD_LOC_DIR 95
#define ZM_UPLOAD_LOC_DIR 96 #define ZM_UPLOAD_FTP_REM_DIR 96
#define ZM_UPLOAD_FTP_REM_DIR 97 #define ZM_UPLOAD_REM_DIR 97
#define ZM_UPLOAD_REM_DIR 98 #define ZM_UPLOAD_FTP_TIMEOUT 98
#define ZM_UPLOAD_FTP_TIMEOUT 99 #define ZM_UPLOAD_TIMEOUT 99
#define ZM_UPLOAD_TIMEOUT 100 #define ZM_UPLOAD_FTP_PASSIVE 100
#define ZM_UPLOAD_FTP_PASSIVE 101 #define ZM_UPLOAD_FTP_DEBUG 101
#define ZM_UPLOAD_FTP_DEBUG 102 #define ZM_UPLOAD_DEBUG 102
#define ZM_UPLOAD_DEBUG 103 #define ZM_OPT_EMAIL 103
#define ZM_OPT_EMAIL 104 #define ZM_EMAIL_ADDRESS 104
#define ZM_EMAIL_ADDRESS 105 #define ZM_EMAIL_TEXT 105
#define ZM_EMAIL_TEXT 106 #define ZM_EMAIL_SUBJECT 106
#define ZM_EMAIL_SUBJECT 107 #define ZM_EMAIL_BODY 107
#define ZM_EMAIL_BODY 108 #define ZM_OPT_MESSAGE 108
#define ZM_OPT_MESSAGE 109 #define ZM_MESSAGE_ADDRESS 109
#define ZM_MESSAGE_ADDRESS 110 #define ZM_MESSAGE_TEXT 110
#define ZM_MESSAGE_TEXT 111 #define ZM_MESSAGE_SUBJECT 111
#define ZM_MESSAGE_SUBJECT 112 #define ZM_MESSAGE_BODY 112
#define ZM_MESSAGE_BODY 113 #define ZM_NEW_MAIL_MODULES 113
#define ZM_NEW_MAIL_MODULES 114 #define ZM_EMAIL_HOST 114
#define ZM_EMAIL_HOST 115 #define ZM_FROM_EMAIL 115
#define ZM_FROM_EMAIL 116 #define ZM_URL 116
#define ZM_URL 117 #define ZM_MAX_RESTART_DELAY 117
#define ZM_MAX_RESTART_DELAY 118 #define ZM_WATCH_CHECK_INTERVAL 118
#define ZM_WATCH_CHECK_INTERVAL 119 #define ZM_WATCH_MAX_DELAY 119
#define ZM_WATCH_MAX_DELAY 120 #define ZM_RUN_AUDIT 120
#define ZM_RUN_AUDIT 121 #define ZM_AUDIT_CHECK_INTERVAL 121
#define ZM_AUDIT_CHECK_INTERVAL 122 #define ZM_FORCED_ALARM_SCORE 122
#define ZM_FORCED_ALARM_SCORE 123 #define ZM_BULK_FRAME_INTERVAL 123
#define ZM_BULK_FRAME_INTERVAL 124 #define ZM_EVENT_CLOSE_MODE 124
#define ZM_EVENT_CLOSE_MODE 125 #define ZM_FORCE_CLOSE_EVENTS 125
#define ZM_FORCE_CLOSE_EVENTS 126 #define ZM_CREATE_ANALYSIS_IMAGES 126
#define ZM_CREATE_ANALYSIS_IMAGES 127 #define ZM_WEIGHTED_ALARM_CENTRES 127
#define ZM_WEIGHTED_ALARM_CENTRES 128 #define ZM_EVENT_IMAGE_DIGITS 128
#define ZM_EVENT_IMAGE_DIGITS 129 #define ZM_DEFAULT_ASPECT_RATIO 129
#define ZM_DEFAULT_ASPECT_RATIO 130 #define ZM_USER_SELF_EDIT 130
#define ZM_USER_SELF_EDIT 131 #define ZM_OPT_FRAME_SERVER 131
#define ZM_OPT_FRAME_SERVER 132 #define ZM_FRAME_SOCKET_SIZE 132
#define ZM_FRAME_SOCKET_SIZE 133 #define ZM_OPT_CONTROL 133
#define ZM_OPT_CONTROL 134 #define ZM_OPT_TRIGGERS 134
#define ZM_OPT_TRIGGERS 135 #define ZM_CHECK_FOR_UPDATES 135
#define ZM_CHECK_FOR_UPDATES 136 #define ZM_UPDATE_CHECK_PROXY 136
#define ZM_UPDATE_CHECK_PROXY 137 #define ZM_SHM_KEY 137
#define ZM_SHM_KEY 138 #define ZM_WEB_REFRESH_METHOD 138
#define ZM_WEB_REFRESH_METHOD 139 #define ZM_WEB_EVENT_SORT_FIELD 139
#define ZM_WEB_EVENT_SORT_FIELD 140 #define ZM_WEB_EVENT_SORT_ORDER 140
#define ZM_WEB_EVENT_SORT_ORDER 141 #define ZM_WEB_EVENTS_PER_PAGE 141
#define ZM_WEB_EVENTS_PER_PAGE 142 #define ZM_WEB_LIST_THUMBS 142
#define ZM_WEB_LIST_THUMBS 143 #define ZM_WEB_LIST_THUMB_WIDTH 143
#define ZM_WEB_LIST_THUMB_WIDTH 144 #define ZM_WEB_LIST_THUMB_HEIGHT 144
#define ZM_WEB_LIST_THUMB_HEIGHT 145 #define ZM_WEB_USE_OBJECT_TAGS 145
#define ZM_WEB_USE_OBJECT_TAGS 146 #define ZM_WEB_H_REFRESH_MAIN 146
#define ZM_WEB_H_REFRESH_MAIN 147 #define ZM_WEB_H_REFRESH_CYCLE 147
#define ZM_WEB_H_REFRESH_CYCLE 148 #define ZM_WEB_H_REFRESH_IMAGE 148
#define ZM_WEB_H_REFRESH_IMAGE 149 #define ZM_WEB_H_REFRESH_STATUS 149
#define ZM_WEB_H_REFRESH_STATUS 150 #define ZM_WEB_H_REFRESH_EVENTS 150
#define ZM_WEB_H_REFRESH_EVENTS 151 #define ZM_WEB_H_CAN_STREAM 151
#define ZM_WEB_H_CAN_STREAM 152 #define ZM_WEB_H_STREAM_METHOD 152
#define ZM_WEB_H_STREAM_METHOD 153 #define ZM_WEB_H_DEFAULT_SCALE 153
#define ZM_WEB_H_DEFAULT_SCALE 154 #define ZM_WEB_H_DEFAULT_RATE 154
#define ZM_WEB_H_DEFAULT_RATE 155 #define ZM_WEB_H_VIDEO_BITRATE 155
#define ZM_WEB_H_VIDEO_BITRATE 156 #define ZM_WEB_H_VIDEO_MAXFPS 156
#define ZM_WEB_H_VIDEO_MAXFPS 157 #define ZM_WEB_H_SCALE_THUMBS 157
#define ZM_WEB_H_SCALE_THUMBS 158 #define ZM_WEB_H_EVENTS_VIEW 158
#define ZM_WEB_H_EVENTS_VIEW 159 #define ZM_WEB_H_SHOW_PROGRESS 159
#define ZM_WEB_H_SHOW_PROGRESS 160 #define ZM_WEB_H_AJAX_TIMEOUT 160
#define ZM_WEB_H_AJAX_TIMEOUT 161 #define ZM_WEB_M_REFRESH_MAIN 161
#define ZM_WEB_M_REFRESH_MAIN 162 #define ZM_WEB_M_REFRESH_CYCLE 162
#define ZM_WEB_M_REFRESH_CYCLE 163 #define ZM_WEB_M_REFRESH_IMAGE 163
#define ZM_WEB_M_REFRESH_IMAGE 164 #define ZM_WEB_M_REFRESH_STATUS 164
#define ZM_WEB_M_REFRESH_STATUS 165 #define ZM_WEB_M_REFRESH_EVENTS 165
#define ZM_WEB_M_REFRESH_EVENTS 166 #define ZM_WEB_M_CAN_STREAM 166
#define ZM_WEB_M_CAN_STREAM 167 #define ZM_WEB_M_STREAM_METHOD 167
#define ZM_WEB_M_STREAM_METHOD 168 #define ZM_WEB_M_DEFAULT_SCALE 168
#define ZM_WEB_M_DEFAULT_SCALE 169 #define ZM_WEB_M_DEFAULT_RATE 169
#define ZM_WEB_M_DEFAULT_RATE 170 #define ZM_WEB_M_VIDEO_BITRATE 170
#define ZM_WEB_M_VIDEO_BITRATE 171 #define ZM_WEB_M_VIDEO_MAXFPS 171
#define ZM_WEB_M_VIDEO_MAXFPS 172 #define ZM_WEB_M_SCALE_THUMBS 172
#define ZM_WEB_M_SCALE_THUMBS 173 #define ZM_WEB_M_EVENTS_VIEW 173
#define ZM_WEB_M_EVENTS_VIEW 174 #define ZM_WEB_M_SHOW_PROGRESS 174
#define ZM_WEB_M_SHOW_PROGRESS 175 #define ZM_WEB_M_AJAX_TIMEOUT 175
#define ZM_WEB_M_AJAX_TIMEOUT 176 #define ZM_WEB_L_REFRESH_MAIN 176
#define ZM_WEB_L_REFRESH_MAIN 177 #define ZM_WEB_L_REFRESH_CYCLE 177
#define ZM_WEB_L_REFRESH_CYCLE 178 #define ZM_WEB_L_REFRESH_IMAGE 178
#define ZM_WEB_L_REFRESH_IMAGE 179 #define ZM_WEB_L_REFRESH_STATUS 179
#define ZM_WEB_L_REFRESH_STATUS 180 #define ZM_WEB_L_REFRESH_EVENTS 180
#define ZM_WEB_L_REFRESH_EVENTS 181 #define ZM_WEB_L_CAN_STREAM 181
#define ZM_WEB_L_CAN_STREAM 182 #define ZM_WEB_L_STREAM_METHOD 182
#define ZM_WEB_L_STREAM_METHOD 183 #define ZM_WEB_L_DEFAULT_SCALE 183
#define ZM_WEB_L_DEFAULT_SCALE 184 #define ZM_WEB_L_DEFAULT_RATE 184
#define ZM_WEB_L_DEFAULT_RATE 185 #define ZM_WEB_L_VIDEO_BITRATE 185
#define ZM_WEB_L_VIDEO_BITRATE 186 #define ZM_WEB_L_VIDEO_MAXFPS 186
#define ZM_WEB_L_VIDEO_MAXFPS 187 #define ZM_WEB_L_SCALE_THUMBS 187
#define ZM_WEB_L_SCALE_THUMBS 188 #define ZM_WEB_L_EVENTS_VIEW 188
#define ZM_WEB_L_EVENTS_VIEW 189 #define ZM_WEB_L_SHOW_PROGRESS 189
#define ZM_WEB_L_SHOW_PROGRESS 190 #define ZM_WEB_L_AJAX_TIMEOUT 190
#define ZM_WEB_L_AJAX_TIMEOUT 191 #define ZM_WEB_P_CAN_STREAM 191
#define ZM_WEB_P_CAN_STREAM 192 #define ZM_WEB_P_STREAM_METHOD 192
#define ZM_WEB_P_STREAM_METHOD 193 #define ZM_WEB_P_DEFAULT_SCALE 193
#define ZM_WEB_P_DEFAULT_SCALE 194 #define ZM_WEB_P_DEFAULT_RATE 194
#define ZM_WEB_P_DEFAULT_RATE 195 #define ZM_WEB_P_VIDEO_BITRATE 195
#define ZM_WEB_P_VIDEO_BITRATE 196 #define ZM_WEB_P_VIDEO_MAXFPS 196
#define ZM_WEB_P_VIDEO_MAXFPS 197 #define ZM_WEB_P_SCALE_THUMBS 197
#define ZM_WEB_P_SCALE_THUMBS 198 #define ZM_WEB_P_AJAX_TIMEOUT 198
#define ZM_WEB_P_AJAX_TIMEOUT 199 #define ZM_DYN_LAST_VERSION 199
#define ZM_DYN_LAST_VERSION 200 #define ZM_DYN_CURR_VERSION 200
#define ZM_DYN_CURR_VERSION 201 #define ZM_DYN_DB_VERSION 201
#define ZM_DYN_DB_VERSION 202 #define ZM_DYN_LAST_CHECK 202
#define ZM_DYN_LAST_CHECK 203 #define ZM_DYN_NEXT_REMINDER 203
#define ZM_DYN_NEXT_REMINDER 204 #define ZM_DYN_DONATE_REMINDER_TIME 204
#define ZM_DYN_DONATE_REMINDER_TIME 205 #define ZM_DYN_SHOW_DONATE_REMINDER 205
#define ZM_DYN_SHOW_DONATE_REMINDER 206 #define ZM_EYEZM_DEBUG 206
#define ZM_EYEZM_DEBUG 207 #define ZM_EYEZM_LOG_TO_FILE 207
#define ZM_EYEZM_LOG_TO_FILE 208 #define ZM_EYEZM_LOG_FILE 208
#define ZM_EYEZM_LOG_FILE 209 #define ZM_EYEZM_EVENT_VCODEC 209
#define ZM_EYEZM_EVENT_VCODEC 210 #define ZM_EYEZM_FEED_VCODEC 210
#define ZM_EYEZM_FEED_VCODEC 211 #define ZM_EYEZM_H264_DEFAULT_BR 211
#define ZM_EYEZM_H264_DEFAULT_BR 212 #define ZM_EYEZM_H264_DEFAULT_EVBR 212
#define ZM_EYEZM_H264_DEFAULT_EVBR 213 #define ZM_EYEZM_H264_TIMEOUT 213
#define ZM_EYEZM_H264_TIMEOUT 214 #define ZM_EYEZM_SEG_DURATION 214
#define ZM_EYEZM_SEG_DURATION 215
#define ZM_MAX_CFG_ID 215 #define ZM_MAX_CFG_ID 214
#define ZM_CFG_DECLARE_LIST \ #define ZM_CFG_DECLARE_LIST \
const char *lang_default;\ const char *lang_default;\
@ -251,7 +250,6 @@
bool cpu_extensions;\ bool cpu_extensions;\
bool fast_image_blends;\ bool fast_image_blends;\
bool opt_adaptive_skip;\ bool opt_adaptive_skip;\
bool blend_alarmed_images;\
int max_suspend_time;\ int max_suspend_time;\
bool opt_remote_cameras;\ bool opt_remote_cameras;\
bool netcam_regexps;\ bool netcam_regexps;\
@ -470,7 +468,6 @@
cpu_extensions = (bool)config.Item( ZM_CPU_EXTENSIONS );\ cpu_extensions = (bool)config.Item( ZM_CPU_EXTENSIONS );\
fast_image_blends = (bool)config.Item( ZM_FAST_IMAGE_BLENDS );\ fast_image_blends = (bool)config.Item( ZM_FAST_IMAGE_BLENDS );\
opt_adaptive_skip = (bool)config.Item( ZM_OPT_ADAPTIVE_SKIP );\ opt_adaptive_skip = (bool)config.Item( ZM_OPT_ADAPTIVE_SKIP );\
blend_alarmed_images = (bool)config.Item( ZM_BLEND_ALARMED_IMAGES );\
max_suspend_time = (int)config.Item( ZM_MAX_SUSPEND_TIME );\ max_suspend_time = (int)config.Item( ZM_MAX_SUSPEND_TIME );\
opt_remote_cameras = (bool)config.Item( ZM_OPT_REMOTE_CAMERAS );\ opt_remote_cameras = (bool)config.Item( ZM_OPT_REMOTE_CAMERAS );\
netcam_regexps = (bool)config.Item( ZM_NETCAM_REGEXPS );\ netcam_regexps = (bool)config.Item( ZM_NETCAM_REGEXPS );\

View File

@ -17,8 +17,201 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#if HAVE_LIBAVCODEC
#include "zm_ffmpeg.h" #include "zm_ffmpeg.h"
#include "zm_image.h"
#include "zm_rgb.h"
#endif // HAVE_LIBAVCODEC #if HAVE_LIBAVCODEC || HAVE_LIBAVUTIL || HAVE_LIBSWSCALE
#if HAVE_LIBAVUTIL
enum PixelFormat GetFFMPEGPixelFormat(unsigned int p_colours, unsigned p_subpixelorder) {
enum PixelFormat pf;
Debug(8,"Colours: %d SubpixelOrder: %d",p_colours,p_subpixelorder);
switch(p_colours) {
case ZM_COLOUR_RGB24:
{
if(p_subpixelorder == ZM_SUBPIX_ORDER_BGR) {
/* BGR subpixel order */
pf = PIX_FMT_BGR24;
} else {
/* Assume RGB subpixel order */
pf = PIX_FMT_RGB24;
}
break;
}
case ZM_COLOUR_RGB32:
{
if(p_subpixelorder == ZM_SUBPIX_ORDER_ARGB) {
/* ARGB subpixel order */
pf = PIX_FMT_ARGB;
} else if(p_subpixelorder == ZM_SUBPIX_ORDER_ABGR) {
/* ABGR subpixel order */
pf = PIX_FMT_ABGR;
} else if(p_subpixelorder == ZM_SUBPIX_ORDER_BGRA) {
/* BGRA subpixel order */
pf = PIX_FMT_BGRA;
} else {
/* Assume RGBA subpixel order */
pf = PIX_FMT_RGBA;
}
break;
}
case ZM_COLOUR_GRAY8:
pf = PIX_FMT_GRAY8;
break;
default:
Panic("Unexpected colours: %d",p_colours);
pf = PIX_FMT_GRAY8; /* Just to shush gcc variable may be unused warning */
break;
}
return pf;
}
#endif // HAVE_LIBAVUTIL
#if HAVE_LIBSWSCALE && HAVE_LIBAVUTIL
SWScale::SWScale() : gotdefaults(false), swscale_ctx(NULL), input_avframe(NULL), output_avframe(NULL) {
Debug(4,"SWScale object created");
/* Allocate AVFrame for the input */
input_avframe = avcodec_alloc_frame();
if(input_avframe == NULL) {
Fatal("Failed allocating AVFrame for the input");
}
/* Allocate AVFrame for the output */
output_avframe = avcodec_alloc_frame();
if(output_avframe == NULL) {
Fatal("Failed allocating AVFrame for the output");
}
}
SWScale::~SWScale() {
/* Free up everything */
av_free(input_avframe);
input_avframe = NULL;
av_free(output_avframe);
output_avframe = NULL;
if(swscale_ctx) {
sws_freeContext(swscale_ctx);
swscale_ctx = NULL;
}
Debug(4,"SWScale object destroyed");
}
int SWScale::SetDefaults(enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height) {
/* Assign the defaults */
default_input_pf = in_pf;
default_output_pf = out_pf;
default_width = width;
default_height = height;
gotdefaults = true;
return 0;
}
int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height) {
/* Parameter checking */
if(in_buffer == NULL || out_buffer == NULL) {
Error("NULL Input or output buffer");
return -1;
}
if(in_pf == 0 || out_pf == 0) {
Error("Invalid input or output pixel formats");
return -2;
}
if(!width || !height) {
Error("Invalid width or height");
return -3;
}
/* Warn if the input or output pixelformat is not supported */
if(!sws_isSupportedInput(in_pf)) {
Warning("swscale does not support the input format: %c%c%c%c",(in_pf)&0xff,((in_pf)&0xff),((in_pf>>16)&0xff),((in_pf>>24)&0xff));
}
if(!sws_isSupportedOutput(out_pf)) {
Warning("swscale does not support the output format: %c%c%c%c",(out_pf)&0xff,((out_pf>>8)&0xff),((out_pf>>16)&0xff),((out_pf>>24)&0xff));
}
/* Check the buffer sizes */
size_t insize = avpicture_get_size(in_pf, width, height);
if(insize != in_buffer_size) {
Error("The input buffer size does not match the expected size for the input format. Required: %d Available: %d", insize, in_buffer_size);
return -4;
}
size_t outsize = avpicture_get_size(out_pf, width, height);
if(outsize < out_buffer_size) {
Error("The output buffer is undersized for the output format. Required: %d Available: %d", outsize, out_buffer_size);
return -5;
}
/* Get the context */
swscale_ctx = sws_getCachedContext( NULL, width, height, in_pf, width, height, out_pf, 0, NULL, NULL, NULL );
if(swscale_ctx == NULL) {
Error("Failed getting swscale context");
return -6;
}
/* Fill in the buffers */
if(!avpicture_fill( (AVPicture*)input_avframe, (uint8_t*)in_buffer, in_pf, width, height ) ) {
Error("Failed filling input frame with input buffer");
return -7;
}
if(!avpicture_fill( (AVPicture*)output_avframe, out_buffer, out_pf, width, height ) ) {
Error("Failed filling output frame with output buffer");
return -8;
}
/* Do the conversion */
if(!sws_scale(swscale_ctx, input_avframe->data, input_avframe->linesize, 0, height, output_avframe->data, output_avframe->linesize ) ) {
Error("swscale conversion failed");
return -10;
}
return 0;
}
int SWScale::Convert(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size, enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height) {
if(img->Width() != width) {
Error("Source image width differs. Source: %d Output: %d",img->Width(), width);
return -12;
}
if(img->Height() != height) {
Error("Source image height differs. Source: %d Output: %d",img->Height(), height);
return -13;
}
return Convert(img->Buffer(),img->Size(),out_buffer,out_buffer_size,in_pf,out_pf,width,height);
}
int SWScale::ConvertDefaults(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size) {
if(!gotdefaults) {
Error("Defaults are not set");
return -24;
}
return Convert(img,out_buffer,out_buffer_size,default_input_pf,default_output_pf,default_width,default_height);
}
int SWScale::ConvertDefaults(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size) {
if(!gotdefaults) {
Error("Defaults are not set");
return -24;
}
return Convert(in_buffer,in_buffer_size,out_buffer,out_buffer_size,default_input_pf,default_output_pf,default_width,default_height);
}
#endif // HAVE_LIBSWSCALE && HAVE_LIBAVUTIL
#endif // HAVE_LIBAVCODEC || HAVE_LIBAVUTIL || HAVE_LIBSWSCALE

View File

@ -20,6 +20,8 @@
#ifndef ZM_FFMPEG_H #ifndef ZM_FFMPEG_H
#define ZM_FFMPEG_H #define ZM_FFMPEG_H
#include <stdint.h> #include <stdint.h>
#include "zm.h"
#include "zm_image.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -95,6 +97,37 @@ extern "C" {
#define SWS_CPU_CAPS_SSE2 0x02000000 #define SWS_CPU_CAPS_SSE2 0x02000000
#endif #endif
#if HAVE_LIBAVUTIL
enum PixelFormat GetFFMPEGPixelFormat(unsigned int p_colours, unsigned p_subpixelorder);
#endif // HAVE_LIBAVUTIL
/* SWScale wrapper class to make our life easier and reduce code reuse */
#if HAVE_LIBSWSCALE && HAVE_LIBAVUTIL
class SWScale {
public:
SWScale();
~SWScale();
int SetDefaults(enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height);
int ConvertDefaults(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size);
int ConvertDefaults(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size);
int Convert(const Image* img, uint8_t* out_buffer, const size_t out_buffer_size, enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height);
int Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum PixelFormat in_pf, enum PixelFormat out_pf, unsigned int width, unsigned int height);
protected:
bool gotdefaults;
struct SwsContext* swscale_ctx;
AVFrame* input_avframe;
AVFrame* output_avframe;
enum PixelFormat default_input_pf;
enum PixelFormat default_output_pf;
unsigned int default_width;
unsigned int default_height;
};
#endif // HAVE_LIBSWSCALE && HAVE_LIBAVUTIL
#endif // ( HAVE_LIBAVUTIL_AVUTIL_H || HAVE_LIBAVCODEC_AVCODEC_H || HAVE_LIBAVFORMAT_AVFORMAT_H || HAVE_LIBAVDEVICE_AVDEVICE_H ) #endif // ( HAVE_LIBAVUTIL_AVUTIL_H || HAVE_LIBAVCODEC_AVCODEC_H || HAVE_LIBAVFORMAT_AVFORMAT_H || HAVE_LIBAVDEVICE_AVDEVICE_H )
#endif // ZM_FFMPEG_H #endif // ZM_FFMPEG_H

View File

@ -3000,23 +3000,23 @@ __attribute__((noinline,__target__("sse2"))) void sse2_fastblend(const uint8_t*
// 1.5625% blending // 1.5625% blending
divider = 6; divider = 6;
clearmask = 0x03030303; clearmask = 0x03030303;
} else if(blendpercent >= 2.34375 && blendpercent < 4.6875) { } else if(blendpercent < 4.6875) {
// 3.125% blending // 3.125% blending
divider = 5; divider = 5;
clearmask = 0x07070707; clearmask = 0x07070707;
} else if(blendpercent >= 4.6875 && blendpercent < 9.375) { } else if(blendpercent < 9.375) {
// 6.25% blending // 6.25% blending
divider = 4; divider = 4;
clearmask = 0x0F0F0F0F; clearmask = 0x0F0F0F0F;
} else if(blendpercent >= 9.375 && blendpercent < 18.75) { } else if(blendpercent < 18.75) {
// 12.5% blending // 12.5% blending
divider = 3; divider = 3;
clearmask = 0x1F1F1F1F; clearmask = 0x1F1F1F1F;
} else if(blendpercent >= 18.75 && blendpercent < 37.5) { } else if(blendpercent < 37.5) {
// 25% blending // 25% blending
divider = 2; divider = 2;
clearmask = 0x3F3F3F3F; clearmask = 0x3F3F3F3F;
} else if(blendpercent >= 37.5) { } else {
// 50% blending // 50% blending
divider = 1; divider = 1;
clearmask = 0x7F7F7F7F; clearmask = 0x7F7F7F7F;
@ -3063,19 +3063,19 @@ __attribute__((noinline)) void std_fastblend(const uint8_t* col1, const uint8_t*
if(blendpercent < 2.34375) { if(blendpercent < 2.34375) {
// 1.5625% blending // 1.5625% blending
divider = 6; divider = 6;
} else if(blendpercent >= 2.34375 && blendpercent < 4.6875) { } else if(blendpercent < 4.6875) {
// 3.125% blending // 3.125% blending
divider = 5; divider = 5;
} else if(blendpercent >= 4.6875 && blendpercent < 9.375) { } else if(blendpercent < 9.375) {
// 6.25% blending // 6.25% blending
divider = 4; divider = 4;
} else if(blendpercent >= 9.375 && blendpercent < 18.75) { } else if(blendpercent < 18.75) {
// 12.5% blending // 12.5% blending
divider = 3; divider = 3;
} else if(blendpercent >= 18.75 && blendpercent < 37.5) { } else if(blendpercent < 37.5) {
// 25% blending // 25% blending
divider = 2; divider = 2;
} else if(blendpercent >= 37.5) { } else {
// 50% blending // 50% blending
divider = 1; divider = 1;
} }

192
src/zm_libvlc_camera.cpp Normal file
View File

@ -0,0 +1,192 @@
/*
* ZoneMinder Libvlc Camera Class Implementation, $Date$, $Revision$
* Copyright (C) 2001-2008 Philip Coombes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "zm.h"
#include "zm_libvlc_camera.h"
#if HAVE_LIBVLC
// Do all the buffer checking work here to avoid unnecessary locking
void* LibvlcLockBuffer(void* opaque, void** planes)
{
LibvlcPrivateData* data = (LibvlcPrivateData*)opaque;
data->mutex.lock();
uint8_t* buffer = data->buffer;
data->buffer = data->prevBuffer;
data->prevBuffer = buffer;
*planes = data->buffer;
return NULL;
}
void LibvlcUnlockBuffer(void* opaque, void* picture, void *const *planes)
{
LibvlcPrivateData* data = (LibvlcPrivateData*)opaque;
bool newFrame = false;
for(uint32_t i = 0; i < data->bufferSize; i++)
{
if(data->buffer[i] != data->prevBuffer[i])
{
newFrame = true;
break;
}
}
data->mutex.unlock();
time_t now;
time(&now);
// Return frames slightly faster than 1fps (if time() supports greater than one second resolution)
if(newFrame || difftime(now, data->prevTime) >= 0.8)
{
data->prevTime = now;
data->newImage.updateValueSignal(true);
}
}
LibvlcCamera::LibvlcCamera( int p_id, const std::string &p_path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) :
Camera( p_id, LIBVLC_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture ),
mPath( p_path )
{
mLibvlcInstance = NULL;
mLibvlcMedia = NULL;
mLibvlcMediaPlayer = NULL;
mLibvlcData.buffer = NULL;
mLibvlcData.prevBuffer = NULL;
/* Has to be located inside the constructor so other components such as zma will receive correct colours and subpixel order */
if(colours == ZM_COLOUR_RGB32) {
subpixelorder = ZM_SUBPIX_ORDER_BGRA;
mTargetChroma = "RV32";
mBpp = 4;
} else if(colours == ZM_COLOUR_RGB24) {
subpixelorder = ZM_SUBPIX_ORDER_BGR;
mTargetChroma = "RV24";
mBpp = 3;
} else if(colours == ZM_COLOUR_GRAY8) {
subpixelorder = ZM_SUBPIX_ORDER_NONE;
mTargetChroma = "GREY";
mBpp = 1;
} else {
Panic("Unexpected colours: %d",colours);
}
if ( capture )
{
Initialise();
}
}
LibvlcCamera::~LibvlcCamera()
{
if ( capture )
{
Terminate();
}
if(mLibvlcMediaPlayer != NULL)
{
libvlc_media_player_release(mLibvlcMediaPlayer);
mLibvlcMediaPlayer = NULL;
}
if(mLibvlcMedia != NULL)
{
libvlc_media_release(mLibvlcMedia);
mLibvlcMedia = NULL;
}
if(mLibvlcInstance != NULL)
{
libvlc_release(mLibvlcInstance);
mLibvlcInstance = NULL;
}
}
void LibvlcCamera::Initialise()
{
}
void LibvlcCamera::Terminate()
{
libvlc_media_player_stop(mLibvlcMediaPlayer);
if(mLibvlcData.buffer != NULL)
{
zm_freealigned(mLibvlcData.buffer);
}
if(mLibvlcData.prevBuffer != NULL)
{
zm_freealigned(mLibvlcData.prevBuffer);
}
}
int LibvlcCamera::PrimeCapture()
{
Info("Priming capture from %s", mPath.c_str());
mLibvlcInstance = libvlc_new (0, NULL);
if(mLibvlcInstance == NULL)
Fatal("Unable to create libvlc instance due to: %s", libvlc_errmsg());
mLibvlcMedia = libvlc_media_new_location(mLibvlcInstance, mPath.c_str());
if(mLibvlcMedia == NULL)
Fatal("Unable to open input %s due to: %s", mPath.c_str(), libvlc_errmsg());
mLibvlcMediaPlayer = libvlc_media_player_new_from_media(mLibvlcMedia);
if(mLibvlcMediaPlayer == NULL)
Fatal("Unable to create player for %s due to: %s", mPath.c_str(), libvlc_errmsg());
libvlc_video_set_format(mLibvlcMediaPlayer, mTargetChroma.c_str(), width, height, width * mBpp);
libvlc_video_set_callbacks(mLibvlcMediaPlayer, &LibvlcLockBuffer, &LibvlcUnlockBuffer, NULL, &mLibvlcData);
mLibvlcData.bufferSize = width * height * mBpp;
// Libvlc wants 32 byte alignment for images (should in theory do this for all image lines)
mLibvlcData.buffer = (uint8_t*)zm_mallocaligned(32, mLibvlcData.bufferSize);
mLibvlcData.prevBuffer = (uint8_t*)zm_mallocaligned(32, mLibvlcData.bufferSize);
mLibvlcData.newImage.setValueImmediate(false);
libvlc_media_player_play(mLibvlcMediaPlayer);
return(0);
}
int LibvlcCamera::PreCapture()
{
return(0);
}
// Should not return -1 as cancels capture. Always wait for image if available.
int LibvlcCamera::Capture( Image &image )
{
while(!mLibvlcData.newImage.getValueImmediate())
mLibvlcData.newImage.getUpdatedValue(1);
mLibvlcData.mutex.lock();
image.Assign(width, height, colours, subpixelorder, mLibvlcData.buffer, width * height * mBpp);
mLibvlcData.newImage.setValueImmediate(false);
mLibvlcData.mutex.unlock();
return (0);
}
int LibvlcCamera::PostCapture()
{
return(0);
}
#endif // HAVE_LIBVLC

73
src/zm_libvlc_camera.h Normal file
View File

@ -0,0 +1,73 @@
/*
* ZoneMinder Libvlc Camera Class Interface, $Date$, $Revision$
* Copyright (C) 2001-2008 Philip Coombes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef ZM_LIBVLC_CAMERA_H
#define ZM_LIBVLC_CAMERA_H
#include "zm_buffer.h"
#include "zm_camera.h"
#include "zm_thread.h"
#if HAVE_LIBVLC
#if HAVE_VLC_VLC_H
#include "vlc/vlc.h"
#endif
// Used by libvlc callbacks
struct LibvlcPrivateData
{
uint8_t* buffer;
uint8_t* prevBuffer;
time_t prevTime;
uint32_t bufferSize;
Mutex mutex;
ThreadData<bool> newImage;
};
class LibvlcCamera : public Camera
{
protected:
std::string mPath;
LibvlcPrivateData mLibvlcData;
std::string mTargetChroma;
uint8_t mBpp;
libvlc_instance_t *mLibvlcInstance;
libvlc_media_t *mLibvlcMedia;
libvlc_media_player_t *mLibvlcMediaPlayer;
public:
LibvlcCamera( int p_id, const std::string &path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture );
~LibvlcCamera();
const std::string &Path() const { return( mPath ); }
void Initialise();
void Terminate();
int PrimeCapture();
int PreCapture();
int Capture( Image &image );
int PostCapture();
};
#endif // HAVE_LIBVLC
#endif // ZM_LIBVLC_CAMERA_H

View File

@ -104,9 +104,11 @@ static PixelFormat getFfPixFormatFromV4lPalette( int v4l_version, int palette )
case V4L2_PIX_FMT_MJPEG : case V4L2_PIX_FMT_MJPEG :
pixFormat = PIX_FMT_YUVJ444P; pixFormat = PIX_FMT_YUVJ444P;
break; break;
case V4L2_PIX_FMT_UYVY :
pixFormat = PIX_FMT_UYVY422;
break;
// These don't seem to have ffmpeg equivalents // These don't seem to have ffmpeg equivalents
// See if you can match any of the ones in the default clause below!? // See if you can match any of the ones in the default clause below!?
case V4L2_PIX_FMT_UYVY :
case V4L2_PIX_FMT_RGB332 : case V4L2_PIX_FMT_RGB332 :
case V4L2_PIX_FMT_RGB555X : case V4L2_PIX_FMT_RGB555X :
case V4L2_PIX_FMT_RGB565X : case V4L2_PIX_FMT_RGB565X :

View File

@ -40,6 +40,9 @@
#if HAVE_LIBAVFORMAT #if HAVE_LIBAVFORMAT
#include "zm_ffmpeg_camera.h" #include "zm_ffmpeg_camera.h"
#endif // HAVE_LIBAVFORMAT #endif // HAVE_LIBAVFORMAT
#if HAVE_LIBVLC
#include "zm_libvlc_camera.h"
#endif // HAVE_LIBVLC
#if HAVE_LIBCURL #if HAVE_LIBCURL
#include "zm_curl_camera.h" #include "zm_curl_camera.h"
#endif // HAVE_LIBCURL #endif // HAVE_LIBCURL
@ -292,6 +295,7 @@ Monitor::Monitor(
int p_alarm_capture_delay, int p_alarm_capture_delay,
int p_fps_report_interval, int p_fps_report_interval,
int p_ref_blend_perc, int p_ref_blend_perc,
int p_alarm_ref_blend_perc,
bool p_track_motion, bool p_track_motion,
Rgb p_signal_check_colour, Rgb p_signal_check_colour,
Purpose p_purpose, Purpose p_purpose,
@ -317,6 +321,7 @@ Monitor::Monitor(
alarm_frame_count( p_alarm_frame_count ), alarm_frame_count( p_alarm_frame_count ),
fps_report_interval( p_fps_report_interval ), fps_report_interval( p_fps_report_interval ),
ref_blend_perc( p_ref_blend_perc ), ref_blend_perc( p_ref_blend_perc ),
alarm_ref_blend_perc( p_alarm_ref_blend_perc ),
track_motion( p_track_motion ), track_motion( p_track_motion ),
signal_check_colour( p_signal_check_colour ), signal_check_colour( p_signal_check_colour ),
delta_image( width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE ), delta_image( width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE ),
@ -512,7 +517,7 @@ Monitor::Monitor(
Debug( 1, "Monitor %s has function %d", name, function ); Debug( 1, "Monitor %s has function %d", name, function );
Debug( 1, "Monitor %s LBF = '%s', LBX = %d, LBY = %d", name, label_format, label_coord.X(), label_coord.Y() ); Debug( 1, "Monitor %s LBF = '%s', LBX = %d, LBY = %d", name, label_format, label_coord.X(), label_coord.Y() );
Debug( 1, "Monitor %s IBC = %d, WUC = %d, pEC = %d, PEC = %d, EAF = %d, FRI = %d, RBP = %d, FM = %d", name, image_buffer_count, warmup_count, pre_event_count, post_event_count, alarm_frame_count, fps_report_interval, ref_blend_perc, track_motion ); Debug( 1, "Monitor %s IBC = %d, WUC = %d, pEC = %d, PEC = %d, EAF = %d, FRI = %d, RBP = %d, ARBP = %d, FM = %d", name, image_buffer_count, warmup_count, pre_event_count, post_event_count, alarm_frame_count, fps_report_interval, ref_blend_perc, alarm_ref_blend_perc, track_motion );
if ( purpose == ANALYSIS ) if ( purpose == ANALYSIS )
{ {
@ -1608,10 +1613,14 @@ bool Monitor::Analyse()
shared_data->state = state = IDLE; shared_data->state = state = IDLE;
last_section_mod = 0; last_section_mod = 0;
} }
if ( (!signal_change && signal) && (function == MODECT || function == MOCORD) && (config.blend_alarmed_images || state != ALARM) ) if ( (!signal_change && signal) && (function == MODECT || function == MOCORD) )
{ {
if ( state == ALARM ) {
ref_image.Blend( *snap_image, alarm_ref_blend_perc );
} else {
ref_image.Blend( *snap_image, ref_blend_perc ); ref_image.Blend( *snap_image, ref_blend_perc );
} }
}
last_signal = signal; last_signal = signal;
} }
@ -1633,7 +1642,7 @@ void Monitor::Reload()
closeEvent(); closeEvent();
static char sql[ZM_SQL_MED_BUFSIZ]; static char sql[ZM_SQL_MED_BUFSIZ];
snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id ); snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id );
if ( mysql_query( &dbconn, sql ) ) if ( mysql_query( &dbconn, sql ) )
{ {
@ -1673,6 +1682,7 @@ void Monitor::Reload()
alarm_capture_delay = (dbrow[index]&&atof(dbrow[index])>0.0)?int(DT_PREC_3/atof(dbrow[index])):0; index++; alarm_capture_delay = (dbrow[index]&&atof(dbrow[index])>0.0)?int(DT_PREC_3/atof(dbrow[index])):0; index++;
fps_report_interval = atoi(dbrow[index++]); fps_report_interval = atoi(dbrow[index++]);
ref_blend_perc = atoi(dbrow[index++]); ref_blend_perc = atoi(dbrow[index++]);
alarm_ref_blend_perc = atoi(dbrow[index++]);
track_motion = atoi(dbrow[index++]); track_motion = atoi(dbrow[index++]);
@ -1823,11 +1833,11 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
static char sql[ZM_SQL_MED_BUFSIZ]; static char sql[ZM_SQL_MED_BUFSIZ];
if ( !device[0] ) if ( !device[0] )
{ {
strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' order by Device, Channel", sizeof(sql) ); strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' order by Device, Channel", sizeof(sql) );
} }
else else
{ {
snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' and Device = '%s' order by Channel", device ); snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' and Device = '%s' order by Channel", device );
} }
if ( mysql_query( &dbconn, sql ) ) if ( mysql_query( &dbconn, sql ) )
{ {
@ -1889,6 +1899,7 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++;
int fps_report_interval = atoi(dbrow[col]); col++; int fps_report_interval = atoi(dbrow[col]); col++;
int ref_blend_perc = atoi(dbrow[col]); col++; int ref_blend_perc = atoi(dbrow[col]); col++;
int alarm_ref_blend_perc = atoi(dbrow[col]); col++;
int track_motion = atoi(dbrow[col]); col++; int track_motion = atoi(dbrow[col]); col++;
int signal_check_colour; int signal_check_colour;
@ -1945,6 +1956,7 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
alarm_capture_delay, alarm_capture_delay,
fps_report_interval, fps_report_interval,
ref_blend_perc, ref_blend_perc,
alarm_ref_blend_perc,
track_motion, track_motion,
signal_check_colour, signal_check_colour,
purpose, purpose,
@ -1973,11 +1985,11 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
static char sql[ZM_SQL_MED_BUFSIZ]; static char sql[ZM_SQL_MED_BUFSIZ];
if ( !protocol ) if ( !protocol )
{ {
strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Remote'", sizeof(sql) ); strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Remote'", sizeof(sql) );
} }
else else
{ {
snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Remote' and Protocol = '%s' and Host = '%s' and Port = '%s' and Path = '%s'", protocol, host, port, path ); snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Remote' and Protocol = '%s' and Host = '%s' and Port = '%s' and Path = '%s'", protocol, host, port, path );
} }
if ( mysql_query( &dbconn, sql ) ) if ( mysql_query( &dbconn, sql ) )
{ {
@ -2040,6 +2052,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++;
int fps_report_interval = atoi(dbrow[col]); col++; int fps_report_interval = atoi(dbrow[col]); col++;
int ref_blend_perc = atoi(dbrow[col]); col++; int ref_blend_perc = atoi(dbrow[col]); col++;
int alarm_ref_blend_perc = atoi(dbrow[col]); col++;
int track_motion = atoi(dbrow[col]); col++; int track_motion = atoi(dbrow[col]); col++;
@ -2114,6 +2127,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
alarm_capture_delay, alarm_capture_delay,
fps_report_interval, fps_report_interval,
ref_blend_perc, ref_blend_perc,
alarm_ref_blend_perc,
track_motion, track_motion,
RGB_WHITE, RGB_WHITE,
purpose, purpose,
@ -2142,11 +2156,11 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
static char sql[ZM_SQL_MED_BUFSIZ]; static char sql[ZM_SQL_MED_BUFSIZ];
if ( !file[0] ) if ( !file[0] )
{ {
strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'File'", sizeof(sql) ); strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'File'", sizeof(sql) );
} }
else else
{ {
snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'File' and Path = '%s'", file ); snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'File' and Path = '%s'", file );
} }
if ( mysql_query( &dbconn, sql ) ) if ( mysql_query( &dbconn, sql ) )
{ {
@ -2205,6 +2219,7 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++;
int fps_report_interval = atoi(dbrow[col]); col++; int fps_report_interval = atoi(dbrow[col]); col++;
int ref_blend_perc = atoi(dbrow[col]); col++; int ref_blend_perc = atoi(dbrow[col]); col++;
int alarm_ref_blend_perc = atoi(dbrow[col]); col++;
int track_motion = atoi(dbrow[col]); col++; int track_motion = atoi(dbrow[col]); col++;
int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width);
@ -2247,6 +2262,7 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
alarm_capture_delay, alarm_capture_delay,
fps_report_interval, fps_report_interval,
ref_blend_perc, ref_blend_perc,
alarm_ref_blend_perc,
track_motion, track_motion,
RGB_WHITE, RGB_WHITE,
purpose, purpose,
@ -2276,11 +2292,11 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
static char sql[ZM_SQL_MED_BUFSIZ]; static char sql[ZM_SQL_MED_BUFSIZ];
if ( !file[0] ) if ( !file[0] )
{ {
strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Ffmpeg'", sizeof(sql) ); strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Ffmpeg'", sizeof(sql) );
} }
else else
{ {
snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Ffmpeg' and Path = '%s'", file ); snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion from Monitors where Function != 'None' and Type = 'Ffmpeg' and Path = '%s'", file );
} }
if ( mysql_query( &dbconn, sql ) ) if ( mysql_query( &dbconn, sql ) )
{ {
@ -2339,6 +2355,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++;
int fps_report_interval = atoi(dbrow[col]); col++; int fps_report_interval = atoi(dbrow[col]); col++;
int ref_blend_perc = atoi(dbrow[col]); col++; int ref_blend_perc = atoi(dbrow[col]); col++;
int alarm_ref_blend_perc = atoi(dbrow[col]); col++;
int track_motion = atoi(dbrow[col]); col++; int track_motion = atoi(dbrow[col]); col++;
int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width);
@ -2381,6 +2398,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
alarm_capture_delay, alarm_capture_delay,
fps_report_interval, fps_report_interval,
ref_blend_perc, ref_blend_perc,
alarm_ref_blend_perc,
track_motion, track_motion,
RGB_WHITE, RGB_WHITE,
purpose, purpose,
@ -2407,7 +2425,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose ) Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose )
{ {
static char sql[ZM_SQL_MED_BUFSIZ]; static char sql[ZM_SQL_MED_BUFSIZ];
snprintf( sql, sizeof(sql), "select Id, Name, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Protocol, Method, Host, Port, Path, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = %d", id ); snprintf( sql, sizeof(sql), "select Id, Name, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Protocol, Method, Host, Port, Path, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = %d", id );
if ( mysql_query( &dbconn, sql ) ) if ( mysql_query( &dbconn, sql ) )
{ {
Error( "Can't run query: %s", mysql_error( &dbconn ) ); Error( "Can't run query: %s", mysql_error( &dbconn ) );
@ -2475,6 +2493,7 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose )
int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++;
int fps_report_interval = atoi(dbrow[col]); col++; int fps_report_interval = atoi(dbrow[col]); col++;
int ref_blend_perc = atoi(dbrow[col]); col++; int ref_blend_perc = atoi(dbrow[col]); col++;
int alarm_ref_blend_perc = atoi(dbrow[col]); col++;
int track_motion = atoi(dbrow[col]); col++; int track_motion = atoi(dbrow[col]); col++;
int signal_check_colour; int signal_check_colour;
@ -2593,6 +2612,25 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose )
#else // HAVE_LIBAVFORMAT #else // HAVE_LIBAVFORMAT
Fatal( "You must have ffmpeg libraries installed to use ffmpeg cameras for monitor %d", id ); Fatal( "You must have ffmpeg libraries installed to use ffmpeg cameras for monitor %d", id );
#endif // HAVE_LIBAVFORMAT #endif // HAVE_LIBAVFORMAT
}
else if (type == "Libvlc")
{
#if HAVE_LIBVLC
camera = new LibvlcCamera(
id,
path.c_str(),
cam_width,
cam_height,
colours,
brightness,
contrast,
hue,
colour,
purpose==CAPTURE
);
#else // HAVE_LIBVLC
Fatal( "You must have vlc libraries installed to use vlc cameras for monitor %d", id );
#endif // HAVE_LIBVLC
} }
else if ( type == "cURL" ) else if ( type == "cURL" )
{ {
@ -2643,6 +2681,7 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose )
alarm_capture_delay, alarm_capture_delay,
fps_report_interval, fps_report_interval,
ref_blend_perc, ref_blend_perc,
alarm_ref_blend_perc,
track_motion, track_motion,
signal_check_colour, signal_check_colour,
purpose, purpose,
@ -3280,6 +3319,7 @@ bool Monitor::DumpSettings( char *output, bool verbose )
sprintf( output+strlen(output), "Maximum FPS : %.2f\n", capture_delay?DT_PREC_3/capture_delay:0.0 ); sprintf( output+strlen(output), "Maximum FPS : %.2f\n", capture_delay?DT_PREC_3/capture_delay:0.0 );
sprintf( output+strlen(output), "Alarm Maximum FPS : %.2f\n", alarm_capture_delay?DT_PREC_3/alarm_capture_delay:0.0 ); sprintf( output+strlen(output), "Alarm Maximum FPS : %.2f\n", alarm_capture_delay?DT_PREC_3/alarm_capture_delay:0.0 );
sprintf( output+strlen(output), "Reference Blend %%ge : %d\n", ref_blend_perc ); sprintf( output+strlen(output), "Reference Blend %%ge : %d\n", ref_blend_perc );
sprintf( output+strlen(output), "Alarm Reference Blend %%ge : %d\n", alarm_ref_blend_perc );
sprintf( output+strlen(output), "Track Motion : %d\n", track_motion ); sprintf( output+strlen(output), "Track Motion : %d\n", track_motion );
sprintf( output+strlen(output), "Function: %d - %s\n", function, sprintf( output+strlen(output), "Function: %d - %s\n", function,
function==NONE?"None":( function==NONE?"None":(

View File

@ -235,6 +235,7 @@ protected:
int alarm_frame_count; // How many alarm frames are required before an event is triggered int alarm_frame_count; // How many alarm frames are required before an event is triggered
int fps_report_interval; // How many images should be captured/processed between reporting the current FPS int fps_report_interval; // How many images should be captured/processed between reporting the current FPS
int ref_blend_perc; // Percentage of new image going into reference image. int ref_blend_perc; // Percentage of new image going into reference image.
int alarm_ref_blend_perc; // Percentage of new image going into reference image during alarm.
bool track_motion; // Whether this monitor tries to track detected motion bool track_motion; // Whether this monitor tries to track detected motion
Rgb signal_check_colour; // The colour that the camera will emit when no video signal detected Rgb signal_check_colour; // The colour that the camera will emit when no video signal detected
@ -287,7 +288,7 @@ protected:
public: public:
// OurCheckAlarms seems to be unused. Check it on zm_monitor.cpp for more info. // OurCheckAlarms seems to be unused. Check it on zm_monitor.cpp for more info.
//bool OurCheckAlarms( Zone *zone, const Image *pImage ); //bool OurCheckAlarms( Zone *zone, const Image *pImage );
Monitor( int p_id, const char *p_name, int p_function, bool p_enabled, const char *p_linked_monitors, Camera *p_camera, int p_orientation, unsigned int p_deinterlacing, const char *p_event_prefix, const char *p_label_format, const Coord &p_label_coord, int p_image_buffer_count, int p_warmup_count, int p_pre_event_count, int p_post_event_count, int p_stream_replay_buffer, int p_alarm_frame_count, int p_section_length, int p_frame_skip, int p_capture_delay, int p_alarm_capture_delay, int p_fps_report_interval, int p_ref_blend_perc, bool p_track_motion, Rgb p_signal_check_colour, Purpose p_purpose, int p_n_zones=0, Zone *p_zones[]=0 ); Monitor( int p_id, const char *p_name, int p_function, bool p_enabled, const char *p_linked_monitors, Camera *p_camera, int p_orientation, unsigned int p_deinterlacing, const char *p_event_prefix, const char *p_label_format, const Coord &p_label_coord, int p_image_buffer_count, int p_warmup_count, int p_pre_event_count, int p_post_event_count, int p_stream_replay_buffer, int p_alarm_frame_count, int p_section_length, int p_frame_skip, int p_capture_delay, int p_alarm_capture_delay, int p_fps_report_interval, int p_ref_blend_perc, int p_alarm_ref_blend_perc, bool p_track_motion, Rgb p_signal_check_colour, Purpose p_purpose, int p_n_zones=0, Zone *p_zones[]=0 );
~Monitor(); ~Monitor();
void AddZones( int p_n_zones, Zone *p_zones[] ); void AddZones( int p_n_zones, Zone *p_zones[] );

View File

@ -35,6 +35,10 @@ RemoteCamera::RemoteCamera( int p_id, const std::string &p_protocol, const std::
RemoteCamera::~RemoteCamera() RemoteCamera::~RemoteCamera()
{ {
if(hp != NULL) {
freeaddrinfo(hp);
hp = NULL;
}
} }
void RemoteCamera::Initialise() void RemoteCamera::Initialise()
@ -61,15 +65,15 @@ void RemoteCamera::Initialise()
auth64 = base64Encode( auth ); auth64 = base64Encode( auth );
} }
if ( !hp ) struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int ret = getaddrinfo(host.c_str(), port.c_str(), &hints, &hp);
if ( ret != 0 )
{ {
if ( !(hp = gethostbyname(host.c_str())) ) Fatal( "Can't getaddrinfo(%s port %s): %s", host.c_str(), port.c_str(), gai_strerror(ret) );
{
Fatal( "Can't gethostbyname(%s): %s", host.c_str(), strerror(h_errno) );
}
memcpy((char *)&sa.sin_addr, (char *)hp->h_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;
sa.sin_port = htons(atoi(port.c_str()));
} }
} }

View File

@ -23,6 +23,8 @@
#include "zm_camera.h" #include "zm_camera.h"
#include <string> #include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h> #include <netdb.h>
// //
@ -40,8 +42,7 @@ protected:
std::string auth64; std::string auth64;
protected: protected:
struct hostent *hp; struct addrinfo *hp;
struct sockaddr_in sa;
public: public:
RemoteCamera( int p_id, const std::string &p_proto, const std::string &p_host, const std::string &p_port, const std::string &p_path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ); RemoteCamera( int p_id, const std::string &p_proto, const std::string &p_host, const std::string &p_port, const std::string &p_path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture );

View File

@ -24,6 +24,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <errno.h> #include <errno.h>
#include <netdb.h>
RemoteCameraHttp::RemoteCameraHttp( int p_id, const std::string &p_method, const std::string &p_host, const std::string &p_port, const std::string &p_path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) : RemoteCameraHttp::RemoteCameraHttp( int p_id, const std::string &p_method, const std::string &p_host, const std::string &p_port, const std::string &p_path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) :
RemoteCamera( p_id, "http", p_host, p_port, p_path, p_width, p_height, p_colours, p_brightness, p_contrast, p_hue, p_colour, p_capture ) RemoteCamera( p_id, "http", p_host, p_port, p_path, p_width, p_height, p_colours, p_brightness, p_contrast, p_hue, p_colour, p_capture )
@ -87,22 +88,34 @@ void RemoteCameraHttp::Initialise()
int RemoteCameraHttp::Connect() int RemoteCameraHttp::Connect()
{ {
struct addrinfo *p;
for(p = hp; p != NULL; p = p->ai_next)
{
sd = socket( p->ai_family, p->ai_socktype, p->ai_protocol );
if ( sd < 0 ) if ( sd < 0 )
{ {
sd = socket( hp->h_addrtype, SOCK_STREAM, 0 ); Warning("Can't create socket: %s", strerror(errno) );
if ( sd < 0 ) continue;
}
if ( connect( sd, p->ai_addr, p->ai_addrlen ) < 0 )
{ {
Error( "Can't create socket: %s", strerror(errno) ); close(sd);
sd = -1;
Warning("Can't connect to remote camera: %s", strerror(errno) );
continue;
}
/* If we got here, we must have connected successfully */
break;
}
if(p == NULL) {
Error("Unable to connect to the remote camera, aborting");
return( -1 ); return( -1 );
} }
if ( connect( sd, (struct sockaddr *)&sa, sizeof(sa) ) < 0 )
{
Error( "Can't connect to remote camera: %s", strerror(errno) );
Disconnect();
return( -1 );
}
}
Debug( 3, "Connected to host, socket = %d", sd ); Debug( 3, "Connected to host, socket = %d", sd );
return( sd ); return( sd );
} }
@ -428,7 +441,7 @@ int RemoteCameraHttp::GetResponse()
if ( content_length ) if ( content_length )
{ {
while ( buffer.size() < (unsigned int)content_length ) while ( (long)buffer.size() < content_length )
{ {
int buffer_len = ReadData( buffer ); int buffer_len = ReadData( buffer );
if ( buffer_len == 0 ) if ( buffer_len == 0 )
@ -960,7 +973,7 @@ int RemoteCameraHttp::GetResponse()
if ( content_length ) if ( content_length )
{ {
while ( buffer.size() < (unsigned int)content_length ) while ( (long)buffer.size() < content_length )
{ {
//int buffer_len = ReadData( buffer, content_length-buffer.size() ); //int buffer_len = ReadData( buffer, content_length-buffer.size() );
int buffer_len = ReadData( buffer ); int buffer_len = ReadData( buffer );
@ -1086,7 +1099,7 @@ int RemoteCameraHttp::PreCapture()
int RemoteCameraHttp::Capture( Image &image ) int RemoteCameraHttp::Capture( Image &image )
{ {
unsigned int content_length = GetResponse(); int content_length = GetResponse();
if ( content_length == 0 ) if ( content_length == 0 )
{ {
Warning( "Unable to capture image, retrying" ); Warning( "Unable to capture image, retrying" );
@ -1112,7 +1125,7 @@ int RemoteCameraHttp::Capture( Image &image )
} }
case X_RGB : case X_RGB :
{ {
if ( content_length != image.Size() ) if ( content_length != (long)image.Size() )
{ {
Error( "Image length mismatch, expected %d bytes, content length was %d", image.Size(), content_length ); Error( "Image length mismatch, expected %d bytes, content length was %d", image.Size(), content_length );
Disconnect(); Disconnect();

View File

@ -261,6 +261,31 @@ int RemoteCameraRtsp::Capture( Image &image )
if ( !buffer.size() ) if ( !buffer.size() )
return( -1 ); return( -1 );
if(mCodecContext->codec_id == CODEC_ID_H264)
{
// SPS and PPS frames should be saved and appended to IDR frames
int nalType = (buffer.head()[3] & 0x1f);
// SPS
if(nalType == 7)
{
lastSps = buffer;
continue;
}
// PPS
else if(nalType == 8)
{
lastPps = buffer;
continue;
}
// IDR
else if(nalType == 5)
{
buffer += lastSps;
buffer += lastPps;
}
}
av_init_packet( &packet ); av_init_packet( &packet );
while ( !frameComplete && buffer.size() > 0 ) while ( !frameComplete && buffer.size() > 0 )

View File

@ -41,6 +41,8 @@ protected:
int rtcp_sd; int rtcp_sd;
Buffer buffer; Buffer buffer;
Buffer lastSps;
Buffer lastPps;
RtspThread::RtspMethod method; RtspThread::RtspMethod method;

View File

@ -143,8 +143,13 @@ int RtpCtrlThread::recvPacket( const unsigned char *packet, ssize_t packetLen )
mStop = true; mStop = true;
break; break;
} }
case RTCP_RR :
case RTCP_APP : case RTCP_APP :
{
// Ignoring as per RFC 3550
Debug( 5, "Received RTCP_APP packet, ignoring.");
break;
}
case RTCP_RR :
default : default :
{ {
Error( "Received unexpected packet type %d, ignoring", pt ); Error( "Received unexpected packet type %d, ignoring", pt );

View File

@ -24,12 +24,19 @@
#include <arpa/inet.h> #include <arpa/inet.h>
RtpSource::RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime ) : #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,25,0)
#define _AVCODECID AVCodecID
#else
#define _AVCODECID CodecID
#endif
RtpSource::RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime, _AVCODECID codecId ) :
mId( id ), mId( id ),
mSsrc( ssrc ), mSsrc( ssrc ),
mLocalHost( localHost ), mLocalHost( localHost ),
mRemoteHost( remoteHost ), mRemoteHost( remoteHost ),
mRtpClock( rtpClock ), mRtpClock( rtpClock ),
mCodecId( codecId ),
mFrame( 65536 ), mFrame( 65536 ),
mFrameCount( 0 ), mFrameCount( 0 ),
mFrameGood( true ), mFrameGood( true ),
@ -61,6 +68,9 @@ RtpSource::RtpSource( int id, const std::string &localHost, int localPortBase, c
mLastSrTimeReal = tvZero(); mLastSrTimeReal = tvZero();
mLastSrTimeNtp = tvZero(); mLastSrTimeNtp = tvZero();
mLastSrTimeRtp = 0; mLastSrTimeRtp = 0;
if(mCodecId != CODEC_ID_H264 && mCodecId != CODEC_ID_MPEG4)
Warning( "The device is using a codec that may not be supported. Do not be surprised if things don't work." );
} }
void RtpSource::init( uint16_t seq ) void RtpSource::init( uint16_t seq )
@ -253,57 +263,63 @@ bool RtpSource::handlePacket( const unsigned char *packet, size_t packetLen )
{ {
const RtpDataHeader *rtpHeader; const RtpDataHeader *rtpHeader;
rtpHeader = (RtpDataHeader *)packet; rtpHeader = (RtpDataHeader *)packet;
bool fragmentEnd = false; int rtpHeaderSize = 12 + rtpHeader->cc * 4;
// No need to check for nal type as non fragmented packets already have 001 start sequence appended
// Each RTP packet delivers only one NAL. It can be either the Single NAL bool h264FragmentEnd = (mCodecId == CODEC_ID_H264) && (packet[rtpHeaderSize+1] & 0x40);
// ( in that case it must be in one packet ) or the Fragmentation NALs bool thisM = rtpHeader->m || h264FragmentEnd;
// that delivers large single NAL...
if ( updateSeq( ntohs(rtpHeader->seqN) ) ) if ( updateSeq( ntohs(rtpHeader->seqN) ) )
{ {
Hexdump( 4, packet+sizeof(RtpDataHeader), 16 ); Hexdump( 4, packet+rtpHeaderSize, 16 );
if ( ((packet[sizeof(RtpDataHeader)] & 0x1f) == 28 &&
(packet[sizeof(RtpDataHeader)+1] & 0x80)) ||
((packet[sizeof(RtpDataHeader)] & 0x1f) != 28 &&
prevM && rtpHeader->m) )
mFrameGood = true; // This means that if packet is in sequence
// and is single NAL with mark set (and prev packet
// was NAL with mark set or it is Fragmentation NAL with
// Start bit set then we assume that sequence
// was restored and we can handle packet
if ( mFrameGood ) if ( mFrameGood )
{ {
// check if there fragmentation NAL int extraHeader = 0;
if ( (packet[sizeof(RtpDataHeader)] & 0x1f) == 28 )
if( mCodecId == CODEC_ID_H264 )
{ {
// is this NAL the first NAL in fragmentation sequence int nalType = (packet[rtpHeaderSize] & 0x1f);
if ( packet[sizeof(RtpDataHeader)+1] & 0x80 )
switch (nalType)
{
case 24:
{
extraHeader = 2;
break;
}
case 25: case 26: case 27:
{
extraHeader = 3;
break;
}
// FU-A and FU-B
case 28: case 29:
{
// Is this NAL the first NAL in fragmentation sequence
if ( packet[rtpHeaderSize+1] & 0x80 )
{ {
// if there is any data in frame then we must
// discard it because that frame was incomplete
if ( mFrame.size() )
mFrame.clear();
// Now we will form new header of frame // Now we will form new header of frame
mFrame.append("\x0\x0\x1\x0",4); mFrame.append( "\x0\x0\x1\x0", 4 );
*(mFrame+3) = (packet[sizeof(RtpDataHeader)+1] & 0x1f) | // Reconstruct NAL header from FU headers
(packet[sizeof(RtpDataHeader)] & 0x60); *(mFrame+3) = (packet[rtpHeaderSize+1] & 0x1f) |
(packet[rtpHeaderSize] & 0xe0);
} }
else
if ( packet[sizeof(RtpDataHeader)+1] & 0x40 ) extraHeader = 2;
fragmentEnd = true; break;
mFrame.append(packet+sizeof(RtpDataHeader)+2, packetLen-sizeof(RtpDataHeader)-2);
} }
else }
{
// mframe.clear(); // Append NAL frame start code
if ( !mFrame.size() ) if ( !mFrame.size() )
mFrame.append("\x0\x0\x1",3); mFrame.append( "\x0\x0\x1", 3 );
mFrame.append( packet+sizeof(RtpDataHeader), packetLen-sizeof(RtpDataHeader) );
} }
mFrame.append( packet+rtpHeaderSize+extraHeader, packetLen-rtpHeaderSize-extraHeader );
} }
Hexdump( 4, mFrame.head(), 16 ); Hexdump( 4, mFrame.head(), 16 );
if ( rtpHeader->m || fragmentEnd ) if ( thisM )
{ {
if ( mFrameGood ) if ( mFrameGood )
{ {
@ -339,7 +355,7 @@ bool RtpSource::handlePacket( const unsigned char *packet, size_t packetLen )
mFrameGood = false; mFrameGood = false;
mFrame.clear(); mFrame.clear();
} }
if ( rtpHeader->m || fragmentEnd ) if ( thisM )
{ {
mFrameGood = true; mFrameGood = true;
prevM = true; prevM = true;
@ -368,3 +384,5 @@ bool RtpSource::getFrame( Buffer &buffer )
Debug( 3, "Copied %d bytes", buffer.size() ); Debug( 3, "Copied %d bytes", buffer.size() );
return( true ); return( true );
} }
#undef _AVCODECID

View File

@ -21,12 +21,19 @@
#define ZM_RTP_SOURCE_H #define ZM_RTP_SOURCE_H
#include "zm_buffer.h" #include "zm_buffer.h"
#include "zm_ffmpeg.h"
#include "zm_thread.h" #include "zm_thread.h"
#include <sys/time.h> #include <sys/time.h>
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,25,0)
#define _AVCODECID AVCodecID
#else
#define _AVCODECID CodecID
#endif
struct RtpDataHeader; struct RtpDataHeader;
class RtpSource class RtpSource
@ -81,6 +88,8 @@ private:
uint32_t mLostPackets; uint32_t mLostPackets;
uint8_t mLostFraction; uint8_t mLostFraction;
_AVCODECID mCodecId;
Buffer mFrame; Buffer mFrame;
int mFrameCount; int mFrameCount;
bool mFrameGood; bool mFrameGood;
@ -92,7 +101,8 @@ private:
void init( uint16_t seq ); void init( uint16_t seq );
public: public:
RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime ); RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime, _AVCODECID codecId );
bool updateSeq( uint16_t seq ); bool updateSeq( uint16_t seq );
void updateJitter( const RtpDataHeader *header ); void updateJitter( const RtpDataHeader *header );
void updateRtcpData( uint32_t ntpTimeSecs, uint32_t ntpTimeFrac, uint32_t rtpTime ); void updateRtcpData( uint32_t ntpTimeSecs, uint32_t ntpTimeFrac, uint32_t rtpTime );
@ -177,4 +187,6 @@ public:
} }
}; };
#undef _AVCODECID
#endif // ZM_RTP_SOURCE_H #endif // ZM_RTP_SOURCE_H

View File

@ -330,6 +330,13 @@ int RtspThread::run()
uint32_t rtpClock = 0; uint32_t rtpClock = 0;
std::string trackUrl = mUrl; std::string trackUrl = mUrl;
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,25,0)
enum AVCodecID codecId;
#else
enum CodecID codecId;
#endif
if ( mFormatContext->nb_streams >= 1 ) if ( mFormatContext->nb_streams >= 1 )
{ {
for ( unsigned int i = 0; i < mFormatContext->nb_streams; i++ ) for ( unsigned int i = 0; i < mFormatContext->nb_streams; i++ )
@ -343,6 +350,7 @@ int RtspThread::run()
{ {
trackUrl += "/"+mediaDesc->getControlUrl(); trackUrl += "/"+mediaDesc->getControlUrl();
rtpClock = mediaDesc->getClock(); rtpClock = mediaDesc->getClock();
codecId = mFormatContext->streams[i]->codec->codec_id;
// Hackery pokery // Hackery pokery
//rtpClock = mFormatContext->streams[i]->codec->sample_rate; //rtpClock = mFormatContext->streams[i]->codec->sample_rate;
break; break;
@ -500,7 +508,7 @@ int RtspThread::run()
{ {
case RTP_UNICAST : case RTP_UNICAST :
{ {
RtpSource *source = new RtpSource( mId, "", localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime ); RtpSource *source = new RtpSource( mId, "", localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime, codecId );
mSources[ssrc] = source; mSources[ssrc] = source;
RtpDataThread rtpDataThread( *this, *source ); RtpDataThread rtpDataThread( *this, *source );
RtpCtrlThread rtpCtrlThread( *this, *source ); RtpCtrlThread rtpCtrlThread( *this, *source );
@ -545,7 +553,7 @@ int RtspThread::run()
case RTP_RTSP : case RTP_RTSP :
case RTP_RTSP_HTTP : case RTP_RTSP_HTTP :
{ {
RtpSource *source = new RtpSource( mId, "", remoteChannels[0], mHost, remoteChannels[0], ssrc, seq, rtpClock, rtpTime ); RtpSource *source = new RtpSource( mId, "", remoteChannels[0], mHost, remoteChannels[0], ssrc, seq, rtpClock, rtpTime, codecId );
mSources[ssrc] = source; mSources[ssrc] = source;
// These never actually run // These never actually run
RtpDataThread rtpDataThread( *this, *source ); RtpDataThread rtpDataThread( *this, *source );
@ -673,7 +681,7 @@ int RtspThread::run()
} }
case RTP_MULTICAST : case RTP_MULTICAST :
{ {
RtpSource *source = new RtpSource( mId, localHost, localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime ); RtpSource *source = new RtpSource( mId, localHost, localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime, codecId );
mSources[ssrc] = source; mSources[ssrc] = source;
RtpDataThread rtpDataThread( *this, *source ); RtpDataThread rtpDataThread( *this, *source );
RtpCtrlThread rtpCtrlThread( *this, *source ); RtpCtrlThread rtpCtrlThread( *this, *source );

View File

@ -1,207 +0,0 @@
//
// ZoneMinder Video Device Fixer, $Date$, $Revision$
// Copyright (C) 2001-2008 Philip Coombes
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <mysql/mysql.h>
#include "zm.h"
#include "zm_db.h"
// Determine if we are a member of the group
int inGroup( gid_t gid )
{
// Get how many groups we are in
int n_gids = getgroups( 0, NULL );
if ( n_gids < 0 )
{
Error( "getgroups:%s", strerror(errno) );
return( -1 );
}
// Not in any groups
if ( !n_gids )
{
return( 0 );
}
// Allocate space to hold groups
gid_t *gids = new gid_t[n_gids * sizeof(gid_t)];
if ( !gids )
{
Error( "Unable to allocate groups: %s", strerror(errno) );
return( -1 );
}
// Get list of groups
if ( getgroups( n_gids, gids ) != n_gids )
{
Error( "getgroups:%s", strerror(errno) );
delete[] gids;
return( -1 );
}
// See if gid in list of groups we belong to
int in_gid = 0;
for ( int i = 0; i < n_gids; i++ )
{
if ( gids[i] == gid )
{
in_gid = 1;
}
}
delete[] gids;
return( in_gid );
}
bool fixDevice( const char *device_path )
{
struct stat stat_buf;
if ( stat( device_path, &stat_buf ) < 0 )
{
Error( "Can't stat %s: %s", device_path, strerror(errno));
return( false );
}
uid_t uid = getuid();
gid_t gid = getgid();
int in_gid;
if ( (in_gid = inGroup( stat_buf.st_gid )) < 0 )
{
return( false );
}
mode_t mask = 0;
if ( uid == stat_buf.st_uid )
{
// If we are the owner
mask = 00600;
}
else if ( gid == stat_buf.st_gid || in_gid )
{
// If we are in the owner group
mask = 00060;
}
else
{
// We are neither the owner nor in the group
mask = 00006;
}
mode_t mode = stat_buf.st_mode;
if ( (mode & mask) == mask )
{
Debug( 1, "Permissions on %s are ok at %o", device_path, mode );
return( true );
}
mode |= mask;
Info( "Resetting permissions on %s to %o", device_path, mode );
if ( chmod( device_path, mode ) < 0 )
{
Error( "Can't chmod %s to %o: %s", device_path, mode, strerror(errno));
return( false );
}
return( true );
}
int main( int argc, char *argv[] )
{
self = argv[0];
zmLoadConfig();
logInit( "zmfix" );
logCapLevel( Logger::ERROR );
// Only do registered devices
static char sql[ZM_SQL_SML_BUFSIZ];
snprintf( sql, sizeof(sql), "select distinct Device from Monitors where not isnull(Device) and Type = 'Local'" );
if ( mysql_query( &dbconn, sql ) )
{
Error( "Can't run query: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
MYSQL_RES *result = mysql_store_result( &dbconn );
if ( !result )
{
Error( "Can't use query result: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ )
{
fixDevice( dbrow[0] );
}
if ( mysql_errno( &dbconn ) )
{
Error( "Can't fetch row: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
// Yadda yadda
mysql_free_result( result );
snprintf( sql, sizeof(sql), "select distinct ControlDevice from Monitors where not isEmpty(ControlDevice)" );
if ( mysql_query( &dbconn, sql ) )
{
Error( "Can't run query: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
result = mysql_store_result( &dbconn );
if ( !result )
{
Error( "Can't use query result: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ )
{
fixDevice( dbrow[0] );
}
if ( mysql_errno( &dbconn ) )
{
Error( "Can't fetch row: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
// Yadda yadda
mysql_free_result( result );
if ( config.opt_x10 )
{
if ( config.x10_device )
{
fixDevice( config.x10_device );
}
}
return( 0 );
}

View File

@ -1 +1 @@
1.26.4 1.26.5

View File

@ -7,6 +7,12 @@ add_subdirectory(tools/mootools)
configure_file(includes/config.php.in "${CMAKE_CURRENT_BINARY_DIR}/includes/config.php" @ONLY) configure_file(includes/config.php.in "${CMAKE_CURRENT_BINARY_DIR}/includes/config.php" @ONLY)
# Install the web files # Install the web files
install(DIRECTORY ajax css graphics includes js lang skins tools views DESTINATION "${ZM_WEBDIR}" PATTERN "*.in" EXCLUDE PATTERN "*Make*" EXCLUDE PATTERN "*cmake*" EXCLUDE REGEX "includes/config.php$" EXCLUDE) install(DIRECTORY ajax css graphics includes js lang skins tools views DESTINATION "${ZM_WEBDIR}" PATTERN "*.in" EXCLUDE PATTERN "*Make*" EXCLUDE PATTERN "*cmake*" EXCLUDE)
install(FILES index.php README.md DESTINATION "${ZM_WEBDIR}") install(FILES index.php DESTINATION "${ZM_WEBDIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/includes/config.php" DESTINATION "${ZM_WEBDIR}/includes") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/includes/config.php" DESTINATION "${ZM_WEBDIR}/includes")
# Install the mootools symlinks (if its not in the source directory)
if(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR))
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tools/mootools/mootools-core.js" DESTINATION "${ZM_WEBDIR}/tools/mootools")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tools/mootools/mootools-more.js" DESTINATION "${ZM_WEBDIR}/tools/mootools")
endif(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR))

View File

@ -554,7 +554,6 @@ if ( !empty($action) )
if ( $restart ) if ( $restart )
{ {
$monitor = dbFetchOne( "select * from Monitors where Id = '".dbEscape($mid)."'" ); $monitor = dbFetchOne( "select * from Monitors where Id = '".dbEscape($mid)."'" );
fixDevices();
//if ( $cookies ) //if ( $cookies )
//session_write_close(); //session_write_close();
if ( daemonCheck() ) if ( daemonCheck() )

View File

@ -22,6 +22,8 @@
// This section contains options substituted by the zmconfig.pl utility, do not edit these directly // This section contains options substituted by the zmconfig.pl utility, do not edit these directly
// //
define( "ZM_CONFIG", "@ZM_CONFIG@" ); // Path to config file define( "ZM_CONFIG", "@ZM_CONFIG@" ); // Path to config file
// Define, and override any given in config file
define( "ZM_VERSION", "@VERSION@" ); // Version
$configFile = ZM_CONFIG; $configFile = ZM_CONFIG;
$localConfigFile = basename($configFile); $localConfigFile = basename($configFile);

View File

@ -256,9 +256,9 @@ classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902"
standby="Loading Microsoft Windows Media Player components..." standby="Loading Microsoft Windows Media Player components..."
type="<?= $mimeType ?>"> type="<?= $mimeType ?>">
<param name="FileName" value="<?= $src ?>"> <param name="FileName" value="<?= $src ?>"/>
<param name="autoStart" value="1"> <param name="autoStart" value="1"/>
<param name="showControls" value="0"> <param name="showControls" value="0"/>
<embed type="<?= $mimeType ?>" <embed type="<?= $mimeType ?>"
pluginspage="http://www.microsoft.com/Windows/MediaPlayer/" pluginspage="http://www.microsoft.com/Windows/MediaPlayer/"
src="<?= $src ?>" src="<?= $src ?>"
@ -281,9 +281,9 @@ showcontrols="0">
classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
codebase="http://www.apple.com/qtactivex/qtplugin.cab" codebase="http://www.apple.com/qtactivex/qtplugin.cab"
type="<?= $mimeType ?>"> type="<?= $mimeType ?>">
<param name="src" value="<?= $src ?>"> <param name="src" value="<?= $src ?>"/>
<param name="autoplay" VALUE="true"> <param name="autoplay" VALUE="true"/>
<param name="controller" VALUE="false"> <param name="controller" VALUE="false"/>
<embed type="<?= $mimeType ?>" <embed type="<?= $mimeType ?>"
src="<?= $src ?>" src="<?= $src ?>"
pluginspage="http://www.apple.com/quicktime/download/" pluginspage="http://www.apple.com/quicktime/download/"
@ -291,7 +291,7 @@ name="<?= validHtmlStr($title) ?>"
width="<?= validInt($width) ?>" width="<?= validInt($width) ?>"
height="<?= validInt($height) ?>" height="<?= validInt($height) ?>"
autoplay="true" autoplay="true"
controller="true" controller="true">
</embed> </embed>
</object> </object>
<?php <?php
@ -305,9 +305,9 @@ controller="true"
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"
type="<?= $mimeType ?>"> type="<?= $mimeType ?>">
<param name="movie" value="<?= $src ?>"> <param name="movie" value="<?= $src ?>"/>
<param name=quality value="high"> <param name="quality" value="high"/>
<param name=bgcolor value="#ffffff"> <param name="bgcolor" value="#ffffff"/>
<embed type="<?= $mimeType ?>" <embed type="<?= $mimeType ?>"
pluginspage="http://www.macromedia.com/go/getflashplayer" pluginspage="http://www.macromedia.com/go/getflashplayer"
src="<?= $src ?>" src="<?= $src ?>"
@ -315,7 +315,7 @@ name="<?= validHtmlStr($title) ?>"
width="<?= validInt($width) ?>" width="<?= validInt($width) ?>"
height="<?= validInt($height) ?>" height="<?= validInt($height) ?>"
quality="high" quality="high"
bgcolor="#ffffff" bgcolor="#ffffff">
</embed> </embed>
</object> </object>
<?php <?php
@ -916,13 +916,6 @@ function canStream()
return( canStreamNative() | canStreamApplet() ); return( canStreamNative() | canStreamApplet() );
} }
function fixDevices()
{
$string = ZM_PATH_BIN."/zmfix";
$string .= " 2>/dev/null >&- <&- >/dev/null";
exec( $string );
}
function packageControl( $command ) function packageControl( $command )
{ {
$string = ZM_PATH_BIN.'/zmpkg.pl '.escapeshellarg( $command ); $string = ZM_PATH_BIN.'/zmpkg.pl '.escapeshellarg( $command );
@ -2225,10 +2218,11 @@ function isVector ( &$array )
return( true ); return( true );
} }
function checkJsonError() function checkJsonError($value)
{ {
if ( function_exists('json_last_error') ) if ( function_exists('json_last_error') )
{ {
$value = var_export($value,true);
switch( json_last_error() ) switch( json_last_error() )
{ {
case JSON_ERROR_DEPTH : case JSON_ERROR_DEPTH :
@ -2252,7 +2246,7 @@ function jsonEncode( &$value )
if ( function_exists('json_encode') ) if ( function_exists('json_encode') )
{ {
$string = json_encode( $value ); $string = json_encode( $value );
checkJsonError(); checkJsonError($value);
return( $string ); return( $string );
} }
@ -2293,7 +2287,7 @@ function jsonDecode( $value )
if ( function_exists('json_decode') ) if ( function_exists('json_decode') )
{ {
$object = json_decode( $value, true ); $object = json_decode( $value, true );
checkJsonError(); checkJsonError($value);
return( $object ); return( $object );
} }

View File

@ -376,6 +376,7 @@ $SLANG = array(
'Language' => 'Language', 'Language' => 'Language',
'Last' => 'Last', 'Last' => 'Last',
'Layout' => 'Layout', 'Layout' => 'Layout',
'Libvlc' => 'Libvlc',
'LimitResultsPost' => 'results only', // This is used at the end of the phrase 'Limit to first N results only' 'LimitResultsPost' => 'results only', // This is used at the end of the phrase 'Limit to first N results only'
'LimitResultsPre' => 'Limit to first', // This is used at the beginning of the phrase 'Limit to first N results only' 'LimitResultsPre' => 'Limit to first', // This is used at the beginning of the phrase 'Limit to first N results only'
'LinkedMonitors' => 'Linked Monitors', 'LinkedMonitors' => 'Linked Monitors',

View File

@ -71,163 +71,8 @@ html ul.tabs li.active, html ul.tabs li.active a:hover {
} }
--> -->
</style> </style>
<script type="text/javascript" src="<?php echo ZM_SKIN_PATH; ?>/js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" language="javascript" charset="utf-8"> <script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
/*==========[jquery]==========*/
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
/*==========[tab code]==========*/ /*==========[tab code]==========*/
$(document).ready(function() { $(document).ready(function() {

154
web/skins/classic/js/jquery-1.4.2.min.js vendored Normal file
View File

@ -0,0 +1,154 @@
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);

View File

@ -308,6 +308,11 @@ foreach( $displayMonitors as $monitor )
<td class="colSource"><?= makePopupLink( '?view=monitor&amp;mid='.$monitor['Id'], 'zmMonitor'.$monitor['Id'], 'monitor', '<span class="'.$dclass.'">'.preg_replace( '/^.*\//', '', $monitor['Path'] ).'</span>', canEdit( 'Monitors' ) ) ?></td> <td class="colSource"><?= makePopupLink( '?view=monitor&amp;mid='.$monitor['Id'], 'zmMonitor'.$monitor['Id'], 'monitor', '<span class="'.$dclass.'">'.preg_replace( '/^.*\//', '', $monitor['Path'] ).'</span>', canEdit( 'Monitors' ) ) ?></td>
<?php } elseif ( $monitor['Type'] == "Ffmpeg" ) { ?> <?php } elseif ( $monitor['Type'] == "Ffmpeg" ) { ?>
<td class="colSource"><?= makePopupLink( '?view=monitor&amp;mid='.$monitor['Id'], 'zmMonitor'.$monitor['Id'], 'monitor', '<span class="'.$dclass.'">'.preg_replace( '/^.*\//', '', $monitor['Path'] ).'</span>', canEdit( 'Monitors' ) ) ?></td> <td class="colSource"><?= makePopupLink( '?view=monitor&amp;mid='.$monitor['Id'], 'zmMonitor'.$monitor['Id'], 'monitor', '<span class="'.$dclass.'">'.preg_replace( '/^.*\//', '', $monitor['Path'] ).'</span>', canEdit( 'Monitors' ) ) ?></td>
<?php } elseif ( $monitor['Type'] == "Libvlc" ) {
$domain = parse_url( $monitor['Path'], PHP_URL_HOST );
$shortpath = $domain ? $domain : preg_replace( '/^.*\//', '', $monitor['Path'] );
?>
<td class="colSource"><?= makePopupLink( '?view=monitor&amp;mid='.$monitor['Id'], 'zmMonitor'.$monitor['Id'], 'monitor', '<span class="'.$dclass.'">'.$shortpath.'</span>', canEdit( 'Monitors' ) ) ?></td>
<?php } elseif ( $monitor['Type'] == "cURL" ) { ?> <?php } elseif ( $monitor['Type'] == "cURL" ) { ?>
<td class="colSource"><?= makePopupLink( '?view=monitor&amp;mid='.$monitor['Id'], 'zmMonitor'.$monitor['Id'], 'monitor', '<span class="'.$dclass.'">'.preg_replace( '/^.*\//', '', $monitor['Path'] ).'</span>', canEdit( 'Monitors' ) ) ?></td> <td class="colSource"><?= makePopupLink( '?view=monitor&amp;mid='.$monitor['Id'], 'zmMonitor'.$monitor['Id'], 'monitor', '<span class="'.$dclass.'">'.preg_replace( '/^.*\//', '', $monitor['Path'] ).'</span>', canEdit( 'Monitors' ) ) ?></td>
<?php } else { ?> <?php } else { ?>

View File

@ -345,7 +345,7 @@ switch ( $tab )
?> ?>
<tr><th scope="row"><?= $SLANG['Name'] ?></th><td><input type="text" name="newControl[Name]" value="<?= validHtmlStr($newControl['Name']) ?>" size="24"/></td></tr> <tr><th scope="row"><?= $SLANG['Name'] ?></th><td><input type="text" name="newControl[Name]" value="<?= validHtmlStr($newControl['Name']) ?>" size="24"/></td></tr>
<?php <?php
$types = array( 'Local'=>$SLANG['Local'], 'Remote'=>$SLANG['Remote'], 'Ffmpeg'=>$SLANG['Ffmpeg'] ); $types = array( 'Local'=>$SLANG['Local'], 'Remote'=>$SLANG['Remote'], 'Ffmpeg'=>$SLANG['Ffmpeg'], 'Libvlc'=>$SLANG['Libvlc'] );
?> ?>
<tr><th scope="row"><?= $SLANG['Type'] ?></th><td><?= buildSelect( "newControl[Type]", $types ); ?></td></tr> <tr><th scope="row"><?= $SLANG['Type'] ?></th><td><?= buildSelect( "newControl[Type]", $types ); ?></td></tr>
<tr><th scope="row"><?= $SLANG['Protocol'] ?></th><td><input type="text" name="newControl[Protocol]" value="<?= validHtmlStr($newControl['Protocol']) ?>" size="24"/></td></tr> <tr><th scope="row"><?= $SLANG['Protocol'] ?></th><td><input type="text" name="newControl[Protocol]" value="<?= validHtmlStr($newControl['Protocol']) ?>" size="24"/></td></tr>

View File

@ -9,17 +9,17 @@ function updateButtons( element )
var canExecute = false; var canExecute = false;
if ( form.elements['autoArchive'].checked ) if ( form.elements['autoArchive'].checked )
canExecute = true; canExecute = true;
if ( form.elements['autoVideo'].checked ) else if ( form.elements['autoVideo'].checked )
canExecute = true; canExecute = true;
if ( form.elements['autoUpload'].checked ) else if ( form.elements['autoUpload'] && form.elements['autoUpload'].checked )
canExecute = true; canExecute = true;
if ( form.elements['autoEmail'].checked ) else if ( form.elements['autoEmail'].checked )
canExecute = true; canExecute = true;
if ( form.elements['autoMessage'].checked ) else if ( form.elements['autoMessage'].checked )
canExecute = true; canExecute = true;
if ( form.elements['autoExecute'].checked && form.elements['autoExecuteCmd'].value != '' ) else if ( form.elements['autoExecute'].checked && form.elements['autoExecuteCmd'].value != '' )
canExecute = true; canExecute = true;
if ( form.elements['autoDelete'].checked ) else if ( form.elements['autoDelete'].checked )
canExecute = true; canExecute = true;
form.elements['executeButton'].disabled = !canExecute; form.elements['executeButton'].disabled = !canExecute;
} }

View File

@ -97,7 +97,8 @@ else
'MaxFPS' => "", 'MaxFPS' => "",
'AlarmMaxFPS' => "", 'AlarmMaxFPS' => "",
'FPSReportInterval' => 1000, 'FPSReportInterval' => 1000,
'RefBlendPerc' => 12, 'RefBlendPerc' => 6,
'AlarmRefBlendPerc' => 3,
'DefaultView' => 'Events', 'DefaultView' => 'Events',
'DefaultRate' => '100', 'DefaultRate' => '100',
'DefaultScale' => '100', 'DefaultScale' => '100',
@ -176,7 +177,8 @@ $sourceTypes = array(
'Remote' => $SLANG['Remote'], 'Remote' => $SLANG['Remote'],
'File' => $SLANG['File'], 'File' => $SLANG['File'],
'Ffmpeg' => $SLANG['Ffmpeg'], 'Ffmpeg' => $SLANG['Ffmpeg'],
'cURL' => "cURL", 'Libvlc' => $SLANG['Libvlc'],
'cURL' => "cURL"
); );
if ( !ZM_HAS_V4L ) if ( !ZM_HAS_V4L )
unset($sourceTypes['Local']); unset($sourceTypes['Local']);
@ -309,7 +311,7 @@ if ( ZM_HAS_V4L2 )
//"YVU410" => fourcc('Y','V','U','9'), /* 9 YVU 4:1:0 */ //"YVU410" => fourcc('Y','V','U','9'), /* 9 YVU 4:1:0 */
//"YVU420" => fourcc('Y','V','1','2'), /* 12 YVU 4:2:0 */ //"YVU420" => fourcc('Y','V','1','2'), /* 12 YVU 4:2:0 */
//"UYVY" => fourcc('U','Y','V','Y'), /* 16 YUV 4:2:2 */ "*UYVY" => fourcc('U','Y','V','Y'), /* 16 YUV 4:2:2 */
"*YUV422P" => fourcc('4','2','2','P'), /* 16 YVU422 planar */ "*YUV422P" => fourcc('4','2','2','P'), /* 16 YVU422 planar */
"*YUV411P" => fourcc('4','1','1','P'), /* 16 YVU411 planar */ "*YUV411P" => fourcc('4','1','1','P'), /* 16 YVU411 planar */
//"Y41P" => fourcc('Y','4','1','P'), /* 12 YUV 4:1:1 */ //"Y41P" => fourcc('Y','4','1','P'), /* 12 YUV 4:1:1 */
@ -389,7 +391,27 @@ $deinterlaceopts_v4l2 = array(
"V4L2: Capture bottom field only" => 0x03000000, "V4L2: Capture bottom field only" => 0x03000000,
"V4L2: Alternate fields (Bob)" => 0x07000000, "V4L2: Alternate fields (Bob)" => 0x07000000,
"V4L2: Progressive" => 0x01000000, "V4L2: Progressive" => 0x01000000,
"V4L2: Interlaced" => 0x04000000, "V4L2: Interlaced" => 0x04000000
);
$fastblendopts = array(
"No blending" => 0,
"1.5625%" => 1,
"3.125%" => 3,
"6.25% (Indoor)" => 6,
"12.5% (Outdoor)" => 12,
"25%" => 25,
"50%" => 50
);
$fastblendopts_alarm = array(
"No blending (Alarm lasts forever)" => 0,
"1.5625%" => 1,
"3.125%" => 3,
"6.25%" => 6,
"12.5%" => 12,
"25%" => 25,
"50% (Alarm lasts a moment)" => 50
); );
xhtmlHeaders(__FILE__, $SLANG['Monitor']." - ".validHtmlStr($monitor['Name']) ); xhtmlHeaders(__FILE__, $SLANG['Monitor']." - ".validHtmlStr($monitor['Name']) );
@ -447,6 +469,7 @@ if ( $tab != 'general' )
<input type="hidden" name="newMonitor[Function]" value="<?= validHtmlStr($newMonitor['Function']) ?>"/> <input type="hidden" name="newMonitor[Function]" value="<?= validHtmlStr($newMonitor['Function']) ?>"/>
<input type="hidden" name="newMonitor[Enabled]" value="<?= validHtmlStr($newMonitor['Enabled']) ?>"/> <input type="hidden" name="newMonitor[Enabled]" value="<?= validHtmlStr($newMonitor['Enabled']) ?>"/>
<input type="hidden" name="newMonitor[RefBlendPerc]" value="<?= validHtmlStr($newMonitor['RefBlendPerc']) ?>"/> <input type="hidden" name="newMonitor[RefBlendPerc]" value="<?= validHtmlStr($newMonitor['RefBlendPerc']) ?>"/>
<input type="hidden" name="newMonitor[AlarmRefBlendPerc]" value="<?= validHtmlStr($newMonitor['AlarmRefBlendPerc']) ?>"/>
<input type="hidden" name="newMonitor[MaxFPS]" value="<?= validHtmlStr($newMonitor['MaxFPS']) ?>"/> <input type="hidden" name="newMonitor[MaxFPS]" value="<?= validHtmlStr($newMonitor['MaxFPS']) ?>"/>
<input type="hidden" name="newMonitor[AlarmMaxFPS]" value="<?= validHtmlStr($newMonitor['AlarmMaxFPS']) ?>"/> <input type="hidden" name="newMonitor[AlarmMaxFPS]" value="<?= validHtmlStr($newMonitor['AlarmMaxFPS']) ?>"/>
<?php <?php
@ -483,7 +506,7 @@ if ( $tab != 'source' || ($newMonitor['Type'] != 'Local' && $newMonitor['Type']
<input type="hidden" name="newMonitor[Method]" value="<?= validHtmlStr($newMonitor['Method']) ?>"/> <input type="hidden" name="newMonitor[Method]" value="<?= validHtmlStr($newMonitor['Method']) ?>"/>
<?php <?php
} }
if ( $tab != 'source' || ($newMonitor['Type'] != 'Remote' && $newMonitor['Type'] != 'File' && $newMonitor['Type'] != 'Ffmpeg') ) if ( $tab != 'source' || ($newMonitor['Type'] != 'Remote' && $newMonitor['Type'] != 'File' && $newMonitor['Type'] != 'Ffmpeg' && $newMonitor['Type'] != 'Libvlc') )
{ {
?> ?>
<input type="hidden" name="newMonitor[Path]" value="<?= validHtmlStr($newMonitor['Path']) ?>"/> <input type="hidden" name="newMonitor[Path]" value="<?= validHtmlStr($newMonitor['Path']) ?>"/>
@ -606,7 +629,20 @@ switch ( $tab )
</tr> </tr>
<tr><td><?= $SLANG['MaximumFPS'] ?></td><td><input type="text" name="newMonitor[MaxFPS]" value="<?= validHtmlStr($newMonitor['MaxFPS']) ?>" size="6"/></td></tr> <tr><td><?= $SLANG['MaximumFPS'] ?></td><td><input type="text" name="newMonitor[MaxFPS]" value="<?= validHtmlStr($newMonitor['MaxFPS']) ?>" size="6"/></td></tr>
<tr><td><?= $SLANG['AlarmMaximumFPS'] ?></td><td><input type="text" name="newMonitor[AlarmMaxFPS]" value="<?= validHtmlStr($newMonitor['AlarmMaxFPS']) ?>" size="6"/></td></tr> <tr><td><?= $SLANG['AlarmMaximumFPS'] ?></td><td><input type="text" name="newMonitor[AlarmMaxFPS]" value="<?= validHtmlStr($newMonitor['AlarmMaxFPS']) ?>" size="6"/></td></tr>
<?php
if ( ZM_FAST_IMAGE_BLENDS )
{
?>
<tr><td><?= $SLANG['RefImageBlendPct'] ?></td><td><select name="newMonitor[RefBlendPerc]"><?php foreach ( $fastblendopts as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['RefBlendPerc'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
<tr><td><?= "Alarm " . $SLANG['RefImageBlendPct'] ?></td><td><select name="newMonitor[AlarmRefBlendPerc]"><?php foreach ( $fastblendopts_alarm as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['AlarmRefBlendPerc'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
<?php
} else {
?>
<tr><td><?= $SLANG['RefImageBlendPct'] ?></td><td><input type="text" name="newMonitor[RefBlendPerc]" value="<?= validHtmlStr($newMonitor['RefBlendPerc']) ?>" size="4"/></td></tr> <tr><td><?= $SLANG['RefImageBlendPct'] ?></td><td><input type="text" name="newMonitor[RefBlendPerc]" value="<?= validHtmlStr($newMonitor['RefBlendPerc']) ?>" size="4"/></td></tr>
<tr><td><?= "Alarm " . $SLANG['RefImageBlendPct'] ?></td><td><input type="text" name="newMonitor[AlarmRefBlendPerc]" value="<?= validHtmlStr($newMonitor['AlarmRefBlendPerc']) ?>" size="4"/></td></tr>
<?php
}
?>
<tr><td><?= $SLANG['Triggers'] ?></td><td> <tr><td><?= $SLANG['Triggers'] ?></td><td>
<?php <?php
$optTriggers = getSetValues( 'Monitors', 'Triggers' ); $optTriggers = getSetValues( 'Monitors', 'Triggers' );
@ -683,7 +719,7 @@ switch ( $tab )
<tr><td><?= $SLANG['RemoteHostPath'] ?></td><td><input type="text" name="newMonitor[Path]" value="<?= validHtmlStr($newMonitor['Path']) ?>" size="36"/></td></tr> <tr><td><?= $SLANG['RemoteHostPath'] ?></td><td><input type="text" name="newMonitor[Path]" value="<?= validHtmlStr($newMonitor['Path']) ?>" size="36"/></td></tr>
<?php <?php
} }
elseif ( $newMonitor['Type'] == "File" || $newMonitor['Type'] == "Ffmpeg" ) elseif ( $newMonitor['Type'] == "File" || $newMonitor['Type'] == "Ffmpeg" || $newMonitor['Type'] == "Libvlc" )
{ {
?> ?>
<tr><td><?= $SLANG['SourcePath'] ?></td><td><input type="text" name="newMonitor[Path]" value="<?= validHtmlStr($newMonitor['Path']) ?>" size="36"/></td></tr> <tr><td><?= $SLANG['SourcePath'] ?></td><td><input type="text" name="newMonitor[Path]" value="<?= validHtmlStr($newMonitor['Path']) ?>" size="36"/></td></tr>

View File

@ -245,6 +245,24 @@ function probeVivotek( $ip )
return( $camera ); return( $camera );
} }
function probeWansview( $ip )
{
$camera = array(
'model' => "Wansview Camera",
'monitor' => array(
'Type' => 'Remote',
'Protocol' => 'http',
'Host' => 'admin:123456@'.$ip,
'Port' => 80,
'Path' => 'videostream.cgi',
'Width' => 640,
'Height' => 480,
'Palette' => 3
),
);
return( $camera );
}
$monitors = array(); $monitors = array();
foreach ( dbFetchAll( "select Id, Name, Host from Monitors where Type = 'Remote' order by Host" ) as $monitor ) foreach ( dbFetchAll( "select Id, Name, Host from Monitors where Type = 'Remote' order by Host" ) as $monitor )
{ {
@ -264,6 +282,8 @@ $macBases = array(
'00:80:f0' => array( 'type'=>'Panasonic','probeFunc'=>'probePana' ), '00:80:f0' => array( 'type'=>'Panasonic','probeFunc'=>'probePana' ),
'00:0f:7c' => array( 'type'=>'ACTi','probeFunc'=>'probeACTi' ), '00:0f:7c' => array( 'type'=>'ACTi','probeFunc'=>'probeACTi' ),
'00:02:d1' => array( 'type'=>'Vivotek','probeFunc'=>'probeVivotek' ), '00:02:d1' => array( 'type'=>'Vivotek','probeFunc'=>'probeVivotek' ),
'7c:dd:90' => array( 'type'=>'Wansview','probeFunc'=>'probeWansview' ),
'78:a5:dd' => array( 'type'=>'Wansview','probeFunc'=>'probeWansview' )
); );
unset($output); unset($output);

View File

@ -32,3 +32,11 @@ else(NOT mtmorelist)
message(WARNING " Failed creating the required symlinks for mootools-more. Exit code: ${mtmoreresult}") message(WARNING " Failed creating the required symlinks for mootools-more. Exit code: ${mtmoreresult}")
endif(mtmoreresult) endif(mtmoreresult)
endif(NOT mtmorelist) endif(NOT mtmorelist)
# If this is an out-of-source build, copy the mootools files we picked to the binary directory
# This is required to fix a cmake bug regarding installing symlinks pointing to nonexistent files
if(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR))
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${mtcorelatest}" "${CMAKE_CURRENT_BINARY_DIR}/${mtcorelatest}")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${mtmorelatest}" "${CMAKE_CURRENT_BINARY_DIR}/${mtmorelatest}")
endif(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR))

View File

@ -9,18 +9,9 @@
# or installations. # or installations.
# #
# Current version of ZoneMinder
ZM_VERSION=@VERSION@
# Path to build directory
ZM_PATH_BUILD=@PATH_BUILD@
# Path to installed data directory, used mostly for finding DB upgrade scripts # Path to installed data directory, used mostly for finding DB upgrade scripts
ZM_PATH_DATA=@PKGDATADIR@ ZM_PATH_DATA=@PKGDATADIR@
# Build time, used to record when to trigger various checks
ZM_TIME_BUILD=@TIME_BUILD@
# Path to ZoneMinder binaries # Path to ZoneMinder binaries
ZM_PATH_BIN=@BINDIR@ ZM_PATH_BIN=@BINDIR@
@ -40,6 +31,9 @@ ZM_PATH_CGI=@CGI_PREFIX@
ZM_WEB_USER=@WEB_USER@ ZM_WEB_USER=@WEB_USER@
ZM_WEB_GROUP=@WEB_GROUP@ ZM_WEB_GROUP=@WEB_GROUP@
# ZoneMinder database type
ZM_DB_TYPE=@ZM_DB_TYPE@
# ZoneMinder database hostname or ip address # ZoneMinder database hostname or ip address
ZM_DB_HOST=@ZM_DB_HOST@ ZM_DB_HOST=@ZM_DB_HOST@
@ -51,3 +45,6 @@ ZM_DB_USER=@ZM_DB_USER@
# ZoneMinder database password # ZoneMinder database password
ZM_DB_PASS=@ZM_DB_PASS@ ZM_DB_PASS=@ZM_DB_PASS@
# Host of this machine
ZM_SERVER_HOST=

View File

@ -15,7 +15,6 @@
#cmakedefine HAVE_DECL_BACKTRACE 1 #cmakedefine HAVE_DECL_BACKTRACE 1
#cmakedefine HAVE_DECL_BACKTRACE_SYMBOLS 1 #cmakedefine HAVE_DECL_BACKTRACE_SYMBOLS 1
#cmakedefine HAVE_POSIX_MEMALIGN 1 #cmakedefine HAVE_POSIX_MEMALIGN 1
#cmakedefine HAVE_DECL_ROUND 1
#cmakedefine HAVE_SIGINFO_T 1 #cmakedefine HAVE_SIGINFO_T 1
#cmakedefine HAVE_UCONTEXT_T 1 #cmakedefine HAVE_UCONTEXT_T 1
@ -51,6 +50,8 @@
#cmakedefine HAVE_LIBAVUTIL_MATHEMATICS_H 1 #cmakedefine HAVE_LIBAVUTIL_MATHEMATICS_H 1
#cmakedefine HAVE_LIBSWSCALE 1 #cmakedefine HAVE_LIBSWSCALE 1
#cmakedefine HAVE_LIBSWSCALE_SWSCALE_H 1 #cmakedefine HAVE_LIBSWSCALE_SWSCALE_H 1
#cmakedefine HAVE_LIBVLC 1
#cmakedefine HAVE_VLC_VLC_H 1
/* Authenication checks */ /* Authenication checks */
#cmakedefine HAVE_MD5_OPENSSL 1 #cmakedefine HAVE_MD5_OPENSSL 1