mirror of
https://github.com/simon987/sist2.git
synced 2025-04-24 12:45:56 +00:00
extract scan code to libscan, (wip)
This commit is contained in:
parent
fe53b79d56
commit
94613415cf
48
.gitmodules
vendored
48
.gitmodules
vendored
@ -1,45 +1,15 @@
|
||||
[submodule "argparse"]
|
||||
path = argparse
|
||||
path = third-party/argparse
|
||||
url = https://github.com/cofyc/argparse
|
||||
[submodule "cJSON"]
|
||||
path = cJSON
|
||||
path = third-party/cJSON
|
||||
url = https://github.com/DaveGamble/cJSON
|
||||
[submodule "lmdb"]
|
||||
path = lmdb
|
||||
url = https://github.com/LMDB/lmdb
|
||||
[submodule "utf8.h"]
|
||||
path = utf8.h
|
||||
url = https://github.com/sheredom/utf8.h
|
||||
[submodule "lib/bzip2-1.0.6"]
|
||||
path = lib/bzip2-1.0.6
|
||||
url = https://github.com/enthought/bzip2-1.0.6
|
||||
[submodule "lib/libmagic"]
|
||||
path = lib/libmagic
|
||||
url = https://github.com/threatstack/libmagic
|
||||
[submodule "lib/harfbuzz"]
|
||||
path = lib/harfbuzz
|
||||
url = https://github.com/harfbuzz/harfbuzz
|
||||
[submodule "lib/openjpeg"]
|
||||
path = lib/openjpeg
|
||||
url = https://github.com/uclouvain/openjpeg
|
||||
[submodule "lib/ffmpeg"]
|
||||
path = lib/ffmpeg
|
||||
url = https://git.ffmpeg.org/ffmpeg.git
|
||||
[submodule "lib/onion"]
|
||||
path = lib/onion
|
||||
path = third-party/onion
|
||||
url = https://github.com/davidmoreno/onion
|
||||
[submodule "lib/mupdf"]
|
||||
path = lib/mupdf
|
||||
url = git://git.ghostscript.com/mupdf.git
|
||||
[submodule "lib/tesseract"]
|
||||
path = lib/tesseract
|
||||
url = https://github.com/tesseract-ocr/tesseract
|
||||
[submodule "lib/leptonica"]
|
||||
path = lib/leptonica
|
||||
url = https://github.com/danbloomberg/leptonica
|
||||
[submodule "lib/libtiff"]
|
||||
path = lib/libtiff
|
||||
url = https://gitlab.com/libtiff/libtiff
|
||||
[submodule "lib/libpng"]
|
||||
path = lib/libpng
|
||||
url = https://github.com/glennrp/libpng
|
||||
[submodule "third-party/libscan"]
|
||||
path = third-party/libscan
|
||||
url = https://github.com/simon987/libscan
|
||||
[submodule "third-party/utf8.h"]
|
||||
path = third-party/utf8.h
|
||||
url = https://github.com/sheredom/utf8.h
|
||||
|
112
CMakeLists.txt
112
CMakeLists.txt
@ -6,81 +6,44 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMakeModules")
|
||||
|
||||
option(SIST_DEBUG "Build a debug executable" on)
|
||||
|
||||
add_subdirectory(third-party/libscan)
|
||||
add_subdirectory(third-party/argparse)
|
||||
|
||||
add_executable(
|
||||
sist2
|
||||
src/main.c
|
||||
src/sist.h
|
||||
src/io/walk.h src/io/walk.c
|
||||
src/parsing/media.h src/parsing/media.c
|
||||
src/parsing/pdf.h src/parsing/pdf.c
|
||||
src/io/store.h src/io/store.c
|
||||
src/tpool.h src/tpool.c
|
||||
src/parsing/parse.h src/parsing/parse.c
|
||||
src/io/serialize.h src/io/serialize.c
|
||||
src/parsing/mime.h src/parsing/mime.c src/parsing/mime_generated.c
|
||||
src/parsing/text.h src/parsing/text.c
|
||||
src/index/web.c src/index/web.h
|
||||
src/web/serve.c src/web/serve.h
|
||||
src/web/auth_basic.h src/web/auth_basic.c
|
||||
src/index/elastic.c src/index/elastic.h
|
||||
src/util.c src/util.h
|
||||
src/ctx.h src/types.h src/parsing/font.c src/parsing/font.h
|
||||
src/parsing/arc.c src/parsing/arc.h
|
||||
src/parsing/doc.c src/parsing/doc.h
|
||||
src/ctx.h src/types.h
|
||||
src/log.c src/log.h
|
||||
src/parsing/cbr.h src/parsing/cbr.c
|
||||
|
||||
# argparse
|
||||
argparse/argparse.h argparse/argparse.c
|
||||
third-party/argparse/argparse.h third-party/argparse/argparse.c
|
||||
|
||||
# cJSON
|
||||
cJSON/cJSON.h cJSON/cJSON.c
|
||||
|
||||
# LMDB
|
||||
lmdb/libraries/liblmdb/lmdb.h lmdb/libraries/liblmdb/mdb.c
|
||||
lmdb/libraries/liblmdb/midl.h lmdb/libraries/liblmdb/midl.c
|
||||
src/cli.c src/cli.h
|
||||
|
||||
# utf8.h
|
||||
utf8.h/utf8.h
|
||||
)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig/")
|
||||
find_package(lmdb CONFIG REQUIRED)
|
||||
find_package(cJSON CONFIG REQUIRED)
|
||||
find_package(unofficial-glib CONFIG REQUIRED)
|
||||
|
||||
find_package(Freetype REQUIRED)
|
||||
|
||||
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
||||
pkg_check_modules(GOBJECT REQUIRED gobject-2.0)
|
||||
pkg_check_modules(UUID REQUIRED uuid)
|
||||
|
||||
add_definitions(${UUID_CFLAGS_OTHER})
|
||||
add_definitions(${GLIB_CFLAGS_OTHER})
|
||||
add_definitions(${GOBJECT_CFLAGS_OTHER})
|
||||
add_definitions(${FREETYPE_CFLAGS_OTHER})
|
||||
|
||||
list(REMOVE_ITEM GLIB_LIBRARIES pcre)
|
||||
list(REMOVE_ITEM GOBJECT_LIBRARIES pcre)
|
||||
list(REMOVE_ITEM UUID_LIBRARIES pcre)
|
||||
|
||||
target_include_directories(
|
||||
sist2 PUBLIC
|
||||
${GOBJECT_INCLUDE_DIRS}
|
||||
${GLIB_INCLUDE_DIRS}
|
||||
${PROJECT_SOURCE_DIR}/lib/ffmpeg/
|
||||
${FREETYPE_INCLUDE_DIRS}
|
||||
${UUID_INCLUDE_DIRS}
|
||||
${PROJECT_SOURCE_DIR}/
|
||||
${PROJECT_SOURCE_DIR}/lmdb/libraries/liblmdb/
|
||||
${PROJECT_SOURCE_DIR}/lib/onion/src/
|
||||
${PROJECT_SOURCE_DIR}/lib/mupdf/include/
|
||||
${PROJECT_SOURCE_DIR}/include/
|
||||
/usr/include/libxml2/
|
||||
${PROJECT_SOURCE_DIR}/lib/tesseract/include/
|
||||
)
|
||||
target_link_directories(
|
||||
sist2 PUBLIC
|
||||
${UUID_LIBRARY_DIRS}
|
||||
${CMAKE_SOURCE_DIR}/third-party/onion/src/
|
||||
${CMAKE_SOURCE_DIR}/third-party/utf8.h/
|
||||
${CMAKE_SOURCE_DIR}/third-party/libscan/
|
||||
${CMAKE_SOURCE_DIR}/
|
||||
)
|
||||
|
||||
target_compile_options(
|
||||
@ -119,53 +82,26 @@ else ()
|
||||
)
|
||||
endif ()
|
||||
|
||||
TARGET_LINK_LIBRARIES(
|
||||
add_dependencies(
|
||||
sist2
|
||||
scan
|
||||
argparse
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
sist2
|
||||
|
||||
${GLIB_LIBRARIES}
|
||||
${GOBJECT_LIBRARIES}
|
||||
${UUID_LIBRARIES}
|
||||
|
||||
# ffmpeg
|
||||
${PROJECT_SOURCE_DIR}/lib/libavcodec.a
|
||||
${PROJECT_SOURCE_DIR}/lib/libavformat.a
|
||||
${PROJECT_SOURCE_DIR}/lib/libavutil.a
|
||||
${PROJECT_SOURCE_DIR}/lib/libswscale.a
|
||||
${PROJECT_SOURCE_DIR}/lib/libswresample.a
|
||||
|
||||
# mupdf
|
||||
${PROJECT_SOURCE_DIR}/lib/libmupdf.a
|
||||
${PROJECT_SOURCE_DIR}/lib/libmupdf-third.a
|
||||
lmdb
|
||||
cjson
|
||||
argparse
|
||||
unofficial::glib::glib
|
||||
|
||||
# onion
|
||||
${PROJECT_SOURCE_DIR}/lib/libonion_static.a
|
||||
|
||||
pthread
|
||||
|
||||
m
|
||||
bz2
|
||||
# ${PROJECT_SOURCE_DIR}/lib/libmagic.a
|
||||
magic
|
||||
${PROJECT_SOURCE_DIR}/lib/libharfbuzz.a
|
||||
${PROJECT_SOURCE_DIR}/lib/libopenjp2.a
|
||||
freetype
|
||||
archive
|
||||
|
||||
xml2
|
||||
|
||||
${PROJECT_SOURCE_DIR}/lib/libtesseract.a
|
||||
${PROJECT_SOURCE_DIR}/lib/liblept.a
|
||||
${PROJECT_SOURCE_DIR}/lib/libtiff.a
|
||||
${PROJECT_SOURCE_DIR}/lib/libpng16.a
|
||||
stdc++
|
||||
|
||||
# curl
|
||||
${PROJECT_SOURCE_DIR}/lib/libcurl.a
|
||||
${PROJECT_SOURCE_DIR}/lib/libcrypto.a
|
||||
${PROJECT_SOURCE_DIR}/lib/libssl.a
|
||||
dl
|
||||
|
||||
pcre
|
||||
scan
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
|
80
CMakeModules/FindFFmpeg.cmake
vendored
80
CMakeModules/FindFFmpeg.cmake
vendored
@ -1,80 +0,0 @@
|
||||
# - Try to find ffmpeg libraries (libavcodec, libavformat and libavutil)
|
||||
# Once done this will define
|
||||
#
|
||||
# FFMPEG_FOUND - system has ffmpeg or libav
|
||||
# FFMPEG_INCLUDE_DIR - the ffmpeg include directory
|
||||
# FFMPEG_LIBRARIES - Link these to use ffmpeg
|
||||
# FFMPEG_LIBAVCODEC
|
||||
# FFMPEG_LIBAVFORMAT
|
||||
# FFMPEG_LIBAVUTIL
|
||||
#
|
||||
# Copyright (c) 2008 Andreas Schneider <mail@cynapses.org>
|
||||
# Modified for other libraries by Lasse Kärkkäinen <tronic>
|
||||
# Modified for Hedgewars by Stepik777
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
#
|
||||
|
||||
if (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR)
|
||||
# in cache already
|
||||
set(FFMPEG_FOUND TRUE)
|
||||
else (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR)
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(_FFMPEG_AVCODEC libavcodec)
|
||||
pkg_check_modules(_FFMPEG_AVFORMAT libavformat)
|
||||
pkg_check_modules(_FFMPEG_AVUTIL libavutil)
|
||||
endif (PKG_CONFIG_FOUND)
|
||||
|
||||
find_path(FFMPEG_AVCODEC_INCLUDE_DIR
|
||||
NAMES libavcodec/avcodec.h
|
||||
PATHS ${_FFMPEG_AVCODEC_INCLUDE_DIRS} /usr/include /usr/local/include /opt/local/include /sw/include
|
||||
PATH_SUFFIXES ffmpeg libav
|
||||
)
|
||||
|
||||
find_library(FFMPEG_LIBAVCODEC
|
||||
NAMES avcodec
|
||||
PATHS ${_FFMPEG_AVCODEC_LIBRARY_DIRS} /usr/lib /usr/local/lib /opt/local/lib /sw/lib
|
||||
)
|
||||
|
||||
find_library(FFMPEG_LIBAVFORMAT
|
||||
NAMES avformat
|
||||
PATHS ${_FFMPEG_AVFORMAT_LIBRARY_DIRS} /usr/lib /usr/local/lib /opt/local/lib /sw/lib
|
||||
)
|
||||
|
||||
find_library(FFMPEG_LIBAVUTIL
|
||||
NAMES avutil
|
||||
PATHS ${_FFMPEG_AVUTIL_LIBRARY_DIRS} /usr/lib /usr/local/lib /opt/local/lib /sw/lib
|
||||
)
|
||||
|
||||
if (FFMPEG_LIBAVCODEC AND FFMPEG_LIBAVFORMAT)
|
||||
set(FFMPEG_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
if (FFMPEG_FOUND)
|
||||
set(FFMPEG_INCLUDE_DIR ${FFMPEG_AVCODEC_INCLUDE_DIR})
|
||||
|
||||
set(FFMPEG_LIBRARIES
|
||||
${FFMPEG_LIBAVCODEC}
|
||||
${FFMPEG_LIBAVFORMAT}
|
||||
${FFMPEG_LIBAVUTIL}
|
||||
)
|
||||
|
||||
endif (FFMPEG_FOUND)
|
||||
|
||||
if (FFMPEG_FOUND)
|
||||
if (NOT FFMPEG_FIND_QUIETLY)
|
||||
message(STATUS "Found FFMPEG or Libav: ${FFMPEG_LIBRARIES}, ${FFMPEG_INCLUDE_DIR}")
|
||||
endif (NOT FFMPEG_FIND_QUIETLY)
|
||||
else (FFMPEG_FOUND)
|
||||
if (FFMPEG_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find libavcodec or libavformat or libavutil")
|
||||
endif (FFMPEG_FIND_REQUIRED)
|
||||
endif (FFMPEG_FOUND)
|
||||
|
||||
endif (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR)
|
||||
|
||||
|
100
CMakeModules/FindLibMagic.cmake
vendored
100
CMakeModules/FindLibMagic.cmake
vendored
@ -1,100 +0,0 @@
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Copyright (c) 2013-2013, Lars Baehren <lbaehren@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# - Check for the presence of LIBMAGIC
|
||||
#
|
||||
# The following variables are set when LIBMAGIC is found:
|
||||
# LIBMAGIC_FOUND = Set to true, if all components of LIBMAGIC have been
|
||||
# found.
|
||||
# LIBMAGIC_INCLUDES = Include path for the header files of LIBMAGIC
|
||||
# LIBMAGIC_LIBRARIES = Link these to use LIBMAGIC
|
||||
# LIBMAGIC_LFLAGS = Linker flags (optional)
|
||||
|
||||
if (NOT LIBMAGIC_FOUND)
|
||||
|
||||
if (NOT LIBMAGIC_ROOT_DIR)
|
||||
set (LIBMAGIC_ROOT_DIR ${CMAKE_INSTALL_PREFIX})
|
||||
endif (NOT LIBMAGIC_ROOT_DIR)
|
||||
|
||||
##____________________________________________________________________________
|
||||
## Check for the header files
|
||||
|
||||
find_path (LIBMAGIC_FILE_H
|
||||
NAMES file/file.h
|
||||
HINTS ${LIBMAGIC_ROOT_DIR} ${CMAKE_INSTALL_PREFIX}
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
if (LIBMAGIC_FILE_H)
|
||||
list (APPEND LIBMAGIC_INCLUDES ${LIBMAGIC_FILE_H})
|
||||
endif (LIBMAGIC_FILE_H)
|
||||
|
||||
find_path (LIBMAGIC_MAGIC_H
|
||||
NAMES magic.h
|
||||
HINTS ${LIBMAGIC_ROOT_DIR} ${CMAKE_INSTALL_PREFIX}
|
||||
PATH_SUFFIXES include include/linux
|
||||
)
|
||||
if (LIBMAGIC_MAGIC_H)
|
||||
list (APPEND LIBMAGIC_INCLUDES ${LIBMAGIC_MAGIC_H})
|
||||
endif (LIBMAGIC_MAGIC_H)
|
||||
|
||||
list (REMOVE_DUPLICATES LIBMAGIC_INCLUDES)
|
||||
|
||||
##____________________________________________________________________________
|
||||
## Check for the library
|
||||
|
||||
find_library (LIBMAGIC_LIBRARIES magic
|
||||
HINTS ${LIBMAGIC_ROOT_DIR} ${CMAKE_INSTALL_PREFIX}
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
##____________________________________________________________________________
|
||||
## Actions taken when all components have been found
|
||||
|
||||
#find_package_handle_standard_args (LIBMAGIC DEFAULT_MSG LIBMAGIC_LIBRARIES LIBMAGIC_INCLUDES)
|
||||
|
||||
if (LIBMAGIC_FOUND)
|
||||
if (NOT LIBMAGIC_FIND_QUIETLY)
|
||||
message (STATUS "Found components for LIBMAGIC")
|
||||
message (STATUS "LIBMAGIC_ROOT_DIR = ${LIBMAGIC_ROOT_DIR}")
|
||||
message (STATUS "LIBMAGIC_INCLUDES = ${LIBMAGIC_INCLUDES}")
|
||||
message (STATUS "LIBMAGIC_LIBRARIES = ${LIBMAGIC_LIBRARIES}")
|
||||
endif (NOT LIBMAGIC_FIND_QUIETLY)
|
||||
else (LIBMAGIC_FOUND)
|
||||
if (LIBMAGIC_FIND_REQUIRED)
|
||||
message (FATAL_ERROR "Could not find LIBMAGIC!")
|
||||
endif (LIBMAGIC_FIND_REQUIRED)
|
||||
endif (LIBMAGIC_FOUND)
|
||||
|
||||
##____________________________________________________________________________
|
||||
## Mark advanced variables
|
||||
|
||||
mark_as_advanced (
|
||||
LIBMAGIC_ROOT_DIR
|
||||
LIBMAGIC_INCLUDES
|
||||
LIBMAGIC_LIBRARIES
|
||||
)
|
||||
|
||||
endif (NOT LIBMAGIC_FOUND)
|
478
CMakeModules/FindOpenSSL.cmake
vendored
478
CMakeModules/FindOpenSSL.cmake
vendored
@ -1,478 +0,0 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
macro(_OpenSSL_test_and_find_dependencies ssl_library crypto_library)
|
||||
if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND
|
||||
(("${ssl_library}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") OR
|
||||
("${crypto_library}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$")))
|
||||
set(_OpenSSL_has_dependencies TRUE)
|
||||
find_package(Threads)
|
||||
else()
|
||||
set(_OpenSSL_has_dependencies FALSE)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
function(_OpenSSL_add_dependencies libraries_var library)
|
||||
if(CMAKE_THREAD_LIBS_INIT)
|
||||
list(APPEND ${libraries_var} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
list(APPEND ${libraries_var} ${CMAKE_DL_LIBS})
|
||||
set(${libraries_var} ${${libraries_var}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_OpenSSL_target_add_dependencies target)
|
||||
if(_OpenSSL_has_dependencies)
|
||||
set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads )
|
||||
set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS} )
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if (UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(_OPENSSL QUIET openssl)
|
||||
endif ()
|
||||
|
||||
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
|
||||
if(OPENSSL_USE_STATIC_LIBS)
|
||||
set(_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
if(WIN32)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
else()
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
# http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
${OPENSSL_ROOT_DIR}
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
|
||||
ENV OPENSSL_ROOT_DIR
|
||||
)
|
||||
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
|
||||
set(_OPENSSL_ROOT_PATHS
|
||||
"${_programfiles}/OpenSSL"
|
||||
"${_programfiles}/OpenSSL-Win32"
|
||||
"${_programfiles}/OpenSSL-Win64"
|
||||
"C:/OpenSSL/"
|
||||
"C:/OpenSSL-Win32/"
|
||||
"C:/OpenSSL-Win64/"
|
||||
)
|
||||
unset(_programfiles)
|
||||
else ()
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
${OPENSSL_ROOT_DIR}
|
||||
ENV OPENSSL_ROOT_DIR
|
||||
)
|
||||
endif ()
|
||||
|
||||
set(_OPENSSL_ROOT_HINTS_AND_PATHS
|
||||
HINTS ${_OPENSSL_ROOT_HINTS}
|
||||
PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
)
|
||||
|
||||
find_path(OPENSSL_INCLUDE_DIR
|
||||
NAMES
|
||||
openssl/ssl.h
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
HINTS
|
||||
${_OPENSSL_INCLUDEDIR}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
||||
if(WIN32 AND NOT CYGWIN)
|
||||
if(MSVC)
|
||||
# /MD and /MDd are the standard values - if someone wants to use
|
||||
# others, the libnames have to change here too
|
||||
# use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b
|
||||
# enable OPENSSL_MSVC_STATIC_RT to get the libs build /MT (Multithreaded no-DLL)
|
||||
# In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix:
|
||||
# * MD for dynamic-release
|
||||
# * MDd for dynamic-debug
|
||||
# * MT for static-release
|
||||
# * MTd for static-debug
|
||||
|
||||
# Implementation details:
|
||||
# We are using the libraries located in the VC subdir instead of the parent directory even though :
|
||||
# libeay32MD.lib is identical to ../libeay32.lib, and
|
||||
# ssleay32MD.lib is identical to ../ssleay32.lib
|
||||
# enable OPENSSL_USE_STATIC_LIBS to use the static libs located in lib/VC/static
|
||||
|
||||
if (OPENSSL_MSVC_STATIC_RT)
|
||||
set(_OPENSSL_MSVC_RT_MODE "MT")
|
||||
else ()
|
||||
set(_OPENSSL_MSVC_RT_MODE "MD")
|
||||
endif ()
|
||||
|
||||
# Since OpenSSL 1.1, lib names are like libcrypto32MTd.lib and libssl32MTd.lib
|
||||
if( "${CMAKE_SIZEOF_VOID_P}" STREQUAL "8" )
|
||||
set(_OPENSSL_MSVC_ARCH_SUFFIX "64")
|
||||
else()
|
||||
set(_OPENSSL_MSVC_ARCH_SUFFIX "32")
|
||||
endif()
|
||||
|
||||
if(OPENSSL_USE_STATIC_LIBS)
|
||||
set(_OPENSSL_PATH_SUFFIXES
|
||||
"lib/VC/static"
|
||||
"VC/static"
|
||||
"lib"
|
||||
)
|
||||
else()
|
||||
set(_OPENSSL_PATH_SUFFIXES
|
||||
"lib/VC"
|
||||
"VC"
|
||||
"lib"
|
||||
)
|
||||
endif ()
|
||||
|
||||
find_library(LIB_EAY_DEBUG
|
||||
NAMES
|
||||
libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d
|
||||
libcrypto${_OPENSSL_MSVC_RT_MODE}d
|
||||
libcryptod
|
||||
libeay32${_OPENSSL_MSVC_RT_MODE}d
|
||||
libeay32d
|
||||
cryptod
|
||||
NAMES_PER_DIR
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
${_OPENSSL_PATH_SUFFIXES}
|
||||
)
|
||||
|
||||
find_library(LIB_EAY_RELEASE
|
||||
NAMES
|
||||
libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}
|
||||
libcrypto${_OPENSSL_MSVC_RT_MODE}
|
||||
libcrypto
|
||||
libeay32${_OPENSSL_MSVC_RT_MODE}
|
||||
libeay32
|
||||
crypto
|
||||
NAMES_PER_DIR
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
${_OPENSSL_PATH_SUFFIXES}
|
||||
)
|
||||
|
||||
find_library(SSL_EAY_DEBUG
|
||||
NAMES
|
||||
libssl${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d
|
||||
libssl${_OPENSSL_MSVC_RT_MODE}d
|
||||
libssld
|
||||
ssleay32${_OPENSSL_MSVC_RT_MODE}d
|
||||
ssleay32d
|
||||
ssld
|
||||
NAMES_PER_DIR
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
${_OPENSSL_PATH_SUFFIXES}
|
||||
)
|
||||
|
||||
find_library(SSL_EAY_RELEASE
|
||||
NAMES
|
||||
libssl${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}
|
||||
libssl${_OPENSSL_MSVC_RT_MODE}
|
||||
libssl
|
||||
ssleay32${_OPENSSL_MSVC_RT_MODE}
|
||||
ssleay32
|
||||
ssl
|
||||
NAMES_PER_DIR
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
${_OPENSSL_PATH_SUFFIXES}
|
||||
)
|
||||
|
||||
set(LIB_EAY_LIBRARY_DEBUG "${LIB_EAY_DEBUG}")
|
||||
set(LIB_EAY_LIBRARY_RELEASE "${LIB_EAY_RELEASE}")
|
||||
set(SSL_EAY_LIBRARY_DEBUG "${SSL_EAY_DEBUG}")
|
||||
set(SSL_EAY_LIBRARY_RELEASE "${SSL_EAY_RELEASE}")
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
|
||||
select_library_configurations(LIB_EAY)
|
||||
select_library_configurations(SSL_EAY)
|
||||
|
||||
mark_as_advanced(LIB_EAY_LIBRARY_DEBUG LIB_EAY_LIBRARY_RELEASE
|
||||
SSL_EAY_LIBRARY_DEBUG SSL_EAY_LIBRARY_RELEASE)
|
||||
set(OPENSSL_SSL_LIBRARY ${SSL_EAY_LIBRARY} )
|
||||
set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY_LIBRARY} )
|
||||
elseif(MINGW)
|
||||
# same player, for MinGW
|
||||
set(LIB_EAY_NAMES crypto libeay32)
|
||||
set(SSL_EAY_NAMES ssl ssleay32)
|
||||
find_library(LIB_EAY
|
||||
NAMES
|
||||
${LIB_EAY_NAMES}
|
||||
NAMES_PER_DIR
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib/MinGW"
|
||||
"lib"
|
||||
)
|
||||
|
||||
find_library(SSL_EAY
|
||||
NAMES
|
||||
${SSL_EAY_NAMES}
|
||||
NAMES_PER_DIR
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib/MinGW"
|
||||
"lib"
|
||||
)
|
||||
|
||||
mark_as_advanced(SSL_EAY LIB_EAY)
|
||||
set(OPENSSL_SSL_LIBRARY ${SSL_EAY} )
|
||||
set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} )
|
||||
unset(LIB_EAY_NAMES)
|
||||
unset(SSL_EAY_NAMES)
|
||||
else()
|
||||
# Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues:
|
||||
find_library(LIB_EAY
|
||||
NAMES
|
||||
libcrypto
|
||||
libeay32
|
||||
NAMES_PER_DIR
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
find_library(SSL_EAY
|
||||
NAMES
|
||||
libssl
|
||||
ssleay32
|
||||
NAMES_PER_DIR
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
mark_as_advanced(SSL_EAY LIB_EAY)
|
||||
set(OPENSSL_SSL_LIBRARY ${SSL_EAY} )
|
||||
set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} )
|
||||
endif()
|
||||
else()
|
||||
|
||||
find_library(OPENSSL_SSL_LIBRARY
|
||||
NAMES
|
||||
ssl
|
||||
ssleay32
|
||||
ssleay32MD
|
||||
NAMES_PER_DIR
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
find_library(OPENSSL_CRYPTO_LIBRARY
|
||||
NAMES
|
||||
crypto
|
||||
NAMES_PER_DIR
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
mark_as_advanced(OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY)
|
||||
|
||||
endif()
|
||||
|
||||
# compat defines
|
||||
set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY})
|
||||
set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
_OpenSSL_test_and_find_dependencies("${OPENSSL_SSL_LIBRARY}" "${OPENSSL_CRYPTO_LIBRARY}")
|
||||
if(_OpenSSL_has_dependencies)
|
||||
_OpenSSL_add_dependencies( OPENSSL_SSL_LIBRARIES "${OPENSSL_SSL_LIBRARY}" )
|
||||
_OpenSSL_add_dependencies( OPENSSL_CRYPTO_LIBRARIES "${OPENSSL_CRYPTO_LIBRARY}" )
|
||||
endif()
|
||||
|
||||
function(from_hex HEX DEC)
|
||||
string(TOUPPER "${HEX}" HEX)
|
||||
set(_res 0)
|
||||
string(LENGTH "${HEX}" _strlen)
|
||||
|
||||
while (_strlen GREATER 0)
|
||||
math(EXPR _res "${_res} * 16")
|
||||
string(SUBSTRING "${HEX}" 0 1 NIBBLE)
|
||||
string(SUBSTRING "${HEX}" 1 -1 HEX)
|
||||
if (NIBBLE STREQUAL "A")
|
||||
math(EXPR _res "${_res} + 10")
|
||||
elseif (NIBBLE STREQUAL "B")
|
||||
math(EXPR _res "${_res} + 11")
|
||||
elseif (NIBBLE STREQUAL "C")
|
||||
math(EXPR _res "${_res} + 12")
|
||||
elseif (NIBBLE STREQUAL "D")
|
||||
math(EXPR _res "${_res} + 13")
|
||||
elseif (NIBBLE STREQUAL "E")
|
||||
math(EXPR _res "${_res} + 14")
|
||||
elseif (NIBBLE STREQUAL "F")
|
||||
math(EXPR _res "${_res} + 15")
|
||||
else()
|
||||
math(EXPR _res "${_res} + ${NIBBLE}")
|
||||
endif()
|
||||
|
||||
string(LENGTH "${HEX}" _strlen)
|
||||
endwhile()
|
||||
|
||||
set(${DEC} ${_res} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h")
|
||||
file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str
|
||||
REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*")
|
||||
|
||||
if(openssl_version_str)
|
||||
# The version number is encoded as 0xMNNFFPPS: major minor fix patch status
|
||||
# The status gives if this is a developer or prerelease and is ignored here.
|
||||
# Major, minor, and fix directly translate into the version numbers shown in
|
||||
# the string. The patch field translates to the single character suffix that
|
||||
# indicates the bug fix state, which 00 -> nothing, 01 -> a, 02 -> b and so
|
||||
# on.
|
||||
|
||||
string(REGEX REPLACE "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F]).*$"
|
||||
"\\1;\\2;\\3;\\4;\\5" OPENSSL_VERSION_LIST "${openssl_version_str}")
|
||||
list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR)
|
||||
list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR)
|
||||
from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR)
|
||||
list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX)
|
||||
from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX)
|
||||
list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH)
|
||||
|
||||
if (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
||||
from_hex("${OPENSSL_VERSION_PATCH}" _tmp)
|
||||
# 96 is the ASCII code of 'a' minus 1
|
||||
math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96")
|
||||
unset(_tmp)
|
||||
# Once anyone knows how OpenSSL would call the patch versions beyond 'z'
|
||||
# this should be updated to handle that, too. This has not happened yet
|
||||
# so it is simply ignored here for now.
|
||||
string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING)
|
||||
endif ()
|
||||
|
||||
set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES} )
|
||||
list(REMOVE_DUPLICATES OPENSSL_LIBRARIES)
|
||||
|
||||
foreach(_comp IN LISTS OpenSSL_FIND_COMPONENTS)
|
||||
if(_comp STREQUAL "Crypto")
|
||||
if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND
|
||||
(EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR
|
||||
EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR
|
||||
EXISTS "${LIB_EAY_LIBRARY_RELEASE}")
|
||||
)
|
||||
set(OpenSSL_${_comp}_FOUND TRUE)
|
||||
else()
|
||||
set(OpenSSL_${_comp}_FOUND FALSE)
|
||||
endif()
|
||||
elseif(_comp STREQUAL "SSL")
|
||||
if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND
|
||||
(EXISTS "${OPENSSL_SSL_LIBRARY}" OR
|
||||
EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR
|
||||
EXISTS "${SSL_EAY_LIBRARY_RELEASE}")
|
||||
)
|
||||
set(OpenSSL_${_comp}_FOUND TRUE)
|
||||
else()
|
||||
set(OpenSSL_${_comp}_FOUND FALSE)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "${_comp} is not a valid OpenSSL component")
|
||||
set(OpenSSL_${_comp}_FOUND FALSE)
|
||||
endif()
|
||||
endforeach()
|
||||
unset(_comp)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||
find_package_handle_standard_args(OpenSSL
|
||||
REQUIRED_VARS
|
||||
OPENSSL_CRYPTO_LIBRARY
|
||||
OPENSSL_INCLUDE_DIR
|
||||
VERSION_VAR
|
||||
OPENSSL_VERSION
|
||||
HANDLE_COMPONENTS
|
||||
FAIL_MESSAGE
|
||||
"Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
|
||||
)
|
||||
|
||||
mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
|
||||
|
||||
if(OPENSSL_FOUND)
|
||||
if(NOT TARGET OpenSSL::Crypto AND
|
||||
(EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR
|
||||
EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR
|
||||
EXISTS "${LIB_EAY_LIBRARY_RELEASE}")
|
||||
)
|
||||
add_library(OpenSSL::Crypto UNKNOWN IMPORTED)
|
||||
set_target_properties(OpenSSL::Crypto PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}")
|
||||
if(EXISTS "${OPENSSL_CRYPTO_LIBRARY}")
|
||||
set_target_properties(OpenSSL::Crypto PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
||||
IMPORTED_LOCATION "${OPENSSL_CRYPTO_LIBRARY}")
|
||||
endif()
|
||||
if(EXISTS "${LIB_EAY_LIBRARY_RELEASE}")
|
||||
set_property(TARGET OpenSSL::Crypto APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(OpenSSL::Crypto PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
|
||||
IMPORTED_LOCATION_RELEASE "${LIB_EAY_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
if(EXISTS "${LIB_EAY_LIBRARY_DEBUG}")
|
||||
set_property(TARGET OpenSSL::Crypto APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS DEBUG)
|
||||
set_target_properties(OpenSSL::Crypto PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
|
||||
IMPORTED_LOCATION_DEBUG "${LIB_EAY_LIBRARY_DEBUG}")
|
||||
endif()
|
||||
_OpenSSL_target_add_dependencies(OpenSSL::Crypto)
|
||||
endif()
|
||||
|
||||
if(NOT TARGET OpenSSL::SSL AND
|
||||
(EXISTS "${OPENSSL_SSL_LIBRARY}" OR
|
||||
EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR
|
||||
EXISTS "${SSL_EAY_LIBRARY_RELEASE}")
|
||||
)
|
||||
add_library(OpenSSL::SSL UNKNOWN IMPORTED)
|
||||
set_target_properties(OpenSSL::SSL PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}")
|
||||
if(EXISTS "${OPENSSL_SSL_LIBRARY}")
|
||||
set_target_properties(OpenSSL::SSL PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
||||
IMPORTED_LOCATION "${OPENSSL_SSL_LIBRARY}")
|
||||
endif()
|
||||
if(EXISTS "${SSL_EAY_LIBRARY_RELEASE}")
|
||||
set_property(TARGET OpenSSL::SSL APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(OpenSSL::SSL PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
|
||||
IMPORTED_LOCATION_RELEASE "${SSL_EAY_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
if(EXISTS "${SSL_EAY_LIBRARY_DEBUG}")
|
||||
set_property(TARGET OpenSSL::SSL APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS DEBUG)
|
||||
set_target_properties(OpenSSL::SSL PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
|
||||
IMPORTED_LOCATION_DEBUG "${SSL_EAY_LIBRARY_DEBUG}")
|
||||
endif()
|
||||
if(TARGET OpenSSL::Crypto)
|
||||
set_target_properties(OpenSSL::SSL PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES OpenSSL::Crypto)
|
||||
endif()
|
||||
_OpenSSL_target_add_dependencies(OpenSSL::SSL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Restore the original find library ordering
|
||||
if(OPENSSL_USE_STATIC_LIBS)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
endif()
|
268
CMakeModules/FindPackageHandleStandardArgs.cmake
vendored
268
CMakeModules/FindPackageHandleStandardArgs.cmake
vendored
@ -1,268 +0,0 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
|
||||
|
||||
# internal helper macro
|
||||
macro(_FPHSA_FAILURE_MESSAGE _msg)
|
||||
set (__msg "${_msg}")
|
||||
if (FPHSA_REASON_FAILURE_MESSAGE)
|
||||
string(APPEND __msg "\n Reason given by package: ${FPHSA_REASON_FAILURE_MESSAGE}\n")
|
||||
endif()
|
||||
if (${_NAME}_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "${__msg}")
|
||||
else ()
|
||||
if (NOT ${_NAME}_FIND_QUIETLY)
|
||||
message(STATUS "${__msg}")
|
||||
endif ()
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
|
||||
# internal helper macro to generate the failure message when used in CONFIG_MODE:
|
||||
macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
|
||||
# <PackageName>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
|
||||
if(${_NAME}_CONFIG)
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
|
||||
else()
|
||||
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
|
||||
# List them all in the error message:
|
||||
if(${_NAME}_CONSIDERED_CONFIGS)
|
||||
set(configsText "")
|
||||
list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
|
||||
math(EXPR configsCount "${configsCount} - 1")
|
||||
foreach(currentConfigIndex RANGE ${configsCount})
|
||||
list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
|
||||
list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
|
||||
string(APPEND configsText "\n ${filename} (version ${version})")
|
||||
endforeach()
|
||||
if (${_NAME}_NOT_FOUND_MESSAGE)
|
||||
if (FPHSA_REASON_FAILURE_MESSAGE)
|
||||
string(PREPEND FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}\n ")
|
||||
else()
|
||||
set(FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}")
|
||||
endif()
|
||||
else()
|
||||
string(APPEND configsText "\n")
|
||||
endif()
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:${configsText}")
|
||||
|
||||
else()
|
||||
# Simple case: No Config-file was found at all:
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
|
||||
|
||||
# Set up the arguments for `cmake_parse_arguments`.
|
||||
set(options CONFIG_MODE HANDLE_COMPONENTS)
|
||||
set(oneValueArgs FAIL_MESSAGE REASON_FAILURE_MESSAGE VERSION_VAR FOUND_VAR)
|
||||
set(multiValueArgs REQUIRED_VARS)
|
||||
|
||||
# Check whether we are in 'simple' or 'extended' mode:
|
||||
set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
|
||||
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
|
||||
|
||||
if(${INDEX} EQUAL -1)
|
||||
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
|
||||
set(FPHSA_REQUIRED_VARS ${ARGN})
|
||||
set(FPHSA_VERSION_VAR)
|
||||
else()
|
||||
cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
|
||||
|
||||
if(FPHSA_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
|
||||
endif()
|
||||
|
||||
if(NOT FPHSA_FAIL_MESSAGE)
|
||||
set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
|
||||
endif()
|
||||
|
||||
# In config-mode, we rely on the variable <PackageName>_CONFIG, which is set by find_package()
|
||||
# when it successfully found the config-file, including version checking:
|
||||
if(FPHSA_CONFIG_MODE)
|
||||
list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
|
||||
list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
|
||||
set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
|
||||
endif()
|
||||
|
||||
if(NOT FPHSA_REQUIRED_VARS)
|
||||
message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# now that we collected all arguments, process them
|
||||
|
||||
if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
|
||||
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
|
||||
endif()
|
||||
|
||||
list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
|
||||
|
||||
string(TOUPPER ${_NAME} _NAME_UPPER)
|
||||
string(TOLOWER ${_NAME} _NAME_LOWER)
|
||||
|
||||
if(FPHSA_FOUND_VAR)
|
||||
if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$")
|
||||
set(_FOUND_VAR ${FPHSA_FOUND_VAR})
|
||||
else()
|
||||
message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.")
|
||||
endif()
|
||||
else()
|
||||
set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
|
||||
endif()
|
||||
|
||||
# collect all variables which were not found, so they can be printed, so the
|
||||
# user knows better what went wrong (#6375)
|
||||
set(MISSING_VARS "")
|
||||
set(DETAILS "")
|
||||
# check if all passed variables are valid
|
||||
set(FPHSA_FOUND_${_NAME} TRUE)
|
||||
foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
|
||||
if(NOT ${_CURRENT_VAR})
|
||||
set(FPHSA_FOUND_${_NAME} FALSE)
|
||||
string(APPEND MISSING_VARS " ${_CURRENT_VAR}")
|
||||
else()
|
||||
string(APPEND DETAILS "[${${_CURRENT_VAR}}]")
|
||||
endif()
|
||||
endforeach()
|
||||
if(FPHSA_FOUND_${_NAME})
|
||||
set(${_NAME}_FOUND TRUE)
|
||||
set(${_NAME_UPPER}_FOUND TRUE)
|
||||
else()
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
set(${_NAME_UPPER}_FOUND FALSE)
|
||||
endif()
|
||||
|
||||
# component handling
|
||||
unset(FOUND_COMPONENTS_MSG)
|
||||
unset(MISSING_COMPONENTS_MSG)
|
||||
|
||||
if(FPHSA_HANDLE_COMPONENTS)
|
||||
foreach(comp ${${_NAME}_FIND_COMPONENTS})
|
||||
if(${_NAME}_${comp}_FOUND)
|
||||
|
||||
if(NOT DEFINED FOUND_COMPONENTS_MSG)
|
||||
set(FOUND_COMPONENTS_MSG "found components:")
|
||||
endif()
|
||||
string(APPEND FOUND_COMPONENTS_MSG " ${comp}")
|
||||
|
||||
else()
|
||||
|
||||
if(NOT DEFINED MISSING_COMPONENTS_MSG)
|
||||
set(MISSING_COMPONENTS_MSG "missing components:")
|
||||
endif()
|
||||
string(APPEND MISSING_COMPONENTS_MSG " ${comp}")
|
||||
|
||||
if(${_NAME}_FIND_REQUIRED_${comp})
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
string(APPEND MISSING_VARS " ${comp}")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endforeach()
|
||||
set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
|
||||
string(APPEND DETAILS "[c${COMPONENT_MSG}]")
|
||||
endif()
|
||||
|
||||
# version handling:
|
||||
set(VERSION_MSG "")
|
||||
set(VERSION_OK TRUE)
|
||||
|
||||
# check with DEFINED here as the requested or found version may be "0"
|
||||
if (DEFINED ${_NAME}_FIND_VERSION)
|
||||
if(DEFINED ${FPHSA_VERSION_VAR})
|
||||
set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}})
|
||||
|
||||
if(${_NAME}_FIND_VERSION_EXACT) # exact version required
|
||||
# count the dots in the version string
|
||||
string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}")
|
||||
# add one dot because there is one dot more than there are components
|
||||
string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS)
|
||||
if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT)
|
||||
# Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT
|
||||
# is at most 4 here. Therefore a simple lookup table is used.
|
||||
if (${_NAME}_FIND_VERSION_COUNT EQUAL 1)
|
||||
set(_VERSION_REGEX "[^.]*")
|
||||
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2)
|
||||
set(_VERSION_REGEX "[^.]*\\.[^.]*")
|
||||
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3)
|
||||
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*")
|
||||
else ()
|
||||
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
|
||||
endif ()
|
||||
string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}")
|
||||
unset(_VERSION_REGEX)
|
||||
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD)
|
||||
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
|
||||
set(VERSION_OK FALSE)
|
||||
else ()
|
||||
set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")")
|
||||
endif ()
|
||||
unset(_VERSION_HEAD)
|
||||
else ()
|
||||
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION)
|
||||
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
|
||||
set(VERSION_OK FALSE)
|
||||
else ()
|
||||
set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")")
|
||||
endif ()
|
||||
endif ()
|
||||
unset(_VERSION_DOTS)
|
||||
|
||||
else() # minimum version specified:
|
||||
if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION)
|
||||
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
|
||||
set(VERSION_OK FALSE)
|
||||
else ()
|
||||
set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
# if the package was not found, but a version was given, add that to the output:
|
||||
if(${_NAME}_FIND_VERSION_EXACT)
|
||||
set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
|
||||
else()
|
||||
set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
else ()
|
||||
# Check with DEFINED as the found version may be 0.
|
||||
if(DEFINED ${FPHSA_VERSION_VAR})
|
||||
set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if(VERSION_OK)
|
||||
string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]")
|
||||
else()
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
endif()
|
||||
|
||||
|
||||
# print the result:
|
||||
if (${_NAME}_FOUND)
|
||||
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
|
||||
else ()
|
||||
|
||||
if(FPHSA_CONFIG_MODE)
|
||||
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
|
||||
else()
|
||||
if(NOT VERSION_OK)
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
|
||||
else()
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif ()
|
||||
|
||||
set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
|
||||
set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
|
||||
endfunction()
|
48
CMakeModules/FindPackageMessage.cmake
vendored
48
CMakeModules/FindPackageMessage.cmake
vendored
@ -1,48 +0,0 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindPackageMessage
|
||||
------------------
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package_message(<name> "message for user" "find result details")
|
||||
|
||||
This function is intended to be used in FindXXX.cmake modules files.
|
||||
It will print a message once for each unique find result. This is
|
||||
useful for telling the user where a package was found. The first
|
||||
argument specifies the name (XXX) of the package. The second argument
|
||||
specifies the message to display. The third argument lists details
|
||||
about the find result so that if they change the message will be
|
||||
displayed again. The macro also obeys the QUIET argument to the
|
||||
find_package command.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
if(X11_FOUND)
|
||||
find_package_message(X11 "Found X11: ${X11_X11_LIB}"
|
||||
"[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
|
||||
else()
|
||||
...
|
||||
endif()
|
||||
#]=======================================================================]
|
||||
|
||||
function(find_package_message pkg msg details)
|
||||
# Avoid printing a message repeatedly for the same find result.
|
||||
if(NOT ${pkg}_FIND_QUIETLY)
|
||||
string(REPLACE "\n" "" details "${details}")
|
||||
set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
|
||||
if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
|
||||
# The message has not yet been printed.
|
||||
message(STATUS "${msg}")
|
||||
|
||||
# Save the find details in the cache to avoid printing the same
|
||||
# message again.
|
||||
set("${DETAILS_VAR}" "${details}"
|
||||
CACHE INTERNAL "Details about finding ${pkg}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
15
README.md
15
README.md
@ -8,7 +8,7 @@ sist2 (Simple incremental search tool)
|
||||
|
||||
*Warning: sist2 is in early development*
|
||||
|
||||

|
||||

|
||||
|
||||
## Features
|
||||
|
||||
@ -49,7 +49,7 @@ sist2 (Simple incremental search tool)
|
||||
1. *(or)* Download a [development snapshot](https://files.simon987.net/artifacts/Sist2/Build/) *(Not recommended!)*
|
||||
1. *(or)* `docker pull simon987/sist2:latest`
|
||||
|
||||
1. See [Usage guide](USAGE.md)
|
||||
1. See [Usage guide](DOCS/USAGE.md)
|
||||
|
||||
|
||||
\* *Windows users*: **sist2** runs under [WSL](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux)
|
||||
@ -57,7 +57,7 @@ sist2 (Simple incremental search tool)
|
||||
|
||||
## Example usage
|
||||
|
||||
See [Usage guide](USAGE.md) for more details
|
||||
See [Usage guide](DOCS/USAGE.md) for more details
|
||||
|
||||
1. Scan a directory: `sist2 scan ~/Documents -o ./docs_idx`
|
||||
1. Push index to Elasticsearch: `sist2 index ./docs_idx`
|
||||
@ -117,13 +117,8 @@ binaries.
|
||||
|
||||
1. Install compile-time dependencies
|
||||
|
||||
*(Debian)*
|
||||
```bash
|
||||
apt install git cmake pkg-config libglib2.0-dev \
|
||||
libssl-dev uuid-dev python3 libmagic-dev libfreetype6-dev \
|
||||
libcurl4-openssl-dev libbz2-dev yasm libharfbuzz-dev ragel \
|
||||
libarchive-dev libtiff5 libpng16-16 libpango1.0-dev \
|
||||
libxml2-dev libopenjp2-7-dev libleptonica-dev
|
||||
```bash
|
||||
vcpkg install lmdb
|
||||
```
|
||||
|
||||
2. Build
|
||||
|
275
USAGE.md
275
USAGE.md
@ -1,275 +0,0 @@
|
||||
# Usage
|
||||
|
||||
*More examples (specifically with docker/compose) are in progress*
|
||||
|
||||
* [scan](#scan)
|
||||
* [options](#scan-options)
|
||||
* [examples](#scan-examples)
|
||||
* [index format](#index-format)
|
||||
* [index](#index)
|
||||
* [options](#index-options)
|
||||
* [examples](#index-examples)
|
||||
* [web](#web)
|
||||
* [options](#web-options)
|
||||
* [examples](#web-examples)
|
||||
* [rewrite_url](#rewrite_url)
|
||||
* [link to specific indices](#link-to-specific-indices)
|
||||
|
||||
```
|
||||
Usage: sist2 scan [OPTION]... PATH
|
||||
or: sist2 index [OPTION]... INDEX
|
||||
or: sist2 web [OPTION]... INDEX...
|
||||
Lightning-fast file system indexer and search tool.
|
||||
|
||||
-h, --help show this help message and exit
|
||||
-v, --version Show version and exit
|
||||
--verbose Turn on logging
|
||||
--very-verbose Turn on debug messages
|
||||
|
||||
Scan options
|
||||
-t, --threads=<int> Number of threads. DEFAULT=1
|
||||
-q, --quality=<flt> Thumbnail quality, on a scale of 1.0 to 31.0, 1.0 being the best. DEFAULT=5
|
||||
--size=<int> Thumbnail size, in pixels. Use negative value to disable. DEFAULT=500
|
||||
--content-size=<int> Number of bytes to be extracted from text documents. Use negative value to disable. DEFAULT=32768
|
||||
--incremental=<str> Reuse an existing index and only scan modified files.
|
||||
-o, --output=<str> Output directory. DEFAULT=index.sist2/
|
||||
--rewrite-url=<str> Serve files from this url instead of from disk.
|
||||
--name=<str> Index display name. DEFAULT: (name of the directory)
|
||||
--depth=<int> Scan up to DEPTH subdirectories deep. Use 0 to only scan files in PATH. DEFAULT: -1
|
||||
--archive=<str> Archive file mode (skip|list|shallow|recurse). skip: Don't parse, list: only get file names as text, shallow: Don't parse archives inside archives. DEFAULT: recurse
|
||||
--ocr=<str> Tesseract language (use tesseract --list-langs to see which are installed on your machine)
|
||||
-e, --exclude=<str> Files that match this regex will not be scanned
|
||||
--fast Only index file names & mime type
|
||||
|
||||
Index options
|
||||
--es-url=<str> Elasticsearch url with port. DEFAULT=http://localhost:9200
|
||||
-p, --print Just print JSON documents to stdout.
|
||||
--script-file=<str> Path to user script.
|
||||
--batch-size=<int> Index batch size. DEFAULT: 100
|
||||
-f, --force-reset Reset Elasticsearch mappings and settings. (You must use this option the first time you use the index command)
|
||||
|
||||
Web options
|
||||
--es-url=<str> Elasticsearch url. DEFAULT=http://localhost:9200
|
||||
--bind=<str> Listen on this address. DEFAULT=localhost
|
||||
--port=<str> Listen on this port. DEFAULT=4090
|
||||
--auth=<str> Basic auth in user:password format
|
||||
Made by simon987 <me@simon987.net>. Released under GPL-3.0
|
||||
|
||||
```
|
||||
|
||||
## Scan
|
||||
|
||||
### Scan options
|
||||
|
||||
* `-t, --threads`
|
||||
Number of threads for file parsing. **Do not set a number higher than `$(nproc)`!**.
|
||||
* `-q, --quality`
|
||||
Thumbnail quality, on a scale of 1.0 to 31.0, 1.0 being the best. *Does not affect PDF thumbnails quality*
|
||||
* `--size`
|
||||
Thumbnail size in pixels.
|
||||
* `--content-size`
|
||||
Number of bytes of text to be extracted from the content of files (plain text and PDFs).
|
||||
Repeated whitespace and special characters do not count toward this limit.
|
||||
* `--incremental`
|
||||
Specify an existing index. Information about files in this index that were not modified (based on *mtime* attribute)
|
||||
will be copied to the new index and will not be parsed again.
|
||||
* `-o, --output` Output directory.
|
||||
* `--rewrite-url` Set the `rewrite_url` option for the web module (See [rewrite_url](#rewrite_url))
|
||||
* `--name` Set the `name` option for the web module
|
||||
* `--depth` Maximum scan dept. Set to 0 only scan files directly in the root directory, set to -1 for infinite depth
|
||||
* `--archive` Archive file mode.
|
||||
* skip: Don't parse
|
||||
* list: Only get file names as text
|
||||
* shallow: Don't parse archives inside archives.
|
||||
* recurse: Scan archives recursively (default)
|
||||
* `--ocr` See [OCR](README.md#OCR)
|
||||
* `-e, --exclude` Regex pattern to exclude files. A file is excluded if the pattern matches any
|
||||
part of the full absolute path.
|
||||
|
||||
Examples:
|
||||
* `-e ".*\.ttf"`: Ignore ttf files
|
||||
* `-e ".*\.(ttf|rar)"`: Ignore ttf and rar files
|
||||
* `-e "^/mnt/backups/"`: Ignore all files in the `/mnt/backups/` directory
|
||||
* `-e "^/mnt/Data[12]/"`: Ignore all files in the `/mnt/Data1/` and `/mnt/Data2/` directory
|
||||
* `-e "(^/usr/)|(^/var/)|(^/media/DRIVE-A/tmp/)|(^/media/DRIVE-B/Trash/)"` Exclude the
|
||||
`/usr`, `/var`, `/media/DRIVE-A/tmp`, `/media/DRIVE-B/Trash` directories
|
||||
* `--fast` Only index file names and mime type
|
||||
|
||||
### Scan examples
|
||||
|
||||
Simple scan
|
||||
```bash
|
||||
sist2 scan ~/Documents
|
||||
|
||||
sist2 scan \
|
||||
--threads 4 --content-size 16000000 --quality 1.0 --archive shallow \
|
||||
--name "My Documents" --rewrite-url "http://nas.domain.local/My Documents/" \
|
||||
~/Documents -o ./documents.idx/
|
||||
```
|
||||
|
||||
Incremental scan
|
||||
```
|
||||
sist2 scan --incremental ./orig_idx/ -o ./updated_idx/ ~/Documents
|
||||
```
|
||||
|
||||
### Index format
|
||||
|
||||
A typical `binary` type index structure looks like this:
|
||||
```
|
||||
documents.idx/
|
||||
├── descriptor.json
|
||||
├── _index_139965416830720
|
||||
├── _index_139965425223424
|
||||
├── _index_139965433616128
|
||||
├── _index_139965442008832
|
||||
└── thumbs
|
||||
├── data.mdb
|
||||
└── lock.mdb
|
||||
```
|
||||
|
||||
The `_index_*` files contain the raw binary index data and are not meant to be
|
||||
read by other applications. The format is generally compatible across different
|
||||
sist2 versions.
|
||||
|
||||
The `thumbs/` folder is a [LMDB](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database)
|
||||
database containing the thumbnails.
|
||||
|
||||
The `descriptor.json` file contains general information about the index. The
|
||||
following fields are safe to modify manually: `root`, `name`, [rewrite_url](#rewrite_url) and `timestamp`.
|
||||
|
||||
|
||||
*Advanced usage*
|
||||
|
||||
Instead of using the `scan` module, you can also import an index generated
|
||||
by a third party application. The 'external' index must have the following format:
|
||||
|
||||
```
|
||||
my_index/
|
||||
├── descriptor.json
|
||||
├── _index_0
|
||||
└── thumbs
|
||||
├── data.mdb
|
||||
└── lock.mdb
|
||||
```
|
||||
|
||||
*descriptor.json*:
|
||||
```json
|
||||
{
|
||||
"uuid": "<valid UUID4>",
|
||||
"version": "_external_v1",
|
||||
"root": "(optional)",
|
||||
"name": "<name>",
|
||||
"rewrite_url": "(optional)",
|
||||
"type": "json",
|
||||
"timestamp": 1578971024
|
||||
}
|
||||
```
|
||||
|
||||
*_index_0*: NDJSON format (One json object per line)
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "unique uuid for the file",
|
||||
"index": "index uuid4 (same one as descriptor.json!)",
|
||||
"mime": "application/x-cbz",
|
||||
"size": 14341204,
|
||||
"mtime": 1578882996,
|
||||
"extension": "cbz",
|
||||
"name": "my_book",
|
||||
"path": "path/to/books",
|
||||
"content": "text contents of the book",
|
||||
"title": "Title of the book",
|
||||
"tag": ["genre.fiction", "author.someguy", "etc..."],
|
||||
"_keyword": [
|
||||
{"k": "ISBN", "v": "ABCD34789231"}
|
||||
],
|
||||
"_text": [
|
||||
{"k": "other", "v": "This will be indexed as text"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You can find the full list of supported fields [here](src/io/serialize.c#L90)
|
||||
|
||||
The `_keyword.*` items will be indexed and searchable as **keyword** fields (only full matches allowed).
|
||||
The `_text.*` items will be indexed and searchable as **text** fields (fuzzy searching allowed)
|
||||
|
||||
|
||||
*thumbs/*:
|
||||
|
||||
LMDB key-value store. Keys are **binary** 128-bit UUID4s (`_id` field)
|
||||
and values are raw image bytes.
|
||||
|
||||
Importing an external `binary` type index is technically possible but
|
||||
it is currently unsupported and has no guaranties of back/forward compatibility.
|
||||
|
||||
|
||||
## Index
|
||||
### Index options
|
||||
* `--es-url`
|
||||
Elasticsearch url and port. If you are using docker, make sure that both containers are on the
|
||||
same network.
|
||||
* `-p, --print`
|
||||
Print index in JSON format to stdout.
|
||||
* `--script-file`
|
||||
Path to user script. See [Scripting](scripting/README.md).
|
||||
* `--batch-size=<int>`
|
||||
Index batch size. Indexing is generally faster with larger batches, but payloads that
|
||||
are too large will fail and additional overhead for retrying with smaller sizes may slow
|
||||
down the process.
|
||||
* `-f, --force-reset`
|
||||
Reset Elasticsearch mappings and settings.
|
||||
**(You must use this option the first time you use the index command)**.
|
||||
|
||||
### Index examples
|
||||
|
||||
**Push to elasticsearch**
|
||||
```bash
|
||||
sist2 index --force-reset --batch-size 1000 --es-url http://localhost:9200 ./my_index/
|
||||
sist2 index ./my_index/
|
||||
```
|
||||
|
||||
**Save index in JSON format**
|
||||
```bash
|
||||
sist2 index --print ./my_index/ > my_index.ndjson
|
||||
```
|
||||
|
||||
**Inspect contents of an index**
|
||||
```bash
|
||||
sist2 index --print ./my_index/ | jq | less
|
||||
```
|
||||
|
||||
## Web
|
||||
|
||||
### Web options
|
||||
* `--es-url=<str>` Elasticsearch url.
|
||||
* `--bind=<str>` Listen on this address.
|
||||
* `--port=<str>` Listen on this port.
|
||||
* `--auth=<str>` Basic auth in user:password format
|
||||
|
||||
### Web examples
|
||||
|
||||
**Single index**
|
||||
```bash
|
||||
sist2 web --auth admin:hunter2 --bind 0.0.0.0 --port 8888 my_index
|
||||
```
|
||||
|
||||
**Multiple indices**
|
||||
```bash
|
||||
# Indices will be displayed in this order in the web interface
|
||||
sist2 web index1 index2 index3 index4
|
||||
```
|
||||
|
||||
### rewrite_url
|
||||
|
||||
When the `rewrite_url` field is not empty, the web module ignores the `root`
|
||||
field and will return a HTTP redirect to `<rewrite_url><path>/<name><extension>`
|
||||
instead of serving the file from disk.
|
||||
Both the `root` and `rewrite_url` fields are safe to manually modify from the
|
||||
`descriptor.json` file.
|
||||
|
||||
### Link to specific indices
|
||||
|
||||
To link to specific indices, you can add a list of comma-separated index name to
|
||||
the URL: `?i=<name>,<name>`. By default, indices with `"(nsfw)"` in their name are
|
||||
not displayed.
|
1
argparse
1
argparse
@ -1 +0,0 @@
|
||||
Subproject commit 4ed6099cb33245b06343518b9f3c45ac56e8283c
|
1
cJSON
1
cJSON
@ -1 +0,0 @@
|
||||
Subproject commit 3ece4c893c123aa3d77f90d580cf6b0a4b3a2ad5
|
@ -1 +0,0 @@
|
||||
Subproject commit 288acf97a15d558f96c24c89f578b724d6e06b0c
|
@ -1 +0,0 @@
|
||||
Subproject commit 7239254b1da28c1a0d8dff8916edefc98b88775e
|
@ -1 +0,0 @@
|
||||
Subproject commit b07714d6b53bb20a2796f5efa607dc32aac587f1
|
@ -1 +0,0 @@
|
||||
Subproject commit a9d04f7b0f72711677241e1c6805612ef56f157b
|
@ -1 +0,0 @@
|
||||
Subproject commit 1249b5cd02c3b6fb9b917d16c76bc76c862932b6
|
@ -1 +0,0 @@
|
||||
Subproject commit 301f7a14295a3bdfaf406dbb5004d0784dc137ea
|
@ -1 +0,0 @@
|
||||
Subproject commit ed881da0db424dd77a195a90511130aca1122dc3
|
@ -1 +0,0 @@
|
||||
Subproject commit abada6f26c8d3e5190bea932cb05e3474558e18d
|
@ -1 +0,0 @@
|
||||
Subproject commit 2b3b230b79ecae119b7eb847f2f9545a46bef13c
|
@ -1 +0,0 @@
|
||||
Subproject commit 563ecfb55ca77c0fc5ea19e4885e00f55ec82ca9
|
@ -1 +0,0 @@
|
||||
Subproject commit d576c7cbd57393ed26d1e02cf60530e690b4f5c2
|
1
lmdb
1
lmdb
@ -1 +0,0 @@
|
||||
Subproject commit 5c012bbe033f9bbb273078b07dded59f080d348d
|
429
mime.csv
429
mime.csv
@ -1,429 +0,0 @@
|
||||
application/arj, arj
|
||||
application/base64, mme
|
||||
application/binhex, hqx
|
||||
application/book, boo|book
|
||||
application/CDFV2-corrupt,
|
||||
application/CDFV2, sdv
|
||||
application/clariscad, ccad
|
||||
application/commonground, dp
|
||||
application/csv,
|
||||
application/dicom, dcm
|
||||
application/drafting, drw
|
||||
application/epub+zip, epub
|
||||
application/freeloader, frl
|
||||
application/futuresplash, spl
|
||||
application/groupwise, vew
|
||||
application/gzip, gz
|
||||
application/hta, hta
|
||||
application/i-deas, unv
|
||||
application/iges, iges|igs
|
||||
application/inf, inf
|
||||
application/java-archive, jar
|
||||
application/java, class
|
||||
application/javascript,
|
||||
application/json, json
|
||||
application/marc, mrc
|
||||
application/mbedlet, mbd
|
||||
application/mime, aps
|
||||
application/mspowerpoint, ppz
|
||||
application/msword, doc|dot|w6w|wiz|word
|
||||
application/netmc, mcp
|
||||
application/octet-stream, bin|dump|gpg
|
||||
application/oda, oda
|
||||
application/ogg, ogv
|
||||
application/pdf, pdf
|
||||
application/pgp-keys,
|
||||
application/pgp-signature, pgp
|
||||
application/pkcs7-signature, p7s
|
||||
application/pkix-cert, cer|crt
|
||||
application/postscript, ai|ps
|
||||
application/pro_eng, part|prt
|
||||
application/ringing-tones, rng
|
||||
application/smil, smi|smil
|
||||
application/solids, sol
|
||||
application/sounder, sdr
|
||||
application/step, step|stp
|
||||
application/streamingmedia, ssm
|
||||
application/vda, vda
|
||||
application/vnd.fdf, fdf
|
||||
application/vnd.font-fontforge-sfd, sfd
|
||||
application/vnd.hp-hpgl, hgl|hpg|hpgl
|
||||
application/vnd.iccprofile, icm
|
||||
application/vnd.iccprofile, icm
|
||||
application/vnd.lotus-1-2-3,
|
||||
application/vnd.ms-cab-compressed, cab
|
||||
application/vnd.ms-excel, xlb|xlc|xll|xlm|xls|xlw
|
||||
application/vnd.ms-fontobject, eot
|
||||
application/vnd.ms-opentype, otf
|
||||
application/vnd.ms-pki.certstore, sst
|
||||
application/vnd.ms-pki.pko, pko
|
||||
application/vnd.ms-pki.seccat, cat
|
||||
application/vnd.ms-powerpoint, pot|ppa|pps|ppt|pwz
|
||||
application/vnd.ms-project, mpp
|
||||
application/vnd.oasis.opendocument.base, odb
|
||||
application/vnd.oasis.opendocument.formula, odf
|
||||
application/vnd.oasis.opendocument.graphics, odg
|
||||
application/vnd.oasis.opendocument.presentation, odp
|
||||
application/vnd.oasis.opendocument.spreadsheet, ods
|
||||
application/vnd.oasis.opendocument.text, odt
|
||||
application/vnd.openxmlformats-officedocument.presentationml.presentation, pptx
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, xlsx
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document, docx
|
||||
application/vnd.symbian.install,
|
||||
application/vnd.tcpdump.pcap, pcap
|
||||
application/vnd.wap.wmlc, wmlc
|
||||
application/vnd.wap.wmlscriptc, wmlsc
|
||||
application/vnd.xara, web
|
||||
application/vocaltec-media-desc, vmd
|
||||
application/vocaltec-media-file, vmf
|
||||
application/warc, warc
|
||||
application/winhelp, hlp
|
||||
application/wordperfect6.0, w60
|
||||
application/wordperfect6.1, w61
|
||||
application/wordperfect, wp|wp5|wp6|wpd
|
||||
application/x-123, wk1
|
||||
application/x-7z-compressed, 7z
|
||||
application/x-aim, aim
|
||||
application/x-apple-diskimage,
|
||||
application/x-arc,
|
||||
application/x-archive, a
|
||||
application/x-atari-7800-rom, a78
|
||||
application/x-authorware-bin, aab
|
||||
application/x-authorware-map, aam
|
||||
application/x-authorware-seg, aas
|
||||
application/x-avira-qua,
|
||||
application/x-bcpio, bcpio
|
||||
application/x-bittorrent, torrent
|
||||
application/x-bsh, bsh
|
||||
application/x-bytecode.python, pyc
|
||||
application/x-bzip2, boz|bz2
|
||||
application/x-bzip, bz
|
||||
application/x-cbr, cbr
|
||||
application/x-cbz, cbz
|
||||
application/x-cdlink, vcd
|
||||
application/x-chat, cha|chat
|
||||
application/x-chrome-extension,
|
||||
application/x-cocoa, cco
|
||||
application/x-conference, nsc
|
||||
application/x-coredump,
|
||||
application/x-cpio, cpio
|
||||
application/x-dbf, dbf
|
||||
application/x-dbt,
|
||||
application/x-debian-package, deb
|
||||
application/x-deepv, deepv
|
||||
application/x-director, dcr|dir|dxr
|
||||
application/x-dmp, dmp
|
||||
application/x-dosdriver,
|
||||
application/x-dosexec, dll
|
||||
application/x-dvi, dvi
|
||||
application/x-elc, elc
|
||||
application/x-empty,
|
||||
application/x-envoy, env|evy
|
||||
application/x-esrehber, es
|
||||
application/x-excel, xla|xld|xlk|xlt|xlv
|
||||
application/x-executable, exe
|
||||
application/x-font-gdos,
|
||||
application/x-font-pf2, pf2
|
||||
application/x-font-pfm, pfm
|
||||
application/x-font-sfn,
|
||||
application/x-font-ttf, ttf|ttc
|
||||
application/x-fptapplication/x-dbt,
|
||||
application/x-freelance, pre
|
||||
application/x-gamecube-rom,
|
||||
application/x-gdbm,
|
||||
application/x-gettext-translation,
|
||||
application/x-git,
|
||||
application/x-gsp, gsp
|
||||
application/x-gss, gss
|
||||
application/x-gtar, gtar
|
||||
application/x-gzip, gzip
|
||||
application/x-hdf, hdf
|
||||
application/x-helpfile, help
|
||||
application/x-httpd-imap, imap
|
||||
application/x-ima, ima
|
||||
application/x-innosetup,
|
||||
application/x-internett-signup, ins
|
||||
application/x-inventor, iv
|
||||
application/x-ip2, ip
|
||||
application/x-java-applet,
|
||||
application/x-java-commerce, jcm
|
||||
application/x-java-image,
|
||||
application/x-java-jmod, jmod
|
||||
application/x-java-keystore,
|
||||
application/x-kdelnk,
|
||||
application/x-koan, skd|skm|skp|skt
|
||||
application/x-latex, latex|ltx
|
||||
application/x-livescreen, ivy
|
||||
application/x-lotus, wq1
|
||||
application/x-lz4+json, jsonlz4
|
||||
application/x-lz4, lz4
|
||||
application/x-lz4, lz4
|
||||
application/x-lzh-compressed,
|
||||
application/x-lzh, lzh
|
||||
application/x-lzip, lz
|
||||
application/x-lzma, lzma
|
||||
application/x-lzop, lzo
|
||||
application/x-lzx, lzx
|
||||
application/x-mach-binary, jnilib|dylib
|
||||
application/x-mach-executable,
|
||||
application/x-magic-cap-package-1.0, mc$
|
||||
application/x-mathcad, mcd
|
||||
application/x-maxis-dbpf,
|
||||
application/x-meme, mm
|
||||
application/x-midi, midi
|
||||
application/x-mif, mif
|
||||
application/x-mix-transfer, nix
|
||||
application/xml, opf
|
||||
application/x-mobipocket-ebook, mobi
|
||||
application/x-msaccess, accdb
|
||||
application/x-ms-compress-szdd, fon
|
||||
application/x-ms-pdb, pdb
|
||||
application/x-ms-reader, lit
|
||||
application/x-n64-rom, z64
|
||||
application/x-navi-animation, ani
|
||||
application/x-navidoc, nvd
|
||||
application/x-navimap, map
|
||||
application/x-navistyle, stl
|
||||
application/x-nes-rom, nes
|
||||
application/x-netcdf, cdf|nc
|
||||
application/x-newton-compatible-pkg, pkg
|
||||
application/x-nintendo-ds-rom,
|
||||
application/x-object, o
|
||||
application/x-omcdatamaker, omcd
|
||||
application/x-omc, omc
|
||||
application/x-omcregerator, omcr
|
||||
application/x-pagemaker, pm4|pm5
|
||||
application/x-pcl, pcl
|
||||
application/x-pgp-keyring,
|
||||
application/x-pixclscript, plx
|
||||
application/x-pkcs7-certreqresp, p7r
|
||||
application/x-pkcs7-signature, p7a
|
||||
application/x-project, mpc|mpt|mpv|mpx
|
||||
application/x-qpro, wb1
|
||||
application/x-rar, rar
|
||||
application/x-rpm, rpm
|
||||
application/x-sdp, sdp
|
||||
application/x-sea, sea
|
||||
application/x-seelogo, sl
|
||||
application/x-setupscript,
|
||||
application/x-sharedlib, so
|
||||
application/x-shar, shar
|
||||
application/x-shockwave-flash, swf
|
||||
application/x-snappy-framed,
|
||||
application/x-sprite, spr|sprite
|
||||
application/x-sqlite3,
|
||||
application/x-stargallery-thm,
|
||||
application/x-stuffit, sit
|
||||
application/x-sv4cpio, sv4cpio
|
||||
application/x-sv4crc, sv4crc
|
||||
application/x-tar, tar
|
||||
application/x-tbook, sbk|tbk
|
||||
application/x-terminfo,
|
||||
application/x-terminfo2,
|
||||
application/x-texinfo, texi|texinfo
|
||||
application/x-tex-tfm, tfm
|
||||
application/x-ustar, ustar
|
||||
application/x-visio, vsd|vst|vsw
|
||||
application/x-vnd.audioexplosion.mzz, mzz
|
||||
application/x-vnd.ls-xpix, xpix
|
||||
application/x-vrml, vrml
|
||||
application/x-wais-source, src|wsrc
|
||||
application/x-wine-extension-ini,
|
||||
application/x-wintalk, wtk
|
||||
application/x-world, svr
|
||||
application/x-wri, wri
|
||||
application/x-x509-ca-cert, der
|
||||
application/x-xz, xz
|
||||
application/x-zip,
|
||||
application/x-zstd, zst
|
||||
application/zip, zip
|
||||
application/zlib, z
|
||||
!audio/basic, au
|
||||
audio/it, it
|
||||
audio/make, funk|my|pfunk
|
||||
audio/midi, kar
|
||||
audio/mid, rmi
|
||||
audio/mp4, m4b
|
||||
audio/mpeg, m2a|mpa
|
||||
audio/ogg, ogg
|
||||
audio/s3m, s3m
|
||||
audio/tsp-audio, tsi
|
||||
audio/tsplayer, tsp
|
||||
audio/vnd.qcelp, qcp
|
||||
audio/voxware, vox
|
||||
audio/x-aiff, aiff|aif
|
||||
audio/x-flac, flac
|
||||
audio/x-gsm, gsd|gsm
|
||||
audio/x-hx-aac-adts,
|
||||
audio/x-jam, jam
|
||||
audio/x-liveaudio, lam
|
||||
audio/x-m4a, m4a
|
||||
audio/x-midi, mid
|
||||
audio/x-mod,
|
||||
audio/x-mp4a-latm,
|
||||
audio/x-mpeg-3, mp3
|
||||
audio/x-mpequrl,
|
||||
audio/xm, xm
|
||||
audio/x-nspaudio, lma
|
||||
audio/x-pn-realaudio, ram|rm|rmm|rmp
|
||||
audio/x-psid, sid
|
||||
audio/x-realaudio, ra
|
||||
audio/x-s3m,
|
||||
audio/x-twinvq-plugin, vqe|vql
|
||||
audio/x-twinvq, vqf
|
||||
audio/x-voc, voc
|
||||
audio/x-wav, wav
|
||||
!audio/x-xbox360-executable, xex
|
||||
!audio/x-xbox-executable, xbe
|
||||
font/otf,
|
||||
font/sfnt,
|
||||
font/woff2, woff2
|
||||
font/woff, woff
|
||||
image/bmp,
|
||||
image/cmu-raster, rast
|
||||
image/fif, fif
|
||||
image/florian, flo|turbot
|
||||
image/g3fax, g3
|
||||
image/gif, gif
|
||||
image/heic, heic
|
||||
image/ief, ief|iefs
|
||||
image/jpeg, jfif|jfif-tbnl|jpe|jpeg|jpg
|
||||
image/jutvision, jut
|
||||
image/naplps, nap|naplps
|
||||
image/pict, pic|pict
|
||||
image/png, png|x-png
|
||||
!image/svg, svg
|
||||
!image/svg+xml,
|
||||
image/tiff,
|
||||
!image/vnd.adobe.photoshop, psd
|
||||
!image/vnd.djvu, djvu
|
||||
image/vnd.fpx, fpx
|
||||
image/vnd.microsoft.icon,
|
||||
image/vnd.rn-realflash, rf
|
||||
image/vnd.rn-realpix, rp
|
||||
image/vnd.wap.wbmp, wbmp
|
||||
image/vnd.xiff, xif
|
||||
image/webp, webp
|
||||
image/wmf,
|
||||
image/x-3ds, 3ds
|
||||
image/x-award-bioslogo,
|
||||
image/x-cmu-raster, ras
|
||||
image/x-cur, tga
|
||||
image/x-dwg, dwg|dxf|svf
|
||||
image/x-eps,
|
||||
image/x-exr, exr
|
||||
image/x-gem,
|
||||
image/x-icns,
|
||||
!image/x-icon, ico
|
||||
image/x-jg, art
|
||||
image/x-jps, jps
|
||||
image/x-ms-bmp, bm|bmp
|
||||
image/x-niff, nif|niff
|
||||
image/x-pcx, pcx
|
||||
image/x-pict, pct
|
||||
image/x-portable-bitmap, pbm
|
||||
image/x-portable-graymap, pgm
|
||||
image/x-portable-pixmap, ppm
|
||||
image/x-quicktime, qif|qti|qtif
|
||||
image/x-rgb, rgb
|
||||
image/x-tga,
|
||||
image/x-tiff, tif|tiff
|
||||
image/x-win-bitmap,
|
||||
!image/x-xcf, xcf
|
||||
!image/x-xpixmap, xpm
|
||||
image/x-xwindowdump, xwd
|
||||
message/news,
|
||||
message/rfc822, mht|mhtml|mime
|
||||
model/vnd.dwf, dwf
|
||||
model/vnd.gdl, gdl
|
||||
model/vnd.gs.gdl, gdsl
|
||||
model/vrml, wrz
|
||||
model/x-pov, pov
|
||||
text/asp, asp
|
||||
text/css, css
|
||||
text/html, acgi|htm|html|htmls|htx|shtml
|
||||
text/javascript, js
|
||||
text/mcf, mcf
|
||||
text/pascal, pas
|
||||
text/PGP,
|
||||
text/plain, com|cmd|conf|def|g|idc|list|lst|mar|sdml|text|txt|md|groovy|license|properties|desktop|ini|rst|cmake|ipynb|readme|less|lo|go|yml|d|cs|hpp|srt|nfo|sfv|m3u|csv|eml
|
||||
text/richtext, rt|rtf|rtx
|
||||
text/rtf,
|
||||
text/scriplet, wsc
|
||||
text/tab-separated-values, tsv
|
||||
text/troff, man|me|ms|roff|t|tr
|
||||
text/uri-list, uji|unis|uri|uris
|
||||
text/vnd.abc, abc
|
||||
text/vnd.fmi.flexstor, flx
|
||||
text/vnd.wap.wmlscript, wmls
|
||||
text/vnd.wap.wml, wml
|
||||
text/webviewhtml, htt
|
||||
text/x-Algol68,
|
||||
text/x-asm, asm|s
|
||||
text/x-audiosoft-intra, aip
|
||||
text/x-awk, awk
|
||||
text/x-bcpl,
|
||||
text/x-c, c|cc|h
|
||||
text/x-c++, cpp|cxx|c++
|
||||
text/x-component, htc
|
||||
text/x-diff,
|
||||
text/x-fortran, f|f77|f90|for
|
||||
text/x-java, jav|java
|
||||
text/x-la-asf, lsx
|
||||
text/x-lisp, el
|
||||
text/x-m4, m4|ac
|
||||
text/x-makefile, am|mak
|
||||
text/xml, xml|pom|iml|plist
|
||||
text/x-m, m
|
||||
text/x-msdos-batch, bat
|
||||
text/x-ms-regedit, reg
|
||||
text/x-objective-c,
|
||||
text/x-pascal, p
|
||||
text/x-perl, pl
|
||||
text/x-php, php
|
||||
text/x-po, po
|
||||
text/x-python, py
|
||||
text/x-ruby, rb
|
||||
text/x-sass, sass
|
||||
text/x-scss, scss
|
||||
text/x-server-parsed-html, ssi
|
||||
text/x-setext, etx
|
||||
text/x-sgml, sgm|sgml
|
||||
text/x-shellscript, sh
|
||||
text/x-speech, talk
|
||||
text/x-tcl,
|
||||
text/x-tex, tex
|
||||
text/x-uil, uil
|
||||
text/x-uuencode, uue
|
||||
text/x-vcalendar, vcs
|
||||
text/x-vcard, vcf
|
||||
video/animaflex, afl
|
||||
video/avi, avi
|
||||
video/avs-video, avs
|
||||
video/MP2T,
|
||||
video/mp4, mp4
|
||||
video/mpeg, m1v|m2v|mpe|mpeg|mpg
|
||||
video/quicktime, moov|mov|qt
|
||||
video/vdo, vdo
|
||||
video/vivo, viv|vivo
|
||||
video/vnd.rn-realvideo, rv
|
||||
video/vosaic, vos
|
||||
video/webm, webm
|
||||
video/x-amt-demorun, xdr
|
||||
video/x-amt-showrun, xsr
|
||||
video/x-atomic3d-feature, fmf
|
||||
video/x-dl, dl
|
||||
video/x-dv, dif|dv
|
||||
video/x-fli, fli
|
||||
video/x-flv, flv
|
||||
video/x-isvideo, isu
|
||||
!video/x-jng, jng
|
||||
video/x-m4v, m4v
|
||||
video/x-matroska, mkv
|
||||
video/x-mng, mng
|
||||
video/x-motion-jpeg, mjpg
|
||||
video/x-ms-asf, asf|asx|wmv
|
||||
video/x-msvideo, divx
|
||||
video/x-qtc, qtc
|
||||
video/x-sgi-movie, movie|mv
|
||||
x-epoc/x-sisx-app,
|
|
@ -1,152 +0,0 @@
|
||||
## User scripts
|
||||
|
||||
*This document is under construction, more in-depth guide coming soon*
|
||||
|
||||
During the `index` step, you can use the `--script-file <script>` option to
|
||||
modify documents or add user tags. This option is mainly used to
|
||||
implement automatic tagging based on file attributes.
|
||||
|
||||
The scripting language used
|
||||
([Painless Scripting Language](https://www.elastic.co/guide/en/elasticsearch/painless/7.4/index.html))
|
||||
is very similar to Java, but you should be able to create user scripts
|
||||
without programming experience at all if you're somewhat familiar with
|
||||
regex.
|
||||
|
||||
This is the base structure of the documents we're working with:
|
||||
```json
|
||||
{
|
||||
"_id": "e171405c-fdb5-4feb-bb32-82637bc32084",
|
||||
"_index": "sist2",
|
||||
"_type": "_doc",
|
||||
"_source": {
|
||||
"index": "206b3050-e821-421a-891d-12fcf6c2db0d",
|
||||
"mime": "application/json",
|
||||
"size": 1799,
|
||||
"mtime": 1545443685,
|
||||
"extension": "md",
|
||||
"name": "README",
|
||||
"path": "sist2/scripting",
|
||||
"content": "..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Example script**
|
||||
|
||||
This script checks if the `genre` attribute exists, if it does
|
||||
it adds the `genre.<genre>` tag.
|
||||
```Java
|
||||
ArrayList tags = ctx._source.tag = new ArrayList();
|
||||
|
||||
if (ctx._source?.genre != null) {
|
||||
tags.add("genre." + ctx._source.genre.toLowerCase())
|
||||
}
|
||||
```
|
||||
|
||||
You can use `.` to create a hierarchical tag tree:
|
||||
|
||||

|
||||
|
||||
|
||||
To use regular expressions, you need to add this line in `/etc/elasticsearch/elasticsearch.yml`
|
||||
```yaml
|
||||
script.painless.regex.enabled: true
|
||||
```
|
||||
Or, if you're using docker add `-e "script.painless.regex.enabled=true"`
|
||||
|
||||
**Tag color**
|
||||
|
||||
You can specify the color for an individual tag by appending an
|
||||
hexadecimal color code (`#RRGGBBAA`) to the tag name.
|
||||
|
||||
### Examples
|
||||
|
||||
If `(20XX)` is in the file name, add the `year.<year>` tag:
|
||||
```Java
|
||||
ArrayList tags = ctx._source.tag = new ArrayList();
|
||||
|
||||
Matcher m = /[\(\.+](20[0-9]{2})[\)\.+]/.matcher(ctx._source.name);
|
||||
if (m.find()) {
|
||||
tags.add("year." + m.group(1))
|
||||
}
|
||||
```
|
||||
|
||||
Use default *Calibre* folder structure to infer author.
|
||||
```Java
|
||||
ArrayList tags = ctx._source.tag = new ArrayList();
|
||||
|
||||
// We expect the book path to look like this:
|
||||
// /path/to/Calibre Library/Author/Title/Title - Author.pdf
|
||||
|
||||
if (ctx._source.name.contains("-") && ctx._source.extension == "pdf") {
|
||||
String[] names = ctx._source.name.splitOnToken('-');
|
||||
tags.add("author." + names[1].strip());
|
||||
}
|
||||
```
|
||||
|
||||
If the file matches a specific pattern `AAAA-000 fName1 lName1, <fName2 lName2>...`, add the `actress.<actress>` and
|
||||
`studio.<studio>` tag:
|
||||
```Java
|
||||
ArrayList tags = ctx._source.tag = new ArrayList();
|
||||
|
||||
Matcher m = /([A-Z]{4})-[0-9]{3} (.*)/.matcher(ctx._source.name);
|
||||
if (m.find()) {
|
||||
tags.add("studio." + m.group(1));
|
||||
|
||||
// Take the matched group (.*), and add a tag for
|
||||
// each name, separated by comma
|
||||
for (String name : m.group(2).splitOnToken(',')) {
|
||||
tags.add("actress." + name);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Set the name of the last folder (`/path/to/<studio>/file.mp4`) to `studio.<studio>` tag
|
||||
```Java
|
||||
ArrayList tags = ctx._source.tag = new ArrayList();
|
||||
|
||||
if (ctx._source.path != "") {
|
||||
String[] names = ctx._source.path.splitOnToken('/');
|
||||
tags.add("studio." + names[names.length-1]);
|
||||
}
|
||||
```
|
||||
|
||||
Set the name of the last folder (`/path/to/<studio>/file.mp4`) to `studio.<studio>` tag
|
||||
```Java
|
||||
ArrayList tags = ctx._source.tag = new ArrayList();
|
||||
|
||||
if (ctx._source.path != "") {
|
||||
String[] names = ctx._source.path.splitOnToken('/');
|
||||
tags.add("studio." + names[names.length-1]);
|
||||
}
|
||||
```
|
||||
|
||||
Parse `EXIF:F Number` tag
|
||||
```Java
|
||||
if (ctx._source?.exif_fnumber != null) {
|
||||
String[] values = ctx._source.exif_fnumber.splitOnToken(' ');
|
||||
String aperture = String.valueOf(Float.parseFloat(values[0]) / Float.parseFloat(values[1]));
|
||||
if (aperture == "NaN") {
|
||||
aperture = "0,0";
|
||||
}
|
||||
tags.add("Aperture.f/" + aperture.replace(".", ","));
|
||||
}
|
||||
```
|
||||
|
||||
Display year and months from `EXIF:DateTime` tag
|
||||
```Java
|
||||
if (ctx._source?.exif_datetime != null) {
|
||||
SimpleDateFormat parser = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
|
||||
Date date = parser.parse(ctx._source.exif_datetime);
|
||||
|
||||
SimpleDateFormat yp = new SimpleDateFormat("yyyy");
|
||||
SimpleDateFormat mp = new SimpleDateFormat("MMMMMMMMM");
|
||||
|
||||
String year = yp.format(date);
|
||||
String month = mp.format(date);
|
||||
|
||||
tags.add("Month." + month);
|
||||
tags.add("Year." + year);
|
||||
}
|
||||
|
||||
```
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
@ -2,15 +2,15 @@
|
||||
|
||||
rm -rf index.sist2/
|
||||
|
||||
rm web/js/bundle.js 2> /dev/null
|
||||
cat `ls web/js/*.min.js` > web/js/bundle.js
|
||||
cat web/js/{util,dom,search}.js >> web/js/bundle.js
|
||||
rm src/static/js/bundle.js 2> /dev/null
|
||||
cat `ls src/static/js/*.min.js` > src/static/js/bundle.js
|
||||
cat src/static/js/{util,dom,search}.js >> src/static/js/bundle.js
|
||||
|
||||
rm web/css/bundle*.css 2> /dev/null
|
||||
cat web/css/*.min.css > web/css/bundle.css
|
||||
cat web/css/light.css >> web/css/bundle.css
|
||||
cat web/css/*.min.css > web/css/bundle_dark.css
|
||||
cat web/css/dark.css >> web/css/bundle_dark.css
|
||||
rm src/static/css/bundle*.css 2> /dev/null
|
||||
cat src/static/css/*.min.css > src/static/css/bundle.css
|
||||
cat src/static/css/light.css >> src/static/css/bundle.css
|
||||
cat src/static/css/*.min.css > src/static/css/bundle_dark.css
|
||||
cat src/static/css/dark.css >> src/static/css/bundle_dark.css
|
||||
|
||||
python3 scripts/mime.py > src/parsing/mime_generated.c
|
||||
python3 scripts/serve_static.py > src/web/static_generated.c
|
||||
|
@ -4,45 +4,6 @@ THREADS=$(nproc)
|
||||
|
||||
cd lib
|
||||
|
||||
cd mupdf
|
||||
CFLAGS=-fPIC make USE_SYSTEM_HARFBUZZ=yes USE_SYSTEM_OPENJPEG=yes HAVE_X11=no HAVE_GLUT=no -j $THREADS
|
||||
cd ..
|
||||
|
||||
mv mupdf/build/release/libmupdf.a .
|
||||
mv mupdf/build/release/libmupdf-third.a .
|
||||
|
||||
# openjp2
|
||||
cd openjpeg
|
||||
cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O3 -DNDEBUG -fPIC"
|
||||
make -j $THREADS
|
||||
cd ..
|
||||
mv openjpeg/bin/libopenjp2.a .
|
||||
|
||||
# harfbuzz
|
||||
cd harfbuzz
|
||||
./autogen.sh
|
||||
CFLAGS=-fPIC ./configure --disable-shared --enable-static
|
||||
make -j $THREADS
|
||||
cd ..
|
||||
mv harfbuzz/src/.libs/libharfbuzz.a .
|
||||
|
||||
# ffmpeg
|
||||
cd ffmpeg
|
||||
./configure --disable-shared --enable-static --disable-ffmpeg --disable-ffplay \
|
||||
--disable-ffprobe --disable-doc\
|
||||
--disable-manpages --disable-postproc --disable-avfilter \
|
||||
--disable-alsa --disable-lzma --disable-xlib --disable-debug\
|
||||
--disable-vdpau --disable-vaapi --disable-sdl2 --disable-network\
|
||||
--extra-cflags=-fPIC
|
||||
make -j $THREADS
|
||||
cd ..
|
||||
|
||||
mv ffmpeg/libavcodec/libavcodec.a .
|
||||
mv ffmpeg/libavformat/libavformat.a .
|
||||
mv ffmpeg/libavutil/libavutil.a .
|
||||
mv ffmpeg/libswresample/libswresample.a .
|
||||
mv ffmpeg/libswscale/libswscale.a .
|
||||
|
||||
# onion
|
||||
cd onion
|
||||
mkdir build 2> /dev/null
|
||||
@ -56,56 +17,6 @@ cd ../..
|
||||
|
||||
mv onion/build/src/onion/libonion_static.a .
|
||||
|
||||
#bzip2
|
||||
cd bzip2-1.0.6
|
||||
make -j $THREADS
|
||||
cd ..
|
||||
mv bzip2-1.0.6/libbz2.a .
|
||||
|
||||
# magic
|
||||
cd libmagic
|
||||
./autogen.sh
|
||||
./configure --enable-static --disable-shared
|
||||
make -j $THREADS
|
||||
cd ..
|
||||
mv libmagic/src/.libs/libmagic.a .
|
||||
|
||||
# tesseract
|
||||
cd tesseract
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DSTATIC=on -DBUILD_TRAINING_TOOLS=off -DBUILD_TESTS=off -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_CXX_FLAGS="-fPIC" -DAUTO_OPTIMIZE=off ..
|
||||
make -j $THREADS
|
||||
cd ../..
|
||||
mv tesseract/build/libtesseract.a .
|
||||
|
||||
# leptonica
|
||||
cd leptonica
|
||||
./autogen.sh
|
||||
CFLAGS="-fPIC" ./configure --without-zlib --without-jpeg --without-giflib \
|
||||
--without-giflib --without-libwebp --without-libwebpmux --without-libopenjpeg \
|
||||
--enable-static --disable-shared
|
||||
make -j $THREADS
|
||||
cd ..
|
||||
mv leptonica/src/.libs/liblept.a .
|
||||
|
||||
# tiff
|
||||
cd libtiff
|
||||
./autogen.sh
|
||||
CFLAGS="-fPIC" CXXFLAGS="-fPIC" CXX_FLAGS="-fPIC" ./configure --enable-static --disable-shared --disable-lzw --disable-jpeg --disable-webp \
|
||||
--disable-lzma --disable-zstd --disable-jbig
|
||||
make -j $THREADS
|
||||
cd ..
|
||||
mv libtiff/libtiff/.libs/libtiff.a .
|
||||
|
||||
# png
|
||||
cd libpng
|
||||
CFLAGS="-fPIC" ./configure --enable-static --disable-shared
|
||||
make -j $THREADS
|
||||
cd ..
|
||||
mv libpng/.libs/libpng16.a .
|
||||
|
||||
# openssl...
|
||||
git clone --depth 1 -b OpenSSL_1_1_0-stable https://github.com/openssl/openssl
|
||||
cd openssl
|
||||
|
@ -91,7 +91,7 @@ def clean(t):
|
||||
return t.replace("/", "_").replace(".", "_").replace("+", "_").replace("-", "_")
|
||||
|
||||
|
||||
with open("mime.csv") as f:
|
||||
with open("scripts/mime.csv") as f:
|
||||
for l in f:
|
||||
mime, ext_list = l.split(",")
|
||||
if l.startswith("!"):
|
||||
@ -103,7 +103,7 @@ with open("mime.csv") as f:
|
||||
print("// **Generated by mime.py**")
|
||||
print("#ifndef MIME_GENERATED_C")
|
||||
print("#define MIME_GENERATED_C")
|
||||
print("#include <glib-2.0/glib.h>\n")
|
||||
print("#include <glib.h>\n")
|
||||
print("#include <stdlib.h>\n")
|
||||
# Enum
|
||||
print("enum mime {")
|
||||
|
@ -1,10 +1,10 @@
|
||||
files = [
|
||||
"web/css/bundle.css",
|
||||
"web/css/bundle_dark.css",
|
||||
"web/js/bundle.js",
|
||||
"web/img/sprite-skin-flat.png",
|
||||
"web/img/sprite-skin-flat-dark.png",
|
||||
"web/search.html",
|
||||
"src/static/css/bundle.css",
|
||||
"src/static/css/bundle_dark.css",
|
||||
"src/static/js/bundle.js",
|
||||
"src/static/img/sprite-skin-flat.png",
|
||||
"src/static/img/sprite-skin-flat-dark.png",
|
||||
"src/static/search.html",
|
||||
]
|
||||
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include "sist.h"
|
||||
|
||||
#include "libscan/scan.h"
|
||||
|
||||
typedef struct scan_args {
|
||||
float quality;
|
||||
int size;
|
||||
|
@ -2,7 +2,13 @@
|
||||
#define SIST2_CTX_H
|
||||
|
||||
#include "sist.h"
|
||||
#include "tpool.h"
|
||||
#include "libscan/scan.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <pcre.h>
|
||||
|
||||
//TODO Move to individual scan ctx
|
||||
struct {
|
||||
struct index_t index;
|
||||
|
||||
@ -34,17 +40,20 @@ struct {
|
||||
int fast;
|
||||
} ScanCtx;
|
||||
|
||||
//TODO Move to log.h
|
||||
struct {
|
||||
int verbose;
|
||||
int very_verbose;
|
||||
int no_color;
|
||||
} LogCtx;
|
||||
|
||||
//TODO Move to index.h ?
|
||||
struct {
|
||||
char *es_url;
|
||||
int batch_size;
|
||||
} IndexCtx;
|
||||
|
||||
//TODO Move to serve.h ?
|
||||
struct {
|
||||
char *es_url;
|
||||
int index_count;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "src/ctx.h"
|
||||
#include "serialize.h"
|
||||
#include "src/parsing/parse.h"
|
||||
#include "src/parsing/mime.h"
|
||||
|
||||
static __thread int index_fd = -1;
|
||||
|
||||
@ -176,11 +178,11 @@ void write_document(document_t *doc) {
|
||||
dyn_buffer_write_char(&buf, meta->key);
|
||||
|
||||
if (IS_META_INT(meta->key)) {
|
||||
dyn_buffer_write_int(&buf, meta->intval);
|
||||
dyn_buffer_write_int(&buf, meta->int_val);
|
||||
} else if (IS_META_LONG(meta->key)) {
|
||||
dyn_buffer_write_long(&buf, meta->longval);
|
||||
dyn_buffer_write_long(&buf, meta->long_val);
|
||||
} else {
|
||||
dyn_buffer_write_str(&buf, meta->strval);
|
||||
dyn_buffer_write_str(&buf, meta->str_val);
|
||||
}
|
||||
|
||||
meta_line_t *tmp = meta;
|
||||
@ -200,7 +202,6 @@ void write_document(document_t *doc) {
|
||||
void thread_cleanup() {
|
||||
close(index_fd);
|
||||
cleanup_parse();
|
||||
cleanup_font();
|
||||
}
|
||||
|
||||
|
||||
@ -270,16 +271,7 @@ void read_index_bin(const char *path, const char *index_id, index_func func) {
|
||||
break;
|
||||
}
|
||||
case MetaMediaAudioCodec:
|
||||
case MetaMediaVideoCodec: {
|
||||
int value;
|
||||
ret = fread(&value, sizeof(int), 1, file);
|
||||
const AVCodecDescriptor *desc = avcodec_descriptor_get(value);
|
||||
if (desc != NULL) {
|
||||
cJSON_AddStringToObject(document, get_meta_key_text(key), desc->name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MetaMediaVideoCodec:
|
||||
case MetaContent:
|
||||
case MetaArtist:
|
||||
case MetaAlbum:
|
||||
|
@ -2,7 +2,10 @@
|
||||
#define SIST2_SERIALIZE_H
|
||||
|
||||
#include "src/sist.h"
|
||||
#include "store.h"
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <glib.h>
|
||||
|
||||
typedef void(*index_func)(cJSON *, const char[UUID_STR_LEN]);
|
||||
|
||||
|
@ -11,7 +11,7 @@ typedef struct store_t {
|
||||
pthread_rwlock_t lock;
|
||||
} store_t;
|
||||
|
||||
#include "src/sist.h"
|
||||
#include "../sist.h"
|
||||
|
||||
store_t *store_create(char *path);
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "walk.h"
|
||||
#include "src/ctx.h"
|
||||
#include "src/parsing/parse.h"
|
||||
|
||||
#include <ftw.h>
|
||||
|
||||
__always_inline
|
||||
parse_job_t *create_fs_parse_job(const char *filepath, const struct stat *info, int base) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#define _XOPEN_SOURCE 500
|
||||
|
||||
#include "src/sist.h"
|
||||
#include "../sist.h"
|
||||
|
||||
int walk_directory_tree(const char *);
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "log.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
const char *log_colors[] = {
|
||||
"\033[34m", "\033[01;34m", "\033[0m",
|
||||
"\033[01;33m", "\033[31m", "\033[01;31m"
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef SIST2_LOG_H
|
||||
#define SIST2_LOG_H
|
||||
|
||||
|
||||
|
||||
#define LOG_MAX_LENGTH 8192
|
||||
|
||||
#define SIST_DEBUG 0
|
||||
@ -36,7 +38,7 @@
|
||||
sist_log(filepath, SIST_FATAL, str);\
|
||||
exit(-1);
|
||||
|
||||
#include "src/sist.h"
|
||||
#include "sist.h"
|
||||
|
||||
void sist_logf(char *filepath, int level, char *format, ...);
|
||||
|
||||
|
20
src/main.c
20
src/main.c
@ -1,6 +1,20 @@
|
||||
#include "sist.h"
|
||||
#include "ctx.h"
|
||||
|
||||
#include <third-party/argparse/argparse.h>
|
||||
#include <uuid/uuid.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "cli.h"
|
||||
#include "io/serialize.h"
|
||||
#include "io/store.h"
|
||||
#include "tpool.h"
|
||||
#include "io/walk.h"
|
||||
#include "io/walk.h"
|
||||
#include "index/elastic.h"
|
||||
#include "web/serve.h"
|
||||
#include "parsing/mime.h"
|
||||
|
||||
#define DESCRIPTION "Lightning-fast file system indexer and search tool."
|
||||
|
||||
#define EPILOG "Made by simon987 <me@simon987.net>. Released under GPL-3.0"
|
||||
@ -15,8 +29,8 @@ static const char *const usage[] = {
|
||||
};
|
||||
|
||||
void global_init() {
|
||||
curl_global_init(CURL_GLOBAL_NOTHING);
|
||||
av_log_set_level(AV_LOG_QUIET);
|
||||
//TODO
|
||||
// curl_global_init(CURL_GLOBAL_NOTHING);
|
||||
}
|
||||
|
||||
void init_dir(const char *dirpath) {
|
||||
@ -59,8 +73,6 @@ void sist2_scan(scan_args_t *args) {
|
||||
ScanCtx.mime_table = mime_get_mime_table();
|
||||
ScanCtx.ext_table = mime_get_ext_table();
|
||||
|
||||
cbr_init();
|
||||
|
||||
char store_path[PATH_MAX];
|
||||
snprintf(store_path, PATH_MAX, "%sthumbs", ScanCtx.index.path);
|
||||
mkdir(store_path, S_IWUSR | S_IRUSR | S_IXUSR);
|
||||
|
@ -1,13 +0,0 @@
|
||||
#ifndef SIST2_ARC_H
|
||||
#define SIST2_ARC_H
|
||||
|
||||
#include "src/sist.h"
|
||||
#define ARC_BUF_SIZE 8192
|
||||
|
||||
int should_parse_filtered_file(const char *filepath, int ext);
|
||||
|
||||
void parse_archive(vfile_t *f, document_t *doc);
|
||||
|
||||
int arc_read(struct vfile * f, void *buf, size_t size);
|
||||
|
||||
#endif
|
@ -1,12 +0,0 @@
|
||||
#ifndef SIST2_CBR_H
|
||||
#define SIST2_CBR_H
|
||||
|
||||
#include "src/sist.h"
|
||||
|
||||
void cbr_init();
|
||||
|
||||
int is_cbr(unsigned int mime);
|
||||
|
||||
void parse_cbr(void *buf, size_t buf_len, document_t *doc);
|
||||
|
||||
#endif
|
@ -1,8 +0,0 @@
|
||||
#ifndef SIST2_DOC_H
|
||||
#define SIST2_DOC_H
|
||||
|
||||
#include "src/sist.h"
|
||||
|
||||
void parse_doc(void *buf, size_t buf_len, document_t *doc);
|
||||
|
||||
#endif
|
@ -1,10 +0,0 @@
|
||||
#ifndef SIST2_FONT_H
|
||||
#define SIST2_FONT_H
|
||||
|
||||
#include "src/sist.h"
|
||||
|
||||
|
||||
void parse_font(const char * buf, size_t buf_len, document_t *doc);
|
||||
void cleanup_font();
|
||||
|
||||
#endif
|
@ -1,14 +0,0 @@
|
||||
#ifndef SIST2_MEDIA_H
|
||||
#define SIST2_MEDIA_H
|
||||
|
||||
|
||||
#include "src/sist.h"
|
||||
|
||||
#define MIN_VIDEO_SIZE 1024 * 64
|
||||
#define MIN_IMAGE_SIZE 1024 * 2
|
||||
|
||||
void parse_media_filename(const char * filepath, document_t *doc);
|
||||
|
||||
void parse_media_vfile(struct vfile *f, document_t *doc);
|
||||
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
#ifndef SIST2_MIME_H
|
||||
#define SIST2_MIME_H
|
||||
|
||||
#include "src/sist.h"
|
||||
#include "../sist.h"
|
||||
|
||||
#define MAJOR_MIME(mime_id) (mime_id & 0x0FFF0000) >> 16
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// **Generated by mime.py**
|
||||
#ifndef MIME_GENERATED_C
|
||||
#define MIME_GENERATED_C
|
||||
#include <glib-2.0/glib.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -1,5 +1,12 @@
|
||||
#include "parse.h"
|
||||
|
||||
#include "src/sist.h"
|
||||
#include "src/ctx.h"
|
||||
#include "mime.h"
|
||||
#include "libscan/scan.h"
|
||||
#include "src/io/serialize.h"
|
||||
|
||||
#include <magic.h>
|
||||
|
||||
__thread magic_t Magic = NULL;
|
||||
|
||||
@ -24,33 +31,6 @@ void fs_close(struct vfile *f) {
|
||||
}
|
||||
}
|
||||
|
||||
void *read_all(parse_job_t *job, const char *buf, int bytes_read) {
|
||||
|
||||
void *full_buf;
|
||||
|
||||
if (job->info.st_size <= bytes_read) {
|
||||
full_buf = malloc(job->info.st_size);
|
||||
memcpy(full_buf, buf, job->info.st_size);
|
||||
} else {
|
||||
full_buf = malloc(job->info.st_size);
|
||||
memcpy(full_buf, buf, bytes_read);
|
||||
|
||||
int ret = job->vfile.read(&job->vfile, full_buf + bytes_read, job->info.st_size - bytes_read);
|
||||
if (ret < 0) {
|
||||
free(full_buf);
|
||||
|
||||
if (job->vfile.is_fs_file) {
|
||||
LOG_ERRORF(job->filepath, "read(): [%d] %s", errno, strerror(errno))
|
||||
} else {
|
||||
LOG_ERRORF(job->filepath, "(virtual) read(): [%d] %s", ret, archive_error_string(job->vfile.arc))
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return full_buf;
|
||||
}
|
||||
|
||||
void parse(void *arg) {
|
||||
|
||||
parse_job_t *job = arg;
|
||||
@ -131,30 +111,17 @@ void parse(void *arg) {
|
||||
} else if ((mmime == MimeVideo && doc.size >= MIN_VIDEO_SIZE) ||
|
||||
(mmime == MimeImage && doc.size >= MIN_IMAGE_SIZE) || mmime == MimeAudio) {
|
||||
|
||||
if (job->vfile.is_fs_file) {
|
||||
parse_media_filename(job->filepath, &doc);
|
||||
} else {
|
||||
parse_media_vfile(&job->vfile, &doc);
|
||||
}
|
||||
parse_media(&job->vfile, &doc);
|
||||
|
||||
} else if (IS_PDF(doc.mime)) {
|
||||
void *pdf_buf = read_all(job, (char *) buf, bytes_read);
|
||||
parse_pdf(pdf_buf, doc.size, &doc);
|
||||
|
||||
if (pdf_buf != buf && pdf_buf != NULL) {
|
||||
free(pdf_buf);
|
||||
}
|
||||
parse_ebook(pdf_buf, doc.size, &doc);
|
||||
|
||||
} else if (mmime == MimeText && ScanCtx.content_size > 0) {
|
||||
parse_text(bytes_read, &job->vfile, (char *) buf, &doc);
|
||||
|
||||
} else if (IS_FONT(doc.mime)) {
|
||||
void *font_buf = read_all(job, (char *) buf, bytes_read);
|
||||
parse_font(font_buf, doc.size, &doc);
|
||||
|
||||
if (font_buf != buf && font_buf != NULL) {
|
||||
free(font_buf);
|
||||
}
|
||||
} else if (
|
||||
ScanCtx.archive_mode != ARC_MODE_SKIP && (
|
||||
IS_ARC(doc.mime) ||
|
||||
@ -162,19 +129,11 @@ void parse(void *arg) {
|
||||
)) {
|
||||
parse_archive(&job->vfile, &doc);
|
||||
} else if (ScanCtx.content_size > 0 && IS_DOC(doc.mime)) {
|
||||
void *doc_buf = read_all(job, (char *) buf, bytes_read);
|
||||
parse_doc(doc_buf, doc.size, &doc);
|
||||
|
||||
if (doc_buf != buf && doc_buf != NULL) {
|
||||
free(doc_buf);
|
||||
}
|
||||
} else if (is_cbr(doc.mime)) {
|
||||
void *cbr_buf = read_all(job, (char *) buf, bytes_read);
|
||||
parse_cbr(cbr_buf, doc.size, &doc);
|
||||
|
||||
if (cbr_buf != buf && cbr_buf != NULL) {
|
||||
free(cbr_buf);
|
||||
}
|
||||
}
|
||||
|
||||
//Parent meta
|
||||
@ -184,7 +143,7 @@ void parse(void *arg) {
|
||||
|
||||
meta_line_t *meta_parent = malloc(sizeof(meta_line_t) + UUID_STR_LEN + 1);
|
||||
meta_parent->key = MetaParent;
|
||||
strcpy(meta_parent->strval, tmp);
|
||||
strcpy(meta_parent->str_val, tmp);
|
||||
APPEND_META((&doc), meta_parent)
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef SIST2_PARSE_H
|
||||
#define SIST2_PARSE_H
|
||||
|
||||
#include "src/sist.h"
|
||||
#include "../sist.h"
|
||||
|
||||
#define PARSE_BUF_SIZE 4096
|
||||
|
||||
|
@ -1,331 +0,0 @@
|
||||
#include "pdf.h"
|
||||
#include "src/ctx.h"
|
||||
|
||||
#define MIN_OCR_SIZE 350
|
||||
#define MIN_OCR_LEN 10
|
||||
__thread text_buffer_t thread_buffer;
|
||||
|
||||
|
||||
int render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) {
|
||||
|
||||
int err = 0;
|
||||
fz_page *cover = NULL;
|
||||
|
||||
fz_var(cover);
|
||||
fz_var(err);
|
||||
fz_try(ctx)
|
||||
cover = fz_load_page(ctx, fzdoc, 0);
|
||||
fz_catch(ctx)
|
||||
err = 1;
|
||||
|
||||
if (err != 0) {
|
||||
fz_drop_page(ctx, cover);
|
||||
LOG_WARNINGF(doc->filepath, "fz_load_page() returned error code [%d] %s", err, ctx->error.message)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fz_rect bounds = fz_bound_page(ctx, cover);
|
||||
|
||||
float scale;
|
||||
float w = (float) bounds.x1 - bounds.x0;
|
||||
float h = (float) bounds.y1 - bounds.y0;
|
||||
if (w > h) {
|
||||
scale = (float) ScanCtx.tn_size / w;
|
||||
} else {
|
||||
scale = (float) ScanCtx.tn_size / h;
|
||||
}
|
||||
fz_matrix m = fz_scale(scale, scale);
|
||||
|
||||
bounds = fz_transform_rect(bounds, m);
|
||||
fz_irect bbox = fz_round_rect(bounds);
|
||||
fz_pixmap *pixmap = fz_new_pixmap_with_bbox(ctx, ctx->colorspace->rgb, bbox, NULL, 0);
|
||||
|
||||
fz_clear_pixmap_with_value(ctx, pixmap, 0xFF);
|
||||
fz_device *dev = fz_new_draw_device(ctx, m, pixmap);
|
||||
|
||||
fz_var(err);
|
||||
fz_try(ctx)
|
||||
{
|
||||
pthread_mutex_lock(&ScanCtx.mupdf_mu);
|
||||
fz_run_page(ctx, cover, dev, fz_identity, NULL);
|
||||
}
|
||||
fz_always(ctx)
|
||||
{
|
||||
fz_close_device(ctx, dev);
|
||||
fz_drop_device(ctx, dev);
|
||||
pthread_mutex_unlock(&ScanCtx.mupdf_mu);
|
||||
}
|
||||
fz_catch(ctx)
|
||||
err = ctx->error.errcode;
|
||||
|
||||
if (err != 0) {
|
||||
LOG_WARNINGF(doc->filepath, "fz_run_page() returned error code [%d] %s", err, ctx->error.message)
|
||||
fz_drop_page(ctx, cover);
|
||||
fz_drop_pixmap(ctx, pixmap);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fz_buffer *fzbuf = NULL;
|
||||
fz_var(fzbuf);
|
||||
fz_var(err);
|
||||
|
||||
fz_try(ctx)
|
||||
fzbuf = fz_new_buffer_from_pixmap_as_png(ctx, pixmap, fz_default_color_params);
|
||||
fz_catch(ctx)
|
||||
err = ctx->error.errcode;
|
||||
|
||||
if (err == 0) {
|
||||
unsigned char *tn_buf;
|
||||
size_t tn_len = fz_buffer_storage(ctx, fzbuf, &tn_buf);
|
||||
store_write(ScanCtx.index.store, (char *) doc->uuid, sizeof(doc->uuid), (char *) tn_buf, tn_len);
|
||||
}
|
||||
|
||||
fz_drop_buffer(ctx, fzbuf);
|
||||
fz_drop_pixmap(ctx, pixmap);
|
||||
fz_drop_page(ctx, cover);
|
||||
|
||||
if (err != 0) {
|
||||
LOG_WARNINGF(doc->filepath, "fz_new_buffer_from_pixmap_as_png() returned error code [%d] %s", err,
|
||||
ctx->error.message)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void fz_err_callback(void *user, UNUSED(const char *message)) {
|
||||
if (LogCtx.verbose) {
|
||||
document_t *doc = (document_t *) user;
|
||||
LOG_WARNINGF(doc->filepath, "FZ: %s", message)
|
||||
}
|
||||
}
|
||||
|
||||
__always_inline
|
||||
static void init_ctx(fz_context *ctx, document_t *doc) {
|
||||
fz_disable_icc(ctx);
|
||||
fz_register_document_handlers(ctx);
|
||||
|
||||
ctx->warn.print_user = doc;
|
||||
ctx->warn.print = fz_err_callback;
|
||||
ctx->error.print_user = doc;
|
||||
ctx->error.print = fz_err_callback;
|
||||
}
|
||||
|
||||
__always_inline
|
||||
static int read_stext_block(fz_stext_block *block, text_buffer_t *tex) {
|
||||
if (block->type != FZ_STEXT_BLOCK_TEXT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fz_stext_line *line = block->u.t.first_line;
|
||||
while (line != NULL) {
|
||||
fz_stext_char *c = line->first_char;
|
||||
while (c != NULL) {
|
||||
if (text_buffer_append_char(tex, c->c) == TEXT_BUF_FULL) {
|
||||
return TEXT_BUF_FULL;
|
||||
}
|
||||
c = c->next;
|
||||
}
|
||||
line = line->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define IS_VALID_BPP(d) (d==1 || d==2 || d==4 || d==8 || d==16 || d==24 || d==32)
|
||||
|
||||
void fill_image(fz_context *ctx, UNUSED(fz_device *dev),
|
||||
fz_image *img, UNUSED(fz_matrix ctm), UNUSED(float alpha),
|
||||
UNUSED(fz_color_params color_params)) {
|
||||
|
||||
int l2factor = 0;
|
||||
|
||||
if (img->w > MIN_OCR_SIZE && img->h > MIN_OCR_SIZE && IS_VALID_BPP(img->n)) {
|
||||
|
||||
fz_pixmap *pix = img->get_pixmap(ctx, img, NULL, img->w, img->h, &l2factor);
|
||||
|
||||
if (pix->h > MIN_OCR_SIZE && img->h > MIN_OCR_SIZE && img->xres != 0) {
|
||||
TessBaseAPI *api = TessBaseAPICreate();
|
||||
TessBaseAPIInit3(api, ScanCtx.tesseract_path, ScanCtx.tesseract_lang);
|
||||
|
||||
TessBaseAPISetImage(api, pix->samples, pix->w, pix->h, pix->n, pix->stride);
|
||||
TessBaseAPISetSourceResolution(api, pix->xres);
|
||||
|
||||
char *text = TessBaseAPIGetUTF8Text(api);
|
||||
size_t len = strlen(text);
|
||||
if (len >= MIN_OCR_LEN) {
|
||||
text_buffer_append_string(&thread_buffer, text, len - 1);
|
||||
LOG_DEBUGF(
|
||||
"pdf.c",
|
||||
"(OCR) %dx%d got %dB from tesseract (%s), buffer:%dB",
|
||||
pix->w, pix->h, len, ScanCtx.tesseract_lang, thread_buffer.dyn_buffer.cur
|
||||
)
|
||||
}
|
||||
|
||||
TessBaseAPIEnd(api);
|
||||
TessBaseAPIDelete(api);
|
||||
}
|
||||
fz_drop_pixmap(ctx, pix);
|
||||
}
|
||||
}
|
||||
|
||||
void parse_pdf(const void *buf, size_t buf_len, document_t *doc) {
|
||||
|
||||
if (buf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
static int mu_is_initialized = 0;
|
||||
if (!mu_is_initialized) {
|
||||
pthread_mutex_init(&ScanCtx.mupdf_mu, NULL);
|
||||
mu_is_initialized = 1;
|
||||
}
|
||||
fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
|
||||
|
||||
init_ctx(ctx, doc);
|
||||
|
||||
int err = 0;
|
||||
|
||||
fz_document *fzdoc = NULL;
|
||||
fz_stream *stream = NULL;
|
||||
fz_var(fzdoc);
|
||||
fz_var(stream);
|
||||
fz_var(err);
|
||||
|
||||
fz_try(ctx)
|
||||
{
|
||||
stream = fz_open_memory(ctx, buf, buf_len);
|
||||
fzdoc = fz_open_document_with_stream(ctx, mime_get_mime_text(doc->mime), stream);
|
||||
}
|
||||
fz_catch(ctx)
|
||||
err = ctx->error.errcode;
|
||||
|
||||
if (err != 0) {
|
||||
fz_drop_stream(ctx, stream);
|
||||
fz_drop_document(ctx, fzdoc);
|
||||
fz_drop_context(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
char title[4096] = {'\0',};
|
||||
fz_try(ctx)
|
||||
fz_lookup_metadata(ctx, fzdoc, FZ_META_INFO_TITLE, title, sizeof(title));
|
||||
fz_catch(ctx)
|
||||
;
|
||||
|
||||
if (strlen(title) > 0) {
|
||||
meta_line_t *meta_content = malloc(sizeof(meta_line_t) + strlen(title));
|
||||
meta_content->key = MetaTitle;
|
||||
strcpy(meta_content->strval, title);
|
||||
APPEND_META(doc, meta_content)
|
||||
}
|
||||
|
||||
int page_count = -1;
|
||||
fz_var(err);
|
||||
fz_try(ctx)
|
||||
page_count = fz_count_pages(ctx, fzdoc);
|
||||
fz_catch(ctx)
|
||||
err = ctx->error.errcode;
|
||||
|
||||
if (err) {
|
||||
LOG_WARNINGF(doc->filepath, "fz_count_pages() returned error code [%d] %s", err, ctx->error.message)
|
||||
fz_drop_stream(ctx, stream);
|
||||
fz_drop_document(ctx, fzdoc);
|
||||
fz_drop_context(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ScanCtx.tn_size > 0) {
|
||||
err = render_cover(ctx, doc, fzdoc);
|
||||
}
|
||||
|
||||
if (err == TRUE) {
|
||||
fz_drop_stream(ctx, stream);
|
||||
fz_drop_document(ctx, fzdoc);
|
||||
fz_drop_context(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ScanCtx.content_size > 0) {
|
||||
fz_stext_options opts = {0};
|
||||
thread_buffer = text_buffer_create(ScanCtx.content_size);
|
||||
|
||||
for (int current_page = 0; current_page < page_count; current_page++) {
|
||||
fz_page *page = NULL;
|
||||
fz_var(err);
|
||||
fz_try(ctx)
|
||||
page = fz_load_page(ctx, fzdoc, current_page);
|
||||
fz_catch(ctx)
|
||||
err = ctx->error.errcode;
|
||||
if (err != 0) {
|
||||
LOG_WARNINGF(doc->filepath, "fz_load_page() returned error code [%d] %s", err, ctx->error.message)
|
||||
text_buffer_destroy(&thread_buffer);
|
||||
fz_drop_page(ctx, page);
|
||||
fz_drop_stream(ctx, stream);
|
||||
fz_drop_document(ctx, fzdoc);
|
||||
fz_drop_context(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
fz_stext_page *stext = fz_new_stext_page(ctx, fz_bound_page(ctx, page));
|
||||
fz_device *dev = fz_new_stext_device(ctx, stext, &opts);
|
||||
dev->stroke_path = NULL;
|
||||
dev->stroke_text = NULL;
|
||||
dev->clip_text = NULL;
|
||||
dev->clip_stroke_path = NULL;
|
||||
dev->clip_stroke_text = NULL;
|
||||
|
||||
if (ScanCtx.tesseract_lang != NULL) {
|
||||
dev->fill_image = fill_image;
|
||||
}
|
||||
|
||||
fz_var(err);
|
||||
fz_try(ctx)
|
||||
fz_run_page(ctx, page, dev, fz_identity, NULL);
|
||||
fz_always(ctx)
|
||||
{
|
||||
fz_close_device(ctx, dev);
|
||||
fz_drop_device(ctx, dev);
|
||||
}
|
||||
fz_catch(ctx)
|
||||
err = ctx->error.errcode;
|
||||
|
||||
if (err != 0) {
|
||||
LOG_WARNINGF(doc->filepath, "fz_run_page() returned error code [%d] %s", err, ctx->error.message)
|
||||
text_buffer_destroy(&thread_buffer);
|
||||
fz_drop_page(ctx, page);
|
||||
fz_drop_stext_page(ctx, stext);
|
||||
fz_drop_stream(ctx, stream);
|
||||
fz_drop_document(ctx, fzdoc);
|
||||
fz_drop_context(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
fz_stext_block *block = stext->first_block;
|
||||
while (block != NULL) {
|
||||
int ret = read_stext_block(block, &thread_buffer);
|
||||
if (ret == TEXT_BUF_FULL) {
|
||||
break;
|
||||
}
|
||||
block = block->next;
|
||||
}
|
||||
fz_drop_stext_page(ctx, stext);
|
||||
fz_drop_page(ctx, page);
|
||||
|
||||
if (thread_buffer.dyn_buffer.cur >= thread_buffer.dyn_buffer.size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
text_buffer_terminate_string(&thread_buffer);
|
||||
|
||||
meta_line_t *meta_content = malloc(sizeof(meta_line_t) + thread_buffer.dyn_buffer.cur);
|
||||
meta_content->key = MetaContent;
|
||||
memcpy(meta_content->strval, thread_buffer.dyn_buffer.buf, thread_buffer.dyn_buffer.cur);
|
||||
APPEND_META(doc, meta_content)
|
||||
|
||||
text_buffer_destroy(&thread_buffer);
|
||||
}
|
||||
|
||||
fz_drop_stream(ctx, stream);
|
||||
fz_drop_document(ctx, fzdoc);
|
||||
fz_drop_context(ctx);
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
#ifndef SIST2_PDF_H
|
||||
#define SIST2_PDF_H
|
||||
|
||||
#include "src/sist.h"
|
||||
|
||||
|
||||
void parse_pdf(const void *buf, size_t buf_len, document_t *doc);
|
||||
|
||||
#endif
|
@ -1,37 +0,0 @@
|
||||
#include "text.h"
|
||||
#include "src/ctx.h"
|
||||
|
||||
void parse_text(int bytes_read, struct vfile *f, char *buf, document_t *doc) {
|
||||
|
||||
char *intermediate_buf;
|
||||
int intermediate_buf_len;
|
||||
|
||||
if (bytes_read == doc->size || bytes_read >= ScanCtx.content_size) {
|
||||
int to_copy = MIN(bytes_read, ScanCtx.content_size);
|
||||
intermediate_buf = malloc(to_copy);
|
||||
intermediate_buf_len = to_copy;
|
||||
memcpy(intermediate_buf, buf, to_copy);
|
||||
|
||||
} else {
|
||||
int to_read = MIN(ScanCtx.content_size, doc->size) - bytes_read;
|
||||
|
||||
intermediate_buf = malloc(to_read + bytes_read);
|
||||
intermediate_buf_len = to_read + bytes_read;
|
||||
if (bytes_read != 0) {
|
||||
memcpy(intermediate_buf, buf, bytes_read);
|
||||
}
|
||||
|
||||
f->read(f, intermediate_buf + bytes_read, to_read);
|
||||
}
|
||||
text_buffer_t tex = text_buffer_create(ScanCtx.content_size);
|
||||
text_buffer_append_string(&tex, intermediate_buf, intermediate_buf_len);
|
||||
text_buffer_terminate_string(&tex);
|
||||
|
||||
meta_line_t *meta = malloc(sizeof(meta_line_t) + tex.dyn_buffer.cur);
|
||||
meta->key = MetaContent;
|
||||
strcpy(meta->strval, tex.dyn_buffer.buf);
|
||||
APPEND_META(doc, meta)
|
||||
|
||||
free(intermediate_buf);
|
||||
text_buffer_destroy(&tex);
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#ifndef SIST2_TEXT_H
|
||||
#define SIST2_TEXT_H
|
||||
|
||||
#include "src/sist.h"
|
||||
|
||||
void parse_text(int bytes_read, struct vfile *f, char *buf, document_t *doc);
|
||||
|
||||
#endif
|
100
src/sist.h
100
src/sist.h
@ -1,75 +1,51 @@
|
||||
#ifndef SIST_H
|
||||
#define SIST_H
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE (0)
|
||||
#define BOOL int
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
#undef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#undef ABS
|
||||
#define ABS(a) (((a) < 0) ? -(a) : (a))
|
||||
|
||||
#define UUID_STR_LEN 37
|
||||
#define UNUSED(x) __attribute__((__unused__)) x
|
||||
|
||||
#include <glib-2.0/glib.h>
|
||||
#include <unistd.h>
|
||||
#include "util.h"
|
||||
#include "log.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "libscan/scan.h"
|
||||
|
||||
#include <cjson/cJSON.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <ftw.h>
|
||||
#include <uuid.h>
|
||||
#include <magic.h>
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libswresample/swresample.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include <ctype.h>
|
||||
#include <mupdf/fitz.h>
|
||||
#include <mupdf/pdf.h>
|
||||
#include "argparse/argparse.h"
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <wordexp.h>
|
||||
#include "ft2build.h"
|
||||
#include "freetype/freetype.h"
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
#include <libxml/xmlstring.h>
|
||||
#include <libxml/parser.h>
|
||||
#define BOOL int
|
||||
#include <tesseract/capi.h>
|
||||
#include <pcre.h>
|
||||
|
||||
#include <onion/onion.h>
|
||||
#include <onion/handler.h>
|
||||
#include <onion/block.h>
|
||||
#include <onion/shortcuts.h>
|
||||
#include <onion/codecs.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "cJSON/cJSON.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "tpool.h"
|
||||
#include "utf8.h/utf8.h"
|
||||
#include "util.h"
|
||||
#include "io/store.h"
|
||||
#include "io/serialize.h"
|
||||
#include "io/walk.h"
|
||||
#include "parsing/parse.h"
|
||||
#include "parsing/mime.h"
|
||||
#include "parsing/text.h"
|
||||
#include "parsing/pdf.h"
|
||||
#include "parsing/media.h"
|
||||
#include "parsing/font.h"
|
||||
#include "parsing/arc.h"
|
||||
#include "parsing/doc.h"
|
||||
#include "parsing/cbr.h"
|
||||
#include "cli.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "src/index/elastic.h"
|
||||
#include "index/web.h"
|
||||
#include "web/serve.h"
|
||||
#include "web/auth_basic.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "tpool.h"
|
||||
#include "ctx.h"
|
||||
#include <pthread.h>
|
||||
|
||||
typedef void (*thread_func_t)(void *arg);
|
||||
|
||||
|
105
src/types.h
105
src/types.h
@ -1,48 +1,6 @@
|
||||
#ifndef SIST2_TYPES_H
|
||||
#define SIST2_TYPES_H
|
||||
|
||||
|
||||
#define META_INT_MASK 0x80
|
||||
#define META_STR_MASK 0x40
|
||||
#define META_LONG_MASK 0x20
|
||||
#define IS_META_INT(key) (key & META_INT_MASK) == META_INT_MASK
|
||||
#define IS_META_LONG(key) (key & META_LONG_MASK) == META_LONG_MASK
|
||||
#define IS_META_STR(meta) (meta->key & META_STR_MASK) == META_STR_MASK
|
||||
|
||||
#define ARC_MODE_SKIP 0
|
||||
#define ARC_MODE_LIST 1
|
||||
#define ARC_MODE_SHALLOW 2
|
||||
#define ARC_MODE_RECURSE 3
|
||||
typedef int archive_mode_t;
|
||||
|
||||
// This is written to file as a 8bit char!
|
||||
enum metakey {
|
||||
MetaContent = 1 | META_STR_MASK,
|
||||
MetaWidth = 2 | META_INT_MASK,
|
||||
MetaHeight = 3 | META_INT_MASK,
|
||||
MetaMediaDuration = 4 | META_LONG_MASK,
|
||||
MetaMediaAudioCodec = 5 | META_INT_MASK,
|
||||
MetaMediaVideoCodec = 6 | META_INT_MASK,
|
||||
MetaMediaBitrate = 7 | META_LONG_MASK,
|
||||
MetaArtist = 8 | META_STR_MASK,
|
||||
MetaAlbum = 9 | META_STR_MASK,
|
||||
MetaAlbumArtist = 10 | META_STR_MASK,
|
||||
MetaGenre = 11 | META_STR_MASK,
|
||||
MetaTitle = 12 | META_STR_MASK,
|
||||
MetaFontName = 13 | META_STR_MASK,
|
||||
MetaParent = 14 | META_STR_MASK,
|
||||
MetaExifMake = 15 | META_STR_MASK,
|
||||
MetaExifSoftware = 16 | META_STR_MASK,
|
||||
MetaExifExposureTime = 17 | META_STR_MASK,
|
||||
MetaExifFNumber = 18 | META_STR_MASK,
|
||||
MetaExifFocalLength = 19 | META_STR_MASK,
|
||||
MetaExifUserComment = 20 | META_STR_MASK,
|
||||
MetaExifModel = 21 | META_STR_MASK,
|
||||
MetaExifIsoSpeedRatings = 22 | META_STR_MASK,
|
||||
MetaExifDateTime = 23 | META_STR_MASK,
|
||||
//Note to self: this will break after 31 entries
|
||||
};
|
||||
|
||||
#define INDEX_TYPE_BIN "binary"
|
||||
#define INDEX_TYPE_JSON "json"
|
||||
#define INDEX_VERSION_EXTERNAL "_external_v1"
|
||||
@ -64,67 +22,4 @@ typedef struct index_t {
|
||||
char path[PATH_MAX];
|
||||
} index_t;
|
||||
|
||||
typedef struct meta_line {
|
||||
struct meta_line *next;
|
||||
enum metakey key;
|
||||
union {
|
||||
unsigned long longval;
|
||||
int intval;
|
||||
char strval[0];
|
||||
};
|
||||
} meta_line_t;
|
||||
|
||||
|
||||
typedef struct document {
|
||||
unsigned char uuid[16];
|
||||
unsigned long ino;
|
||||
unsigned long size;
|
||||
unsigned int mime;
|
||||
int mtime;
|
||||
short base;
|
||||
short ext;
|
||||
meta_line_t *meta_head;
|
||||
meta_line_t *meta_tail;
|
||||
char *filepath;
|
||||
} document_t;
|
||||
|
||||
typedef struct vfile vfile_t;
|
||||
|
||||
typedef int (*read_func_t)(struct vfile *, void *buf, size_t size);
|
||||
|
||||
typedef void (*close_func_t)(struct vfile *);
|
||||
|
||||
typedef struct vfile {
|
||||
union {
|
||||
int fd;
|
||||
struct archive *arc;
|
||||
};
|
||||
|
||||
int is_fs_file;
|
||||
char *filepath;
|
||||
|
||||
read_func_t read;
|
||||
close_func_t close;
|
||||
} vfile_t;
|
||||
|
||||
typedef struct parse_job_t {
|
||||
int base;
|
||||
int ext;
|
||||
struct stat info;
|
||||
struct vfile vfile;
|
||||
uuid_t parent;
|
||||
char filepath[1];
|
||||
} parse_job_t;
|
||||
|
||||
|
||||
#define APPEND_META(doc, meta) \
|
||||
meta->next = NULL;\
|
||||
if (doc->meta_head == NULL) {\
|
||||
doc->meta_head = meta;\
|
||||
doc->meta_tail = doc->meta_head;\
|
||||
} else {\
|
||||
doc->meta_tail->next = meta;\
|
||||
doc->meta_tail = meta;\
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "util.h"
|
||||
#include "src/ctx.h"
|
||||
|
||||
#include <wordexp.h>
|
||||
#include <glib.h>
|
||||
|
||||
#define PBSTR "========================================"
|
||||
#define PBWIDTH 40
|
||||
|
||||
|
@ -2,6 +2,12 @@
|
||||
#define SIST2_UTIL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "third-party/utf8.h/utf8.h"
|
||||
|
||||
#define TEXT_BUF_FULL -1
|
||||
#define INITIAL_BUF_SIZE 1024 * 16
|
||||
|
10
third-party/libscan/.gitignore
vendored
Normal file
10
third-party/libscan/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
.idea/
|
||||
cmake_install.cmake
|
||||
Makefile
|
||||
libscan.a
|
||||
libscan.so
|
||||
*.cbp
|
||||
CMakeFiles
|
||||
CMakeCache.txt
|
||||
scan_test
|
||||
third-party/
|
12
third-party/libscan/.gitmodules
vendored
Normal file
12
third-party/libscan/.gitmodules
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
[submodule "third-party/uuid"]
|
||||
path = third-party/uuid
|
||||
url = https://github.com/certik/uuid
|
||||
[submodule "third-party/utf8.h"]
|
||||
path = third-party/utf8.h
|
||||
url = https://github.com/sheredom/utf8.h
|
||||
[submodule "third-party/libarchive"]
|
||||
path = third-party/libarchive
|
||||
url = https://github.com/libarchive/libarchive
|
||||
[submodule "third-party/zlib"]
|
||||
path = third-party/zlib
|
||||
url = https://github.com/madler/zlib
|
103
third-party/libscan/CMakeLists.txt
vendored
Normal file
103
third-party/libscan/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(scan C)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
find_package(LibArchive REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(Tesseract CONFIG REQUIRED)
|
||||
find_package(harfbuzz CONFIG REQUIRED)
|
||||
find_package(OpenJPEG CONFIG REQUIRED)
|
||||
find_package(JPEG REQUIRED)
|
||||
find_package(LibXml2 REQUIRED)
|
||||
find_package(FFMPEG REQUIRED)
|
||||
|
||||
|
||||
include(ExternalProject)
|
||||
find_program(MAKE_EXE NAMES gmake nmake make)
|
||||
ExternalProject_Add(
|
||||
mupdf
|
||||
# TODO: use master branch ?
|
||||
URL https://mupdf.com/downloads/archive/mupdf-1.16.1-source.tar.xz
|
||||
|
||||
UPDATE_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
PREFIX "third-party/ext_mupdf"
|
||||
BINARY_DIR "third-party/ext_mupdf/src/mupdf"
|
||||
|
||||
BUILD_COMMAND CFLAGS=-fPIC HAVE_CURL=no HAVE_GLUT=no ${MAKE_EXE} -j 4 --silent
|
||||
&& ar d build/release/libmupdf-third.a jutils.o jdinput.o jdmarker.o jdmaster.o
|
||||
)
|
||||
|
||||
add_library(
|
||||
scan
|
||||
libscan/util.c libscan/util.h
|
||||
libscan/scan.h
|
||||
libscan/macros.h
|
||||
|
||||
libscan/text/text.c libscan/text/text.h
|
||||
libscan/arc/arc.c libscan/arc/arc.h
|
||||
libscan/ebook/ebook.c libscan/ebook/ebook.h
|
||||
libscan/cbr/cbr.c libscan/cbr/cbr.h
|
||||
libscan/ooxml/ooxml.c libscan/ooxml/ooxml.h
|
||||
libscan/media/media.c libscan/media/media.h
|
||||
libscan/font/font.c libscan/font/font.h
|
||||
|
||||
third-party/utf8.h
|
||||
)
|
||||
|
||||
target_compile_options(
|
||||
scan
|
||||
PRIVATE
|
||||
-Werror
|
||||
-g
|
||||
)
|
||||
|
||||
add_dependencies(
|
||||
scan
|
||||
mupdf
|
||||
)
|
||||
|
||||
SET(CMAKE_C_LINK_EXECUTABLE "g++ <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
||||
|
||||
string(REGEX REPLACE "-lvdpau" "" FFMPEG_LIBRARIES "${FFMPEG_LIBRARIES}")
|
||||
string(REGEX REPLACE "-lX11" "" FFMPEG_LIBRARIES "${FFMPEG_LIBRARIES}")
|
||||
|
||||
target_link_libraries(
|
||||
scan
|
||||
|
||||
-static
|
||||
-static-libgcc
|
||||
-static-libstdc++
|
||||
|
||||
-Wl,--whole-archive
|
||||
m
|
||||
-Wl,--no-whole-archive
|
||||
|
||||
"${CMAKE_SOURCE_DIR}/third-party/ext_mupdf/src/mupdf/build/release/libmupdf.a"
|
||||
"${CMAKE_SOURCE_DIR}/third-party/ext_mupdf/src/mupdf/build/release/libmupdf-third.a"
|
||||
|
||||
${JPEG_LIBRARIES}
|
||||
${LibArchive_LIBRARIES}
|
||||
${Tesseract_LIBRARIES}
|
||||
${LIBXML2_LIBRARIES}
|
||||
${FFMPEG_LIBRARIES}
|
||||
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
|
||||
# TODO: Looks like I don't need to explicitly link to libuuid?
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
scan
|
||||
BEFORE
|
||||
PRIVATE
|
||||
"${CMAKE_SOURCE_DIR}/third-party/ext_mupdf/src/mupdf/include/"
|
||||
${JPEG_INCLUDE_DIR}
|
||||
${LIBXML2_INCLUDE_DIR}
|
||||
${FFMPEG_INCLUDE_DIR}
|
||||
)
|
7
third-party/libscan/README.md
vendored
Normal file
7
third-party/libscan/README.md
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
```bash
|
||||
vcpkg install libarchive pthread tesseract libxml2 ffmpeg
|
||||
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=/usr/share/vcpkg/scripts/buildsystems/vcpkg.cmake .
|
||||
make -j 4
|
||||
```
|
8
third-party/libscan/build.sh
vendored
Executable file
8
third-party/libscan/build.sh
vendored
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
|
||||
rm -rf CMakeFiles CMakeCache.txt
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=/usr/share/vcpkg/scripts/buildsystems/vcpkg.cmake . || exit
|
||||
make -j 4
|
@ -1,5 +1,14 @@
|
||||
#include "arc.h"
|
||||
#include "src/ctx.h"
|
||||
|
||||
#include "../scan.h"
|
||||
#include "../util.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
|
||||
int should_parse_filtered_file(const char *filepath, int ext) {
|
||||
char tmp[PATH_MAX * 2];
|
||||
@ -60,7 +69,7 @@ int vfile_close_callback(struct archive *a, void *user_data) {
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
void parse_archive(vfile_t *f, document_t *doc) {
|
||||
scan_code_t parse_archive(scan_arc_ctx_t *ctx, vfile_t *f, document_t *doc) {
|
||||
|
||||
struct archive *a;
|
||||
struct archive_entry *entry;
|
||||
@ -77,7 +86,7 @@ void parse_archive(vfile_t *f, document_t *doc) {
|
||||
archive_read_support_format_all(a);
|
||||
|
||||
ret = archive_read_open_filename(a, doc->filepath, ARC_BUF_SIZE);
|
||||
} else if (ScanCtx.archive_mode == ARC_MODE_RECURSE) {
|
||||
} else if (ctx->mode == ARC_MODE_RECURSE) {
|
||||
|
||||
a = archive_read_new();
|
||||
archive_read_support_filter_all(a);
|
||||
@ -90,16 +99,17 @@ void parse_archive(vfile_t *f, document_t *doc) {
|
||||
vfile_close_callback
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
return SCAN_OK;
|
||||
}
|
||||
|
||||
if (ret != ARCHIVE_OK) {
|
||||
LOG_ERRORF(doc->filepath, "(arc.c) [%d] %s", ret, archive_error_string(a))
|
||||
//TODO: log
|
||||
// LOG_ERRORF(doc->filepath, "(arc.c) [%d] %s", ret, archive_error_string(a))
|
||||
archive_read_free(a);
|
||||
return;
|
||||
return SCAN_ERR_READ;
|
||||
}
|
||||
|
||||
if (ScanCtx.archive_mode == ARC_MODE_LIST) {
|
||||
if (ctx->mode == ARC_MODE_LIST) {
|
||||
|
||||
dyn_buffer_t buf = dyn_buffer_create();
|
||||
|
||||
@ -116,7 +126,7 @@ void parse_archive(vfile_t *f, document_t *doc) {
|
||||
|
||||
meta_line_t *meta_list = malloc(sizeof(meta_line_t) + buf.cur);
|
||||
meta_list->key = MetaContent;
|
||||
strcpy(meta_list->strval, buf.buf);
|
||||
strcpy(meta_list->str_val, buf.buf);
|
||||
APPEND_META(doc, meta_list);
|
||||
dyn_buffer_destroy(&buf);
|
||||
|
||||
@ -144,7 +154,8 @@ void parse_archive(vfile_t *f, document_t *doc) {
|
||||
sub_job->ext = (int) strlen(sub_job->filepath);
|
||||
}
|
||||
|
||||
parse(sub_job);
|
||||
//TODO:
|
||||
// parse(sub_job);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,4 +163,5 @@ void parse_archive(vfile_t *f, document_t *doc) {
|
||||
}
|
||||
|
||||
archive_read_free(a);
|
||||
return SCAN_OK;
|
||||
}
|
26
third-party/libscan/libscan/arc/arc.h
vendored
Normal file
26
third-party/libscan/libscan/arc/arc.h
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef SCAN_ARC_H
|
||||
#define SCAN_ARC_H
|
||||
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
#include "../scan.h"
|
||||
|
||||
#define ARC_MODE_SKIP 0
|
||||
#define ARC_MODE_LIST 1
|
||||
#define ARC_MODE_SHALLOW 2
|
||||
#define ARC_MODE_RECURSE 3
|
||||
typedef int archive_mode_t;
|
||||
|
||||
typedef struct {
|
||||
archive_mode_t mode;
|
||||
} scan_arc_ctx_t;
|
||||
|
||||
#define ARC_BUF_SIZE 8192
|
||||
|
||||
int should_parse_filtered_file(const char *filepath, int ext);
|
||||
|
||||
scan_code_t parse_archive(scan_arc_ctx_t *ctx, vfile_t *f, document_t *doc);
|
||||
|
||||
int arc_read(struct vfile * f, void *buf, size_t size);
|
||||
|
||||
#endif
|
@ -1,20 +1,31 @@
|
||||
#include "cbr.h"
|
||||
#include "src/ctx.h"
|
||||
#include "../scan.h"
|
||||
#include "../util.h"
|
||||
#include "../arc/arc.h"
|
||||
#include "../ebook/ebook.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <archive.h>
|
||||
|
||||
unsigned int cbr_mime;
|
||||
unsigned int cbz_mime;
|
||||
|
||||
void cbr_init() {
|
||||
cbr_mime = mime_get_mime_by_string(ScanCtx.mime_table, "application/x-cbr");
|
||||
cbz_mime = mime_get_mime_by_string(ScanCtx.mime_table, "application/x-cbz");
|
||||
//TODO: get mime str
|
||||
// cbr_mime = mime_get_mime_by_string(ScanCtx.mime_table, "application/x-cbr");
|
||||
// cbz_mime = mime_get_mime_by_string(ScanCtx.mime_table, "application/x-cbz");
|
||||
}
|
||||
|
||||
int is_cbr(unsigned int mime) {
|
||||
return mime == cbr_mime;
|
||||
}
|
||||
|
||||
void parse_cbr(void *buf, size_t buf_len, document_t *doc) {
|
||||
char *out_buf = malloc(buf_len * 2);
|
||||
void parse_cbr(scan_cbr_ctx_t *ctx, vfile_t *f, document_t *doc) {
|
||||
|
||||
size_t buf_len;
|
||||
void *buf = read_all(f, &buf_len);
|
||||
|
||||
char *out_buf = malloc(buf_len * 2); // TODO: we probably only need 1.2x or 1.5x, even better would be a dynamic buffer
|
||||
size_t out_buf_used = 0;
|
||||
|
||||
struct archive *rar_in = archive_read_new();
|
||||
@ -46,7 +57,9 @@ void parse_cbr(void *buf, size_t buf_len, document_t *doc) {
|
||||
archive_read_free(rar_in);
|
||||
|
||||
doc->mime = cbz_mime;
|
||||
parse_pdf(out_buf, out_buf_used, doc);
|
||||
|
||||
//TODO: get mime string
|
||||
// parse_ebook(out_buf, out_buf_used, doc);
|
||||
doc->mime = cbr_mime;
|
||||
free(out_buf);
|
||||
}
|
17
third-party/libscan/libscan/cbr/cbr.h
vendored
Normal file
17
third-party/libscan/libscan/cbr/cbr.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef SCAN_CBR_H
|
||||
#define SCAN_CBR_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "../scan.h"
|
||||
|
||||
typedef struct {
|
||||
|
||||
} scan_cbr_ctx_t;
|
||||
|
||||
void cbr_init();
|
||||
|
||||
int is_cbr(unsigned int mime);
|
||||
|
||||
void parse_cbr(scan_cbr_ctx_t *ctx, vfile_t *f, document_t *doc);
|
||||
|
||||
#endif
|
334
third-party/libscan/libscan/ebook/ebook.c
vendored
Normal file
334
third-party/libscan/libscan/ebook/ebook.c
vendored
Normal file
@ -0,0 +1,334 @@
|
||||
#include "ebook.h"
|
||||
#include "../util.h"
|
||||
#include <mupdf/fitz.h>
|
||||
#include <pthread.h>
|
||||
#include <tesseract/capi.h>
|
||||
|
||||
#define MIN_OCR_SIZE 350
|
||||
#define MIN_OCR_LEN 10
|
||||
|
||||
/* fill_image callback doesn't let us pass opaque pointers unless I create my own device */
|
||||
__thread text_buffer_t thread_buffer;
|
||||
__thread scan_ebook_ctx_t thread_ctx;
|
||||
|
||||
|
||||
int render_cover(scan_ebook_ctx_t *ctx, fz_context *fzctx, document_t *doc, fz_document *fzdoc) {
|
||||
|
||||
int err = 0;
|
||||
fz_page *cover = NULL;
|
||||
|
||||
fz_var(cover);
|
||||
fz_var(err);
|
||||
fz_try(fzctx)
|
||||
cover = fz_load_page(fzctx, fzdoc, 0);
|
||||
fz_catch(fzctx)
|
||||
err = 1;
|
||||
|
||||
if (err != 0) {
|
||||
fz_drop_page(fzctx, cover);
|
||||
// LOG_WARNINGF(doc->filepath, "fz_load_page() returned error code [%d] %s", err, ctx->error.message)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fz_rect bounds = fz_bound_page(fzctx, cover);
|
||||
|
||||
float scale;
|
||||
float w = (float) bounds.x1 - bounds.x0;
|
||||
float h = (float) bounds.y1 - bounds.y0;
|
||||
if (w > h) {
|
||||
scale = (float) ctx->tn_size / w;
|
||||
} else {
|
||||
scale = (float) ctx->tn_size / h;
|
||||
}
|
||||
fz_matrix m = fz_scale(scale, scale);
|
||||
|
||||
bounds = fz_transform_rect(bounds, m);
|
||||
fz_irect bbox = fz_round_rect(bounds);
|
||||
fz_pixmap *pixmap = fz_new_pixmap_with_bbox(fzctx, fzctx->colorspace->rgb, bbox, NULL, 0);
|
||||
|
||||
fz_clear_pixmap_with_value(fzctx, pixmap, 0xFF);
|
||||
fz_device *dev = fz_new_draw_device(fzctx, m, pixmap);
|
||||
|
||||
fz_var(err);
|
||||
fz_try(fzctx)
|
||||
{
|
||||
pthread_mutex_lock(&ctx->mupdf_mutex);
|
||||
fz_run_page(fzctx, cover, dev, fz_identity, NULL);
|
||||
}
|
||||
fz_always(fzctx)
|
||||
{
|
||||
fz_close_device(fzctx, dev);
|
||||
fz_drop_device(fzctx, dev);
|
||||
pthread_mutex_unlock(&ctx->mupdf_mutex);
|
||||
}
|
||||
fz_catch(fzctx)
|
||||
err = fzctx->error.errcode;
|
||||
|
||||
if (err != 0) {
|
||||
// LOG_WARNINGF(doc->filepath, "fz_run_page() returned error code [%d] %s", err, ctx->error.message)
|
||||
fz_drop_page(fzctx, cover);
|
||||
fz_drop_pixmap(fzctx, pixmap);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fz_buffer *fzbuf = NULL;
|
||||
fz_var(fzbuf);
|
||||
fz_var(err);
|
||||
|
||||
fz_try(fzctx)
|
||||
fzbuf = fz_new_buffer_from_pixmap_as_png(fzctx, pixmap, fz_default_color_params);
|
||||
fz_catch(fzctx)
|
||||
err = fzctx->error.errcode;
|
||||
|
||||
if (err == 0) {
|
||||
unsigned char *tn_buf;
|
||||
size_t tn_len = fz_buffer_storage(fzctx, fzbuf, &tn_buf);
|
||||
// store_write(ScanCtx.index.store, (char *) doc->uuid, sizeof(doc->uuid), (char *) tn_buf, tn_len);
|
||||
}
|
||||
|
||||
fz_drop_buffer(fzctx, fzbuf);
|
||||
fz_drop_pixmap(fzctx, pixmap);
|
||||
fz_drop_page(fzctx, cover);
|
||||
|
||||
if (err != 0) {
|
||||
// LOG_WARNINGF(doc->filepath, "fz_new_buffer_from_pixmap_as_png() returned error code [%d] %s", err,
|
||||
// ctx->error.message)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void fz_err_callback(void *user, UNUSED(const char *message)) {
|
||||
// if (LogCtx.verbose) {
|
||||
// document_t *doc = (document_t *) user;
|
||||
// LOG_WARNINGF(doc->filepath, "FZ: %s", message)
|
||||
// }
|
||||
}
|
||||
|
||||
static void init_fzctx(fz_context *fzctx, document_t *doc) {
|
||||
fz_disable_icc(fzctx);
|
||||
fz_register_document_handlers(fzctx);
|
||||
|
||||
fzctx->warn.print_user = doc;
|
||||
fzctx->warn.print = fz_err_callback;
|
||||
fzctx->error.print_user = doc;
|
||||
fzctx->error.print = fz_err_callback;
|
||||
}
|
||||
|
||||
static int read_stext_block(fz_stext_block *block, text_buffer_t *tex) {
|
||||
if (block->type != FZ_STEXT_BLOCK_TEXT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fz_stext_line *line = block->u.t.first_line;
|
||||
while (line != NULL) {
|
||||
fz_stext_char *c = line->first_char;
|
||||
while (c != NULL) {
|
||||
if (text_buffer_append_char(tex, c->c) == TEXT_BUF_FULL) {
|
||||
return TEXT_BUF_FULL;
|
||||
}
|
||||
c = c->next;
|
||||
}
|
||||
line = line->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define IS_VALID_BPP(d) (d==1 || d==2 || d==4 || d==8 || d==16 || d==24 || d==32)
|
||||
|
||||
void fill_image(fz_context *fzctx, UNUSED(fz_device *dev),
|
||||
fz_image *img, UNUSED(fz_matrix ctm), UNUSED(float alpha),
|
||||
UNUSED(fz_color_params color_params)) {
|
||||
|
||||
int l2factor = 0;
|
||||
|
||||
if (img->w > MIN_OCR_SIZE && img->h > MIN_OCR_SIZE && IS_VALID_BPP(img->n)) {
|
||||
|
||||
fz_pixmap *pix = img->get_pixmap(fzctx, img, NULL, img->w, img->h, &l2factor);
|
||||
|
||||
if (pix->h > MIN_OCR_SIZE && img->h > MIN_OCR_SIZE && img->xres != 0) {
|
||||
TessBaseAPI *api = TessBaseAPICreate();
|
||||
TessBaseAPIInit3(api, thread_ctx.tesseract_path, thread_ctx.tesseract_lang);
|
||||
|
||||
TessBaseAPISetImage(api, pix->samples, pix->w, pix->h, pix->n, pix->stride);
|
||||
TessBaseAPISetSourceResolution(api, pix->xres);
|
||||
|
||||
char *text = TessBaseAPIGetUTF8Text(api);
|
||||
size_t len = strlen(text);
|
||||
if (len >= MIN_OCR_LEN) {
|
||||
text_buffer_append_string(&thread_buffer, text, len - 1);
|
||||
// LOG_DEBUGF(
|
||||
// "ebook.c",
|
||||
// "(OCR) %dx%d got %dB from tesseract (%s), buffer:%dB",
|
||||
// pix->w, pix->h, len, ScanCtx.tesseract_lang, thread_buffer.dyn_buffer.cur
|
||||
// )
|
||||
}
|
||||
|
||||
TessBaseAPIEnd(api);
|
||||
TessBaseAPIDelete(api);
|
||||
}
|
||||
fz_drop_pixmap(fzctx, pix);
|
||||
}
|
||||
}
|
||||
|
||||
void parse_ebook(scan_ebook_ctx_t *ctx, vfile_t *f, const char* mime_str, document_t *doc) {
|
||||
|
||||
size_t buf_len;
|
||||
void * buf = read_all(f, &buf_len);
|
||||
|
||||
static int mu_is_initialized = 0;
|
||||
if (!mu_is_initialized) {
|
||||
pthread_mutex_init(&ctx->mupdf_mutex, NULL);
|
||||
mu_is_initialized = 1;
|
||||
}
|
||||
fz_context *fzctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
|
||||
|
||||
init_fzctx(fzctx, doc);
|
||||
|
||||
int err = 0;
|
||||
|
||||
fz_document *fzdoc = NULL;
|
||||
fz_stream *stream = NULL;
|
||||
fz_var(fzdoc);
|
||||
fz_var(stream);
|
||||
fz_var(err);
|
||||
|
||||
fz_try(fzctx)
|
||||
{
|
||||
stream = fz_open_memory(fzctx, buf, buf_len);
|
||||
fzdoc = fz_open_document_with_stream(fzctx, mime_str, stream);
|
||||
}
|
||||
fz_catch(fzctx)
|
||||
err = fzctx->error.errcode;
|
||||
|
||||
if (err != 0) {
|
||||
fz_drop_stream(fzctx, stream);
|
||||
fz_drop_document(fzctx, fzdoc);
|
||||
fz_drop_context(fzctx);
|
||||
return;
|
||||
}
|
||||
|
||||
char title[4096] = {'\0',};
|
||||
fz_try(fzctx)
|
||||
fz_lookup_metadata(fzctx, fzdoc, FZ_META_INFO_TITLE, title, sizeof(title));
|
||||
fz_catch(fzctx)
|
||||
;
|
||||
|
||||
if (strlen(title) > 0) {
|
||||
meta_line_t *meta_content = malloc(sizeof(meta_line_t) + strlen(title));
|
||||
meta_content->key = MetaTitle;
|
||||
strcpy(meta_content->str_val, title);
|
||||
APPEND_META(doc, meta_content)
|
||||
}
|
||||
|
||||
int page_count = -1;
|
||||
fz_var(err);
|
||||
fz_try(fzctx)
|
||||
page_count = fz_count_pages(fzctx, fzdoc);
|
||||
fz_catch(fzctx)
|
||||
err = fzctx->error.errcode;
|
||||
|
||||
if (err) {
|
||||
// LOG_WARNINGF(doc->filepath, "fz_count_pages() returned error code [%d] %s", err, ctx->error.message)
|
||||
fz_drop_stream(fzctx, stream);
|
||||
fz_drop_document(fzctx, fzdoc);
|
||||
fz_drop_context(fzctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->tn_size > 0) {
|
||||
err = render_cover(ctx, fzctx, doc, fzdoc);
|
||||
}
|
||||
|
||||
if (err == TRUE) {
|
||||
fz_drop_stream(fzctx, stream);
|
||||
fz_drop_document(fzctx, fzdoc);
|
||||
fz_drop_context(fzctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->content_size > 0) {
|
||||
fz_stext_options opts = {0};
|
||||
thread_buffer = text_buffer_create(ctx->content_size);
|
||||
|
||||
for (int current_page = 0; current_page < page_count; current_page++) {
|
||||
fz_page *page = NULL;
|
||||
fz_var(err);
|
||||
fz_try(fzctx)
|
||||
page = fz_load_page(fzctx, fzdoc, current_page);
|
||||
fz_catch(fzctx)
|
||||
err = fzctx->error.errcode;
|
||||
if (err != 0) {
|
||||
// LOG_WARNINGF(doc->filepath, "fz_load_page() returned error code [%d] %s", err, ctx->error.message)
|
||||
text_buffer_destroy(&thread_buffer);
|
||||
fz_drop_page(fzctx, page);
|
||||
fz_drop_stream(fzctx, stream);
|
||||
fz_drop_document(fzctx, fzdoc);
|
||||
fz_drop_context(fzctx);
|
||||
return;
|
||||
}
|
||||
|
||||
fz_stext_page *stext = fz_new_stext_page(fzctx, fz_bound_page(fzctx, page));
|
||||
fz_device *dev = fz_new_stext_device(fzctx, stext, &opts);
|
||||
dev->stroke_path = NULL;
|
||||
dev->stroke_text = NULL;
|
||||
dev->clip_text = NULL;
|
||||
dev->clip_stroke_path = NULL;
|
||||
dev->clip_stroke_text = NULL;
|
||||
|
||||
if (ctx->tesseract_lang!= NULL) {
|
||||
dev->fill_image = fill_image;
|
||||
}
|
||||
|
||||
fz_var(err);
|
||||
fz_try(fzctx)
|
||||
fz_run_page(fzctx, page, dev, fz_identity, NULL);
|
||||
fz_always(fzctx)
|
||||
{
|
||||
fz_close_device(fzctx, dev);
|
||||
fz_drop_device(fzctx, dev);
|
||||
}
|
||||
fz_catch(fzctx)
|
||||
err = fzctx->error.errcode;
|
||||
|
||||
if (err != 0) {
|
||||
// LOG_WARNINGF(doc->filepath, "fz_run_page() returned error code [%d] %s", err, ctx->error.message)
|
||||
text_buffer_destroy(&thread_buffer);
|
||||
fz_drop_page(fzctx, page);
|
||||
fz_drop_stext_page(fzctx, stext);
|
||||
fz_drop_stream(fzctx, stream);
|
||||
fz_drop_document(fzctx, fzdoc);
|
||||
fz_drop_context(fzctx);
|
||||
return;
|
||||
}
|
||||
|
||||
fz_stext_block *block = stext->first_block;
|
||||
while (block != NULL) {
|
||||
int ret = read_stext_block(block, &thread_buffer);
|
||||
if (ret == TEXT_BUF_FULL) {
|
||||
break;
|
||||
}
|
||||
block = block->next;
|
||||
}
|
||||
fz_drop_stext_page(fzctx, stext);
|
||||
fz_drop_page(fzctx, page);
|
||||
|
||||
if (thread_buffer.dyn_buffer.cur >= thread_buffer.dyn_buffer.size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
text_buffer_terminate_string(&thread_buffer);
|
||||
|
||||
meta_line_t *meta_content = malloc(sizeof(meta_line_t) + thread_buffer.dyn_buffer.cur);
|
||||
meta_content->key = MetaContent;
|
||||
memcpy(meta_content->str_val, thread_buffer.dyn_buffer.buf, thread_buffer.dyn_buffer.cur);
|
||||
APPEND_META(doc, meta_content)
|
||||
|
||||
text_buffer_destroy(&thread_buffer);
|
||||
}
|
||||
|
||||
fz_drop_stream(fzctx, stream);
|
||||
fz_drop_document(fzctx, fzdoc);
|
||||
fz_drop_context(fzctx);
|
||||
}
|
16
third-party/libscan/libscan/ebook/ebook.h
vendored
Normal file
16
third-party/libscan/libscan/ebook/ebook.h
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef SCAN_EBOOK_H
|
||||
#define SCAN_EBOOK_H
|
||||
|
||||
#include "../scan.h"
|
||||
|
||||
typedef struct {
|
||||
long content_size;
|
||||
int tn_size;
|
||||
const char *tesseract_lang;
|
||||
const char *tesseract_path;
|
||||
pthread_mutex_t mupdf_mutex;
|
||||
} scan_ebook_ctx_t;
|
||||
|
||||
void parse_ebook(scan_ebook_ctx_t *ctx, vfile_t *f, const char* mime_str, document_t *doc);
|
||||
|
||||
#endif
|
@ -1,7 +1,9 @@
|
||||
#include "font.h"
|
||||
|
||||
#include <ft2build.h>
|
||||
#include <freetype/freetype.h>
|
||||
#include "../util.h"
|
||||
|
||||
#include "src/ctx.h"
|
||||
|
||||
__thread FT_Library ft_lib = NULL;
|
||||
|
||||
@ -136,19 +138,18 @@ void bmp_format(dyn_buffer_t *buf, text_dimensions_t dimensions, const unsigned
|
||||
*(int *) ((char *) buf->buf + 2) = buf->cur;
|
||||
}
|
||||
|
||||
void parse_font(const char *buf, size_t buf_len, document_t *doc) {
|
||||
void parse_font(scan_font_cxt_t *ctx, vfile_t *f, document_t *doc) {
|
||||
if (ft_lib == NULL) {
|
||||
FT_Init_FreeType(&ft_lib);
|
||||
}
|
||||
|
||||
if (buf == NULL) {
|
||||
return;
|
||||
}
|
||||
size_t buf_len;
|
||||
void * buf = read_all(f, &buf_len);
|
||||
|
||||
FT_Face face;
|
||||
FT_Error err = FT_New_Memory_Face(ft_lib, (unsigned char *) buf, buf_len, 0, &face);
|
||||
if (err != 0) {
|
||||
LOG_ERRORF(doc->filepath, "(font.c) FT_New_Memory_Face() returned error code [%d] %s", err, ft_error_string(err));
|
||||
// LOG_ERRORF(doc->filepath, "(font.c) FT_New_Memory_Face() returned error code [%d] %s", err, ft_error_string(err));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -166,10 +167,10 @@ void parse_font(const char *buf, size_t buf_len, document_t *doc) {
|
||||
|
||||
meta_line_t *meta_name = malloc(sizeof(meta_line_t) + strlen(font_name));
|
||||
meta_name->key = MetaFontName;
|
||||
strcpy(meta_name->strval, font_name);
|
||||
strcpy(meta_name->str_val, font_name);
|
||||
APPEND_META(doc, meta_name)
|
||||
|
||||
if (ScanCtx.tn_size <= 0) {
|
||||
if (ctx->enable_tn == TRUE) {
|
||||
FT_Done_Face(face);
|
||||
return;
|
||||
}
|
||||
@ -179,7 +180,7 @@ void parse_font(const char *buf, size_t buf_len, document_t *doc) {
|
||||
|
||||
err = FT_Set_Pixel_Sizes(face, 0, pixel);
|
||||
if (err != 0) {
|
||||
LOG_WARNINGF(doc->filepath, "(font.c) FT_Set_Pixel_Sizes() returned error code [%d] %s", err, ft_error_string(err))
|
||||
// LOG_WARNINGF(doc->filepath, "(font.c) FT_Set_Pixel_Sizes() returned error code [%d] %s", err, ft_error_string(err))
|
||||
FT_Done_Face(face);
|
||||
return;
|
||||
}
|
||||
@ -199,7 +200,7 @@ void parse_font(const char *buf, size_t buf_len, document_t *doc) {
|
||||
c = c >= 'a' && c <= 'z' ? c - 32 : c + 32;
|
||||
err = FT_Load_Char(face, c, FT_LOAD_NO_HINTING | FT_LOAD_RENDER);
|
||||
if (err != 0) {
|
||||
LOG_WARNINGF(doc->filepath, "(font.c) FT_Load_Char() returned error code [%d] %s", err, ft_error_string(err));
|
||||
// LOG_WARNINGF(doc->filepath, "(font.c) FT_Load_Char() returned error code [%d] %s", err, ft_error_string(err));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -220,7 +221,7 @@ void parse_font(const char *buf, size_t buf_len, document_t *doc) {
|
||||
dyn_buffer_t bmp_data = dyn_buffer_create();
|
||||
bmp_format(&bmp_data, dimensions, bitmap);
|
||||
|
||||
store_write(ScanCtx.index.store, (char *) doc->uuid, sizeof(doc->uuid), (char *) bmp_data.buf, bmp_data.cur);
|
||||
// store_write(ScanCtx.index.store, (char *) doc->uuid, sizeof(doc->uuid), (char *) bmp_data.buf, bmp_data.cur);
|
||||
|
||||
dyn_buffer_destroy(&bmp_data);
|
||||
free(bitmap);
|
14
third-party/libscan/libscan/font/font.h
vendored
Normal file
14
third-party/libscan/libscan/font/font.h
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef SCAN_FONT_H
|
||||
#define SCAN_FONT_H
|
||||
|
||||
#include "../scan.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
int enable_tn;
|
||||
} scan_font_cxt_t;
|
||||
|
||||
void parse_font(scan_font_cxt_t *ctx, vfile_t *f, document_t *doc);
|
||||
void cleanup_font();
|
||||
|
||||
#endif
|
21
third-party/libscan/libscan/macros.h
vendored
Normal file
21
third-party/libscan/libscan/macros.h
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef FALSE
|
||||
#define FALSE (0)
|
||||
#define BOOL int
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
#undef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#undef ABS
|
||||
#define ABS(a) (((a) < 0) ? -(a) : (a))
|
@ -1,5 +1,14 @@
|
||||
#include "src/sist.h"
|
||||
#include "src/ctx.h"
|
||||
#include "media.h"
|
||||
|
||||
#include "../util.h"
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libswresample/swresample.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#define MIN_SIZE 32
|
||||
#define AVIO_BUF_SIZE 8192
|
||||
@ -92,10 +101,10 @@ static AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder,
|
||||
|
||||
if (read_frame_ret != 0) {
|
||||
if (read_frame_ret != AVERROR_EOF) {
|
||||
LOG_WARNINGF(doc->filepath,
|
||||
"(media.c) avcodec_read_frame() returned error code [%d] %s",
|
||||
read_frame_ret, av_err2str(read_frame_ret)
|
||||
)
|
||||
// LOG_WARNINGF(doc->filepath,
|
||||
// "(media.c) avcodec_read_frame() returned error code [%d] %s",
|
||||
// read_frame_ret, av_err2str(read_frame_ret)
|
||||
// )
|
||||
}
|
||||
av_frame_free(&frame);
|
||||
av_packet_unref(&avPacket);
|
||||
@ -113,10 +122,10 @@ static AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder,
|
||||
// Feed it to decoder
|
||||
int decode_ret = avcodec_send_packet(decoder, &avPacket);
|
||||
if (decode_ret != 0) {
|
||||
LOG_ERRORF(doc->filepath,
|
||||
"(media.c) avcodec_send_packet() returned error code [%d] %s",
|
||||
decode_ret, av_err2str(decode_ret)
|
||||
)
|
||||
// LOG_ERRORF(doc->filepath,
|
||||
// "(media.c) avcodec_send_packet() returned error code [%d] %s",
|
||||
// decode_ret, av_err2str(decode_ret)
|
||||
// )
|
||||
av_frame_free(&frame);
|
||||
av_packet_unref(&avPacket);
|
||||
return NULL;
|
||||
@ -133,7 +142,7 @@ static AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder,
|
||||
text_buffer_terminate_string(&tex); \
|
||||
meta_line_t *meta_tag = malloc(sizeof(meta_line_t) + tex.dyn_buffer.cur); \
|
||||
meta_tag->key = keyname; \
|
||||
strcpy(meta_tag->strval, tex.dyn_buffer.buf); \
|
||||
strcpy(meta_tag->str_val, tex.dyn_buffer.buf); \
|
||||
APPEND_META(doc, meta_tag) \
|
||||
text_buffer_destroy(&tex);
|
||||
|
||||
@ -169,12 +178,12 @@ append_video_meta(AVFormatContext *pFormatCtx, AVFrame *frame, document_t *doc,
|
||||
if (is_video) {
|
||||
meta_line_t *meta_duration = malloc(sizeof(meta_line_t));
|
||||
meta_duration->key = MetaMediaDuration;
|
||||
meta_duration->longval = pFormatCtx->duration / AV_TIME_BASE;
|
||||
meta_duration->long_val = pFormatCtx->duration / AV_TIME_BASE;
|
||||
APPEND_META(doc, meta_duration)
|
||||
|
||||
meta_line_t *meta_bitrate = malloc(sizeof(meta_line_t));
|
||||
meta_bitrate->key = MetaMediaBitrate;
|
||||
meta_bitrate->longval = pFormatCtx->bit_rate;
|
||||
meta_bitrate->long_val = pFormatCtx->bit_rate;
|
||||
APPEND_META(doc, meta_bitrate)
|
||||
}
|
||||
|
||||
@ -219,7 +228,7 @@ append_video_meta(AVFormatContext *pFormatCtx, AVFrame *frame, document_t *doc,
|
||||
}
|
||||
}
|
||||
|
||||
void parse_media(AVFormatContext *pFormatCtx, document_t *doc) {
|
||||
void parse_media_format_ctx(scan_media_ctx_t *ctx, AVFormatContext *pFormatCtx, document_t *doc) {
|
||||
|
||||
int video_stream = -1;
|
||||
int audio_stream = -1;
|
||||
@ -233,7 +242,7 @@ void parse_media(AVFormatContext *pFormatCtx, document_t *doc) {
|
||||
if (audio_stream == -1) {
|
||||
meta_line_t *meta_audio = malloc(sizeof(meta_line_t));
|
||||
meta_audio->key = MetaMediaAudioCodec;
|
||||
meta_audio->intval = stream->codecpar->codec_id;
|
||||
meta_audio->int_val = stream->codecpar->codec_id;
|
||||
APPEND_META(doc, meta_audio)
|
||||
|
||||
append_audio_meta(pFormatCtx, doc);
|
||||
@ -244,17 +253,17 @@ void parse_media(AVFormatContext *pFormatCtx, document_t *doc) {
|
||||
if (video_stream == -1) {
|
||||
meta_line_t *meta_vid = malloc(sizeof(meta_line_t));
|
||||
meta_vid->key = MetaMediaVideoCodec;
|
||||
meta_vid->intval = stream->codecpar->codec_id;
|
||||
meta_vid->int_val = stream->codecpar->codec_id;
|
||||
APPEND_META(doc, meta_vid)
|
||||
|
||||
meta_line_t *meta_w = malloc(sizeof(meta_line_t));
|
||||
meta_w->key = MetaWidth;
|
||||
meta_w->intval = stream->codecpar->width;
|
||||
meta_w->int_val = stream->codecpar->width;
|
||||
APPEND_META(doc, meta_w)
|
||||
|
||||
meta_line_t *meta_h = malloc(sizeof(meta_line_t));
|
||||
meta_h->key = MetaHeight;
|
||||
meta_h->intval = stream->codecpar->height;
|
||||
meta_h->int_val = stream->codecpar->height;
|
||||
APPEND_META(doc, meta_h)
|
||||
|
||||
video_stream = i;
|
||||
@ -262,7 +271,7 @@ void parse_media(AVFormatContext *pFormatCtx, document_t *doc) {
|
||||
}
|
||||
}
|
||||
|
||||
if (video_stream != -1 && ScanCtx.tn_size > 0) {
|
||||
if (video_stream != -1 && ctx->tn_size > 0) {
|
||||
AVStream *stream = pFormatCtx->streams[video_stream];
|
||||
|
||||
if (stream->codecpar->width <= MIN_SIZE || stream->codecpar->height <= MIN_SIZE) {
|
||||
@ -300,7 +309,7 @@ void parse_media(AVFormatContext *pFormatCtx, document_t *doc) {
|
||||
append_video_meta(pFormatCtx, frame, doc, audio_stream == -1, stream->nb_frames > 1);
|
||||
|
||||
// Scale frame
|
||||
AVFrame *scaled_frame = scale_frame(decoder, frame, ScanCtx.tn_size);
|
||||
AVFrame *scaled_frame = scale_frame(decoder, frame, ctx->tn_size);
|
||||
|
||||
if (scaled_frame == NULL) {
|
||||
av_frame_free(&frame);
|
||||
@ -311,7 +320,7 @@ void parse_media(AVFormatContext *pFormatCtx, document_t *doc) {
|
||||
}
|
||||
|
||||
// Encode frame to jpeg
|
||||
AVCodecContext *jpeg_encoder = alloc_jpeg_encoder(scaled_frame->width, scaled_frame->height, ScanCtx.tn_qscale);
|
||||
AVCodecContext *jpeg_encoder = alloc_jpeg_encoder(scaled_frame->width, scaled_frame->height, ctx->tn_qscale);
|
||||
avcodec_send_frame(jpeg_encoder, scaled_frame);
|
||||
|
||||
AVPacket jpeg_packet;
|
||||
@ -319,8 +328,8 @@ void parse_media(AVFormatContext *pFormatCtx, document_t *doc) {
|
||||
avcodec_receive_packet(jpeg_encoder, &jpeg_packet);
|
||||
|
||||
// Save thumbnail
|
||||
store_write(ScanCtx.index.store, (char *) doc->uuid, sizeof(doc->uuid), (char *) jpeg_packet.data,
|
||||
jpeg_packet.size);
|
||||
// store_write(ScanCtx.index.store, (char *) doc->uuid, sizeof(doc->uuid), (char *) jpeg_packet.data,
|
||||
// jpeg_packet.size);
|
||||
|
||||
av_packet_unref(&jpeg_packet);
|
||||
av_frame_free(&frame);
|
||||
@ -334,22 +343,22 @@ void parse_media(AVFormatContext *pFormatCtx, document_t *doc) {
|
||||
avformat_free_context(pFormatCtx);
|
||||
}
|
||||
|
||||
void parse_media_filename(const char *filepath, document_t *doc) {
|
||||
void parse_media_filename(scan_media_ctx_t *ctx, const char *filepath, document_t *doc) {
|
||||
|
||||
AVFormatContext *pFormatCtx = avformat_alloc_context();
|
||||
if (pFormatCtx == NULL) {
|
||||
LOG_ERROR(doc->filepath, "(media.c) Could not allocate context with avformat_alloc_context()")
|
||||
// LOG_ERROR(doc->filepath, "(media.c) Could not allocate context with avformat_alloc_context()")
|
||||
return;
|
||||
}
|
||||
int res = avformat_open_input(&pFormatCtx, filepath, NULL, NULL);
|
||||
if (res < 0) {
|
||||
LOG_ERRORF(doc->filepath, "(media.c) avformat_open_input() returned [%d] %s", res, av_err2str(res))
|
||||
// LOG_ERRORF(doc->filepath, "(media.c) avformat_open_input() returned [%d] %s", res, av_err2str(res))
|
||||
avformat_close_input(&pFormatCtx);
|
||||
avformat_free_context(pFormatCtx);
|
||||
return;
|
||||
}
|
||||
|
||||
parse_media(pFormatCtx, doc);
|
||||
parse_media_format_ctx(ctx, pFormatCtx, doc);
|
||||
}
|
||||
|
||||
|
||||
@ -364,11 +373,11 @@ int vfile_read(void *ptr, uint8_t *buf, int buf_size) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void parse_media_vfile(struct vfile *f, document_t *doc) {
|
||||
void parse_media_vfile(scan_media_ctx_t *ctx, struct vfile *f, document_t *doc) {
|
||||
|
||||
AVFormatContext *pFormatCtx = avformat_alloc_context();
|
||||
if (pFormatCtx == NULL) {
|
||||
LOG_ERROR(doc->filepath, "(media.c) Could not allocate context with avformat_alloc_context()")
|
||||
// LOG_ERROR(doc->filepath, "(media.c) Could not allocate context with avformat_alloc_context()")
|
||||
return;
|
||||
}
|
||||
|
||||
@ -387,7 +396,7 @@ void parse_media_vfile(struct vfile *f, document_t *doc) {
|
||||
avformat_free_context(pFormatCtx);
|
||||
return;
|
||||
} else if (res < 0) {
|
||||
LOG_ERRORF(doc->filepath, "(media.c) avformat_open_input() returned [%d] %s", res, av_err2str(res))
|
||||
// LOG_ERRORF(doc->filepath, "(media.c) avformat_open_input() returned [%d] %s", res, av_err2str(res))
|
||||
av_free(io_ctx->buffer);
|
||||
avio_context_free(&io_ctx);
|
||||
avformat_close_input(&pFormatCtx);
|
||||
@ -395,8 +404,16 @@ void parse_media_vfile(struct vfile *f, document_t *doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
parse_media(pFormatCtx, doc);
|
||||
parse_media_format_ctx(ctx, pFormatCtx, doc);
|
||||
av_free(io_ctx->buffer);
|
||||
avio_context_free(&io_ctx);
|
||||
}
|
||||
|
||||
void parse_media(scan_media_ctx_t *ctx, vfile_t *f, document_t *doc) {
|
||||
|
||||
if (f->is_fs_file) {
|
||||
parse_media_filename(ctx, f->filepath, doc);
|
||||
} else {
|
||||
parse_media_vfile(ctx, f, doc);
|
||||
}
|
||||
}
|
18
third-party/libscan/libscan/media/media.h
vendored
Normal file
18
third-party/libscan/libscan/media/media.h
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef SIST2_MEDIA_H
|
||||
#define SIST2_MEDIA_H
|
||||
|
||||
|
||||
#include "../scan.h"
|
||||
|
||||
#define MIN_VIDEO_SIZE 1024 * 64
|
||||
#define MIN_IMAGE_SIZE 1024 * 2
|
||||
|
||||
typedef struct {
|
||||
long content_size;
|
||||
int tn_size;
|
||||
float tn_qscale;
|
||||
} scan_media_ctx_t;
|
||||
|
||||
void parse_media(scan_media_ctx_t *ctx, vfile_t *f, document_t *doc);
|
||||
|
||||
#endif
|
@ -1,13 +1,15 @@
|
||||
#include "doc.h"
|
||||
#include "src/ctx.h"
|
||||
#include "ooxml.h"
|
||||
|
||||
|
||||
#define STR_STARTS_WITH(x, y) (strncmp(y, x, sizeof(y) - 1) == 0)
|
||||
#include "../util.h"
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
#include <libxml/xmlstring.h>
|
||||
#include <libxml/parser.h>
|
||||
|
||||
__always_inline
|
||||
static int should_read_part(const char *part) {
|
||||
|
||||
LOG_DEBUGF("doc.c", "Got part : %s", part)
|
||||
// LOG_DEBUGF("ooxml.c", "Got part : %s", part)
|
||||
|
||||
if (part == NULL) {
|
||||
return FALSE;
|
||||
@ -38,10 +40,10 @@ int extract_text(xmlDoc *xml, xmlNode *node, text_buffer_t *buf) {
|
||||
xmlErrorPtr err = xmlGetLastError();
|
||||
if (err != NULL) {
|
||||
if (err->level == XML_ERR_FATAL) {
|
||||
LOG_ERRORF("doc.c", "Got fatal XML error while parsing document: %s", err->message)
|
||||
// LOG_ERRORF("ooxml.c", "Got fatal XML error while parsing document: %s", err->message)
|
||||
return -1;
|
||||
} else {
|
||||
LOG_ERRORF("doc.c", "Got recoverable XML error while parsing document: %s", err->message)
|
||||
// LOG_ERRORF("ooxml.c", "Got recoverable XML error while parsing document: %s", err->message)
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,13 +79,13 @@ static int read_part(struct archive *a, text_buffer_t *buf, document_t *doc) {
|
||||
xmlDoc *xml = xmlReadIO(xml_io_read, xml_io_close, a, "/", NULL, XML_PARSE_RECOVER | XML_PARSE_NOWARNING | XML_PARSE_NOERROR | XML_PARSE_NONET);
|
||||
|
||||
if (xml == NULL) {
|
||||
LOG_ERROR(doc->filepath, "Could not parse XML")
|
||||
// LOG_ERROR(doc->filepath, "Could not parse XML")
|
||||
return -1;
|
||||
}
|
||||
|
||||
xmlNode *root = xmlDocGetRootElement(xml);
|
||||
if (root == NULL) {
|
||||
LOG_ERROR(doc->filepath, "Empty document")
|
||||
// LOG_ERROR(doc->filepath, "Empty document")
|
||||
xmlFreeDoc(xml);
|
||||
return -1;
|
||||
}
|
||||
@ -94,23 +96,22 @@ static int read_part(struct archive *a, text_buffer_t *buf, document_t *doc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void parse_doc(void *mem, size_t mem_len, document_t *doc) {
|
||||
void parse_doc(scan_ooxml_cxt_t *ctx, vfile_t *f, document_t *doc) {
|
||||
|
||||
if (mem == NULL) {
|
||||
return;
|
||||
}
|
||||
size_t buf_len;
|
||||
void * buf = read_all(f, &buf_len);
|
||||
|
||||
struct archive *a = archive_read_new();
|
||||
archive_read_support_format_zip(a);
|
||||
|
||||
int ret = archive_read_open_memory(a, mem, mem_len);
|
||||
int ret = archive_read_open_memory(a, buf, buf_len);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
LOG_ERRORF(doc->filepath, "Could not read archive: %s", archive_error_string(a))
|
||||
// LOG_ERRORF(doc->filepath, "Could not read archive: %s", archive_error_string(a))
|
||||
archive_read_free(a);
|
||||
return;
|
||||
}
|
||||
|
||||
text_buffer_t buf = text_buffer_create(ScanCtx.content_size);
|
||||
text_buffer_t tex = text_buffer_create(ctx->content_size);
|
||||
|
||||
struct archive_entry *entry;
|
||||
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
|
||||
@ -118,7 +119,7 @@ void parse_doc(void *mem, size_t mem_len, document_t *doc) {
|
||||
const char *path = archive_entry_pathname(entry);
|
||||
|
||||
if (should_read_part(path)) {
|
||||
ret = read_part(a, &buf, doc);
|
||||
ret = read_part(a, &tex, doc);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
@ -126,16 +127,16 @@ void parse_doc(void *mem, size_t mem_len, document_t *doc) {
|
||||
}
|
||||
}
|
||||
|
||||
if (buf.dyn_buffer.cur > 0) {
|
||||
text_buffer_terminate_string(&buf);
|
||||
if (tex.dyn_buffer.cur > 0) {
|
||||
text_buffer_terminate_string(&tex);
|
||||
|
||||
meta_line_t *meta = malloc(sizeof(meta_line_t) + buf.dyn_buffer.cur);
|
||||
meta_line_t *meta = malloc(sizeof(meta_line_t) + tex.dyn_buffer.cur);
|
||||
meta->key = MetaContent;
|
||||
strcpy(meta->strval, buf.dyn_buffer.buf);
|
||||
strcpy(meta->str_val, tex.dyn_buffer.buf);
|
||||
APPEND_META(doc, meta)
|
||||
}
|
||||
|
||||
archive_read_close(a);
|
||||
archive_read_free(a);
|
||||
text_buffer_destroy(&buf);
|
||||
text_buffer_destroy(&tex);
|
||||
}
|
13
third-party/libscan/libscan/ooxml/ooxml.h
vendored
Normal file
13
third-party/libscan/libscan/ooxml/ooxml.h
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef SCAN_OOXML_H
|
||||
#define SCAN_OOXML_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "../scan.h"
|
||||
|
||||
typedef struct {
|
||||
long content_size;
|
||||
} scan_ooxml_cxt_t;
|
||||
|
||||
void parse_doc(scan_ooxml_cxt_t *ctx, vfile_t *f, document_t *doc);
|
||||
|
||||
#endif
|
131
third-party/libscan/libscan/scan.h
vendored
Normal file
131
third-party/libscan/libscan/scan.h
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
#ifndef SCAN_SCAN_H
|
||||
#define SCAN_SCAN_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
|
||||
#define META_INT_MASK 0x80
|
||||
#define META_STR_MASK 0x40
|
||||
#define META_LONG_MASK 0x20
|
||||
|
||||
#define UNUSED(x) __attribute__((__unused__)) x
|
||||
|
||||
#define META_STR(id) ((unsigned) id) | ((unsigned) META_STR_MASK)
|
||||
#define META_INT(id) ((unsigned) id) | ((unsigned) META_INT_MASK)
|
||||
#define META_LONG(id) ((unsigned) id) | ((unsigned) META_LONG_MASK)
|
||||
|
||||
#define IS_META_INT(key) (key & META_INT_MASK) == META_INT_MASK
|
||||
#define IS_META_LONG(key) (key & META_LONG_MASK) == META_LONG_MASK
|
||||
#define IS_META_STR(meta) (meta->key & META_STR_MASK) == META_STR_MASK
|
||||
|
||||
|
||||
typedef int scan_code_t;
|
||||
#define SCAN_OK (scan_code_t) 0
|
||||
#define SCAN_ERR_READ (scan_code_t) -1
|
||||
|
||||
// This is written to file as a 16-bit int!
|
||||
enum metakey {
|
||||
MetaContent = META_STR(1),
|
||||
MetaWidth = META_INT(2),
|
||||
MetaHeight = META_INT(3),
|
||||
MetaMediaDuration = META_LONG(4),
|
||||
MetaMediaAudioCodec = META_INT(5),
|
||||
MetaMediaVideoCodec = META_INT(6),
|
||||
MetaMediaBitrate = META_LONG(7),
|
||||
MetaArtist = META_STR(8),
|
||||
MetaAlbum = META_STR(9),
|
||||
MetaAlbumArtist = META_STR(10),
|
||||
MetaGenre = META_STR(11),
|
||||
MetaTitle = META_STR(12),
|
||||
MetaFontName = META_STR(13),
|
||||
MetaParent = META_STR(14),
|
||||
MetaExifMake = META_STR(15),
|
||||
MetaExifSoftware = META_STR(16),
|
||||
MetaExifExposureTime = META_STR(17),
|
||||
MetaExifFNumber = META_STR(18),
|
||||
MetaExifFocalLength = META_STR(19),
|
||||
MetaExifUserComment = META_STR(20),
|
||||
MetaExifModel = META_STR(21),
|
||||
MetaExifIsoSpeedRatings = META_STR(22),
|
||||
MetaExifDateTime = META_STR(23),
|
||||
};
|
||||
|
||||
typedef struct meta_line {
|
||||
struct meta_line *next;
|
||||
enum metakey key;
|
||||
union {
|
||||
char str_val[0];
|
||||
int int_val;
|
||||
unsigned long long_val;
|
||||
};
|
||||
} meta_line_t;
|
||||
|
||||
|
||||
typedef struct document {
|
||||
unsigned char uuid[16];
|
||||
unsigned long ino;
|
||||
unsigned long size;
|
||||
unsigned int mime;
|
||||
int mtime;
|
||||
short base;
|
||||
short ext;
|
||||
meta_line_t *meta_head;
|
||||
meta_line_t *meta_tail;
|
||||
char *filepath;
|
||||
} document_t;
|
||||
|
||||
typedef struct vfile vfile_t;
|
||||
|
||||
__attribute__((warn_unused_result))
|
||||
typedef int (*read_func_t)(struct vfile *, void *buf, size_t size);
|
||||
|
||||
typedef void (*close_func_t)(struct vfile *);
|
||||
|
||||
typedef struct vfile {
|
||||
union {
|
||||
int fd;
|
||||
struct archive *arc;
|
||||
};
|
||||
|
||||
int is_fs_file;
|
||||
char *filepath;
|
||||
struct stat info;
|
||||
|
||||
read_func_t read;
|
||||
close_func_t close;
|
||||
} vfile_t;
|
||||
|
||||
typedef struct parse_job_t {
|
||||
int base;
|
||||
int ext;
|
||||
struct stat info;
|
||||
struct vfile vfile;
|
||||
uuid_t parent;
|
||||
char filepath[1];
|
||||
} parse_job_t;
|
||||
|
||||
|
||||
#define APPEND_META(doc, meta) \
|
||||
meta->next = NULL;\
|
||||
if (doc->meta_head == NULL) {\
|
||||
doc->meta_head = meta;\
|
||||
doc->meta_tail = doc->meta_head;\
|
||||
} else {\
|
||||
doc->meta_tail->next = meta;\
|
||||
doc->meta_tail = meta;\
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#include "arc/arc.h"
|
||||
#include "cbr/cbr.h"
|
||||
#include "ebook/ebook.h"
|
||||
#include "font/font.h"
|
||||
#include "media/media.h"
|
||||
#include "ooxml/ooxml.h"
|
||||
#include "text/text.h"
|
31
third-party/libscan/libscan/text/text.c
vendored
Normal file
31
third-party/libscan/libscan/text/text.c
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
#include "text.h"
|
||||
|
||||
scan_code_t parse_text(scan_text_ctx_t *ctx, struct vfile *f, document_t *doc) {
|
||||
|
||||
int to_read = MIN(ctx->content_size, doc->size);
|
||||
|
||||
char *buf = malloc(to_read);
|
||||
int ret = f->read(f, buf, to_read);
|
||||
if (ret < 0) {
|
||||
//TODO: log
|
||||
return SCAN_ERR_READ;
|
||||
}
|
||||
|
||||
text_buffer_t tex = text_buffer_create(ctx->content_size);
|
||||
text_buffer_append_string(&tex, buf, to_read);
|
||||
text_buffer_terminate_string(&tex);
|
||||
|
||||
meta_line_t *meta = malloc(sizeof(meta_line_t) + tex.dyn_buffer.cur);
|
||||
meta->key = MetaContent;
|
||||
strcpy(meta->str_val, tex.dyn_buffer.buf);
|
||||
|
||||
APPEND_META(doc, meta)
|
||||
|
||||
printf("%s", meta->str_val);
|
||||
|
||||
free(buf);
|
||||
text_buffer_destroy(&tex);
|
||||
|
||||
return SCAN_OK;
|
||||
}
|
||||
|
13
third-party/libscan/libscan/text/text.h
vendored
Normal file
13
third-party/libscan/libscan/text/text.h
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef SCAN_TEXT_H
|
||||
#define SCAN_TEXT_H
|
||||
|
||||
#include "../scan.h"
|
||||
#include "../util.h"
|
||||
|
||||
typedef struct {
|
||||
long content_size;
|
||||
} scan_text_ctx_t;
|
||||
|
||||
scan_code_t parse_text(scan_text_ctx_t *ctx, struct vfile *f, document_t *doc);
|
||||
|
||||
#endif
|
0
third-party/libscan/libscan/util.c
vendored
Normal file
0
third-party/libscan/libscan/util.c
vendored
Normal file
276
third-party/libscan/libscan/util.h
vendored
Normal file
276
third-party/libscan/libscan/util.h
vendored
Normal file
@ -0,0 +1,276 @@
|
||||
#ifndef SCAN_UTIL_H
|
||||
#define SCAN_UTIL_H
|
||||
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "../third-party/utf8.h/utf8.h"
|
||||
#include "macros.h"
|
||||
|
||||
#define STR_STARTS_WITH(x, y) (strncmp(y, x, sizeof(y) - 1) == 0)
|
||||
|
||||
#define TEXT_BUF_FULL -1
|
||||
#define INITIAL_BUF_SIZE 1024 * 16
|
||||
|
||||
#define SHOULD_IGNORE_CHAR(c) !(SHOULD_KEEP_CHAR(c))
|
||||
#define SHOULD_KEEP_CHAR(c) ((c >= '\'' && c <= ';') || (c >= 'A' && c <= 'z') || (c > 127))
|
||||
|
||||
|
||||
typedef struct dyn_buffer {
|
||||
char *buf;
|
||||
size_t cur;
|
||||
size_t size;
|
||||
} dyn_buffer_t;
|
||||
|
||||
typedef struct text_buffer {
|
||||
long max_size;
|
||||
int last_char_was_whitespace;
|
||||
dyn_buffer_t dyn_buffer;
|
||||
} text_buffer_t;
|
||||
|
||||
static int utf8_validchr2(const char *s) {
|
||||
if (0x00 == (0x80 & *s)) {
|
||||
return TRUE;
|
||||
} else if (0xf0 == (0xf8 & *s)) {
|
||||
if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2])) ||
|
||||
(0x80 != (0xc0 & s[3]))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (0x80 == (0xc0 & s[4])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((0 == (0x07 & s[0])) && (0 == (0x30 & s[1]))) {
|
||||
return FALSE;
|
||||
}
|
||||
} else if (0xe0 == (0xf0 & *s)) {
|
||||
if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2]))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (0x80 == (0xc0 & s[3])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((0 == (0x0f & s[0])) && (0 == (0x20 & s[1]))) {
|
||||
return FALSE;
|
||||
}
|
||||
} else if (0xc0 == (0xe0 & *s)) {
|
||||
if (0x80 != (0xc0 & s[1])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (0x80 == (0xc0 & s[2])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (0 == (0x1e & s[0])) {
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static dyn_buffer_t dyn_buffer_create() {
|
||||
dyn_buffer_t buf;
|
||||
|
||||
buf.size = INITIAL_BUF_SIZE;
|
||||
buf.cur = 0;
|
||||
buf.buf = malloc(INITIAL_BUF_SIZE);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void grow_buffer(dyn_buffer_t *buf, size_t size) {
|
||||
if (buf->cur + size > buf->size) {
|
||||
do {
|
||||
buf->size *= 2;
|
||||
} while (buf->cur + size > buf->size);
|
||||
|
||||
buf->buf = realloc(buf->buf, buf->size);
|
||||
}
|
||||
}
|
||||
|
||||
static void grow_buffer_small(dyn_buffer_t *buf) {
|
||||
if (buf->cur + sizeof(long) > buf->size) {
|
||||
buf->size *= 2;
|
||||
buf->buf = realloc(buf->buf, buf->size);
|
||||
}
|
||||
}
|
||||
|
||||
static void dyn_buffer_write(dyn_buffer_t *buf, const void *data, size_t size) {
|
||||
grow_buffer(buf, size);
|
||||
|
||||
memcpy(buf->buf + buf->cur, data, size);
|
||||
buf->cur += size;
|
||||
}
|
||||
|
||||
static void dyn_buffer_write_char(dyn_buffer_t *buf, char c) {
|
||||
grow_buffer_small(buf);
|
||||
|
||||
*(buf->buf + buf->cur) = c;
|
||||
buf->cur += sizeof(c);
|
||||
}
|
||||
|
||||
static void dyn_buffer_write_str(dyn_buffer_t *buf, char *str) {
|
||||
dyn_buffer_write(buf, str, strlen(str));
|
||||
dyn_buffer_write_char(buf, '\0');
|
||||
}
|
||||
|
||||
static void dyn_buffer_append_string(dyn_buffer_t *buf, char *str) {
|
||||
dyn_buffer_write(buf, str, strlen(str));
|
||||
}
|
||||
|
||||
static void dyn_buffer_write_int(dyn_buffer_t *buf, int d) {
|
||||
grow_buffer_small(buf);
|
||||
|
||||
*(int *) (buf->buf + buf->cur) = d;
|
||||
buf->cur += sizeof(int);
|
||||
}
|
||||
|
||||
static void dyn_buffer_write_short(dyn_buffer_t *buf, short s) {
|
||||
grow_buffer_small(buf);
|
||||
|
||||
*(short *) (buf->buf + buf->cur) = s;
|
||||
buf->cur += sizeof(short);
|
||||
}
|
||||
|
||||
static void dyn_buffer_write_long(dyn_buffer_t *buf, unsigned long l) {
|
||||
grow_buffer_small(buf);
|
||||
|
||||
*(unsigned long *) (buf->buf + buf->cur) = l;
|
||||
buf->cur += sizeof(unsigned long);
|
||||
}
|
||||
|
||||
static void dyn_buffer_destroy(dyn_buffer_t *buf) {
|
||||
free(buf->buf);
|
||||
}
|
||||
|
||||
static void text_buffer_destroy(text_buffer_t *buf) {
|
||||
dyn_buffer_destroy(&buf->dyn_buffer);
|
||||
}
|
||||
|
||||
static text_buffer_t text_buffer_create(long max_size) {
|
||||
text_buffer_t text_buf;
|
||||
|
||||
text_buf.dyn_buffer = dyn_buffer_create();
|
||||
text_buf.max_size = max_size;
|
||||
text_buf.last_char_was_whitespace = FALSE;
|
||||
|
||||
return text_buf;
|
||||
}
|
||||
|
||||
static int text_buffer_append_char(text_buffer_t *buf, int c) {
|
||||
|
||||
if (SHOULD_IGNORE_CHAR(c) || c == ' ') {
|
||||
if (!buf->last_char_was_whitespace && buf->dyn_buffer.cur != 0) {
|
||||
dyn_buffer_write_char(&buf->dyn_buffer, ' ');
|
||||
buf->last_char_was_whitespace = TRUE;
|
||||
|
||||
if (buf->max_size > 0 && buf->dyn_buffer.cur >= buf->max_size) {
|
||||
return TEXT_BUF_FULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buf->last_char_was_whitespace = FALSE;
|
||||
grow_buffer_small(&buf->dyn_buffer);
|
||||
|
||||
if (((utf8_int32_t) 0xffffff80 & c) == 0) {
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = (char) c;
|
||||
} else if (((utf8_int32_t) 0xfffff800 & c) == 0) {
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xc0 | (char) (c >> 6);
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
|
||||
} else if (((utf8_int32_t) 0xffff0000 & c) == 0) {
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xe0 | (char) (c >> 12);
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 6) & 0x3f);
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
|
||||
} else {
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xf0 | (char) (c >> 18);
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 12) & 0x3f);
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 6) & 0x3f);
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
|
||||
}
|
||||
|
||||
if (buf->max_size > 0 && buf->dyn_buffer.cur >= buf->max_size) {
|
||||
return TEXT_BUF_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void text_buffer_terminate_string(text_buffer_t *buf) {
|
||||
if (buf->dyn_buffer.cur > 0 && *(buf->dyn_buffer.buf + buf->dyn_buffer.cur - 1) == ' ') {
|
||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur - 1) = '\0';
|
||||
} else {
|
||||
dyn_buffer_write_char(&buf->dyn_buffer, '\0');
|
||||
}
|
||||
}
|
||||
|
||||
#define UTF8_END_OF_STRING \
|
||||
(ptr - str >= len || *ptr == 0 || \
|
||||
(0xc0 == (0xe0 & *ptr) && ptr - str > len - 2) || \
|
||||
(0xe0 == (0xf0 & *ptr) && ptr - str > len - 3) || \
|
||||
(0xf0 == (0xf8 & *ptr) && ptr - str > len - 4))
|
||||
|
||||
static int text_buffer_append_string(text_buffer_t *buf, const char *str, size_t len) {
|
||||
|
||||
const char *ptr = str;
|
||||
const char *oldPtr = ptr;
|
||||
|
||||
if (str == NULL || UTF8_END_OF_STRING) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len <= 4) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (((utf8_int32_t)0xffffff80 & str[i]) == 0) {
|
||||
dyn_buffer_write_char(&buf->dyn_buffer, str[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
utf8_int32_t c;
|
||||
char tmp[16];
|
||||
|
||||
do {
|
||||
ptr = utf8codepoint(ptr, &c);
|
||||
*(int *) tmp = 0x00000000;
|
||||
memcpy(tmp, oldPtr, ptr - oldPtr);
|
||||
oldPtr = ptr;
|
||||
|
||||
if (!utf8_validchr2(tmp)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int ret = text_buffer_append_char(buf, c);
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
} while (!UTF8_END_OF_STRING);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int text_buffer_append_string0(text_buffer_t *buf, char *str) {
|
||||
return text_buffer_append_string(buf, str, strlen(str));
|
||||
}
|
||||
|
||||
static void* read_all(vfile_t *f, size_t *size) {
|
||||
void* buf = malloc(f->info.st_size);
|
||||
*size = f->read(f, buf, f->info.st_size);
|
||||
|
||||
//TODO: log
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif
|
1
utf8.h
1
utf8.h
@ -1 +0,0 @@
|
||||
Subproject commit 2a7c5bfa952816cd1c674e604d31c6e0268ba770
|
6
web/css/bootstrap.min.css
vendored
6
web/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
1
web/css/bricklayer.min.css
vendored
1
web/css/bricklayer.min.css
vendored
@ -1 +0,0 @@
|
||||
.bricklayer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.bricklayer-column-sizer{width:100%;display:none}@media screen and (min-width:640px){.bricklayer-column-sizer{width:50%}}@media screen and (min-width:980px){.bricklayer-column-sizer{width:33.333%}}@media screen and (min-width:1200px){.bricklayer-column-sizer{width:25%}}.bricklayer-column{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;padding-left:5px;padding-right:5px}
|
458
web/css/dark.css
458
web/css/dark.css
@ -1,458 +0,0 @@
|
||||
*:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.info-icon {
|
||||
width: 1rem;
|
||||
margin-right: 0.2rem;
|
||||
cursor: pointer;
|
||||
color: #757575;
|
||||
line-height: 1rem;
|
||||
height: 1.1rem;
|
||||
}
|
||||
|
||||
.info-icon:hover {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
max-width: calc(100% - 2rem);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
|
||||
.path-row {
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-align: start;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.tag-container {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.path-line {
|
||||
color: #BBB;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #00BCD4;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-y: scroll;
|
||||
background: black;
|
||||
}
|
||||
|
||||
.progress {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.card, .modal-content {
|
||||
margin-top: 1em;
|
||||
background: #212121;
|
||||
color: #e0e0e0;
|
||||
border-radius: 1px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.table {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.table td, .table th {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.table thead th {
|
||||
border-bottom: 1px solid #646464;
|
||||
}
|
||||
|
||||
.modal-header .close {
|
||||
color: #e0e0e0;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
border-bottom: 1px solid #646464;
|
||||
}
|
||||
|
||||
.sub-document {
|
||||
background: #37474F !important;
|
||||
}
|
||||
|
||||
.list-group-item.sub-document {
|
||||
border-top: 1px solid #646464 !important;
|
||||
}
|
||||
|
||||
.sub-document .text-muted {
|
||||
color: #8a949c !important;
|
||||
}
|
||||
|
||||
|
||||
.list-group-item {
|
||||
background: #212121;
|
||||
color: #e0e0e0;
|
||||
|
||||
border-top: 1px solid #424242;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
padding: .25rem 0.5rem;
|
||||
}
|
||||
|
||||
.list-group-item:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.75rem;
|
||||
padding: 0;
|
||||
color: #f5f5f5;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background: #546b7a;
|
||||
}
|
||||
|
||||
.navbar a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.navbar span {
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
.document {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.document p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.document:hover p {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.badge-video {
|
||||
color: #FFFFFF;
|
||||
background-color: #F27761;
|
||||
}
|
||||
|
||||
.badge-image {
|
||||
color: #FFFFFF;
|
||||
background-color: #AA99C9;
|
||||
}
|
||||
|
||||
.badge-audio {
|
||||
color: #FFFFFF;
|
||||
background-color: #00ADEF;
|
||||
}
|
||||
|
||||
.badge-resolution {
|
||||
color: #212529;
|
||||
background-color: #B0BEC5;
|
||||
}
|
||||
|
||||
.badge-text {
|
||||
color: #FFFFFF;
|
||||
background-color: #FAAB3C;
|
||||
}
|
||||
|
||||
.card-img-overlay {
|
||||
pointer-events: none;
|
||||
padding: 0.75rem;
|
||||
|
||||
bottom: unset;
|
||||
top: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
}
|
||||
|
||||
.file-title {
|
||||
width: 100%;
|
||||
line-height: 1rem;
|
||||
height: 1.1rem;
|
||||
font-size: 10pt;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #00BCD4;
|
||||
}
|
||||
|
||||
.badge {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.badge-user {
|
||||
color: #212529;
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.fit {
|
||||
display: block;
|
||||
min-width: 64px;
|
||||
max-width: 100%;
|
||||
max-height: 175px;
|
||||
margin: 0 auto 0;
|
||||
padding: 3px 3px 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.fit-sm {
|
||||
display: block;
|
||||
max-width: 64px;
|
||||
max-height: 64px;
|
||||
margin: 0 auto;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.audio-fit {
|
||||
height: 39px;
|
||||
vertical-align: bottom;
|
||||
display: inline;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
.container {
|
||||
max-width: 1440px;
|
||||
}
|
||||
|
||||
.bricklayer-column-sizer {
|
||||
width: 20% !important;
|
||||
}
|
||||
|
||||
.bricklayer-column {
|
||||
max-width: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1800px) {
|
||||
.container {
|
||||
max-width: 1550px;
|
||||
}
|
||||
}
|
||||
|
||||
mark {
|
||||
background: rgba(251, 191, 41, 0.25);
|
||||
border-radius: 0;
|
||||
padding: 1px 0;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.content-div mark {
|
||||
background: rgba(251, 191, 41, 0.40);
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
.content-div {
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 13px;
|
||||
padding: 1em;
|
||||
background-color: #37474F;
|
||||
border: 1px solid #616161;
|
||||
border-radius: 4px;
|
||||
margin: 3px;
|
||||
white-space: normal;
|
||||
color: rgb(224, 224, 224);
|
||||
}
|
||||
|
||||
.irs-single, .irs-from, .irs-to {
|
||||
font-size: 13px;
|
||||
background-color: #00BCD4;
|
||||
}
|
||||
|
||||
.irs-slider {
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.irs {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.custom-select {
|
||||
overflow: auto;
|
||||
background-color: #37474F;
|
||||
border: 1px solid #616161;
|
||||
color: #bdbdbd;
|
||||
}
|
||||
|
||||
.custom-select:focus {
|
||||
border-color: #757575;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 .2rem rgba(0, 123, 255, .25);
|
||||
}
|
||||
|
||||
option {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
background-color: #37474F;
|
||||
border: 1px solid #616161;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
background-color: #546E7A;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.input-group-text {
|
||||
background: #263238;
|
||||
border: 1px solid #616161;
|
||||
color: #dbdbdb;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: #BDBDBD !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
.inspire-tree .selected > .wholerow, .inspire-tree .selected > .title-wrap:hover + .wholerow {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.inspire-tree .icon-expand::before, .inspire-tree .icon-collapse::before {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.inspire-tree .title {
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
.inspire-tree {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
font-family: Helvetica, Nueue, Verdana, sans-serif;
|
||||
max-height: 350px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.page-indicator {
|
||||
line-height: 1rem;
|
||||
padding: 0.5rem;
|
||||
background: #212121;
|
||||
color: #eee;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.btn-xs {
|
||||
padding: .1rem .3rem;
|
||||
font-size: .875rem;
|
||||
border-radius: .2rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active {
|
||||
background-color: #212121;
|
||||
border-color: #616161 #616161 #212121;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link:focus, .nav-tabs .nav-link:focus {
|
||||
border-color: #616161 #616161 #212121;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover {
|
||||
border-color: #e0e0e0 #e0e0e0 #212121;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom: #616161;
|
||||
}
|
||||
|
||||
.nav {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
#treeTabs {
|
||||
flex-basis: inherit;
|
||||
flex-grow: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.list-group {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.wrapper-sm {
|
||||
min-width: 64px;
|
||||
}
|
||||
|
||||
.media-expanded {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
.media-expanded .fit {
|
||||
max-height: 250px;
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
.media-expanded .fit {
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.tagline {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.version {
|
||||
color: #00BCD4;
|
||||
margin-left: -18px;
|
||||
margin-top: -14px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
.small-btn {
|
||||
display: none;
|
||||
}
|
||||
.large-btn {
|
||||
display: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 801px) {
|
||||
.small-btn {
|
||||
display: inherit;
|
||||
}
|
||||
.large-btn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#searchBar {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
#pathTree .title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: white;
|
||||
}
|
1
web/css/inspire-tree-light.min.css
vendored
1
web/css/inspire-tree-light.min.css
vendored
File diff suppressed because one or more lines are too long
1
web/css/ion.rangeSlider.min.css
vendored
1
web/css/ion.rangeSlider.min.css
vendored
@ -1 +0,0 @@
|
||||
.irs{position:relative;display:block;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.irs-line{position:relative;display:block;overflow:hidden;outline:none !important}.irs-line-left,.irs-line-mid,.irs-line-right{position:absolute;display:block;top:0}.irs-line-left{left:0;width:11%}.irs-line-mid{left:9%;width:82%}.irs-line-right{right:0;width:11%}.irs-bar{position:absolute;display:block;left:0;width:0}.irs-bar-edge{position:absolute;display:block;top:0;left:0}.irs-shadow{position:absolute;display:none;left:0;width:0}.irs-slider{position:absolute;display:block;cursor:default;z-index:1}.irs-slider.single{}.irs-slider.from{}.irs-slider.to{}.irs-slider.type_last{z-index:2}.irs-min{position:absolute;display:block;left:0;cursor:default}.irs-max{position:absolute;display:block;right:0;cursor:default}.irs-from,.irs-single,.irs-to{position:absolute;display:block;top:0;left:0;cursor:default;white-space:nowrap}.irs-grid{position:absolute;display:none;bottom:0;left:0;width:100%;height:20px}.irs-with-grid .irs-grid{display:block}.irs-grid-pol{position:absolute;top:0;left:0;width:1px;height:8px;background:#000}.irs-grid-pol.small{height:4px}.irs-grid-text{position:absolute;bottom:0;left:0;white-space:nowrap;text-align:center;font-size:9px;line-height:9px;padding:0 3px;color:#000}.irs-disable-mask{position:absolute;display:block;top:0;left:-1%;width:102%;height:100%;cursor:default;background:rgba(0,0,0,0.0);z-index:2}.irs-disabled{opacity:0.4}.lt-ie9 .irs-disabled{filter: alpha(opacity=40)}.irs-hidden-input{position:absolute !important;display:block !important;top:0 !important;left:0 !important;width:0 !important;height:0 !important;font-size:0 !important;line-height:0 !important;padding:0 !important;margin:0 !important;outline:none !important;z-index:-9999 !important;background:none !important;border-style:solid !important;border-color:transparent !important}
|
1
web/css/ion.rangeSlider.skinFlat.min.css
vendored
1
web/css/ion.rangeSlider.skinFlat.min.css
vendored
@ -1 +0,0 @@
|
||||
.irs-bar,.irs-bar-edge,.irs-line-left,.irs-line-mid,.irs-line-right,.irs-slider{background:url("../img/sprite-skin-flat.png") repeat-x}.irs{height:40px}.irs-with-grid{height:60px}.irs-line{height:12px;top:25px}.irs-line-left{height:12px;background-position:0 -30px}.irs-line-mid{height:12px;background-position:0 0}.irs-line-right{height:12px;background-position:100% -30px}.irs-bar{height:12px;top:25px;background-position:0 -60px}.irs-bar-edge{top:25px;height:12px;width:9px;background-position:0 -90px}.irs-shadow{height:3px;top:34px;background:#000;opacity:0.25}.lt-ie9 .irs-shadow{filter: alpha(opacity=25)}.irs-slider{width:16px;height:18px;top:22px;background-position:0 -120px}.irs-slider.state_hover,.irs-slider:hover{background-position:0 -150px}.irs-max,.irs-min{color:#999;font-size:10px;line-height:1.333;text-shadow:none;top:0;padding:1px 3px;background:#e1e4e9;-moz-border-radius:4px;border-radius:4px}.irs-from,.irs-single,.irs-to{color:#fff;font-size:10px;line-height:1.333;text-shadow:none;padding:1px 5px;background:#2196F3;-moz-border-radius:4px;border-radius:4px}.irs-from:after,.irs-single:after,.irs-to:after{position:absolute;display:block;content:"";bottom:-6px;left:50%;width:0;height:0;margin-left:-3px;overflow:hidden;border:3px solid transparent;border-top-color:#2196F3}.irs-grid-pol{background:#e1e4e9}.irs-grid-text{color:#999}.irs-disabled{}
|
1
web/css/jquery.toast.min.css
vendored
1
web/css/jquery.toast.min.css
vendored
@ -1 +0,0 @@
|
||||
.jq-toast-wrap,.jq-toast-wrap *{margin:0;padding:0}.jq-toast-wrap{display:block;position:fixed;width:250px;pointer-events:none!important;letter-spacing:normal;z-index:9000!important}.jq-toast-wrap.bottom-left{bottom:20px;left:20px}.jq-toast-wrap.bottom-right{bottom:20px;right:40px}.jq-toast-wrap.top-left{top:20px;left:20px}.jq-toast-wrap.top-right{top:20px;right:40px}.jq-toast-single{display:block;width:100%;padding:10px;margin:0 0 5px;border-radius:4px;font-size:12px;font-family:arial,sans-serif;line-height:17px;position:relative;pointer-events:all!important;background-color:#444;color:#fff}.jq-toast-single h2{font-family:arial,sans-serif;font-size:14px;margin:0 0 7px;background:0 0;color:inherit;line-height:inherit;letter-spacing:normal}.jq-toast-single a{color:#eee;text-decoration:none;font-weight:700;border-bottom:1px solid #fff;padding-bottom:3px;font-size:12px}.jq-toast-single ul{margin:0 0 0 15px;background:0 0;padding:0}.jq-toast-single ul li{list-style-type:disc!important;line-height:17px;background:0 0;margin:0;padding:0;letter-spacing:normal}.close-jq-toast-single{position:absolute;top:3px;right:7px;font-size:14px;cursor:pointer}.jq-toast-loader{display:block;position:absolute;top:-2px;height:5px;width:0;left:0;border-radius:5px;background:red}.jq-toast-loaded{width:100%}.jq-has-icon{padding:10px 10px 10px 50px;background-repeat:no-repeat;background-position:10px}.jq-icon-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=);background-color:#31708f;color:#d9edf7;border-color:#bce8f1}.jq-icon-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=);background-color:#8a6d3b;color:#fcf8e3;border-color:#faebcc}.jq-icon-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=);background-color:#a94442;color:#f2dede;border-color:#ebccd1}.jq-icon-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==);color:#dff0d8;background-color:#3c763d;border-color:#d6e9c6}
|
@ -1,318 +0,0 @@
|
||||
*:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.info-icon {
|
||||
width: 1rem;
|
||||
margin-right: 0.2rem;
|
||||
cursor: pointer;
|
||||
color: #757575;
|
||||
line-height: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.info-icon:hover {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
max-width: calc(100% - 2rem);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.path-row {
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-align: start;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.tag-container {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.path-line {
|
||||
color: #444;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.progress {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin-top: 1em;
|
||||
box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .08) !important;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.sub-document {
|
||||
background: #AB47BC1F !important;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.75rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background: #F7F7F7;
|
||||
border-bottom: solid 1px #dfdfdf;
|
||||
}
|
||||
|
||||
.document {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.document p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.document:hover p {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.badge-video {
|
||||
color: #FFFFFF;
|
||||
background-color: #F27761;
|
||||
}
|
||||
|
||||
.badge-image {
|
||||
color: #FFFFFF;
|
||||
background-color: #AA99C9;
|
||||
}
|
||||
|
||||
.badge-audio {
|
||||
color: #FFFFFF;
|
||||
background-color: #00ADEF;
|
||||
}
|
||||
|
||||
.badge-resolution {
|
||||
color: #212529;
|
||||
background-color: #FFC107;
|
||||
}
|
||||
|
||||
.badge-user {
|
||||
color: #212529;
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.badge-text {
|
||||
color: #FFFFFF;
|
||||
background-color: #FAAB3C;
|
||||
}
|
||||
|
||||
.card-img-overlay {
|
||||
pointer-events: none;
|
||||
padding: 0.75rem;
|
||||
|
||||
bottom: unset;
|
||||
top: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
}
|
||||
|
||||
.file-title {
|
||||
width: 100%;
|
||||
line-height: 1rem;
|
||||
height: 1.1rem;
|
||||
font-size: 10pt;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.badge {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.fit {
|
||||
display: block;
|
||||
min-width: 64px;
|
||||
max-width: 100%;
|
||||
max-height: 175px;
|
||||
margin: 0 auto 0;
|
||||
padding: 3px 3px 0 3px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.fit-sm {
|
||||
display: block;
|
||||
max-width: 64px;
|
||||
max-height: 64px;
|
||||
margin: 0 auto 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.audio-fit {
|
||||
height: 39px;
|
||||
vertical-align: bottom;
|
||||
display: inline;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
.container {
|
||||
max-width: 1440px;
|
||||
}
|
||||
|
||||
.bricklayer-column-sizer {
|
||||
width: 20% !important;
|
||||
}
|
||||
|
||||
.bricklayer-column {
|
||||
max-width: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1800px) {
|
||||
.container {
|
||||
max-width: 1550px;
|
||||
}
|
||||
}
|
||||
|
||||
mark {
|
||||
background: #fff217;
|
||||
border-radius: 0;
|
||||
padding: 1px 0;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.content-div {
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 13px;
|
||||
padding: 1em;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
margin: 3px;
|
||||
white-space: normal;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.irs-single, .irs-from, .irs-to {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.irs-slider {
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.custom-select {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.irs {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.inspire-tree .selected > .wholerow, .inspire-tree .selected > .title-wrap:hover + .wholerow {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.inspire-tree {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
font-family: Helvetica, Nueue, Verdana, sans-serif;
|
||||
max-height: 350px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.page-indicator {
|
||||
line-height: 1rem;
|
||||
padding: 0.5rem;
|
||||
background: #f8f9fa;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.btn-xs {
|
||||
padding: .1rem .3rem;
|
||||
font-size: .875rem;
|
||||
border-radius: .2rem;
|
||||
}
|
||||
|
||||
.nav {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
#treeTabs {
|
||||
flex-basis: inherit;
|
||||
flex-grow: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.list-group {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
padding: .25rem 0.5rem;
|
||||
}
|
||||
|
||||
.wrapper-sm {
|
||||
min-width: 64px;
|
||||
}
|
||||
|
||||
.media-expanded {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
.media-expanded .fit {
|
||||
max-height: 250px;
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
.media-expanded .fit {
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.tagline {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.version {
|
||||
color: #007bff;
|
||||
margin-left: -18px;
|
||||
margin-top: -14px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
.small-btn {
|
||||
display: none;
|
||||
}
|
||||
.large-btn {
|
||||
display: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 801px) {
|
||||
.small-btn {
|
||||
display: inherit;
|
||||
}
|
||||
.large-btn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#searchBar {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
#pathTree .title {
|
||||
cursor: pointer;
|
||||
}
|
1
web/css/smartphoto.min.css
vendored
1
web/css/smartphoto.min.css
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 595 B |
Binary file not shown.
Before Width: | Height: | Size: 669 B |
2
web/js/2_jquery-3.4.1.min.js
vendored
2
web/js/2_jquery-3.4.1.min.js
vendored
File diff suppressed because one or more lines are too long
7
web/js/3_bootstrap.bundle.min.js
vendored
7
web/js/3_bootstrap.bundle.min.js
vendored
File diff suppressed because one or more lines are too long
137
web/js/4_lodash.min.js
vendored
137
web/js/4_lodash.min.js
vendored
@ -1,137 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(){function n(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function t(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u<i;){var o=n[u];t(e,o,r(o),n)}return e}function r(n,t){for(var r=-1,e=null==n?0:n.length;++r<e&&false!==t(n[r],r,n););return n}function e(n,t){for(var r=null==n?0:n.length;r--&&false!==t(n[r],r,n););return n}function u(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(!t(n[r],r,n))return false;
|
||||
return true}function i(n,t){for(var r=-1,e=null==n?0:n.length,u=0,i=[];++r<e;){var o=n[r];t(o,r,n)&&(i[u++]=o)}return i}function o(n,t){return!(null==n||!n.length)&&-1<v(n,t,0)}function f(n,t,r){for(var e=-1,u=null==n?0:n.length;++e<u;)if(r(t,n[e]))return true;return false}function c(n,t){for(var r=-1,e=null==n?0:n.length,u=Array(e);++r<e;)u[r]=t(n[r],r,n);return u}function a(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function l(n,t,r,e){var u=-1,i=null==n?0:n.length;for(e&&i&&(r=n[++u]);++u<i;)r=t(r,n[u],u,n);
|
||||
return r}function s(n,t,r,e){var u=null==n?0:n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r}function h(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(t(n[r],r,n))return true;return false}function p(n,t,r){var e;return r(n,function(n,r,u){if(t(n,r,u))return e=r,false}),e}function _(n,t,r,e){var u=n.length;for(r+=e?1:-1;e?r--:++r<u;)if(t(n[r],r,n))return r;return-1}function v(n,t,r){if(t===t)n:{--r;for(var e=n.length;++r<e;)if(n[r]===t){n=r;break n}n=-1}else n=_(n,d,r);return n}function g(n,t,r,e){
|
||||
--r;for(var u=n.length;++r<u;)if(e(n[r],t))return r;return-1}function d(n){return n!==n}function y(n,t){var r=null==n?0:n.length;return r?m(n,t)/r:F}function b(n){return function(t){return null==t?T:t[n]}}function x(n){return function(t){return null==n?T:n[t]}}function j(n,t,r,e,u){return u(n,function(n,u,i){r=e?(e=false,n):t(r,n,u,i)}),r}function w(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function m(n,t){for(var r,e=-1,u=n.length;++e<u;){var i=t(n[e]);i!==T&&(r=r===T?i:r+i)}return r;
|
||||
}function A(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function E(n,t){return c(t,function(t){return[t,n[t]]})}function k(n){return function(t){return n(t)}}function S(n,t){return c(t,function(t){return n[t]})}function O(n,t){return n.has(t)}function I(n,t){for(var r=-1,e=n.length;++r<e&&-1<v(t,n[r],0););return r}function R(n,t){for(var r=n.length;r--&&-1<v(t,n[r],0););return r}function z(n){return"\\"+Un[n]}function W(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n];
|
||||
}),r}function B(n,t){return function(r){return n(t(r))}}function L(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r];o!==t&&"__lodash_placeholder__"!==o||(n[r]="__lodash_placeholder__",i[u++]=r)}return i}function U(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=n}),r}function C(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function D(n){if(Rn.test(n)){for(var t=On.lastIndex=0;On.test(n);)++t;n=t}else n=Qn(n);return n}function M(n){return Rn.test(n)?n.match(On)||[]:n.split("");
|
||||
}var T,$=1/0,F=NaN,N=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],P=/\b__p\+='';/g,Z=/\b(__p\+=)''\+/g,q=/(__e\(.*?\)|\b__t\))\+'';/g,V=/&(?:amp|lt|gt|quot|#39);/g,K=/[&<>"']/g,G=RegExp(V.source),H=RegExp(K.source),J=/<%-([\s\S]+?)%>/g,Y=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nn=/^\w*$/,tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,rn=/[\\^$.*+?()[\]{}|]/g,en=RegExp(rn.source),un=/^\s+|\s+$/g,on=/^\s+/,fn=/\s+$/,cn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,an=/\{\n\/\* \[wrapped with (.+)\] \*/,ln=/,? & /,sn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,hn=/\\(\\)?/g,pn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_n=/\w*$/,vn=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,dn=/^\[object .+?Constructor\]$/,yn=/^0o[0-7]+$/i,bn=/^(?:0|[1-9]\d*)$/,xn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,jn=/($^)/,wn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",An="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,En="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",kn=RegExp("['\u2019]","g"),Sn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),On=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+En+mn,"g"),In=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])|\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])|\\d+",An].join("|"),"g"),Rn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),zn=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={};
|
||||
Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object Boolean]"]=Bn["[object DataView]"]=Bn["[object Date]"]=Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object WeakMap]"]=false;
|
||||
var Ln={};Ln["[object Arguments]"]=Ln["[object Array]"]=Ln["[object ArrayBuffer]"]=Ln["[object DataView]"]=Ln["[object Boolean]"]=Ln["[object Date]"]=Ln["[object Float32Array]"]=Ln["[object Float64Array]"]=Ln["[object Int8Array]"]=Ln["[object Int16Array]"]=Ln["[object Int32Array]"]=Ln["[object Map]"]=Ln["[object Number]"]=Ln["[object Object]"]=Ln["[object RegExp]"]=Ln["[object Set]"]=Ln["[object String]"]=Ln["[object Symbol]"]=Ln["[object Uint8Array]"]=Ln["[object Uint8ClampedArray]"]=Ln["[object Uint16Array]"]=Ln["[object Uint32Array]"]=true,
|
||||
Ln["[object Error]"]=Ln["[object Function]"]=Ln["[object WeakMap]"]=false;var Un={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Cn=parseFloat,Dn=parseInt,Mn=typeof global=="object"&&global&&global.Object===Object&&global,Tn=typeof self=="object"&&self&&self.Object===Object&&self,$n=Mn||Tn||Function("return this")(),Fn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Nn=Fn&&typeof module=="object"&&module&&!module.nodeType&&module,Pn=Nn&&Nn.exports===Fn,Zn=Pn&&Mn.process,qn=function(){
|
||||
try{var n=Nn&&Nn.f&&Nn.f("util").types;return n?n:Zn&&Zn.binding&&Zn.binding("util")}catch(n){}}(),Vn=qn&&qn.isArrayBuffer,Kn=qn&&qn.isDate,Gn=qn&&qn.isMap,Hn=qn&&qn.isRegExp,Jn=qn&&qn.isSet,Yn=qn&&qn.isTypedArray,Qn=b("length"),Xn=x({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I",
|
||||
"\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C",
|
||||
"\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i",
|
||||
"\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r",
|
||||
"\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij",
|
||||
"\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),nt=x({"&":"&","<":"<",">":">",'"':""","'":"'"}),tt=x({"&":"&","<":"<",">":">",""":'"',"'":"'"}),rt=function x(mn){function An(n){if(yu(n)&&!ff(n)&&!(n instanceof Un)){if(n instanceof On)return n;if(oi.call(n,"__wrapped__"))return Fe(n)}return new On(n)}function En(){}function On(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=T}function Un(n){this.__wrapped__=n,
|
||||
this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Mn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Tn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Fn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Nn(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new Fn;++t<r;)this.add(n[t]);
|
||||
}function Zn(n){this.size=(this.__data__=new Tn(n)).size}function qn(n,t){var r,e=ff(n),u=!e&&of(n),i=!e&&!u&&af(n),o=!e&&!u&&!i&&_f(n),u=(e=e||u||i||o)?A(n.length,ni):[],f=u.length;for(r in n)!t&&!oi.call(n,r)||e&&("length"==r||i&&("offset"==r||"parent"==r)||o&&("buffer"==r||"byteLength"==r||"byteOffset"==r)||Se(r,f))||u.push(r);return u}function Qn(n){var t=n.length;return t?n[ir(0,t-1)]:T}function et(n,t){return De(Ur(n),pt(t,0,n.length))}function ut(n){return De(Ur(n))}function it(n,t,r){(r===T||lu(n[t],r))&&(r!==T||t in n)||st(n,t,r);
|
||||
}function ot(n,t,r){var e=n[t];oi.call(n,t)&&lu(e,r)&&(r!==T||t in n)||st(n,t,r)}function ft(n,t){for(var r=n.length;r--;)if(lu(n[r][0],t))return r;return-1}function ct(n,t,r,e){return uo(n,function(n,u,i){t(e,n,r(n),i)}),e}function at(n,t){return n&&Cr(t,Wu(t),n)}function lt(n,t){return n&&Cr(t,Bu(t),n)}function st(n,t,r){"__proto__"==t&&Ai?Ai(n,t,{configurable:true,enumerable:true,value:r,writable:true}):n[t]=r}function ht(n,t){for(var r=-1,e=t.length,u=Ku(e),i=null==n;++r<e;)u[r]=i?T:Ru(n,t[r]);return u;
|
||||
}function pt(n,t,r){return n===n&&(r!==T&&(n=n<=r?n:r),t!==T&&(n=n>=t?n:t)),n}function _t(n,t,e,u,i,o){var f,c=1&t,a=2&t,l=4&t;if(e&&(f=i?e(n,u,i,o):e(n)),f!==T)return f;if(!du(n))return n;if(u=ff(n)){if(f=me(n),!c)return Ur(n,f)}else{var s=vo(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(af(n))return Ir(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Ae(n),!c)return a?Mr(n,lt(f,n)):Dr(n,at(f,n))}else{if(!Ln[s])return i?n:{};f=Ee(n,s,c)}}if(o||(o=new Zn),
|
||||
i=o.get(n))return i;o.set(n,f),pf(n)?n.forEach(function(r){f.add(_t(r,t,e,r,n,o))}):sf(n)&&n.forEach(function(r,u){f.set(u,_t(r,t,e,u,n,o))});var a=l?a?ve:_e:a?Bu:Wu,p=u?T:a(n);return r(p||n,function(r,u){p&&(u=r,r=n[u]),ot(f,u,_t(r,t,e,u,n,o))}),f}function vt(n){var t=Wu(n);return function(r){return gt(r,n,t)}}function gt(n,t,r){var e=r.length;if(null==n)return!e;for(n=Qu(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===T&&!(u in n)||!i(o))return false}return true}function dt(n,t,r){if(typeof n!="function")throw new ti("Expected a function");
|
||||
return bo(function(){n.apply(T,r)},t)}function yt(n,t,r,e){var u=-1,i=o,a=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,k(r))),e?(i=f,a=false):200<=t.length&&(i=O,a=false,t=new Nn(t));n:for(;++u<l;){var p=n[u],_=null==r?p:r(p),p=e||0!==p?p:0;if(a&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function bt(n,t){var r=true;return uo(n,function(n,e,u){return r=!!t(n,e,u)}),r}function xt(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===T?o===o&&!wu(o):r(o,f)))var f=o,c=i;
|
||||
}return c}function jt(n,t){var r=[];return uo(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function wt(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=ke),u||(u=[]);++i<o;){var f=n[i];0<t&&r(f)?1<t?wt(f,t-1,r,e,u):a(u,f):e||(u[u.length]=f)}return u}function mt(n,t){return n&&oo(n,t,Wu)}function At(n,t){return n&&fo(n,t,Wu)}function Et(n,t){return i(t,function(t){return _u(n[t])})}function kt(n,t){t=Sr(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[Me(t[r++])];return r&&r==e?n:T}function St(n,t,r){return t=t(n),
|
||||
ff(n)?t:a(t,r(n))}function Ot(n){if(null==n)n=n===T?"[object Undefined]":"[object Null]";else if(mi&&mi in Qu(n)){var t=oi.call(n,mi),r=n[mi];try{n[mi]=T;var e=true}catch(n){}var u=ai.call(n);e&&(t?n[mi]=r:delete n[mi]),n=u}else n=ai.call(n);return n}function It(n,t){return n>t}function Rt(n,t){return null!=n&&oi.call(n,t)}function zt(n,t){return null!=n&&t in Qu(n)}function Wt(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=Ku(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,k(t))),s=Ci(p.length,s),
|
||||
l[a]=!r&&(t||120<=u&&120<=p.length)?new Nn(a&&p):T}var p=n[0],_=-1,v=l[0];n:for(;++_<u&&h.length<s;){var g=p[_],d=t?t(g):g,g=r||0!==g?g:0;if(v?!O(v,d):!e(h,d,r)){for(a=i;--a;){var y=l[a];if(y?!O(y,d):!e(n[a],d,r))continue n}v&&v.push(d),h.push(g)}}return h}function Bt(n,t,r){var e={};return mt(n,function(n,u,i){t(e,r(n),u,i)}),e}function Lt(t,r,e){return r=Sr(r,t),t=2>r.length?t:kt(t,hr(r,0,-1)),r=null==t?t:t[Me(Ve(r))],null==r?T:n(r,t,e)}function Ut(n){return yu(n)&&"[object Arguments]"==Ot(n)}function Ct(n){
|
||||
return yu(n)&&"[object ArrayBuffer]"==Ot(n)}function Dt(n){return yu(n)&&"[object Date]"==Ot(n)}function Mt(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!yu(n)&&!yu(t))t=n!==n&&t!==t;else n:{var i=ff(n),o=ff(t),f=i?"[object Array]":vo(n),c=o?"[object Array]":vo(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&af(n)){if(!af(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Zn),t=i||_f(n)?se(n,t,r,e,Mt,u):he(n,t,f,r,e,Mt,u);else{
|
||||
if(!(1&r)&&(i=a&&oi.call(n,"__wrapped__"),f=o&&oi.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Zn),t=Mt(n,t,r,e,u);break n}if(c)t:if(u||(u=new Zn),i=1&r,f=_e(n),o=f.length,c=_e(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:oi.call(t,l))){t=false;break t}}if((c=u.get(n))&&u.get(t))t=c==t;else{c=true,u.set(n,t),u.set(t,n);for(var s=i;++a<o;){var l=f[a],h=n[l],p=t[l];if(e)var _=i?e(p,h,l,t,n,u):e(h,p,l,n,t,u);if(_===T?h!==p&&!Mt(h,p,r,e,u):!_){c=false;break}s||(s="constructor"==l);
|
||||
}c&&!s&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(c=false)),u.delete(n),u.delete(t),t=c}}else t=false;else t=false}}return t}function Tt(n){return yu(n)&&"[object Map]"==vo(n)}function $t(n,t,r,e){var u=r.length,i=u,o=!e;if(null==n)return!i;for(n=Qu(n);u--;){var f=r[u];if(o&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return false}for(;++u<i;){var f=r[u],c=f[0],a=n[c],l=f[1];if(o&&f[2]){if(a===T&&!(c in n))return false;
|
||||
}else{if(f=new Zn,e)var s=e(a,l,c,n,t,f);if(s===T?!Mt(l,a,3,e,f):!s)return false}}return true}function Ft(n){return!(!du(n)||ci&&ci in n)&&(_u(n)?hi:dn).test(Te(n))}function Nt(n){return yu(n)&&"[object RegExp]"==Ot(n)}function Pt(n){return yu(n)&&"[object Set]"==vo(n)}function Zt(n){return yu(n)&&gu(n.length)&&!!Bn[Ot(n)]}function qt(n){return typeof n=="function"?n:null==n?$u:typeof n=="object"?ff(n)?Jt(n[0],n[1]):Ht(n):Zu(n)}function Vt(n){if(!ze(n))return Li(n);var t,r=[];for(t in Qu(n))oi.call(n,t)&&"constructor"!=t&&r.push(t);
|
||||
return r}function Kt(n,t){return n<t}function Gt(n,t){var r=-1,e=su(n)?Ku(n.length):[];return uo(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Ht(n){var t=xe(n);return 1==t.length&&t[0][2]?We(t[0][0],t[0][1]):function(r){return r===n||$t(r,n,t)}}function Jt(n,t){return Ie(n)&&t===t&&!du(t)?We(Me(n),t):function(r){var e=Ru(r,n);return e===T&&e===t?zu(r,n):Mt(t,e,3)}}function Yt(n,t,r,e,u){n!==t&&oo(t,function(i,o){if(u||(u=new Zn),du(i)){var f=u,c=Le(n,o),a=Le(t,o),l=f.get(a);if(l)it(n,o,l);else{
|
||||
var l=e?e(c,a,o+"",n,t,f):T,s=l===T;if(s){var h=ff(a),p=!h&&af(a),_=!h&&!p&&_f(a),l=a;h||p||_?ff(c)?l=c:hu(c)?l=Ur(c):p?(s=false,l=Ir(a,true)):_?(s=false,l=zr(a,true)):l=[]:xu(a)||of(a)?(l=c,of(c)?l=Ou(c):du(c)&&!_u(c)||(l=Ae(a))):s=false}s&&(f.set(a,l),Yt(l,a,r,e,f),f.delete(a)),it(n,o,l)}}else f=e?e(Le(n,o),i,o+"",n,t,u):T,f===T&&(f=i),it(n,o,f)},Bu)}function Qt(n,t){var r=n.length;if(r)return t+=0>t?r:0,Se(t,r)?n[t]:T}function Xt(n,t,r){var e=-1;return t=c(t.length?t:[$u],k(ye())),n=Gt(n,function(n){return{
|
||||
a:c(t,function(t){return t(n)}),b:++e,c:n}}),w(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e<o;){var c=Wr(u[e],i[e]);if(c){e=e>=f?c:c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function nr(n,t){return tr(n,t,function(t,r){return zu(n,r)})}function tr(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=kt(n,o);r(f,o)&&lr(i,Sr(o,n),f)}return i}function rr(n){return function(t){return kt(t,n)}}function er(n,t,r,e){var u=e?g:v,i=-1,o=t.length,f=n;for(n===t&&(t=Ur(t)),
|
||||
r&&(f=c(n,k(r)));++i<o;)for(var a=0,l=t[i],l=r?r(l):l;-1<(a=u(f,l,a,e));)f!==n&&xi.call(f,a,1),xi.call(n,a,1);return n}function ur(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;Se(u)?xi.call(n,u,1):xr(n,u)}}}function ir(n,t){return n+Ii(Ti()*(t-n+1))}function or(n,t){var r="";if(!n||1>t||9007199254740991<t)return r;do t%2&&(r+=n),(t=Ii(t/2))&&(n+=n);while(t);return r}function fr(n,t){return xo(Be(n,t,$u),n+"")}function cr(n){return Qn(Uu(n))}function ar(n,t){var r=Uu(n);
|
||||
return De(r,pt(t,0,r.length))}function lr(n,t,r,e){if(!du(n))return n;t=Sr(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){var c=Me(t[u]),a=r;if(u!=o){var l=f[c],a=e?e(l,c,f):T;a===T&&(a=du(l)?l:Se(t[u+1])?[]:{})}ot(f,c,a),f=f[c]}return n}function sr(n){return De(Uu(n))}function hr(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Ku(u);++e<u;)r[e]=n[e+t];return r}function pr(n,t){var r;return uo(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}
|
||||
function _r(n,t,r){var e=0,u=null==n?e:n.length;if(typeof t=="number"&&t===t&&2147483647>=u){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!wu(o)&&(r?o<=t:o<t)?e=i+1:u=i}return u}return vr(n,t,$u,r)}function vr(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=wu(t),a=t===T;u<i;){var l=Ii((u+i)/2),s=r(n[l]),h=s!==T,p=null===s,_=s===s,v=wu(s);(o?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?s<=t:s<t)?u=l+1:i=l}return Ci(i,4294967294)}function gr(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){
|
||||
var o=n[r],f=t?t(o):o;if(!r||!lu(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function dr(n){return typeof n=="number"?n:wu(n)?F:+n}function yr(n){if(typeof n=="string")return n;if(ff(n))return c(n,yr)+"";if(wu(n))return ro?ro.call(n):"";var t=n+"";return"0"==t&&1/n==-$?"-0":t}function br(n,t,r){var e=-1,u=o,i=n.length,c=true,a=[],l=a;if(r)c=false,u=f;else if(200<=i){if(u=t?null:so(n))return U(u);c=false,u=O,l=new Nn}else l=t?[]:a;n:for(;++e<i;){var s=n[e],h=t?t(s):s,s=r||0!==s?s:0;if(c&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;
|
||||
t&&l.push(h),a.push(s)}else u(l,h,r)||(l!==a&&l.push(h),a.push(s))}return a}function xr(n,t){return t=Sr(t,n),n=2>t.length?n:kt(n,hr(t,0,-1)),null==n||delete n[Me(Ve(t))]}function jr(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?hr(n,e?0:i,e?i+1:u):hr(n,e?i+1:0,e?u:i)}function wr(n,t){var r=n;return r instanceof Un&&(r=r.value()),l(t,function(n,t){return t.func.apply(t.thisArg,a([n],t.args))},r)}function mr(n,t,r){var e=n.length;if(2>e)return e?br(n[0]):[];for(var u=-1,i=Ku(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=yt(i[u]||o,n[f],t,r));
|
||||
return br(wt(i,1),t,r)}function Ar(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;)r(o,n[e],e<i?t[e]:T);return o}function Er(n){return hu(n)?n:[]}function kr(n){return typeof n=="function"?n:$u}function Sr(n,t){return ff(n)?n:Ie(n,t)?[n]:jo(Iu(n))}function Or(n,t,r){var e=n.length;return r=r===T?e:r,!t&&r>=e?n:hr(n,t,r)}function Ir(n,t){if(t)return n.slice();var r=n.length,r=gi?gi(r):new n.constructor(r);return n.copy(r),r}function Rr(n){var t=new n.constructor(n.byteLength);return new vi(t).set(new vi(n)),
|
||||
t}function zr(n,t){return new n.constructor(t?Rr(n.buffer):n.buffer,n.byteOffset,n.length)}function Wr(n,t){if(n!==t){var r=n!==T,e=null===n,u=n===n,i=wu(n),o=t!==T,f=null===t,c=t===t,a=wu(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Br(n,t,r,e){var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Ui(i-o,0),l=Ku(c+a);for(e=!e;++f<c;)l[f]=t[f];for(;++u<o;)(e||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];
|
||||
return l}function Lr(n,t,r,e){var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Ui(i-f,0),s=Ku(l+a);for(e=!e;++u<l;)s[u]=n[u];for(l=u;++c<a;)s[l+c]=t[c];for(;++o<f;)(e||u<i)&&(s[l+r[o]]=n[u++]);return s}function Ur(n,t){var r=-1,e=n.length;for(t||(t=Ku(e));++r<e;)t[r]=n[r];return t}function Cr(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):T;c===T&&(c=n[f]),u?st(r,f,c):ot(r,f,c)}return r}function Dr(n,t){return Cr(n,po(n),t)}function Mr(n,t){return Cr(n,_o(n),t);
|
||||
}function Tr(n,r){return function(e,u){var i=ff(e)?t:ct,o=r?r():{};return i(e,n,ye(u,2),o)}}function $r(n){return fr(function(t,r){var e=-1,u=r.length,i=1<u?r[u-1]:T,o=2<u?r[2]:T,i=3<n.length&&typeof i=="function"?(u--,i):T;for(o&&Oe(r[0],r[1],o)&&(i=3>u?T:i,u=1),t=Qu(t);++e<u;)(o=r[e])&&n(t,o,e,i);return t})}function Fr(n,t){return function(r,e){if(null==r)return r;if(!su(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=Qu(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function Nr(n){return function(t,r,e){
|
||||
var u=-1,i=Qu(t);e=e(t);for(var o=e.length;o--;){var f=e[n?o:++u];if(false===r(i[f],f,i))break}return t}}function Pr(n,t,r){function e(){return(this&&this!==$n&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=1&t,i=Vr(n);return e}function Zr(n){return function(t){t=Iu(t);var r=Rn.test(t)?M(t):T,e=r?r[0]:t.charAt(0);return t=r?Or(r,1).join(""):t.slice(1),e[n]()+t}}function qr(n){return function(t){return l(Mu(Du(t).replace(kn,"")),n,"")}}function Vr(n){return function(){var t=arguments;switch(t.length){
|
||||
case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=eo(n.prototype),t=n.apply(r,t);return du(t)?t:r}}function Kr(t,r,e){function u(){for(var o=arguments.length,f=Ku(o),c=o,a=de(u);c--;)f[c]=arguments[c];return c=3>o&&f[0]!==a&&f[o-1]!==a?[]:L(f,a),
|
||||
o-=c.length,o<e?ue(t,r,Jr,u.placeholder,T,f,c,T,T,e-o):n(this&&this!==$n&&this instanceof u?i:t,this,f)}var i=Vr(t);return u}function Gr(n){return function(t,r,e){var u=Qu(t);if(!su(t)){var i=ye(r,3);t=Wu(t),r=function(n){return i(u[n],n,u)}}return r=n(t,r,e),-1<r?u[i?t[r]:r]:T}}function Hr(n){return pe(function(t){var r=t.length,e=r,u=On.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if(typeof i!="function")throw new ti("Expected a function");if(u&&!o&&"wrapper"==ge(i))var o=new On([],true)}for(e=o?e:r;++e<r;)var i=t[e],u=ge(i),f="wrapper"==u?ho(i):T,o=f&&Re(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?o[ge(f[0])].apply(o,f[3]):1==i.length&&Re(i)?o[u]():o.thru(i);
|
||||
return function(){var n=arguments,e=n[0];if(o&&1==n.length&&ff(e))return o.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}})}function Jr(n,t,r,e,u,i,o,f,c,a){function l(){for(var d=arguments.length,y=Ku(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=de(l),b=y.length;for(x=0;b--;)y[b]===j&&++x}if(e&&(y=Br(y,e,u,_)),i&&(y=Lr(y,i,o,_)),d-=x,_&&d<a)return j=L(y,j),ue(n,t,Jr,l.placeholder,r,y,j,f,c,a-d);if(j=h?r:this,b=p?j[n]:n,d=y.length,f){x=y.length;for(var w=Ci(f.length,x),m=Ur(y);w--;){
|
||||
var A=f[w];y[w]=Se(A,x)?m[A]:T}}else v&&1<d&&y.reverse();return s&&c<d&&(y.length=c),this&&this!==$n&&this instanceof l&&(b=g||Vr(b)),b.apply(j,y)}var s=128&t,h=1&t,p=2&t,_=24&t,v=512&t,g=p?T:Vr(n);return l}function Yr(n,t){return function(r,e){return Bt(r,n,t(e))}}function Qr(n,t){return function(r,e){var u;if(r===T&&e===T)return t;if(r!==T&&(u=r),e!==T){if(u===T)return e;typeof r=="string"||typeof e=="string"?(r=yr(r),e=yr(e)):(r=dr(r),e=dr(e)),u=n(r,e)}return u}}function Xr(t){return pe(function(r){
|
||||
return r=c(r,k(ye())),fr(function(e){var u=this;return t(r,function(t){return n(t,u,e)})})})}function ne(n,t){t=t===T?" ":yr(t);var r=t.length;return 2>r?r?or(t,n):t:(r=or(t,Oi(n/D(t))),Rn.test(t)?Or(M(r),0,n).join(""):r.slice(0,n))}function te(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=Ku(l+c),h=this&&this!==$n&&this instanceof i?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++r];return n(h,o?e:this,s)}var o=1&r,f=Vr(t);return i}function re(n){return function(t,r,e){
|
||||
e&&typeof e!="number"&&Oe(t,r,e)&&(r=e=T),t=Au(t),r===T?(r=t,t=0):r=Au(r),e=e===T?t<r?1:-1:Au(e);var u=-1;r=Ui(Oi((r-t)/(e||1)),0);for(var i=Ku(r);r--;)i[n?r:++u]=t,t+=e;return i}}function ee(n){return function(t,r){return typeof t=="string"&&typeof r=="string"||(t=Su(t),r=Su(r)),n(t,r)}}function ue(n,t,r,e,u,i,o,f,c,a){var l=8&t,s=l?o:T;o=l?T:o;var h=l?i:T;return i=l?T:i,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),u=[n,t,u,h,s,i,o,f,c,a],r=r.apply(T,u),Re(n)&&yo(r,u),r.placeholder=e,Ue(r,n,t)}function ie(n){
|
||||
var t=Yu[n];return function(n,r){if(n=Su(n),(r=null==r?0:Ci(Eu(r),292))&&Wi(n)){var e=(Iu(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(Iu(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function oe(n){return function(t){var r=vo(t);return"[object Map]"==r?W(t):"[object Set]"==r?C(t):E(t,n(t))}}function fe(n,t,r,e,u,i,o,f){var c=2&t;if(!c&&typeof n!="function")throw new ti("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=T),o=o===T?o:Ui(Eu(o),0),f=f===T?f:Eu(f),a-=u?u.length:0,
|
||||
64&t){var l=e,s=u;e=u=T}var h=c?T:ho(n);return i=[n,t,r,e,u,l,s,i,o,f],h&&(r=i[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&i[7].length<=h[8]||384==n&&h[7].length<=h[8]&&8==r,131>t||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Br(e,r,h[4]):r,i[4]=e?L(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Lr(e,r,h[6]):r,i[6]=e?L(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Ci(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],
|
||||
t=i[1],r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===T?c?0:n.length:Ui(i[9]-a,0),!f&&24&t&&(t&=-25),Ue((h?co:yo)(t&&1!=t?8==t||16==t?Kr(n,t,f):32!=t&&33!=t||u.length?Jr.apply(T,i):te(n,t,r,e):Pr(n,t,r),i),n,t)}function ce(n,t,r,e){return n===T||lu(n,ei[r])&&!oi.call(e,r)?t:n}function ae(n,t,r,e,u,i){return du(n)&&du(t)&&(i.set(t,n),Yt(n,t,T,ae,i),i.delete(t)),n}function le(n){return xu(n)?T:n}function se(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;
|
||||
var c=-1,a=true,l=2&r?new Nn:T;for(i.set(n,t),i.set(t,n);++c<f;){var s=n[c],p=t[c];if(e)var _=o?e(p,s,c,t,n,i):e(s,p,c,n,t,i);if(_!==T){if(_)continue;a=false;break}if(l){if(!h(t,function(n,t){if(!O(l,t)&&(s===n||u(s,n,r,e,i)))return l.push(t)})){a=false;break}}else if(s!==p&&!u(s,p,r,e,i)){a=false;break}}return i.delete(n),i.delete(t),a}function he(n,t,r,e,u,i,o){switch(r){case"[object DataView]":if(n.byteLength!=t.byteLength||n.byteOffset!=t.byteOffset)break;n=n.buffer,t=t.buffer;case"[object ArrayBuffer]":
|
||||
if(n.byteLength!=t.byteLength||!i(new vi(n),new vi(t)))break;return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return lu(+n,+t);case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object RegExp]":case"[object String]":return n==t+"";case"[object Map]":var f=W;case"[object Set]":if(f||(f=U),n.size!=t.size&&!(1&e))break;return(r=o.get(n))?r==t:(e|=2,o.set(n,t),t=se(f(n),f(t),e,u,i,o),o.delete(n),t);case"[object Symbol]":if(to)return to.call(n)==to.call(t)}
|
||||
return false}function pe(n){return xo(Be(n,T,Ze),n+"")}function _e(n){return St(n,Wu,po)}function ve(n){return St(n,Bu,_o)}function ge(n){for(var t=n.name+"",r=Gi[t],e=oi.call(Gi,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function de(n){return(oi.call(An,"placeholder")?An:n).placeholder}function ye(){var n=An.iteratee||Fu,n=n===Fu?qt:n;return arguments.length?n(arguments[0],arguments[1]):n}function be(n,t){var r=n.__data__,e=typeof t;return("string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t)?r[typeof t=="string"?"string":"hash"]:r.map;
|
||||
}function xe(n){for(var t=Wu(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,u===u&&!du(u)]}return t}function je(n,t){var r=null==n?T:n[t];return Ft(r)?r:T}function we(n,t,r){t=Sr(t,n);for(var e=-1,u=t.length,i=false;++e<u;){var o=Me(t[e]);if(!(i=null!=n&&r(n,o)))break;n=n[o]}return i||++e!=u?i:(u=null==n?0:n.length,!!u&&gu(u)&&Se(o,u)&&(ff(n)||of(n)))}function me(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&oi.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Ae(n){
|
||||
return typeof n.constructor!="function"||ze(n)?{}:eo(di(n))}function Ee(n,t,r){var e=n.constructor;switch(t){case"[object ArrayBuffer]":return Rr(n);case"[object Boolean]":case"[object Date]":return new e(+n);case"[object DataView]":return t=r?Rr(n.buffer):n.buffer,new n.constructor(t,n.byteOffset,n.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":
|
||||
case"[object Uint16Array]":case"[object Uint32Array]":return zr(n,r);case"[object Map]":return new e;case"[object Number]":case"[object String]":return new e(n);case"[object RegExp]":return t=new n.constructor(n.source,_n.exec(n)),t.lastIndex=n.lastIndex,t;case"[object Set]":return new e;case"[object Symbol]":return to?Qu(to.call(n)):{}}}function ke(n){return ff(n)||of(n)||!!(ji&&n&&n[ji])}function Se(n,t){var r=typeof n;return t=null==t?9007199254740991:t,!!t&&("number"==r||"symbol"!=r&&bn.test(n))&&-1<n&&0==n%1&&n<t;
|
||||
}function Oe(n,t,r){if(!du(r))return false;var e=typeof t;return!!("number"==e?su(r)&&Se(t,r.length):"string"==e&&t in r)&&lu(r[t],n)}function Ie(n,t){if(ff(n))return false;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!wu(n))||(nn.test(n)||!X.test(n)||null!=t&&n in Qu(t))}function Re(n){var t=ge(n),r=An[t];return typeof r=="function"&&t in Un.prototype&&(n===r||(t=ho(r),!!t&&n===t[0]))}function ze(n){var t=n&&n.constructor;return n===(typeof t=="function"&&t.prototype||ei)}function We(n,t){
|
||||
return function(r){return null!=r&&(r[n]===t&&(t!==T||n in Qu(r)))}}function Be(t,r,e){return r=Ui(r===T?t.length-1:r,0),function(){for(var u=arguments,i=-1,o=Ui(u.length-r,0),f=Ku(o);++i<o;)f[i]=u[r+i];for(i=-1,o=Ku(r+1);++i<r;)o[i]=u[i];return o[r]=e(f),n(t,this,o)}}function Le(n,t){if(("constructor"!==t||"function"!=typeof n[t])&&"__proto__"!=t)return n[t]}function Ue(n,t,r){var e=t+"";t=xo;var u,i=$e;return u=(u=e.match(an))?u[1].split(ln):[],r=i(u,r),(i=r.length)&&(u=i-1,r[u]=(1<i?"& ":"")+r[u],
|
||||
r=r.join(2<i?", ":" "),e=e.replace(cn,"{\n/* [wrapped with "+r+"] */\n")),t(n,e)}function Ce(n){var t=0,r=0;return function(){var e=Di(),u=16-(e-r);if(r=e,0<u){if(800<=++t)return arguments[0]}else t=0;return n.apply(T,arguments)}}function De(n,t){var r=-1,e=n.length,u=e-1;for(t=t===T?e:t;++r<t;){var e=ir(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function Me(n){if(typeof n=="string"||wu(n))return n;var t=n+"";return"0"==t&&1/n==-$?"-0":t}function Te(n){if(null!=n){try{return ii.call(n)}catch(n){}
|
||||
return n+""}return""}function $e(n,t){return r(N,function(r){var e="_."+r[0];t&r[1]&&!o(n,e)&&n.push(e)}),n.sort()}function Fe(n){if(n instanceof Un)return n.clone();var t=new On(n.__wrapped__,n.__chain__);return t.__actions__=Ur(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Ne(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Eu(r),0>r&&(r=Ui(e+r,0)),_(n,ye(t,3),r)):-1}function Pe(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==T&&(u=Eu(r),u=0>r?Ui(e+u,0):Ci(u,e-1)),
|
||||
_(n,ye(t,3),u,true)}function Ze(n){return(null==n?0:n.length)?wt(n,1):[]}function qe(n){return n&&n.length?n[0]:T}function Ve(n){var t=null==n?0:n.length;return t?n[t-1]:T}function Ke(n,t){return n&&n.length&&t&&t.length?er(n,t):n}function Ge(n){return null==n?n:$i.call(n)}function He(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(hu(n))return t=Ui(n.length,t),true}),A(t,function(t){return c(n,b(t))})}function Je(t,r){if(!t||!t.length)return[];var e=He(t);return null==r?e:c(e,function(t){
|
||||
return n(r,T,t)})}function Ye(n){return n=An(n),n.__chain__=true,n}function Qe(n,t){return t(n)}function Xe(){return this}function nu(n,t){return(ff(n)?r:uo)(n,ye(t,3))}function tu(n,t){return(ff(n)?e:io)(n,ye(t,3))}function ru(n,t){return(ff(n)?c:Gt)(n,ye(t,3))}function eu(n,t,r){return t=r?T:t,t=n&&null==t?n.length:t,fe(n,128,T,T,T,T,t)}function uu(n,t){var r;if(typeof t!="function")throw new ti("Expected a function");return n=Eu(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=T),
|
||||
r}}function iu(n,t,r){return t=r?T:t,n=fe(n,8,T,T,T,T,T,t),n.placeholder=iu.placeholder,n}function ou(n,t,r){return t=r?T:t,n=fe(n,16,T,T,T,T,T,t),n.placeholder=ou.placeholder,n}function fu(n,t,r){function e(t){var r=c,e=a;return c=a=T,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===T||r>=t||0>r||g&&n>=l}function i(){var n=Go();if(u(n))return o(n);var r,e=bo;r=n-_,n=t-(n-p),r=g?Ci(n,l-r):n,h=e(i,r)}function o(n){return h=T,d&&c?e(n):(c=a=T,s)}function f(){var n=Go(),r=u(n);if(c=arguments,
|
||||
a=this,p=n,r){if(h===T)return _=n=p,h=bo(i,t),v?e(n):s;if(g)return lo(h),h=bo(i,t),e(p)}return h===T&&(h=bo(i,t)),s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ti("Expected a function");return t=Su(t)||0,du(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Ui(Su(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==T&&lo(h),_=0,c=p=a=h=T},f.flush=function(){return h===T?s:o(Go())},f}function cu(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;
|
||||
return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e)||i,e)}if(typeof n!="function"||null!=t&&typeof t!="function")throw new ti("Expected a function");return r.cache=new(cu.Cache||Fn),r}function au(n){if(typeof n!="function")throw new ti("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function lu(n,t){return n===t||n!==n&&t!==t;
|
||||
}function su(n){return null!=n&&gu(n.length)&&!_u(n)}function hu(n){return yu(n)&&su(n)}function pu(n){if(!yu(n))return false;var t=Ot(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!xu(n)}function _u(n){return!!du(n)&&(n=Ot(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function vu(n){return typeof n=="number"&&n==Eu(n)}function gu(n){return typeof n=="number"&&-1<n&&0==n%1&&9007199254740991>=n;
|
||||
}function du(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function yu(n){return null!=n&&typeof n=="object"}function bu(n){return typeof n=="number"||yu(n)&&"[object Number]"==Ot(n)}function xu(n){return!(!yu(n)||"[object Object]"!=Ot(n))&&(n=di(n),null===n||(n=oi.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&ii.call(n)==li))}function ju(n){return typeof n=="string"||!ff(n)&&yu(n)&&"[object String]"==Ot(n)}function wu(n){return typeof n=="symbol"||yu(n)&&"[object Symbol]"==Ot(n);
|
||||
}function mu(n){if(!n)return[];if(su(n))return ju(n)?M(n):Ur(n);if(wi&&n[wi]){n=n[wi]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=vo(n),("[object Map]"==t?W:"[object Set]"==t?U:Uu)(n)}function Au(n){return n?(n=Su(n),n===$||n===-$?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Eu(n){n=Au(n);var t=n%1;return n===n?t?n-t:n:0}function ku(n){return n?pt(Eu(n),0,4294967295):0}function Su(n){if(typeof n=="number")return n;if(wu(n))return F;if(du(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,
|
||||
n=du(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(un,"");var t=gn.test(n);return t||yn.test(n)?Dn(n.slice(2),t?2:8):vn.test(n)?F:+n}function Ou(n){return Cr(n,Bu(n))}function Iu(n){return null==n?"":yr(n)}function Ru(n,t,r){return n=null==n?T:kt(n,t),n===T?r:n}function zu(n,t){return null!=n&&we(n,t,zt)}function Wu(n){return su(n)?qn(n):Vt(n)}function Bu(n){if(su(n))n=qn(n,true);else if(du(n)){var t,r=ze(n),e=[];for(t in n)("constructor"!=t||!r&&oi.call(n,t))&&e.push(t);n=e}else{if(t=[],
|
||||
null!=n)for(r in Qu(n))t.push(r);n=t}return n}function Lu(n,t){if(null==n)return{};var r=c(ve(n),function(n){return[n]});return t=ye(t),tr(n,r,function(n,r){return t(n,r[0])})}function Uu(n){return null==n?[]:S(n,Wu(n))}function Cu(n){return $f(Iu(n).toLowerCase())}function Du(n){return(n=Iu(n))&&n.replace(xn,Xn).replace(Sn,"")}function Mu(n,t,r){return n=Iu(n),t=r?T:t,t===T?zn.test(n)?n.match(In)||[]:n.match(sn)||[]:n.match(t)||[]}function Tu(n){return function(){return n}}function $u(n){return n;
|
||||
}function Fu(n){return qt(typeof n=="function"?n:_t(n,1))}function Nu(n,t,e){var u=Wu(t),i=Et(t,u);null!=e||du(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=Et(t,Wu(t)));var o=!(du(e)&&"chain"in e&&!e.chain),f=_u(n);return r(i,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Ur(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Pu(){}
|
||||
function Zu(n){return Ie(n)?b(Me(n)):rr(n)}function qu(){return[]}function Vu(){return false}mn=null==mn?$n:rt.defaults($n.Object(),mn,rt.pick($n,Wn));var Ku=mn.Array,Gu=mn.Date,Hu=mn.Error,Ju=mn.Function,Yu=mn.Math,Qu=mn.Object,Xu=mn.RegExp,ni=mn.String,ti=mn.TypeError,ri=Ku.prototype,ei=Qu.prototype,ui=mn["__core-js_shared__"],ii=Ju.prototype.toString,oi=ei.hasOwnProperty,fi=0,ci=function(){var n=/[^.]+$/.exec(ui&&ui.keys&&ui.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),ai=ei.toString,li=ii.call(Qu),si=$n._,hi=Xu("^"+ii.call(oi).replace(rn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),pi=Pn?mn.Buffer:T,_i=mn.Symbol,vi=mn.Uint8Array,gi=pi?pi.g:T,di=B(Qu.getPrototypeOf,Qu),yi=Qu.create,bi=ei.propertyIsEnumerable,xi=ri.splice,ji=_i?_i.isConcatSpreadable:T,wi=_i?_i.iterator:T,mi=_i?_i.toStringTag:T,Ai=function(){
|
||||
try{var n=je(Qu,"defineProperty");return n({},"",{}),n}catch(n){}}(),Ei=mn.clearTimeout!==$n.clearTimeout&&mn.clearTimeout,ki=Gu&&Gu.now!==$n.Date.now&&Gu.now,Si=mn.setTimeout!==$n.setTimeout&&mn.setTimeout,Oi=Yu.ceil,Ii=Yu.floor,Ri=Qu.getOwnPropertySymbols,zi=pi?pi.isBuffer:T,Wi=mn.isFinite,Bi=ri.join,Li=B(Qu.keys,Qu),Ui=Yu.max,Ci=Yu.min,Di=Gu.now,Mi=mn.parseInt,Ti=Yu.random,$i=ri.reverse,Fi=je(mn,"DataView"),Ni=je(mn,"Map"),Pi=je(mn,"Promise"),Zi=je(mn,"Set"),qi=je(mn,"WeakMap"),Vi=je(Qu,"create"),Ki=qi&&new qi,Gi={},Hi=Te(Fi),Ji=Te(Ni),Yi=Te(Pi),Qi=Te(Zi),Xi=Te(qi),no=_i?_i.prototype:T,to=no?no.valueOf:T,ro=no?no.toString:T,eo=function(){
|
||||
function n(){}return function(t){return du(t)?yi?yi(t):(n.prototype=t,t=new n,n.prototype=T,t):{}}}();An.templateSettings={escape:J,evaluate:Y,interpolate:Q,variable:"",imports:{_:An}},An.prototype=En.prototype,An.prototype.constructor=An,On.prototype=eo(En.prototype),On.prototype.constructor=On,Un.prototype=eo(En.prototype),Un.prototype.constructor=Un,Mn.prototype.clear=function(){this.__data__=Vi?Vi(null):{},this.size=0},Mn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n],
|
||||
this.size-=n?1:0,n},Mn.prototype.get=function(n){var t=this.__data__;return Vi?(n=t[n],"__lodash_hash_undefined__"===n?T:n):oi.call(t,n)?t[n]:T},Mn.prototype.has=function(n){var t=this.__data__;return Vi?t[n]!==T:oi.call(t,n)},Mn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=Vi&&t===T?"__lodash_hash_undefined__":t,this},Tn.prototype.clear=function(){this.__data__=[],this.size=0},Tn.prototype.delete=function(n){var t=this.__data__;return n=ft(t,n),!(0>n)&&(n==t.length-1?t.pop():xi.call(t,n,1),
|
||||
--this.size,true)},Tn.prototype.get=function(n){var t=this.__data__;return n=ft(t,n),0>n?T:t[n][1]},Tn.prototype.has=function(n){return-1<ft(this.__data__,n)},Tn.prototype.set=function(n,t){var r=this.__data__,e=ft(r,n);return 0>e?(++this.size,r.push([n,t])):r[e][1]=t,this},Fn.prototype.clear=function(){this.size=0,this.__data__={hash:new Mn,map:new(Ni||Tn),string:new Mn}},Fn.prototype.delete=function(n){return n=be(this,n).delete(n),this.size-=n?1:0,n},Fn.prototype.get=function(n){return be(this,n).get(n);
|
||||
},Fn.prototype.has=function(n){return be(this,n).has(n)},Fn.prototype.set=function(n,t){var r=be(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},Nn.prototype.add=Nn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},Nn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.clear=function(){this.__data__=new Tn,this.size=0},Zn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Zn.prototype.get=function(n){
|
||||
return this.__data__.get(n)},Zn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Tn){var e=r.__data__;if(!Ni||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Fn(e)}return r.set(n,t),this.size=r.size,this};var uo=Fr(mt),io=Fr(At,true),oo=Nr(),fo=Nr(true),co=Ki?function(n,t){return Ki.set(n,t),n}:$u,ao=Ai?function(n,t){return Ai(n,"toString",{configurable:true,enumerable:false,value:Tu(t),writable:true})}:$u,lo=Ei||function(n){
|
||||
return $n.clearTimeout(n)},so=Zi&&1/U(new Zi([,-0]))[1]==$?function(n){return new Zi(n)}:Pu,ho=Ki?function(n){return Ki.get(n)}:Pu,po=Ri?function(n){return null==n?[]:(n=Qu(n),i(Ri(n),function(t){return bi.call(n,t)}))}:qu,_o=Ri?function(n){for(var t=[];n;)a(t,po(n)),n=di(n);return t}:qu,vo=Ot;(Fi&&"[object DataView]"!=vo(new Fi(new ArrayBuffer(1)))||Ni&&"[object Map]"!=vo(new Ni)||Pi&&"[object Promise]"!=vo(Pi.resolve())||Zi&&"[object Set]"!=vo(new Zi)||qi&&"[object WeakMap]"!=vo(new qi))&&(vo=function(n){
|
||||
var t=Ot(n);if(n=(n="[object Object]"==t?n.constructor:T)?Te(n):"")switch(n){case Hi:return"[object DataView]";case Ji:return"[object Map]";case Yi:return"[object Promise]";case Qi:return"[object Set]";case Xi:return"[object WeakMap]"}return t});var go=ui?_u:Vu,yo=Ce(co),bo=Si||function(n,t){return $n.setTimeout(n,t)},xo=Ce(ao),jo=function(n){n=cu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return 46===n.charCodeAt(0)&&t.push(""),n.replace(tn,function(n,r,e,u){
|
||||
t.push(e?u.replace(hn,"$1"):r||n)}),t}),wo=fr(function(n,t){return hu(n)?yt(n,wt(t,1,hu,true)):[]}),mo=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),ye(r,2)):[]}),Ao=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),T,r):[]}),Eo=fr(function(n){var t=c(n,Er);return t.length&&t[0]===n[0]?Wt(t):[]}),ko=fr(function(n){var t=Ve(n),r=c(n,Er);return t===Ve(r)?t=T:r.pop(),r.length&&r[0]===n[0]?Wt(r,ye(t,2)):[]}),So=fr(function(n){var t=Ve(n),r=c(n,Er);return(t=typeof t=="function"?t:T)&&r.pop(),
|
||||
r.length&&r[0]===n[0]?Wt(r,T,t):[]}),Oo=fr(Ke),Io=pe(function(n,t){var r=null==n?0:n.length,e=ht(n,t);return ur(n,c(t,function(n){return Se(n,r)?+n:n}).sort(Wr)),e}),Ro=fr(function(n){return br(wt(n,1,hu,true))}),zo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),br(wt(n,1,hu,true),ye(t,2))}),Wo=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return br(wt(n,1,hu,true),T,t)}),Bo=fr(function(n,t){return hu(n)?yt(n,t):[]}),Lo=fr(function(n){return mr(i(n,hu))}),Uo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),
|
||||
mr(i(n,hu),ye(t,2))}),Co=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return mr(i(n,hu),T,t)}),Do=fr(He),Mo=fr(function(n){var t=n.length,t=1<t?n[t-1]:T,t=typeof t=="function"?(n.pop(),t):T;return Je(n,t)}),To=pe(function(n){function t(t){return ht(t,n)}var r=n.length,e=r?n[0]:0,u=this.__wrapped__;return!(1<r||this.__actions__.length)&&u instanceof Un&&Se(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:Qe,args:[t],thisArg:T}),new On(u,this.__chain__).thru(function(n){return r&&!n.length&&n.push(T),
|
||||
n})):this.thru(t)}),$o=Tr(function(n,t,r){oi.call(n,r)?++n[r]:st(n,r,1)}),Fo=Gr(Ne),No=Gr(Pe),Po=Tr(function(n,t,r){oi.call(n,r)?n[r].push(t):st(n,r,[t])}),Zo=fr(function(t,r,e){var u=-1,i=typeof r=="function",o=su(t)?Ku(t.length):[];return uo(t,function(t){o[++u]=i?n(r,t,e):Lt(t,r,e)}),o}),qo=Tr(function(n,t,r){st(n,r,t)}),Vo=Tr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Ko=fr(function(n,t){if(null==n)return[];var r=t.length;return 1<r&&Oe(n,t[0],t[1])?t=[]:2<r&&Oe(t[0],t[1],t[2])&&(t=[t[0]]),
|
||||
Xt(n,wt(t,1),[])}),Go=ki||function(){return $n.Date.now()},Ho=fr(function(n,t,r){var e=1;if(r.length)var u=L(r,de(Ho)),e=32|e;return fe(n,e,t,r,u)}),Jo=fr(function(n,t,r){var e=3;if(r.length)var u=L(r,de(Jo)),e=32|e;return fe(t,e,n,r,u)}),Yo=fr(function(n,t){return dt(n,1,t)}),Qo=fr(function(n,t,r){return dt(n,Su(t)||0,r)});cu.Cache=Fn;var Xo=fr(function(t,r){r=1==r.length&&ff(r[0])?c(r[0],k(ye())):c(wt(r,1),k(ye()));var e=r.length;return fr(function(u){for(var i=-1,o=Ci(u.length,e);++i<o;)u[i]=r[i].call(this,u[i]);
|
||||
return n(t,this,u)})}),nf=fr(function(n,t){return fe(n,32,T,t,L(t,de(nf)))}),tf=fr(function(n,t){return fe(n,64,T,t,L(t,de(tf)))}),rf=pe(function(n,t){return fe(n,256,T,T,T,t)}),ef=ee(It),uf=ee(function(n,t){return n>=t}),of=Ut(function(){return arguments}())?Ut:function(n){return yu(n)&&oi.call(n,"callee")&&!bi.call(n,"callee")},ff=Ku.isArray,cf=Vn?k(Vn):Ct,af=zi||Vu,lf=Kn?k(Kn):Dt,sf=Gn?k(Gn):Tt,hf=Hn?k(Hn):Nt,pf=Jn?k(Jn):Pt,_f=Yn?k(Yn):Zt,vf=ee(Kt),gf=ee(function(n,t){return n<=t}),df=$r(function(n,t){
|
||||
if(ze(t)||su(t))Cr(t,Wu(t),n);else for(var r in t)oi.call(t,r)&&ot(n,r,t[r])}),yf=$r(function(n,t){Cr(t,Bu(t),n)}),bf=$r(function(n,t,r,e){Cr(t,Bu(t),n,e)}),xf=$r(function(n,t,r,e){Cr(t,Wu(t),n,e)}),jf=pe(ht),wf=fr(function(n,t){n=Qu(n);var r=-1,e=t.length,u=2<e?t[2]:T;for(u&&Oe(t[0],t[1],u)&&(e=1);++r<e;)for(var u=t[r],i=Bu(u),o=-1,f=i.length;++o<f;){var c=i[o],a=n[c];(a===T||lu(a,ei[c])&&!oi.call(n,c))&&(n[c]=u[c])}return n}),mf=fr(function(t){return t.push(T,ae),n(Of,T,t)}),Af=Yr(function(n,t,r){
|
||||
null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),n[t]=r},Tu($u)),Ef=Yr(function(n,t,r){null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),oi.call(n,t)?n[t].push(r):n[t]=[r]},ye),kf=fr(Lt),Sf=$r(function(n,t,r){Yt(n,t,r)}),Of=$r(function(n,t,r,e){Yt(n,t,r,e)}),If=pe(function(n,t){var r={};if(null==n)return r;var e=false;t=c(t,function(t){return t=Sr(t,n),e||(e=1<t.length),t}),Cr(n,ve(n),r),e&&(r=_t(r,7,le));for(var u=t.length;u--;)xr(r,t[u]);return r}),Rf=pe(function(n,t){return null==n?{}:nr(n,t);
|
||||
}),zf=oe(Wu),Wf=oe(Bu),Bf=qr(function(n,t,r){return t=t.toLowerCase(),n+(r?Cu(t):t)}),Lf=qr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Uf=qr(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Cf=Zr("toLowerCase"),Df=qr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),Mf=qr(function(n,t,r){return n+(r?" ":"")+$f(t)}),Tf=qr(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),$f=Zr("toUpperCase"),Ff=fr(function(t,r){try{return n(t,T,r)}catch(n){return pu(n)?n:new Hu(n)}}),Nf=pe(function(n,t){
|
||||
return r(t,function(t){t=Me(t),st(n,t,Ho(n[t],n))}),n}),Pf=Hr(),Zf=Hr(true),qf=fr(function(n,t){return function(r){return Lt(r,n,t)}}),Vf=fr(function(n,t){return function(r){return Lt(n,r,t)}}),Kf=Xr(c),Gf=Xr(u),Hf=Xr(h),Jf=re(),Yf=re(true),Qf=Qr(function(n,t){return n+t},0),Xf=ie("ceil"),nc=Qr(function(n,t){return n/t},1),tc=ie("floor"),rc=Qr(function(n,t){return n*t},1),ec=ie("round"),uc=Qr(function(n,t){return n-t},0);return An.after=function(n,t){if(typeof t!="function")throw new ti("Expected a function");
|
||||
return n=Eu(n),function(){if(1>--n)return t.apply(this,arguments)}},An.ary=eu,An.assign=df,An.assignIn=yf,An.assignInWith=bf,An.assignWith=xf,An.at=jf,An.before=uu,An.bind=Ho,An.bindAll=Nf,An.bindKey=Jo,An.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return ff(n)?n:[n]},An.chain=Ye,An.chunk=function(n,t,r){if(t=(r?Oe(n,t,r):t===T)?1:Ui(Eu(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Ku(Oi(r/t));e<r;)i[u++]=hr(n,e,e+=t);return i},An.compact=function(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){
|
||||
var i=n[t];i&&(u[e++]=i)}return u},An.concat=function(){var n=arguments.length;if(!n)return[];for(var t=Ku(n-1),r=arguments[0];n--;)t[n-1]=arguments[n];return a(ff(r)?Ur(r):[r],wt(t,1))},An.cond=function(t){var r=null==t?0:t.length,e=ye();return t=r?c(t,function(n){if("function"!=typeof n[1])throw new ti("Expected a function");return[e(n[0]),n[1]]}):[],fr(function(e){for(var u=-1;++u<r;){var i=t[u];if(n(i[0],this,e))return n(i[1],this,e)}})},An.conforms=function(n){return vt(_t(n,1))},An.constant=Tu,
|
||||
An.countBy=$o,An.create=function(n,t){var r=eo(n);return null==t?r:at(r,t)},An.curry=iu,An.curryRight=ou,An.debounce=fu,An.defaults=wf,An.defaultsDeep=mf,An.defer=Yo,An.delay=Qo,An.difference=wo,An.differenceBy=mo,An.differenceWith=Ao,An.drop=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),hr(n,0>t?0:t,e)):[]},An.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),t=e-t,hr(n,0,0>t?0:t)):[]},An.dropRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true,true):[];
|
||||
},An.dropWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true):[]},An.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&Oe(n,t,r)&&(r=0,e=u),u=n.length,r=Eu(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:Eu(e),0>e&&(e+=u),e=r>e?0:ku(e);r<e;)n[r++]=t;return n},An.filter=function(n,t){return(ff(n)?i:jt)(n,ye(t,3))},An.flatMap=function(n,t){return wt(ru(n,t),1)},An.flatMapDeep=function(n,t){return wt(ru(n,t),$)},An.flatMapDepth=function(n,t,r){return r=r===T?1:Eu(r),
|
||||
wt(ru(n,t),r)},An.flatten=Ze,An.flattenDeep=function(n){return(null==n?0:n.length)?wt(n,$):[]},An.flattenDepth=function(n,t){return null!=n&&n.length?(t=t===T?1:Eu(t),wt(n,t)):[]},An.flip=function(n){return fe(n,512)},An.flow=Pf,An.flowRight=Zf,An.fromPairs=function(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e},An.functions=function(n){return null==n?[]:Et(n,Wu(n))},An.functionsIn=function(n){return null==n?[]:Et(n,Bu(n))},An.groupBy=Po,An.initial=function(n){
|
||||
return(null==n?0:n.length)?hr(n,0,-1):[]},An.intersection=Eo,An.intersectionBy=ko,An.intersectionWith=So,An.invert=Af,An.invertBy=Ef,An.invokeMap=Zo,An.iteratee=Fu,An.keyBy=qo,An.keys=Wu,An.keysIn=Bu,An.map=ru,An.mapKeys=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,t(n,e,u),n)}),r},An.mapValues=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,e,t(n,e,u))}),r},An.matches=function(n){return Ht(_t(n,1))},An.matchesProperty=function(n,t){return Jt(n,_t(t,1))},An.memoize=cu,
|
||||
An.merge=Sf,An.mergeWith=Of,An.method=qf,An.methodOf=Vf,An.mixin=Nu,An.negate=au,An.nthArg=function(n){return n=Eu(n),fr(function(t){return Qt(t,n)})},An.omit=If,An.omitBy=function(n,t){return Lu(n,au(ye(t)))},An.once=function(n){return uu(2,n)},An.orderBy=function(n,t,r,e){return null==n?[]:(ff(t)||(t=null==t?[]:[t]),r=e?T:r,ff(r)||(r=null==r?[]:[r]),Xt(n,t,r))},An.over=Kf,An.overArgs=Xo,An.overEvery=Gf,An.overSome=Hf,An.partial=nf,An.partialRight=tf,An.partition=Vo,An.pick=Rf,An.pickBy=Lu,An.property=Zu,
|
||||
An.propertyOf=function(n){return function(t){return null==n?T:kt(n,t)}},An.pull=Oo,An.pullAll=Ke,An.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,ye(r,2)):n},An.pullAllWith=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,T,r):n},An.pullAt=Io,An.range=Jf,An.rangeRight=Yf,An.rearg=rf,An.reject=function(n,t){return(ff(n)?i:jt)(n,au(ye(t,3)))},An.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=ye(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),
|
||||
u.push(e))}return ur(n,u),r},An.rest=function(n,t){if(typeof n!="function")throw new ti("Expected a function");return t=t===T?t:Eu(t),fr(n,t)},An.reverse=Ge,An.sampleSize=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Eu(t),(ff(n)?et:ar)(n,t)},An.set=function(n,t,r){return null==n?n:lr(n,t,r)},An.setWith=function(n,t,r,e){return e=typeof e=="function"?e:T,null==n?n:lr(n,t,r,e)},An.shuffle=function(n){return(ff(n)?ut:sr)(n)},An.slice=function(n,t,r){var e=null==n?0:n.length;return e?(r&&typeof r!="number"&&Oe(n,t,r)?(t=0,
|
||||
r=e):(t=null==t?0:Eu(t),r=r===T?e:Eu(r)),hr(n,t,r)):[]},An.sortBy=Ko,An.sortedUniq=function(n){return n&&n.length?gr(n):[]},An.sortedUniqBy=function(n,t){return n&&n.length?gr(n,ye(t,2)):[]},An.split=function(n,t,r){return r&&typeof r!="number"&&Oe(n,t,r)&&(t=r=T),r=r===T?4294967295:r>>>0,r?(n=Iu(n))&&(typeof t=="string"||null!=t&&!hf(t))&&(t=yr(t),!t&&Rn.test(n))?Or(M(n),0,r):n.split(t,r):[]},An.spread=function(t,r){if(typeof t!="function")throw new ti("Expected a function");return r=null==r?0:Ui(Eu(r),0),
|
||||
fr(function(e){var u=e[r];return e=Or(e,0,r),u&&a(e,u),n(t,this,e)})},An.tail=function(n){var t=null==n?0:n.length;return t?hr(n,1,t):[]},An.take=function(n,t,r){return n&&n.length?(t=r||t===T?1:Eu(t),hr(n,0,0>t?0:t)):[]},An.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),t=e-t,hr(n,0>t?0:t,e)):[]},An.takeRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),false,true):[]},An.takeWhile=function(n,t){return n&&n.length?jr(n,ye(t,3)):[]},An.tap=function(n,t){return t(n),
|
||||
n},An.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ti("Expected a function");return du(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),fu(n,t,{leading:e,maxWait:t,trailing:u})},An.thru=Qe,An.toArray=mu,An.toPairs=zf,An.toPairsIn=Wf,An.toPath=function(n){return ff(n)?c(n,Me):wu(n)?[n]:Ur(jo(Iu(n)))},An.toPlainObject=Ou,An.transform=function(n,t,e){var u=ff(n),i=u||af(n)||_f(n);if(t=ye(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:du(n)&&_u(o)?eo(di(n)):{};
|
||||
}return(i?r:mt)(n,function(n,r,u){return t(e,n,r,u)}),e},An.unary=function(n){return eu(n,1)},An.union=Ro,An.unionBy=zo,An.unionWith=Wo,An.uniq=function(n){return n&&n.length?br(n):[]},An.uniqBy=function(n,t){return n&&n.length?br(n,ye(t,2)):[]},An.uniqWith=function(n,t){return t=typeof t=="function"?t:T,n&&n.length?br(n,T,t):[]},An.unset=function(n,t){return null==n||xr(n,t)},An.unzip=He,An.unzipWith=Je,An.update=function(n,t,r){return null==n?n:lr(n,t,kr(r)(kt(n,t)),void 0)},An.updateWith=function(n,t,r,e){
|
||||
return e=typeof e=="function"?e:T,null!=n&&(n=lr(n,t,kr(r)(kt(n,t)),e)),n},An.values=Uu,An.valuesIn=function(n){return null==n?[]:S(n,Bu(n))},An.without=Bo,An.words=Mu,An.wrap=function(n,t){return nf(kr(t),n)},An.xor=Lo,An.xorBy=Uo,An.xorWith=Co,An.zip=Do,An.zipObject=function(n,t){return Ar(n||[],t||[],ot)},An.zipObjectDeep=function(n,t){return Ar(n||[],t||[],lr)},An.zipWith=Mo,An.entries=zf,An.entriesIn=Wf,An.extend=yf,An.extendWith=bf,Nu(An,An),An.add=Qf,An.attempt=Ff,An.camelCase=Bf,An.capitalize=Cu,
|
||||
An.ceil=Xf,An.clamp=function(n,t,r){return r===T&&(r=t,t=T),r!==T&&(r=Su(r),r=r===r?r:0),t!==T&&(t=Su(t),t=t===t?t:0),pt(Su(n),t,r)},An.clone=function(n){return _t(n,4)},An.cloneDeep=function(n){return _t(n,5)},An.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,5,t)},An.cloneWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,4,t)},An.conformsTo=function(n,t){return null==t||gt(n,t,Wu(t))},An.deburr=Du,An.defaultTo=function(n,t){return null==n||n!==n?t:n},An.divide=nc,An.endsWith=function(n,t,r){
|
||||
n=Iu(n),t=yr(t);var e=n.length,e=r=r===T?e:pt(Eu(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},An.eq=lu,An.escape=function(n){return(n=Iu(n))&&H.test(n)?n.replace(K,nt):n},An.escapeRegExp=function(n){return(n=Iu(n))&&en.test(n)?n.replace(rn,"\\$&"):n},An.every=function(n,t,r){var e=ff(n)?u:bt;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.find=Fo,An.findIndex=Ne,An.findKey=function(n,t){return p(n,ye(t,3),mt)},An.findLast=No,An.findLastIndex=Pe,An.findLastKey=function(n,t){return p(n,ye(t,3),At);
|
||||
},An.floor=tc,An.forEach=nu,An.forEachRight=tu,An.forIn=function(n,t){return null==n?n:oo(n,ye(t,3),Bu)},An.forInRight=function(n,t){return null==n?n:fo(n,ye(t,3),Bu)},An.forOwn=function(n,t){return n&&mt(n,ye(t,3))},An.forOwnRight=function(n,t){return n&&At(n,ye(t,3))},An.get=Ru,An.gt=ef,An.gte=uf,An.has=function(n,t){return null!=n&&we(n,t,Rt)},An.hasIn=zu,An.head=qe,An.identity=$u,An.includes=function(n,t,r,e){return n=su(n)?n:Uu(n),r=r&&!e?Eu(r):0,e=n.length,0>r&&(r=Ui(e+r,0)),ju(n)?r<=e&&-1<n.indexOf(t,r):!!e&&-1<v(n,t,r);
|
||||
},An.indexOf=function(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Eu(r),0>r&&(r=Ui(e+r,0)),v(n,t,r)):-1},An.inRange=function(n,t,r){return t=Au(t),r===T?(r=t,t=0):r=Au(r),n=Su(n),n>=Ci(t,r)&&n<Ui(t,r)},An.invoke=kf,An.isArguments=of,An.isArray=ff,An.isArrayBuffer=cf,An.isArrayLike=su,An.isArrayLikeObject=hu,An.isBoolean=function(n){return true===n||false===n||yu(n)&&"[object Boolean]"==Ot(n)},An.isBuffer=af,An.isDate=lf,An.isElement=function(n){return yu(n)&&1===n.nodeType&&!xu(n)},An.isEmpty=function(n){
|
||||
if(null==n)return true;if(su(n)&&(ff(n)||typeof n=="string"||typeof n.splice=="function"||af(n)||_f(n)||of(n)))return!n.length;var t=vo(n);if("[object Map]"==t||"[object Set]"==t)return!n.size;if(ze(n))return!Vt(n).length;for(var r in n)if(oi.call(n,r))return false;return true},An.isEqual=function(n,t){return Mt(n,t)},An.isEqualWith=function(n,t,r){var e=(r=typeof r=="function"?r:T)?r(n,t):T;return e===T?Mt(n,t,T,r):!!e},An.isError=pu,An.isFinite=function(n){return typeof n=="number"&&Wi(n)},An.isFunction=_u,
|
||||
An.isInteger=vu,An.isLength=gu,An.isMap=sf,An.isMatch=function(n,t){return n===t||$t(n,t,xe(t))},An.isMatchWith=function(n,t,r){return r=typeof r=="function"?r:T,$t(n,t,xe(t),r)},An.isNaN=function(n){return bu(n)&&n!=+n},An.isNative=function(n){if(go(n))throw new Hu("Unsupported core-js use. Try https://npms.io/search?q=ponyfill.");return Ft(n)},An.isNil=function(n){return null==n},An.isNull=function(n){return null===n},An.isNumber=bu,An.isObject=du,An.isObjectLike=yu,An.isPlainObject=xu,An.isRegExp=hf,
|
||||
An.isSafeInteger=function(n){return vu(n)&&-9007199254740991<=n&&9007199254740991>=n},An.isSet=pf,An.isString=ju,An.isSymbol=wu,An.isTypedArray=_f,An.isUndefined=function(n){return n===T},An.isWeakMap=function(n){return yu(n)&&"[object WeakMap]"==vo(n)},An.isWeakSet=function(n){return yu(n)&&"[object WeakSet]"==Ot(n)},An.join=function(n,t){return null==n?"":Bi.call(n,t)},An.kebabCase=Lf,An.last=Ve,An.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==T&&(u=Eu(r),u=0>u?Ui(e+u,0):Ci(u,e-1)),
|
||||
t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=_(n,d,u,true);return n},An.lowerCase=Uf,An.lowerFirst=Cf,An.lt=vf,An.lte=gf,An.max=function(n){return n&&n.length?xt(n,$u,It):T},An.maxBy=function(n,t){return n&&n.length?xt(n,ye(t,2),It):T},An.mean=function(n){return y(n,$u)},An.meanBy=function(n,t){return y(n,ye(t,2))},An.min=function(n){return n&&n.length?xt(n,$u,Kt):T},An.minBy=function(n,t){return n&&n.length?xt(n,ye(t,2),Kt):T},An.stubArray=qu,An.stubFalse=Vu,An.stubObject=function(){return{}},An.stubString=function(){
|
||||
return""},An.stubTrue=function(){return true},An.multiply=rc,An.nth=function(n,t){return n&&n.length?Qt(n,Eu(t)):T},An.noConflict=function(){return $n._===this&&($n._=si),this},An.noop=Pu,An.now=Go,An.pad=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return!t||e>=t?n:(t=(t-e)/2,ne(Ii(t),r)+n+ne(Oi(t),r))},An.padEnd=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return t&&e<t?n+ne(t-e,r):n},An.padStart=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return t&&e<t?ne(t-e,r)+n:n},An.parseInt=function(n,t,r){
|
||||
return r||null==t?t=0:t&&(t=+t),Mi(Iu(n).replace(on,""),t||0)},An.random=function(n,t,r){if(r&&typeof r!="boolean"&&Oe(n,t,r)&&(t=r=T),r===T&&(typeof t=="boolean"?(r=t,t=T):typeof n=="boolean"&&(r=n,n=T)),n===T&&t===T?(n=0,t=1):(n=Au(n),t===T?(t=n,n=0):t=Au(t)),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Ti(),Ci(n+r*(t-n+Cn("1e-"+((r+"").length-1))),t)):ir(n,t)},An.reduce=function(n,t,r){var e=ff(n)?l:j,u=3>arguments.length;return e(n,ye(t,4),r,u,uo)},An.reduceRight=function(n,t,r){var e=ff(n)?s:j,u=3>arguments.length;
|
||||
return e(n,ye(t,4),r,u,io)},An.repeat=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Eu(t),or(Iu(n),t)},An.replace=function(){var n=arguments,t=Iu(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},An.result=function(n,t,r){t=Sr(t,n);var e=-1,u=t.length;for(u||(u=1,n=T);++e<u;){var i=null==n?T:n[Me(t[e])];i===T&&(e=u,i=r),n=_u(i)?i.call(n):i}return n},An.round=ec,An.runInContext=x,An.sample=function(n){return(ff(n)?Qn:cr)(n)},An.size=function(n){if(null==n)return 0;if(su(n))return ju(n)?D(n):n.length;
|
||||
var t=vo(n);return"[object Map]"==t||"[object Set]"==t?n.size:Vt(n).length},An.snakeCase=Df,An.some=function(n,t,r){var e=ff(n)?h:pr;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.sortedIndex=function(n,t){return _r(n,t)},An.sortedIndexBy=function(n,t,r){return vr(n,t,ye(r,2))},An.sortedIndexOf=function(n,t){var r=null==n?0:n.length;if(r){var e=_r(n,t);if(e<r&&lu(n[e],t))return e}return-1},An.sortedLastIndex=function(n,t){return _r(n,t,true)},An.sortedLastIndexBy=function(n,t,r){return vr(n,t,ye(r,2),true);
|
||||
},An.sortedLastIndexOf=function(n,t){if(null==n?0:n.length){var r=_r(n,t,true)-1;if(lu(n[r],t))return r}return-1},An.startCase=Mf,An.startsWith=function(n,t,r){return n=Iu(n),r=null==r?0:pt(Eu(r),0,n.length),t=yr(t),n.slice(r,r+t.length)==t},An.subtract=uc,An.sum=function(n){return n&&n.length?m(n,$u):0},An.sumBy=function(n,t){return n&&n.length?m(n,ye(t,2)):0},An.template=function(n,t,r){var e=An.templateSettings;r&&Oe(n,t,r)&&(t=T),n=Iu(n),t=bf({},t,e,ce),r=bf({},t.imports,e.imports,ce);var u,i,o=Wu(r),f=S(r,o),c=0;
|
||||
r=t.interpolate||jn;var a="__p+='";r=Xu((t.escape||jn).source+"|"+r.source+"|"+(r===Q?pn:jn).source+"|"+(t.evaluate||jn).source+"|$","g");var l=oi.call(t,"sourceURL")?"//# sourceURL="+(t.sourceURL+"").replace(/[\r\n]/g," ")+"\n":"";if(n.replace(r,function(t,r,e,o,f,l){return e||(e=o),a+=n.slice(c,l).replace(wn,z),r&&(u=true,a+="'+__e("+r+")+'"),f&&(i=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=oi.call(t,"variable")&&t.variable)||(a="with(obj){"+a+"}"),
|
||||
a=(i?a.replace(P,""):a).replace(Z,"$1").replace(q,"$1;"),a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=Ff(function(){return Ju(o,l+"return "+a).apply(T,f)}),t.source=a,pu(t))throw t;return t},An.times=function(n,t){if(n=Eu(n),1>n||9007199254740991<n)return[];var r=4294967295,e=Ci(n,4294967295);for(t=ye(t),n-=4294967295,e=A(e,t);++r<n;)t(r);return e},An.toFinite=Au,
|
||||
An.toInteger=Eu,An.toLength=ku,An.toLower=function(n){return Iu(n).toLowerCase()},An.toNumber=Su,An.toSafeInteger=function(n){return n?pt(Eu(n),-9007199254740991,9007199254740991):0===n?n:0},An.toString=Iu,An.toUpper=function(n){return Iu(n).toUpperCase()},An.trim=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(un,""):n&&(t=yr(t))?(n=M(n),r=M(t),t=I(n,r),r=R(n,r)+1,Or(n,t,r).join("")):n},An.trimEnd=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(fn,""):n&&(t=yr(t))?(n=M(n),t=R(n,M(t))+1,
|
||||
Or(n,0,t).join("")):n},An.trimStart=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(on,""):n&&(t=yr(t))?(n=M(n),t=I(n,M(t)),Or(n,t).join("")):n},An.truncate=function(n,t){var r=30,e="...";if(du(t))var u="separator"in t?t.separator:u,r="length"in t?Eu(t.length):r,e="omission"in t?yr(t.omission):e;n=Iu(n);var i=n.length;if(Rn.test(n))var o=M(n),i=o.length;if(r>=i)return n;if(i=r-D(e),1>i)return e;if(r=o?Or(o,0,i).join(""):n.slice(0,i),u===T)return r+e;if(o&&(i+=r.length-i),hf(u)){if(n.slice(i).search(u)){
|
||||
var f=r;for(u.global||(u=Xu(u.source,Iu(_n.exec(u))+"g")),u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===T?i:c)}}else n.indexOf(yr(u),i)!=i&&(u=r.lastIndexOf(u),-1<u&&(r=r.slice(0,u)));return r+e},An.unescape=function(n){return(n=Iu(n))&&G.test(n)?n.replace(V,tt):n},An.uniqueId=function(n){var t=++fi;return Iu(n)+t},An.upperCase=Tf,An.upperFirst=$f,An.each=nu,An.eachRight=tu,An.first=qe,Nu(An,function(){var n={};return mt(An,function(t,r){oi.call(An.prototype,r)||(n[r]=t)}),n}(),{chain:false
|
||||
}),An.VERSION="4.17.15",r("bind bindKey curry curryRight partial partialRight".split(" "),function(n){An[n].placeholder=An}),r(["drop","take"],function(n,t){Un.prototype[n]=function(r){r=r===T?1:Ui(Eu(r),0);var e=this.__filtered__&&!t?new Un(this):this.clone();return e.__filtered__?e.__takeCount__=Ci(r,e.__takeCount__):e.__views__.push({size:Ci(r,4294967295),type:n+(0>e.__dir__?"Right":"")}),e},Un.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){
|
||||
var r=t+1,e=1==r||3==r;Un.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:ye(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){var r="take"+(t?"Right":"");Un.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Un.prototype[n]=function(){return this.__filtered__?new Un(this):this[r](1)}}),Un.prototype.compact=function(){return this.filter($u)},Un.prototype.find=function(n){
|
||||
return this.filter(n).head()},Un.prototype.findLast=function(n){return this.reverse().find(n)},Un.prototype.invokeMap=fr(function(n,t){return typeof n=="function"?new Un(this):this.map(function(r){return Lt(r,n,t)})}),Un.prototype.reject=function(n){return this.filter(au(ye(n)))},Un.prototype.slice=function(n,t){n=Eu(n);var r=this;return r.__filtered__&&(0<n||0>t)?new Un(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==T&&(t=Eu(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Un.prototype.takeRightWhile=function(n){
|
||||
return this.reverse().takeWhile(n).reverse()},Un.prototype.toArray=function(){return this.take(4294967295)},mt(Un.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=An[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(An.prototype[t]=function(){function t(n){return n=u.apply(An,a([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Un,l=f[0],s=c||ff(o);s&&r&&typeof l=="function"&&1!=l.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,l=i&&!h,c=c&&!p;
|
||||
return!i&&s?(o=c?o:new Un(this),o=n.apply(o,f),o.__actions__.push({func:Qe,args:[t],thisArg:T}),new On(o,h)):l&&c?n.apply(this,f):(o=this.thru(t),l?e?o.value()[0]:o.value():o)})}),r("pop push shift sort splice unshift".split(" "),function(n){var t=ri[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);An.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(ff(u)?u:[],n)}return this[r](function(r){return t.apply(ff(r)?r:[],n)});
|
||||
}}),mt(Un.prototype,function(n,t){var r=An[t];if(r){var e=r.name+"";oi.call(Gi,e)||(Gi[e]=[]),Gi[e].push({name:t,func:r})}}),Gi[Jr(T,2).name]=[{name:"wrapper",func:T}],Un.prototype.clone=function(){var n=new Un(this.__wrapped__);return n.__actions__=Ur(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Ur(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Ur(this.__views__),n},Un.prototype.reverse=function(){if(this.__filtered__){var n=new Un(this);
|
||||
n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Un.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=ff(t),u=0>r,i=e?t.length:0;n=i;for(var o=this.__views__,f=0,c=-1,a=o.length;++c<a;){var l=o[c],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":n-=s;break;case"take":n=Ci(n,f+s);break;case"takeRight":f=Ui(f,n-s)}}if(n={start:f,end:n},o=n.start,f=n.end,n=f-o,o=u?f:o-1,f=this.__iteratees__,c=f.length,a=0,l=Ci(n,this.__takeCount__),!e||!u&&i==n&&l==n)return wr(t,this.__actions__);
|
||||
e=[];n:for(;n--&&a<l;){for(o+=r,u=-1,i=t[o];++u<c;){var h=f[u],s=h.type,h=(0,h.iteratee)(i);if(2==s)i=h;else if(!h){if(1==s)continue n;break n}}e[a++]=i}return e},An.prototype.at=To,An.prototype.chain=function(){return Ye(this)},An.prototype.commit=function(){return new On(this.value(),this.__chain__)},An.prototype.next=function(){this.__values__===T&&(this.__values__=mu(this.value()));var n=this.__index__>=this.__values__.length;return{done:n,value:n?T:this.__values__[this.__index__++]}},An.prototype.plant=function(n){
|
||||
for(var t,r=this;r instanceof En;){var e=Fe(r);e.__index__=0,e.__values__=T,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},An.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Un?(this.__actions__.length&&(n=new Un(this)),n=n.reverse(),n.__actions__.push({func:Qe,args:[Ge],thisArg:T}),new On(n,this.__chain__)):this.thru(Ge)},An.prototype.toJSON=An.prototype.valueOf=An.prototype.value=function(){return wr(this.__wrapped__,this.__actions__)},An.prototype.first=An.prototype.head,
|
||||
wi&&(An.prototype[wi]=Xe),An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($n._=rt, define(function(){return rt})):Nn?((Nn.exports=rt)._=rt,Fn._=rt):$n._=rt}).call(this);
|
16
web/js/5_inspire-tree.min.js
vendored
16
web/js/5_inspire-tree.min.js
vendored
File diff suppressed because one or more lines are too long
8
web/js/6_inspire-tree-dom.min.js
vendored
8
web/js/6_inspire-tree-dom.min.js
vendored
File diff suppressed because one or more lines are too long
1
web/js/7_jquery.toast.min.js
vendored
1
web/js/7_jquery.toast.min.js
vendored
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user